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.
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:Typesubrelation eqke eqkfirstorder. Qed.elt:Typesubrelation eqke eqk
Alternative definitions of eqke and eqk
elt:Typek, k':keye, e':elteqke (k, e) (k', e') = (D.eq k k' /\ e = e')reflexivity. Defined.elt:Typek, k':keye, e':elteqke (k, e) (k', e') = (D.eq k k' /\ e = e')elt:Typep, q:(key * elt)%typeeqke p q = (D.eq (fst p) (fst q) /\ snd p = snd q)reflexivity. Defined.elt:Typep, q:(key * elt)%typeeqke p q = (D.eq (fst p) (fst q) /\ snd p = snd q)elt:Typek, k':keye, e':elteqke (k, e) (k', e') -> D.eq k k'now destruct 1. Qed.elt:Typek, k':keye, e':elteqke (k, e) (k', e') -> D.eq k k'elt:Typek, k':keye, e':elteqke (k, e) (k', e') -> e = e'now destruct 1. Qed.elt:Typek, k':keye, e':elteqke (k, e) (k', e') -> e = e'elt:Typek, k':keye, e':elteqk (k, e) (k', e') = D.eq k k'reflexivity. Defined.elt:Typek, k':keye, e':elteqk (k, e) (k', e') = D.eq k k'elt:Typep, q:(key * elt)%typeeqk p q = D.eq (fst p) (fst q)reflexivity. Qed.elt:Typep, q:(key * elt)%typeeqk p q = D.eq (fst p) (fst q)elt:Typek, k':keye, e':elteqk (k, e) (k', e') -> D.eq k k'trivial. Qed. Hint Resolve eqke_1 eqke_2 eqk_1 : core. (* Additional facts *)elt:Typek, k':keye, e':elteqk (k, e) (k', e') -> D.eq k k'elt:Typep:(key * elt)%typem:list (key * elt)InA eqke p m -> InA eqk p minduction 1; firstorder. Qed. Hint Resolve InA_eqke_eqk : core.elt:Typep:(key * elt)%typem:list (key * elt)InA eqke p m -> InA eqk p melt:Typep:(key * elt)%typem:list (key * elt)InA eqk p m -> exists q : key * elt, eqk p q /\ InA eqke q minduction 1; firstorder. Qed.elt:Typep:(key * elt)%typem:list (key * elt)InA eqk p m -> exists q : key * elt, eqk p q /\ InA eqke q melt:Typep, q:(key * elt)%typem:list (key * elt)eqk p q -> InA eqk p m -> InA eqk q mnow 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:Typep, q:(key * elt)%typem:list (key * elt)eqk p q -> InA eqk p m -> InA eqk q melt:Typek:keyl:list (key * elt)In k l <-> (exists e : elt, InA eqk (k, e) l)elt:Typek:keyl:list (key * elt)In k l <-> (exists e : elt, InA eqk (k, e) l)elt:Typek:keyl:list (key * elt)(exists e : elt, InA eqke (k, e) l) <-> (exists e : elt, InA eqk (k, e) l)elt:Typek:keyl:list (key * elt)e:eltH:InA eqke (k, e) lexists e0 : elt, InA eqk (k, e0) lelt:Typek:keyl:list (key * elt)e:eltH:InA eqk (k, e) lexists e0 : elt, InA eqke (k, e0) lexists e; auto.elt:Typek:keyl:list (key * elt)e:eltH:InA eqke (k, e) lexists e0 : elt, InA eqk (k, e0) lelt:Typek:keyl:list (key * elt)e:eltH:InA eqk (k, e) lexists e0 : elt, InA eqke (k, e0) lelt:Typek:keyl:list (key * elt)e:eltH:exists q : key * elt, eqk (k, e) q /\ InA eqke q lexists e0 : elt, InA eqke (k, e0) lelt:Typek:keyl:list (key * elt)e:eltk':keye':eltE:eqk (k, e) (k', e')H:InA eqke (k', e') lexists e0 : elt, InA eqke (k, e0) lelt:Typek:keyl:list (key * elt)e:eltk':keye':eltE:D.eq k k'H:InA eqke (k', e') lexists e0 : elt, InA eqke (k, e0) lnow rewrite E. Qed.elt:Typek:keyl:list (key * elt)e:eltk':keye':eltE:D.eq k k'H:InA eqke (k', e') lInA eqke (k, e') lelt:Typel:list (key * elt)k:keye:eltIn k l <-> InA eqk (k, e) lelt:Typel:list (key * elt)k:keye:eltIn k l <-> InA eqk (k, e) lelt:Typel:list (key * elt)k:keye:elt(exists e0 : elt, InA eqk (k, e0) l) <-> InA eqk (k, e) lelt:Typel:list (key * elt)k:keye, x:eltH:InA eqk (k, x) lInA eqk (k, e) lnow compute. Qed.elt:Typel:list (key * elt)k:keye, x:eltH:InA eqk (k, x) leqk (k, x) (k, e)elt:Typek:keyl:list (key * elt)In k l <-> Exists (fun p : key * elt => D.eq k (fst p)) lelt:Typek:keyl:list (key * elt)In k l <-> Exists (fun p : key * elt => D.eq k (fst p)) lelt:Typek:keyl:list (key * elt)(exists e : elt, InA eqke (k, e) l) <-> Exists (fun p : key * elt => D.eq k (fst p)) lelt:Typek:keyl: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))exists (snd x), x; auto. Qed.elt:Typek:keyl:list (key * elt)x:(key * elt)%typeH:List.In x lH0:D.eq k (fst x)exists (e : elt) (y : key * elt), eqke (k, e) y /\ List.In y lelt:Typek:keyIn k nil <-> Falserewrite In_alt2; apply Exists_nil. Qed.elt:Typek:keyIn k nil <-> Falseelt:Typek:keyp:(key * elt)%typel:list (key * elt)In k (p :: l) <-> D.eq k (fst p) \/ In k lrewrite !In_alt2, Exists_cons; intuition. Qed.elt:Typek:keyp:(key * elt)%typel:list (key * elt)In k (p :: l) <-> D.eq k (fst p) \/ In k lelt:TypeProper (D.eq ==> eq ==> equivlistA eqke ==> iff) MapsToelt:TypeProper (D.eq ==> eq ==> equivlistA eqke ==> iff) MapsToelt:Typex, x':keyHx:D.eq x x'e, e':eltHe:e = e'l, l':list (key * elt)Hl:equivlistA eqke l l'MapsTo x e l <-> MapsTo x' e' l'rewrite Hx, He, Hl; intuition. Qed.elt:Typex, x':keyHx:D.eq x x'e, e':eltHe:e = e'l, l':list (key * elt)Hl:equivlistA eqke l l'InA eqke (x, e) l <-> InA eqke (x', e') l'elt:TypeProper (D.eq ==> equivlistA eqk ==> iff) Inelt:TypeProper (D.eq ==> equivlistA eqk ==> iff) Inelt:Typex, x':keyHx:D.eq x x'l, l':list (key * elt)Hl:equivlistA eqk l l'In x l <-> In x' l'elt:Typex, x':keyHx: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:Typex, x':keyHx: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:Typex, x':keyHx: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:Typel:list (key * elt)x, y:keye:eltD.eq x y -> MapsTo x e l -> MapsTo y e lnow intros <-. Qed.elt:Typel:list (key * elt)x, y:keye:eltD.eq x y -> MapsTo x e l -> MapsTo y e lelt:Typel:list (key * elt)x, y:keyD.eq x y -> In x l -> In y lnow intros <-. Qed.elt:Typel:list (key * elt)x, y:keyD.eq x y -> In x l -> In y lelt:Typek, k':keye:eltl:list (key * elt)In k ((k', e) :: l) -> D.eq k k' \/ In k lelt:Typek, k':keye:eltl:list (key * elt)In k ((k', e) :: l) -> D.eq k k' \/ In k lelt:Typek, k':keye:eltl:list (key * elt)e':eltH:MapsTo k e' ((k', e) :: l)D.eq k k' \/ In k lelt:Typek, k':keye:eltl:list (key * elt)e':eltH:InA eqke (k, e') ((k', e) :: l)D.eq k k' \/ In k lelt:Typek, k':keye:eltl:list (key * elt)e':eltH:D.eq k k' /\ e' = e \/ InA eqke (k, e') lD.eq k k' \/ In k lelt:Typek, k':keye:eltl:list (key * elt)e':eltH0:InA eqke (k, e') lD.eq k k' \/ In k lnow exists e'. Qed.elt:Typek, k':keye:eltl:list (key * elt)e':eltH0:InA eqke (k, e') lIn k lelt:Typek, k':keye, e':eltl:list (key * elt)InA eqk (k, e) ((k', e') :: l) -> ~ D.eq k k' -> InA eqk (k, e) lelt:Typek, k':keye, e':eltl:list (key * elt)InA eqk (k, e) ((k', e') :: l) -> ~ D.eq k k' -> InA eqk (k, e) lintuition. Qed.elt:Typek, k':keye, e':eltl:list (key * elt)D.eq k k' \/ InA eqk (k, e) l -> ~ D.eq k k' -> InA eqk (k, e) lelt:Typex, x':(key * elt)%typel:list (key * elt)InA eqke x (x' :: l) -> ~ eqk x x' -> InA eqke x lelt:Typex, x':(key * elt)%typel:list (key * elt)InA eqke x (x' :: l) -> ~ eqk x x' -> InA eqke x lelt:Typex, x':(key * elt)%typel:list (key * elt)eqke x x' \/ InA eqke x l -> ~ eqk x x' -> InA eqke x lelt:Typex, x':(key * elt)%typel:list (key * elt)H:eqke x x'~ eqk x x' -> InA eqke x leauto 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.elt:Typex, x':(key * elt)%typel:list (key * elt)H:eqke x x'eqk x x'
PairDecidableType
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}destruct (D1.eq_dec x1 y1); destruct (D2.eq_dec x2 y2); compute; intuition. Defined. End PairDecidableType.x1:D1.tx2:D2.ty1:D1.ty2:D2.t{(D1.eq * D2.eq)%signature (x1, x2) (y1, y2)} + {~ (D1.eq * D2.eq)%signature (x1, x2) (y1, y2)}
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}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.forall x y : t, {eq x y} + {~ eq x y}
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.