z3 0.0.0

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.
data/lib/z3/sort.rb ADDED
@@ -0,0 +1,33 @@
1
+ class Z3::Sort
2
+ attr_reader :_sort
3
+ # Do not use .new directly
4
+ def initialize(_sort)
5
+ @_sort = _sort
6
+ end
7
+
8
+ def ==(other)
9
+ other.is_a?(Z3::Sort) and @_sort == other._sort
10
+ end
11
+
12
+ def to_s
13
+ Z3::LowLevel.sort_to_string(self)
14
+ end
15
+
16
+ def inspect
17
+ "Z3::Sort<#{to_s}>"
18
+ end
19
+
20
+ class << self
21
+ def bool
22
+ Z3::Sort.new(Z3::LowLevel.mk_bool_sort)
23
+ end
24
+
25
+ def int
26
+ Z3::Sort.new(Z3::LowLevel.mk_int_sort)
27
+ end
28
+
29
+ def real
30
+ Z3::Sort.new(Z3::LowLevel.mk_real_sort)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,89 @@
1
+ # Seriously do not use this directly in your code
2
+
3
+ require 'ffi'
4
+
5
+ module Z3::VeryLowLevel
6
+ extend FFI::Library
7
+ ffi_lib "z3"
8
+ # Aliases defined just to make APIs below look nicer
9
+ ctx_pointer = :pointer
10
+ solver_pointer = :pointer
11
+ ast_pointer = :pointer
12
+ sort_pointer = :pointer
13
+ symbol = :pointer
14
+ model_pointer = :pointer
15
+ func_decl_pointer = :pointer
16
+ z3_bool = :int
17
+
18
+ # Common API
19
+ callback :error_handler, [ctx_pointer, :int], :void
20
+
21
+ attach_function :Z3_get_version, [:pointer, :pointer, :pointer, :pointer], :void
22
+ attach_function :Z3_set_error_handler, [ctx_pointer, :error_handler], :void
23
+ attach_function :Z3_global_param_set, [:string, :string], :void
24
+
25
+ # Context API
26
+ attach_function :Z3_mk_context, [], ctx_pointer
27
+
28
+ # Symbol API
29
+ attach_function :Z3_mk_string_symbol, [ctx_pointer, :string], symbol
30
+ attach_function :Z3_get_symbol_string, [ctx_pointer, symbol], :string
31
+
32
+ # Sort API
33
+ attach_function :Z3_mk_bool_sort, [ctx_pointer], sort_pointer
34
+ attach_function :Z3_mk_int_sort, [ctx_pointer], sort_pointer
35
+ attach_function :Z3_mk_real_sort, [ctx_pointer], sort_pointer
36
+ attach_function :Z3_sort_to_string, [ctx_pointer, sort_pointer], :string
37
+
38
+ # Solver API
39
+ attach_function :Z3_mk_solver, [ctx_pointer], solver_pointer
40
+ attach_function :Z3_solver_push, [ctx_pointer, solver_pointer], :void
41
+ attach_function :Z3_solver_pop, [ctx_pointer, solver_pointer, :int], :void
42
+ attach_function :Z3_solver_reset, [ctx_pointer, solver_pointer], :void
43
+ attach_function :Z3_solver_assert, [ctx_pointer, solver_pointer, ast_pointer], :void
44
+ attach_function :Z3_solver_check, [ctx_pointer, solver_pointer], z3_bool
45
+ attach_function :Z3_solver_inc_ref, [ctx_pointer, solver_pointer], :void
46
+
47
+ # Model API
48
+ attach_function :Z3_solver_get_model, [ctx_pointer, solver_pointer], model_pointer
49
+ attach_function :Z3_model_get_num_consts, [ctx_pointer, model_pointer], :int
50
+ attach_function :Z3_model_get_num_funcs, [ctx_pointer, model_pointer], :int
51
+ attach_function :Z3_model_get_num_sorts, [ctx_pointer, model_pointer], :int
52
+ attach_function :Z3_model_eval, [ctx_pointer, model_pointer, ast_pointer, :bool, :pointer], :int
53
+ attach_function :Z3_model_get_const_decl, [ctx_pointer, model_pointer, :int], func_decl_pointer
54
+ attach_function :Z3_model_get_const_interp, [ctx_pointer, model_pointer, func_decl_pointer], ast_pointer
55
+
56
+ # FuncDecl API
57
+ attach_function :Z3_func_decl_to_ast, [ctx_pointer, func_decl_pointer], ast_pointer
58
+ attach_function :Z3_get_decl_name, [ctx_pointer, func_decl_pointer], symbol
59
+ attach_function :Z3_get_arity, [ctx_pointer, func_decl_pointer], :uint
60
+ attach_function :Z3_get_decl_ast_parameter, [ctx_pointer, func_decl_pointer, :uint], ast_pointer
61
+
62
+ # AST API
63
+ attach_function :Z3_mk_true, [ctx_pointer], ast_pointer
64
+ attach_function :Z3_mk_false, [ctx_pointer], ast_pointer
65
+ attach_function :Z3_mk_eq, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
66
+ attach_function :Z3_mk_ge, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
67
+ attach_function :Z3_mk_gt, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
68
+ attach_function :Z3_mk_le, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
69
+ attach_function :Z3_mk_lt, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
70
+ attach_function :Z3_mk_power, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
71
+ attach_function :Z3_mk_rem, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
72
+ attach_function :Z3_mk_mod, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
73
+ attach_function :Z3_mk_div, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
74
+ attach_function :Z3_mk_not, [ctx_pointer, ast_pointer], ast_pointer
75
+ attach_function :Z3_mk_const, [ctx_pointer, symbol, sort_pointer], ast_pointer
76
+ attach_function :Z3_mk_and, [ctx_pointer, :int, :pointer], ast_pointer
77
+ attach_function :Z3_mk_or, [ctx_pointer, :int, :pointer], ast_pointer
78
+ attach_function :Z3_mk_iff, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
79
+ attach_function :Z3_mk_implies, [ctx_pointer, ast_pointer, ast_pointer], ast_pointer
80
+ attach_function :Z3_mk_add, [ctx_pointer, :int, :pointer], ast_pointer
81
+ attach_function :Z3_mk_sub, [ctx_pointer, :int, :pointer], ast_pointer
82
+ attach_function :Z3_mk_mul, [ctx_pointer, :int, :pointer], ast_pointer
83
+ attach_function :Z3_mk_distinct, [ctx_pointer, :int, :pointer], ast_pointer
84
+ attach_function :Z3_ast_to_string, [ctx_pointer, ast_pointer], :string
85
+ attach_function :Z3_get_sort, [ctx_pointer, ast_pointer], sort_pointer
86
+ attach_function :Z3_mk_int2real, [ctx_pointer, ast_pointer], ast_pointer
87
+ attach_function :Z3_mk_numeral, [ctx_pointer, :string, sort_pointer], ast_pointer
88
+ attach_function :Z3_mk_unary_minus, [ctx_pointer, ast_pointer], ast_pointer
89
+ end
data/lib/z3.rb ADDED
@@ -0,0 +1,43 @@
1
+ module Z3
2
+ class <<self
3
+ def version
4
+ Z3::LowLevel.get_version.join(".")
5
+ end
6
+
7
+ def set_param(k,v)
8
+ Z3::LowLevel.global_param_set(k,v)
9
+ end
10
+ end
11
+ end
12
+
13
+ class Z3::Exception < StandardError
14
+ end
15
+
16
+ require_relative "z3/very_low_level"
17
+ require_relative "z3/low_level"
18
+ require_relative "z3/context"
19
+ require_relative "z3/solver"
20
+ require_relative "z3/sort"
21
+ require_relative "z3/ast"
22
+ require_relative "z3/model"
23
+ require_relative "z3/func_decl"
24
+
25
+ Z3::LowLevel.set_error_handler do |ctx, error|
26
+ error_codes_enum = %W[
27
+ Z3_OK
28
+ Z3_SORT_ERROR
29
+ Z3_IOB
30
+ Z3_INVALID_ARG
31
+ Z3_PARSER_ERROR
32
+ Z3_NO_PARSER
33
+ Z3_INVALID_PATTERN
34
+ Z3_MEMOUT_FAIL
35
+ Z3_FILE_ACCESS_ERROR
36
+ Z3_INTERNAL_FATAL
37
+ Z3_INVALID_USAGE
38
+ Z3_DEC_REF_ERROR
39
+ Z3_EXCEPTION
40
+ ]
41
+ error = error_codes_enum[error] || error
42
+ raise Z3::Exception, "Z3 library failed with error #{error}"
43
+ end
data/spec/ast_spec.rb ADDED
@@ -0,0 +1,172 @@
1
+ describe Z3::Ast do
2
+ let(:a) { Z3::Ast.int("a") }
3
+ let(:b) { Z3::Ast.int("b") }
4
+ let(:c) { Z3::Ast.bool("c") }
5
+ let(:d) { Z3::Ast.bool("d") }
6
+ let(:e) { Z3::Ast.real("e") }
7
+ let(:f) { Z3::Ast.real("f") }
8
+
9
+ it "#sort returns Sort object" do
10
+ expect(a.sort).to eq(Z3::Sort.int)
11
+ expect(c.sort).to eq(Z3::Sort.bool)
12
+ expect(e.sort).to eq(Z3::Sort.real)
13
+ end
14
+
15
+ it "#to_s" do
16
+ expect(a.to_s).to eq("a")
17
+ end
18
+
19
+ it "#inspect" do
20
+ expect(a.inspect).to eq("Z3::Ast<a :: Int>")
21
+ expect((e+f).inspect).to eq("Z3::Ast<(+ e f) :: Real>")
22
+ end
23
+
24
+ describe "#~" do
25
+ it "allows negating boolean variables" do
26
+ expect((~c).to_s).to eq("(not c)")
27
+ end
28
+
29
+ it "raises exception if type cast is not possible" do
30
+ expect{~a}.to raise_error(Z3::Exception)
31
+ expect{~e}.to raise_error(Z3::Exception)
32
+ end
33
+ end
34
+
35
+ describe "#&" do
36
+ it "allows and of boolean variables" do
37
+ expect((c & d).to_s).to eq("(and c d)")
38
+ end
39
+
40
+ it "raises exception if type cast is not possible" do
41
+ expect{a&b}.to raise_error(Z3::Exception)
42
+ expect{e&f}.to raise_error(Z3::Exception)
43
+ expect{a&c}.to raise_error(Z3::Exception)
44
+ expect{e&c}.to raise_error(Z3::Exception)
45
+ expect{c&a}.to raise_error(Z3::Exception)
46
+ expect{c&e}.to raise_error(Z3::Exception)
47
+ end
48
+ end
49
+
50
+ describe "#|" do
51
+ it "allows or of boolean variables" do
52
+ expect((c | d).to_s).to eq("(or c d)")
53
+ end
54
+
55
+ it "raises exception if type cast is not possible" do
56
+ expect{a|b}.to raise_error(Z3::Exception)
57
+ expect{e|f}.to raise_error(Z3::Exception)
58
+ expect{a|c}.to raise_error(Z3::Exception)
59
+ expect{e|c}.to raise_error(Z3::Exception)
60
+ expect{c|a}.to raise_error(Z3::Exception)
61
+ expect{c|e}.to raise_error(Z3::Exception)
62
+ end
63
+ end
64
+
65
+ %W[+ - * <= < >= >].each do |op|
66
+ describe "#{op} arithmetic operator" do
67
+ it "allows + of int or real variables" do
68
+ expect((a.send op, b).to_s).to eq "(#{op} a b)"
69
+ expect((e.send op, f).to_s).to eq "(#{op} e f)"
70
+ end
71
+
72
+ it "casts to correct type if possible" do
73
+ expect((a.send op, e).to_s).to eq "(#{op} (to_real a) e)"
74
+ expect((e.send op, a).to_s).to eq "(#{op} e (to_real a))"
75
+ expect((a.send op, 42).to_s).to eq "(#{op} a 42)"
76
+ expect((42.send op, a).to_s).to eq "(#{op} 42 a)"
77
+ expect((a.send op, 42.5).to_s).to eq "(#{op} (to_real a) (/ 85.0 2.0))"
78
+ expect((42.5.send op, a).to_s).to eq "(#{op} (/ 85.0 2.0) (to_real a))"
79
+ expect((e.send op, 42).to_s).to eq "(#{op} e 42.0)"
80
+ expect((42.send op, e).to_s).to eq "(#{op} 42.0 e)"
81
+ expect((e.send op, 42.5).to_s).to eq "(#{op} e (/ 85.0 2.0))"
82
+ expect((42.5.send op, e).to_s).to eq "(#{op} (/ 85.0 2.0) e)"
83
+ end
84
+
85
+ it "raises exception if type cast is not possible" do
86
+ expect{a.send op, c}.to raise_error(Z3::Exception)
87
+ expect{c.send op, a}.to raise_error(Z3::Exception)
88
+ expect{e.send op, c}.to raise_error(Z3::Exception)
89
+ expect{c.send op, e}.to raise_error(Z3::Exception)
90
+ expect{c.send op, d}.to raise_error(Z3::Exception)
91
+ expect{a.send op, true}.to raise_error(Z3::Exception)
92
+ expect{c.send op, true}.to raise_error(Z3::Exception)
93
+ expect{e.send op, true}.to raise_error(Z3::Exception)
94
+ expect{a.send op, false}.to raise_error(Z3::Exception)
95
+ expect{c.send op, false}.to raise_error(Z3::Exception)
96
+ expect{e.send op, false}.to raise_error(Z3::Exception)
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "#==" do
102
+ it "allows == of variables of same sort" do
103
+ expect((a == b).to_s).to eq "(= a b)"
104
+ expect((c == d).to_s).to eq "(= c d)"
105
+ expect((e == f).to_s).to eq "(= e f)"
106
+ end
107
+
108
+ it "casts to correct type if possible" do
109
+ expect((a == 42).to_s).to eq "(= a 42)"
110
+ expect((42 == a).to_s).to eq "(= a 42)"
111
+ expect((a == e).to_s).to eq "(= (to_real a) e)"
112
+ expect((e == a).to_s).to eq "(= e (to_real a))"
113
+ expect((c == true).to_s).to eq "(= c true)"
114
+ expect((c == false).to_s).to eq "(= c false)"
115
+ expect((a == 42.5).to_s).to eq "(= (to_real a) (/ 85.0 2.0))"
116
+ expect((42.5 == a).to_s).to eq "(= (to_real a) (/ 85.0 2.0))"
117
+ expect((e == 42.5).to_s).to eq "(= e (/ 85.0 2.0))"
118
+ expect((42.5 == e).to_s).to eq "(= e (/ 85.0 2.0))"
119
+ # expect((true == c).to_s).to eq "(= true c)"
120
+ # expect((false == c).to_s).to eq "(= false c)"
121
+ end
122
+
123
+ it "raises exception if type cast is not possible" do
124
+ expect{a == c}.to raise_error(Z3::Exception)
125
+ expect{e == c}.to raise_error(Z3::Exception)
126
+ expect{a == true}.to raise_error(Z3::Exception)
127
+ expect{e == true}.to raise_error(Z3::Exception)
128
+ # expect{true == a}.to raise_error(Z3::Exception)
129
+ # expect{true == e}.to raise_error(Z3::Exception)
130
+ expect{c == 42}.to raise_error(Z3::Exception)
131
+ expect{c == 42.5}.to raise_error(Z3::Exception)
132
+ expect{42 == c}.to raise_error(Z3::Exception)
133
+ expect{42.5 == c}.to raise_error(Z3::Exception)
134
+ end
135
+ end
136
+
137
+ describe "#!=" do
138
+ it "allows != of variables of same sort" do
139
+ expect((a != b).to_s).to eq "(distinct a b)"
140
+ expect((c != d).to_s).to eq "(distinct c d)"
141
+ expect((e != f).to_s).to eq "(distinct e f)"
142
+ end
143
+
144
+ it "casts to correct type if possible" do
145
+ expect((a != 42).to_s).to eq "(distinct a 42)"
146
+ # expect((42 != a).to_s).to eq "(distinct a 42)"
147
+ expect((a != e).to_s).to eq "(distinct (to_real a) e)"
148
+ expect((e != a).to_s).to eq "(distinct e (to_real a))"
149
+ expect((c != true).to_s).to eq "(distinct c true)"
150
+ expect((c != false).to_s).to eq "(distinct c false)"
151
+ expect((a != 42.5).to_s).to eq "(distinct (to_real a) (/ 85.0 2.0))"
152
+ # expect((42.5 != a).to_s).to eq "(distinct (to_real a) (/ 85.0 2.0))"
153
+ expect((e != 42.5).to_s).to eq "(distinct e (/ 85.0 2.0))"
154
+ # expect((42.5 != e).to_s).to eq "(distinct e (/ 85.0 2.0))"
155
+ # expect((true != c).to_s).to eq "(distinct true c)"
156
+ # expect((false != c).to_s).to eq "(distinct false c)"
157
+ end
158
+
159
+ it "raises exception if type cast is not possible" do
160
+ expect{a != c}.to raise_error(Z3::Exception)
161
+ expect{e != c}.to raise_error(Z3::Exception)
162
+ expect{a != true}.to raise_error(Z3::Exception)
163
+ expect{e != true}.to raise_error(Z3::Exception)
164
+ # expect{true != a}.to raise_error(Z3::Exception)
165
+ # expect{true != e}.to raise_error(Z3::Exception)
166
+ expect{c != 42}.to raise_error(Z3::Exception)
167
+ expect{c != 42.5}.to raise_error(Z3::Exception)
168
+ # expect{42 != c}.to raise_error(Z3::Exception)
169
+ # expect{42.5 != c}.to raise_error(Z3::Exception)
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,30 @@
1
+ describe "Algebra Problems" do
2
+ let(:executable) { "#{__dir__}/../../examples/algebra_problems" }
3
+ it "can solve algebra puzzles" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ Solution to problem 01:
6
+ Solution to problem 03:
7
+ * x = (- 22.0)
8
+ * |-6| = 6.0
9
+ * |x-2| = 24.0
10
+ Solution to problem 04:
11
+ * ax = (- 4.0)
12
+ * ay = (- 5.0)
13
+ * bx = (- 1.0)
14
+ * by = (- 1.0)
15
+ * |a-b| = 5.0
16
+ Solution to problem 05:
17
+ * x = (/ 9.0 2.0)
18
+ * y = 0.0
19
+ Solution to problem 06:
20
+ * answer = 6.0
21
+ * x1 = 1.0
22
+ * x2 = 2.0
23
+ * y1 = 7.0
24
+ * y2 = 13.0
25
+ Solution to problem 10:
26
+ * x = 1.0
27
+ * |-2x + 2| = 0.0
28
+ EOF
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ describe "Basic Int Math" do
2
+ let(:executable) { "#{__dir__}/../../examples/basic_int_math" }
3
+ it "can solve basic integer math problems" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ Checking if (a+b)(a-b)==a*a-b*b
6
+ Proven
7
+ Checking if a+b >= a
8
+ Counterexample exists
9
+ * b = (- 1)
10
+ Checking if a+b >= a if a,b >= 0
11
+ Proven
12
+ EOF
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ describe "Basic Logic" do
2
+ let(:executable) { "#{__dir__}/../../examples/basic_logic" }
3
+ it "can solve basic logic problems" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ Checking if true == true
6
+ Proven
7
+ Checking if true == false
8
+ Counterexample exists
9
+ Proving ~(a & b) == (~a | ~b)
10
+ Proven
11
+ Proving ~(a | b) == (~a & ~b)
12
+ Proven
13
+ EOF
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ describe "Geometry Problem" do
2
+ let(:executable) { "#{__dir__}/../../examples/geometry_problem" }
3
+ it "can solve verbal arithmetic puzzles" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ * a.x = 0.0
6
+ * a.y = (root-obj (+ (^ x 2) (- 300)) 1)
7
+ * b.x = 0.0
8
+ * b.y = 0.0
9
+ * c.x = 10.0
10
+ * c.y = 0.0
11
+ * d.x = 10.0
12
+ * d.y = (root-obj (+ (^ x 2) (- 300)) 1)
13
+ * |a-c| = (- 20.0)
14
+ * |b-d| = 20.0
15
+ EOF
16
+ end
17
+ end
@@ -0,0 +1,54 @@
1
+ describe "Kinematics Problems" do
2
+ let(:executable) { "#{__dir__}/../../examples/kinematics_problems" }
3
+ it "can solve kinematics problems" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ Solution to problem 01:
6
+ * a = (/ 16.0 5.0)
7
+ * d = (/ 215168.0 125.0)
8
+ * t = (/ 164.0 5.0)
9
+ Solution to problem 02:
10
+ * a = (/ 2200000.0 271441.0)
11
+ * d = 110.0
12
+ * t = (/ 521.0 100.0)
13
+ Solution to problem 03:
14
+ * a = (/ 981.0 100.0)
15
+ * d = (/ 165789.0 5000.0)
16
+ * t = (/ 13.0 5.0)
17
+ * v = (/ 12753.0 500.0)
18
+ Solution to problem 04:
19
+ * a = (/ 2760.0 247.0)
20
+ * d = (/ 79781.0 1000.0)
21
+ * t = (/ 247.0 100.0)
22
+ * ve = (/ 461.0 10.0)
23
+ * vs = (/ 37.0 2.0)
24
+ Solution to problem 05:
25
+ * a = (/ 167.0 100.0)
26
+ * d = (/ 7.0 5.0)
27
+ * t = (root-obj (+ (* 167 (^ x 2)) (- 280)) 2)
28
+ Solution to problem 06:
29
+ * a = (/ 14800.0 61.0)
30
+ * d = (/ 20313.0 50.0)
31
+ * t = (/ 183.0 100.0)
32
+ * v = 444.0
33
+ Solution to problem 07:
34
+ * a = (/ 5041.0 7080.0)
35
+ * d = (/ 177.0 5.0)
36
+ * t = (/ 708.0 71.0)
37
+ * v = (/ 71.0 10.0)
38
+ Solution to problem 08:
39
+ * a = 3.0
40
+ * d = (/ 4225.0 6.0)
41
+ * t = (/ 65.0 3.0)
42
+ * v = 65.0
43
+ Solution to problem 09:
44
+ * d = (/ 714.0 25.0)
45
+ * t = (/ 51.0 20.0)
46
+ * v = (/ 112.0 5.0)
47
+ Solution to problem 10:
48
+ * a = (- (/ 981.0 100.0))
49
+ * d = (/ 131.0 50.0)
50
+ * t = (root-obj (+ (* 981 (^ x 2)) (- 524)) 2)
51
+ * v = (root-obj (+ (* 2500 (^ x 2)) (- 128511)) 2)
52
+ EOF
53
+ end
54
+ end
@@ -0,0 +1,14 @@
1
+ describe "LightUp" do
2
+ let(:executable) { "#{__dir__}/../../examples/light_up_solver" }
3
+ it "can solve light up puzzle" do
4
+ expect(IO.popen(executable).read.gsub(/ *$/, "")).to eq <<EOF
5
+ * 0
6
+ *
7
+ x 2*x
8
+ *3 *
9
+ * x*x*3
10
+ *
11
+ *1 *
12
+ EOF
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ describe "MiniSudoku" do
2
+ let(:executable) { "#{__dir__}/../../examples/minisudoku_solver" }
3
+ it "can solve minisudoku" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ 2 1 5 4 3 6
6
+ 3 6 4 1 2 5
7
+ 1 3 6 5 4 2
8
+ 4 5 2 3 6 1
9
+ 5 2 3 6 1 4
10
+ 6 4 1 2 5 3
11
+ EOF
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ describe "Self-Referential Aptitude Test" do
2
+ let(:executable) { "#{__dir__}/../../examples/selfref_solver" }
3
+ it "can solve minisudokus" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ Q 1: D
6
+ Q 2: A
7
+ Q 3: D
8
+ Q 4: B
9
+ Q 5: E
10
+ Q 6: D
11
+ Q 7: D
12
+ Q 8: E
13
+ Q 9: D
14
+ Q10: A
15
+ Q11: B
16
+ Q12: A
17
+ Q13: D
18
+ Q14: B
19
+ Q15: A
20
+ Q16: D
21
+ Q17: B
22
+ Q18: A
23
+ Q19: B
24
+ Q20: E
25
+ EOF
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ describe "Sudoku" do
2
+ let(:executable) { "#{__dir__}/../../examples/sudoku_solver" }
3
+ it "can solve sudoku" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ 8 6 3 5 7 9 2 4 1
6
+ 9 2 5 3 1 4 8 7 6
7
+ 4 7 1 8 2 6 9 5 3
8
+ 7 1 4 6 8 3 5 2 9
9
+ 6 8 9 7 5 2 3 1 4
10
+ 3 5 2 4 9 1 6 8 7
11
+ 1 3 6 2 4 5 7 9 8
12
+ 2 4 8 9 3 7 1 6 5
13
+ 5 9 7 1 6 8 4 3 2
14
+ EOF
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ describe "Verbal Arithmetic" do
2
+ let(:executable) { "#{__dir__}/../../examples/verbal_arithmetic" }
3
+ it "can solve verbal arithmetic puzzles" do
4
+ expect(IO.popen(executable).read).to eq <<EOF
5
+ [["S", 9], ["E", 5], ["N", 6], ["D", 7]]
6
+ [["M", 1], ["O", 0], ["R", 8], ["E", 5]]
7
+ [["M", 1], ["O", 0], ["N", 6], ["E", 5], ["Y", 2]]
8
+ EOF
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ # Solver and Model specs are codependent, so half of functionality of each is tested in other class's tests
2
+ describe Z3::Model do
3
+ let(:solver) { Z3::Solver.new }
4
+ let(:a) { Z3::Ast.int("a") }
5
+ let(:b) { Z3::Ast.int("b") }
6
+ let(:c) { Z3::Ast.int("c") }
7
+ let(:model) { solver.model }
8
+
9
+ it "knows how many variables are in the model" do
10
+ solver.assert(a == 2)
11
+ solver.assert(b == a+2)
12
+ expect(solver.check).to eq(:sat)
13
+ expect(model.num_consts).to eq(2)
14
+ expect(model.num_funcs).to eq(0)
15
+ expect(model.num_sorts).to eq(0)
16
+ end
17
+
18
+ it "can evaluate variables" do
19
+ solver.assert(a == 2)
20
+ solver.assert(b == a+2)
21
+ expect(solver.check).to eq(:sat)
22
+ expect(model.model_eval(a).inspect).to eq("Z3::Ast<2 :: Int>")
23
+ expect(model.model_eval(b).inspect).to eq("Z3::Ast<4 :: Int>")
24
+ expect(model.model_eval(c).inspect).to eq("Z3::Ast<c :: Int>")
25
+ expect(model.model_eval(a, true).inspect).to eq("Z3::Ast<2 :: Int>")
26
+ expect(model.model_eval(b, true).inspect).to eq("Z3::Ast<4 :: Int>")
27
+ expect(model.model_eval(c, true).inspect).to eq("Z3::Ast<0 :: Int>")
28
+ end
29
+
30
+ it "#to_s" do
31
+ solver.assert(a == 2)
32
+ solver.assert(b == a+2)
33
+ expect(solver.check).to eq(:sat)
34
+ expect(model.to_s).to eq("Z3::Model<a=2, b=4>")
35
+ expect(model.inspect).to eq("Z3::Model<a=2, b=4>")
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ # Solver and Model specs are codependent, so half of functionality of each is tested in other class's tests
2
+ describe Z3::Solver do
3
+ let(:solver) { Z3::Solver.new }
4
+ let(:a) { Z3::Ast.int("a") }
5
+ let(:b) { Z3::Ast.int("b") }
6
+
7
+ it "basic functionality" do
8
+ solver.assert(a == b)
9
+ expect(solver.check).to eq(:sat)
10
+ solver.assert(a != b)
11
+ expect(solver.check).to eq(:unsat)
12
+ end
13
+
14
+ it "push/pop" do
15
+ solver.assert(a == b)
16
+ solver.push
17
+ solver.assert(a != b)
18
+ expect(solver.check).to eq(:unsat)
19
+ solver.pop
20
+ expect(solver.check).to eq(:sat)
21
+ end
22
+ end
data/spec/sort_spec.rb ADDED
@@ -0,0 +1,22 @@
1
+ describe Z3::Sort do
2
+ it "#bool creates Bool sort" do
3
+ expect(Z3::Sort.bool.to_s).to eq("Bool")
4
+ expect(Z3::Sort.bool.inspect).to eq("Z3::Sort<Bool>")
5
+ end
6
+
7
+ it "#int creates Int sort" do
8
+ expect(Z3::Sort.int.to_s).to eq("Int")
9
+ expect(Z3::Sort.int.inspect).to eq("Z3::Sort<Int>")
10
+ end
11
+
12
+ it "#real creates Real sort" do
13
+ expect(Z3::Sort.real.to_s).to eq("Real")
14
+ expect(Z3::Sort.real.inspect).to eq("Z3::Sort<Real>")
15
+ end
16
+
17
+ it "supports ==" do
18
+ expect(Z3::Sort.bool).to eq(Z3::Sort.bool)
19
+ expect(Z3::Sort.int).to eq(Z3::Sort.int)
20
+ expect(Z3::Sort.bool).to_not eq(Z3::Sort.int)
21
+ end
22
+ end