From Undecidability.FOLC Require Export FOL.
Section ND_def.
Context {Sigma : Signature}.
(* **** Definition *)
Inductive peirce := class | intu.
Inductive bottom := expl | lconst.
Existing Class peirce.
Existing Class bottom.
Inductive prv : forall (p : peirce) (b : bottom), list (form) -> form -> Prop :=
| II {p b} A phi psi : prv p b (phi::A) psi -> prv p b A (phi --> psi)
| IE {p b} A phi psi : prv p b A (phi --> psi) -> prv p b A phi -> prv p b A psi
| AllI {p b} A phi : prv p b (map (subst_form ↑) A) phi -> prv p b A (∀ phi)
| AllE {p b} A phi t : prv p b A (All phi) -> prv p b A (subst_form (t .: ids) phi)
| Exp {p} A phi : prv p expl A Fal -> prv p expl A phi
| Pc {b} A phi psi : prv class b A (((phi --> psi) --> phi) --> phi)
| Ctx {p b} A phi : phi el A -> prv p b A phi.
Arguments prv {_ _} _ _.
Hint Constructors prv.
Notation "A ⊢ phi" := (prv A phi) (at level 30).
Notation "A '⊢(' p , b ')' phi" := (@prv p b A phi) (at level 30).
Notation "A ⊢CE phi" := (@prv class expl A phi) (at level 30).
Notation "A ⊢CL phi" := (@prv class lconst A phi) (at level 30).
Notation "A ⊢IE phi" := (@prv intu expl A phi) (at level 30).
Definition tprv p b T phi := (exists A, A ⊏ T /\ @prv p b A phi).
Arguments tprv {_ _} _ _.
Notation "T ⊩ phi" := (tprv T phi) (at level 30).
Notation "T '⊩(' s , b ')' phi" := (@tprv s b T phi) (at level 30).
Notation "T ⊩CE phi" := (@tprv class expl T phi) (at level 30).
Notation "T ⊩CL phi" := (@tprv class lconst T phi) (at level 30).
Notation "T ⊩IE phi" := (@tprv intu expl T phi) (at level 30).
Section Weakening.
Context {p : peirce} {b : bottom}.
Theorem Weak A B phi :
A ⊢ phi -> A <<= B -> B ⊢ phi.
Proof.
induction 1 in B |-*; eauto using incl_map.
Qed.
Theorem subst_Weak A phi xi :
A ⊢ phi -> [phi[xi] | phi ∈ A] ⊢ phi[xi].
Proof.
induction 1 in xi |-*; comp; eauto using in_map.
- apply AllI. setoid_rewrite map_map in IHprv. erewrite map_map, map_ext.
apply IHprv. intros ?. comp. now apply ext_form.
- specialize (IHprv xi). apply AllE with (t0 := t [xi]) in IHprv. comp. now asimpl in IHprv.
Qed.
Lemma Weak_T T1 T2 phi :
T1 ⊩ phi -> T1 ⊑ T2 -> T2 ⊩ phi.
Proof.
intros (A & HA1 & HA2) HT2. exists A; firstorder.
Qed.
Definition cycle_shift n x :=
if Dec (n = x) then var_term 0 else var_term (S x).
Hint Unfold cycle_shift.
Lemma cycle_shift_shift n phi :
unused n phi -> phi[cycle_shift n] = phi[↑].
Proof.
intros H. apply (subst_unused_single H). intros m ?. unfold cycle_shift. now decide (n = m).
Qed.
Lemma cycle_shift_subject n phi :
unused (S n) phi -> phi[(var_term n)..][cycle_shift n] = phi.
Proof.
intros H. asimpl. rewrite (@subst_unused_single _ _ ids _ _ H). 1: now asimpl.
intros m H'; comp; decide (n = n); try congruence. destruct m; [reflexivity |].
comp; decide (n = m); comp; congruence.
Qed.
Lemma nameless_equiv A phi n :
unused_L n A -> unused (S n) phi -> ((A ⊢ phi[(var_term n)..]) <-> [phi[↑] | phi ∈ A] ⊢ phi).
Proof.
intros HL Hphi. split.
- intros H % (subst_Weak (cycle_shift n)). rewrite cycle_shift_subject,
(map_ext_in _ (subst_form form_shift)) in H. 1,3: assumption. intros ? ? % HL.
now apply cycle_shift_shift.
- intros H % (subst_Weak ((var_term n)..)). rewrite map_map in *. rewrite (map_ext _ id), map_id in H.
assumption. now intuition comp.
Qed.
End Weakening.
Lemma prv_cut {p : peirce} {b : bottom} A phi psi :
A ⊢ phi -> (phi :: A) ⊢ psi -> A ⊢ psi.
Proof.
eauto.
Qed.
Lemma tprv_list_T {p : peirce} {b : bottom} A phi :
list_T A ⊩ phi -> A ⊢ phi.
Proof.
intros (B & HB1 & HB2). apply (Weak HB2). firstorder.
Qed.
Definition capture_subs n x := var_term (x + n).
Lemma capture_extract {p : peirce} {b : bottom} n A phi :
A ⊢ subst_form (capture_subs n) (capture n phi) -> A ⊢ subst_form (capture_subs 0) phi.
Proof.
induction n; comp; intuition. apply IHn. apply (AllE (var_term n)) in H. asimpl in H.
erewrite ext_form. 1: apply H. intros [| x]; unfold capture_subs; cbn; f_equal; omega.
Qed.
Lemma close_extract {p : peirce} {b : bottom} A phi :
A ⊢ close phi -> A ⊢ phi.
Proof.
intros H. assert (Hclosed : closed (close phi)) by apply close_closed.
unfold close in *. destruct (find_unused phi) as [n Hn]; cbn in *.
rewrite <- subst_unused_closed' with (xi := capture_subs n) in H. 2: firstorder.
apply capture_extract in H. rewrite idSubst_form in H; intuition.
destruct x; unfold capture_subs; f_equal; omega.
Qed.
Lemma big_imp_extract {p : peirce} {b : bottom} A B phi :
B ⊢ (big_imp A phi) -> (rev A ++ B) ⊢ phi.
Proof.
induction A in B |-*.
- tauto.
- cbn. intros Hprv. rewrite <- app_assoc. comp.
apply IHA. eapply IE. 1: apply (Weak Hprv); intuition.
now apply Ctx.
Qed.
Lemma prv_from_single {p : peirce} { b : bottom} A phi :
nil ⊢ close (A ⟹ phi) -> A ⊢ phi.
Proof.
intros Hprv % close_extract. apply big_imp_extract in Hprv.
eapply Weak. apply Hprv. rewrite app_nil_r. now intros ? ? % in_rev.
Qed.
End ND_def.
Hint Constructors prv.
Arguments prv {_ _ _} _ _.
Notation "A ⊢ phi" := (prv A phi) (at level 30).
Notation "A '⊢(' p , b ')' phi" := (@prv _ p b A phi) (at level 30).
Notation "A ⊢CE phi" := (@prv _ class expl A phi) (at level 30).
Notation "A ⊢CL phi" := (@prv _ class lconst A phi) (at level 30).
Notation "A ⊢IE phi" := (@prv _ intu expl A phi) (at level 30).
Arguments tprv {_ _ _} _ _.
Notation "T ⊩ phi" := (tprv T phi) (at level 30).
Notation "T '⊩(' s , b ')' phi" := (@tprv _ s b T phi) (at level 30).
Notation "T ⊩CE phi" := (@tprv _ class expl T phi) (at level 30).
Notation "T ⊩CL phi" := (@tprv _ class lconst T phi) (at level 30).
Notation "T ⊩IE phi" := (@tprv _ intu expl T phi) (at level 30).
(* **** Proof Tacticts *)
Ltac ointro_all :=
match goal with
| [ |- ?A ⊢ ∀ ?phi] => apply AllI; cbn; asimpl
end.
Ltac ointro_impl :=
match goal with
| [ |- _ ⊢ (_ --> _)] => apply II
| [ |- _ ⊢ (¬ _)] => apply II
end.
Ltac ointro := ointro_impl + ointro_all + fail "Nothing to intro!".
Ltac ointros := repeat ointro.
Ltac ctx_index' n :=
match n with
| O => now left
| S ?m => right; ctx_index' m
end.
Ltac ctx_index n := apply Ctx; ctx_index' n.
Ltac ctx := apply Ctx; intuition.
Ltac oapply n := eapply IE; [ctx_index n|].
Ltac ospecialize n t :=
eapply prv_cut; [eapply (@AllE _ _ _ _ _ t); ctx_index n|]; cbn; asimpl.
Ltac ouse H := eapply Weak; [apply H |]; intuition.
Ltac oimport H := eapply prv_cut; [ouse H |].
Ltac oassert form := eapply (@prv_cut _ _ _ _ form).
Ltac oexfalso := apply Exp.
Ltac opeirce form := eapply IE; [apply (@Pc _ _ _ _ form) | apply II].
Lemma DN {Sigma : Signature} A phi :
A ⊢CE ¬ (¬ phi) -> A ⊢CE phi.
Proof.
intros H. oimport H. opeirce Fal. oexfalso. oapply 1. ctx.
Qed.
Lemma DN_T {Sigma : Signature} T phi :
T ⊩CE ¬ (¬ phi) -> T ⊩CE phi.
Proof.
intros (A & HA1 & HA2 % DN). now use_theory A.
Qed.
Ltac oindirect := apply DN, II.
Lemma ExE {Sigma : Signature} A phi psi :
A ⊢CE (∃ phi) -> (phi :: [phi[↑] | phi ∈ A]) ⊢CE psi[↑] -> A ⊢CE psi.
Proof.
intros Hex Hinst.
oindirect. oimport Hex. oapply 0.
ointros. oapply 2. ouse Hinst.
Qed.
Ltac odestruct n := eapply ExE; [ctx_index n|]; cbn; asimpl.
Lemma ExI {Sigma : Signature} {p : peirce} {b : bottom} A t phi :
A ⊢ phi [t..] -> A ⊢ ∃ phi.
Proof.
intros Hc. apply II. ospecialize 0 t. oapply 0. ouse Hc.
Qed.
Ltac oexists t :=
eapply (@ExI _ _ _ _ t); cbn; asimpl.
Lemma AXM {Sigma : Signature} A phi psi :
(phi :: A) ⊢CE psi -> (¬ phi :: A) ⊢CE psi -> A ⊢CE psi.
Proof.
intros Ht Hf. oindirect. oassert (¬ phi). ointros. oapply 1.
ouse Ht. oapply 1. ouse Hf.
Qed.
Ltac oxm form :=
apply (@AXM _ _ form).
Lemma DP {Sigma : Signature} phi :
[] ⊢CE ∃ (phi --> (∀ phi)[↑]).
Proof.
oxm (∃ ¬ phi).
- odestruct 0. oexists (var_term 0). ointros. oexfalso. oapply 1. ctx.
- oexists (var_term 0). ointros. oindirect. oapply 2. oexists (var_term 0). ctx.
Qed.
(* **** Theory manipulation *)
Section TheoryManipulation.
Context {Sigma : Signature}.
Context {p : peirce} {b : bottom}.
Context {HF : eq_dec Funcs} {HP : eq_dec Preds}.
Lemma prv_T_impl T phi psi :
(T ⋄ phi) ⊩ psi -> T ⊩ (phi --> psi).
Proof.
intros (A & HA1 & HA2). exists (rem A phi); split.
- intros f [[] % HA1 Hf2] % in_rem_iff; subst; intuition.
- eapply II, Weak. 1: apply HA2. transitivity (phi :: A). 1: eauto. apply rem_equi.
Qed.
Lemma prv_T_remove T phi psi :
T ⊩ phi -> T ⋄ phi ⊩ psi -> T ⊩ psi.
Proof.
intros (A & HA1 & HA2) (B & HB1 & HB2) % prv_T_impl.
use_theory (A ++ B). oimport HA2. oimport HB2. oapply 0. ctx.
Qed.
Lemma prv_T_comp T phi psi xi :
T ⋄ phi ⊩ xi -> T ⋄ psi ⊩ phi -> T ⋄ psi ⊩ xi.
Proof.
intros (A & HA1 & HA2) % prv_T_impl (B & HB1 & HB2) % prv_T_impl.
use_theory (psi :: A ++ B). oimport HA2. oimport HB2. oapply 1. oapply 0. ctx.
Qed.
Lemma elem_prv T phi :
phi ∈ T -> T ⊩ phi.
Proof.
intros ?. use_theory [phi]. ctx.
Qed.
End TheoryManipulation.
(* **** Refutation completeness *)
Section RefutationComp.
Context {Sigma : Signature}.
Context {HF : eq_dec Funcs} {HP : eq_dec Preds}.
Lemma refutation_prv T phi :
T ⊩CE phi <-> (T ⋄ ¬ phi) ⊩CE ⊥.
Proof.
split.
- intros (A & HA1 & HA2). use_theory (¬ phi :: A). oimport HA2. oapply 1. ctx.
- intros (A & HA1 & HA2) % prv_T_impl. use_theory A. now apply DN.
Qed.
End RefutationComp.
(* **** Enumerability of proofs *)
Section Enumerability.
Context {Sigma : Signature}.
Context {HdF : eq_dec Funcs} {HdP : eq_dec Preds}.
Context {HeF : enumT Funcs} {HeP : enumT Preds}.
Fixpoint L_ded {p : peirce} {b : bottom} (A : list form) (n : nat) : list form :=
match n with
| 0 => A
| S n => L_ded A n ++
(* II *) concat ([ [ phi --> psi | psi ∈ L_ded (phi :: A) n ] | phi ∈ L_T form n ]) ++
(* IE *) [ psi | (phi, psi) ∈ (L_ded A n × L_T form n) , (phi --> psi el L_ded A n) ] ++
(* AllI *) [ ∀ phi | phi ∈ L_ded (map (subst_form ↑) A) n ] ++
(* AllE *) [ phi[t..] | (phi, t) ∈ (L_T form n × L_T term n), (∀ phi) el L_ded A n ] ++
(* Exp *) (if b then
[ phi | phi ∈ L_T form n, ⊥ el L_ded A n]
else nil) ++
(* Pc *) (if p then
[ (((phi --> psi) --> phi) --> phi) | (pair phi psi) ∈ (L_T form n × L_T form n)]
else nil)
end.
Opaque in_dec.
Lemma enum_prv {p : peirce} {b : bottom} A : enum (prv A) (L_ded A).
Proof with try (eapply cum_ge'; eauto; omega).
repeat split.
- eauto.
- rename x into phi. induction 1; try congruence; subst.
+ destruct IHprv as [m1], (el_T phi) as [m2]. exists (1 + m1 + m2). cbn. in_app 2.
eapply in_concat_iff. eexists. split. 2:in_collect phi... in_collect psi...
+ destruct IHprv1 as [m1], IHprv2 as [m2], (el_T psi) as [m3]; eauto.
exists (1 + m1 + m2 + m3).
cbn. in_app 3. in_collect (phi, psi)...
+ destruct IHprv as [m]. exists (1 + m). cbn. in_app 4. in_collect phi...
+ destruct IHprv as [m1], (el_T t) as [m2], (el_T phi) as [m3]. exists (1 + m1 + m2 + m3).
cbn. in_app 5. in_collect (phi, t)...
+ destruct IHprv as [m1], (el_T phi) as [m2]. exists (1 + m1 + m2). cbn. in_app 6. in_collect phi...
+ destruct (el_T phi) as [m1], (el_T psi) as [m2]. exists (1 + m1 + m2). cbn. in_app 7. in_collect (phi, psi)...
+ now exists 0.
- intros [m]; induction m in A, x, H |-*; cbn in *.
+ ctx.
+ destruct p, b; inv_collect; eauto. all: apply AllE; eauto.
Qed.
Fixpoint L_con (L : nat -> list form) (n : nat) : list (list form) :=
match n with
| 0 => [ nil ]
| S n => L_con L n ++ [ phi :: A | (pair phi A) ∈ (L n × L_con L n) ]
end.
Lemma enum_el X (p : X -> Prop) L x :
enum p L -> p x -> exists m, x el L m.
Proof.
firstorder.
Qed.
Arguments enum_el {X p L} x _ _.
Lemma enum_p X (p : X -> Prop) L x m :
enum p L -> x el L m -> p x.
Proof.
firstorder.
Qed.
Lemma enum_containsL T L : enum T L -> enum (fun A => A ⊏ T) (L_con L).
Proof with try (eapply cum_ge'; eauto; omega).
intros He. repeat split.
- eauto.
- induction x as [| phi A]; intros HT.
+ exists 0. firstorder.
+ destruct IHA as [m1], (enum_el phi He) as [m2]. 1,2,3: firstorder.
exists (1 + m1 + m2). cbn. in_app 2. destruct He. in_collect (phi, A)...
- intros [m]. induction m in x, H |-*; cbn in *.
+ destruct H as [<- | []]. intuition.
+ inv_collect. apply IHm in H1. apply (enum_p He) in H. eauto with contains_theory.
Qed.
Fixpoint L_tded {p : peirce} {b : bottom} (L : nat -> list form) (n : nat) : list form :=
match n with
| 0 => nil
| S n => L_tded L n ++ concat ([ L_ded A n | A ∈ L_con L n ])
end.
Lemma enum_tprv {p : peirce} {b : bottom} T L : enum T L -> enum (tprv T) (L_tded L).
Proof with try (eapply cum_ge'; eauto; omega).
intros He. repeat split.
- eauto.
- intros (A & [m1] % (enum_el A (enum_containsL He)) & [m2] % (enum_el x (enum_prv A))).
exists (1 + m1 + m2). cbn. in_app 2. eapply in_concat_iff. eexists. split. 2: in_collect A... idtac...
- intros [m]. induction m in x, H |-*; cbn in *. 1: contradiction. inv_collect. exists x1. split.
+ eapply (enum_p (enum_containsL He)); eassumption.
+ eapply (enum_p (enum_prv x1)); eassumption.
Qed.
End Enumerability.
(* **** Signature extension and proofs *)
Section SigExt.
Context {p : peirce} {b : bottom}.
Lemma sig_lift_Weak {Sigma : Signature} A phi :
A ⊢ phi -> (map sig_lift A) ⊢ sig_lift phi.
Proof.
destruct Sigma. induction 1; try (solve [cbn in *; constructor; eauto using in_map]).
- eapply IE; cbn in *; eauto.
- constructor. rewrite map_map in *. erewrite map_ext. 1: exact IHprv. now setoid_rewrite sig_lift_subst.
- rewrite sig_lift_subst. apply @AllE with (t := sig_lift_term t) in IHprv. erewrite ext_form. exact IHprv.
now intros [].
Qed.
Lemma vsubs_form_shift {Sigma : Signature} x :
form_shift x = vsubs 1 Vector.nil x.
Proof.
unfold vsubs. destruct (fin_minus x 0). 1: omega. destruct s; subst. now replace (x - 0 + 1) with (S x) by omega.
Qed.
Lemma vsubs_single_subst {Sigma : Signature} (t : term) x :
(t..) x = vsubs 0 (Vector.cons t Vector.nil) x.
Proof.
destruct x. 1: reflexivity. unfold vsubs. destruct (fin_minus (S x) 1).
1: omega. destruct s; subst. now replace (S x - 1 + 0) with x by omega.
Qed.
Lemma sig_drop_Weak {Sigma : Signature} n A phi :
A ⊢ phi -> map (sig_drop n) A ⊢ sig_drop n phi.
Proof with solve [eauto] + firstorder + (intros ? []; subst; firstorder).
destruct Sigma. induction 1 in n |-*; try (solve [cbn in *; constructor; eauto using in_map]).
- eapply IE. 1: apply IHprv1. apply IHprv2.
- comp. apply AllI. specialize (IHprv (S n)). setoid_rewrite map_map in IHprv. rewrite map_map.
erewrite map_ext in IHprv. 2: intros a; erewrite ext_form with (s := a). 3: apply vsubs_form_shift.
2: replace (S n) with (n + 1) by omega; rewrite sig_drop_subst'.
2: erewrite ext_form with (s := sig_drop' (n + 0) a). 3: intros x; symmetry; apply vsubs_form_shift.
2: replace (n + 0) with n by omega; reflexivity. assumption.
- comp. specialize (IHprv n). apply @AllE with (t := sig_drop_term' n t) in IHprv.
erewrite @ext_form with (s := sig_drop' (S n) phi) in IHprv. 2: apply vsubs_single_subst.
replace (S n) with (n + 1) in IHprv by omega.
change (Vector.cons (sig_drop_term' n t) Vector.nil) with (Vector.map (sig_drop_term' n) (Vector.cons t Vector.nil)) in IHprv.
replace (sig_drop_term' n) with (@sig_drop_term' Funcs fun_ar Preds pred_ar (n + 0)) in IHprv by (f_equal; omega).
rewrite <- sig_drop_subst' in IHprv. erewrite ext_form with (s := phi) in IHprv. 2: intros; symmetry; apply vsubs_single_subst.
replace (n + 0) with n in IHprv by omega. apply IHprv.
Qed.
Lemma sig_lift_out {Sigma : Signature} (A : list form) (phi : form) :
@prv (sig_ext Sigma) _ _ (map (fun psi => (sig_lift psi)[@ext_c Sigma]) A) ((sig_lift phi)[@ext_c Sigma]) -> A ⊢ phi.
Proof.
intros H % (sig_drop_Weak 0). rewrite lift_drop_inverse in H. rewrite map_map in H. erewrite map_ext in H.
2: apply lift_drop_inverse. now rewrite map_id in H.
Qed.
Lemma sig_lift_out_T {Sigma : Signature} (T : theory) (phi : form) :
@tprv (sig_ext Sigma) _ _ (tmap (fun psi => (sig_lift psi)[@ext_c Sigma]) T) ((sig_lift phi)[@ext_c Sigma]) -> T ⊩ phi.
Proof.
intros (A & HA1 & HA2). enough (exists C, C ⊏ T /\ A = (map (fun psi => (sig_lift psi)[@ext_c Sigma]) C)) as (C & HC1 & HC2).
1: subst; use_theory C; exact (sig_lift_out HA2). clear HA2. induction A. 1: exists nil; cbn; firstorder.
destruct IHA as (C & HC1 & HC2). 1: firstorder. destruct (HA1 a (or_introl eq_refl)) as (c & Hc1 & Hc2). use_theory (c :: C). now subst.
Qed.
End SigExt.
(* **** Double Negation Translation *)
Section DNT.
Context {Sigma : Signature}.
Fixpoint dnt phi :=
match phi with
| ⊥ => ⊥
| Pred P v => ¬ ¬ Pred P v
| phi --> psi => dnt phi --> dnt psi
| ∀ phi => ∀ dnt phi
end.
Lemma dnt_subst phi sigma :
dnt (phi[sigma]) = (dnt phi)[sigma].
Proof.
induction phi in sigma |-*; comp; congruence.
Qed.
Lemma dnt_float A phi :
A ⊢IE (¬ ¬ dnt phi) -> A ⊢IE dnt phi.
Proof.
intros Hprv. induction phi in A, Hprv |-*; comp.
- eauto.
- oimport Hprv. ointros. oapply 1. ointros. oapply 0. ctx.
- oimport Hprv. ointros. apply IHphi2. ointros. oapply 2. ointros. oapply 1.
oapply 0. ctx.
- oimport Hprv. ointros. comp. apply IHphi. ointros. oapply 1.
ointros. ospecialize 0 (var_term 0). oapply 2. ctx.
Qed.
Ltac clean_dnt_correct :=
repeat (match goal with
| [ H : ?x = ?x -> _ |- _ ] => specialize (H eq_refl)
end).
Lemma dnt_to_IE A phi :
A ⊢CE phi -> map dnt A ⊢IE dnt phi.
Proof.
remember expl; remember class; induction 1; subst; comp; eauto using in_map; clean_dnt_correct.
- apply AllI. rewrite map_map in *. erewrite map_ext. apply IHprv. now setoid_rewrite <- dnt_subst.
- apply AllE with (t0 := t) in IHprv. now rewrite dnt_subst.
- change (((dnt phi --> dnt psi) --> dnt phi) --> dnt phi) with (dnt (((phi --> psi) --> phi) --> phi)).
apply dnt_float. comp. ointros. oapply 0. ointros. oapply 0. ointros. oexfalso. oapply 2.
ointros. ctx.
Qed.
Lemma dnt_to_TIE T phi :
T ⊩CE phi -> tmap dnt T ⊩IE dnt phi.
Proof.
intros (A & HA1 & HA2 % dnt_to_IE). use_theory [dnt p | p ∈ A]. 2: assumption.
intros ? (psi & <- & ?) % in_map_iff. exists psi. firstorder.
Qed.
Lemma IE_to_CE A phi :
A ⊢IE phi -> A ⊢CE phi.
Proof.
induction 1; eauto.
Qed.
Lemma dnt_CE A phi :
A ⊢CE dnt phi <-> A ⊢CE phi.
Proof.
induction phi in A |-*; cbn in *.
- reflexivity.
- split. 1: eauto using DN. intros Hprv. ointros. oapply 0. ouse Hprv.
- split; intros Hprv; oimport Hprv. all: ointros; apply IHphi2; oapply 1; apply IHphi1; ctx.
- split; intros Hprv; oimport Hprv. all: ointros; apply IHphi; ospecialize 0 (var_term 0); ctx.
Qed.
Lemma dnt_remove_ctx A B phi :
(A ++ map dnt B) ⊢CE phi -> (A ++ B) ⊢CE phi.
Proof.
induction B in A |-*; cbn.
- now rewrite app_nil_r.
- intros H. specialize (IHB (A ++ [a])). do 2 rewrite <- app_assoc in IHB. apply IHB.
apply prv_cut with (dnt a). 1: apply dnt_CE; ctx; intuition. apply (Weak H).
intros ? [| []] % in_app_or; subst; intuition. repeat (right; apply in_or_app). now right.
Qed.
Lemma dnt_to_CE A phi :
map dnt A ⊢IE dnt phi -> A ⊢CE phi.
Proof.
intros H % IE_to_CE. now apply dnt_remove_ctx with (A := nil), dnt_CE.
Qed.
Lemma dnt_to_TCE T phi :
tmap dnt T ⊩IE dnt phi -> T ⊩CE phi.
Proof.
intros (? & (A & -> & HA1) % tmap_contains_L & HA2 % dnt_to_CE). now use_theory A.
Qed.
End DNT.