z3 0.0.20160221 → 0.0.20160323

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/examples/algebra_problems +24 -24
  4. data/examples/basic_int_math +8 -8
  5. data/examples/basic_logic +8 -8
  6. data/examples/bit_tricks +161 -0
  7. data/examples/bridges_solver +1 -1
  8. data/examples/clogic_puzzle_solver +135 -0
  9. data/examples/four_hackers_puzzle +194 -0
  10. data/examples/geometry_problem +11 -11
  11. data/examples/kakuro_solver +3 -3
  12. data/examples/kinematics_problems +37 -37
  13. data/examples/letter_connections_solver +11 -11
  14. data/examples/light_up_solver +5 -5
  15. data/examples/minisudoku_solver +4 -4
  16. data/examples/selfref_solver +35 -35
  17. data/examples/sudoku_solver +4 -4
  18. data/examples/verbal_arithmetic +2 -2
  19. data/lib/z3/exception.rb +25 -0
  20. data/lib/z3/func_decl.rb +7 -7
  21. data/lib/z3/interface.rb +255 -0
  22. data/lib/z3/low_level.rb +4 -6
  23. data/lib/z3/low_level_auto.rb +1551 -1547
  24. data/lib/z3/model.rb +3 -2
  25. data/lib/z3/solver.rb +65 -54
  26. data/lib/z3/sort/bitvec_sort.rb +40 -0
  27. data/lib/z3/sort/bool_sort.rb +31 -0
  28. data/lib/z3/sort/int_sort.rb +21 -0
  29. data/lib/z3/sort/real_sort.rb +36 -0
  30. data/lib/z3/sort/sort.rb +76 -0
  31. data/lib/z3/value/arith_value.rb +53 -0
  32. data/lib/z3/value/bitvec_value.rb +67 -0
  33. data/lib/z3/value/bool_value.rb +29 -0
  34. data/lib/z3/value/int_value.rb +7 -0
  35. data/lib/z3/value/real_value.rb +7 -0
  36. data/lib/z3/value/value.rb +48 -0
  37. data/lib/z3/very_low_level.rb +28 -45
  38. data/lib/z3/very_low_level_auto.rb +518 -516
  39. data/lib/z3.rb +23 -33
  40. data/spec/integration/bit_tricks_spec.rb +21 -0
  41. data/spec/model_spec.rb +9 -9
  42. data/spec/solver_spec.rb +2 -2
  43. data/spec/sort_spec.rb +38 -13
  44. data/spec/{ast_spec.rb → value_spec.rb} +60 -57
  45. metadata +21 -6
  46. data/lib/z3/ast.rb +0 -302
  47. data/lib/z3/sort.rb +0 -33
  48. /data/spec/integration/{bagic_int_math_spec.rb → basic_int_math_spec.rb} +0 -0
data/lib/z3/model.rb CHANGED
@@ -23,7 +23,7 @@ class Z3::Model
23
23
  end
24
24
 
25
25
  def model_eval(ast, model_completion=false)
26
- Z3::Ast.new(Z3::LowLevel.model_eval(self, ast, model_completion))
26
+ Z3::Value.new_from_pointer(Z3::LowLevel.model_eval(self, ast, model_completion))
27
27
  end
28
28
 
29
29
  def [](ast)
@@ -40,9 +40,10 @@ class Z3::Model
40
40
 
41
41
  def each
42
42
  consts.sort_by(&:name).each do |c|
43
+ _ast = Z3::LowLevel.model_get_const_interp(self, c)
43
44
  yield(
44
45
  c.name,
45
- Z3::Ast::new(Z3::LowLevel.model_get_const_interp(self, c))
46
+ Z3::Value.new_from_pointer(_ast)
46
47
  )
47
48
  end
48
49
  end
data/lib/z3/solver.rb CHANGED
@@ -1,68 +1,79 @@
1
- class Z3::Solver
2
- attr_reader :_solver
3
- def initialize
4
- @_solver = Z3::LowLevel.mk_solver
5
- Z3::LowLevel.solver_inc_ref(self)
6
- end
1
+ module Z3
2
+ class Solver
3
+ attr_reader :_solver
4
+ def initialize
5
+ @_solver = Z3::LowLevel.mk_solver
6
+ Z3::LowLevel.solver_inc_ref(self)
7
+ end
7
8
 
8
- def push
9
- Z3::LowLevel.solver_push(self)
10
- end
9
+ def push
10
+ Z3::LowLevel.solver_push(self)
11
+ end
11
12
 
12
- def pop(n=1)
13
- Z3::LowLevel.solver_pop(self, n)
14
- end
13
+ def pop(n=1)
14
+ Z3::LowLevel.solver_pop(self, n)
15
+ end
15
16
 
