z3 0.0.20160323 → 0.0.20160330
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.
- checksums.yaml +4 -4
- data/examples/knights_puzzle_solver +122 -0
- data/lib/z3/interface.rb +6 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b616eadc04d3acebed002b5e30969543ec87288
|
4
|
+
data.tar.gz: 51b12ceac3ca413e11d445c21524aa709e0d0c86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 755c4a975d120202b93efe203d3eeea53dc7898a0a15b8008c287bc7821c773f5e88a73680dd32eb4acfcd55208659c55591ee9151a06056884e2760101492a3
|
7
|
+
data.tar.gz: 5bc45fa1e31598830ce699b55cccbfac82ed9f83b72d9700fd454ecc2d05f68800bad0d2f8c2dc9f6485163b1ada994cfdd233323a52e49af1f142fa8107673e
|
@@ -0,0 +1,122 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative "../lib/z3"
|
4
|
+
|
5
|
+
class KnightsPuzzle
|
6
|
+
def initialize
|
7
|
+
@x_size = 4
|
8
|
+
@y_size = 4
|
9
|
+
@num_moves = 12
|
10
|
+
@solver = Z3::Solver.new
|
11
|
+
@boards = (@num_moves+1).times.map{|t| board(t) }
|
12
|
+
@moves = @num_moves.times.map{|t| move(t)}
|
13
|
+
setup_board @boards[0], """
|
14
|
+
bbb.
|
15
|
+
xb.w
|
16
|
+
..ww
|
17
|
+
x.xw
|
18
|
+
"""
|
19
|
+
setup_board @boards[-1], """
|
20
|
+
www.
|
21
|
+
xw.b
|
22
|
+
..bb
|
23
|
+
x.xb
|
24
|
+
"""
|
25
|
+
@num_moves.times do |t|
|
26
|
+
setup_board_move @boards[t], @boards[t+1], @moves[t]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_board(t)
|
31
|
+
puts "State #{t}:"
|
32
|
+
puts @boards[t].transpose.map{|row| row.map{|c| ".wbx"[@model[c].to_i]}.join }.join("\n")
|
33
|
+
end
|
34
|
+
|
35
|
+
def print_move(t)
|
36
|
+
move = Hash[@moves[t].map{|k,v| [k,@model[v].to_i]}]
|
37
|
+
figure = " wbx"[move[:figure]]
|
38
|
+
puts "#{figure}: #{move[:start_x]},#{move[:start_y]} -> #{move[:end_x]},#{move[:end_y]}"
|
39
|
+
puts ""
|
40
|
+
end
|
41
|
+
|
42
|
+
def solve!
|
43
|
+
if @solver.check == :sat
|
44
|
+
@model = @solver.model
|
45
|
+
puts "Solved"
|
46
|
+
@num_moves.times do |t|
|
47
|
+
print_board(t)
|
48
|
+
print_move(t)
|
49
|
+
end
|
50
|
+
print_board(@num_moves)
|
51
|
+
else
|
52
|
+
puts "Puzzle can't be solved"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def setup_board_move(board_start, board_end, move)
|
59
|
+
@x_size.times.map do |x|
|
60
|
+
@y_size.times.map do |y|
|
61
|
+
# If not part of the move, stays the same
|
62
|
+
starts_here = (move[:start_x] == x) & (move[:start_y] == y)
|
63
|
+
ends_here = (move[:end_x] == x) & (move[:end_y] == y)
|
64
|
+
@solver.assert Z3::Implies(~starts_here & ~ends_here, board_start[x][y] == board_end[x][y])
|
65
|
+
# Every move starts with figure, ends on empty space
|
66
|
+
@solver.assert Z3::Implies(starts_here, board_start[x][y] == move[:figure])
|
67
|
+
@solver.assert Z3::Implies(starts_here, board_end[x][y] == 0)
|
68
|
+
@solver.assert Z3::Implies(ends_here, board_start[x][y] == 0)
|
69
|
+
@solver.assert Z3::Implies(ends_here, board_end[x][y] == move[:figure])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def board(t)
|
75
|
+
@x_size.times.map do |x|
|
76
|
+
@y_size.times.map do |y|
|
77
|
+
v = Z3::Int("b[#{t},#{x},#{y}]")
|
78
|
+
@solver.assert v >= 0
|
79
|
+
@solver.assert v <= 3
|
80
|
+
v
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def setup_board(vars, str)
|
86
|
+
str = str.split.map(&:chomp)
|
87
|
+
4.times do |x|
|
88
|
+
4.times do |y|
|
89
|
+
c = str[y][x]
|
90
|
+
i = ".wbx".index(c) or raise "Unknown character #{c}"
|
91
|
+
@solver.assert vars[x][y] == i
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def abs(t)
|
97
|
+
Z3::IfThenElse(t >= 0, t, -t)
|
98
|
+
end
|
99
|
+
|
100
|
+
def move(t)
|
101
|
+
move_start_x = Z3::Int("move_start_x_#{t}")
|
102
|
+
move_start_y = Z3::Int("move_start_y_#{t}")
|
103
|
+
move_end_x = Z3::Int("move_end_x_#{t}")
|
104
|
+
move_end_y = Z3::Int("move_end_y_#{t}")
|
105
|
+
figure = Z3::Int("move_figure_#{t}")
|
106
|
+
@solver.assert (figure >= 1) & (figure <= 2)
|
107
|
+
@solver.assert (move_start_x >= 0) & (move_start_x < @x_size)
|
108
|
+
@solver.assert (move_start_y >= 0) & (move_start_y < @y_size)
|
109
|
+
@solver.assert (move_end_x >= 0) & (move_end_x < @x_size)
|
110
|
+
@solver.assert (move_end_y >= 0) & (move_end_y < @y_size)
|
111
|
+
|
112
|
+
# 8 possible moves
|
113
|
+
@solver.assert (
|
114
|
+
((abs(move_start_x - move_end_x) == 2) & (abs(move_start_y - move_end_y) == 1)) |
|
115
|
+
((abs(move_start_x - move_end_x) == 1) & (abs(move_start_y - move_end_y) == 2))
|
116
|
+
)
|
117
|
+
|
118
|
+
{start_x: move_start_x, start_y: move_start_y, end_x: move_end_x, end_y: move_end_y, figure: figure}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
KnightsPuzzle.new.solve!
|
data/lib/z3/interface.rb
CHANGED
@@ -75,6 +75,12 @@ module Z3
|
|
75
75
|
BoolSort.new.new(Z3::LowLevel.mk_iff(a, b))
|
76
76
|
end
|
77
77
|
|
78
|
+
def IfThenElse(a, b, c)
|
79
|
+
a, = coerce_to_same_bool_sort(a)
|
80
|
+
b, c = coerce_to_same_sort(b, c)
|
81
|
+
b.sort.new(Z3::LowLevel.mk_ite(a, b, c))
|
82
|
+
end
|
83
|
+
|
78
84
|
def Add(*args)
|
79
85
|
raise ArgumentError if args.empty?
|
80
86
|
args = coerce_to_same_sort(*args)
|
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.
|
4
|
+
version: 0.0.20160330
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomasz Wegrzanowski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- examples/geometry_problem
|
42
42
|
- examples/kakuro_solver
|
43
43
|
- examples/kinematics_problems
|
44
|
+
- examples/knights_puzzle_solver
|
44
45
|
- examples/letter_connections_solver
|
45
46
|
- examples/light_up_solver
|
46
47
|
- examples/minisudoku_solver
|