(* 
  Find the list of booleans associated with an element,
  return the empty list if the element does not exists
*)
Fixpoint find_code (a : A) (l : code) {struct l} : list bool :=
  match l with
  | nil => nil
  | (b, c) :: l1 =>
      match eqA_dec a b with
      | left _ => c
      | right _ => find_code a l1
      end
  end.

(* Specifications: *)
Theorem find_code_correct1 : forall (c : code) (a : A) (b : bool) (l : list bool), find_code a c = b :: l -> In (a, b :: l) c.
Theorem find_code_correct2 : forall (c : code) (a : A) (l : list bool), unique_key c -> In (a, l) c -> find_code a c = l.
Theorem not_in_find_code : forall a l, (forall p, ~ In (a, p) l) -> find_code a l = nil.
Theorem find_code_app : forall a l1 l2, not_null l1 -> find_code a (l1 ++ l2) = match find_code a l1 with | nil => find_code a l2 | b1 :: l3 => b1 :: l3 end.
Theorem find_code_permutation : forall (a : A) (c1 c2 : code), permutation c1 c2 -> unique_prefix c1 -> find_code a c1 = find_code a c2.
Theorem in_find_map : forall p a l b, In (a, l) p -> find_code a (map (fun v : A * list bool => match v with | (a1, b1) => (a1, b :: b1) end) p) = b :: find_code a p.
Theorem not_in_find_map : forall p a b, (forall l, ~ In (a, l) p) -> find_code a (map (fun v : A * list bool => match v with | (a1, b1) => (a1, b :: b1) end) p) = nil.