/-
Copyright (c) 2022 Stuart Presnell. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Stuart Presnell, Eric Wieser, Yaël Dillies, Patrick Massot, Scott Morrison
! This file was ported from Lean 3 source module data.set.intervals.instances
! leanprover-community/mathlib commit d012cd09a9b256d870751284dd6a29882b0be105
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Algebra.GroupPower.Order
import Mathlib.Algebra.Ring.Regular

/-!
# Algebraic instances for unit intervals

For suitably structured underlying type `α`, we exhibit the structure of
the unit intervals (`Set.Icc`, `Set.Ioc`, `Set.Ioc`, and `Set.Ioo`) from `0` to `1`.
Note: Instances for the interval `Ici 0` are dealt with in `Algebra/Order/Nonneg.lean`.

## Main definitions

The strongest typeclass provided on each interval is:
* `Set.Icc.cancelCommMonoidWithZero`
* `Set.Ico.commSemigroup`
* `Set.Ioc.commMonoid`
* `Set.Ioo.commSemigroup`

## TODO

* algebraic instances for intervals -1 to 1
* algebraic instances for `Ici 1`
* algebraic instances for `(Ioo (-1) 1)ᶜ`
* provide `distribNeg` instances where applicable
* prove versions of `mul_le_{left,right}` for other intervals
* prove versions of the lemmas in `Topology/UnitInterval` with `ℝ` generalized to
  some arbitrary ordered semiring
-/

open Set

variable {α : Type _}

section OrderedSemiring

variable [OrderedSemiring α]

/-! ### Instances for `↥(Set.Icc 0 1)` -/

namespace Set.Icc

instance zero : Zero (Icc (0 : α) 1) where zero := ⟨0, left_mem_Icc.2 zero_le_one⟩
#align set.Icc.has_zero Set.Icc.zero

instance one : One (Icc (0 : α) 1) where one := ⟨1, right_mem_Icc.2 zero_le_one⟩
#align set.Icc.has_one Set.Icc.one

@[simp, norm_cast]
theorem coe_zero : ↑(0 : Icc (0 : α) 1) = (0 : α) :=
  rfl
#align set.Icc.coe_zero Set.Icc.coe_zero

@[simp, norm_cast]
theorem coe_one : ↑(1 : Icc (0 : α) 1) = (1 : α) :=
  rfl
#align set.Icc.coe_one Set.Icc.coe_one

@[simp]
theorem mk_zero (h : (0 : α) ∈ Icc (0 : α) 1) : (⟨0, h⟩ : Icc (0 : α) 1) = 0 :=
  rfl
#align set.Icc.mk_zero Set.Icc.mk_zero

@[simp]
theorem mk_one (h : (1 : α) ∈ Icc (0 : α) 1) : (⟨1, h⟩ : Icc (0 : α) 1) = 1 :=
  rfl
#align set.Icc.mk_one Set.Icc.mk_one

@[simp, norm_cast]
theorem coe_eq_zero {x : Icc (0 : α) 1} : (x : α) = 0 ↔ x = 0 := by
  symm
  exact Subtype.ext_iff
#align set.Icc.coe_eq_zero Set.Icc.coe_eq_zero

theorem coe_ne_zero {x : Icc (0 : α) 1} : (x : α) ≠ 0 ↔ x ≠ 0 :=
  not_iff_not.mpr coe_eq_zero
#align set.Icc.coe_ne_zero Set.Icc.coe_ne_zero

@[simp, norm_cast]
theorem coe_eq_one {x : Icc (0 : α) 1} : (x : α) = 1 ↔ x = 1 := by
  symm
  exact Subtype.ext_iff
#align set.Icc.coe_eq_one Set.Icc.coe_eq_one

theorem coe_ne_one {x : Icc (0 : α) 1} : (x : α) ≠ 1 ↔ x ≠ 1 :=
  not_iff_not.mpr coe_eq_one
#align set.Icc.coe_ne_one Set.Icc.coe_ne_one

theorem coe_nonneg (x : Icc (0 : α) 1) : 0 ≤ (x : α) :=
  x.2.1
#align set.Icc.coe_nonneg Set.Icc.coe_nonneg

theorem coe_le_one (x : Icc (0 : α) 1) : (x : α) ≤ 1 :=
  x.2.2
#align set.Icc.coe_le_one Set.Icc.coe_le_one

/-- like `coe_nonneg`, but with the inequality in `Icc (0:α) 1`. -/
theorem nonneg {t : Icc (0 : α) 1} : 0 ≤ t :=
  t.2.1
#align set.Icc.nonneg Set.Icc.nonneg

/-- like `coe_le_one`, but with the inequality in `Icc (0:α) 1`. -/
theorem le_one {t : Icc (0 : α) 1} : t ≤ 1 :=
  t.2.2
#align set.Icc.le_one Set.Icc.le_one

instance mul : Mul (Icc (0 : α) 1) where
  mul p q := ⟨p * q, ⟨mul_nonneg p.2.1 q.2.1, mul_le_one p.2.2 q.2.1 q.2.2⟩⟩
#align set.Icc.has_mul Set.Icc.mul

instance pow : Pow (Icc (0 : α) 1) ℕ where
  pow p n := ⟨p.1 ^ n, ⟨pow_nonneg p.2.1 n, pow_le_one n p.2.1 p.2.2⟩⟩
#align set.Icc.has_pow Set.Icc.pow

@[simp, norm_cast]
theorem coe_mul (x y : Icc (0 : α) 1) : ↑(x * y) = (x * y : α) :=
  rfl
#align set.Icc.coe_mul Set.Icc.coe_mul

@[simp, norm_cast]
theorem coe_pow (x : Icc (0 : α) 1) (n : ℕ) : ↑(x ^ n) = ((x : α) ^ n) :=
  rfl
#align set.Icc.coe_pow Set.Icc.coe_pow

theorem mul_le_left {x y : Icc (0 : α) 1} : x * y ≤ x :=
  (mul_le_mul_of_nonneg_left y.2.2 x.2.1).trans_eq (mul_one _)

#align set.Icc.mul_le_left Set.Icc.mul_le_left

theorem mul_le_right {x y : Icc (0 : α) 1} : x * y ≤ y :=
  (mul_le_mul_of_nonneg_right x.2.2 y.2.1).trans_eq (one_mul _)
#align set.Icc.mul_le_right Set.Icc.mul_le_right

instance monoidWithZero : MonoidWithZero (Icc (0 : α) 1) :=
  Subtype.coe_injective.monoidWithZero _ coe_zero coe_one coe_mul coe_pow
#align set.Icc.monoid_with_zero Set.Icc.monoidWithZero

instance commMonoidWithZero {α : Type _} [OrderedCommSemiring α] :
    CommMonoidWithZero (Icc (0 : α) 1) :=
  Subtype.coe_injective.commMonoidWithZero _ coe_zero coe_one coe_mul coe_pow
#align set.Icc.comm_monoid_with_zero Set.Icc.commMonoidWithZero

instance cancelMonoidWithZero {α : Type _} [OrderedRing α] [NoZeroDivisors α] :
    CancelMonoidWithZero (Icc (0 : α) 1) :=
  @Function.Injective.cancelMonoidWithZero α _ NoZeroDivisors.toCancelMonoidWithZero _ _ _ _
    (fun v => v.val) Subtype.coe_injective coe_zero coe_one coe_mul coe_pow
#align set.Icc.cancel_monoid_with_zero Set.Icc.cancelMonoidWithZero

instance cancelCommMonoidWithZero {α : Type _} [OrderedCommRing α] [NoZeroDivisors α] :
    CancelCommMonoidWithZero (Icc (0 : α) 1) :=
  @Function.Injective.cancelCommMonoidWithZero α _ NoZeroDivisors.toCancelCommMonoidWithZero _ _ _ _
    (fun v => v.val) Subtype.coe_injective coe_zero coe_one coe_mul coe_pow
#align set.Icc.cancel_comm_monoid_with_zero Set.Icc.cancelCommMonoidWithZero

variable {β : Type _} [OrderedRing β]

theorem one_sub_mem {t : β} (ht : t ∈ Icc (0 : β) 1) : 1 - t ∈ Icc (0 : β) 1 := by
  rw [mem_Icc] at *
  exact ⟨sub_nonneg.2 ht.2, (sub_le_self_iff _).2 ht.1⟩
