Fixpoint PdivlessAux (bound p base length : positive) {struct length}
 : Option positive * Option positive * nat :=
  match Pcompare bound p Datatypes.Eq with
  | Datatypes.Gt => (Some _ p, None _, 0)
  | _ =>
      match PdivAux p base with
      | (None, None) => (None _, None _, 1)
      | (None, Some r1) => (None _, Some _ r1, 1)
      | (Some q1, None) =>
          match length with
          | xH => (Some _ q1, None _, 0)
          | xO length' =>
              match PdivlessAux bound q1 base length' with
              | (s2, None, n) => (s2, None _, S n)
              | (s2, Some r2, n) =>
                  (s2,
                  Some _
                    ((fun (x : positive)
                        (_ : positive -> positive)
                        (y : positive) => (x * y)%positive) r2
                       (fun x => x) base), S n)
              end
          | xI length' =>
              match PdivlessAux bound q1 base length' with
              | (s2, None, n) => (s2, None _, S n)
              | (s2, Some r2, n) =>
                  (s2,
                  Some _
                    ((fun (x : positive)
                        (_ : positive -> positive)
                        (y : positive) => (x * y)%positive) r2
                       (fun x => x) base), S n)
              end
          end
      | (Some q1, Some r1) =>
          match length with
          | xH => (Some _ q1, None _, 0)
          | xO length' =>
              match PdivlessAux bound q1 base length' with
              | (s2, None, n) => (s2, Some _ r1, S n)
              | (s2, Some r2, n) =>
                  (s2,
                  Some _
                    ((fun (x : positive)
                        (_ : positive -> positive)
                        (y : positive) => x * y) r2 (
                       fun x => x) base + r1)%positive, 
                  S n)
              end
          | xI length' =>
              match PdivlessAux bound q1 base length' with
              | (s2, None, n) => (s2, Some _ r1, S n)
              | (s2, Some r2, n) =>
                  (s2,
                  Some _
                    ((fun (x : positive)
                        (_ : positive -> positive)
                        (y : positive) => x * y) r2 (
                       fun x => x) base + r1)%positive, 
                  S n)
              end
          end
      end
  end.Definition Pdivless := PdivlessAux Pdiv.

(* Specifications: *)
Theorem Pdivless1 : forall bound p q base, Pcompare bound p Datatypes.Eq = Datatypes.Gt -> Pdivless bound p base q = (Some _ p, None _, 0).
Theorem Pdivless2 : forall bound p length base, Pcompare bound p Datatypes.Eq <> Datatypes.Gt -> Pdivless bound p base length = match Pdiv p base with | (None, None) => (None _, None _, 1) | (None, Some r1) => (None _, Some _ r1, 1) | (Some q1, None) => match length with | xH => (Some _ q1, None _, 0) | xO length' => match Pdivless bound q1 base length' with | (s2, None, n) => (s2, None _, S n) | (s2, Some r2, n) => (s2, Some _ ((fun (x : positive) (_ : positive -> positive) (y : positive) => (x * y)%positive) r2 ( fun x => x) base), S n) end | xI length' => match Pdivless bound q1 base length' with | (s2, None, n) => (s2, None _, S n) | (s2, Some r2, n) => (s2, Some _ ((fun (x : positive) (_ : positive -> positive) (y : positive) => (x * y)%positive) r2 ( fun x => x) base), S n) end end | (Some q1, Some r1) => match length with | xH => (Some _ q1, None _, 0) | xO length' => match Pdivless bound q1 base length' with | (s2, None, n) => (s2, Some _ r1, S n) | (s2, Some r2, n) => (s2, Some _ ((fun (x : positive) (_ : positive -> positive) (y : positive) => x * y) r2 ( fun x => x) base + r1)%positive, S n) end | xI length' => match Pdivless bound q1 base length' with | (s2, None, n) => (s2, Some _ r1, S n) | (s2, Some r2, n) => (s2, Some _ ((fun (x : positive) (_ : positive -> positive) (y : positive) => x * y) r2 ( fun x => x) base + r1)%positive, S n) end end end.
Theorem compare_SUP_dec : forall p q : positive, Pcompare p q Datatypes.Eq = Datatypes.Gt \/ Pcompare p q Datatypes.Eq <> Datatypes.Gt.
Theorem odd_even_lem : forall p q, 2 * p + 1 <> 2 * q.
Theorem Pdivless_correct : forall bound p q base, 1 < nat_of_P base -> nat_of_P p <= nat_of_P q -> nat_of_P p = oZ (fst (fst (Pdivless bound p base q))) * exp (nat_of_P base) (snd (Pdivless bound p base q)) + oZ (snd (fst (Pdivless bound p base q))) /\ (oZ (fst (fst (Pdivless bound p base q))) < nat_of_P bound /\ oZ (snd (fst (Pdivless bound p base q))) < exp (nat_of_P base) (snd (Pdivless bound p base q))) /\ (forall bound', nat_of_P bound = nat_of_P base * bound' -> nat_of_P bound <= nat_of_P p -> nat_of_P bound <= nat_of_P base * oZ (fst (fst (Pdivless bound p base q)))).