(** For decoding and encoing elements of Q: binary sequneces versus pairs of integers. *)
(*** Building the rational number m/n *)
(*** 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.
intros [| p| p].
intros H; abstract discriminate H.
intro.
exact (Qpositive_c (nat_of_P p) 1 (S (nat_of_P p))).
intro; abstract discriminate H.
Defined.
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.
Coercion Z_to_Q : Z >-> Q.
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.
unfold Qlt in |- *; auto with *.