Require Import BigQ.
Import List.

Definition pi_4_approx_low' := 
([encoded data, 4846 characters]
        # [encoded data, 4845 characters])%bigQ
.

Definition pi_4_approx_high' := 
([encoded data, 4846 characters]
        # [encoded data, 4845 characters])%bigQ
.

Fixpoint numden_Rcontfrac_tailrecB (accu: list bigZ) (n1 d1: bigZ) (n2 d2: bigZ) (fuel: nat) {struct fuel}:
  (list bigZ * bigQ * bigQ) :=
  let default := (rev_append accu nil, BigQ.div (BigQ.Qz n1) (BigQ.Qz d1), BigQ.div (BigQ.Qz n2) (BigQ.Qz d2)) in
  match fuel with
  | O => default
  | S fuel' =>
    let '(q1, r1) := BigZ.div_eucl n1 d1 in
    let '(q2, r2) := BigZ.div_eucl n2 d2 in
    match BigZ.eqb q1 q2 with
    | false => default
    | true =>
      let r1_is_zero := BigZ.eqb r1 0 in
      let r2_is_zero := BigZ.eqb r2 0 in
      match Bool.eqb r1_is_zero r2_is_zero with
      | false => default
      | true =>
        match r1_is_zero with
          | true =>
            match BigZ.eqb q1 1 with
              | true => (rev_append accu nil, 1%bigQ, 1%bigQ)
              | false => (rev_append ((q1 - 1)%bigZ :: accu) nil, 1%bigQ, 1%bigQ)
            end
          | false => numden_Rcontfrac_tailrecB (q1 :: accu) d1 r1 d2 r2 fuel'
        end
      end
    end
  end.

Definition Bnum b :=
  match b with
  | BigQ.Qz t => t
  | BigQ.Qq n d =>
    if (d =? BigN.zero)%bigN then 0%bigZ else n
  end.

Definition Bden b :=
  match b with
  | BigQ.Qz _ => 1%bigN
  | BigQ.Qq _ d => if (d =? BigN.zero)%bigN then 1%bigN else d 
  end.

Definition rat_Rcontfrac_tailrecB q1 q2 :=
  numden_Rcontfrac_tailrecB nil (Bnum q1) (BigZ.Pos (Bden q1)) (Bnum q2) (BigZ.Pos (Bden q2)).

Definition pi_4_contfrac :=
  rat_Rcontfrac_tailrecB pi_4_approx_low' pi_4_approx_high' 3000.

(* The following used to fail because of a non canonical representation of 0 in
the bytecode interpreter. Bug reported privately by Tahina Ramananandro. *)
Goal pi_4_contfrac = pi_4_contfrac.
vm_compute.
reflexivity.
Qed.
