@@ -14,6 +14,7 @@ import Mathlib.Data.Pi.Interval
1414import Mathlib.Data.Rat.Floor
1515import Mathlib.LinearAlgebra.Matrix.ToLin
1616import Mathlib.ModelTheory.Arithmetic.Presburger.Basic
17+ import Mathlib.ModelTheory.Arithmetic.Presburger.Semilinear.Basic
1718import Mathlib.ModelTheory.Definability
1819import Mathlib.RingTheory.Localization.Module
1920
@@ -62,40 +63,6 @@ open Pointwise Submodule Matrix
6263
6364variable {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. -/
10168theorem 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. -/
285139theorem 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-
577241private 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
1060724lemma 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