Theory Derivations
chapter ‹Derivations›
theory Derivations imports Maximal_Consistent_Sets begin
lemma split_finite_sets:
  assumes ‹finite A› ‹finite B›
    and ‹A ⊆ B ∪ S›
  shows ‹∃B' C. finite C ∧ A = B' ∪ C ∧ B' = A ∩ B ∧ C ⊆ S›
  using assms subset_UnE by auto
lemma split_list:
  assumes ‹set A ⊆ set B ∪ S›
  shows ‹∃B' C. set (B' @ C) = set A ∧ set B' = set A ∩ set B ∧ set C ⊆ S›
  using assms split_finite_sets[where A=‹set A› and B=‹set B› and S=S]
  by (metis List.finite_set finite_Un finite_list set_append)
section ‹Derivations›
locale Derivations =
  fixes derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50)
  assumes derive_assm [simp]: ‹⋀A p. p ∈ set A ⟹ A ⊢ p›
    and derive_set: ‹⋀A B r. A ⊢ r ⟹ set A = set B ⟹ B ⊢ r›
begin
theorem derive_split:
  assumes ‹set A ⊆ set B ∪ X› ‹A ⊢ p›
  shows ‹∃B' C. set B' = set A ∩ set B ∧ set C ⊆ X ∧ B' @ C ⊢ p›
  using assms derive_set split_list[where A=A and B=B] by metis
corollary derive_split1:
  assumes ‹set A ⊆ {q} ∪ X› ‹A ⊢ p› ‹q ∈ set A›
  shows ‹∃C. set C ⊆ X ∧ q # C ⊢ p›
  using assms derive_split[where A=A and X=X and B=‹[q]› and p=p] derive_set[where B=‹q # _›]
  by auto
end
section ‹MCSs and Explosion›
locale Derivations_MCS = MCS_Base consistent + Derivations derive
  for consistent :: ‹'fm set ⇒ bool›
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50) +
  assumes consistent_underivable: ‹⋀S. consistent S ⟷ (∀A. set A ⊆ S ⟶ (∃q. ¬ A ⊢ q))›
