z3 0.0.20160427 → 0.0.20161008

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/Rakefile +56 -0
  4. data/examples/bit_tricks +21 -38
  5. data/examples/circuit_problems +170 -0
  6. data/lib/z3/ast.rb +21 -3
  7. data/lib/z3/context.rb +9 -7
  8. data/lib/z3/exception.rb +1 -2
  9. data/lib/z3/expr/arith_expr.rb +29 -11
  10. data/lib/z3/expr/array_expr.rb +5 -0
  11. data/lib/z3/expr/bitvec_expr.rb +293 -13
  12. data/lib/z3/expr/bool_expr.rb +30 -6
  13. data/lib/z3/expr/expr.rb +155 -2
  14. data/lib/z3/expr/float_expr.rb +185 -0
  15. data/lib/z3/expr/int_expr.rb +20 -5
  16. data/lib/z3/expr/real_expr.rb +1 -3
  17. data/lib/z3/expr/rounding_mode_expr.rb +5 -0
  18. data/lib/z3/expr/set_expr.rb +66 -0
  19. data/lib/z3/func_decl.rb +5 -5
  20. data/lib/z3/goal.rb +64 -0
  21. data/lib/z3/interface.rb +21 -222
  22. data/lib/z3/low_level.rb +84 -58
  23. data/lib/z3/low_level_auto.rb +1509 -1563
  24. data/lib/z3/model.rb +39 -37
  25. data/lib/z3/printer.rb +54 -12
  26. data/lib/z3/probe.rb +69 -0
  27. data/lib/z3/solver.rb +20 -20
  28. data/lib/z3/sort/array_sort.rb +24 -0
  29. data/lib/z3/sort/bitvec_sort.rb +1 -1
  30. data/lib/z3/sort/float_sort.rb +92 -0
  31. data/lib/z3/sort/rounding_mode_sort.rb +41 -0
  32. data/lib/z3/sort/set_sort.rb +31 -0
  33. data/lib/z3/sort/sort.rb +39 -5
  34. data/lib/z3/tactic.rb +69 -0
  35. data/lib/z3/very_low_level.rb +33 -29
  36. data/lib/z3/very_low_level_auto.rb +505 -517
  37. data/lib/z3.rb +13 -0
  38. data/spec/array_expr_spec.rb +18 -0
  39. data/spec/array_sort_spec.rb +11 -0
  40. data/spec/bitvec_expr_spec.rb +196 -44
  41. data/spec/bitvec_sort_spec.rb +29 -27
  42. data/spec/bool_expr_spec.rb +57 -55
  43. data/spec/bool_sort_spec.rb +17 -15
  44. data/spec/coverage_helper.rb +11 -0
  45. data/spec/expr_spec.rb +151 -147
  46. data/spec/float_expr_spec.rb +167 -0
  47. data/spec/float_sort_spec.rb +44 -0
  48. data/spec/goal_spec.rb +17 -0
  49. data/spec/int_expr_spec.rb +76 -63
  50. data/spec/int_sort_spec.rb +16 -14
  51. data/spec/integration/algebra_problems_spec.rb +4 -4
  52. data/spec/integration/cicruit_problem_spec.rb +23 -0
  53. data/spec/integration/geometry_problem_spec.rb +4 -4
  54. data/spec/integration/kinematics_problems_spec.rb +3 -3
  55. data/spec/model_spec.rb +39 -37
  56. data/spec/printer_spec.rb +49 -18
  57. data/spec/probe_spec.rb +17 -0
  58. data/spec/real_expr_spec.rb +59 -51
  59. data/spec/real_sort_spec.rb +22 -20
  60. data/spec/rounding_mode_expr_spec.rb +16 -0
  61. data/spec/rounding_mode_sort_spec.rb +13 -0
  62. data/spec/set_expr_spec.rb +61 -0
  63. data/spec/set_sort_spec.rb +27 -0
  64. data/spec/solver_spec.rb +37 -27
  65. data/spec/sort_spec.rb +38 -36
  66. data/spec/spec_helper.rb +59 -2
  67. data/spec/tactic_spec.rb +9 -0
  68. metadata +44 -4
