Library morphisms



Coertions between untyped and typed expressions.

Produces an untyped expression by removing all ω.
Fixpoint erase (e : expr) : expr :=
  match e with
    | 0 | _0
    | 1 | id _1
    | var xvar x
    | vat xvat x
    | e + ferase e + erase f
    | e · ferase e · erase f
    | e ^*(erase e) ^*
    | p e p (erase e)
    | ν a eν a (erase e)
    | ω a eerase e
  end.
Notation " ⎣ e ⎦ " := (erase e).
erase perserves no_perm, single, multi, str_positive and positive. An atom is fresh for e if it doesn't appear in the type of e.
Lemma fresh_type : A e, A e a, ¬ In a A a # e.

The support of §e is included in its type.
Lemma support_min_type : e A, A e support e A.

W gets obliterated by erase.
The size of e is smaller than that of e.
Lemma size_erase : e, size e size e.
e is always untyped.
Lemma untyped_erase : e, untyped e.
⎣⎦ preserves ==.
Produces a typed expression, by using W and support heavily.
Fixpoint typed_vers (e : expr) :=
  match e with
    | 0 []
    | 1id []
    | var xvar x
    | vat xvat x
    | e + f
      W (support f--(support e)) (typed_vers e)
      + W (support e--(support f)) (typed_vers f)
    | e · f
      W (support f--(support e)) (typed_vers e)
      · W (support e--(support f)) (typed_vers f)
    | e ^*(typed_vers e)^*
    | p e p (typed_vers e)
    | ν a e
      if inb a (support e)
      then ν a (typed_vers e)
      else ν a (ω a (typed_vers e))
    | _e
  end.
Notation " ⎡ e ⎤ " := (typed_vers e).

Section poly.
  Hypothesis K_not_zero : O < K.
  Hypothesis bounded_τ : x, length (τ x) K.
  Lemma typed_vers_size e : size (e) (K*(size e)*(size e))%nat.
End poly.

First half of a bijection between typed and untyped expressions.
typed_vers perserves no_perm, single, multi, str_positive and positive.
The size of e is larger than that of e.
Lemma size_typed_vers : e, size e size e.
The support of e can type e, if e is untyped.

rm0 e removes 0 and _ from e if it is possible,

