Timings for rings.v
Require Import
HoTT.Classes.theory.groups
HoTT.Classes.theory.apartness.
Require Import
HoTT.Classes.interfaces.abstract_algebra.
Generalizable Variables R A B C f z.
Definition is_ne_0 `(x : R) `{Zero R} `{p : PropHolds (x <> 0)}
: x <> 0 := p.
Definition is_nonneg `(x : R) `{Le R} `{Zero R} `{p : PropHolds (0 ≤ x)}
: 0 ≤ x := p.
Definition is_pos `(x : R) `{Lt R} `{Zero R} `{p : PropHolds (0 < x)}
: 0 < x := p.
(* Lemma stdlib_semiring_theory R `{SemiRing R}
: Ring_theory.semi_ring_theory 0 1 (+) (.*.) (=).
Proof.
Qed.
*)
(* We cannot apply [left_cancellation (.*.) z] directly in case we have
no [PropHolds (0 <> z)] instance in the context. *)
Context `(op : A -> A -> A) `{!Zero A}.
Lemma left_cancellation_ne_0
`{forall z, PropHolds (z <> 0) -> LeftCancellation op z} z
: z <> 0 -> LeftCancellation op z.
Lemma right_cancellation_ne_0
`{forall z, PropHolds (z <> 0) -> RightCancellation op z} z
: z <> 0 -> RightCancellation op z.
Lemma right_cancel_from_left `{!Commutative op} `{!LeftCancellation op z}
: RightCancellation op z.
apply (left_cancellation op z).
rewrite 2!(commutativity (f:=op) z _).
Section strong_cancellation.
Context `{IsApart A} (op : A -> A -> A).
Lemma strong_right_cancel_from_left `{!Commutative op}
`{!StrongLeftCancellation op z}
: StrongRightCancellation op z.
rewrite 2!(commutativity _ z).
apply (strong_left_cancellation op z);trivial.
#[export] Instance strong_left_cancellation_cancel `{!StrongLeftCancellation op z}
: LeftCancellation op z | 20.
apply tight_apart in E1;apply tight_apart;intros E2.
apply (strong_left_cancellation op);trivial.
#[export] Instance strong_right_cancellation_cancel `{!StrongRightCancellation op z}
: RightCancellation op z | 20.
apply tight_apart in E1;apply tight_apart;intros E2.
apply (strong_right_cancellation op);trivial.
Context `{IsSemiCRing R}.
(* Add Ring SR : (stdlib_semiring_theory R). *)
Instance mult_ne_0 `{!NoZeroDivisors R} x y
: PropHolds (x <> 0) -> PropHolds (y <> 0) -> PropHolds (x * y <> 0).
apply (no_zero_divisors x); split; eauto.
#[export] Instance plus_0_r: RightIdentity (+) 0 := right_identity.
#[export] Instance plus_0_l: LeftIdentity (+) 0 := left_identity.
#[export] Instance mult_1_l: LeftIdentity (.*.) 1 := left_identity.
#[export] Instance mult_1_r: RightIdentity (.*.) 1 := right_identity.
#[export] Instance plus_assoc: Associative (+) := simple_associativity.
#[export] Instance mult_assoc: Associative (.*.) := simple_associativity.
#[export] Instance plus_comm: Commutative (+) := commutativity.
#[export] Instance mult_comm: Commutative (.*.) := commutativity.
#[export] Instance mult_0_l: LeftAbsorb (.*.) 0 := left_absorb.
#[export] Instance mult_0_r: RightAbsorb (.*.) 0.
#[export] Instance plus_mult_distr_r : RightDistribute (.*.) (+).
etransitivity;[|etransitivity].
apply ap011;apply mult_comm.
Lemma plus_mult_distr_l : LeftDistribute (.*.) (+).
#[export] Instance: forall r : R, @IsMonoidPreserving R R (+) (+) 0 0 (r *.).
repeat (constructor; try exact _).
#[export]
Hint Extern 3 (PropHolds (_ * _ <> 0)) => eapply @mult_ne_0 : typeclass_instances.
Section semiringmor_props.
Context `{IsSemiRingPreserving A B f}.
Lemma preserves_0: f 0 = 0.
exact preserves_mon_unit.
Lemma preserves_1: f 1 = 1.
exact preserves_mon_unit.
Lemma preserves_mult: forall x y, f (x * y) = f x * f y.
Lemma preserves_plus: forall x y, f (x + y) = f x + f y.
Lemma preserves_2: f 2 = 2.
Lemma preserves_3: f 3 = 3.
rewrite ?preserves_plus, ?preserves_1.
Lemma preserves_4: f 4 = 4.
rewrite ?preserves_plus, ?preserves_1.
Context `{!IsInjective f}.
Instance isinjective_ne_0 x : PropHolds (x <> 0) -> PropHolds (f x <> 0).
Lemma injective_ne_1 x : x <> 1 -> f x <> 1.
#[export]
Hint Extern 12 (PropHolds (_ _ <> 0)) =>
eapply @isinjective_ne_0 : typeclass_instances.
(* Lemma stdlib_ring_theory R `{Ring R} :
Ring_theory.ring_theory 0 1 (+) (.*.) (fun x y => x - y) (-) (=).
Proof.
Qed.
*)
Instance: LeftAbsorb (.*.) 0.
rewrite (commutativity (f:=(.*.)) 0).
apply (left_cancellation (+) (y * 0)).
path_via (y * 0);[|apply symmetry, right_identity].
apply symmetry,distribute_l.
#[export] Instance CRing_Semi: IsSemiCRing R.
repeat (constructor; try exact _).
#[export] Instance mult_left_absorb : LeftAbsorb (.*.) 0.
rapply (right_cancellation (+) (0 * y)).
lhs_V rapply simple_distribute_r.
rhs rapply left_identity.
#[export] Instance mult_right_absorb : RightAbsorb (.*.) 0.
rapply (right_cancellation (+) (x * 0)).
lhs_V rapply simple_distribute_l.
rhs rapply left_identity.
(** This hint helps other results go through. We do it in two steps, since if we specify the type [IsGroup R], Coq infers the wrong implicit arguments to [IsGroup]. *)
Definition isgroup_ring := abgroup_group R.
#[export] Existing Instance isgroup_ring.
#[export] Instance negate_involutive : Involutive (-) := inverse_involutive.
(* alias for convenience *)
#[export] Instance plus_negate_r : RightInverse (+) (-) 0.
#[export] Instance plus_negate_l : LeftInverse (+) (-) 0.
Lemma negate_swap_r : forall x y, x - y = -(y - x).
lhs rapply groups.inverse_sg_op.
Lemma negate_swap_l x y : -x + y = -(x - y).
rhs_V rapply negate_swap_r.
#[export] Instance isinj_ring_neg : IsInjective (-)
:= groups.isinj_group_inverse.
Lemma negate_plus_distr : forall x y, -(x + y) = -x + -y.
exact groups.negate_sg_op_distr.
Lemma negate_mult_l x : -x = - 1 * x.
apply (left_cancellation (+) x).
path_via (1 * x + (- 1) * x).
rhs_V rapply distribute_r.
rhs_V exact (left_absorb x).
apply ap011;try reflexivity.
Lemma negate_mult_r x : -x = x * -1.
apply (right_cancellation (+) x).
transitivity (x * -1 + x * 1).
rhs_V rapply simple_distribute_l.
lhs_V exact (right_absorb x).
Lemma negate_mult_distr_l x y : -(x * y) = -x * y.
lhs napply negate_mult_l.
lhs exact (simple_associativity (f := (.*.)) (-1) x y).
Lemma negate_mult_distr_r x y : -(x * y) = x * -y.
lhs napply negate_mult_r.
lhs_V rapply (simple_associativity (f := (.*.)) x y).
Lemma negate_mult_negate x y : -x * -y = x * y.
rewrite <-negate_mult_distr_l, <-negate_mult_distr_r.
exact groups.inverse_mon_unit.
#[export] Instance minus_0_r: RightIdentity (fun x y => x - y) 0.
intro x; rewrite negate_0.
Lemma equal_by_zero_sum x y : x - y = 0 <-> x = y.
rewrite <- (left_identity y).
change (sg_op ?x ?y) with (0 + y).
rewrite <-simple_associativity.
apply symmetry,right_identity.
Lemma flip_negate x y : -x = y <-> x = -y.
Lemma flip_negate_0 x : -x = 0 <-> x = 0.
Lemma flip_negate_ne_0 x : -x <> 0 <-> x <> 0.
split; intros E ?; apply E; apply flip_negate_0;trivial.
Lemma negate_zero_prod_l x y : -x * y = 0 <-> x * y = 0.
rewrite negate_mult_distr_l, negate_0.
rewrite negate_mult_distr_l, negate_involutive, negate_0.
Lemma negate_zero_prod_r x y : x * -y = 0 <-> x * y = 0.
2: apply negate_zero_prod_l.
lhs_V napply negate_mult_distr_l.
lhs napply negate_mult_distr_r.
lhs_V napply negate_mult_distr_r.
lhs napply negate_mult_distr_l.
Context `{!NoZeroDivisors R} `{forall x y:R, Stable (x = y)}.
#[export] Instance mult_left_cancel: forall z, PropHolds (z <> 0) ->
LeftCancellation (.*.) z.
intros z z_nonzero x y E.
apply (mult_ne_0 z (x - y) (is_ne_0 z)).
rewrite <-simple_distribute_l,right_inverse.
Instance mult_ne_0' `{!NoZeroDivisors R} x y
: PropHolds (x <> 0) -> PropHolds (y <> 0) -> PropHolds (x * y <> 0).
apply (no_zero_divisors x); split; eauto.
#[export] Instance mult_right_cancel : forall z, PropHolds (z <> 0) ->
RightCancellation (.*.) z.
napply (mult_ne_0' (x - y) z).
apply U, equal_by_zero_sum, r.
lhs rapply ring_dist_right.
rewrite <- negate_mult_distr_l.
apply equal_by_zero_sum in p.
Lemma plus_conjugate x y : x = y + x - y.
rewrite (commutativity (f := (+)) y x),
<- (simple_associativity (f := (+)) x y (-y)),
right_inverse, right_identity.
Lemma plus_conjugate_alt x y : x = y + (x - y).
rewrite (simple_associativity (f := (+))).
Section integral_domain_props.
Context `{IsIntegralDomain R}.
Instance intdom_nontrivial_apart `{Apart R} `{!TrivialApart R} :
PropHolds (1 ≶ 0).
apply apartness.ne_apart.
rapply intdom_nontrivial.
End integral_domain_props.
#[export]
Hint Extern 6 (PropHolds (1 ≶ 0)) =>
eapply @intdom_nontrivial_apart : typeclass_instances.
Context `{IsRing A} `{IsRing B} `{!IsSemiRingPreserving (f : A -> B)}.
Definition preserves_negate x : f (- x) = - f x.
rapply preserves_inverse.
Lemma preserves_minus x y : f (x - y) = f x - f y.
rewrite <-preserves_negate.
Lemma injective_preserves_0 : (forall x, f x = 0 -> x = 0) -> IsInjective f.
rewrite preserves_minus, E.
Section from_another_ring.
Context `{IsCRing A} `{IsHSet B}
`{Bplus : Plus B} `{Zero B} `{Bmult : Mult B} `{One B} `{Bnegate : Negate B}
(f : B -> A) `{!IsInjective f}
(plus_correct : forall x y, f (x + y) = f x + f y) (zero_correct : f 0 = 0)
(mult_correct : forall x y, f (x * y) = f x * f y) (one_correct : f 1 = 1)
(negate_correct : forall x, f (-x) = -f x).
Lemma projected_ring: IsCRing B.
apply (groups.projected_ab_group f);assumption.
exact (groups.projected_com_monoid f mult_correct one_correct);assumption.
repeat intro; apply (injective f).
rewrite plus_correct, !mult_correct, plus_correct.
(* Section from_stdlib_semiring_theory.
Context
`(H: @semi_ring_theory R Rzero Rone Rplus Rmult Re)
`{!@Setoid R Re}
`{!Proper (Re ==> Re ==> Re) Rplus}
`{!Proper (Re ==> Re ==> Re) Rmult}.
Add Ring R2: H.
Definition from_stdlib_semiring_theory: @SemiRing R Re Rplus Rmult Rzero Rone.
Proof.
repeat (constructor; try assumption); repeat intro
; unfold equiv, mon_unit, sg_op, zero_is_mon_unit, plus_is_sg_op,
one_is_mon_unit, mult_is_sg_op, zero, mult, plus; ring.
Qed.
End from_stdlib_semiring_theory.
Section from_stdlib_ring_theory.
Context
`(H: @ring_theory R Rzero Rone Rplus Rmult Rminus Rnegate Re)
`{!@Setoid R Re}
`{!Proper (Re ==> Re ==> Re) Rplus}
`{!Proper (Re ==> Re ==> Re) Rmult}
`{!Proper (Re ==> Re) Rnegate}.
Add Ring R3: H.
Definition from_stdlib_ring_theory: @Ring R Re Rplus Rmult Rzero Rone Rnegate.
Proof.
repeat (constructor; try assumption); repeat intro
; unfold equiv, mon_unit, sg_op, zero_is_mon_unit, plus_is_sg_op,
one_is_mon_unit, mult_is_sg_op, mult, plus, negate; ring.
Qed.
End from_stdlib_ring_theory. *)
Instance id_sr_morphism `{IsSemiCRing A}: IsSemiRingPreserving (@id A) := {}.
Section morphism_composition.
Context `{Mult A} `{Plus A} `{One A} `{Zero A}
`{Mult B} `{Plus B} `{One B} `{Zero B}
`{Mult C} `{Plus C} `{One C} `{Zero C}
(f : A -> B) (g : B -> C).
Instance compose_sr_morphism:
IsSemiRingPreserving f -> IsSemiRingPreserving g -> IsSemiRingPreserving (g ∘ f).
Instance invert_sr_morphism:
forall `{!IsEquiv f}, IsSemiRingPreserving f -> IsSemiRingPreserving (f^-1).
End morphism_composition.
#[export]
Hint Extern 4 (IsSemiRingPreserving (_ ∘ _)) =>
class_apply @compose_sr_morphism : typeclass_instances.
#[export]
Hint Extern 4 (IsSemiRingPreserving (_^-1)) =>
class_apply @invert_sr_morphism : typeclass_instances.