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
@@ -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
+ """
@@ -4,17 +4,17 @@ require_relative "../lib/z3"
4
4
 
5
5
  solver = Z3::Solver.new
6
6
 
7
- ax = Z3::Ast.real("a.x")
8
- ay = Z3::Ast.real("a.y")
9
- bx = Z3::Ast.real("b.x")
10
- by = Z3::Ast.real("b.y")
11
- cx = Z3::Ast.real("c.x")
12
- cy = Z3::Ast.real("c.y")
13
- dx = Z3::Ast.real("d.x")
14
- dy = Z3::Ast.real("d.y")
15
-
16
- a_c = Z3::Ast.real("|a-c|")
17
- b_d = Z3::Ast.real("|b-d|")
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)
@@ -87,7 +87,7 @@ class Kakuro
87
87
  end
88
88
 
89
89
  def cell_var(x,y)
90
- v = Z3::Ast.int("c#{x},#{y}")
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::Ast.distinct(*vs)
107
- @solver.assert Z3::Ast.add(*vs) == sum
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::Ast.real("a")
36
- t = Z3::Ast.real("t")
37
- d = Z3::Ast.real("d")
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::Ast.real("a")
51
- t = Z3::Ast.real("t")
52
- d = Z3::Ast.real("d")
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::Ast.real("a")
67
- t = Z3::Ast.real("t")
68
- v = Z3::Ast.real("v")
69
- d = Z3::Ast.real("d")
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::Ast.real("a")
84
- t = Z3::Ast.real("t")
85
- vs= Z3::Ast.real("vs")
86
- ve = Z3::Ast.real("ve")
87
- d = Z3::Ast.real("d")
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::Ast.real("a")
105
- t = Z3::Ast.real("t")
106
- d = Z3::Ast.real("d")
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::Ast.real("a")
123
- t = Z3::Ast.real("t")
124
- d = Z3::Ast.real("d")
125
- v = Z3::Ast.real("v")
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::Ast.real("a")
141
- t = Z3::Ast.real("t")
142
- d = Z3::Ast.real("d")
143
- v = Z3::Ast.real("v")
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::Ast.real("a")
161
- t = Z3::Ast.real("t")
162
- d = Z3::Ast.real("d")
163
- v = Z3::Ast.real("v")
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::Ast.real("t")
179
- d = Z3::Ast.real("d")
180
- v = Z3::Ast.real("v")
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::Ast.real("a")
195
- t = Z3::Ast.real("t")
196
- d = Z3::Ast.real("d")
197
- v = Z3::Ast.real("v")
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::Ast.implies(@dir[[x,y]] == 0, @line[[x,y]] == @line[[x-1,y]])
78
- @solver.assert Z3::Ast.implies(@dir[[x,y]] == 0, @dir[[x-1,y]] != 2)
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::Ast.implies(@dir[[x,y]] == 1, @line[[x,y]] == @line[[x,y-1]])
85
- @solver.assert Z3::Ast.implies(@dir[[x,y]] == 1, @dir[[x,y-1]] != 3)
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::Ast.implies(@dir[[x,y]] == 2, @line[[x,y]] == @line[[x+1,y]])
92
- @solver.assert Z3::Ast.implies(@dir[[x,y]] == 2, @dir[[x+1,y]] != 0)
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::Ast.implies(@dir[[x,y]] == 3, @line[[x,y]] == @line[[x,y+1]])
99
- @solver.assert Z3::Ast.implies(@dir[[x,y]] == 3, @dir[[x,y+1]] != 1)
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::Ast.int("l#{x},#{y}")
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::Ast.int("d#{x},#{y}")
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::Ast.or(*conds)
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
@@ -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::Ast.add(*lamps_next_to_cell(x,y)) == v.to_i
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::Ast.add(*raycast_cells(x,y))
35
- @solver.assert Z3::Ast.implies(@lamps[[x,y]] == 0, raycast >= 1)
36
- @solver.assert Z3::Ast.implies(@lamps[[x,y]] == 1, raycast == 0)
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::Ast.int("l#{x},#{y}")
88
+ v = Z3.Int("l#{x},#{y}")
89
89
  @solver.assert v >= 0
90
90
  @solver.assert v <= 1
91
91
  v
@@ -16,14 +16,14 @@ class MiniSudokuSolver
16
16
  end
17
17
 
18
18
  @cells.each do |row|
19
- @solver.assert Z3::Ast.distinct(*row)
19
+ @solver.assert Z3.Distinct(*row)
20
20
  end
21
21
  @cells.transpose.each do |column|
22
- @solver.assert Z3::Ast.distinct(*column)
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::Ast.distinct(*square.flatten)
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::Ast.int("cell[#{i+1},#{j+1}]")
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
@@ -10,12 +10,12 @@ class SelfRefPuzzleSolver
10
10
  @q = {}
11
11
  @a = {}
12
12
  (1..20).each do |i|
13
- @q[i] = Z3::Ast.int("q#{i}")
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::Ast.int("a#{i},#{' ABCDE'[j]}")
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::Ast.or(*ary.map{|i| cons_answers == i})
30
+ Z3.Or(*ary.map{|i| cons_answers == i})
31
31
  end
32
32
 
33
33
  def solve!
34
- @a_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][1]})
35
- @b_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][2]})
36
- @c_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][3]})
37
- @d_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][4]})
38
- @e_answers = Z3::Ast.add(*(1..20).map{|i| @a[i][5]})
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::Ast.and(q[1] != 2, q[2] == 2)
44
- assert (q[1] == 3) == Z3::Ast.and(q[1] != 2, q[2] != 2, q[3] == 2)
45
- assert (q[1] == 4) == Z3::Ast.and(q[1] != 2, q[2] != 2, q[3] != 2, q[4] == 2)
46
- assert (q[1] == 5) == Z3::Ast.and(q[1] != 2, q[2] != 2, q[3] != 2, q[4] != 2, q[5] == 2)
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::Ast.implies(q[5] == 1, q[5] == q[1])
85
- assert Z3::Ast.implies(q[5] == 2, q[5] == q[2])
86
- assert Z3::Ast.implies(q[5] == 3, q[5] == q[3])
87
- assert Z3::Ast.implies(q[5] == 4, q[5] == q[4])
88
- assert Z3::Ast.implies(q[5] == 5, q[5] == q[5])
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::Ast.or(q[17] == 1, q[17] == 2) == (q[6] == 4)
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::Ast.or(q[7] - q[8] == 4, q[8] - q[7] == 4) == (q[7] == 1)
99
- assert Z3::Ast.or(q[7] - q[8] == 3, q[8] - q[7] == 3) == (q[7] == 2)
100
- assert Z3::Ast.or(q[7] - q[8] == 2, q[8] - q[7] == 2) == (q[7] == 3)
101
- assert Z3::Ast.or(q[7] - q[8] == 1, q[8] - q[7] == 1) == (q[7] == 4)
102
- assert Z3::Ast.or(q[7] - q[8] == 0, q[8] - q[7] == 0) == (q[7] == 5)
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::Ast.and(q[10] != q[9], q[11] == q[9]) == (q[9] == 2)
114
- assert Z3::Ast.and(q[10] != q[9], q[11] != q[9], q[12] == q[9]) == (q[9] == 3)
115
- assert Z3::Ast.and(q[10] != q[9], q[11] != q[9], q[12] != q[9], q[13] == q[9]) == (q[9] == 4)
116
- assert Z3::Ast.and(q[10] != q[9], q[11] != q[9], q[12] != q[9], q[13] != q[9], q[14] == q[9]) == (q[9] == 5)
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::Ast.add(*(1..10).map{|i| @a[i][2]})
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::Ast.implies(q[12] == 1, cons_in(2,4,6,8,10,12,14,16,18,20))
135
- assert Z3::Ast.implies(q[12] == 2, cons_in(1,3,5,7,9,11,13,15,17,19))
136
- assert Z3::Ast.implies(q[12] == 3, cons_in(1,4,9,16))
137
- assert Z3::Ast.implies(q[12] == 4, cons_in(2,3,5,7,11,13,17,19))
138
- assert Z3::Ast.implies(q[12] == 5, cons_in(5,10,15,20))
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::Ast.and(q[6] != 3, q[6] != 4, q[6] != 5) == (q[17] == 4)
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::Ast.and(
181
+ assert Z3.And(
182
182
  a_answers != b_answers,
183
183
  a_answers != c_answers,
184
184
  a_answers != d_answers,
@@ -16,14 +16,14 @@ class SudokuSolver
16
16
  end
17
17
 
18
18
  @cells.each do |row|
19
- @solver.assert Z3::Ast.distinct(*row)
19
+ @solver.assert Z3.Distinct(*row)
20
20
  end
21
21
  @cells.transpose.each do |column|
22
- @solver.assert Z3::Ast.distinct(*column)
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::Ast.distinct(*square.flatten)
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::Ast.int("cell[#{i+1},#{j+1}]")
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