(* * This code was developped by IDEALX (http://IDEALX.org/) and * contributors (their names can be found in the CONTRIBUTORS file). It * is released under the terms of the BSD license (see LICENCE file * for details). *)
(****************************************************************** *          	      ASSOCIATIVE ARRAYS V0.1 (April 2001) * * ****************************************************************** * *   We define the associative array (key -> value associations) * datatype as list of couples, providing definitions of standards * operations such as adding, deleting. * *   We introduce predicates for membership of a key and of couples. * *   Finally we define a search operator ("find") which returns the * value associated with a key or the "none" option (see file * Option.v which should be part of this contribution) on failure. * *   Lemmas we prove about these concepts were motivated by our * needs at the moment we created this file. We hope they'll suit * your needs too but anyway, feel free to communicate any wish *  or remark. * ******************************************************************)
Unset Standard Proposition Elimination Names.
Section associative_arrays.
Set Asymmetric Patterns.
Set Strict Implicit.
Unset Implicit Arguments.
Variable K : Set.
Variable V : Set.
Hypothesis Keq_dec : forall x y : K, {x = y} + {x <> y}.
Record Tuple : Set := mkTuple {k : K; v : V}.
(**************************************************)
(* Definitions                                    *)
(**************************************************)
Definition assoc := list Tuple.
(* <Warning> : Syntax is discontinued *)
Definition assoc_empty := nil (A:=Tuple).
(* search function : locate a value by its key *)
Fixpoint assoc_find (l : assoc) : K -> option V :=
fun k0 : K =>
match l with
| nil => none V
| mkTuple k v :: l' =>
match Keq_dec k k0 with
| left _ => some V v
| right _ => assoc_find l' k0
end
end.
(* function to add an entry in an array:  may replace an existing entry if the key is already present in the array *)
Fixpoint assoc_add (l : assoc) : K -> V -> assoc :=
fun (k0 : K) (v0 : V) =>
match l with
| nil => mkTuple k0 v0 :: nil
| mkTuple k v :: l' =>
match Keq_dec k k0 with
| left _ => mkTuple k0 v0 :: l'
| _ => mkTuple k v :: assoc_add l' k0 v0
end
end.
(* remove an entry from an array or do nothing if the key isn't present in the array *)
Fixpoint assoc_delete (l : assoc) : K -> assoc :=
fun k0 : K =>
match l with
| nil => nil (A:=Tuple)
| mkTuple k v :: l' =>
match Keq_dec k k0 with
| left _ => assoc_delete l' k0
| _ => mkTuple k v :: assoc_delete l' k0
end
end.
(* tests the existence of a key in an array *)
Definition assoc_mem (l : assoc) (k : K) : Prop :=
match assoc_find l k with
| some _ => True
| _ => False
end.
(* tests the existence of the specified tuple in an array *)
Definition assoc_hasmem (l : assoc) (k : K) (v : V) : Prop :=
match assoc_find l k with
| some v' => v = v'
| _ => False
end.
(* definition of equal functions from keys to values option *)
Definition assoc_eqm (f1 f2 : K -> option V) := forall k : K, f1 k = f2 k.
(* definition of almost-everywhere-equal functions from keys to values option *)
Definition assoc_almost_eqm (k0 : K) (f1 f2 : K -> option V) :=
forall k : K, k <> k0 -> f1 k = f2 k.
(**************************************************)
(* Some properties about eqm functions            *)
(**************************************************)

(* Specifications: *)
Lemma assoc_almost_eqm_trans :
forall (k : K) (f1 f2 f3 : K -> option V),
assoc_almost_eqm k f1 f2 ->
assoc_almost_eqm k f2 f3 -> assoc_almost_eqm k f1 f3.
Lemma assoc_almost_eqm_sym :
forall (k : K) (f1 f2 : K -> option V),
assoc_almost_eqm k f1 f2 -> assoc_almost_eqm k f2 f1.
Lemma assoc_eqm_trans :
forall f1 f2 f3 : K -> option V,
assoc_eqm f1 f2 -> assoc_eqm f2 f3 -> assoc_eqm f1 f3.