#align set.Icc.one_sub_mem Set.Icc.one_sub_mem

theorem mem_iff_one_sub_mem {t : β} : t ∈ Icc (0 : β) 1 ↔ 1 - t ∈ Icc (0 : β) 1 :=
  ⟨one_sub_mem, fun h => sub_sub_cancel 1 t ▸ one_sub_mem h⟩
#align set.Icc.mem_iff_one_sub_mem Set.Icc.mem_iff_one_sub_mem

theorem one_sub_nonneg (x : Icc (0 : β) 1) : 0 ≤ 1 - (x : β) := by simpa using x.2.2
#align set.Icc.one_sub_nonneg Set.Icc.one_sub_nonneg

theorem one_sub_le_one (x : Icc (0 : β) 1) : 1 - (x : β) ≤ 1 := by simpa using x.2.1
#align set.Icc.one_sub_le_one Set.Icc.one_sub_le_one

end Set.Icc

/-! ### Instances for `↥(Set.Ico 0 1)` -/

namespace Set.Ico

instance zero [Nontrivial α] : Zero (Ico (0 : α) 1) where zero := ⟨0, left_mem_Ico.2 zero_lt_one⟩
#align set.Ico.has_zero Set.Ico.zero

@[simp, norm_cast]
theorem coe_zero [Nontrivial α] : ↑(0 : Ico (0 : α) 1) = (0 : α) :=
  rfl
#align set.Ico.coe_zero Set.Ico.coe_zero

@[simp]
theorem mk_zero [Nontrivial α] (h : (0 : α) ∈ Ico (0 : α) 1) : (⟨0, h⟩ : Ico (0 : α) 1) = 0 :=
  rfl
#align set.Ico.mk_zero Set.Ico.mk_zero

@[simp, norm_cast]
theorem coe_eq_zero [Nontrivial α] {x : Ico (0 : α) 1} : (x : α) = 0 ↔ x = 0 := by
  symm
  exact Subtype.ext_iff
#align set.Ico.coe_eq_zero Set.Ico.coe_eq_zero

theorem coe_ne_zero [Nontrivial α] {x : Ico (0 : α) 1} : (x : α) ≠ 0 ↔ x ≠ 0 :=
  not_iff_not.mpr coe_eq_zero
#align set.Ico.coe_ne_zero Set.Ico.coe_ne_zero

theorem coe_nonneg (x : Ico (0 : α) 1) : 0 ≤ (x : α) :=
  x.2.1
#align set.Ico.coe_nonneg Set.Ico.coe_nonneg

theorem coe_lt_one (x : Ico (0 : α) 1) : (x : α) < 1 :=
  x.2.2
#align set.Ico.coe_lt_one Set.Ico.coe_lt_one

/-- like `coe_nonneg`, but with the inequality in `Ico (0:α) 1`. -/
theorem nonneg [Nontrivial α] {t : Ico (0 : α) 1} : 0 ≤ t :=
  t.2.1
#align set.Ico.nonneg Set.Ico.nonneg

instance mul : Mul (Ico (0 : α) 1) where
  mul p q :=
    ⟨p * q, ⟨mul_nonneg p.2.1 q.2.1, mul_lt_one_of_nonneg_of_lt_one_right p.2.2.le q.2.1 q.2.2⟩⟩
#align set.Ico.has_mul Set.Ico.mul

@[simp, norm_cast]
theorem coe_mul (x y : Ico (0 : α) 1) : ↑(x * y) = (x * y : α) :=
  rfl
#align set.Ico.coe_mul Set.Ico.coe_mul

instance semigroup : Semigroup (Ico (0 : α) 1) :=
  Subtype.coe_injective.semigroup _ coe_mul
#align set.Ico.semigroup Set.Ico.semigroup

instance commSemigroup {α : Type _} [OrderedCommSemiring α] : CommSemigroup (Ico (0 : α) 1) :=
  Subtype.coe_injective.commSemigroup _ coe_mul
#align set.Ico.comm_semigroup Set.Ico.commSemigroup

end Set.Ico

end OrderedSemiring

variable [StrictOrderedSemiring α]

/-! ### Instances for `↥(set.Ioc 0 1)` -/

namespace Set.Ioc

instance one [Nontrivial α] : One (Ioc (0 : α) 1) where one := ⟨1, ⟨zero_lt_one, le_refl 1⟩⟩
#align set.Ioc.has_one Set.Ioc.one

@[simp, norm_cast]
theorem coe_one [Nontrivial α] : ↑(1 : Ioc (0 : α) 1) = (1 : α) :=
  rfl
#align set.Ioc.coe_one Set.Ioc.coe_one

@[simp]
theorem mk_one [Nontrivial α] (h : (1 : α) ∈ Ioc (0 : α) 1) : (⟨1, h⟩ : Ioc (0 : α) 1) = 1 :=
  rfl
#align set.Ioc.mk_one Set.Ioc.mk_one

@[simp, norm_cast]
theorem coe_eq_one [Nontrivial α] {x : Ioc (0 : α) 1} : (x : α) = 1 ↔ x = 1 := by
  symm
  exact Subtype.ext_iff
#align set.Ioc.coe_eq_one Set.Ioc.coe_eq_one

theorem coe_ne_one [Nontrivial α] {x : Ioc (0 : α) 1} : (x : α) ≠ 1 ↔ x ≠ 1 :=
  not_iff_not.mpr coe_eq_one
#align set.Ioc.coe_ne_one Set.Ioc.coe_ne_one

theorem coe_le_one (x : Ioc (0 : α) 1) : (x : α) ≤ 1 :=
  x.2.2
#align set.Ioc.coe_le_one Set.Ioc.coe_le_one

/-- like `coe_le_one`, but with the inequality in `Ioc (0:α) 1`. -/
theorem le_one [Nontrivial α] {t : Ioc (0 : α) 1} : t ≤ 1 :=
  t.2.2
#align set.Ioc.le_one Set.Ioc.le_one

instance mul : Mul (Ioc (0 : α) 1) where
  mul p q := ⟨p.1 * q.1, ⟨mul_pos p.2.1 q.2.1, mul_le_one p.2.2 (le_of_lt q.2.1) q.2.2⟩⟩
#align set.Ioc.has_mul Set.Ioc.mul

instance pow : Pow (Ioc (0 : α) 1) ℕ where
  pow p n := ⟨p.1 ^ n, ⟨pow_pos p.2.1 n, pow_le_one n (le_of_lt p.2.1) p.2.2⟩⟩
#align set.Ioc.has_pow Set.Ioc.pow

@[simp, norm_cast]
theorem coe_mul (x y : Ioc (0 : α) 1) : ↑(x * y) = (x * y : α) :=
  rfl
#align set.Ioc.coe_mul Set.Ioc.coe_mul

@[simp, norm_cast]
theorem coe_pow (x : Ioc (0 : α) 1) (n : ℕ) : ↑(x ^ n) = ((x : α) ^ n) :=
  rfl
#align set.Ioc.coe_pow Set.Ioc.coe_pow

instance semigroup : Semigroup (Ioc (0 : α) 1) :=
  Subtype.coe_injective.semigroup _ coe_mul
#align set.Ioc.semigroup Set.Ioc.semigroup

instance monoid [Nontrivial α] : Monoid (Ioc (0 : α) 1) :=
  Subtype.coe_injective.monoid _ coe_one coe_mul coe_pow
#align set.Ioc.monoid Set.Ioc.monoid

instance commSemigroup {α : Type _} [StrictOrderedCommSemiring α] : CommSemigroup (Ioc (0 : α) 1) :=
  Subtype.coe_injective.commSemigroup _ coe_mul
#align set.Ioc.comm_semigroup Set.Ioc.commSemigroup

instance commMonoid {α : Type _} [StrictOrderedCommSemiring α] [Nontrivial α] :
    CommMonoid (Ioc (0 : α) 1) :=
  Subtype.coe_injective.commMonoid _ coe_one coe_mul coe_pow
#align set.Ioc.comm_monoid Set.Ioc.commMonoid

