Skip to content

Commit fb7b73b

Browse files
committed
update
1 parent 8bd409f commit fb7b73b

1 file changed

Lines changed: 4 additions & 340 deletions

File tree

Mathlib/ModelTheory/Arithmetic/Presburger/Definability.lean

Lines changed: 4 additions & 340 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Mathlib.Data.Pi.Interval
1414
import Mathlib.Data.Rat.Floor
1515
import Mathlib.LinearAlgebra.Matrix.ToLin
1616
import Mathlib.ModelTheory.Arithmetic.Presburger.Basic
17+
import Mathlib.ModelTheory.Arithmetic.Presburger.Semilinear.Basic
1718
import Mathlib.ModelTheory.Definability
1819
import Mathlib.RingTheory.Localization.Module
1920

@@ -62,40 +63,6 @@ open Pointwise Submodule Matrix
6263

6364
variable {v : α → ℕ} {s s₁ s₂ : Set (α → ℕ)}
6465

65-
/-- A set is linear if it is a finitely generated `ℕ`-submodule added by a single vector `v`. -/
66-
def Linear (s : Set (α → ℕ)) :=
67-
∃ (v : α → ℕ) (t : Finset (α → ℕ)), s = v +ᵥ (span ℕ (t : Set (α → ℕ)) : Set (α → ℕ))
68-
69-
theorem Linear.singleton (v) : ({v} : Set (α → ℕ)).Linear :=
70-
⟨v, ∅, by simp⟩
71-
72-
theorem Linear.span_finset (s : Finset (α → ℕ)) : (span ℕ (s : Set (α → ℕ)) : Set (α → ℕ)).Linear :=
73-
0, s, by simp⟩
74-
75-
theorem Linear.univ [Fintype α] : (univ : Set (α → ℕ)).Linear := by
76-
classical
77-
convert span_finset ((Finset.univ : Finset α).image (Pi.basisFun ℕ α))
78-
rw [← top_coe (R := ℕ), ← Basis.span_eq (Pi.basisFun ℕ α)]
79-
simp [-Basis.span_eq, Pi.basisFun]
80-
81-
theorem Linear.vadd (hs : s.Linear) : (v +ᵥ s).Linear := by
82-
rcases hs with ⟨u, t, rfl⟩
83-
rw [vadd_vadd]
84-
exact ⟨v +ᵥ u, t, rfl⟩
85-
86-
theorem Linear.add (hs₁ : s₁.Linear) (hs₂ : s₂.Linear) : (s₁ + s₂).Linear := by
87-
classical
88-
rcases hs₁ with ⟨v, t₁, rfl⟩
89-
rcases hs₂ with ⟨u, t₂, rfl⟩
90-
rw [vadd_add_vadd, ← coe_sup, ← span_union, ← Finset.coe_union]
91-
exact ⟨v + u, t₁ ∪ t₂, rfl⟩
92-
93-
theorem Linear.image (hs : s.Linear) (f : (α → ℕ) →ₗ[ℕ] (β → ℕ)) : (f '' s).Linear := by
94-
classical
95-
rcases hs with ⟨v, t, rfl⟩
96-
refine ⟨f v, t.image f, ?_⟩
97-
simp [image_vadd_distrib]
98-
9966
/-- A verison of *Gordan's lemma*: the solution of a homogeneous linear Diophantine equation
10067
`A *ᵥ x = B *ᵥ x` is a linear set. -/
10168
theorem Linear.of_homogeneous_equation [Fintype β] (A B : Matrix α β ℕ) :
@@ -168,119 +135,6 @@ lemma Linear.iff_eq_setOf_vadd_mulVec :
168135
ext x
169136
simp [mem_vadd_set, ← range_mulVecLin]
170137

