Module docstring
{"### Lexicographic ordering "}
{"### Lexicographic ordering "}
List.lex_lt
theorem
[LT α] {l₁ l₂ : List α} : Lex (· < ·) l₁ l₂ ↔ l₁ < l₂
List.not_lex_lt
theorem
[LT α] {l₁ l₂ : List α} : ¬Lex (· < ·) l₁ l₂ ↔ l₂ ≤ l₁
@[simp] theorem not_lex_lt [LT α] {l₁ l₂ : List α} : ¬ Lex (· < ·) l₁ l₂¬ Lex (· < ·) l₁ l₂ ↔ l₂ ≤ l₁ := Iff.rfl
List.not_lt_iff_ge
theorem
[LT α] {l₁ l₂ : List α} : ¬l₁ < l₂ ↔ l₂ ≤ l₁
protected theorem not_lt_iff_ge [LT α] {l₁ l₂ : List α} : ¬ l₁ < l₂¬ l₁ < l₂ ↔ l₂ ≤ l₁ := Iff.rfl
List.not_le_iff_gt
theorem
[DecidableEq α] [LT α] [DecidableLT α] {l₁ l₂ : List α} : ¬l₁ ≤ l₂ ↔ l₂ < l₁
protected theorem not_le_iff_gt [DecidableEq α] [LT α] [DecidableLT α] {l₁ l₂ : List α} :
¬ l₁ ≤ l₂¬ l₁ ≤ l₂ ↔ l₂ < l₁ :=
Decidable.not_not
List.lex_irrefl
theorem
{r : α → α → Prop} (irrefl : ∀ x, ¬r x x) (l : List α) : ¬Lex r l l
theorem lex_irrefl {r : α → α → Prop} (irrefl : ∀ x, ¬r x x) (l : List α) : ¬Lex r l l := by
induction l with
| nil => nofun
| cons a l ih => intro
| .rel h => exact irrefl _ h
| .cons h => exact ih h
List.lt_irrefl
theorem
[LT α] [Std.Irrefl (· < · : α → α → Prop)] (l : List α) : ¬l < l
protected theorem lt_irrefl [LT α] [Std.Irrefl (· < · : α → α → Prop)] (l : List α) : ¬ l < l :=
lex_irrefl Std.Irrefl.irrefl l
List.ltIrrefl
instance
[LT α] [Std.Irrefl (· < · : α → α → Prop)] : Std.Irrefl (α := List α) (· < ·)
instance ltIrrefl [LT α] [Std.Irrefl (· < · : α → α → Prop)] : Std.Irrefl (α := List α) (· < ·) where
irrefl := List.lt_irrefl
List.not_lex_nil
theorem
: ¬Lex r l []
@[simp] theorem not_lex_nil : ¬Lex r l [] := fun h => nomatch h
List.not_lt_nil
theorem
[LT α] (l : List α) : ¬l < []
@[simp] theorem not_lt_nil [LT α] (l : List α) : ¬ l < [] := fun h => nomatch h
List.nil_le
theorem
[LT α] (l : List α) : [] ≤ l
List.not_nil_lex_iff
theorem
: ¬Lex r [] l ↔ l = []
@[simp] theorem not_nil_lex_iff : ¬Lex r [] l¬Lex r [] l ↔ l = [] := by
constructor
· rintro h
match l, h with
| [], h => rfl
| a :: _, h => exact False.elim (h Lex.nil)
· rintro rfl
exact not_lex_nil
List.le_nil
theorem
[LT α] {l : List α} : l ≤ [] ↔ l = []
@[simp] theorem le_nil [LT α] {l : List α} : l ≤ [] ↔ l = [] := not_nil_lex_iff
List.nil_lex_cons'
theorem
: Lex r [] (a :: l)
@[simp] theorem nil_lex_cons' : Lex r [] (a :: l) := Lex.nil
List.nil_lt_cons
theorem
[LT α] (a : α) (l : List α) : [] < a :: l
List.cons_lex_cons_iff
theorem
: Lex r (a :: l₁) (b :: l₂) ↔ r a b ∨ a = b ∧ Lex r l₁ l₂
List.cons_lt_cons_iff
theorem
[LT α] {a b} {l₁ l₂ : List α} : (a :: l₁) < (b :: l₂) ↔ a < b ∨ a = b ∧ l₁ < l₂
theorem cons_lt_cons_iff [LT α] {a b} {l₁ l₂ : List α} :
(a :: l₁) < (b :: l₂) ↔ a < b ∨ a = b ∧ l₁ < l₂ := by
dsimp only [instLT, List.lt]
simp [cons_lex_cons_iff]
List.cons_lt_cons_self
theorem
[LT α] [i₀ : Std.Irrefl (· < · : α → α → Prop)] {l₁ l₂ : List α} : (a :: l₁) < (a :: l₂) ↔ l₁ < l₂
@[simp] theorem cons_lt_cons_self [LT α] [i₀ : Std.Irrefl (· < · : α → α → Prop)] {l₁ l₂ : List α} :
(a :: l₁) < (a :: l₂) ↔ l₁ < l₂ := by
simp [cons_lt_cons_iff, i₀.irrefl]
List.not_cons_lex_cons_iff
theorem
[DecidableEq α] [DecidableRel r] {a b} {l₁ l₂ : List α} :
¬Lex r (a :: l₁) (b :: l₂) ↔ (¬r a b ∧ a ≠ b) ∨ (¬r a b ∧ ¬Lex r l₁ l₂)
theorem not_cons_lex_cons_iff [DecidableEq α] [DecidableRel r] {a b} {l₁ l₂ : List α} :
¬ Lex r (a :: l₁) (b :: l₂)¬ Lex r (a :: l₁) (b :: l₂) ↔ (¬ r a b ∧ a ≠ b) ∨ (¬ r a b ∧ ¬ Lex r l₁ l₂) := by
rw [cons_lex_cons_iff, not_or, Decidable.not_and_iff_or_not, and_or_left]
List.cons_le_cons_iff
theorem
[DecidableEq α] [LT α] [DecidableLT α] [i₀ : Std.Irrefl (· < · : α → α → Prop)] [i₁ : Std.Asymm (· < · : α → α → Prop)]
[i₂ : Std.Antisymm (¬· < · : α → α → Prop)] {a b} {l₁ l₂ : List α} : (a :: l₁) ≤ (b :: l₂) ↔ a < b ∨ a = b ∧ l₁ ≤ l₂
theorem cons_le_cons_iff [DecidableEq α] [LT α] [DecidableLT α]
[i₀ : Std.Irrefl (· < · : α → α → Prop)]
[i₁ : Std.Asymm (· < · : α → α → Prop)]
[i₂ : Std.Antisymm (¬ · < · : α → α → Prop)]
{a b} {l₁ l₂ : List α} :
(a :: l₁) ≤ (b :: l₂) ↔ a < b ∨ a = b ∧ l₁ ≤ l₂ := by
dsimp only [instLE, instLT, List.le, List.lt]
simp only [not_cons_lex_cons_iff, ne_eq]
constructor
· rintro (⟨h₁, h₂⟩ | ⟨h₁, h₂⟩)
· left
apply Decidable.byContradiction
intro h₃
apply h₂
exact i₂.antisymm _ _ h₁ h₃
· if h₃ : a < b then
exact .inl h₃
else
right
exact ⟨i₂.antisymm _ _ h₃ h₁, h₂⟩
· rintro (h | ⟨h₁, h₂⟩)
· left
exact ⟨i₁.asymm _ _ h, fun w => i₀.irrefl _ (w ▸ h)⟩
· right
exact ⟨fun w => i₀.irrefl _ (h₁ ▸ w), h₂⟩
List.not_lt_of_cons_le_cons
theorem
[DecidableEq α] [LT α] [DecidableLT α] [i₀ : Std.Irrefl (· < · : α → α → Prop)] [i₁ : Std.Asymm (· < · : α → α → Prop)]
[i₂ : Std.Antisymm (¬· < · : α → α → Prop)] {a b : α} {l₁ l₂ : List α} (h : a :: l₁ ≤ b :: l₂) : ¬b < a
theorem not_lt_of_cons_le_cons [DecidableEq α] [LT α] [DecidableLT α]
[i₀ : Std.Irrefl (· < · : α → α → Prop)]
[i₁ : Std.Asymm (· < · : α → α → Prop)]
[i₂ : Std.Antisymm (¬ · < · : α → α → Prop)]
{a b : α} {l₁ l₂ : List α} (h : a :: l₁ ≤ b :: l₂) : ¬ b < a := by
rw [cons_le_cons_iff] at h
rcases h with h | ⟨rfl, h⟩
· exact i₁.asymm _ _ h
· exact i₀.irrefl _
List.le_of_cons_le_cons
theorem
[DecidableEq α] [LT α] [DecidableLT α] [i₀ : Std.Irrefl (· < · : α → α → Prop)] [i₁ : Std.Asymm (· < · : α → α → Prop)]
[i₂ : Std.Antisymm (¬· < · : α → α → Prop)] {a} {l₁ l₂ : List α} (h : a :: l₁ ≤ a :: l₂) : l₁ ≤ l₂
theorem le_of_cons_le_cons [DecidableEq α] [LT α] [DecidableLT α]
[i₀ : Std.Irrefl (· < · : α → α → Prop)]
[i₁ : Std.Asymm (· < · : α → α → Prop)]
[i₂ : Std.Antisymm (¬ · < · : α → α → Prop)]
{a} {l₁ l₂ : List α} (h : a :: l₁ ≤ a :: l₂) : l₁ ≤ l₂ := by
rw [cons_le_cons_iff] at h
rcases h with h | ⟨_, h⟩
· exact False.elim (i₀.irrefl _ h)
· exact h
List.le_refl
theorem
[LT α] [i₀ : Std.Irrefl (· < · : α → α → Prop)] (l : List α) : l ≤ l
List.instReflLeOfIrreflLt
instance
[LT α] [Std.Irrefl (· < · : α → α → Prop)] : Std.Refl (· ≤ · : List α → List α → Prop)
instance [LT α] [Std.Irrefl (· < · : α → α → Prop)] : Std.Refl (· ≤ · : List α → List α → Prop) where
refl := List.le_refl
List.lex_trans
theorem
{r : α → α → Prop} (lt_trans : ∀ {x y z : α}, r x y → r y z → r x z) (h₁ : Lex r l₁ l₂) (h₂ : Lex r l₂ l₃) :
Lex r l₁ l₃
theorem lex_trans {r : α → α → Prop}
(lt_trans : ∀ {x y z : α}, r x y → r y z → r x z)
(h₁ : Lex r l₁ l₂) (h₂ : Lex r l₂ l₃) : Lex r l₁ l₃ := by
induction h₁ generalizing l₃ with
| nil => let _::_ := l₃; exact List.Lex.nil ..
| @rel a l₁ b l₂ ab =>
match h₂ with
| .rel bc => exact List.Lex.rel (lt_trans ab bc)
| .cons ih =>
exact List.Lex.rel ab
| @cons a l₁ l₂ h₁ ih2 =>
match h₂ with
| .rel bc =>
exact List.Lex.rel bc
| .cons ih =>
exact List.Lex.cons (ih2 ih)
List.lt_trans
theorem
[LT α] [i₁ : Trans (· < · : α → α → Prop) (· < ·) (· < ·)] {l₁ l₂ l₃ : List α} (h₁ : l₁ < l₂) (h₂ : l₂ < l₃) : l₁ < l₃
List.instTransLt
instance
[LT α] [Trans (· < · : α → α → Prop) (· < ·) (· < ·)] : Trans (· < · : List α → List α → Prop) (· < ·) (· < ·)
List.lt_antisymm
abbrev
@[deprecated List.le_antisymm (since := "2024-12-13")]
protected abbrev lt_antisymm := @List.le_antisymm
List.lt_of_le_of_lt
theorem
[DecidableEq α] [LT α] [DecidableLT α] [i₀ : Std.Irrefl (· < · : α → α → Prop)] [i₁ : Std.Asymm (· < · : α → α → Prop)]
[i₂ : Std.Antisymm (¬· < · : α → α → Prop)] [i₃ : Trans (¬· < · : α → α → Prop) (¬· < ·) (¬· < ·)] {l₁ l₂ l₃ : List α}
(h₁ : l₁ ≤ l₂) (h₂ : l₂ < l₃) : l₁ < l₃
protected theorem lt_of_le_of_lt [DecidableEq α] [LT α] [DecidableLT α]
[i₀ : Std.Irrefl (· < · : α → α → Prop)]
[i₁ : Std.Asymm (· < · : α → α → Prop)]
[i₂ : Std.Antisymm (¬ · < · : α → α → Prop)]
[i₃ : Trans (¬ · < · : α → α → Prop) (¬ · < ·) (¬ · < ·)]
{l₁ l₂ l₃ : List α} (h₁ : l₁ ≤ l₂) (h₂ : l₂ < l₃) : l₁ < l₃ := by
induction h₂ generalizing l₁ with
| nil => simp_all
| rel hab =>
rename_i a xs
cases l₁ with
| nil => simp_all
| cons c l₁ =>
apply Lex.rel
replace h₁ := not_lt_of_cons_le_cons h₁
apply Decidable.byContradiction
intro h₂
have := i₃.trans h₁ h₂
contradiction
| cons w₃ ih =>
rename_i a as bs
cases l₁ with
| nil => simp_all
| cons c l₁ =>
have w₄ := not_lt_of_cons_le_cons h₁
by_cases w₅ : a = c
· subst w₅
exact Lex.cons (ih (le_of_cons_le_cons h₁))
· exact Lex.rel (Decidable.byContradiction fun w₆ => w₅ (i₂.antisymm _ _ w₄ w₆))
List.le_trans
theorem
[DecidableEq α] [LT α] [DecidableLT α] [Std.Irrefl (· < · : α → α → Prop)] [Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬· < · : α → α → Prop)] [Trans (¬· < · : α → α → Prop) (¬· < ·) (¬· < ·)] {l₁ l₂ l₃ : List α}
(h₁ : l₁ ≤ l₂) (h₂ : l₂ ≤ l₃) : l₁ ≤ l₃
protected theorem le_trans [DecidableEq α] [LT α] [DecidableLT α]
[Std.Irrefl (· < · : α → α → Prop)]
[Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬ · < · : α → α → Prop)]
[Trans (¬ · < · : α → α → Prop) (¬ · < ·) (¬ · < ·)]
{l₁ l₂ l₃ : List α} (h₁ : l₁ ≤ l₂) (h₂ : l₂ ≤ l₃) : l₁ ≤ l₃ :=
fun h₃ => h₁ (List.lt_of_le_of_lt h₂ h₃)
List.instTransLeOfDecidableEqOfDecidableLTOfIrreflOfAsymmOfAntisymmOfNotLt
instance
[DecidableEq α] [LT α] [DecidableLT α] [Std.Irrefl (· < · : α → α → Prop)] [Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬· < · : α → α → Prop)] [Trans (¬· < · : α → α → Prop) (¬· < ·) (¬· < ·)] :
Trans (· ≤ · : List α → List α → Prop) (· ≤ ·) (· ≤ ·)
instance [DecidableEq α] [LT α] [DecidableLT α]
[Std.Irrefl (· < · : α → α → Prop)]
[Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬ · < · : α → α → Prop)]
[Trans (¬ · < · : α → α → Prop) (¬ · < ·) (¬ · < ·)] :
Trans (· ≤ · : List α → List α → Prop) (· ≤ ·) (· ≤ ·) where
trans h₁ h₂ := List.le_trans h₁ h₂
List.lex_asymm
theorem
{r : α → α → Prop} (h : ∀ {x y : α}, r x y → ¬r y x) : ∀ {l₁ l₂ : List α}, Lex r l₁ l₂ → ¬Lex r l₂ l₁
theorem lex_asymm {r : α → α → Prop}
(h : ∀ {x y : α}, r x y → ¬ r y x) : ∀ {l₁ l₂ : List α}, Lex r l₁ l₂ → ¬ Lex r l₂ l₁
| nil, _, .nil => by simp
| x :: l₁, y :: l₂, .rel h₁ =>
fun
| .rel h₂ => h h₁ h₂
| .cons h₂ => h h₁ h₁
| x :: l₁, _ :: l₂, .cons h₁ =>
fun
| .rel h₂ => h h₂ h₂
| .cons h₂ => lex_asymm h h₁ h₂
List.lt_asymm
theorem
[LT α] [i : Std.Asymm (· < · : α → α → Prop)] {l₁ l₂ : List α} (h : l₁ < l₂) : ¬l₂ < l₁
List.instAsymmLt
instance
[LT α] [Std.Asymm (· < · : α → α → Prop)] : Std.Asymm (· < · : List α → List α → Prop)
List.not_lex_total
theorem
[DecidableEq α] {r : α → α → Prop} [DecidableRel r] (h : ∀ x y : α, ¬r x y ∨ ¬r y x) (l₁ l₂ : List α) :
¬Lex r l₁ l₂ ∨ ¬Lex r l₂ l₁
theorem not_lex_total [DecidableEq α] {r : α → α → Prop} [DecidableRel r]
(h : ∀ x y : α, ¬ r x y¬ r x y ∨ ¬ r y x) (l₁ l₂ : List α) : ¬ Lex r l₁ l₂¬ Lex r l₁ l₂ ∨ ¬ Lex r l₂ l₁ := by
rw [Decidable.or_iff_not_imp_left, Decidable.not_not]
intro w₁ w₂
match l₁, l₂, w₁, w₂ with
| nil, _ :: _, .nil, w₂ => simp at w₂
| x :: _, y :: _, .rel _, .rel _ =>
obtain (_ | _) := h x y <;> contradiction
| x :: _, _ :: _, .rel _, .cons _ =>
obtain (_ | _) := h x x <;> contradiction
| x :: _, _ :: _, .cons _, .rel _ =>
obtain (_ | _) := h x x <;> contradiction
| _ :: l₁, _ :: l₂, .cons _, .cons _ =>
obtain (_ | _) := not_lex_total h l₁ l₂ <;> contradiction
List.le_total
theorem
[DecidableEq α] [LT α] [DecidableLT α] [i : Std.Total (¬· < · : α → α → Prop)] (l₁ l₂ : List α) : l₁ ≤ l₂ ∨ l₂ ≤ l₁
protected theorem le_total [DecidableEq α] [LT α] [DecidableLT α]
[i : Std.Total (¬ · < · : α → α → Prop)] (l₁ l₂ : List α) : l₁ ≤ l₂ ∨ l₂ ≤ l₁ :=
not_lex_total i.total l₂ l₁
List.instTotalLeOfDecidableEqOfDecidableLTOfNotLt
instance
[DecidableEq α] [LT α] [DecidableLT α] [Std.Total (¬· < · : α → α → Prop)] : Std.Total (· ≤ · : List α → List α → Prop)
instance [DecidableEq α] [LT α] [DecidableLT α]
[Std.Total (¬ · < · : α → α → Prop)] :
Std.Total (· ≤ · : List α → List α → Prop) where
total := List.le_total
List.not_lt
theorem
[LT α] {l₁ l₂ : List α} : ¬l₁ < l₂ ↔ l₂ ≤ l₁
List.not_le
theorem
[DecidableEq α] [LT α] [DecidableLT α] {l₁ l₂ : List α} : ¬l₂ ≤ l₁ ↔ l₁ < l₂
@[simp] protected theorem not_le [DecidableEq α] [LT α] [DecidableLT α]
{l₁ l₂ : List α} : ¬ l₂ ≤ l₁¬ l₂ ≤ l₁ ↔ l₁ < l₂ := Decidable.not_not
List.le_of_lt
theorem
[DecidableEq α] [LT α] [DecidableLT α] [i : Std.Total (¬· < · : α → α → Prop)] {l₁ l₂ : List α} (h : l₁ < l₂) : l₁ ≤ l₂
protected theorem le_of_lt [DecidableEq α] [LT α] [DecidableLT α]
[i : Std.Total (¬ · < · : α → α → Prop)]
{l₁ l₂ : List α} (h : l₁ < l₂) : l₁ ≤ l₂ := by
obtain (h' | h') := List.le_total l₁ l₂
· exact h'
· exfalso
exact h' h
List.le_iff_lt_or_eq
theorem
[DecidableEq α] [LT α] [DecidableLT α] [Std.Irrefl (· < · : α → α → Prop)] [Std.Antisymm (¬· < · : α → α → Prop)]
[Std.Total (¬· < · : α → α → Prop)] {l₁ l₂ : List α} : l₁ ≤ l₂ ↔ l₁ < l₂ ∨ l₁ = l₂
protected theorem le_iff_lt_or_eq [DecidableEq α] [LT α] [DecidableLT α]
[Std.Irrefl (· < · : α → α → Prop)]
[Std.Antisymm (¬ · < · : α → α → Prop)]
[Std.Total (¬ · < · : α → α → Prop)]
{l₁ l₂ : List α} : l₁ ≤ l₂ ↔ l₁ < l₂ ∨ l₁ = l₂ := by
constructor
· intro h
by_cases h' : l₂ ≤ l₁
· right
apply List.le_antisymm h h'
· left
exact Decidable.not_not.mp h'
· rintro (h | rfl)
· exact List.le_of_lt h
· exact List.le_refl l₁
List.lex_eq_decide_lex
theorem
[DecidableEq α] (lt : α → α → Bool) : lex l₁ l₂ lt = decide (Lex (fun x y => lt x y) l₁ l₂)
theorem lex_eq_decide_lex [DecidableEq α] (lt : α → α → Bool) :
lex l₁ l₂ lt = decide (Lex (fun x y => lt x y) l₁ l₂) := by
induction l₁ generalizing l₂ with
| nil =>
cases l₂ with
| nil => simp [lex]
| cons b bs => simp [lex]
| cons a l₁ ih =>
cases l₂ with
| nil => simp [lex]
| cons b bs =>
simp [lex, ih, cons_lex_cons_iff, Bool.beq_eq_decide_eq]
List.lex_eq_true_iff_lex
theorem
[DecidableEq α] (lt : α → α → Bool) : lex l₁ l₂ lt = true ↔ Lex (fun x y => lt x y) l₁ l₂
/-- Variant of `lex_eq_true_iff` using an arbitrary comparator. -/
@[simp] theorem lex_eq_true_iff_lex [DecidableEq α] (lt : α → α → Bool) :
lexlex l₁ l₂ lt = true ↔ Lex (fun x y => lt x y) l₁ l₂ := by
simp [lex_eq_decide_lex]
List.lex_eq_false_iff_not_lex
theorem
[DecidableEq α] (lt : α → α → Bool) : lex l₁ l₂ lt = false ↔ ¬Lex (fun x y => lt x y) l₁ l₂
/-- Variant of `lex_eq_false_iff` using an arbitrary comparator. -/
@[simp] theorem lex_eq_false_iff_not_lex [DecidableEq α] (lt : α → α → Bool) :
lexlex l₁ l₂ lt = false ↔ ¬ Lex (fun x y => lt x y) l₁ l₂ := by
simp [Bool.eq_false_iff, lex_eq_true_iff_lex]
List.lex_eq_true_iff_lt
theorem
[DecidableEq α] [LT α] [DecidableLT α] {l₁ l₂ : List α} : lex l₁ l₂ = true ↔ l₁ < l₂
@[simp] theorem lex_eq_true_iff_lt [DecidableEq α] [LT α] [DecidableLT α]
{l₁ l₂ : List α} : lexlex l₁ l₂ = true ↔ l₁ < l₂ := by
simp only [lex_eq_true_iff_lex, decide_eq_true_eq]
exact Iff.rfl
List.lex_eq_false_iff_ge
theorem
[DecidableEq α] [LT α] [DecidableLT α] {l₁ l₂ : List α} : lex l₁ l₂ = false ↔ l₂ ≤ l₁
@[simp] theorem lex_eq_false_iff_ge [DecidableEq α] [LT α] [DecidableLT α]
{l₁ l₂ : List α} : lexlex l₁ l₂ = false ↔ l₂ ≤ l₁ := by
simp only [lex_eq_false_iff_not_lex, decide_eq_true_eq]
exact Iff.rfl
List.lex_eq_true_iff_exists
theorem
[BEq α] (lt : α → α → Bool) :
lex l₁ l₂ lt = true ↔
(l₁.isEqv (l₂.take l₁.length) (· == ·) ∧ l₁.length < l₂.length) ∨
(∃ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length),
(∀ j, (hj : j < i) → l₁[j]'(Nat.lt_trans hj h₁) == l₂[j]'(Nat.lt_trans hj h₂)) ∧ lt l₁[i] l₂[i])
/--
`l₁` is lexicographically less than `l₂` if either
- `l₁` is pairwise equivalent under `· == ·` to `l₂.take l₁.length`,
and `l₁` is shorter than `l₂` or
- there exists an index `i` such that
- for all `j < i`, `l₁[j] == l₂[j]` and
- `l₁[i] < l₂[i]`
-/
theorem lex_eq_true_iff_exists [BEq α] (lt : α → α → Bool) :
lexlex l₁ l₂ lt = true ↔
(l₁.isEqv (l₂.take l₁.length) (· == ·) ∧ l₁.length < l₂.length) ∨
(∃ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length),
(∀ j, (hj : j < i) →
l₁[j]'(Nat.lt_trans hj h₁) == l₂[j]'(Nat.lt_trans hj h₂)) ∧ lt l₁[i] l₂[i]) := by
induction l₁ generalizing l₂ with
| nil =>
cases l₂ with
| nil => simp [lex]
| cons b bs => simp [lex]
| cons a l₁ ih =>
cases l₂ with
| nil => simp [lex]
| cons b l₂ =>
simp [cons_lex_cons, Bool.or_eq_true, Bool.and_eq_true, ih, isEqv, length_cons]
constructor
· rintro (hab | ⟨hab, ⟨h₁, h₂⟩ | ⟨i, h₁, h₂, w₁, w₂⟩⟩)
· exact .inr ⟨0, by simp [hab]⟩
· exact .inl ⟨⟨hab, h₁⟩, by simpa using h₂⟩
· refine .inr ⟨i + 1, by simp [h₁],
by simp [h₂], ?_, ?_⟩
· intro j hj
cases j with
| zero => simp [hab]
| succ j =>
simp only [getElem_cons_succ]
rw [w₁]
simpa using hj
· simpa using w₂
· rintro (⟨⟨h₁, h₂⟩, h₃⟩ | ⟨i, h₁, h₂, w₁, w₂⟩)
· exact .inr ⟨h₁, .inl ⟨h₂, by simpa using h₃⟩⟩
· cases i with
| zero =>
left
simpa using w₂
| succ i =>
right
refine ⟨by simpa using w₁ 0 (by simp), ?_⟩
right
refine ⟨i, by simpa using h₁, by simpa using h₂, ?_, ?_⟩
· intro j hj
simpa using w₁ (j + 1) (by simpa)
· simpa using w₂
List.lex_eq_false_iff_exists
theorem
[BEq α] [PartialEquivBEq α] (lt : α → α → Bool) (lt_irrefl : ∀ x y, x == y → lt x y = false)
(lt_asymm : ∀ x y, lt x y = true → lt y x = false) (lt_antisymm : ∀ x y, lt x y = false → lt y x = false → x == y) :
lex l₁ l₂ lt = false ↔
(l₂.isEqv (l₁.take l₂.length) (· == ·)) ∨
(∃ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length),
(∀ j, (hj : j < i) → l₁[j]'(Nat.lt_trans hj h₁) == l₂[j]'(Nat.lt_trans hj h₂)) ∧ lt l₂[i] l₁[i])
/--
`l₁` is *not* lexicographically less than `l₂`
(which you might think of as "`l₂` is lexicographically greater than or equal to `l₁`"") if either
- `l₁` is pairwise equivalent under `· == ·` to `l₂.take l₁.length` or
- there exists an index `i` such that
- for all `j < i`, `l₁[j] == l₂[j]` and
- `l₂[i] < l₁[i]`
This formulation requires that `==` and `lt` are compatible in the following senses:
- `==` is symmetric
(we unnecessarily further assume it is transitive, to make use of the existing typeclasses)
- `lt` is irreflexive with respect to `==` (i.e. if `x == y` then `lt x y = false`
- `lt` is asymmmetric (i.e. `lt x y = true → lt y x = false`)
- `lt` is antisymmetric with respect to `==` (i.e. `lt x y = false → lt y x = false → x == y`)
-/
theorem lex_eq_false_iff_exists [BEq α] [PartialEquivBEq α] (lt : α → α → Bool)
(lt_irrefl : ∀ x y, x == y → lt x y = false)
(lt_asymm : ∀ x y, lt x y = true → lt y x = false)
(lt_antisymm : ∀ x y, lt x y = false → lt y x = false → x == y) :
lexlex l₁ l₂ lt = false ↔
(l₂.isEqv (l₁.take l₂.length) (· == ·)) ∨
(∃ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length),
(∀ j, (hj : j < i) →
l₁[j]'(Nat.lt_trans hj h₁) == l₂[j]'(Nat.lt_trans hj h₂)) ∧ lt l₂[i] l₁[i]) := by
induction l₁ generalizing l₂ with
| nil =>
cases l₂ with
| nil => simp [lex]
| cons b bs => simp [lex]
| cons a l₁ ih =>
cases l₂ with
| nil => simp [lex]
| cons b l₂ =>
simp [cons_lex_cons, Bool.or_eq_false_iff, Bool.and_eq_false_imp, ih, isEqv,
Bool.and_eq_true, length_cons]
constructor
· rintro ⟨hab, h⟩
if eq : b == a then
specialize h (BEq.symm eq)
obtain (h | ⟨i, h₁, h₂, w₁, w₂⟩) := h
· exact .inl ⟨eq, h⟩
· refine .inr ⟨i + 1, by simpa using h₁, by simpa using h₂, ?_, ?_⟩
· intro j hj
cases j with
| zero => simpa using BEq.symm eq
| succ j =>
simp only [getElem_cons_succ]
rw [w₁]
simpa using hj
· simpa using w₂
else
right
have hba : lt b a :=
Decidable.byContradiction fun hba => eq (lt_antisymm _ _ (by simpa using hba) hab)
exact ⟨0, by simp, by simp, by simpa⟩
· rintro (⟨eq, h⟩ | ⟨i, h₁, h₂, w₁, w₂⟩)
· exact ⟨lt_irrefl _ _ (BEq.symm eq), fun _ => .inl h⟩
· cases i with
| zero =>
simp at w₂
refine ⟨lt_asymm _ _ w₂, ?_⟩
intro eq
exfalso
simp [lt_irrefl _ _ (BEq.symm eq)] at w₂
| succ i =>
refine ⟨lt_irrefl _ _ (by simpa using w₁ 0 (by simp)), ?_⟩
refine fun _ => .inr ⟨i, by simpa using h₁, by simpa using h₂, ?_, ?_⟩
· intro j hj
simpa using w₁ (j + 1) (by simpa)
· simpa using w₂
List.lt_iff_exists
theorem
[DecidableEq α] [LT α] [DecidableLT α] {l₁ l₂ : List α} :
l₁ < l₂ ↔
(l₁ = l₂.take l₁.length ∧ l₁.length < l₂.length) ∨
(∃ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length),
(∀ j, (hj : j < i) → l₁[j]'(Nat.lt_trans hj h₁) = l₂[j]'(Nat.lt_trans hj h₂)) ∧ l₁[i] < l₂[i])
protected theorem lt_iff_exists [DecidableEq α] [LT α] [DecidableLT α] {l₁ l₂ : List α} :
l₁ < l₂ ↔
(l₁ = l₂.take l₁.length ∧ l₁.length < l₂.length) ∨
(∃ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length),
(∀ j, (hj : j < i) →
l₁[j]'(Nat.lt_trans hj h₁) = l₂[j]'(Nat.lt_trans hj h₂)) ∧ l₁[i] < l₂[i]) := by
rw [← lex_eq_true_iff_lt, lex_eq_true_iff_exists]
simp
List.le_iff_exists
theorem
[DecidableEq α] [LT α] [DecidableLT α] [Std.Irrefl (· < · : α → α → Prop)] [Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬· < · : α → α → Prop)] {l₁ l₂ : List α} :
l₁ ≤ l₂ ↔
(l₁ = l₂.take l₁.length) ∨
(∃ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length),
(∀ j, (hj : j < i) → l₁[j]'(Nat.lt_trans hj h₁) = l₂[j]'(Nat.lt_trans hj h₂)) ∧ l₁[i] < l₂[i])
protected theorem le_iff_exists [DecidableEq α] [LT α] [DecidableLT α]
[Std.Irrefl (· < · : α → α → Prop)]
[Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬ · < · : α → α → Prop)] {l₁ l₂ : List α} :
l₁ ≤ l₂ ↔
(l₁ = l₂.take l₁.length) ∨
(∃ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length),
(∀ j, (hj : j < i) →
l₁[j]'(Nat.lt_trans hj h₁) = l₂[j]'(Nat.lt_trans hj h₂)) ∧ l₁[i] < l₂[i]) := by
rw [← lex_eq_false_iff_ge, lex_eq_false_iff_exists]
· simp only [isEqv_eq, beq_iff_eq, decide_eq_true_eq]
simp only [eq_comm]
conv => lhs; simp +singlePass [exists_comm]
· simpa using Std.Irrefl.irrefl
· simpa using Std.Asymm.asymm
· simpa using Std.Antisymm.antisymm
List.append_left_lt
theorem
[LT α] {l₁ l₂ l₃ : List α} (h : l₂ < l₃) : l₁ ++ l₂ < l₁ ++ l₃
theorem append_left_lt [LT α] {l₁ l₂ l₃ : List α} (h : l₂ < l₃) :
l₁ ++ l₂ < l₁ ++ l₃ := by
induction l₁ with
| nil => simp [h]
| cons a l₁ ih => simp [cons_lt_cons_iff, ih]
List.append_left_le
theorem
[DecidableEq α] [LT α] [DecidableLT α] [Std.Irrefl (· < · : α → α → Prop)] [Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬· < · : α → α → Prop)] {l₁ l₂ l₃ : List α} (h : l₂ ≤ l₃) : l₁ ++ l₂ ≤ l₁ ++ l₃
theorem append_left_le [DecidableEq α] [LT α] [DecidableLT α]
[Std.Irrefl (· < · : α → α → Prop)]
[Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬ · < · : α → α → Prop)]
{l₁ l₂ l₃ : List α} (h : l₂ ≤ l₃) :
l₁ ++ l₂ ≤ l₁ ++ l₃ := by
induction l₁ with
| nil => simp [h]
| cons a l₁ ih => simp [cons_le_cons_iff, ih]
List.le_append_left
theorem
[LT α] [Std.Irrefl (· < · : α → α → Prop)] {l₁ l₂ : List α} : l₁ ≤ l₁ ++ l₂
theorem le_append_left [LT α] [Std.Irrefl (· < · : α → α → Prop)]
{l₁ l₂ : List α} : l₁ ≤ l₁ ++ l₂ := by
intro h
match l₁, h with
| nil, h => simp at h
| cons a l₁, h => exact le_append_left (by simpa using h)
List.IsPrefix.le
theorem
[LT α] [Std.Irrefl (· < · : α → α → Prop)] {l₁ l₂ : List α} (h : l₁ <+: l₂) : l₁ ≤ l₂
theorem IsPrefix.le [LT α] [Std.Irrefl (· < · : α → α → Prop)]
{l₁ l₂ : List α} (h : l₁ <+: l₂) : l₁ ≤ l₂ := by
rcases h with ⟨_, rfl⟩
apply le_append_left
List.map_lt
theorem
[LT α] [LT β] {l₁ l₂ : List α} {f : α → β} (w : ∀ x y, x < y → f x < f y) (h : l₁ < l₂) : map f l₁ < map f l₂
protected theorem map_lt [LT α] [LT β]
{l₁ l₂ : List α} {f : α → β} (w : ∀ x y, x < y → f x < f y) (h : l₁ < l₂) :
map f l₁ < map f l₂ := by
match l₁, l₂, h with
| nil, nil, h => simp at h
| nil, cons b l₂, h => simp
| cons a l₁, nil, h => simp at h
| cons a l₁, cons _ l₂, .cons h =>
simp [cons_lt_cons_iff, List.map_lt w (by simpa using h)]
| cons a l₁, cons b l₂, .rel h =>
simp [cons_lt_cons_iff, w, h]
List.map_le
theorem
[DecidableEq α] [LT α] [DecidableLT α] [DecidableEq β] [LT β] [DecidableLT β] [Std.Irrefl (· < · : α → α → Prop)]
[Std.Asymm (· < · : α → α → Prop)] [Std.Antisymm (¬· < · : α → α → Prop)] [Std.Irrefl (· < · : β → β → Prop)]
[Std.Asymm (· < · : β → β → Prop)] [Std.Antisymm (¬· < · : β → β → Prop)] {l₁ l₂ : List α} {f : α → β}
(w : ∀ x y, x < y → f x < f y) (h : l₁ ≤ l₂) : map f l₁ ≤ map f l₂
protected theorem map_le [DecidableEq α] [LT α] [DecidableLT α] [DecidableEq β] [LT β] [DecidableLT β]
[Std.Irrefl (· < · : α → α → Prop)]
[Std.Asymm (· < · : α → α → Prop)]
[Std.Antisymm (¬ · < · : α → α → Prop)]
[Std.Irrefl (· < · : β → β → Prop)]
[Std.Asymm (· < · : β → β → Prop)]
[Std.Antisymm (¬ · < · : β → β → Prop)]
{l₁ l₂ : List α} {f : α → β} (w : ∀ x y, x < y → f x < f y) (h : l₁ ≤ l₂) :
map f l₁ ≤ map f l₂ := by
rw [List.le_iff_exists] at h ⊢
obtain (h | ⟨i, h₁, h₂, w₁, w₂⟩) := h
· left
rw [h]
simp
· right
refine ⟨i, by simpa using h₁, by simpa using h₂, ?_, ?_⟩
· simp +contextual [w₁]
· simpa using w _ _ w₂