@@ -0,0 +1,13 @@
1
+ module Z3
2
+ describe RoundingModeSort do
3
+ let(:sort) { RoundingModeSort.new }
4
+
5
+ it "to_s" do
6
+ expect(sort.to_s).to eq("RoundingMode")
7
+ end
8
+
9
+ it "inspect" do
10
+ expect(sort.inspect).to eq("RoundingModeSort")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,61 @@
1
+ module Z3
2
+ describe SetExpr do
3
+ let(:sort) { SetSort.new(IntSort.new) }
4
+ let(:a) { sort.var("a") }
5
+ let(:b) { sort.var("b") }
6
+ let(:c) { sort.var("c") }
7
+ let(:x) { Z3::Bool("x") }
8
+
9
+ # TODO: Formatting is dreadful
10
+ it "== and !=" do
11
+ expect([a == b, b != c]).to have_solution(
12
+ a => "store(const(false), 0, true)",
13
+ b => "store(const(false), 0, true)",
14
+ c => "const(false)",
15
+ )
16
+ end
17
+
18
+ # FIXME: This is not even real spec at this point, just a no-crash-spec
19
+ it "union" do
20
+ expect([
21
+ a.include?(1),
22
+ a.include?(2),
23
+ b.include?(2),
24
+ b.include?(3),
25
+ c == a.union(b),
26
+ ]).to have_solution(
27
+ a => "(declare-fun k! (Int) Bool)",
28
+ b => "(declare-fun k! (Int) Bool)",
29
+ c => "(declare-fun k! (Int) Bool)",
30
+ )
31
+ end
32
+
33
+ it "difference" do
34
+ expect([
35
+ a.include?(1),
36
+ a.include?(2),
37
+ b.include?(2),
38
+ b.include?(3),
39
+ c == a.difference(b),
40
+ ]).to have_solution(
41
+ a => "(declare-fun k! (Int) Bool)",
42
+ b => "(declare-fun k! (Int) Bool)",
43
+ c => "(declare-fun k! (Int) Bool)",
44
+ )
45
+ end
46
+
47
+ it "intersection" do
48
+ expect([
49
+ a.include?(1),
50
+ a.include?(2),
51
+ b.include?(2),
52
+ b.include?(3),
53
+ c == a.intersection(b),
54
+ ]).to have_solution(
55
+ a => "(declare-fun k! (Int) Bool)",
56
+ b => "(declare-fun k! (Int) Bool)",
57
+ c => "(declare-fun k! (Int) Bool)",
58
+ )
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,27 @@
1
+ module Z3
2
+ describe SetSort do
3
+
4
+ let(:int_set) { SetSort.new(IntSort.new) }
5
+ let(:real_set) { SetSort.new(RealSort.new) }
6
+ let(:bool_set) { SetSort.new(BoolSort.new) }
7
+ let(:bv32_set) { SetSort.new(BitvecSort.new(32)) }
8
+ let(:int_set_set) { SetSort.new(SetSort.new(IntSort.new)) }
9
+
10
+ it "can instantiate variables" do
11
+ expect(int_set.var("a").inspect).to eq("Set(Int)<a>")
12
+ expect(real_set.var("a").inspect).to eq("Set(Real)<a>")
13
+ expect(bool_set.var("a").inspect).to eq("Set(Bool)<a>")
14
+ expect(bv32_set.var("a").inspect).to eq("Set(Bitvec(32))<a>")
15
+ expect(int_set_set.var("a").inspect).to eq("Set(Set(Int))<a>")
16
+ end
17
+
18
+ # These are pretty awful formattings
19
+ it "can instantiate full set" do
20
+ expect(int_set.Full.inspect).to eq("Set(Int)<const(true)>")
21
+ end
22
+
23
+ it "can instantiate empty set" do
24
+ expect(int_set.Empty.inspect).to eq("Set(Int)<const(false)>")
25
+ end
26
+ end
27
+ end
data/spec/solver_spec.rb CHANGED
@@ -1,33 +1,43 @@
1
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.Int("a") }
5
- let(:b) { Z3.Int("b") }
2
+ module Z3
3
+ describe Solver do
4
+ let(:solver) { Solver.new }
5
+ let(:a) { Z3.Int("a") }
6
+ let(:b) { Z3.Int("b") }
6
7
 
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
8
+ it "basic functionality" do
9
+ solver.assert(a == b)
10
+ expect(solver.check).to eq(:sat)
11
+ solver.assert(a != b)
12
+ expect(solver.check).to eq(:unsat)
13
+ end
13
14
 
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
15
+ it "push/pop" do
16
+ solver.assert(a == b)
17
+ solver.push
18
+ solver.assert(a != b)
19
+ expect(solver.check).to eq(:unsat)
20
+ solver.pop
21
+ expect(solver.check).to eq(:sat)
22
+ end
23
+
24
+ it "#assertions" do
25
+ solver.assert a + b == 4
26
+ solver.assert b >= 2
27
+ solver.assert Z3.Or(a == 2, a == -2)
28
+ expect(solver.assertions).to be_same_as([
29
+ a + b == 4,
30
+ b >= 2,
31
+ (a == 2) | (a == -2),
32
+ ])
33
+ end
22
34
 
