l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
instance minimalPeriod_pos [Finite <| orbit (zpowers a) b] :
    NeZero <| minimalPeriod (a • ·) b :=
  ⟨by
    cases nonempty_fintype (orbit (zpowers a) b)
    haveI : Nonempty (orbit (zpowers a) b) := (orbit_nonempty b).to_subtype
    rw [minimalPeriod_eq_card]
    

Proof state:
case intro
n : ℕ
A : Type u_1
R : Type u_2
inst✝⁴ : AddGroup A
inst✝³ : Ring R
α : Type u_3
β : Type u_4
inst✝² : Group α
a : α
inst✝¹ : MulAction α β
b : β
inst✝ : Finite ↑(orbit (↥(zpowers a)) b)
val✝ : Fintype ↑(orbit (↥(zpowers a)) b)
this : Nonempty ↑(orbit (↥(zpowers a)) b)
⊢ Fintype.card ↑(orbit (↥(zpowers a)) b) ≠ 0

Next tactic:
exact Fintype.card_ne_zero
/-- See also `Fintype.card_zpowers`. -/
@[to_additive (attr := simp) Nat.card_zmultiples "See also `Fintype.card_zmultiples`."]
theorem Nat.card_zpowers : Nat.card (zpowers a) = orderOf a := by
  

Proof state:
n : ℕ
A : Type u_1
R : Type u_2
inst✝² : AddGroup A
inst✝¹ : Ring R
α : Type u_3
inst✝ : Group α
a : α
⊢ Nat.card ↥(zpowers a) = orderOf a

Next tactic:
have := Nat.card_congr (MulAction.orbitZPowersEquiv a (1 : α))
/-- See also `Fintype.card_zpowers`. -/
@[to_additive (attr := simp) Nat.card_zmultiples "See also `Fintype.card_zmultiples`."]
theorem Nat.card_zpowers : Nat.card (zpowers a) = orderOf a := by
  have := Nat.card_congr (MulAction.orbitZPowersEquiv a (1 : α))
  

Proof state:
n : ℕ
A : Type u_1
R : Type u_2
inst✝² : AddGroup A
inst✝¹ : Ring R
α : Type u_3
inst✝ : Group α
a : α
this : Nat.card ↑(MulAction.orbit (↥(zpowers a)) 1) = Nat.card (ZMod (Function.minimalPeriod (fun x => a • x) 1))
⊢ Nat.card ↥(zpowers a) = orderOf a

Next tactic:
rwa [Nat.card_zmod, orbit_subgroup_one_eq_self] at this
@[to_additive (attr := simp) finite_zmultiples]
lemma finite_zpowers : (zpowers a : Set α).Finite ↔ IsOfFinOrder a := by
  

Proof state:
n : ℕ
A : Type u_1
R : Type u_2
inst✝² : AddGroup A
inst✝¹ : Ring R
α : Type u_3
inst✝ : Group α
a : α
⊢ Set.Finite ↑(zpowers a) ↔ IsOfFinOrder a

Next tactic:
simp only [← orderOf_pos_iff, ← Nat.card_zpowers, Nat.card_pos_iff, ← SetLike.coe_sort_coe,
    nonempty_coe_sort, Nat.card_pos_iff, Set.finite_coe_iff, Subgroup.coe_nonempty, true_and]
instance instSetLike : SetLike (L.Substructure M) M :=
  ⟨Substructure.carrier, fun p q h => by 

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
p q : Substructure L M
h : ↑p = ↑q
⊢ p = q

Next tactic:
cases p
instance instSetLike : SetLike (L.Substructure M) M :=
  ⟨Substructure.carrier, fun p q h => by cases p; 

Proof state:
case mk
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
q : Substructure L M
carrier✝ : Set M
fun_mem✝ : ∀ {n : ℕ} (f : Functions L n), ClosedUnder f carrier✝
h : ↑{ carrier := carrier✝, fun_mem := fun_mem✝ } = ↑q
⊢ { carrier := carrier✝, fun_mem := fun_mem✝ } = q