begin
theorem MCS_explode:
  assumes ‹consistent S› ‹maximal S›
  shows ‹p ∉ S ⟷ (∃A. set A ⊆ S ∧ (∀q. p # A ⊢ q))›
proof safe
  assume ‹p ∉ S›
  then obtain B where B: ‹set B ⊆ {p} ∪ S› ‹p ∈ set B› ‹∀q. B ⊢ q›
    using assms unfolding consistent_underivable maximal_def by blast
  moreover have ‹set (p # removeAll p B) = set B›
    using B(2) by auto
  ultimately have ‹∀q. p # removeAll p B ⊢ q›
    using derive_set by metis
  then show ‹∃A. set A ⊆ S ∧ (∀q. p # A ⊢ q)›
    using B(1) by (metis Diff_subset_conv set_removeAll)
next
  fix A
  assume ‹set A ⊆ S› ‹∀q. p # A ⊢ q› ‹p ∈ S›
  then show False
    using assms unfolding consistent_underivable
    by (metis (no_types, lifting) insert_subsetI list.simps(15))
qed
end
section ‹MCSs and Derivability›
locale Derivations_Cut_MCS = Derivations_MCS consistent derive
  for consistent :: ‹'fm set ⇒ bool›
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50) +
  assumes derive_cut: ‹⋀A B p q. A ⊢ p ⟹ p # B ⊢ q ⟹ A @ B ⊢ q›
begin
theorem MCS_derive:
  assumes ‹consistent S› ‹maximal S›
  shows ‹p ∈ S ⟷ (∃A. set A ⊆ S ∧ A ⊢ p)›
proof safe
  assume ‹p ∈ S›
  then show ‹∃A. set A ⊆ S ∧ A ⊢ p›
    using derive_assm by (metis List.set_insert empty_set empty_subsetI insert_subset singletonI)
next
  fix A
  assume A: ‹set A ⊆ S› ‹A ⊢ p›
  have bot: ‹∀A. set A ⊆ S ⟶ (∃q. ¬ A ⊢ q)›
    using assms(1) unfolding consistent_underivable by blast
  have ‹consistent ({p} ∪ S)›
    unfolding consistent_underivable
  proof safe
    fix B
    assume B: ‹set B ⊆ {p} ∪ S›
    show ‹∃q. ¬ B ⊢ q›
    proof (rule ccontr)
      assume *: ‹∄q. ¬ B ⊢ q›
      then have ‹∀q. B ⊢ q›
        by blast
      show False
      proof (cases ‹p ∈ set B›)
        case True
        then have ‹set (p # removeAll p B) = set B›
          by auto
        then have ‹∀q. p # removeAll p B ⊢ q›
          using ‹∀q. B ⊢ q› derive_set by blast
        then have ‹∀q. A @ removeAll p B ⊢ q›
          using A(2) derive_cut by blast
        moreover have ‹set (A @ removeAll p B) ⊆ S›
          using A(1) B by auto
        ultimately show False
          using bot by blast
      next
        case False
        then show False
          using * B bot by auto
      qed
    qed
  qed
  then show ‹p ∈ S›
    using assms unfolding maximal_def by auto
qed
end
section ‹Proof Rules›
locale Derivations_Bot = Derivations_Cut_MCS consistent derive
  for consistent :: ‹'fm set ⇒ bool›
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50) +
  fixes bot :: 'fm (‹❙⊥›)
  assumes botE: ‹⋀A p. A ⊢ ❙⊥ ⟹ A ⊢ p›
begin
corollary MCS_botE [elim]:
  assumes ‹consistent S› ‹maximal S›
    and ‹❙⊥ ∈ S›
  shows ‹p ∈ S›
  using assms botE MCS_derive by blast
corollary MCS_bot [simp]:
  assumes ‹consistent S› ‹maximal S›
  shows ‹❙⊥ ∉ S›
  using assms botE MCS_derive consistent_underivable by blast
end
locale Derivations_Top = Derivations_Cut_MCS +
  fixes top (‹❙⊤›)
  assumes topI: ‹⋀A. A ⊢ ❙⊤›
begin
corollary MCS_topI [simp]:
  assumes ‹consistent S› ‹maximal S›
  shows ‹❙⊤ ∈ S›
  using assms topI MCS_derive by (metis empty_set empty_subsetI)
end
locale Derivations_Not = Derivations_Bot consistent derive bot
  for consistent :: ‹'fm set ⇒ bool›
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50)
    and bot :: 'fm (‹❙⊥›) +
  fixes not :: ‹'fm ⇒ 'fm› (‹❙¬›)
  assumes
    notI: ‹⋀A p. p # A ⊢ ❙⊥ ⟹ A  ⊢ ❙¬ p› and
    notE: ‹⋀A p. A ⊢ p ⟹ A ⊢ ❙¬ p ⟹ A ⊢ ❙⊥›
begin
corollary MCS_not_xor:
  assumes ‹consistent S› ‹maximal S›
  shows ‹p ∈ S ⟷ ❙¬ p ∉ S›
proof safe
  assume ‹p ∈ S› ‹❙¬ p ∈ S›
  then have ‹set [p, ❙¬ p] ⊆ S›
    by simp
  moreover have ‹[p, ❙¬ p] ⊢ ❙⊥›
    using notE derive_assm by (meson list.set_intros(1) list.set_intros(2))
  ultimately have ‹❙⊥ ∈ S›
    using assms MCS_derive by blast
  then show False
    using assms MCS_bot by blast
next
  assume *: ‹❙¬ p ∉ S›
  show ‹p ∈ S›
  proof (rule ccontr)
    assume ‹p ∉ S›
    then obtain A where A: ‹set A ⊆ S› ‹∀q. p # A ⊢ q›
      using assms MCS_explode by blast
    then have ‹p # A ⊢ ❙⊥›
      by fast
    then have ‹A ⊢ ❙¬ p›
      using notI by blast
    then have ‹❙¬ p ∈ S›
      using A(1) assms MCS_derive by blast
    then show False
      using * by blast
  qed
qed
    
corollary MCS_not_both:
  assumes ‹consistent S› ‹maximal S›
  shows ‹p ∉ S ∨ ❙¬ p ∉ S›
  using assms MCS_not_xor by blast
corollary MCS_not_neither:
  assumes ‹consistent S› ‹maximal S›
  shows ‹p ∈ S ∨ ❙¬ p ∈ S›
  using assms MCS_not_xor by blast
end
locale Derivations_Con = Derivations_Cut_MCS consistent derive
  for consistent :: ‹'fm set ⇒ bool›
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50)  +
  fixes con :: ‹'fm ⇒ 'fm ⇒ 'fm› (‹_ ❙∧ _›)
  assumes
    conI: ‹⋀A p q. A ⊢ p ⟹ A ⊢ q ⟹ A ⊢ (p ❙∧ q)› and
    conE: ‹⋀A p q r. A ⊢ (p ❙∧ q) ⟹ p # q # A ⊢ r ⟹ A ⊢ r›
begin
corollary MCS_conI [intro]:
  assumes ‹consistent S› ‹maximal S›
    and ‹p ∈ S› ‹q ∈ S›
  shows ‹(p ❙∧ q) ∈ S›
  using assms MCS_derive derive_assm conI
  by (metis (mono_tags, lifting) insert_subset list.set_intros(1) list.simps(15) set_subset_Cons)
corollary MCS_conE [dest]:
  assumes ‹consistent S› ‹maximal S›
    and ‹(p ❙∧ q) ∈ S›
  shows ‹p ∈ S ∧ q ∈ S›
proof -
  have ‹p # q # A ⊢ p› ‹p # q # A ⊢ q› for A
    using derive_assm by simp_all
  then show ?thesis
    using assms MCS_derive conE by blast
qed
corollary MCS_con:
  assumes ‹consistent S› ‹maximal S›
  shows ‹(p ❙∧ q) ∈ S ⟷ p ∈ S ∧ q ∈ S›
  using assms MCS_conI MCS_conE by blast
end
locale Derivations_Dis = Derivations_Cut_MCS consistent derive
  for consistent :: ‹'fm set ⇒ bool›
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50)  +
  fixes dis :: ‹'fm ⇒ 'fm ⇒ 'fm› (‹_ ❙∨ _›)
  assumes
    disI1: ‹⋀A p q. A ⊢ p ⟹ A ⊢ (p ❙∨ q)› and
    disI2: ‹⋀A p q. A ⊢ q ⟹ A ⊢ (p ❙∨ q)› and
    disE: ‹⋀A p q r. A ⊢ (p ❙∨ q) ⟹ p # A ⊢ r ⟹ q # A ⊢ r ⟹ A ⊢ r›
