gecoder 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/CHANGES +16 -3
  2. data/example/magic_sequence.rb +1 -1
  3. data/example/queens.rb +1 -1
  4. data/example/send_more_money.rb +1 -1
  5. data/example/sudoku.rb +1 -1
  6. data/ext/missing.cpp +18 -4
  7. data/ext/missing.h +8 -0
  8. data/lib/gecoder/bindings.rb +30 -3
  9. data/lib/gecoder/bindings/bindings.rb +22 -0
  10. data/lib/gecoder/interface/binding_changes.rb +81 -107
  11. data/lib/gecoder/interface/branch.rb +65 -14
  12. data/lib/gecoder/interface/constraints.rb +1 -0
  13. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +16 -12
  14. data/lib/gecoder/interface/constraints/int/arithmetic.rb +7 -3
  15. data/lib/gecoder/interface/constraints/int/linear.rb +19 -16
  16. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +8 -4
  17. data/lib/gecoder/interface/constraints/int_enum/channel.rb +14 -6
  18. data/lib/gecoder/interface/constraints/int_enum/element.rb +7 -5
  19. data/lib/gecoder/interface/constraints/int_enum/sort.rb +1 -4
  20. data/lib/gecoder/interface/constraints/set/cardinality.rb +6 -3
  21. data/lib/gecoder/interface/constraints/set/connection.rb +136 -0
  22. data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
  23. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +61 -0
  24. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +32 -0
  25. data/lib/gecoder/interface/constraints/set_var_constraints.rb +1 -0
  26. data/lib/gecoder/interface/enum_wrapper.rb +12 -3
  27. data/lib/gecoder/interface/model.rb +77 -56
  28. data/lib/gecoder/interface/search.rb +74 -5
  29. data/lib/gecoder/interface/variables.rb +117 -15
  30. data/lib/gecoder/version.rb +1 -1
  31. data/specs/binding_changes.rb +9 -5
  32. data/specs/bool_var.rb +8 -12
  33. data/specs/branch.rb +85 -19
  34. data/specs/constraints/arithmetic.rb +99 -71
  35. data/specs/constraints/bool_enum.rb +26 -18
  36. data/specs/constraints/boolean.rb +53 -49
  37. data/specs/constraints/cardinality.rb +33 -26
  38. data/specs/constraints/channel.rb +77 -6
  39. data/specs/constraints/connection.rb +352 -0
  40. data/specs/constraints/constraints.rb +10 -1
  41. data/specs/constraints/count.rb +79 -39
  42. data/specs/constraints/distinct.rb +128 -9
  43. data/specs/constraints/element.rb +26 -19
  44. data/specs/constraints/equality.rb +2 -1
  45. data/specs/constraints/int_domain.rb +19 -12
  46. data/specs/constraints/int_relation.rb +12 -6
  47. data/specs/constraints/linear.rb +30 -30
  48. data/specs/constraints/reification_sugar.rb +8 -4
  49. data/specs/constraints/set_domain.rb +24 -18
  50. data/specs/constraints/set_relation.rb +38 -23
  51. data/specs/constraints/sort.rb +12 -10
  52. data/specs/enum_wrapper.rb +9 -3
  53. data/specs/int_var.rb +8 -4
  54. data/specs/logging.rb +24 -0
  55. data/specs/model.rb +25 -7
  56. data/specs/search.rb +41 -1
  57. data/specs/set_var.rb +36 -7
  58. data/specs/spec_helper.rb +3 -10
  59. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +1 -1
  60. metadata +12 -3
  61. 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, {})
@@ -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
- target = target.bind if target.respond_to? :bind
27
- element = element.bind if element.respond_to? :bind
28
- if reif_var.nil?
29
- Gecode::Raw.should_receive(:count).once.with(@model.active_space,
30
- an_instance_of(Gecode::Raw::IntVarArray),
31
- element, relation, target, strength)
32
- else
33
- Gecode::Raw.should_receive(:count).once.with(@model.active_space,
34
- an_instance_of(Gecode::Raw::IntVarArray),
35
- element, Gecode::Raw::IRT_EQ,
36
- an_instance_of(Gecode::Raw::IntVar), strength)
37
- Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
38
- an_instance_of(Gecode::Raw::IntVar), relation,
39
- target, reif_var.bind, strength)
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, nil denotes that a variable should
54
- # be used.
55
- situations = {
56
- 'variable element and target' => [nil, nil],
57
- 'variable element and constant target' => [nil, 2],
58
- 'constant element and variable target' => [1, nil],
59
- 'constant element and constant target' => [1, 2]
60
- }.each_pair do |description, element_and_target|
61
- element, target = element_and_target
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
- Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
72
- it "should translate negated #{relation} with #{description}" do
73
- element = @element if element.nil?
74
- target = @target if target.nil?
75
- @expect.call(element, type, target, Gecode::Raw::ICL_DEF, nil)
76
- @list.count(element).must_not.send(relation, target)
77
- @model.solve!
78
- end
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