Library letter



Parameter Name : Set.
Parameter τ_nm : Name list Atom.
Parameter beq_name : Name Name bool.
Axiom beq_name_spec : x y, reflect (x=y) (beq_name x y).
Axiom τ_nm_spec : a, NoDup (τ_nm a).

Definition is_perm x := p, p (snd x) = τ_nm (fst x).
Parameter get_new : list Atom Atom.
Axiom new_atom : l, ¬In (get_new l) l.

Fixpoint transfer_perm l m :=
  match (l,m) with
  | ([],_) |(_,[])[]
  | (a::l,b::m)
    let q :=(transfer_perm l m) in
    let n := get_new (l++(elements q)) in
    ([b,n]++q++[a,n])
  end.
Lemma is_perm_no_dup_length m l :
  NoDup l NoDup m length l = length m
  (transfer_perm l m) l = m.
Definition nodup_bool (l : list Atom):=
  (forallb (fun x(count_occ Atom_eq_dec l x) =? 1) l).
Lemma nodup_bool_spec l : reflect (NoDup l) (nodup_bool l).

Definition is_perm_bool x :=
  (length (snd x) =? length (τ_nm (fst x))) && (nodup_bool (snd x)).

Lemma is_perm_bool_spec x : reflect (is_perm x) (is_perm_bool x).
Lemma is_perm_bool_is_perm x :
   is_perm x is_perm_bool x = true.

Definition Letter := { x | is_perm_bool x = true}.
Definition beq_letter : Letter Letter bool :=
  fun n1 n2
    match (proj1_sig n1,proj1_sig n2) with
    |((x,l),(y,m))
     if (beq_name x y)
     then beq_list l m
     else false
    end.
Definition eq_letter (x y : Letter) := proj1_sig x = proj1_sig y.
Infix " ≃ " := eq_letter (at level 50).

Global Instance eq_letter_Equivalence : Equivalence eq_letter.
Lemma beq_letter_spec : x y, reflect (x y) (beq_letter x y).
Definition τ : Letter (list Atom) :=
  fun n
    match (proj1_sig n) with
    | (x,l)l
    end.
Tactic Notation "simpl_is_perm" "in" ident(h):=
  let p := fresh "p" in
   simpl_is_perm_hyp p h.
Tactic Notation "simpl_is_perm" "in" ident(h) "as" ident(p) :=
   simpl_is_perm_hyp p h.
Lemma τ_spec : a, NoDup (τ a).
Lemma eq_letter_τ : Proper (eq_letter ==> Logic.eq) τ.