23
- it "#assertions" do
24
- solver.assert a + b == 4
25
- solver.assert b >= 2
26
- solver.assert Z3.Or(a == 2, a == -2)
27
- expect(solver.assertions).to be_same_as([
28
- a + b == 4,
29
- b >= 2,
30
- (a == 2) | (a == -2),
31
- ])
35
+ it "#statistics" do
36
+ solver.assert a + b == 4
37
+ solver.assert b >= 2
38
+ solver.assert Z3.Or(a == 2, a == -2)
39
+ stats = solver.statistics
40
+ expect(stats.keys).to match_array(["rlimit count", "max memory", "memory", "num allocs"])
41
+ end
32
42
  end
33
43
  end
data/spec/sort_spec.rb CHANGED
@@ -1,45 +1,47 @@
1
- describe Z3::Sort do
2
- let(:bool_sort) { Z3::BoolSort.new }
3
- let(:int_sort) { Z3::IntSort.new }
4
- let(:real_sort) { Z3::RealSort.new }
5
- let(:bv8_sort) { Z3::BitvecSort.new(8) }
6
- let(:bv32_sort) { Z3::BitvecSort.new(32) }
1
+ module Z3
2
+ describe Sort do
3
+ let(:bool_sort) { BoolSort.new }
4
+ let(:int_sort) { IntSort.new }
5
+ let(:real_sort) { RealSort.new }
6
+ let(:bv8_sort) { BitvecSort.new(8) }
7
+ let(:bv32_sort) { BitvecSort.new(32) }
7
8
 
8
- let(:sorts) { [bool_sort, int_sort, real_sort, bv8_sort, bv32_sort] }
9
+ let(:sorts) { [bool_sort, int_sort, real_sort, bv8_sort, bv32_sort] }
9
10
 
10
- it "can't instantiate Sort abstract superclass" do
11
- expect{ Z3::Sort.new }.to raise_error(NoMethodError)
12
- end
13
-
14
- it "#to_s" do
15
- expect(bool_sort.to_s).to eq("Bool")
16
- expect( int_sort.to_s).to eq("Int")
17
- expect(real_sort.to_s).to eq("Real")
18
- expect( bv8_sort.to_s).to eq("Bitvec(8)")
19
- expect(bv32_sort.to_s).to eq("Bitvec(32)")
20
- end
11
+ it "can't instantiate Sort abstract superclass" do
12
+ expect{ Sort.new }.to raise_error(NoMethodError)
13
+ end
21
14
 
22
- it "#inspect" do
23
- expect(bool_sort.inspect).to eq("BoolSort")
24
- expect( int_sort.inspect).to eq("IntSort")
25
- expect(real_sort.inspect).to eq("RealSort")
26
- expect( bv8_sort.inspect).to eq("BitvecSort(8)")
27
- expect(bv32_sort.inspect).to eq("BitvecSort(32)")
28
- end
15
+ it "#to_s" do
16
+ expect(bool_sort.to_s).to eq("Bool")
17
+ expect( int_sort.to_s).to eq("Int")
18
+ expect(real_sort.to_s).to eq("Real")
19
+ expect( bv8_sort.to_s).to eq("Bitvec(8)")
20
+ expect(bv32_sort.to_s).to eq("Bitvec(32)")
21
+ end
29
22
 
30
- describe "==" do
31
- it "all Sorts are value-objects" do
32
- expect(bool_sort).to eq( Z3::BoolSort.new )
33
- expect( int_sort).to eq( Z3::IntSort.new )
34
- expect(real_sort).to eq( Z3::RealSort.new )
35
- expect( bv8_sort).to eq( Z3::BitvecSort.new(8) )
36
- expect(bv32_sort).to eq( Z3::BitvecSort.new(32) )
23
+ it "#inspect" do
24
+ expect(bool_sort.inspect).to eq("BoolSort")
25
+ expect( int_sort.inspect).to eq("IntSort")
26
+ expect(real_sort.inspect).to eq("RealSort")
27
+ expect( bv8_sort.inspect).to eq("BitvecSort(8)")
28
+ expect(bv32_sort.inspect).to eq("BitvecSort(32)")
37
29
  end
38
30
 