instance cancelMonoid {α : Type _} [StrictOrderedRing α] [IsDomain α] :
    CancelMonoid (Ioc (0 : α) 1) :=
  { Set.Ioc.monoid with
    mul_left_cancel := fun a _ _ h =>
      Subtype.ext <| mul_left_cancel₀ a.prop.1.ne' <| (congr_arg Subtype.val h : _)
    mul_right_cancel := fun _ b _ h =>
      Subtype.ext <| mul_right_cancel₀ b.prop.1.ne' <| (congr_arg Subtype.val h : _) }
#align set.Ioc.cancel_monoid Set.Ioc.cancelMonoid

-- Porting note: This takes too long
set_option maxHeartbeats 0 in
instance cancelCommMonoid {α : Type _} [StrictOrderedCommRing α] [IsDomain α] :
    CancelCommMonoid (Ioc (0 : α) 1) :=
  { Set.Ioc.cancelMonoid, Set.Ioc.commMonoid with }
#align set.Ioc.cancel_comm_monoid Set.Ioc.cancelCommMonoid

end Set.Ioc

/-! ### Instances for `↥(Set.Ioo 0 1)` -/

namespace Set.Ioo

theorem pos (x : Ioo (0 : α) 1) : 0 < (x : α) :=
  x.2.1
#align set.Ioo.pos Set.Ioo.pos

theorem lt_one (x : Ioo (0 : α) 1) : (x : α) < 1 :=
  x.2.2
#align set.Ioo.lt_one Set.Ioo.lt_one

instance mul : Mul (Ioo (0 : α) 1) where
  mul p q :=
    ⟨p.1 * q.1, ⟨mul_pos p.2.1 q.2.1, mul_lt_one_of_nonneg_of_lt_one_right p.2.2.le q.2.1.le q.2.2⟩⟩
#align set.Ioo.has_mul Set.Ioo.mul

@[simp, norm_cast]
theorem coe_mul (x y : Ioo (0 : α) 1) : ↑(x * y) = (x * y : α) :=
  rfl
#align set.Ioo.coe_mul Set.Ioo.coe_mul

instance semigroup : Semigroup (Ioo (0 : α) 1) :=
  Subtype.coe_injective.semigroup _ coe_mul
#align set.Ioo.semigroup Set.Ioo.semigroup

instance commSemigroup {α : Type _} [StrictOrderedCommSemiring α] : CommSemigroup (Ioo (0 : α) 1) :=
  Subtype.coe_injective.commSemigroup _ coe_mul
#align set.Ioo.comm_semigroup Set.Ioo.commSemigroup

variable {β : Type _} [OrderedRing β]

theorem one_sub_mem {t : β} (ht : t ∈ Ioo (0 : β) 1) : 1 - t ∈ Ioo (0 : β) 1 := by
  rw [mem_Ioo] at *
  refine' ⟨sub_pos.2 ht.2, _⟩
  exact lt_of_le_of_ne ((sub_le_self_iff 1).2 ht.1.le) (mt sub_eq_self.mp ht.1.ne')
#align set.Ioo.one_sub_mem Set.Ioo.one_sub_mem

theorem mem_iff_one_sub_mem {t : β} : t ∈ Ioo (0 : β) 1 ↔ 1 - t ∈ Ioo (0 : β) 1 :=
  ⟨one_sub_mem, fun h => sub_sub_cancel 1 t ▸ one_sub_mem h⟩
#align set.Ioo.mem_iff_one_sub_mem Set.Ioo.mem_iff_one_sub_mem

theorem one_minus_pos (x : Ioo (0 : β) 1) : 0 < 1 - (x : β) := by simpa using x.2.2
#align set.Ioo.one_minus_pos Set.Ioo.one_minus_pos

theorem one_minus_lt_one (x : Ioo (0 : β) 1) : 1 - (x : β) < 1 := by simpa using x.2.1
#align set.Ioo.one_minus_lt_one Set.Ioo.one_minus_lt_one

end Set.Ioo


/-
Copyright (c) 2016 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad, Leonardo de Moura, Mario Carneiro, Johannes Hölzl, Yuyang Zhao

! This file was ported from Lean 3 source module algebra.order.monoid.nat_cast
! leanprover-community/mathlib commit 448144f7ae193a8990cb7473c9e9a01990f64ac7
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Algebra.Order.Monoid.Lemmas
import Mathbin.Algebra.Order.ZeroLeOne
import Mathbin.Data.Nat.Cast.Defs

/-!
# Order of numerials in an `add_monoid_with_one`.

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.
-/

variable {α : Type _}

open Function

/- warning: lt_add_one -> lt_add_one is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : One.{u1} α] [_inst_2 : AddZeroClass.{u1} α] [_inst_3 : PartialOrder.{u1} α] [_inst_4 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α _inst_2) _inst_1 (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3))] [_inst_5 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α _inst_2) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α _inst_1)))] [_inst_6 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α _inst_2))) (LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3)))] (a : α), LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3)) a (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α _inst_2)) a (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α _inst_1))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : One.{u1} α] [_inst_2 : AddZeroClass.{u1} α] [_inst_3 : PartialOrder.{u1} α] [_inst_4 : ZeroLEOneClass.{u1} α (AddZeroClass.toZero.{u1} α _inst_2) _inst_1 (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3))] [_inst_5 : NeZero.{u1} α (AddZeroClass.toZero.{u1} α _inst_2) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α _inst_1))] [_inst_6 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.36 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.38 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.36 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.38) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.51 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.53 : α) => LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.51 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.53)] (a : α), LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3)) a (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α _inst_2)) a (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α _inst_1)))
Case conversion may be inaccurate. Consider using '#align lt_add_one lt_add_oneₓ'. -/
theorem lt_add_one [One α] [AddZeroClass α] [PartialOrder α] [ZeroLEOneClass α] [NeZero (1 : α)]
    [CovariantClass α α (· + ·) (· < ·)] (a : α) : a < a + 1 :=
  lt_add_of_pos_right _ zero_lt_one
#align lt_add_one lt_add_one

/- warning: lt_one_add -> lt_one_add is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : One.{u1} α] [_inst_2 : AddZeroClass.{u1} α] [_inst_3 : PartialOrder.{u1} α] [_inst_4 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α _inst_2) _inst_1 (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3))] [_inst_5 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α _inst_2) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α _inst_1)))] [_inst_6 : CovariantClass.{u1, u1} α α (Function.swap.{succ u1, succ u1, succ u1} α α (fun (ᾰ : α) (ᾰ : α) => α) (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α _inst_2)))) (LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3)))] (a : α), LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3)) a (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α _inst_1))) a)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : One.{u1} α] [_inst_2 : AddZeroClass.{u1} α] [_inst_3 : PartialOrder.{u1} α] [_inst_4 : ZeroLEOneClass.{u1} α (AddZeroClass.toZero.{u1} α _inst_2) _inst_1 (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3))] [_inst_5 : NeZero.{u1} α (AddZeroClass.toZero.{u1} α _inst_2) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α _inst_1))] [_inst_6 : CovariantClass.{u1, u1} α α (Function.swap.{succ u1, succ u1, succ u1} α α (fun (ᾰ : α) (ᾰ : α) => α) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.107 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.109 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.107 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.109)) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.122 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.124 : α) => LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.122 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.124)] (a : α), LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_3)) a (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α _inst_1)) a)
Case conversion may be inaccurate. Consider using '#align lt_one_add lt_one_addₓ'. -/
theorem lt_one_add [One α] [AddZeroClass α] [PartialOrder α] [ZeroLEOneClass α] [NeZero (1 : α)]
    [CovariantClass α α (swap (· + ·)) (· < ·)] (a : α) : a < 1 + a :=
  lt_add_of_pos_left _ zero_lt_one
#align lt_one_add lt_one_add

variable [AddMonoidWithOne α]

/- warning: zero_le_two -> zero_le_two is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : Preorder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α _inst_2)] [_inst_4 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2))], LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 2 (OfNat.mk.{u1} α 2 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : Preorder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α _inst_2)] [_inst_4 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.172 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.174 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.172 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.174) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.187 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.189 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.187 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.189)], LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 2 (instOfNat.{u1} α 2 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))))
Case conversion may be inaccurate. Consider using '#align zero_le_two zero_le_twoₓ'. -/
theorem zero_le_two [Preorder α] [ZeroLEOneClass α] [CovariantClass α α (· + ·) (· ≤ ·)] :
    (0 : α) ≤ 2 :=
  add_nonneg zero_le_one zero_le_one
