z3 0.0.20160330 → 0.0.20160427

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -0
  3. data/examples/{bridges_solver → bridges} +5 -12
  4. data/examples/bridges-1.txt +7 -0
  5. data/examples/{clogic_puzzle_solver → clogic_puzzle} +0 -0
  6. data/examples/four_hackers_puzzle +2 -1
  7. data/examples/{kakuro_solver → kakuro} +5 -15
  8. data/examples/kakuro-1.txt +10 -0
  9. data/examples/{knights_puzzle_solver → knights_puzzle} +4 -4
  10. data/examples/{letter_connections_solver → letter_connections} +6 -15
  11. data/examples/letter_connections-1.txt +10 -0
  12. data/examples/{light_up_solver → light_up} +5 -12
  13. data/examples/light_up-1.txt +7 -0
  14. data/examples/{minisudoku_solver → minisudoku} +8 -11
  15. data/examples/minisudoku-1.txt +6 -0
  16. data/examples/nonogram +152 -0
  17. data/examples/{selfref_solver → selfref} +0 -0
  18. data/examples/{sudoku_solver → sudoku} +9 -14
  19. data/examples/sudoku-1.txt +9 -0
  20. data/lib/z3.rb +10 -6
  21. data/lib/z3/ast.rb +33 -0
  22. data/lib/z3/{value/arith_value.rb → expr/arith_expr.rb} +3 -3
  23. data/lib/z3/{value/bitvec_value.rb → expr/bitvec_expr.rb} +1 -1
  24. data/lib/z3/{value/bool_value.rb → expr/bool_expr.rb} +5 -1
  25. data/lib/z3/{value/value.rb → expr/expr.rb} +7 -13
  26. data/lib/z3/expr/int_expr.rb +15 -0
  27. data/lib/z3/{value/int_value.rb → expr/real_expr.rb} +2 -2
  28. data/lib/z3/func_decl.rb +33 -23
  29. data/lib/z3/interface.rb +52 -30
  30. data/lib/z3/low_level.rb +10 -1
  31. data/lib/z3/low_level_auto.rb +83 -83
  32. data/lib/z3/model.rb +6 -5
  33. data/lib/z3/printer.rb +26 -0
  34. data/lib/z3/solver.rb +1 -5
  35. data/lib/z3/sort/bitvec_sort.rb +3 -3
  36. data/lib/z3/sort/bool_sort.rb +4 -4
  37. data/lib/z3/sort/int_sort.rb +2 -2
  38. data/lib/z3/sort/real_sort.rb +5 -5
  39. data/lib/z3/sort/sort.rb +22 -7
  40. data/lib/z3/very_low_level.rb +1 -1
  41. data/spec/bitvec_expr_spec.rb +55 -0
  42. data/spec/bitvec_sort_spec.rb +34 -0
  43. data/spec/bool_expr_spec.rb +65 -0
  44. data/spec/bool_sort_spec.rb +20 -0
  45. data/spec/{value_spec.rb → expr_spec.rb} +3 -3
  46. data/spec/int_expr_spec.rb +78 -0
  47. data/spec/int_sort_spec.rb +18 -0
  48. data/spec/integration/algebra_problems_spec.rb +19 -20
  49. data/spec/integration/basic_int_math_spec.rb +4 -5
  50. data/spec/integration/basic_logic_spec.rb +3 -4
  51. data/spec/integration/bit_tricks_spec.rb +2 -3
  52. data/spec/integration/bridges_spec.rb +2 -3
  53. data/spec/integration/four_hackers_puzzle_spec.rb +26 -0
  54. data/spec/integration/geometry_problem_spec.rb +10 -11
  55. data/spec/integration/kakuro_spec.rb +2 -3
  56. data/spec/integration/kinematics_problems_spec.rb +36 -37
  57. data/spec/integration/knights_puzzle_spec.rb +96 -0
  58. data/spec/integration/letter_connections_spec.rb +2 -3
  59. data/spec/integration/light_up_spec.rb +3 -4
  60. data/spec/integration/minisudoku_spec.rb +2 -3
  61. data/spec/integration/nonogram_spec.rb +26 -0
  62. data/spec/integration/selfref_spec.rb +2 -3
  63. data/spec/integration/sudoku_spec.rb +2 -3
  64. data/spec/integration/verbal_arithmetic_spec.rb +2 -3
  65. data/spec/model_spec.rb +13 -6
  66. data/spec/printer_spec.rb +22 -0
  67. data/spec/real_expr_spec.rb +64 -0
  68. data/spec/real_sort_spec.rb +24 -0
  69. data/spec/solver_spec.rb +11 -0
  70. data/spec/spec_helper.rb +39 -64
  71. metadata +81 -18
  72. data/lib/z3/value/real_value.rb +0 -7
