Notation "m %/ d" := (divn m d) : nat_scope.
(* We redefine modn so that it is structurally decreasing. *)
Definition modn_rec d := fix loop m := if m - d is m'.+1 then loop m' else m.
Definition modn m d := if d > 0 then modn_rec d.-1 m else m.
Notation "m %% d" := (modn m d) : nat_scope.
Notation "m = n %[mod d ]" := (m %% d = n %% d) : nat_scope.
Notation "m == n %[mod d ]" := (m %% d == n %% d) : nat_scope.
Notation "m <> n %[mod d ]" := (m %% d <> n %% d) : nat_scope.
Notation "m != n %[mod d ]" := (m %% d != n %% d) : nat_scope.

(* Specifications: *)
Lemma modn_def m d : m %% d = (edivn m d).2.
Lemma edivn_def m d : edivn m d = (m %/ d, m %% d).
Lemma mulnK m d : 0 < d -> m * d %/ d = m.
Lemma modn1 m : m %% 1 = 0.
Arguments divnMl [p m d].
Lemma divnMr p m d : p > 0 -> m * p %/ (d * p) = m %/ d.
Lemma ltn_ceil m d : 0 < d -> m < (m %/ d).+1 * d.
Lemma ltn_divLR m n d : d > 0 -> (m %/ d < n) = (m < n * d).
Lemma leq_divRL m n d : d > 0 -> (m <= n %/ d) = (m * d <= n).
Lemma leq_div2l m d e : 0 < d -> d <= e -> m %/ e <= m %/ d.
Lemma leq_divDl p m n : (m + n) %/ p <= m %/ p + n %/ p + 1.
Lemma geq_divBl k m p : k %/ p - m %/ p <= (k - m) %/ p + 1.
Lemma divnMA m n p : m %/ (n * p) = m %/ n %/ p.
Lemma divnAC m n p : m %/ n %/ p =  m %/ p %/ n.
Lemma muln_modr {p m d} : 0 < p -> p * (m %% d) = (p * m) %% (p * d).
Lemma muln_modl {p m d} : 0 < p -> (m %% d) * p = (m * p) %% (d * p).
Lemma eqn_modDr p m n d : (m + p == n + p %[mod d]) = (m == n %[mod d]).
Lemma modnXm m n a : (a %% n) ^ m = a ^ m %[mod n].
Definition dvdn d m := m %% d == 0.