#align zero_le_two zero_le_two

/- warning: zero_le_three -> zero_le_three is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : Preorder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α _inst_2)] [_inst_4 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2))], LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 3 (OfNat.mk.{u1} α 3 (bit1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : Preorder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α _inst_2)] [_inst_4 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.265 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.267 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.265 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.267) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.280 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.282 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.280 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.282)], LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 3 (instOfNat.{u1} α 3 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
Case conversion may be inaccurate. Consider using '#align zero_le_three zero_le_threeₓ'. -/
theorem zero_le_three [Preorder α] [ZeroLEOneClass α] [CovariantClass α α (· + ·) (· ≤ ·)] :
    (0 : α) ≤ 3 :=
  add_nonneg zero_le_two zero_le_one
#align zero_le_three zero_le_three

/- warning: zero_le_four -> zero_le_four is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : Preorder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α _inst_2)] [_inst_4 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2))], LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 4 (OfNat.mk.{u1} α 4 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : Preorder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α _inst_2)] [_inst_4 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.358 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.360 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.358 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.360) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.373 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.375 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.373 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.375)], LE.le.{u1} α (Preorder.toLE.{u1} α _inst_2) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 4 (instOfNat.{u1} α 4 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2)))))
Case conversion may be inaccurate. Consider using '#align zero_le_four zero_le_fourₓ'. -/
theorem zero_le_four [Preorder α] [ZeroLEOneClass α] [CovariantClass α α (· + ·) (· ≤ ·)] :
    (0 : α) ≤ 4 :=
  add_nonneg zero_le_two zero_le_two
#align zero_le_four zero_le_four

/- warning: one_le_two -> one_le_two is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : LE.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) _inst_2] [_inst_4 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α _inst_2)], LE.le.{u1} α _inst_2 (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 2 (OfNat.mk.{u1} α 2 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : LE.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) _inst_2] [_inst_4 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.451 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.453 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.451 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.453) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.466 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.468 : α) => LE.le.{u1} α _inst_2 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.466 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.468)], LE.le.{u1} α _inst_2 (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 2 (instOfNat.{u1} α 2 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))))
Case conversion may be inaccurate. Consider using '#align one_le_two one_le_twoₓ'. -/
theorem one_le_two [LE α] [ZeroLEOneClass α] [CovariantClass α α (· + ·) (· ≤ ·)] : (1 : α) ≤ 2 :=
  calc
    1 = 1 + 0 := (add_zero 1).symm
    _ ≤ 1 + 1 := add_le_add_left zero_le_one _

#align one_le_two one_le_two

/- warning: one_le_two' -> one_le_two' is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : LE.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) _inst_2] [_inst_4 : CovariantClass.{u1, u1} α α (Function.swap.{succ u1, succ u1, succ u1} α α (fun (ᾰ : α) (ᾰ : α) => α) (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (LE.le.{u1} α _inst_2)], LE.le.{u1} α _inst_2 (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 2 (OfNat.mk.{u1} α 2 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : LE.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) _inst_2] [_inst_4 : CovariantClass.{u1, u1} α α (Function.swap.{succ u1, succ u1, succ u1} α α (fun (ᾰ : α) (ᾰ : α) => α) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.563 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.565 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.563 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.565)) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.578 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.580 : α) => LE.le.{u1} α _inst_2 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.578 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.580)], LE.le.{u1} α _inst_2 (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 2 (instOfNat.{u1} α 2 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))))
Case conversion may be inaccurate. Consider using '#align one_le_two' one_le_two'ₓ'. -/
theorem one_le_two' [LE α] [ZeroLEOneClass α] [CovariantClass α α (swap (· + ·)) (· ≤ ·)] :
    (1 : α) ≤ 2 :=
  calc
    1 = 0 + 1 := (zero_add 1).symm
    _ ≤ 1 + 1 := add_le_add_right zero_le_one _

#align one_le_two' one_le_two'

section

variable [PartialOrder α] [ZeroLEOneClass α] [NeZero (1 : α)]

section

variable [CovariantClass α α (· + ·) (· ≤ ·)]

/- warning: zero_lt_two -> zero_lt_two is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 2 (OfNat.mk.{u1} α 2 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.752 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.754 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.752 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.754) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.767 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.769 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.767 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.769)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 2 (instOfNat.{u1} α 2 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))))
Case conversion may be inaccurate. Consider using '#align zero_lt_two zero_lt_twoₓ'. -/
/-- See `zero_lt_two'` for a version with the type explicit. -/
@[simp]
theorem zero_lt_two : (0 : α) < 2 :=
  zero_lt_one.trans_le one_le_two
#align zero_lt_two zero_lt_two

/- warning: zero_lt_three -> zero_lt_three is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 3 (OfNat.mk.{u1} α 3 (bit1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.816 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.818 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.816 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.818) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.831 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.833 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.831 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.833)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 3 (instOfNat.{u1} α 3 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
Case conversion may be inaccurate. Consider using '#align zero_lt_three zero_lt_threeₓ'. -/
/-- See `zero_lt_three'` for a version with the type explicit. -/
@[simp]
theorem zero_lt_three : (0 : α) < 3 :=
  lt_add_of_lt_of_nonneg zero_lt_two zero_le_one
#align zero_lt_three zero_lt_three

/- warning: zero_lt_four -> zero_lt_four is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 4 (OfNat.mk.{u1} α 4 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.914 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.916 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.914 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.916) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.929 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.931 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.929 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.931)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 4 (instOfNat.{u1} α 4 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2)))))
Case conversion may be inaccurate. Consider using '#align zero_lt_four zero_lt_fourₓ'. -/
/-- See `zero_lt_four'` for a version with the type explicit. -/
@[simp]
theorem zero_lt_four : (0 : α) < 4 :=
  lt_add_of_lt_of_nonneg zero_lt_two zero_le_two
#align zero_lt_four zero_lt_four

variable (α)

/- warning: zero_lt_two' -> zero_lt_two' is a dubious translation:
lean 3 declaration is
  forall (α : Type.{u1}) [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 2 (OfNat.mk.{u1} α 2 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall (α : Type.{u1}) [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1067 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1069 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1067 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1069) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1082 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1084 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1082 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1084)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 2 (instOfNat.{u1} α 2 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))))
Case conversion may be inaccurate. Consider using '#align zero_lt_two' zero_lt_two'ₓ'. -/
/-- See `zero_lt_two` for a version with the type implicit. -/
theorem zero_lt_two' : (0 : α) < 2 :=
  zero_lt_two
#align zero_lt_two' zero_lt_two'

/- warning: zero_lt_three' -> zero_lt_three' is a dubious translation:
lean 3 declaration is
  forall (α : Type.{u1}) [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 3 (OfNat.mk.{u1} α 3 (bit1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall (α : Type.{u1}) [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1130 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1132 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1130 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1132) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1145 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1147 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1145 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1147)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 3 (instOfNat.{u1} α 3 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
Case conversion may be inaccurate. Consider using '#align zero_lt_three' zero_lt_three'ₓ'. -/
/-- See `zero_lt_three` for a version with the type implicit. -/
theorem zero_lt_three' : (0 : α) < 3 :=
  zero_lt_three
#align zero_lt_three' zero_lt_three'

/- warning: zero_lt_four' -> zero_lt_four' is a dubious translation:
lean 3 declaration is
  forall (α : Type.{u1}) [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 4 (OfNat.mk.{u1} α 4 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))))
but is expected to have type
  forall (α : Type.{u1}) [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1193 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1195 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1193 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1195) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1208 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1210 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1208 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1210)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 4 (instOfNat.{u1} α 4 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2)))))
Case conversion may be inaccurate. Consider using '#align zero_lt_four' zero_lt_four'ₓ'. -/
/-- See `zero_lt_four` for a version with the type implicit. -/
theorem zero_lt_four' : (0 : α) < 4 :=
  zero_lt_four
#align zero_lt_four' zero_lt_four'

instance ZeroLEOneClass.NeZero.two : NeZero (2 : α) :=
  ⟨zero_lt_two.ne'⟩
#align zero_le_one_class.ne_zero.two ZeroLEOneClass.NeZero.two

