Theory SC_Cut

theory SC_Cut
imports SC
begin
  
subsubsection‹Contraction›
  
text‹First, we need contraction:›
lemma contract:
  "(F,F,Γ  Δ  F,Γ  Δ)  (Γ  F,F,Δ  Γ  F,Δ)"
proof(induction F arbitrary: Γ Δ)
  case (Atom k)
  have "Atom k, Atom k, Γ  Δ  Atom k, Γ  Δ"
    by(induction "Atom k, Atom k, Γ" Δ arbitrary: Γ rule: SCp.induct)
      (auto dest!: multi_member_split intro!: SCp.intros(3-) simp add: lem2 lem1 SCp.intros)  
  moreover have "Γ  Atom k, Atom k, Δ  Γ  Atom k, Δ"
    by(induction "Γ" "Atom k, Atom k, Δ" arbitrary: Δ rule: SCp.induct)
      (auto dest!: multi_member_split intro!: SCp.intros(3-) simp add: lem2 lem1 SCp.intros)
  ultimately show ?case by blast
next
  case Bot
  have ", , Γ  Δ  , Γ  Δ" by(blast)
  moreover have "(Γ  , , Δ  Γ  , Δ)"    
    using Bot_delR by fastforce
  ultimately show ?case by blast
next
  case (Not F)
  then show ?case by (meson NotL_inv NotR_inv SCp.NotL SCp.NotR)
next
  case (And F1 F2) then show ?case by(auto intro!: SCp.intros(3-) dest!: AndR_inv AndL_inv) (metis add_mset_commute)
next
  case (Or F1 F2) then show ?case by(auto intro!: SCp.intros(3-) dest!: OrR_inv OrL_inv) (metis add_mset_commute)
