l3lab/ntp-mathlib huggingface dataset:
theorem Products.span_nil_eq_top :
    Submodule.span ℤ (eval ({fun _ ↦ false} : Set (I → Bool)) '' {nil}) = ⊤ := by
  rw [Set.image_singleton, eq_top_iff]
  intro f _
  rw [Submodule.mem_span_singleton]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
f : LocallyConstant ↑{fun x => false} ℤ
a✝ : f ∈ ⊤
⊢ ∃ a, a • eval {fun x => false} nil = f

Next tactic:
refine ⟨f default, ?_⟩
theorem Products.span_nil_eq_top :
    Submodule.span ℤ (eval ({fun _ ↦ false} : Set (I → Bool)) '' {nil}) = ⊤ := by
  rw [Set.image_singleton, eq_top_iff]
  intro f _
  rw [Submodule.mem_span_singleton]
  refine ⟨f default, ?_⟩
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
f : LocallyConstant ↑{fun x => false} ℤ
a✝ : f ∈ ⊤
⊢ f default • eval {fun x => false} nil = f

Next tactic:
simp only [eval, List.map, List.prod_nil, zsmul_eq_mul, mul_one]
theorem Products.span_nil_eq_top :
    Submodule.span ℤ (eval ({fun _ ↦ false} : Set (I → Bool)) '' {nil}) = ⊤ := by
  rw [Set.image_singleton, eq_top_iff]
  intro f _
  rw [Submodule.mem_span_singleton]
  refine ⟨f default, ?_⟩
  simp only [eval, List.map, List.prod_nil, zsmul_eq_mul, mul_one]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
f : LocallyConstant ↑{fun x => false} ℤ
a✝ : f ∈ ⊤
⊢ ↑(f default) = f

Next tactic:
ext x
theorem Products.span_nil_eq_top :
    Submodule.span ℤ (eval ({fun _ ↦ false} : Set (I → Bool)) '' {nil}) = ⊤ := by
  rw [Set.image_singleton, eq_top_iff]
  intro f _
  rw [Submodule.mem_span_singleton]
  refine ⟨f default, ?_⟩
  simp only [eval, List.map, List.prod_nil, zsmul_eq_mul, mul_one]
  ext x
  

Proof state:
case h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
f : LocallyConstant ↑{fun x => false} ℤ
a✝ : f ∈ ⊤
x : ↑{fun x => false}
⊢ ↑(f default) x = f x

Next tactic:
obtain rfl : x = default := by simp only [Set.default_coe_singleton, eq_iff_true_of_subsingleton]
theorem Products.span_nil_eq_top :
    Submodule.span ℤ (eval ({fun _ ↦ false} : Set (I → Bool)) '' {nil}) = ⊤ := by
  rw [Set.image_singleton, eq_top_iff]
  intro f _
  rw [Submodule.mem_span_singleton]
  refine ⟨f default, ?_⟩
  simp only [eval, List.map, List.prod_nil, zsmul_eq_mul, mul_one]
  ext x
  obtain rfl : x = default := by 

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
f : LocallyConstant ↑{fun x => false} ℤ
a✝ : f ∈ ⊤
x : ↑{fun x => false}
⊢ x = default

Next tactic:
simp only [Set.default_coe_singleton, eq_iff_true_of_subsingleton]
theorem Products.span_nil_eq_top :
    Submodule.span ℤ (eval ({fun _ ↦ false} : Set (I → Bool)) '' {nil}) = ⊤ := by
  rw [Set.image_singleton, eq_top_iff]
  intro f _
  rw [Submodule.mem_span_singleton]
  refine ⟨f default, ?_⟩
  simp only [eval, List.map, List.prod_nil, zsmul_eq_mul, mul_one]
  ext x
  obtain rfl : x = default := by simp only [Set.default_coe_singleton, eq_iff_true_of_subsingleton]
  

Proof state:
case h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
f : LocallyConstant ↑{fun x => false} ℤ
a✝ : f ∈ ⊤
⊢ ↑(f default) default = f default