and returns 0 or _ otherwise.
Fixpoint rm0 e :=
  match e with
    | e + f
      let e := rm0 e in
      let f := rm0 f in
      if (eq0' e)
      then f
      else if eq0' f
           then e
           else (e + f)
    | e · f
      let e := rm0 e in
      let f := rm0 f in
      if (eq0' e)
      then e
      else if eq0' f
           then f
           else (e · f)
    | e^*
      let e := rm0 e in
      match get_bot e with
      | inl false1
      | inr Aid A
      | inl truee^*
      end
    | ν a e
      let e := rm0 e in
      match get_bot e with
      | inl false0
      | inr A (rm a A)
      | inl trueν a e
      end
    | p e
      let e := rm0 e in
      match get_bot e with
      | inl false0
      | inr A (p A)
      | inl true p e
      end
    | ω a e
      let e := rm0 e in
      match get_bot e with
      | inl false0
      | inr A (a :: A)
      | inl trueω a e
      end
    | ee
  end.
rm0 perserves no_perm,single,multi and str_positive.
Lemma no_perm_rm0 : e, no_perm e no_perm (rm0 e).
Lemma single_rm0 : e, single e single (rm0 e).
Lemma multi_rm0 : e, multi e multi (rm0 e).
Lemma str_positive_rm0 : e, str_positive e
                                   str_positive (rm0 e).
rm0 preserves untypedness.
Lemma untyped_rm0 : e, untyped e untyped (rm0 e).
rm0 reduces the size of the expression.
Lemma size_rm0 : e, size (rm0 e) size e.
rm0 preserves types.
Lemma typed_rm0 : e A, A e A (rm0 e).

rm0 and eq0 agree on untyped expressions.
Lemma eq0_rm0_u : e, eq0 e = eq0' (rm0 e).
rm0 e is either syntactically null or str_positive.
Lemma positive_or_nul_rm0 e : eq0' (rm0 e) = true
                              (str_positive (rm0 e)).
rm0 e is always positive.
Lemma positive_rm0 e : positive (rm0 e).
rm0 is the identity over str_positive expressions.
positive expressions compose the kernel of rm0.
Lemma positive_rm0_id : e, positive e rm0 e = e.
rm0 is involutive.
Lemma rm0_involutive : e, rm0 (rm0 e) = rm0 e.
rm0 preserves freshness for untyped expressions.
Lemma fresh_rm0 a e : untyped e fresh a e fresh a (rm0 e).
rm0 preserves ==.

Applying permutations.

Reserved Notation " p • e " (at level 19).
Lemma apply_perm_var_bis : p x l, is_perm_bool (x,l) = true
    is_perm_bool (x,p l) = true.

Definition apply_perm_var (p : perm) (n : Letter) : Letter :=
  match n with
  | exist _ (x,l) h ⇒ (exist (fun xis_perm_bool x = true) (x,pl)
                              (@apply_perm_var_bis p x l h))
  end.

Lemma apply_perm_var_τ (p : perm) (n : Letter) :
  τ (apply_perm_var p n) = p (τ n).
Lemma apply_perm_var_app (p q : perm) (n : Letter) :
  (apply_perm_var q (apply_perm_var p n)) apply_perm_var (q++p) n.
Lemma apply_perm_var_equiv_perm n :
  Proper (equiv_perm ==> eq_letter) (Basics.flip apply_perm_var n).
Lemma apply_perm_var_eq_letter p :
  Proper (eq_letter ==> eq_letter) (apply_perm_var p).
Lemma apply_perm_var_equiv_perm_eq_letter :
  Proper (equiv_perm ==> eq_letter ==> eq_letter) apply_perm_var.

Fixpoint apply_perm p e :=
  match e with
  | id Aid (pA)
  | A (pA)
  | 00
  | 11
  | var xvar (apply_perm_var p x)
  | vat avat (pa)
  | e + fp e + p f
  | e · fp e · p f
  | e^*p e ^*
  | q e [] (p++q) e
  | ν a eν (pa) (p e)
  | ω a eω (pa) (p e)
  end
where " p • e " := (apply_perm p e).
Global Instance apply_perm_equiv_perm :
  Proper (equiv_perm ==> eq_expr ==> eq_expr) apply_perm.

pe is not bigger than twice the size of e.
Lemma apply_perm_size e p : size (pe) 2 × size e.

apply_perm perserves single, multi and eq0.
Lemma multi_apply_perm : e p, multi e multi (pe).

Lemma single_apply_perm : e p, single e single (pe).

Lemma eq0_apply_perm : e p, eq0 (pe) = eq0 e.

apply_perm doesn't change no_perm.
Lemma no_perm_apply_perm :
   e p, (no_perm e no_perm (pe)).

apply_perm isn't a problem for typing.
Lemma has_type_apply_perm : e A p, (pA) e A p e.
Lemma apply_perm_has_type {e A} :
   p, (pA) (p e) A e.

apply_perm doesn't change untypedness.
apply_perm works well with freshness.
Lemma fresh_apply_perm : e a p, a # e (pa) # p e.

The support of pe is p applied to the support of e.
apply_perm commutes with erase,typed_vers and W.
Lemma erase_apply_perm : e p, p e = pe.

Lemma W_apply_perm : e l p, p (W l e) = W (pl) (pe).

Lemma typed_vers_apply_perm : e p, p e = pe.

apply_perm preserves positive and str_positive.
Simplification lemma.
Lemma eq0'_rm0_apply_perm : e p, eq0' (rm0 (pe)) = eq0' (rm0 e).

Technical lemma.
Lemma rm0_eq0_get_bot : e p,
    rm0 e = e reflect3 (e = 0)
                          (fun Be = (pB))
                          (get_bot e = inl true)
                          (get_bot (p e)).

apply_perm commutes wiht rm0.
Lemma rm0_apply_perm : e p, rm0 (pe) = prm0 e.

If e doesn't contain any θ constructors, then applying the permutations [(a,a)] or [] doesn't change the expression.
Lemma apply_perm_nil (e : expr) :
  no_perm e [] e == e.
Lemma apply_perm_id e a :
  no_perm e [a,a] e == e.

Removing permutations

Fixpoint rm_perm e :=
  match e with
  | e + frm_perm e + rm_perm f
  | e · frm_perm e · rm_perm f
  | e ^*(rm_perm e)^*
  | ν a eν a (rm_perm e)
  | ω a eω a (rm_perm e)
  | _ erm_perm e
  | ee
  end.
rm_perm reduces the size of expressions.
rm_perm doesn't change untypedness, single or str_positive.
Lemma untyped_rm_perm e : untyped e untyped (rm_perm e).
Lemma single_rm_perm e : single e single (rm_perm e).
Lemma multi_rm_perm e : multi e multi (rm_perm e).
Lemma str_positive_rm_perm : e, str_positive e
                                   str_positive (rm_perm e).
rm_perm preserves positive.
The kernel of rm_perm is no_perm.
rm_perm produces expressions statisfying no_perm.
rm_perm and apply_perm commute partially.
rm_perm preserves ==.
fresh and has_type behave well with rm_perm and apply_perm.
Lemma fresh_rm_perm p a e : (a # e p a # rm_perm (p e)).

Lemma has_type_rm_perm_apply_perm e p A :
  A (pe) A rm_perm (pe).