z3 0.0.20171020 → 0.0.20180203

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f60c524dca681eab09bf92ff91d055060c806c80
4
- data.tar.gz: e93747a1a7d10f62d1f8384f625c005651eeaf2e
2
+ SHA256:
3
+ metadata.gz: 82ddc6984f24ee79d2dcd7fba162818c0bce9959f6f7c4daad11305b09ac84b8
4
+ data.tar.gz: 977d33cbd061672c85297e19dba7612c2f67bc0b5785ab1a67da828f17678b65
5
5
  SHA512:
6
- metadata.gz: c7282273ba2bc89bd26e7096104fde50487956994300765957495a0c123ca0f06897103512c01ab9121e3349715fe9bf02e71832a3a73a7d9664ae33d8a2c5a5
7
- data.tar.gz: a44bdce9868882fee77cfc502d9c1e977dce11df27648025d06172512396c2c35ddd4b7b56ecefcd60a04d9012cd9db74e1f0eb06e2fdffc1cd2a416c89ddce5
6
+ metadata.gz: 49db1f83e829f4b982abb5aea5014f9b64f6e558ee945a3d4d451227004fbd562cc5cddda955b3148582bedc73e2d8e251bf1198f87454145fe22e889bb9eaba
7
+ data.tar.gz: edcd476f98a22595b6a60a11606aec007b7852b7447904413c57388f3a8d6d06c5a058cc72d115f85ce61ebcb57d02c51c66535928b30a6f7de78f5a94ccc852
data/README.md CHANGED
@@ -20,6 +20,8 @@ To use it, you'll need to install `z3`. On OSX that would be:
20
20
 
21
21
  On other systems use appropriate package manager.
22
22
 
23
+ *NB: On Linux, since FFI will look for `libz3.so`, you might need to install `libz3-dev`using your usual package manager.*
24
+
23
25
  ### Known Issues
24
26
 
