Skip to content

Commit c8ff8ce

Browse files
committed
Formalize Exercise 5-1
Claude 3.7 (free version) was involved in small parts of this
1 parent 6af6640 commit c8ff8ce

File tree

3 files changed

+189
-3
lines changed

3 files changed

+189
-3
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import InferenceInLean.Basic
2+
import Mathlib.Data.Finset.Defs
3+
import Mathlib.Data.Set.Card
4+
import Mathlib.SetTheory.Cardinal.Finite
5+
6+
set_option autoImplicit false
7+
8+
open Syntax
9+
open Semantics
10+
open Models
11+
open Unification
12+
open Inferences
13+
14+
variable {sig : Signature} {X : Variables} {univ : Universes}
15+
16+
/- ## Exercise 5 -/
17+
18+
namespace Exercise5
19+
20+
/- ### Exercise 5-1 -/
21+
22+
namespace Task1
23+
24+
/- Claude Sonnet 3.7 (free version) was involved in some of these solutions. -/
25+
26+
inductive funs where | b | f deriving BEq
27+
inductive preds where | P deriving BEq
28+
29+
def sig5_1 : Signature := ⟨funs, preds⟩
30+
31+
def b : Term sig5_1 String := .func .b []
32+
def f : List (Term sig5_1 String) -> Term sig5_1 String := .func .f
33+
def P : List (Term sig5_1 String) -> Formula sig5_1 String := fun args =>.atom <| .pred .P args
34+
35+
/- Force the interpretation of P to be false for every list of arguments with the wrong arity. -/
36+
def ArityP : (preds -> List (Term sig5_1 Empty) -> Prop) -> Prop
37+
| ps => ∀ (args : List (Term sig5_1 Empty)), (args.length ≠ 1) → ¬(ps .P args)
38+
39+
-- (1) There is a Σ-model A of P (b) ∧ ¬P (f (b)) such that UA = {7, 8, 9}.
40+
def F₁ : Formula sig5_1 String := .and (P [b]) (.neg (P [f [b]]))
41+
theorem task5_1_1 : ∃ (I : Interpretation sig5_1 (Fin 3)), ∀ β : Assignment String (Fin 3),
42+
EntailsInterpret I β F₁ := by
43+
-- Define the interpretation I for universe {0, 1, 2} (representing {7, 8, 9})
44+
let I : Interpretation sig5_1 (Fin 3) := ⟨
45+
-- Function interpretations
46+
fun g args => match g with
47+
| .b => 0 -- Interpret b as 0 (representing 7)
48+
| .f => match args with
49+
| [x] => 1 -- Interpret f(x) as 1 (representing 8) for any x
50+
| _ => 0, -- Default case
51+
-- Predicate interpretations
52+
fun p args => match p with
53+
| .P => match args with
54+
| [x] => x = 0 -- P is true only for 0 (representing 7)
55+
| _ => false-- Default case
56+
use I
57+
intro β
58+
simp [F₁, EntailsInterpret, I, P, b, f]
59+
60+
-- (2) There is no Σ-model A of P (b) ∧ ¬P (f (f (b))) such that fA (a) = a for every a ∈ UA.
61+
def F₂ : Formula sig5_1 String := .and (P [b]) (.neg (P [f [f [b]]]))
62+
theorem task5_1_2 : ¬∃ (univ : Universes) (I : Interpretation sig5_1 univ),
63+
∀ β : Assignment String univ, EntailsInterpret I β F₂ ∧
64+
(∀ a, (I.functions .f) [a] = a):= by
65+
-- Get the universe and interpretation from the hypothesis
66+
intro ⟨univ, I, hI⟩
67+
have h := hI (fun _ => I.functions .b [])
68+
obtain ⟨h_entails, h_identity⟩ := h
69+
obtain ⟨h_P_b, h_not_P_ffb⟩ := h_entails
70+
let bval := I.functions .b []
71+
have h_fb : I.functions .f [bval] = bval := h_identity bval
72+
have h_ffb : I.functions .f [I.functions .f [bval]] = bval := by
73+
rw [h_fb]
74+
exact h_fb
75+
have h_P_bval : I.predicates .P [bval] := by
76+
simp [P,b] at h_P_b
77+
exact h_P_b
78+
have h_not_P_ffbval : ¬I.predicates .P [bval] := by
79+
simp [Formula.eval, P, f, b, bval] at h_not_P_ffb
80+
rw [h_ffb] at h_not_P_ffb
81+
exact h_not_P_ffb
82+
contradiction
83+
84+
-- (3) P(b) ∧ ¬P(f (b)) has a Herbrand model.
85+
theorem task5_1_3 : ∃ preds, ∀ β, EntailsInterpret (HerbrandInterpretation sig5_1 preds) β F₁ := by
86+
-- First, let's define our Herbrand interpretation
87+
-- We need to define how predicates behave on ground terms
88+
let preds : sig5_1.preds → List (Term sig5_1 Empty) → Prop := fun p args =>
89+
match p, args with
90+
| .P, [.func .b []] => True
91+
| .P, [.func .f [.func .b []]] => False
92+
| .P, _ => False
93+
use preds
94+
intro β
95+
simp [F₁, EntailsInterpret]
96+
apply And.intro
97+
· simp [HerbrandInterpretation, Atom.eval, Term.eval, preds, P, b]
98+
· simp [HerbrandInterpretation, Atom.eval, preds, P, f, b]
99+
100+
-- (4) P(b) ∧ ∀x ¬P(x) has no Herbrand model.
101+
def F₄ : Formula sig5_1 String := .and (P [b]) (.all "x" (.neg (P [.var "x"])))
102+
theorem task5_1_4 : ¬∃ preds, ∀ β, EntailsInterpret (HerbrandInterpretation sig5_1 preds) β F₄ := by
103+
let b' : Term sig5_1 Empty := Term.func .b []
104+
intro h
105+
rcases h with ⟨preds, h⟩
106+
let β₀ : Assignment String (Term sig5_1 Empty) := fun _ => b'
107+
have h₀ := h β₀
108+
have hPb : preds .P [b'] := by
109+
simp [F₄, P, b] at h₀
110+
exact h₀.1
111+
obtain ⟨_, h_forall⟩ := h₀
112+
let β₁ : Assignment String (Term sig5_1 Empty) := β₀.modify "x" b'
113+
have hNotPb : ¬preds .P [b'] := by
114+
simp [Formula.eval, HerbrandInterpretation, Atom.eval, Term.eval,
115+
Assignment.modify, Formula.all, β₁] at h_forall
116+
specialize h_forall b'
117+
simp [P] at h_forall
118+
exact h_forall
119+
contradiction
120+
121+
-- (5) ∀x P (f (x)) does not have a Herbrand model with a two-element universe.
122+
def F₅ : Formula sig5_1 String := .all "x" (P [f [.var "x"]])
123+
theorem task5_1_5 (S : Set <| Term sig5_1 Empty) (hall : ∀ t : Term sig5_1 Empty, t ∈ S) :
124+
Set.encard S ≠ 2 := by
125+
let t₀ : Term sig5_1 Empty := .func .b []
126+
let t₁ : Term sig5_1 Empty := .func .f [t₀]
127+
let t₂ : Term sig5_1 Empty := .func .f [t₁]
128+
let t₃ : Term sig5_1 Empty := .func .f [t₂]
129+
let S' : Set (Term sig5_1 Empty) := {t₀, t₁, t₂}
130+
have ht₀ := hall t₀
131+
have ht₁ := hall t₁
132+
have ht₂ := hall t₂
133+
have hsub : S' ⊆ S := by
134+
simp [Set.subset_def, S']
135+
exact ⟨ht₀, ht₁, ht₂⟩
136+
have hS'finite : S'.Finite := by aesop
137+
have hS'ncard3 : S'.ncard = 3 := by aesop
138+
have hS'encard3 : S'.encard = 3 := by
139+
have := hS'finite.cast_ncard_eq
140+
aesop
141+
have hle := Set.encard_le_card hsub
142+
intro hSncard2
143+
rw [hS'encard3, hSncard2] at hle
144+
contradiction
145+
146+
-- (6) ∀x P(x) has exactly one Herbrand model.
147+
def F₆ : Formula sig5_1 String := .all "x" (P [.var "x"])
148+
theorem task5_1_6 : ∃! ps,
149+
(ArityP ps ∧ ∀ β, EntailsInterpret (HerbrandInterpretation sig5_1 ps) β F₆) := by
150+
use fun _ args => args.length = 1
151+
apply And.intro
152+
· constructor
153+
· simp [ArityP]
154+
· intro β
155+
simp [F₆, P]
156+
· intro preds'
157+
intro ⟨h_arity, h_entails⟩
158+
ext p args
159+
cases p
160+
-- Let's prove that P must be true for all args for preds'
161+
have h : ∀ (t : Term sig5_1 Empty), preds' .P [t] := by
162+
intro t
163+
-- Create an assignment that maps x to t
164+
let β : Assignment String (Term sig5_1 Empty) := fun v => Term.func .b []
165+
-- Use the entailment hypothesis
166+
have h_entails_β := h_entails β
167+
-- Extract the universal quantifier's meaning
168+
simp [F₆, P] at h_entails_β
169+
-- Show that P holds for t
170+
specialize h_entails_β t
171+
exact h_entails_β
172+
simp_all only [EntailsInterpret]
173+
cases args with
174+
| nil =>
175+
simp_all only [ArityP, ne_eq, List.length_nil, zero_ne_one, not_false_eq_true]
176+
| cons head tail =>
177+
aesop
178+
179+
-- (7) ∀x P(f(x)) entails ∀x P(f(f(x))).
180+
def F₇ : Formula sig5_1 String := .all "x" (P [f [.var "x"]])
181+
def F₇' : Formula sig5_1 String := .all "y" (P [f [f [.var "y"]]])
182+
theorem task5_1_7 : @Entails _ _ univ _ F₇ F₇' := by simp_all [F₇, F₇', f, P]
183+
184+
185+
end Task1
186+
187+
end Exercise5

InferenceInLean/Semantics.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ structure Interpretation where
1919
functions : sig.funs -> (List univ -> univ)
2020
predicates : sig.preds -> (List univ -> Prop)
2121

22+
@[simp]
2223
def HerbrandInterpretation (sig : Signature) (preds : sig.preds -> List (Term sig Empty) -> Prop) :
2324
Interpretation sig (Term sig Empty) := ⟨fun f args => Term.func f args, preds⟩
2425

InferenceInLean/Syntax.lean

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ mutual
5353
| x :: xs, y :: ys => eqTerm x y && eqArgs xs ys
5454
end
5555

56-
instance [instX : BEq X] [instF : BEq sig.funs] :
57-
BEq (Term sig X) :=
58-
⟨eqTerm sig X⟩
56+
instance [instX : BEq X] [instF : BEq sig.funs] : BEq (Term sig X) := ⟨eqTerm sig X⟩
5957

6058
@[simp]
6159
def Term.freeVars : Term sig X -> Set X

0 commit comments

Comments
 (0)