z3 0.0.20160427 → 0.0.20161008
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/Rakefile +56 -0
- data/examples/bit_tricks +21 -38
- data/examples/circuit_problems +170 -0
- data/lib/z3/ast.rb +21 -3
- data/lib/z3/context.rb +9 -7
- data/lib/z3/exception.rb +1 -2
- data/lib/z3/expr/arith_expr.rb +29 -11
- data/lib/z3/expr/array_expr.rb +5 -0
- data/lib/z3/expr/bitvec_expr.rb +293 -13
- data/lib/z3/expr/bool_expr.rb +30 -6
- data/lib/z3/expr/expr.rb +155 -2
- data/lib/z3/expr/float_expr.rb +185 -0
- data/lib/z3/expr/int_expr.rb +20 -5
- data/lib/z3/expr/real_expr.rb +1 -3
- data/lib/z3/expr/rounding_mode_expr.rb +5 -0
- data/lib/z3/expr/set_expr.rb +66 -0
- data/lib/z3/func_decl.rb +5 -5
- data/lib/z3/goal.rb +64 -0
- data/lib/z3/interface.rb +21 -222
- data/lib/z3/low_level.rb +84 -58
- data/lib/z3/low_level_auto.rb +1509 -1563
- data/lib/z3/model.rb +39 -37
- data/lib/z3/printer.rb +54 -12
- data/lib/z3/probe.rb +69 -0
- data/lib/z3/solver.rb +20 -20
- data/lib/z3/sort/array_sort.rb +24 -0
- data/lib/z3/sort/bitvec_sort.rb +1 -1
- data/lib/z3/sort/float_sort.rb +92 -0
- data/lib/z3/sort/rounding_mode_sort.rb +41 -0
- data/lib/z3/sort/set_sort.rb +31 -0
- data/lib/z3/sort/sort.rb +39 -5
- data/lib/z3/tactic.rb +69 -0
- data/lib/z3/very_low_level.rb +33 -29
- data/lib/z3/very_low_level_auto.rb +505 -517
- data/lib/z3.rb +13 -0
- data/spec/array_expr_spec.rb +18 -0
- data/spec/array_sort_spec.rb +11 -0
- data/spec/bitvec_expr_spec.rb +196 -44
- data/spec/bitvec_sort_spec.rb +29 -27
- data/spec/bool_expr_spec.rb +57 -55
- data/spec/bool_sort_spec.rb +17 -15
- data/spec/coverage_helper.rb +11 -0
- data/spec/expr_spec.rb +151 -147
- data/spec/float_expr_spec.rb +167 -0
- data/spec/float_sort_spec.rb +44 -0
- data/spec/goal_spec.rb +17 -0
- data/spec/int_expr_spec.rb +76 -63
- data/spec/int_sort_spec.rb +16 -14
- data/spec/integration/algebra_problems_spec.rb +4 -4
- data/spec/integration/cicruit_problem_spec.rb +23 -0
- data/spec/integration/geometry_problem_spec.rb +4 -4
- data/spec/integration/kinematics_problems_spec.rb +3 -3
- data/spec/model_spec.rb +39 -37
- data/spec/printer_spec.rb +49 -18
- data/spec/probe_spec.rb +17 -0
- data/spec/real_expr_spec.rb +59 -51
- data/spec/real_sort_spec.rb +22 -20
- data/spec/rounding_mode_expr_spec.rb +16 -0
- data/spec/rounding_mode_sort_spec.rb +13 -0
- data/spec/set_expr_spec.rb +61 -0
- data/spec/set_sort_spec.rb +27 -0
- data/spec/solver_spec.rb +37 -27
- data/spec/sort_spec.rb +38 -36
- data/spec/spec_helper.rb +59 -2
- data/spec/tactic_spec.rb +9 -0
- metadata +44 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f77923728739173352acc32c2b86d15d158df0aa
|
4
|
+
data.tar.gz: 6d14bf2597324dfaeb56fef62126466a80312b59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c298ac6d9809173f284ac05ae13e19a52cebd56cff557f36894a6b8e5168f68bcfee71e1652ae3848d7009a2572bcdc3663e858e66f808b8c8a112f8a1a25bf
|
7
|
+
data.tar.gz: cf216b75b22a6c172f06613972a8d1c0644efee56ea1462df24d040aa189b58558d594d84156ba1e3ebc3e23b24fc4371faa661f519aecd8e2fa0afe47c98da9
|
data/.rspec
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
task "default" => "spec"
|
4
|
+
task "test" => "spec"
|
5
|
+
task "test:integration" => "spec:integration"
|
6
|
+
task "test:unit" => "spec:unit"
|
7
|
+
|
8
|
+
desc "Regenerate API"
|
9
|
+
task "api" do
|
10
|
+
system "./api/gen_api api/definitions.h"
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Clean up"
|
14
|
+
task "clean" do
|
15
|
+
system "trash z3-*.gem coverage"
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Run tests"
|
19
|
+
task "spec" do
|
20
|
+
system "rspec"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Run unit tests"
|
24
|
+
task "spec:unit" do
|
25
|
+
system "rspec spec/*_spec.rb"
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Run integration tests"
|
29
|
+
task "spec:integration" do
|
30
|
+
system "rspec spec/integration/*_spec.rb"
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Build gem"
|
34
|
+
task "gem:build" do
|
35
|
+
system "gem build z3.gemspec"
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Upload gem"
|
39
|
+
task "gem:push" => "gem:build" do
|
40
|
+
gem_file = Dir["z3-*.gem"][-1] or raise "No gem found"
|
41
|
+
system "gem", "push", gem_file
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Report missing APIs"
|
45
|
+
task "coverage:missing" do
|
46
|
+
system "COVERAGE=1 rake test"
|
47
|
+
data = JSON.load(open("coverage/.resultset.json"))["RSpec"]["coverage"]
|
48
|
+
lla_path = data.keys.find{|k| k.end_with?("lib/z3/low_level_auto.rb")}
|
49
|
+
coverage = data[lla_path].zip(File.readlines(lla_path).map(&:strip))
|
50
|
+
missing = coverage.each_cons(2).map(&:flatten).select{|_,_,bc,_| bc == 0}.map{|_,a,_,_| a.sub(/\Adef /, "")}
|
51
|
+
# Also missing is everything that uses too fancy calling convention for automated generation
|
52
|
+
# That's currently 60 functions
|
53
|
+
open("missing_apis.txt", "w") do |file|
|
54
|
+
file.puts missing
|
55
|
+
end
|
56
|
+
end
|
data/examples/bit_tricks
CHANGED
@@ -2,15 +2,21 @@
|
|
2
2
|
|
3
3
|
require_relative "../lib/z3"
|
4
4
|
|
5
|
+
def c_boolean(expr)
|
6
|
+
one = Z3::BitvecSort.new(32).from_const(1)
|
7
|
+
zero = Z3::BitvecSort.new(32).from_const(0)
|
8
|
+
expr.ite(one, zero)
|
9
|
+
end
|
10
|
+
|
5
11
|
def validate_sign_by_shift!
|
6
12
|
"""
|
7
13
|
sign = v >> (sizeof(int) * CHAR_BIT - 1);
|
8
14
|
"""
|
9
15
|
solver = Z3::Solver.new
|
10
16
|
v = Z3.Bitvec("v", 32)
|
11
|
-
s = v
|
17
|
+
s = v.signed_rshift(31)
|
12
18
|
puts "Validating sign trick:"
|
13
|
-
solver.prove! ((
|
19
|
+
solver.prove! (v.signed_lt(0) & (s == -1)) | (v.signed_ge(0) & (s == 0))
|
14
20
|
end
|
15
21
|
|
16
22
|
def validate_opposite_sign_by_xor!
|
@@ -21,15 +27,15 @@ def validate_opposite_sign_by_xor!
|
|
21
27
|
solver = Z3::Solver.new
|
22
28
|
x = Z3.Bitvec("x", 32)
|
23
29
|
y = Z3.Bitvec("y", 32)
|
24
|
-
f = (x^y)
|
30
|
+
f = (x^y).signed_lt(0)
|
25
31
|
|
26
32
|
puts "Validating sign trick:"
|
27
33
|
solver.prove!(
|
28
34
|
Z3.Or(
|
29
|
-
Z3.And(x
|
30
|
-
Z3.And(x
|
31
|
-
Z3.And(x
|
32
|
-
Z3.And(x
|
35
|
+
Z3.And(x.signed_ge(0), y.signed_ge(0), f == false),
|
36
|
+
Z3.And(x.signed_lt(0), y.signed_lt(0), f == false),
|
37
|
+
Z3.And(x.signed_ge(0), y.signed_lt(0), f == true),
|
38
|
+
Z3.And(x.signed_lt(0), y.signed_ge(0), f == true),
|
33
39
|
)
|
34
40
|
)
|
35
41
|
end
|
@@ -43,14 +49,11 @@ def validate_abs_without_branching_1!
|
|
43
49
|
"""
|
44
50
|
solver = Z3::Solver.new
|
45
51
|
v = Z3.Bitvec("v", 32)
|
46
|
-
mask = v
|
52
|
+
mask = v.signed_rshift(31)
|
47
53
|
r = (v + mask) ^ mask
|
48
54
|
puts "Validating abs without branching, version 1"
|
49
55
|
solver.prove!(
|
50
|
-
|
51
|
-
Z3.And(v >= 0, r==v),
|
52
|
-
Z3.And(v < 0, r==-v)
|
53
|
-
)
|
56
|
+
v.signed_ge(0).ite(r == v, r == -v)
|
54
57
|
)
|
55
58
|
end
|
56
59
|
|
@@ -63,28 +66,14 @@ def validate_abs_without_branching_2!
|
|
63
66
|
"""
|
64
67
|
solver = Z3::Solver.new
|
65
68
|
v = Z3.Bitvec("v", 32)
|
66
|
-
mask = v
|
69
|
+
mask = v.signed_rshift(31)
|
67
70
|
r = (v^mask) - mask
|
68
71
|
puts "Validating abs without branching, version 2"
|
69
72
|
solver.prove!(
|
70
|
-
|
71
|
-
Z3.And(v >= 0, r==v),
|
72
|
-
Z3.And(v < 0, r==-v)
|
73
|
-
)
|
73
|
+
v.signed_ge(0).ite(r == v, r == -v)
|
74
74
|
)
|
75
75
|
end
|
76
76
|
|
77
|
-
def c_boolean(solver, bool_expr, name)
|
78
|
-
expr_val = Z3.Bitvec(name, 32)
|
79
|
-
solver.assert(
|
80
|
-
Z3.Or(
|
81
|
-
Z3.And(bool_expr, expr_val == 1),
|
82
|
-
Z3.And(~bool_expr, expr_val == 0),
|
83
|
-
)
|
84
|
-
)
|
85
|
-
expr_val
|
86
|
-
end
|
87
|
-
|
88
77
|
def validate_min_without_branching!
|
89
78
|
"""
|
90
79
|
int x; // we want to find the minimum of x and y
|
@@ -95,13 +84,10 @@ def validate_min_without_branching!
|
|
95
84
|
solver = Z3::Solver.new
|
96
85
|
x = Z3.Bitvec("x", 32)
|
97
86
|
y = Z3.Bitvec("y", 32)
|
98
|
-
r = y ^ ((x ^ y) & -c_boolean(
|
87
|
+
r = y ^ ((x ^ y) & -c_boolean(x.signed_lt(y)))
|
99
88
|
puts "Validating min without branching"
|
100
89
|
solver.prove!(
|
101
|
-
|
102
|
-
Z3.And(x <= y, r == x),
|
103
|
-
Z3.And(y <= y, r == y),
|
104
|
-
)
|
90
|
+
x.signed_le(y).ite(r == x, r == y)
|
105
91
|
)
|
106
92
|
end
|
107
93
|
|
@@ -115,13 +101,10 @@ def validate_max_without_branching!
|
|
115
101
|
solver = Z3::Solver.new
|
116
102
|
x = Z3.Bitvec("x", 32)
|
117
103
|
y = Z3.Bitvec("y", 32)
|
118
|
-
r = x ^ ((x ^ y) & -c_boolean(
|
104
|
+
r = x ^ ((x ^ y) & -c_boolean(x.signed_lt(y)))
|
119
105
|
puts "Validating max without branching"
|
120
106
|
solver.prove!(
|
121
|
-
|
122
|
-
Z3.And(x >= y, r == x),
|
123
|
-
Z3.And(y >= y, r == y),
|
124
|
-
)
|
107
|
+
x.signed_ge(y).ite(r == x, r == y)
|
125
108
|
)
|
126
109
|
end
|
127
110
|
|
@@ -0,0 +1,170 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative "../lib/z3"
|
4
|
+
|
5
|
+
# It's totally possible everything is backwards
|
6
|
+
class CircuitProblem
|
7
|
+
def initialize
|
8
|
+
@solver = Z3::Solver.new
|
9
|
+
@pins = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def battery(name, battery_voltage)
|
13
|
+
plus = create_pin("#{name}+")
|
14
|
+
minus = create_pin("#{name}-")
|
15
|
+
current = create_current("#{name}", "#{name}+", "#{name}-")
|
16
|
+
@solver.assert plus[:voltage] - minus[:voltage] == battery_voltage
|
17
|
+
end
|
18
|
+
|
19
|
+
def resistor(name, resistance)
|
20
|
+
a = create_pin("#{name}a")
|
21
|
+
b = create_pin("#{name}b")
|
22
|
+
current = create_current("#{name}", "#{name}a", "#{name}b")
|
23
|
+
# dV = RI
|
24
|
+
@solver.assert (a[:voltage] - b[:voltage]) == current * resistance
|
25
|
+
end
|
26
|
+
|
27
|
+
# This is super simple diode model
|
28
|
+
def diode(name)
|
29
|
+
a = create_pin("#{name}+")
|
30
|
+
b = create_pin("#{name}-")
|
31
|
+
current = create_current("#{name}", "#{name}+", "#{name}-")
|
32
|
+
# * current can't flow backwards
|
33
|
+
# * if voltage is reversed, current is stopped (infinite resistance)
|
34
|
+
# * if current is flowing, voltage is equalized (zero resistance)
|
35
|
+
# * voltage is same or current is zero
|
36
|
+
@solver.assert current >= 0
|
37
|
+
@solver.assert a[:voltage] <= b[:voltage]
|
38
|
+
# @solver.assert Z3.Implies(current > 0, a[:voltage] == b[:voltage])
|
39
|
+
# @solver.assert Z3.Implies(a[:voltage] < b[:voltage], current == 0)
|
40
|
+
@solver.assert Z3.Or(a[:voltage] == b[:voltage], current == 0)
|
41
|
+
end
|
42
|
+
|
43
|
+
def connect(a, b)
|
44
|
+
create_current("Wire #{a} #{b}", a, b)
|
45
|
+
@solver.assert @pins[a][:voltage] == @pins[b][:voltage]
|
46
|
+
end
|
47
|
+
|
48
|
+
def solve!(*vars)
|
49
|
+
setup_flow_rules!
|
50
|
+
with_solved_model do |model|
|
51
|
+
model.each do |n,v|
|
52
|
+
next unless vars.include?(n.to_s)
|
53
|
+
puts "* #{n} = #{v}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def debug!
|
59
|
+
setup_flow_rules!
|
60
|
+
with_solved_model do |model|
|
61
|
+
model.each do |n,v|
|
62
|
+
puts "* #{n} = #{v}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def ground(name)
|
68
|
+
@solver.assert @pins[name][:voltage] == 0
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def with_solved_model
|
74
|
+
if @solver.check == :sat
|
75
|
+
yield @solver.model
|
76
|
+
else
|
77
|
+
puts "Can't solve the problem"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def setup_flow_rules!
|
82
|
+
@pins.each do |name, pin|
|
83
|
+
# All current flows are equal
|
84
|
+
@solver.assert Z3.Add(*pin[:current]) == 0
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_pin(name)
|
89
|
+
raise "Pin named #{name} already exists" if @pins[name]
|
90
|
+
@pins[name] = {
|
91
|
+
voltage: Z3.Real("V #{name}"),
|
92
|
+
current: [],
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def create_current(name, source, sink)
|
97
|
+
raise "No such pin: #{source}" unless @pins[source]
|
98
|
+
raise "No such pin: #{sink}" unless @pins[sink]
|
99
|
+
current = Z3.Real("I #{name}")
|
100
|
+
@pins[source][:current] << current
|
101
|
+
@pins[sink][:current] << -current
|
102
|
+
current
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# http://physics.info/circuits-r/practice.shtml
|
107
|
+
def problem_1!
|
108
|
+
problem = CircuitProblem.new
|
109
|
+
problem.battery "V", 125
|
110
|
+
problem.ground "V-"
|
111
|
+
problem.resistor "R1", 20
|
112
|
+
problem.resistor "R2", 30
|
113
|
+
problem.resistor "R3", 50
|
114
|
+
problem.connect "V-", "R1a"
|
115
|
+
problem.connect "R1b", "R2a"
|
116
|
+
problem.connect "R2b", "R3a"
|
117
|
+
problem.connect "R3b", "V+"
|
118
|
+
problem.solve! "I V"
|
119
|
+
end
|
120
|
+
|
121
|
+
def problem_2!
|
122
|
+
problem = CircuitProblem.new
|
123
|
+
problem.battery "V", 125
|
124
|
+
problem.ground "V-"
|
125
|
+
problem.resistor "R1", 20
|
126
|
+
problem.resistor "R2", 100
|
127
|
+
problem.resistor "R3", 50
|
128
|
+
problem.connect "V-", "R1a"
|
129
|
+
problem.connect "V-", "R2a"
|
130
|
+
problem.connect "V-", "R3a"
|
131
|
+
problem.connect "V+", "R1b"
|
132
|
+
problem.connect "V+", "R2b"
|
133
|
+
problem.connect "V+", "R3b"
|
134
|
+
problem.solve! "I V"
|
135
|
+
end
|
136
|
+
|
137
|
+
def problem_3!
|
138
|
+
# V+ [ D1 -> ] La
|
139
|
+
# V- [ D2 -> ] La
|
140
|
+
# V+ [ D3 <- ] Lb
|
141
|
+
# V- [ D4 <- ] Lb
|
142
|
+
[100, 50, 0, -50, -100].each do |v|
|
143
|
+
problem = CircuitProblem.new
|
144
|
+
problem.battery "V", v
|
145
|
+
problem.ground "V-"
|
146
|
+
problem.resistor "L", 100
|
147
|
+
problem.diode "D1"
|
148
|
+
problem.diode "D2"
|
149
|
+
problem.diode "D3"
|
150
|
+
problem.diode "D4"
|
151
|
+
problem.connect "D1-", "V+"
|
152
|
+
problem.connect "D1+", "La"
|
153
|
+
problem.connect "D2-", "V-"
|
154
|
+
problem.connect "D2+", "La"
|
155
|
+
problem.connect "D3-", "Lb"
|
156
|
+
problem.connect "D3+", "V+"
|
157
|
+
problem.connect "D4-", "Lb"
|
158
|
+
problem.connect "D4+", "V-"
|
159
|
+
problem.solve! "I V", "I L"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
puts "Problem 1"
|
164
|
+
problem_1!
|
165
|
+
puts ""
|
166
|
+
puts "Problem 2"
|
167
|
+
problem_2!
|
168
|
+
puts ""
|
169
|
+
puts "Problem 3"
|
170
|
+
problem_3!
|
data/lib/z3/ast.rb
CHANGED
@@ -16,16 +16,34 @@ module Z3
|
|
16
16
|
5 => :func_decl,
|
17
17
|
1000 => :unknown,
|
18
18
|
}
|
19
|
-
kind_id =
|
19
|
+
kind_id = LowLevel.get_ast_kind(self)
|
20
20
|
ast_kind_lookup[kind_id] or raise Z3::Exception, "Unknown AST kind #{kind_id}"
|
21
21
|
end
|
22
22
|
|
23
|
+
def func_decl
|
24
|
+
raise Z3::Exception, "Only app ASTs can have func decls" unless ast_kind == :app
|
25
|
+
FuncDecl.new(LowLevel::get_app_decl(self))
|
26
|
+
end
|
27
|
+
|
28
|
+
def arguments
|
29
|
+
raise Z3::Exception, "Only app ASTs can have arguments" unless ast_kind == :app
|
30
|
+
num = LowLevel::get_app_num_args(self)
|
31
|
+
(0...num).map do |i|
|
32
|
+
_ast = LowLevel::get_app_arg(self, i)
|
33
|
+
Expr.new_from_pointer(_ast)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
23
37
|
def to_s
|
24
|
-
|
38
|
+
Printer.new.format(self)
|
25
39
|
end
|
26
40
|
|
27
41
|
def sexpr
|
28
|
-
|
42
|
+
LowLevel.ast_to_string(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def simplify
|
46
|
+
sort.new(LowLevel.simplify(self))
|
29
47
|
end
|
30
48
|
|
31
49
|
private_class_method :new
|
data/lib/z3/context.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Z3
|
2
|
+
class Context
|
3
|
+
attr_reader :_context
|
4
|
+
def initialize
|
5
|
+
@_context = LowLevel.mk_context
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
def self.instance
|
9
|
+
@instance ||= new
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
data/lib/z3/exception.rb
CHANGED
data/lib/z3/expr/arith_expr.rb
CHANGED
@@ -1,40 +1,39 @@
|
|
1
1
|
module Z3
|
2
|
-
|
3
|
-
module ArithExpr
|
2
|
+
class ArithExpr < Expr
|
4
3
|
def +(other)
|
5
|
-
|
4
|
+
Expr.Add(self, other)
|
6
5
|
end
|
7
6
|
|
8
7
|
def -(other)
|
9
|
-
|
8
|
+
Expr.Sub(self, other)
|
10
9
|
end
|
11
10
|
|
12
11
|
def *(other)
|
13
|
-
|
12
|
+
Expr.Mul(self, other)
|
14
13
|
end
|
15
14
|
|
16
15
|
def /(other)
|
17
|
-
|
16
|
+
ArithExpr.Div(self, other)
|
18
17
|
end
|
19
18
|
|
20
19
|
def **(other)
|
21
|
-
|
20
|
+
ArithExpr.Power(self, other)
|
22
21
|
end
|
23
22
|
|
24
23
|
def >(other)
|
25
|
-
|
24
|
+
Expr.Gt(self, other)
|
26
25
|
end
|
27
26
|
|
28
27
|
def >=(other)
|
29
|
-
|
28
|
+
Expr.Ge(self, other)
|
30
29
|
end
|
31
30
|
|
32
31
|
def <=(other)
|
33
|
-
|
32
|
+
Expr.Le(self, other)
|
34
33
|
end
|
35
34
|
|
36
35
|
def <(other)
|
37
|
-
|
36
|
+
Expr.Lt(self, other)
|
38
37
|
end
|
39
38
|
|
40
39
|
def -@
|
@@ -49,5 +48,24 @@ module Z3
|
|
49
48
|
max_sort = [sort, other_sort].max
|
50
49
|
[max_sort.from_const(other), max_sort.from_value(self)]
|
51
50
|
end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
def coerce_to_same_arith_sort(*args)
|
54
|
+
args = coerce_to_same_sort(*args)
|
55
|
+
raise Z3::Exception, "Int or Real value expected" unless args[0].is_a?(IntExpr) or args[0].is_a?(RealExpr)
|
56
|
+
args
|
57
|
+
end
|
58
|
+
|
59
|
+
def Div(a,b)
|
60
|
+
a, b = coerce_to_same_arith_sort(a, b)
|
61
|
+
a.sort.new(LowLevel.mk_div(a, b))
|
62
|
+
end
|
63
|
+
|
64
|
+
def Power(a, b)
|
65
|
+
# Wait, is this even legitimate that it's I**I and R**R?
|
66
|
+
a, b = coerce_to_same_arith_sort(a, b)
|
67
|
+
a.sort.new(LowLevel.mk_power(a, b))
|
68
|
+
end
|
69
|
+
end
|
52
70
|
end
|
53
71
|
end
|