@@ -7,6 +7,12 @@ module Shards
7
7
alias Literal = Int32
8
8
alias Clause = Array (Literal )
9
9
10
+ enum Assignment : Int8
11
+ NOT_SELECTED = 0
12
+ SELECTED = 1
13
+ UNDEFINED = -1
14
+ end
15
+
10
16
def self.from_io (io : IO ) : SAT
11
17
new.tap do |sat |
12
18
while line = io.gets
@@ -65,39 +71,35 @@ module Shards
65
71
end
66
72
end
67
73
68
- protected def assignment_to_s (assignment : Array ( Literal ?) , brief = false )
74
+ protected def assignment_to_s (assignment , brief = false )
69
75
String .build do |str |
70
- assignment.zip(@variables ).compact_map do |(a , v )|
71
- if a == 0
72
- next if brief
73
- str << '~'
76
+ assignment.each_with_index do |a , index |
77
+ if a.selected?
78
+ str << @variables [index] << ' '
79
+ elsif ! brief && a.not_selected?
80
+ str << '~' << @variables [index] << ' ' unless brief
74
81
end
75
- str << v << ' '
76
82
end
77
83
end
78
84
end
79
85
80
- protected def to_assigment (assignment : Array (Literal ?), brief = false )
81
- aa = Array (String ).new(assignment.size)
82
-
83
- assignment.zip(@variables ).each do |(a , v )|
84
- if a == 0
85
- aa << " ~#{ v } " unless brief
86
- else
87
- aa << v
86
+ protected def to_variables (assignment , brief = false )
87
+ assignment.each_with_index.compact_map do |(a , index )|
88
+ if a.selected?
89
+ @variables [index]
90
+ elsif ! brief && a.not_selected?
91
+ " ~#{ @variables [index]} "
88
92
end
89
- end
90
-
91
- aa
93
+ end .to_a
92
94
end
93
95
94
96
# Solves SAT and yields solutions.
95
97
def solve (brief = true , verbose = false ) : Nil
96
98
watchlist = setup_watchlist
97
- assignment = Array (Literal ? ).new(@variables .size) { nil }
99
+ assignment = Array (Assignment ).new(@variables .size) { Assignment :: UNDEFINED }
98
100
99
101
solve(watchlist, assignment, 0 , verbose) do |solution |
100
- yield to_assigment (solution, brief)
102
+ yield to_variables (solution, brief)
101
103
end
102
104
end
103
105
@@ -130,10 +132,10 @@ module Shards
130
132
131
133
# set the bit indicating a has been tried for d:
132
134
state[d] |= 1 << a
133
- assignment[d] = a
135
+ assignment[d] = Assignment .from_value(a)
134
136
135
137
if ! update_watchlist(watchlist, (d << 1 ) | a, assignment, verbose)
136
- assignment[d] = nil
138
+ assignment[d] = Assignment :: UNDEFINED
137
139
else
138
140
d += 1
139
141
break
@@ -149,7 +151,7 @@ module Shards
149
151
150
152
# backtrack:
151
153
state[d] = 0
152
- assignment[d] = nil
154
+ assignment[d] = Assignment :: UNDEFINED
153
155
d -= 1
154
156
end
155
157
end
@@ -183,7 +185,7 @@ module Shards
183
185
a = alternative & 1
184
186
av = assignment[v]
185
187
186
- if av.nil ? || av == a ^ 1
188
+ if av.undefined ? || av.value == a ^ 1
187
189
found_alternative = true
188
190
watchlist[false_literal].shift?
189
191
watchlist[alternative] << clause
0 commit comments