Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
Euclidean Division
Require Import NZAxioms NZMulOrder.
The first signatures will be common to all divisions over NZ, N and Z
Module Type DivMod (Import A : Typ). Parameters Inline div modulo : t -> t -> t. End DivMod. Module Type DivModNotation (A : Typ)(Import B : DivMod A). Infix "/" := div. Infix "mod" := modulo (at level 40, no associativity). End DivModNotation. Module Type DivMod' (A : Typ) := DivMod A <+ DivModNotation A. Module Type NZDivSpec (Import A : NZOrdAxiomsSig')(Import B : DivMod' A). Declare Instance div_wd : Proper (eq==>eq==>eq) div. Declare Instance mod_wd : Proper (eq==>eq==>eq) modulo. Axiom div_mod : forall a b, b ~= 0 -> a == b*(a/b) + (a mod b). Axiom mod_bound_pos : forall a b, 0<=a -> 0<b -> 0 <= a mod b < b. End NZDivSpec.
The different divisions will only differ in the conditions
they impose on modulo. For NZ, we have only described the
behavior on positive numbers.
Module Type NZDiv (A : NZOrdAxiomsSig) := DivMod A <+ NZDivSpec A. Module Type NZDiv' (A : NZOrdAxiomsSig) := NZDiv A <+ DivModNotation A. Module Type NZDivProp (Import A : NZOrdAxiomsSig') (Import B : NZDiv' A) (Import C : NZMulOrderProp A).
Uniqueness theorems
forall b q1 q2 r1 r2 : t, 0 <= r1 < b -> 0 <= r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2forall b q1 q2 r1 r2 : t, 0 <= r1 < b -> 0 <= r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2b:tforall q1 q2 r1 r2 : t, 0 <= r1 < b -> 0 <= r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2b:tforall q1 q2 r1 r2 : t, b * q1 + r1 == b * q2 + r2 -> 0 <= r1 < b -> 0 <= r2 -> q1 < q2 -> Falseb:tU:forall q1 q2 r1 r2 : t, b * q1 + r1 == b * q2 + r2 -> 0 <= r1 < b -> 0 <= r2 -> q1 < q2 -> Falseforall q1 q2 r1 r2 : t, 0 <= r1 < b -> 0 <= r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2b:tforall q1 q2 r1 r2 : t, b * q1 + r1 == b * q2 + r2 -> 0 <= r1 < b -> 0 <= r2 -> q1 < q2 -> Falseb, q1, q2, r1, r2:tEQ:b * q1 + r1 == b * q2 + r2LT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2Falseb, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q1 + r1 ~= b * q2 + r2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q1 + r1 < b * q2 + r2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q1 + r1 < b * q1 + bb, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q1 + b <= b * q2 + r2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q1 + r1 < b * q1 + btauto.b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2r1 < bb, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q1 + b <= b * q2 + r2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q1 + b <= b * q2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q2 <= b * q2 + r2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q1 + b <= b * q2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * S q1 <= b * q2rewrite le_succ_l; auto.b, q1, q2, r1, r2:tHr1:0 <= r2Hr2:q1 < q2H:0 <= r1H0:r1 < bS q1 <= q2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q2 <= b * q2 + r2b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q2b * q2 + 0 <= b * q2 + r2tauto.b, q1, q2, r1, r2:tLT:0 <= r1 < bHr1:0 <= r2Hr2:q1 < q20 <= r2b:tU:forall q1 q2 r1 r2 : t, b * q1 + r1 == b * q2 + r2 -> 0 <= r1 < b -> 0 <= r2 -> q1 < q2 -> Falseforall q1 q2 r1 r2 : t, 0 <= r1 < b -> 0 <= r2 < b -> b * q1 + r1 == b * q2 + r2 -> q1 == q2 /\ r1 == r2b:tU:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> Falseq1, q2, r1, r2:tHr1:0 <= r1 < bHr2:0 <= r2 < bEQ:b * q1 + r1 == b * q2 + r2LT:q1 < q2q1 == q2 /\ r1 == r2b:tU:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> Falseq1, q2, r1, r2:tHr1:0 <= r1 < bHr2:0 <= r2 < bEQ:b * q1 + r1 == b * q2 + r2EQ':q1 == q2q1 == q2 /\ r1 == r2b:tU:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> Falseq1, q2, r1, r2:tHr1:0 <= r1 < bHr2:0 <= r2 < bEQ:b * q1 + r1 == b * q2 + r2GT:q2 < q1q1 == q2 /\ r1 == r2elim (U q1 q2 r1 r2); intuition.b:tU:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> Falseq1, q2, r1, r2:tHr1:0 <= r1 < bHr2:0 <= r2 < bEQ:b * q1 + r1 == b * q2 + r2LT:q1 < q2q1 == q2 /\ r1 == r2b:tU:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> Falseq1, q2, r1, r2:tHr1:0 <= r1 < bHr2:0 <= r2 < bEQ:b * q1 + r1 == b * q2 + r2EQ':q1 == q2q1 == q2 /\ r1 == r2b:tU:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> Falseq1, q2, r1, r2:tHr1:0 <= r1 < bHr2:0 <= r2 < bEQ:b * q1 + r1 == b * q2 + r2EQ':q1 == q2r1 == r2rewrite add_cancel_l in EQ; auto.b:tU:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> Falseq1, q2, r1, r2:tHr1:0 <= r1 < bHr2:0 <= r2 < bEQ:b * q2 + r1 == b * q2 + r2EQ':q1 == q2r1 == r2elim (U q2 q1 r2 r1); intuition. Qed.b:tU:forall q0 q3 r0 r3 : t, b * q0 + r0 == b * q3 + r3 -> 0 <= r0 < b -> 0 <= r3 -> q0 < q3 -> Falseq1, q2, r1, r2:tHr1:0 <= r1 < bHr2:0 <= r2 < bEQ:b * q1 + r1 == b * q2 + r2GT:q2 < q1q1 == q2 /\ r1 == r2forall a b q r : t, 0 <= a -> 0 <= r < b -> a == b * q + r -> q == a / bforall a b q r : t, 0 <= a -> 0 <= r < b -> a == b * q + r -> q == a / ba, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + rq == a / ba, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + r0 <= a mod b < ba, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + rb * q + r == b * (a / b) + a mod bapply mod_bound_pos; order.a, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + r0 <= a mod b < brewrite <- div_mod; order. Qed.a, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + rb * q + r == b * (a / b) + a mod bforall a b q r : t, 0 <= a -> 0 <= r < b -> a == b * q + r -> r == a mod bforall a b q r : t, 0 <= a -> 0 <= r < b -> a == b * q + r -> r == a mod ba, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + rr == a mod ba, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + r0 <= a mod b < ba, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + rb * q + r == b * (a / b) + a mod bapply mod_bound_pos; order.a, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + r0 <= a mod b < brewrite <- div_mod; order. Qed.a, b, q, r:tHa:0 <= aHb:0 <= rHr:r < bEQ:a == b * q + rb * q + r == b * (a / b) + a mod ba, b, q:t0 <= a -> 0 < b -> a == b * q -> q == a / ba, b, q:t0 <= a -> 0 < b -> a == b * q -> q == a / bapply div_unique with 0; nzsimpl; now try split. Qed.a, b, q:tHa:0 <= aHb:0 < bH:a == b * qq == a / b
A division by itself returns 1
forall a : t, 0 < a -> a / a == 1forall a : t, 0 < a -> a / a == 1a:tH:0 < aa / a == 1apply div_unique_exact; nzsimpl; order. Qed.a:tH:0 < a1 == a / aforall a : t, 0 < a -> a mod a == 0forall a : t, 0 < a -> a mod a == 0a:tH:0 < aa mod a == 0a:tH:0 < a0 == a mod anow nzsimpl. Qed.a:tH:0 < aa == a * 1 + 0
A division of a small number by a bigger one yields zero.
forall a b : t, 0 <= a < b -> a / b == 0forall a b : t, 0 <= a < b -> a / b == 0a, b:tH:0 <= a < ba / b == 0a, b:tH:0 <= a < b0 == a / bnow nzsimpl. Qed.a, b:tH0:0 <= aH1:a < ba == b * 0 + a
Same situation, in term of modulo:
forall a b : t, 0 <= a < b -> a mod b == aforall a b : t, 0 <= a < b -> a mod b == aa, b:tH:0 <= a < ba mod b == aa, b:tH:0 <= a < ba == a mod bnow nzsimpl. Qed.a, b:tH0:0 <= aH1:a < ba == b * 0 + a
forall a : t, 0 < a -> 0 / a == 0intros; apply div_small; split; order. Qed.forall a : t, 0 < a -> 0 / a == 0forall a : t, 0 < a -> 0 mod a == 0intros; apply mod_small; split; order. Qed.forall a : t, 0 < a -> 0 mod a == 0forall a : t, 0 <= a -> a / 1 == aforall a : t, 0 <= a -> a / 1 == aa:tH:0 <= aa / 1 == aapply div_unique_exact; nzsimpl; order'. Qed.a:tH:0 <= aa == a / 1forall a : t, 0 <= a -> a mod 1 == 0forall a : t, 0 <= a -> a mod 1 == 0a:tH:0 <= aa mod 1 == 0a:tH:0 <= a0 == a mod 1now nzsimpl. Qed.a:tH:0 <= aa == 1 * a + 0forall a : t, 1 < a -> 1 / a == 0forall a : t, 1 < a -> 1 / a == 0apply le_0_1. Qed.a:tH:1 < a0 <= 1forall a : t, 1 < a -> 1 mod a == 1forall a : t, 1 < a -> 1 mod a == 1apply le_0_1. Qed.a:tH:1 < a0 <= 1forall a b : t, 0 <= a -> 0 < b -> a * b / b == aforall a b : t, 0 <= a -> 0 < b -> a * b / b == aa, b:tH:0 <= aH0:0 < ba == a * b / ba, b:tH:0 <= aH0:0 < b0 <= a * ba, b:tH:0 <= aH0:0 < ba * b == b * aapply mul_nonneg_nonneg; order.a, b:tH:0 <= aH0:0 < b0 <= a * bapply mul_comm. Qed.a, b:tH:0 <= aH0:0 < ba * b == b * aforall a b : t, 0 <= a -> 0 < b -> (a * b) mod b == 0forall a b : t, 0 <= a -> 0 < b -> (a * b) mod b == 0a, b:tH:0 <= aH0:0 < b0 == (a * b) mod ba, b:tH:0 <= aH0:0 < b0 <= a * ba, b:tH:0 <= aH0:0 < ba * b == b * a + 0apply mul_nonneg_nonneg; order.a, b:tH:0 <= aH0:0 < b0 <= a * bnzsimpl; apply mul_comm. Qed.a, b:tH:0 <= aH0:0 < ba * b == b * a + 0
A modulo cannot grow beyond its starting point.
forall a b : t, 0 <= a -> 0 < b -> a mod b <= aforall a b : t, 0 <= a -> 0 < b -> a mod b <= aa, b:tH:0 <= aH0:0 < ba mod b <= aa, b:tH:0 <= aH0:0 < bH1:b <= aa mod b <= aa, b:tH:0 <= aH0:0 < bH1:a < ba mod b <= aa, b:tH:0 <= aH0:0 < bH1:b <= aa mod b <= aa, b:tH:0 <= aH0:0 < bH1:b <= aa mod b <= bdestruct (mod_bound_pos a b); auto.a, b:tH:0 <= aH0:0 < bH1:b <= aa mod b < ba, b:tH:0 <= aH0:0 < bH1:a < ba mod b <= aapply mod_small; auto. Qed. (* Division of positive numbers is positive. *)a, b:tH:0 <= aH0:0 < bH1:a < ba mod b == aforall a b : t, 0 <= a -> 0 < b -> 0 <= a / bforall a b : t, 0 <= a -> 0 < b -> 0 <= a / ba, b:tH:0 <= aH0:0 < b0 <= a / ba, b:tH:0 <= aH0:0 < b0 <= b * (a / b)a, b:tH:0 <= aH0:0 < b0 + a mod b <= b * (a / b) + a mod ba, b:tH:0 <= aH0:0 < b0 + a mod b <= aapply mod_le; auto. Qed.a, b:tH:0 <= aH0:0 < ba mod b <= aforall a b : t, 0 < b <= a -> 0 < a / bforall a b : t, 0 < b <= a -> 0 < a / ba, b:tHb:0 < bHab:b <= a0 < a / ba, b:tHb:0 < bHab:b <= aLE:0 <= a / b0 < a / ba, b:tHb:0 < bHab:b <= aLE:0 <= a / bMOD:a mod b < b0 < a / ba, b:tHb:0 < bHab:b <= aEQ:0 == a / bMOD:a mod b < b0 < a / brewrite (div_mod a b), <-EQ; nzsimpl; order. Qed.a, b:tHb:0 < bEQ:0 == a / bMOD:a mod b < bb <= a -> Falseforall a b : t, 0 <= a -> 0 < b -> a / b == 0 <-> a < bforall a b : t, 0 <= a -> 0 < b -> a / b == 0 <-> a < ba, b:tHa:0 <= aHb:0 < bHab:a / b == 0a < ba, b:tHa:0 <= aHb:0 < bHab:a < ba / b == 0a, b:tHa:0 <= aHb:0 < bHab:a / b == 0a < ba, b:tHa:0 <= aHb:0 < bHab:a / b == 0H:b <= aa < ba, b:tHa:0 <= aHb:0 < bHab:0 == a / bH:b <= aa < bapply lt_neq, div_str_pos; auto.a, b:tHa:0 <= aHb:0 < bH:b <= a0 ~= a / bapply div_small; auto. Qed.a, b:tHa:0 <= aHb:0 < bHab:a < ba / b == 0forall a b : t, 0 <= a -> 0 < b -> a mod b == a <-> a < bforall a b : t, 0 <= a -> 0 < b -> a mod b == a <-> a < ba, b:tHa:0 <= aHb:0 < ba mod b == a <-> a < ba, b:tHa:0 <= aHb:0 < bH:a mod b == aa < ba, b:tHa:0 <= aHb:0 < bH:a mod b == aa / b == 0a, b:tHa:0 <= aHb:0 < bH:a mod b == ab * (a / b) == b * 0a, b:tHa:0 <= aHb:0 < bH:a mod b == ab * (a / b) + a mod b == b * 0 + a mod bnow nzsimpl. Qed.a, b:tHa:0 <= aHb:0 < bH:a mod b == aa == b * 0 + aforall a b : t, 0 <= a -> 0 < b -> 0 < a / b <-> b <= aforall a b : t, 0 <= a -> 0 < b -> 0 < a / b <-> b <= aa, b:tHa:0 <= aHb:0 < bHab:0 < a / bb <= aa, b:tHa:0 <= aHb:0 < bHab:b <= a0 < a / ba, b:tHa:0 <= aHb:0 < bHab:0 < a / bb <= arewrite <- div_small_iff in LT; order.a, b:tHa:0 <= aHb:0 < bHab:0 < a / bLT:a < bb <= aapply div_str_pos; auto. Qed.a, b:tHa:0 <= aHb:0 < bHab:b <= a0 < a / b
As soon as the divisor is strictly greater than 1,
the division is strictly decreasing.
forall a b : t, 0 < a -> 1 < b -> a / b < aforall a b : t, 0 < a -> 1 < b -> a / b < aa, b:tH:0 < aH0:1 < ba / b < aa, b:tH:0 < aH0:1 < bH1:0 < ba / b < aa, b:tH:0 < aH0:1 < bH1:0 < bH2:a < ba / b < aa, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= aa / b < arewrite div_small; try split; order.a, b:tH:0 < aH0:1 < bH1:0 < bH2:a < ba / b < aa, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= aa / b < aa, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= aa / b < b * (a / b) + a mod ba, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= aa / b < b * (a / b)a, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= ab * (a / b) <= b * (a / b) + a mod ba, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= aa / b < b * (a / b)a, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= a1 * (a / b) < b * (a / b)apply div_str_pos; auto.a, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= a0 < a / ba, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= ab * (a / b) <= b * (a / b) + a mod ba, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= ab * (a / b) + 0 <= b * (a / b) + a mod bdestruct (mod_bound_pos a b); order. Qed.a, b:tH:0 < aH0:1 < bH1:0 < bH2:b <= a0 <= a mod b
le is compatible with a positive division.
forall a b c : t, 0 < c -> 0 <= a <= b -> a / c <= b / cforall a b c : t, 0 < c -> 0 <= a <= b -> a / c <= b / ca, b, c:tHc:0 < cHa:0 <= aHab:a <= ba / c <= b / ca, b, c:tHc:0 < cHa:0 <= aHab:a < b \/ a == ba / c <= b / ca, b, c:tHc:0 < cHa:0 <= aLT:a < ba / c <= b / ca, b, c:tHc:0 < cHa:0 <= aLT:a < ba / c < S (b / c)a, b, c:tHc:0 < cHa:0 <= aLT:a < bc * (a / c) < c * S (b / c)a, b, c:tHc:0 < cHa:0 <= aLT:a < bc * (a / c) < c * (b / c) + ca, b, c:tHc:0 < cHa:0 <= aLT:a < bc * (a / c) + a mod c < c * (b / c) + c + a mod ca, b, c:tHc:0 < cHa:0 <= aLT:a < ba < c * (b / c) + c + a mod ca, b, c:tHc:0 < cHa:0 <= aLT:a < bb <= c * (b / c) + c + a mod ca, b, c:tHc:0 < cHa:0 <= aLT:a < bc * (b / c) + b mod c <= c * (b / c) + c + a mod ca, b, c:tHc:0 < cHa:0 <= aLT:a < bb mod c <= c + a mod ca, b, c:tHc:0 < cHa:0 <= aLT:a < bb mod c <= c + 0a, b, c:tHc:0 < cHa:0 <= aLT:a < bc + 0 <= c + a mod cnzsimpl; destruct (mod_bound_pos b c); order.a, b, c:tHc:0 < cHa:0 <= aLT:a < bb mod c <= c + 0a, b, c:tHc:0 < cHa:0 <= aLT:a < bc + 0 <= c + a mod cdestruct (mod_bound_pos a c); order. Qed.a, b, c:tHc:0 < cHa:0 <= aLT:a < b0 <= a mod c
The following two properties could be used as specification of div
forall a b : t, 0 <= a -> 0 < b -> b * (a / b) <= aforall a b : t, 0 <= a -> 0 < b -> b * (a / b) <= aa, b:tH:0 <= aH0:0 < bb * (a / b) <= aa, b:tH:0 <= aH0:0 < ba <= a + a mod ba, b:tH:0 <= aH0:0 < ba + 0 <= a + a mod bdestruct (mod_bound_pos a b); order. Qed.a, b:tH:0 <= aH0:0 < b0 <= a mod bforall a b : t, 0 <= a -> 0 < b -> a < b * S (a / b)forall a b : t, 0 <= a -> 0 < b -> a < b * S (a / b)a, b:tH:0 <= aH0:0 < ba < b * S (a / b)a, b:tH:0 <= aH0:0 < bb * (a / b) + a mod b < b * S (a / b)a, b:tH:0 <= aH0:0 < bb * (a / b) + a mod b < b * (a / b) + bdestruct (mod_bound_pos a b); auto. Qed.a, b:tH:0 <= aH0:0 < ba mod b < b
The previous inequality is exact iff the modulo is zero.
forall a b : t, 0 <= a -> 0 < b -> a == b * (a / b) <-> a mod b == 0forall a b : t, 0 <= a -> 0 < b -> a == b * (a / b) <-> a mod b == 0a, b:tH:0 <= aH0:0 < ba == b * (a / b) <-> a mod b == 0a, b:tH:0 <= aH0:0 < bb * (a / b) + a mod b == b * (a / b) <-> a mod b == 0apply add_cancel_l. Qed.a, b:tH:0 <= aH0:0 < bb * (a / b) + a mod b == b * (a / b) + 0 <-> a mod b == 0
Some additional inequalities about div.
forall a b q : t, 0 <= a -> 0 < b -> a < b * q -> a / b < qforall a b q : t, 0 <= a -> 0 < b -> a < b * q -> a / b < qa, b, q:tH:0 <= aH0:0 < bH1:a < b * qa / b < qa, b, q:tH:0 <= aH0:0 < bH1:a < b * qb * (a / b) < b * qapply mul_div_le; auto. Qed.a, b, q:tH:0 <= aH0:0 < bH1:a < b * qb * (a / b) <= aforall a b q : t, 0 <= a -> 0 < b -> a <= b * q -> a / b <= qforall a b q : t, 0 <= a -> 0 < b -> a <= b * q -> a / b <= qa, b, q:tH:0 <= aH0:0 < bH1:a <= b * qa / b <= qa, b, q:tH:0 <= aH0:0 < bH1:a <= b * qb * (a / b) <= b * qapply mul_div_le; auto. Qed.a, b, q:tH:0 <= aH0:0 < bH1:a <= b * qb * (a / b) <= aforall a b q : t, 0 <= a -> 0 < b -> b * q <= a -> q <= a / bforall a b q : t, 0 <= a -> 0 < b -> b * q <= a -> q <= a / ba, b, q:tHa:0 <= aHb:0 < bH:b * q <= aq <= a / ba, b, q:tHa:0 <= aHb:0 < bH:b * q <= aH0:0 < qq <= a / ba, b, q:tHa:0 <= aHb:0 < bH:b * q <= aH0:q <= 0q <= a / ba, b, q:tHa:0 <= aHb:0 < bH:b * q <= aH0:0 < qq <= a / ba, b, q:tHa:0 <= aHb:0 < bH:b * q <= aH0:0 < qq * b / b <= a / ba, b, q:tHa:0 <= aHb:0 < bH:b * q <= aH0:0 < q0 <= q * b <= aapply lt_le_incl, mul_pos_pos; auto.a, b, q:tHa:0 <= aHb:0 < bH:b * q <= aH0:0 < q0 <= b * qapply le_trans with 0; auto; apply div_pos; auto. Qed.a, b, q:tHa:0 <= aHb:0 < bH:b * q <= aH0:q <= 0q <= a / b
A division respects opposite monotonicity for the divisor
forall p q r : t, 0 <= p -> 0 < q <= r -> p / r <= p / qforall p q r : t, 0 <= p -> 0 < q <= r -> p / r <= p / qp, q, r:tHp:0 <= pHq:0 < qHqr:q <= rp / r <= p / qp, q, r:tHp:0 <= pHq:0 < qHqr:q <= rq * (p / r) <= pp, q, r:tHp:0 <= pHq:0 < qHqr:q <= rq * (p / r) <= r * (p / r) + p mod rp, q, r:tHp:0 <= pHq:0 < qHqr:q <= rq * (p / r) <= r * (p / r)p, q, r:tHp:0 <= pHq:0 < qHqr:q <= rr * (p / r) <= r * (p / r) + p mod rp, q, r:tHp:0 <= pHq:0 < qHqr:q <= rq * (p / r) <= r * (p / r)apply div_pos; order.p, q, r:tHp:0 <= pHq:0 < qHqr:q <= r0 <= p / rp, q, r:tHp:0 <= pHq:0 < qHqr:q <= rr * (p / r) <= r * (p / r) + p mod rp, q, r:tHp:0 <= pHq:0 < qHqr:q <= rr * (p / r) + 0 <= r * (p / r) + p mod rdestruct (mod_bound_pos p r); order. Qed.p, q, r:tHp:0 <= pHq:0 < qHqr:q <= r0 <= p mod r
forall a b c : t, 0 <= a -> 0 <= a + b * c -> 0 < c -> (a + b * c) mod c == a mod cforall a b c : t, 0 <= a -> 0 <= a + b * c -> 0 < c -> (a + b * c) mod c == a mod ca, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < c(a + b * c) mod c == a mod ca, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < ca mod c == (a + b * c) mod ca, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < c0 <= a mod c < ca, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < ca + b * c == c * (a / c + b) + a mod capply mod_bound_pos; auto.a, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < c0 <= a mod c < ca, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < ca + b * c == c * (a / c + b) + a mod cnow rewrite mul_comm. Qed.a, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < ca + b * c == a + c * bforall a b c : t, 0 <= a -> 0 <= a + b * c -> 0 < c -> (a + b * c) / c == a / c + bforall a b c : t, 0 <= a -> 0 <= a + b * c -> 0 < c -> (a + b * c) / c == a / c + ba, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < c(a + b * c) / c == a / c + ba, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < cc * ((a + b * c) / c) == c * (a / c + b)a, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < cc * ((a + b * c) / c) + (a + b * c) mod c == c * (a / c + b) + (a + b * c) mod ca, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < ca + b * c == c * (a / c + b) + a mod cnow rewrite mul_comm. Qed.a, b, c:tH:0 <= aH0:0 <= a + b * cH1:0 < ca + b * c == a + c * bforall a b c : t, 0 <= c -> 0 <= a * b + c -> 0 < b -> (a * b + c) / b == a + c / bforall a b c : t, 0 <= c -> 0 <= a * b + c -> 0 < b -> (a * b + c) / b == a + c / ba, b, c:t0 <= c -> 0 <= a * b + c -> 0 < b -> (a * b + c) / b == a + c / ba, b, c:t0 <= c -> 0 <= c + a * b -> 0 < b -> (c + a * b) / b == c / b + aapply div_add; auto. Qed.a, b, c:tH:0 <= cH0:0 <= c + a * bH1:0 < b(c + a * b) / b == c / b + a
Cancellations.
forall a b c : t, 0 <= a -> 0 < b -> 0 < c -> a * c / (b * c) == a / bforall a b c : t, 0 <= a -> 0 < b -> 0 < c -> a * c / (b * c) == a / ba, b, c:tH:0 <= aH0:0 < bH1:0 < ca * c / (b * c) == a / ba, b, c:tH:0 <= aH0:0 < bH1:0 < ca / b == a * c / (b * c)a, b, c:tH:0 <= aH0:0 < bH1:0 < c0 <= a * ca, b, c:tH:0 <= aH0:0 < bH1:0 < c0 <= a mod b * c < b * ca, b, c:tH:0 <= aH0:0 < bH1:0 < ca * c == b * c * (a / b) + a mod b * capply mul_nonneg_nonneg; order.a, b, c:tH:0 <= aH0:0 < bH1:0 < c0 <= a * ca, b, c:tH:0 <= aH0:0 < bH1:0 < c0 <= a mod b * c < b * ca, b, c:tH:0 <= aH0:0 < bH1:0 < c0 <= a mod b * ca, b, c:tH:0 <= aH0:0 < bH1:0 < ca mod b * c < b * capply mul_nonneg_nonneg; destruct (mod_bound_pos a b); order.a, b, c:tH:0 <= aH0:0 < bH1:0 < c0 <= a mod b * ca, b, c:tH:0 <= aH0:0 < bH1:0 < ca mod b * c < b * cdestruct (mod_bound_pos a b); auto.a, b, c:tH:0 <= aH0:0 < bH1:0 < ca mod b < ba, b, c:tH:0 <= aH0:0 < bH1:0 < ca * c == b * c * (a / b) + a mod b * ca, b, c:tH:0 <= aH0:0 < bH1:0 < c(b * (a / b) + a mod b) * c == b * c * (a / b) + a mod b * ca, b, c:tH:0 <= aH0:0 < bH1:0 < cb * (a / b) * c + a mod b * c == b * c * (a / b) + a mod b * ca, b, c:tH:0 <= aH0:0 < bH1:0 < cb * (a / b) * c == b * c * (a / b)now rewrite (mul_comm c). Qed.a, b, c:tH:0 <= aH0:0 < bH1:0 < cb * (a / b * c) == b * (c * (a / b))forall a b c : t, 0 <= a -> 0 < b -> 0 < c -> c * a / (c * b) == a / bforall a b c : t, 0 <= a -> 0 < b -> 0 < c -> c * a / (c * b) == a / brewrite !(mul_comm c); apply div_mul_cancel_r; auto. Qed.a, b, c:tH:0 <= aH0:0 < bH1:0 < cc * a / (c * b) == a / bforall a b c : t, 0 <= a -> 0 < b -> 0 < c -> (c * a) mod (c * b) == c * (a mod b)forall a b c : t, 0 <= a -> 0 < b -> 0 < c -> (c * a) mod (c * b) == c * (a mod b)a, b, c:tH:0 <= aH0:0 < bH1:0 < c(c * a) mod (c * b) == c * (a mod b)a, b, c:tH:0 <= aH0:0 < bH1:0 < cc * b * (c * a / (c * b)) + (c * a) mod (c * b) == c * b * (c * a / (c * b)) + c * (a mod b)a, b, c:tH:0 <= aH0:0 < bH1:0 < cc * a == c * b * (c * a / (c * b)) + c * (a mod b)a, b, c:tH:0 <= aH0:0 < bH1:0 < cc * b ~= 0a, b, c:tH:0 <= aH0:0 < bH1:0 < cc * a == c * b * (c * a / (c * b)) + c * (a mod b)a, b, c:tH:0 <= aH0:0 < bH1:0 < cc * a == c * b * (a / b) + c * (a mod b)apply div_mod; order.a, b, c:tH:0 <= aH0:0 < bH1:0 < ca == b * (a / b) + a mod brewrite <- neq_mul_0; intuition; order. Qed.a, b, c:tH:0 <= aH0:0 < bH1:0 < cc * b ~= 0forall a b c : t, 0 <= a -> 0 < b -> 0 < c -> (a * c) mod (b * c) == a mod b * cforall a b c : t, 0 <= a -> 0 < b -> 0 < c -> (a * c) mod (b * c) == a mod b * crewrite !(mul_comm _ c); now rewrite mul_mod_distr_l. Qed.a, b, c:tH:0 <= aH0:0 < bH1:0 < c(a * c) mod (b * c) == a mod b * c
Operations modulo.
forall a n : t, 0 <= a -> 0 < n -> (a mod n) mod n == a mod nforall a n : t, 0 <= a -> 0 < n -> (a mod n) mod n == a mod na, n:tH:0 <= aH0:0 < n(a mod n) mod n == a mod nnow rewrite mod_small_iff. Qed.a, n:tH:0 <= aH0:0 < nH1:0 <= a mod nH2:a mod n < n(a mod n) mod n == a mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a mod n * b) mod n == (a * b) mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a mod n * b) mod n == (a * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n(a mod n * b) mod n == (a * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n(a * b) mod n == (a mod n * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n0 <= a * b -> (a * b) mod n == (a mod n * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n0 <= (n * (a / n) + a mod n) * b -> ((n * (a / n) + a mod n) * b) mod n == (a mod n * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n0 <= b * (a mod n + a / n * n) -> (b * (a mod n + a / n * n)) mod n == (a mod n * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n0 <= b * (a mod n) + b * (a / n) * n -> (b * (a mod n) + b * (a / n) * n) mod n == (a mod n * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= b * (a mod n) + b * (a / n) * n(b * (a mod n) + b * (a / n) * n) mod n == (a mod n * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= b * (a mod n) + b * (a / n) * n(b * (a mod n)) mod n == (a mod n * b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= b * (a mod n) + b * (a / n) * n0 <= b * (a mod n)now rewrite mul_comm.a, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= b * (a mod n) + b * (a / n) * n(b * (a mod n)) mod n == (a mod n * b) mod napply mul_nonneg_nonneg; destruct (mod_bound_pos a n); auto. Qed.a, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= b * (a mod n) + b * (a / n) * n0 <= b * (a mod n)forall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a * (b mod n)) mod n == (a * b) mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a * (b mod n)) mod n == (a * b) mod na, b, n:tH:0 <= aH0:0 <= bH1:0 < n(a * (b mod n)) mod n == (a * b) mod napply mul_mod_idemp_l; auto. Qed.a, b, n:tH:0 <= aH0:0 <= bH1:0 < n(b mod n * a) mod n == (b * a) mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a * b) mod n == (a mod n * (b mod n)) mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a * b) mod n == (a mod n * (b mod n)) mod na, b, n:tH:0 <= aH0:0 <= bH1:0 < n(a * b) mod n == (a mod n * (b mod n)) mod na, b, n:tH:0 <= aH0:0 <= bH1:0 < n(a * b) mod n == (a * b) mod na, b, n:tH:0 <= aH0:0 <= bH1:0 < n0 <= b mod nreflexivity.a, b, n:tH:0 <= aH0:0 <= bH1:0 < n(a * b) mod n == (a * b) mod nnow destruct (mod_bound_pos b n). Qed.a, b, n:tH:0 <= aH0:0 <= bH1:0 < n0 <= b mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a mod n + b) mod n == (a + b) mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a mod n + b) mod n == (a + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n(a mod n + b) mod n == (a + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n(a + b) mod n == (a mod n + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n0 <= a + b -> (a + b) mod n == (a mod n + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n0 <= n * (a / n) + a mod n + b -> (n * (a / n) + a mod n + b) mod n == (a mod n + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < n0 <= a mod n + b + a / n * n -> (a mod n + b + a / n * n) mod n == (a mod n + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= a mod n + b + a / n * n(a mod n + b + a / n * n) mod n == (a mod n + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= a mod n + b + a / n * n(a mod n + b) mod n == (a mod n + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= a mod n + b + a / n * n0 <= a mod n + breflexivity.a, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= a mod n + b + a / n * n(a mod n + b) mod n == (a mod n + b) mod na, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= a mod n + b + a / n * n0 <= a mod n + bdestruct (mod_bound_pos a n); auto. Qed.a, b, n:tHa:0 <= aHb:0 <= bHn:0 < nH:0 <= a mod n + b + a / n * n0 <= a mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a + b mod n) mod n == (a + b) mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a + b mod n) mod n == (a + b) mod na, b, n:tH:0 <= aH0:0 <= bH1:0 < n(a + b mod n) mod n == (a + b) mod napply add_mod_idemp_l; auto. Qed.a, b, n:tH:0 <= aH0:0 <= bH1:0 < n(b mod n + a) mod n == (b + a) mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a + b) mod n == (a mod n + b mod n) mod nforall a b n : t, 0 <= a -> 0 <= b -> 0 < n -> (a + b) mod n == (a mod n + b mod n) mod na, b, n:tH:0 <= aH0:0 <= bH1:0 < n(a + b) mod n == (a mod n + b mod n) mod na, b, n:tH:0 <= aH0:0 <= bH1:0 < n(a + b) mod n == (a + b) mod na, b, n:tH:0 <= aH0:0 <= bH1:0 < n0 <= b mod nreflexivity.a, b, n:tH:0 <= aH0:0 <= bH1:0 < n(a + b) mod n == (a + b) mod nnow destruct (mod_bound_pos b n). Qed.a, b, n:tH:0 <= aH0:0 <= bH1:0 < n0 <= b mod nforall a b c : t, 0 <= a -> 0 < b -> 0 < c -> a / b / c == a / (b * c)forall a b c : t, 0 <= a -> 0 < b -> 0 < c -> a / b / c == a / (b * c)a, b, c:tHa:0 <= aHb:0 < bHc:0 < ca / b / c == a / (b * c)(* begin 0<= ... <b*c *)a, b, c:tHa:0 <= aHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * ca, b, c:tHa:0 <= aHb:0 < bHc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHa:0 <= aHb:0 < bHc:0 < c0 <= b * ((a / b) mod c) + a mod b < b * ca, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < b0 <= b * ((a / b) mod c) + a mod b < b * ca, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < b0 <= b * ((a / b) mod c) + a mod ba, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + a mod b < b * ca, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < b0 <= b * ((a / b) mod c) + a mod bapply mul_nonneg_nonneg; order.a, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < b0 <= b * ((a / b) mod c)a, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + a mod b < b * ca, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + a mod b < b * ((a / b) mod c) + ba, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + b <= b * crewrite <- add_lt_mono_l; auto.a, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + a mod b < b * ((a / b) mod c) + brewrite <- mul_succ_r, <- mul_le_mono_pos_l, le_succ_l; auto. (* end 0<= ... < b*c *)a, b, c:tHa:0 <= aHb:0 < bHc:0 < cH:0 <= (a / b) mod cH0:(a / b) mod c < cH1:0 <= a mod bH2:a mod b < bb * ((a / b) mod c) + b <= b * ca, b, c:tHa:0 <= aHb:0 < bHc:0 < ca == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHa:0 <= aHb:0 < bHc:0 < cb * (a / b) + a mod b == b * c * (a / b / c) + (b * ((a / b) mod c) + a mod b)a, b, c:tHa:0 <= aHb:0 < bHc:0 < cb * (a / b) == b * c * (a / b / c) + b * ((a / b) mod c)apply div_mod; order. Qed.a, b, c:tHa:0 <= aHb:0 < bHc:0 < ca / b == c * (a / b / c) + (a / b) mod cforall a b c : t, 0 <= a -> 0 < b -> 0 < c -> a mod (b * c) == a mod b + b * ((a / b) mod c)forall a b c : t, 0 <= a -> 0 < b -> 0 < c -> a mod (b * c) == a mod b + b * ((a / b) mod c)a, b, c:tHa:0 <= aHb:0 < bHc:0 < ca mod (b * c) == a mod b + b * ((a / b) mod c)a, b, c:tHa:0 <= aHb:0 < bHc:0 < cb * c * (a / (b * c)) + a mod (b * c) == b * c * (a / (b * c)) + (a mod b + b * ((a / b) mod c))a, b, c:tHa:0 <= aHb:0 < bHc:0 < ca == b * c * (a / (b * c)) + (a mod b + b * ((a / b) mod c))a, b, c:tHa:0 <= aHb:0 < bHc:0 < ca == b * c * (a / b / c) + (a mod b + b * ((a / b) mod c))a, b, c:tHa:0 <= aHb:0 < bHc:0 < ca == b * (c * (a / b / c) + (a / b) mod c) + a mod bapply div_mod; order. Qed.a, b, c:tHa:0 <= aHb:0 < bHc:0 < ca == b * (a / b) + a mod b
A last inequality:
forall a b c : t, 0 <= a -> 0 < b -> 0 <= c -> c * (a / b) <= c * a / bforall a b c : t, 0 <= a -> 0 < b -> 0 <= c -> c * (a / b) <= c * a / ba, b, c:tH:0 <= aH0:0 < bH1:0 <= cc * (a / b) <= c * a / ba, b, c:tH:0 <= aH0:0 < bH1:0 <= c0 <= c * aa, b, c:tH:0 <= aH0:0 < bH1:0 <= cb * (c * (a / b)) <= c * aapply mul_nonneg_nonneg; auto.a, b, c:tH:0 <= aH0:0 < bH1:0 <= c0 <= c * aa, b, c:tH:0 <= aH0:0 < bH1:0 <= cb * (c * (a / b)) <= c * aa, b, c:tH:0 <= aH0:0 < bH1:0 <= cc * (b * (a / b)) <= c * aapply mul_div_le; auto. Qed.a, b, c:tH:0 <= aH0:0 < bH1:0 <= cb * (a / b) <= a
mod is related to divisibility
forall a b : t, 0 <= a -> 0 < b -> a mod b == 0 <-> (exists c : t, a == b * c)forall a b : t, 0 <= a -> 0 < b -> a mod b == 0 <-> (exists c : t, a == b * c)a, b:tH:0 <= aH0:0 < ba mod b == 0 -> exists c : t, a == b * ca, b:tH:0 <= aH0:0 < b(exists c : t, a == b * c) -> a mod b == 0a, b:tH:0 <= aH0:0 < ba mod b == 0 -> exists c : t, a == b * ca, b:tH:0 <= aH0:0 < bH1:a mod b == 0exists c : t, a == b * crewrite div_exact; auto.a, b:tH:0 <= aH0:0 < bH1:a mod b == 0a == b * (a / b)a, b:tH:0 <= aH0:0 < b(exists c : t, a == b * c) -> a mod b == 0a, b:tH:0 <= aH0:0 < bc:tHc:a == b * ca mod b == 0a, b:tH:0 <= aH0:0 < bc:tHc:a == b * c(c * b) mod b == 0a, b:tH:0 <= aH0:0 < bc:tHc:a == b * c0 <= ca, b:tH:0 <= aH0:0 < bc:tHc:a == b * cb * 0 <= b * corder. Qed. End NZDivProp.a, b:tH:0 <= aH0:0 < bc:tHc:a == b * c0 <= b * c