begin
corollary MCS_disI1 [intro]:
  assumes ‹consistent S› ‹maximal S›
    and ‹p ∈ S›
  shows ‹(p ❙∨ q) ∈ S›
  using assms disI1 MCS_derive by auto
corollary MCS_disI2 [intro]:
  assumes ‹consistent S› ‹maximal S›
    and ‹q ∈ S›
  shows ‹(p ❙∨ q) ∈ S›
  using assms disI2 MCS_derive by auto
corollary MCS_disE [elim]:
  assumes ‹consistent S› ‹maximal S›
    and ‹(p ❙∨ q) ∈ S›
  shows ‹p ∈ S ∨ q ∈ S›
proof (rule ccontr)
  have bot: ‹∀A. set A ⊆ S ⟶ (∃q. ¬ A ⊢ q)›
    using assms(1) unfolding consistent_underivable by blast
  assume ‹¬ (p ∈ S ∨ q ∈ S)›
  then obtain P Q where
    P: ‹set P ⊆ S› ‹∀r. p # P ⊢ r› and
    Q: ‹set Q ⊆ S› ‹∀r. q # Q ⊢ r›
    using assms MCS_explode by auto
  have ‹p # (p ❙∨ q) # Q ⊢ p›
    by simp
  then have ‹p # (p ❙∨ q) # Q @ P ⊢ r› for r
    using P derive_cut[of _ p] by (metis append_Cons)
  then have ‹p # (p ❙∨ q) # P @ Q ⊢ r› for r
    using derive_set[where B=‹p # (p ❙∨ q) # P @ Q›] by fastforce
  moreover have ‹q # (p ❙∨ q) # P ⊢ q›
    by simp
  then have ‹q # (p ❙∨ q) # P @ Q ⊢ r› for r
    using Q derive_cut[of _ q] by (metis append_Cons)
  moreover have ‹(p ❙∨ q) # P @ Q ⊢ (p ❙∨ q)›
    by simp
  ultimately have ‹(p ❙∨ q) # P @ Q ⊢ r› for r
    using disE by blast
  moreover have ‹set ((p ❙∨ q) # P @ Q) ⊆ S›
    using assms(3) P Q by simp
  ultimately show False
    using assms(1) unfolding consistent_underivable by blast
qed
corollary MCS_dis:
  assumes ‹consistent S› ‹maximal S›
  shows ‹(p ❙∨ q) ∈ S ⟷ p ∈ S ∨ q ∈ S›
  using assms MCS_disI1 MCS_disI2 MCS_disE by blast
end
locale Derivations_Imp = Derivations_Cut_MCS consistent derive
  for consistent :: ‹'fm set ⇒ bool›
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50)  +
  fixes imp :: ‹'fm ⇒ 'fm ⇒ 'fm› (‹_ ❙→ _›)
  assumes
    impI: ‹⋀A p q. p # A ⊢ q ⟹ A ⊢ (p ❙→ q)› and
    impE: ‹⋀A p q. A ⊢ p ⟹ A ⊢ (p ❙→ q) ⟹ A ⊢ q›
begin
corollary MCS_impI [intro]:
  assumes ‹consistent S› ‹maximal S›
    and ‹p ∈ S ⟶ q ∈ S›
  shows ‹(p ❙→ q) ∈ S›
    using assms impI derive_assm MCS_derive MCS_explode
    by (metis insert_subset list.simps(15) subsetI)
corollary MCS_impE [dest]:
  assumes ‹consistent S› ‹maximal S›
    and ‹(p ❙→ q) ∈ S› ‹p ∈ S›
  shows ‹q ∈ S›
  using assms(3-4) impE MCS_derive[OF assms(1-2)] derive_assm
  by (metis insert_subset list.set_intros(1) list.simps(15) set_subset_Cons)
corollary MCS_imp:
  assumes ‹consistent S› ‹maximal S›
  shows ‹(p ❙→ q) ∈ S ⟷ (p ∈ S ⟶ q ∈ S)›
  using assms MCS_impI MCS_impE by blast
end
locale Derivations_Exi = MCS_Witness consistent witness params + Derivations_Cut_MCS consistent derive
  for consistent :: ‹'fm set ⇒ bool›
    and witness params
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50)  +
  fixes exi :: ‹'fm ⇒ 'fm› (‹❙∃›)
    and inst :: ‹'t ⇒ 'fm ⇒ 'fm› (‹⟨_⟩›)
  assumes
    exi_witness: ‹⋀S S' p. MCS S ⟹ witness (❙∃p) S' ⊆ S ⟹ ∃t. ⟨t⟩p ∈ S› and
    exiI: ‹⋀A p t. A ⊢ ⟨t⟩p ⟹ A ⊢ ❙∃p›
