@@ -9,6 +9,7 @@ import Mathlib.Algebra.Order.Monoid.Unbundled.Defs
9
9
import Mathlib.Algebra.Order.ZeroLEOne
10
10
import Mathlib.Tactic.Bound.Attribute
11
11
import Mathlib.Tactic.GCongr.CoreAttrs
12
+ import Mathlib.Tactic.Monotonicity.Attr
12
13
import Mathlib.Tactic.Nontriviality
13
14
14
15
/-!
@@ -1008,12 +1009,30 @@ lemma pow_right_mono₀ (h : 1 ≤ a) : Monotone (a ^ ·) :=
1008
1009
monotone_nat_of_le_succ fun n => by
1009
1010
rw [pow_succ']; exact le_mul_of_one_le_left (pow_nonneg (zero_le_one.trans h) _) h
1010
1011
1012
+ /-- `bound` lemma for branching on `1 ≤ a ∨ a ≤ 1` when proving `a ^ n ≤ a ^ m` -/
1013
+ @[bound]
1014
+ lemma Bound.pow_le_pow_right_of_le_one_or_one_le (h : 1 ≤ a ∧ n ≤ m ∨ 0 ≤ a ∧ a ≤ 1 ∧ m ≤ n) :
1015
+ a ^ n ≤ a ^ m := by
1016
+ obtain ⟨a1, nm⟩ | ⟨a0, a1, mn⟩ := h
1017
+ · exact pow_right_mono₀ a1 nm
1018
+ · exact pow_le_pow_of_le_one a0 a1 mn
1019
+
1011
1020
@[gcongr]
1012
1021
lemma pow_le_pow_right₀ (ha : 1 ≤ a) (hmn : m ≤ n) : a ^ m ≤ a ^ n := pow_right_mono₀ ha hmn
1013
1022
1014
1023
lemma le_self_pow₀ (ha : 1 ≤ a) (hn : n ≠ 0 ) : a ≤ a ^ n := by
1015
1024
simpa only [pow_one] using pow_le_pow_right₀ ha <| Nat.pos_iff_ne_zero.2 hn
1016
1025
1026
+ /-- The `bound` tactic can't handle `m ≠ 0` goals yet, so we express as `0 < m` -/
1027
+ @[bound]
1028
+ lemma Bound.le_self_pow_of_pos (ha : 1 ≤ a) (hn : 0 < n) : a ≤ a ^ n := le_self_pow₀ ha hn.ne'
1029
+
1030
+ @[mono, gcongr, bound]
1031
+ theorem pow_le_pow_left₀ (ha : 0 ≤ a) (hab : a ≤ b) : ∀ n, a ^ n ≤ b ^ n
1032
+ | 0 => by simp
1033
+ | n + 1 => by simpa only [pow_succ']
1034
+ using mul_le_mul hab (pow_le_pow_left₀ ha hab _) (pow_nonneg ha _) (ha.trans hab)
1035
+
1017
1036
end
1018
1037
1019
1038
variable [Preorder α] {f g : α → M₀}
@@ -1044,11 +1063,7 @@ end Preorder
1044
1063
1045
1064
1046
1065
section PartialOrder
1047
- variable [PartialOrder M₀] {a b c d : M₀}
1048
-
1049
- @[simp] lemma pow_pos [ZeroLEOneClass M₀] [PosMulStrictMono M₀] (ha : 0 < a) : ∀ n, 0 < a ^ n
1050
- | 0 => by nontriviality; rw [pow_zero]; exact zero_lt_one
1051
- | _ + 1 => pow_succ a _ ▸ mul_pos (pow_pos ha _) ha
1066
+ variable [PartialOrder M₀] {a b c d : M₀} {m n : ℕ}
1052
1067
1053
1068
lemma mul_self_lt_mul_self [PosMulStrictMono M₀] [MulPosMono M₀] (ha : 0 ≤ a) (hab : a < b) :
1054
1069
a * a < b * b := mul_lt_mul' hab.le hab ha <| ha.trans_lt hab
@@ -1076,6 +1091,61 @@ lemma lt_mul_right [PosMulStrictMono M₀] (ha : 0 < a) (hb : 1 < b) : a < a * b
1076
1091
lemma lt_mul_self [ZeroLEOneClass M₀] [MulPosStrictMono M₀] (ha : 1 < a) : a < a * a :=
1077
1092
lt_mul_left (ha.trans_le' zero_le_one) ha
1078
1093
1094
+ section strict_mono
1095
+ variable [ZeroLEOneClass M₀] [PosMulStrictMono M₀]
1096
+
1097
+ @[simp] lemma pow_pos (ha : 0 < a) : ∀ n, 0 < a ^ n
1098
+ | 0 => by nontriviality; rw [pow_zero]; exact zero_lt_one
1099
+ | _ + 1 => pow_succ a _ ▸ mul_pos (pow_pos ha _) ha
1100
+
1101
+ lemma sq_pos_of_pos (ha : 0 < a) : 0 < a ^ 2 := pow_pos ha _
1102
+
1103
+ variable [MulPosStrictMono M₀]
1104
+
1105
+ @[gcongr, bound]
1106
+ lemma pow_lt_pow_left₀ (hab : a < b)
1107
+ (ha : 0 ≤ a) : ∀ {n : ℕ}, n ≠ 0 → a ^ n < b ^ n
1108
+ | n + 1 , _ => by
1109
+ simpa only [pow_succ] using mul_lt_mul_of_le_of_lt_of_nonneg_of_pos
1110
+ (pow_le_pow_left₀ ha hab.le _) hab ha (pow_pos (ha.trans_lt hab) _)
1111
+
1112
+ /-- See also `pow_left_strictMono₀` and `Nat.pow_left_strictMono`. -/
1113
+ lemma pow_left_strictMonoOn₀ (hn : n ≠ 0 ) : StrictMonoOn (· ^ n : M₀ → M₀) {a | 0 ≤ a} :=
1114
+ fun _a ha _b _ hab ↦ pow_lt_pow_left₀ hab ha hn
1115
+
1116
+ /-- See also `pow_right_strictMono'`. -/
1117
+ lemma pow_right_strictMono₀ (h : 1 < a) : StrictMono (a ^ ·) :=
1118
+ have : 0 < a := zero_le_one.trans_lt h
1119
+ strictMono_nat_of_lt_succ fun n => by
1120
+ simpa only [one_mul, pow_succ'] using mul_lt_mul h (le_refl (a ^ n)) (pow_pos this _) this.le
1121
+
1122
+ @[gcongr]
1123
+ lemma pow_lt_pow_right₀ (h : 1 < a) (hmn : m < n) : a ^ m < a ^ n := pow_right_strictMono₀ h hmn
1124
+
1125
+ lemma pow_lt_pow_iff_right₀ (h : 1 < a) : a ^ n < a ^ m ↔ n < m :=
1126
+ (pow_right_strictMono₀ h).lt_iff_lt
1127
+
1128
+ lemma pow_le_pow_iff_right₀ (h : 1 < a) : a ^ n ≤ a ^ m ↔ n ≤ m :=
1129
+ (pow_right_strictMono₀ h).le_iff_le
1130
+
1131
+ lemma lt_self_pow₀ (h : 1 < a) (hm : 1 < m) : a < a ^ m := by
1132
+ simpa only [pow_one] using pow_lt_pow_right₀ h hm
1133
+
1134
+ lemma pow_right_strictAnti₀ (h₀ : 0 < a) (h₁ : a < 1 ) : StrictAnti (a ^ ·) :=
1135
+ strictAnti_nat_of_succ_lt fun n => by
1136
+ simpa only [pow_succ', one_mul] using mul_lt_mul h₁ le_rfl (pow_pos h₀ n) zero_le_one
1137
+
1138
+ lemma pow_lt_pow_iff_right_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1 ) : a ^ m < a ^ n ↔ n < m :=
1139
+ (pow_right_strictAnti₀ h₀ h₁).lt_iff_lt
1140
+
1141
+ lemma pow_lt_pow_right_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1 ) (hmn : m < n) : a ^ n < a ^ m :=
1142
+ (pow_lt_pow_iff_right_of_lt_one₀ h₀ h₁).2 hmn
1143
+
1144
+ lemma pow_lt_self_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1 ) (hn : 1 < n) : a ^ n < a := by
1145
+ simpa only [pow_one] using pow_lt_pow_right_of_lt_one₀ h₀ h₁ hn
1146
+
1147
+ end strict_mono
1148
+
1079
1149
variable [Preorder α] {f g : α → M₀}
1080
1150
1081
1151
lemma strictMono_mul_left_of_pos [PosMulStrictMono M₀] (ha : 0 < a) :
@@ -1108,7 +1178,72 @@ lemma StrictMono.mul [PosMulStrictMono M₀] [MulPosStrictMono M₀] (hf : Stric
1108
1178
(hg : StrictMono g) (hf₀ : ∀ x, 0 ≤ f x) (hg₀ : ∀ x, 0 ≤ g x) :
1109
1179
StrictMono (f * g) := fun _ _ h ↦ mul_lt_mul'' (hf h) (hg h) (hf₀ _) (hg₀ _)
1110
1180
1111
- end MonoidWithZero.PartialOrder
1181
+ end PartialOrder
1182
+
1183
+ section LinearOrder
1184
+ variable [LinearOrder M₀] [ZeroLEOneClass M₀] [PosMulStrictMono M₀] [MulPosStrictMono M₀] {a b : M₀}
1185
+ {m n : ℕ}
1186
+
1187
+ lemma pow_le_pow_iff_left₀ (ha : 0 ≤ a) (hb : 0 ≤ b) (hn : n ≠ 0 ) : a ^ n ≤ b ^ n ↔ a ≤ b :=
1188
+ (pow_left_strictMonoOn₀ hn).le_iff_le ha hb
1189
+
1190
+ lemma pow_lt_pow_iff_left₀ (ha : 0 ≤ a) (hb : 0 ≤ b) (hn : n ≠ 0 ) : a ^ n < b ^ n ↔ a < b :=
1191
+ (pow_left_strictMonoOn₀ hn).lt_iff_lt ha hb
1192
+
1193
+ @[simp]
1194
+ lemma pow_left_inj₀ (ha : 0 ≤ a) (hb : 0 ≤ b) (hn : n ≠ 0 ) : a ^ n = b ^ n ↔ a = b :=
1195
+ (pow_left_strictMonoOn₀ hn).eq_iff_eq ha hb
1196
+
1197
+ lemma pow_right_injective₀ (ha₀ : 0 < a) (ha₁ : a ≠ 1 ) : Injective (a ^ ·) := by
1198
+ obtain ha₁ | ha₁ := ha₁.lt_or_lt
1199
+ · exact (pow_right_strictAnti₀ ha₀ ha₁).injective
1200
+ · exact (pow_right_strictMono₀ ha₁).injective
1201
+
1202
+ @[simp]
1203
+ lemma pow_right_inj₀ (ha₀ : 0 < a) (ha₁ : a ≠ 1 ) : a ^ m = a ^ n ↔ m = n :=
1204
+ (pow_right_injective₀ ha₀ ha₁).eq_iff
1205
+
1206
+ lemma pow_le_one_iff_of_nonneg (ha : 0 ≤ a) (hn : n ≠ 0 ) : a ^ n ≤ 1 ↔ a ≤ 1 := by
1207
+ simpa only [one_pow] using pow_le_pow_iff_left₀ ha zero_le_one hn
1208
+
1209
+ lemma one_le_pow_iff_of_nonneg (ha : 0 ≤ a) (hn : n ≠ 0 ) : 1 ≤ a ^ n ↔ 1 ≤ a := by
1210
+ simpa only [one_pow] using pow_le_pow_iff_left₀ zero_le_one ha hn
1211
+
1212
+ lemma pow_lt_one_iff_of_nonneg (ha : 0 ≤ a) (hn : n ≠ 0 ) : a ^ n < 1 ↔ a < 1 :=
1213
+ lt_iff_lt_of_le_iff_le (one_le_pow_iff_of_nonneg ha hn)
1214
+
1215
+ lemma one_lt_pow_iff_of_nonneg (ha : 0 ≤ a) (hn : n ≠ 0 ) : 1 < a ^ n ↔ 1 < a := by
1216
+ simpa only [one_pow] using pow_lt_pow_iff_left₀ zero_le_one ha hn
1217
+
1218
+ lemma pow_eq_one_iff_of_nonneg (ha : 0 ≤ a) (hn : n ≠ 0 ) : a ^ n = 1 ↔ a = 1 := by
1219
+ simpa only [one_pow] using pow_left_inj₀ ha zero_le_one hn
1220
+
1221
+ lemma sq_le_one_iff₀ (ha : 0 ≤ a) : a ^ 2 ≤ 1 ↔ a ≤ 1 :=
1222
+ pow_le_one_iff_of_nonneg ha (Nat.succ_ne_zero _)
1223
+
1224
+ lemma sq_lt_one_iff₀ (ha : 0 ≤ a) : a ^ 2 < 1 ↔ a < 1 :=
1225
+ pow_lt_one_iff_of_nonneg ha (Nat.succ_ne_zero _)
1226
+
1227
+ lemma one_le_sq_iff₀ (ha : 0 ≤ a) : 1 ≤ a ^ 2 ↔ 1 ≤ a :=
1228
+ one_le_pow_iff_of_nonneg ha (Nat.succ_ne_zero _)
1229
+
1230
+ lemma one_lt_sq_iff₀ (ha : 0 ≤ a) : 1 < a ^ 2 ↔ 1 < a :=
1231
+ one_lt_pow_iff_of_nonneg ha (Nat.succ_ne_zero _)
1232
+
1233
+ lemma lt_of_pow_lt_pow_left₀ (n : ℕ) (hb : 0 ≤ b) (h : a ^ n < b ^ n) : a < b :=
1234
+ lt_of_not_ge fun hn => not_lt_of_ge (pow_le_pow_left₀ hb hn _) h
1235
+
1236
+ lemma le_of_pow_le_pow_left₀ (hn : n ≠ 0 ) (hb : 0 ≤ b) (h : a ^ n ≤ b ^ n) : a ≤ b :=
1237
+ le_of_not_lt fun h1 => not_le_of_lt (pow_lt_pow_left₀ h1 hb hn) h
1238
+
1239
+ @[simp]
1240
+ lemma sq_eq_sq₀ (ha : 0 ≤ a) (hb : 0 ≤ b) : a ^ 2 = b ^ 2 ↔ a = b := pow_left_inj₀ ha hb (by decide)
1241
+
1242
+ lemma lt_of_mul_self_lt_mul_self₀ (hb : 0 ≤ b) : a * a < b * b → a < b := by
1243
+ simp_rw [← sq]
1244
+ exact lt_of_pow_lt_pow_left₀ _ hb
1245
+
1246
+ end MonoidWithZero.LinearOrder
1112
1247
1113
1248
section CancelMonoidWithZero
1114
1249
@@ -1654,4 +1789,4 @@ lemma div_lt_comm₀ (hb : 0 < b) (hc : 0 < c) : a / b < c ↔ a / c < b := by
1654
1789
end PosMulStrictMono
1655
1790
end CommGroupWithZero
1656
1791
1657
- set_option linter.style.longFile 1700
1792
+ set_option linter.style.longFile 1900
0 commit comments