Skip to content

Commit 1bcc29b

Browse files
committed
apply suggestion
1 parent 9a10189 commit 1bcc29b

2 files changed

Lines changed: 92 additions & 112 deletions

File tree

Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean

Lines changed: 18 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ public import Mathlib.ModelTheory.Arithmetic.Presburger.Basic
99
public import Mathlib.ModelTheory.Arithmetic.Presburger.Semilinear.Basic
1010
public import Mathlib.ModelTheory.Definability
1111

12-
import Mathlib.Algebra.GCDMonoid.Finset
13-
import Mathlib.Algebra.GCDMonoid.Nat
1412
import Mathlib.Algebra.Group.Submonoid.Finsupp
15-
import Mathlib.LinearAlgebra.Dimension.Basic
1613
import Mathlib.LinearAlgebra.Matrix.Notation
1714

1815
/-!
@@ -39,13 +36,13 @@ definable.
3936
* [Samuel Eilenberg and M. P. Schützenberger, *Rational Sets in Commutative Monoids*][eilenberg1969]
4037
-/
4138

42-
@[expose] public section
39+
public section
4340

44-
variable {α : Type*} [Fintype α] {s : Set (α → ℕ)} {A : Set ℕ}
41+
variable {α : Type*} {s : Set (α → ℕ)} {A : Set ℕ}
4542

46-
open Set Submodule FirstOrder Language
43+
open Set FirstOrder Language
4744

