Library morphisms
Fixpoint erase (e : expr) : expr :=
match e with
| 0 | ⊥ _ ⇒ 0
| 1 | id _ ⇒ 1
| var x ⇒ var x
| vat x ⇒ vat x
| e + f ⇒ erase e + erase f
| e · f ⇒ erase e · erase f
| e ^* ⇒ (erase e) ^*
| ‹ p › e ⇒ ‹ p › (erase e)
| ν a e ⇒ ν a (erase e)
| ω a e ⇒ erase e
end.
Notation " ⎣ e ⎦ " := (erase e).
match e with
| 0 | ⊥ _ ⇒ 0
| 1 | id _ ⇒ 1
| var x ⇒ var x
| vat x ⇒ vat x
| e + f ⇒ erase e + erase f
| e · f ⇒ erase e · erase f
| e ^* ⇒ (erase e) ^*
| ‹ p › e ⇒ ‹ p › (erase e)
| ν a e ⇒ ν a (erase e)
| ω a e ⇒ erase 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.
The support of §e is included in its type.
W gets obliterated by erase.
Lemma W_erase l e : ⎣W l e⎦ = ⎣e⎦.
Lemma no_perm_erase : ∀ e, no_perm e → no_perm ⎣e⎦.
Lemma single_erase : ∀ e, single e → single ⎣e⎦.
Lemma multi_erase : ∀ e, multi e → multi ⎣e⎦.
Lemma str_positive_erase :
∀ e, str_positive e → str_positive ⎣e⎦.
Lemma positive_erase : ∀ e, positive e → positive ⎣e⎦.
Lemma no_perm_erase : ∀ e, no_perm e → no_perm ⎣e⎦.
Lemma single_erase : ∀ e, single e → single ⎣e⎦.
Lemma multi_erase : ∀ e, multi e → multi ⎣e⎦.
Lemma str_positive_erase :
∀ e, str_positive e → str_positive ⎣e⎦.
Lemma positive_erase : ∀ e, positive e → positive ⎣e⎦.
The size of ⎣e⎦ is smaller than that of e.
⎣e⎦ is always untyped.
⎣⎦ preserves ==.
Produces a typed expression, by using W and support heavily.
Fixpoint typed_vers (e : expr) :=
match e with
| 0 ⇒ ⊥ []
| 1 ⇒ id []
| var x ⇒ var x
| vat x ⇒ vat 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.
match e with
| 0 ⇒ ⊥ []
| 1 ⇒ id []
| var x ⇒ var x
| vat x ⇒ vat 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.
Lemma no_perm_typed_vers : ∀ e, no_perm e → no_perm ⎡e⎤.
Lemma single_typed_vers : ∀ e, single e → single ⎡e⎤.
Lemma multi_typed_vers : ∀ e, multi e → multi ⎡e⎤.
Lemma str_positive_typed_vers :
∀ e, str_positive e → str_positive ⎡e⎤.
Lemma positive_typed_vers :
∀ e, positive e → positive ⎡e⎤.
Lemma single_typed_vers : ∀ e, single e → single ⎡e⎤.
Lemma multi_typed_vers : ∀ e, multi e → multi ⎡e⎤.
Lemma str_positive_typed_vers :
∀ e, str_positive e → str_positive ⎡e⎤.
Lemma positive_typed_vers :
∀ e, positive e → positive ⎡e⎤.
The size of ⎡e⎤ is larger than that of e.
The support of e can type ⎡e⎤, if e is untyped.
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 false ⇒ 1
| inr A ⇒ id A
| inl true ⇒ e^*
end
| ν a e ⇒
let e := rm0 e in
match get_bot e with
| inl false ⇒ 0
| inr A ⇒ ⊥ (rm a A)
| inl true ⇒ ν a e
end
| ‹ p › e ⇒
let e := rm0 e in
match get_bot e with
| inl false ⇒ 0
| inr A ⇒ ⊥ (p⧓ A)
| inl true ⇒ ‹ p › e
end
| ω a e ⇒
let e := rm0 e in
match get_bot e with
| inl false ⇒ 0
| inr A ⇒ ⊥ (a :: A)
| inl true ⇒ ω a e
end
| e ⇒ e
end.
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 false ⇒ 1
| inr A ⇒ id A
| inl true ⇒ e^*
end
| ν a e ⇒
let e := rm0 e in
match get_bot e with
| inl false ⇒ 0
| inr A ⇒ ⊥ (rm a A)
| inl true ⇒ ν a e
end
| ‹ p › e ⇒
let e := rm0 e in
match get_bot e with
| inl false ⇒ 0
| inr A ⇒ ⊥ (p⧓ A)
| inl true ⇒ ‹ p › e
end
| ω a e ⇒
let e := rm0 e in
match get_bot e with
| inl false ⇒ 0
| inr A ⇒ ⊥ (a :: A)
| inl true ⇒ ω a e
end
| e ⇒ e
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).
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.
rm0 reduces the size of the expression.
rm0 preserves types.
rm0 and eq0 agree on untyped expressions.
rm0 e is either syntactically null or str_positive.
rm0 e is always positive.
rm0 is the identity over str_positive expressions.
positive expressions compose the kernel of rm0.
rm0 is involutive.
rm0 preserves freshness for untyped expressions.
rm0 preserves ==.
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 x ⇒ is_perm_bool x = true) (x,p⧓l)
(@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 A ⇒ id (p⧓A)
| ⊥ A ⇒ ⊥ (p⧓A)
| 0 ⇒ 0
| 1 ⇒ 1
| var x ⇒ var (apply_perm_var p x)
| vat a ⇒ vat (p⋈a)
| e + f ⇒ p • e + p • f
| e · f ⇒ p • e · p • f
| e^* ⇒ p • e ^*
| ‹ q › e ⇒ ‹ [] › (p++q) • e
| ν a e ⇒ ν (p⋈a) (p • e)
| ω a e ⇒ ω (p⋈a) (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.
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 x ⇒ is_perm_bool x = true) (x,p⧓l)
(@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 A ⇒ id (p⧓A)
| ⊥ A ⇒ ⊥ (p⧓A)
| 0 ⇒ 0
| 1 ⇒ 1
| var x ⇒ var (apply_perm_var p x)
| vat a ⇒ vat (p⋈a)
| e + f ⇒ p • e + p • f
| e · f ⇒ p • e · p • f
| e^* ⇒ p • e ^*
| ‹ q › e ⇒ ‹ [] › (p++q) • e
| ν a e ⇒ ν (p⋈a) (p • e)
| ω a e ⇒ ω (p⋈a) (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.
p•e is not bigger than twice the size of e.
apply_perm perserves single, multi and eq0.
Lemma multi_apply_perm : ∀ e p, multi e ↔ multi (p•e).
Lemma single_apply_perm : ∀ e p, single e ↔ single (p•e).
Lemma eq0_apply_perm : ∀ e p, eq0 (p•e) = eq0 e.
Lemma single_apply_perm : ∀ e p, single e ↔ single (p•e).
Lemma eq0_apply_perm : ∀ e p, eq0 (p•e) = eq0 e.
apply_perm doesn't change no_perm.
apply_perm isn't a problem for typing.
Lemma has_type_apply_perm : ∀ e A p, (p⋆⧓A) ⊨ e → A ⊨ p • e.
Lemma apply_perm_has_type {e A} :
∀ p, (p⧓A) ⊨ (p • e) → A ⊨ e.
Lemma apply_perm_has_type {e A} :
∀ p, (p⧓A) ⊨ (p • e) → A ⊨ e.
apply_perm doesn't change untypedness.
apply_perm works well with freshness.
The support of p•e 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⎦ = ⎣p•e⎦.
Lemma W_apply_perm : ∀ e l p, p • (W l e) = W (p⧓l) (p•e).
Lemma typed_vers_apply_perm : ∀ e p, p • ⎡e⎤ = ⎡p•e⎤.
Lemma W_apply_perm : ∀ e l p, p • (W l e) = W (p⧓l) (p•e).
Lemma typed_vers_apply_perm : ∀ e p, p • ⎡e⎤ = ⎡p•e⎤.
apply_perm preserves positive and str_positive.
Lemma str_positive_apply_perm e p :
str_positive e ↔ str_positive (p•e).
Lemma positive_apply_perm e p :
positive e ↔ positive (p•e).
Lemma rm0_inv_apply_perm : ∀ e p, rm0 e = e → rm0 (p•e) = p•e.
str_positive e ↔ str_positive (p•e).
Lemma positive_apply_perm e p :
positive e ↔ positive (p•e).
Lemma rm0_inv_apply_perm : ∀ e p, rm0 e = e → rm0 (p•e) = p•e.
Simplification lemma.
Technical lemma.
Lemma rm0_eq0_get_bot : ∀ e p,
rm0 e = e → reflect3 (e = 0)
(fun B ⇒ e = ⊥ (p⋆⧓B))
(get_bot e = inl true)
(get_bot (p • e)).
rm0 e = e → reflect3 (e = 0)
(fun B ⇒ e = ⊥ (p⋆⧓B))
(get_bot e = inl true)
(get_bot (p • e)).
apply_perm commutes wiht rm0.
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.
no_perm e → [] • e == e.
Lemma apply_perm_id e a :
no_perm e → [a,a] • e == e.
Fixpoint rm_perm e :=
match e with
| e + f ⇒ rm_perm e + rm_perm f
| e · f ⇒ rm_perm e · rm_perm f
| e ^* ⇒ (rm_perm e)^*
| ν a e ⇒ ν a (rm_perm e)
| ω a e ⇒ ω a (rm_perm e)
| ‹ _ › e ⇒ rm_perm e
| e ⇒ e
end.
match e with
| e + f ⇒ rm_perm e + rm_perm f
| e · f ⇒ rm_perm e · rm_perm f
| e ^* ⇒ (rm_perm e)^*
| ν a e ⇒ ν a (rm_perm e)
| ω a e ⇒ ω a (rm_perm e)
| ‹ _ › e ⇒ rm_perm e
| e ⇒ e
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).
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.