(* Pythagorean.v *)
(***********************)
(* Pythagorean triples *)
(***********************)
Require Export Tactics.
(* A non nul predicate *)
Definition nnl_triple (a b c : Z) := ~(a = 0) /\ ~(b = 0) /\ ~(c = 0).
(* A positive predicate *)
Definition pos_triple (a b c : Z) := (a >= 0) /\ (b >= 0) /\ (c >= 0).
(* A Pythagorean predicate *)
Definition is_pytha (a b c : Z) := (pos_triple a b c) /\ a * a + b * b = c * c.
(* Unit circle and D_r *)
Definition in_ucirc (x y : R) := (x * x + y * y = 1)%R.
Definition D_r (r x y : R) := (y = r * (x + 1))%R.
(******************************)
(* Set of Pythagorean triples *)
(******************************)
(* step1 *)
(* step 2 *)
(* Intersection between the unit circle and D_r *)
Definition interCDr (r x y : R) := (in_ucirc x y) /\ (D_r r x y).
(* Points of the intersection *)
Definition p1 := (-1,0)%R.
Definition p2 (r : R) :=
let den := (1 + r * r)%R in
((1 - r * r) / den, 2 * r / den)%R.
(* Equality over points *)
Definition eqp (p1 p2 : R * R) := (fst p1) = (fst p2) /\ (snd p1)= (snd p2).
(* step 3 *)
(* step 4 *)
(* Positivity predicate over points *)
Definition is_posp (c : R * R) := (fst c >= 0)%R /\ (snd c >= 0)%R.
(* Predicate for the positive rational coordinates of the unit circle *)
Definition is_ucp (c : R * R) :=
(in_ucirc (fst c) (snd c)) /\ (is_ratp c) /\ (is_posp c).
(* Positive rational coordinates of the unit circle *)
Definition ucp (p q : Z) :=
let pr := (IZR p) in
let qr := (IZR q) in
let den := (pr * pr + qr * qr)%R in
((qr * qr - pr * pr) / den, (2 * pr * qr) / den)%R.
(* A basic condition over p and q *)
Definition cond_pqb (p q : Z) := p >= 0 /\ q > 0 /\ p <= q /\ (rel_prime p q).
(* Set of positive rational coordinates of the unit circle *)
Definition in_ucp_setb (x y : R) :=
exists p : Z, exists q : Z,
x = (fst (ucp p q)) /\ y = (snd (ucp p q)) /\ (cond_pqb p q).
(* Step 5 *)
(* The full condition over p and q *)
Definition cond_pq (p q : Z) := cond_pqb p q /\ (distinct_parity p q).
(* The (new) set of positive rational coordinates of the unit circle *)
Definition in_ucp_set (x y : R) :=
exists p : Z, exists q : Z,
(x = (fst (ucp p q)) /\ y = (snd (ucp p q)) \/
x = (snd (ucp p q)) /\ y = (fst (ucp p q))) /\ (cond_pq p q).
(* step 6 *)
(* The set of Pythagorean triples *)
Definition pytha_set (a b c : Z) :=
exists p : Z, exists q : Z, exists m : Z,
(a = m * (q * q - p * p) /\ b = 2 * m * (p * q) \/
a = 2 * m * (p * q) /\ b = m * (q * q - p * p)) /\
c = m * (p * p + q * q) /\ m >= 0 /\ (cond_pq p q).

Lemma pytha_thm1 : forall a b c : Z, (is_pytha a b c) -> (pytha_set a b c).