39
- it "is == to itself and no other sort" do
40
- sorts.each do |sort1|
41
- sorts.each do |sort2|
42
- expect(sort1 == sort2).to eq(sort1.to_s == sort2.to_s)
31
+ describe "==" do
32
+ it "all Sorts are value-objects" do
33
+ expect(bool_sort).to eq( BoolSort.new )
34
+ expect( int_sort).to eq( IntSort.new )
35
+ expect(real_sort).to eq( RealSort.new )
36
+ expect( bv8_sort).to eq( BitvecSort.new(8) )
37
+ expect(bv32_sort).to eq( BitvecSort.new(32) )
38
+ end
39
+
40
+ it "is == to itself and no other sort" do
41
+ sorts.each do |sort1|
42
+ sorts.each do |sort2|
43
+ expect(sort1 == sort2).to eq(sort1.to_s == sort2.to_s)
44
+ end
43
45
  end
44
46
  end
45
47
  end
data/spec/spec_helper.rb CHANGED
@@ -2,7 +2,9 @@ require "pry"
2
2
 
3
3
  if ENV["COVERAGE"]
4
4
  require 'simplecov'
5
- SimpleCov.start
5
+ SimpleCov.start do
6
+ add_filter "/spec/"
7
+ end
6
8
  end
7
9
 
8
10
  require_relative "../lib/z3"
@@ -36,7 +38,7 @@ end
36
38
  RSpec::Matchers.define :have_output do |expected|
37
39
  match do |file_name|
38
40
  executable_path = "#{__dir__}/../examples/#{file_name}"
39
- actual = IO.popen(executable_path).read
41
+ actual = IO.popen("ruby -r./spec/coverage_helper #{executable_path}").read
40
42
  actual.gsub(/ *$/, "") == expected.gsub(/ *$/, "")
41
43
  end
42
44
  end
@@ -47,10 +49,26 @@ RSpec::Matchers.define :be_same_as do |expected|
47
49
  end
48
50
  end
49
51
 
52
+ RSpec::Matchers.define :be_all_same do
53
+ match do |array|
54
+ array.uniq.size == 1
55
+ end
56
+ end
57
+
58
+ RSpec::Matchers.define :be_all_different do
59
+ match do |array|
60
+ array.uniq.size == array.size
61
+ end
62
+ end
63
+
50
64
  RSpec::Matchers.define :stringify do |expected|
51
65
  match do |actual|
52
66
  actual.to_s == expected
53
67
  end
68
+
69
+ failure_message do
70
+ "Expected #{actual.inspect} to stringify to `#{expected}', got `#{actual.to_s}' instead"
71
+ end
54
72
  end
55
73
 
56
74
  RSpec::Matchers.define :have_solution do |expected|
@@ -76,3 +94,42 @@ RSpec::Matchers.define :have_solution do |expected|
76
94
  end
77
95
  end
78
96
  end
97
+
98
+ RSpec::Matchers.define :have_solutions do |expected|
99
+ match do |asts|
100
+ solutions = get_all_solutions(asts)
101
+ solutions == expected
102
+ end
103
+
104
+ failure_message do |asts|
105
+ solutions = get_all_solutions(asts)
106
+ "expected #{asts.inspect} to have solutions:\n#{expected.map{|s| "* #{s.inspect}\n"}.join}, instead got:\n#{solutions.map{|s| "* #{s.inspect}\n"}.join}"
107
+ end
108
+
109
+ def get_all_solutions(asts)
110
+ vars = expected.map(&:keys)
111
+ raise "All expectations need same set of keys" unless vars.uniq.size == 1
112
+ vars = vars[0]
113
+ solver = setup_solver(asts)
114
+ solutions = []
115
+ while solver.check == :sat
116
+ model = solver.model
117
+ solution = Hash[vars.map{|v| [v, model.model_eval(v, true)] }]
118
+ solutions << solution
119
+ solver.assert Z3.Or(*solution.map{|var,val| var != val})
120
+ if solutions.size >= 10
121
+ binding.pry
122
+ raise "Too many solutions found, presumably infinite loop"
123
+ end
124
+ end
125
+ solutions
126
+ end
127
+
128
+ def setup_solver(asts)
129
+ Z3::Solver.new.tap do |solver|
130
+ asts.each do |ast|
131
+ solver.assert ast
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,9 @@
1
+ module Z3
2
+ describe Tactic do
3
+ it "constructors" do
4
+ expect(Tactic.fail).to be_a Tactic
5
+ expect(Tactic.fail_if_not_decided).to be_a Tactic
6
+ expect(Tactic.skip).to be_a Tactic
7
+ end
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: z3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20160427
4
+ version: 0.0.20161008
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Wegrzanowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-27 00:00:00.000000000 Z
11
+ date: 2016-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,13 +86,16 @@ executables: []
72
86
  extensions: []
73
87
  extra_rdoc_files: []
74
88
  files:
89
+ - ".rspec"
75
90
  - README.md
91
+ - Rakefile
76
92
  - examples/algebra_problems