48-
theorem IsLinearSet.definable (hs : IsLinearSet s) : A.Definable presburger s := by
45+
theorem IsLinearSet.definable [Finite α] (hs : IsLinearSet s) : A.Definable presburger s := by
4946
rw [isLinearSet_iff] at hs
5047
rcases hs with ⟨v, t, rfl⟩
5148
refine ⟨Formula.iExs t (Formula.iInf fun i : α =>
@@ -64,7 +61,8 @@ theorem IsLinearSet.definable (hs : IsLinearSet s) : A.Definable presburger s :=
6461
congr! 1 with i
6562
simp
6663

67-
theorem IsSemilinearSet.definable (hs : IsSemilinearSet s) : A.Definable presburger s := by
64+
theorem IsSemilinearSet.definable [Finite α] (hs : IsSemilinearSet s) :
65+
A.Definable presburger s := by
6866
rw [isSemilinearSet_iff] at hs
6967
rcases hs with ⟨S, hS, rfl⟩
7068
choose φ hφ using fun s : S => (hS s.1 s.2).definable
@@ -76,13 +74,12 @@ theorem IsSemilinearSet.definable (hs : IsSemilinearSet s) : A.Definable presbur
7674

7775
namespace FirstOrder.Language.presburger
7876

79-
lemma term_realize_eq_add_dotProduct (t : presburger[[A]].Term α) :
77+
lemma term_realize_eq_add_dotProduct [Fintype α] (t : presburger[[A]].Term α) :
8078
∃ (k : ℕ) (u : α → ℕ), ∀ (v : α → ℕ), t.realize v = k + u ⬝ᵥ v := by
8179
classical
8280
induction t with simp only [Term.realize]
8381
| var i =>
84-
refine ⟨0, Pi.single i 1, ?_⟩
85-
simp
82+
exact ⟨0, Pi.single i 1, by simp⟩
8683
| @func l f ts ih =>
8784
cases f with
8885
| inl f =>
@@ -105,13 +102,15 @@ lemma term_realize_eq_add_dotProduct (t : presburger[[A]].Term α) :
105102
cases l with
106103
| zero =>
107104
refine ⟨f, 0, fun v => ?_⟩
108-
rw [withConstants_funMap_sumInr]
109-
simp only [constantsOn_Functions, constantsOnFunc.eq_1, coe_con, zero_dotProduct, add_zero]
105+
rw [withConstants_funMap_sumInr, zero_dotProduct, add_zero]
110106
rfl
111107
| succ => nomatch f
112108

109+
variable [Finite α]
110+
113111
lemma isSemilinearSet_boundedFormula_realize {n} (φ : presburger[[A]].BoundedFormula α n) :
114112
IsSemilinearSet {v : α ⊕ Fin n → ℕ | φ.Realize (v ∘ Sum.inl) (v ∘ Sum.inr)} := by
113+
haveI := Fintype.ofFinite α
115114
induction φ with simp only [BoundedFormula.Realize]
116115
| equal t₁ t₂ =>
117116
rcases term_realize_eq_add_dotProduct t₁ with ⟨k₁, u₁, ht₁⟩
@@ -156,109 +155,16 @@ theorem definable₁_iff_ultimately_periodic {s : Set ℕ} :
156155
rw [Definable₁, definable_iff_isSemilinearSet,
157156
← isSemilinearSet_image_iff (LinearEquiv.funUnique (Fin 1) ℕ ℕ), ← preimage_setOf_eq]
158157
simp only [LinearEquiv.funUnique_apply, Function.eval, Fin.default_eq_zero, setOf_mem_eq]
159-
rw [image_preimage_eq s fun x => ⟨![x], rfl⟩]
160-
constructor
161-
· intro hs
162-
apply IsSemilinearSet.isProperSemilinearSet at hs
163-
rw [isProperSemilinearSet_iff] at hs
164-
rcases hs with ⟨S, hS, rfl⟩
165-
replace hS : ∀ t ∈ S, ∃ k, ∃ p > 0, ∀ x ≥ k, x ∈ t ↔ x + p ∈ t := by
166-
intro t ht
167-
apply hS at ht
168-
rw [isProperLinearSet_iff] at ht
169-
rcases ht with ⟨a, t, ht, rfl⟩
170-
have hcard : t.card ≤ 1 := by simpa [CommSemiring.rank_self] using ht.cardinal_le_rank
171-
simp_rw [Finset.card_le_one_iff_subset_singleton, Finset.subset_singleton_iff] at hcard
172-
rcases hcard with ⟨b, (rfl | rfl)⟩
173-
· refine ⟨a + 1, 1, zero_lt_one, fun x hx => ?_⟩
174-
simp [(Nat.lt_of_succ_le hx).ne', (Nat.lt_of_succ_le (Nat.le_succ_of_le hx)).ne']
175-
· have hb : b ≠ 0 := by simpa [ne_comm] using ht.zero_notMem_image
176-
rw [Nat.ne_zero_iff_zero_lt] at hb
177-
refine ⟨a, b, hb, fun x hx => ?_⟩
178-
simp only [Finset.coe_singleton, mem_vadd_set, SetLike.mem_coe,
179-
AddSubmonoid.mem_closure_singleton, smul_eq_mul, vadd_eq_add, exists_exists_eq_and]
180-
constructor
181-
· rintro ⟨x, rfl⟩
182-
refine ⟨x + 1, ?_⟩
183-
simp [add_one_mul, add_assoc]
184-
· rintro ⟨y, heq⟩
185-
cases y with
186-
| zero =>
187-
rw [zero_mul, add_zero] at heq
188-
simp only [heq, ge_iff_le, add_le_iff_nonpos_right, nonpos_iff_eq_zero] at hx
189-
simp [hx] at hb
190-
| succ y =>
191-
rw [add_one_mul, ← add_assoc, add_right_cancel_iff] at heq
192-
exact ⟨y, heq⟩
193-
choose! k p hS hS' using hS
194-
refine ⟨S.sup k, S.lcm p, ?_, fun x hx => ?_⟩
195-
· rw [gt_iff_lt, Nat.pos_iff_ne_zero, ne_eq]
196-
simpa [Finset.lcm_eq_zero_iff, ← Nat.pos_iff_ne_zero]
197-
· simp only [ge_iff_le, Finset.sup_le_iff] at hx
198-
refine exists_congr fun t => and_congr_right fun ht => ?_
199-
have hpt : p t ∣ S.lcm p := Finset.dvd_lcm ht
200-
rw [dvd_iff_exists_eq_mul_left] at hpt
201-
rcases hpt with ⟨m, hpt⟩
202-
rw [hpt]
203-
clear hpt
204-
induction m with
205-
| zero => simp
206-
| succ m ih =>
207-
simp [← ih, Nat.succ_mul, ← add_assoc,
208-
← hS' t ht (x + m * p t) (le_add_of_le_left (hx t ht))]
209-
· intro ⟨k, p, hp, hs⟩
210-
have h₁ : {x ∈ s | x < k}.Finite := (Set.finite_lt_nat k).subset (sep_subset_setOf _ _)
211-
have h₂ : {x ∈ s | k ≤ x ∧ x < k + p}.Finite :=
212-
(Set.finite_Ico k (k + p)).subset (sep_subset_setOf _ _)
213-
convert (IsSemilinearSet.of_finite h₁).union (.add (.of_finite h₂) (.closure_finset {p}))
214-
ext x
215-
simp only [sep_and, Finset.coe_singleton, mem_union, mem_setOf_eq, mem_add, mem_inter_iff,
216-
SetLike.mem_coe, AddSubmonoid.mem_closure_singleton, smul_eq_mul, exists_exists_eq_and]
217-
constructor
218-
· intro hx
219-
by_cases hx' : x < k
220-
· exact Or.inl ⟨hx, hx'⟩
221-
· rw [not_lt] at hx'
222-
refine Or.inr ⟨k + (x - k) % p, ⟨⟨?_1, ?_2⟩, ?_1, ?_3⟩, (x - k) / p, ?_4⟩
223-
· rw [← add_tsub_cancel_of_le hx', ← Nat.mod_add_div' (x - k) p, ← add_assoc] at hx
224-
generalize (x - k) / p = m at hx
225-
induction m with
226-
| zero => simpa using hx
227-
| succ m ih =>
228-
refine ih ?_
229-
rwa [hs _ (Nat.le_add_right_of_le (Nat.le_add_right _ _)), add_assoc, ← Nat.add_one_mul]
230-
· apply Nat.le_add_right
231-
· apply Nat.add_lt_add_left (Nat.mod_lt _ hp)
232-
· rw [add_assoc, Nat.mod_add_div', add_tsub_cancel_of_le hx']
233-
· rintro (⟨hx, hx'⟩ | ⟨x, ⟨⟨hx, hx'⟩, _⟩, m, rfl⟩)
234-
· exact hx
235-
· induction m with
236-
| zero => simpa
237-
| succ m ih =>
238-
rw [hs _ (le_add_right hx')] at ih
239-
rwa [Nat.add_one_mul, ← add_assoc]
158+
rw [image_preimage_eq s fun x => ⟨![x], rfl⟩, Nat.isSemilinearSet_iff_ultimately_periodic]
240159

241160
/-- The graph of multiplication is not Presburger definable in `ℕ`. -/
242-
theorem mul_not_definable :
243-
¬ A.Definable presburger {v : Fin 3 → ℕ | v 0 = v 1 * v 2} := by
161+
theorem mul_not_definable : ¬ A.Definable presburger {v : Fin 3 → ℕ | v 0 = v 1 * v 2} := by
244162
intro hmul
245163
have hsqr : A.Definable₁ presburger {x * x | x : ℕ} := by
246-
rcases hmul with ⟨φ, hφ⟩
247-
exists Formula.iExs (Fin 1) (φ.subst ![Term.var (.inl 0), Term.var (.inr 0), Term.var (.inr 0)])
248-
simp only [setOf] at hφ
249-
ext x
250-
simp only [Fin.isValue, mem_setOf_eq, Formula.Realize, BoundedFormula.realize_iExs,
251-
BoundedFormula.realize_subst]
252-
constructor
253-
· intro ⟨y, h⟩
254-
refine ⟨![y], ?_⟩
255-
rw [← Formula.Realize, ← hφ]
256-
simp [h]
257-
· intro ⟨v, h⟩
258-
rw [← Formula.Realize, ← hφ] at h
259-
simp only [Fin.isValue, Matrix.cons_val_zero, Term.realize_var, Sum.elim_inl,
260-
Matrix.cons_val_one, Sum.elim_inr, Matrix.cons_val] at h
261-
exact ⟨v 0, h.symm⟩
164+
rw [Definable₁]
165+
convert (hmul.preimage_comp (β := Fin 2) ![0, 1, 1]).image_comp ![0]
166+
ext
167+
simpa [funext_iff, Fin.exists_fin_succ_pi] using exists_congr fun _ => Eq.comm
262168
rw [definable₁_iff_ultimately_periodic] at hsqr
263169
rcases hsqr with ⟨k, p, hp, h⟩
264170
specialize h ((max k p) * (max k p)) ((Nat.le_mul_self _).trans' (le_max_left _ _))

Mathlib/ModelTheory/Arithmetic/Presburger/Semilinear/Defs.lean

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ module
88
public import Mathlib.GroupTheory.Finiteness
99
public import Mathlib.LinearAlgebra.LinearIndependent.Defs
1010

11+
import Mathlib.Algebra.GCDMonoid.Finset
12+
import Mathlib.Algebra.GCDMonoid.Nat
13+
import Mathlib.LinearAlgebra.Dimension.Basic
14+
1115
/-!
1216
# Linear and semilinear sets
1317
@@ -31,6 +35,8 @@ which are linear sets with linearly independent submonoid generators (periods).
3135
- `IsSemilinearSet` is closed under union, projection, set addition and additive closure.
3236
- `IsSemilinearSet.isProperSemilinearSet`: every semilinear set is a finite union of proper linear
3337
sets.
38+
- `Nat.isSemilinearSet_iff_ultimately_periodic`: A set of `ℕ` is semilinear if and only if it is
39+
ultimately periodic, i.e. periodic after some number `k`.
3440
3541
## Naming convention
3642
@@ -379,3 +385,71 @@ theorem IsSemilinearSet.isProperSemilinearSet [IsCancelAdd M] (hs : IsSemilinear
379385
rcases hs with ⟨S, hS, hS', rfl⟩
380386
simp_rw [sUnion_eq_biUnion]
381387
exact IsProperSemilinearSet.biUnion hS fun s hs => (hS' s hs).isProperSemilinearSet
388+
389+
390+
391+
/-- A set of `ℕ` is semilinear if and only if it is ultimately periodic, i.e. periodic after some
392+
number `k`. -/
393+
theorem Nat.isSemilinearSet_iff_ultimately_periodic {s : Set ℕ} :
394+
IsSemilinearSet s ↔ ∃ k, ∃ p > 0, ∀ x ≥ k, x ∈ s ↔ x + p ∈ s := by
395+
constructor
396+
· intro hs
397+
apply IsSemilinearSet.isProperSemilinearSet at hs
398+
rw [isProperSemilinearSet_iff] at hs
399+
rcases hs with ⟨S, hS, rfl⟩
400+
replace hS : ∀ t ∈ S, ∃ k, ∃ p > 0, ∀ x ≥ k, x ∈ t ↔ x + p ∈ t := by
401+
intro t ht
402+
apply hS at ht
403+
rw [isProperLinearSet_iff] at ht
404+
rcases ht with ⟨a, t, ht, rfl⟩
405+
have hcard : t.card ≤ 1 := by simpa [CommSemiring.rank_self] using ht.cardinal_le_rank
406+
simp_rw [Finset.card_le_one_iff_subset_singleton, Finset.subset_singleton_iff] at hcard
407+
rcases hcard with ⟨b, (rfl | rfl)⟩
408+
· refine ⟨a + 1, 1, zero_lt_one, fun x hx => ?_⟩
409+
simp [(by grind : x ≠ a), (by grind : x + 1 ≠ a)]
410+
· have hb : b ≠ 0 := by simpa [ne_comm] using ht.zero_notMem_image
411+
rw [Nat.ne_zero_iff_zero_lt] at hb
412+
refine ⟨a, b, hb, fun x hx => ?_⟩
413+
simp only [Finset.coe_singleton, mem_vadd_set, SetLike.mem_coe,
414+
AddSubmonoid.mem_closure_singleton, smul_eq_mul, vadd_eq_add, exists_exists_eq_and]
415+
constructor
416+
· rintro ⟨x, rfl⟩
417+
exact ⟨x + 1, by grind⟩
418+
· rintro ⟨y, heq⟩
419+
cases y with
420+
| zero => exact ⟨0, by grind⟩
421+
| succ y => exact ⟨y, by grind⟩
422+
choose! k p hS hS' using hS
423+
refine ⟨S.sup k, S.lcm p, ?_, fun x hx => ?_⟩
424+
· grind [Finset.lcm_eq_zero_iff]
425+
· simp only [mem_sUnion, SetLike.mem_coe]
426+
refine exists_congr fun t => and_congr_right fun ht => ?_
427+
have hpt : p t ∣ S.lcm p := Finset.dvd_lcm ht
428+
rw [dvd_iff_exists_eq_mul_left] at hpt
429+
rcases hpt with ⟨m, hpt⟩
430+
rw [hpt]
431+
clear hpt
432+
induction m with grind [Finset.sup_le_iff]
433+
· intro ⟨k, p, hp, hs⟩
434+
have h₁ : {x ∈ s | x < k}.Finite := (Set.finite_lt_nat k).subset (sep_subset_setOf _ _)
435+
have h₂ : {x ∈ s | k ≤ x ∧ x < k + p}.Finite :=
436+
(Set.finite_Ico k (k + p)).subset (sep_subset_setOf _ _)
437+
convert (IsSemilinearSet.of_finite h₁).union (.add (.of_finite h₂) (.closure_finset {p}))
438+
ext x
439+
simp only [sep_and, Finset.coe_singleton, mem_union, mem_setOf_eq, mem_add, mem_inter_iff,
440+
SetLike.mem_coe, AddSubmonoid.mem_closure_singleton, smul_eq_mul, exists_exists_eq_and]
441+
constructor
442+
· intro hx
443+
by_cases hx' : x < k
444+
· exact Or.inl ⟨hx, hx'⟩
445+
· rw [not_lt] at hx'
446+
refine Or.inr ⟨k + (x - k) % p, ⟨⟨?_1, ?_2⟩, ?_1, ?_3⟩, (x - k) / p, ?_4⟩
447+
· rw [← add_tsub_cancel_of_le hx', ← Nat.mod_add_div' (x - k) p, ← add_assoc] at hx
448+
generalize (x - k) / p = m at hx
449+
induction m with grind
450+
· grind
451+
· exact Nat.add_lt_add_left (Nat.mod_lt _ hp) _
452+
· rw [add_assoc, Nat.mod_add_div', add_tsub_cancel_of_le hx']
453+
· rintro (⟨hx, hx'⟩ | ⟨x, ⟨⟨hx, hx'⟩, _⟩, m, rfl⟩)
454+
· exact hx
455+
· induction m with grind

0 commit comments

Comments
 (0)