Skip to content

Commit e4eb07a

Browse files
feat(Order/Basic): Add ltByCases API (#9114)
I noticed that `ltByCases` doesn't have any API, and it would be useful to have some when working trichotomously, especially if one wishes to define things trichotomously. A non-dependent version is also defined.
1 parent 9410c2d commit e4eb07a

File tree

1 file changed

+117
-1
lines changed

1 file changed

+117
-1
lines changed

Mathlib/Order/Basic.lean

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ theorem not_gt (h : x = y) : ¬y < x :=
238238

239239
end Eq
240240

241-
242241
section
243242

244243
variable [Preorder α] {a b : α}
@@ -676,6 +675,123 @@ instance Order.Preimage.decidable {α β} (f : α → β) (s : β → β → Pro
676675
DecidableRel (f ⁻¹'o s) := fun _ _ ↦ H _ _
677676
#align order.preimage.decidable Order.Preimage.decidable
678677

678+
section ltByCases
679+
680+
variable [LinearOrder α] {P : Sort*} {x y : α}
681+
682+
@[simp]
683+
lemma ltByCases_lt (h : x < y) {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P} :
684+
ltByCases x y h₁ h₂ h₃ = h₁ h := dif_pos h
685+
686+
@[simp]
687+
lemma ltByCases_gt (h : y < x) {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P} :
688+
ltByCases x y h₁ h₂ h₃ = h₃ h := (dif_neg h.not_lt).trans (dif_pos h)
689+
690+
@[simp]
691+
lemma ltByCases_eq (h : x = y) {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P} :
692+
ltByCases x y h₁ h₂ h₃ = h₂ h := (dif_neg h.not_lt).trans (dif_neg h.not_gt)
693+
694+
lemma ltByCases_not_lt (h : ¬ x < y) {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P}
695+
(p : ¬ y < x → x = y := fun h' => (le_antisymm (le_of_not_gt h') (le_of_not_gt h))) :
696+
ltByCases x y h₁ h₂ h₃ = if h' : y < x then h₃ h' else h₂ (p h') := dif_neg h
697+
698+
lemma ltByCases_not_gt (h : ¬ y < x) {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P}
699+
(p : ¬ x < y → x = y := fun h' => (le_antisymm (le_of_not_gt h) (le_of_not_gt h'))) :
700+
ltByCases x y h₁ h₂ h₃ = if h' : x < y then h₁ h' else h₂ (p h') :=
701+
dite_congr rfl (fun _ => rfl) (fun _ => dif_neg h)
702+
703+
lemma ltByCases_ne (h : x ≠ y) {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P}
704+
(p : ¬ x < y → y < x := fun h' => h.lt_or_lt.resolve_left h') :
705+
ltByCases x y h₁ h₂ h₃ = if h' : x < y then h₁ h' else h₃ (p h') :=
706+
dite_congr rfl (fun _ => rfl) (fun _ => dif_pos _)
707+
708+
lemma ltByCases_comm {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P}
709+
(p : y = x → x = y := fun h' => h'.symm) :
710+
ltByCases x y h₁ h₂ h₃ = ltByCases y x h₃ (h₂ ∘ p) h₁ := by
711+
refine ltByCases x y (fun h => ?_) (fun h => ?_) (fun h => ?_)
712+
· rw [ltByCases_lt h, ltByCases_gt h]
713+
· rw [ltByCases_eq h, ltByCases_eq h.symm, comp_apply]
714+
· rw [ltByCases_lt h, ltByCases_gt h]
715+
716+
lemma eq_iff_eq_of_lt_iff_lt_of_gt_iff_gt {x' y' : α}
717+
(ltc : (x < y) ↔ (x' < y')) (gtc : (y < x) ↔ (y' < x')) :
718+
x = y ↔ x' = y' := by simp_rw [eq_iff_le_not_lt, ← not_lt, ltc, gtc]
719+
720+
lemma ltByCases_rec {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P} (p : P)
721+
(hlt : (h : x < y) → h₁ h = p) (heq : (h : x = y) → h₂ h = p)
722+
(hgt : (h : y < x) → h₃ h = p) :
723+
ltByCases x y h₁ h₂ h₃ = p :=
724+
ltByCases x y
725+
(fun h => ltByCases_lt h ▸ hlt h)
726+
(fun h => ltByCases_eq h ▸ heq h)
727+
(fun h => ltByCases_gt h ▸ hgt h)
728+
729+
lemma ltByCases_eq_iff {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P} {p : P} :
730+
ltByCases x y h₁ h₂ h₃ = p ↔ (∃ h, h₁ h = p) ∨ (∃ h, h₂ h = p) ∨ (∃ h, h₃ h = p) := by
731+
refine ltByCases x y (fun h => ?_) (fun h => ?_) (fun h => ?_)
732+
· simp only [ltByCases_lt, exists_prop_of_true, h, h.not_lt, not_false_eq_true,
733+
exists_prop_of_false, or_false, h.ne]
734+
· simp only [h, lt_self_iff_false, ltByCases_eq, not_false_eq_true,
735+
exists_prop_of_false, exists_prop_of_true, or_false, false_or]
736+
· simp only [ltByCases_gt, exists_prop_of_true, h, h.not_lt, not_false_eq_true,
737+
exists_prop_of_false, false_or, h.ne']
738+
739+
lemma ltByCases_congr {x' y' : α} {h₁ : x < y → P} {h₂ : x = y → P} {h₃ : y < x → P}
740+
{h₁' : x' < y' → P} {h₂' : x' = y' → P} {h₃' : y' < x' → P} (ltc : (x < y) ↔ (x' < y'))
741+
(gtc : (y < x) ↔ (y' < x')) (hh'₁ : ∀ (h : x' < y'), h₁ (ltc.mpr h) = h₁' h)
742+
(hh'₂ : ∀ (h : x' = y'), h₂ ((eq_iff_eq_of_lt_iff_lt_of_gt_iff_gt ltc gtc).mpr h) = h₂' h)
743+
(hh'₃ : ∀ (h : y' < x'), h₃ (gtc.mpr h) = h₃' h) :
744+
ltByCases x y h₁ h₂ h₃ = ltByCases x' y' h₁' h₂' h₃' := by
745+
refine ltByCases_rec _ (fun h => ?_) (fun h => ?_) (fun h => ?_)
746+
· rw [ltByCases_lt (ltc.mp h), hh'₁]
747+
· rw [eq_iff_eq_of_lt_iff_lt_of_gt_iff_gt ltc gtc] at h
748+
rw [ltByCases_eq h, hh'₂]
749+
· rw [ltByCases_gt (gtc.mp h), hh'₃]
750+
751+
/-- Perform a case-split on the ordering of `x` and `y` in a decidable linear order,
752+
non-dependently. -/
753+
abbrev ltTrichotomy (x y : α) (p q r : P) := ltByCases x y (fun _ => p) (fun _ => q) (fun _ => r)
754+
755+
variable {p q r s : P}
756+
757+
@[simp]
758+
lemma ltTrichotomy_lt (h : x < y) : ltTrichotomy x y p q r = p := ltByCases_lt h
759+
760+
@[simp]
761+
lemma ltTrichotomy_gt (h : y < x) : ltTrichotomy x y p q r = r := ltByCases_gt h
762+
763+
@[simp]
764+
lemma ltTrichotomy_eq (h : x = y) : ltTrichotomy x y p q r = q := ltByCases_eq h
765+
766+
lemma ltTrichotomy_not_lt (h : ¬ x < y) :
767+
ltTrichotomy x y p q r = if y < x then r else q := ltByCases_not_lt h
768+
769+
lemma ltTrichotomy_not_gt (h : ¬ y < x) :
770+
ltTrichotomy x y p q r = if x < y then p else q := ltByCases_not_gt h
771+
772+
lemma ltTrichotomy_ne (h : x ≠ y) :
773+
ltTrichotomy x y p q r = if x < y then p else r := ltByCases_ne h
774+
775+
lemma ltTrichotomy_comm : ltTrichotomy x y p q r = ltTrichotomy y x r q p := ltByCases_comm
776+
777+
lemma ltTrichotomy_self {p : P} : ltTrichotomy x y p p p = p :=
778+
ltByCases_rec p (fun _ => rfl) (fun _ => rfl) (fun _ => rfl)
779+
780+
lemma ltTrichotomy_eq_iff : ltTrichotomy x y p q r = s ↔
781+
(x < y ∧ p = s) ∨ (x = y ∧ q = s) ∨ (y < x ∧ r = s) := by
782+
refine ltByCases x y (fun h => ?_) (fun h => ?_) (fun h => ?_)
783+
· simp only [ltTrichotomy_lt, false_and, true_and, or_false, h, h.not_lt, h.ne]
784+
· simp only [ltTrichotomy_eq, false_and, true_and, or_false, false_or, h, lt_irrefl]
785+
· simp only [ltTrichotomy_gt, false_and, true_and, false_or, h, h.not_lt, h.ne']
786+
787+
lemma ltTrichotomy_congr {x' y' : α} {p' q' r' : P} (ltc : (x < y) ↔ (x' < y'))
788+
(gtc : (y < x) ↔ (y' < x')) (hh'₁ : x' < y' → p = p')
789+
(hh'₂ : x' = y' → q = q') (hh'₃ : y' < x' → r = r') :
790+
ltTrichotomy x y p q r = ltTrichotomy x' y' p' q' r' :=
791+
ltByCases_congr ltc gtc hh'₁ hh'₂ hh'₃
792+
793+
end ltByCases
794+
679795
/-! ### Order dual -/
680796

681797

0 commit comments

Comments
 (0)