Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(*         *   The Coq Proof Assistant / The Coq Development Team       *)
(*  v      *   INRIA, CNRS and contributors - Copyright 1999-2018       *)
(* <O___,, *       (see CREDITS file for the list of authors)           *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)

Require Import Equalities Bool SetoidList RelationPairs.

Set Implicit Arguments.

Keys and datas used in the future MMaps

Module KeyDecidableType(D:DecidableType).

 Local Open Scope signature_scope.
 Notation key := D.t.

 Definition eqk {elt} : relation (key*elt) := D.eq @@1.
 Definition eqke {elt} : relation (key*elt) := D.eq * Logic.eq.

 Hint Unfold eqk eqke : core.
eqk, eqke are equalities
 Instance eqk_equiv {elt} : Equivalence (@eqk elt) := _.

 Instance eqke_equiv {elt} : Equivalence (@eqke elt) := _.
eqke is stricter than eqk
 
elt:Type

subrelation eqke eqk
elt:Type

subrelation eqke eqk
firstorder. Qed.
Alternative definitions of eqke and eqk
 
elt:Type
k, k':key
e, e':elt

eqke (k, e) (k', e') = (D.eq k k' /\ e = e')
elt:Type
k, k':key
e, e':elt

eqke (k, e) (k', e') = (D.eq k k' /\ e = e')
reflexivity. Defined.
elt:Type
p, q:(key * elt)%type

eqke p q = (D.eq (fst p) (fst q) /\ snd p = snd q)
elt:Type
p, q:(key * elt)%type

eqke p q = (D.eq (fst p) (fst q) /\ snd p = snd q)
reflexivity. Defined.
elt:Type
k, k':key
e, e':elt

eqke (k, e) (k', e') -> D.eq k k'
elt:Type
k, k':key
e, e':elt

eqke (k, e) (k', e') -> D.eq k k'
now destruct 1. Qed.
elt:Type
k, k':key
e, e':elt

eqke (k, e) (k', e') -> e = e'
elt:Type
k, k':key
e, e':elt

eqke (k, e) (k', e') -> e = e'
now destruct 1. Qed.
elt:Type
k, k':key
e, e':elt

eqk (k, e) (k', e') = D.eq k k'
elt:Type
k, k':key
e, e':elt

eqk (k, e) (k', e') = D.eq k k'
reflexivity. Defined.
elt:Type
p, q:(key * elt)%type

eqk p q = D.eq (fst p) (fst q)
elt:Type
p, q:(key * elt)%type

eqk p q = D.eq (fst p) (fst q)
reflexivity. Qed.
elt:Type
k, k':key
e, e':elt

eqk (k, e) (k', e') -> D.eq k k'
elt:Type
k, k':key
e, e':elt

eqk (k, e) (k', e') -> D.eq k k'
trivial. Qed. Hint Resolve eqke_1 eqke_2 eqk_1 : core. (* Additional facts *)
elt:Type
p:(key * elt)%type
m:list (key * elt)

InA eqke p m -> InA eqk p m
elt:Type
p:(key * elt)%type
m:list (key * elt)

InA eqke p m -> InA eqk p m
induction 1; firstorder. Qed. Hint Resolve InA_eqke_eqk : core.
elt:Type
p:(key * elt)%type
m:list (key * elt)

InA eqk p m -> exists q : key * elt, eqk p q /\ InA eqke q m
elt:Type
p:(key * elt)%type
m:list (key * elt)

InA eqk p m -> exists q : key * elt, eqk p q /\ InA eqke q m
induction 1; firstorder. Qed.
elt:Type
p, q:(key * elt)%type
m:list (key * elt)

eqk p q -> InA eqk p m -> InA eqk q m
elt:Type
p, q:(key * elt)%type
m:list (key * elt)

eqk p q -> InA eqk p m -> InA eqk q m
now intros <-. Qed. Definition MapsTo {elt} (k:key)(e:elt):= InA eqke (k,e). Definition In {elt} k m := exists e:elt, MapsTo k e m. Hint Unfold MapsTo In : core. (* Alternative formulations for [In k l] *)
elt:Type
k:key
l:list (key * elt)

In k l <-> (exists e : elt, InA eqk (k, e) l)
elt:Type
k:key
l:list (key * elt)

In k l <-> (exists e : elt, InA eqk (k, e) l)
elt:Type
k:key
l:list (key * elt)

(exists e : elt, InA eqke (k, e) l) <-> (exists e : elt, InA eqk (k, e) l)
elt:Type
k:key
l:list (key * elt)
e:elt
H:InA eqke (k, e) l

exists e0 : elt, InA eqk (k, e0) l
elt:Type
k:key
l:list (key * elt)
e:elt
H:InA eqk (k, e) l
exists e0 : elt, InA eqke (k, e0) l
elt:Type
k:key
l:list (key * elt)
e:elt
H:InA eqke (k, e) l

exists e0 : elt, InA eqk (k, e0) l
exists e; auto.
elt:Type
k:key
l:list (key * elt)
e:elt
H:InA eqk (k, e) l

