Definition bezout_generalized p q : { a : nat 
                                      & { b : nat 
                                      & { g : nat
                                      & { l : nat 
                                        | a*p+b*q = g + l
                                       /\ is_gcd p q g
                                       /\ is_lcm p q l } } } }.Definition gcd p q := proj1_sig (gcd_full p q).Fact gcd_spec p q : is_gcd p q (gcd p q).Definition lcm p q := proj1_sig (lcm_full p q).Fact lcm_spec p q : is_lcm p q (lcm p q).Fact div_full q p : { n : nat & { r | q = n*p+r /\ (p <> 0 -> r < p) } }.Definition rem q p := proj1_sig (projT2 (div_full q p)).Fact div_rem_spec2 q p : p <> 0 -> rem q p < p.Fact rem_0 q : rem q 0 = q.Fact div_rem_uniq p n1 r1 n2 r2 : 
        p <> 0 -> n1*p + r1 = n2*p + r2 -> r1 < p -> r2 < p -> n1 = n2 /\ r1 = r2.Fact rem_prop q p n r : q = n*p+r -> r < p -> rem q p = r.Fact rem_idem q p : q < p -> rem q p = q.Fact is_gcd_rem p n a : is_gcd p n a <-> is_gcd p (rem n p) a.Fact rem_erase q n p r : q = n*p+r -> rem q p = rem r p.Fact divides_rem_eq q p : divides p q <-> rem q p = 0.Fact rem_of_0 p : rem 0 p = 0.Fact divides_dec q p : { k | q = k*p } + { ~ divides p q }.Fact rem_plus_rem a b : rem (a+rem b p) p = rem (a+b) p.Fact rem_mult_rem a b : rem (a*rem b p) p = rem (a*b) p.Fact rem_diag : rem p p = 0.Fact rem_lt a : a < p -> rem a p = a.Fact rem_plus a b : rem (a+b) p = rem (rem a p + rem b p) p.Fact rem_scal k a : rem (k*a) p = rem (k*rem a p) p.Fact rem_plus_div a b : divides p b -> rem a p = rem (a+b) p.Fact rem_2_is_0_or_1 x : rem x 2 = 0 \/ rem x 2 = 1.Fact rem_2_mult x y : rem (x*y) 2 = 1 <-> rem x 2 = 1 /\ rem y 2 = 1.Fact rem_2_fix_0 : rem 0 2 = 0.Fact rem_2_fix_1 n : rem (2*n) 2 = 0.Fact rem_2_fix_2 n : rem (1+2*n) 2 = 1.Fact rem_2_lt n : rem n 2 < 2.Fact euclid_2 n : exists q, n = 2*q \/ n = 1+2*q.

(* Specifications: *)
Theorem CRT u v a b : u <> 0 -> v <> 0 -> is_gcd u v 1 -> exists w, rem w u = rem a u /\ rem w v = rem b v /\ 2 < w.