16
- def reset
17
- Z3::LowLevel.solver_reset(self)
18
- end
17
+ def reset
18
+ Z3::LowLevel.solver_reset(self)
19
+ end
19
20
 
20
- def assert(ast)
21
- Z3::LowLevel.solver_assert(self, ast)
22
- end
21
+ def assert(ast)
22
+ Z3::LowLevel.solver_assert(self, ast)
23
+ end
23
24
 
24
- def check
25
- check_sat_results(Z3::LowLevel.solver_check(self))
26
- end
25
+ def check
26
+ check_sat_results(Z3::LowLevel.solver_check(self))
27
+ end
27
28
 
28
- def model
29
- Z3::Model.new(
30
- Z3::LowLevel.solver_get_model(self)
31
- )
32
- end
29
+ def model
30
+ Z3::Model.new(
31
+ Z3::LowLevel.solver_get_model(self)
32
+ )
33
+ end
33
34
 
34
- def prove!(ast)
35
- push
36
- assert(~ast)
37
- case check
38
- when :sat
39
- puts "Counterexample exists"
40
- model.each do |n,v|
41
- puts "* #{n} = #{v}"
35
+ def assertions
36
+ _ast_vector = Z3::LowLevel.solver_get_assertions(self)
37
+ n = Z3::VeryLowLevel.Z3_ast_vector_size(Z3::LowLevel._ctx_pointer, _ast_vector)
38
+ (0...n).map{|i|
39
+ _ast = Z3::VeryLowLevel.Z3_ast_vector_get(Z3::LowLevel._ctx_pointer, _ast_vector, i)
40
+ Z3::Value.new_from_pointer(_ast)
41
+ }
42
+ end
43
+
44
+ def prove!(ast)
45
+ push
46
+ assert(~ast)
47
+ case check
48
+ when :sat
49
+ puts "Counterexample exists"
50
+ model.each do |n,v|
51
+ puts "* #{n} = #{v}"
52
+ end
53
+ when :unknown
54
+ puts "Unknown"
55
+ when :unsat
56
+ puts "Proven"
57
+ else
58
+ raise "Wrong SAT result #{r}"
42
59
  end
43
- when :unknown
44
- puts "Unknown"
45
- when :unsat
46
- puts "Proven"
47
- else
48
- raise "Wrong SAT result #{r}"
60
+ ensure
61
+ pop
49
62
  end
50
- ensure
51
- pop
52
- end
53
63
 
54
- private
64
+ private
55
65
 
56
- def check_sat_results(r)
57
- case r
58
- when 1
59
- :sat
60
- when 0
61
- :unknown
62
- when -1
63
- :unsat
64
- else
65
- raise "Wrong SAT result #{r}"
66
+ def check_sat_results(r)
67
+ case r
68
+ when 1
69
+ :sat
70
+ when 0
71
+ :unknown
72
+ when -1
73
+ :unsat
74
+ else
75
+ raise "Wrong SAT result #{r}"
76
+ end
66
77
  end
67
78
  end
68
79
  end
