l3lab/ntp-mathlib huggingface dataset:
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · intro a
      exact le_of_dvd (pow_pos (succ_pos x) l) a
    · intro a
      cases' x with x
      · 

Proof state:
case mpr.zero
m n x y k l : ℕ
w : 0 < zero + 1
a : (zero + 1) ^ k ≤ (zero + 1) ^ l
⊢ (zero + 1) ^ k ∣ (zero + 1) ^ l

Next tactic:
simp
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · intro a
      exact le_of_dvd (pow_pos (succ_pos x) l) a
    · intro a
      cases' x with x
      · simp
      · 

Proof state:
case mpr.succ
m n x✝ y k l x : ℕ
w : 0 < succ x + 1
a : (succ x + 1) ^ k ≤ (succ x + 1) ^ l
⊢ (succ x + 1) ^ k ∣ (succ x + 1) ^ l

Next tactic:
have le := (pow_le_pow_iff_right $ by simp).mp a
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · intro a
      exact le_of_dvd (pow_pos (succ_pos x) l) a
    · intro a
      cases' x with x
      · simp
      · have le := (pow_le_pow_iff_right $ by 

Proof state:
m n x✝ y k l x : ℕ
w : 0 < succ x + 1
a : (succ x + 1) ^ k ≤ (succ x + 1) ^ l
⊢ 1 < succ x + 1

Next tactic:
simp
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · intro a
      exact le_of_dvd (pow_pos (succ_pos x) l) a
    · intro a
      cases' x with x
      · simp
      · have le := (pow_le_pow_iff_right $ by simp).mp a
        

Proof state:
case mpr.succ
m n x✝ y k l x : ℕ
w : 0 < succ x + 1
a : (succ x + 1) ^ k ≤ (succ x + 1) ^ l
le : k ≤ l
⊢ (succ x + 1) ^ k ∣ (succ x + 1) ^ l

Next tactic:
use (x + 2) ^ (l - k)
theorem pow_dvd_pow_iff_pow_le_pow {k l : ℕ} : ∀ {x : ℕ} (_ : 0 < x), x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l
  | x + 1, w => by
    constructor
    · intro a
      exact le_of_dvd (pow_pos (succ_pos x) l) a
    · intro a
      cases' x with x
      · simp
      · have le := (pow_le_pow_iff_right $ by simp).mp a
        use (x + 2) ^ (l - k)
        

Proof state:
case h
m n x✝ y k l x : ℕ
w : 0 < succ x + 1
a : (succ x + 1) ^ k ≤ (succ x + 1) ^ l
le : k ≤ l
⊢ (succ x + 1) ^ l = (succ x + 1) ^ k * (x + 2) ^ (l - k)

Next tactic:
rw [← pow_add, add_comm k, tsub_add_cancel_of_le le]
/-- If `1 < x`, then `x^k` divides `x^l` if and only if `k` is at most `l`. -/
theorem pow_dvd_pow_iff_le_right {x k l : ℕ} (w : 1 < x) : x ^ k ∣ x ^ l ↔ k ≤ l := by
  

Proof state:
m n x✝ y x k l : ℕ
w : 1 < x
⊢ x ^ k ∣ x ^ l ↔ k ≤ l

Next tactic:
rw [pow_dvd_pow_iff_pow_le_pow (lt_of_succ_lt w), pow_le_pow_iff_right w]
theorem not_pos_pow_dvd : ∀ {p k : ℕ} (_ : 1 < p) (_ : 1 < k), ¬p ^ k ∣ p
  | succ p, succ k, hp, hk, h =>
    have : succ p * succ p ^ k ∣ succ p * 1 := by 

Proof state:
m n x y p k : ℕ
hp : 1 < succ p
hk : 1 < succ k
h : succ p ^ succ k ∣ succ p
⊢ succ p * succ p ^ k ∣ succ p * 1

Next tactic:
simpa [pow_succ'] using h
theorem not_pos_pow_dvd : ∀ {p k : ℕ} (_ : 1 < p) (_ : 1 < k), ¬p ^ k ∣ p
  | succ p, succ k, hp, hk, h =>
    have : succ p * succ p ^ k ∣ succ p * 1 := by simpa [pow_succ'] using h
    have : succ p ^ k ∣ 1 := Nat.dvd_of_mul_dvd_mul_left (succ_pos _) this
    have he : succ p ^ k = 1 := eq_one_of_dvd_one this
    have : k < succ p ^ k := lt_pow_self hp k
    have : k < 1 := by 

Proof state:
m n x y p k : ℕ
hp : 1 < succ p
hk : 1 < succ k
h : succ p ^ succ k ∣ succ p
this✝¹ : succ p * succ p ^ k ∣ succ p * 1
this✝ : succ p ^ k ∣ 1
he : succ p ^ k = 1
this : k < succ p ^ k
⊢ k < 1

Next tactic:
rwa [he] at this
theorem not_pos_pow_dvd : ∀ {p k : ℕ} (_ : 1 < p) (_ : 1 < k), ¬p ^ k ∣ p
  | succ p, succ k, hp, hk, h =>
    have : succ p * succ p ^ k ∣ succ p * 1 := by simpa [pow_succ'] using h
    have : succ p ^ k ∣ 1 := Nat.dvd_of_mul_dvd_mul_left (succ_pos _) this
    have he : succ p ^ k = 1 := eq_one_of_dvd_one this
    have : k < succ p ^ k := lt_pow_self hp k
    have : k < 1 := by rwa [he] at this
    have : k = 0 := Nat.eq_zero_of_le_zero <| le_of_lt_succ this
    have : 1 < 1 := by 

Proof state:
m n x y p k : ℕ
hp : 1 < succ p
hk : 1 < succ k
h : succ p ^ succ k ∣ succ p
this✝³ : succ p * succ p ^ k ∣ succ p * 1
this✝² : succ p ^ k ∣ 1
he : succ p ^ k = 1
this✝¹ : k < succ p ^ k
this✝ : k < 1
this : k = 0
⊢ 1 < 1

Next tactic:
rwa [this] at hk
theorem not_pos_pow_dvd : ∀ {p k : ℕ} (_ : 1 < p) (_ : 1 < k), ¬p ^ k ∣ p
  | succ p, succ k, hp, hk, h =>
    have : succ p * succ p ^ k ∣ succ p * 1 := by simpa [pow_succ'] using h
    have : succ p ^ k ∣ 1 := Nat.dvd_of_mul_dvd_mul_left (succ_pos _) this
    have he : succ p ^ k = 1 := eq_one_of_dvd_one this
    have : k < succ p ^ k := lt_pow_self hp k
    have : k < 1 := by rwa [he] at this
    have : k = 0 := Nat.eq_zero_of_le_zero <| le_of_lt_succ this
    have : 1 < 1 := by rwa [this] at hk
    absurd this (by 

Proof state:
m n x y p k : ℕ
hp : 1 < succ p
hk : 1 < succ k
h : succ p ^ succ k ∣ succ p
this✝⁴ : succ p * succ p ^ k ∣ succ p * 1
this✝³ : succ p ^ k ∣ 1
he : succ p ^ k = 1
this✝² : k < succ p ^ k
this✝¹ : k < 1
this✝ : k = 0
this : 1 < 1
⊢ ¬1 < 1

Next tactic:
decide
theorem dvd_of_pow_dvd {p k m : ℕ} (hk : 1 ≤ k) (hpk : p ^ k ∣ m) : p ∣ m := by
  

Proof state:
m✝ n x y p k m : ℕ
hk : 1 ≤ k
hpk : p ^ k ∣ m
⊢ p ∣ m

Next tactic:
rw [← pow_one p]
theorem dvd_of_pow_dvd {p k m : ℕ} (hk : 1 ≤ k) (hpk : p ^ k ∣ m) : p ∣ m := by
  rw [← pow_one p]; 

Proof state:
m✝ n x y p k m : ℕ
hk : 1 ≤ k
hpk : p ^ k ∣ m
⊢ p ^ 1 ∣ m

Next tactic:
exact pow_dvd_of_le_of_pow_dvd hk hpk
theorem pow_div {x m n : ℕ} (h : n ≤ m) (hx : 0 < x) : x ^ m / x ^ n = x ^ (m - n) := by
  

Proof state:
m✝ n✝ x✝ y x m n : ℕ
h : n ≤ m
hx : 0 < x
⊢ x ^ m / x ^ n = x ^ (m - n)

Next tactic:
rw [Nat.div_eq_iff_eq_mul_left (pow_pos hx n) (pow_dvd_pow _ h), pow_sub_mul_pow _ h]
theorem lt_of_pow_dvd_right {p i n : ℕ} (hn : n ≠ 0) (hp : 2 ≤ p) (h : p ^ i ∣ n) : i < n := by
  

Proof state:
m n✝ x y p i n : ℕ
hn : n ≠ 0
hp : 2 ≤ p
h : p ^ i ∣ n
⊢ i < n

Next tactic:
rw [← pow_lt_pow_iff_right (succ_le_iff.1 hp)]
theorem lt_of_pow_dvd_right {p i n : ℕ} (hn : n ≠ 0) (hp : 2 ≤ p) (h : p ^ i ∣ n) : i < n := by
  rw [← pow_lt_pow_iff_right (succ_le_iff.1 hp)]
  

Proof state:
m n✝ x y p i n : ℕ
hn : n ≠ 0
hp : 2 ≤ p
h : p ^ i ∣ n
⊢ p ^ i < p ^ n

Next tactic:
exact lt_of_le_of_lt (le_of_dvd hn.bot_lt h) (lt_pow_self (succ_le_iff.mp hp) n)
@[simp] lemma infIrred_Ici (a : α) : InfIrred (Ici a) := by
  

Proof state:
α : Type u_1
inst✝ : SemilatticeInf α
s : UpperSet α
a✝ a : α
⊢ InfIrred (Ici a)

Next tactic:
refine ⟨fun h ↦ Ici_ne_top h.eq_top, fun s t hst ↦ ?_⟩
@[simp] lemma infIrred_Ici (a : α) : InfIrred (Ici a) := by
  refine ⟨fun h ↦ Ici_ne_top h.eq_top, fun s t hst ↦ ?_⟩
  

Proof state:
α : Type u_1
inst✝ : SemilatticeInf α
s✝ : UpperSet α
a✝ a : α
s t : UpperSet α
hst : s ⊓ t = Ici a
⊢ s = Ici a ∨ t = Ici a

Next tactic:
have := mem_Ici_iff.2 (le_refl a)
@[simp] lemma infIrred_Ici (a : α) : InfIrred (Ici a) := by
  refine ⟨fun h ↦ Ici_ne_top h.eq_top, fun s t hst ↦ ?_⟩
  have := mem_Ici_iff.2 (le_refl a)
  

Proof state:
α : Type u_1
inst✝ : SemilatticeInf α
s✝ : UpperSet α
a✝ a : α
s t : UpperSet α
hst : s ⊓ t = Ici a
this : a ∈ Ici a
⊢ s = Ici a ∨ t = Ici a

Next tactic:
rw [← hst] at this
@[simp] lemma infIrred_Ici (a : α) : InfIrred (Ici a) := by
  refine ⟨fun h ↦ Ici_ne_top h.eq_top, fun s t hst ↦ ?_⟩
  have := mem_Ici_iff.2 (le_refl a)
  rw [← hst] at this
  

Proof state:
α : Type u_1
inst✝ : SemilatticeInf α
s✝ : UpperSet α
a✝ a : α
s t : UpperSet α
hst : s ⊓ t = Ici a
this : a ∈ s ⊓ t
⊢ s = Ici a ∨ t = Ici a

Next tactic:
exact this.imp (fun ha ↦ le_antisymm (le_Ici.2 ha) $ hst.ge.trans inf_le_left) fun ha ↦
      le_antisymm (le_Ici.2 ha) $ hst.ge.trans inf_le_right
@[simp] lemma infIrred_iff_of_finite : InfIrred s ↔ ∃ a, Ici a = s := by
  

Proof state:
α : Type u_1
inst✝¹ : SemilatticeInf α
s : UpperSet α
a : α
inst✝ : Finite α
⊢ InfIrred s ↔ ∃ a, Ici a = s

Next tactic:
refine' ⟨fun hs ↦ _, _⟩
@[simp] lemma infIrred_iff_of_finite : InfIrred s ↔ ∃ a, Ici a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · 

Proof state:
case refine'_1
α : Type u_1
inst✝¹ : SemilatticeInf α
s : UpperSet α
a : α
inst✝ : Finite α
hs : InfIrred s
⊢ ∃ a, Ici a = s

Next tactic:
obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_minimal_wrt id _ (coe_nonempty.2 hs.ne_top)
@[simp] lemma infIrred_iff_of_finite : InfIrred s ↔ ∃ a, Ici a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_minimal_wrt id _ (coe_nonempty.2 hs.ne_top)
    

Proof state:
case refine'_1.intro.intro
α : Type u_1
inst✝¹ : SemilatticeInf α
s : UpperSet α
a✝ : α
inst✝ : Finite α
hs : InfIrred s
a : α
ha : a ∈ ↑s
has : ∀ a' ∈ ↑s, id a' ≤ id a → id a = id a'
⊢ ∃ a, Ici a = s

Next tactic:
exact ⟨a, (hs.2 $ erase_inf_Ici ha $ by simpa [eq_comm] using has).resolve_left
      (lt_erase.2 ha).ne'⟩
@[simp] lemma infIrred_iff_of_finite : InfIrred s ↔ ∃ a, Ici a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_minimal_wrt id _ (coe_nonempty.2 hs.ne_top)
    exact ⟨a, (hs.2 $ erase_inf_Ici ha $ by 

Proof state:
α : Type u_1
inst✝¹ : SemilatticeInf α
s : UpperSet α
a✝ : α
inst✝ : Finite α
hs : InfIrred s
a : α
ha : a ∈ ↑s
has : ∀ a' ∈ ↑s, id a' ≤ id a → id a = id a'
⊢ ∀ b ∈ s, b ≤ a → b = a

Next tactic:
simpa [eq_comm] using has
@[simp] lemma infIrred_iff_of_finite : InfIrred s ↔ ∃ a, Ici a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_minimal_wrt id _ (coe_nonempty.2 hs.ne_top)
    exact ⟨a, (hs.2 $ erase_inf_Ici ha $ by simpa [eq_comm] using has).resolve_left
      (lt_erase.2 ha).ne'⟩
  · 

Proof state:
case refine'_2
α : Type u_1
inst✝¹ : SemilatticeInf α
s : UpperSet α
a : α
inst✝ : Finite α
⊢ (∃ a, Ici a = s) → InfIrred s

Next tactic:
rintro ⟨a, rfl⟩
@[simp] lemma infIrred_iff_of_finite : InfIrred s ↔ ∃ a, Ici a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_minimal_wrt id _ (coe_nonempty.2 hs.ne_top)
    exact ⟨a, (hs.2 $ erase_inf_Ici ha $ by simpa [eq_comm] using has).resolve_left
      (lt_erase.2 ha).ne'⟩
  · rintro ⟨a, rfl⟩
    

Proof state:
case refine'_2.intro
α : Type u_1
inst✝¹ : SemilatticeInf α
a✝ : α
inst✝ : Finite α
a : α
⊢ InfIrred (Ici a)

Next tactic:
exact infIrred_Ici _
@[simp] lemma supIrred_Iic (a : α) : SupIrred (Iic a) := by
  

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
s : LowerSet α
a✝ a : α
⊢ SupIrred (Iic a)

Next tactic:
refine' ⟨fun h ↦ Iic_ne_bot h.eq_bot, fun s t hst ↦ _⟩
@[simp] lemma supIrred_Iic (a : α) : SupIrred (Iic a) := by
  refine' ⟨fun h ↦ Iic_ne_bot h.eq_bot, fun s t hst ↦ _⟩
  

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
s✝ : LowerSet α
a✝ a : α
s t : LowerSet α
hst : s ⊔ t = Iic a
⊢ s = Iic a ∨ t = Iic a

Next tactic:
have := mem_Iic_iff.2 (le_refl a)
@[simp] lemma supIrred_Iic (a : α) : SupIrred (Iic a) := by
  refine' ⟨fun h ↦ Iic_ne_bot h.eq_bot, fun s t hst ↦ _⟩
  have := mem_Iic_iff.2 (le_refl a)
  

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
s✝ : LowerSet α
a✝ a : α
s t : LowerSet α
hst : s ⊔ t = Iic a
this : a ∈ Iic a
⊢ s = Iic a ∨ t = Iic a

Next tactic:
rw [← hst] at this
@[simp] lemma supIrred_Iic (a : α) : SupIrred (Iic a) := by
  refine' ⟨fun h ↦ Iic_ne_bot h.eq_bot, fun s t hst ↦ _⟩
  have := mem_Iic_iff.2 (le_refl a)
  rw [← hst] at this
  

Proof state:
α : Type u_1
inst✝ : SemilatticeSup α
s✝ : LowerSet α
a✝ a : α
s t : LowerSet α
hst : s ⊔ t = Iic a
this : a ∈ s ⊔ t
⊢ s = Iic a ∨ t = Iic a

Next tactic:
exact this.imp (fun ha ↦ (le_sup_left.trans_eq hst).antisymm $ Iic_le.2 ha) fun ha ↦
    (le_sup_right.trans_eq hst).antisymm $ Iic_le.2 ha
@[simp] lemma supIrred_iff_of_finite : SupIrred s ↔ ∃ a, Iic a = s := by
  

Proof state:
α : Type u_1
inst✝¹ : SemilatticeSup α
s : LowerSet α
a : α
inst✝ : Finite α
⊢ SupIrred s ↔ ∃ a, Iic a = s

Next tactic:
refine' ⟨fun hs ↦ _, _⟩
@[simp] lemma supIrred_iff_of_finite : SupIrred s ↔ ∃ a, Iic a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · 

Proof state:
case refine'_1
α : Type u_1
inst✝¹ : SemilatticeSup α
s : LowerSet α
a : α
inst✝ : Finite α
hs : SupIrred s
⊢ ∃ a, Iic a = s

Next tactic:
obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_maximal_wrt id _ (coe_nonempty.2 hs.ne_bot)
@[simp] lemma supIrred_iff_of_finite : SupIrred s ↔ ∃ a, Iic a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_maximal_wrt id _ (coe_nonempty.2 hs.ne_bot)
    

Proof state:
case refine'_1.intro.intro
α : Type u_1
inst✝¹ : SemilatticeSup α
s : LowerSet α
a✝ : α
inst✝ : Finite α
hs : SupIrred s
a : α
ha : a ∈ ↑s
has : ∀ a' ∈ ↑s, id a ≤ id a' → id a = id a'
⊢ ∃ a, Iic a = s

Next tactic:
exact ⟨a, (hs.2 $ erase_sup_Iic ha $ by simpa [eq_comm] using has).resolve_left
      (erase_lt.2 ha).ne⟩
@[simp] lemma supIrred_iff_of_finite : SupIrred s ↔ ∃ a, Iic a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_maximal_wrt id _ (coe_nonempty.2 hs.ne_bot)
    exact ⟨a, (hs.2 $ erase_sup_Iic ha $ by 

Proof state:
α : Type u_1
inst✝¹ : SemilatticeSup α
s : LowerSet α
a✝ : α
inst✝ : Finite α
hs : SupIrred s
a : α
ha : a ∈ ↑s
has : ∀ a' ∈ ↑s, id a ≤ id a' → id a = id a'
⊢ ∀ b ∈ s, a ≤ b → b = a

Next tactic:
simpa [eq_comm] using has
@[simp] lemma supIrred_iff_of_finite : SupIrred s ↔ ∃ a, Iic a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_maximal_wrt id _ (coe_nonempty.2 hs.ne_bot)
    exact ⟨a, (hs.2 $ erase_sup_Iic ha $ by simpa [eq_comm] using has).resolve_left
      (erase_lt.2 ha).ne⟩
  · 

Proof state:
case refine'_2
α : Type u_1
inst✝¹ : SemilatticeSup α
s : LowerSet α
a : α
inst✝ : Finite α
⊢ (∃ a, Iic a = s) → SupIrred s

Next tactic:
rintro ⟨a, rfl⟩
@[simp] lemma supIrred_iff_of_finite : SupIrred s ↔ ∃ a, Iic a = s := by
  refine' ⟨fun hs ↦ _, _⟩
  · obtain ⟨a, ha, has⟩ := (s : Set α).toFinite.exists_maximal_wrt id _ (coe_nonempty.2 hs.ne_bot)
    exact ⟨a, (hs.2 $ erase_sup_Iic ha $ by simpa [eq_comm] using has).resolve_left
      (erase_lt.2 ha).ne⟩
  · rintro ⟨a, rfl⟩
    

Proof state:
case refine'_2.intro
α : Type u_1
inst✝¹ : SemilatticeSup α
a✝ : α
inst✝ : Finite α
a : α
⊢ SupIrred (Iic a)

Next tactic:
exact supIrred_Iic _
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
a : α
⊢ (fun s => sup (Set.toFinset ↑s) Subtype.val)
      ((fun a =>
          { carrier := {b | ↑b ≤ a}, lower' := (_ : ∀ (b c : { a // SupIrred a }), c ≤ b → b ∈ {b | ↑b ≤ a} → ↑c ≤ a) })
        a) =
    a

Next tactic:
refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
        

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
a : α
⊢ a ≤
    (fun s => sup (Set.toFinset ↑s) Subtype.val)
      ((fun a =>
          { carrier := {b | ↑b ≤ a}, lower' := (_ : ∀ (b c : { a // SupIrred a }), c ≤ b → b ∈ {b | ↑b ≤ a} → ↑c ≤ a) })
        a)

Next tactic:
obtain ⟨s, rfl, hs⟩ := exists_supIrred_decomposition a
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
        obtain ⟨s, rfl, hs⟩ := exists_supIrred_decomposition a
        

Proof state:
case intro.intro
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
s : Finset α
hs : ∀ ⦃b : α⦄, b ∈ s → SupIrred b
⊢ sup s id ≤
    (fun s => sup (Set.toFinset ↑s) Subtype.val)
      ((fun a =>
          { carrier := {b | ↑b ≤ a}, lower' := (_ : ∀ (b c : { a // SupIrred a }), c ≤ b → b ∈ {b | ↑b ≤ a} → ↑c ≤ a) })
        (sup s id))

Next tactic:
exact Finset.sup_le fun i hi ↦
          le_sup_of_le (b := ⟨i, hs hi⟩) (Set.mem_toFinset.2 $ le_sup (f := id) hi) le_rfl
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
        obtain ⟨s, rfl, hs⟩ := exists_supIrred_decomposition a
        exact Finset.sup_le fun i hi ↦
          le_sup_of_le (b := ⟨i, hs hi⟩) (Set.mem_toFinset.2 $ le_sup (f := id) hi) le_rfl
      right_inv := fun s ↦ by
        

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
s : LowerSet { a // SupIrred a }
⊢ (fun a =>
        { carrier := {b | ↑b ≤ a}, lower' := (_ : ∀ (b c : { a // SupIrred a }), c ≤ b → b ∈ {b | ↑b ≤ a} → ↑c ≤ a) })
      ((fun s => sup (Set.toFinset ↑s) Subtype.val) s) =
    s

Next tactic:
ext a
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
        obtain ⟨s, rfl, hs⟩ := exists_supIrred_decomposition a
        exact Finset.sup_le fun i hi ↦
          le_sup_of_le (b := ⟨i, hs hi⟩) (Set.mem_toFinset.2 $ le_sup (f := id) hi) le_rfl
      right_inv := fun s ↦ by
        ext a
        

Proof state:
case a.h
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
s : LowerSet { a // SupIrred a }
a : { a // SupIrred a }
⊢ a ∈
      ↑((fun a =>
            { carrier := {b | ↑b ≤ a},
              lower' := (_ : ∀ (b c : { a // SupIrred a }), c ≤ b → b ∈ {b | ↑b ≤ a} → ↑c ≤ a) })
          ((fun s => sup (Set.toFinset ↑s) Subtype.val) s)) ↔
    a ∈ ↑s

Next tactic:
dsimp
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
        obtain ⟨s, rfl, hs⟩ := exists_supIrred_decomposition a
        exact Finset.sup_le fun i hi ↦
          le_sup_of_le (b := ⟨i, hs hi⟩) (Set.mem_toFinset.2 $ le_sup (f := id) hi) le_rfl
      right_inv := fun s ↦ by
        ext a
        dsimp
        

Proof state:
case a.h
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
s : LowerSet { a // SupIrred a }
a : { a // SupIrred a }
⊢ ↑a ≤ sup (Set.toFinset ↑s) Subtype.val ↔ a ∈ ↑s

Next tactic:
refine' ⟨fun ha ↦ _, fun ha ↦ _⟩
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
        obtain ⟨s, rfl, hs⟩ := exists_supIrred_decomposition a
        exact Finset.sup_le fun i hi ↦
          le_sup_of_le (b := ⟨i, hs hi⟩) (Set.mem_toFinset.2 $ le_sup (f := id) hi) le_rfl
      right_inv := fun s ↦ by
        ext a
        dsimp
        refine' ⟨fun ha ↦ _, fun ha ↦ _⟩
        · 

Proof state:
case a.h.refine'_1
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
s : LowerSet { a // SupIrred a }
a : { a // SupIrred a }
ha : ↑a ≤ sup (Set.toFinset ↑s) Subtype.val
⊢ a ∈ ↑s

Next tactic:
obtain ⟨i, hi, ha⟩ := a.2.supPrime.le_finset_sup.1 ha
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
        obtain ⟨s, rfl, hs⟩ := exists_supIrred_decomposition a
        exact Finset.sup_le fun i hi ↦
          le_sup_of_le (b := ⟨i, hs hi⟩) (Set.mem_toFinset.2 $ le_sup (f := id) hi) le_rfl
      right_inv := fun s ↦ by
        ext a
        dsimp
        refine' ⟨fun ha ↦ _, fun ha ↦ _⟩
        · obtain ⟨i, hi, ha⟩ := a.2.supPrime.le_finset_sup.1 ha
          

Proof state:
case a.h.refine'_1.intro.intro
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
s : LowerSet { a // SupIrred a }
a : { a // SupIrred a }
ha✝ : ↑a ≤ sup (Set.toFinset ↑s) Subtype.val
i : { a // SupIrred a }
hi : i ∈ Set.toFinset ↑s
ha : ↑a ≤ ↑i
⊢ a ∈ ↑s

Next tactic:
exact s.lower ha (Set.mem_toFinset.1 hi)
/-- **Birkhoff's Representation Theorem**. Any nonempty finite distributive lattice is isomorphic to
the lattice of lower sets of its sup-irreducible elements. -/
noncomputable def OrderIso.lowerSetSupIrred : α ≃o LowerSet {a : α // SupIrred a} :=
  Equiv.toOrderIso
    { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩
      invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑)
      left_inv := fun a ↦ by
        refine' le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) _
        obtain ⟨s, rfl, hs⟩ := exists_supIrred_decomposition a
        exact Finset.sup_le fun i hi ↦
          le_sup_of_le (b := ⟨i, hs hi⟩) (Set.mem_toFinset.2 $ le_sup (f := id) hi) le_rfl
      right_inv := fun s ↦ by
        ext a
        dsimp
        refine' ⟨fun ha ↦ _, fun ha ↦ _⟩
        · obtain ⟨i, hi, ha⟩ := a.2.supPrime.le_finset_sup.1 ha
          exact s.lower ha (Set.mem_toFinset.1 hi)
        · 

Proof state:
case a.h.refine'_2
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : Fintype α
inst✝ : OrderBot α
s : LowerSet { a // SupIrred a }
a : { a // SupIrred a }
ha : a ∈ ↑s
⊢ ↑a ≤ sup (Set.toFinset ↑s) Subtype.val

Next tactic:
dsimp