25
27
  As Z3 is a C library, doing anything weird with it will segfault your process. Ruby API tries its best to prevent such problems and turn them into exceptions instead, but if you do anything weird (especially touch any method prefixed with `_` or `Z3::LowLevel` interface), crashes are possible. If you have reproducible crash on reasonable looking code, definitely submit it as a bug, and I'll try to come up with a workaround.
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # https://en.wikipedia.org/wiki/Zebra_Puzzle
4
+
5
+ require_relative "../lib/z3"
6
+
7
+ class ZebraPuzzle
8
+ def initialize
9
+ @solver = Z3::Solver.new
10
+ end
11
+
12
+ def traits
13
+ [:color, :nationality, :drink, :cigarettes, :pet]
14
+ end
15
+
16
+ def color
17
+ ["red", "yellow", "green", "blue", "ivory"]
18
+ end
19
+
20
+ def nationality
21
+ ["Englishman", "Spaniard", "Norwegian", "Ukrainian", "Japanese"]
22
+ end
23
+
24
+ def drink
25
+ ["water", "coffee", "tea", "milk", "orange juice"]
26
+ end
27
+
28
+ def pet
29
+ ["zebra", "dog", "snails", "fox", "horse"]
30
+ end
31
+
32
+ def cigarettes
33
+ ["Parliaments", "Old Gold", "Lucky Strike", "Kools", "Chesterfields"]
34
+ end
35
+
36
+ def trait_index(trait, name)
37
+ send(trait).index(name) or raise "Bad value #{name.inspect} for trait #{trait.inspect}"
38
+ end
39
+
40
+ def trait_value(trait, index)
41
+ send(trait)[index] or raise "Bad index #{index.inspect} for trait #{trait.inspect}"
42
+ end
43
+
44
+ # House I has TRAIT value X
45
+ def variable(trait, i)
46
+ Z3.Int("#{trait}-#{i}")
47
+ end
48
+
49
+ def setup_variables(trait)
50
+ vars = (0..4).map{|i| variable(trait, i) }
51
+ @solver.assert Z3.Distinct(*vars)
52
+ vars.each do |v|
53
+ @solver.assert v >= 0
54
+ @solver.assert v <= 4
55
+ end
56
+ end
57
+
58
+
59
+ def house_has_trait_value(i, trait, value)
60
+ index = trait_index(trait, value)
61
+ (variable(trait, i) == index)
62
+ end
63
+
64
+ def same_house(t1,v1,t2,v2)
65
+ (0..4).each do |i|
66
+ @solver.assert house_has_trait_value(i,t1,v1) == house_has_trait_value(i,t2,v2)
67
+ end
68
+ end
69
+
70
+ def left_rigth_house(t1,v1,t2,v2)
71
+ (0..3).each do |i|
72
+ @solver.assert house_has_trait_value(i,t1,v1) == house_has_trait_value(i+1,t2,v2)
73
+ end
74
+ end
75
+
76
+ def next_house(t1,v1,t2,v2)
77
+ (0..4).each do |i|
78
+ opts = [i+1,i-1].grep(0..4).map{|j| house_has_trait_value(i,t1,v1) == house_has_trait_value(j,t2,v2) }
79
+ @solver.assert Z3.Or(*opts)
80
+ end
81
+ end
82
+
83
+ def call
84
+ traits.each do |trait|
85
+ setup_variables(trait)
86
+ end
87
+
88
+ same_house(:nationality, "Englishman", :color, "red")
89
+ same_house(:nationality, "Spaniard", :pet, "dog")
90
+ same_house(:drink, "coffee", :color, "green")
91
+ same_house(:nationality, "Ukrainian", :drink, "tea")
92
+ same_house(:pet, "snails", :cigarettes, "Old Gold")
93
+ same_house(:cigarettes, "Kools", :color, "yellow")
94
+ same_house(:cigarettes, "Lucky Strike", :drink, "orange juice")
95
+ same_house(:nationality, "Japanese", :cigarettes, "Parliaments")
96
+
97
+ next_house(:nationality, "Norwegian", :color, "blue")
98
+ next_house(:cigarettes, "Chesterfields", :pet, "fox")
99
+ next_house(:cigarettes, "Kools", :pet, "horse")
100
+
101
+ left_rigth_house(:color, "ivory", :color, "green")
102
+
103
+ @solver.assert house_has_trait_value(2, :drink, "milk")
104
+ @solver.assert house_has_trait_value(0, :nationality, "Norwegian")
105
+
106
+ if @solver.satisfiable?
107
+ print_solution
108
+ else
109
+ puts "No solution"
110
+ end
111
+ end
112
+
113
+ def print_solution
114
+ model = @solver.model
115
+ (0..4).each do |i|
116
+ print "House #{i}:"
117
+ traits.each do |trait|
118
+ j = model[variable(trait, i)].to_s.to_i
119
+ t = trait_value(trait, j)
120
+ print " #{t}"
121
+ end
122
+ print "\n"
123
+ end
124
+ end
125
+ end
126
+
127
+ ZebraPuzzle.new.call
128
+
129
+ __END__
130
+
131
+ There are five houses.
132
+ The Englishman lives in the red house.
133
+ The Spaniard owns the dog.
134
+ Coffee is drunk in the green house.
135
+ The Ukrainian drinks tea.
136
+ The green house is immediately to the right of the ivory house.
137
+ The Old Gold smoker owns snails.
138
+ Kools are smoked in the yellow house.
139
+ Milk is drunk in the middle house.
140
+ The Norwegian lives in the first house.
141
+ The man who smokes Chesterfields lives in the house next to the man with the fox.
142
+ Kools are smoked in the house next to the house where the horse is kept.
143
+ The Lucky Strike smoker drinks orange juice.
144
+ The Japanese smokes Parliaments.
145
+ The Norwegian lives next to the blue house.
146
+ Now, who drinks water? Who owns the zebra?
@@ -581,42 +581,6 @@ module Z3
581
581
  VeryLowLevel.Z3_get_relation_column(_ctx_pointer, sort._ast, num)
582
582
  end
583
583
 
