Skip to content

Commit f9e5fd4

Browse files
committed
chore(Order/SuccPred/Limit): improve induction principles (#16575)
This PR does the following: - We define `isSuccPrelimitRecOn` without using tactics, which allows us to golf a proof slightly. - We define `prelimitRecOn` using `cast` instead of `Eq.subst`, which is more idiomatic. - We introduce variants of `prelimitRecOn_succ` for orders without maximum elements. - Better variable management throughout.
1 parent 035936f commit f9e5fd4

File tree

2 files changed

+70
-64
lines changed

2 files changed

+70
-64
lines changed

Mathlib/Order/SuccPred/Limit.lean

Lines changed: 69 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ end Preorder
146146

147147
section PartialOrder
148148

149-
variable [PartialOrder α] [SuccOrder α] {a b : α} {C : α → Sort*}
149+
variable [PartialOrder α] [SuccOrder α] {a b : α}
150150

151151
theorem isSuccPrelimit_of_succ_ne (h : ∀ b, succ b ≠ a) : IsSuccPrelimit a := fun b hba =>
152152
h b (CovBy.succ_eq hba)
@@ -389,7 +389,7 @@ end Preorder
389389

390390
section PartialOrder
391391

392-
variable [PartialOrder α] [PredOrder α] {a b : α} {C : α → Sort*}
392+
variable [PartialOrder α] [PredOrder α] {a b : α}
393393

394394
theorem isPredPrelimit_of_pred_ne (h : ∀ b, pred b ≠ a) : IsPredPrelimit a := fun b hba =>
395395
h b (CovBy.pred_eq hba)
@@ -478,30 +478,29 @@ end PartialOrder
478478
/-! ### Induction principles -/
479479

480480

481-
variable {C : α → Sort*} {b : α}
482-
483481
section isSuccPrelimitRecOn
484482

483+
variable {C : α → Sort*} {b : α}
484+
485485
section PartialOrder
486486

487487
variable [PartialOrder α] [SuccOrder α]
488+
(hs : ∀ a, ¬ IsMax a → C (succ a)) (hl : ∀ a, IsSuccPrelimit a → C a)
488489

489-
/-- A value can be built by building it on successors and successor limits. -/
490+
variable (b) in
491+
open Classical in
492+
/-- A value can be built by building it on successors and successor pre-limits. -/
490493
@[elab_as_elim]
491-
noncomputable def isSuccPrelimitRecOn (b : α) (hs : ∀ a, ¬ IsMax a → C (succ a))
492-
(hl : ∀ a, IsSuccPrelimit a → C a) : C b := by
493-
by_cases hb : IsSuccPrelimit b
494-
· exact hl b hb
495-
· have H := Classical.choose_spec (not_isSuccPrelimit_iff.1 hb)
496-
rw [← H.2]
497-
exact hs _ H.1
494+
noncomputable def isSuccPrelimitRecOn : C b :=
495+
if hb : IsSuccPrelimit b then hl b hb else
496+
haveI H := Classical.choose_spec (not_isSuccPrelimit_iff.1 hb)
497+
cast (congr_arg C H.2) (hs _ H.1)
498498

499499
@[deprecated isSuccPrelimitRecOn (since := "2024-09-05")]
500500
alias isSuccLimitRecOn := isSuccPrelimitRecOn
501501

502-
theorem isSuccPrelimitRecOn_limit (hs : ∀ a, ¬ IsMax a → C (succ a))
503-
(hl : ∀ a, IsSuccPrelimit a → C a) (hb : IsSuccPrelimit b) :
504-
isSuccPrelimitRecOn b hs hl = hl b hb :=
502+
@[simp]
503+
theorem isSuccPrelimitRecOn_limit (hb : IsSuccPrelimit b) : isSuccPrelimitRecOn b hs hl = hl b hb :=
505504
dif_pos hb
506505

507506
@[deprecated isSuccPrelimitRecOn_limit (since := "2024-09-05")]
@@ -512,25 +511,22 @@ end PartialOrder
512511
section LinearOrder
513512

514513
variable [LinearOrder α] [SuccOrder α]
514+
(hs : ∀ a, ¬ IsMax a → C (succ a)) (hl : ∀ a, IsSuccPrelimit a → C a)
515515

516-
theorem isSuccPrelimitRecOn_succ' (hs : ∀ a, ¬ IsMax a → C (succ a))
517-
(hl : ∀ a, IsSuccPrelimit a → C a) (hb : ¬ IsMax b) :
516+
theorem isSuccPrelimitRecOn_succ' (hb : ¬ IsMax b) :
518517
isSuccPrelimitRecOn (succ b) hs hl = hs b hb := by
519518
have hb' := not_isSuccPrelimit_succ_of_not_isMax hb
520519
have H := Classical.choose_spec (not_isSuccPrelimit_iff.1 hb')
521-
rw [isSuccPrelimitRecOn]
522-
simp only [cast_eq_iff_heq, hb', not_false_iff, eq_mpr_eq_cast, dif_neg]
523-
congr 1 <;> first |
524-
exact (succ_eq_succ_iff_of_not_isMax H.left hb).mp H.right |
525-
exact proof_irrel_heq H.left hb
520+
rw [isSuccPrelimitRecOn, dif_neg hb', cast_eq_iff_heq]
521+
congr
522+
exacts [(succ_eq_succ_iff_of_not_isMax H.1 hb).1 H.2, proof_irrel_heq _ _]
526523

527524
@[deprecated isSuccPrelimitRecOn_succ' (since := "2024-09-05")]
528525
alias isSuccLimitRecOn_succ' := isSuccPrelimitRecOn_succ'
529526

530527
@[simp]
531-
theorem isSuccPrelimitRecOn_succ [NoMaxOrder α] (hs : ∀ a, ¬ IsMax a → C (succ a))
532-
(hl : ∀ a, IsSuccPrelimit a → C a) (b : α) :
533-
@isSuccPrelimitRecOn α C _ _ (succ b) hs hl = hs b (not_isMax b) :=
528+
theorem isSuccPrelimitRecOn_succ [NoMaxOrder α] (b : α) :
529+
isSuccPrelimitRecOn (succ b) hs hl = hs b (not_isMax b) :=
534530
isSuccPrelimitRecOn_succ' _ _ _
535531

536532
@[deprecated isSuccPrelimitRecOn_succ (since := "2024-09-05")]
@@ -542,22 +538,24 @@ end isSuccPrelimitRecOn
542538

543539
section isPredPrelimitRecOn
544540

541+
variable {C : α → Sort*} {b : α}
542+
545543
section PartialOrder
546544

547545
variable [PartialOrder α] [PredOrder α]
546+
(hs : ∀ a, ¬ IsMin a → C (pred a)) (hl : ∀ a, IsPredPrelimit a → C a)
548547

549-
/-- A value can be built by building it on predecessors and predecessor limits. -/
548+
variable (b) in
549+
/-- A value can be built by building it on predecessors and predecessor pre-limits. -/
550550
@[elab_as_elim]
551-
noncomputable def isPredPrelimitRecOn (b : α) (hs : ∀ a, ¬ IsMin a → C (pred a))
552-
(hl : ∀ a, IsPredPrelimit a → C a) : C b :=
553-
@isSuccPrelimitRecOn αᵒᵈ _ _ _ _ hs fun _ ha => hl _ ha.dual
551+
noncomputable def isPredPrelimitRecOn : C b :=
552+
isSuccPrelimitRecOn (α := αᵒᵈ) b hs (fun a ha ↦ hl a ha.dual)
554553

555554
@[deprecated isPredPrelimitRecOn (since := "2024-09-05")]
556555
alias isPredLimitRecOn := isPredPrelimitRecOn
557556

558-
theorem isPredPrelimitRecOn_limit (hs : ∀ a, ¬ IsMin a → C (pred a))
559-
(hl : ∀ a, IsPredPrelimit a → C a) (hb : IsPredPrelimit b) :
560-
isPredPrelimitRecOn b hs hl = hl b hb :=
557+
@[simp]
558+
theorem isPredPrelimitRecOn_limit (hb : IsPredPrelimit b) : isPredPrelimitRecOn b hs hl = hl b hb :=
561559
isSuccPrelimitRecOn_limit _ _ hb.dual
562560

563561
@[deprecated isPredPrelimitRecOn_limit (since := "2024-09-05")]
@@ -570,17 +568,17 @@ section LinearOrder
570568
variable [LinearOrder α] [PredOrder α]
571569
(hs : ∀ a, ¬ IsMin a → C (pred a)) (hl : ∀ a, IsPredPrelimit a → C a)
572570

573-
theorem isPredPrelimitRecOn_pred' {b : α} (hb : ¬ IsMin b) :
574-
@isPredPrelimitRecOn α C _ _ (pred b) hs hl = hs b hb :=
575-
isSuccPrelimitRecOn_succ' _ _ _
571+
theorem isPredPrelimitRecOn_pred' (hb : ¬ IsMin b) :
572+
isPredPrelimitRecOn (pred b) hs hl = hs b hb :=
573+
isSuccPrelimitRecOn_succ' (α := αᵒᵈ) _ _ _
576574

577575
@[deprecated isPredPrelimitRecOn_pred' (since := "2024-09-05")]
578576
alias isPredLimitRecOn_pred' := isPredPrelimitRecOn_pred'
579577

580578
@[simp]
581579
theorem isPredPrelimitRecOn_pred [NoMinOrder α] (b : α) :
582-
@isPredPrelimitRecOn α C _ _ (pred b) hs hl = hs b (not_isMin b) :=
583-
isSuccPrelimitRecOn_succ _ _ _
580+
isPredPrelimitRecOn (pred b) hs hl = hs b (not_isMin b) :=
581+
isPredPrelimitRecOn_pred' _ _ _
584582

585583
@[deprecated isPredPrelimitRecOn_pred (since := "2024-09-05")]
586584
alias isPredLimitRecOn_pred := isPredPrelimitRecOn_pred
@@ -593,34 +591,33 @@ end Order
593591

594592
open Order
595593

596-
variable {C : α → Sort*} {b : α}
597-
598594
namespace SuccOrder
599595

600596
section prelimitRecOn
601597

598+
variable {C : α → Sort*} {b : α}
599+
602600
section PartialOrder
603601

604602
variable [PartialOrder α] [SuccOrder α] [WellFoundedLT α]
603+
(hs : ∀ a, ¬ IsMax a → C a → C (Order.succ a)) (hl : ∀ a, IsSuccPrelimit a → (∀ b < a, C b) → C a)
605604

606-
open scoped Classical in
605+
variable (b) in
606+
open Classical in
607607
/-- Recursion principle on a well-founded partial `SuccOrder`. -/
608-
@[elab_as_elim] noncomputable def prelimitRecOn (b : α)
609-
(hs : ∀ a, ¬ IsMax a → C a → C (Order.succ a))
610-
(hl : ∀ a, IsSuccPrelimit a → (∀ b < a, C b) → C a) : C b :=
608+
@[elab_as_elim] noncomputable def prelimitRecOn : C b :=
611609
wellFounded_lt.fix
612610
(fun a IH ↦ if h : IsSuccPrelimit a then hl a h IH else
613-
let x := Classical.indefiniteDescription _ (not_isSuccPrelimit_iff.mp h)
614-
x.2.2hs x x.2.1 (IH x <| x.2.2.subst <| lt_succ_of_not_isMax x.2.1))
611+
haveI H := Classical.choose_spec (not_isSuccPrelimit_iff.1 h)
612+
cast (congr_arg C H.2) (hs _ H.1 <| IH _ <| H.2.subst <| lt_succ_of_not_isMax H.1))
615613
b
616614

617615
@[deprecated prelimitRecOn (since := "2024-09-05")]
618616
alias limitRecOn := prelimitRecOn
619617

620618
@[simp]
621-
theorem prelimitRecOn_limit (hs : ∀ a, ¬ IsMax a → C a → C (Order.succ a))
622-
(hl : ∀ a, IsSuccPrelimit a → (∀ b < a, C b) → C a) (hb : IsSuccPrelimit b) :
623-
prelimitRecOn b hs hl = hl b hb fun x _ ↦ prelimitRecOn x hs hl := by
619+
theorem prelimitRecOn_limit (hb : IsSuccPrelimit b) :
620+
prelimitRecOn b hs hl = hl b hb fun x _ ↦ SuccOrder.prelimitRecOn x hs hl := by
624621
rw [prelimitRecOn, WellFounded.fix_eq, dif_pos hb]; rfl
625622

626623
@[deprecated prelimitRecOn_limit (since := "2024-09-05")]
@@ -633,15 +630,19 @@ section LinearOrder
633630
variable [LinearOrder α] [SuccOrder α] [WellFoundedLT α]
634631
(hs : ∀ a, ¬ IsMax a → C a → C (Order.succ a)) (hl : ∀ a, IsSuccPrelimit a → (∀ b < a, C b) → C a)
635632

636-
@[simp]
637-
theorem prelimitRecOn_succ (hb : ¬ IsMax b) :
633+
theorem prelimitRecOn_succ' (hb : ¬ IsMax b) :
638634
prelimitRecOn (Order.succ b) hs hl = hs b hb (prelimitRecOn b hs hl) := by
639635
have h := not_isSuccPrelimit_succ_of_not_isMax hb
636+
have H := Classical.choose_spec (not_isSuccPrelimit_iff.1 h)
640637
rw [prelimitRecOn, WellFounded.fix_eq, dif_neg h]
641-
have {b c hb hc} {x : ∀ a, C a} (h : b = c) :
642-
congr_arg Order.succ h ▸ hs b hb (x b) = hs c hc (x c) := by subst h; rfl
643-
let x := Classical.indefiniteDescription _ (not_isSuccPrelimit_iff.mp h)
644-
exact this ((succ_eq_succ_iff_of_not_isMax x.2.1 hb).mp x.2.2)
638+
have {a c : α} {ha hc} {x : ∀ a, C a} (h : a = c) :
639+
cast (congr_arg (C ∘ succ) h) (hs a ha (x a)) = hs c hc (x c) := by subst h; rfl
640+
exact this <| (succ_eq_succ_iff_of_not_isMax H.1 hb).1 H.2
641+
642+
@[simp]
643+
theorem prelimitRecOn_succ [NoMaxOrder α] (b : α) :
644+
prelimitRecOn (Order.succ b) hs hl = hs b (not_isMax b) (prelimitRecOn b hs hl) :=
645+
prelimitRecOn_succ' _ _ _
645646

646647
@[deprecated prelimitRecOn_succ (since := "2024-09-05")]
647648
alias limitRecOn_succ := prelimitRecOn_succ
@@ -654,24 +655,25 @@ end SuccOrder
654655

655656
namespace PredOrder
656657

658+
variable {C : α → Sort*} {b : α}
659+
657660
section prelimitRecOn
658661

659662
section PartialOrder
660663

661664
variable [PartialOrder α] [PredOrder α] [WellFoundedGT α]
665+
(hp : ∀ a, ¬ IsMin a → C a → C (Order.pred a)) (hl : ∀ a, IsPredPrelimit a → (∀ b > a, C b) → C a)
662666

667+
variable (b) in
663668
/-- Recursion principle on a well-founded partial `PredOrder`. -/
664-
@[elab_as_elim] noncomputable def prelimitRecOn (b : α)
665-
(hp : ∀ a, ¬ IsMin a → C a → C (Order.pred a))
666-
(hl : ∀ a, IsPredPrelimit a → (∀ b > a, C b) → C a) : C b :=
667-
SuccOrder.prelimitRecOn (α := αᵒᵈ) b hp fun a ha => hl a ha.dual
669+
@[elab_as_elim] noncomputable def prelimitRecOn : C b :=
670+
SuccOrder.prelimitRecOn (α := αᵒᵈ) b hp (fun a ha => hl a ha.dual)
668671

669672
@[deprecated prelimitRecOn (since := "2024-09-05")]
670673
alias limitRecOn := prelimitRecOn
671674

672675
@[simp]
673-
theorem prelimitRecOn_limit (hp : ∀ a, ¬ IsMin a → C a → C (Order.pred a))
674-
(hl : ∀ a, IsPredPrelimit a → (∀ b > a, C b) → C a) (hb : IsPredPrelimit b) :
676+
theorem prelimitRecOn_limit (hb : IsPredPrelimit b) :
675677
prelimitRecOn b hp hl = hl b hb fun x _ ↦ prelimitRecOn x hp hl :=
676678
SuccOrder.prelimitRecOn_limit _ _ hb.dual
677679

@@ -685,10 +687,14 @@ section LinearOrder
685687
variable [LinearOrder α] [PredOrder α] [WellFoundedGT α]
686688
(hp : ∀ a, ¬ IsMin a → C a → C (Order.pred a)) (hl : ∀ a, IsPredPrelimit a → (∀ b > a, C b) → C a)
687689

688-
@[simp]
689-
theorem prelimitRecOn_pred (hb : ¬ IsMin b) :
690+
theorem prelimitRecOn_pred' (hb : ¬ IsMin b) :
690691
prelimitRecOn (Order.pred b) hp hl = hp b hb (prelimitRecOn b hp hl) :=
691-
SuccOrder.prelimitRecOn_succ (α := αᵒᵈ) _ _ hb
692+
SuccOrder.prelimitRecOn_succ' _ _ _
693+
694+
@[simp]
695+
theorem prelimitRecOn_pred [NoMinOrder α] (b : α) :
696+
prelimitRecOn (Order.pred b) hp hl = hp b (not_isMin b) (prelimitRecOn b hp hl) :=
697+
prelimitRecOn_pred' _ _ _
692698

693699
@[deprecated prelimitRecOn_pred (since := "2024-09-05")]
694700
alias limitRecOn_pred := prelimitRecOn_pred

Mathlib/SetTheory/Ordinal/Arithmetic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ theorem limitRecOn_zero {C} (H₁ H₂ H₃) : @limitRecOn C 0 H₁ H₂ H₃ =
294294
@[simp]
295295
theorem limitRecOn_succ {C} (o H₁ H₂ H₃) :
296296
@limitRecOn C (succ o) H₁ H₂ H₃ = H₂ o (@limitRecOn C o H₁ H₂ H₃) := by
297-
rw [limitRecOn, limitRecOn, SuccOrder.prelimitRecOn_succ _ _ (not_isMax _)]
297+
rw [limitRecOn, limitRecOn, SuccOrder.prelimitRecOn_succ]
298298

299299
@[simp]
300300
theorem limitRecOn_limit {C} (o H₁ H₂ H₃ h) :

0 commit comments

Comments
 (0)