Theory Implicational_Logic_Natural_Deduction
theory Implicational_Logic_Natural_Deduction imports Main begin
datatype form =
Pro nat (‹⋅›) |
Imp form form (infixr ‹→› 100)
primrec semantics (infix ‹⊨› 50) where
‹I ⊨ ⋅n = I n› |
‹I ⊨ p → q = (I ⊨ p ⟶ I ⊨ q)›
inductive Calculus (infix ‹↝› 50) where
Assm: ‹p ∈ set A ⟹ A ↝ p› |
ImpI: ‹p # A ↝ q ⟹ A ↝ p → q› |
ImpE: ‹A ↝ p → q ⟹ A ↝ p ⟹ A ↝ q› |
ImpC: ‹p → _ # A ↝ p ⟹ A ↝ p›
abbreviation natural_deduction (‹⊢ _› [100] 100) where ‹⊢ p ≡ [] ↝ p›
theorem soundness: ‹A ↝ p ⟹ ∀p ∈ set A. I ⊨ p ⟹ I ⊨ p›
by (induct rule: Calculus.induct) auto
lemma weaken': ‹A ↝ p ⟹ set A = set B ⟹ B ↝ p›
proof (induct arbitrary: B rule: Calculus.induct)
case ImpC
with Calculus.ImpC show ?case
using list.set(2) by metis
qed (auto intro: Calculus.intros)
lemma weak: ‹A ↝ p ⟹ q # A ↝ p›
proof (induct rule: Calculus.induct)
case ImpI
with Calculus.ImpI show ?case
using insert_commute list.set(2) weaken' by (metis (full_types))
next
case ImpC
with Calculus.ImpC show ?case
using insert_commute list.set(2) weaken' by (metis (full_types))
qed (auto intro: Calculus.intros)
lemma add_assumptions: ‹⊢ p ⟹ A ↝ p›
by (induct A) (simp_all add: weak)
lemma weaken: ‹A ↝ p ⟹ set A ⊆ set B ⟹ B ↝ p›
proof (induct A arbitrary: p)
case (Cons q A)
moreover from this have ‹A ↝ q → p› and ‹set A ⊆ set B› and ‹B ↝ q›
by (simp_all add: Assm ImpI)
ultimately show ?case
using ImpE by blast
qed (simp add: add_assumptions)
lemma deduct: ‹A ↝ p → q ⟹ p # A ↝ q›
using Assm ImpE list.set_intros(1) weak by meson
lemma Peirce: ‹⊢ ((p → q) → p) → p›
using Assm ImpC ImpI deduct list.set_intros(1) by meson
lemma Simp: ‹⊢ p → q → p›
by (simp add: Assm ImpI)
lemma Tran: ‹⊢ (p → q) → (q → r) → p → r›
proof -
have ‹[p, q → r, p → q] ↝ r›
using Assm ImpE list.set_intros(1) weak by meson
then show ?thesis
using ImpI by blast
qed
lemma Swap: ‹⊢ (p → q → r) → q → p → r›
proof -
have ‹[p, q, p → q → r] ↝ r›
using Assm ImpE list.set_intros(1) weak by meson
then show ?thesis
using ImpI by blast
qed
lemma Tran': ‹⊢ (q → r) → (p → q) → p → r›
using ImpE Swap Tran .
lemma Imp1: ‹⊢ (q → s) → ((q → r) → s) → s›
using ImpE Peirce Tran Tran' by meson
lemma Imp2: ‹⊢ ((r → s) → s) → ((q → r) → s) → s›
using ImpE Tran ImpE Tran Simp .
lemma Imp3: ‹⊢ ((q → s) → s) → (r → s) → (q → r) → s›
using ImpE Tran Tran' by meson
fun pros where
‹pros (p → q) = remdups (pros p @ pros q)› |
‹pros p = (case p of ⋅n ⇒ [n] | _ ⇒ [])›
lemma distinct_pros: ‹distinct (pros p)›
by induct simp_all
abbreviation ‹lift t s p ≡ if t then (p → s) → s else p → s›
abbreviation ‹lifts I s ≡ map (λn. lift (I n) s (⋅n))›
lemma lifts_weaken: ‹lifts I s l ↝ p ⟹ set l ⊆ set l' ⟹ lifts I s l' ↝ p›
proof -
assume ‹lifts I s l ↝ p›
moreover assume ‹set l ⊆ set l'›
then have ‹set ((lifts I s) l) ⊆ set ((lifts I s) l')›
by auto
ultimately show ?thesis
using weaken by blast
qed
lemma lifts_pros_lift: ‹lifts I s (pros p) ↝ lift (I ⊨ p) s p›
proof (induct p)
case (Imp q r)
consider ‹¬ I ⊨ q› | ‹I ⊨ r› | ‹I ⊨ q› and ‹¬ I ⊨ r›
by blast
then show ?case
proof cases
case 1
then have ‹lifts I s (pros (q → r)) ↝ q → s›
using Imp(1) lifts_weaken[where l' = ‹pros (q → r)›] by simp
then have ‹lifts I s (pros (q → r)) ↝ ((q → r) → s) → s›
using Imp1 ImpE add_assumptions by blast
with 1 show ?thesis
by simp
next
case 2
then have ‹lifts I s (pros (q → r)) ↝ (r → s) → s›
using Imp(2) lifts_weaken[where l' = ‹pros (q → r)›] by simp
then have ‹lifts I s (pros (q → r)) ↝ ((q → r) → s) → s›
using Imp2 ImpE add_assumptions by blast
with 2 show ?thesis
by simp
next
case 3
then have
‹lifts I s (pros (q → r)) ↝ (q → s) → s›
‹lifts I s (pros (q → r)) ↝ r → s›
using Imp lifts_weaken[where l' = ‹pros (q → r)›] by simp_all
then have ‹lifts I s (pros (q → r)) ↝ (q → r) → s›
using Imp3 ImpE add_assumptions by blast
with 3 show ?thesis
by simp
qed
qed (simp add: Assm)
lemma lifts_pros: ‹I ⊨ p ⟹ lifts I p (pros p) ↝ p›
proof -
assume ‹I ⊨ p›
then have ‹lifts I p (pros p) ↝ (p → p) → p›
using lifts_pros_lift[of I p p] by simp
then show ?thesis
using ImpC deduct by blast
qed
theorem completeness: ‹∀I. I ⊨ p ⟹ ⊢ p›
proof -
let ?A = ‹λl I. lifts I p l ↝ p›
let ?B = ‹λl. ∀I. ?A l I ∧ distinct l›
assume ‹∀I. I ⊨ p›
moreover have ‹?B l ⟹ (⋀n l. ?B (n # l) ⟹ ?B l) ⟹ ?B []› for l
by (induct l) blast+
moreover have ‹?B (n # l) ⟹ ?B l› for n l
proof -
assume *: ‹?B (n # l)›
show ‹?B l›
proof
fix I
from * have
‹?A (n # l) (I(n := True))›
‹?A (n # l) (I(n := False))›
by blast+
moreover from * have ‹∀m ∈ set l. ∀t. (I(n := t)) m = I m›
by simp
ultimately have
‹((⋅n → p) → p) # lifts I p l ↝ p›
‹(⋅n → p) # lifts I p l ↝ p›
by (simp_all cong: map_cong)
then have ‹?A l I›
using ImpE ImpI by blast
moreover from * have ‹distinct (n # l)›
by blast
ultimately show ‹?A l I ∧ distinct l›
by simp
qed
qed
ultimately have ‹?B []›
using lifts_pros distinct_pros by blast
then show ?thesis
by simp
qed
primrec chain where
‹chain p [] = p› |
‹chain p (q # A) = q → chain p A›
lemma chain_rev: ‹B ↝ chain p A ⟹ rev A @ B ↝ p›
by (induct A arbitrary: B) (simp_all add: deduct)
lemma chain_deduct: ‹⊢ chain p A ⟹ A ↝ p›
proof (induct A)
case (Cons q A)
then have ‹rev (q # A) @ [] ↝ p›
using chain_rev by blast
moreover have ‹set (rev (q # A) @ []) = set (q # A)›
by simp
ultimately show ?case
using weaken by blast
qed simp
lemma chain_semantics: ‹I ⊨ chain p A = ((∀p ∈ set A. I ⊨ p) ⟶ I ⊨ p)›
by (induct A) auto
theorem main: ‹A ↝ p = (∀I. (∀p ∈ set A. I ⊨ p) ⟶ I ⊨ p)›
using chain_deduct chain_semantics completeness soundness by meson
end