584
- def get_smtlib_assumption(num) #=> :ast_pointer
585
- VeryLowLevel.Z3_get_smtlib_assumption(_ctx_pointer, num)
586
- end
587
-
588
- def get_smtlib_decl(num) #=> :func_decl_pointer
589
- VeryLowLevel.Z3_get_smtlib_decl(_ctx_pointer, num)
590
- end
591
-
592
- def get_smtlib_error #=> :string
593
- VeryLowLevel.Z3_get_smtlib_error(_ctx_pointer)
594
- end
595
-
596
- def get_smtlib_formula(num) #=> :ast_pointer
597
- VeryLowLevel.Z3_get_smtlib_formula(_ctx_pointer, num)
598
- end
599
-
600
- def get_smtlib_num_assumptions #=> :uint
601
- VeryLowLevel.Z3_get_smtlib_num_assumptions(_ctx_pointer)
602
- end
603
-
604
- def get_smtlib_num_decls #=> :uint
605
- VeryLowLevel.Z3_get_smtlib_num_decls(_ctx_pointer)
606
- end
607
-
608
- def get_smtlib_num_formulas #=> :uint
609
- VeryLowLevel.Z3_get_smtlib_num_formulas(_ctx_pointer)
610
- end
611
-
612
- def get_smtlib_num_sorts #=> :uint
613
- VeryLowLevel.Z3_get_smtlib_num_sorts(_ctx_pointer)
614
- end
615
-
616
- def get_smtlib_sort(num) #=> :sort_pointer
617
- VeryLowLevel.Z3_get_smtlib_sort(_ctx_pointer, num)
618
- end
619
-
620
584
  def get_sort(ast) #=> :sort_pointer
621
585
  VeryLowLevel.Z3_get_sort(_ctx_pointer, ast._ast)
622
586
  end
@@ -145,15 +145,6 @@ module Z3
145
145
  attach_function :Z3_get_range, [:ctx_pointer, :func_decl_pointer], :sort_pointer
146
146
  attach_function :Z3_get_relation_arity, [:ctx_pointer, :sort_pointer], :uint
147
147
  attach_function :Z3_get_relation_column, [:ctx_pointer, :sort_pointer, :uint], :sort_pointer
148
- attach_function :Z3_get_smtlib_assumption, [:ctx_pointer, :uint], :ast_pointer
149
- attach_function :Z3_get_smtlib_decl, [:ctx_pointer, :uint], :func_decl_pointer
150
- attach_function :Z3_get_smtlib_error, [:ctx_pointer], :string
151
- attach_function :Z3_get_smtlib_formula, [:ctx_pointer, :uint], :ast_pointer
152
- attach_function :Z3_get_smtlib_num_assumptions, [:ctx_pointer], :uint
153
- attach_function :Z3_get_smtlib_num_decls, [:ctx_pointer], :uint
154
- attach_function :Z3_get_smtlib_num_formulas, [:ctx_pointer], :uint
155
- attach_function :Z3_get_smtlib_num_sorts, [:ctx_pointer], :uint
156
- attach_function :Z3_get_smtlib_sort, [:ctx_pointer, :uint], :sort_pointer
157
148
  attach_function :Z3_get_sort, [:ctx_pointer, :ast_pointer], :sort_pointer
158
149
  attach_function :Z3_get_sort_id, [:ctx_pointer, :sort_pointer], :uint
159
150
  attach_function :Z3_get_sort_kind, [:ctx_pointer, :sort_pointer], :uint
data/spec/expr_spec.rb CHANGED
@@ -113,15 +113,16 @@ module Z3
113
113
 
114
114
  it "casts to correct type if possible" do
115
115
  expect((a == 42).sexpr).to eq "(= a 42)"
116
- expect((42 == a).sexpr).to eq "(= a 42)"
116
+ # https://bugs.ruby-lang.org/issues/14437
117
+ #expect((42 == a).sexpr).to eq "(= a 42)"
117
118
  expect((a == e).sexpr).to eq "(= (to_real a) e)"
118
119
  expect((e == a).sexpr).to eq "(= e (to_real a))"
119
120
  expect((c == true).sexpr).to eq "(= c true)"
120
121
  expect((c == false).sexpr).to eq "(= c false)"
121
122
  expect((a == 42.5).sexpr).to eq "(= (to_real a) (/ 85.0 2.0))"
122
- expect((42.5 == a).sexpr).to eq "(= (to_real a) (/ 85.0 2.0))"
123
+ # expect((42.5 == a).sexpr).to eq "(= (to_real a) (/ 85.0 2.0))"
123
124
  expect((e == 42.5).sexpr).to eq "(= e (/ 85.0 2.0))"
