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