z3 0.0.0

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.
@@ -0,0 +1,370 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/z3"
4
+
5
+ class SelfRefPuzzleSolver
6
+ attr_reader :q, :a
7
+ attr_reader :a_answers, :b_answers, :c_answers, :d_answers, :e_answers, :cons_answers
8
+ def initialize
9
+ @solver = Z3::Solver.new
10
+ @q = {}
11
+ @a = {}
12
+ (1..20).each do |i|
13
+ @q[i] = Z3::Ast.int("q#{i}")
14
+ assert @q[i] >= 1
15
+ assert @q[i] <= 5
16
+ @a[i] = {}
17
+ (1..5).each do |j|
18
+ @a[i][j] = Z3::Ast.int("a#{i},#{' ABCDE'[j]}")
19
+ assert (@a[i][j] == 0) == (@q[i] != j)
20
+ assert (@a[i][j] == 1) == (@q[i] == j)
21
+ end
22
+ end
23
+ end
24
+
25
+ def assert(ast)
26
+ @solver.assert(ast)
27
+ end
28
+
29
+ def cons_in(*ary)
30
+ Z3::Ast.or(*ary.map{|i| cons_answers == i})
31
+ end
32
+
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]})
39
+ @cons_answers = b_answers + c_answers + d_answers
40
+
41
+ # Question 1
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)
47
+
48
+ # Question 2
49
+ assert q[ 1] != q[ 2]
50
+ assert q[ 2] != q[ 3]
51
+ assert q[ 3] != q[ 4]
52
+ assert q[ 4] != q[ 5]
53
+ assert q[ 5] != q[ 6]
54
+ assert (q[ 6] == q[ 7]) == (q[2] == 1)
55
+ assert (q[ 7] == q[ 8]) == (q[2] == 2)
56
+ assert (q[ 8] == q[ 9]) == (q[2] == 3)
57
+ assert (q[ 9] == q[10]) == (q[2] == 4)
58
+ assert (q[10] == q[11]) == (q[2] == 5)
59
+ assert q[11] != q[12]
60
+ assert q[12] != q[13]
61
+ assert q[13] != q[14]
62
+ assert q[14] != q[15]
63
+ assert q[15] != q[16]
64
+ assert q[16] != q[17]
65
+ assert q[17] != q[18]
66
+ assert q[18] != q[19]
67
+ assert q[19] != q[20]
68
+
69
+ # Question 3
70
+ assert (e_answers == 0) == (q[3] == 1)
71
+ assert (e_answers == 1) == (q[3] == 2)
72
+ assert (e_answers == 2) == (q[3] == 3)
73
+ assert (e_answers == 3) == (q[3] == 4)
74
+ assert (e_answers == 4) == (q[3] == 5)
75
+
76
+ # Question 4
77
+ assert (a_answers == 4) == (q[4] == 1)
78
+ assert (a_answers == 5) == (q[4] == 2)
79
+ assert (a_answers == 6) == (q[4] == 3)
80
+ assert (a_answers == 7) == (q[4] == 4)
81
+ assert (a_answers == 8) == (q[4] == 5)
82
+
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])
89
+
90
+ # Question 6
91
+ assert (q[17] == 3) == (q[6] == 1)
92
+ assert (q[17] == 4) == (q[6] == 2)
93
+ assert (q[17] == 5) == (q[6] == 3)
94
+ assert Z3::Ast.or(q[17] == 1, q[17] == 2) == (q[6] == 4)
95
+ assert q[6] != 5
96
+
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)
103
+
104
+ # Question 8
105
+ assert (a_answers + e_answers == 4) == (q[8] == 1)
106
+ assert (a_answers + e_answers == 5) == (q[8] == 2)
107
+ assert (a_answers + e_answers == 6) == (q[8] == 3)
108
+ assert (a_answers + e_answers == 7) == (q[8] == 4)
109
+ assert (a_answers + e_answers == 8) == (q[8] == 5)
110
+
111
+ # Question 9
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)
117
+
118
+ # Question 10
119
+ assert (q[16] == 4) == (q[10] == 1)
120
+ assert (q[16] == 1) == (q[10] == 2)
121
+ assert (q[16] == 5) == (q[10] == 3)
122
+ assert (q[16] == 2) == (q[10] == 4)
123
+ assert (q[16] == 3) == (q[10] == 5)
124
+
125
+ # Question 11
126
+ prec_b_answers = Z3::Ast.add(*(1..10).map{|i| @a[i][2]})
127
+ assert (prec_b_answers == 0) == (q[11] == 1)
128
+ assert (prec_b_answers == 1) == (q[11] == 2)
129
+ assert (prec_b_answers == 2) == (q[11] == 3)
130
+ assert (prec_b_answers == 3) == (q[11] == 4)
131
+ assert (prec_b_answers == 4) == (q[11] == 5)
132
+
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))
139
+
140
+ # Question 13
141
+ assert q[1] != 1
142
+ assert q[3] != 1
143
+ assert q[5] != 1
144
+ assert q[7] != 1
145
+ assert (q[ 9] == 1) == (q[13] == 1)
146
+ assert (q[11] == 1) == (q[13] == 2)
147
+ assert (q[13] == 1) == (q[13] == 3)
148
+ assert (q[15] == 1) == (q[13] == 4)
149
+ assert (q[17] == 1) == (q[13] == 5)
150
+ assert q[19] != 1
151
+
152
+ # Question 14
153
+ assert (d_answers == 6) == (q[4] == 1)
154
+ assert (d_answers == 7) == (q[4] == 2)
155
+ assert (d_answers == 8) == (q[4] == 3)
156
+ assert (d_answers == 9) == (q[4] == 4)
157
+ assert (d_answers == 10) == (q[4] == 5)
158
+
159
+ # Question 15
160
+ assert q[15] == q[12]
161
+
162
+ # Question 16
163
+ assert (q[10] == 4) == (q[16] == 1)
164
+ assert (q[10] == 3) == (q[16] == 2)
165
+ assert (q[10] == 2) == (q[16] == 3)
166
+ assert (q[10] == 1) == (q[16] == 4)
167
+ assert (q[10] == 5) == (q[16] == 5)
168
+
169
+ # Question 17
170
+ assert (q[6] == 3) == (q[17] == 1)
171
+ assert (q[6] == 4) == (q[17] == 2)
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)
174
+ assert q[17] != 5
175
+
176
+ # Question 18
177
+ assert (a_answers == b_answers) == (q[18] == 1)
178
+ assert (a_answers == c_answers) == (q[18] == 2)
179
+ assert (a_answers == d_answers) == (q[18] == 3)
180
+ assert (a_answers == e_answers) == (q[18] == 4)
181
+ assert Z3::Ast.and(
182
+ a_answers != b_answers,
183
+ a_answers != c_answers,
184
+ a_answers != d_answers,
185
+ a_answers != e_answers
186
+ ) == (q[18] == 5)
187
+
188
+ # Question 19
189
+ assert q[19] == q[19]
190
+
191
+ # Question 20
192
+ assert q[20] == 5
193
+
194
+ # Print solutions
195
+ if @solver.check == :sat
196
+ model = @solver.model
197
+ (1..20).each do |i|
198
+ a = model[q[i]].to_s.to_i
199
+ puts "Q%2d: %s" % [i, " ABCDE"[a]]
200
+ end
201
+ else
202
+ puts "failed to solve"
203
+ end
204
+ end
205
+ end
206
+
207
+
208
+ SelfRefPuzzleSolver.new.solve!
209
+
210
+ __END__
211
+ http://faculty.uml.edu/jpropp/srat-Q.txt
212
+
213
+ SELF-REFERENTIAL APTITUDE TEST, by Jim Propp (jimpropp at gmaildotcom)
214
+
215
+ The solution to the following puzzle is unique; in some cases the
216
+ knowledge that the solution is unique may actually give you a short-cut
217
+ to finding the answer to a particular question. (Thanks to Andy Latto
218
+ for bringing this subtlety to my attention.)
219
+
220
+ I should mention that if you don't agree with me about the answer to #20,
221
+ you will get a different solution to the puzzle than the one I had in mind.
222
+ But I should also mention that if you don't agree with me about the answer
223
+ to #20, you are just plain wrong. :-)
224
+
225
+ You may now begin work.
226
+
227
+
228
+ 1. The first question whose answer is B is question
229
+ (A) 1
230
+ (B) 2
231
+ (C) 3
232
+ (D) 4
233
+ (E) 5
234
+
235
+ 2. The only two consecutive questions with identical answers are questions
236
+ (A) 6 and 7
237
+ (B) 7 and 8
238
+ (C) 8 and 9
239
+ (D) 9 and 10
240
+ (E) 10 and 11
241
+
242
+ 3. The number of questions with the answer E is
243
+ (A) 0
244
+ (B) 1
245
+ (C) 2
246
+ (D) 3
247
+ (E) 4
248
+
249
+ 4. The number of questions with the answer A is
250
+ (A) 4
251
+ (B) 5
252
+ (C) 6
253
+ (D) 7
254
+ (E) 8
255
+
256
+ 5. The answer to this question is the same as the answer to question
257
+ (A) 1
258
+ (B) 2
259
+ (C) 3
260
+ (D) 4
261
+ (E) 5
262
+
263
+ 6. The answer to question 17 is
264
+ (A) C
265
+ (B) D
266
+ (C) E
267
+ (D) none of the above
268
+ (E) all of the above
269
+
270
+ 7. Alphabetically, the answer to this question and the answer to the
271
+ following question are
272
+ (A) 4 apart
273
+ (B) 3 apart
274
+ (C) 2 apart
275
+ (D) 1 apart
276
+ (E) the same
277
+
278
+ 8. The number of questions whose answers are vowels is
279
+ (A) 4
280
+ (B) 5
281
+ (C) 6
282
+ (D) 7
283
+ (E) 8
284
+
285
+ 9. The next question with the same answer as this one is question
286
+ (A) 10
287
+ (B) 11
288
+ (C) 12
289
+ (D) 13
290
+ (E) 14
291
+
292
+ 10. The answer to question 16 is
293
+ (A) D
294
+ (B) A
295
+ (C) E
296
+ (D) B
297
+ (E) C
298
+
299
+ 11. The number of questions preceding this one with the answer B is
300
+ (A) 0
301
+ (B) 1
302
+ (C) 2
303
+ (D) 3
304
+ (E) 4
305
+
306
+ 12. The number of questions whose answer is a consonant is
307
+ (A) an even number
308
+ (B) an odd number
309
+ (C) a perfect square
310
+ (D) a prime
311
+ (E) divisible by 5
312
+
313
+ 13. The only odd-numbered problem with answer A is
314
+ (A) 9
315
+ (B) 11
316
+ (C) 13
317
+ (D) 15
318
+ (E) 17
319
+
320
+ 14. The number of questions with answer D is
321
+ (A) 6
322
+ (B) 7
323
+ (C) 8
324
+ (D) 9
325
+ (E) 10
326
+
327
+ 15. The answer to question 12 is
328
+ (A) A
329
+ (B) B
330
+ (C) C
331
+ (D) D
332
+ (E) E
333
+
334
+ 16. The answer to question 10 is
335
+ (A) D
336
+ (B) C
337
+ (C) B
338
+ (D) A
339
+ (E) E
340
+
341
+ 17. The answer to question 6 is
342
+ (A) C
343
+ (B) D
344
+ (C) E
345
+ (D) none of the above
346
+ (E) all of the above
347
+
348
+ 18. The number of questions with answer A equals the number of questions
349
+ with answer
350
+ (A) B
351
+ (B) C
352
+ (C) D
353
+ (D) E
354
+ (E) none of the above
355
+
356
+ 19. The answer to this question is:
357
+ (A) A
358
+ (B) B
359
+ (C) C
360
+ (D) D
361
+ (E) E
362
+
363
+ 20. Standardized test is to intelligence as barometer is to
364
+ (A) temperature (only)
365
+ (B) wind-velocity (only)
366
+ (C) latitude (only)
367
+ (D) longitude (only)
368
+ (E) temperature, wind-velocity, latitude, and longitude
369
+
370
+ ( to go to the main SRAT page, go to jamespropp.org/srat.html )
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/z3"
4
+
5
+ class SudokuSolver
6
+ def initialize(data)
7
+ @data = data
8
+ @solver = Z3::Solver.new
9
+ end
10
+
11
+ def solve!
12
+ @cells = (0..8).map do |j|
13
+ (0..8).map do |i|
14
+ cell_var(@data[j][i], i, j)
15
+ end
16
+ end
17
+
18
+ @cells.each do |row|
19
+ @solver.assert Z3::Ast.distinct(*row)
20
+ end
21
+ @cells.transpose.each do |column|
22
+ @solver.assert Z3::Ast.distinct(*column)
23
+ end
24
+ @cells.each_slice(3) do |rows|
25
+ rows.transpose.each_slice(3) do |square|
26
+ @solver.assert Z3::Ast.distinct(*square.flatten)
27
+ end
28
+ end
29
+
30
+ if @solver.check == :sat
31
+ @model = @solver.model
32
+ print_answer!
33
+ else
34
+ puts "failed to solve"
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def cell_var(cell, i, j)
41
+ v = Z3::Ast.int("cell[#{i+1},#{j+1}]")
42
+ @solver.assert v >= 1
43
+ @solver.assert v <= 9
44
+ @solver.assert v == cell if cell != nil
45
+ v
46
+ end
47
+
48
+ def print_answer!
49
+ @cells.each do |row|
50
+ puts row.map{|v| @model[v]}.join(" ")
51
+ end
52
+ end
53
+ end
54
+
55
+ _ = nil
56
+ sudoku = SudokuSolver.new([
57
+ [_, 6, _, 5, _, 9, _, 4, _],
58
+ [9, 2, _, _, _, _, _, 7, 6],
59
+ [_, _, 1, _, _, _, 9, _, _],
60
+ [7, _, _, 6, _, 3, _, _, 9],
61
+ [_, _, _, _, _, _, _, _, _],
62
+ [3, _, _, 4, _, 1, _, _, 7],
63
+ [_, _, 6, _, _, _, 7, _, _],
64
+ [2, 4, _, _, _, _, _, 6, 5],
65
+ [_, 9, _, 1, _, 8, _, 3, _],
66
+ ])
67
+ sudoku.solve!
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/z3"
4
+
5
+ class VerbalArithmetic
6
+ def initialize(a, b, c)
7
+ @solver = Z3::Solver.new
8
+ @vars = Hash.new do |ht,name|
9
+ v = Z3::Ast.int(name)
10
+ @solver.assert v >= 0
11
+ @solver.assert v <= 9
12
+ ht[name] = v
13
+ end
14
+ @a = a.chars.map{|v| @vars[v]}
15
+ @b = b.chars.map{|v| @vars[v]}
16
+ @c = c.chars.map{|v| @vars[v]}
17
+ end
18
+
19
+ def solve!
20
+ @solver.assert @a[0] != 0
21
+ @solver.assert @b[0] != 0
22
+ @solver.assert @c[0] != 0
23
+ @solver.assert word_value(@a) + word_value(@b) == word_value(@c)
24
+ @solver.assert Z3::Ast.distinct(*@vars.values)
25
+
26
+ if @solver.check == :sat
27
+ @model = @solver.model
28
+ print_answer!
29
+ else
30
+ puts "failed to solve"
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def word_value(word)
37
+ word.inject(0){|x,y| 10*x+y}
38
+ end
39
+
40
+ def print_answer!
41
+ [@a,@b,@c].each do |word|
42
+ p word.map{|v| [v.to_s, @model[v].to_s.to_i]}
43
+ end
44
+ end
45
+ end
46
+
47
+ VerbalArithmetic.new("SEND", "MORE", "MONEY").solve!