171-
/-- A set is semilinear if it is a finite union of linear sets. -/
172-
def Semilinear (s : Set (α → ℕ)) :=
173-
∃ (S : Finset (Set (α → ℕ))), (∀ t ∈ S, t.Linear) ∧ s = ⋃₀ S
174-
175-
theorem Linear.semilinear (h : s.Linear) : s.Semilinear :=
176-
⟨{s}, by simp [h], by simp⟩
177-
178-
theorem Semilinear.empty : (∅ : Set (α → ℕ)).Semilinear :=
179-
⟨∅, by simp, by simp⟩
180-
181-
theorem Semilinear.singleton (v) : ({v} : Set (α → ℕ)).Semilinear :=
182-
(Linear.singleton v).semilinear
183-
184-
theorem Semilinear.span_finset (s : Finset (α → ℕ)) :
185-
(span ℕ (s : Set (α → ℕ)) : Set (α → ℕ)).Semilinear :=
186-
(Linear.span_finset s).semilinear
187-
188-
theorem Semilinear.univ [Fintype α] : (univ : Set (α → ℕ)).Semilinear :=
189-
Linear.univ.semilinear
190-
191-
/-- Semilinear sets are closed under union. -/
192-
theorem Semilinear.union (hs₁ : s₁.Semilinear) (hs₂ : s₂.Semilinear) : (s₁ ∪ s₂).Semilinear := by
193-
classical
194-
rcases hs₁ with ⟨S₁, hS₁, rfl⟩
195-
rcases hs₂ with ⟨S₂, hS₂, rfl⟩
196-
rw [← sUnion_union, ← Finset.coe_union]
197-
refine ⟨S₁ ∪ S₂, ?_, rfl⟩
198-
intro s hs
199-
simp only [Finset.mem_union] at hs
200-
exact hs.elim (hS₁ s) (hS₂ s)
201-
202-
theorem Semilinear.sUnion_finset {S : Finset (Set (α → ℕ))} (hS : ∀ s ∈ S, s.Semilinear) :
203-
(⋃₀ (S : Set (Set (α → ℕ)))).Semilinear := by
204-
classical
205-
induction S using Finset.induction with
206-
| empty => simpa using empty
207-
| insert s S _ ih =>
208-
simp only [Finset.mem_insert, forall_eq_or_imp] at hS
209-
simpa using union hS.1 (ih hS.2)
210-
211-
theorem Semilinear.iUnion_fintype [Fintype ι] {s : ι → Set (α → ℕ)}
212-
(hs : ∀ i, (s i).Semilinear) : (⋃ i, s i).Semilinear := by
213-
classical
214-
rw [← sUnion_range, ← image_univ, ← Finset.coe_univ, ← Finset.coe_image]
215-
apply sUnion_finset
216-
simpa
217-
218-
theorem Semilinear.biUnion_finset {s : Finset ι} {t : ι → Set (α → ℕ)}
219-
(ht : ∀ i ∈ s, (t i).Semilinear) : (⋃ i ∈ s, t i).Semilinear := by
220-
classical
221-
simp_rw [← Finset.mem_coe, ← sUnion_image, ← Finset.coe_image]
222-
apply sUnion_finset
223-
simpa
224-
225-
theorem Semilinear.finset (s : Finset (α → ℕ)) : (s : Set (α → ℕ)).Semilinear := by
226-
rw [← biUnion_of_singleton (s : Set (α → ℕ))]
227-
simp_rw [Finset.mem_coe]
228-
apply biUnion_finset
229-
simp [singleton]
230-
231-
theorem Finite.semilinear (hs : s.Finite) : s.Semilinear := by
232-
rw [← hs.coe_toFinset]
233-
exact Semilinear.finset _
234-
235-
theorem Semilinear.vadd (hs : s.Semilinear) : (v +ᵥ s).Semilinear := by
236-
classical
237-
rcases hs with ⟨S, hS, rfl⟩
238-
refine ⟨S.image (v +ᵥ ·), ?_, ?_⟩
239-
· simp only [Finset.mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂]
240-
intro s hs
241-
exact (hS s hs).vadd
242-
· simp [vadd_set_sUnion, sUnion_eq_iUnion (s := v +ᵥ _), mem_vadd_set]
243-
244-
/-- Semilinear sets are closed under set addition. -/
245-
theorem Semilinear.add (hs₁ : s₁.Semilinear) (hs₂ : s₂.Semilinear) :
246-
(s₁ + s₂).Semilinear := by
247-
classical
248-
rcases hs₁ with ⟨S₁, hS₁, rfl⟩
249-
rcases hs₂ with ⟨S₂, hS₂, rfl⟩
250-
simp_rw [sUnion_add, add_sUnion, Finset.mem_coe]
251-
apply biUnion_finset
252-
intro s₁ hs₁
253-
apply biUnion_finset
254-
intro s₂ hs₂
255-
exact ((hS₁ s₁ hs₁).add (hS₂ s₂ hs₂)).semilinear
256-
257-
theorem Semilinear.image (hs : s.Semilinear) (f : (α → ℕ) →ₗ[ℕ] (β → ℕ)) : (f '' s).Semilinear := by
258-
classical
259-
rcases hs with ⟨S, hS, rfl⟩
260-
simp_rw [sUnion_eq_biUnion, Finset.mem_coe, image_iUnion]
261-
exact biUnion_finset fun s hs => ((hS s hs).image f).semilinear
262-
263-
theorem Semilinear.reindex (hs : s.Semilinear) (f : β → α) : ((· ∘ f) '' s).Semilinear :=
264-
hs.image (LinearMap.funLeft _ _ f)
265-
266-
/-- Semilinear sets are closed under projection. -/
267-
theorem Semilinear.proj {s : Set (α ⊕ β → ℕ)} (hs : s.Semilinear) :
268-
{x | ∃ y, Sum.elim x y ∈ s}.Semilinear := by
269-
convert hs.reindex Sum.inl
270-
ext x
271-
constructor
272-
· intro ⟨y, hy⟩
273-
refine ⟨Sum.elim x y, hy, ?_⟩
274-
rfl
275-
· simp only [mem_image, mem_setOf_eq, forall_exists_index, and_imp]
276-
rintro y hy rfl
277-
refine ⟨y ∘ Sum.inr, ?_⟩
278-
simp [hy]
279-
280-
theorem Semilinear.proj' {p : (α → ℕ) → (β → ℕ) → Prop} :
281-
{x | p (x ∘ Sum.inl) (x ∘ Sum.inr)}.Semilinear → {x | ∃ y, p x y}.Semilinear :=
282-
proj
283-
284138
/-- The solution of a linear Diophantine equation `u + A *ᵥ x = v + B *ᵥ x` is a semilinear set. -/
285139
theorem Semilinear.of_linear_equation [Fintype β] (u v : α → ℕ) (A B : Matrix α β ℕ) :
286140
{x | u + A *ᵥ x = v + B *ᵥ x}.Semilinear := by
@@ -384,196 +238,6 @@ theorem Semilinear.biInter_finset [Fintype α] {s : Finset ι} {t : ι → Set (
384238
apply sInter_finset
385239
simpa
386240

387-
lemma Linear.span (hs : s.Linear) : (span ℕ s : Set (α → ℕ)).Semilinear := by
388-
classical
389-
rcases hs with ⟨v, t, rfl⟩
390-
convert_to ({0} ∪ (v +ᵥ (span ℕ ({v} ∪ t) : Set (α → ℕ)))).Semilinear
391-
· ext x
392-
simp only [SetLike.mem_coe, mem_union, mem_singleton_iff]
393-
constructor
394-
· intro hx
395-
induction hx using span_induction with simp only [mem_vadd_set, SetLike.mem_coe] at *
396-
| mem x hx =>
397-
right
398-
rcases hx with ⟨x, hx, rfl⟩
399-
refine ⟨x, ?_, rfl⟩
400-
simp only [span_union]
401-
exact mem_sup_right hx
402-
| zero =>
403-
left
404-
trivial
405-
| add x y _ _ ih₁ ih₂ =>
406-
rcases ih₁ with rfl | ⟨x, hx, rfl⟩
407-
· simpa only [zero_add]
408-
· right
409-
rcases ih₂ with rfl | ⟨y, hy, rfl⟩
410-
· refine ⟨x, hx, ?_⟩
411-
simp
412-
· refine ⟨v + (x + y), add_mem (mem_span_of_mem ?_) (add_mem hx hy), ?_⟩
413-
· simp
414-
· simp only [vadd_eq_add]
415-
ring_nf
416-
| smul n x _ ih =>
417-
rcases ih with rfl | ⟨x, hx, rfl⟩
418-
· simp
419-
· rcases n with (_ | n)
420-
· simp
421-
· right
422-
refine ⟨n • v + (n + 1) • x,
423-
add_mem (smul_mem _ _ (mem_span_of_mem ?_)) (smul_mem _ _ hx), ?_⟩
424-
· simp
425-
· simp only [vadd_eq_add]
426-
ring_nf
427-
· rintro (hx | hx)
428-
· simp [hx]
429-
· simp only [mem_vadd_set, SetLike.mem_coe, span_union, mem_sup, mem_span_singleton] at hx
430-
rcases hx with ⟨_, ⟨_, ⟨n, rfl⟩, z, hz, rfl⟩, rfl⟩
431-
rw [vadd_eq_add, add_left_comm, ← vadd_eq_add v]
432-
refine add_mem (smul_mem _ _ (mem_span_of_mem ?_)) (mem_span_of_mem (vadd_mem_vadd_set hz))
433-
simp [mem_vadd_set]
434-
rw [← Finset.coe_singleton v, ← Finset.coe_union]
435-
exact (Semilinear.singleton 0).union (semilinear ⟨v, {v} ∪ t, rfl⟩)
436-
437-
/-- Semilinear sets are closed under `span ℕ` (additive closure). -/
438-
theorem Semilinear.span (hs : s.Semilinear) : (span ℕ s : Set (α → ℕ)).Semilinear := by
439-
classical
440-
rcases hs with ⟨S, hS, rfl⟩
441-
induction S using Finset.induction with
442-
| empty => simpa using singleton 0
443-
| insert s S _ ih =>
444-
simp only [Finset.mem_insert, forall_eq_or_imp] at hS
445-
simpa [span_union, coe_sup] using hS.1.span.add (ih hS.2)
446-
447-
/-- A linear set is proper if its `ℕ`-submodule generators (periods) are linear independent. -/
448-
def ProperLinear (s : Set (α → ℕ)) :=
449-
∃ (v : α → ℕ) (t : Finset (α → ℕ)),
450-
LinearIndepOn ℕ id (t : Set (α → ℕ)) ∧ s = v +ᵥ (span ℕ (t : Set (α → ℕ)) : Set (α → ℕ))
451-
452-
theorem ProperLinear.linear (hs : s.ProperLinear) : s.Linear := by
453-
rcases hs with ⟨v, t, _, rfl⟩
454-
exact ⟨v, t, rfl⟩
455-
456-
/-- A semilinear set is proper if it is a finite union of proper linear sets. -/
457-
def ProperSemilinear (s : Set (α → ℕ)) :=
458-
∃ (S : Finset (Set (α → ℕ))), (∀ t ∈ S, t.ProperLinear) ∧ s = ⋃₀ S
459-
460-
theorem ProperSemilinear.semilinear (hs : s.ProperSemilinear) : s.Semilinear := by
461-
rcases hs with ⟨S, hS, rfl⟩
462-
refine ⟨S, ?_, rfl⟩
463-
intro s hs
464-
exact (hS s hs).linear
465-
466-
theorem ProperLinear.proper_semilinear (hs : s.ProperLinear) : s.ProperSemilinear :=
467-
⟨{s}, by simp [hs], by simp⟩
468-
469-
theorem ProperSemilinear.empty : (∅ : Set (α → ℕ)).ProperSemilinear :=
470-
⟨∅, by simp, by simp⟩
471-
472-
theorem ProperSemilinear.union (hs₁ : s₁.ProperSemilinear) (hs₂ : s₂.ProperSemilinear) :
473-
(s₁ ∪ s₂).ProperSemilinear := by
474-
classical
475-
rcases hs₁ with ⟨S₁, hS₁, rfl⟩
476-
rcases hs₂ with ⟨S₂, hS₂, rfl⟩
477-
rw [← sUnion_union, ← Finset.coe_union]
478-
refine ⟨S₁ ∪ S₂, ?_, rfl⟩
479-
intro s hs
480-
simp only [Finset.mem_union] at hs
481-
exact hs.elim (hS₁ s) (hS₂ s)
482-
483-
theorem ProperSemilinear.sUnion_finset {S : Finset (Set (α → ℕ))}
484-
(hS : ∀ s ∈ S, s.ProperSemilinear) : (⋃₀ (S : Set (Set (α → ℕ)))).ProperSemilinear := by
485-
classical
486-
induction S using Finset.induction with
487-
| empty => simpa using empty
488-
| insert s S _ ih =>
489-
simp only [Finset.mem_insert, forall_eq_or_imp] at hS
490-
simpa using union hS.1 (ih hS.2)
491-
492-
theorem ProperSemilinear.iUnion_fintype [Fintype ι] {s : ι → Set (α → ℕ)}
493-
(hs : ∀ i, (s i).ProperSemilinear) : (⋃ i, s i).ProperSemilinear := by
494-
classical
495-
rw [← sUnion_range, ← image_univ, ← Finset.coe_univ, ← Finset.coe_image]
496-
apply sUnion_finset
497-
simpa
498-
499-
theorem ProperSemilinear.biUnion_finset {s : Finset ι} {t : ι → Set (α → ℕ)}
500-
(ht : ∀ i ∈ s, (t i).ProperSemilinear) : (⋃ i ∈ s, t i).ProperSemilinear := by
501-
classical
502-
simp_rw [← Finset.mem_coe, ← sUnion_image, ← Finset.coe_image]
503-
apply sUnion_finset
504-
simpa
505-
506-
lemma Linear.proper_semilinear [Fintype α] (hs : s.Linear) : s.ProperSemilinear := by
507-
classical
508-
rcases hs with ⟨v, t, rfl⟩
509-
induction hn : t.card using Nat.strong_induction_on generalizing v t with | h n ih
510-
subst hn
511-
by_cases hindep : LinearIndepOn ℕ id (t : Set (α → ℕ))
512-
· exact ProperLinear.proper_semilinear ⟨v, t, hindep, rfl⟩
513-
· have : ∃ (f g : (α → ℕ) → ℕ),
514-
∑ u ∈ t, f u • u = ∑ u ∈ t, g u • u ∧ ∃ u ∈ t, 0 < f u ∧ g u = 0 := by
515-
rw [not_linearIndepOn_finset_iffₛ] at hindep
516-
rcases hindep with ⟨f, g, heq, u, hu, hne⟩
517-
wlog h : g u < f u generalizing f g
518-
· exact this g f heq.symm hne.symm (lt_of_le_of_ne (le_of_not_gt h) hne)
519-
· refine ⟨Function.update f u (f u - g u), Function.update g u 0, ?_, u, hu, ?_, ?_⟩
520-
· rw [← Finset.sum_erase_add _ _ hu, ← Finset.sum_erase_add _ _ hu] at heq ⊢
521-
rw [← add_right_cancel_iff (a := g u • u), add_assoc, add_assoc]
522-
convert heq using 2
523-
· refine Finset.sum_congr rfl fun j hj => ?_
524-
simp only [Finset.mem_erase] at hj
525-
simp [hj.1]
526-
· rw [Function.update_self, id_eq, ← add_smul, tsub_add_cancel_of_le h.le]
527-
· refine Finset.sum_congr rfl fun j hj => ?_
528-
simp only [Finset.mem_erase] at hj
529-
simp [hj.1]
530-
· rw [Function.update_self, id_eq, zero_smul, zero_add]
531-
· rwa [Function.update_self, lt_tsub_iff_left_of_le h.le, add_zero]
532-
· rw [Function.update_self]
533-
rcases this with ⟨f, g, heq, u, hu, hfu, hgu⟩
534-
convert_to
535-
(⋃ w ∈ t, ⋃ k ∈ Finset.range (f w),
536-
(v + k • w) +ᵥ (Submodule.span ℕ (t.erase w : Set (α → ℕ)) : Set (α → ℕ))).ProperSemilinear
537-
· ext x
538-
simp only [mem_vadd_set, SetLike.mem_coe]
539-
constructor
540-
· rintro ⟨x, hx, rfl⟩
541-
rw [mem_span_finset] at hx
542-
rcases hx with ⟨h, hh, rfl⟩
543-
clear hh
544-
induction hn : h u using Nat.strong_induction_on generalizing h with | h n ih
545-
subst hn
546-
by_cases hh : ∀ w ∈ t, f w ≤ h w
547-
· convert ih (h u - f u) (tsub_lt_self (hfu.trans_le (hh u hu)) hfu)
548-
(h - f + g) (by simp [hgu]) using 1
549-
simp_rw [Pi.add_apply, Pi.sub_apply, add_smul, Finset.sum_add_distrib, ← heq,
550-
← Finset.sum_add_distrib, ← add_smul]
551-
congr 1
552-
refine Finset.sum_congr rfl fun w hw => ?_
553-
rw [tsub_add_cancel_of_le (hh w hw)]
554-
· simp only [not_forall, not_le] at hh
555-
rcases hh with ⟨w, hw, hhw⟩
556-
simp only [mem_iUnion, Finset.mem_range, mem_vadd_set, SetLike.mem_coe, vadd_eq_add]
557-
refine ⟨w, hw, h w, hhw, ∑ x ∈ t.erase w, h x • x,
558-
sum_mem fun x hx => (smul_mem _ _ (mem_span_of_mem hx)), ?_⟩
559-
rw [← Finset.sum_erase_add _ _ hw, ← add_assoc, add_right_comm]
560-
· simp only [mem_iUnion, Finset.mem_range, mem_vadd_set, SetLike.mem_coe, vadd_eq_add]
561-
rintro ⟨w, hw, k, hk, y, hy, rfl⟩
562-
refine ⟨k • w + y,
563-
add_mem (smul_mem _ _ (mem_span_of_mem hw)) ((span_mono (Finset.erase_subset w t)) hy),
564-
?_⟩
565-
rw [add_assoc]
566-
· exact ProperSemilinear.biUnion_finset fun w hw =>
567-
ProperSemilinear.biUnion_finset fun k hk =>
568-
ih _ (Finset.card_lt_card (Finset.erase_ssubset hw)) _ _ rfl
569-
570-
/-- The **proper decomposition** of semilinear sets: every semilinear set is a finite union of
571-
proper linear sets. -/
572-
theorem Semilinear.proper_semilinear [Fintype α] (hs : s.Semilinear) : s.ProperSemilinear := by
573-
rcases hs with ⟨S, hS, rfl⟩
574-
simp_rw [sUnion_eq_biUnion, Finset.mem_coe]
575-
exact ProperSemilinear.biUnion_finset fun s hs => (hS s hs).proper_semilinear
576-
577241
private def toRatVec : (α → ℕ) →ₗ[ℕ] (α → ℚ) :=
578242
LinearMap.compLeft (Nat.castAddMonoidHom ℚ).toNatLinearMap α
579243

@@ -965,8 +629,8 @@ theorem Linear.definable (hs : s.Linear) : A.Definable presburger s := by
965629
refine ⟨Formula.iExs t (Formula.iInf fun i : α =>
966630
(Term.var (Sum.inl i)).equal
967631
(Term.varsToConstants
968-
((v i : presburger.Term _) + presburger.finsum fun x : t =>
969-
x.1 i • (Term.var (Sum.inr (Sum.inr x)))))), ?_⟩
632+
((v i : presburger.Term _) + presburger.sum Finset.univ fun x : t =>
633+
x.1 i • Term.var (Sum.inr (Sum.inr x))))), ?_⟩
970634
ext x
971635
simpa [mem_vadd_set, mem_span_finset'] using exists_congr fun a =>
972636
funext_iff.trans <| forall_congr' fun b => Eq.comm.trans <|
@@ -1058,7 +722,7 @@ lemma boundedFormula_realize_semilinear {n} (φ : presburger[[A]].BoundedFormula
1058722
| inr i => fin_cases i; simp
1059723

1060724
lemma formula_realize_semilinear (φ : presburger[[A]].Formula α) :
1061-
(setOf φ.Realize).Semilinear := by
725+
(setOf φ.Realize : Set (α → ℕ)).Semilinear := by
1062726
convert (boundedFormula_realize_semilinear φ).reindex (Equiv.sumEmpty α (Fin 0)).symm
1063727
ext x
1064728
simp only [mem_setOf_eq, mem_image]

0 commit comments

Comments
 (0)