Library Digit

Require Export ZArithRing.
Require Export Omega.
Require Export Faux.
Section Pdigit.
Variable n : Z.
Hypothesis nMoreThan1 : (1 < n)%Z.

Let nMoreThanOne := Zlt_1_O _ (Zlt_le_weak _ _ nMoreThan1).
Hint Resolve nMoreThanOne: zarith.

Theorem Zpower_nat_less : forall q : nat, (0 < Zpower_nat n q)%Z.
Hint Resolve Zpower_nat_less: zarith.

Theorem Zpower_nat_monotone_S :
 forall p : nat, (Zpower_nat n p < Zpower_nat n (S p))%Z.

Theorem Zpower_nat_monotone_lt :
 forall p q : nat, p < q -> (Zpower_nat n p < Zpower_nat n q)%Z.
Hint Resolve Zpower_nat_monotone_lt: zarith.

Theorem Zpower_nat_anti_monotone_lt :
 forall p q : nat, (Zpower_nat n p < Zpower_nat n q)%Z -> p < q.

Theorem Zpower_nat_monotone_le :
 forall p q : nat, p <= q -> (Zpower_nat n p <= Zpower_nat n q)%Z.

Theorem Zpower_nat_anti_monotone_le :
 forall p q : nat, (Zpower_nat n p <= Zpower_nat n q)%Z -> p <= q.

Theorem Zpower_nat_anti_eq :
 forall p q : nat, Zpower_nat n p = Zpower_nat n q -> p = q.

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.

Definition digit (q : Z) :=
  match q with
  | Z0 => 0
  | Zpos q' => digitAux (Zabs q) 1 (xO q')
  | Zneg q' => digitAux (Zabs q) 1 (xO q')
  end.
Hint Unfold digit.

Theorem digitAux1 :
 forall p r, (Zpower_nat n (S p) * r)%Z = (Zpower_nat n p * (n * r))%Z.

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.

Theorem digitAuxLess :
 forall (v r : Z) (q : positive),
 match digitAux v r q with
 | S r' => (Zpower_nat n r' * r <= v)%Z
 | O => True
 end.

Theorem digitLess :
 forall q : Z, q <> 0%Z -> (Zpower_nat n (pred (digit q)) <= Zabs q)%Z.
Hint Resolve digitLess: zarith.
Hint Resolve Zmult_gt_0_lt_compat_r Zmult_gt_0_lt_compat_l: zarith.

Fixpoint pos_length (p : positive) : nat :=
  match p with
  | xH => 0
  | xO p' => S (pos_length p')
  | xI p' => S (pos_length p')
  end.

Theorem digitAuxMore :
 forall (v r : Z) (q : positive),
 (0 < r)%Z ->
 (v < Zpower_nat n (pos_length q) * r)%Z ->
 (v < Zpower_nat n (digitAux v r q) * r)%Z.

Theorem pos_length_pow :
 forall p : positive, (Zpos p < Zpower_nat n (S (pos_length p)))%Z.

Theorem digitMore : forall q : Z, (Zabs q < Zpower_nat n (digit q))%Z.
Hint Resolve digitMore: zarith.

Theorem digitInv :
 forall (q : Z) (r : nat),
 (Zpower_nat n (pred r) <= Zabs q)%Z ->
 (Zabs q < Zpower_nat n r)%Z -> digit q = r.

Theorem digitO : digit 0 = 0.

Theorem digit1 : digit 1 = 1.

Theorem digit_monotone :
 forall p q : Z, (Zabs p <= Zabs q)%Z -> digit p <= digit q.
Hint Resolve digit_monotone: arith.

Theorem digitNotZero : forall q : Z, q <> 0%Z -> 0 < digit q.
Hint Resolve Zlt_gt: zarith.

Theorem digitAdd :
 forall (q : Z) (r : nat),
 q <> 0%Z -> digit (q * Zpower_nat n r) = digit q + r.

Theorem digit_minus1 : forall p : nat, digit (Zpower_nat n p - 1) = p.

Theorem digit_bound :
 forall (x y z : Z) (n : nat),
 (Zabs x <= Zabs y)%Z ->
 (Zabs y <= Zabs z)%Z -> digit x = n -> digit z = n -> digit y = n.

Theorem digit_abs : forall p : Z, digit (Zabs p) = digit p.

Theorem digit_anti_monotone_lt :
 (1 < n)%Z -> forall p q : Z, digit p < digit q -> (Zabs p < Zabs q)%Z.
End Pdigit.
Hint Resolve Zpower_nat_less: zarith.
Hint Resolve Zpower_nat_monotone_lt: zarith.
Hint Resolve Zpower_nat_monotone_le: zarith.
Hint Unfold digit.
Hint Resolve digitLess: zarith.
Hint Resolve digitMore: zarith.
Hint Resolve digit_monotone: arith.