Theory SC
section‹Proof Systems›
subsection‹Sequent Calculus›
theory SC
imports Formulas "HOL-Library.Multiset"
begin
abbreviation msins (‹_, _› [56,56] 56) where "x,M == add_mset x M"
text‹We do not formalize the concept of sequents, only that of sequent calculus derivations.›
inductive SCp :: "'a formula multiset ⇒ 'a formula multiset ⇒ bool" (‹(_ ⇒/ _)› [53] 53) where
BotL: "⊥ ∈# Γ ⟹ Γ⇒Δ" |
Ax: "Atom k ∈# Γ ⟹ Atom k ∈# Δ ⟹ Γ⇒Δ" |
NotL: "Γ ⇒ F,Δ ⟹ Not F, Γ ⇒ Δ" |
NotR: "F,Γ ⇒ Δ ⟹ Γ ⇒ Not F, Δ" |
AndL: "F,G,Γ ⇒ Δ ⟹ And F G, Γ ⇒ Δ" |
AndR: "⟦ Γ ⇒ F,Δ; Γ ⇒ G,Δ ⟧ ⟹ Γ ⇒ And F G, Δ" |
OrL: "⟦ F,Γ ⇒ Δ; G,Γ ⇒ Δ ⟧ ⟹ Or F G, Γ ⇒ Δ" |
OrR: "Γ ⇒ F,G,Δ ⟹ Γ ⇒ Or F G, Δ" |
ImpL: "⟦ Γ ⇒ F,Δ; G,Γ ⇒ Δ ⟧ ⟹ Imp F G, Γ ⇒ Δ" |
ImpR: "F,Γ ⇒ G,Δ ⟹ Γ ⇒ Imp F G, Δ"
text‹Many of the proofs here are inspired Troelstra and Schwichtenberg~\<^cite>‹"troelstra2000basic"›.›
lemma
shows BotL_canonical[intro!]: "⊥,Γ⇒Δ"
and Ax_canonical[intro!]: "Atom k,Γ ⇒ Atom k,Δ"
by (meson SCp.intros union_single_eq_member)+
lemma lem1: "x ≠ y ⟹ x, M = y,N ⟷ x ∈# N ∧ M = y,(N - {#x#})"
by (metis (no_types, lifting) add_eq_conv_ex add_mset_remove_trivial add_mset_remove_trivial_eq)
lemma lem2: "x ≠ y ⟹ x, M = y, N ⟷ y ∈# M ∧ N = x, (M - {#y#})"
using lem1 by fastforce
text‹This is here to deal with a technical problem: the way the simplifier uses @{thm add_mset_commute} is really suboptimal for the unification of SC rules.›
lemma sc_insertion_ordering[simp]:
"NO_MATCH (I❙→J) H ⟹ H,F❙→G,S = F❙→G,H,S"
"NO_MATCH (I❙→J) H ⟹ NO_MATCH (I❙∨J) H ⟹ H,F❙∨G,S = F❙∨G,H,S"
"NO_MATCH (I❙→J) H ⟹ NO_MATCH (I❙∨J) H ⟹ NO_MATCH (I❙∧J) H ⟹ H,F❙∧G,S = F❙∧G,H,S"
"NO_MATCH (I❙→J) H ⟹ NO_MATCH (I❙∨J) H ⟹ NO_MATCH (I❙∧J) H ⟹ NO_MATCH (❙¬J) H ⟹ H,❙¬G,S = ❙¬G,H,S"
"NO_MATCH (I❙→J) H ⟹ NO_MATCH (I❙∨J) H ⟹ NO_MATCH (I❙∧J) H ⟹ NO_MATCH (❙¬J) H ⟹ NO_MATCH (⊥) H ⟹ H,⊥,S = ⊥,H,S"
"NO_MATCH (I❙→J) H ⟹ NO_MATCH (I❙∨J) H ⟹ NO_MATCH (I❙∧J) H ⟹ NO_MATCH (❙¬J) H ⟹ NO_MATCH (⊥) H ⟹ NO_MATCH (Atom k) H ⟹ H,Atom l,S = Atom l,H,S"
by simp_all
lemma shows
inR1: "Γ ⇒ G, H, Δ ⟹ Γ ⇒ H, G, Δ"
and inL1: "G, H, Γ ⇒ Δ ⟹ H, G, Γ ⇒ Δ"
and inR2: "Γ ⇒ F, G, H, Δ ⟹ Γ ⇒ G, H, F, Δ"
and inL2: "F, G, H, Γ ⇒ Δ ⟹ G, H, F, Γ ⇒ Δ" by(simp_all add: add_mset_commute)
lemmas SCp_swap_applies[elim!,intro] = inL1 inL2 inR1 inR2
lemma NotL_inv: "Not F, Γ ⇒ Δ ⟹ Γ ⇒ F,Δ"
proof(induction "Not F, Γ" Δ arbitrary: Γ rule: SCp.induct)
case (NotL Γ' G Δ) thus ?case by(cases "Not F = Not G") (auto intro!: SCp.intros(3-) dest!: multi_member_split simp: lem1 lem2)
qed (auto intro!: SCp.intros(3-) dest!: multi_member_split simp: SCp.intros lem1 lem2)
lemma AndL_inv: "And F G, Γ ⇒ Δ ⟹ F,G,Γ ⇒ Δ"
proof(induction "And F G, Γ" Δ arbitrary: Γ rule: SCp.induct)
case (AndL F' G' Γ' Δ) thus ?case
by(cases "And F G = And F' G'";
auto intro!: SCp.intros(3-) dest!: multi_member_split simp: lem1 lem2;
metis add_mset_commute)
qed (auto intro!: SCp.intros(3-) dest!: multi_member_split simp: SCp.intros lem1 lem2 inL2)
lemma OrL_inv:
assumes "Or F G, Γ ⇒ Δ"
shows "F,Γ ⇒ Δ ∧ G,Γ ⇒ Δ"
proof(insert assms, induction "Or F G, Γ" Δ arbitrary: Γ rule: SCp.induct)
case (OrL F' Γ' Δ G') thus ?case
by(cases "Or F G = Or F' G'";
auto intro!: SCp.intros(3-) dest!: multi_member_split simp: lem1 lem2;
blast)
qed (fastforce intro!: SCp.intros(3-) dest!: multi_member_split simp: SCp.intros lem1 lem2)+
lemma ImpL_inv:
assumes "Imp F G, Γ ⇒ Δ"
shows "Γ ⇒ F,Δ ∧ G,Γ ⇒ Δ"
proof(insert assms, induction "Imp F G, Γ" Δ arbitrary: Γ rule: SCp.induct)
case (ImpL Γ' F' Δ G') thus ?case
by(cases "Or F G = Or F' G'";
auto intro!: SCp.intros(3-) dest!: multi_member_split simp: lem1 lem2;
blast)
qed (fastforce intro!: SCp.intros(3-) dest!: multi_member_split simp: SCp.intros lem1 lem2)+
lemma ImpR_inv:
assumes "Γ ⇒ Imp F G,Δ"
shows "F,Γ ⇒ G,Δ"
proof(insert assms, induction Γ "Imp F G, Δ" arbitrary: Δ rule: SCp.induct)
case (ImpR F' Γ G' Δ') thus ?case
by(cases "Or F G = Or F' G'";
auto intro!: SCp.intros(3-) dest!: multi_member_split simp: lem1 lem2;
blast)
qed (fastforce intro!: SCp.intros(3-) dest!: multi_member_split simp: SCp.intros lem1 lem2)+
lemma AndR_inv:
shows "Γ ⇒ And F G, Δ ⟹ Γ ⇒ F, Δ ∧ Γ ⇒ G, Δ"
proof(induction Γ "And F G, Δ" arbitrary: Δ rule: SCp.induct)
case (AndR Γ F' Δ' G') thus ?case
by(cases "Or F G = Or F' G'";
auto intro!: SCp.intros(3-) dest!: multi_member_split simp: lem1 lem2;
blast)
qed (fastforce intro!: SCp.intros(3-) dest!: multi_member_split simp: SCp.intros lem1 lem2)+
lemma OrR_inv: "Γ ⇒ Or F G, Δ ⟹ Γ ⇒ F,G,Δ"
proof(induction Γ "Or F G, Δ" arbitrary: Δ rule: SCp.induct)
case (OrR Γ F' G' Δ') thus ?case
by(cases "Or F G = Or F' G'";
auto intro!: SCp.intros(3-) dest!: multi_member_split simp: lem1 lem2;
metis add_mset_commute)
qed (fastforce intro!: SCp.intros(3-) dest!: multi_member_split simp: SCp.intros lem1 lem2)+
lemma NotR_inv: "Γ ⇒ Not F, Δ ⟹ F,Γ ⇒ Δ"
proof(induction Γ "Not F, Δ" arbitrary: Δ rule: SCp.induct)
case (NotR G Γ Δ') thus ?case
by(cases "Not F = Not G";
auto intro!: SCp.intros(3-) dest!: multi_member_split simp: lem1 lem2;
metis add_mset_commute)
qed (fastforce intro!: SCp.intros(3-) dest!: multi_member_split simp: SCp.intros lem1 lem2)+
lemma weakenL: "Γ ⇒ Δ ⟹ F,Γ ⇒ Δ"
by(induction rule: SCp.induct)
(auto intro!: SCp.intros(3-) intro: SCp.intros(1,2))
lemma weakenR: "Γ ⇒ Δ ⟹ Γ ⇒ F,Δ "
by(induction rule: SCp.induct)
(auto intro!: SCp.intros(3-) intro: SCp.intros(1,2))
lemma weakenL_set: "Γ ⇒ Δ ⟹ F + Γ ⇒ Δ"
by(induction F; simp add: weakenL)
lemma weakenR_set: "Γ ⇒ Δ ⟹ Γ ⇒ F + Δ"
by(induction F; simp add: weakenR)
lemma extended_Ax: "Γ ∩# Δ ≠ {#} ⟹ Γ ⇒ Δ"
proof -
assume "Γ ∩# Δ ≠ {#}"
then obtain W where "W ∈# Γ" "W ∈# Δ" by force
then show ?thesis proof(induction W arbitrary: Γ Δ)
case (Not W)
from Not.prems obtain Γ' Δ' where [simp]: "Γ = Not W,Γ'" "Δ = Not W,Δ'" by (metis insert_DiffM)
have "W ∈# W,Γ'" "W ∈# W,Δ'" by simp_all
from Not.IH[OF this] obtain n where "W, Γ' ⇒ W, Δ'" by presburger
hence "Not W, Γ' ⇒ Not W, Δ'" using SCp.intros(3,4) add_mset_commute by metis
thus "Γ ⇒ Δ" by auto
next
case (And G H)
from And.prems obtain Γ' Δ' where [simp]: "Γ = And G H,Γ'" "Δ = And G H,Δ'" by (metis insert_DiffM)
have "G ∈# G, H, Γ'" "G ∈# G, Δ'" by simp_all
with And.IH(1) have IH1: "G, H, Γ' ⇒ G, Δ'" .
have "H ∈# G, H, Γ'" "H ∈# H, Δ'" by simp_all
with And.IH(2) have IH2: "G, H, Γ' ⇒ H, Δ'" .
from IH1 IH2 have "G, H, Γ' ⇒ G, Δ'" "G, H, Γ' ⇒ H, Δ'" by fast+
thus "Γ ⇒ Δ" using SCp.intros(5,6) by fastforce
next
case (Or G H)
case (Imp G H)
text‹analogously›
next
case (Or G H)
from Or.prems obtain Γ' Δ' where [simp]: "Γ = Or G H,Γ'" "Δ = Or G H,Δ'" by (metis insert_DiffM)
with Or.IH show ?case using SCp.intros(7,8)[where 'a='a] by fastforce
next
case (Imp G H)
from Imp.prems obtain Γ' Δ' where [simp]: "Γ = Imp G H,Γ'" "Δ = Imp G H,Δ'" by (metis insert_DiffM)
from Imp.IH have "G, Γ' ⇒ G, H, Δ'" "H, G, Γ' ⇒ H, Δ'" by simp_all
thus ?case by(auto intro!: SCp.intros(3-))
qed (auto intro: SCp.intros)
qed
lemma Bot_delR: "Γ ⇒ Δ ⟹ Γ ⇒ Δ-{#⊥#}"
proof(induction rule: SCp.induct)
case BotL
thus ?case by (simp add: SCp.BotL)
next
case Ax
thus ?case
by (metis SCp.Ax diff_union_swap formula.distinct(1) insert_DiffM union_single_eq_member)
next
case NotL
thus ?case
by (metis SCp.NotL diff_single_trivial diff_union_swap2)
next
case NotR
thus ?case by(simp add: SCp.NotR)
next
case AndL
thus ?case by (simp add: SCp.AndL)
next
case AndR
thus ?case
by (metis SCp.AndR diff_single_trivial diff_union_swap diff_union_swap2 formula.distinct(13))
next
case OrL
thus ?case by(simp add: SCp.OrL)
next
case OrR
thus ?case
by (metis SCp.OrR diff_single_trivial diff_union_swap2 formula.distinct(15) insert_iff set_mset_add_mset_insert)
next
case ImpL
thus ?case by (metis SCp.ImpL diff_single_trivial diff_union_swap2)
next
case ImpR
thus ?case
by (metis SCp.ImpR diff_single_trivial diff_union_swap diff_union_swap2 formula.distinct(17))
qed
corollary Bot_delR_simp: "Γ ⇒ ⊥,Δ = Γ ⇒ Δ"
using Bot_delR weakenR by fastforce
end