Definition positive_fraction_encoding (x y : Z) (Hx : (0 < x)%Z)
  (Hy : (0 < y)%Z) := encoding_algorithm x y Hx Hy (Zminus2_wf x y Hx Hy).(** First we shall define [fraction_encoding], which is extension of [positive_fraction_encoding] to [Q] *)

Definition fraction_encoding (m n : Z) (Hn : n <> 0%Z) : Q.(*
Functional Scheme bog3_ind := Induction for fraction_encoding. 
*)

(*
VERY BIZARRE ERROR: only happens on the first run!
 
Error: In environment
Q : Z->(n:Z)`n <> 0`->Prop
Hyprec :
(m,n:Z; Hn:`n <> 0`;
 s0:({`(Z.sgn m)*(Z.sgn n) < 0`}+{`(Z.sgn m)*(Z.sgn n) > 0`}))
 (Z_dec `(Z.sgn m)*(Z.sgn n)` `0`)
   =(inleft {`(Z.sgn m)*(Z.sgn n) < 0`}+{`(Z.sgn m)*(Z.sgn n) > 0`}
      `(Z.sgn m)*(Z.sgn n) = 0` s0)
 ->(z:`(Z.sgn m)*(Z.sgn n) < 0`)
    s0=(left `(Z.sgn m)*(Z.sgn n) < 0` `(Z.sgn m)*(Z.sgn n) > 0` z)
    ->(Q m n Hn)
m : Z
n : Z
Hn : `n <> 0`
s0 : {`(Z.sgn m)*(Z.sgn n) < 0`}+{`(Z.sgn m)*(Z.sgn n) > 0`}
_eq_ :
(Z_dec `(Z.sgn m)*(Z.sgn n)` `0`)
  =(inleft {`(Z.sgn m)*(Z.sgn n) < 0`}+{`(Z.sgn m)*(Z.sgn n) > 0`}
     `(Z.sgn m)*(Z.sgn n) = 0` s0)
z : `(Z.sgn m)*(Z.sgn n) > 0`
_eq_ :
s0=(right `(Z.sgn m)*(Z.sgn n) < 0` `(Z.sgn m)*(Z.sgn n) > 0` z)
the term (Hyprec m n Hn) has type
(s0:({`(Z.sgn m)*(Z.sgn n) < 0`}+{`(Z.sgn m)*(Z.sgn n) > 0`}))
 (Z_dec `(Z.sgn m)*(Z.sgn n)` `0`)
   =(inleft {`(Z.sgn m)*(Z.sgn n) < 0`}+{`(Z.sgn m)*(Z.sgn n) > 0`}
      `(Z.sgn m)*(Z.sgn n) = 0` s0)
 ->(z:`(Z.sgn m)*(Z.sgn n) < 0`)
    s0=(left `(Z.sgn m)*(Z.sgn n) < 0` `(Z.sgn m)*(Z.sgn n) > 0` z)
    ->(Q m n Hn) which should be Set, Prop or Type.

*)

Ltac Irreflex :=
  try solve
   [ elimtype False;
      match goal with
      | id1:(?X1 <> ?X1) |- _ => apply id1; reflexivity
      | id1:(?X1 < ?X1)%Z |- _ =>
          apply (Z.lt_irrefl X1); assumption
      | id1:(?X1 < ?X2)%Z,id2:(?X1 = ?X2) |- _ =>
          rewrite id2 in id1; apply (Z.lt_irrefl X2); assumption
      | id1:(?X1 < ?X2)%Z,id2:(?X2 = ?X1) |- _ =>
          rewrite id2 in id1; apply (Z.lt_irrefl X1); assumption
      | id1:(?X1 < ?X2)%Z,id2:(?X2 < ?X1)%Z |- _ =>
          apply (Z.lt_irrefl X2); apply Z.lt_trans with X1; assumption
      | id1:_ |- _ => idtac
      end ].(** Proof independence of encoding_algorithm: *) 

Scheme fractionalAcc_ind_dep := Induction for fractionalAcc Sort Prop.