@@ -0,0 +1,40 @@
1
+ module Z3
2
+ class BitvecSort < Sort
3
+ def initialize(n)
4
+ super LowLevel.mk_bv_sort(n)
5
+ end
6
+
7
+ def value_class
8
+ BitvecValue
9
+ end
10
+
11
+ def from_const(val)
12
+ if val.is_a?(Integer) or val.is_a?(Float)
13
+ new LowLevel.mk_numeral(val.to_s, self)
14
+ else
15
+ raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
16
+ end
17
+ end
18
+
19
+ def size
20
+ LowLevel.get_bv_sort_size(self)
21
+ end
22
+
23
+ def to_s
24
+ "Bitvec(#{size})"
25
+ end
26
+
27
+ def inspect
28
+ "BitvecSort(#{size})"
29
+ end
30
+
31
+ def >(other)
32
+ raise ArgumentError unless other.is_a?(Sort)
33
+ return true if other.is_a?(IntSort)
34
+ return true if other.is_a?(BitvecSort) and size > other.size
35
+ false
36
+ end
37
+
38
+ public_class_method :new
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ module Z3
2
+ class BoolSort < Sort
3
+ def initialize
4
+ super LowLevel.mk_bool_sort
5
+ end
6
+
7
+ def value_class
8
+ BoolValue
9
+ end
10
+
11
+ def from_const(val)
12
+ if val == true
13
+ BoolValue.new(LowLevel.mk_true, self)
14
+ elsif val == false
15
+ BoolValue.new(LowLevel.mk_false, self)
16
+ else
17
+ raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
18
+ end
19
+ end
20
+
21
+ def True
22
+ from_const(true)
23
+ end
24
+
25
+ def False
26
+ from_const(false)
27
+ end
28
+
29
+ public_class_method :new
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ module Z3
2
+ class IntSort < Sort
3
+ def initialize
4
+ super LowLevel.mk_int_sort
5
+ end
6
+
7
+ def value_class
8
+ IntValue
9
+ end
10
+
11
+ def from_const(val)
12
+ if val.is_a?(Integer)
13
+ new(LowLevel.mk_numeral(val.to_s, self))
14
+ else
15
+ raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
16
+ end
17
+ end
18
+
19
+ public_class_method :new
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ module Z3
2
+ class RealSort < Sort
3
+ def initialize
4
+ super LowLevel.mk_real_sort
5
+ end
6
+
7
+ def value_class
8
+ RealValue
9
+ end
10
+
11
+ def from_const(val)
12
+ if val.is_a?(Integer) or val.is_a?(Float)
13
+ new LowLevel.mk_numeral(val.to_s, self)
14
+ else
15
+ raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
16
+ end
17
+ end
18
+
19
+ def from_value(val)
20
+ if val.is_a?(IntValue)
21
+ new LowLevel.mk_int2real(val)
22
+ elsif val.is_a?(RealValue)
23
+ val
24
+ else
25
+ raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
26
+ end
27
+ end
28
+
29
+ def >(other)
30
+ raise ArgumentError unless other.is_a?(Sort)
31
+ other.is_a?(IntSort)
32
+ end
33
+
34
+ public_class_method :new
35
+ end
36
+ end
@@ -0,0 +1,76 @@
1
+ module Z3
2
+ class Sort
3
+ attr_reader :_sort
4
+ def initialize(_sort)
5
+ @_sort = _sort
6
+ end
7
+
8
+ include Comparable
9
+ def ==(other)
10
+ other.is_a?(Sort) and @_sort == other._sort
11
+ end
12
+
13
+ def >(other)
14
+ raise ArgumentError unless other.is_a?(Sort)
15
+ false
16
+ end
17
+
18
+ # Reimplementing Comparable
19
+ # Check if it can handle partial orders OK
20
+ def <(other)
21
+ raise ArgumentError unless other.is_a?(Sort)
22
+ other > self
23
+ end
24
+
25
+ def >=(other)
26
+ raise ArgumentError unless other.is_a?(Sort)
27
+ self == other or self > other
28
+ end
29
+
30
+ def <=(other)
31
+ raise ArgumentError unless other.is_a?(Sort)
32
+ other >= self
33
+ end
34
+
35
+ def <=>(other)
36
+ raise ArgumentError unless other.is_a?(Sort)
37
+ return 0 if self == other
38
+ return 1 if self > other
39
+ return -1 if other > self
40
+ nil
41
+ end
42
+
43
+ def to_s
44
+ LowLevel.sort_to_string(self)
45
+ end
46
+
47
+ def inspect
48
+ "#{self}Sort"
49
+ end
50
+
51
+ def var(name)
52
+ new(
53
+ Z3::LowLevel.mk_const(
54
+ Z3::LowLevel.mk_string_symbol(name),
55
+ self,
56
+ )
57
+ )
58
+ end
59
+
60
+ # We pretend to be a class, sort of
61
+ def new(_ast)
62
+ value_class.new(_ast, self)
63
+ end
64
+
65
+ def value_class
66
+ raise "SubclassResponsibility"
67
+ end
68
+
69
+ def from_value(v)
70
+ return v if v.sort == self
71
+ raise Z3::Exception, "Can't convert #{v.sort} into #{self}"
72
+ end
73
+
74
+ private_class_method :new
75
+ end
76
+ end
@@ -0,0 +1,53 @@
1
+ module Z3
2
+ # IntValue / RealValue
3
+ module ArithValue
4
+ def +(other)
5
+ ::Z3.Add(self, other)
6
+ end
7
+
8
+ def -(other)
9
+ ::Z3.Sub(self, other)
10
+ end
11
+
12
+ def *(other)
13
+ ::Z3.Mul(self, other)
14
+ end
15
+
16
+ def /(other)
17
+ ::Z3.Div(self, other)
18
+ end
19
+
20
+ def **(other)
21
+ ::Z3.Power(self, other)
22
+ end
23
+
24
+ def >(other)
25
+ ::Z3.Gt(self, other)
26
+ end
27
+
28
+ def >=(other)
29
+ ::Z3.Ge(self, other)
30
+ end
31
+
32
+ def <=(other)
33
+ ::Z3.Le(self, other)
34
+ end
35
+
36
+ def <(other)
37
+ ::Z3.Lt(self, other)
38
+ end
39
+
40
+ def -@
41
+ sort.new(LowLevel.mk_unary_minus(self))
42
+ end
43
+
44
+ # Recast so 1 + x:Float
45
+ # is: (+ 1.0 x)
46
+ # not: (+ (to_real 1) x)
47
+ def coerce(other)
48
+ other_sort = Value.sort_for_const(other)
49
+ max_sort = [sort, other_sort].max
50
+ [max_sort.from_const(other), max_sort.from_value(self)]
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,67 @@
1
+ module Z3
2
+ class BitvecValue < Value
3
+ def ~
4
+ sort.new(LowLevel.mk_bvnot(self))
5
+ end
6
+
7
+ def -@
8
+ sort.new(LowLevel.mk_bvneg(self))
9
+ end
10
+
11
+ def &(other)
12
+ Z3.And(self, other)
13
+ end
14
+
15
+ def |(other)
16
+ Z3.Or(self, other)
17
+ end
18
+
19
+ def ^(other)
20
+ Z3.Xor(self, other)
21
+ end
22
+
23
+ def +(other)
24
+ ::Z3.Add(self, other)
25
+ end
26
+
27
+ def -(other)
28
+ ::Z3.Sub(self, other)
29
+ end
30
+
31
+ def *(other)
32
+ ::Z3.Mul(self, other)
33
+ end
34
+
35
+ def >>(other)
36
+ Z3.RShift(self, other)
37
+ end
38
+
39
+ def <<(other)
40
+ Z3.LShift(self, other)
41
+ end
42
+
43
+ def >(other)
44
+ ::Z3.Gt(self, other)
45
+ end
46
+
47
+ def >=(other)
48
+ ::Z3.Ge(self, other)
49
+ end
50
+
51
+ def <=(other)
52
+ ::Z3.Le(self, other)
53
+ end
54
+
55
+ def <(other)
56
+ ::Z3.Lt(self, other)
57
+ end
58
+
59
+ def coerce(other)
60
+ other_sort = Value.sort_for_const(other)
61
+ max_sort = [sort, other_sort].max
62
+ [max_sort.from_const(other), max_sort.from_value(self)]
63
+ end
64
+
65
+ public_class_method :new
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ module Z3
2
+ class BoolValue < Value
3
+ def ~
4
+ sort.new(LowLevel.mk_not(self))
5
+ end
6
+
7
+ def &(other)
8
+ Z3.And(self, other)
9
+ end
10
+
11
+ def |(other)
12
+ Z3.Or(self, other)
13
+ end
14
+
15
+ def ^(other)
16
+ Z3.Xor(self, other)
17
+ end
18
+
19
+ def iff(other)
20
+ Z3.Iff(self, other)
21
+ end
22
+
23
+ def implies(other)
24
+ Z3.Implies(self, other)
25
+ end
26
+
27
+ public_class_method :new
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ module Z3
2
+ class IntValue < Value
3
+ include ArithValue
4
+
5
+ public_class_method :new
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Z3
2
+ class RealValue < Value
3
+ include ArithValue
4
+
5
+ public_class_method :new
6
+ end
7
+ end
@@ -0,0 +1,48 @@
1
+ module Z3
2
+ class Value
3
+ attr_reader :_ast, :sort
4
+ def initialize(_ast, sort)
5
+ @_ast = _ast
6
+ @sort = sort
7
+ end
8
+
9
+ def to_s
10
+ Z3::LowLevel.ast_to_string(self)
11
+ end
12
+
13
+ def inspect
14
+ "Value<#{to_s} :: #{sort.to_s}>"
15
+ end
16
+
17
+ def ==(other)
18
+ ::Z3.Eq(self, other)
19
+ end
20
+
21
+ def !=(other)
22
+ ::Z3.Distinct(self, other)
23
+ end
24
+
25
+ private_class_method :new
26
+
27
+ class << self
28
+ def sort_for_const(a)
29
+ case a
30
+ when TrueClass, FalseClass
31
+ BoolSort.new
32
+ when Integer
33
+ IntSort.new
34
+ when Float
35
+ RealSort.new
36
+ else
37
+ raise Z3::Exception, "No idea how to autoconvert `#{a.class}': `#{a.inspect}'"
38
+ end
39
+ end
40
+
41
+ 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
45
+ end
46
+ end
47
+ end
48
+ end
@@ -5,53 +5,36 @@ require 'ffi'
5
5
  module Z3::VeryLowLevel