instance ZeroLEOneClass.NeZero.three : NeZero (3 : α) :=
  ⟨zero_lt_three.ne'⟩
#align zero_le_one_class.ne_zero.three ZeroLEOneClass.NeZero.three

instance ZeroLEOneClass.NeZero.four : NeZero (4 : α) :=
  ⟨zero_lt_four.ne'⟩
#align zero_le_one_class.ne_zero.four ZeroLEOneClass.NeZero.four

end

/- warning: one_lt_two -> one_lt_two is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 2 (OfNat.mk.{u1} α 2 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1449 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1451 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1449 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1451) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1464 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1466 : α) => LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1464 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.1466)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 2 (instOfNat.{u1} α 2 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))))
Case conversion may be inaccurate. Consider using '#align one_lt_two one_lt_twoₓ'. -/
theorem one_lt_two [CovariantClass α α (· + ·) (· < ·)] : (1 : α) < 2 :=
  lt_add_one _
#align one_lt_two one_lt_two

end

/- warning: two_pos -> two_pos is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 2 (OfNat.mk.{u1} α 2 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.752 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.754 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.752 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.754) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.767 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.769 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.767 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.769)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 2 (instOfNat.{u1} α 2 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)))))
Case conversion may be inaccurate. Consider using '#align two_pos two_posₓ'. -/
alias zero_lt_two ← two_pos
#align two_pos two_pos