begin
corollary MCS_exiI [intro]:
  assumes ‹consistent S› ‹maximal S›
    and ‹⟨t⟩p ∈ S›
  shows ‹❙∃p ∈ S›
  using assms MCS_derive exiI by blast
corollary MCS_exiE [dest]:
  assumes ‹consistent S› ‹maximal S› ‹witnessed S›
    and ‹❙∃p ∈ S›
  shows ‹∃t. ⟨t⟩p ∈ S›
  using assms exi_witness unfolding witnessed_def by blast
corollary MCS_exi:
  assumes ‹consistent S› ‹maximal S› ‹witnessed S›
  shows ‹❙∃p ∈ S ⟷ (∃t. ⟨t⟩p ∈ S)›
  using assms MCS_exiI MCS_exiE by blast
end
locale Derivations_Uni = MCS_Witness consistent witness params + Derivations_Not consistent derive bot not
  for consistent :: ‹'fm set ⇒ bool›
    and witness params
    and derive :: ‹'fm list ⇒ 'fm ⇒ bool› (infix ‹⊢› 50)
    and bot :: 'fm (‹❙⊥›)
    and not :: ‹'fm ⇒ 'fm› (‹❙¬›) +
  fixes uni :: ‹'fm ⇒ 'fm› (‹❙∀›)
    and inst :: ‹'t ⇒ 'fm ⇒ 'fm› (‹⟨_⟩›)
  assumes
    uni_witness: ‹⋀S S' p. MCS S ⟹ witness (❙¬ (❙∀p)) S' ⊆ S ⟹ ∃t. ❙¬ (⟨t⟩p) ∈ S› and
    uniE: ‹⋀A p t. A ⊢ ❙∀p ⟹ A ⊢ ⟨t⟩p›
begin
corollary MCS_uniE [dest]:
  assumes ‹consistent S› ‹maximal S›
    and ‹❙∀p ∈ S›
  shows ‹⟨t⟩p ∈ S›
  using assms MCS_derive uniE by blast
corollary MCS_uniI [intro]:
  assumes ‹consistent S› ‹maximal S› ‹witnessed S›
    and ‹∀t. ⟨t⟩p ∈ S›
  shows ‹❙∀p ∈ S›
proof (rule ccontr)
  assume ‹❙∀p ∉ S›
  then have ‹❙¬ (❙∀p) ∈ S›
    using assms MCS_not_xor by blast
  then have ‹∃t. ❙¬ (⟨t⟩p) ∈ S›
    using assms uni_witness unfolding witnessed_def by blast
  then show False
    using assms MCS_not_xor by blast
qed
corollary MCS_uni:
  assumes ‹consistent S› ‹maximal S› ‹witnessed S›
  shows ‹❙∀p ∈ S ⟷ (∀t. ⟨t⟩p ∈ S)›
  using assms MCS_uniI MCS_uniE by blast
end
end