6
6
  extend FFI::Library
7
7
  ffi_lib "z3"
8
- # Aliases defined just to make APIs below look nicer
9
- ast_pointer = :pointer
10
- ctx_pointer = :pointer
11
- fixedpoint_pointer = :pointer
12
- func_decl_pointer = :pointer
13
- goal_pointer = :pointer
14
- model_pointer = :pointer
15
- optimize_pointer = :pointer
16
- param_descrs_pointer = :pointer
17
- params_pointer = :pointer
18
- pattern_pointer = :pointer
19
- probe_pointer = :pointer
20
- solver_pointer = :pointer
21
- sort_pointer = :pointer
22
- symbol_pointer = :pointer
23
- tactic_pointer = :pointer
24
- rcf_num_pointer = :pointer
25
- stats_pointer = :pointer
26
- app_pointer = :pointer
27
- apply_result_pointer = :pointer
28
- ast_map_pointer = :pointer
29
- ast_vector_pointer = :pointer
30
- config_pointer = :pointer
31
- constructor_pointer = :pointer
32
- constructor_list_pointer = :pointer
33
- func_entry_pointer = :pointer
34
- func_interp_pointer = :pointer
35
8
 
9
+ class << self
10
+ # Aliases defined just to make APIs below look nicer
11
+ def attach_function(name, arg_types, return_type)
36
12
 
