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.

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.