package alt-ergo-lib

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file zarithNumbers.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
(******************************************************************************)
(*                                                                            *)
(*     The Alt-Ergo theorem prover                                            *)
(*     Copyright (C) 2006-2013                                                *)
(*                                                                            *)
(*     Sylvain Conchon                                                        *)
(*     Evelyne Contejean                                                      *)
(*                                                                            *)
(*     Francois Bobot                                                         *)
(*     Mohamed Iguernelala                                                    *)
(*     Stephane Lescuyer                                                      *)
(*     Alain Mebsout                                                          *)
(*                                                                            *)
(*     CNRS - INRIA - Universite Paris Sud                                    *)
(*                                                                            *)
(*     This file is distributed under the terms of the Apache Software        *)
(*     License version 2.0                                                    *)
(*                                                                            *)
(*  ------------------------------------------------------------------------  *)
(*                                                                            *)
(*     Alt-Ergo: The SMT Solver For Software Verification                     *)
(*     Copyright (C) 2013-2018 --- OCamlPro SAS                               *)
(*                                                                            *)
(*     This file is distributed under the terms of the Apache Software        *)
(*     License version 2.0                                                    *)
(*                                                                            *)
(******************************************************************************)

(** Integers implementation. Based on Zarith's integers **)
module Z : NumbersInterface.ZSig with type t = Z.t = struct

  type t = Z.t

  let zero           = Z.zero
  let one            = Z.one
  let m_one          = Z.minus_one

  let compare a b    = Z.compare a b
  let compare_to_0 t = Z.sign t
  let equal   a b    = Z.equal a b
  let sign t         = Z.sign t
  let hash t         = Z.hash t

  let is_zero t      = compare_to_0 t = 0
  let is_one  t      = equal t one
  let is_m_one t     = equal t m_one

  let add a b     = Z.add a b
  let sub a b     = Z.sub a b
  let mult a b    = Z.mul a b
  let div a b     = assert (not (is_zero b)); Z.div a b
  let rem a b     = assert (not (is_zero b)); Z.rem a b
  let div_rem a b = assert (not (is_zero b)); Z.div_rem a b
  let minus t     = Z.neg t
  let abs t       = Z.abs t
  let max t1 t2   = Z.max t1 t2
  let from_int n    = Z.of_int n
  let from_string s = Z.of_string s
  let to_string t   = Z.to_string t
  let print fmt z   = Format.fprintf fmt "%s" (to_string z)

  let my_gcd a b =
    if is_zero a then b
    else if is_zero b then a
    else Z.gcd a b

  let my_lcm a b =
    try
      let res1 = Z.lcm a b in
      assert (equal res1 (div (mult a b) (my_gcd a b)));
      res1
    with Division_by_zero -> assert false

  let to_machine_int t =
    try Some (Z.to_int t) with Z.Overflow -> None

  (* These functuons are not exported, but they are used by module Q below *)
  let to_float z = Z.to_float z
  let fdiv z1 z2 = assert (not (is_zero z2)); Z.fdiv z1 z2
  let cdiv z1 z2 = assert (not (is_zero z2)); Z.cdiv z1 z2
  let power z n  =
    assert (n >= 0);
    Z.pow z n

  (* Shifts left by (n:int >= 0) bits. This is the same as t * pow(2,n) *)
  let shift_left = Z.shift_left

  (* returns sqrt truncated with the remainder. It assumes that the argument
     is positive, otherwise, [Invalid_argument] is raised. *)
  let sqrt_rem = Z.sqrt_rem

  let testbit z n =
    assert (n >= 0);
    Z.testbit z n

  let numbits = Z.numbits

end


(** Rationals implementation. Based on Zarith's rationals **)
module Q : NumbersInterface.QSig with module Z = Z = struct

  module Z = Z
  exception Not_a_float

  type t = Q.t

  let num t  = Q.num t
  let den t  = Q.den t

  let zero   = Q.zero
  let one    = Q.one
  let m_one  = Q.minus_one

  let compare t1 t2  = Q.compare t1 t2
  let compare_to_0 t = Q.sign t
  let equal t1 t2    = Q.equal t1 t2
  let sign t         = Q.sign t
  let hash t         = 13 * Z.hash (num t) + 23 * Z.hash (den t)

  let is_zero t  = compare_to_0 t = 0
  let is_one  t  = equal t one
  let is_m_one t = equal t m_one
  let is_int t   = Z.is_one (den t)

  let add t1 t2  = Q.add t1 t2
  let sub t1 t2  = Q.sub t1 t2
  let mult t1 t2 = Q.mul t1 t2
  let div t1 t2  = assert (not (is_zero t2)); Q.div t1 t2
  let minus t    = Q.neg t
  let abs t      = Q.abs t
  let min t1 t2  = Q.min t1 t2
  let max t1 t2  = Q.max t1 t2

  let inv t      =
    if Z.is_zero (num t) then raise Division_by_zero;
    Q.inv t

  let from_int n    = Q.of_int n
  let from_z z      = Q.make z Z.one
  let from_zz z1 z2 = Q.make z1 z2
  let from_string s = Q.of_string s
  let from_float f  =
    if f = infinity || f = neg_infinity then raise Not_a_float;
    Q.of_float f

  let to_string t = Q.to_string t
  let to_z q      = assert (is_int q); num q
  let to_float t  = (Z.to_float (num t)) /. (Z.to_float (den t))
  let print fmt q = Format.fprintf fmt "%s" (to_string q)

  let floor t      = from_z (Z.fdiv (num t) (den t))
  let ceiling t    = from_z (Z.cdiv (num t) (den t))
  let power t n    =
    let abs_n = Stdlib.abs n in
    let num_pow = Z.power (num t) abs_n in
    let den_pow = Z.power (den t) abs_n in
    if n >= 0 then from_zz num_pow den_pow else from_zz den_pow num_pow

  let modulo t1 t2 =
    assert (is_int t1 && is_int t2);
    from_zz (Z.rem (num t1) (num t2)) Z.one

  (* converts the argument to an integer by truncation. *)
  let truncate = Q.to_bigint

  let mult_2exp = Q.mul_2exp

  let div_2exp = Q.div_2exp

end
OCaml

Innovation. Community. Security.