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) τ.