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
|
Require
MathClasses.varieties.monoids MathClasses.theory.groups MathClasses.theory.strong_setoids.
Require Import
Coq.setoid_ring.Ring MathClasses.interfaces.abstract_algebra.
Definition is_ne_0 `(x : R) `{Equiv R} `{Zero R} `{p : PropHolds (x ≠ 0)} : x ≠ 0 := p.
Definition is_nonneg `(x : R) `{Equiv R} `{Le R} `{Zero R} `{p : PropHolds (0 ≤ x)} : 0 ≤ x := p.
Definition is_pos `(x : R) `{Equiv 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.
constructor; intros.
apply left_identity.
apply commutativity.
apply associativity.
apply left_identity.
apply left_absorb.
apply commutativity.
apply associativity.
rewrite commutativity, distribute_l.
now setoid_rewrite commutativity at 2 3.
Qed.
(* We cannot apply [left_cancellation (.*.) z] directly in case we have
no [PropHolds (0 ≠ z)] instance in the context. *)
Section cancellation.
Context `{Ae : Equiv A} (op : A → A → A) `{!Zero A}.
Lemma left_cancellation_ne_0 `{∀ z, PropHolds (z ≠ 0) → LeftCancellation op z} z : z ≠ 0 → LeftCancellation op z.
Proof. auto. Qed.
Lemma right_cancellation_ne_0 `{∀ z, PropHolds (z ≠ 0) → RightCancellation op z} z : z ≠ 0 → RightCancellation op z.
Proof. auto. Qed.
Lemma right_cancel_from_left `{!Setoid A} `{!Commutative op} `{!LeftCancellation op z} :
RightCancellation op z.
Proof.
intros x y E.
apply (left_cancellation op z).
now rewrite 2!(commutativity z _).
Qed.
End cancellation.
Section strong_cancellation.
Context `{StrongSetoid A} (op : A → A → A).
Lemma strong_right_cancel_from_left `{!Commutative op} `{!StrongLeftCancellation op z} :
StrongRightCancellation op z.
Proof.
intros x y E.
rewrite 2!(commutativity _ z).
now apply (strong_left_cancellation op z).
Qed.
Global Instance strong_left_cancellation_cancel `{!StrongLeftCancellation op z} : LeftCancellation op z | 20.
Proof.
intros x y. rewrite <-!tight_apart. intros E1 E2.
destruct E1. now apply (strong_left_cancellation op).
Qed.
Global Instance strong_right_cancellation_cancel `{!StrongRightCancellation op z} : RightCancellation op z | 20.
Proof.
intros x y. rewrite <-!tight_apart. intros E1 E2.
destruct E1. now apply (strong_right_cancellation op).
Qed.
End strong_cancellation.
Section semiring_props.
Context `{SemiRing 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).
Proof.
intros Ex Ey Exy.
unfold PropHolds in *.
apply (no_zero_divisors x); split; eauto.
Qed.
Global Instance plus_0_r: RightIdentity (+) 0 := right_identity.
Global Instance plus_0_l: LeftIdentity (+) 0 := left_identity.
Global Instance mult_1_l: LeftIdentity (.*.) 1 := left_identity.
Global Instance mult_1_r: RightIdentity (.*.) 1 := right_identity.
Global Instance plus_assoc: Associative (+) := simple_associativity.
Global Instance mult_assoc: Associative (.*.) := simple_associativity.
Global Instance plus_comm: Commutative (+) := commutativity.
Global Instance mult_comm: Commutative (.*.) := commutativity.
Global Instance mult_0_l: LeftAbsorb (.*.) 0 := left_absorb.
Global Instance mult_0_r: RightAbsorb (.*.) 0.
Proof. intro. ring. Qed.
Global Instance: RightDistribute (.*.) (+).
Proof. intros x y z. ring. Qed.
Lemma plus_mult_distr_r x y z: (x + y) * z = x * z + y * z. Proof. ring. Qed.
Lemma plus_mult_distr_l x y z: x * (y + z) = x * y + x * z. Proof. ring. Qed.
Global Instance: ∀ r : R, @Monoid_Morphism R R _ _ (0:R) (0:R) (+) (+) (r *.).
Proof.
repeat (constructor; try apply _).
apply distribute_l.
apply right_absorb.
Qed.
End semiring_props.
(* Due to bug #2528 *)
#[global]
Hint Extern 3 (PropHolds (_ * _ ≠ 0)) => eapply @mult_ne_0 : typeclass_instances.
Section semiringmor_props.
Context `{SemiRing_Morphism A B f}.
Lemma preserves_0: f 0 = 0.
Proof (preserves_mon_unit (f:=f)).
Lemma preserves_1: f 1 = 1.
Proof (preserves_mon_unit (f:=f)).
Lemma preserves_mult: ∀ x y, f (x * y) = f x * f y.
Proof. intros. apply preserves_sg_op. Qed.
Lemma preserves_plus: ∀ x y, f (x + y) = f x + f y.
Proof. intros. apply preserves_sg_op. Qed.
Instance: SemiRing B := semiringmor_b.
Lemma preserves_2: f 2 = 2.
Proof. rewrite preserves_plus. now rewrite preserves_1. Qed.
Lemma preserves_3: f 3 = 3.
Proof. now rewrite ?preserves_plus, ?preserves_1. Qed.
Lemma preserves_4: f 4 = 4.
Proof. now rewrite ?preserves_plus, ?preserves_1. Qed.
Context `{!Injective f}.
Instance injective_ne_0 x : PropHolds (x ≠ 0) → PropHolds (f x ≠ 0).
Proof. intros. rewrite <-preserves_0. now apply (jections.injective_ne f). Qed.
Lemma injective_ne_1 x : x ≠ 1 → f x ≠ 1.
Proof. intros. rewrite <-preserves_1. now apply (jections.injective_ne f). Qed.
End semiringmor_props.
(* Due to bug #2528 *)
#[global]
Hint Extern 12 (PropHolds (_ _ ≠ 0)) => eapply @injective_ne_0 : typeclass_instances.
Lemma stdlib_ring_theory R `{Ring R} :
Ring_theory.ring_theory 0 1 (+) (.*.) (λ x y, x - y) (-) (=).
Proof.
constructor; intros.
apply left_identity.
apply commutativity.
apply associativity.
apply left_identity.
apply commutativity.
apply associativity.
rewrite commutativity, distribute_l.
now setoid_rewrite commutativity at 2 3.
reflexivity.
apply (right_inverse x).
Qed.
Section ring_props.
Context `{Ring R}.
Add Ring R: (stdlib_ring_theory R).
Instance: LeftAbsorb (.*.) 0.
Proof. intro. ring. Qed.
Global Instance Ring_Semi: SemiRing R.
Proof. repeat (constructor; try apply _). Qed.
Definition negate_involutive x : - - x = x := groups.negate_involutive x. (* alias for convinience *)
Lemma plus_negate_r x : x + -x = 0. Proof. ring. Qed.
Lemma plus_negate_l x : -x + x = 0. Proof. ring. Qed.
Lemma negate_swap_r x y : x - y = -(y - x). Proof. ring. Qed.
Lemma negate_swap_l x y : -x + y = -(x - y). Proof. ring. Qed.
Lemma negate_plus_distr x y : -(x + y) = -x + -y. Proof. ring. Qed.
Lemma negate_mult x : -x = -1 * x. Proof. ring. Qed.
Lemma negate_mult_distr_l x y : -(x * y) = -x * y. Proof. ring. Qed.
Lemma negate_mult_distr_r x y : -(x * y) = x * -y. Proof. ring. Qed.
Lemma negate_mult_negate x y : -x * -y = x * y. Proof. ring. Qed.
Lemma negate_0: -0 = 0. Proof. ring. Qed.
Global Instance minus_0_r: RightIdentity (λ x y, x - y) 0.
Proof. intro x; rewrite negate_0; apply plus_0_r. Qed.
Lemma equal_by_zero_sum x y : x - y = 0 ↔ x = y.
Proof.
split; intros E.
rewrite <- (plus_0_l y). rewrite <- E. ring.
rewrite E. ring.
Qed.
Lemma flip_negate x y : -x = y ↔ x = -y.
Proof. split; intros E. now rewrite <-E, involutive. now rewrite E, involutive. Qed.
Lemma flip_negate_0 x : -x = 0 ↔ x = 0.
Proof. now rewrite flip_negate, negate_0. Qed.
Lemma flip_negate_ne_0 x : -x ≠ 0 ↔ x ≠ 0.
Proof. split; intros E ?; apply E; now apply flip_negate_0. Qed.
Lemma negate_zero_prod_l x y : -x * y = 0 ↔ x * y = 0.
Proof.
split; intros E.
apply (injective (-)). now rewrite negate_mult_distr_l, negate_0.
apply (injective (-)). now rewrite negate_mult_distr_l, negate_involutive, negate_0.
Qed.
Lemma negate_zero_prod_r x y : x * -y = 0 ↔ x * y = 0.
Proof. rewrite (commutativity x (-y)), (commutativity x y). apply negate_zero_prod_l. Qed.
Lemma unit_no_zero_divisor (x : R) {unit : RingUnit x}: ¬ZeroDivisor x.
Proof.
destruct unit as [y x_y_unit].
intros [_ [z [z_nonzero xz_zero]]].
destruct z_nonzero.
transitivity ((x * z) * y); try (rewrite xz_zero; ring).
transitivity (x * y * z); try (rewrite x_y_unit; ring). ring.
Qed.
Context `{!NoZeroDivisors R} `{∀ x y, Stable (x = y)}.
Global Instance mult_left_cancel: ∀ z, PropHolds (z ≠ 0) → LeftCancellation (.*.) z.
Proof.
intros z z_nonzero x y E.
apply stable.
intro U.
apply (mult_ne_0 z (x - y) (is_ne_0 z)).
intro. apply U. now apply equal_by_zero_sum.
rewrite distribute_l, E. ring.
Qed.
Global Instance: ∀ z, PropHolds (z ≠ 0) → RightCancellation (.*.) z.
Proof. intros ? ?. apply (right_cancel_from_left (.*.)). Qed.
End ring_props.
Section integral_domain_props.
Context `{IntegralDomain R}.
Instance intdom_nontrivial_apart `{Apart R} `{!TrivialApart R} :
PropHolds (1 ≶ 0).
Proof. apply strong_setoids.ne_apart. solve_propholds. Qed.
End integral_domain_props.
(* Due to bug #2528 *)
#[global]
Hint Extern 6 (PropHolds (1 ≶ 0)) => eapply @intdom_nontrivial_apart : typeclass_instances.
Section ringmor_props.
Context `{Ring A} `{Ring B} `{!SemiRing_Morphism (f : A → B)}.
Definition preserves_negate x : f (-x) = -f x := groups.preserves_negate x. (* alias for convinience *)
Lemma preserves_minus x y : f (x - y) = f x - f y.
Proof.
rewrite <-preserves_negate.
apply preserves_plus.
Qed.
Lemma injective_preserves_0 : (∀ x, f x = 0 → x = 0) → Injective f.
Proof.
intros E1.
split; try apply _. intros x y E.
apply equal_by_zero_sum.
apply E1.
rewrite preserves_minus, E.
now apply plus_negate_r.
Qed.
End ringmor_props.
Section from_another_ring.
Context `{Ring A} `{Setoid B}
`{Bplus : Plus B} `{Zero B} `{Bmult : Mult B} `{One B} `{Bnegate : Negate B}
(f : B → A) `{!Injective f}
(plus_correct : ∀ x y, f (x + y) = f x + f y) (zero_correct : f 0 = 0)
(mult_correct : ∀ x y, f (x * y) = f x * f y) (one_correct : f 1 = 1) (negate_correct : ∀ x, f (-x) = -f x).
Lemma projected_ring: Ring B.
Proof.
split.
now apply (groups.projected_ab_group f).
now apply (groups.projected_com_monoid f mult_correct one_correct).
repeat intro; apply (injective f). rewrite plus_correct, !mult_correct, plus_correct.
now rewrite distribute_l.
Qed.
End from_another_ring.
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.
#[global]
Instance id_sr_morphism `{SemiRing A}: SemiRing_Morphism (@id A) := {}.
Section morphism_composition.
Context `{Equiv A} `{Mult A} `{Plus A} `{One A} `{Zero A}
`{Equiv B} `{Mult B} `{Plus B} `{One B} `{Zero B}
`{Equiv C} `{Mult C} `{Plus C} `{One C} `{Zero C}
(f : A → B) (g : B → C).
Instance compose_sr_morphism:
SemiRing_Morphism f → SemiRing_Morphism g → SemiRing_Morphism (g ∘ f).
Proof. split; try apply _; firstorder. Qed.
Instance invert_sr_morphism:
∀ `{!Inverse f}, Bijective f → SemiRing_Morphism f → SemiRing_Morphism (f⁻¹).
Proof. split; try apply _; firstorder. Qed.
End morphism_composition.
#[global]
Hint Extern 4 (SemiRing_Morphism (_ ∘ _)) => class_apply @compose_sr_morphism : typeclass_instances.
#[global]
Hint Extern 4 (SemiRing_Morphism (_⁻¹)) => class_apply @invert_sr_morphism : typeclass_instances.
#[global]
Instance semiring_morphism_proper {A B eA eB pA mA zA oA pB mB zB oB} :
Proper ((=) ==> (=)) (@SemiRing_Morphism A B eA eB pA mA zA oA pB mB zB oB).
Proof.
assert (∀ (f g : A → B), g = f → SemiRing_Morphism f → SemiRing_Morphism g) as P.
intros f g E [? ? ? ?].
now split; try apply _; eapply groups.monoid_morphism_proper; eauto.
intros f g ?; split; intros Mor.
apply P with f. destruct Mor. now symmetry. now apply _.
now apply P with g.
Qed.
|