37
- ### Manually added functions gen_api can't handle [yet]
38
- callback :error_handler, [ctx_pointer, :int], :void
39
- attach_function :Z3_get_version, [:pointer, :pointer, :pointer, :pointer], :void
40
- attach_function :Z3_set_error_handler, [ctx_pointer, :error_handler], :void
41
- attach_function :Z3_mk_context, [], ctx_pointer
42
- attach_function :Z3_model_eval, [ctx_pointer, model_pointer, ast_pointer, :bool, :pointer], :int
43
-
44
- # attach_function :Z3_model_get_const_decl, [ctx_pointer, model_pointer, :int], func_decl_pointer
45
- # attach_function :Z3_model_get_const_interp, [ctx_pointer, model_pointer, func_decl_pointer], ast_pointer
46
- # attach_function :Z3_get_decl_name, [ctx_pointer, func_decl_pointer], symbol_pointer
13
+ arg_types = arg_types.map{|t| map_type(t)}
14
+ return_type = map_type(return_type)
15
+ super(name, arg_types, return_type)
16
+ end
47
17
 
48
- attach_function :Z3_mk_and, [ctx_pointer, :int, :pointer], ast_pointer
49
- attach_function :Z3_mk_or, [ctx_pointer, :int, :pointer], ast_pointer
50
- attach_function :Z3_mk_add, [ctx_pointer, :int, :pointer], ast_pointer
51
- attach_function :Z3_mk_sub, [ctx_pointer, :int, :pointer], ast_pointer
52
- attach_function :Z3_mk_mul, [ctx_pointer, :int, :pointer], ast_pointer
53
- attach_function :Z3_mk_distinct, [ctx_pointer, :int, :pointer], ast_pointer
18
+ def map_type(t)
19
+ if t.to_s =~ /\A(.*)_pointer\z/
20
+ :pointer
21
+ else
22
+ t
23
+ end
24
+ end
25
+ end
54
26
 
55
- ### Automatically generated, do not edit that file
56
- eval open("#{__dir__}/very_low_level_auto.rb").read
27
+ ### Manually added functions gen_api can't handle [yet]
28
+ # callback :error_handler, [:ctx_pointer, :int], :void
29
+ callback :error_handler, [:pointer, :int], :void
30
+ attach_function :Z3_get_version, [:pointer, :pointer, :pointer, :pointer], :void
31
+ attach_function :Z3_set_error_handler, [:ctx_pointer, :error_handler], :void
32
+ attach_function :Z3_mk_context, [], :ctx_pointer
33
+ attach_function :Z3_model_eval, [:ctx_pointer, :model_pointer, :ast_pointer, :bool, :pointer], :int
34
+ attach_function :Z3_mk_and, [:ctx_pointer, :int, :pointer], :ast_pointer
35
+ attach_function :Z3_mk_or, [:ctx_pointer, :int, :pointer], :ast_pointer
36
+ attach_function :Z3_mk_add, [:ctx_pointer, :int, :pointer], :ast_pointer
37
+ attach_function :Z3_mk_sub, [:ctx_pointer, :int, :pointer], :ast_pointer
38
+ attach_function :Z3_mk_mul, [:ctx_pointer, :int, :pointer], :ast_pointer
39
+ attach_function :Z3_mk_distinct, [:ctx_pointer, :int, :pointer], :ast_pointer
57
40
  end