Record Tuple : Set := mkTuple {k : K; v : V}.Record Tuple : Set := mkTuple {k : K; v : V}.Record Tuple : Set := mkTuple {k : K; v : V}.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.

Lemma assoc_semfind_commute : forall (k0 k1 : K) (v0 v1 : V) (l : assoc), k0 <> k1 -> assoc_eqm (assoc_find (mkTuple k1 v1 :: mkTuple k0 v0 :: l)) (assoc_find (mkTuple k0 v0 :: mkTuple k1 v1 :: l)).