Built with
doc-gen4 , running Lean4.
Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents.
Use
Ctrl+β Ctrl+β to navigate,
Ctrl+π±οΈ to focus.
On Mac, use
Cmd instead of
Ctrl .
/-
Copyright (c) 2017 Johannes HΓΆlzl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johannes HΓΆlzl
! This file was ported from Lean 3 source module order.zorn
! leanprover-community/mathlib commit 46a64b5b4268c594af770c44d9e502afc6a515cb
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Order.Chain
/-!
# Zorn's lemmas
This file proves several formulations of Zorn's Lemma.
## Variants
The primary statement of Zorn's lemma is `exists_maximal_of_chains_bounded`. Then it is specialized
to particular relations:
* `(β€)` with `zorn_partialOrder`
* `(β)` with `zorn_subset`
* `(β)` with `zorn_superset`
Lemma names carry modifiers:
* `β`: Quantifies over a set, as opposed to over a type.
* `_nonempty`: Doesn't ask to prove that the empty chain is bounded and lets you give an element
that will be smaller than the maximal element found (the maximal element is no smaller than any
other element, but it can also be incomparable to some).
## How-to
This file comes across as confusing to those who haven't yet used it, so here is a detailed
walkthrough:
1. Know what relation on which type/set you're looking for. See Variants above. You can discharge
some conditions to Zorn's lemma directly using a `_nonempty` variant.
2. Write down the definition of your type/set, put a `suffices : β m, β a, m βΊ a β a βΊ m, { ... },`
(or whatever you actually need) followed by a `apply some_version_of_zorn`.
3. Fill in the details. This is where you start talking about chains.
A typical proof using Zorn could look like this (TODO: update to mathlib4)
```lean
lemma zorny_lemma : zorny_statement :=
begin
let s : Set Ξ± := {x | whatever x},
suffices : β x β s, β y β s, y β x β y = x, -- or with another operator
{ exact proof_post_zorn },
apply zorn_subset, -- or another variant
rintro c hcs hc,
obtain rfl | hcnemp := c.eq_empty_or_nonempty, -- you might need to disjunct on c empty or not
{ exact β¨edge_case_construction,
proof_that_edge_case_construction_respects_whatever,
proof_that_edge_case_construction_contains_all_stuff_in_cβ© },
exact β¨construction,
proof_that_construction_respects_whatever,
proof_that_construction_contains_all_stuff_in_cβ©,
end
```
## Notes
Originally ported from Isabelle/HOL. The
[original file](https://isabelle.in.tum.de/dist/library/HOL/HOL/Zorn.html) was written by Jacques D.
Fleuriot, Tobias Nipkow, Christian Sternagel.
-/
open Classical Set
variable { Ξ± Ξ² : Type _ } { r : Ξ± β Ξ± β Prop } { c : Set Ξ± }
/-- Local notation for the relation being considered. -/
local infixl :50 " βΊ " => r
/-- **Zorn's lemma**
If every chain has an upper bound, then there exists a maximal element. -/
theorem exists_maximal_of_chains_bounded : (β (c : Set Ξ± ), IsChain r c β β ub , β (a : Ξ± ), a β c β r a ub ) β
(β {a b c : Ξ± }, r a b β r b c β r a c ) β β m , β (a : Ξ± ), r m a β r a m exists_maximal_of_chains_bounded ( h : β (c : Set Ξ± ), IsChain r c β β ub , β (a : Ξ± ), a β c β r a ub h : β c , IsChain r c β β ub , β a β c , a βΊ ub )
( trans : β {a b c : Ξ± }, r a b β r b c β r a c
trans : β { a b c }, a βΊ b β b βΊ c β a βΊ c ) : β m , β a , m βΊ a β a βΊ m :=
have : β ub , β a β maxChain : {Ξ± : Type ?u.2400} β (Ξ± β Ξ± β Prop ) β Set Ξ± maxChain r , a βΊ ub := h : β (c : Set Ξ± ), IsChain r c β β ub , β (a : Ξ± ), a β c β r a ub h _ <| maxChain_spec . left : β {a b : Prop }, a β§ b β a left
let β¨ ub , ( hub : β a β maxChain r, a βΊ ub)β© := this : β ub , β (a : Ξ± ), a β maxChain r β r a ub this
β¨ ub , fun a ha =>
have : IsChain r ( insert a <| maxChain : {Ξ± : Type ?u.2615} β (Ξ± β Ξ± β Prop ) β Set Ξ± maxChain r ) :=
maxChain_spec . 1 . insert fun b hb _ => Or.inr : β {a b : Prop }, b β a β¨ b Or.inr <| trans : β {a b c : Ξ± }, r a b β r b c β r a c
trans ( hub b hb ) ha
hub a <| by
rw [ maxChain_spec . right : β {a b : Prop }, a β§ b β b right this ( subset_insert _ _ ) ]
exact mem_insert _ _ β©
#align exists_maximal_of_chains_bounded exists_maximal_of_chains_bounded : β {Ξ± : Type u_1} {r : Ξ± β Ξ± β Prop },
(β (c : Set Ξ± ), IsChain r c β β ub , β (a : Ξ± ), a β c β r a ub ) β
(β {a b c : Ξ± }, r a b β r b c β r a c ) β β m , β (a : Ξ± ), r m a β r a m exists_maximal_of_chains_bounded
/-- A variant of Zorn's lemma. If every nonempty chain of a nonempty type has an upper bound, then
there is a maximal element.
-/
theorem exists_maximal_of_nonempty_chains_bounded : β [inst : Nonempty Ξ± ],
(β (c : Set Ξ± ), IsChain r c β Set.Nonempty c β β ub , β (a : Ξ± ), a β c β r a ub ) β
(β {a b c : Ξ± }, r a b β r b c β r a c ) β β m , β (a : Ξ± ), r m a β r a m exists_maximal_of_nonempty_chains_bounded [ Nonempty Ξ± ]
( h : β c , IsChain r c β c . Nonempty β β ub , β a β c , a βΊ ub )
( trans : β {a b c : Ξ± }, r a b β r b c β r a c
trans : β { a b c }, a βΊ b β b βΊ c β a βΊ c ) : β m , β a , m βΊ a β a βΊ m :=
exists_maximal_of_chains_bounded : β {Ξ± : Type ?u.3023} {r : Ξ± β Ξ± β Prop },
(β (c : Set Ξ± ), IsChain r c β β ub , β (a : Ξ± ), a β c β r a ub ) β
(β {a b c : Ξ± }, r a b β r b c β r a c ) β β m , β (a : Ξ± ), r m a β r a m exists_maximal_of_chains_bounded
( fun c hc =>
( eq_empty_or_nonempty c ). elim : β {a b c : Prop }, a β¨ b β (a β c ) β (b β c ) β c elim
( fun h => β¨ Classical.arbitrary : (Ξ± : Sort ?u.3072) β [h : Nonempty Ξ± ] β Ξ± Classical.arbitrary Ξ± , fun x hx => ( h βΈ hx : x β ( β
: Set Ξ± )). elim β©) ( h c hc ))
trans : β {a b c : Ξ± }, r a b β r b c β r a c
trans
#align exists_maximal_of_nonempty_chains_bounded exists_maximal_of_nonempty_chains_bounded : β {Ξ± : Type u_1} {r : Ξ± β Ξ± β Prop } [inst : Nonempty Ξ± ],
(β (c : Set Ξ± ), IsChain r c β Set.Nonempty c β β ub , β (a : Ξ± ), a β c β r a ub ) β
(β {a b c : Ξ± }, r a b β r b c β r a c ) β β m , β (a : Ξ± ), r m a β r a m exists_maximal_of_nonempty_chains_bounded
section Preorder
variable [ Preorder Ξ± ]
theorem zorn_preorder ( h : β c : Set Ξ± , IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β BddAbove c ) :
β m : Ξ± , β a , m β€ a β a β€ m :=
exists_maximal_of_chains_bounded : β {Ξ± : Type ?u.3420} {r : Ξ± β Ξ± β Prop },
(β (c : Set Ξ± ), IsChain r c β β ub , β (a : Ξ± ), a β c β r a ub ) β
(β {a b c : Ξ± }, r a b β r b c β r a c ) β β m , β (a : Ξ± ), r m a β r a m exists_maximal_of_chains_bounded h le_trans
#align zorn_preorder zorn_preorder
theorem zorn_nonempty_preorder [ Nonempty Ξ± ]
( h : β c : Set Ξ± , IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β c . Nonempty β BddAbove c ) : β m : Ξ± , β a , m β€ a β a β€ m :=
exists_maximal_of_nonempty_chains_bounded : β {Ξ± : Type ?u.3673} {r : Ξ± β Ξ± β Prop } [inst : Nonempty Ξ± ],
(β (c : Set Ξ± ), IsChain r c β Set.Nonempty c β β ub , β (a : Ξ± ), a β c β r a ub ) β
(β {a b c : Ξ± }, r a b β r b c β r a c ) β β m , β (a : Ξ± ), r m a β r a m exists_maximal_of_nonempty_chains_bounded h le_trans
#align zorn_nonempty_preorder zorn_nonempty_preorder
theorem zorn_preorderβ : β (s : Set Ξ± ),
(β (c : Set Ξ± ), c β s β IsChain (fun x x_1 => x β€ x_1 ) c β β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub ) β
β m , m β s β§ β (z : Ξ± ), z β s β m β€ z β z β€ m zorn_preorderβ ( s : Set Ξ± )
( ih : β ( c ) ( _ : c β s ), IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β β ub β s , β z β c , z β€ ub ) :
β m β s , β z β s , m β€ z β z β€ m :=
let β¨β¨ m , hms β©, h : β (a : βs ), { val := m , property := hms } β€ a β a β€ { val := m , property := hms } h β© :=
@ zorn_preorder s _ fun c hc =>
let β¨ ub , hubs , hub : β (z : Ξ± ), z β Subtype.val '' c β z β€ ub hub β© :=
ih ( Subtype.val : {Ξ± : Sort ?u.4228} β {p : Ξ± β Prop } β Subtype p β Ξ± Subtype.val '' c ) ( fun _ β¨β¨ _ , hx β©, _, h : β{ val := valβ , property := hx } = xβΒΉ h β© => h : β{ val := valβ , property := hx } = xβΒΉ h βΈ hx )
( by
rintro _ β¨p, hpc, rflβ© : xβ β Subtype.val '' c β¨p β¨p, hpc, rflβ© : xβ β Subtype.val '' c , hpc β¨p, hpc, rflβ© : xβ β Subtype.val '' c , rfl β¨p, hpc, rflβ© : xβ β Subtype.val '' c β© _ β¨q, hqc, rflβ© : q β c β§ βq = yβ β¨q β¨q, hqc, rflβ© : q β c β§ βq = yβ , hqc β¨q, hqc, rflβ© : q β c β§ βq = yβ , rfl β¨q, hqc, rflβ© : q β c β§ βq = yβ β© hpq intro.intro.intro.intro (fun x x_1 => x β€ x_1 ) βp βq β¨ (fun x x_1 => x β€ x_1 ) βq βp
refine' hc hpc hqc fun t => hpq ( Subtype.ext_iff : β {Ξ± : Sort ?u.5410} {p : Ξ± β Prop } {a1 a2 : { x // p x } }, a1 = a2 β βa1 = βa2 Subtype.ext_iff. 1 : β {a b : Prop }, (a β b ) β a β b 1 t ) )
β¨β¨ ub , hubs β©, fun β¨ y , hy β© hc => hub : β (z : Ξ± ), z β Subtype.val '' c β z β€ ub hub _ β¨ _ , hc : { val := y , property := hy } β c hc , rfl : β {Ξ± : Sort ?u.4682} {a : Ξ± }, a = a rflβ©β©
β¨ m , hms , fun z hzs hmz => h : β (a : βs ), { val := m , property := hms } β€ a β a β€ { val := m , property := hms } h β¨ z , hzs β© hmz β©
#align zorn_preorderβ zorn_preorderβ
theorem zorn_nonempty_preorderβ : β (s : Set Ξ± ),
(β (c : Set Ξ± ),
c β s β IsChain (fun x x_1 => x β€ x_1 ) c β β (y : Ξ± ), y β c β β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub ) β
β (x : Ξ± ), x β s β β m , m β s β§ x β€ m β§ β (z : Ξ± ), z β s β m β€ z β z β€ m zorn_nonempty_preorderβ ( s : Set Ξ± )
( ih : β (c : Set Ξ± ), c β s β IsChain (fun x x_1 => x β€ x_1 ) c β β (y : Ξ± ), y β c β β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub ih : β ( c ) ( _ : c β s ), IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β β y β c , β ub β s , β z β c , z β€ ub ) ( x : Ξ± )
( hxs : x β s ) : β m β s , x β€ m β§ β z β s , m β€ z β z β€ m := by
-- Porting note: the first three lines replace the following two lines in mathlib3.
-- The mathlib3 `rcases` supports holes for proof obligations, this is not yet implemented in 4.
-- rcases zorn_preorderβ ({ y β s | x β€ y }) fun c hcs hc => ?_ with β¨m, β¨hms, hxmβ©, hmβ©
-- Β· exact β¨m, hms, hxm, fun z hzs hmz => hm _ β¨hzs, hxm.trans hmzβ© hmzβ©
have H := zorn_preorderβ ({ y β s | x β€ y }) fun c hcs hc => ?_
. rcases H with β¨m, β¨hms, hxmβ©, hmβ© : ?m.5863
β¨m β¨m, β¨hms, hxmβ©, hmβ© : ?m.5863
, β¨ hms , hxm β© β¨m, β¨hms, hxmβ©, hmβ© : ?m.5863
, hm β¨m, β¨hms, hxmβ©, hmβ© : ?m.5863
β©refine_2.intro.intro.intro
exact β¨ m , hms , hxm , fun z hzs hmz => hm _ β¨ hzs , hxm . trans hmz β© hmz β©
Β· rcases c . eq_empty_or_nonempty with ( rfl | β¨ y , hy β© ) refine_1.inl refine_1.inr.intro
Β· refine_1.inl refine_1.inr.intro exact β¨ x , β¨ hxs , le_rfl β©, fun z => False.elim : β {C : Sort ?u.6199}, False β C False.elimβ©
Β· rcases ih : β (c : Set Ξ± ), c β s β IsChain (fun x x_1 => x β€ x_1 ) c β β (y : Ξ± ), y β c β β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub ih c ( fun z hz => ( hcs hz ). 1 ) hc y hy with β¨z, hzs, hzβ© : β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub β¨z β¨z, hzs, hzβ© : β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub , hzs β¨z, hzs, hzβ© : β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub , hz : β (z_1 : Ξ± ), z_1 β c β z_1 β€ z hz β¨z, hzs, hzβ© : β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub β©refine_1.inr.intro.intro.intro
exact β¨ z , β¨ hzs , ( hcs hy ). 2 . trans <| hz : β (z_1 : Ξ± ), z_1 β c β z_1 β€ z hz _ hy β©, hz : β (z_1 : Ξ± ), z_1 β c β z_1 β€ z hz β©
#align zorn_nonempty_preorderβ zorn_nonempty_preorderβ
theorem zorn_nonempty_Iciβ : β {Ξ± : Type u_1} [inst : Preorder Ξ± ] (a : Ξ± ),
(β (c : Set Ξ± ),
c β Ici a β IsChain (fun x x_1 => x β€ x_1 ) c β β (y : Ξ± ), y β c β β ub , a β€ ub β§ β (z : Ξ± ), z β c β z β€ ub ) β
β (x : Ξ± ), a β€ x β β m , x β€ m β§ β (z : Ξ± ), m β€ z β z β€ m zorn_nonempty_Iciβ ( a : Ξ± )
( ih : β ( c ) ( _ : c β Ici a ), IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β β y β c , β ub , a β€ ub β§ β z β c , z β€ ub )
( x : Ξ± ) ( hax : a β€ x ) : β m , x β€ m β§ β z , m β€ z β z β€ m :=
let β¨ m , _, hxm , hm β© := zorn_nonempty_preorderβ ( Ici a ) ( by simpa using ih ) x hax
β¨ m , hxm , fun z hmz => hm _ ( hax . trans <| hxm . trans hmz ) hmz β©
#align zorn_nonempty_Iciβ zorn_nonempty_Iciβ : β {Ξ± : Type u_1} [inst : Preorder Ξ± ] (a : Ξ± ),
(β (c : Set Ξ± ),
c β Ici a β IsChain (fun x x_1 => x β€ x_1 ) c β β (y : Ξ± ), y β c β β ub , a β€ ub β§ β (z : Ξ± ), z β c β z β€ ub ) β
β (x : Ξ± ), a β€ x β β m , x β€ m β§ β (z : Ξ± ), m β€ z β z β€ m zorn_nonempty_Iciβ
end Preorder
section PartialOrder
variable [ PartialOrder : Type ?u.14751 β Type ?u.14751 PartialOrder Ξ± ]
theorem zorn_partialOrder : (β (c : Set Ξ± ), IsChain (fun x x_1 => x β€ x_1 ) c β BddAbove c ) β β m , β (a : Ξ± ), m β€ a β a = m zorn_partialOrder ( h : β c : Set Ξ± , IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β BddAbove c ) :
β m : Ξ± , β a , m β€ a β a = m :=
let β¨ m , hm : β (a : Ξ± ), m β€ a β a β€ m hm β© := zorn_preorder h
β¨ m , fun a ha => le_antisymm ( hm : β (a : Ξ± ), m β€ a β a β€ m hm a ha ) ha β©
#align zorn_partial_order zorn_partialOrder
theorem zorn_nonempty_partialOrder [ Nonempty Ξ± ]
( h : β c : Set Ξ± , IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β c . Nonempty β BddAbove c ) : β m : Ξ± , β a , m β€ a β a = m :=
let β¨ m , hm : β (a : Ξ± ), m β€ a β a β€ m hm β© := zorn_nonempty_preorder h
β¨ m , fun a ha => le_antisymm ( hm : β (a : Ξ± ), m β€ a β a β€ m hm a ha ) ha β©
#align zorn_nonempty_partial_order zorn_nonempty_partialOrder
theorem zorn_partialOrderβ : β (s : Set Ξ± ),
(β (c : Set Ξ± ), c β s β IsChain (fun x x_1 => x β€ x_1 ) c β β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub ) β
β m , m β s β§ β (z : Ξ± ), z β s β m β€ z β z = m zorn_partialOrderβ ( s : Set Ξ± )
( ih : β ( c ) ( _ : c β s ), IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β β ub β s , β z β c , z β€ ub ) :
β m β s , β z β s , m β€ z β z = m :=
let β¨ m , hms , hm : β (z : Ξ± ), z β s β m β€ z β z β€ m hm β© := zorn_preorderβ s ih
β¨ m , hms , fun z hzs hmz => ( hm : β (z : Ξ± ), z β s β m β€ z β z β€ m hm z hzs hmz ). antisymm hmz β©
#align zorn_partial_orderβ zorn_partialOrderβ
theorem zorn_nonempty_partialOrderβ ( s : Set Ξ± )
( ih : β (c : Set Ξ± ) (x : c β s ),
IsChain (fun x_1 x_2 => x_1 β€ x_2 ) c β β (y : Ξ± ), y β c β β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub ih : β ( c ) ( _ : c β s ), IsChain (Β· β€ Β·) : Ξ± β Ξ± β Prop (Β· β€ Β·) c β β y β c , β ub β s , β z β c , z β€ ub ) ( x : Ξ± )
( hxs : x β s ) : β m β s , x β€ m β§ β z β s , m β€ z β z = m :=
let β¨ m , hms , hxm , hm : β (z : Ξ± ), z β s β m β€ z β z β€ m hm β© := zorn_nonempty_preorderβ s ih : β (c : Set Ξ± ), c β s β IsChain (fun x x_1 => x β€ x_1 ) c β β (y : Ξ± ), y β c β β ub , ub β s β§ β (z : Ξ± ), z β c β z β€ ub ih x hxs
β¨ m , hms , hxm , fun z hzs hmz => ( hm : β (z : Ξ± ), z β s β m β€ z β z β€ m hm z hzs hmz ). antisymm hmz β©
#align zorn_nonempty_partial_orderβ zorn_nonempty_partialOrderβ
end PartialOrder
theorem zorn_subset ( S : Set ( Set Ξ± ))
( h : β ( c ) ( _ : c β S ), IsChain (Β· β Β·) c β β ub β S , β s β c , s β ub ) :
β m β S , β a β S , m β a β a = m :=
zorn_partialOrderβ S h
#align zorn_subset zorn_subset
theorem zorn_subset_nonempty ( S : Set ( Set Ξ± ))
( H : β ( c ) ( _ : c β S ), IsChain (Β· β Β·) c β c . Nonempty β β ub β S , β s β c , s β ub ) ( x )
( hx : x β S ) : β m β S , x β m β§ β a β S , m β a β a = m :=
zorn_nonempty_partialOrderβ _ ( fun _ cS hc y yc => H _ cS hc β¨ y , yc β©) _ hx
#align zorn_subset_nonempty zorn_subset_nonempty
theorem zorn_superset ( S : Set ( Set Ξ± ))
( h : β ( c ) ( _ : c β S ), IsChain (Β· β Β·) c β β lb β S , β s β c , lb β s ) :
β m β S , β a β S , a β m β a = m :=
(@ zorn_partialOrderβ ( Set Ξ± )α΅α΅ _ S ) fun c cS hc => h c cS hc . symm
#align zorn_superset zorn_superset
theorem zorn_superset_nonempty ( S : Set ( Set Ξ± ))
( H : β ( c ) ( _ : c β S ), IsChain (Β· β Β·) c β c . Nonempty β β lb β S , β s β c , lb β s ) ( x )
( hx : x β S ) : β m β S , m β x β§ β a β S , a β m β a = m :=
@ zorn_nonempty_partialOrderβ ( Set Ξ± )α΅α΅ _ S ( fun _ cS hc y yc => H _ cS hc . symm β¨ y , yc β©) _ hx
#align zorn_superset_nonempty zorn_superset_nonempty
/-- Every chain is contained in a maximal chain. This generalizes Hausdorff's maximality principle.
-/
theorem IsChain.exists_maxChain ( hc : IsChain r c ) : β M , @ IsMaxChain : {Ξ± : Type ?u.18783} β (Ξ± β Ξ± β Prop ) β Set Ξ± β Prop IsMaxChain _ r M β§ c β M := by
-- Porting note: the first three lines replace the following two lines in mathlib3.
-- The mathlib3 `obtain` supports holes for proof obligations, this is not yet implemented in 4.
-- obtain β¨M, β¨_, hMββ©, hMβ, hMββ© :=
-- zorn_subset_nonempty { s | c β s β§ IsChain r s } _ c β¨Subset.rfl, hcβ©
have H := zorn_subset_nonempty { s | c β s β§ IsChain r s } ?_ c β¨ Subset.rfl : β {Ξ± : Type ?u.18853} {s : Set Ξ± }, s β s Subset.rfl, hc β©
Β· obtain β¨ M , β¨ _ , hMβ β© , hMβ , hMβ β© := H refine_2.intro.intro.intro.intro
exact β¨ M , β¨ hMβ , fun d hd hMd => ( hMβ _ β¨ hMβ . trans hMd , hd β© hMd ). symm : β {Ξ± : Sort ?u.19033} {a b : Ξ± }, a = b β b = a symm β©, hMβ β©
rintro cs hcsβ hcsβ β¨ s , hs β©
refine'
β¨ββ cs , β¨ fun _ ha => Set.mem_sUnion_of_mem (( hcsβ hs ). left : β {a b : Prop }, a β§ b β a left ha ) hs , _ β©, fun _ =>
Set.subset_sUnion_of_mem β©
rintro y β¨ sy , hsy , hysy β© z β¨ sz , hsz , hzsz β© hyz refine_1.intro.intro.intro.intro.intro
obtain rfl rfl | hsseq : sy = sz β¨ sy β sz | hsseq := eq_or_ne : β {Ξ± : Sort ?u.19244} (x y : Ξ± ), x = y β¨ x β y eq_or_ne sy sz refine_1.intro.intro.intro.intro.intro.inl refine_1.intro.intro.intro.intro.intro.inr
Β· refine_1.intro.intro.intro.intro.intro.inl refine_1.intro.intro.intro.intro.intro.inl refine_1.intro.intro.intro.intro.intro.inr exact ( hcsβ hsy ). right : β {a b : Prop }, a β§ b β b right hysy hzsz hyz
cases' hcsβ hsy hsz hsseq with h h refine_1.intro.intro.intro.intro.intro.inr.inl refine_1.intro.intro.intro.intro.intro.inr.inr
Β· refine_1.intro.intro.intro.intro.intro.inr.inl refine_1.intro.intro.intro.intro.intro.inr.inl refine_1.intro.intro.intro.intro.intro.inr.inr exact ( hcsβ hsz ). right : β {a b : Prop }, a β§ b β b right ( h hysy ) hzsz hyz
Β· refine_1.intro.intro.intro.intro.intro.inr.inr refine_1.intro.intro.intro.intro.intro.inr.inr exact ( hcsβ hsy ). right : β {a b : Prop }, a β§ b β b right hysy ( h hzsz ) hyz
#align is_chain.exists_max_chain IsChain.exists_maxChain