124
- expect((42.5 == e).sexpr).to eq "(= e (/ 85.0 2.0))"
125
+ # expect((42.5 == e).sexpr).to eq "(= e (/ 85.0 2.0))"
125
126
  # expect((true == c).sexpr).to eq "(= true c)"
126
127
  # expect((false == c).sexpr).to eq "(= false c)"
127
128
  end
@@ -149,6 +150,7 @@ module Z3
149
150
 
150
151
  it "casts to correct type if possible" do
151
152
  expect((a != 42).sexpr).to eq "(distinct a 42)"
153
+ # https://bugs.ruby-lang.org/issues/14437
152
154
  # expect((42 != a).sexpr).to eq "(distinct a 42)"
153
155
  expect((a != e).sexpr).to eq "(distinct (to_real a) e)"
154
156
  expect((e != a).sexpr).to eq "(distinct e (to_real a))"
@@ -1,3 +1,5 @@
1
+ # There are multiple solutions, so this test is nondeterministic
2
+ # Changing it to one returned by z3 4.6.0, but perhaps it needs some serious fixing
1
3
  describe "Knights Swap Puzzle" do
2
4
  it do
3
5
  expect("knights_puzzle").to have_output <<EOF
@@ -7,84 +9,84 @@ bbb.
7
9
  xbxw
8
10
  ..ww
9
11
  x.xw
10
- b: 1,1 -> 3,0
12
+ b: 0,0 -> 1,2
11
13
 
12
14
  State 1:
13
- bbbb
14
- x.xw
15
- ..ww
15
+ .bb.
16
+ xbxw
17
+ .bww
16
18
  x.xw
17
- w: 3,2 -> 1,1
19
+ w: 2,2 -> 3,0
18
20
 
19
21
  State 2:
20
- bbbb
21
- xwxw
22
- ..w.
22
+ .bbw
23
+ xbxw
24
+ .b.w
23
25
  x.xw
24
- b: 2,0 -> 3,2
26
+ b: 1,0 -> 2,2
25
27
 
26
28
  State 3:
27
- bb.b
28
- xwxw
29
- ..wb
29
+ ..bw
30
+ xbxw
31
+ .bbw
30
32
  x.xw
31
- w: 3,3 -> 1,2
33
+ w: 3,1 -> 1,0
32
34
 
33
35
  State 4:
34
- bb.b
35
- xwxw
36
- .wwb
37
- x.x.
38
- w: 1,2 -> 2,0
36
+ .wbw
37
+ xbx.
38
+ .bbw
39
+ x.xw
40
+ b: 1,2 -> 3,1
39
41
 
40
42
  State 5:
41
- bbwb
42
- xwxw
43
- ..wb
44
- x.x.
45
- b: 0,0 -> 1,2
43
+ .wbw
44
+ xbxb
45
+ ..bw
46
+ x.xw
47
+ w: 3,3 -> 1,2
46
48
 
47
49
  State 6:
48
- .bwb
49
- xwxw
50
- .bwb
50
+ .wbw
51
+ xbxb
52
+ .wbw
51
53
  x.x.
52
- b: 1,2 -> 3,3
54
+ w: 1,2 -> 0,0
53
55
 
54
56
  State 7:
55
- .bwb
56
- xwxw
57
- ..wb
58
- x.xb
59
- w: 3,1 -> 1,2
57
+ wwbw
58
+ xbxb
59
+ ..bw
60
+ x.x.
61
+ b: 2,0 -> 1,2
60
62
 
61
63
  State 8:
62
- .bwb
63
- xwx.
64
- .wwb
65
- x.xb
66
- b: 1,0 -> 3,1
64
+ ww.w
65
+ xbxb
66
+ .bbw
67
+ x.x.
68
+ w: 3,2 -> 2,0
67
69
 
68
70
  State 9:
69
- ..wb
70
- xwxb
71
- .wwb
72
- x.xb
73
- w: 2,2 -> 1,0
71
+ wwww
72
+ xbxb
73
+ .bb.
74
+ x.x.
75
+ b: 1,1 -> 3,2
74
76
 
75
77
  State 10:
76
- .wwb
77
- xwxb
78
- .w.b
78
+ wwww
79
79
  x.xb
80
- b: 3,0 -> 2,2
80
+ .bbb
81
+ x.x.
82
+ b: 1,2 -> 3,3
81
83
 