exists e0 : elt, InA eqke (k, e0) l
elt:Type
k:key
l:list (key * elt)
e:elt
H:exists q : key * elt, eqk (k, e) q /\ InA eqke q l

exists e0 : elt, InA eqke (k, e0) l
elt:Type
k:key
l:list (key * elt)
e:elt
k':key
e':elt
E:eqk (k, e) (k', e')
H:InA eqke (k', e') l

exists e0 : elt, InA eqke (k, e0) l
elt:Type
k:key
l:list (key * elt)
e:elt
k':key
e':elt
E:D.eq k k'
H:InA eqke (k', e') l

exists e0 : elt, InA eqke (k, e0) l
elt:Type
k:key
l:list (key * elt)
e:elt
k':key
e':elt
E:D.eq k k'
H:InA eqke (k', e') l

InA eqke (k, e') l
now rewrite E. Qed.
elt:Type
l:list (key * elt)
k:key
e:elt

In k l <-> InA eqk (k, e) l
elt:Type
l:list (key * elt)
k:key
e:elt

In k l <-> InA eqk (k, e) l
elt:Type
l:list (key * elt)
k:key
e:elt

(exists e0 : elt, InA eqk (k, e0) l) <-> InA eqk (k, e) l
elt:Type
l:list (key * elt)
k:key
e, x:elt
H:InA eqk (k, x) l

InA eqk (k, e) l
elt:Type
l:list (key * elt)
k:key
e, x:elt
H:InA eqk (k, x) l

eqk (k, x) (k, e)
now compute. Qed.
elt:Type
k:key
l:list (key * elt)

In k l <-> Exists (fun p : key * elt => D.eq k (fst p)) l
elt:Type
k:key
l:list (key * elt)

In k l <-> Exists (fun p : key * elt => D.eq k (fst p)) l
elt:Type
k:key
l:list (key * elt)

(exists e : elt, InA eqke (k, e) l) <-> Exists (fun p : key * elt => D.eq k (fst p)) l
elt:Type
k:key
l:list (key * elt)

(exists (e : elt) (y : key * elt), eqke (k, e) y /\ List.In y l) <-> (exists x : key * elt, List.In x l /\ D.eq k (fst x))
elt:Type
k:key
l:list (key * elt)
x:(key * elt)%type
H:List.In x l
H0:D.eq k (fst x)

exists (e : elt) (y : key * elt), eqke (k, e) y /\ List.In y l
exists (snd x), x; auto. Qed.
elt:Type
k:key

In k nil <-> False
elt:Type
k:key

In k nil <-> False
rewrite In_alt2; apply Exists_nil. Qed.
elt:Type
k:key
p:(key * elt)%type
l:list (key * elt)

In k (p :: l) <-> D.eq k (fst p) \/ In k l
elt:Type
k:key
p:(key * elt)%type
l:list (key * elt)

In k (p :: l) <-> D.eq k (fst p) \/ In k l
rewrite !In_alt2, Exists_cons; intuition. Qed.
elt:Type

Proper (D.eq ==> eq ==> equivlistA eqke ==> iff) MapsTo
elt:Type

Proper (D.eq ==> eq ==> equivlistA eqke ==> iff) MapsTo
elt:Type
x, x':key
Hx:D.eq x x'
e, e':elt
He:e = e'
l, l':list (key * elt)
Hl:equivlistA eqke l l'

MapsTo x e l <-> MapsTo x' e' l'
elt:Type
x, x':key
Hx:D.eq x x'
e, e':elt
He:e = e'
l, l':list (key * elt)
Hl:equivlistA eqke l l'

InA eqke (x, e) l <-> InA eqke (x', e') l'
rewrite Hx, He, Hl; intuition. Qed.
elt:Type

Proper (D.eq ==> equivlistA eqk ==> iff) In
elt:Type

Proper (D.eq ==> equivlistA eqk ==> iff) In
elt:Type
x, x':key
Hx:D.eq x x'
l, l':list (key * elt)
Hl:equivlistA eqk l l'

In x l <-> In x' l'
elt:Type
x, x':key
Hx:D.eq x x'
l, l':list (key * elt)
Hl:equivlistA eqk l l'

(exists e : elt, InA eqk (x, e) l) <-> (exists e : elt, InA eqk (x', e) l')
elt:Type
x, x':key
Hx:D.eq x x'
l, l':list (key * elt)
Hl:equivlistA eqk l l'

(exists e : elt, InA eqk (x, e) l') <-> (exists e : elt, InA eqk (x', e) l')
elt:Type
x, x':key
Hx:D.eq x x'
l, l':list (key * elt)
Hl:equivlistA eqk l l'

(exists e : elt, InA eqk (x', e) l') <-> (exists e : elt, InA eqk (x', e) l')
intuition. Qed.
elt:Type
l:list (key * elt)
x, y:key
e:elt

D.eq x y -> MapsTo x e l -> MapsTo y e l
elt:Type
l:list (key * elt)
x, y:key
e:elt

D.eq x y -> MapsTo x e l -> MapsTo y e l
now intros <-. Qed.
elt:Type
l:list (key * elt)
x, y:key

D.eq x y -> In x l -> In y l
elt:Type
l:list (key * elt)
x, y:key

D.eq x y -> In x l -> In y l
now intros <-. Qed.
elt:Type
k, k':key
e:elt
l:list (key * elt)

In k ((k', e) :: l) -> D.eq k k' \/ In k l
elt:Type
k, k':key
e:elt
l:list (key * elt)

In k ((k', e) :: l) -> D.eq k k' \/ In k l
elt:Type
k, k':key
e:elt
l:list (key * elt)
e':elt
H:MapsTo k e' ((k', e) :: l)

D.eq k k' \/ In k l
elt:Type
k, k':key
e:elt
l:list (key * elt)
e':elt
H:InA eqke (k, e') ((k', e) :: l)

D.eq k k' \/ In k l
elt:Type
k, k':key
e:elt
l:list (key * elt)
e':elt
H:D.eq k k' /\ e' = e \/ InA eqke (k, e') l

D.eq k k' \/ In k l
elt:Type
k, k':key
e:elt
l:list (key * elt)
e':elt
H0:InA eqke (k, e') l

D.eq k k' \/ In k l
elt:Type
k, k':key
e:elt
l:list (key * elt)
e':elt
H0:InA eqke (k, e') l

In k l
now exists e'. Qed.
elt:Type
k, k':key
e, e':elt
l:list (key * elt)

InA eqk (k, e) ((k', e') :: l) -> ~ D.eq k k' -> InA eqk (k, e) l
elt:Type
k, k':key
e, e':elt
l:list (key * elt)

InA eqk (k, e) ((k', e') :: l) -> ~ D.eq k k' -> InA eqk (k, e) l
elt:Type
k, k':key
e, e':elt
l:list (key * elt)

D.eq k k' \/ InA eqk (k, e) l -> ~ D.eq k k' -> InA eqk (k, e) l
intuition. Qed.
elt:Type
x, x':(key * elt)%type
l:list (key * elt)

InA eqke x (x' :: l) -> ~ eqk x x' -> InA eqke x l
elt:Type
x, x':(key * elt)%type
l:list (key * elt)

InA eqke x (x' :: l) -> ~ eqk x x' -> InA eqke x l
elt:Type
x, x':(key * elt)%type
l:list (key * elt)

eqke x x' \/ InA eqke x l -> ~ eqk x x' -> InA eqke x l
elt:Type
x, x':(key * elt)%type
l:list (key * elt)
H:eqke x x'

~ eqk x x' -> InA eqke x l
elt:Type
x, x':(key * elt)%type
l:list (key * elt)
H:eqke x x'

eqk x x'
eauto with *. Qed. Hint Extern 2 (eqke ?a ?b) => split : core. Hint Resolve InA_eqke_eqk : core. Hint Resolve In_inv_2 In_inv_3 : core. End KeyDecidableType.

PairDecidableType

From two decidable types, we can build a new DecidableType over their cartesian product.
Module PairDecidableType(D1 D2:DecidableType) <: DecidableType.

 Definition t := (D1.t * D2.t)%type.

 Definition eq := (D1.eq * D2.eq)%signature.

 Instance eq_equiv : Equivalence eq := _.

 

forall x y : D1.t * D2.t, {eq x y} + {~ eq x y}

forall x y : D1.t * D2.t, {eq x y} + {~ eq x y}
x1:D1.t
x2:D2.t
y1:D1.t
y2:D2.t

{(D1.eq * D2.eq)%signature (x1, x2) (y1, y2)} + {~ (D1.eq * D2.eq)%signature (x1, x2) (y1, y2)}
destruct (D1.eq_dec x1 y1); destruct (D2.eq_dec x2 y2); compute; intuition. Defined. End PairDecidableType.
Similarly for pairs of UsualDecidableType
Module PairUsualDecidableType(D1 D2:UsualDecidableType) <: UsualDecidableType.
 Definition t := (D1.t * D2.t)%type.
 Definition eq := @eq t.
 Instance eq_equiv : Equivalence eq := _.
 

forall x y : t, {eq x y} + {~ eq x y}

forall x y : t, {eq x y} + {~ eq x y}
intros (x1,x2) (y1,y2); destruct (D1.eq_dec x1 y1); destruct (D2.eq_dec x2 y2); unfold eq, D1.eq, D2.eq in *; simpl; (left; f_equal; auto; fail) || (right; intros [=]; auto). Defined. End PairUsualDecidableType.
And also for pairs of UsualDecidableTypeFull
Module PairUsualDecidableTypeFull (D1 D2:UsualDecidableTypeFull)
  <: UsualDecidableTypeFull.

 Module M := PairUsualDecidableType D1 D2.
 Include Backport_DT (M).
 Include HasEqDec2Bool.

End PairUsualDecidableTypeFull.