@@ -0,0 +1,9 @@
1
+ _ 6 _ 5 _ 9 _ 4 _
2
+ 9 2 _ _ _ _ _ 7 6
3
+ _ _ 1 _ _ _ 9 _ _
4
+ 7 _ _ 6 _ 3 _ _ 9
5
+ _ _ _ _ _ _ _ _ _
6
+ 3 _ _ 4 _ 1 _ _ 7
7
+ _ _ 6 _ _ _ 7 _ _
8
+ 2 4 _ _ _ _ _ 6 5
9
+ _ 9 _ 1 _ 8 _ 3 _
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/value/value"
26
- require_relative "z3/value/arith_value"
27
- require_relative "z3/value/int_value"
28
- require_relative "z3/value/real_value"
29
- require_relative "z3/value/bool_value"
30
- require_relative "z3/value/bitvec_value"
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"
@@ -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
- # IntValue / RealValue
3
- module ArithValue
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 = Value.sort_for_const(other)
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 BitvecValue < Value
2
+ class BitvecExpr < Expr
3
3
  def ~
4
4
  sort.new(LowLevel.mk_bvnot(self))
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Z3
2
- class BoolValue < Value
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 Value
3
- attr_reader :_ast, :sort
2
+ class Expr < AST
3
+ attr_reader :sort
4
4
  def initialize(_ast, sort)
5
- @_ast = _ast
5
+ super(_ast)
6
6
  @sort = sort
7
- end
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
- "Value<#{to_s} :: #{sort.to_s}>"
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
- _txt = Z3::VeryLowLevel.Z3_ast_to_string(Z3::LowLevel._ctx_pointer, _ast)
43
- # raise "No idea how to convert this value"
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
@@ -0,0 +1,15 @@
1
+ module Z3
2
+ class IntExpr < Expr
3
+ include ArithExpr
4
+
5
+ def mod(other)
6
+ ::Z3.Mod(self, other)
7
+ end
8
+
9
+ def rem(other)
10
+ ::Z3.Rem(self, other)
11
+ end
12
+
13
+ public_class_method :new
14
+ end
15
+ end
@@ -1,6 +1,6 @@
1
1
  module Z3
2
- class IntValue < Value
3
- include ArithValue
2
+ class RealExpr < Expr
3
+ include ArithExpr
4
4
 
5
5
  public_class_method :new
6
6
  end
@@ -1,31 +1,41 @@
1
- class Z3::FuncDecl
2
- attr_reader :_func_decl
3
- def initialize(_func_decl)
4
- @_func_decl = _func_decl
5
- end
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
- def name
8
- Z3::LowLevel.get_symbol_string(Z3::LowLevel.get_decl_name(self))
9
- end
8
+ def name
9
+ Z3::LowLevel.get_symbol_string(Z3::LowLevel.get_decl_name(self))
10
+ end
10
11
 
11
- def arity
12
- Z3::LowLevel.get_arity(self)
13
- end
12
+ def arity
13
+ Z3::LowLevel.get_arity(self)
14
+ end
14
15
 
15
- # def to_ast
16
- # Z3::Ast.new(Z3::LowLevel.func_decl_to_ast(self))
17
- # end
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
- # def ast_parameter(i)
20
- # # vs arity ?
21
- # Z3::Ast.new(Z3::LowLevel.get_decl_ast_parameter(self, i))
22
- # end
22
+ def range
23
+ Sort.from_pointer(Z3::LowLevel::get_range(self))
24
+ end
23
25
 
24
- def to_s
25
- name
26
- end
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
- def inspect
29
- "Z3::FuncDecl<#{name}/#{arity}>"
39
+ public_class_method :new
30
40
  end
31
41
  end
@@ -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 BoolValue
33
+ when BoolExpr
30
34
  BoolSort.new.new(Z3::LowLevel.mk_and(args))
31
- when BitvecValue
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} values, only Bool and Bitvec"
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 BoolValue
47
+ when BoolExpr
44
48
  BoolSort.new.new(Z3::LowLevel.mk_or(args))
45
- when BitvecValue
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} values, only Bool and Bitvec"
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 BoolValue
58
- BoolSort.new.new(Z3::LowLevel.mk_xor(args))
59
- when BitvecValue
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} values, only Bool and Bitvec"
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 ArithValue
94
+ when ArithExpr
89
95
  args[0].sort.new(LowLevel.mk_add(args))
90
- when BitvecValue
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} values, only Int/Real/Bitvec"
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 ArithValue
108
+ when ArithExpr
103
109
  args[0].sort.new(LowLevel.mk_sub(args))
104
- when BitvecValue
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 ArithValue
122
+ when ArithExpr
117
123
  args[0].sort.new(LowLevel.mk_mul(args))
118
- when BitvecValue
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 ArithValue
167
+ when ArithExpr
152
168
  BoolSort.new.new(LowLevel.mk_gt(a, b))
153
- when BitvecValue
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 ArithValue
179
+ when ArithExpr
164
180
  BoolSort.new.new(LowLevel.mk_ge(a, b))
165
- when BitvecValue
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 ArithValue
191
+ when ArithExpr
176
192
  BoolSort.new.new(LowLevel.mk_lt(a, b))
177
- when BitvecValue
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 ArithValue
203
+ when ArithExpr
188
204
  BoolSort.new.new(LowLevel.mk_le(a, b))
189
- when BitvecValue
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?(Value) ? a.sort : Value.sort_for_const(a)}.max
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?(Value)
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?(BoolValue)
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?(IntValue) or args[0].is_a?(RealValue)
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 nize expected" unless args[0].is_a?(BitvecValue)
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