77
93
  - examples/basic_int_math
78
94
  - examples/basic_logic
79
95
  - examples/bit_tricks
80
96
  - examples/bridges
81
97
  - examples/bridges-1.txt
98
+ - examples/circuit_problems
82
99
  - examples/clogic_puzzle
83
100
  - examples/four_hackers_puzzle
84
101
  - examples/geometry_problem
@@ -102,30 +119,47 @@ files:
102
119
  - lib/z3/context.rb
103
120
  - lib/z3/exception.rb
104
121
  - lib/z3/expr/arith_expr.rb
122
+ - lib/z3/expr/array_expr.rb
105
123
  - lib/z3/expr/bitvec_expr.rb
106
124
  - lib/z3/expr/bool_expr.rb
107
125
  - lib/z3/expr/expr.rb
126
+ - lib/z3/expr/float_expr.rb
108
127
  - lib/z3/expr/int_expr.rb
109
128
  - lib/z3/expr/real_expr.rb
129
+ - lib/z3/expr/rounding_mode_expr.rb
130
+ - lib/z3/expr/set_expr.rb
110
131
  - lib/z3/func_decl.rb
132
+ - lib/z3/goal.rb
111
133
  - lib/z3/interface.rb
112
134
  - lib/z3/low_level.rb
113
135
  - lib/z3/low_level_auto.rb
114
136
  - lib/z3/model.rb
115
137
  - lib/z3/printer.rb
138
+ - lib/z3/probe.rb
116
139
  - lib/z3/solver.rb
140
+ - lib/z3/sort/array_sort.rb
117
141
  - lib/z3/sort/bitvec_sort.rb
118
142
  - lib/z3/sort/bool_sort.rb
143
+ - lib/z3/sort/float_sort.rb
119
144
  - lib/z3/sort/int_sort.rb
120
145
  - lib/z3/sort/real_sort.rb
146
+ - lib/z3/sort/rounding_mode_sort.rb
147
+ - lib/z3/sort/set_sort.rb
121
148
  - lib/z3/sort/sort.rb
149
+ - lib/z3/tactic.rb
122
150
  - lib/z3/very_low_level.rb
123
151
  - lib/z3/very_low_level_auto.rb
152
+ - spec/array_expr_spec.rb
153
+ - spec/array_sort_spec.rb
124
154
  - spec/bitvec_expr_spec.rb
125
155
  - spec/bitvec_sort_spec.rb
126
156
  - spec/bool_expr_spec.rb
127
157
  - spec/bool_sort_spec.rb
158
+ - spec/coverage_helper.rb
128
159
  - spec/expr_spec.rb
160
+ - spec/float_expr_spec.rb
161
+ - spec/float_sort_spec.rb
162
+ - spec/goal_spec.rb
129
163
  - spec/int_expr_spec.rb
130
164
  - spec/int_sort_spec.rb
131
165
  - spec/integration/algebra_problems_spec.rb
@@ -133,6 +167,7 @@ files:
133
167
  - spec/integration/basic_logic_spec.rb
134
168
  - spec/integration/bit_tricks_spec.rb
135
169
  - spec/integration/bridges_spec.rb
170
+ - spec/integration/cicruit_problem_spec.rb
136
171
  - spec/integration/four_hackers_puzzle_spec.rb
137
172
  - spec/integration/geometry_problem_spec.rb
138
173
  - spec/integration/kakuro_spec.rb
@@ -147,11 +182,17 @@ files:
147
182
  - spec/integration/verbal_arithmetic_spec.rb
148
183
  - spec/model_spec.rb
149
184
  - spec/printer_spec.rb
185
+ - spec/probe_spec.rb
150
186
  - spec/real_expr_spec.rb
151
187
  - spec/real_sort_spec.rb
188
+ - spec/rounding_mode_expr_spec.rb
189
+ - spec/rounding_mode_sort_spec.rb
190
+ - spec/set_expr_spec.rb
191
+ - spec/set_sort_spec.rb
152
192
  - spec/solver_spec.rb
153
193
  - spec/sort_spec.rb
154
194
  - spec/spec_helper.rb
195
+ - spec/tactic_spec.rb
155
196
  - spec/z3_spec.rb
156
197
  homepage: https://github.com/taw/z3
157
198
  licenses:
@@ -174,9 +215,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
215
  requirements:
175
216
  - z3 library
176
217
  rubyforge_project:
177
- rubygems_version: 2.4.5
218
+ rubygems_version: 2.5.1
178
219
  signing_key:
179
220
  specification_version: 4
180
221
  summary: Z3 Constraint Solver
181
222
  test_files: []
182
- has_rdoc: