z3 0.0.20160323 → 0.0.20160330

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ec7feb43474477a1c3a7220fbbd5c6e11246cd2
4
- data.tar.gz: 687aedb2c8aaeca944108d4361459bba5ba08eb5
3
+ metadata.gz: 9b616eadc04d3acebed002b5e30969543ec87288
4
+ data.tar.gz: 51b12ceac3ca413e11d445c21524aa709e0d0c86
5
5
  SHA512:
6
- metadata.gz: 9e641cf575e0810de111a96f394747b1316dc2f9cebd63c7a52390c2439c7836abf1660d67b52998f5e4a048fea74a569121e7f9fd9e4a2e32bce82367082362
7
- data.tar.gz: 9d1c79300d21645a5ed1e121a8f069fd0a4504c5731ff07c5e5f6a6727647c94ae64fb885c4f4e5bfb2b4641183b2e697f8128d3f66f784cdc9ab6dcce3361fe
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.20160323
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-23 00:00:00.000000000 Z
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