aboutsummaryrefslogtreecommitdiffstats
path: root/src/versions/standard/Int63/Int63Op_standard.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/versions/standard/Int63/Int63Op_standard.v')
-rw-r--r--src/versions/standard/Int63/Int63Op_standard.v272
1 files changed, 272 insertions, 0 deletions
diff --git a/src/versions/standard/Int63/Int63Op_standard.v b/src/versions/standard/Int63/Int63Op_standard.v
new file mode 100644
index 0000000..933a045
--- /dev/null
+++ b/src/versions/standard/Int63/Int63Op_standard.v
@@ -0,0 +1,272 @@
+(**************************************************************************)
+(* *)
+(* SMTCoq *)
+(* Copyright (C) 2011 - 2015 *)
+(* *)
+(* Chantal Keller *)
+(* *)
+(* from the Int63 library of native-coq *)
+(* by Benjamin Gregoire and Laurent Thery *)
+(* *)
+(* Inria - École Polytechnique - MSR-Inria Joint Lab *)
+(* *)
+(* This file is distributed under the terms of the CeCILL-C licence *)
+(* *)
+(**************************************************************************)
+
+
+Require Export Int63Native.
+Require Import BigNumPrelude.
+Require Import Bvector.
+
+Set Vm Optimize.
+
+
+Local Open Scope int63_scope.
+
+(** The number of digits as a int *)
+Definition digits := 63.
+
+(** The bigger int *)
+Definition max_int := Eval vm_compute in 0 - 1.
+Register max_int as PrimInline.
+
+(** Access to the nth digits *)
+Definition get_digit x p := (0 < (x land (1 << p))).
+
+Definition set_digit x p (b:bool) :=
+ if (0 <= p) && (p < digits) then
+ if b then x lor (1 << p)
+ else x land (max_int lxor (1 << p))
+ else x.
+
+(** Equality to 0 *)
+Definition is_zero (i:int) := i == 0.
+Register is_zero as PrimInline.
+
+(** Parity *)
+Definition is_even (i:int) := is_zero (i land 1).
+Register is_even as PrimInline.
+
+(** Bit *)
+
+Definition bit i n := negb (is_zero ((i >> n) << (digits - 1))).
+(* Register bit as PrimInline. *)
+
+(** Extra modulo operations *)
+Definition opp (i:int) := 0 - i.
+Register opp as PrimInline.
+Notation "- x" := (opp x) : int63_scope.
+
+Definition oppcarry i := max_int - i.
+Register oppcarry as PrimInline.
+
+Definition succ i := i + 1.
+Register succ as PrimInline.
+
+Definition pred i := i - 1.
+Register pred as PrimInline.
+
+Definition addcarry i j := i + j + 1.
+Register addcarry as PrimInline.
+
+Definition subcarry i j := i - j - 1.
+Register subcarry as PrimInline.
+
+(** Exact arithmetic operations *)
+
+Definition addc_def x y :=
+ let r := x + y in
+ if r < x then C1 r else C0 r.
+(* the same but direct implementation for effeciancy *)
+Register addc : int -> int -> carry int as int63_addc.
+Notation "n '+c' m" := (addc n m) (at level 50, no associativity) : int63_scope.
+
+Definition addcarryc_def x y :=
+ let r := addcarry x y in
+ if r <= x then C1 r else C0 r.
+(* the same but direct implementation for effeciancy *)
+Register addcarryc : int -> int -> carry int as int63_addcarryc.
+
+Definition subc_def x y :=
+ if y <= x then C0 (x - y) else C1 (x - y).
+(* the same but direct implementation for effeciancy *)
+Register subc : int -> int -> carry int as int63_subc.
+Notation "n '-c' m" := (subc n m) (at level 50, no associativity) : int63_scope.
+
+Definition subcarryc_def x y :=
+ if y < x then C0 (x - y - 1) else C1 (x - y - 1).
+(* the same but direct implementation for effeciancy *)
+Register subcarryc : int -> int -> carry int as int63_subcarryc.
+
+Definition diveucl_def x y := (x/y, x\%y).
+(* the same but direct implementation for effeciancy *)
+Register diveucl : int -> int -> int * int as int63_diveucl.
+
+Register diveucl_21 : int -> int -> int -> int * int as int63_div21.
+
+Definition addmuldiv_def p x y :=
+ (x << p) lor (y >> (digits - p)).
+Register addmuldiv : int -> int -> int -> int as int63_addmuldiv.
+
+Definition oppc (i:int) := 0 -c i.
+Register oppc as PrimInline.
+
+Definition succc i := i +c 1.
+Register succc as PrimInline.
+
+Definition predc i := i -c 1.
+Register predc as PrimInline.
+
+(** Comparison *)
+Definition compare_def x y :=
+ if x < y then Lt
+ else if (x == y) then Eq else Gt.
+
+Register compare : int -> int -> comparison as int63_compare.
+Notation "n ?= m" := (compare n m) (at level 70, no associativity) : int63_scope.
+
+(** Exotic operations *)
+
+(** I should add the definition (like for compare) *)
+Register head0 : int -> int as int63_head0.
+Register tail0 : int -> int as int63_tail0.
+
+(** Iterators *)
+
+Definition foldi {A} (f:int -> A -> A) from to :=
+ foldi_cont (fun i cont a => cont (f i a)) from to (fun a => a).
+Register foldi as PrimInline.
+
+Definition fold {A} (f: A -> A) from to :=
+ foldi_cont (fun i cont a => cont (f a)) from to (fun a => a).
+Register fold as PrimInline.
+
+Definition foldi_down {A} (f:int -> A -> A) from downto :=
+ foldi_down_cont (fun i cont a => cont (f i a)) from downto (fun a => a).
+Register foldi_down as PrimInline.
+
+Definition fold_down {A} (f:A -> A) from downto :=
+ foldi_down_cont (fun i cont a => cont (f a)) from downto (fun a => a).
+Register fold_down as PrimInline.
+
+Definition forallb (f:int -> bool) from to :=
+ foldi_cont (fun i cont _ => if f i then cont tt else false) from to (fun _ => true) tt.
+
+Definition existsb (f:int -> bool) from to :=
+ foldi_cont (fun i cont _ => if f i then true else cont tt) from to (fun _ => false) tt.
+
+(** Translation to Z *)
+
+Fixpoint to_Z_rec (n:nat) (i:int) :=
+ match n with
+ | O => 0%Z
+ | S n =>
+ (if is_even i then Zdouble else Zdouble_plus_one) (to_Z_rec n (i >> 1))
+ end.
+
+Definition to_Z := to_Z_rec size.
+
+Fixpoint of_pos_rec (n:nat) (p:positive) :=
+ match n, p with
+ | O, _ => 0
+ | S n, xH => 1
+ | S n, xO p => (of_pos_rec n p) << 1
+ | S n, xI p => (of_pos_rec n p) << 1 lor 1
+ end.
+
+Definition of_pos := of_pos_rec size.
+
+Definition of_Z z :=
+ match z with
+ | Zpos p => of_pos p
+ | Z0 => 0
+ | Zneg p => - (of_pos p)
+ 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 \% j)
+ end.
+
+Definition gcd := gcd_rec (2*size).
+
+(** Square root functions using newton iteration **)
+
+Definition sqrt_step (rec: int -> int -> int) (i j: int) :=
+ let quo := i/j in
+ if quo < j then rec i ((j + i/j) >> 1)
+ else j.
+
+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 sqrt i :=
+ match compare 1 i with
+ Gt => 0
+ | Eq => 1
+ | Lt => iter_sqrt size (fun i j => j) i (i >> 1)
+ end.
+
+Definition high_bit := 1 << (digits - 1).
+
+Definition sqrt2_step (rec: int -> int -> int -> int)
+ (ih il j: int) :=
+ if ih < j then
+ let (quo,_) := diveucl_21 ih il j in
+ if quo < j then
+ match j +c quo with
+ | C0 m1 => rec ih il (m1 >> 1)
+ | C1 m1 => rec ih il ((m1 >> 1) + high_bit)
+ end
+ else j
+ else 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.
+
+(* Extra function on equality *)
+
+Definition cast i j :=
+ (if i == j as b return ((b = true -> i = j) -> option (forall P : int -> Type, P i -> P j))
+ then fun Heq : true = true -> i = j =>
+ Some
+ (fun (P : int -> Type) (Hi : P i) =>
+ match Heq (eq_refl true) in (_ = y) return (P y) with
+ | eq_refl => Hi
+ end)
+ else fun _ : false = true -> i = j => None) (eqb_correct i j).
+
+Definition eqo i j :=
+ (if i == j as b return ((b = true -> i = j) -> option (i=j))
+ then fun Heq : true = true -> i = j =>
+ Some (Heq (eq_refl true))
+ else fun _ : false = true -> i = j => None) (eqb_correct i j).