Section Pdigit.
(* n is the base *)
Variable n : Z.
(* and it is greater or equal to 2 *)
Hypothesis nMoreThan1 : (1 < n)%Z.
Let nMoreThanOne := Zlt_1_O _ (Zlt_le_weak _ _ nMoreThan1).
Hint Resolve nMoreThanOne: zarith.
intros q; elim q; simpl in |- *;
auto with zarith.
Qed.
Hint Resolve Zpower_nat_less: zarith.
intros p; rewrite <- (Zmult_1_l (Zpower_nat n p)); replace (S p) with (1 + p);
[ rewrite Zpower_nat_is_exp | auto with zarith ].
rewrite Zpower_nat_1; auto with zarith.
apply Zmult_gt_0_lt_compat_r; auto with zarith.
apply Z.lt_gt; auto with zarith.
Qed.
intros p q H'; elim H'; simpl in |- *; auto.
apply Zpower_nat_monotone_S.
intros m H H0; apply Z.lt_trans with (1 := H0).
apply Zpower_nat_monotone_S.
Qed.
Hint Resolve Zpower_nat_monotone_lt: zarith.
intros p q H'.
case (le_or_lt q p); auto; (intros H'1; generalize H'; case H'1).
intros H'0; Contradict H'0; auto with zarith.
intros m H'0 H'2; Contradict H'2; auto with zarith.
Qed.
intros p q H'; case (le_lt_or_eq _ _ H'); auto with zarith.
intros H1; rewrite H1; auto with zarith.
Qed.
intros p q H'; case (le_or_lt p q); intros H'0; auto with arith.
Contradict H'; auto with zarith.
Qed.
intros p q H'; apply le_antisym; apply Zpower_nat_anti_monotone_le;
rewrite H'; auto with zarith.
Qed.
(* To compute the number of digits structurally, we suppose that we know already an upper bound q. So we start from q down to 0 to find the bigger exponent r such that n^(r-1) < v *)
Fixpoint digitAux (v r : Z) (q : positive) {struct q} : nat :=
match q with
| xH => 0
| xI q' =>
match (n * r)%Z with
| r' =>
match (r ?= v)%Z with
| Datatypes.Gt => 0
| _ => S (digitAux v r' q')
end
end
| xO q' =>
match (n * r)%Z with
| r' =>
match (r ?= v)%Z with
| Datatypes.Gt => 0
| _ => S (digitAux v r' q')
end
end
end.
(* As we know that log_n q < log_2 q we can define our function digit*)
Definition digit (q : Z) :=
match q with
| Z0 => 0
| Zpos q' => digitAux (Z.abs q) 1 (xO q')
| Zneg q' => digitAux (Z.abs q) 1 (xO q')
end.
Hint Unfold digit.
intros p r; replace (S p) with (1 + p);
[ rewrite Zpower_nat_is_exp | auto with arith ].
rewrite Zpower_nat_1; ring.
Qed.

Theorem Zcompare_correct :
forall p q : Z,
match (p ?= q)%Z with
| Datatypes.Gt => (q < p)%Z
| Datatypes.Lt => (p < q)%Z
| Datatypes.Eq => p = q
end.