Proof using.
intros m1 m2 c H; elim H; simpl in |- *; auto; clear H m1 m2.
intros; repeat rewrite <- app_ass; auto.
intros l1 l2 l3 H H0 H1 H2; apply permutation_trans with (1 := H0); auto.
Qed.
(* To decode, first find the initial section of booleans that maps an encoding, this initial section is accumulated in the head *)
Fixpoint decode_aux (c : code) (head m : list bool) {struct m} : list A :=
match m with
| nil => match find_val head c with
| Some a => a :: nil
| None => nil
end
| a :: m1 =>
match find_val head c with
| Some a1 => a1 :: decode_aux c (a :: nil) m1
| None => decode_aux c (head ++ a :: nil) m1
end
end.

(* Specifications: *)
(* decode_aux is correct *)
Theorem decode_aux_correct :
forall c : code,
unique_prefix c ->
not_null c ->
forall (m1 m2 head : list bool) (a : A),
find_val (head ++ m1) c = Some a ->
decode_aux c head (m1 ++ m2) = a :: decode_aux c nil m2.