Imports
module
public import Mathlib.ModelTheory.Arithmetic.Presburger.Semilinear.Defs
public import Mathlib.Tactic.Ring
public import Mathlib.LinearAlgebra.Dimension.Basic
public import Pdl.Semantics
public import Pdl.Vocab
public import PdlTestFree.Paths@[expose] public sectionSemilinearity of L α for programs over a single atomic program
For a test-free program α the set L α = {n | L α n} of possible execution lengths of α
(see PdlTestFree.Paths) is semilinear (L_isSemilinearSet); no assumption on the
vocabulary is needed for this.
Conversely, not every semilinear X ⊆ ℕ is L α for a test-free α with voc α = {a}:
a test-free α always admits some positive number of steps (L_pos), so ∅ and {0} are
not of this form, and if it admits 0 steps then it admits all multiples of some p > 0
(L_zero), so e.g. {0, 2} is not of this form either. These are the only obstructions:
exists_L_eq_iff characterises the sets L α as the nonempty semilinear sets X such that
0 ∈ X implies k * p ∈ X for all k, for some p > 0.
open Set Pointwise AddSubmonoidopen scoped FinsetL of compound programs as set operations
lemma L_atom_set (c : ℕ) : {n | L (·c) n} = {1} := c:ℕ⊢ {n | L (·c) n} = {1}
c:ℕn:ℕ⊢ n ∈ {n | L (·c) n} ↔ n ∈ {1}
All goals completed! 🐙lemma L_seq_set (α β : Program) : {n | L (α ;' β) n} = {n | L α n} + {n | L β n} := α:Programβ:Program⊢ {n | L (α;'β) n} = {n | L α n} + {n | L β n}
α:Programβ:Programn:ℕ⊢ n ∈ {n | L (α;'β) n} ↔ n ∈ {n | L α n} + {n | L β n}
α:Programβ:Programn:ℕ⊢ (∃ i j, L α i ∧ L β j ∧ n = i + j) ↔ ∃ x, L α x ∧ ∃ y, L β y ∧ x + y = n
α:Programβ:Programn:ℕ⊢ (∃ i j, L α i ∧ L β j ∧ n = i + j) → ∃ x, L α x ∧ ∃ y, L β y ∧ x + y = nα:Programβ:Programn:ℕ⊢ (∃ x, L α x ∧ ∃ y, L β y ∧ x + y = n) → ∃ i j, L α i ∧ L β j ∧ n = i + j
α:Programβ:Programn:ℕ⊢ (∃ i j, L α i ∧ L β j ∧ n = i + j) → ∃ x, L α x ∧ ∃ y, L β y ∧ x + y = n α:Programβ:Programi:ℕj:ℕhi:L α ihj:L β j⊢ ∃ x, L α x ∧ ∃ y, L β y ∧ x + y = i + j; All goals completed! 🐙
α:Programβ:Programn:ℕ⊢ (∃ x, L α x ∧ ∃ y, L β y ∧ x + y = n) → ∃ i j, L α i ∧ L β j ∧ n = i + j α:Programβ:Programi:ℕhi:L α ij:ℕhj:L β j⊢ ∃ i_1 j_1, L α i_1 ∧ L β j_1 ∧ i + j = i_1 + j_1; All goals completed! 🐙lemma L_union_set (α β : Program) : {n | L (α ⋓ β) n} = {n | L α n} ∪ {n | L β n} := α:Programβ:Program⊢ {n | L (α⋓β) n} = {n | L α n} ∪ {n | L β n}
α:Programβ:Programn:ℕ⊢ n ∈ {n | L (α⋓β) n} ↔ n ∈ {n | L α n} ∪ {n | L β n}
All goals completed! 🐙lemma L_star_set (α : Program) : {n | L (∗α) n} = (closure {n | L α n} : Set ℕ) := α:Program⊢ {n | L (∗α) n} = ↑(closure {n | L α n})
α:Programn:ℕ⊢ n ∈ {n | L (∗α) n} ↔ n ∈ ↑(closure {n | L α n})
α:Programn:ℕ⊢ (∃ l, (∀ i ∈ l, L α i) ∧ n = l.sum) ↔ n ∈ closure {n | L α n}
α:Programn:ℕ⊢ (∃ l, (∀ i ∈ l, L α i) ∧ n = l.sum) → n ∈ closure {n | L α n}α:Programn:ℕ⊢ n ∈ closure {n | L α n} → ∃ l, (∀ i ∈ l, L α i) ∧ n = l.sum
α:Programn:ℕ⊢ (∃ l, (∀ i ∈ l, L α i) ∧ n = l.sum) → n ∈ closure {n | L α n} α:Programl:List ℕhl:∀ i ∈ l, L α i⊢ l.sum ∈ closure {n | L α n}
All goals completed! 🐙
α:Programn:ℕ⊢ n ∈ closure {n | L α n} → ∃ l, (∀ i ∈ l, L α i) ∧ n = l.sum α:Programn:ℕh:n ∈ closure {n | L α n}⊢ ∃ l, (∀ i ∈ l, L α i) ∧ n = l.sum
α:Programl:List ℕhl:∀ y ∈ l, y ∈ {n | L α n}h:l.sum ∈ closure {n | L α n}⊢ ∃ l_1, (∀ i ∈ l_1, L α i) ∧ l.sum = l_1.sum
All goals completed! 🐙Every L α is semilinear
For any test-free program α the set L α is semilinear.
theorem L_isSemilinearSet : ∀ α : Program, α.testFree → IsSemilinearSet {n | L α n}
a✝:Formulahα:(?'a✝).testFree⊢ IsSemilinearSet {n | L (?'a✝) n} a✝:Formulahα:(?'a✝).testFree⊢ IsSemilinearSet {n | L (?'a✝) n} All goals completed! 🐙
c:ℕx✝:(·c).testFree⊢ IsSemilinearSet {n | L (·c) n} c:ℕx✝:(·c).testFree⊢ IsSemilinearSet {n | L (·c) n}
c:ℕx✝:(·c).testFree⊢ IsSemilinearSet {1}
simp All goals completed! 🐙
| α ;' β, hαβ => α:Programβ:Programhαβ:(α;'β).testFree⊢ IsSemilinearSet {n | L (α;'β) n} by α:Programβ:Programhαβ:(α;'β).testFree⊢ IsSemilinearSet {n | L (α;'β) n}
simp only [Program.testFree] at hαβ α:Programβ:Programhαβ:α.testFree ∧ β.testFree⊢ IsSemilinearSet {n | L (α;'β) n}
rw [L_seq_set α:Programβ:Programhαβ:α.testFree ∧ β.testFree⊢ IsSemilinearSet ({n | L α n} + {n | L β n})] α:Programβ:Programhαβ:α.testFree ∧ β.testFree⊢ IsSemilinearSet ({n | L α n} + {n | L β n})
exact (L_isSemilinearSet α hαβ.1).add (L_isSemilinearSet β hαβ.2) All goals completed! 🐙
| α ⋓ β, hαβ => α:Programβ:Programhαβ:(α⋓β).testFree⊢ IsSemilinearSet {n | L (α⋓β) n} by α:Programβ:Programhαβ:(α⋓β).testFree⊢ IsSemilinearSet {n | L (α⋓β) n}
simp only [Program.testFree] at hαβ α:Programβ:Programhαβ:α.testFree ∧ β.testFree⊢ IsSemilinearSet {n | L (α⋓β) n}
rw [L_union_set α:Programβ:Programhαβ:α.testFree ∧ β.testFree⊢ IsSemilinearSet ({n | L α n} ∪ {n | L β n})] α:Programβ:Programhαβ:α.testFree ∧ β.testFree⊢ IsSemilinearSet ({n | L α n} ∪ {n | L β n})
exact (L_isSemilinearSet α hαβ.1).union (L_isSemilinearSet β hαβ.2) All goals completed! 🐙
| ∗α, hα => α:Programhα:(∗α).testFree⊢ IsSemilinearSet {n | L (∗α) n} by α:Programhα:(∗α).testFree⊢ IsSemilinearSet {n | L (∗α) n}
simp only [Program.testFree] at hα α:Programhα:α.testFree⊢ IsSemilinearSet {n | L (∗α) n}
rw [L_star_set α:Programhα:α.testFree⊢ IsSemilinearSet ↑(closure {n | L α n})] α:Programhα:α.testFree⊢ IsSemilinearSet ↑(closure {n | L α n})
exact (L_isSemilinearSet α hα).closure All goals completed! 🐙Two obstructions to the converse
A test-free program admits some positive number of steps.
theorem L_pos : ∀ α : Program, α.testFree → ∃ n, 0 < n ∧ L α n
| ?'_, hα => a✝:Formulahα:(?'a✝).testFree⊢ ∃ n, 0 < n ∧ L (?'a✝) n by a✝:Formulahα:(?'a✝).testFree⊢ ∃ n, 0 < n ∧ L (?'a✝) n simp only [Program.testFree] at hα All goals completed! 🐙
| ·_, _ => ⟨1, one_pos, rfl⟩
| α ;' β, hαβ => α:Programβ:Programhαβ:(α;'β).testFree⊢ ∃ n, 0 < n ∧ L (α;'β) n by α:Programβ:Programhαβ:(α;'β).testFree⊢ ∃ n, 0 < n ∧ L (α;'β) n
simp only [Program.testFree] at hαβ α:Programβ:Programhαβ:α.testFree ∧ β.testFree⊢ ∃ n, 0 < n ∧ L (α;'β) n
obtain ⟨i, hi, hLi⟩ := L_pos α hαβ.1 α:Programβ:Programhαβ:α.testFree ∧ β.testFreei:ℕhi:0 < ihLi:L α i⊢ ∃ n, 0 < n ∧ L (α;'β) n
obtain ⟨j, hj, hLj⟩ := L_pos β hαβ.2 α:Programβ:Programhαβ:α.testFree ∧ β.testFreei:ℕhi:0 < ihLi:L α ij:ℕhj:0 < jhLj:L β j⊢ ∃ n, 0 < n ∧ L (α;'β) n
exact ⟨i + j, by α:Programβ:Programhαβ:α.testFree ∧ β.testFreei:ℕhi:0 < ihLi:L α ij:ℕhj:0 < jhLj:L β j⊢ 0 < i + j omega All goals completed! 🐙, i, j, hLi, hLj, rfl⟩
| α ⋓ β, hαβ => α:Programβ:Programhαβ:(α⋓β).testFree⊢ ∃ n, 0 < n ∧ L (α⋓β) n by α:Programβ:Programhαβ:(α⋓β).testFree⊢ ∃ n, 0 < n ∧ L (α⋓β) n
simp only [Program.testFree] at hαβ α:Programβ:Programhαβ:α.testFree ∧ β.testFree⊢ ∃ n, 0 < n ∧ L (α⋓β) n
obtain ⟨i, hi, hLi⟩ := L_pos α hαβ.1 α:Programβ:Programhαβ:α.testFree ∧ β.testFreei:ℕhi:0 < ihLi:L α i⊢ ∃ n, 0 < n ∧ L (α⋓β) n
exact ⟨i, hi, Or.inl hLi⟩ All goals completed! 🐙
| ∗α, hα => α:Programhα:(∗α).testFree⊢ ∃ n, 0 < n ∧ L (∗α) n by α:Programhα:(∗α).testFree⊢ ∃ n, 0 < n ∧ L (∗α) n
simp only [Program.testFree] at hα α:Programhα:α.testFree⊢ ∃ n, 0 < n ∧ L (∗α) n
obtain ⟨i, hi, hLi⟩ := L_pos α hα α:Programhα:α.testFreei:ℕhi:0 < ihLi:L α i⊢ ∃ n, 0 < n ∧ L (∗α) n
exact ⟨i, hi, [i], by α:Programhα:α.testFreei:ℕhi:0 < ihLi:L α i⊢ ∀ i_1 ∈ [i], L α i_1 simpa All goals completed! 🐙, by α:Programhα:α.testFreei:ℕhi:0 < ihLi:L α i⊢ i = [i].sum simp All goals completed! 🐙⟩If a test-free program admits 0 steps, then it admits all multiples of some p > 0.
theorem L_zero : ∀ α : Program, α.testFree → L α 0 → ∃ p, 0 < p ∧ ∀ k, L α (k * p)
| ?'_, hα, _ => a✝:Formulahα:(?'a✝).testFreex✝:L (?'a✝) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (?'a✝) (k * p) by a✝:Formulahα:(?'a✝).testFreex✝:L (?'a✝) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (?'a✝) (k * p) simp only [Program.testFree] at hα All goals completed! 🐙
| ·c, _, h0 => c:ℕx✝:(·c).testFreeh0:L (·c) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (·c) (k * p) by c:ℕx✝:(·c).testFreeh0:L (·c) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (·c) (k * p) simp [L] at h0 All goals completed! 🐙
| α ;' β, hαβ, h0 => α:Programβ:Programhαβ:(α;'β).testFreeh0:L (α;'β) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α;'β) (k * p) by α:Programβ:Programhαβ:(α;'β).testFreeh0:L (α;'β) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α;'β) (k * p)
simp only [Program.testFree] at hαβ α:Programβ:Programhαβ:α.testFree ∧ β.testFreeh0:L (α;'β) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α;'β) (k * p)
obtain ⟨i, j, hi, hj, hij⟩ := h0 α:Programβ:Programhαβ:α.testFree ∧ β.testFreei:ℕj:ℕhi:L α ihj:L β jhij:0 = i + j⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α;'β) (k * p)
obtain ⟨rfl, rfl⟩ : i = 0 ∧ j = 0 := by α:Programβ:Programhαβ:α.testFree ∧ β.testFreei:ℕj:ℕhi:L α ihj:L β jhij:0 = i + j⊢ i = 0 ∧ j = 0 omega α:Programβ:Programhαβ:α.testFree ∧ β.testFreehi:L α 0hj:L β 0hij:0 = 0 + 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α;'β) (k * p)
obtain ⟨p, hp, hLp⟩ := L_zero α hαβ.1 hi α:Programβ:Programhαβ:α.testFree ∧ β.testFreehi:L α 0hj:L β 0hij:0 = 0 + 0p:ℕhp:0 < phLp:∀ (k : ℕ), L α (k * p)⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α;'β) (k * p)
exact ⟨p, hp, fun k => ⟨k * p, 0, hLp k, hj, by α:Programβ:Programhαβ:α.testFree ∧ β.testFreehi:L α 0hj:L β 0hij:0 = 0 + 0p:ℕhp:0 < phLp:∀ (k : ℕ), L α (k * p)k:ℕ⊢ k * p = k * p + 0 simp All goals completed! 🐙⟩⟩
| α ⋓ β, hαβ, h0 => α:Programβ:Programhαβ:(α⋓β).testFreeh0:L (α⋓β) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p) by α:Programβ:Programhαβ:(α⋓β).testFreeh0:L (α⋓β) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p)
simp only [Program.testFree] at hαβ α:Programβ:Programhαβ:α.testFree ∧ β.testFreeh0:L (α⋓β) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p)
rcases h0 with h0 | h0 inl α:Programβ:Programhαβ:α.testFree ∧ β.testFreeh0:L α 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p)inr α:Programβ:Programhαβ:α.testFree ∧ β.testFreeh0:L β 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p)
· inl α:Programβ:Programhαβ:α.testFree ∧ β.testFreeh0:L α 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p) obtain ⟨p, hp, hLp⟩ := L_zero α hαβ.1 h0 inl α:Programβ:Programhαβ:α.testFree ∧ β.testFreeh0:L α 0p:ℕhp:0 < phLp:∀ (k : ℕ), L α (k * p)⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p)
exact ⟨p, hp, fun k => Or.inl (hLp k)⟩ All goals completed! 🐙
· inr α:Programβ:Programhαβ:α.testFree ∧ β.testFreeh0:L β 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p) obtain ⟨p, hp, hLp⟩ := L_zero β hαβ.2 h0 inr α:Programβ:Programhαβ:α.testFree ∧ β.testFreeh0:L β 0p:ℕhp:0 < phLp:∀ (k : ℕ), L β (k * p)⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (α⋓β) (k * p)
exact ⟨p, hp, fun k => Or.inr (hLp k)⟩ All goals completed! 🐙
| ∗α, hα, _ => α:Programhα:(∗α).testFreex✝:L (∗α) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (∗α) (k * p) by α:Programhα:(∗α).testFreex✝:L (∗α) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (∗α) (k * p)
simp only [Program.testFree] at hα α:Programhα:α.testFreex✝:L (∗α) 0⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (∗α) (k * p)
obtain ⟨p, hp, hLp⟩ := L_pos α hα α:Programhα:α.testFreex✝:L (∗α) 0p:ℕhp:0 < phLp:L α p⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), L (∗α) (k * p)
refine ⟨p, hp, fun k => ⟨List.replicate k p, ?_, by α:Programhα:α.testFreex✝:L (∗α) 0p:ℕhp:0 < phLp:L α pk:ℕ⊢ k * p = (List.replicate k p).sum simp All goals completed! 🐙⟩⟩
intro i hi α:Programhα:α.testFreex✝:L (∗α) 0p:ℕhp:0 < phLp:L α pk:ℕi:ℕhi:i ∈ List.replicate k p⊢ L α i
rw [List.eq_of_mem_replicate hi α:Programhα:α.testFreex✝:L (∗α) 0p:ℕhp:0 < phLp:L α pk:ℕi:ℕhi:i ∈ List.replicate k p⊢ L α p] α:Programhα:α.testFreex✝:L (∗α) 0p:ℕhp:0 < phLp:L α pk:ℕi:ℕhi:i ∈ List.replicate k p⊢ L α p
exact hLp All goals completed! 🐙The converse, for the sets without these obstructions
aPow n is the program a^(n+1), i.e. a ;' ⋯ ;' a with n + 1 copies of a = ·0.
def aPow : ℕ → Program
| 0 => ·0
| n + 1 => ·0 ;' aPow n@[simp] lemma L_aPow (n m : ℕ) : L (aPow n) m ↔ m = n + 1 := by n:ℕm:ℕ⊢ L (aPow n) m ↔ m = n + 1
induction n generalizing m with
| zero => zero m:ℕ⊢ L (aPow 0) m ↔ m = 0 + 1 simp [aPow, L] All goals completed! 🐙
| succ n IH => succ n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1m:ℕ⊢ L (aPow (n + 1)) m ↔ m = n + 1 + 1
simp only [aPow, L, IH] succ n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1m:ℕ⊢ (∃ i j, i = 1 ∧ j = n + 1 ∧ m = i + j) ↔ m = n + 1 + 1
constructor succ.mp n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1m:ℕ⊢ (∃ i j, i = 1 ∧ j = n + 1 ∧ m = i + j) → m = n + 1 + 1succ.mpr n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1m:ℕ⊢ m = n + 1 + 1 → ∃ i j, i = 1 ∧ j = n + 1 ∧ m = i + j
· succ.mp n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1m:ℕ⊢ (∃ i j, i = 1 ∧ j = n + 1 ∧ m = i + j) → m = n + 1 + 1 rintro ⟨i, j, rfl, rfl, rfl⟩ succ.mp n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1⊢ 1 + (n + 1) = n + 1 + 1; ring All goals completed! 🐙
· succ.mpr n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1m:ℕ⊢ m = n + 1 + 1 → ∃ i j, i = 1 ∧ j = n + 1 ∧ m = i + j rintro rfl succ.mpr n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1⊢ ∃ i j, i = 1 ∧ j = n + 1 ∧ n + 1 + 1 = i + j; exact ⟨1, n + 1, rfl, rfl, by n:ℕIH:∀ (m : ℕ), L (aPow n) m ↔ m = n + 1⊢ n + 1 + 1 = 1 + (n + 1) ring All goals completed! 🐙⟩lemma aPow_testFree (n : ℕ) : (aPow n).testFree := by n:ℕ⊢ (aPow n).testFree
induction n zero ⊢ (aPow 0).testFreesucc n✝:ℕa✝:(aPow n✝).testFree⊢ (aPow (n✝ + 1)).testFree <;> zero ⊢ (aPow 0).testFreesucc n✝:ℕa✝:(aPow n✝).testFree⊢ (aPow (n✝ + 1)).testFree simp [aPow, *] All goals completed! 🐙lemma aPow_voc (n : ℕ) : (aPow n).voc = {Sum.inr 0} := by n:ℕ⊢ (aPow n).voc = {Sum.inr 0}
induction n zero ⊢ (aPow 0).voc = {Sum.inr 0}succ n✝:ℕa✝:(aPow n✝).voc = {Sum.inr 0}⊢ (aPow (n✝ + 1)).voc = {Sum.inr 0} <;> zero ⊢ (aPow 0).voc = {Sum.inr 0}succ n✝:ℕa✝:(aPow n✝).voc = {Sum.inr 0}⊢ (aPow (n✝ + 1)).voc = {Sum.inr 0} simp [aPow, *] All goals completed! 🐙IsL X: the set X ⊆ ℕ is L α for a test-free program α with voc α = {a}.
lemma IsL.union {X Y : Set ℕ} (hX : IsL X) (hY : IsL Y) : IsL (X ∪ Y) := by X:Set ℕY:Set ℕhX:IsL XhY:IsL Y⊢ IsL (X ∪ Y)
obtain ⟨α, hα, hvα, rfl⟩ := hX Y:Set ℕhY:IsL Yα:Programhα:α.testFreehvα:α.voc = {Sum.inr 0}⊢ IsL ({n | L α n} ∪ Y)
obtain ⟨β, hβ, hvβ, rfl⟩ := hY α:Programhα:α.testFreehvα:α.voc = {Sum.inr 0}β:Programhβ:β.testFreehvβ:β.voc = {Sum.inr 0}⊢ IsL ({n | L α n} ∪ {n | L β n})
exact ⟨α ⋓ β, ⟨hα, hβ⟩, by α:Programhα:α.testFreehvα:α.voc = {Sum.inr 0}β:Programhβ:β.testFreehvβ:β.voc = {Sum.inr 0}⊢ (α⋓β).voc = {Sum.inr 0} simp [hvα, hvβ] All goals completed! 🐙, L_union_set α β⟩lemma IsL.add {X Y : Set ℕ} (hX : IsL X) (hY : IsL Y) : IsL (X + Y) := by X:Set ℕY:Set ℕhX:IsL XhY:IsL Y⊢ IsL (X + Y)
obtain ⟨α, hα, hvα, rfl⟩ := hX Y:Set ℕhY:IsL Yα:Programhα:α.testFreehvα:α.voc = {Sum.inr 0}⊢ IsL ({n | L α n} + Y)
obtain ⟨β, hβ, hvβ, rfl⟩ := hY α:Programhα:α.testFreehvα:α.voc = {Sum.inr 0}β:Programhβ:β.testFreehvβ:β.voc = {Sum.inr 0}⊢ IsL ({n | L α n} + {n | L β n})
exact ⟨α ;' β, ⟨hα, hβ⟩, by α:Programhα:α.testFreehvα:α.voc = {Sum.inr 0}β:Programhβ:β.testFreehvβ:β.voc = {Sum.inr 0}⊢ (α;'β).voc = {Sum.inr 0} simp [hvα, hvβ] All goals completed! 🐙, L_seq_set α β⟩lemma IsL.closure {X : Set ℕ} (hX : IsL X) : IsL (closure X : Set ℕ) := by X:Set ℕhX:IsL X⊢ IsL ↑(AddSubmonoid.closure X)
obtain ⟨α, hα, hvα, rfl⟩ := hX α:Programhα:α.testFreehvα:α.voc = {Sum.inr 0}⊢ IsL ↑(AddSubmonoid.closure {n | L α n})
exact ⟨∗α, hα, by α:Programhα:α.testFreehvα:α.voc = {Sum.inr 0}⊢ (∗α).voc = {Sum.inr 0} simp [hvα] All goals completed! 🐙, L_star_set α⟩lemma IsL.singleton_succ (n : ℕ) : IsL {n + 1} :=
⟨aPow n, aPow_testFree n, aPow_voc n, by n:ℕ⊢ {n_1 | L (aPow n) n_1} = {n + 1} ext m n:ℕm:ℕ⊢ m ∈ {n_1 | L (aPow n) n_1} ↔ m ∈ {n + 1}; simp All goals completed! 🐙⟩lemma IsL.singleton_of_pos {n : ℕ} (hn : 0 < n) : IsL {n} := by n:ℕhn:0 < n⊢ IsL {n}
obtain ⟨m, rfl⟩ := Nat.exists_eq_add_one_of_ne_zero hn.ne' m:ℕhn:0 < m + 1⊢ IsL {m + 1}
exact IsL.singleton_succ m All goals completed! 🐙The positive part of a proper linear subset of ℕ is empty or IsL.
lemma IsProperLinearSet.isL_diff_zero {s : Set ℕ} (hs : IsProperLinearSet s) :
s \ {0} = ∅ ∨ IsL (s \ {0}) := by s:Set ℕhs:IsProperLinearSet s⊢ s \ {0} = ∅ ∨ IsL (s \ {0})
rw [isProperLinearSet_iff s:Set ℕhs:∃ a t, LinearIndepOn ℕ id ↑t ∧ s = a +ᵥ ↑(closure ↑t)⊢ s \ {0} = ∅ ∨ IsL (s \ {0})] at hs s:Set ℕhs:∃ a t, LinearIndepOn ℕ id ↑t ∧ s = a +ᵥ ↑(closure ↑t)⊢ s \ {0} = ∅ ∨ IsL (s \ {0})
obtain ⟨a, t, ht, rfl⟩ := hs a:ℕt:Finset ℕht:LinearIndepOn ℕ id ↑t⊢ (a +ᵥ ↑(closure ↑t)) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑t)) \ {0})
have hcard : #t ≤ 1 := by s:Set ℕhs:IsProperLinearSet s⊢ s \ {0} = ∅ ∨ IsL (s \ {0}) simpa [CommSemiring.rank_self] using ht.cardinal_le_rank a:ℕt:Finset ℕht:LinearIndepOn ℕ id ↑thcard:#t ≤ 1⊢ (a +ᵥ ↑(closure ↑t)) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑t)) \ {0})
simp_rw [ a:ℕt:Finset ℕht:LinearIndepOn ℕ id ↑thcard:#t ≤ 1⊢ (a +ᵥ ↑(closure ↑t)) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑t)) \ {0})Finset.card_le_one_iff_subset_singleton, a:ℕt:Finset ℕht:LinearIndepOn ℕ id ↑thcard:∃ x, t ⊆ {x}⊢ (a +ᵥ ↑(closure ↑t)) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑t)) \ {0}) Finset.subset_singleton_iff a:ℕt:Finset ℕht:LinearIndepOn ℕ id ↑thcard:∃ x, t = ∅ ∨ t = {x}⊢ (a +ᵥ ↑(closure ↑t)) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑t)) \ {0})] at hcard
rcases hcard with ⟨b, (rfl | rfl)⟩ inl a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅⊢ (a +ᵥ ↑(closure ↑∅)) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑∅)) \ {0})inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}⊢ (a +ᵥ ↑(closure ↑{b})) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑{b})) \ {0})
· inl a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅⊢ (a +ᵥ ↑(closure ↑∅)) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑∅)) \ {0}) -- `s = {a}`
have hs : a +ᵥ (closure ((∅ : Finset ℕ) : Set ℕ) : Set ℕ) = {a} := by s:Set ℕhs:IsProperLinearSet s⊢ s \ {0} = ∅ ∨ IsL (s \ {0})
ext n a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅n:ℕ⊢ n ∈ a +ᵥ ↑(closure ↑∅) ↔ n ∈ {a}; simp inl a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅hs:a +ᵥ ↑(closure ↑∅) = {a}⊢ (a +ᵥ ↑(closure ↑∅)) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑∅)) \ {0})
rw [hs inl a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅hs:a +ᵥ ↑(closure ↑∅) = {a}⊢ {a} \ {0} = ∅ ∨ IsL ({a} \ {0})] inl a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅hs:a +ᵥ ↑(closure ↑∅) = {a}⊢ {a} \ {0} = ∅ ∨ IsL ({a} \ {0})
rcases Nat.eq_zero_or_pos a with rfl | ha inl.inl b:ℕht:LinearIndepOn ℕ id ↑∅hs:0 +ᵥ ↑(closure ↑∅) = {0}⊢ {0} \ {0} = ∅ ∨ IsL ({0} \ {0})inl.inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅hs:a +ᵥ ↑(closure ↑∅) = {a}ha:a > 0⊢ {a} \ {0} = ∅ ∨ IsL ({a} \ {0})
· inl.inl b:ℕht:LinearIndepOn ℕ id ↑∅hs:0 +ᵥ ↑(closure ↑∅) = {0}⊢ {0} \ {0} = ∅ ∨ IsL ({0} \ {0}) left inl.inl b:ℕht:LinearIndepOn ℕ id ↑∅hs:0 +ᵥ ↑(closure ↑∅) = {0}⊢ {0} \ {0} = ∅; simp All goals completed! 🐙
· inl.inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅hs:a +ᵥ ↑(closure ↑∅) = {a}ha:a > 0⊢ {a} \ {0} = ∅ ∨ IsL ({a} \ {0}) right inl.inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅hs:a +ᵥ ↑(closure ↑∅) = {a}ha:a > 0⊢ IsL ({a} \ {0})
rw [sdiff_singleton_eq_self (by a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅hs:a +ᵥ ↑(closure ↑∅) = {a}ha:a > 0⊢ 0 ∉ {a} simpa using ha.ne All goals completed! 🐙)] inl.inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑∅hs:a +ᵥ ↑(closure ↑∅) = {a}ha:a > 0⊢ IsL {a}
exact IsL.singleton_of_pos ha All goals completed! 🐙
· inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}⊢ (a +ᵥ ↑(closure ↑{b})) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑{b})) \ {0}) -- `s = a + bℕ` with `b ≠ 0`
have hb : b ≠ 0 := by s:Set ℕhs:IsProperLinearSet s⊢ s \ {0} = ∅ ∨ IsL (s \ {0}) simpa [ne_comm] using ht.zero_notMem_image inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0⊢ (a +ᵥ ↑(closure ↑{b})) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑{b})) \ {0})
have hb' : 0 < b := Nat.pos_of_ne_zero hb inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < b⊢ (a +ᵥ ↑(closure ↑{b})) \ {0} = ∅ ∨ IsL ((a +ᵥ ↑(closure ↑{b})) \ {0})
right inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < b⊢ IsL ((a +ᵥ ↑(closure ↑{b})) \ {0})
have hmem : ∀ n,
n ∈ a +ᵥ (closure (({b} : Finset ℕ) : Set ℕ) : Set ℕ) ↔ ∃ m, a + m * b = n := by s:Set ℕhs:IsProperLinearSet s⊢ s \ {0} = ∅ ∨ IsL (s \ {0})
intro n a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bn:ℕ⊢ n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = n
simp only [Finset.coe_singleton, mem_vadd_set, SetLike.mem_coe,
AddSubmonoid.mem_closure_singleton, smul_eq_mul, vadd_eq_add, exists_exists_eq_and] inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = n⊢ IsL ((a +ᵥ ↑(closure ↑{b})) \ {0})
rcases Nat.eq_zero_or_pos a with rfl | ha inr.inl b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = n⊢ IsL ((0 +ᵥ ↑(closure ↑{b})) \ {0})inr.inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0⊢ IsL ((a +ᵥ ↑(closure ↑{b})) \ {0})
· inr.inl b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = n⊢ IsL ((0 +ᵥ ↑(closure ↑{b})) \ {0}) -- `bℕ \ {0} = {b} + bℕ`
convert (IsL.singleton_of_pos hb').add (IsL.singleton_of_pos hb').closure using 1 b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = n⊢ (0 +ᵥ ↑(closure ↑{b})) \ {0} = {b} + ↑(closure {b})
ext n b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nn:ℕ⊢ n ∈ (0 +ᵥ ↑(closure ↑{b})) \ {0} ↔ n ∈ {b} + ↑(closure {b})
simp only [mem_sdiff, hmem, mem_singleton_iff, mem_add, SetLike.mem_coe,
AddSubmonoid.mem_closure_singleton, smul_eq_mul, zero_add] b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nn:ℕ⊢ (∃ m, m * b = n) ∧ ¬n = 0 ↔ ∃ x, x = b ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = n
constructor mp b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nn:ℕ⊢ (∃ m, m * b = n) ∧ ¬n = 0 → ∃ x, x = b ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = nmpr b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nn:ℕ⊢ (∃ x, x = b ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = n) → (∃ m, m * b = n) ∧ ¬n = 0
· mp b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nn:ℕ⊢ (∃ m, m * b = n) ∧ ¬n = 0 → ∃ x, x = b ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = n rintro ⟨⟨m, rfl⟩, hm⟩ mp b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nm:ℕhm:¬m * b = 0⊢ ∃ x, x = b ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = m * b
obtain ⟨m, rfl⟩ : ∃ m', m = m' + 1 :=
Nat.exists_eq_add_one_of_ne_zero (by b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nm:ℕhm:¬m * b = 0⊢ m ≠ 0 rintro rfl b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nhm:¬0 * b = 0⊢ False; simp at hm All goals completed! 🐙) mp b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nm:ℕhm:¬(m + 1) * b = 0⊢ ∃ x, x = b ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = (m + 1) * b
exact ⟨b, rfl, m * b, ⟨m, rfl⟩, by b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nm:ℕhm:¬(m + 1) * b = 0⊢ b + m * b = (m + 1) * b ring All goals completed! 🐙⟩
· mpr b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{b}) ↔ ∃ m, 0 + m * b = nn:ℕ⊢ (∃ x, x = b ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = n) → (∃ m, m * b = n) ∧ ¬n = 0 rintro ⟨x, rfl, y, ⟨m, rfl⟩, rfl⟩ mpr x:ℕht:LinearIndepOn ℕ id ↑{x}hb:x ≠ 0hb':0 < xhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{x}) ↔ ∃ m, 0 + m * x = nm:ℕ⊢ (∃ m_1, m_1 * x = x + m * x) ∧ ¬x + m * x = 0
exact ⟨⟨m + 1, by x:ℕht:LinearIndepOn ℕ id ↑{x}hb:x ≠ 0hb':0 < xhmem:∀ (n : ℕ), n ∈ 0 +ᵥ ↑(closure ↑{x}) ↔ ∃ m, 0 + m * x = nm:ℕ⊢ (m + 1) * x = x + m * x ring All goals completed! 🐙⟩, (Nat.add_pos_left hb' _).ne'⟩
· inr.inr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0⊢ IsL ((a +ᵥ ↑(closure ↑{b})) \ {0}) -- `(a + bℕ) \ {0} = {a} + bℕ`
convert (IsL.singleton_of_pos ha).add (IsL.singleton_of_pos hb').closure using 1 a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0⊢ (a +ᵥ ↑(closure ↑{b})) \ {0} = {a} + ↑(closure {b})
ext n a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0n:ℕ⊢ n ∈ (a +ᵥ ↑(closure ↑{b})) \ {0} ↔ n ∈ {a} + ↑(closure {b})
simp only [mem_sdiff, hmem, mem_singleton_iff, mem_add, SetLike.mem_coe,
AddSubmonoid.mem_closure_singleton, smul_eq_mul] a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0n:ℕ⊢ (∃ m, a + m * b = n) ∧ ¬n = 0 ↔ ∃ x, x = a ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = n
constructor mp a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0n:ℕ⊢ (∃ m, a + m * b = n) ∧ ¬n = 0 → ∃ x, x = a ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = nmpr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0n:ℕ⊢ (∃ x, x = a ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = n) → (∃ m, a + m * b = n) ∧ ¬n = 0
· mp a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0n:ℕ⊢ (∃ m, a + m * b = n) ∧ ¬n = 0 → ∃ x, x = a ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = n rintro ⟨⟨m, rfl⟩, -⟩ mp a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0m:ℕ⊢ ∃ x, x = a ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = a + m * b
exact ⟨a, rfl, m * b, ⟨m, rfl⟩, rfl⟩ All goals completed! 🐙
· mpr a:ℕb:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bhmem:∀ (n : ℕ), n ∈ a +ᵥ ↑(closure ↑{b}) ↔ ∃ m, a + m * b = nha:a > 0n:ℕ⊢ (∃ x, x = a ∧ ∃ y, (∃ n, n * b = y) ∧ x + y = n) → (∃ m, a + m * b = n) ∧ ¬n = 0 rintro ⟨x, rfl, y, ⟨m, rfl⟩, rfl⟩ mpr b:ℕht:LinearIndepOn ℕ id ↑{b}hb:b ≠ 0hb':0 < bx:ℕhmem:∀ (n : ℕ), n ∈ x +ᵥ ↑(closure ↑{b}) ↔ ∃ m, x + m * b = nha:x > 0m:ℕ⊢ (∃ m_1, x + m_1 * b = x + m * b) ∧ ¬x + m * b = 0
exact ⟨⟨m, rfl⟩, (Nat.add_pos_left ha _).ne'⟩ All goals completed! 🐙The positive part of a semilinear subset of ℕ is empty or IsL.
lemma IsSemilinearSet.isL_diff_zero {X : Set ℕ} (hX : IsSemilinearSet X) :
X \ {0} = ∅ ∨ IsL (X \ {0}) := by X:Set ℕhX:IsSemilinearSet X⊢ X \ {0} = ∅ ∨ IsL (X \ {0})
obtain ⟨S, hS, rfl⟩ := isProperSemilinearSet_iff.mp hX.isProperSemilinearSet S:Finset (Set ℕ)hS:∀ t ∈ S, IsProperLinearSet thX:IsSemilinearSet (⋃₀ ↑S)⊢ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})
clear hX S:Finset (Set ℕ)hS:∀ t ∈ S, IsProperLinearSet t⊢ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})
induction S using Finset.induction_on with
| empty => empty hS:∀ t ∈ ∅, IsProperLinearSet t⊢ ⋃₀ ↑∅ \ {0} = ∅ ∨ IsL (⋃₀ ↑∅ \ {0}) left empty hS:∀ t ∈ ∅, IsProperLinearSet t⊢ ⋃₀ ↑∅ \ {0} = ∅; simp All goals completed! 🐙
| insert t S _ IH => insert t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:∀ t_1 ∈ insert t S, IsProperLinearSet t_1⊢ ⋃₀ ↑(insert t S) \ {0} = ∅ ∨ IsL (⋃₀ ↑(insert t S) \ {0})
simp only [Finset.mem_insert, forall_eq_or_imp] at hS insert t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet a⊢ ⋃₀ ↑(insert t S) \ {0} = ∅ ∨ IsL (⋃₀ ↑(insert t S) \ {0})
rw [Finset.coe_insert, insert t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet a⊢ ⋃₀ insert t ↑S \ {0} = ∅ ∨ IsL (⋃₀ insert t ↑S \ {0}) sUnion_insert, insert t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet a⊢ (t ∪ ⋃₀ ↑S) \ {0} = ∅ ∨ IsL ((t ∪ ⋃₀ ↑S) \ {0}) union_sdiff_distrib insert t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet a⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0})] insert t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet a⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0})
rcases hS.1.isL_diff_zero with h1 | h1 insert.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0})insert.inr t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:IsL (t \ {0})⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}) <;> insert.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0})insert.inr t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:IsL (t \ {0})⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}) rcases IH hS.2 with h2 | h2 insert.inr.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:IsL (t \ {0})h2:⋃₀ ↑S \ {0} = ∅⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0})insert.inr.inr t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:IsL (t \ {0})h2:IsL (⋃₀ ↑S \ {0})⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0})
· insert.inl.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅h2:⋃₀ ↑S \ {0} = ∅⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}) left insert.inl.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅h2:⋃₀ ↑S \ {0} = ∅⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅; rw [h1, insert.inl.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅h2:⋃₀ ↑S \ {0} = ∅⊢ ∅ ∪ ⋃₀ ↑S \ {0} = ∅ h2, insert.inl.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅h2:⋃₀ ↑S \ {0} = ∅⊢ ∅ ∪ ∅ = ∅ union_empty insert.inl.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅h2:⋃₀ ↑S \ {0} = ∅⊢ ∅ = ∅] All goals completed! 🐙
· insert.inl.inr t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅h2:IsL (⋃₀ ↑S \ {0})⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}) right insert.inl.inr t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:t \ {0} = ∅h2:IsL (⋃₀ ↑S \ {0})⊢ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}); rwa [h1, empty_union] All goals completed! 🐙
· insert.inr.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:IsL (t \ {0})h2:⋃₀ ↑S \ {0} = ∅⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}) right insert.inr.inl t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:IsL (t \ {0})h2:⋃₀ ↑S \ {0} = ∅⊢ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}); rwa [h2, union_empty] All goals completed! 🐙
· insert.inr.inr t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:IsL (t \ {0})h2:IsL (⋃₀ ↑S \ {0})⊢ t \ {0} ∪ ⋃₀ ↑S \ {0} = ∅ ∨ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}) right insert.inr.inr t:Set ℕS:Finset (Set ℕ)a✝:t ∉ SIH:(∀ t ∈ S, IsProperLinearSet t) → ⋃₀ ↑S \ {0} = ∅ ∨ IsL (⋃₀ ↑S \ {0})hS:IsProperLinearSet t ∧ ∀ a ∈ S, IsProperLinearSet ah1:IsL (t \ {0})h2:IsL (⋃₀ ↑S \ {0})⊢ IsL (t \ {0} ∪ ⋃₀ ↑S \ {0}); exact h1.union h2 All goals completed! 🐙The sets L α for test-free α with voc α = {a} are exactly the nonempty semilinear
sets X ⊆ ℕ such that, if 0 ∈ X, then X contains all multiples of some p > 0.
theorem exists_L_eq_iff (X : Set ℕ) :
(∃ α : Program, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X) ↔
IsSemilinearSet X ∧ X.Nonempty ∧ (0 ∈ X → ∃ p, 0 < p ∧ ∀ k, k * p ∈ X) := by X:Set ℕ⊢ (∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X) ↔
IsSemilinearSet X ∧ X.Nonempty ∧ (0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ X)
constructor mp X:Set ℕ⊢ (∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X) →
IsSemilinearSet X ∧ X.Nonempty ∧ (0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ X)mpr X:Set ℕ⊢ IsSemilinearSet X ∧ X.Nonempty ∧ (0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ X) →
∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X
· mp X:Set ℕ⊢ (∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X) →
IsSemilinearSet X ∧ X.Nonempty ∧ (0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ X) rintro ⟨α, hα, -, rfl⟩ mp α:Programhα:α.testFree⊢ IsSemilinearSet {n | L α n} ∧ {n | L α n}.Nonempty ∧ (0 ∈ {n | L α n} → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ {n | L α n})
refine ⟨L_isSemilinearSet α hα, ?_, ?_⟩ mp.refine_1 α:Programhα:α.testFree⊢ {n | L α n}.Nonemptymp.refine_2 α:Programhα:α.testFree⊢ 0 ∈ {n | L α n} → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ {n | L α n}
· mp.refine_1 α:Programhα:α.testFree⊢ {n | L α n}.Nonempty obtain ⟨n, -, hn⟩ := L_pos α hα mp.refine_1 α:Programhα:α.testFreen:ℕhn:L α n⊢ {n | L α n}.Nonempty
exact ⟨n, hn⟩ All goals completed! 🐙
· mp.refine_2 α:Programhα:α.testFree⊢ 0 ∈ {n | L α n} → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ {n | L α n} intro h0 mp.refine_2 α:Programhα:α.testFreeh0:0 ∈ {n | L α n}⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ {n | L α n}
obtain ⟨p, hp, hLp⟩ := L_zero α hα h0 mp.refine_2 α:Programhα:α.testFreeh0:0 ∈ {n | L α n}p:ℕhp:0 < phLp:∀ (k : ℕ), L α (k * p)⊢ ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ {n | L α n}
exact ⟨p, hp, hLp⟩ All goals completed! 🐙
· mpr X:Set ℕ⊢ IsSemilinearSet X ∧ X.Nonempty ∧ (0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ X) →
∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X rintro ⟨hX, hne, h0⟩ mpr X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ X⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X
rcases hX.isL_diff_zero with h | h mpr.inl X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X \ {0} = ∅⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = Xmpr.inr X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X
· mpr.inl X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X \ {0} = ∅⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X -- then `X ⊆ {0}`, so `X = {0}`, which is excluded
exfalso mpr.inl X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X \ {0} = ∅⊢ False
rw [sdiff_eq_empty mpr.inl X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X ⊆ {0}⊢ False] at h mpr.inl X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X ⊆ {0}⊢ False
obtain ⟨x, hx⟩ := hne mpr.inl X:Set ℕhX:IsSemilinearSet Xh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X ⊆ {0}x:ℕhx:x ∈ X⊢ False
obtain rfl : x = 0 := h hx mpr.inl X:Set ℕhX:IsSemilinearSet Xh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X ⊆ {0}hx:0 ∈ X⊢ False
obtain ⟨p, hp, hLp⟩ := h0 hx mpr.inl X:Set ℕhX:IsSemilinearSet Xh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X ⊆ {0}hx:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ X⊢ False
have := h (hLp 1) mpr.inl X:Set ℕhX:IsSemilinearSet Xh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X ⊆ {0}hx:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xthis:1 * p ∈ {0}⊢ False
simp at this mpr.inl X:Set ℕhX:IsSemilinearSet Xh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:X ⊆ {0}hx:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xthis:p = 0⊢ False
omega All goals completed! 🐙
· mpr.inr X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X by_cases h0X : 0 ∈ X pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ X⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = Xneg X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∉ X⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X
· pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ X⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X obtain ⟨p, hp, hLp⟩ := h0 h0X pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ X⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X
obtain ⟨α, hα, hv, hL⟩ := h.union (IsL.singleton_of_pos hp).closure pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X
refine ⟨α, hα, hv, ?_⟩ pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})⊢ {n | L α n} = X
rw [hL pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})⊢ X \ {0} ∪ ↑(closure {p}) = X] pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})⊢ X \ {0} ∪ ↑(closure {p}) = X
ext n pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕ⊢ n ∈ X \ {0} ∪ ↑(closure {p}) ↔ n ∈ X
simp only [mem_union, mem_sdiff, mem_singleton_iff, SetLike.mem_coe,
AddSubmonoid.mem_closure_singleton, smul_eq_mul] pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕ⊢ (n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n) ↔ n ∈ X
constructor pos.mp X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕ⊢ (n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n) → n ∈ Xpos.mpr X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕ⊢ n ∈ X → n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n
· pos.mp X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕ⊢ (n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n) → n ∈ X rintro (⟨hn, -⟩ | ⟨k, rfl⟩) pos.mp.inl X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕhn:n ∈ X⊢ n ∈ Xpos.mp.inr X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})k:ℕ⊢ k * p ∈ X
· pos.mp.inl X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕhn:n ∈ X⊢ n ∈ X exact hn All goals completed! 🐙
· pos.mp.inr X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})k:ℕ⊢ k * p ∈ X exact hLp k All goals completed! 🐙
· pos.mpr X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕ⊢ n ∈ X → n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n intro hn pos.mpr X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕhn:n ∈ X⊢ n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n
by_cases hn0 : n = 0 pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕhn:n ∈ Xhn0:n = 0⊢ n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = nneg X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕhn:n ∈ Xhn0:¬n = 0⊢ n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n
· pos X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕhn:n ∈ Xhn0:n = 0⊢ n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n exact Or.inr ⟨0, by X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕhn:n ∈ Xhn0:n = 0⊢ 0 * p = n simp [hn0] All goals completed! 🐙⟩
· neg X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∈ Xp:ℕhp:0 < phLp:∀ (k : ℕ), k * p ∈ Xα:Programhα:α.testFreehv:α.voc = {Sum.inr 0}hL:{n | L α n} = X \ {0} ∪ ↑(closure {p})n:ℕhn:n ∈ Xhn0:¬n = 0⊢ n ∈ X ∧ ¬n = 0 ∨ ∃ n_1, n_1 * p = n exact Or.inl ⟨hn, hn0⟩ All goals completed! 🐙
· neg X:Set ℕhX:IsSemilinearSet Xhne:X.Nonemptyh0:0 ∈ X → ∃ p, 0 < p ∧ ∀ (k : ℕ), k * p ∈ Xh:IsL (X \ {0})h0X:0 ∉ X⊢ ∃ α, α.testFree ∧ α.voc = {Sum.inr 0} ∧ {n | L α n} = X rwa [sdiff_singleton_eq_self h0X] at h All goals completed! 🐙