82
84
  State 11:
83
- .ww.
84
- xwxb
85
- .wbb
85
+ wwww
86
86
  x.xb
87
- w: 1,2 -> 0,0
87
+ ..bb
88
+ x.xb
89
+ w: 3,0 -> 1,1
88
90
 
89
91
  State 12:
90
92
  www.
@@ -0,0 +1,11 @@
1
+ describe "Zebra Puzzle" do
2
+ it do
3
+ expect("zebra_puzzle").to have_output <<EOF
4
+ House 0: yellow Norwegian water Kools fox
5
+ House 1: blue Ukrainian tea Chesterfields horse
6
+ House 2: red Englishman milk Old Gold snails
7
+ House 3: ivory Spaniard orange juice Lucky Strike dog
8
+ House 4: green Japanese coffee Parliaments zebra
9
+ EOF
10
+ end
11
+ end
@@ -35,6 +35,8 @@ module Z3
35
35
  expect([
36
36
  a.include?(1),
37
37
  a.include?(2),
38
+ !a.include?(3),
39
+ !b.include?(1),
38
40
  b.include?(2),
39
41
  b.include?(3),
40
42
  c == a.difference(b),
data/spec/solver_spec.rb CHANGED
@@ -37,13 +37,31 @@ module Z3
37
37
  solver.assert b >= 2
38
38
  solver.assert Z3.Or(a == 2, a == -2)
39
39
  stats = solver.statistics
40
- expect(stats.keys).to match_array(["rlimit count", "max memory", "memory", "num allocs"])
40
+ # "mk bool var" added in 4.6.0
41
+ expect(stats.keys).to match_array(["rlimit count", "max memory", "memory", "num allocs", "mk bool var"])
41
42
  end
42
43
 
43
44
  # This is a very simple example of unknown satisfiablity
44
45
  # so we might need more complex one in the future
46
+ # This is now satisfiable in 4.6.0
47
+ if Z3.version >= "4.6"
48
+ it "third way (until 4.6 fix)" do
49
+ solver.assert a**3 == a
50
+ expect(solver.check).to eq(:sat)
51
+ expect(solver).to be_satisfiable
52
+ expect(solver).to_not be_unsatisfiable
53
+ end
54
+ else
55
+ it "third way (until 4.6 fix)" do
56
+ solver.assert a**3 == a
57
+ expect(solver.check).to eq(:unknown)
58
+ expect{solver.satisfiable?}.to raise_error("Satisfiability unknown")
59
+ expect{solver.unsatisfiable?}.to raise_error("Satisfiability unknown")
60
+ end
61
+ end
62
+
45
63
  it "third way" do
46
- solver.assert a**3 == a
64
+ solver.assert a**a == a
47
65
  expect(solver.check).to eq(:unknown)
48
66
  expect{solver.satisfiable?}.to raise_error("Satisfiability unknown")
49
67
  expect{solver.unsatisfiable?}.to raise_error("Satisfiability unknown")
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.20171020
4
+ version: 0.0.20180203
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Wegrzanowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-20 00:00:00.000000000 Z
11
+ date: 2018-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -156,6 +156,7 @@ files:
156
156
  - examples/sudoku
157
157
  - examples/sudoku-1.txt
158
158
  - examples/verbal_arithmetic
159
+ - examples/zebra_puzzle
159
160
  - lib/z3.rb
160
161
  - lib/z3/ast.rb
161
162
  - lib/z3/context.rb
@@ -228,6 +229,7 @@ files:
228
229
  - spec/integration/selfref_spec.rb
229
230
  - spec/integration/sudoku_spec.rb
230
231
  - spec/integration/verbal_arithmetic_spec.rb
232
+ - spec/integration/zebra_puzzle_spec.rb
231
233
  - spec/model_spec.rb
232
234
  - spec/printer_spec.rb
233
235
  - spec/probe_spec.rb
@@ -263,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
263
265
  requirements:
264
266
  - z3 library
265
267
  rubyforge_project:
266
- rubygems_version: 2.5.2
268
+ rubygems_version: 2.7.3
267
269
  signing_key:
268
270
  specification_version: 4
269
271
  summary: Z3 Constraint Solver