diff --git a/src/Init/Data/Int/Order.lean b/src/Init/Data/Int/Order.lean index 1300bab584..94c5936ec7 100644 --- a/src/Init/Data/Int/Order.lean +++ b/src/Init/Data/Int/Order.lean @@ -127,9 +127,14 @@ protected theorem lt_iff_le_not_le {a b : Int} : a < b ↔ a ≤ b ∧ ¬b ≤ a · exact Int.le_antisymm h h' · subst h'; apply Int.le_refl +protected theorem lt_of_not_ge {a b : Int} (h : ¬a ≤ b) : b < a := + Int.lt_iff_le_not_le.mpr ⟨(Int.le_total ..).resolve_right h, h⟩ + +protected theorem not_le_of_gt {a b : Int} (h : b < a) : ¬a ≤ b := + (Int.lt_iff_le_not_le.mp h).right + protected theorem not_le {a b : Int} : ¬a ≤ b ↔ b < a := - ⟨fun h => Int.lt_iff_le_not_le.2 ⟨(Int.le_total ..).resolve_right h, h⟩, - fun h => (Int.lt_iff_le_not_le.1 h).2⟩ + Iff.intro Int.lt_of_not_ge Int.not_le_of_gt protected theorem not_lt {a b : Int} : ¬a < b ↔ b ≤ a := by rw [← Int.not_le, Decidable.not_not] @@ -509,9 +514,6 @@ theorem mem_toNat' : ∀ (a : Int) (n : Nat), toNat' a = some n ↔ a = n /-! ## Order properties of the integers -/ -protected theorem lt_of_not_ge {a b : Int} : ¬a ≤ b → b < a := Int.not_le.mp -protected theorem not_le_of_gt {a b : Int} : b < a → ¬a ≤ b := Int.not_le.mpr - protected theorem le_of_not_le {a b : Int} : ¬ a ≤ b → b ≤ a := (Int.le_total a b).resolve_left @[simp] theorem negSucc_not_pos (n : Nat) : 0 < -[n+1] ↔ False := by @@ -586,7 +588,10 @@ theorem add_one_le_iff {a b : Int} : a + 1 ≤ b ↔ a < b := .rfl theorem lt_add_one_iff {a b : Int} : a < b + 1 ↔ a ≤ b := Int.add_le_add_iff_right _ @[simp] theorem succ_ofNat_pos (n : Nat) : 0 < (n : Int) + 1 := - lt_add_one_iff.2 (ofNat_zero_le _) + lt_add_one_iff.mpr (ofNat_zero_le _) + +theorem not_ofNat_neg (n : Nat) : ¬((n : Int) < 0) := + Int.not_lt.mpr (ofNat_zero_le ..) theorem le_add_one {a b : Int} (h : a ≤ b) : a ≤ b + 1 := Int.le_of_lt (Int.lt_add_one_iff.2 h) @@ -801,6 +806,12 @@ protected theorem lt_add_of_neg_lt_sub_right {a b c : Int} (h : -b < a - c) : c protected theorem neg_lt_sub_right_of_lt_add {a b c : Int} (h : c < a + b) : -b < a - c := Int.lt_sub_left_of_add_lt (Int.sub_right_lt_of_lt_add h) +protected theorem add_lt_iff (a b c : Int) : a + b < c ↔ a < -b + c := by + rw [← Int.add_lt_add_iff_left (-b), Int.add_comm (-b), Int.add_neg_cancel_right] + +protected theorem sub_lt_iff (a b c : Int) : a - b < c ↔ a < c + b := + Iff.intro Int.lt_add_of_sub_right_lt Int.sub_right_lt_of_lt_add + protected theorem sub_lt_of_sub_lt {a b c : Int} (h : a - b < c) : a - c < b := Int.sub_left_lt_of_lt_add (Int.lt_add_of_sub_right_lt h) diff --git a/src/Init/Data/Nat/Div.lean b/src/Init/Data/Nat/Div.lean index 7cbff46be5..48461cd03a 100644 --- a/src/Init/Data/Nat/Div.lean +++ b/src/Init/Data/Nat/Div.lean @@ -251,10 +251,10 @@ theorem div_mul_le_self : ∀ (m n : Nat), m / n * n ≤ m theorem div_lt_iff_lt_mul (Hk : 0 < k) : x / k < y ↔ x < y * k := by rw [← Nat.not_le, ← Nat.not_le]; exact not_congr (le_div_iff_mul_le Hk) -@[simp] theorem add_div_right (x : Nat) {z : Nat} (H : 0 < z) : (x + z) / z = succ (x / z) := by +@[simp] theorem add_div_right (x : Nat) {z : Nat} (H : 0 < z) : (x + z) / z = (x / z) + 1 := by rw [div_eq_sub_div H (Nat.le_add_left _ _), Nat.add_sub_cancel] -@[simp] theorem add_div_left (x : Nat) {z : Nat} (H : 0 < z) : (z + x) / z = succ (x / z) := by +@[simp] theorem add_div_left (x : Nat) {z : Nat} (H : 0 < z) : (z + x) / z = (x / z) + 1 := by rw [Nat.add_comm, add_div_right x H] theorem add_mul_div_left (x z : Nat) {y : Nat} (H : 0 < y) : (x + y * z) / y = x / y + z := by diff --git a/src/Lean/Meta/Tactic/Simp/BuiltinSimprocs/Int.lean b/src/Lean/Meta/Tactic/Simp/BuiltinSimprocs/Int.lean index 57a3286a85..3939a4b49e 100644 --- a/src/Lean/Meta/Tactic/Simp/BuiltinSimprocs/Int.lean +++ b/src/Lean/Meta/Tactic/Simp/BuiltinSimprocs/Int.lean @@ -25,6 +25,12 @@ def fromExpr? (e : Expr) : SimpM (Option Int) := let some v₂ ← fromExpr? e.appArg! | return .continue return .done <| toExpr (op v₁ v₂) +def reduceBinIntNatOp (name : Name) (op : Int → Nat → Int) (e : Expr) : SimpM DStep := do + unless e.isAppOfArity name 2 do return .continue + let some v₁ ← getIntValue? e.appFn!.appArg! | return .continue + let some v₂ ← getNatValue? e.appArg! | return .continue + return .done <| toExpr (op v₁ v₂) + @[inline] def reduceBinPred (declName : Name) (arity : Nat) (op : Int → Int → Bool) (e : Expr) : SimpM Step := do unless e.isAppOfArity declName arity do return .continue let some v₁ ← fromExpr? e.appFn!.appArg! | return .continue @@ -65,6 +71,12 @@ builtin_dsimproc [simp, seval] reduceMul ((_ * _ : Int)) := reduceBin ``HMul.hMu builtin_dsimproc [simp, seval] reduceSub ((_ - _ : Int)) := reduceBin ``HSub.hSub 6 (· - ·) builtin_dsimproc [simp, seval] reduceDiv ((_ / _ : Int)) := reduceBin ``HDiv.hDiv 6 (· / ·) builtin_dsimproc [simp, seval] reduceMod ((_ % _ : Int)) := reduceBin ``HMod.hMod 6 (· % ·) +builtin_dsimproc [simp, seval] reduceTDiv (div _ _) := reduceBin ``Int.div 2 Int.div +builtin_dsimproc [simp, seval] reduceTMod (mod _ _) := reduceBin ``Int.mod 2 Int.mod +builtin_dsimproc [simp, seval] reduceFDiv (fdiv _ _) := reduceBin ``Int.fdiv 2 Int.fdiv +builtin_dsimproc [simp, seval] reduceFMod (fmod _ _) := reduceBin ``Int.fmod 2 Int.fmod +builtin_dsimproc [simp, seval] reduceBdiv (bdiv _ _) := reduceBinIntNatOp ``bdiv bdiv +builtin_dsimproc [simp, seval] reduceBmod (bmod _ _) := reduceBinIntNatOp ``bmod bmod builtin_dsimproc [simp, seval] reducePow ((_ : Int) ^ (_ : Nat)) := fun e => do let_expr HPow.hPow _ _ _ _ a b ← e | return .continue