z3 0.0.20160221 → 0.0.20160323
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/examples/algebra_problems +24 -24
- data/examples/basic_int_math +8 -8
- data/examples/basic_logic +8 -8
- data/examples/bit_tricks +161 -0
- data/examples/bridges_solver +1 -1
- data/examples/clogic_puzzle_solver +135 -0
- data/examples/four_hackers_puzzle +194 -0
- data/examples/geometry_problem +11 -11
- data/examples/kakuro_solver +3 -3
- data/examples/kinematics_problems +37 -37
- data/examples/letter_connections_solver +11 -11
- data/examples/light_up_solver +5 -5
- data/examples/minisudoku_solver +4 -4
- data/examples/selfref_solver +35 -35
- data/examples/sudoku_solver +4 -4
- data/examples/verbal_arithmetic +2 -2
- data/lib/z3/exception.rb +25 -0
- data/lib/z3/func_decl.rb +7 -7
- data/lib/z3/interface.rb +255 -0
- data/lib/z3/low_level.rb +4 -6
- data/lib/z3/low_level_auto.rb +1551 -1547
- data/lib/z3/model.rb +3 -2
- data/lib/z3/solver.rb +65 -54
- data/lib/z3/sort/bitvec_sort.rb +40 -0
- data/lib/z3/sort/bool_sort.rb +31 -0
- data/lib/z3/sort/int_sort.rb +21 -0
- data/lib/z3/sort/real_sort.rb +36 -0
- data/lib/z3/sort/sort.rb +76 -0
- data/lib/z3/value/arith_value.rb +53 -0
- data/lib/z3/value/bitvec_value.rb +67 -0
- data/lib/z3/value/bool_value.rb +29 -0
- data/lib/z3/value/int_value.rb +7 -0
- data/lib/z3/value/real_value.rb +7 -0
- data/lib/z3/value/value.rb +48 -0
- data/lib/z3/very_low_level.rb +28 -45
- data/lib/z3/very_low_level_auto.rb +518 -516
- data/lib/z3.rb +23 -33
- data/spec/integration/bit_tricks_spec.rb +21 -0
- data/spec/model_spec.rb +9 -9
- data/spec/solver_spec.rb +2 -2
- data/spec/sort_spec.rb +38 -13
- data/spec/{ast_spec.rb → value_spec.rb} +60 -57
- metadata +21 -6
- data/lib/z3/ast.rb +0 -302
- data/lib/z3/sort.rb +0 -33
- /data/spec/integration/{bagic_int_math_spec.rb → basic_int_math_spec.rb} +0 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative "../lib/z3"
|
4
|
+
|
5
|
+
class LogicPuzzleCase
|
6
|
+
attr_reader :index
|
7
|
+
def initialize(puzzle, index)
|
8
|
+
@puzzle = puzzle
|
9
|
+
@index = index
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(key, *args)
|
13
|
+
key = key.to_s
|
14
|
+
if @puzzle.has_key?(key) and args.size == 1
|
15
|
+
@puzzle.attribute(@index, key, *args)
|
16
|
+
elsif @puzzle.has_key?(key) and args.size == 0
|
17
|
+
@puzzle.vars[key][@index]
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class LogicPuzzle
|
25
|
+
attr_reader :vars, :dict
|
26
|
+
def initialize(count)
|
27
|
+
# In puzzles of this kind, all assignments are of same size
|
28
|
+
@count = count
|
29
|
+
@solver = Z3::Solver.new
|
30
|
+
@vars = {}
|
31
|
+
@dict = {}
|
32
|
+
@cases = @count.times.map{|i| LogicPuzzleCase.new(self, i) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def each(&blk)
|
36
|
+
@cases.each(&blk)
|
37
|
+
end
|
38
|
+
|
39
|
+
def attribute_values(name, *vals)
|
40
|
+
raise "All assignments must have same number of elements" unless vals.size == @count
|
41
|
+
vars = @count.times.map{|i| Z3.Int("#{i}-#{name}") }
|
42
|
+
vars.each do |v|
|
43
|
+
@solver.assert v >= 0
|
44
|
+
@solver.assert v < @count
|
45
|
+
end
|
46
|
+
@solver.assert Z3.Distinct(*vars)
|
47
|
+
@dict[name] = vals
|
48
|
+
@vars[name] = vars
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_key?(key)
|
52
|
+
@vars.has_key?(key)
|
53
|
+
end
|
54
|
+
|
55
|
+
def attribute(idx, key, val)
|
56
|
+
raise "Attribute #{key} not defined" unless @vars.has_key?(key)
|
57
|
+
val_idx = @dict[key].index(val) or raise "Value #{val} for attribute #{key} not possible"
|
58
|
+
@vars[key][idx] == val_idx
|
59
|
+
end
|
60
|
+
|
61
|
+
def solve!
|
62
|
+
add_assertions!
|
63
|
+
if @solver.check == :sat
|
64
|
+
@solver.model.each do |k,v|
|
65
|
+
i, name = k.split("-", 2)
|
66
|
+
puts "#{k} = #{@dict[name][v.to_i]}"
|
67
|
+
end
|
68
|
+
else
|
69
|
+
puts "Puzzle has no solutions"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def implies!(a, b)
|
74
|
+
@solver.assert Z3.Implies(a, b)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class FourHackersPuzzle < LogicPuzzle
|
79
|
+
def initialize
|
80
|
+
super(4)
|
81
|
+
attribute_values *%W[name Armand Dragonene Frogger Phineus]
|
82
|
+
attribute_values *%W[alias Badger Griffin Lennard Monks]
|
83
|
+
attribute_values *%W[country Belgium England Norway Yemen]
|
84
|
+
attribute_values *%W[language C Java Lisp Perl]
|
85
|
+
attribute_values *%W[amount 10000 80000 160000 640000]
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_assertions!
|
89
|
+
each do |hacker|
|
90
|
+
implies!( hacker.name("Phineus"), hacker.amount("10000") )
|
91
|
+
implies!( hacker.alias("Lennard"), hacker.amount("160000") )
|
92
|
+
implies!( hacker.alias("Lennard"), ~hacker.country("England") )
|
93
|
+
# 2nd connection less money transferred than C coder
|
94
|
+
implies!( hacker.language("C"), @cases[1].amount < hacker.amount )
|
95
|
+
implies!( hacker.language("C"), ~hacker.country("Norway") )
|
96
|
+
implies!( hacker.name("Armand"), hacker.alias("Monks") )
|
97
|
+
end
|
98
|
+
|
99
|
+
# Armand stole more than Frogger
|
100
|
+
each do |a|
|
101
|
+
each do |b|
|
102
|
+
implies!(
|
103
|
+
a.name("Armand") & b.name("Frogger"),
|
104
|
+
a.amount > b.amount
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
each do |hacker|
|
110
|
+
implies!( hacker.name("Dragonene"), hacker.country("Belgium") )
|
111
|
+
end
|
112
|
+
|
113
|
+
# Dragonene less money than Perl coder
|
114
|
+
each do |a|
|
115
|
+
each do |b|
|
116
|
+
implies!(
|
117
|
+
a.name("Dragonene") & b.language("Perl"),
|
118
|
+
a.amount < b.amount
|
119
|
+
)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
# perl coder made the connection before Dragonene?
|
123
|
+
each do |a|
|
124
|
+
each do |b|
|
125
|
+
implies!(
|
126
|
+
a.name("Dragonene") & b.language("Perl"),
|
127
|
+
a.index > b.index
|
128
|
+
)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
# Lisp coder more money than Griffin
|
132
|
+
each do |a|
|
133
|
+
each do |b|
|
134
|
+
implies!(
|
135
|
+
a.alias("Griffin") & b.language("Lisp"),
|
136
|
+
a.amount < b.amount
|
137
|
+
)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
# 3rd connection used Java
|
141
|
+
@solver.assert @cases[2].language("Java")
|
142
|
+
# Badger stole more than Yemen coder
|
143
|
+
each do |a|
|
144
|
+
each do |b|
|
145
|
+
implies!(
|
146
|
+
a.alias("Badger") & b.country("Yemen"),
|
147
|
+
a.amount > b.amount
|
148
|
+
)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
FourHackersPuzzle.new.solve!
|
155
|
+
|
156
|
+
"""
|
157
|
+
There is little we can do but wait, so we may as well take another job.
|
158
|
+
It seems there has been a bank robbery. Scotland Yard has turned to us for help in figuring out who did it.
|
159
|
+
We have been the given the following information:
|
160
|
+
|
161
|
+
There were 4 hackers each connecting one after another.
|
162
|
+
Each hacker has a name and another alias too.
|
163
|
+
Each hacker connected from a different country.
|
164
|
+
Each hacker connected using a different programming language.
|
165
|
+
Each hacker transferred a different amount of money.
|
166
|
+
|
167
|
+
The 4 hacker names: Armand Dragonene Frogger Phineus
|
168
|
+
The 4 hacker aliases: Badger Griffin Lennard Monks
|
169
|
+
The 4 countries: Belgium England Norway Yemen
|
170
|
+
The 4 coding langauges: C Java Lisp Perl
|
171
|
+
The 4 amounts: 10000 80000 160000 640000
|
172
|
+
You must also determine the order the hackers connected: 1st, 2nd, 3rd, 4th
|
173
|
+
|
174
|
+
Perhaps following the news may help. The attacks all took place on the 29th, but the newspapers reported it for a couple of days afterwards as they found new information:
|
175
|
+
|
176
|
+
https://www.sabrefilms.co.uk/revolutionelite/casefiles/case9/img1.jpg
|
177
|
+
https://www.sabrefilms.co.uk/revolutionelite/casefiles/case9/img2.jpg
|
178
|
+
https://www.sabrefilms.co.uk/revolutionelite/casefiles/case9/img3.jpg
|
179
|
+
|
180
|
+
--------------------------------------------------------------------------------
|
181
|
+
Extracted rules:
|
182
|
+
Phineus => 10000
|
183
|
+
Lennard => 160000 && !England
|
184
|
+
2nd connection less money transferred than C coder
|
185
|
+
C coder !Norwary
|
186
|
+
Armand (Monks)
|
187
|
+
Armand stole more than Frogger
|
188
|
+
Dragonene => Belgium
|
189
|
+
Dragonene less money than Perl coder
|
190
|
+
perl coder made the connection before Dragonene?
|
191
|
+
Lisp coder more money than Griffin
|
192
|
+
3rd connection used Java
|
193
|
+
Badger stole more than Yemen coder
|
194
|
+
"""
|
data/examples/geometry_problem
CHANGED
@@ -4,17 +4,17 @@ require_relative "../lib/z3"
|
|
4
4
|
|
5
5
|
solver = Z3::Solver.new
|
6
6
|
|
7
|
-
ax = Z3
|
8
|
-
ay = Z3
|
9
|
-
bx = Z3
|
10
|
-
by = Z3
|
11
|
-
cx = Z3
|
12
|
-
cy = Z3
|
13
|
-
dx = Z3
|
14
|
-
dy = Z3
|
15
|
-
|
16
|
-
a_c = Z3
|
17
|
-
b_d = Z3
|
7
|
+
ax = Z3.Real("a.x")
|
8
|
+
ay = Z3.Real("a.y")
|
9
|
+
bx = Z3.Real("b.x")
|
10
|
+
by = Z3.Real("b.y")
|
11
|
+
cx = Z3.Real("c.x")
|
12
|
+
cy = Z3.Real("c.y")
|
13
|
+
dx = Z3.Real("d.x")
|
14
|
+
dy = Z3.Real("d.y")
|
15
|
+
|
16
|
+
a_c = Z3.Real("|a-c|")
|
17
|
+
b_d = Z3.Real("|b-d|")
|
18
18
|
|
19
19
|
solver.assert(bx == 0)
|
20
20
|
solver.assert(by == 0)
|
data/examples/kakuro_solver
CHANGED
@@ -87,7 +87,7 @@ class Kakuro
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def cell_var(x,y)
|
90
|
-
v = Z3
|
90
|
+
v = Z3.Int("c#{x},#{y}")
|
91
91
|
@solver.assert v >= 1
|
92
92
|
@solver.assert v <= 9
|
93
93
|
v
|
@@ -103,8 +103,8 @@ class Kakuro
|
|
103
103
|
y += dy
|
104
104
|
end
|
105
105
|
return if vs.empty?
|
106
|
-
@solver.assert Z3
|
107
|
-
@solver.assert Z3
|
106
|
+
@solver.assert Z3.Distinct(*vs)
|
107
|
+
@solver.assert Z3.Add(*vs) == sum
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -32,9 +32,9 @@ class KinematicsProblem01 < KinematicsProblem
|
|
32
32
|
Determine the distance traveled before takeoff.
|
33
33
|
"""
|
34
34
|
def solve!
|
35
|
-
a = Z3
|
36
|
-
t = Z3
|
37
|
-
d = Z3
|
35
|
+
a = Z3.Real("a")
|
36
|
+
t = Z3.Real("t")
|
37
|
+
d = Z3.Real("d")
|
38
38
|
assert a == 3.20
|
39
39
|
assert t == 32.8
|
40
40
|
assert d == a*t*t/2
|
@@ -47,9 +47,9 @@ class KinematicsProblem02 < KinematicsProblem
|
|
47
47
|
A car starts from rest and accelerates uniformly over a time of 5.21 seconds for a distance of 110 m. Determine the acceleration of the car.
|
48
48
|
"""
|
49
49
|
def solve!
|
50
|
-
a = Z3
|
51
|
-
t = Z3
|
52
|
-
d = Z3
|
50
|
+
a = Z3.Real("a")
|
51
|
+
t = Z3.Real("t")
|
52
|
+
d = Z3.Real("d")
|
53
53
|
assert d == a*t*t/2
|
54
54
|
assert t == 5.21
|
55
55
|
assert d == 110
|
@@ -63,10 +63,10 @@ class KinematicsProblem03 < KinematicsProblem
|
|
63
63
|
If Upton free falls for 2.60 seconds, what will be his final velocity and how far will he fall?
|
64
64
|
"""
|
65
65
|
def solve!
|
66
|
-
a = Z3
|
67
|
-
t = Z3
|
68
|
-
v = Z3
|
69
|
-
d = Z3
|
66
|
+
a = Z3.Real("a")
|
67
|
+
t = Z3.Real("t")
|
68
|
+
v = Z3.Real("v")
|
69
|
+
d = Z3.Real("d")
|
70
70
|
assert a == 9.81
|
71
71
|
assert d == a*t*t/2
|
72
72
|
assert v == a*t
|
@@ -80,11 +80,11 @@ class KinematicsProblem04 < KinematicsProblem
|
|
80
80
|
A race car accelerates uniformly from 18.5 m/s to 46.1 m/s in 2.47 seconds. Determine the acceleration of the car and the distance traveled.
|
81
81
|
"""
|
82
82
|
def solve!
|
83
|
-
a = Z3
|
84
|
-
t = Z3
|
85
|
-
vs= Z3
|
86
|
-
ve = Z3
|
87
|
-
d = Z3
|
83
|
+
a = Z3.Real("a")
|
84
|
+
t = Z3.Real("t")
|
85
|
+
vs= Z3.Real("vs")
|
86
|
+
ve = Z3.Real("ve")
|
87
|
+
d = Z3.Real("d")
|
88
88
|
assert vs == 18.5
|
89
89
|
assert ve == 46.1
|
90
90
|
assert t == 2.47
|
@@ -101,9 +101,9 @@ class KinematicsProblem05 < KinematicsProblem
|
|
101
101
|
Determine the time for the feather to fall to the surface of the moon.
|
102
102
|
"""
|
103
103
|
def solve!
|
104
|
-
a = Z3
|
105
|
-
t = Z3
|
106
|
-
d = Z3
|
104
|
+
a = Z3.Real("a")
|
105
|
+
t = Z3.Real("t")
|
106
|
+
d = Z3.Real("d")
|
107
107
|
assert a == 1.67
|
108
108
|
assert d == 1.40
|
109
109
|
assert t >= 0
|
@@ -119,10 +119,10 @@ class KinematicsProblem06 < KinematicsProblem
|
|
119
119
|
then what is the acceleration and what is the distance that the sled travels?
|
120
120
|
"""
|
121
121
|
def solve!
|
122
|
-
a = Z3
|
123
|
-
t = Z3
|
124
|
-
d = Z3
|
125
|
-
v = Z3
|
122
|
+
a = Z3.Real("a")
|
123
|
+
t = Z3.Real("t")
|
124
|
+
d = Z3.Real("d")
|
125
|
+
v = Z3.Real("v")
|
126
126
|
assert v == 444
|
127
127
|
assert t == 1.83
|
128
128
|
assert v == a*t
|
@@ -137,10 +137,10 @@ class KinematicsProblem07 < KinematicsProblem
|
|
137
137
|
Determine the acceleration of the bike.
|
138
138
|
"""
|
139
139
|
def solve!
|
140
|
-
a = Z3
|
141
|
-
t = Z3
|
142
|
-
d = Z3
|
143
|
-
v = Z3
|
140
|
+
a = Z3.Real("a")
|
141
|
+
t = Z3.Real("t")
|
142
|
+
d = Z3.Real("d")
|
143
|
+
v = Z3.Real("v")
|
144
144
|
assert v == 7.10
|
145
145
|
assert d == 35.4
|
146
146
|
assert a*t == v
|
@@ -157,10 +157,10 @@ class KinematicsProblem08 < KinematicsProblem
|
|
157
157
|
Assuming this minimum acceleration, what is the minimum allowed length for the runway?
|
158
158
|
"""
|
159
159
|
def solve!
|
160
|
-
a = Z3
|
161
|
-
t = Z3
|
162
|
-
d = Z3
|
163
|
-
v = Z3
|
160
|
+
a = Z3.Real("a")
|
161
|
+
t = Z3.Real("t")
|
162
|
+
d = Z3.Real("d")
|
163
|
+
v = Z3.Real("v")
|
164
164
|
assert a == 3
|
165
165
|
assert v == 65
|
166
166
|
assert a*t == v
|
@@ -175,9 +175,9 @@ class KinematicsProblem09 < KinematicsProblem
|
|
175
175
|
Determine the skidding distance of the car (assume uniform acceleration).
|
176
176
|
"""
|
177
177
|
def solve!
|
178
|
-
t = Z3
|
179
|
-
d = Z3
|
180
|
-
v = Z3
|
178
|
+
t = Z3.Real("t")
|
179
|
+
d = Z3.Real("d")
|
180
|
+
v = Z3.Real("v")
|
181
181
|
assert v == 22.4
|
182
182
|
assert t == 2.55
|
183
183
|
assert d == t*v/2
|
@@ -191,10 +191,10 @@ class KinematicsProblem10 < KinematicsProblem
|
|
191
191
|
Determine the takeoff speed of the kangaroo.
|
192
192
|
"""
|
193
193
|
def solve!
|
194
|
-
a = Z3
|
195
|
-
t = Z3
|
196
|
-
d = Z3
|
197
|
-
v = Z3
|
194
|
+
a = Z3.Real("a")
|
195
|
+
t = Z3.Real("t")
|
196
|
+
d = Z3.Real("d")
|
197
|
+
v = Z3.Real("v")
|
198
198
|
assert d == 2.62
|
199
199
|
assert a == -9.81
|
200
200
|
assert d == v*t/2
|
@@ -74,29 +74,29 @@ class LetterConnections
|
|
74
74
|
if x == 0
|
75
75
|
@solver.assert @dir[[x,y]] != 0
|
76
76
|
else
|
77
|
-
@solver.assert Z3
|
78
|
-
@solver.assert Z3
|
77
|
+
@solver.assert Z3.Implies(@dir[[x,y]] == 0, @line[[x,y]] == @line[[x-1,y]])
|
78
|
+
@solver.assert Z3.Implies(@dir[[x,y]] == 0, @dir[[x-1,y]] != 2)
|
79
79
|
end
|
80
80
|
# Direction Up
|
81
81
|
if y == 0
|
82
82
|
@solver.assert @dir[[x,y]] != 1
|
83
83
|
else
|
84
|
-
@solver.assert Z3
|
85
|
-
@solver.assert Z3
|
84
|
+
@solver.assert Z3.Implies(@dir[[x,y]] == 1, @line[[x,y]] == @line[[x,y-1]])
|
85
|
+
@solver.assert Z3.Implies(@dir[[x,y]] == 1, @dir[[x,y-1]] != 3)
|
86
86
|
end
|
87
87
|
# Direction Right
|
88
88
|
if x == @xsize - 1
|
89
89
|
@solver.assert @dir[[x,y]] != 2
|
90
90
|
else
|
91
|
-
@solver.assert Z3
|
92
|
-
@solver.assert Z3
|
91
|
+
@solver.assert Z3.Implies(@dir[[x,y]] == 2, @line[[x,y]] == @line[[x+1,y]])
|
92
|
+
@solver.assert Z3.Implies(@dir[[x,y]] == 2, @dir[[x+1,y]] != 0)
|
93
93
|
end
|
94
94
|
# Direction Down
|
95
95
|
if y == @ysize - 1
|
96
96
|
@solver.assert @dir[[x,y]] != 3
|
97
97
|
else
|
98
|
-
@solver.assert Z3
|
99
|
-
@solver.assert Z3
|
98
|
+
@solver.assert Z3.Implies(@dir[[x,y]] == 3, @line[[x,y]] == @line[[x,y+1]])
|
99
|
+
@solver.assert Z3.Implies(@dir[[x,y]] == 3, @dir[[x,y+1]] != 1)
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
@@ -128,14 +128,14 @@ class LetterConnections
|
|
128
128
|
end
|
129
129
|
|
130
130
|
def line_var(x, y)
|
131
|
-
v = Z3
|
131
|
+
v = Z3.Int("l#{x},#{y}")
|
132
132
|
@solver.assert v >= 0
|
133
133
|
@solver.assert v < @letters.size
|
134
134
|
v
|
135
135
|
end
|
136
136
|
|
137
137
|
def dir_var(x, y)
|
138
|
-
v = Z3
|
138
|
+
v = Z3.Int("d#{x},#{y}")
|
139
139
|
@solver.assert v >= 0
|
140
140
|
@solver.assert v <= 3
|
141
141
|
v
|
@@ -154,7 +154,7 @@ class LetterConnections
|
|
154
154
|
|
155
155
|
# Surely Z3 must have a thing for it
|
156
156
|
def condition_exactly_one(conds)
|
157
|
-
@solver.assert Z3
|
157
|
+
@solver.assert Z3.Or(*conds)
|
158
158
|
(0...conds.size).each do |ci|
|
159
159
|
(0...conds.size).each do |cj|
|
160
160
|
if ci < cj
|
data/examples/light_up_solver
CHANGED
@@ -22,7 +22,7 @@ class LightUp
|
|
22
22
|
next if v == "."
|
23
23
|
@solver.assert @lamps[[x,y]] == 0
|
24
24
|
if ("0".."4").include?(v)
|
25
|
-
@solver.assert Z3
|
25
|
+
@solver.assert Z3.Add(*lamps_next_to_cell(x,y)) == v.to_i
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -31,9 +31,9 @@ class LightUp
|
|
31
31
|
# No lamp is in raycast of another lamp
|
32
32
|
(0...@ysize).each do |y|
|
33
33
|
(0...@xsize).each do |x|
|
34
|
-
raycast = Z3
|
35
|
-
@solver.assert Z3
|
36
|
-
@solver.assert Z3
|
34
|
+
raycast = Z3.Add(*raycast_cells(x,y))
|
35
|
+
@solver.assert Z3.Implies(@lamps[[x,y]] == 0, raycast >= 1)
|
36
|
+
@solver.assert Z3.Implies(@lamps[[x,y]] == 1, raycast == 0)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -85,7 +85,7 @@ class LightUp
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def int01(x,y)
|
88
|
-
v = Z3
|
88
|
+
v = Z3.Int("l#{x},#{y}")
|
89
89
|
@solver.assert v >= 0
|
90
90
|
@solver.assert v <= 1
|
91
91
|
v
|
data/examples/minisudoku_solver
CHANGED
@@ -16,14 +16,14 @@ class MiniSudokuSolver
|
|
16
16
|
end
|
17
17
|
|
18
18
|
@cells.each do |row|
|
19
|
-
@solver.assert Z3
|
19
|
+
@solver.assert Z3.Distinct(*row)
|
20
20
|
end
|
21
21
|
@cells.transpose.each do |column|
|
22
|
-
@solver.assert Z3
|
22
|
+
@solver.assert Z3.Distinct(*column)
|
23
23
|
end
|
24
24
|
@cells.each_slice(2) do |rows|
|
25
25
|
rows.transpose.each_slice(3) do |square|
|
26
|
-
@solver.assert Z3
|
26
|
+
@solver.assert Z3.Distinct(*square.flatten)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -38,7 +38,7 @@ class MiniSudokuSolver
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def cell_var(cell, i, j)
|
41
|
-
v = Z3
|
41
|
+
v = Z3.Int("cell[#{i+1},#{j+1}]")
|
42
42
|
@solver.assert v >= 1
|
43
43
|
@solver.assert v <= 6
|
44
44
|
@solver.assert v == cell if cell != nil
|
data/examples/selfref_solver
CHANGED
@@ -10,12 +10,12 @@ class SelfRefPuzzleSolver
|
|
10
10
|
@q = {}
|
11
11
|
@a = {}
|
12
12
|
(1..20).each do |i|
|
13
|
-
@q[i] = Z3
|
13
|
+
@q[i] = Z3.Int("q#{i}")
|
14
14
|
assert @q[i] >= 1
|
15
15
|
assert @q[i] <= 5
|
16
16
|
@a[i] = {}
|
17
17
|
(1..5).each do |j|
|
18
|
-
@a[i][j] = Z3
|
18
|
+
@a[i][j] = Z3.Int("a#{i},#{' ABCDE'[j]}")
|
19
19
|
assert (@a[i][j] == 0) == (@q[i] != j)
|
20
20
|
assert (@a[i][j] == 1) == (@q[i] == j)
|
21
21
|
end
|
@@ -27,23 +27,23 @@ class SelfRefPuzzleSolver
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def cons_in(*ary)
|
30
|
-
Z3
|
30
|
+
Z3.Or(*ary.map{|i| cons_answers == i})
|
31
31
|
end
|
32
32
|
|
33
33
|
def solve!
|
34
|
-
@a_answers = Z3
|
35
|
-
@b_answers = Z3
|
36
|
-
@c_answers = Z3
|
37
|
-
@d_answers = Z3
|
38
|
-
@e_answers = Z3
|
34
|
+
@a_answers = Z3.Add(*(1..20).map{|i| @a[i][1]})
|
35
|
+
@b_answers = Z3.Add(*(1..20).map{|i| @a[i][2]})
|
36
|
+
@c_answers = Z3.Add(*(1..20).map{|i| @a[i][3]})
|
37
|
+
@d_answers = Z3.Add(*(1..20).map{|i| @a[i][4]})
|
38
|
+
@e_answers = Z3.Add(*(1..20).map{|i| @a[i][5]})
|
39
39
|
@cons_answers = b_answers + c_answers + d_answers
|
40
40
|
|
41
41
|
# Question 1
|
42
42
|
assert (q[1] == 1) == (q[1] == 2)
|
43
|
-
assert (q[1] == 2) == Z3
|
44
|
-
assert (q[1] == 3) == Z3
|
45
|
-
assert (q[1] == 4) == Z3
|
46
|
-
assert (q[1] == 5) == Z3
|
43
|
+
assert (q[1] == 2) == Z3.And(q[1] != 2, q[2] == 2)
|
44
|
+
assert (q[1] == 3) == Z3.And(q[1] != 2, q[2] != 2, q[3] == 2)
|
45
|
+
assert (q[1] == 4) == Z3.And(q[1] != 2, q[2] != 2, q[3] != 2, q[4] == 2)
|
46
|
+
assert (q[1] == 5) == Z3.And(q[1] != 2, q[2] != 2, q[3] != 2, q[4] != 2, q[5] == 2)
|
47
47
|
|
48
48
|
# Question 2
|
49
49
|
assert q[ 1] != q[ 2]
|
@@ -81,25 +81,25 @@ class SelfRefPuzzleSolver
|
|
81
81
|
assert (a_answers == 8) == (q[4] == 5)
|
82
82
|
|
83
83
|
# Question 5
|
84
|
-
assert Z3
|
85
|
-
assert Z3
|
86
|
-
assert Z3
|
87
|
-
assert Z3
|
88
|
-
assert Z3
|
84
|
+
assert Z3.Implies(q[5] == 1, q[5] == q[1])
|
85
|
+
assert Z3.Implies(q[5] == 2, q[5] == q[2])
|
86
|
+
assert Z3.Implies(q[5] == 3, q[5] == q[3])
|
87
|
+
assert Z3.Implies(q[5] == 4, q[5] == q[4])
|
88
|
+
assert Z3.Implies(q[5] == 5, q[5] == q[5])
|
89
89
|
|
90
90
|
# Question 6
|
91
91
|
assert (q[17] == 3) == (q[6] == 1)
|
92
92
|
assert (q[17] == 4) == (q[6] == 2)
|
93
93
|
assert (q[17] == 5) == (q[6] == 3)
|
94
|
-
assert Z3
|
94
|
+
assert Z3.Or(q[17] == 1, q[17] == 2) == (q[6] == 4)
|
95
95
|
assert q[6] != 5
|
96
96
|
|
97
97
|
# Question 7
|
98
|
-
assert Z3
|
99
|
-
assert Z3
|
100
|
-
assert Z3
|
101
|
-
assert Z3
|
102
|
-
assert Z3
|
98
|
+
assert Z3.Or(q[7] - q[8] == 4, q[8] - q[7] == 4) == (q[7] == 1)
|
99
|
+
assert Z3.Or(q[7] - q[8] == 3, q[8] - q[7] == 3) == (q[7] == 2)
|
100
|
+
assert Z3.Or(q[7] - q[8] == 2, q[8] - q[7] == 2) == (q[7] == 3)
|
101
|
+
assert Z3.Or(q[7] - q[8] == 1, q[8] - q[7] == 1) == (q[7] == 4)
|
102
|
+
assert Z3.Or(q[7] - q[8] == 0, q[8] - q[7] == 0) == (q[7] == 5)
|
103
103
|
|
104
104
|
# Question 8
|
105
105
|
assert (a_answers + e_answers == 4) == (q[8] == 1)
|
@@ -110,10 +110,10 @@ class SelfRefPuzzleSolver
|
|
110
110
|
|
111
111
|
# Question 9
|
112
112
|
assert (q[10] == q[9]) == (q[9] == 1)
|
113
|
-
assert Z3
|
114
|
-
assert Z3
|
115
|
-
assert Z3
|
116
|
-
assert Z3
|
113
|
+
assert Z3.And(q[10] != q[9], q[11] == q[9]) == (q[9] == 2)
|
114
|
+
assert Z3.And(q[10] != q[9], q[11] != q[9], q[12] == q[9]) == (q[9] == 3)
|
115
|
+
assert Z3.And(q[10] != q[9], q[11] != q[9], q[12] != q[9], q[13] == q[9]) == (q[9] == 4)
|
116
|
+
assert Z3.And(q[10] != q[9], q[11] != q[9], q[12] != q[9], q[13] != q[9], q[14] == q[9]) == (q[9] == 5)
|
117
117
|
|
118
118
|
# Question 10
|
119
119
|
assert (q[16] == 4) == (q[10] == 1)
|
@@ -123,7 +123,7 @@ class SelfRefPuzzleSolver
|
|
123
123
|
assert (q[16] == 3) == (q[10] == 5)
|
124
124
|
|
125
125
|
# Question 11
|
126
|
-
prec_b_answers = Z3
|
126
|
+
prec_b_answers = Z3.Add(*(1..10).map{|i| @a[i][2]})
|
127
127
|
assert (prec_b_answers == 0) == (q[11] == 1)
|
128
128
|
assert (prec_b_answers == 1) == (q[11] == 2)
|
129
129
|
assert (prec_b_answers == 2) == (q[11] == 3)
|
@@ -131,11 +131,11 @@ class SelfRefPuzzleSolver
|
|
131
131
|
assert (prec_b_answers == 4) == (q[11] == 5)
|
132
132
|
|
133
133
|
# Question 12
|
134
|
-
assert Z3
|
135
|
-
assert Z3
|
136
|
-
assert Z3
|
137
|
-
assert Z3
|
138
|
-
assert Z3
|
134
|
+
assert Z3.Implies(q[12] == 1, cons_in(2,4,6,8,10,12,14,16,18,20))
|
135
|
+
assert Z3.Implies(q[12] == 2, cons_in(1,3,5,7,9,11,13,15,17,19))
|
136
|
+
assert Z3.Implies(q[12] == 3, cons_in(1,4,9,16))
|
137
|
+
assert Z3.Implies(q[12] == 4, cons_in(2,3,5,7,11,13,17,19))
|
138
|
+
assert Z3.Implies(q[12] == 5, cons_in(5,10,15,20))
|
139
139
|
|
140
140
|
# Question 13
|
141
141
|
assert q[1] != 1
|
@@ -170,7 +170,7 @@ class SelfRefPuzzleSolver
|
|
170
170
|
assert (q[6] == 3) == (q[17] == 1)
|
171
171
|
assert (q[6] == 4) == (q[17] == 2)
|
172
172
|
assert (q[6] == 5) == (q[17] == 3)
|
173
|
-
assert Z3
|
173
|
+
assert Z3.And(q[6] != 3, q[6] != 4, q[6] != 5) == (q[17] == 4)
|
174
174
|
assert q[17] != 5
|
175
175
|
|
176
176
|
# Question 18
|
@@ -178,7 +178,7 @@ class SelfRefPuzzleSolver
|
|
178
178
|
assert (a_answers == c_answers) == (q[18] == 2)
|
179
179
|
assert (a_answers == d_answers) == (q[18] == 3)
|
180
180
|
assert (a_answers == e_answers) == (q[18] == 4)
|
181
|
-
assert Z3
|
181
|
+
assert Z3.And(
|
182
182
|
a_answers != b_answers,
|
183
183
|
a_answers != c_answers,
|
184
184
|
a_answers != d_answers,
|
data/examples/sudoku_solver
CHANGED
@@ -16,14 +16,14 @@ class SudokuSolver
|
|
16
16
|
end
|
17
17
|
|
18
18
|
@cells.each do |row|
|
19
|
-
@solver.assert Z3
|
19
|
+
@solver.assert Z3.Distinct(*row)
|
20
20
|
end
|
21
21
|
@cells.transpose.each do |column|
|
22
|
-
@solver.assert Z3
|
22
|
+
@solver.assert Z3.Distinct(*column)
|
23
23
|
end
|
24
24
|
@cells.each_slice(3) do |rows|
|
25
25
|
rows.transpose.each_slice(3) do |square|
|
26
|
-
@solver.assert Z3
|
26
|
+
@solver.assert Z3.Distinct(*square.flatten)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -38,7 +38,7 @@ class SudokuSolver
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def cell_var(cell, i, j)
|
41
|
-
v = Z3
|
41
|
+
v = Z3.Int("cell[#{i+1},#{j+1}]")
|
42
42
|
@solver.assert v >= 1
|
43
43
|
@solver.assert v <= 9
|
44
44
|
@solver.assert v == cell if cell != nil
|