(** For decoding and encoing elements of Q: binary sequneces versus pairs of integers. *) 


(*** Building the rational number m/n *)
Definition make_Q (m n : Z) :=
  match m, n with
  | Zpos _, Zpos _ =>
      Qpos (Qpositive_c (Z.abs_nat m) (Z.abs_nat n) (Z.abs_nat m + Z.abs_nat n))
  | Zneg _, Zneg _ =>
      Qpos (Qpositive_c (Z.abs_nat m) (Z.abs_nat n) (Z.abs_nat m + Z.abs_nat n))
  | Z0, _ => Zero
  | _, Z0 => Zero (* dummy *) 
  | _, _ =>
      Qneg (Qpositive_c (Z.abs_nat m) (Z.abs_nat n) (Z.abs_nat m + Z.abs_nat n))
  end.(*** decoding a sequnce consisting of dL and nR and ending in One. *) 
Definition decode_Q (q : Q) :=
  match q with
  | Qpos p =>
      (Z_of_nat (fst (Qpositive_i p)), Z_of_nat (snd (Qpositive_i p)))
  | Qneg p =>
      ((- Z_of_nat (fst (Qpositive_i p)))%Z, Z_of_nat (snd (Qpositive_i p)))
  | Zero => (0%Z, 1%Z)
  end.Definition numerator (q:Q) :Z := fst (decode_Q q).Definition denominator (q:Q) :Z := snd (decode_Q q).(** Definition of various functions *) 
Definition Z_to_Qpositive : forall x : Z, (0 < x)%Z -> Qpositive.Definition Z_to_Q (x : Z) : Q :=
  match x with
  | Z0 => Zero
  | Zpos p => Qpos (Qpositive_c (nat_of_P p) 1 (S (nat_of_P p)))
  | Zneg p => Qneg (Qpositive_c (nat_of_P p) 1 (S (nat_of_P p)))
  end.Definition Qpositive_tail (z : Qpositive) :=
  match z with
  | nR p => p
  | dL p => p
  | One => One
  end.Definition Q_tail (z : Q) :=
  match z with
  | Zero => One
  | Qpos p => p
  | Qneg p => p
  end.Definition Qsgn (q : Q) :=
  match q with
  | Zero => 0%Z
  | Qpos _ => 1%Z
  | Qneg _ => (-1)%Z
  end.(** These two only consider the length, we won't use them further *)
Fixpoint length_of_Qpositive_to_positive (qp : Qpositive) : positive :=
  match qp with
  | One => 1%positive
  | dL qp' => Pos.succ (length_of_Qpositive_to_positive qp')
  | nR qp' => Pos.succ (length_of_Qpositive_to_positive qp')
  end.Fixpoint length_of_Qpositive (qp : Qpositive) : Z :=
  match qp with
  | One => 0%Z
  | dL qp' => (1 + length_of_Qpositive qp')%Z
  | nR qp' => (1 + length_of_Qpositive qp')%Z
  end.(** This is the oredr preserving projection from Q to Z *)

Fixpoint Qpositive_to_Z (qp : Qpositive) : Z :=
  match qp with
  | One => 1%Z
  | dL qp' => 0%Z
  | nR qp' => (1 + Qpositive_to_Z qp')%Z
  end.Definition Q_to_Z (x : Q) : Z :=
  match x with
  | Zero => 0%Z
  | Qpos qp => Qpositive_to_Z qp
  | Qneg qp => (- Qpositive_to_Z qp)%Z
  end.Definition Qlt (x y : Q) : Prop := Qgt y x.Definition Qle (x y : Q) : Prop := ~ Qlt y x.

(* Specifications: *)
Lemma Qlt_zero_pos : forall x' : Qpositive, Qlt Zero (Qpos x').
Lemma Qlt_neg_pos : forall x' y' : Qpositive, Qlt (Qneg y') (Qpos x').
Lemma Qlt_neg_zero : forall x' : Qpositive, Qlt (Qneg x') Zero.