l3lab/ntp-mathlib huggingface dataset:
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    exists Pi.tail f
    constructor
    · apply xs_ih
    · 

Proof state:
case cons.right.right
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
⊢ f = Pi.cons xs_hd xs_tl (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl)) (Pi.tail f)

Next tactic:
ext x h
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    exists Pi.tail f
    constructor
    · apply xs_ih
    · ext x h
      

Proof state:
case cons.right.right.h.h
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
x : α
h : x ∈ xs_hd :: xs_tl
⊢ f x h = Pi.cons xs_hd xs_tl (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl)) (Pi.tail f) x h

Next tactic:
simp only [Pi.cons]
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    exists Pi.tail f
    constructor
    · apply xs_ih
    · ext x h
      simp only [Pi.cons]
      

Proof state:
case cons.right.right.h.h
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
x : α
h : x ∈ xs_hd :: xs_tl
⊢ f x h =
    if h' : x = xs_hd then cast (_ : β xs_hd = β x) (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl))
    else Pi.tail f x (_ : x ∈ xs_tl)

Next tactic:
split_ifs
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    exists Pi.tail f
    constructor
    · apply xs_ih
    · ext x h
      simp only [Pi.cons]
      split_ifs
      · 

Proof state:
case pos
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
x : α
h : x ∈ xs_hd :: xs_tl
h✝ : x = xs_hd
⊢ f x h = cast (_ : β xs_hd = β x) (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl))

Next tactic:
subst x
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    exists Pi.tail f
    constructor
    · apply xs_ih
    · ext x h
      simp only [Pi.cons]
      split_ifs
      · subst x
        

Proof state:
case pos
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
h : xs_hd ∈ xs_hd :: xs_tl
⊢ f xs_hd h = cast (_ : β xs_hd = β xs_hd) (f xs_hd (_ : xs_hd ∈ xs_hd :: xs_tl))

Next tactic:
rfl
theorem mem_pi {β : α → Type _} [FinEnum α] [∀ a, FinEnum (β a)] (xs : List α)
    (f : ∀ a, a ∈ xs → β a) : f ∈ pi xs fun x => toList (β x) := by
  induction' xs with xs_hd xs_tl xs_ih <;> simp [pi, -List.map_eq_map, monad_norm, functor_norm]
  · ext a ⟨⟩
  · exists Pi.cons xs_hd xs_tl (f _ (List.mem_cons_self _ _))
    constructor
    exact ⟨_, rfl⟩
    exists Pi.tail f
    constructor
    · apply xs_ih
    · ext x h
      simp only [Pi.cons]
      split_ifs
      · subst x
        rfl
      · 

Proof state:
case neg
α : Type u
β✝ : α → Type v
β : α → Type (max u u_1)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
xs_hd : α
xs_tl : List α
xs_ih : ∀ (f : (a : α) → a ∈ xs_tl → β a), f ∈ pi xs_tl fun x => toList (β x)
f : (a : α) → a ∈ xs_hd :: xs_tl → β a
x : α
h : x ∈ xs_hd :: xs_tl
h✝ : ¬x = xs_hd
⊢ f x h = Pi.tail f x (_ : x ∈ xs_tl)

Next tactic:
rfl
theorem pi.mem_enum {β : α → Type (max u v)} [FinEnum α] [∀ a, FinEnum (β a)] (f : ∀ a, β a) :
    f ∈ pi.enum.{u, v} β := by 

Proof state:
α : Type u
β✝ : α → Type v
β : α → Type (max u v)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
f : (a : α) → β a
⊢ f ∈ enum β

Next tactic:
simp [pi.enum]
theorem pi.mem_enum {β : α → Type (max u v)} [FinEnum α] [∀ a, FinEnum (β a)] (f : ∀ a, β a) :
    f ∈ pi.enum.{u, v} β := by simp [pi.enum]; 

Proof state:
α : Type u
β✝ : α → Type v
β : α → Type (max u v)
inst✝¹ : FinEnum α
inst✝ : (a : α) → FinEnum (β a)
f : (a : α) → β a
⊢ ∃ a ∈ pi (toList α) fun x => toList (β x), (fun x => a x (_ : x ∈ toList α)) = f

