Section Int31_Specs.
Local Open Scope Z_scope.
Notation "[| x |]" := (phi x)  (at level 0, x at level 99).
Local Notation wB := (2 ^ (Z.of_nat size)).
Notation "[+| c |]" :=
(interp_carry 1 wB phi c)  (at level 0, c at level 99).
Notation "[-| c |]" :=
(interp_carry (-1) wB phi c)  (at level 0, c at level 99).
Notation "[|| x ||]" :=
(zn2z_to_Z wB phi x)  (at level 0, x at level 99).
(** Subtraction *)
(** Multiplication *)
(** Division *)
Fixpoint addmuldiv31_alt n i j :=
match n with
| O => i
| S n => addmuldiv31_alt n (sneakl (firstl j) i) (shiftl j)
end.
(** Shift operations *)
Fixpoint head031_alt n x :=
match n with
| O => 0%nat
| S n => match firstl x with
| D0 => S (head031_alt n (shiftl x))
| D1 => 0%nat
end
end.
Fixpoint tail031_alt n x :=
match n with
| O => 0%nat
| S n => match firstr x with
| D0 => S (tail031_alt n (shiftr x))
| D1 => 0%nat
end
end.
(* Sqrt *)
(* Direct transcription of an old proof of a fortran program in boyer-moore *)
intros Hj; generalize (spec_div i j Hj).
case div31; intros q r; simpl @fst.
intros (H1,H2); apply Zdiv_unique with [|r|]; auto with zarith.
rewrite H1; ring.
Qed.

Lemma iter312_sqrt_correct n rec ih il j:
2^29 <= [|ih|] ->  0 < [|j|] -> phi2 ih il < ([|j|] + 1) ^ 2 ->
(forall j1, 0 < [|j1|] -> 2^(Z.of_nat n) + [|j1|] <= [|j|] ->
phi2 ih il < ([|j1|] + 1) ^ 2 ->
[|rec ih il j1|] ^ 2 <= phi2 ih il < ([|rec ih il j1|] + 1) ^ 2)  ->
[|iter312_sqrt n rec ih il j|] ^ 2 <= phi2 ih il
< ([|iter312_sqrt n rec ih il j|] + 1) ^ 2.