Next tactic:
cases q
instance instSetLike : SetLike (L.Substructure M) M :=
  ⟨Substructure.carrier, fun p q h => by cases p; cases q; 

Proof state:
case mk.mk
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
carrier✝¹ : Set M
fun_mem✝¹ : ∀ {n : ℕ} (f : Functions L n), ClosedUnder f carrier✝¹
carrier✝ : Set M
fun_mem✝ : ∀ {n : ℕ} (f : Functions L n), ClosedUnder f carrier✝
h : ↑{ carrier := carrier✝¹, fun_mem := fun_mem✝¹ } = ↑{ carrier := carrier✝, fun_mem := fun_mem✝ }
⊢ { carrier := carrier✝¹, fun_mem := fun_mem✝¹ } = { carrier := carrier✝, fun_mem := fun_mem✝ }

Next tactic:
congr
theorem Term.realize_mem {α : Type*} (t : L.Term α) (xs : α → M) (h : ∀ a, xs a ∈ S) :
    t.realize xs ∈ S := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
α : Type u_3
t : Term L α
xs : α → M
h : ∀ (a : α), xs a ∈ S
⊢ realize xs t ∈ S

Next tactic:
induction' t with a n f ts ih
theorem Term.realize_mem {α : Type*} (t : L.Term α) (xs : α → M) (h : ∀ a, xs a ∈ S) :
    t.realize xs ∈ S := by
  induction' t with a n f ts ih
  · 

Proof state:
case var
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
α : Type u_3
xs : α → M
h : ∀ (a : α), xs a ∈ S
a : α
⊢ realize xs (var a) ∈ S

Next tactic:
exact h a
theorem Term.realize_mem {α : Type*} (t : L.Term α) (xs : α → M) (h : ∀ a, xs a ∈ S) :
    t.realize xs ∈ S := by
  induction' t with a n f ts ih
  · exact h a
  · 

Proof state:
case func
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
α : Type u_3
xs : α → M
h : ∀ (a : α), xs a ∈ S
n : ℕ
f : Functions L n
ts : Fin n → Term L α
ih : ∀ (a : Fin n), realize xs (ts a) ∈ S
⊢ realize xs (func f ts) ∈ S

