Theory HC

subsection‹Hilbert Calculus›
theory HC
imports Formulas
begin

text‹We can define Hilbert Calculus as the modus ponens closure over a set of axioms:›
inductive HC :: "'a formula  set ⇒ 'a formula ⇒ bool" (infix ‹⊢H› 30) for Γ :: "'a formula set" where
Ax: "F ∈ Γ ⟹ Γ ⊢H F" |
MP: "Γ ⊢H F ⟹ Γ ⊢H F → G ⟹ Γ ⊢H G"
text‹.›

context begin

text‹The problem with that is defining the axioms. Normally, we just write that @{term "F → (G → F)"} is an axiom, 
  and mean that anything can be substituted for @{term F} and @{term G}.
Now, we can't just write down a set ‹{F → (G → F), \dots›.
Instead, defining it as an inductive set with no induction is a good idea.
›
(* Note to self: Don't try to formulate these as a definition. Possible, but painful to use. *)
inductive_set AX0 where
"F → (G → F) ∈ AX0" |
"(F → (G → H)) → ((F → G) → (F → H)) ∈ AX0"
inductive_set AX10 where
"F ∈ AX0 ⟹ F ∈ AX10" |
"F → (F ∨ G) ∈ AX10" |
"G → (F ∨ G) ∈ AX10" |
"(F → H) → ((G → H) → ((F ∨ G) → H)) ∈ AX10" |
"(F ∧ G) → F ∈ AX10" | 
"(F ∧ G) → G ∈ AX10" |
"F → (G → (F ∧ G)) ∈ AX10" |
"(F → ⊥) → ¬F ∈ AX10" |
"¬F → (F → ⊥) ∈ AX10" |
"(¬F → ⊥) → F ∈ AX10"
lemmas HC_intros[intro!] = 
  AX0.intros[THEN HC.intros(1)]
  AX0.intros[THEN AX10.intros(1), THEN HC.intros(1)]
  AX10.intros(2-)[THEN HC.intros(1)]

text‹The first four axioms, as originally formulated by Hilbert~cite‹"hilbert1928grundlagen"›.›
inductive_set AXH where
  "(F → (G → F)) ∈ AXH" |
  "(F → (F → G)) → (F → G) ∈ AXH" |
  "(F → (G → H)) → (G → (F → H)) ∈ AXH" |
  "(G → H) → ((F → G) → (F → H)) ∈ AXH"

lemma HC_mono: "S ⊢H F ⟹ S ⊆ T ⟹ T ⊢H F"
  by(induction rule: HC.induct) (auto intro: HC.intros)
lemma AX010: "AX0 ⊆ AX10"
  apply(rule)
  apply(cases rule: AX0.cases, assumption)
   apply(auto intro: AX10.intros)
done
lemma AX100[simp]: "AX0 ∪ AX10 = AX10" using AX010 by blast

text‹Hilbert's first four axioms and @{const AX0} are syntactically quite different.
  Derivability does not change:›
lemma hilbert_folgeaxiome_as_strong_as_AX0: "AX0 ∪ Γ ⊢H F ⟷ AXH ∪ Γ ⊢H F"
proof -
  have 0:
  "AX0 ⊢H (F → (F → G)) → (F → G)"
  "AX0 ⊢H (F → (G → H)) → (G → (F → H))"
  "AX0 ⊢H (G → H) → ((F → G) → (F → H))" 
    for F G H using HC_intros(1,2) MP by metis+
  have H:
    "AXH ⊢H (F → (G → H)) → ((F → G) → (F → H))"
    for F G H
  proof -
    note AXH.intros[THEN HC.Ax]
    thus ?thesis using MP by metis (* 4s *)
  qed
  note * = H 0
  note * = *[THEN HC_mono, OF Un_upper1]
  show ?thesis (is "?Z ⟷ ?H") (* HC, where nothing is automatic (except for after this, nearly everything in this file is) *)
  proof
    assume ?Z thus ?H proof induction
      case MP thus ?case using HC.MP by blast
    next
      case (Ax F) thus ?case proof
        assume "F ∈ AX0" thus ?thesis by induction (simp_all add: AXH.intros(1) HC.Ax *)
      next
        assume "F ∈ Γ" thus ?case using HC.Ax[of F] by simp
      qed
    qed
  next
    assume ?H thus ?Z proof induction
      case MP thus ?case using HC.MP by blast
    next
      case (Ax F) thus ?case proof
        assume "F ∈ AXH" thus ?thesis by induction (simp_all add: AX0.intros(1) HC.Ax *)
      next
        assume "F ∈ Γ" thus ?case using HC.Ax[of F] by simp
      qed
    qed
  qed
qed

lemma "AX0 ⊢H F → F" by (meson HC_intros(1,2) HC.MP)
(* Can you do that again, but slowly? *)
lemma imp_self: "AX0 ⊢H F → F" proof -
  let ?d = "λf. AX0 ⊢H f"
  note MP
  moreover have "?d (F → (G → F))" for G using HC_intros(1)[where G=G and F=F] .
  moreover {
    note MP
    moreover have "?d (F → ((G → F) → F))" for G using HC_intros(1)[where G="G → F" and F=F] .
    moreover have "?d ((F → ((G → F) → F)) → ((F → (G → F)) → (F → F)))" for G using HC_intros(2)[where G="G → F" and F=F and H=F] .
    ultimately have "?d ((F → (G → F)) → (F → F))" for G . }
  ultimately show "?d (F → F)" .
qed

(* You'd get the idea for this theorem just when writing the HCND proof. It's really quite natural. *)
theorem Deduction_theorem: "AX0 ∪ insert F Γ ⊢H G ⟹ AX0 ∪ Γ ⊢H F → G"
proof(induction rule: HC.induct)
  case (Ax G)
  show ?case proof cases
    assume "F = G"
    from imp_self have "AX0 ⊢H G → G" .
    with HC_mono show ?case unfolding ‹F = G› using sup_ge1 .
  next
    assume "F ≠ G"
    note HC.MP
    moreover {
      from ‹F ≠ G› ‹G ∈ AX0 ∪ insert F Γ› have "G ∈ AX0 ∪ Γ" by simp
      with HC.Ax have "AX0 ∪ Γ ⊢H G" .
    }
    moreover from HC_mono[OF HC_intros(1) sup_ge1] have "AX0 ∪ Γ ⊢H G → (F → G)" .
    ultimately show ?case .
  qed
next
  case (MP G H)
  have "AX0 ∪ Γ ⊢H (F → (G → H)) → ((F → G) → (F → H))" using HC_mono by blast
  with HC.MP ‹AX0 ∪ Γ ⊢H F → (G → H)› have "AX0 ∪ Γ ⊢H (F → G) → (F → H)" .
  with HC.MP ‹AX0 ∪ Γ ⊢H F → G› show "AX0 ∪ Γ ⊢H F → H" .
qed


end

end