(** I should add the definition (like for compare) *)
Notation head0 := head0 (only parsing).Notation tail0 := tail0 (only parsing).Definition iter_sqrt :=
 Eval lazy beta delta [sqrt_step] in
 fix iter_sqrt (n: nat) (rec: int -> int -> int)
          (i j: int) {struct n} : int :=
  sqrt_step
   (fun i j => match n with
      O =>  rec i j
   | S n => (iter_sqrt n (iter_sqrt n rec)) i j
   end) i j.Definition iter2_sqrt :=
 Eval lazy beta delta [sqrt2_step] in
 fix iter2_sqrt (n: nat)
          (rec: int  -> int -> int -> int)
          (ih il j: int) {struct n} : int :=
  sqrt2_step
   (fun ih il j =>
     match n with
     | O =>  rec ih il j
     | S n => (iter2_sqrt n (iter2_sqrt n rec)) ih il j
   end) ih il j.Definition sqrt2 ih il :=
  let s := iter2_sqrt size (fun ih il j => j) ih il max_int in
  let (ih1, il1) := mulc s s in
  match il -c il1 with
  | C0 il2 =>
    if ih1 <? ih then (s, C1 il2) else (s, C0 il2)
  | C1 il2 =>
    if ih1 <? (ih - 1) then (s, C1 il2) else (s, C0 il2)
  end.(** Gcd **)
Fixpoint gcd_rec (guard:nat) (i j:int) {struct guard} :=
   match guard with
   | O => 1
   | S p => if j =? 0 then i else gcd_rec p j (i mod j)
   end.Definition gcd := gcd_rec (2*size).

Lemma eqb_complete : forall x y, x = y -> (x =? y) = true.