Next tactic:
refine' ⟨fun a _ => f a, mem_pi _ _, rfl⟩
instance pfunFinEnum (p : Prop) [Decidable p] (α : p → Type) [∀ hp, FinEnum (α hp)] :
    FinEnum (∀ hp : p, α hp) :=
  if hp : p then
    ofList ((toList (α hp)).map fun x _ => x) (by 

Proof state:
α✝ : Type u
β : α✝ → Type v
p : Prop
inst✝¹ : Decidable p
α : p → Type
inst✝ : (hp : p) → FinEnum (α hp)
hp : p
⊢ ∀ (x : (hp : p) → α hp), x ∈ List.map (fun x x_1 => x) (toList (α hp))

Next tactic:
intro x
instance pfunFinEnum (p : Prop) [Decidable p] (α : p → Type) [∀ hp, FinEnum (α hp)] :
    FinEnum (∀ hp : p, α hp) :=
  if hp : p then
    ofList ((toList (α hp)).map fun x _ => x) (by intro x; 

Proof state:
α✝ : Type u
β : α✝ → Type v
p : Prop
inst✝¹ : Decidable p
α : p → Type
inst✝ : (hp : p) → FinEnum (α hp)
hp : p
x : (hp : p) → α hp
⊢ x ∈ List.map (fun x x_1 => x) (toList (α hp))

Next tactic:
simp
instance pfunFinEnum (p : Prop) [Decidable p] (α : p → Type) [∀ hp, FinEnum (α hp)] :
    FinEnum (∀ hp : p, α hp) :=
  if hp : p then
    ofList ((toList (α hp)).map fun x _ => x) (by intro x; simp; 

Proof state:
α✝ : Type u
β : α✝ → Type v
p : Prop
inst✝¹ : Decidable p
α : p → Type
inst✝ : (hp : p) → FinEnum (α hp)
hp : p
x : (hp : p) → α hp
⊢ ∃ a, (fun x => a) = x

Next tactic:
exact ⟨x hp, rfl⟩
instance pfunFinEnum (p : Prop) [Decidable p] (α : p → Type) [∀ hp, FinEnum (α hp)] :
    FinEnum (∀ hp : p, α hp) :=
  if hp : p then
    ofList ((toList (α hp)).map fun x _ => x) (by intro x; simp; exact ⟨x hp, rfl⟩)
  else ofList [fun hp' => (hp hp').elim] (by 

Proof state:
α✝ : Type u
β : α✝ → Type v
p : Prop
inst✝¹ : Decidable p
α : p → Type
inst✝ : (hp : p) → FinEnum (α hp)
hp : ¬p
⊢ ∀ (x : (hp : p) → α hp), x ∈ [fun hp' => (_ : False).elim]

Next tactic:
intro
instance pfunFinEnum (p : Prop) [Decidable p] (α : p → Type) [∀ hp, FinEnum (α hp)] :
    FinEnum (∀ hp : p, α hp) :=
  if hp : p then
    ofList ((toList (α hp)).map fun x _ => x) (by intro x; simp; exact ⟨x hp, rfl⟩)
  else ofList [fun hp' => (hp hp').elim] (by intro; 

Proof state:
α✝ : Type u
β : α✝ → Type v
p : Prop
inst✝¹ : Decidable p
α : p → Type
inst✝ : (hp : p) → FinEnum (α hp)
hp : ¬p
x✝ : (hp : p) → α hp
⊢ x✝ ∈ [fun hp' => (_ : False).elim]

Next tactic:
simp
instance pfunFinEnum (p : Prop) [Decidable p] (α : p → Type) [∀ hp, FinEnum (α hp)] :
    FinEnum (∀ hp : p, α hp) :=
  if hp : p then
    ofList ((toList (α hp)).map fun x _ => x) (by intro x; simp; exact ⟨x hp, rfl⟩)
  else ofList [fun hp' => (hp hp').elim] (by intro; simp; 

Proof state:
α✝ : Type u
β : α✝ → Type v
p : Prop
inst✝¹ : Decidable p
α : p → Type
inst✝ : (hp : p) → FinEnum (α hp)
hp : ¬p
x✝ : (hp : p) → α hp
⊢ x✝ = fun hp' => (_ : False).elim

Next tactic:
ext hp'
instance pfunFinEnum (p : Prop) [Decidable p] (α : p → Type) [∀ hp, FinEnum (α hp)] :
    FinEnum (∀ hp : p, α hp) :=
  if hp : p then
    ofList ((toList (α hp)).map fun x _ => x) (by intro x; simp; exact ⟨x hp, rfl⟩)
  else ofList [fun hp' => (hp hp').elim] (by intro; simp; ext hp'; 

Proof state:
case h
α✝ : Type u
β : α✝ → Type v
p : Prop
inst✝¹ : Decidable p
α : p → Type
inst✝ : (hp : p) → FinEnum (α hp)
hp : ¬p
x✝ : (hp : p) → α hp
hp' : p
⊢ x✝ hp' = (_ : False).elim

Next tactic:
cases hp hp'
@[to_additive]
theorem Set.OrdConnected.smul (hs : s.OrdConnected) : (a • s).OrdConnected := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
hs : OrdConnected s
⊢ OrdConnected (a • s)

Next tactic:
rw [← hs.upperClosure_inter_lowerClosure, smul_set_inter]
@[to_additive]
theorem Set.OrdConnected.smul (hs : s.OrdConnected) : (a • s).OrdConnected := by
  rw [← hs.upperClosure_inter_lowerClosure, smul_set_inter]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
hs : OrdConnected s
⊢ OrdConnected (a • ↑(upperClosure s) ∩ a • ↑(lowerClosure s))

Next tactic:
exact (upperClosure _).upper.smul.ordConnected.inter (lowerClosure _).lower.smul.ordConnected
@[to_additive]
theorem IsUpperSet.mul_left (ht : IsUpperSet t) : IsUpperSet (s * t) := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
ht : IsUpperSet t
⊢ IsUpperSet (s * t)

Next tactic:
rw [← smul_eq_mul, ← Set.iUnion_smul_set]
@[to_additive]
theorem IsUpperSet.mul_left (ht : IsUpperSet t) : IsUpperSet (s * t) := by
  rw [← smul_eq_mul, ← Set.iUnion_smul_set]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
ht : IsUpperSet t
⊢ IsUpperSet (⋃ a ∈ s, a • t)

Next tactic:
exact isUpperSet_iUnion₂ fun x _ ↦ ht.smul
@[to_additive]
theorem IsUpperSet.mul_right (hs : IsUpperSet s) : IsUpperSet (s * t) := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
hs : IsUpperSet s
⊢ IsUpperSet (s * t)

Next tactic:
rw [mul_comm]
@[to_additive]
theorem IsUpperSet.mul_right (hs : IsUpperSet s) : IsUpperSet (s * t) := by
  rw [mul_comm]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
hs : IsUpperSet s
⊢ IsUpperSet (t * s)

Next tactic:
exact hs.mul_left
@[to_additive]
theorem IsUpperSet.div_left (ht : IsUpperSet t) : IsLowerSet (s / t) := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
ht : IsUpperSet t
⊢ IsLowerSet (s / t)

Next tactic:
rw [div_eq_mul_inv]
@[to_additive]
theorem IsUpperSet.div_left (ht : IsUpperSet t) : IsLowerSet (s / t) := by
  rw [div_eq_mul_inv]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
ht : IsUpperSet t
⊢ IsLowerSet (s * t⁻¹)

Next tactic:
exact ht.inv.mul_left
@[to_additive]
theorem IsUpperSet.div_right (hs : IsUpperSet s) : IsUpperSet (s / t) := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
hs : IsUpperSet s
⊢ IsUpperSet (s / t)

Next tactic:
rw [div_eq_mul_inv]
@[to_additive]
theorem IsUpperSet.div_right (hs : IsUpperSet s) : IsUpperSet (s / t) := by
  rw [div_eq_mul_inv]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
hs : IsUpperSet s
⊢ IsUpperSet (s * t⁻¹)

Next tactic:
exact hs.mul_right
@[to_additive]
private theorem one_mul (s : UpperSet α) : 1 * s = s :=
  SetLike.coe_injective <|
    (subset_mul_right _ left_mem_Ici).antisymm' <| by
      

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s✝ t : Set α
a : α
s : UpperSet α
⊢ Set.Ici 1 * ↑s ⊆ ↑s

Next tactic:
rw [← smul_eq_mul, ← Set.iUnion_smul_set]
@[to_additive]
private theorem one_mul (s : UpperSet α) : 1 * s = s :=
  SetLike.coe_injective <|
    (subset_mul_right _ left_mem_Ici).antisymm' <| by
      rw [← smul_eq_mul, ← Set.iUnion_smul_set]
      

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s✝ t : Set α
a : α
s : UpperSet α
⊢ ⋃ a ∈ Set.Ici 1, a • ↑s ⊆ ↑s

Next tactic:
exact Set.iUnion₂_subset fun _ ↦ s.upper.smul_subset
@[to_additive]
instance : CommMonoid (UpperSet α) :=
  { UpperSet.commSemigroup with
    one := 1
    one_mul := one_mul
    mul_one := fun s ↦ by
      

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s✝ t : Set α
a : α
src✝ : CommSemigroup (UpperSet α) := commSemigroup
s : UpperSet α
⊢ s * 1 = s

Next tactic:
rw [mul_comm]
@[to_additive]
instance : CommMonoid (UpperSet α) :=
  { UpperSet.commSemigroup with
    one := 1
    one_mul := one_mul
    mul_one := fun s ↦ by
      rw [mul_comm]
      

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s✝ t : Set α
a : α
src✝ : CommSemigroup (UpperSet α) := commSemigroup
s : UpperSet α
⊢ 1 * s = s

Next tactic:
exact one_mul _
@[to_additive]
private theorem one_mul (s : LowerSet α) : 1 * s = s :=
  SetLike.coe_injective <|
    (subset_mul_right _ right_mem_Iic).antisymm' <| by
      

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s✝ t : Set α
a : α
s : LowerSet α
⊢ Set.Iic 1 * ↑s ⊆ ↑s

Next tactic:
rw [← smul_eq_mul, ← Set.iUnion_smul_set]
@[to_additive]
private theorem one_mul (s : LowerSet α) : 1 * s = s :=
  SetLike.coe_injective <|
    (subset_mul_right _ right_mem_Iic).antisymm' <| by
      rw [← smul_eq_mul, ← Set.iUnion_smul_set]
      

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s✝ t : Set α
a : α
s : LowerSet α
⊢ ⋃ a ∈ Set.Iic 1, a • ↑s ⊆ ↑s

Next tactic:
exact Set.iUnion₂_subset fun _ ↦ s.lower.smul_subset
@[to_additive]
instance : CommMonoid (LowerSet α) :=
  { LowerSet.commSemigroup with
    one := 1
    one_mul := one_mul
    mul_one := fun s ↦ by
      

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s✝ t : Set α
a : α
src✝ : CommSemigroup (LowerSet α) := commSemigroup
s : LowerSet α
⊢ s * 1 = s

Next tactic:
rw [mul_comm]
@[to_additive]
instance : CommMonoid (LowerSet α) :=
  { LowerSet.commSemigroup with
    one := 1
    one_mul := one_mul
    mul_one := fun s ↦ by
      rw [mul_comm]
      

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s✝ t : Set α
a : α
src✝ : CommSemigroup (LowerSet α) := commSemigroup
s : LowerSet α
⊢ 1 * s = s

Next tactic:
exact one_mul _
@[to_additive]
theorem mul_upperClosure : s * upperClosure t = upperClosure (s * t) := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ s * ↑(upperClosure t) = ↑(upperClosure (s * t))

Next tactic:
simp_rw [← smul_eq_mul, ← Set.iUnion_smul_set, upperClosure_iUnion, upperClosure_smul,
    UpperSet.coe_iInf₂]
@[to_additive]
theorem mul_upperClosure : s * upperClosure t = upperClosure (s * t) := by
  simp_rw [← smul_eq_mul, ← Set.iUnion_smul_set, upperClosure_iUnion, upperClosure_smul,
    UpperSet.coe_iInf₂]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ ⋃ a ∈ s, a • ↑(upperClosure t) = ⋃ i ∈ s, ↑(i • upperClosure t)

Next tactic:
rfl
@[to_additive]
theorem mul_lowerClosure : s * lowerClosure t = lowerClosure (s * t) := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ s * ↑(lowerClosure t) = ↑(lowerClosure (s * t))

Next tactic:
simp_rw [← smul_eq_mul, ← Set.iUnion_smul_set, lowerClosure_iUnion, lowerClosure_smul,
    LowerSet.coe_iSup₂]
@[to_additive]
theorem mul_lowerClosure : s * lowerClosure t = lowerClosure (s * t) := by
  simp_rw [← smul_eq_mul, ← Set.iUnion_smul_set, lowerClosure_iUnion, lowerClosure_smul,
    LowerSet.coe_iSup₂]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ ⋃ a ∈ s, a • ↑(lowerClosure t) = ⋃ i ∈ s, ↑(i • lowerClosure t)

Next tactic:
rfl
@[to_additive]
theorem upperClosure_mul : ↑(upperClosure s) * t = upperClosure (s * t) := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ ↑(upperClosure s) * t = ↑(upperClosure (s * t))

Next tactic:
simp_rw [mul_comm _ t]
@[to_additive]
theorem upperClosure_mul : ↑(upperClosure s) * t = upperClosure (s * t) := by
  simp_rw [mul_comm _ t]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ t * ↑(upperClosure s) = ↑(upperClosure (t * s))

Next tactic:
exact mul_upperClosure _ _
@[to_additive]
theorem lowerClosure_mul : ↑(lowerClosure s) * t = lowerClosure (s * t) := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ ↑(lowerClosure s) * t = ↑(lowerClosure (s * t))

Next tactic:
simp_rw [mul_comm _ t]
@[to_additive]
theorem lowerClosure_mul : ↑(lowerClosure s) * t = lowerClosure (s * t) := by
  simp_rw [mul_comm _ t]
  

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ t * ↑(lowerClosure s) = ↑(lowerClosure (t * s))

Next tactic:
exact mul_lowerClosure _ _
@[to_additive (attr := simp)]
theorem upperClosure_mul_distrib : upperClosure (s * t) = upperClosure s * upperClosure t :=
  SetLike.coe_injective <| by
    

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ ↑(upperClosure (s * t)) = ↑(upperClosure s * upperClosure t)

Next tactic:
rw [UpperSet.coe_mul, mul_upperClosure, upperClosure_mul, UpperSet.upperClosure]
@[to_additive (attr := simp)]
theorem lowerClosure_mul_distrib : lowerClosure (s * t) = lowerClosure s * lowerClosure t :=
  SetLike.coe_injective <| by
    

Proof state:
α : Type u_1
inst✝ : OrderedCommGroup α
s t : Set α
a : α
⊢ ↑(lowerClosure (s * t)) = ↑(lowerClosure s * lowerClosure t)

Next tactic:
rw [LowerSet.coe_mul, mul_lowerClosure, lowerClosure_mul, LowerSet.lowerClosure]
theorem Duplicate.mem (h : x ∈+ l) : x ∈ l := by
  

Proof state:
α : Type u_1
l : List α
x : α
h : x ∈+ l
⊢ x ∈ l

Next tactic:
induction' h with l' _ y l' _ hm
theorem Duplicate.mem (h : x ∈+ l) : x ∈ l := by
  induction' h with l' _ y l' _ hm
  · 

Proof state:
case cons_mem
α : Type u_1
l : List α
x : α
l' : List α
a✝ : x ∈ l'
⊢ x ∈ x :: l'

Next tactic:
exact mem_cons_self _ _
theorem Duplicate.mem (h : x ∈+ l) : x ∈ l := by
  induction' h with l' _ y l' _ hm
  · exact mem_cons_self _ _
  · 

Proof state:
case cons_duplicate
α : Type u_1
l : List α
x y : α
l' : List α
a✝ : x ∈+ l'
hm : x ∈ l'
⊢ x ∈ y :: l'

Next tactic:
exact mem_cons_of_mem _ hm
theorem Duplicate.mem_cons_self (h : x ∈+ x :: l) : x ∈ l := by
  

Proof state:
α : Type u_1
l : List α
x : α
h : x ∈+ x :: l
⊢ x ∈ l

Next tactic:
cases' h with _ h _ _ h
theorem Duplicate.mem_cons_self (h : x ∈+ x :: l) : x ∈ l := by
  cases' h with _ h _ _ h
  · 

Proof state:
case cons_mem
α : Type u_1
l : List α
x : α
h : x ∈ l
⊢ x ∈ l

Next tactic:
exact h
theorem Duplicate.mem_cons_self (h : x ∈+ x :: l) : x ∈ l := by
  cases' h with _ h _ _ h
  · exact h
  · 

Proof state:
case cons_duplicate
α : Type u_1
l : List α
x : α
h : x ∈+ l
⊢ x ∈ l

Next tactic:
exact h.mem
theorem Duplicate.ne_singleton (h : x ∈+ l) (y : α) : l ≠ [y] := by
  

Proof state:
α : Type u_1
l : List α
x : α
h : x ∈+ l
y : α
⊢ l ≠ [y]

Next tactic:
induction' h with l' h z l' h _
theorem Duplicate.ne_singleton (h : x ∈+ l) (y : α) : l ≠ [y] := by
  induction' h with l' h z l' h _
  · 

Proof state:
case cons_mem
α : Type u_1
l : List α
x y : α
l' : List α
h : x ∈ l'
⊢ x :: l' ≠ [y]

Next tactic:
simp [ne_nil_of_mem h]
theorem Duplicate.ne_singleton (h : x ∈+ l) (y : α) : l ≠ [y] := by
  induction' h with l' h z l' h _
  · simp [ne_nil_of_mem h]
  · 

Proof state:
case cons_duplicate
α : Type u_1
l : List α
x y z : α
l' : List α
h : x ∈+ l'
a_ih✝ : l' ≠ [y]
⊢ z :: l' ≠ [y]

Next tactic:
simp [ne_nil_of_mem h.mem]
theorem duplicate_cons_iff {y : α} : x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l := by
  

Proof state:
α : Type u_1
l : List α
x y : α
⊢ x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l

Next tactic:
refine' ⟨fun h => _, fun h => _⟩
theorem duplicate_cons_iff {y : α} : x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l := by
  refine' ⟨fun h => _, fun h => _⟩
  · 

Proof state:
case refine'_1
α : Type u_1
l : List α
x y : α
h : x ∈+ y :: l
⊢ y = x ∧ x ∈ l ∨ x ∈+ l

Next tactic:
cases' h with _ hm _ _ hm
theorem duplicate_cons_iff {y : α} : x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l := by
  refine' ⟨fun h => _, fun h => _⟩
  · cases' h with _ hm _ _ hm
    · 

Proof state:
case refine'_1.cons_mem
α : Type u_1
l : List α
x : α
hm : x ∈ l
⊢ x = x ∧ x ∈ l ∨ x ∈+ l

Next tactic:
exact Or.inl ⟨rfl, hm⟩
theorem duplicate_cons_iff {y : α} : x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l := by
  refine' ⟨fun h => _, fun h => _⟩
  · cases' h with _ hm _ _ hm
    · exact Or.inl ⟨rfl, hm⟩
    · 

Proof state:
case refine'_1.cons_duplicate
α : Type u_1
l : List α
x y : α
hm : x ∈+ l
⊢ y = x ∧ x ∈ l ∨ x ∈+ l

Next tactic:
exact Or.inr hm
theorem duplicate_cons_iff {y : α} : x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l := by
  refine' ⟨fun h => _, fun h => _⟩
  · cases' h with _ hm _ _ hm
    · exact Or.inl ⟨rfl, hm⟩
    · exact Or.inr hm
  · 

Proof state:
case refine'_2
α : Type u_1
l : List α
x y : α
h : y = x ∧ x ∈ l ∨ x ∈+ l
⊢ x ∈+ y :: l

Next tactic:
rcases h with (⟨rfl | h⟩ | h)
theorem duplicate_cons_iff {y : α} : x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l := by
  refine' ⟨fun h => _, fun h => _⟩
  · cases' h with _ hm _ _ hm
    · exact Or.inl ⟨rfl, hm⟩
    · exact Or.inr hm
  · rcases h with (⟨rfl | h⟩ | h)
    · 

Proof state:
case refine'_2.inl.intro.refl
α : Type u_1
l : List α
x : α
right✝ : x ∈ l
⊢ x ∈+ x :: l

Next tactic:
simpa
theorem duplicate_cons_iff {y : α} : x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l := by
  refine' ⟨fun h => _, fun h => _⟩
  · cases' h with _ hm _ _ hm
    · exact Or.inl ⟨rfl, hm⟩
    · exact Or.inr hm
  · rcases h with (⟨rfl | h⟩ | h)
    · simpa
    · 

Proof state:
case refine'_2.inr
α : Type u_1
l : List α
x y : α
h : x ∈+ l
⊢ x ∈+ y :: l

Next tactic:
exact h.cons_duplicate
theorem Duplicate.of_duplicate_cons {y : α} (h : x ∈+ y :: l) (hx : x ≠ y) : x ∈+ l := by
  

Proof state:
α : Type u_1
l : List α
x y : α
h : x ∈+ y :: l
hx : x ≠ y
⊢ x ∈+ l

Next tactic:
simpa [duplicate_cons_iff, hx.symm] using h
theorem duplicate_cons_iff_of_ne {y : α} (hne : x ≠ y) : x ∈+ y :: l ↔ x ∈+ l := by
  

Proof state:
α : Type u_1
l : List α
x y : α
hne : x ≠ y
⊢ x ∈+ y :: l ↔ x ∈+ l

Next tactic:
simp [duplicate_cons_iff, hne.symm]
theorem Duplicate.mono_sublist {l' : List α} (hx : x ∈+ l) (h : l <+ l') : x ∈+ l' := by
  

Proof state:
α : Type u_1
l : List α
x : α
l' : List α
hx : x ∈+ l
h : l <+ l'
⊢ x ∈+ l'

Next tactic:
induction' h with l₁ l₂ y _ IH l₁ l₂ y h IH
theorem Duplicate.mono_sublist {l' : List α} (hx : x ∈+ l) (h : l <+ l') : x ∈+ l' := by
  induction' h with l₁ l₂ y _ IH l₁ l₂ y h IH
  · 

Proof state:
case slnil
α : Type u_1
l : List α
x : α
l' : List α
hx : x ∈+ []
⊢ x ∈+ []

Next tactic:
exact hx
theorem Duplicate.mono_sublist {l' : List α} (hx : x ∈+ l) (h : l <+ l') : x ∈+ l' := by
  induction' h with l₁ l₂ y _ IH l₁ l₂ y h IH
  · exact hx
  · 

Proof state:
case cons
α : Type u_1
l : List α
x : α
l' l₁ l₂ : List α
y : α
a✝ : l₁ <+ l₂
IH : x ∈+ l₁ → x ∈+ l₂
hx : x ∈+ l₁
⊢ x ∈+ y :: l₂

Next tactic:
exact (IH hx).duplicate_cons _
theorem Duplicate.mono_sublist {l' : List α} (hx : x ∈+ l) (h : l <+ l') : x ∈+ l' := by
  induction' h with l₁ l₂ y _ IH l₁ l₂ y h IH
  · exact hx
  · exact (IH hx).duplicate_cons _
  · 

Proof state:
case cons₂
α : Type u_1
l : List α
x : α
l' l₁ l₂ : List α
y : α
h : l₁ <+ l₂
IH : x ∈+ l₁ → x ∈+ l₂
hx : x ∈+ y :: l₁
⊢ x ∈+ y :: l₂

Next tactic:
rw [duplicate_cons_iff] at hx ⊢
theorem Duplicate.mono_sublist {l' : List α} (hx : x ∈+ l) (h : l <+ l') : x ∈+ l' := by
  induction' h with l₁ l₂ y _ IH l₁ l₂ y h IH
  · exact hx
  · exact (IH hx).duplicate_cons _
  · rw [duplicate_cons_iff] at hx ⊢
    

Proof state:
case cons₂
α : Type u_1
l : List α
x : α
l' l₁ l₂ : List α
y : α
h : l₁ <+ l₂
IH : x ∈+ l₁ → x ∈+ l₂
hx : y = x ∧ x ∈ l₁ ∨ x ∈+ l₁
⊢ y = x ∧ x ∈ l₂ ∨ x ∈+ l₂

Next tactic:
rcases hx with (⟨rfl, hx⟩ | hx)