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.
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