Require Import List Permutation Arith Lia.
From Undecidability.Shared.Libs.DLW
Require Import utils pos vec.
From Undecidability.ILL
Require Import ILL.
Set Implicit Arguments.
Section obvious_links_between_fragments.
Notation "P ⇒ Q" := (forall Γ A, P Γ A -> Q Γ A) (at level 70).
Fact S_ill_restr_restr_wc : S_ill_restr ⇒ S_ill_restr_wc.
Proof.
induction 1.
all: try now constructor.
now constructor 3 with (Γ := Γ).
Qed.
Fact S_ill_full_wc : S_ill ⇒ S_ill_wc.
Proof.
induction 1.
all: try now constructor.
now constructor 3 with (Γ := Γ).
Qed.
Fact S_ill_restr_full : S_ill_restr ⇒ S_ill.
Proof.
induction 1.
all: try now constructor.
now constructor 2 with (Γ := Γ).
Qed.
Fact S_ill_restr_full_wc : S_ill_restr_wc ⇒ S_ill_wc.
Proof.
induction 1.
all: try now constructor.
+ now constructor 2 with A.
+ now constructor 3 with (Γ := Γ).
Qed.
End obvious_links_between_fragments.
Local Notation "Γ '⊢r' A" := (S_ill_restr Γ A) (at level 70, no associativity).
Local Notation "Γ '⊢' A" := (S_ill_wc Γ A) (at level 70, no associativity).
Fact S_ill_restr_weak Γ Δ B : Δ ⊢r B -> ‼Γ++Δ ⊢r B.
Proof. intro; induction Γ; simpl; auto; apply in_ill1_weak; auto. Qed.
Fact S_ill_wc_weak Γ Δ B : Δ ⊢ B -> ‼Γ++Δ ⊢ B.
Proof. intro; induction Γ; simpl; auto; apply in_ill4_weak; auto. Qed.
Fact S_ill_restr_cntr Γ Δ B : ‼Γ++‼Γ++Δ ⊢r B -> ‼Γ++ Δ ⊢r B.
Proof.
revert Γ Δ; intros Ga.
induction Ga as [ | A Ga IH ]; simpl; auto; intros De.
intros H.
apply in_ill1_cntr.
apply in_ill1_perm with (‼Ga ++ (!A::!A::De)).
+ apply Permutation_sym.
do 2 apply Permutation_cons_app; auto.
+ apply IH.
revert H; apply in_ill1_perm.
rewrite app_assoc.
apply Permutation_cons_app.
rewrite <- app_assoc.
apply Permutation_app; auto.
apply Permutation_cons_app; auto.
Qed.
Fact S_ill_wc_cntr Γ Δ B : ‼Γ++‼Γ++Δ ⊢ B -> ‼Γ++ Δ ⊢ B.
Proof.
revert Γ Δ; intros Ga.
induction Ga as [ | A Ga IH ]; simpl; auto; intros De.
intros H.
apply in_ill4_cntr.
apply in_ill4_perm with (‼Ga ++ (!A::!A::De)).
+ apply Permutation_sym.
do 2 apply Permutation_cons_app; auto.
+ apply IH.
revert H; apply in_ill4_perm.
rewrite app_assoc.
apply Permutation_cons_app.
rewrite <- app_assoc.
apply Permutation_app; auto.
apply Permutation_cons_app; auto.
Qed.
Theorem S_ill_restr_weak_cntr Σ Γ A B : In A Σ -> ‼Σ++Γ ⊢r B <-> !A::‼Σ++Γ ⊢r B.
Proof.
revert Σ Γ; intros Si Ga.
intros H.
apply In_perm in H.
destruct H as (Si' & H).
split.
+ apply in_ill1_weak.
+ intros H1.
apply in_ill1_perm with (‼(A :: Si') ++ Ga).
* apply Permutation_app; auto.
apply Permutation_map; auto.
* simpl; apply in_ill1_cntr.
revert H1; apply in_ill1_perm.
simpl; apply Permutation_cons; auto.
change (!A::‼Si'++Ga) with (‼(A::Si')++Ga).
apply Permutation_app; auto.
apply Permutation_map, Permutation_sym; auto.
Qed.
Theorem S_ill_wc_weak_cntr Σ Γ A B : In A Σ -> ‼Σ++Γ ⊢ B <-> !A::‼Σ++Γ ⊢ B.
Proof.
revert Σ Γ; intros Si Ga.
intros H.
apply In_perm in H.
destruct H as (Si' & H).
split.
+ apply in_ill4_weak.
+ intros H1.
apply in_ill4_perm with (‼(A :: Si') ++ Ga).
* apply Permutation_app; auto.
apply Permutation_map; auto.
* simpl; apply in_ill4_cntr.
revert H1; apply in_ill4_perm.
simpl; apply Permutation_cons; auto.
change (!A::‼Si'++Ga) with (‼(A::Si')++Ga).
apply Permutation_app; auto.
apply Permutation_map, Permutation_sym; auto.
Qed.
Section trivial_phase_semantics.
Variables (n : nat) (s : ill_vars -> vec nat n -> Prop).
Reserved Notation "'⟦' A '⟧'" (at level 65).
Definition ill_tps_imp (X Y : _ -> Prop) (v : vec _ n) := forall x, X x -> Y (vec_plus x v).
Definition ill_tps_mult (X Y : _ -> Prop) (x : vec _ n) := exists a b, x = vec_plus a b /\ X a /\ Y b.
Infix "**" := ill_tps_mult (at level 65, right associativity).
Infix "-*" := ill_tps_imp (at level 65, right associativity).
Fact ll_tps_mult_mono (X1 X2 Y1 Y2 : _ -> Prop) :
(forall x, X1 x -> X2 x)
-> (forall x, Y1 x -> Y2 x)
-> (forall x, (X1**Y1) x -> (X2**Y2) x).
Proof.
intros H1 H2 x (a & b & H3 & H4 & H5); subst.
exists a, b; auto.
Qed.
Fixpoint ill_tps A x : Prop :=
match A with
| £ X => s X x
| A & B => ⟦A⟧ x /\ ⟦B⟧ x
| !A => ⟦A⟧ x /\ x = vec_zero
| A ⊸ B => (⟦A⟧ -* ⟦B⟧) x
| A ⊗ B => (⟦A⟧ ** ⟦B⟧) x
| A ⊕ B => ⟦A⟧ x \/ ⟦B⟧ x
| ⟘ => False
| ⟙ => True
| 𝝐 => x = vec_zero
end
where "⟦ A ⟧" := (ill_tps A).
Reserved Notation "'[[' Γ ']]'" (at level 0).
Fixpoint ill_tps_list Γ :=
match Γ with
| ∅ => eq vec_zero
| A::Γ => ⟦A⟧ ** [[Γ]]
end
where "[[ Γ ]]" := (ill_tps_list Γ).
Fact ill_tps_app Γ Δ x : [[Γ++Δ]] x <-> ([[Γ]]**[[Δ]]) x.
Proof.
revert Γ Δ x; intros Ga De.
induction Ga as [ | A Ga IH ]; intros x; simpl; split; intros Hx.
+ exists vec_zero, x; simpl; rew vec.
+ destruct Hx as (a & b & H1 & H2 & H3); subst; auto; rewrite vec_zero_plus; auto.
+ destruct Hx as (a & b & H1 & H2 & H3).
apply IH in H3.
destruct H3 as (c & d & H4 & H5 & H6).
exists (vec_plus a c), d; split.
* subst; apply vec_plus_assoc.
* split; auto.
exists a, c; auto.
+ destruct Hx as (y & d & H1 & H2 & H3).
destruct H2 as (a & g & H2 & H4 & H5).
exists a, (vec_plus g d); split.
* subst; symmetry; apply vec_plus_assoc.
* split; auto.
apply IH.
exists g, d; auto.
Qed.
Fact ill_tps_lbang Γ x : [[‼Γ]] x <-> [[Γ]] x /\ x = vec_zero.
Proof.
revert Γ x; intros Ga.
induction Ga as [ | A Ga IH ]; intros x.
+ simpl; split; auto; tauto.
+ split.
* intros (a & g & H1 & H2 & H3).
split.
- exists a, g; repeat split; auto.
** apply H2.
** apply IH; auto.
- apply IH, proj2 in H3.
apply proj2 in H2; subst; auto.
apply vec_zero_plus.
* intros ((a & g & H1 & H2 & H3) & H4).
exists x, x.
assert (a = vec_zero /\ g = vec_zero) as E.
{ apply vec_plus_is_zero; subst; auto. }
destruct E; subst; repeat split; auto; rew vec.
apply IH; auto.
Qed.
Fact ill_tps_list_bang_zero Γ : [[‼Γ]] vec_zero <-> forall A, In A Γ -> ⟦A⟧ vec_zero.
Proof.
induction Γ as [ | A Ga IH ].
+ split.
* simpl; tauto.
* intros _; simpl; auto.
+ split.
* intros (u & v & H1 & H2 & H3).
destruct H2 as [ H2 H4 ]; subst; auto.
rewrite vec_zero_plus in H1; subst.
rewrite IH in H3.
intros B [ E | HB ]; subst; auto.
* intros H.
exists vec_zero, vec_zero.
rewrite vec_zero_plus; repeat split; auto.
- apply H; left; auto.
- rewrite IH.
intros; apply H; right; auto.
Qed.
Fact ill_tps_perm Γ Δ : Γ ~p Δ -> forall x, [[Γ]] x -> [[Δ]] x.
Proof.
induction 1 as [ | A Ga De H IH | A B Ga | ]; simpl; auto.
+ intros x (a & b & H1 & H2 & H3).
exists a, b; repeat split; auto.
+ intros x (a & b & H1 & H2 & c & d & H3 & H4 & H5).
exists c, (vec_plus a d); split.
* subst; rewrite (vec_plus_comm c), vec_plus_assoc, (vec_plus_comm c); auto.
* split; auto.
exists a, d; auto.
Qed.
Definition ill_sequent_tps Γ A := [[Γ]] -* ⟦A⟧.
Notation "'[<' Γ '|-' A '>]'" := (ill_sequent_tps Γ A).
Fact ill_sequent_tps_mono Γ A B :
(forall x, ⟦A⟧ x -> ⟦B⟧ x) -> forall x, [< Γ |- A >] x -> [< Γ |- B >] x.
Proof.
intros H x; simpl; unfold ill_sequent_tps.
intros H1 a H2.
apply H, H1; auto.
Qed.
Fact ill_perm_tps Γ Δ : Γ ~p Δ -> forall x A, [< Γ |- A >] x -> [< Δ |- A >] x.
Proof.
intros H1 x B; unfold ill_sequent_tps.
intros H2 a H3.
apply H2; revert H3.
apply ill_tps_perm, Permutation_sym; auto.
Qed.
Fact ill_sequent_tps_eq Γ A : [< Γ |- A >] vec_zero <-> forall x, [[Γ]] x -> ⟦A⟧ x.
Proof.
split.
* intros H x Hx.
rewrite <- vec_zero_plus, vec_plus_comm.
apply (H x); trivial.
* intros H x Hx.
rewrite vec_plus_comm, vec_zero_plus; auto.
Qed.
Theorem ill_tps_sound Γ A : Γ ⊢ A -> [< Γ |- A >] vec_zero.
Proof.
induction 1 as [ A
| Γ Δ A B H1 IH1 H2 IH2
| Γ Δ A H1 H2 IH2
| Γ Δ A B C H1 IH1 H2 IH2
| Γ A B H1 IH1
| Γ A B C H1 IH1
| Γ A B C H1 IH1
| Γ A B H1 IH1 H2 IH2
| Γ A B H1 IH1
| Γ A H1 IH1
| Γ A B H1 IH1
| Γ A B H1 IH1
| Γ A B C H1 IH1
| Γ Δ A B H1 IH1 H2 IH2
| Γ A B C H1 IH1 H2 IH2
| Γ A B H1 IH1
| Γ A B H1 IH1
| Γ A
| Γ
| Γ A H1 IH1
|
]; unfold ill_sequent_tps in * |- *.
+ intros x; simpl; intros (a & b & H1 & H2 & H3); subst; eq goal H2.
f_equal; do 2 rewrite vec_plus_comm, vec_zero_plus; auto.
+ intros x Hx.
rewrite ill_tps_app in Hx.
apply IH2.
destruct Hx as (a & b & G1 & G2 & G3); subst.
exists a, b; split; auto.
split; auto.
rewrite <- vec_zero_plus, vec_plus_comm.
apply IH1; auto.
+ revert IH2; apply ill_perm_tps; auto.
+ intros x (y & z & H3 & H4 & H5); simpl.
apply IH2.
apply ill_tps_app in H5.
destruct H5 as (g & d & H5 & H6 & H7).
simpl in H4.
apply IH1, H4 in H6.
exists (vec_plus y g), d; repeat split; auto.
* subst; apply vec_plus_assoc.
* eq goal H6; f_equal; rew vec.
+ simpl; intros y Hy a Ha.
rewrite vec_plus_assoc.
apply IH1.
exists a, y; repeat split; auto; lia.
+ intros x (a & b & H2 & H3 & H4); apply IH1.
exists a, b; repeat split; auto; apply H3.
+ intros x (a & b & H2 & H3 & H4); apply IH1.
exists a, b; repeat split; auto; apply H3.
+ intros x Hx; split.
* apply IH1; auto.
* apply IH2; auto.
+ intros x (a & g & H2 & H3 & H4).
apply IH1; exists a, g; repeat split; auto.
apply H3.
+ intros x Hx; split.
apply IH1; auto.
rew vec.
apply ill_tps_lbang in Hx; tauto.
+ intros x (a & g & H2 & H3 & H4).
apply IH1.
apply proj2 in H3; subst; auto.
rew vec; auto.
+ intros x (a & g & H2 & H3 & H4).
apply IH1.
exists a, g.
repeat (split; auto).
exists a, g.
repeat (split; auto).
apply proj2 in H3.
subst; rew vec; auto.
+ intros x Hx.
apply IH1.
destruct Hx as (c & g & ? & (a & b & ? & H2 & H3) & H4); subst.
exists a, (vec_plus b g); split; auto.
* rewrite vec_plus_assoc; trivial.
* split; auto; exists b, g; auto.
+ intros x Hx.
apply ill_tps_app in Hx.
destruct Hx as (a & b & ? & H3 & H4); subst.
exists a, b; split.
* rewrite vec_plus_comm, vec_zero_plus; auto.
* split; rewrite <- vec_zero_plus, vec_plus_comm.
- apply IH1; auto.
- apply IH2; auto.
+ intros x Hx.
destruct Hx as (u & g & ? & [ G1 | G1 ] & G2); subst.
* apply IH1; exists u, g; auto.
* apply IH2; exists u, g; auto.
+ intros x Hx; left; apply IH1; auto.
+ intros x Hx; right; apply IH1; auto.
+ intros ? (? & _ & _ & [] & _).
+ intros x _; red; trivial.
+ intros x (i & g & ? & H2 & H3); subst.
red in H2; subst.
rewrite vec_zero_plus.
apply IH1; auto.
+ intros x Hx; red in Hx; subst.
rewrite vec_zero_plus; red; trivial.
Qed.
End trivial_phase_semantics.