Skip to content

Commit e026b77

Browse files
committed
chore(ModelTheory/Encoding): improve the encoding of formulas to avoid sizeOf (#15209)
Edits the decoding of lists into first-order formulas, so that the proof of well-foundedness is easier and no longer invokes `sizeOf`.
1 parent 9ca8f83 commit e026b77

File tree

1 file changed

+67
-83
lines changed

1 file changed

+67
-83
lines changed

Mathlib/ModelTheory/Encoding.lean

Lines changed: 67 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -52,46 +52,36 @@ def listEncode : L.Term α → List (α ⊕ (Σi, L.Functions i))
5252
Sum.inr (⟨_, f⟩ : Σi, L.Functions i)::(List.finRange _).bind fun i => (ts i).listEncode
5353

5454
/-- Decodes a list of variables and function symbols as a list of terms. -/
55-
def listDecode : List (α ⊕ (Σi, L.Functions i)) → List (Option (L.Term α))
55+
def listDecode : List (α ⊕ (Σi, L.Functions i)) → List (L.Term α)
5656
| [] => []
57-
| Sum.inl a::l => some (var a)::listDecode l
57+
| Sum.inl a::l => (var a)::listDecode l
5858
| Sum.inr ⟨n, f⟩::l =>
59-
if h : ∀ i : Fin n, ((listDecode l).get? i).join.isSome then
60-
(func f fun i => Option.get _ (h i))::(listDecode l).drop n
61-
else [none]
59+
if h : n ≤ (listDecode l).length then
60+
(func f (fun i => (listDecode l)[i])) :: (listDecode l).drop n
61+
else []
6262

6363
theorem listDecode_encode_list (l : List (L.Term α)) :
64-
listDecode (l.bind listEncode) = l.map Option.some := by
64+
listDecode (l.bind listEncode) = l := by
6565
suffices h : ∀ (t : L.Term α) (l : List (α ⊕ (Σi, L.Functions i))),
66-
listDecode (t.listEncode ++ l) = some t::listDecode l by
66+
listDecode (t.listEncode ++ l) = t::listDecode l by
6767
induction' l with t l lih
6868
· rfl
69-
· rw [bind_cons, h t (l.bind listEncode), lih, List.map]
69+
· rw [bind_cons, h t (l.bind listEncode), lih]
7070
intro t
7171
induction' t with a n f ts ih <;> intro l
7272
· rw [listEncode, singleton_append, listDecode]
7373
· rw [listEncode, cons_append, listDecode]
7474
have h : listDecode (((finRange n).bind fun i : Fin n => (ts i).listEncode) ++ l) =
75-
(finRange n).map (Option.some ∘ ts) ++ listDecode l := by
75+
(finRange n).map ts ++ listDecode l := by
7676
induction' finRange n with i l' l'ih
7777
· rfl
78-
· rw [bind_cons, List.append_assoc, ih, map_cons, l'ih, cons_append, Function.comp]
79-
have h' : ∀ i : Fin n,
80-
(listDecode (((finRange n).bind fun i : Fin n => (ts i).listEncode) ++ l))[(i : Nat)]? =
81-
some (some (ts i)) := by
82-
intro i
83-
rw [h, getElem?_append, getElem?_map]
84-
· simp only [Option.map_eq_some', Function.comp_apply, getElem?_eq_some]
85-
refine ⟨i, ⟨lt_of_lt_of_le i.2 (ge_of_eq (length_finRange _)), ?_⟩, rfl⟩
86-
rw [getElem_finRange, Fin.eta]
87-
· refine lt_of_lt_of_le i.2 ?_
88-
simp
89-
refine (dif_pos fun i => Option.isSome_iff_exists.2 ⟨ts i, ?_⟩).trans ?_
90-
· rw [get?_eq_getElem?, Option.join_eq_some, h']
91-
refine congr (congr rfl (congr rfl (congr rfl (funext fun i => Option.get_of_mem _ ?_)))) ?_
92-
· simp [h']
93-
· rw [h, drop_left']
94-
rw [length_map, length_finRange]
78+
· rw [bind_cons, List.append_assoc, ih, map_cons, l'ih, cons_append]
79+
simp only [h, length_append, length_map, length_finRange, le_add_iff_nonneg_right,
80+
_root_.zero_le, ↓reduceDIte, getElem_fin, cons.injEq, func.injEq, heq_eq_eq, true_and]
81+
refine ⟨funext (fun i => ?_), ?_⟩
82+
· rw [List.getElem_append, List.getElem_map, List.getElem_finRange]
83+
simp only [length_map, length_finRange, i.2]
84+
· simp only [length_map, length_finRange, drop_left']
9585

9686
/-- An encoding of terms as lists. -/
9787
@[simps]
@@ -102,7 +92,8 @@ protected def encoding : Encoding (L.Term α) where
10292
decode_encode t := by
10393
have h := listDecode_encode_list [t]
10494
rw [bind_singleton] at h
105-
simp only [h, Option.join, head?, List.map, Option.some_bind, id]
95+
simp only [Option.join, h, head?_cons, Option.pure_def, Option.bind_eq_bind, Option.some_bind,
96+
id_eq]
10697

10798
theorem listEncode_injective :
10899
Function.Injective (listEncode : L.Term α → List (α ⊕ (Σi, L.Functions i))) :=
@@ -146,7 +137,8 @@ instance [Encodable α] [Encodable (Σi, L.Functions i)] : Encodable (L.Term α)
146137
Encodable.ofLeftInjection listEncode (fun l => (listDecode l).head?.join) fun t => by
147138
simp only
148139
rw [← bind_singleton listEncode, listDecode_encode_list]
149-
simp only [Option.join, head?, List.map, Option.some_bind, id]
140+
simp only [Option.join, head?_cons, Option.pure_def, Option.bind_eq_bind, Option.some_bind,
141+
id_eq]
150142

151143
instance [h1 : Countable α] [h2 : Countable (Σl, L.Functions l)] : Countable (L.Term α) := by
152144
refine mk_le_aleph0_iff.1 (card_le.trans (max_le_iff.2 ?_))
@@ -176,61 +168,55 @@ def sigmaAll : (Σn, L.BoundedFormula α n) → Σn, L.BoundedFormula α n
176168
| ⟨n + 1, φ⟩ => ⟨n, φ.all⟩
177169
| _ => default
178170

171+
172+
@[simp]
173+
lemma sigmaAll_apply {n} {φ : L.BoundedFormula α (n + 1)} :
174+
sigmaAll ⟨n + 1, φ⟩ = ⟨n, φ.all⟩ := rfl
175+
179176
/-- Applies `imp` to two elements of `(Σ n, L.BoundedFormula α n)`,
180177
or returns `default` if not possible. -/
181178
def sigmaImp : (Σn, L.BoundedFormula α n) → (Σn, L.BoundedFormula α n) → Σn, L.BoundedFormula α n
182179
| ⟨m, φ⟩, ⟨n, ψ⟩ => if h : m = n then ⟨m, φ.imp (Eq.mp (by rw [h]) ψ)⟩ else default
183180

184-
/-- Decodes a list of symbols as a list of formulas. -/
185181
@[simp]
186-
def listDecode : ∀ l : List ((Σk, L.Term (α ⊕ Fin k)) ⊕ ((Σn, L.Relations n) ⊕ ℕ)),
187-
(Σn, L.BoundedFormula α n) ×
188-
{ l' : List ((Σk, L.Term (α ⊕ Fin k)) ⊕ ((Σn, L.Relations n) ⊕ ℕ)) //
189-
SizeOf.sizeOf l' ≤ max 1 (SizeOf.sizeOf l) }
190-
| Sum.inr (Sum.inr (n + 2))::l => ⟨⟨n, falsum⟩, l, le_max_of_le_right le_add_self⟩
182+
lemma sigmaImp_apply {n} {φ ψ : L.BoundedFormula α n} :
183+
sigmaImp ⟨n, φ⟩ ⟨n, ψ⟩ = ⟨n, φ.imp ψ⟩ := by
184+
simp only [sigmaImp, ↓reduceDIte, eq_mp_eq_cast, cast_eq]
185+
186+
/-- Decodes a list of symbols as a list of formulas. -/
187+
def listDecode :
188+
List ((Σk, L.Term (α ⊕ Fin k)) ⊕ ((Σn, L.Relations n) ⊕ ℕ)) → List (Σn, L.BoundedFormula α n)
189+
| Sum.inr (Sum.inr (n + 2))::l => ⟨n, falsum⟩::(listDecode l)
191190
| Sum.inl ⟨n₁, t₁⟩::Sum.inl ⟨n₂, t₂⟩::l =>
192-
if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by rw [h]) t₂)⟩ else default, l, by
193-
simp only [SizeOf.sizeOf, List._sizeOf_1, ← add_assoc]
194-
exact le_max_of_le_right le_add_self⟩
195-
| Sum.inr (Sum.inl ⟨n, R⟩)::Sum.inr (Sum.inr k)::l =>
196-
if h : ∀ i : Fin n, ((l.map Sum.getLeft?).get? i).join.isSome then
191+
(if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by rw [h]) t₂)⟩ else default)::(listDecode l)
192+
| Sum.inr (Sum.inl ⟨n, R⟩)::Sum.inr (Sum.inr k)::l => (
193+
if h : ∀ i : Fin n, ((l.map Sum.getLeft?).get? i).join.isSome then
197194
if h' : ∀ i, (Option.get _ (h i)).1 = k then
198195
⟨k, BoundedFormula.rel R fun i => Eq.mp (by rw [h' i]) (Option.get _ (h i)).2
199196
else default
200-
else default,
201-
l.drop n, le_max_of_le_right (le_add_left (le_add_left (List.drop_sizeOf_le _ _)))⟩
202-
| Sum.inr (Sum.inr 0)::l =>
203-
have : SizeOf.sizeOf
204-
(↑(listDecode l).2 : List ((Σk, L.Term (α ⊕ Fin k)) ⊕ ((Σn, L.Relations n) ⊕ ℕ))) <
205-
1 + (1 + 1) + SizeOf.sizeOf l := by
206-
refine lt_of_le_of_lt (listDecode l).2.2 (max_lt ?_ (Nat.lt_add_of_pos_left (by decide)))
207-
rw [add_assoc, lt_add_iff_pos_right, add_pos_iff]
208-
exact Or.inl zero_lt_two
209-
⟨sigmaImp (listDecode l).1 (listDecode (listDecode l).2).1,
210-
(listDecode (listDecode l).2).2,
211-
le_max_of_le_right
212-
(_root_.trans (listDecode _).2.2
213-
(max_le (le_add_right le_self_add)
214-
(_root_.trans (listDecode _).2.2 (max_le (le_add_right le_self_add) le_add_self))))⟩
215-
| Sum.inr (Sum.inr 1)::l =>
216-
⟨sigmaAll (listDecode l).1, (listDecode l).2,
217-
(listDecode l).2.2.trans (max_le_max le_rfl le_add_self)⟩
218-
| _ => ⟨default, [], le_max_left _ _⟩
219-
220-
set_option linter.deprecated false in
197+
else default)::(listDecode (l.drop n))
198+
| Sum.inr (Sum.inr 0)::l => if h : 2 ≤ (listDecode l).length
199+
then (sigmaImp (listDecode l)[0] (listDecode l)[1])::(drop 2 (listDecode l))
200+
else []
201+
| Sum.inr (Sum.inr 1)::l => if h : 1 ≤ (listDecode l).length
202+
then (sigmaAll (listDecode l)[0])::(drop 1 (listDecode l))
203+
else []
204+
| _ => []
205+
termination_by l => l.length
206+
221207
@[simp]
222208
theorem listDecode_encode_list (l : List (Σn, L.BoundedFormula α n)) :
223-
(listDecode (l.bind fun φ => φ.2.listEncode)).1 = l.headI := by
224-
suffices h : ∀ (φ : Σn, L.BoundedFormula α n) (l),
225-
(listDecode (listEncode φ.2 ++ l)).1 = φ ∧ (listDecode (listEncode φ.2 ++ l)).2.1 = l by
226-
induction' l with φ l _
227-
· rw [List.nil_bind]
209+
listDecode (l.bind (fun φ => φ.2.listEncode)) = l := by
210+
suffices h : ∀ (φ : Σn, L.BoundedFormula α n)
211+
(l' : List ((Σk, L.Term (α ⊕ Fin k)) ⊕ ((Σn, L.Relations n) ⊕ ℕ))),
212+
(listDecode (listEncode φ.2 ++ l')) = φ::(listDecode l') by
213+
induction' l with φ l ih
214+
· rw [List.bind_nil]
228215
simp [listDecode]
229-
· rw [cons_bind, (h φ _).1, headI_cons]
216+
· rw [bind_cons, h φ _, ih]
230217
rintro ⟨n, φ⟩
231218
induction' φ with _ _ _ _ φ_n φ_l φ_R ts _ _ _ ih1 ih2 _ _ ih <;> intro l
232219
· rw [listEncode, singleton_append, listDecode]
233-
simp only [eq_self_iff_true, heq_iff_eq, and_self_iff]
234220
· rw [listEncode, cons_append, cons_append, listDecode, dif_pos]
235221
· simp only [eq_mp_eq_cast, cast_eq, eq_self_iff_true, heq_iff_eq, and_self_iff, nil_append]
236222
· simp only [eq_self_iff_true, heq_iff_eq, and_self_iff]
@@ -242,9 +228,8 @@ theorem listDecode_encode_list (l : List (Σn, L.BoundedFormula α n)) :
242228
simp only [Option.join, map_append, map_map, Option.bind_eq_some, id, exists_eq_right,
243229
get?_eq_some, length_append, length_map, length_finRange]
244230
refine ⟨lt_of_lt_of_le i.2 le_self_add, ?_⟩
245-
rw [get_append, get_map]
246-
· simp only [Sum.getLeft?, get_finRange, Fin.eta, Function.comp_apply, eq_self_iff_true,
247-
heq_iff_eq, and_self_iff]
231+
rw [get_eq_getElem, getElem_append, getElem_map]
232+
· simp only [getElem_finRange, Fin.eta, Function.comp_apply, Sum.getLeft?]
248233
· simp only [length_map, length_finRange, is_lt]
249234
rw [dif_pos]
250235
swap
@@ -254,31 +239,30 @@ theorem listDecode_encode_list (l : List (Σn, L.BoundedFormula α n)) :
254239
· intro i
255240
obtain ⟨h1, h2⟩ := Option.eq_some_iff_get_eq.1 (h i)
256241
rw [h2]
257-
simp only [Sigma.mk.inj_iff, heq_eq_eq, rel.injEq, true_and]
242+
simp only [Option.join, eq_mp_eq_cast, cons.injEq, Sigma.mk.inj_iff, heq_eq_eq, rel.injEq,
243+
true_and]
258244
refine ⟨funext fun i => ?_, ?_⟩
259245
· obtain ⟨h1, h2⟩ := Option.eq_some_iff_get_eq.1 (h i)
260-
rw [eq_mp_eq_cast, cast_eq_iff_heq]
246+
rw [cast_eq_iff_heq]
261247
exact (Sigma.ext_iff.1 ((Sigma.eta (Option.get _ h1)).trans h2)).2
262248
rw [List.drop_append_eq_append_drop, length_map, length_finRange, Nat.sub_self, drop,
263249
drop_eq_nil_of_le, nil_append]
264250
rw [length_map, length_finRange]
265-
· rw [listEncode, List.append_assoc, cons_append, listDecode]
266-
simp only [] at *
267-
rw [(ih1 _).1, (ih1 _).2, (ih2 _).1, (ih2 _).2, sigmaImp]
268-
simp only [dite_true]
269-
exact ⟨rfl, trivial⟩
270-
· rw [listEncode, cons_append, listDecode]
271-
simp only
272-
simp only [] at *
273-
rw [(ih _).1, (ih _).2, sigmaAll]
274-
exact ⟨rfl, rfl⟩
251+
· simp only [] at *
252+
rw [listEncode, List.append_assoc, cons_append, listDecode]
253+
simp only [ih1, ih2, length_cons, le_add_iff_nonneg_left, _root_.zero_le, ↓reduceDIte,
254+
getElem_cons_zero, getElem_cons_succ, sigmaImp_apply, drop_succ_cons, drop_zero]
255+
· simp only [] at *
256+
rw [listEncode, cons_append, listDecode]
257+
simp only [ih, length_cons, le_add_iff_nonneg_left, _root_.zero_le, ↓reduceDIte,
258+
getElem_cons_zero, sigmaAll_apply, drop_succ_cons, drop_zero]
275259

276260
/-- An encoding of bounded formulas as lists. -/
277261
@[simps]
278262
protected def encoding : Encoding (Σn, L.BoundedFormula α n) where
279263
Γ := (Σk, L.Term (α ⊕ Fin k)) ⊕ ((Σn, L.Relations n) ⊕ ℕ)
280264
encode φ := φ.2.listEncode
281-
decode l := (listDecode l).1
265+
decode l := (listDecode l)[0]?
282266
decode_encode φ := by
283267
have h := listDecode_encode_list [φ]
284268
rw [bind_singleton] at h

0 commit comments

Comments
 (0)