Next tactic:
rfl
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
⊢ ∀ (a : { l // Products.isGood {fun x => false} l }), a = default

Next tactic:
intro ⟨⟨l, hl⟩, hll⟩
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
⊢ { val := { val := l, property := hl }, property := hll } = default

Next tactic:
ext
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    

Proof state:
case a
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
⊢ ↑{ val := { val := l, property := hl }, property := hll } = ↑default

Next tactic:
apply Subtype.ext
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    apply Subtype.ext
    

Proof state:
case a.a
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
⊢ ↑↑{ val := { val := l, property := hl }, property := hll } = ↑↑default

Next tactic:
apply (List.Lex.nil_left_or_eq_nil l (r := (·<·))).resolve_left
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    apply Subtype.ext
    apply (List.Lex.nil_left_or_eq_nil l (r := (·<·))).resolve_left
    

Proof state:
case a.a
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
⊢ ¬List.Lex (fun x x_1 => x < x_1) [] l

Next tactic:
intro _
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    apply Subtype.ext
    apply (List.Lex.nil_left_or_eq_nil l (r := (·<·))).resolve_left
    intro _
    

Proof state:
case a.a
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
a✝ : List.Lex (fun x x_1 => x < x_1) [] l
⊢ False

Next tactic:
apply hll
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    apply Subtype.ext
    apply (List.Lex.nil_left_or_eq_nil l (r := (·<·))).resolve_left
    intro _
    apply hll
    

Proof state:
case a.a
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
a✝ : List.Lex (fun x x_1 => x < x_1) [] l
⊢ Products.eval {fun x => false} { val := l, property := hl } ∈
    Submodule.span ℤ (Products.eval {fun x => false} '' {m | m < { val := l, property := hl }})

Next tactic:
have he : {Products.nil} ⊆ {m | m < ⟨l,hl⟩}
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    apply Subtype.ext
    apply (List.Lex.nil_left_or_eq_nil l (r := (·<·))).resolve_left
    intro _
    apply hll
    have he : {Products.nil} ⊆ {m | m < ⟨l,hl⟩}
    · 

Proof state:
case he
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
a✝ : List.Lex (fun x x_1 => x < x_1) [] l
⊢ {Products.nil} ⊆ {m | m < { val := l, property := hl }}

Next tactic:
simpa only [Products.nil, Products.lt_iff_lex_lt, Set.singleton_subset_iff, Set.mem_setOf_eq]
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    apply Subtype.ext
    apply (List.Lex.nil_left_or_eq_nil l (r := (·<·))).resolve_left
    intro _
    apply hll
    have he : {Products.nil} ⊆ {m | m < ⟨l,hl⟩}
    · simpa only [Products.nil, Products.lt_iff_lex_lt, Set.singleton_subset_iff, Set.mem_setOf_eq]
    

Proof state:
case a.a
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
a✝ : List.Lex (fun x x_1 => x < x_1) [] l
he : {Products.nil} ⊆ {m | m < { val := l, property := hl }}
⊢ Products.eval {fun x => false} { val := l, property := hl } ∈
    Submodule.span ℤ (Products.eval {fun x => false} '' {m | m < { val := l, property := hl }})

Next tactic:
apply Submodule.span_mono (Set.image_subset _ he)
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    apply Subtype.ext
    apply (List.Lex.nil_left_or_eq_nil l (r := (·<·))).resolve_left
    intro _
    apply hll
    have he : {Products.nil} ⊆ {m | m < ⟨l,hl⟩}
    · simpa only [Products.nil, Products.lt_iff_lex_lt, Set.singleton_subset_iff, Set.mem_setOf_eq]
    apply Submodule.span_mono (Set.image_subset _ he)
    

Proof state:
case a.a.a
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
a✝ : List.Lex (fun x x_1 => x < x_1) [] l
he : {Products.nil} ⊆ {m | m < { val := l, property := hl }}
⊢ Products.eval {fun x => false} { val := l, property := hl } ∈
    Submodule.span ℤ (Products.eval {fun x => false} '' {Products.nil})

Next tactic:
rw [Products.span_nil_eq_top]
/-- There is a unique `GoodProducts` for the singleton `{fun _ ↦ false}`. -/
noncomputable
instance : Unique { l // Products.isGood ({fun _ ↦ false} : Set (I → Bool)) l } where
  default := ⟨Products.nil, Products.isGood_nil⟩
  uniq := by
    intro ⟨⟨l, hl⟩, hll⟩
    ext
    apply Subtype.ext
    apply (List.Lex.nil_left_or_eq_nil l (r := (·<·))).resolve_left
    intro _
    apply hll
    have he : {Products.nil} ⊆ {m | m < ⟨l,hl⟩}
    · simpa only [Products.nil, Products.lt_iff_lex_lt, Set.singleton_subset_iff, Set.mem_setOf_eq]
    apply Submodule.span_mono (Set.image_subset _ he)
    rw [Products.span_nil_eq_top]
    

Proof state:
case a.a.a
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : List I
hl : List.Chain' (fun x x_1 => x > x_1) l
hll : Products.isGood {fun x => false} { val := l, property := hl }
a✝ : List.Lex (fun x x_1 => x < x_1) [] l
he : {Products.nil} ⊆ {m | m < { val := l, property := hl }}
⊢ Products.eval {fun x => false} { val := l, property := hl } ∈ ⊤

Next tactic:
exact Submodule.mem_top
instance (α : Type*) [TopologicalSpace α] : NoZeroSMulDivisors ℤ (LocallyConstant α ℤ) := by
  

Proof state:
I : Type u
inst✝³ : Inhabited I
inst✝² : LinearOrder I
inst✝¹ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
α : Type u_1
inst✝ : TopologicalSpace α
⊢ NoZeroSMulDivisors ℤ (LocallyConstant α ℤ)

Next tactic:
constructor
instance (α : Type*) [TopologicalSpace α] : NoZeroSMulDivisors ℤ (LocallyConstant α ℤ) := by
  constructor
  

Proof state:
case eq_zero_or_eq_zero_of_smul_eq_zero
I : Type u
inst✝³ : Inhabited I
inst✝² : LinearOrder I
inst✝¹ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
α : Type u_1
inst✝ : TopologicalSpace α
⊢ ∀ {c : ℤ} {x : LocallyConstant α ℤ}, c • x = 0 → c = 0 ∨ x = 0

Next tactic:
intro c f h
instance (α : Type*) [TopologicalSpace α] : NoZeroSMulDivisors ℤ (LocallyConstant α ℤ) := by
  constructor
  intro c f h
  

Proof state:
case eq_zero_or_eq_zero_of_smul_eq_zero
I : Type u
inst✝³ : Inhabited I
inst✝² : LinearOrder I
inst✝¹ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
α : Type u_1
inst✝ : TopologicalSpace α
c : ℤ
f : LocallyConstant α ℤ
h : c • f = 0
⊢ c = 0 ∨ f = 0

Next tactic:
rw [or_iff_not_imp_left]
instance (α : Type*) [TopologicalSpace α] : NoZeroSMulDivisors ℤ (LocallyConstant α ℤ) := by
  constructor
  intro c f h
  rw [or_iff_not_imp_left]
  

Proof state:
case eq_zero_or_eq_zero_of_smul_eq_zero
I : Type u
inst✝³ : Inhabited I
inst✝² : LinearOrder I
inst✝¹ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
α : Type u_1
inst✝ : TopologicalSpace α
c : ℤ
f : LocallyConstant α ℤ
h : c • f = 0
⊢ ¬c = 0 → f = 0

Next tactic:
intro hc
instance (α : Type*) [TopologicalSpace α] : NoZeroSMulDivisors ℤ (LocallyConstant α ℤ) := by
  constructor
  intro c f h
  rw [or_iff_not_imp_left]
  intro hc
  

Proof state:
case eq_zero_or_eq_zero_of_smul_eq_zero
I : Type u
inst✝³ : Inhabited I
inst✝² : LinearOrder I
inst✝¹ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
α : Type u_1
inst✝ : TopologicalSpace α
c : ℤ
f : LocallyConstant α ℤ
h : c • f = 0
hc : ¬c = 0
⊢ f = 0

Next tactic:
ext x
instance (α : Type*) [TopologicalSpace α] : NoZeroSMulDivisors ℤ (LocallyConstant α ℤ) := by
  constructor
  intro c f h
  rw [or_iff_not_imp_left]
  intro hc
  ext x
  

Proof state:
case eq_zero_or_eq_zero_of_smul_eq_zero.h
I : Type u
inst✝³ : Inhabited I
inst✝² : LinearOrder I
inst✝¹ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
α : Type u_1
inst✝ : TopologicalSpace α
c : ℤ
f : LocallyConstant α ℤ
h : c • f = 0
hc : ¬c = 0
x : α
⊢ f x = 0 x

Next tactic:
apply mul_right_injective₀ hc
instance (α : Type*) [TopologicalSpace α] : NoZeroSMulDivisors ℤ (LocallyConstant α ℤ) := by
  constructor
  intro c f h
  rw [or_iff_not_imp_left]
  intro hc
  ext x
  apply mul_right_injective₀ hc
  

Proof state:
case eq_zero_or_eq_zero_of_smul_eq_zero.h.a
I : Type u
inst✝³ : Inhabited I
inst✝² : LinearOrder I
inst✝¹ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
α : Type u_1
inst✝ : TopologicalSpace α
c : ℤ
f : LocallyConstant α ℤ
h : c • f = 0
hc : ¬c = 0
x : α
⊢ (fun x => c * x) (f x) = (fun x => c * x) (0 x)

Next tactic:
simp [LocallyConstant.ext_iff] at h ⊢
instance (α : Type*) [TopologicalSpace α] : NoZeroSMulDivisors ℤ (LocallyConstant α ℤ) := by
  constructor
  intro c f h
  rw [or_iff_not_imp_left]
  intro hc
  ext x
  apply mul_right_injective₀ hc
  simp [LocallyConstant.ext_iff] at h ⊢
  

Proof state:
case eq_zero_or_eq_zero_of_smul_eq_zero.h.a
I : Type u
inst✝³ : Inhabited I
inst✝² : LinearOrder I
inst✝¹ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
α : Type u_1
inst✝ : TopologicalSpace α
c : ℤ
f : LocallyConstant α ℤ
hc : ¬c = 0
x : α
h : ∀ (x : α), ↑c x = 0 ∨ f x = 0
⊢ c = 0 ∨ f x = 0

Next tactic:
exact h x
theorem GoodProducts.linearIndependentSingleton :
    LinearIndependent ℤ (eval ({fun _ ↦ false} : Set (I → Bool))) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
⊢ LinearIndependent ℤ (eval {fun x => false})

Next tactic:
refine linearIndependent_unique (eval ({fun _ ↦ false} : Set (I → Bool))) ?_
theorem GoodProducts.linearIndependentSingleton :
    LinearIndependent ℤ (eval ({fun _ ↦ false} : Set (I → Bool))) := by
  refine linearIndependent_unique (eval ({fun _ ↦ false} : Set (I → Bool))) ?_
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
⊢ eval {fun x => false} default ≠ 0

Next tactic:
simp only [eval, Products.eval, List.map, List.prod_nil, ne_eq, one_ne_zero, not_false_eq_true]
theorem contained_eq_proj (o : Ordinal) (h : contained C o) :
    C = π C (ord I · < o) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
h : contained C o
⊢ C = π C fun x => ord I x < o

Next tactic:
have := proj_prop_eq_self C (ord I · < o)
theorem contained_eq_proj (o : Ordinal) (h : contained C o) :
    C = π C (ord I · < o) := by
  have := proj_prop_eq_self C (ord I · < o)
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
h : contained C o
this : (∀ (i : I), ∀ x ∈ C, x i ≠ false → ord I i < o) → (π C fun x => ord I x < o) = C
⊢ C = π C fun x => ord I x < o

Next tactic:
simp [π, Bool.not_eq_false] at this
theorem contained_eq_proj (o : Ordinal) (h : contained C o) :
    C = π C (ord I · < o) := by
  have := proj_prop_eq_self C (ord I · < o)
  simp [π, Bool.not_eq_false] at this
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
h : contained C o
this : (∀ (i : I), ∀ x ∈ C, x i = true → ord I i < o) → (fun a => Proj (fun x => ord I x < o) a) '' C = C
⊢ C = π C fun x => ord I x < o

Next tactic:
exact (this (fun i x hx ↦ h x hx i)).symm
theorem contained_proj (o : Ordinal) : contained (π C (ord I · < o)) o := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
⊢ contained (π C fun x => ord I x < o) o

Next tactic:
intro x ⟨_, ⟨_, h⟩⟩ j hj
theorem contained_proj (o : Ordinal) : contained (π C (ord I · < o)) o := by
  intro x ⟨_, ⟨_, h⟩⟩ j hj
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
x w✝ : I → Bool
left✝ : w✝ ∈ C
h : Proj (fun x => ord I x < o) w✝ = x
j : I
hj : x j = true
⊢ ord I j < o

Next tactic:
dsimp (config := { unfoldPartialApp := true }) [Proj] at h
theorem contained_proj (o : Ordinal) : contained (π C (ord I · < o)) o := by
  intro x ⟨_, ⟨_, h⟩⟩ j hj
  dsimp (config := { unfoldPartialApp := true }) [Proj] at h
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
x w✝ : I → Bool
left✝ : w✝ ∈ C
h : (fun i => if ord I i < o then w✝ i else false) = x
j : I
hj : x j = true
⊢ ord I j < o

Next tactic:
simp only [← congr_fun h j, Bool.ite_eq_true_distrib, if_false_right_eq_and] at hj
theorem contained_proj (o : Ordinal) : contained (π C (ord I · < o)) o := by
  intro x ⟨_, ⟨_, h⟩⟩ j hj
  dsimp (config := { unfoldPartialApp := true }) [Proj] at h
  simp only [← congr_fun h j, Bool.ite_eq_true_distrib, if_false_right_eq_and] at hj
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
x w✝ : I → Bool
left✝ : w✝ ∈ C
h : (fun i => if ord I i < o then w✝ i else false) = x
j : I
hj : ord I j < o ∧ w✝ j = true
⊢ ord I j < o

Next tactic:
exact hj.1
theorem coe_πs (o : Ordinal) (f : LocallyConstant (π C (ord I · < o)) ℤ) :
    πs C o f = f ∘ ProjRestrict C (ord I · < o) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
f : LocallyConstant ↑(π C fun x => ord I x < o) ℤ
⊢ ⇑((πs C o) f) = ⇑f ∘ ProjRestrict C fun x => ord I x < o

Next tactic:
simp only [πs_apply, continuous_projRestrict, LocallyConstant.coe_comap]
theorem coe_πs' {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) (f : LocallyConstant (π C (ord I · < o₁)) ℤ) :
    (πs' C h f).toFun = f.toFun ∘ (ProjRestricts C (fun _ hh ↦ lt_of_lt_of_le hh h)) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
f : LocallyConstant ↑(π C fun x => ord I x < o₁) ℤ
⊢ ((πs' C h) f).toFun = f.toFun ∘ ProjRestricts C (_ : ∀ (x : I), ord I x < o₁ → ord I x < o₂)

Next tactic:
simp only [πs'_apply, LocallyConstant.toFun_eq_coe, continuous_projRestricts,
    LocallyConstant.coe_comap]
theorem eval_πs {l : Products I} {o : Ordinal} (hlt : ∀ i ∈ l.val, ord I i < o) :
    πs C o (l.eval (π C (ord I · < o))) = l.eval C := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : Products I
o : Ordinal.{u}
hlt : ∀ i ∈ ↑l, ord I i < o
⊢ (πs C o) (eval (π C fun x => ord I x < o) l) = eval C l

Next tactic:
simpa only [← LocallyConstant.coe_inj, πs_apply, continuous_projRestrict,
    LocallyConstant.coe_comap] using evalFacProp C (ord I · < o) hlt
theorem eval_πs' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hlt : ∀ i ∈ l.val, ord I i < o₁) :
    πs' C h (l.eval (π C (ord I · < o₁))) = l.eval (π C (ord I · < o₂)) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hlt : ∀ i ∈ ↑l, ord I i < o₁
⊢ (πs' C h) (eval (π C fun x => ord I x < o₁) l) = eval (π C fun x => ord I x < o₂) l

Next tactic:
rw [← LocallyConstant.coe_inj, ← LocallyConstant.toFun_eq_coe]
theorem eval_πs' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hlt : ∀ i ∈ l.val, ord I i < o₁) :
    πs' C h (l.eval (π C (ord I · < o₁))) = l.eval (π C (ord I · < o₂)) := by
  rw [← LocallyConstant.coe_inj, ← LocallyConstant.toFun_eq_coe]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hlt : ∀ i ∈ ↑l, ord I i < o₁
⊢ ((πs' C h) (eval (π C fun x => ord I x < o₁) l)).toFun = ⇑(eval (π C fun x => ord I x < o₂) l)

Next tactic:
simp only [πs'_apply, LocallyConstant.toFun_eq_coe, continuous_projRestricts,
    LocallyConstant.coe_comap]
theorem eval_πs' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hlt : ∀ i ∈ l.val, ord I i < o₁) :
    πs' C h (l.eval (π C (ord I · < o₁))) = l.eval (π C (ord I · < o₂)) := by
  rw [← LocallyConstant.coe_inj, ← LocallyConstant.toFun_eq_coe]
  simp only [πs'_apply, LocallyConstant.toFun_eq_coe, continuous_projRestricts,
    LocallyConstant.coe_comap]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hlt : ∀ i ∈ ↑l, ord I i < o₁
⊢ ⇑(eval (π C fun x => ord I x < o₁) l) ∘ ProjRestricts C (_ : ∀ (x : I), ord I x < o₁ → ord I x < o₂) =
    ⇑(eval (π C fun x => ord I x < o₂) l)

Next tactic:
exact evalFacProps C (fun (i : I) ↦ ord I i < o₁) (fun (i : I) ↦ ord I i < o₂) hlt _