/- warning: three_pos -> three_pos is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 3 (OfNat.mk.{u1} α 3 (bit1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.816 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.818 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.816 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.818) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.831 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.833 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.831 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.833)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 3 (instOfNat.{u1} α 3 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
Case conversion may be inaccurate. Consider using '#align three_pos three_posₓ'. -/
alias zero_lt_three ← three_pos
#align three_pos three_pos

/- warning: four_pos -> four_pos is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))] [_inst_5 : CovariantClass.{u1, u1} α α (HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))))) (LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)))], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (OfNat.mk.{u1} α 0 (Zero.zero.{u1} α (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))))) (OfNat.ofNat.{u1} α 4 (OfNat.mk.{u1} α 4 (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (bit0.{u1} α (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1))) (One.one.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1))))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : AddMonoidWithOne.{u1} α] [_inst_2 : PartialOrder.{u1} α] [_inst_3 : ZeroLEOneClass.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (AddMonoidWithOne.toOne.{u1} α _inst_1) (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2))] [_inst_4 : NeZero.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (AddMonoidWithOne.toOne.{u1} α _inst_1)))] [_inst_5 : CovariantClass.{u1, u1} α α (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.914 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.916 : α) => HAdd.hAdd.{u1, u1, u1} α α α (instHAdd.{u1} α (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.914 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.916) (fun (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.929 : α) (x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.931 : α) => LE.le.{u1} α (Preorder.toLE.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.929 x._@.Mathlib.Algebra.Order.Monoid.NatCast._hyg.931)], LT.lt.{u1} α (Preorder.toLT.{u1} α (PartialOrder.toPreorder.{u1} α _inst_2)) (OfNat.ofNat.{u1} α 0 (Zero.toOfNat0.{u1} α (AddMonoid.toZero.{u1} α (AddMonoidWithOne.toAddMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 4 (instOfNat.{u1} α 4 (AddMonoidWithOne.toNatCast.{u1} α _inst_1) (instAtLeastTwoHAddNatInstHAddInstAddNatOfNat (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2)))))
Case conversion may be inaccurate. Consider using '#align four_pos four_posₓ'. -/
alias zero_lt_four ← four_pos
#align four_pos four_pos


--------------------------------------------------------------------------------
-- File     : PUZ135_1 : TPTP v7.3.0. Released v5.1.0.
-- Domain   : Puzzles
-- Problem  : The Knowheyan Art Fair Puzzle - Entries
-- Version  : Especial.
-- English  : Knowheyans are not negative by nature; it is just that their way
--            of expressing themselves, using negative sentences, makes it
--            appear that way. Several fortunate visitors have an opportunity
--            to attend the Midseason Art Fair, in which they are able to
--            observe a variety of Knowheyans art forms. An artists' competition
--            was held as part of the fair and awards were given for the top
--            four entries, which were collage painting, holography, laser
--            etchings, and reconstituted materials sculpture. The interpreter
--            is explaining the results of the competition to the visitors:
--            1. A, who was not the first-place winner, did not enter a
--               holograph.
--            2. The fourth-place winner did not enter a sculpture or a
--               holograph.
--            3. The one who entered the collage painting, who was neither A
--               nor C, did not win first or second place.
--            4. Neither B, nor the one who entered the laser etching, was the
--               fourth-place winner.
--            5. The third-place winner was neither B nor C.
--            6. The one who entered the laser etching, who was not A, was not
--               the second place winner.
--            What was the art entry of each of the four?

-- Refs     : [WS+06] Willis et al. (2006), The World's Biggest Book of Brai
-- Source   : [TPTP]
------------------------------------------------------------------------------

variable knowheyan: Type

variable place: Type

variable entry: Type

variable entry_of: knowheyan → entry

variable place_of: knowheyan → place

variable a: knowheyan

variable b: knowheyan

variable c: knowheyan

variable d: knowheyan

variable a_not_b: a ≠ b

variable a_not_c: a ≠ c

variable a_not_d: a ≠ d

variable b_not_c: b ≠ c

variable b_not_d: b ≠ d

variable c_not_d: c ≠ d

variable collage_painting: entry

variable holography: entry

variable laser_etching: entry

variable reconstituted_materials_sculpture: entry

-- axioms
variable collage_painting_not_holography:
    collage_painting ≠ holography

variable collage_painting_not_laser_etching:
    collage_painting ≠ laser_etching

variable collage_painting_not_reconstituted_materials_sculpture:
    collage_painting ≠ reconstituted_materials_sculpture

variable holography_not_laser_etching:
    holography ≠ laser_etching

variable holography_not_reconstituted_materials_sculpture:
    holography ≠ reconstituted_materials_sculpture

variable laser_etching_not_reconstituted_materials_sculpture:
    laser_etching ≠ reconstituted_materials_sculpture

variable first: place

variable second: place

variable third: place

variable fourth: place

variable first_not_second: first ≠ second

variable first_not_third: first ≠ third

variable first_not_fourth: first ≠ fourth

variable second_not_third: second ≠ third

variable second_not_fourth: second ≠ fourth

variable third_not_fourth: third ≠ fourth

variable only_knowheyans:
    ∀ (X: knowheyan) ,
      ( X = a
      ∨ X = b
      ∨ X = c
      ∨ X = d )

variable only_entries:
    ∀ (X: entry) ,
      ( X = collage_painting
      ∨ X = holography
      ∨ X = laser_etching
      ∨ X = reconstituted_materials_sculpture )

variable only_places:
    ∀ (X: place) ,
      ( X = first
      ∨ X = second
      ∨ X = third
      ∨ X = fourth )

variable unique_entrys:
    ∀ (X: knowheyan)(Y: knowheyan) ,
      ( X ≠ Y
     → entry_of(X) ≠ entry_of(Y) )

variable unique_places:
    ∀ (X: knowheyan)(Y: knowheyan) ,
      ( X ≠ Y
     → place_of(X) ≠ place_of(Y) )

variable a_info:
    ( place_of(a) ≠ first
    ∧ entry_of(a) ≠ holography )

variable fourth_info:
    ∀ (X: knowheyan) ,
      ( place_of(X) = fourth
      → ( entry_of(X) ≠ reconstituted_materials_sculpture
        ∧ entry_of(X) ≠ holography ))

variable collage_info:
    ∀ (X: knowheyan) ,
      ( entry_of(X) = collage_painting
      → ( X ≠ a
        ∧ X ≠ c
        ∧ place_of(X) ≠ first
        ∧ place_of(X) ≠ second ) )

variable fourth_info2:
    ( place_of(b) ≠ fourth
    ∧ ∀ (X: knowheyan) ,
        ( entry_of(X) = laser_etching
        → place_of(X) ≠ fourth ) )

variable third_info:
    ( place_of(b) ≠ third
    ∧ place_of(c) ≠ third )

variable laser_etching_info:
    ( entry_of(b) ≠ laser_etching
    ∧ ∀ (X: knowheyan) ,
        ( entry_of(X) = laser_etching
        → ( X ≠ a
          ∧ place_of(X) ≠ second ) ) )

-- conjecture : entries
theorem entries :
    ( entry_of(a) = reconstituted_materials_sculpture
    ∧ entry_of(b) = holography
    ∧ entry_of(c) = laser_etching
    ∧ entry_of(d) = collage_painting ) := sorry


import tactic
import row_insertion

/-

Defining "row_bump" by successive row insertions

Given an ssyt T and natural numbers i, k, we insert k into T in row i, then
insert the bumped-out entry into row i+1, and so on, until the inserted
entry goes at the end of the row.

This is defined using well-founded recursion (see ssyt.rbs_cert.bound_decr).

Analogs of each of the lemmas shown for ssyt.rbs and ssyt.rbs_end are shown here:
  * ssyt.rbs_cert.rbwf only changes the rows ≥ the initial row
    [ssyt.rbs_cert.rbwf_shape_eq_self_lt_initial_row]
    [ssyt.rbs_cert.rbwf_eq_self_lt_initial_row]
  * the input rows ≥ the initial row determine the output rows ≥ the initial row
    [ssyt.rbs_cert.rbwf_corner_eq_of_eq_ge_initial_row]
    [ssyt.rbs_cert.rbwf_shape_eq_of_eq_ge_initial_row]
    [ssyt.rbs_cert.rbwf_eq_of_eq_ge_initial_row]
  * rbwf commutes with rbs in a lower starting row
    [ssyt.rbs_cert.rbwf_rbs_comm]
    (TODO: write ssyt.rbs_cert.rbwf_rbs_comm_corner and ssyt.rbs_cert.rbwf_rbs_comm_shape)
  * appropriate statements regarding the size and weight of the output
    [ssyt.rbs_cert.rbwf_size]
    [ssyt.rbs_cert.rbwf_wt]

The *key lemma* is the *"pieri" property* [ssyt.rbs_cert.rbwf_pieri] :
  if we bump in k, then k' ≥ k starting from the same row,
  then the first output column is < the second output column.
This is essentially a consequence of
  [ssyt.rbs_cert.rbc_lt_rbc] and
  [ssyt.rbs_cert.rbc_out_le_rbc_out] and
  [ssyt.rbs_cert.rbwf_rbs_comm].
This lemma is used to define the recording tableau.
The proof is currently *very long* and could probably be improved.

-/

section row_bump_well_founded

def ssyt.rbs_cert.bound {μ : young_diagram} {T : ssyt μ} (h : T.rbs_cert) : ℕ :=
μ.col_len 0 - h.i

lemma ssyt.rbs_cert.bound_decr {μ : young_diagram} {T : ssyt μ} (h : T.rbs_cert)
  (cell : (h.i, h.j) ∈ μ) : (h.next_cert cell).bound < h.bound :=
begin
  apply nat.sub_mono_right_strict _ _,
  rw [h.next_cert_i, nat.succ_le_iff, ← μ.mem_col_iff'],
  exact μ.nw_of (le_refl _) (nat.zero_le _) cell,
  exact lt_add_one h.i,
end

def ssyt.rbs_cert.rbwf {μ : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert), Σ (c : μ.outer_corner), ssyt c.add
| T h := dite ((h.i, h.j) ∈ μ)
  (λ cell, have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
           (h.next_cert cell).rbwf)
  (λ not_cell, ⟨_, h.rbs_end not_cell⟩)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

lemma ssyt.rbs_cert.rbwf_of_cell {μ : young_diagram} {T : ssyt μ} (h : T.rbs_cert)
 (cell : (h.i, h.j) ∈ μ) : h.rbwf = (h.next_cert cell).rbwf :=
by rw [ssyt.rbs_cert.rbwf, dif_pos cell]

lemma ssyt.rbs_cert.rbwf_of_not_cell {μ : young_diagram} {T : ssyt μ}
  (h : T.rbs_cert) (not_cell : (h.i, h.j) ∉ μ) :
  h.rbwf = ⟨_, h.rbs_end not_cell⟩ :=
by rw [ssyt.rbs_cert.rbwf, dif_neg not_cell]

lemma ssyt.rbs_cert.rbwf_size {μ : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert), h.rbwf.1.add.size = μ.size + 1
| T h := dite ((h.i, h.j) ∈ μ)
  (λ cell,
    have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
    by rw [h.rbwf_of_cell cell, ssyt.rbs_cert.rbwf_size])
  (λ not_cell, begin
    rw h.rbwf_of_not_cell not_cell,
    apply young_diagram.outer_corner.add_size,
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

lemma ssyt.rbs_cert.rbwf_wt {μ : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert) (val : ℕ),
h.rbwf.2.wt val = T.wt val + ite (val = h.val) 1 0
| T h := λ val, dite ((h.i, h.j) ∈ μ)
  (λ cell,
    have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
    begin
      rw [h.rbwf_of_cell cell, ssyt.rbs_cert.rbwf_wt],
      apply ssyt.wt_replace,
    end)
  (λ not_cell, begin
    rw h.rbwf_of_not_cell not_cell,
    apply ssyt.wt_add,
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

lemma ssyt.rbs_cert.i_le_rbwf_corner {μ : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert), h.i ≤ h.rbwf.1.i
| T h := dite ((h.i, h.j) ∈ μ)
  (λ cell,
    have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
    begin
      rw h.rbwf_of_cell cell,
      apply le_trans _ (ssyt.rbs_cert.i_le_rbwf_corner _),
      exact h.i.le_succ,
    end)
  (λ not_cell, begin
    rw h.rbwf_of_not_cell not_cell, refl,
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

lemma ssyt.rbs_cert.rbwf_shape_eq_self_lt_initial_row {μ : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert) (i j : ℕ) (hi : i < h.i),
  (i, j) ∈ h.rbwf.1.add ↔ (i, j) ∈ μ
| T h := λ i j hi, dite ((h.i, h.j) ∈ μ)
  (λ cell,
    have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
    begin
      rw [h.rbwf_of_cell cell, ssyt.rbs_cert.rbwf_shape_eq_self_lt_initial_row],
      exact hi.trans (lt_add_one _),
    end)
  (λ not_cell, begin
    rw [h.rbwf_of_not_cell not_cell, h.rbs_end_shape_eq_of_ne_row _ (ne_of_lt hi)],
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

lemma ssyt.rbs_cert.rbwf_eq_self_lt_initial_row {μ : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert) (i j : ℕ) (hi : i < h.i), h.rbwf.2 i j = T i j
| T h := λ i j hi, dite ((h.i, h.j) ∈ μ)
  (λ cell,
    have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
    begin
      rw [h.rbwf_of_cell cell, ssyt.rbs_cert.rbwf_eq_self_lt_initial_row],
      apply h.rbs_entry_eq_of_ne_row _ (ne_of_lt hi),
      exact hi.trans (lt_add_one _),
    end)
  (λ not_cell, begin
    rw h.rbwf_of_not_cell not_cell,
    apply h.rbs_end_entry_eq_of_ne_row not_cell (ne_of_lt hi),
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

lemma ssyt.rbs_cert.rbwf_corner_eq_of_eq_ge_initial_row {μ ν : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert) {T' : ssyt ν} (h' : T'.rbs_cert)
  (hi : h'.i = h.i) (hval : h'.val = h.val)
  (eq_cell_ge : ∀ i j (hi' : h.i ≤ i), (i, j) ∈ μ ↔ (i, j) ∈ ν)
  (eq_row_ge : ∀ i j (hi' : h.i ≤ i), T i j = T' i j),
h'.rbwf.1.i = h.rbwf.1.i ∧ h'.rbwf.1.j = h.rbwf.1.j
| T h := λ T' h' hi hval eq_cell_ge eq_row_ge,
  have hj : h'.j = h.j := by {
    rw [ssyt.rbs_cert.j, ssyt.rbs_cert.j, hi, hval,
        T.rbc_eq_of_eq_row T' (λ j, eq_cell_ge _ j (by refl)) (λ j, eq_row_ge _ j (by refl))] },
  dite ((h.i, h.j) ∈ μ)
  (λ cell,
    have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
    begin
      have cell' : (h'.i, h'.j) ∈ ν := by rwa [hi, hj, ← eq_cell_ge _ _ (by refl)],
      rw [h.rbwf_of_cell cell, h'.rbwf_of_cell cell'],
      apply ssyt.rbs_cert.rbwf_corner_eq_of_eq_ge_initial_row,
      change h'.i.succ = h.i.succ, rw hi,
      change T' h'.i h'.j = T h.i h.j, rw [hi, hj, eq_row_ge _ _ (by refl)],
      exact λ i j hi', eq_cell_ge _ _ (le_trans h.i.le_succ hi'),
      intros i j hi',
        rw [h'.rbs_entry, hi, hj, hval, ← eq_row_ge _ _ (le_trans h.i.le_succ hi')], refl,
    end)
  (λ not_cell, begin
    have not_cell' : (h'.i, h'.j) ∉ ν := by rwa [hi, hj, ← eq_cell_ge _ _ (by refl)],
    rw [h.rbwf_of_not_cell not_cell, h'.rbwf_of_not_cell not_cell'],
    exact ⟨hi, hj⟩,
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

lemma ssyt.rbs_cert.rbwf_shape_eq_of_eq_ge_initial_row {μ ν : young_diagram}
  {T : ssyt μ} (h : T.rbs_cert) {T' : ssyt ν} (h' : T'.rbs_cert)
  (hi : h'.i = h.i) (hval : h'.val = h.val)
  (eq_cell_ge : ∀ i j (hi' : h.i ≤ i), (i, j) ∈ μ ↔ (i, j) ∈ ν)
  (eq_row_ge : ∀ i j (hi' : h.i ≤ i), T i j = T' i j)
  (i j : ℕ) (hi' : h.i ≤ i) :
  (i, j) ∈ h.rbwf.1.add ↔ (i, j) ∈ h'.rbwf.1.add :=
begin
  rw [young_diagram.outer_corner.mem_add, young_diagram.outer_corner.mem_add],
  obtain ⟨rwi, rwj⟩ := h.rbwf_corner_eq_of_eq_ge_initial_row h' hi hval eq_cell_ge eq_row_ge,
  rw [rwi, rwj, ← eq_cell_ge _ _ hi'],
end

lemma ssyt.rbs_cert.rbwf_eq_of_eq_ge_initial_row {μ ν : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert) {T' : ssyt ν} (h' : T'.rbs_cert)
  (hi : h'.i = h.i) (hval : h'.val = h.val)
  (eq_cell_ge : ∀ i j (hi' : h.i ≤ i), (i, j) ∈ μ ↔ (i, j) ∈ ν)
  (eq_row_ge : ∀ i j (hi' : h.i ≤ i), T i j = T' i j)
  (i j : ℕ) (hi' : h.i ≤ i),
  h.rbwf.2 i j = h'.rbwf.2 i j
| T h := λ T' h' hi hval eq_cell_ge eq_row_ge i j hi',
  have hj : h'.j = h.j := by {
    rw [ssyt.rbs_cert.j, ssyt.rbs_cert.j, hi, hval,
        T.rbc_eq_of_eq_row T' (λ j, eq_cell_ge _ j (by refl)) (λ j, eq_row_ge _ j (by refl))] },
  dite ((h.i, h.j) ∈ μ)
  (λ cell,
    have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
    begin
      have cell' : (h'.i, h'.j) ∈ ν := by rwa [hi, hj, ← eq_cell_ge _ _ (by refl)],
      rw [h.rbwf_of_cell cell, h'.rbwf_of_cell cell'],
      cases eq_or_lt_of_le hi',
      { subst i,
        repeat {rw ssyt.rbs_cert.rbwf_eq_self_lt_initial_row},
        rw [h'.rbs_entry, hi, hj, hval, ← eq_row_ge _ _ (by refl)], refl,
        rw ← hi, exact lt_add_one _, exact lt_add_one _ },
      { rw ssyt.rbs_cert.rbwf_eq_of_eq_ge_initial_row,
        exact congr_arg nat.succ hi,
        change T' h'.i h'.j = T h.i h.j, rw [hi, hj, eq_row_ge _ _ (by refl)],
        exact λ i j hi', eq_cell_ge _ _ (le_trans h.i.le_succ hi'),
        intros i j hi',
          rw [h'.rbs_entry, hi, hj, hval, ← eq_row_ge _ _ (le_trans h.i.le_succ hi')], refl,
        exact nat.succ_le_iff.mpr h_1, },
      end)
  (λ not_cell, begin
    have not_cell' : (h'.i, h'.j) ∉ ν := by rwa [hi, hj, ← eq_cell_ge _ _ (by refl)],
    rw [h.rbwf_of_not_cell not_cell, h'.rbwf_of_not_cell not_cell'], dsimp,
    rw [h'.rbs_end_entry not_cell', hi, hj, hval, ← eq_row_ge _ _ hi'], refl,
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

lemma ssyt.rbs_cert.rbwf_rbs_comm {μ : young_diagram}
  {T : ssyt μ} (h h1 : T.rbs_cert) (cell1 : (h1.i, h1.j) ∈ μ)
  (h_h1_i : h1.i < h.i)
  (h' : (h1.rbs cell1).rbs_cert) (hi' : h'.i = h.i) (hval' : h'.val = h.val)
  (h1' : h.rbwf.2.rbs_cert) (h1i' : h1'.i = h1.i) (h1val' : h1'.val = h1.val)
  (cell1' : (h1'.i, h1'.j) ∈ h.rbwf.1.add) :
  ∀ (i j : ℕ), h1'.rbs cell1' i j = h'.rbwf.2 i j :=
begin
  have h1j : h1'.j = h1.j := by {
    rw [ssyt.rbs_cert.j, ssyt.rbs_cert.j, h1i', h1val',
        h.rbwf.2.rbc_eq_of_eq_row T (λ j, _) (λ j, _)],
    rw h.rbwf_shape_eq_self_lt_initial_row _ _ h_h1_i,
    rw h.rbwf_eq_self_lt_initial_row _ _ h_h1_i },
  have key_lt_hi : ∀ i j (hi : i < h.i), h1'.rbs cell1' i j = h'.rbwf.2 i j,
  { intros i j hi,
    rw h'.rbwf_eq_self_lt_initial_row i _ (hi'.symm ▸ hi),
    rw [ssyt.rbs_cert.rbs_entry, ssyt.rbs_cert.rbs_entry, h1i', h1val', h1j],
    rw h.rbwf_eq_self_lt_initial_row _ _ hi, },
  have key_ge_hi : ∀ i j (hi : h.i ≤ i), h1'.rbs cell1' i j = h'.rbwf.2 i j,
  { intros i j hi,
    rw h1'.rbs_entry_eq_of_ne_row, rotate, rw h1i',
    symmetry, exact ne_of_lt (lt_of_lt_of_le h_h1_i hi),
    rw h.rbwf_eq_of_eq_ge_initial_row h' hi' hval' (λ _ _ _, iff.rfl) _ _ _ hi,
    intros i' j' hi'', rw h1.rbs_entry_eq_of_ne_row,
    symmetry, exact ne_of_lt (lt_of_lt_of_le h_h1_i hi'') },
  intros i j,
  cases lt_or_ge i h.i,
  apply key_lt_hi _ _ h_1,
  apply key_ge_hi _ _ h_1,
end

end row_bump_well_founded

section pieri

lemma ssyt.rbs_cert.rbwf_j_le {μ : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert), h.rbwf.1.j ≤ h.j
| T h := dite ((h.i, h.j) ∈ μ)
  (λ cell,
    have wf : (h.next_cert cell).bound < h.bound := h.bound_decr cell,
    begin
      rw h.rbwf_of_cell cell,
      apply le_trans _ (h.next_rbc_le cell),
      apply ssyt.rbs_cert.rbwf_j_le,
    end)
  (λ not_cell, begin
    rw h.rbwf_of_not_cell not_cell, refl,
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

/- Setup for this proof (the hardest one so far!) :

The main case is where both h.rbwf and h'.rbwf are nonterminal.
Then we obtain h1 and h'', and trace out the diagram in blue below:
  T
  ↓h
  T1  `→h'_1` T12
  ↓h1         `↓h1_2`
  :           `T12f →h12f ..`   *This is three rbs_cert.copy steps!*
  T1f    →h'   T1f2 →h'' ..

This corresponds to doing the first step of each rbwf. We conclude by induction.
(There is a side case where h is nonterminal and h' is terminal, and a base case
where both h and h' are terminal.)
-/
lemma ssyt.rbs_cert.rbwf_pieri {μ : young_diagram} :
Π {T : ssyt μ} (h : T.rbs_cert) (h' : h.rbwf.2.rbs_cert)
  (hi : h'.i = h.i) (hval : h.val ≤ h'.val),
  h.rbwf.1.j < h'.rbwf.1.j
| T h := dite ((h.i, h.j) ∈ μ)
  (λ cell, begin
    rw h.rbwf_of_cell cell,
    set T1 := h.rbs cell,
    set h1 : T1.rbs_cert := h.next_cert cell,
    set T1f := h1.rbwf.2,
    intro h',
    by_cases cell' : (h'.i, h'.j) ∈ (h.next_cert cell).rbwf.1.add,
    { rw h'.rbwf_of_cell cell',
      intros hi hval,
      set T1f2 := h'.rbs cell',
      set h'' : T1f2.rbs_cert := h'.next_cert cell',

      -- copy h' cert to T1
      set h'_1 : T1.rbs_cert := h'.copy T1
        (λ i' j' hi', by {
          rw ssyt.rbs_cert.rbwf_shape_eq_self_lt_initial_row,
          exact nat.lt_succ_iff.mpr (hi ▸ hi') })
        (λ i' j' hi', by {
          rw ssyt.rbs_cert.rbwf_eq_self_lt_initial_row,
          exact nat.lt_succ_iff.mpr (hi ▸ hi') }),
      have cell'_1 : (h'_1.i, h'_1.j) ∈ μ := by {
        rw ssyt.rbs_cert.copy_j,
        rw ssyt.rbs_cert.rbwf_shape_eq_self_lt_initial_row at cell',
        exact cell',
        rw hi, exact lt_add_one _,
      },

      -- copy h1 cert to T12
      set T12 := h'_1.rbs cell'_1,
      set h1_2 := h1.copy' T12
        (λ _ _ _, id)
        (λ _, iff.rfl)
        (λ i' j' hi', by apply ssyt.rbs_cert.rbs_entry_le)
        (λ j', by { rw h'_1.rbs_entry_eq_of_ne_row,
                    change h.i.succ ≠ h'.i, rw hi,
                    exact h.i.succ_ne_self }),

      -- copy h'' cert to T12f
      set T12f := h1_2.rbwf.2,
      set h12f : T12f.rbs_cert := h''.copy' T12f
        (λ i j hi', by {
          change i < h'.i.succ at hi', rw hi at hi',
          repeat {rw ssyt.rbs_cert.rbwf_shape_eq_self_lt_initial_row}, exact id,
          exact hi', exact hi' })
        (λ j, by {
          rw h1_2.rbwf_shape_eq_of_eq_ge_initial_row h1 rfl rfl (λ _ _ _, iff.rfl) _,
          change h.i.succ ≤ h'.i.succ, rw hi,
          intros i' j' hi',
            apply ssyt.rbs_cert.rbs_entry_eq_of_ne_row,
            rintro rfl, exact not_lt_of_le hi' (hi.symm ▸ lt_add_one h.i) })
        (λ i j hi', by {
          apply le_of_eq,
          rw ssyt.rbs_cert.rbwf_rbs_comm,
          exact hi.symm ▸ lt_add_one h.i, refl, refl, refl, refl })
        (λ j, by {
          rw ssyt.rbs_cert.rbwf_rbs_comm,
          exact hi.symm ▸ lt_add_one h.i, refl, refl, refl, refl }),

      -- convert the goal
      rw (_ : h1.rbwf.fst.j = h1_2.rbwf.fst.j),
      rw (_ : h''.rbwf.fst.j = h12f.rbwf.fst.j),

      -- complete by induction
      exact have wf : h1_2.bound < h.bound := h.bound_decr cell,
        ssyt.rbs_cert.rbwf_pieri h1_2 h12f (congr_arg nat.succ hi)
          (by { change T _ _ ≤ T1f _ _,
                rw [hi, h1.rbwf_eq_self_lt_initial_row _ _ (lt_add_one _)],
                rw (by rw ssyt.rbs_cert.copy_j : h'.j = h'_1.j),
                convert h.rbc_out_le_rbc_out cell hval _,
                rw ← hi, refl,
                rw ← hi, exact cell'_1 }),

      -- justify the two rewrites
      { apply (h12f.rbwf_corner_eq_of_eq_ge_initial_row h'' rfl rfl _ _).2,
        { intros i j hi',
            apply h1_2.rbwf_shape_eq_of_eq_ge_initial_row h1 rfl rfl (λ _ _ _, iff.rfl) _,
            change h.i.succ ≤ i, change h'.i.succ ≤ i at hi',
            rwa hi at hi',
          intros i' j' hi',
            apply ssyt.rbs_cert.rbs_entry_eq_of_ne_row,
            rintro rfl, exact not_lt_of_le hi' (hi.symm ▸ lt_add_one h.i) },
        intros i j hi',
        rw ssyt.rbs_cert.rbwf_rbs_comm,
        exact hi.symm ▸ lt_add_one h.i, refl, refl, refl, refl },
      { apply (h1_2.rbwf_corner_eq_of_eq_ge_initial_row h1 rfl rfl (λ _ _ _, iff.rfl) _).2,
        intros i j hi',
        apply ssyt.rbs_cert.rbs_entry_eq_of_ne_row,
        rintro rfl, exact not_lt_of_le hi' (hi.symm ▸ lt_add_one h.i) },
    },
    { -- side case: h is nonterminal, h' is terminal
      rename cell' not_cell',
      rw h'.rbwf_of_not_cell not_cell',
      intros hi hval, change _ < h'.j,
      apply lt_of_le_of_lt h1.rbwf_j_le,
      apply lt_of_le_of_lt (h.next_rbc_le cell),

      by_contra h_le, push_neg at h_le, apply not_cell',
      rw hi, apply young_diagram.nw_of _ (le_refl _) h_le,
      rw young_diagram.outer_corner.mem_add, right, exact cell },
  end)
  (λ not_cell, begin
    -- base case: h, and (we show) therefore h', are both terminal
    rw h.rbwf_of_not_cell not_cell,
    intros h' hi hval,
    have key : h.j < h'.j,
    { rw [ssyt.lt_rbc_iff, hi], split,
      { rw young_diagram.outer_corner.mem_add,
        exact or.inl rfl },
      { rw [h.rbs_end_entry, if_pos rfl],
        exact hval, }, },
    rwa h'.rbwf_of_not_cell,
    rw [hi, young_diagram.outer_corner.mem_add], push_neg,
    exact ⟨λ h_eq, (ne_of_lt key).symm (prod.mk.inj_iff.mp h_eq).2,
           λ cell', not_cell (μ.nw_of (le_refl _) (le_of_lt key) cell')⟩,
  end)
using_well_founded { rel_tac := λ _ _, `[exact ⟨_, measure_wf (λ x, x.2.bound)⟩] }

end pieri

section row_bump
/- Definition of row bumping! -/

def ssyt.row_bump {μ : young_diagram} (T : ssyt μ) (bumpval : ℕ) :
  Σ (c : μ.outer_corner), ssyt c.add :=
(T.rbs_start_cert bumpval).rbwf

lemma ssyt.row_bump_size {μ : young_diagram} (T : ssyt μ) (bumpval : ℕ) :
  (T.row_bump bumpval).1.add.size = μ.size + 1 :=
by apply ssyt.rbs_cert.rbwf_size

lemma ssyt.row_bump_wt {μ : young_diagram} (T : ssyt μ) (bumpval : ℕ) (val : ℕ) :
(T.row_bump bumpval).2.wt val = T.wt val + ite (val = bumpval) 1 0 :=
by apply ssyt.rbs_cert.rbwf_wt

end row_bump

#eval μ5331.lowest_ssyt
#eval (μ5331.lowest_ssyt.rbs_start_cert 0).rbwf.2
#eval (μ5331.lowest_ssyt.rbs_start_cert 1).rbwf.2
#eval (μ5331.lowest_ssyt.row_bump 2).2