(* Specifications: *)
Lemma encoding_algorithm_equal_1 : forall (a b : Z) (Ha : (0 < a)%Z) (Hb : (0 < b)%Z) (H1 H2 : fractionalAcc a b), encoding_algorithm a b Ha Hb H1 = encoding_algorithm a b Ha Hb H2.
Lemma encoding_algorithm_equal : forall (a b : Z) (Ha1 Ha2 : (0 < a)%Z) (Hb1 Hb2 : (0 < b)%Z) (H1 H2 : fractionalAcc a b), encoding_algorithm a b Ha1 Hb1 H1 = encoding_algorithm a b Ha2 Hb2 H2.
Lemma encoding_algorithm_equal_strong : forall (a1 a2 b1 b2 : Z) (Ha1 : (0 < a1)%Z) (Ha2 : (0 < a2)%Z) (Hb1 : (0 < b1)%Z) (Hb2 : (0 < b2)%Z) (H1 : fractionalAcc a1 b1) (H2 : fractionalAcc a2 b2), a1 = a2 -> b1 = b2 -> encoding_algorithm a1 b1 Ha1 Hb1 H1 = encoding_algorithm a2 b2 Ha2 Hb2 H2.
Lemma encoding_algorithm_0 : forall (m n : Z) (Hm : (0 < m)%Z) (Hn : (0 < n)%Z) (H : fractionalAcc m n), m = n -> encoding_algorithm m n Hm Hn H = One.
Lemma encoding_algorithm_1 : forall (m n : Z) (Hm : (0 < m)%Z) (Hn : (0 < n)%Z) (H : fractionalAcc m n), (m < n)%Z -> forall (H'm : (0 < m)%Z) (H'nm : (0 < n - m)%Z) (H' : fractionalAcc m (n - m)), encoding_algorithm m n Hm Hn H = dL (encoding_algorithm m (n - m) H'm H'nm H').
Lemma encoding_algorithm_2 : forall (m n : Z) (Hm : (0 < m)%Z) (Hn : (0 < n)%Z) (H : fractionalAcc m n), (n < m)%Z -> forall (H'mn : (0 < m - n)%Z) (H'n : (0 < n)%Z) (H' : fractionalAcc (m - n) n), encoding_algorithm m n Hm Hn H = nR (encoding_algorithm (m - n) n H'mn H'n H').
Lemma positive_fraction_encoding_equal : forall (a b : Z) (Ha1 Ha2 : (0 < a)%Z) (Hb1 Hb2 : (0 < b)%Z), positive_fraction_encoding a b Ha1 Hb1 = positive_fraction_encoding a b Ha2 Hb2.
Lemma positive_fraction_encoding_equal_strong : forall (a1 a2 b1 b2 : Z) (Ha1 : (0 < a1)%Z) (Ha2 : (0 < a2)%Z) (Hb1 : (0 < b1)%Z) (Hb2 : (0 < b2)%Z), a1 = a2 -> b1 = b2 -> positive_fraction_encoding a1 b1 Ha1 Hb1 = positive_fraction_encoding a2 b2 Ha2 Hb2.
Lemma positive_fraction_encoding_0 : forall (m n : Z) (Hm : (0 < m)%Z) (Hn : (0 < n)%Z), m = n -> positive_fraction_encoding m n Hm Hn = One.
Lemma positive_fraction_encoding_1 : forall (m n : Z) (Hm : (0 < m)%Z) (Hn : (0 < n)%Z), (m < n)%Z -> forall (H'm : (0 < m)%Z) (H'nm : (0 < n - m)%Z), positive_fraction_encoding m n Hm Hn = dL (positive_fraction_encoding m (n - m) H'm H'nm).
Lemma positive_fraction_encoding_2 : forall (m n : Z) (Hm : (0 < m)%Z) (Hn : (0 < n)%Z), (n < m)%Z -> forall (H'mn : (0 < m - n)%Z) (H'n : (0 < n)%Z), positive_fraction_encoding m n Hm Hn = nR (positive_fraction_encoding (m - n) n H'mn H'n).