-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathDefs.lean
More file actions
1364 lines (1027 loc) · 61 KB
/
Copy pathDefs.lean
File metadata and controls
1364 lines (1027 loc) · 61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/-
Copyright (c) 2023 Yaël Dillies. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
-/
module
public import Mathlib.Algebra.Module.Torsion.Free
public import Mathlib.Algebra.Order.Group.Basic
public import Mathlib.Algebra.Order.GroupWithZero.Action.Synonym
public import Mathlib.Algebra.Order.Monoid.Unbundled.Pow
public import Mathlib.Algebra.Order.Ring.Defs
public import Mathlib.Order.Hom.Basic
public import Mathlib.Algebra.GroupWithZero.Action.Units
/-!
# Monotonicity of scalar multiplication by positive elements
This file defines typeclasses to reason about monotonicity of the operations
* `b ↦ a • b`, "left scalar multiplication"
* `a ↦ a • b`, "right scalar multiplication"
We use eight typeclasses to encode the various properties we care about for those two operations.
These typeclasses are meant to be mostly internal to this file, to set up each lemma in the
appropriate generality.
Less granular typeclasses like `IsOrderedAddMonoid` and `IsOrderedModule` should be enough for most
purposes, and the system is set up so that they imply the correct granular typeclasses here.
If those are enough for you, you may stop reading here! Else, beware that what
follows is a bit technical.
In all that follows, `α` and `β` are orders which have a `0` and such that `α` acts on `β` by scalar
multiplication. Note however that we do not use lawfulness of this action in most of the file. Hence
`•` should be considered here as a mostly arbitrary function `α → β → β`.
We use the following four typeclasses to reason about left scalar multiplication (`b ↦ a • b`):
* `PosSMulMono`: If `a ≥ 0`, then `b₁ ≤ b₂` implies `a • b₁ ≤ a • b₂`.
* `PosSMulStrictMono`: If `a > 0`, then `b₁ < b₂` implies `a • b₁ < a • b₂`.
* `PosSMulReflectLT`: If `a ≥ 0`, then `a • b₁ < a • b₂` implies `b₁ < b₂`.
* `PosSMulReflectLE`: If `a > 0`, then `a • b₁ ≤ a • b₂` implies `b₁ ≤ b₂`.
We use the following four typeclasses to reason about right scalar multiplication (`a ↦ a • b`):
* `SMulPosMono`: If `b ≥ 0`, then `a₁ ≤ a₂` implies `a₁ • b ≤ a₂ • b`.
* `SMulPosStrictMono`: If `b > 0`, then `a₁ < a₂` implies `a₁ • b < a₂ • b`.
* `SMulPosReflectLT`: If `b ≥ 0`, then `a₁ • b < a₂ • b` implies `a₁ < a₂`.
* `SMulPosReflectLE`: If `b > 0`, then `a₁ • b ≤ a₂ • b` implies `a₁ ≤ a₂`.
Furthermore, in a *module*, i.e. a group acted on by a ring, `PosSMulMono` and `SMulPosMono` are
equivalent (they are both the same as `∀ r ≥ 0, ∀ m ≥ 0, 0 ≤ r • m`),
and similarly for `PosSMulStrictMono` and `SMulPosStrictMono`.
To avoid dangerous instances going both, we have the extra two typeclasses:
* `IsOrderedModule`: Conjunction of `PosSMulMono` and `SMulPosMono`
* `IsStrictOrderedModule`: Conjunction of `PosSMulStrictMono` and `SMulPosStrictMono`.
## Constructors
The four typeclasses about nonnegativity can usually be checked only on positive inputs due to their
condition becoming trivial when `a = 0` or `b = 0`. We therefore make the following constructors
available: `PosSMulMono.of_pos`, `PosSMulReflectLT.of_pos`, `SMulPosMono.of_pos`,
`SMulPosReflectLT.of_pos`
## Implications
As `α` and `β` get more and more structure, those typeclasses end up being equivalent. The commonly
used implications are:
* When `α`, `β` are partial orders:
* `PosSMulStrictMono → PosSMulMono`
* `SMulPosStrictMono → SMulPosMono`
* `PosSMulReflectLE → PosSMulReflectLT`
* `SMulPosReflectLE → SMulPosReflectLT`
* When `β` is a linear order:
* `PosSMulStrictMono → PosSMulReflectLE`
* `PosSMulReflectLT → PosSMulMono` (not registered as instance)
* `SMulPosReflectLT → SMulPosMono` (not registered as instance)
* `PosSMulReflectLE → PosSMulStrictMono` (not registered as instance)
* `SMulPosReflectLE → SMulPosStrictMono` (not registered as instance)
* When `α` is a linear order:
* `SMulPosStrictMono → SMulPosReflectLE`
* When `α` is an ordered ring, `β` an ordered group and also an `α`-module:
* `PosSMulMono → SMulPosMono`
* `PosSMulStrictMono → SMulPosStrictMono`
* When `α` is a linear ordered semifield, `β` is an `α`-module:
* `PosSMulStrictMono → PosSMulReflectLT`
* `PosSMulMono → PosSMulReflectLE`
* When `α` is a semiring, `β` is an `α`-module with `Module.IsTorsionFree`:
* `PosSMulMono → PosSMulStrictMono` (not registered as instance)
* When `α` is a ring, `β` is an `α`-module with `Module.IsTorsionFree`:
* `SMulPosMono → SMulPosStrictMono` (not registered as instance)
Further, the bundled non-granular typeclasses imply the granular ones like so:
* `IsOrderedModule → PosSMulMono`
* `IsOrderedModule → SMulPosMono`
* `IsStrictOrderedModule → PosSMulStrictMono`
* `IsStrictOrderedModule → SMulPosStrictMono`
Unless otherwise stated, all these implications are registered as instances,
which means that in practice you should not worry about these implications.
However, if you encounter a case where you think a statement is true but
not covered by the current implications, please bring it up on Zulip!
## Implementation notes
This file uses custom typeclasses instead of abbreviations of `CovariantClass`/`ContravariantClass`
because:
* They get displayed as classes in the docs. In particular, one can see their list of instances,
instead of their instances being invariably dumped to the `CovariantClass`/`ContravariantClass`
list.
* They don't pollute other typeclass searches. Having many abbreviations of the same typeclass for
different purposes always felt like a performance issue (more instances with the same key, for no
added benefit), and indeed making the classes here abbreviation previous creates timeouts due to
the higher number of `CovariantClass`/`ContravariantClass` instances.
* `SMulPosReflectLT`/`SMulPosReflectLE` do not fit in the framework since they relate `≤` on two
different types. So we would have to generalise `CovariantClass`/`ContravariantClass` to three
types and two relations.
* Very minor, but the constructors let you work with `a : α`, `h : 0 ≤ a` instead of
`a : {a : α // 0 ≤ a}`. This actually makes some instances surprisingly cleaner to prove.
* The `CovariantClass`/`ContravariantClass` framework is only useful to automate very simple logic
anyway. It is easily copied over.
In the future, it would be good to make the corresponding typeclasses in
`Mathlib/Algebra/Order/GroupWithZero/Unbundled/Defs.lean` custom typeclasses too.
-/
@[expose] public section
assert_not_exists Field Finset
open OrderDual
variable (α β : Type*)
section Defs
variable [SMul α β] [Preorder α] [Preorder β]
section Left
variable [Zero α]
/-- Typeclass for monotonicity of scalar multiplication by nonnegative elements on the left,
namely `b₁ ≤ b₂ → a • b₁ ≤ a • b₂` if `0 ≤ a`.
You should usually not use this very granular typeclass directly, but rather a typeclass like
`IsOrderedModule`. -/
class PosSMulMono : Prop where
/-- Do not use this. Use `smul_le_smul_of_nonneg_left` instead. -/
protected smul_le_smul_of_nonneg_left ⦃a : α⦄ (ha : 0 ≤ a) ⦃b₁ b₂ : β⦄ (hb : b₁ ≤ b₂) :
a • b₁ ≤ a • b₂
/-- Typeclass for strict monotonicity of scalar multiplication by positive elements on the left,
namely `b₁ < b₂ → a • b₁ < a • b₂` if `0 < a`.
You should usually not use this very granular typeclass directly, but rather a typeclass like
`IsOrderedModule`. -/
class PosSMulStrictMono : Prop where
/-- Do not use this. Use `smul_lt_smul_of_pos_left` instead. -/
protected smul_lt_smul_of_pos_left ⦃a : α⦄ (ha : 0 < a) ⦃b₁ b₂ : β⦄ (hb : b₁ < b₂) :
a • b₁ < a • b₂
/-- Typeclass for strict reverse monotonicity of scalar multiplication by nonnegative elements on
the left, namely `a • b₁ < a • b₂ → b₁ < b₂` if `0 ≤ a`.
You should usually not use this very granular typeclass directly, but rather a typeclass like
`IsOrderedModule`. -/
class PosSMulReflectLT : Prop where
/-- Do not use this. Use `lt_of_smul_lt_smul_left` instead. -/
protected lt_of_smul_lt_smul_left ⦃a : α⦄ (ha : 0 ≤ a) ⦃b₁ b₂ : β⦄ (hb : a • b₁ < a • b₂) :
b₁ < b₂
/-- Typeclass for reverse monotonicity of scalar multiplication by positive elements on the left,
namely `a • b₁ ≤ a • b₂ → b₁ ≤ b₂` if `0 < a`.
You should usually not use this very granular typeclass directly, but rather a typeclass like
`IsOrderedModule`. -/
class PosSMulReflectLE : Prop where
/-- Do not use this. Use `le_of_smul_le_smul_left` instead. -/
protected le_of_smul_le_smul_left ⦃a : α⦄ (ha : 0 < a) ⦃b₁ b₂ : β⦄ (hb : a • b₁ ≤ a • b₂) :
b₁ ≤ b₂
end Left
section Right
variable [Zero β]
/-- Typeclass for monotonicity of scalar multiplication by nonnegative elements on the left,
namely `a₁ ≤ a₂ → a₁ • b ≤ a₂ • b` if `0 ≤ b`.
You should usually not use this very granular typeclass directly, but rather a typeclass like
`IsOrderedModule`. -/
class SMulPosMono : Prop where
/-- Do not use this. Use `smul_le_smul_of_nonneg_right` instead. -/
protected smul_le_smul_of_nonneg_right ⦃b : β⦄ (hb : 0 ≤ b) ⦃a₁ a₂ : α⦄ (ha : a₁ ≤ a₂) :
a₁ • b ≤ a₂ • b
/-- Typeclass for strict monotonicity of scalar multiplication by positive elements on the left,
namely `a₁ < a₂ → a₁ • b < a₂ • b` if `0 < b`.
You should usually not use this very granular typeclass directly, but rather a typeclass like
`IsOrderedModule`. -/
class SMulPosStrictMono : Prop where
/-- Do not use this. Use `smul_lt_smul_of_pos_right` instead. -/
protected smul_lt_smul_of_pos_right ⦃b : β⦄ (hb : 0 < b) ⦃a₁ a₂ : α⦄ (ha : a₁ < a₂) :
a₁ • b < a₂ • b
/-- Typeclass for strict reverse monotonicity of scalar multiplication by nonnegative elements on
the left, namely `a₁ • b < a₂ • b → a₁ < a₂` if `0 ≤ b`.
You should usually not use this very granular typeclass directly, but rather a typeclass like
`IsOrderedModule`. -/
class SMulPosReflectLT : Prop where
/-- Do not use this. Use `lt_of_smul_lt_smul_right` instead. -/
protected lt_of_smul_lt_smul_right ⦃b : β⦄ (hb : 0 ≤ b) ⦃a₁ a₂ : α⦄ (hb : a₁ • b < a₂ • b) :
a₁ < a₂
/-- Typeclass for reverse monotonicity of scalar multiplication by positive elements on the left,
namely `a₁ • b ≤ a₂ • b → a₁ ≤ a₂` if `0 < b`.
You should usually not use this very granular typeclass directly, but rather a typeclass like
`IsOrderedModule`. -/
class SMulPosReflectLE : Prop where
/-- Do not use this. Use `le_of_smul_le_smul_right` instead. -/
protected le_of_smul_le_smul_right ⦃b : β⦄ (hb : 0 < b) ⦃a₁ a₂ : α⦄ (hb : a₁ • b ≤ a₂ • b) :
a₁ ≤ a₂
end Right
section LeftRight
variable [Zero α] [Zero β]
/-- An ordered module is a module with a partial order such that scalar multiplication by a
nonnegative scalar and of a nonnegative vector are both monotone. -/
class IsOrderedModule extends PosSMulMono α β, SMulPosMono α β
/-- An ordered module is a module with a partial order such that scalar multiplication by a
positive scalar and of a positive vector are both strictly monotone. -/
class IsStrictOrderedModule extends PosSMulStrictMono α β, SMulPosStrictMono α β
end LeftRight
end Defs
variable {α β} {a a₁ a₂ : α} {b b₁ b₂ : β}
section Mul
variable [Zero α] [Mul α] [Preorder α]
-- See note [lower instance priority]
instance (priority := 100) PosMulMono.toPosSMulMono [PosMulMono α] : PosSMulMono α α where
smul_le_smul_of_nonneg_left _a ha _b₁ _b₂ hb := mul_le_mul_of_nonneg_left hb ha
-- See note [lower instance priority]
instance (priority := 100) PosMulStrictMono.toPosSMulStrictMono [PosMulStrictMono α] :
PosSMulStrictMono α α where
smul_lt_smul_of_pos_left _a ha _b₁ _b₂ hb := mul_lt_mul_of_pos_left hb ha
-- See note [lower instance priority]
instance (priority := 100) PosMulReflectLT.toPosSMulReflectLT [PosMulReflectLT α] :
PosSMulReflectLT α α where
lt_of_smul_lt_smul_left _a ha _b₁ _b₂ h := lt_of_mul_lt_mul_left h ha
-- See note [lower instance priority]
instance (priority := 100) PosMulReflectLE.toPosSMulReflectLE [PosMulReflectLE α] :
PosSMulReflectLE α α where
le_of_smul_le_smul_left _a ha _b₁ _b₂ h := le_of_mul_le_mul_left h ha
-- See note [lower instance priority]
instance (priority := 100) MulPosMono.toSMulPosMono [MulPosMono α] : SMulPosMono α α where
smul_le_smul_of_nonneg_right _b hb _a₁ _a₂ ha := mul_le_mul_of_nonneg_right ha hb
-- See note [lower instance priority]
instance (priority := 100) MulPosStrictMono.toSMulPosStrictMono [MulPosStrictMono α] :
SMulPosStrictMono α α where
smul_lt_smul_of_pos_right _b hb _a₁ _a₂ ha := mul_lt_mul_of_pos_right ha hb
-- See note [lower instance priority]
instance (priority := 100) MulPosReflectLT.toSMulPosReflectLT [MulPosReflectLT α] :
SMulPosReflectLT α α where
lt_of_smul_lt_smul_right _b hb _a₁ _a₂ h := lt_of_mul_lt_mul_right h hb
-- See note [lower instance priority]
instance (priority := 100) MulPosReflectLE.toSMulPosReflectLE [MulPosReflectLE α] :
SMulPosReflectLE α α where
le_of_smul_le_smul_right _b hb _a₁ _a₂ h := le_of_mul_le_mul_right h hb
end Mul
instance {M : Type*} [PartialOrder M] [AddCommMonoid M] [IsOrderedAddMonoid M] :
PosSMulMono ℕ M where
smul_le_smul_of_nonneg_left _n _ _a _b hab := nsmul_le_nsmul_right hab _
instance {M : Type*} [PartialOrder M] [AddCommMonoid M] [IsOrderedAddMonoid M] :
SMulPosMono ℕ M where
smul_le_smul_of_nonneg_right _a ha _m _n hmn := nsmul_le_nsmul_left ha hmn
instance {M : Type*} [PartialOrder M] [AddCancelCommMonoid M] [IsOrderedAddMonoid M] :
PosSMulStrictMono ℕ M where
smul_lt_smul_of_pos_left _n hn _m₁ _m₂ := nsmul_lt_nsmul_right hn.ne'
instance {M : Type*} [PartialOrder M] [AddCommMonoid M] [IsOrderedCancelAddMonoid M] :
SMulPosStrictMono ℕ M where
smul_lt_smul_of_pos_right _a ha _m _n hmn := nsmul_lt_nsmul_left ha hmn
instance {G : Type*} [PartialOrder G] [AddCommGroup G] [IsOrderedAddMonoid G] :
PosSMulStrictMono ℤ G where
smul_lt_smul_of_pos_left _n hn _m₁ _m₂ := zsmul_lt_zsmul_right hn
instance {G : Type*} [PartialOrder G] [AddCommGroup G] [IsOrderedAddMonoid G] :
SMulPosStrictMono ℤ G where
smul_lt_smul_of_pos_right _a ha _m _n hmn := zsmul_lt_zsmul_left ha hmn
section SMul
variable [SMul α β]
section Preorder
variable [Preorder α] [Preorder β]
section Left
variable [Zero α]
lemma monotone_smul_left_of_nonneg [PosSMulMono α β] (ha : 0 ≤ a) : Monotone ((a • ·) : β → β) :=
PosSMulMono.smul_le_smul_of_nonneg_left ha
lemma strictMono_smul_left_of_pos [PosSMulStrictMono α β] (ha : 0 < a) :
StrictMono ((a • ·) : β → β) := PosSMulStrictMono.smul_lt_smul_of_pos_left ha
@[gcongr] lemma smul_le_smul_of_nonneg_left [PosSMulMono α β] (hb : b₁ ≤ b₂) (ha : 0 ≤ a) :
a • b₁ ≤ a • b₂ := monotone_smul_left_of_nonneg ha hb
@[gcongr] lemma smul_lt_smul_of_pos_left [PosSMulStrictMono α β] (hb : b₁ < b₂) (ha : 0 < a) :
a • b₁ < a • b₂ := strictMono_smul_left_of_pos ha hb
/-- Scalar multiplication on the left by a nonnegative element preserves monotonicity. -/
lemma Monotone.const_smul [PosSMulMono α β] {γ : Type*} [Preorder γ] {f : γ → β}
(hf : Monotone f) (ha : 0 ≤ a) : Monotone fun x ↦ a • f x :=
(monotone_smul_left_of_nonneg ha).comp hf
/-- Scalar multiplication on the left by a nonnegative element preserves antitonicity. -/
lemma Antitone.const_smul [PosSMulMono α β] {γ : Type*} [Preorder γ] {f : γ → β}
(hf : Antitone f) (ha : 0 ≤ a) : Antitone fun x ↦ a • f x :=
(monotone_smul_left_of_nonneg ha).comp_antitone hf
/-- Scalar multiplication on the left by a positive element preserves strict monotonicity. -/
lemma StrictMono.const_smul [PosSMulStrictMono α β] {γ : Type*} [Preorder γ] {f : γ → β}
(hf : StrictMono f) (ha : 0 < a) : StrictMono fun x ↦ a • f x :=
(strictMono_smul_left_of_pos ha).comp hf
/-- Scalar multiplication on the left by a positive element preserves strict antitonicity. -/
lemma StrictAnti.const_smul [PosSMulStrictMono α β] {γ : Type*} [Preorder γ] {f : γ → β}
(hf : StrictAnti f) (ha : 0 < a) : StrictAnti fun x ↦ a • f x :=
(strictMono_smul_left_of_pos ha).comp_strictAnti hf
lemma lt_of_smul_lt_smul_left [PosSMulReflectLT α β] (h : a • b₁ < a • b₂) (ha : 0 ≤ a) : b₁ < b₂ :=
PosSMulReflectLT.lt_of_smul_lt_smul_left ha h
lemma le_of_smul_le_smul_left [PosSMulReflectLE α β] (h : a • b₁ ≤ a • b₂) (ha : 0 < a) : b₁ ≤ b₂ :=
PosSMulReflectLE.le_of_smul_le_smul_left ha h
alias lt_of_smul_lt_smul_of_nonneg_left := lt_of_smul_lt_smul_left
alias le_of_smul_le_smul_of_pos_left := le_of_smul_le_smul_left
@[simp]
lemma smul_le_smul_iff_of_pos_left [PosSMulMono α β] [PosSMulReflectLE α β] (ha : 0 < a) :
a • b₁ ≤ a • b₂ ↔ b₁ ≤ b₂ :=
⟨fun h ↦ le_of_smul_le_smul_left h ha, fun h ↦ smul_le_smul_of_nonneg_left h ha.le⟩
@[simp]
lemma smul_lt_smul_iff_of_pos_left [PosSMulStrictMono α β] [PosSMulReflectLT α β] (ha : 0 < a) :
a • b₁ < a • b₂ ↔ b₁ < b₂ :=
⟨fun h ↦ lt_of_smul_lt_smul_left h ha.le, fun hb ↦ smul_lt_smul_of_pos_left hb ha⟩
end Left
section Right
variable [Zero β]
lemma monotone_smul_right_of_nonneg [SMulPosMono α β] (hb : 0 ≤ b) : Monotone ((· • b) : α → β) :=
SMulPosMono.smul_le_smul_of_nonneg_right hb
lemma strictMono_smul_right_of_pos [SMulPosStrictMono α β] (hb : 0 < b) :
StrictMono ((· • b) : α → β) := SMulPosStrictMono.smul_lt_smul_of_pos_right hb
/-- Scalar multiplication on the right by a nonnegative element preserves monotonicity. -/
lemma Monotone.smul_const [SMulPosMono α β] {γ : Type*} [Preorder γ] {f : γ → α}
(hf : Monotone f) (hb : 0 ≤ b) : Monotone fun x ↦ f x • b :=
(monotone_smul_right_of_nonneg hb).comp hf
/-- Scalar multiplication on the right by a nonnegative element preserves antitonicity. -/
lemma Antitone.smul_const [SMulPosMono α β] {γ : Type*} [Preorder γ] {f : γ → α}
(hf : Antitone f) (hb : 0 ≤ b) : Antitone fun x ↦ f x • b :=
(monotone_smul_right_of_nonneg hb).comp_antitone hf
/-- Scalar multiplication on the right by a positive element preserves strict monotonicity. -/
lemma StrictMono.smul_const [SMulPosStrictMono α β] {γ : Type*} [Preorder γ] {f : γ → α}
(hf : StrictMono f) (hb : 0 < b) : StrictMono fun x ↦ f x • b :=
(strictMono_smul_right_of_pos hb).comp hf
/-- Scalar multiplication on the right by a positive element preserves strict antitonicity. -/
lemma StrictAnti.smul_const [SMulPosStrictMono α β] {γ : Type*} [Preorder γ] {f : γ → α}
(hf : StrictAnti f) (hb : 0 < b) : StrictAnti fun x ↦ f x • b :=
(strictMono_smul_right_of_pos hb).comp_strictAnti hf
@[gcongr] lemma smul_le_smul_of_nonneg_right [SMulPosMono α β] (ha : a₁ ≤ a₂) (hb : 0 ≤ b) :
a₁ • b ≤ a₂ • b := monotone_smul_right_of_nonneg hb ha
variable (β) in
@[gcongr, mono]
lemma smul_one_mono [One β] [ZeroLEOneClass β] [SMulPosMono α β] :
Monotone (fun x : α ↦ x • (1 : β)) :=
fun _ _ ha ↦ smul_le_smul_of_nonneg_right ha zero_le_one
@[gcongr] lemma smul_lt_smul_of_pos_right [SMulPosStrictMono α β] (ha : a₁ < a₂) (hb : 0 < b) :
a₁ • b < a₂ • b := strictMono_smul_right_of_pos hb ha
lemma lt_of_smul_lt_smul_right [SMulPosReflectLT α β] (h : a₁ • b < a₂ • b) (hb : 0 ≤ b) :
a₁ < a₂ := SMulPosReflectLT.lt_of_smul_lt_smul_right hb h
lemma le_of_smul_le_smul_right [SMulPosReflectLE α β] (h : a₁ • b ≤ a₂ • b) (hb : 0 < b) :
a₁ ≤ a₂ := SMulPosReflectLE.le_of_smul_le_smul_right hb h
alias lt_of_smul_lt_smul_of_nonneg_right := lt_of_smul_lt_smul_right
alias le_of_smul_le_smul_of_pos_right := le_of_smul_le_smul_right
@[simp]
lemma smul_le_smul_iff_of_pos_right [SMulPosMono α β] [SMulPosReflectLE α β] (hb : 0 < b) :
a₁ • b ≤ a₂ • b ↔ a₁ ≤ a₂ :=
⟨fun h ↦ le_of_smul_le_smul_right h hb, fun ha ↦ smul_le_smul_of_nonneg_right ha hb.le⟩
@[simp]
lemma smul_lt_smul_iff_of_pos_right [SMulPosStrictMono α β] [SMulPosReflectLT α β] (hb : 0 < b) :
a₁ • b < a₂ • b ↔ a₁ < a₂ :=
⟨fun h ↦ lt_of_smul_lt_smul_right h hb.le, fun ha ↦ smul_lt_smul_of_pos_right ha hb⟩
end Right
section LeftRight
variable [Zero α] [Zero β]
lemma smul_lt_smul_of_le_of_lt [PosSMulStrictMono α β] [SMulPosMono α β] (ha : a₁ ≤ a₂)
(hb : b₁ < b₂) (h₁ : 0 < a₁) (h₂ : 0 ≤ b₂) : a₁ • b₁ < a₂ • b₂ :=
(smul_lt_smul_of_pos_left hb h₁).trans_le (smul_le_smul_of_nonneg_right ha h₂)
lemma smul_lt_smul_of_le_of_lt' [PosSMulStrictMono α β] [SMulPosMono α β] (ha : a₁ ≤ a₂)
(hb : b₁ < b₂) (h₂ : 0 < a₂) (h₁ : 0 ≤ b₁) : a₁ • b₁ < a₂ • b₂ :=
(smul_le_smul_of_nonneg_right ha h₁).trans_lt (smul_lt_smul_of_pos_left hb h₂)
lemma smul_lt_smul_of_lt_of_le [PosSMulMono α β] [SMulPosStrictMono α β] (ha : a₁ < a₂)
(hb : b₁ ≤ b₂) (h₁ : 0 ≤ a₁) (h₂ : 0 < b₂) : a₁ • b₁ < a₂ • b₂ :=
(smul_le_smul_of_nonneg_left hb h₁).trans_lt (smul_lt_smul_of_pos_right ha h₂)
lemma smul_lt_smul_of_lt_of_le' [PosSMulMono α β] [SMulPosStrictMono α β] (ha : a₁ < a₂)
(hb : b₁ ≤ b₂) (h₂ : 0 ≤ a₂) (h₁ : 0 < b₁) : a₁ • b₁ < a₂ • b₂ :=
(smul_lt_smul_of_pos_right ha h₁).trans_le (smul_le_smul_of_nonneg_left hb h₂)
lemma smul_lt_smul [PosSMulStrictMono α β] [SMulPosStrictMono α β] (ha : a₁ < a₂) (hb : b₁ < b₂)
(h₁ : 0 < a₁) (h₂ : 0 < b₂) : a₁ • b₁ < a₂ • b₂ :=
(smul_lt_smul_of_pos_left hb h₁).trans (smul_lt_smul_of_pos_right ha h₂)
lemma smul_lt_smul' [PosSMulStrictMono α β] [SMulPosStrictMono α β] (ha : a₁ < a₂) (hb : b₁ < b₂)
(h₂ : 0 < a₂) (h₁ : 0 < b₁) : a₁ • b₁ < a₂ • b₂ :=
(smul_lt_smul_of_pos_right ha h₁).trans (smul_lt_smul_of_pos_left hb h₂)
lemma smul_le_smul [PosSMulMono α β] [SMulPosMono α β] (ha : a₁ ≤ a₂) (hb : b₁ ≤ b₂)
(h₁ : 0 ≤ a₁) (h₂ : 0 ≤ b₂) : a₁ • b₁ ≤ a₂ • b₂ :=
(smul_le_smul_of_nonneg_left hb h₁).trans (smul_le_smul_of_nonneg_right ha h₂)
lemma smul_le_smul' [PosSMulMono α β] [SMulPosMono α β] (ha : a₁ ≤ a₂) (hb : b₁ ≤ b₂) (h₂ : 0 ≤ a₂)
(h₁ : 0 ≤ b₁) : a₁ • b₁ ≤ a₂ • b₂ :=
(smul_le_smul_of_nonneg_right ha h₁).trans (smul_le_smul_of_nonneg_left hb h₂)
end LeftRight
end Preorder
variable (β) in
@[gcongr, mono]
lemma smul_one_strictMono [Preorder α] [PartialOrder β] [Zero β] [One β] [ZeroLEOneClass β]
[NeZero (1 : β)] [SMulPosStrictMono α β] :
StrictMono (fun x : α ↦ x • (1 : β)) :=
fun _ _ ha ↦ smul_lt_smul_of_pos_right ha (zero_lt_one (α := β))
section PartialOrder
variable [Semiring α] [PartialOrder α]
-- See note [lower instance priority]
instance (priority := 100) IsOrderedRing.toIsOrderedModule [IsOrderedRing α] :
IsOrderedModule α α where
-- See note [lower instance priority]
instance (priority := 100) IsStrictOrderedRing.toIsStrictOrderedModule [IsStrictOrderedRing α] :
IsStrictOrderedModule α α where
end PartialOrder
section LinearOrder
variable [Preorder α] [LinearOrder β]
section Left
variable [Zero α]
-- See note [lower instance priority]
instance (priority := 100) PosSMulStrictMono.toPosSMulReflectLE [PosSMulStrictMono α β] :
PosSMulReflectLE α β where
le_of_smul_le_smul_left _a ha _b₁ _b₂ := (strictMono_smul_left_of_pos ha).le_iff_le.1
lemma PosSMulReflectLE.toPosSMulStrictMono [PosSMulReflectLE α β] : PosSMulStrictMono α β where
smul_lt_smul_of_pos_left _a ha _b₁ _b₂ hb :=
not_le.1 fun h ↦ hb.not_ge <| le_of_smul_le_smul_left h ha
lemma posSMulStrictMono_iff_PosSMulReflectLE : PosSMulStrictMono α β ↔ PosSMulReflectLE α β :=
⟨fun _ ↦ inferInstance, fun _ ↦ PosSMulReflectLE.toPosSMulStrictMono⟩
instance PosSMulMono.toPosSMulReflectLT [PosSMulMono α β] : PosSMulReflectLT α β where
lt_of_smul_lt_smul_left _a ha _b₁ _b₂ := (monotone_smul_left_of_nonneg ha).reflect_lt
lemma PosSMulReflectLT.toPosSMulMono [PosSMulReflectLT α β] : PosSMulMono α β where
smul_le_smul_of_nonneg_left _a ha _b₁ _b₂ hb :=
not_lt.1 fun h ↦ hb.not_gt <| lt_of_smul_lt_smul_left h ha
lemma posSMulMono_iff_posSMulReflectLT : PosSMulMono α β ↔ PosSMulReflectLT α β :=
⟨fun _ ↦ PosSMulMono.toPosSMulReflectLT, fun _ ↦ PosSMulReflectLT.toPosSMulMono⟩
lemma smul_max_of_nonneg [PosSMulMono α β] (ha : 0 ≤ a) (b₁ b₂ : β) :
a • max b₁ b₂ = max (a • b₁) (a • b₂) := (monotone_smul_left_of_nonneg ha).map_max
lemma smul_min_of_nonneg [PosSMulMono α β] (ha : 0 ≤ a) (b₁ b₂ : β) :
a • min b₁ b₂ = min (a • b₁) (a • b₂) := (monotone_smul_left_of_nonneg ha).map_min
end Left
section Right
variable [Zero β]
lemma SMulPosReflectLE.toSMulPosStrictMono [SMulPosReflectLE α β] : SMulPosStrictMono α β where
smul_lt_smul_of_pos_right _b hb _a₁ _a₂ ha :=
not_le.1 fun h ↦ ha.not_ge <| le_of_smul_le_smul_of_pos_right h hb
lemma SMulPosReflectLT.toSMulPosMono [SMulPosReflectLT α β] : SMulPosMono α β where
smul_le_smul_of_nonneg_right _b hb _a₁ _a₂ ha :=
not_lt.1 fun h ↦ ha.not_gt <| lt_of_smul_lt_smul_right h hb
end Right
end LinearOrder
section LinearOrder
variable [LinearOrder α] [Preorder β]
section Right
variable [Zero β]
-- See note [lower instance priority]
instance (priority := 100) SMulPosStrictMono.toSMulPosReflectLE [SMulPosStrictMono α β] :
SMulPosReflectLE α β where
le_of_smul_le_smul_right _b hb _a₁ _a₂ h :=
not_lt.1 fun ha ↦ h.not_gt <| smul_lt_smul_of_pos_right ha hb
lemma SMulPosMono.toSMulPosReflectLT [SMulPosMono α β] : SMulPosReflectLT α β where
lt_of_smul_lt_smul_right _b hb _a₁ _a₂ h :=
not_le.1 fun ha ↦ h.not_ge <| smul_le_smul_of_nonneg_right ha hb
end Right
end LinearOrder
section LinearOrder
variable [LinearOrder α] [LinearOrder β]
section Right
variable [Zero β]
lemma smulPosStrictMono_iff_SMulPosReflectLE : SMulPosStrictMono α β ↔ SMulPosReflectLE α β :=
⟨fun _ ↦ SMulPosStrictMono.toSMulPosReflectLE, fun _ ↦ SMulPosReflectLE.toSMulPosStrictMono⟩
lemma smulPosMono_iff_smulPosReflectLT : SMulPosMono α β ↔ SMulPosReflectLT α β :=
⟨fun _ ↦ SMulPosMono.toSMulPosReflectLT, fun _ ↦ SMulPosReflectLT.toSMulPosMono⟩
end Right
end LinearOrder
end SMul
section SMulZeroClass
variable [Zero α] [Zero β] [SMulZeroClass α β]
section Preorder
variable [Preorder α] [Preorder β]
lemma smul_pos [PosSMulStrictMono α β] (ha : 0 < a) (hb : 0 < b) : 0 < a • b := by
simpa only [smul_zero] using smul_lt_smul_of_pos_left hb ha
lemma smul_neg_of_pos_of_neg [PosSMulStrictMono α β] (ha : 0 < a) (hb : b < 0) : a • b < 0 := by
simpa only [smul_zero] using smul_lt_smul_of_pos_left hb ha
@[simp]
lemma smul_pos_iff_of_pos_left [PosSMulStrictMono α β] [PosSMulReflectLT α β] (ha : 0 < a) :
0 < a • b ↔ 0 < b := by
simpa only [smul_zero] using smul_lt_smul_iff_of_pos_left ha (b₁ := 0) (b₂ := b)
lemma smul_neg_iff_of_pos_left [PosSMulStrictMono α β] [PosSMulReflectLT α β] (ha : 0 < a) :
a • b < 0 ↔ b < 0 := by
simpa only [smul_zero] using smul_lt_smul_iff_of_pos_left ha (b₂ := (0 : β))
lemma smul_nonneg [PosSMulMono α β] (ha : 0 ≤ a) (hb : 0 ≤ b₁) : 0 ≤ a • b₁ := by
simpa only [smul_zero] using smul_le_smul_of_nonneg_left hb ha
lemma smul_nonpos_of_nonneg_of_nonpos [PosSMulMono α β] (ha : 0 ≤ a) (hb : b ≤ 0) : a • b ≤ 0 := by
simpa only [smul_zero] using smul_le_smul_of_nonneg_left hb ha
lemma pos_of_smul_pos_left [PosSMulReflectLT α β] (h : 0 < a • b) (ha : 0 ≤ a) : 0 < b :=
lt_of_smul_lt_smul_left (by rwa [smul_zero]) ha
lemma neg_of_smul_neg_left [PosSMulReflectLT α β] (h : a • b < 0) (ha : 0 ≤ a) : b < 0 :=
lt_of_smul_lt_smul_left (by rwa [smul_zero]) ha
lemma nonneg_of_smul_nonneg_of_pos_left [PosSMulReflectLE α β] (h : 0 ≤ a • b) (ha : 0 < a) :
0 ≤ b :=
le_of_smul_le_smul_of_pos_left (by simpa) ha
lemma nonpos_of_smul_nonpos_of_pos_left [PosSMulReflectLE α β] (h : a • b ≤ 0) (ha : 0 < a) :
b ≤ 0 :=
le_of_smul_le_smul_of_pos_left (by simpa) ha
lemma smul_nonneg_iff_nonneg_of_pos_left [PosSMulMono α β] [PosSMulReflectLE α β] (ha : 0 < a) :
0 ≤ a • b ↔ 0 ≤ b :=
⟨(nonneg_of_smul_nonneg_of_pos_left · ha), smul_nonneg ha.le⟩
lemma smul_nonpos_iff_nonpos_of_pos_left [PosSMulMono α β] [PosSMulReflectLE α β] (ha : 0 < a) :
a • b ≤ 0 ↔ b ≤ 0 :=
⟨(nonpos_of_smul_nonpos_of_pos_left · ha), smul_nonpos_of_nonneg_of_nonpos ha.le⟩
end Preorder
end SMulZeroClass
section SMulWithZero
variable [Zero α] [Zero β] [SMulWithZero α β]
section Preorder
variable [Preorder α] [Preorder β]
lemma smul_pos' [SMulPosStrictMono α β] (ha : 0 < a) (hb : 0 < b) : 0 < a • b := by
simpa only [zero_smul] using smul_lt_smul_of_pos_right ha hb
lemma smul_neg_of_neg_of_pos [SMulPosStrictMono α β] (ha : a < 0) (hb : 0 < b) : a • b < 0 := by
simpa only [zero_smul] using smul_lt_smul_of_pos_right ha hb
@[simp]
lemma smul_pos_iff_of_pos_right [SMulPosStrictMono α β] [SMulPosReflectLT α β] (hb : 0 < b) :
0 < a • b ↔ 0 < a := by
simpa only [zero_smul] using smul_lt_smul_iff_of_pos_right hb (a₁ := 0) (a₂ := a)
lemma smul_nonneg' [SMulPosMono α β] (ha : 0 ≤ a) (hb : 0 ≤ b₁) : 0 ≤ a • b₁ := by
simpa only [zero_smul] using smul_le_smul_of_nonneg_right ha hb
lemma smul_nonpos_of_nonpos_of_nonneg [SMulPosMono α β] (ha : a ≤ 0) (hb : 0 ≤ b) : a • b ≤ 0 := by
simpa only [zero_smul] using smul_le_smul_of_nonneg_right ha hb
lemma pos_of_smul_pos_right [SMulPosReflectLT α β] (h : 0 < a • b) (hb : 0 ≤ b) : 0 < a :=
lt_of_smul_lt_smul_right (by rwa [zero_smul]) hb
lemma neg_of_smul_neg_right [SMulPosReflectLT α β] (h : a • b < 0) (hb : 0 ≤ b) : a < 0 :=
lt_of_smul_lt_smul_right (by rwa [zero_smul]) hb
lemma pos_iff_pos_of_smul_pos [PosSMulReflectLT α β] [SMulPosReflectLT α β] (hab : 0 < a • b) :
0 < a ↔ 0 < b :=
⟨pos_of_smul_pos_left hab ∘ le_of_lt, pos_of_smul_pos_right hab ∘ le_of_lt⟩
lemma nonneg_of_smul_nonneg_of_pos_right [SMulPosReflectLE α β] (h : 0 ≤ a • b) (hb : 0 < b) :
0 ≤ a :=
le_of_smul_le_smul_of_pos_right (by simpa) hb
lemma nonpos_of_smul_nonpos_of_pos_right [SMulPosReflectLE α β] (h : a • b ≤ 0) (hb : 0 < b) :
a ≤ 0 :=
le_of_smul_le_smul_of_pos_right (by simpa) hb
lemma smul_nonneg_iff_nonneg_of_pos_right [SMulPosMono α β] [SMulPosReflectLE α β] (hb : 0 < b) :
0 ≤ a • b ↔ 0 ≤ a :=
⟨(nonneg_of_smul_nonneg_of_pos_right · hb), (smul_nonneg' · hb.le)⟩
lemma smul_nonpos_iff_nonpos_of_pos_right [SMulPosMono α β] [SMulPosReflectLE α β] (hb : 0 < b) :
a • b ≤ 0 ↔ a ≤ 0 :=
⟨(nonpos_of_smul_nonpos_of_pos_right · hb), (smul_nonpos_of_nonpos_of_nonneg · hb.le)⟩
lemma IsOrderedModule.of_smul_one_mono
[MulOneClass β] [PosMulMono β] [MulPosMono β] [IsScalarTower α β β]
(h : Monotone (fun x : α ↦ x • (1 : β))) : IsOrderedModule α β where
smul_le_smul_of_nonneg_left _ ha _ _ hb := by
have := mul_le_mul_of_nonneg_left hb (by simpa using h ha)
simpa
smul_le_smul_of_nonneg_right _ ha _ _ hb := by
simpa using mul_le_mul_of_nonneg_right (h hb) ha
theorem isOrderedModule_iff_smul_one_mono
[MulOneClass β] [ZeroLEOneClass β] [PosMulMono β] [MulPosMono β] [IsScalarTower α β β] :
IsOrderedModule α β ↔ Monotone (fun x : α ↦ x • (1 : β)) where
mp _ := smul_one_mono _
mpr := IsOrderedModule.of_smul_one_mono
end Preorder
section PartialOrder
variable [PartialOrder α] [Preorder β]
/-- A constructor for `PosSMulMono` requiring you to prove `b₁ ≤ b₂ → a • b₁ ≤ a • b₂` only when
`0 < a` -/
lemma PosSMulMono.of_pos (h₀ : ∀ a : α, 0 < a → ∀ b₁ b₂ : β, b₁ ≤ b₂ → a • b₁ ≤ a • b₂) :
PosSMulMono α β where
smul_le_smul_of_nonneg_left a ha b₁ b₂ h := by
obtain ha | ha := ha.eq_or_lt
· simp [← ha]
· exact h₀ _ ha _ _ h
/-- A constructor for `PosSMulReflectLT` requiring you to prove `a • b₁ < a • b₂ → b₁ < b₂` only
when `0 < a` -/
lemma PosSMulReflectLT.of_pos (h₀ : ∀ a : α, 0 < a → ∀ b₁ b₂ : β, a • b₁ < a • b₂ → b₁ < b₂) :
PosSMulReflectLT α β where
lt_of_smul_lt_smul_left a ha b₁ b₂ h := by
obtain ha | ha := ha.eq_or_lt
· simp [← ha] at h
· exact h₀ _ ha _ _ h
end PartialOrder
section PartialOrder
variable [Preorder α] [PartialOrder β]
/-- A constructor for `SMulPosMono` requiring you to prove `a₁ ≤ a₂ → a₁ • b ≤ a₂ • b` only when
`0 < b` -/
lemma SMulPosMono.of_pos (h₀ : ∀ b : β, 0 < b → ∀ a₁ a₂ : α, a₁ ≤ a₂ → a₁ • b ≤ a₂ • b) :
SMulPosMono α β where
smul_le_smul_of_nonneg_right b hb a₁ a₂ h := by
obtain hb | hb := hb.eq_or_lt
· simp [← hb]
· exact h₀ _ hb _ _ h
/-- A constructor for `SMulPosReflectLT` requiring you to prove `a₁ • b < a₂ • b → a₁ < a₂` only
when `0 < b` -/
lemma SMulPosReflectLT.of_pos (h₀ : ∀ b : β, 0 < b → ∀ a₁ a₂ : α, a₁ • b < a₂ • b → a₁ < a₂) :
SMulPosReflectLT α β where
lt_of_smul_lt_smul_right b hb a₁ a₂ h := by
obtain hb | hb := hb.eq_or_lt
· simp [← hb] at h
· exact h₀ _ hb _ _ h
end PartialOrder
section PartialOrder
variable [PartialOrder α] [PartialOrder β]
-- See note [lower instance priority]
instance (priority := 100) PosSMulStrictMono.toPosSMulMono [PosSMulStrictMono α β] :
PosSMulMono α β :=
PosSMulMono.of_pos fun _a ha ↦ (strictMono_smul_left_of_pos ha).monotone
-- See note [lower instance priority]
instance (priority := 100) SMulPosStrictMono.toSMulPosMono [SMulPosStrictMono α β] :
SMulPosMono α β :=
SMulPosMono.of_pos fun _b hb ↦ (strictMono_smul_right_of_pos hb).monotone
-- See note [lower instance priority]
instance (priority := 100) PosSMulReflectLE.toPosSMulReflectLT [PosSMulReflectLE α β] :
PosSMulReflectLT α β :=
PosSMulReflectLT.of_pos fun a ha b₁ b₂ h ↦
(le_of_smul_le_smul_of_pos_left h.le ha).lt_of_ne <| by rintro rfl; simp at h
-- See note [lower instance priority]
instance (priority := 100) SMulPosReflectLE.toSMulPosReflectLT [SMulPosReflectLE α β] :
SMulPosReflectLT α β :=
SMulPosReflectLT.of_pos fun b hb a₁ a₂ h ↦
(le_of_smul_le_smul_of_pos_right h.le hb).lt_of_ne <| by rintro rfl; simp at h
-- See note [lower instance priority]
instance (priority := 100) IsStrictOrderedModule.toIsOrderedModule [IsStrictOrderedModule α β] :
IsOrderedModule α β where
lemma smul_eq_smul_iff_eq_and_eq_of_pos [PosSMulStrictMono α β] [SMulPosStrictMono α β]
(ha : a₁ ≤ a₂) (hb : b₁ ≤ b₂) (h₁ : 0 < a₁) (h₂ : 0 < b₂) :
a₁ • b₁ = a₂ • b₂ ↔ a₁ = a₂ ∧ b₁ = b₂ := by
refine ⟨fun h ↦ ?_, by rintro ⟨rfl, rfl⟩; rfl⟩
simp only [eq_iff_le_not_lt, ha, hb, true_and]
refine ⟨fun ha ↦ h.not_lt ?_, fun hb ↦ h.not_lt ?_⟩
· exact (smul_le_smul_of_nonneg_left hb h₁.le).trans_lt (smul_lt_smul_of_pos_right ha h₂)
· exact (smul_lt_smul_of_pos_left hb h₁).trans_le (smul_le_smul_of_nonneg_right ha h₂.le)
lemma smul_eq_smul_iff_eq_and_eq_of_pos' [PosSMulStrictMono α β] [SMulPosStrictMono α β]
(ha : a₁ ≤ a₂) (hb : b₁ ≤ b₂) (h₂ : 0 < a₂) (h₁ : 0 < b₁) :
a₁ • b₁ = a₂ • b₂ ↔ a₁ = a₂ ∧ b₁ = b₂ := by
refine ⟨fun h ↦ ?_, by rintro ⟨rfl, rfl⟩; rfl⟩
simp only [eq_iff_le_not_lt, ha, hb, true_and]
refine ⟨fun ha ↦ h.not_lt ?_, fun hb ↦ h.not_lt ?_⟩
· exact (smul_lt_smul_of_pos_right ha h₁).trans_le (smul_le_smul_of_nonneg_left hb h₂.le)
· exact (smul_le_smul_of_nonneg_right ha h₁.le).trans_lt (smul_lt_smul_of_pos_left hb h₂)
end PartialOrder
section LinearOrder
variable [LinearOrder α] [LinearOrder β]
lemma pos_and_pos_or_neg_and_neg_of_smul_pos [PosSMulMono α β] [SMulPosMono α β] (hab : 0 < a • b) :
0 < a ∧ 0 < b ∨ a < 0 ∧ b < 0 := by
obtain ha | rfl | ha := lt_trichotomy a 0
· refine Or.inr ⟨ha, lt_imp_lt_of_le_imp_le (fun hb ↦ ?_) hab⟩
exact smul_nonpos_of_nonpos_of_nonneg ha.le hb
· rw [zero_smul] at hab
exact hab.false.elim
· refine Or.inl ⟨ha, lt_imp_lt_of_le_imp_le (fun hb ↦ ?_) hab⟩
exact smul_nonpos_of_nonneg_of_nonpos ha.le hb
lemma neg_of_smul_pos_right [PosSMulMono α β] [SMulPosMono α β] (h : 0 < a • b) (ha : a ≤ 0) :
b < 0 := ((pos_and_pos_or_neg_and_neg_of_smul_pos h).resolve_left fun h ↦ h.1.not_ge ha).2
lemma neg_of_smul_pos_left [PosSMulMono α β] [SMulPosMono α β] (h : 0 < a • b) (ha : b ≤ 0) :
a < 0 := ((pos_and_pos_or_neg_and_neg_of_smul_pos h).resolve_left fun h ↦ h.2.not_ge ha).1
lemma neg_iff_neg_of_smul_pos [PosSMulMono α β] [SMulPosMono α β] (hab : 0 < a • b) :
a < 0 ↔ b < 0 :=
⟨neg_of_smul_pos_right hab ∘ le_of_lt, neg_of_smul_pos_left hab ∘ le_of_lt⟩
lemma neg_of_smul_neg_left' [SMulPosMono α β] (h : a • b < 0) (ha : 0 ≤ a) : b < 0 :=
lt_of_not_ge fun hb ↦ (smul_nonneg' ha hb).not_gt h
lemma neg_of_smul_neg_right' [PosSMulMono α β] (h : a • b < 0) (hb : 0 ≤ b) : a < 0 :=
lt_of_not_ge fun ha ↦ (smul_nonneg ha hb).not_gt h
end LinearOrder
end SMulWithZero
section MulAction
variable [Monoid α] [Zero β] [MulAction α β]
section Preorder
variable [Preorder α] [Preorder β]
@[simp]
lemma le_smul_iff_one_le_left [SMulPosMono α β] [SMulPosReflectLE α β] (hb : 0 < b) :
b ≤ a • b ↔ 1 ≤ a := Iff.trans (by rw [one_smul]) (smul_le_smul_iff_of_pos_right hb)
@[simp]
lemma lt_smul_iff_one_lt_left [SMulPosStrictMono α β] [SMulPosReflectLT α β] (hb : 0 < b) :
b < a • b ↔ 1 < a := Iff.trans (by rw [one_smul]) (smul_lt_smul_iff_of_pos_right hb)
@[simp]
lemma smul_le_iff_le_one_left [SMulPosMono α β] [SMulPosReflectLE α β] (hb : 0 < b) :
a • b ≤ b ↔ a ≤ 1 := Iff.trans (by rw [one_smul]) (smul_le_smul_iff_of_pos_right hb)
@[simp]
lemma smul_lt_iff_lt_one_left [SMulPosStrictMono α β] [SMulPosReflectLT α β] (hb : 0 < b) :
a • b < b ↔ a < 1 := Iff.trans (by rw [one_smul]) (smul_lt_smul_iff_of_pos_right hb)
lemma smul_le_of_le_one_left [SMulPosMono α β] (hb : 0 ≤ b) (h : a ≤ 1) : a • b ≤ b := by
simpa only [one_smul] using smul_le_smul_of_nonneg_right h hb
lemma le_smul_of_one_le_left [SMulPosMono α β] (hb : 0 ≤ b) (h : 1 ≤ a) : b ≤ a • b := by
simpa only [one_smul] using smul_le_smul_of_nonneg_right h hb
lemma smul_lt_of_lt_one_left [SMulPosStrictMono α β] (hb : 0 < b) (h : a < 1) : a • b < b := by
simpa only [one_smul] using smul_lt_smul_of_pos_right h hb
lemma lt_smul_of_one_lt_left [SMulPosStrictMono α β] (hb : 0 < b) (h : 1 < a) : b < a • b := by
simpa only [one_smul] using smul_lt_smul_of_pos_right h hb
end Preorder
end MulAction
section Semiring
variable [Semiring α] [AddCommGroup β] [Module α β]
/-- Constructor for `PosSMulMono` when the semimodule is in fact a group. -/
lemma PosSMulMono.of_smul_nonneg [PartialOrder α] [PartialOrder β] [IsOrderedAddMonoid β]
(h : ∀ a : α, 0 ≤ a → ∀ b : β, 0 ≤ b → 0 ≤ a • b) : PosSMulMono α β where
smul_le_smul_of_nonneg_left _a ha b₁ b₂ := by simpa [sub_nonneg, smul_sub] using h _ ha (b₂ - b₁)
variable [IsDomain α] [Module.IsTorsionFree α β]
section PartialOrder
variable [Preorder α] [PartialOrder β]
lemma PosSMulMono.toPosSMulStrictMono [PosSMulMono α β] : PosSMulStrictMono α β :=
⟨fun _a ha _b₁ _b₂ hb ↦ (smul_le_smul_of_nonneg_left hb.le ha.le).lt_of_ne <|
(smul_right_injective _ ha.ne').ne hb.ne⟩
instance PosSMulReflectLT.toPosSMulReflectLE [PosSMulReflectLT α β] : PosSMulReflectLE α β :=
⟨fun _a ha _b₁ _b₂ h ↦ h.eq_or_lt.elim
(fun h ↦ (smul_right_injective _ ha.ne' h).le) fun h' ↦
(lt_of_smul_lt_smul_left h' ha.le).le⟩
end PartialOrder
section PartialOrder
variable [PartialOrder α] [PartialOrder β]
lemma posSMulMono_iff_posSMulStrictMono : PosSMulMono α β ↔ PosSMulStrictMono α β :=
⟨fun _ ↦ PosSMulMono.toPosSMulStrictMono, fun _ ↦ inferInstance⟩
lemma PosSMulReflectLE_iff_posSMulReflectLT : PosSMulReflectLE α β ↔ PosSMulReflectLT α β :=
⟨fun _ ↦ inferInstance, fun _ ↦ PosSMulReflectLT.toPosSMulReflectLE⟩
end PartialOrder
end Semiring
section Ring
variable [Ring α] [AddCommGroup β] [Module α β] [PartialOrder α] [PartialOrder β]
/-- Constructor for `IsOrderedModule` when the semimodule is in fact a module. -/
lemma IsOrderedModule.of_smul_nonneg [IsOrderedAddMonoid α] [IsOrderedAddMonoid β]
(h : ∀ a : α, 0 ≤ a → ∀ b : β, 0 ≤ b → 0 ≤ a • b) : IsOrderedModule α β where
toPosSMulMono := .of_smul_nonneg h
smul_le_smul_of_nonneg_right _b hb a₁ a₂ := by
simpa [sub_nonneg, sub_smul] using (h (a₂ - a₁) · _ hb)
variable [IsDomain α] [Module.IsTorsionFree α β]
lemma SMulPosMono.toSMulPosStrictMono [SMulPosMono α β] : SMulPosStrictMono α β :=
⟨fun _b hb _a₁ _a₂ ha ↦ (smul_le_smul_of_nonneg_right ha.le hb.le).lt_of_ne <|
(smul_left_injective _ hb.ne').ne ha.ne⟩
lemma smulPosMono_iff_smulPosStrictMono : SMulPosMono α β ↔ SMulPosStrictMono α β :=
⟨fun _ ↦ SMulPosMono.toSMulPosStrictMono, fun _ ↦ inferInstance⟩
lemma SMulPosReflectLT.toSMulPosReflectLE [SMulPosReflectLT α β] : SMulPosReflectLE α β :=
⟨fun _b hb _a₁ _a₂ h ↦ h.eq_or_lt.elim (fun h ↦ (smul_left_injective _ hb.ne' h).le) fun h' ↦
(lt_of_smul_lt_smul_right h' hb.le).le⟩
lemma SMulPosReflectLE_iff_smulPosReflectLT : SMulPosReflectLE α β ↔ SMulPosReflectLT α β :=
⟨fun _ ↦ inferInstance, fun _ ↦ SMulPosReflectLT.toSMulPosReflectLE⟩
end Ring
section GroupWithZero
variable [GroupWithZero α] [Preorder α] [Preorder β] [MulAction α β]
lemma inv_smul_le_iff_of_pos [PosSMulMono α β] [PosSMulReflectLE α β] (ha : 0 < a) :
a⁻¹ • b₁ ≤ b₂ ↔ b₁ ≤ a • b₂ := by rw [← smul_le_smul_iff_of_pos_left ha, smul_inv_smul₀ ha.ne']
lemma le_inv_smul_iff_of_pos [PosSMulMono α β] [PosSMulReflectLE α β] (ha : 0 < a) :
b₁ ≤ a⁻¹ • b₂ ↔ a • b₁ ≤ b₂ := by rw [← smul_le_smul_iff_of_pos_left ha, smul_inv_smul₀ ha.ne']
lemma inv_smul_lt_iff_of_pos [PosSMulStrictMono α β] [PosSMulReflectLT α β] (ha : 0 < a) :
a⁻¹ • b₁ < b₂ ↔ b₁ < a • b₂ := by rw [← smul_lt_smul_iff_of_pos_left ha, smul_inv_smul₀ ha.ne']
lemma lt_inv_smul_iff_of_pos [PosSMulStrictMono α β] [PosSMulReflectLT α β] (ha : 0 < a) :
b₁ < a⁻¹ • b₂ ↔ a • b₁ < b₂ := by rw [← smul_lt_smul_iff_of_pos_left ha, smul_inv_smul₀ ha.ne']
/-- Right scalar multiplication as an order isomorphism. -/
@[simps!]
def OrderIso.smulRight [PosSMulMono α β] [PosSMulReflectLE α β] {a : α} (ha : 0 < a) : β ≃o β where
toEquiv := Equiv.smulRight ha.ne'
map_rel_iff' := smul_le_smul_iff_of_pos_left ha
end GroupWithZero
namespace OrderDual
section Left
variable [Preorder α] [Preorder β] [SMul α β] [Zero α]
instance instPosSMulMono [PosSMulMono α β] : PosSMulMono α βᵒᵈ where
smul_le_smul_of_nonneg_left _a ha _b₁ _b₂ hb := smul_le_smul_of_nonneg_left (β := β) hb ha
instance instPosSMulStrictMono [PosSMulStrictMono α β] : PosSMulStrictMono α βᵒᵈ where
smul_lt_smul_of_pos_left _a ha _b₁ _b₂ hb := smul_lt_smul_of_pos_left (β := β) hb ha
instance instPosSMulReflectLT [PosSMulReflectLT α β] : PosSMulReflectLT α βᵒᵈ where
lt_of_smul_lt_smul_left _a ha _b₁ _b₂ h := lt_of_smul_lt_smul_of_nonneg_left (β := β) h ha
instance instPosSMulReflectLE [PosSMulReflectLE α β] : PosSMulReflectLE α βᵒᵈ where
le_of_smul_le_smul_left _a ha _b₁ _b₂ h := le_of_smul_le_smul_of_pos_left (β := β) h ha
end Left
section Right
variable [Preorder α] [Monoid α] [AddCommGroup β] [PartialOrder β] [IsOrderedAddMonoid β]
[DistribMulAction α β]
instance instSMulPosMono [SMulPosMono α β] : SMulPosMono α βᵒᵈ where
smul_le_smul_of_nonneg_right _b hb a₁ a₂ ha := by
rw [← neg_le_neg_iff, ← smul_neg, ← smul_neg]
exact smul_le_smul_of_nonneg_right (β := β) ha <| neg_nonneg.2 hb
instance instSMulPosStrictMono [SMulPosStrictMono α β] : SMulPosStrictMono α βᵒᵈ where
smul_lt_smul_of_pos_right _b hb a₁ a₂ ha := by
rw [← neg_lt_neg_iff, ← smul_neg, ← smul_neg]
exact smul_lt_smul_of_pos_right (β := β) ha <| neg_pos.2 hb
instance instSMulPosReflectLT [SMulPosReflectLT α β] : SMulPosReflectLT α βᵒᵈ where
lt_of_smul_lt_smul_right _b hb a₁ a₂ h := by
rw [← neg_lt_neg_iff, ← smul_neg, ← smul_neg] at h
exact lt_of_smul_lt_smul_right (β := β) h <| neg_nonneg.2 hb
instance instSMulPosReflectLE [SMulPosReflectLE α β] : SMulPosReflectLE α βᵒᵈ where
le_of_smul_le_smul_right _b hb a₁ a₂ h := by
rw [← neg_le_neg_iff, ← smul_neg, ← smul_neg] at h
exact le_of_smul_le_smul_right (β := β) h <| neg_pos.2 hb
end Right
section LeftRight
variable [Preorder α] [MonoidWithZero α] [AddCommGroup β] [PartialOrder β] [IsOrderedAddMonoid β]
[DistribMulAction α β]
instance instIsOrderedModule [IsOrderedModule α β] : IsOrderedModule α βᵒᵈ where
instance instIsStrictOrderedModule [IsStrictOrderedModule α β] : IsStrictOrderedModule α βᵒᵈ where
end LeftRight
end OrderDual
section OrderedAddCommMonoid
variable [Semiring α] [PartialOrder α] [IsStrictOrderedRing α] [ExistsAddOfLE α]
[AddCommMonoid β] [PartialOrder β] [IsOrderedCancelAddMonoid β] [Module α β]
section PosSMulMono