Next tactic:
exact Substructure.fun_mem _ _ _ ih
instance instInfSet : InfSet (L.Substructure M) :=
  ⟨fun s =>
    { carrier := ⋂ t ∈ s, (t : Set M)
      fun_mem := fun {n} f =>
        ClosedUnder.sInf
          (by
            

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set (Substructure L M)
n : ℕ
f : Functions L n
⊢ ∀ s_1 ∈ Set.range fun t => ⋂ (_ : t ∈ s), ↑t, ClosedUnder f s_1

Next tactic:
rintro _ ⟨t, rfl⟩
instance instInfSet : InfSet (L.Substructure M) :=
  ⟨fun s =>
    { carrier := ⋂ t ∈ s, (t : Set M)
      fun_mem := fun {n} f =>
        ClosedUnder.sInf
          (by
            rintro _ ⟨t, rfl⟩
            

Proof state:
case intro
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set (Substructure L M)
n : ℕ
f : Functions L n
t : Substructure L M
⊢ ClosedUnder f ((fun t => ⋂ (_ : t ∈ s), ↑t) t)

Next tactic:
by_cases h : t ∈ s
instance instInfSet : InfSet (L.Substructure M) :=
  ⟨fun s =>
    { carrier := ⋂ t ∈ s, (t : Set M)
      fun_mem := fun {n} f =>
        ClosedUnder.sInf
          (by
            rintro _ ⟨t, rfl⟩
            by_cases h : t ∈ s
            · 

Proof state:
case pos
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set (Substructure L M)
n : ℕ
f : Functions L n
t : Substructure L M
h : t ∈ s
⊢ ClosedUnder f ((fun t => ⋂ (_ : t ∈ s), ↑t) t)

Next tactic:
simpa [h] using t.fun_mem f
instance instInfSet : InfSet (L.Substructure M) :=
  ⟨fun s =>
    { carrier := ⋂ t ∈ s, (t : Set M)
      fun_mem := fun {n} f =>
        ClosedUnder.sInf
          (by
            rintro _ ⟨t, rfl⟩
            by_cases h : t ∈ s
            · simpa [h] using t.fun_mem f
            · 

Proof state:
case neg
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set (Substructure L M)
n : ℕ
f : Functions L n
t : Substructure L M
h : t ∉ s
⊢ ClosedUnder f ((fun t => ⋂ (_ : t ∈ s), ↑t) t)

Next tactic:
simp [h]
theorem mem_iInf {ι : Sort*} {S : ι → L.Substructure M} {x : M} : (x ∈ ⨅ i, S i) ↔ ∀ i, x ∈ S i :=
  by 

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S✝ : Substructure L M
ι : Sort u_3
S : ι → Substructure L M
x : M
⊢ x ∈ ⨅ i, S i ↔ ∀ (i : ι), x ∈ S i

Next tactic:
simp only [iInf, mem_sInf, Set.forall_range_iff]
@[simp, norm_cast]
theorem coe_iInf {ι : Sort*} {S : ι → L.Substructure M} :
    ((⨅ i, S i : L.Substructure M) : Set M) = ⋂ i, (S i : Set M) := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S✝ : Substructure L M
ι : Sort u_3
S : ι → Substructure L M
⊢ ↑(⨅ i, S i) = ⋂ i, ↑(S i)

Next tactic:
simp only [iInf, coe_sInf, Set.biInter_range]
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ ↑(LowerAdjoint.toFun (closure L) s) = range (Term.realize Subtype.val)

Next tactic:
let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    simp only [mem_range] at *
    refine' ⟨func f fun i => Classical.choose (hx i), _⟩
    simp only [Term.realize, fun i => Classical.choose_spec (hx i)]⟩
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
n : ℕ
f : Functions L n
x : Fin n → M
hx : ∀ (i : Fin n), x i ∈ range (Term.realize Subtype.val)
⊢ funMap f x ∈ range (Term.realize Subtype.val)

Next tactic:
simp only [mem_range] at *
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    simp only [mem_range] at *
    

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
n : ℕ
f : Functions L n
x : Fin n → M
hx : ∀ (i : Fin n), ∃ y, Term.realize Subtype.val y = x i
⊢ ∃ y, Term.realize Subtype.val y = funMap f x

Next tactic:
refine' ⟨func f fun i => Classical.choose (hx i), _⟩
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    simp only [mem_range] at *
    refine' ⟨func f fun i => Classical.choose (hx i), _⟩
    

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
n : ℕ
f : Functions L n
x : Fin n → M
hx : ∀ (i : Fin n), ∃ y, Term.realize Subtype.val y = x i
⊢ Term.realize Subtype.val (func f fun i => Classical.choose (_ : ∃ y, Term.realize Subtype.val y = x i)) = funMap f x

Next tactic:
simp only [Term.realize, fun i => Classical.choose_spec (hx i)]
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    simp only [mem_range] at *
    refine' ⟨func f fun i => Classical.choose (hx i), _⟩
    simp only [Term.realize, fun i => Classical.choose_spec (hx i)]⟩
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S✝ : Substructure L M
s : Set M
S : Substructure L M :=
  { carrier := range (Term.realize Subtype.val),
    fun_mem :=
      (_ :
        ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M),
          (∀ (i : Fin n), x i ∈ range (Term.realize Subtype.val)) → funMap f x ∈ range (Term.realize Subtype.val)) }
⊢ ↑(LowerAdjoint.toFun (closure L) s) = range (Term.realize Subtype.val)

Next tactic:
change _ = (S : Set M)
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    simp only [mem_range] at *
    refine' ⟨func f fun i => Classical.choose (hx i), _⟩
    simp only [Term.realize, fun i => Classical.choose_spec (hx i)]⟩
  change _ = (S : Set M)
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S✝ : Substructure L M
s : Set M
S : Substructure L M :=
  { carrier := range (Term.realize Subtype.val),
    fun_mem :=
      (_ :
        ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M),
          (∀ (i : Fin n), x i ∈ range (Term.realize Subtype.val)) → funMap f x ∈ range (Term.realize Subtype.val)) }
⊢ ↑(LowerAdjoint.toFun (closure L) s) = ↑S

Next tactic:
rw [← SetLike.ext'_iff]
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    simp only [mem_range] at *
    refine' ⟨func f fun i => Classical.choose (hx i), _⟩
    simp only [Term.realize, fun i => Classical.choose_spec (hx i)]⟩
  change _ = (S : Set M)
  rw [← SetLike.ext'_iff]
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S✝ : Substructure L M
s : Set M
S : Substructure L M :=
  { carrier := range (Term.realize Subtype.val),
    fun_mem :=
      (_ :
        ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M),
          (∀ (i : Fin n), x i ∈ range (Term.realize Subtype.val)) → funMap f x ∈ range (Term.realize Subtype.val)) }
⊢ LowerAdjoint.toFun (closure L) s = S

Next tactic:
refine' closure_eq_of_le (fun x hx => ⟨var ⟨x, hx⟩, rfl⟩) (le_sInf fun S' hS' => _)
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    simp only [mem_range] at *
    refine' ⟨func f fun i => Classical.choose (hx i), _⟩
    simp only [Term.realize, fun i => Classical.choose_spec (hx i)]⟩
  change _ = (S : Set M)
  rw [← SetLike.ext'_iff]
  refine' closure_eq_of_le (fun x hx => ⟨var ⟨x, hx⟩, rfl⟩) (le_sInf fun S' hS' => _)
  · 

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S✝ : Substructure L M
s : Set M
S : Substructure L M :=
  { carrier := range (Term.realize Subtype.val),
    fun_mem :=
      (_ :
        ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M),
          (∀ (i : Fin n), x i ∈ range (Term.realize Subtype.val)) → funMap f x ∈ range (Term.realize Subtype.val)) }
S' : Substructure L M
hS' : S' ∈ {S | s ⊆ ↑S}
⊢ S ≤ S'

Next tactic:
rintro _ ⟨t, rfl⟩
theorem coe_closure_eq_range_term_realize :
    (closure L s : Set M) = range (@Term.realize L _ _ _ ((↑) : s → M)) := by
  let S : L.Substructure M := ⟨range (Term.realize (L := L) ((↑) : s → M)), fun {n} f x hx => by
    simp only [mem_range] at *
    refine' ⟨func f fun i => Classical.choose (hx i), _⟩
    simp only [Term.realize, fun i => Classical.choose_spec (hx i)]⟩
  change _ = (S : Set M)
  rw [← SetLike.ext'_iff]
  refine' closure_eq_of_le (fun x hx => ⟨var ⟨x, hx⟩, rfl⟩) (le_sInf fun S' hS' => _)
  · rintro _ ⟨t, rfl⟩
    

Proof state:
case intro
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S✝ : Substructure L M
s : Set M
S : Substructure L M :=
  { carrier := range (Term.realize Subtype.val),
    fun_mem :=
      (_ :
        ∀ {n : ℕ} (f : Functions L n) (x : Fin n → M),
          (∀ (i : Fin n), x i ∈ range (Term.realize Subtype.val)) → funMap f x ∈ range (Term.realize Subtype.val)) }
S' : Substructure L M
hS' : S' ∈ {S | s ⊆ ↑S}
t : Term L { x // x ∈ s }
⊢ Term.realize Subtype.val t ∈ S'

Next tactic:
exact t.realize_mem _ fun i => hS' i.2
instance small_closure [Small.{u} s] : Small.{u} (closure L s) := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
S : Substructure L M
s : Set M
inst✝ : Small.{u, w} ↑s
⊢ Small.{u, w} ↥(LowerAdjoint.toFun (closure L) s)

Next tactic:
rw [← SetLike.coe_sort_coe, Substructure.coe_closure_eq_range_term_realize]
instance small_closure [Small.{u} s] : Small.{u} (closure L s) := by
  rw [← SetLike.coe_sort_coe, Substructure.coe_closure_eq_range_term_realize]
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
S : Substructure L M
s : Set M
inst✝ : Small.{u, w} ↑s
⊢ Small.{u, w} ↑(range (Term.realize Subtype.val))

Next tactic:
exact small_range _
theorem mem_closure_iff_exists_term {x : M} :
    x ∈ closure L s ↔ ∃ t : L.Term s, t.realize ((↑) : s → M) = x := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
x : M
⊢ x ∈ LowerAdjoint.toFun (closure L) s ↔ ∃ t, Term.realize Subtype.val t = x

Next tactic:
rw [← SetLike.mem_coe, coe_closure_eq_range_term_realize, mem_range]
theorem lift_card_closure_le_card_term : Cardinal.lift.{max u w} #(closure L s) ≤ #(L.Term s) := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ lift.{max u w, w} #↥(LowerAdjoint.toFun (closure L) s) ≤ #(Term L ↑s)

Next tactic:
rw [← SetLike.coe_sort_coe, coe_closure_eq_range_term_realize]
theorem lift_card_closure_le_card_term : Cardinal.lift.{max u w} #(closure L s) ≤ #(L.Term s) := by
  rw [← SetLike.coe_sort_coe, coe_closure_eq_range_term_realize]
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ lift.{max u w, w} #↑(range (Term.realize Subtype.val)) ≤ #(Term L ↑s)

Next tactic:
rw [← Cardinal.lift_id'.{w, max u w} #(L.Term s)]
theorem lift_card_closure_le_card_term : Cardinal.lift.{max u w} #(closure L s) ≤ #(L.Term s) := by
  rw [← SetLike.coe_sort_coe, coe_closure_eq_range_term_realize]
  rw [← Cardinal.lift_id'.{w, max u w} #(L.Term s)]
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ lift.{max u w, w} #↑(range (Term.realize Subtype.val)) ≤ lift.{w, max u w} #(Term L ↑s)

Next tactic:
exact Cardinal.mk_range_le_lift
theorem lift_card_closure_le :
    Cardinal.lift.{u, w} #(closure L s) ≤
      max ℵ₀ (Cardinal.lift.{u, w} #s + Cardinal.lift.{w, u} #(Σi, L.Functions i)) := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ lift.{u, w} #↥(LowerAdjoint.toFun (closure L) s) ≤ max ℵ₀ (lift.{u, w} #↑s + lift.{w, u} #((i : ℕ) × Functions L i))

Next tactic:
rw [← lift_umax]
theorem lift_card_closure_le :
    Cardinal.lift.{u, w} #(closure L s) ≤
      max ℵ₀ (Cardinal.lift.{u, w} #s + Cardinal.lift.{w, u} #(Σi, L.Functions i)) := by
  rw [← lift_umax]
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ lift.{max w u, w} #↥(LowerAdjoint.toFun (closure L) s) ≤
    max ℵ₀ (lift.{max w u, w} #↑s + lift.{w, u} #((i : ℕ) × Functions L i))

Next tactic:
refine' lift_card_closure_le_card_term.trans (Term.card_le.trans _)
theorem lift_card_closure_le :
    Cardinal.lift.{u, w} #(closure L s) ≤
      max ℵ₀ (Cardinal.lift.{u, w} #s + Cardinal.lift.{w, u} #(Σi, L.Functions i)) := by
  rw [← lift_umax]
  refine' lift_card_closure_le_card_term.trans (Term.card_le.trans _)
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ max ℵ₀ #(↑s ⊕ (i : ℕ) × Functions L i) ≤ max ℵ₀ (lift.{max w u, w} #↑s + lift.{w, u} #((i : ℕ) × Functions L i))

Next tactic:
rw [mk_sum, lift_umax.{w, u}]
theorem _root_.Set.Countable.substructure_closure
    [Countable (Σl, L.Functions l)] (h : s.Countable) : Countable.{w + 1} (closure L s) := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
S : Substructure L M
s : Set M
inst✝ : Countable ((l : ℕ) × Functions L l)
h : Set.Countable s
⊢ Countable ↥(LowerAdjoint.toFun (closure L) s)

Next tactic:
haveI : Countable s := h.to_subtype
theorem _root_.Set.Countable.substructure_closure
    [Countable (Σl, L.Functions l)] (h : s.Countable) : Countable.{w + 1} (closure L s) := by
  haveI : Countable s := h.to_subtype
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
S : Substructure L M
s : Set M
inst✝ : Countable ((l : ℕ) × Functions L l)
h : Set.Countable s
this : Countable ↑s
⊢ Countable ↥(LowerAdjoint.toFun (closure L) s)

Next tactic:
rw [← mk_le_aleph0_iff, ← lift_le_aleph0]
theorem _root_.Set.Countable.substructure_closure
    [Countable (Σl, L.Functions l)] (h : s.Countable) : Countable.{w + 1} (closure L s) := by
  haveI : Countable s := h.to_subtype
  rw [← mk_le_aleph0_iff, ← lift_le_aleph0]
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
S : Substructure L M
s : Set M
inst✝ : Countable ((l : ℕ) × Functions L l)
h : Set.Countable s
this : Countable ↑s
⊢ lift.{?u.36828, w} #↥(LowerAdjoint.toFun (closure L) s) ≤ ℵ₀

Next tactic:
exact lift_card_closure_le_card_term.trans mk_le_aleph0
/-- If `s` is a dense set in a structure `M`, `Substructure.closure L s = ⊤`, then in order to prove
that some predicate `p` holds for all `x : M` it suffices to verify `p x` for `x ∈ s`, and verify
that `p` is preserved under function symbols. -/
@[elab_as_elim]
theorem dense_induction {p : M → Prop} (x : M) {s : Set M} (hs : closure L s = ⊤)
    (Hs : ∀ x ∈ s, p x) (Hfun : ∀ {n : ℕ} (f : L.Functions n), ClosedUnder f (setOf p)) : p x := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s✝ : Set M
p : M → Prop
x : M
s : Set M
hs : LowerAdjoint.toFun (closure L) s = ⊤
Hs : ∀ x ∈ s, p x
Hfun : ∀ {n : ℕ} (f : Functions L n), ClosedUnder f (setOf p)
⊢ p x

Next tactic:
have : ∀ x ∈ closure L s, p x := fun x hx => closure_induction hx Hs fun {n} => Hfun
/-- If `s` is a dense set in a structure `M`, `Substructure.closure L s = ⊤`, then in order to prove
that some predicate `p` holds for all `x : M` it suffices to verify `p x` for `x ∈ s`, and verify
that `p` is preserved under function symbols. -/
@[elab_as_elim]
theorem dense_induction {p : M → Prop} (x : M) {s : Set M} (hs : closure L s = ⊤)
    (Hs : ∀ x ∈ s, p x) (Hfun : ∀ {n : ℕ} (f : L.Functions n), ClosedUnder f (setOf p)) : p x := by
  have : ∀ x ∈ closure L s, p x := fun x hx => closure_induction hx Hs fun {n} => Hfun
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s✝ : Set M
p : M → Prop
x : M
s : Set M
hs : LowerAdjoint.toFun (closure L) s = ⊤
Hs : ∀ x ∈ s, p x
Hfun : ∀ {n : ℕ} (f : Functions L n), ClosedUnder f (setOf p)
this : ∀ x ∈ LowerAdjoint.toFun (closure L) s, p x
⊢ p x

Next tactic:
simpa [hs] using this x
instance small_bot : Small.{u} (⊥ : L.Substructure M) := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ Small.{u, w} ↥⊥

Next tactic:
rw [← closure_empty]
instance small_bot : Small.{u} (⊥ : L.Substructure M) := by
  rw [← closure_empty]
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
⊢ Small.{u, w} ↥(LowerAdjoint.toFun (closure L) ∅)

Next tactic:
haveI : Small.{u} (∅ : Set M) := small_subsingleton _
instance small_bot : Small.{u} (⊥ : L.Substructure M) := by
  rw [← closure_empty]
  haveI : Small.{u} (∅ : Set M) := small_subsingleton _
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
S : Substructure L M
s : Set M
this : Small.{u, w} ↑∅
⊢ Small.{u, w} ↥(LowerAdjoint.toFun (closure L) ∅)

Next tactic:
exact Substructure.small_closure