z3 0.0.20160221 → 0.0.20160323

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.
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