Axiom
diff_key :
forall (d : dict) (k k' : key) (v : data),
k <> k' -> find k (add k' v d) = find k d.
End DICT.
(* building a dictionary from a list of entries *)
Module Type DICT_PLUS.
Declare Module Dict : DICT.
Parameter build : list (Dict.key * Dict.data) -> Dict.dict.
End DICT_PLUS.
Module Dict_Plus (D: DICT) : DICT_PLUS with Module Dict := D.
Module Dict := D.
Definition key := D.key.
Definition data := D.data.
Definition dict := D.dict.
Definition add := D.add.
Definition empty := D.empty.
Fixpoint addlist (l : list (key * data)) : dict -> dict :=
fun d : dict =>
match l with
| nil => d
| p :: l' => match p with
| (k, v) => addlist l' (add k v d)
end
end.
Definition build (l : list (key * data)) := addlist l empty.
End Dict_Plus.
(* keys for dictionaries We just need a data type on which Leibniz equality is decidable *)
Module Type KEY.
Parameter A : Set.
Parameter eqdec : forall a b : A, {a = b} + {a <> b}.
End KEY.
Module LKey (K: KEY) : KEY with Definition A := list K.A.
Definition A := list K.A.
Definition eqdec : forall a b : A, {a = b} + {a <> b}.
intro a; elim a.
simple induction b; [ left; auto | right; red in |- *; discriminate 1 ].
intros a0 k Ha; simple induction b.
right; red in |- *; discriminate 1.
intros a1 l0 s; case (K.eqdec a0 a1); intro H0.
case (Ha l0); intro H1.
left; rewrite H1; rewrite H0; auto.
right; red in |- *; injection 1.
intro H3; case (H1 H3).
right; red in |- *; injection 1.
intros H3 H4; case (H0 H4).
Defined.
End LKey.
Module ZKey : KEY with Definition A := Z.
Definition A := Z.
Definition eqdec := Z_eq_dec.
End ZKey.
Module LZKey := LKey ZKey.
(* Check (LZKey.eqdec (cons `7` (nil ?)) (cons `3+4` (nil ?))). *)
(* pairs of keys *)
Module PairKey (K1: KEY) (K2: KEY) : KEY with Definition
A := (K1.A * K2.A)%type.
Definition A := (K1.A * K2.A)%type.
Definition eqdec : forall a b : A, {a = b} + {a <> b}.
simple destruct a.
intros a0 a1; simple destruct b; intros b0 b1.
case (K1.eqdec a0 b0); intro H; case (K2.eqdec a1 b1); intro H0;
[ left | right | right | right ]; try (rewrite H; rewrite H0; trivial);
red in |- *; intro H1; injection H1; tauto.
Defined.
End PairKey.
(* Total decidable orders *)
Module Type DEC_ORDER.
Parameter A : Set.
Parameter le : A -> A -> Prop.
Parameter lt : A -> A -> Prop.

Axiom le_lt_or_eq : forall a b : A, le a b -> lt a b \/ a = b.
Parameter lt_eq_lt_dec : forall a b : A, {lt a b} + {a = b} + {lt b a}.