z3 0.0.20160330 → 0.0.20160427
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/examples/{bridges_solver → bridges} +5 -12
- data/examples/bridges-1.txt +7 -0
- data/examples/{clogic_puzzle_solver → clogic_puzzle} +0 -0
- data/examples/four_hackers_puzzle +2 -1
- data/examples/{kakuro_solver → kakuro} +5 -15
- data/examples/kakuro-1.txt +10 -0
- data/examples/{knights_puzzle_solver → knights_puzzle} +4 -4
- data/examples/{letter_connections_solver → letter_connections} +6 -15
- data/examples/letter_connections-1.txt +10 -0
- data/examples/{light_up_solver → light_up} +5 -12
- data/examples/light_up-1.txt +7 -0
- data/examples/{minisudoku_solver → minisudoku} +8 -11
- data/examples/minisudoku-1.txt +6 -0
- data/examples/nonogram +152 -0
- data/examples/{selfref_solver → selfref} +0 -0
- data/examples/{sudoku_solver → sudoku} +9 -14
- data/examples/sudoku-1.txt +9 -0
- data/lib/z3.rb +10 -6
- data/lib/z3/ast.rb +33 -0
- data/lib/z3/{value/arith_value.rb → expr/arith_expr.rb} +3 -3
- data/lib/z3/{value/bitvec_value.rb → expr/bitvec_expr.rb} +1 -1
- data/lib/z3/{value/bool_value.rb → expr/bool_expr.rb} +5 -1
- data/lib/z3/{value/value.rb → expr/expr.rb} +7 -13
- data/lib/z3/expr/int_expr.rb +15 -0
- data/lib/z3/{value/int_value.rb → expr/real_expr.rb} +2 -2
- data/lib/z3/func_decl.rb +33 -23
- data/lib/z3/interface.rb +52 -30
- data/lib/z3/low_level.rb +10 -1
- data/lib/z3/low_level_auto.rb +83 -83
- data/lib/z3/model.rb +6 -5
- data/lib/z3/printer.rb +26 -0
- data/lib/z3/solver.rb +1 -5
- data/lib/z3/sort/bitvec_sort.rb +3 -3
- data/lib/z3/sort/bool_sort.rb +4 -4
- data/lib/z3/sort/int_sort.rb +2 -2
- data/lib/z3/sort/real_sort.rb +5 -5
- data/lib/z3/sort/sort.rb +22 -7
- data/lib/z3/very_low_level.rb +1 -1
- data/spec/bitvec_expr_spec.rb +55 -0
- data/spec/bitvec_sort_spec.rb +34 -0
- data/spec/bool_expr_spec.rb +65 -0
- data/spec/bool_sort_spec.rb +20 -0
- data/spec/{value_spec.rb → expr_spec.rb} +3 -3
- data/spec/int_expr_spec.rb +78 -0
- data/spec/int_sort_spec.rb +18 -0
- data/spec/integration/algebra_problems_spec.rb +19 -20
- data/spec/integration/basic_int_math_spec.rb +4 -5
- data/spec/integration/basic_logic_spec.rb +3 -4
- data/spec/integration/bit_tricks_spec.rb +2 -3
- data/spec/integration/bridges_spec.rb +2 -3
- data/spec/integration/four_hackers_puzzle_spec.rb +26 -0
- data/spec/integration/geometry_problem_spec.rb +10 -11
- data/spec/integration/kakuro_spec.rb +2 -3
- data/spec/integration/kinematics_problems_spec.rb +36 -37
- data/spec/integration/knights_puzzle_spec.rb +96 -0
- data/spec/integration/letter_connections_spec.rb +2 -3
- data/spec/integration/light_up_spec.rb +3 -4
- data/spec/integration/minisudoku_spec.rb +2 -3
- data/spec/integration/nonogram_spec.rb +26 -0
- data/spec/integration/selfref_spec.rb +2 -3
- data/spec/integration/sudoku_spec.rb +2 -3
- data/spec/integration/verbal_arithmetic_spec.rb +2 -3
- data/spec/model_spec.rb +13 -6
- data/spec/printer_spec.rb +22 -0
- data/spec/real_expr_spec.rb +64 -0
- data/spec/real_sort_spec.rb +24 -0
- data/spec/solver_spec.rb +11 -0
- data/spec/spec_helper.rb +39 -64
- metadata +81 -18
- data/lib/z3/value/real_value.rb +0 -7
data/lib/z3.rb
CHANGED
@@ -8,6 +8,7 @@ require_relative "z3/low_level"
|
|
8
8
|
require_relative "z3/low_level_auto"
|
9
9
|
|
10
10
|
# Classes
|
11
|
+
require_relative "z3/ast"
|
11
12
|
require_relative "z3/context"
|
12
13
|
require_relative "z3/solver"
|
13
14
|
require_relative "z3/model"
|
@@ -22,12 +23,15 @@ require_relative "z3/sort/bool_sort"
|
|
22
23
|
require_relative "z3/sort/bitvec_sort"
|
23
24
|
|
24
25
|
# ASTs
|
25
|
-
require_relative "z3/
|
26
|
-
require_relative "z3/
|
27
|
-
require_relative "z3/
|
28
|
-
require_relative "z3/
|
29
|
-
require_relative "z3/
|
30
|
-
require_relative "z3/
|
26
|
+
require_relative "z3/expr/expr"
|
27
|
+
require_relative "z3/expr/arith_expr"
|
28
|
+
require_relative "z3/expr/int_expr"
|
29
|
+
require_relative "z3/expr/real_expr"
|
30
|
+
require_relative "z3/expr/bool_expr"
|
31
|
+
require_relative "z3/expr/bitvec_expr"
|
31
32
|
|
32
33
|
# Python-style interface
|
33
34
|
require_relative "z3/interface"
|
35
|
+
|
36
|
+
# Printer
|
37
|
+
require_relative "z3/printer"
|
data/lib/z3/ast.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Z3
|
2
|
+
class AST
|
3
|
+
attr_reader :_ast
|
4
|
+
def initialize(_ast)
|
5
|
+
raise Z3::Exception, "AST expected, got #{_ast.class}" unless _ast.is_a?(FFI::Pointer)
|
6
|
+
@_ast = _ast
|
7
|
+
end
|
8
|
+
|
9
|
+
def ast_kind
|
10
|
+
ast_kind_lookup = {
|
11
|
+
0 => :numeral,
|
12
|
+
1 => :app,
|
13
|
+
2 => :var,
|
14
|
+
3 => :quantifier,
|
15
|
+
4 => :sort,
|
16
|
+
5 => :func_decl,
|
17
|
+
1000 => :unknown,
|
18
|
+
}
|
19
|
+
kind_id = Z3::LowLevel.get_ast_kind(self)
|
20
|
+
ast_kind_lookup[kind_id] or raise Z3::Exception, "Unknown AST kind #{kind_id}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
Z3::Printer.new.format(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def sexpr
|
28
|
+
Z3::LowLevel.ast_to_string(self)
|
29
|
+
end
|
30
|
+
|
31
|
+
private_class_method :new
|
32
|
+
end
|
33
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Z3
|
2
|
-
#
|
3
|
-
module
|
2
|
+
# IntExpr / RealExpr
|
3
|
+
module ArithExpr
|
4
4
|
def +(other)
|
5
5
|
::Z3.Add(self, other)
|
6
6
|
end
|
@@ -45,7 +45,7 @@ module Z3
|
|
45
45
|
# is: (+ 1.0 x)
|
46
46
|
# not: (+ (to_real 1) x)
|
47
47
|
def coerce(other)
|
48
|
-
other_sort =
|
48
|
+
other_sort = Expr.sort_for_const(other)
|
49
49
|
max_sort = [sort, other_sort].max
|
50
50
|
[max_sort.from_const(other), max_sort.from_value(self)]
|
51
51
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Z3
|
2
|
-
class
|
2
|
+
class BoolExpr < Expr
|
3
3
|
def ~
|
4
4
|
sort.new(LowLevel.mk_not(self))
|
5
5
|
end
|
@@ -24,6 +24,10 @@ module Z3
|
|
24
24
|
Z3.Implies(self, other)
|
25
25
|
end
|
26
26
|
|
27
|
+
def ite(a, b)
|
28
|
+
Z3.IfThenElse(self, a, b)
|
29
|
+
end
|
30
|
+
|
27
31
|
public_class_method :new
|
28
32
|
end
|
29
33
|
end
|
@@ -1,17 +1,14 @@
|
|
1
1
|
module Z3
|
2
|
-
class
|
3
|
-
attr_reader :
|
2
|
+
class Expr < AST
|
3
|
+
attr_reader :sort
|
4
4
|
def initialize(_ast, sort)
|
5
|
-
|
5
|
+
super(_ast)
|
6
6
|
@sort = sort
|
7
|
-
|
8
|
-
|
9
|
-
def to_s
|
10
|
-
Z3::LowLevel.ast_to_string(self)
|
7
|
+
raise Z3::Exception, "Values must have AST kind numeral or app" unless [:numeral, :app].include?(ast_kind)
|
11
8
|
end
|
12
9
|
|
13
10
|
def inspect
|
14
|
-
"
|
11
|
+
"#{sort.to_s}<#{to_s}>"
|
15
12
|
end
|
16
13
|
|
17
14
|
def ==(other)
|
@@ -22,8 +19,6 @@ module Z3
|
|
22
19
|
::Z3.Distinct(self, other)
|
23
20
|
end
|
24
21
|
|
25
|
-
private_class_method :new
|
26
|
-
|
27
22
|
class << self
|
28
23
|
def sort_for_const(a)
|
29
24
|
case a
|
@@ -39,9 +34,8 @@ module Z3
|
|
39
34
|
end
|
40
35
|
|
41
36
|
def new_from_pointer(_ast)
|
42
|
-
|
43
|
-
|
44
|
-
# if == Z3::LowLevel.mk_bool_sort
|
37
|
+
_sort = Z3::VeryLowLevel.Z3_get_sort(Z3::LowLevel._ctx_pointer, _ast)
|
38
|
+
Sort.from_pointer(_sort).new(_ast)
|
45
39
|
end
|
46
40
|
end
|
47
41
|
end
|
data/lib/z3/func_decl.rb
CHANGED
@@ -1,31 +1,41 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Z3
|
2
|
+
class FuncDecl < AST
|
3
|
+
def initialize(_ast)
|
4
|
+
super(_ast)
|
5
|
+
raise Z3::Exception, "FuncDecls must have AST kind func decl" unless ast_kind == :func_decl
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def name
|
9
|
+
Z3::LowLevel.get_symbol_string(Z3::LowLevel.get_decl_name(self))
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def arity
|
13
|
+
Z3::LowLevel.get_arity(self)
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def domain(i)
|
17
|
+
a = arity
|
18
|
+
raise Z3::Exception, "Trying to access domain #{i} but function arity is #{a}" if i < 0 or i >= a
|
19
|
+
Sort.from_pointer(Z3::LowLevel::get_domain(self, i))
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
# end
|
22
|
+
def range
|
23
|
+
Sort.from_pointer(Z3::LowLevel::get_range(self))
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
# def ast_parameter(i)
|
27
|
+
# # vs arity ?
|
28
|
+
# Z3::Ast.new(Z3::LowLevel.get_decl_ast_parameter(self, i))
|
29
|
+
# end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
name
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
"Z3::FuncDecl<#{name}/#{arity}>"
|
37
|
+
end
|
27
38
|
|
28
|
-
|
29
|
-
"Z3::FuncDecl<#{name}/#{arity}>"
|
39
|
+
public_class_method :new
|
30
40
|
end
|
31
41
|
end
|
data/lib/z3/interface.rb
CHANGED
@@ -23,45 +23,51 @@ module Z3
|
|
23
23
|
BoolSort.new.False
|
24
24
|
end
|
25
25
|
|
26
|
+
def Const(v)
|
27
|
+
Expr.sort_for_const(v).from_const(v)
|
28
|
+
end
|
29
|
+
|
26
30
|
def And(*args)
|
27
31
|
args = coerce_to_same_sort(*args)
|
28
32
|
case args[0]
|
29
|
-
when
|
33
|
+
when BoolExpr
|
30
34
|
BoolSort.new.new(Z3::LowLevel.mk_and(args))
|
31
|
-
when
|
35
|
+
when BitvecExpr
|
32
36
|
args.inject do |a,b|
|
33
37
|
a.sort.new(Z3::LowLevel.mk_bvand(a, b))
|
34
38
|
end
|
35
39
|
else
|
36
|
-
raise ArgumentError, "Can't perform logic operations on #{a.sort}
|
40
|
+
raise ArgumentError, "Can't perform logic operations on #{a.sort} exprs, only Bool and Bitvec"
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
40
44
|
def Or(*args)
|
41
45
|
args = coerce_to_same_sort(*args)
|
42
46
|
case args[0]
|
43
|
-
when
|
47
|
+
when BoolExpr
|
44
48
|
BoolSort.new.new(Z3::LowLevel.mk_or(args))
|
45
|
-
when
|
49
|
+
when BitvecExpr
|
46
50
|
args.inject do |a,b|
|
47
51
|
a.sort.new(Z3::LowLevel.mk_bvor(a, b))
|
48
52
|
end
|
49
53
|
else
|
50
|
-
raise ArgumentError, "Can't perform logic operations on #{a.sort}
|
54
|
+
raise ArgumentError, "Can't perform logic operations on #{a.sort} exprs, only Bool and Bitvec"
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
58
|
def Xor(*args)
|
55
59
|
args = coerce_to_same_sort(*args)
|
56
60
|
case args[0]
|
57
|
-
when
|
58
|
-
|
59
|
-
|
61
|
+
when BoolExpr
|
62
|
+
args.inject do |a,b|
|
63
|
+
BoolSort.new.new(Z3::LowLevel.mk_xor(a, b))
|
64
|
+
end
|
65
|
+
when BitvecExpr
|
60
66
|
args.inject do |a,b|
|
61
67
|
a.sort.new(Z3::LowLevel.mk_bvxor(a, b))
|
62
68
|
end
|
63
69
|
else
|
64
|
-
raise ArgumentError, "Can't perform logic operations on #{a.sort}
|
70
|
+
raise ArgumentError, "Can't perform logic operations on #{a.sort} exprs, only Bool and Bitvec"
|
65
71
|
end
|
66
72
|
end
|
67
73
|
|
@@ -85,23 +91,23 @@ module Z3
|
|
85
91
|
raise ArgumentError if args.empty?
|
86
92
|
args = coerce_to_same_sort(*args)
|
87
93
|
case args[0]
|
88
|
-
when
|
94
|
+
when ArithExpr
|
89
95
|
args[0].sort.new(LowLevel.mk_add(args))
|
90
|
-
when
|
96
|
+
when BitvecExpr
|
91
97
|
args.inject do |a,b|
|
92
98
|
a.sort.new(LowLevel.mk_bvadd(a,b))
|
93
99
|
end
|
94
100
|
else
|
95
|
-
raise ArgumentError, "Can't perform logic operations on #{args[0].sort}
|
101
|
+
raise ArgumentError, "Can't perform logic operations on #{args[0].sort} exprs, only Int/Real/Bitvec"
|
96
102
|
end
|
97
103
|
end
|
98
104
|
|
99
105
|
def Sub(*args)
|
100
106
|
args = coerce_to_same_sort(*args)
|
101
107
|
case args[0]
|
102
|
-
when
|
108
|
+
when ArithExpr
|
103
109
|
args[0].sort.new(LowLevel.mk_sub(args))
|
104
|
-
when
|
110
|
+
when BitvecExpr
|
105
111
|
args.inject do |a,b|
|
106
112
|
a.sort.new(LowLevel.mk_bvsub(a,b))
|
107
113
|
end
|
@@ -113,9 +119,9 @@ module Z3
|
|
113
119
|
def Mul(*args)
|
114
120
|
args = coerce_to_same_sort(*args)
|
115
121
|
case args[0]
|
116
|
-
when
|
122
|
+
when ArithExpr
|
117
123
|
args[0].sort.new(LowLevel.mk_mul(args))
|
118
|
-
when
|
124
|
+
when BitvecExpr
|
119
125
|
args.inject do |a,b|
|
120
126
|
a.sort.new(LowLevel.mk_bvmul(a,b))
|
121
127
|
end
|
@@ -129,6 +135,16 @@ module Z3
|
|
129
135
|
a.sort.new(LowLevel.mk_div(a, b))
|
130
136
|
end
|
131
137
|
|
138
|
+
def Mod(a,b)
|
139
|
+
a, b = coerce_to_same_int_sort(a, b)
|
140
|
+
a.sort.new(LowLevel.mk_mod(a, b))
|
141
|
+
end
|
142
|
+
|
143
|
+
def Rem(a,b)
|
144
|
+
a, b = coerce_to_same_int_sort(a, b)
|
145
|
+
a.sort.new(LowLevel.mk_rem(a, b))
|
146
|
+
end
|
147
|
+
|
132
148
|
def Power(a, b)
|
133
149
|
# Wait, is this even legitimate that it's I**I and R**R?
|
134
150
|
a, b = coerce_to_same_arith_sort(a, b)
|
@@ -148,9 +164,9 @@ module Z3
|
|
148
164
|
def Gt(a, b)
|
149
165
|
a, b = coerce_to_same_sort(a, b)
|
150
166
|
case a
|
151
|
-
when
|
167
|
+
when ArithExpr
|
152
168
|
BoolSort.new.new(LowLevel.mk_gt(a, b))
|
153
|
-
when
|
169
|
+
when BitvecExpr
|
154
170
|
BoolSort.new.new(LowLevel.mk_bvsgt(a, b))
|
155
171
|
else
|
156
172
|
raise ArgumentError, "Can't compare #{a.sort} values"
|
@@ -160,9 +176,9 @@ module Z3
|
|
160
176
|
def Ge(a, b)
|
161
177
|
a, b = coerce_to_same_sort(a, b)
|
162
178
|
case a
|
163
|
-
when
|
179
|
+
when ArithExpr
|
164
180
|
BoolSort.new.new(LowLevel.mk_ge(a, b))
|
165
|
-
when
|
181
|
+
when BitvecExpr
|
166
182
|
BoolSort.new.new(LowLevel.mk_bvsge(a, b))
|
167
183
|
else
|
168
184
|
raise ArgumentError, "Can't compare #{a.sort} values"
|
@@ -172,9 +188,9 @@ module Z3
|
|
172
188
|
def Lt(a, b)
|
173
189
|
a, b = coerce_to_same_sort(a, b)
|
174
190
|
case a
|
175
|
-
when
|
191
|
+
when ArithExpr
|
176
192
|
BoolSort.new.new(LowLevel.mk_lt(a, b))
|
177
|
-
when
|
193
|
+
when BitvecExpr
|
178
194
|
BoolSort.new.new(LowLevel.mk_bvslt(a, b))
|
179
195
|
else
|
180
196
|
raise ArgumentError, "Can't compare #{a.sort} values"
|
@@ -184,9 +200,9 @@ module Z3
|
|
184
200
|
def Le(a, b)
|
185
201
|
a, b = coerce_to_same_sort(a, b)
|
186
202
|
case a
|
187
|
-
when
|
203
|
+
when ArithExpr
|
188
204
|
BoolSort.new.new(LowLevel.mk_le(a, b))
|
189
|
-
when
|
205
|
+
when BitvecExpr
|
190
206
|
BoolSort.new.new(LowLevel.mk_bvsle(a, b))
|
191
207
|
else
|
192
208
|
raise ArgumentError, "Can't compare #{a.sort} values"
|
@@ -223,9 +239,9 @@ module Z3
|
|
223
239
|
def coerce_to_same_sort(*args)
|
224
240
|
# This will raise exception unless one of the sorts is highest
|
225
241
|
# So [true, IntSort]
|
226
|
-
max_sort = args.map{|a| a.is_a?(
|
242
|
+
max_sort = args.map{|a| a.is_a?(Expr) ? a.sort : Expr.sort_for_const(a)}.max
|
227
243
|
args.map do |a|
|
228
|
-
if a.is_a?(
|
244
|
+
if a.is_a?(Expr)
|
229
245
|
if a.sort == max_sort
|
230
246
|
a
|
231
247
|
else
|
@@ -239,19 +255,25 @@ module Z3
|
|
239
255
|
|
240
256
|
def coerce_to_same_bool_sort(*args)
|
241
257
|
args = coerce_to_same_sort(*args)
|
242
|
-
raise Z3::Exception, "Bool value expected" unless args[0].is_a?(
|
258
|
+
raise Z3::Exception, "Bool value expected" unless args[0].is_a?(BoolExpr)
|
243
259
|
args
|
244
260
|
end
|
245
261
|
|
246
262
|
def coerce_to_same_arith_sort(*args)
|
247
263
|
args = coerce_to_same_sort(*args)
|
248
|
-
raise Z3::Exception, "Int or Real value expected" unless args[0].is_a?(
|
264
|
+
raise Z3::Exception, "Int or Real value expected" unless args[0].is_a?(IntExpr) or args[0].is_a?(RealExpr)
|
249
265
|
args
|
250
266
|
end
|
251
267
|
|
252
268
|
def coerce_to_same_bv_sort(*args)
|
253
269
|
args = coerce_to_same_sort(*args)
|
254
|
-
raise Z3::Exception, "Bitvec value with same
|
270
|
+
raise Z3::Exception, "Bitvec value with same size expected" unless args[0].is_a?(BitvecExpr)
|
271
|
+
args
|
272
|
+
end
|
273
|
+
|
274
|
+
def coerce_to_same_int_sort(*args)
|
275
|
+
args = coerce_to_same_sort(*args)
|
276
|
+
raise Z3::Exception, "Int value expected" unless args[0].is_a?(IntExpr)
|
255
277
|
args
|
256
278
|
end
|
257
279
|
|