next
  (* Okay, so the induction hypothesis is poison for the simplifier. 
     For some reason, this didn't cause trouble for the other two cases, but here, it does. *)
  case (Imp F1 F2) show ?case by(auto dest!: ImpR_inv ImpL_inv intro!: SCp.intros(3-)) (insert Imp.IH; blast)+
qed
corollary
  shows contractL: "F, F, Γ  Δ  F, Γ  Δ"
  and contractR:   "Γ  F, F, Δ  Γ  F, Δ"
  using contract by blast+
    
subsubsection‹Cut›
  
text‹Which cut rule we show is up to us:›
lemma cut_cs_cf:
  assumes context_sharing_Cut: "(A::'a formula) Γ Δ. Γ  A,Δ  A,Γ  Δ  Γ  Δ"
  shows context_free_Cut: "Γ  (A::'a formula),Δ  A,Γ'  Δ'  Γ + Γ'  Δ + Δ'"
  by(intro context_sharing_Cut[of "Γ + Γ'" A "Δ + Δ'"])
    (metis add.commute union_mset_add_mset_left weakenL_set weakenR_set)+
lemma cut_cf_cs:
  assumes context_free_Cut: "(A::'a formula) Γ Γ' Δ Δ'. Γ  A,Δ  A,Γ'  Δ'  Γ + Γ'  Δ + Δ'"
  shows context_sharing_Cut: "Γ  (A::'a formula),Δ  A,Γ  Δ  Γ  Δ"
proof - 
  have contractΓΓ: "Γ+Γ'  Δ  Γ' ⊆# Γ  Γ  Δ" for Γ Γ' Δ
  proof(induction "Γ'" arbitrary: Γ)
    case empty thus ?case using weakenL_set by force
  next
    case (add x Γ' Γ)
    from add.prems(2) have "x ∈# Γ" by (simp add: insert_subset_eq_iff)
    then obtain Γ'' where Γ[simp]: "Γ = x,Γ''" by (meson multi_member_split)
    from add.prems(1) have "x,x,Γ'' + Γ'  Δ" by simp
    with contractL have "x, Γ'' + Γ'  Δ" .
    with add.IH[of Γ] show ?case using Γ  add.prems(2) subset_mset.trans by force
  qed
  have contractΔΔ: "Γ  Δ+Δ'  Δ' ⊆# Δ  Γ  Δ" for Γ Δ Δ'
  proof(induction "Δ'" arbitrary: Δ)
    case empty thus ?case using weakenL_set by force
  next
    case (add x Δ' Δ)
    from add.prems(2) have "x ∈# Δ" by (simp add: insert_subset_eq_iff)
    then obtain Δ'' where Δ[simp]: "Δ = x,Δ''" by (metis multi_member_split)
    from add.prems(1) have "Γ  x,x,Δ'' + Δ'" by simp
    with contractR have "Γ  x, Δ'' + Δ'" .
    with add.IH[of Δ] show ?case using Δ add.prems(2) subset_mset.trans by force
  qed
  show "Γ  A,Δ  A,Γ  Δ  Γ  Δ"
    using context_free_Cut[of Γ A Δ Γ Δ] contractΓΓ contractΔΔ
    by blast
qed
(* since these are the only lemmas that need contraction on sets, I've decided to transfer those in place *)
text‹According to Troelstra and Schwichtenberg~cite"troelstra2000basic", the sharing variant is the one we want to prove.›
  
lemma Cut_Atom_pre: "Atom k,Γ  Δ  Γ  Atom k,Δ  Γ  Δ"
proof(induction "Atom k,Γ" "Δ" arbitrary: Γ rule: SCp.induct)
  case BotL
  hence " ∈# Γ" by simp
  thus ?case using SCp.BotL by blast
next
  case (Ax l Δ)
  show ?case proof cases
    assume "l = k"
    with Atom l ∈# Δ obtain Δ' where "Δ = Atom k, Δ'" by (meson multi_member_split)
    with Γ  Atom k, Δ have "Γ  Δ" using contractR by blast
    thus ?thesis by auto
  next
    assume "l  k"
    with Atom l ∈# Atom k, Γ have "Atom l ∈# Γ" by simp
    with Atom l ∈# Δ show ?thesis using SCp.Ax[of l] by blast
  qed
next
  case NotL
  thus ?case by(auto simp: add_eq_conv_ex intro!: SCp.NotL dest!: NotL_inv)
next
  case NotR
  then show ?case by(auto intro!: SCp.NotR dest!: NotR_inv)
next
  case AndL
  thus ?case by(auto simp: add_eq_conv_ex intro!: SCp.AndL dest!: AndL_inv)
next
  case AndR
  then show ?case by(auto intro!: SCp.AndR dest!: AndR_inv)
next
  case OrL
  thus ?case by(auto simp: add_eq_conv_ex intro!: SCp.OrL dest!: OrL_inv)
next
  case OrR
  thus ?case by(auto intro!: SCp.OrR dest!: OrR_inv)
next
  case ImpL
  thus ?case by(auto simp: add_eq_conv_ex intro!: SCp.ImpL dest!: ImpL_inv)
next
  case ImpR
  then show ?case by (auto dest!: ImpR_inv intro!: SCp.ImpR)
qed
  
text‹We can show the admissibility of the cut rule by induction on the cut formula 
(or, if you will, as a procedure that splits the cut into smaller formulas that get cut).
The only mildly complicated case is that of cutting in an @{term "Atom k"}.
It is, contrary to the general case, only mildly complicated, since the cut formula can only appear principal in the axiom rules.›

theorem cut: "Γ  F,Δ  F,Γ  Δ  Γ  Δ"
proof(induction F arbitrary: Γ Δ)
  case Atom thus ?case using Cut_Atom_pre by metis
next
  case Bot thus ?case using Bot_delR by fastforce 
next
  case Not with  NotL_inv NotR_inv show ?case by blast
next
  case And thus ?case by (meson AndL_inv AndR_inv weakenL)
next
  case Or thus ?case by (metis OrL_inv OrR_inv weakenR)
next
  case (Imp F G)
(* an automatic proof:
  thus ?case by (meson ImpL_inv ImpR_inv weakenR)
   a readable one: *)
  from ImpR_inv Γ  F  G, Δ have R: "F, Γ  G, Δ" by blast
  from ImpL_inv F  G, Γ  Δ have L: "Γ  F, Δ" "G, Γ  Δ" by blast+
  from L(1) have "Γ  F, G, Δ" using weakenR add_ac(3) by blast
  with R have "Γ  G, Δ" using Imp.IH(1) by simp
  with L(2) show "Γ  Δ" using Imp.IH(2) by clarsimp
qed
  (* For this proof to work with FOL, I think we would need very special inversion rules.
  For example, for ∀R, we would need that there's a (finite!) multiset of substitutions S, such that
  instead of having ∀x.F,Δ, having {F[s/x] | s ∈ S} + Δ is enough. I don't think that holds,
  but we may be able to cheat ourselves around it… *)
  
corollary cut_cf: " Γ  A, Δ; A, Γ'  Δ'  Γ + Γ'  Δ + Δ'"
  using cut_cs_cf cut by metis

lemma assumes cut: " Γ' Δ' (A::'a formula). Γ'  A, Δ'; A, Γ'  Δ'  Γ'  Δ'"
  shows contraction_admissibility: "F,F,Γ  Δ  (F::'a formula),Γ  Δ"
  by(rule cut[of "F,Γ" F Δ, OF extended_Ax]) simp_all
(* yes, unpublished Chapman p 2/5, second to last paragraph. that's right. we can prove contraction with cut. but what's that good for? *)
  
end