Timings for semirings.v
Require Import
HoTT.Classes.theory.apartness
HoTT.Classes.interfaces.abstract_algebra
HoTT.Classes.interfaces.orders
HoTT.Classes.theory.rings.
Require Export
HoTT.Classes.orders.orders
HoTT.Classes.orders.maps.
Generalizable Variables R Rlt f.
Context `{SemiRingOrder R} `{!IsSemiCRing R}.
(* Add Ring R : (stdlib_semiring_theory R). *)
#[export] Instance plus_le_embed_l : forall (z : R), OrderEmbedding (+z).
exact order_preserving_flip.
exact order_reflecting_flip.
#[export] Instance plus_ordered_cancel_l : forall z, LeftCancellation (+) z.
apply (antisymmetry (≤)); apply (order_reflecting (z+)); apply eq_le;trivial.
#[export] Instance plus_ordered_cancel_r : forall z, RightCancellation (+) z.
apply (right_cancel_from_left (+)).
Lemma nonneg_plus_le_compat_r x z : 0 ≤ z <-> x ≤ x + z.
apply (transport _ (plus_0_r x)).
apply (order_preserving _).
apply (order_reflecting (x+)).
Lemma nonneg_plus_le_compat_l x z : 0 ≤ z <-> x ≤ z + x.
rewrite (commutativity (f:=plus)).
apply nonneg_plus_le_compat_r.
Lemma plus_le_compat x₁ y₁ x₂ y₂ : x₁ ≤ y₁ -> x₂ ≤ y₂ -> x₁ + x₂ ≤ y₁ + y₂.
apply (order_preserving (+ x₂));trivial.
apply (order_preserving (y₁ +));trivial.
Lemma plus_le_compat_r x y z : 0 ≤ z -> x ≤ y -> x ≤ y + z.
apply plus_le_compat;trivial.
Lemma plus_le_compat_l x y z : 0 ≤ z -> x ≤ y -> x ≤ z + y.
rewrite (commutativity (f:=plus)).
Lemma nonpos_plus_compat x y : x ≤ 0 -> y ≤ 0 -> x + y ≤ 0.
apply plus_le_compat;trivial.
Instance nonneg_plus_compat (x y : R)
: PropHolds (0 ≤ x) -> PropHolds (0 ≤ y) -> PropHolds (0 ≤ x + y).
apply plus_le_compat_l;trivial.
Lemma decompose_le {x y} : x ≤ y -> exists z, 0 ≤ z /\ y = x + z.
destruct (srorder_partial_minus x y E) as [z Ez].
apply (order_reflecting (x+)).
Lemma compose_le x y z : 0 ≤ z -> y = x + z -> x ≤ y.
apply nonneg_plus_le_compat_r.
#[export] Instance nonneg_mult_le_l : forall (z : R), PropHolds (0 ≤ z) ->
OrderPreserving (z *.).
repeat (split; try exact _).
destruct (decompose_le F) as [a [Ea1 Ea2]].
rewrite Ea2, plus_mult_distr_l.
apply nonneg_plus_le_compat_r.
apply nonneg_mult_compat;trivial.
#[export] Instance nonneg_mult_le_r : forall (z : R), PropHolds (0 ≤ z) ->
OrderPreserving (.* z).
exact order_preserving_flip.
Lemma mult_le_compat x₁ y₁ x₂ y₂ :
0 ≤ x₁ -> 0 ≤ x₂ -> x₁ ≤ y₁ -> x₂ ≤ y₂ -> x₁ * x₂ ≤ y₁ * y₂.
apply (order_preserving_flip_nonneg (.*.) x₂);trivial.
apply (order_preserving_nonneg (.*.) y₁); [| trivial].
Lemma ge_1_mult_le_compat_r x y z : 1 ≤ z -> 0 ≤ y -> x ≤ y -> x ≤ y * z.
transitivity y; [trivial |].
pattern y at 1;apply (transport _ (mult_1_r y)).
apply (order_preserving_nonneg (.*.) y);trivial.
Lemma ge_1_mult_le_compat_l x y z : 1 ≤ z -> 0 ≤ y -> x ≤ y -> x ≤ z * y.
rewrite (commutativity (f:=mult)).
apply ge_1_mult_le_compat_r.
Lemma flip_nonpos_mult_l x y z : z ≤ 0 -> x ≤ y -> z * y ≤ z * x.
destruct (decompose_le Ez) as [a [Ea1 Ea2]], (decompose_le Exy) as [b [Eb1 Eb2]].
apply compose_le with (a * b).
apply nonneg_mult_compat;trivial.
transitivity (z * x + (z + a) * b).
rewrite mult_0_l,plus_0_r.
rewrite plus_mult_distr_r,plus_mult_distr_l.
Lemma flip_nonpos_mult_r x y z : z ≤ 0 -> x ≤ y -> y * z ≤ x * z.
rewrite 2!(commutativity _ z).
apply flip_nonpos_mult_l.
Lemma nonpos_mult x y : x ≤ 0 -> y ≤ 0 -> 0 ≤ x * y.
apply flip_nonpos_mult_l;trivial.
Lemma nonpos_nonneg_mult x y : x ≤ 0 -> 0 ≤ y -> x * y ≤ 0.
apply flip_nonpos_mult_l;trivial.
Lemma nonneg_nonpos_mult x y : 0 ≤ x -> y ≤ 0 -> x * y ≤ 0.
rewrite (commutativity (f:=mult)).
apply nonpos_nonneg_mult;trivial.
#[export]
Hint Extern 7 (PropHolds (0 ≤ _ + _)) =>
eapply @nonneg_plus_compat : typeclass_instances.
Section strict_semiring_order.
Context `{IsSemiCRing R} `{!StrictSemiRingOrder Rlt}.
(* Add Ring Rs : (stdlib_semiring_theory R). *)
#[export] Instance plus_lt_embed : forall (z : R), StrictOrderEmbedding (+z).
exact strictly_order_preserving_flip.
exact strictly_order_reflecting_flip.
Lemma pos_plus_lt_compat_r x z : 0 < z <-> x < x + z.
pattern x at 1;apply (transport _ (plus_0_r x)).
apply (strictly_order_preserving _);trivial.
apply (strictly_order_reflecting (x+));trivial.
Lemma pos_plus_lt_compat_l x z : 0 < z -> x < z + x.
rewrite (commutativity (f:=plus)).
apply pos_plus_lt_compat_r.
Lemma plus_lt_compat x₁ y₁ x₂ y₂ : x₁ < y₁ -> x₂ < y₂ -> x₁ + x₂ < y₁ + y₂.
apply (strictly_order_preserving (+ x₂));trivial.
apply (strictly_order_preserving (y₁ +));trivial.
Lemma plus_lt_compat_r x y z : 0 < z -> x < y -> x < y + z.
apply plus_lt_compat;trivial.
Lemma plus_lt_compat_l x y z : 0 < z -> x < y -> x < z + y.
rewrite (commutativity (f:=plus)).
Lemma neg_plus_compat x y : x < 0 -> y < 0 -> x + y < 0.
apply plus_lt_compat;trivial.
Instance pos_plus_compat (x y : R)
: PropHolds (0 < x) -> PropHolds (0 < y) -> PropHolds (0 < x + y).
apply plus_lt_compat_l;trivial.
Lemma compose_lt x y z : 0 < z -> y = x + z -> x < y.
apply pos_plus_lt_compat_r;trivial.
Lemma decompose_lt {x y} : x < y -> exists z, 0 < z /\ y = x + z.
destruct (strict_srorder_partial_minus x y E) as [z Ez].
apply (strictly_order_reflecting (x+)).
rewrite <-Ez, rings.plus_0_r.
#[export] Instance pos_mult_lt_l : forall (z : R), PropHolds (0 < z) ->
StrictlyOrderPreserving (z *.).
destruct (decompose_lt F) as [a [Ea1 Ea2]].
rewrite Ea2, plus_mult_distr_l.
apply pos_plus_lt_compat_r.
apply pos_mult_compat;trivial.
#[export] Instance pos_mult_lt_r : forall (z : R), PropHolds (0 < z) ->
StrictlyOrderPreserving (.* z).
exact strictly_order_preserving_flip.
Lemma mult_lt_compat x₁ y₁ x₂ y₂ :
0 < x₁ -> 0 < x₂ -> x₁ < y₁ -> x₂ < y₂ -> x₁ * x₂ < y₁ * y₂.
apply (strictly_order_preserving_flip_pos (.*.) x₂);trivial.
apply (strictly_order_preserving_pos (.*.) y₁); [| trivial ].
Lemma gt_1_mult_lt_compat_r x y z : 1 < z -> 0 < y -> x < y -> x < y * z.
transitivity y; [ trivial |].
pattern y at 1;apply (transport _ (mult_1_r y)).
apply (strictly_order_preserving_pos (.*.) y);trivial.
Lemma gt_1_mult_lt_compat_l x y z : 1 < z -> 0 < y -> x < y -> x < z * y.
rewrite (commutativity (f:=mult)).
apply gt_1_mult_lt_compat_r.
Lemma flip_neg_mult_l x y z : z < 0 -> x < y -> z * y < z * x.
destruct (decompose_lt Ez) as [a [Ea1 Ea2]], (decompose_lt Exy) as [b [Eb1 Eb2]].
apply compose_lt with (a * b).
apply pos_mult_compat;trivial.
transitivity (z * x + (z + a) * b).
rewrite mult_0_l,plus_0_r;reflexivity.
rewrite plus_mult_distr_r,plus_mult_distr_l.
Lemma flip_neg_mult_r x y z : z < 0 -> x < y -> y * z < x * z.
rewrite 2!(commutativity _ z).
Lemma neg_mult x y : x < 0 -> y < 0 -> 0 < x * y.
apply flip_neg_mult_l;trivial.
Lemma pos_mult x y : 0 < x -> 0 < y -> 0 < x * y.
apply (pos_mult_lt_l); assumption.
Lemma neg_pos_mult x y : x < 0 -> 0 < y -> x * y < 0.
apply flip_neg_mult_l;trivial.
Lemma pos_neg_mult x y : 0 < x -> y < 0 -> x * y < 0.
rewrite (commutativity (f:=mult)).
apply neg_pos_mult;trivial.
End strict_semiring_order.
#[export]
Hint Extern 7 (PropHolds (0 < _ + _)) =>
eapply @pos_plus_compat : typeclass_instances.
Section pseudo_semiring_order.
Context `{PseudoSemiRingOrder R} `{!IsSemiCRing R}.
(* Add Ring Rp : (stdlib_semiring_theory R). *)
Local Existing Instance pseudo_order_apart.
#[export] Instance pseudosrorder_strictsrorder : StrictSemiRingOrder (_ : Lt R).
apply pseudo_srorder_partial_minus, lt_flip.
exact pseudo_srorder_pos_mult_compat.
#[export] Instance plus_strong_ext : StrongBinaryExtensionality (+).
assert (forall z, StrongExtensionality (z +)).
exact pseudo_order_embedding_ext.
exact apartness.strong_binary_setoid_morphism_commutative.
#[export] Instance plus_strong_cancel_l
: forall z, StrongLeftCancellation (+) z.
apply apart_iff_total_lt in E;apply apart_iff_total_lt.
destruct E; [left | right]; apply (strictly_order_preserving (z +));trivial.
#[export] Instance plus_strong_cancel_r
: forall z, StrongRightCancellation (+) z.
exact (strong_right_cancel_from_left (+)).
Lemma neg_mult_decompose x y : x * y < 0 -> (x < 0 /\ 0 < y) |_| (0 < x /\ y < 0).
assert (0 ≶ x) as Ex;[|assert (apart 0 y) as Ey].
apply (strong_extensionality (.* y)).
apply pseudo_order_lt_apart_flip;trivial.
apply (strong_extensionality (x *.)).
apply pseudo_order_lt_apart_flip;trivial.
apply apart_iff_total_lt in Ex;apply apart_iff_total_lt in Ey.
destruct Ex as [Ex|Ex], Ey as [Ey|Ey]; try auto.
destruct (irreflexivity (<) 0).
transitivity (x * y); [| trivial].
apply pos_mult_compat;trivial.
destruct (irreflexivity (<) 0).
transitivity (x * y); [| trivial].
Lemma pos_mult_decompose x y : 0 < x * y -> (0 < x /\ 0 < y) |_| (x < 0 /\ y < 0).
assert (0 ≶ x /\ apart 0 y) as [Ex Ey];[split|].
apply (strong_extensionality (.* y)).
apply pseudo_order_lt_apart;trivial.
apply (strong_extensionality (x *.)).
apply pseudo_order_lt_apart;trivial.
apply apart_iff_total_lt in Ex;apply apart_iff_total_lt in Ey.
destruct Ex as [Ex|Ex], Ey as [Ey|Ey]; try auto.
destruct (irreflexivity (<) 0).
transitivity (x * y); [trivial |].
apply pos_neg_mult;trivial.
destruct (irreflexivity (<) 0).
transitivity (x * y); [trivial |].
apply neg_pos_mult;trivial.
#[export] Instance pos_mult_reflect_l
: forall (z : R), PropHolds (0 < z) -> StrictlyOrderReflecting (z *.).
apply not_lt_apart_lt_flip.
apply (strictly_order_preserving (z *.));trivial.
apply (strong_extensionality (z *.)).
apply pseudo_order_lt_apart_flip;trivial.
#[export] Instance pos_mult_reflect_r
: forall (z : R), PropHolds (0 < z) -> StrictlyOrderReflecting (.* z).
exact strictly_order_reflecting_flip.
#[export] Instance apartzero_mult_strong_cancel_l
: forall z, PropHolds (z ≶ 0) -> StrongLeftCancellation (.*.) z.
apply apart_iff_total_lt in E;apply apart_iff_total_lt in Ez;
apply apart_iff_total_lt.
destruct E as [E|E], Ez as [Ez|Ez].
apply flip_neg_mult_l;trivial.
apply (strictly_order_preserving_pos (.*.) z);trivial.
apply flip_neg_mult_l;trivial.
apply (strictly_order_preserving_pos (.*.) z);trivial.
#[export] Instance apartzero_mult_strong_cancel_r
: forall z, PropHolds (z ≶ 0) -> StrongRightCancellation (.*.) z.
exact (strong_right_cancel_from_left (.*.)).
#[export] Instance apartzero_mult_cancel_l
: forall z, PropHolds (z ≶ 0) -> LeftCancellation (.*.) z.
#[export] Instance apartzero_mult_cancel_r
: forall z, PropHolds (z ≶ 0) -> RightCancellation (.*.) z.
Lemma square_pos x : x ≶ 0 -> 0 < x * x.
apply apart_iff_total_lt in E.
destruct (decompose_lt E) as [z [Ez1 Ez2]].
apply compose_lt with (z * z).
apply pos_mult_compat;trivial.
apply (left_cancellation (+) (x * z)).
rewrite <-plus_mult_distr_r, <-plus_mult_distr_l.
rewrite (commutativity (f:=plus) z x), <-!Ez2.
rewrite mult_0_l,mult_0_r.
apply pos_mult_compat;trivial.
Lemma pos_mult_rev_l x y : 0 < x * y -> 0 < y -> 0 < x.
apply (strictly_order_reflecting (.* y)).
rewrite rings.mult_0_l;trivial.
Lemma pos_mult_rev_r x y : 0 < x * y -> 0 < x -> 0 < y.
apply pos_mult_rev_l with x.
rewrite (commutativity (f:=mult));trivial.
Context `{PropHolds (1 ≶ 0)}.
Instance lt_0_1 : PropHolds (0 < 1).
apply square_pos;trivial.
Instance lt_0_2 : PropHolds (0 < 2).
Instance lt_0_3 : PropHolds (0 < 3).
Instance lt_0_4 : PropHolds (0 < 4).
apply pos_plus_lt_compat_r, lt_0_1.
apply pos_plus_lt_compat_r, lt_0_2.
apply pos_plus_lt_compat_r, lt_0_3.
apply (strictly_order_preserving (1+)), lt_1_2.
apply (strictly_order_preserving (1+)), lt_1_3.
apply (strictly_order_preserving (1+)), lt_2_3.
Instance apart_0_2 : PropHolds (2 ≶ 0).
apply pseudo_order_lt_apart, lt_0_2.
End pseudo_semiring_order.
#[export]
Hint Extern 7 (PropHolds (0 < 1)) => eapply @lt_0_1 : typeclass_instances.
#[export]
Hint Extern 7 (PropHolds (0 < 2)) => eapply @lt_0_2 : typeclass_instances.
#[export]
Hint Extern 7 (PropHolds (0 < 3)) => eapply @lt_0_3 : typeclass_instances.
#[export]
Hint Extern 7 (PropHolds (0 < 4)) => eapply @lt_0_4 : typeclass_instances.
#[export]
Hint Extern 7 (PropHolds (2 ≶ 0)) => eapply @apart_0_2 : typeclass_instances.
Section full_pseudo_semiring_order.
Context `{FullPseudoSemiRingOrder R} `{!IsSemiCRing R}.
(* Add Ring Rf : (stdlib_semiring_theory R). *)
#[export] Instance fullpseudosrorder_fullpseudoorder
: FullPseudoOrder (_ : Le R) (_ : Lt R).
exact full_pseudo_srorder_le_iff_not_lt_flip.
#[export] Instance fullpseudosrorder_srorder : SemiRingOrder (_ : Le R).
apply le_iff_not_lt_flip in E.
apply pseudo_srorder_partial_minus;trivial.
repeat (split; try exact _).
apply le_iff_not_lt_flip in E1;apply le_iff_not_lt_flip.
apply (strictly_order_reflecting (z+)).
apply le_iff_not_lt_flip in E1;apply le_iff_not_lt_flip.
apply (strictly_order_preserving _);trivial.
apply le_iff_not_lt_flip in Ex;apply le_iff_not_lt_flip in Ey;
apply le_iff_not_lt_flip.
destruct (neg_mult_decompose x y E) as [[? ?]|[? ?]];auto.
#[export] Instance orderreflecting_left_mult : forall (z : R), PropHolds (0 < z) -> OrderReflecting (z *.).
exact full_pseudo_order_reflecting.
#[export] Instance orderreflecting_right_mult : forall (z : R), PropHolds (0 < z) -> OrderReflecting (.* z).
exact order_reflecting_flip.
Lemma plus_lt_le_compat x₁ y₁ x₂ y₂ : x₁ < y₁ -> x₂ ≤ y₂ -> x₁ + x₂ < y₁ + y₂.
apply lt_le_trans with (y₁ + x₂).
apply (strictly_order_preserving (+ x₂));trivial.
apply (order_preserving (y₁ +));trivial.
Lemma plus_le_lt_compat x₁ y₁ x₂ y₂ : x₁ ≤ y₁ -> x₂ < y₂ -> x₁ + x₂ < y₁ + y₂.
apply le_lt_trans with (y₁ + x₂).
apply (order_preserving (+ x₂));trivial.
apply (strictly_order_preserving (y₁ +));trivial.
Lemma nonneg_plus_lt_compat_r x y z : 0 ≤ z -> x < y -> x < y + z.
apply plus_lt_le_compat;trivial.
Lemma nonneg_plus_lt_compat_l x y z : 0 ≤ z -> x < y -> x < z + y.
rewrite (commutativity (f:=plus)).
apply nonneg_plus_lt_compat_r;trivial.
Lemma pos_plus_le_lt_compat_r x y z : 0 < z -> x ≤ y -> x < y + z.
apply plus_le_lt_compat;trivial.
Lemma pos_plus_le_lt_compat_l x y z : 0 < z -> x ≤ y -> x < z + y.
rewrite (commutativity (f:=plus)).
apply pos_plus_le_lt_compat_r;trivial.
Lemma square_nonneg x : 0 ≤ x * x.
destruct (lt_antisym (x * x) 0).
pose proof pseudo_order_apart.
apply (strong_extensionality (x *.)).
Lemma nonneg_mult_rev_l x y : 0 ≤ x * y -> 0 < y -> 0 ≤ x.
apply (order_reflecting (.* y)).
Lemma nonneg_mult_rev_r x y : 0 ≤ x * y -> 0 < x -> 0 ≤ y.
apply nonneg_mult_rev_l with x.
rewrite (commutativity (f:=mult)).
Instance le_0_1 : PropHolds (0 ≤ 1).
Instance le_0_2 : PropHolds (0 ≤ 2).
Instance le_0_3 : PropHolds (0 ≤ 3).
Instance le_0_4 : PropHolds (0 ≤ 4).
apply nonneg_plus_le_compat_r, le_0_1.
apply nonneg_plus_le_compat_r, le_0_2.
apply nonneg_plus_le_compat_r, le_0_3.
apply (order_preserving (1+)), le_1_2.
apply (order_preserving (1+)), le_1_3.
apply (order_preserving (1+)), le_2_3.
Lemma ge_1_mult_compat x y : 1 ≤ x -> 1 ≤ y -> 1 ≤ x * y.
apply ge_1_mult_le_compat_r; trivial.
Lemma gt_1_ge_1_mult_compat x y : 1 < x -> 1 ≤ y -> 1 < x * y.
apply lt_le_trans with x; trivial.
apply ge_1_mult_le_compat_r;[trivial| |apply reflexivity].
Lemma ge_1_gt_1_mult_compat x y : 1 ≤ x -> 1 < y -> 1 < x * y.
rewrite (commutativity (f:=mult)).
apply gt_1_ge_1_mult_compat;trivial.
Lemma pos_mult_le_lt_compat : forall a b c d, 0 <= a /\ a <= b -> 0 < b ->
0 <= c /\ c < d ->
a * c < b * d.
intros a b c d [E1 E2] E3 [E4 E5] .
apply le_lt_trans with (b * c).
apply mult_le_compat;auto.
apply (strictly_order_preserving (b *.)).
Context `{PropHolds (1 ≶ 0)}.
Lemma not_le_1_0 : ~(1 ≤ 0).
apply lt_not_le_flip, lt_0_1.
Lemma not_le_2_0 : ~(2 ≤ 0).
apply lt_not_le_flip, lt_0_2.
Lemma repeat_nat_nonneg : forall n, 0 <= Core.nat_iter n (plus 1) 0.
apply nonneg_plus_compat.
Lemma repeat_nat_pos : forall n, 0 < Core.nat_iter (S n) (plus 1) 0.
apply pos_plus_le_lt_compat_l.
Local Existing Instance pseudo_order_apart.
#[export] Instance ordered_characteristic_0 : FieldCharacteristic R 0.
intros E';apply (irreflexivity _) in E';destruct E'.
intros _;apply apart_iff_total_lt;right;apply repeat_nat_pos.
apply (ap (fun n => match n with | S _ => Unit | _ => Empty end)) in E;
simpl in E.
End full_pseudo_semiring_order.
#[export]
Hint Extern 7 (PropHolds (0 ≤ 1)) => eapply @le_0_1 : typeclass_instances.
#[export]
Hint Extern 7 (PropHolds (0 ≤ 2)) => eapply @le_0_2 : typeclass_instances.
#[export]
Hint Extern 7 (PropHolds (0 ≤ 3)) => eapply @le_0_3 : typeclass_instances.
#[export]
Hint Extern 7 (PropHolds (0 ≤ 4)) => eapply @le_0_4 : typeclass_instances.
Section dec_semiring_order.
(* Maybe these assumptions can be weakened? *)
Context `{SemiRingOrder R} `{Apart R} `{!TrivialApart R}
`{!NoZeroDivisors R} `{!TotalRelation (≤)} `{DecidablePaths R}.
Context `{Rlt : Lt R} `{is_mere_relation R lt}
(lt_correct : forall x y, x < y <-> x ≤ y /\ x <> y).
Instance dec_srorder_fullpseudo
: FullPseudoOrder _ _ := dec_full_pseudo_order lt_correct.
Local Existing Instance pseudo_order_apart.
Instance dec_pseudo_srorder: PseudoSemiRingOrder (<).
apply srorder_partial_minus, not_lt_le_flip;trivial.
repeat (split; try exact _).
apply lt_correct in E;apply lt_correct.
apply (order_preserving (z+));trivial.
apply (left_cancellation (+) z);trivial.
exact (apartness.dec_strong_binary_morphism (.*.)).
apply lt_correct in E1;apply lt_correct in E2;apply lt_correct.
destruct E1 as [E1a E1b], E2 as [E2a E2b].
apply nonneg_mult_compat;trivial.
apply mult_ne_0; apply symmetric_neq;trivial.
Instance dec_full_pseudo_srorder: FullPseudoSemiRingOrder (≤) (<).
exact le_iff_not_lt_flip.
Section another_semiring.
Context `{SemiRingOrder R1}.
Lemma projected_srorder `{IsSemiCRing R2} `{R2le : Le R2}
`{is_mere_relation R2 R2le} (f : R2 -> R1)
`{!IsSemiRingPreserving f} `{!IsInjective f}
: (forall x y, x ≤ y <-> f x ≤ f y) -> (forall x y : R2, x ≤ y -> exists z, y = x + z) ->
SemiRingOrder R2le.
pose proof (projected_partial_order f P).
repeat (split; try exact _).
rewrite 2!(preserves_plus (f:=f)).
apply (order_preserving _), P.
apply (order_reflecting (f z +)).
rewrite <-2!preserves_plus.
rewrite preserves_mult, preserves_0.
apply nonneg_mult_compat; rewrite <-(preserves_0 (f:=f)); apply P;trivial.
Context `{!IsSemiCRing R1} `{SemiRingOrder R2} `{!IsSemiCRing R2}
`{!IsSemiRingPreserving (f : R1 -> R2)}.
(* If a morphism agrees on the positive cone then it is order preserving *)
Lemma preserving_preserves_nonneg : (forall x, 0 ≤ x -> 0 ≤ f x) -> OrderPreserving f.
repeat (split; try exact _).
destruct (decompose_le F) as [z [Ez1 Ez2]].
apply compose_le with (f z).
rewrite Ez2, (preserves_plus (f:=f)).
Instance preserves_nonneg `{!OrderPreserving f} x
: PropHolds (0 ≤ x) -> PropHolds (0 ≤ f x).
rewrite <-(preserves_0 (f:=f)).
apply (order_preserving f);trivial.
Lemma preserves_nonpos `{!OrderPreserving f} x : x ≤ 0 -> f x ≤ 0.
rewrite <-(preserves_0 (f:=f)).
apply (order_preserving f);trivial.
Lemma preserves_ge_1 `{!OrderPreserving f} x : 1 ≤ x -> 1 ≤ f x.
rewrite <-(preserves_1 (f:=f)).
apply (order_preserving f);trivial.
Lemma preserves_le_1 `{!OrderPreserving f} x : x ≤ 1 -> f x ≤ 1.
rewrite <-(preserves_1 (f:=f)).
apply (order_preserving f);trivial.
Section another_semiring_strict.
Context `{StrictSemiRingOrder R1} `{StrictSemiRingOrder R2}
`{!IsSemiCRing R1} `{!IsSemiCRing R2}
`{!IsSemiRingPreserving (f : R1 -> R2)}.
Lemma strictly_preserving_preserves_pos
: (forall x, 0 < x -> 0 < f x) -> StrictlyOrderPreserving f.
repeat (split; try exact _).
destruct (decompose_lt F) as [z [Ez1 Ez2]].
apply compose_lt with (f z).
rewrite Ez2, (preserves_plus (f:=f)).
Instance preserves_pos `{!StrictlyOrderPreserving f} x
: PropHolds (0 < x) -> PropHolds (0 < f x).
rewrite <-(preserves_0 (f:=f)).
apply (strictly_order_preserving f);trivial.
Lemma preserves_neg `{!StrictlyOrderPreserving f} x
: x < 0 -> f x < 0.
rewrite <-(preserves_0 (f:=f)).
apply (strictly_order_preserving f);trivial.
Lemma preserves_gt_1 `{!StrictlyOrderPreserving f} x
: 1 < x -> 1 < f x.
rewrite <-(preserves_1 (f:=f)).
apply (strictly_order_preserving f);trivial.
Lemma preserves_lt_1 `{!StrictlyOrderPreserving f} x
: x < 1 -> f x < 1.
rewrite <-(preserves_1 (f:=f)).
apply (strictly_order_preserving f);trivial.
End another_semiring_strict.
#[export]
Hint Extern 15 (PropHolds (_ ≤ _ _)) =>
eapply @preserves_nonneg : typeclass_instances.
#[export]
Hint Extern 15 (PropHolds (_ < _ _)) =>
eapply @preserves_pos : typeclass_instances.
(* Oddly enough, the above hints do not work for goals of the following shape? *)
#[export]
Hint Extern 15 (PropHolds (_ ≤ '_)) =>
eapply @preserves_nonneg : typeclass_instances.
#[export]
Hint Extern 15 (PropHolds (_ < '_)) =>
eapply @preserves_pos : typeclass_instances.