gecoder 0.5.0 → 0.6.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.
- data/CHANGES +16 -3
- data/example/magic_sequence.rb +1 -1
- data/example/queens.rb +1 -1
- data/example/send_more_money.rb +1 -1
- data/example/sudoku.rb +1 -1
- data/ext/missing.cpp +18 -4
- data/ext/missing.h +8 -0
- data/lib/gecoder/bindings.rb +30 -3
- data/lib/gecoder/bindings/bindings.rb +22 -0
- data/lib/gecoder/interface/binding_changes.rb +81 -107
- data/lib/gecoder/interface/branch.rb +65 -14
- data/lib/gecoder/interface/constraints.rb +1 -0
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +16 -12
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +7 -3
- data/lib/gecoder/interface/constraints/int/linear.rb +19 -16
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +8 -4
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +14 -6
- data/lib/gecoder/interface/constraints/int_enum/element.rb +7 -5
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +1 -4
- data/lib/gecoder/interface/constraints/set/cardinality.rb +6 -3
- data/lib/gecoder/interface/constraints/set/connection.rb +136 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +61 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +32 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +1 -0
- data/lib/gecoder/interface/enum_wrapper.rb +12 -3
- data/lib/gecoder/interface/model.rb +77 -56
- data/lib/gecoder/interface/search.rb +74 -5
- data/lib/gecoder/interface/variables.rb +117 -15
- data/lib/gecoder/version.rb +1 -1
- data/specs/binding_changes.rb +9 -5
- data/specs/bool_var.rb +8 -12
- data/specs/branch.rb +85 -19
- data/specs/constraints/arithmetic.rb +99 -71
- data/specs/constraints/bool_enum.rb +26 -18
- data/specs/constraints/boolean.rb +53 -49
- data/specs/constraints/cardinality.rb +33 -26
- data/specs/constraints/channel.rb +77 -6
- data/specs/constraints/connection.rb +352 -0
- data/specs/constraints/constraints.rb +10 -1
- data/specs/constraints/count.rb +79 -39
- data/specs/constraints/distinct.rb +128 -9
- data/specs/constraints/element.rb +26 -19
- data/specs/constraints/equality.rb +2 -1
- data/specs/constraints/int_domain.rb +19 -12
- data/specs/constraints/int_relation.rb +12 -6
- data/specs/constraints/linear.rb +30 -30
- data/specs/constraints/reification_sugar.rb +8 -4
- data/specs/constraints/set_domain.rb +24 -18
- data/specs/constraints/set_relation.rb +38 -23
- data/specs/constraints/sort.rb +12 -10
- data/specs/enum_wrapper.rb +9 -3
- data/specs/int_var.rb +8 -4
- data/specs/logging.rb +24 -0
- data/specs/model.rb +25 -7
- data/specs/search.rb +41 -1
- data/specs/set_var.rb +36 -7
- data/specs/spec_helper.rb +3 -10
- data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +1 -1
- metadata +12 -3
- data/specs/tmp +0 -22
@@ -0,0 +1,352 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
# Requires @expect, @model, @stub, @target.
|
5
|
+
describe 'connection constraint', :shared => true do
|
6
|
+
before do
|
7
|
+
@invoke = lambda do |rhs|
|
8
|
+
@stub.must == rhs
|
9
|
+
@model.solve!
|
10
|
+
end
|
11
|
+
|
12
|
+
# For composite spec.
|
13
|
+
@invoke_relation = lambda do |relation, target, negated|
|
14
|
+
if negated
|
15
|
+
@stub.must_not.send(relation, target)
|
16
|
+
else
|
17
|
+
@stub.must.send(relation, target)
|
18
|
+
end
|
19
|
+
@model.solve!
|
20
|
+
end
|
21
|
+
@expect_relation = lambda do |relation, target, negated|
|
22
|
+
@expect.call(relation, target, Gecode::Raw::ICL_DEF, nil, negated)
|
23
|
+
end
|
24
|
+
|
25
|
+
# For options spec.
|
26
|
+
@invoke_options = lambda do |hash|
|
27
|
+
@stub.must_be.less_than_or_equal_to(17, hash)
|
28
|
+
@model.solve!
|
29
|
+
end
|
30
|
+
@expect_options = lambda do |strength, reif_var|
|
31
|
+
@expect.call(Gecode::Raw::IRT_LQ, 17, strength, reif_var, false)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it_should_behave_like 'constraint with options'
|
36
|
+
it_should_behave_like 'composite constraint'
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Gecode::Constraints::Set::Connection, ' (min)' do
|
40
|
+
before do
|
41
|
+
@model = Gecode::Model.new
|
42
|
+
@set = @model.set_var([], 0..9)
|
43
|
+
@target = @var = @model.int_var(0..10)
|
44
|
+
@model.branch_on @model.wrap_enum([@set])
|
45
|
+
@stub = @set.min
|
46
|
+
|
47
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
48
|
+
@model.allow_space_access do
|
49
|
+
rhs = rhs.bind if rhs.respond_to? :bind
|
50
|
+
if reif_var.nil?
|
51
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
52
|
+
rhs.kind_of? Gecode::Raw::IntVar
|
53
|
+
Gecode::Raw.should_receive(:min).once.with(
|
54
|
+
an_instance_of(Gecode::Raw::Space), @set.bind, rhs)
|
55
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
56
|
+
else
|
57
|
+
Gecode::Raw.should_receive(:min).once.with(
|
58
|
+
an_instance_of(Gecode::Raw::Space), @set.bind,
|
59
|
+
an_instance_of(Gecode::Raw::IntVar))
|
60
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
61
|
+
an_instance_of(Gecode::Raw::Space),
|
62
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
63
|
+
strength)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
Gecode::Raw.should_receive(:min).once.with(
|
67
|
+
an_instance_of(Gecode::Raw::Space),
|
68
|
+
@set.bind, an_instance_of(Gecode::Raw::IntVar))
|
69
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
70
|
+
an_instance_of(Gecode::Raw::Space),
|
71
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs, reif_var.bind,
|
72
|
+
strength)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should constrain the min of a set' do
|
79
|
+
@set.min.must == @var
|
80
|
+
@model.solve!
|
81
|
+
@set.lower_bound.min.should == @var.value
|
82
|
+
end
|
83
|
+
|
84
|
+
it_should_behave_like 'connection constraint'
|
85
|
+
end
|
86
|
+
|
87
|
+
describe Gecode::Constraints::Set::Connection, ' (max)' do
|
88
|
+
before do
|
89
|
+
@model = Gecode::Model.new
|
90
|
+
@set = @model.set_var([], 0..9)
|
91
|
+
@target = @var = @model.int_var(0..10)
|
92
|
+
@model.branch_on @model.wrap_enum([@set])
|
93
|
+
@stub = @set.max
|
94
|
+
|
95
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
96
|
+
@model.allow_space_access do
|
97
|
+
rhs = rhs.bind if rhs.respond_to? :bind
|
98
|
+
if reif_var.nil?
|
99
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
100
|
+
rhs.kind_of? Gecode::Raw::IntVar
|
101
|
+
Gecode::Raw.should_receive(:max).once.with(
|
102
|
+
an_instance_of(Gecode::Raw::Space), @set.bind, rhs)
|
103
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
104
|
+
else
|
105
|
+
Gecode::Raw.should_receive(:max).once.with(
|
106
|
+
an_instance_of(Gecode::Raw::Space), @set.bind,
|
107
|
+
an_instance_of(Gecode::Raw::IntVar))
|
108
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
109
|
+
an_instance_of(Gecode::Raw::Space),
|
110
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
111
|
+
strength)
|
112
|
+
end
|
113
|
+
else
|
114
|
+
Gecode::Raw.should_receive(:max).once.with(
|
115
|
+
an_instance_of(Gecode::Raw::Space),
|
116
|
+
@set.bind, an_instance_of(Gecode::Raw::IntVar))
|
117
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
118
|
+
an_instance_of(Gecode::Raw::Space),
|
119
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs, reif_var.bind,
|
120
|
+
strength)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should constrain the max of a set' do
|
127
|
+
@set.max.must == @var
|
128
|
+
@model.solve!
|
129
|
+
@set.lower_bound.max.should == @var.value
|
130
|
+
end
|
131
|
+
|
132
|
+
it_should_behave_like 'connection constraint'
|
133
|
+
end
|
134
|
+
|
135
|
+
describe Gecode::Constraints::Set::Connection, ' (sum)' do
|
136
|
+
before do
|
137
|
+
@model = Gecode::Model.new
|
138
|
+
@set = @model.set_var([], 0..9)
|
139
|
+
@target = @var = @model.int_var(0..20)
|
140
|
+
@model.branch_on @model.wrap_enum([@set])
|
141
|
+
@stub = @set.sum
|
142
|
+
|
143
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
144
|
+
@model.allow_space_access do
|
145
|
+
rhs = rhs.bind if rhs.respond_to? :bind
|
146
|
+
if reif_var.nil?
|
147
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
148
|
+
rhs.kind_of? Gecode::Raw::IntVar
|
149
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
150
|
+
an_instance_of(Gecode::Raw::Space), anything, anything, @set.bind,
|
151
|
+
rhs)
|
152
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
153
|
+
else
|
154
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
155
|
+
an_instance_of(Gecode::Raw::Space), anything, anything, @set.bind,
|
156
|
+
an_instance_of(Gecode::Raw::IntVar))
|
157
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
158
|
+
an_instance_of(Gecode::Raw::Space),
|
159
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
160
|
+
strength)
|
161
|
+
end
|
162
|
+
else
|
163
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
164
|
+
an_instance_of(Gecode::Raw::Space),
|
165
|
+
anything, anything, @set.bind, an_instance_of(Gecode::Raw::IntVar))
|
166
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
167
|
+
an_instance_of(Gecode::Raw::Space),
|
168
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs, reif_var.bind,
|
169
|
+
strength)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should constrain the sum of a set' do
|
176
|
+
@set.sum.must == @var
|
177
|
+
@model.solve!.should_not be_nil
|
178
|
+
@set.value.inject(0){ |x, y| x + y }.should == @var.value
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should raise error if unsupported options is given' do
|
182
|
+
lambda do
|
183
|
+
@set.sum(:does_not_exist => :foo).must == @var
|
184
|
+
end.should raise_error(ArgumentError)
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'should raise error if multiple options are given' do
|
188
|
+
lambda do
|
189
|
+
@set.sum(:weights => {}, :substitutions => {}).must == @var
|
190
|
+
end.should raise_error(ArgumentError)
|
191
|
+
end
|
192
|
+
|
193
|
+
it_should_behave_like 'connection constraint'
|
194
|
+
end
|
195
|
+
|
196
|
+
describe Gecode::Constraints::Set::Connection, ' (sum with weights)' do
|
197
|
+
before do
|
198
|
+
@model = Gecode::Model.new
|
199
|
+
@set = @model.set_var([], 0..9)
|
200
|
+
@target = @var = @model.int_var(-20..20)
|
201
|
+
@model.branch_on @model.wrap_enum([@set])
|
202
|
+
@weights = Hash[*(0..9).zip((-9..-0).to_a.reverse).flatten]
|
203
|
+
@stub = @set.sum(:weights => @weights)
|
204
|
+
|
205
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
206
|
+
@model.allow_space_access do
|
207
|
+
rhs = rhs.bind if rhs.respond_to? :bind
|
208
|
+
if reif_var.nil?
|
209
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
210
|
+
rhs.kind_of? Gecode::Raw::IntVar
|
211
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
212
|
+
an_instance_of(Gecode::Raw::Space), anything, anything, @set.bind, rhs)
|
213
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
214
|
+
else
|
215
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
216
|
+
an_instance_of(Gecode::Raw::Space), anything, anything, @set.bind,
|
217
|
+
an_instance_of(Gecode::Raw::IntVar))
|
218
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
219
|
+
an_instance_of(Gecode::Raw::Space),
|
220
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
221
|
+
strength)
|
222
|
+
end
|
223
|
+
else
|
224
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
225
|
+
an_instance_of(Gecode::Raw::Space),
|
226
|
+
anything, anything, @set.bind, an_instance_of(Gecode::Raw::IntVar))
|
227
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
228
|
+
an_instance_of(Gecode::Raw::Space),
|
229
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs, reif_var.bind,
|
230
|
+
strength)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'should constrain the sum of a set' do
|
237
|
+
@stub.must_be.in(-10..-1)
|
238
|
+
@model.solve!.should_not be_nil
|
239
|
+
weighted_sum = @set.value.inject(0){ |sum, x| sum - x**2 }
|
240
|
+
weighted_sum.should >= -10
|
241
|
+
weighted_sum.should <= -1
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should remove any elements not in the weight hash' do
|
245
|
+
@set.sum(:weights => {}).must_be == 0
|
246
|
+
@model.solve!.should_not be_nil
|
247
|
+
@set.value.size.should be_zero
|
248
|
+
end
|
249
|
+
|
250
|
+
it_should_behave_like 'connection constraint'
|
251
|
+
end
|
252
|
+
|
253
|
+
describe Gecode::Constraints::Set::Connection, ' (sum with substitutions)' do
|
254
|
+
before do
|
255
|
+
@model = Gecode::Model.new
|
256
|
+
@set = @model.set_var([], 0..9)
|
257
|
+
@target = @var = @model.int_var(-20..20)
|
258
|
+
@model.branch_on @model.wrap_enum([@set])
|
259
|
+
@subs = Hash[*(0..9).zip((-9..-0).to_a.reverse).flatten]
|
260
|
+
@stub = @set.sum(:substitutions => @subs)
|
261
|
+
|
262
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
263
|
+
@model.allow_space_access do
|
264
|
+
rhs = rhs.bind if rhs.respond_to? :bind
|
265
|
+
if reif_var.nil?
|
266
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
267
|
+
rhs.kind_of? Gecode::Raw::IntVar
|
268
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
269
|
+
an_instance_of(Gecode::Raw::Space), anything, anything, @set.bind, rhs)
|
270
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
271
|
+
else
|
272
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
273
|
+
an_instance_of(Gecode::Raw::Space), anything, anything, @set.bind,
|
274
|
+
an_instance_of(Gecode::Raw::IntVar))
|
275
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
276
|
+
an_instance_of(Gecode::Raw::Space),
|
277
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
278
|
+
strength)
|
279
|
+
end
|
280
|
+
else
|
281
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
282
|
+
an_instance_of(Gecode::Raw::Space),
|
283
|
+
anything, anything, @set.bind, an_instance_of(Gecode::Raw::IntVar))
|
284
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
285
|
+
an_instance_of(Gecode::Raw::Space),
|
286
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs, reif_var.bind,
|
287
|
+
strength)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'should constrain the sum of a set' do
|
294
|
+
@stub.must_be.in(-10..-1)
|
295
|
+
@model.solve!.should_not be_nil
|
296
|
+
substituted_sum = @set.value.inject{ |sum, x| sum + @subs[x] }
|
297
|
+
substituted_sum.should >= -10
|
298
|
+
substituted_sum.should <= -1
|
299
|
+
end
|
300
|
+
|
301
|
+
it_should_behave_like 'connection constraint'
|
302
|
+
end
|
303
|
+
|
304
|
+
describe Gecode::Constraints::Set::Connection, ' (include)' do
|
305
|
+
before do
|
306
|
+
@model = Gecode::Model.new
|
307
|
+
@set = @model.set_var([], 2..5)
|
308
|
+
@array = @model.int_var_array(4, 0..9)
|
309
|
+
@array.must_be.distinct
|
310
|
+
@model.branch_on @array
|
311
|
+
#@model.branch_on @model.wrap_enum([@set])
|
312
|
+
|
313
|
+
@expect = lambda do |rhs, strength, reif_var|
|
314
|
+
@model.allow_space_access do
|
315
|
+
Gecode::Raw.should_receive(:match).once.with(
|
316
|
+
an_instance_of(Gecode::Raw::Space),
|
317
|
+
@set.bind, an_instance_of(Gecode::Raw::IntVarArray))
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
@expect_options = lambda do |strength, reif_var|
|
322
|
+
@expect.call(@array, strength, reif_var)
|
323
|
+
end
|
324
|
+
@invoke_options = lambda do |hash|
|
325
|
+
@set.must.include(@array, hash)
|
326
|
+
@model.solve!
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'should translate to a match constraint' do
|
331
|
+
@expect_options.call(Gecode::Raw::ICL_DEF, nil)
|
332
|
+
@set.must.include @array
|
333
|
+
@model.solve!
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'should constrain the variables to be included in the set' do
|
337
|
+
@set.must.include @array
|
338
|
+
@model.solve!.should_not be_nil
|
339
|
+
@array.all?{ |x| @set.lower_bound.include? x.value }.should be_true
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'should raise error if the right hand side is not an array of variables' do
|
343
|
+
lambda{ @set.must.include 'hello' }.should raise_error(TypeError)
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'should raise error if negated' do
|
347
|
+
lambda{ @set.must_not.include @array }.should raise_error(
|
348
|
+
Gecode::MissingConstraintError)
|
349
|
+
end
|
350
|
+
|
351
|
+
it_should_behave_like 'non-reifiable set constraint'
|
352
|
+
end
|
@@ -9,7 +9,7 @@ describe Gecode::Constraints::Expression do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe Gecode::Constraints::IntEnum::Expression do
|
12
|
-
it 'should raise error unless lhs is an enum' do
|
12
|
+
it 'should raise error unless lhs is an int enum' do
|
13
13
|
lambda do
|
14
14
|
Gecode::Constraints::IntEnum::Expression.new(Gecode::Model.new,
|
15
15
|
:lhs => 'foo', :negate => false)
|
@@ -17,6 +17,15 @@ describe Gecode::Constraints::IntEnum::Expression do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
describe Gecode::Constraints::SetEnum::Expression do
|
21
|
+
it 'should raise error unless lhs is a set enum' do
|
22
|
+
lambda do
|
23
|
+
Gecode::Constraints::SetEnum::Expression.new(Gecode::Model.new,
|
24
|
+
:lhs => 'foo', :negate => false)
|
25
|
+
end.should raise_error(TypeError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
20
29
|
describe Gecode::Constraints::Int::CompositeStub, ' (not subclassed)' do
|
21
30
|
before do
|
22
31
|
@con = Gecode::Constraints::Int::CompositeStub.new(Gecode::Model.new, {})
|
data/specs/constraints/count.rb
CHANGED
@@ -23,20 +23,25 @@ describe Gecode::Constraints::IntEnum::Count do
|
|
23
23
|
|
24
24
|
# Creates an expectation corresponding to the specified input.
|
25
25
|
@expect = lambda do |element, relation, target, strength, reif_var|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
26
|
+
@model.allow_space_access do
|
27
|
+
target = target.bind if target.respond_to? :bind
|
28
|
+
element = element.bind if element.respond_to? :bind
|
29
|
+
if reif_var.nil?
|
30
|
+
Gecode::Raw.should_receive(:count).once.with(
|
31
|
+
an_instance_of(Gecode::Raw::Space),
|
32
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
33
|
+
element, relation, target, strength)
|
34
|
+
else
|
35
|
+
Gecode::Raw.should_receive(:count).once.with(
|
36
|
+
an_instance_of(Gecode::Raw::Space),
|
37
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
38
|
+
element, Gecode::Raw::IRT_EQ,
|
39
|
+
an_instance_of(Gecode::Raw::IntVar), strength)
|
40
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
41
|
+
an_instance_of(Gecode::Raw::Space),
|
42
|
+
an_instance_of(Gecode::Raw::IntVar), relation,
|
43
|
+
target, reif_var.bind, strength)
|
44
|
+
end
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
@@ -50,32 +55,67 @@ describe Gecode::Constraints::IntEnum::Count do
|
|
50
55
|
end
|
51
56
|
end
|
52
57
|
|
53
|
-
# Various situations that must be handled
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
|
63
|
-
it "should translate #{relation} with #{description}" do
|
64
|
-
element = @element if element.nil?
|
65
|
-
target = @target if target.nil?
|
66
|
-
@expect.call(element, type, target, Gecode::Raw::ICL_DEF, nil)
|
67
|
-
@list.count(element).must.send(relation, target)
|
68
|
-
@model.solve!
|
69
|
-
end
|
58
|
+
# Various situations that must be handled (4*2 in total). This was originally
|
59
|
+
# written without the repetition (r269), but that interfered with the spec
|
60
|
+
# somehow.
|
61
|
+
|
62
|
+
Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
|
63
|
+
it "should translate #{relation} with variable element and target" do
|
64
|
+
@expect.call(@element, type, @target, Gecode::Raw::ICL_DEF, nil)
|
65
|
+
@list.count(@element).must.send(relation, @target)
|
66
|
+
@model.solve!
|
70
67
|
end
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
68
|
+
end
|
69
|
+
Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
|
70
|
+
it "should translate negated #{relation} with variable element and target" do
|
71
|
+
@expect.call(@element, type, @target, Gecode::Raw::ICL_DEF, nil)
|
72
|
+
@list.count(@element).must_not.send(relation, @target)
|
73
|
+
@model.solve!
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
|
78
|
+
it "should translate #{relation} with variable element and constant target" do
|
79
|
+
@expect.call(@element, type, 2, Gecode::Raw::ICL_DEF, nil)
|
80
|
+
@list.count(@element).must.send(relation, 2)
|
81
|
+
@model.solve!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
|
85
|
+
it "should translate negated #{relation} with variable element and constant target" do
|
86
|
+
@expect.call(@element, type, 2, Gecode::Raw::ICL_DEF, nil)
|
87
|
+
@list.count(@element).must_not.send(relation, 2)
|
88
|
+
@model.solve!
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
|
93
|
+
it "should translate #{relation} with constant element and constant target" do
|
94
|
+
@expect.call(1, type, 2, Gecode::Raw::ICL_DEF, nil)
|
95
|
+
@list.count(1).must.send(relation, 2)
|
96
|
+
@model.solve!
|
97
|
+
end
|
98
|
+
end
|
99
|
+
Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
|
100
|
+
it "should translate negated #{relation} with constant element and constant target" do
|
101
|
+
@expect.call(1, type, 2, Gecode::Raw::ICL_DEF, nil)
|
102
|
+
@list.count(1).must_not.send(relation, 2)
|
103
|
+
@model.solve!
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
|
108
|
+
it "should translate #{relation} with constant element and variable target" do
|
109
|
+
@expect.call(1, type, @target, Gecode::Raw::ICL_DEF, nil)
|
110
|
+
@list.count(1).must.send(relation, @target)
|
111
|
+
@model.solve!
|
112
|
+
end
|
113
|
+
end
|
114
|
+
Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
|
115
|
+
it "should translate negated #{relation} with constant element and variable target" do
|
116
|
+
@expect.call(1, type, @target, Gecode::Raw::ICL_DEF, nil)
|
117
|
+
@list.count(1).must_not.send(relation, @target)
|
118
|
+
@model.solve!
|
79
119
|
end
|
80
120
|
end
|
81
121
|
|