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
@@ -0,0 +1,443 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ # Every property should have a spec that specs the following:
4
+ #
5
+ # * An example where the property is used to constrain a sample problem.
6
+ # * should_behave_like foo operand
7
+ # * A test that the property is translated to the correct Gecode
8
+ # constraint if deemed necessary.
9
+
10
+ # Several of these shared specs requires one or more of the following instance
11
+ # variables to be used:
12
+ # [@operand] The operand that is being tested.
13
+ # [@model] The model that defines the context in which the test is
14
+ # conducted.
15
+ # [@property_types] An array of symbols signaling what types of
16
+ # arguments @select_property accepts. The symbols
17
+ # must be one of: :int, :bool, :set, :int_enum,
18
+ # :bool_enum, :set_enum, :fixnum_enum.
19
+ # [@select_property] A proc that selects the property under test. It
20
+ # should take at least one argument: the operand that
21
+ # the property should be selected from.
22
+ # [@selected_property] The resulting operand of the property. It should
23
+ # be constrained to the degree that it has a
24
+ # non-maximal domain.
25
+ # [@constraint_class] The class of the constraints that are expected to be
26
+ # produced when a constraint is short circuited.
27
+ #
28
+
29
+
30
+ # Requires @operand and @model.
31
+ describe 'int var operand', :shared => true do
32
+ it 'should implement #model' do
33
+ @operand.model.should be_kind_of(Gecode::Model)
34
+ end
35
+
36
+ it 'should implement #to_int_var' do
37
+ int_var = @operand.to_int_var
38
+ int_var.should be_kind_of(Gecode::IntVar)
39
+ @model.solve!
40
+ (int_var.min..int_var.max).should_not equal(Gecode::Model::LARGEST_INT_DOMAIN)
41
+ end
42
+
43
+ it 'should implement #must' do
44
+ receiver = @operand.must
45
+ receiver.should be_kind_of(
46
+ Gecode::Int::IntConstraintReceiver)
47
+ end
48
+ end
49
+
50
+ # Requires @operand and @model.
51
+ describe 'bool var operand', :shared => true do
52
+ it 'should implement #model' do
53
+ @operand.model.should be_kind_of(Gecode::Model)
54
+ end
55
+
56
+ it 'should implement #to_bool_var' do
57
+ bool_var = @operand.to_bool_var
58
+ bool_var.should be_kind_of(Gecode::BoolVar)
59
+ end
60
+
61
+ it 'should implement #must' do
62
+ receiver = @operand.must
63
+ receiver.should be_kind_of(
64
+ Gecode::Bool::BoolConstraintReceiver)
65
+ end
66
+ end
67
+
68
+ # Requires @operand and @model.
69
+ describe 'set var operand', :shared => true do
70
+ it 'should implement #model' do
71
+ @operand.model.should be_kind_of(Gecode::Model)
72
+ end
73
+
74
+ it 'should implement #to_set_var' do
75
+ set_var = @operand.to_set_var
76
+ set_var.should be_kind_of(Gecode::SetVar)
77
+ @model.solve!
78
+ ((set_var.lower_bound == []) &&
79
+ (set_var.upper_bound == Gecode::Model::LARGEST_SET_BOUND)).should_not(
80
+ be_true)
81
+ end
82
+
83
+ it 'should implement #must' do
84
+ receiver = @operand.must
85
+ receiver.should be_kind_of(
86
+ Gecode::Set::SetConstraintReceiver)
87
+ end
88
+ end
89
+
90
+ # Requires @model, @property_types and @select_property.
91
+ describe 'property that produces operand', :shared => true do
92
+ it 'should raise errors if parameters of the incorrect type are given' do
93
+ operands, variables = produce_general_arguments(@property_types)
94
+ (1...operands.size).each do |i|
95
+ bogus_operands = operands.clone
96
+ bogus_operands[i] = Object.new
97
+ lambda do
98
+ @select_property.call(*bogus_operands)
99
+ end.should raise_error(TypeError)
100
+ end
101
+ end
102
+ end
103
+
104
+ # Requires @model, @property_types and @select_property.
105
+ describe 'property that produces int operand', :shared => true do
106
+ it 'should produce int operand' do
107
+ operands, variables = produce_general_arguments(@property_types)
108
+ operand = @select_property.call(*operands)
109
+
110
+ # Test the same invariants as in the test for int var operands.
111
+ operand.model.should be_kind_of(Gecode::Model)
112
+
113
+ int_var = operand.to_int_var
114
+ int_var.should be_kind_of(Gecode::IntVar)
115
+
116
+ receiver = operand.must
117
+ receiver.should be_kind_of(
118
+ Gecode::Int::IntConstraintReceiver)
119
+ end
120
+
121
+ it_should_behave_like 'property that produces operand'
122
+ end
123
+
124
+ # Requires @model, @property_types and @select_property.
125
+ describe 'property that produces bool operand', :shared => true do
126
+ it 'should produce bool operand' do
127
+ operands, variables = produce_general_arguments(@property_types)
128
+ operand = @select_property.call(*operands)
129
+
130
+ # Test the same invariants as in the test for bool var operands.
131
+ operand.model.should be_kind_of(Gecode::Model)
132
+
133
+ bool_var = operand.to_bool_var
134
+ bool_var.should be_kind_of(Gecode::BoolVar)
135
+
136
+ receiver = operand.must
137
+ receiver.should be_kind_of(
138
+ Gecode::Bool::BoolConstraintReceiver)
139
+ end
140
+
141
+ it_should_behave_like 'property that produces operand'
142
+ end
143
+
144
+ # Requires @model, @property_types and @select_property.
145
+ describe 'property that produces set operand', :shared => true do
146
+ it 'should produce set operand' do
147
+ operands, variables = produce_general_arguments(@property_types)
148
+ operand = @select_property.call(*operands)
149
+
150
+ # Test the same invariants as in the test for int var operands.
151
+ operand.model.should be_kind_of(Gecode::Model)
152
+
153
+ set_var = operand.to_set_var
154
+ set_var.should be_kind_of(Gecode::SetVar)
155
+
156
+ receiver = operand.must
157
+ receiver.should be_kind_of(
158
+ Gecode::Set::SetConstraintReceiver)
159
+ end
160
+
161
+ it_should_behave_like 'property that produces operand'
162
+ end
163
+
164
+ # Requires @model, @constraint_class, @property_types, @select_property and
165
+ # @selected_property.
166
+ #
167
+ # These properties should only short circuit equality when there is no
168
+ # negation nor reification and the right hand side is an int operand.
169
+ describe 'property that produces int operand by short circuiting equality', :shared => true do
170
+ it 'should produce constraints when short circuited' do
171
+ @constraint_class.superclass.should == Gecode::Constraint
172
+ end
173
+
174
+ it 'should give the same solution regardless of whether short circuit was used' do
175
+ int_operand = @selected_property
176
+ direct_int_var = int_operand.to_int_var
177
+ indirect_int_op, _ = general_int_operand(@model)
178
+ @selected_property.must == indirect_int_op
179
+ @model.solve!
180
+
181
+ direct_int_var.should_not have_domain(Gecode::Model::LARGEST_INT_DOMAIN)
182
+ direct_int_var.should have_domain(indirect_int_op.domain)
183
+ end
184
+
185
+ it 'should short circuit equality' do
186
+ (@selected_property.must == @model.int_var).should(
187
+ be_kind_of(@constraint_class))
188
+ end
189
+
190
+ it 'should not short circuit when negation is used' do
191
+ (@selected_property.must_not == @model.int_var).should_not(
192
+ be_kind_of(@constraint_class))
193
+ end
194
+
195
+ it 'should not short circuit when reification is used' do
196
+ @selected_property.must.equal(@model.int_var,
197
+ :reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
198
+ end
199
+
200
+ it 'should not short circuit when the right hand side is not a operand' do
201
+ @selected_property.must.equal(2).should_not(be_kind_of(@constraint_class))
202
+ end
203
+
204
+ it 'should not short circuit when equality is not used' do
205
+ (@selected_property.must > @model.int_var).should_not(
206
+ be_kind_of(@constraint_class))
207
+ end
208
+
209
+ it 'should raise error when the right hand side is of illegal type' do
210
+ lambda do
211
+ @selected_property.must == 'foo'
212
+ end.should raise_error(TypeError)
213
+ end
214
+
215
+ it_should_behave_like 'property that produces int operand'
216
+ end
217
+
218
+ # Requires @model, @constraint_class, @property_types, @select_property and
219
+ # @selected_property.
220
+ #
221
+ # These properties should only short circuit equality when there is no
222
+ # negation nor reification and the right hand side is a bool operand.
223
+ describe 'property that produces bool operand by short circuiting equality', :shared => true do
224
+ it 'should produce constraints when short circuited' do
225
+ @constraint_class.superclass.should == Gecode::Constraint
226
+ end
227
+
228
+ it 'should give the same solution regardless of whether short circuit was used' do
229
+ bool_operand = @selected_property
230
+ direct_bool_var = bool_operand.to_bool_var
231
+ indirect_bool_var = @model.bool_var
232
+ @selected_property.must == indirect_bool_var
233
+ @model.solve!
234
+
235
+ direct_bool_var.value.should == indirect_bool_var.value
236
+ end
237
+
238
+ it 'should short circuit equality' do
239
+ (@selected_property.must == @model.bool_var).should(
240
+ be_kind_of(@constraint_class))
241
+ end
242
+
243
+ it 'should not short circuit when negation is used' do
244
+ (@selected_property.must_not == @model.bool_var).should_not(
245
+ be_kind_of(@constraint_class))
246
+ end
247
+
248
+ it 'should not short circuit when reification is used' do
249
+ @selected_property.must.equal(@model.bool_var,
250
+ :reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
251
+ end
252
+
253
+ it 'should not short circuit when equality is not used' do
254
+ (@selected_property.must.imply @model.bool_var).should_not(
255
+ be_kind_of(@constraint_class))
256
+ end
257
+
258
+ it 'should raise error when the right hand side is of illegal type' do
259
+ lambda do
260
+ @selected_property.must == 'foo'
261
+ end.should raise_error(TypeError)
262
+ end
263
+
264
+ it_should_behave_like 'property that produces bool operand'
265
+ end
266
+
267
+ # Requires @model, @constraint_class, @property_types and @select_property.
268
+ #
269
+ # These properties should short circuit all comparison relations
270
+ # even when negated and when fixnums are used as right hand side.
271
+ describe 'property that produces int operand by short circuiting relations', :shared => true do
272
+ it 'should produce reifiable constraints when short circuited' do
273
+ @constraint_class.superclass.should ==
274
+ Gecode::ReifiableConstraint
275
+ end
276
+
277
+ Gecode::Util::RELATION_TYPES.keys.each do |relation|
278
+ it "should give the same solution regardless of whether short circuit #{relation} was used" do
279
+ direct_int_var = @model.int_var
280
+ @selected_property.to_int_var.must.method(relation).call direct_int_var
281
+ indirect_int_var = @model.int_var
282
+ @selected_property.must.method(relation).call indirect_int_var
283
+ @model.solve!
284
+
285
+ direct_int_var.should_not have_domain(Gecode::Model::LARGEST_INT_DOMAIN)
286
+ direct_int_var.should have_domain(indirect_int_var.domain)
287
+ end
288
+
289
+ it "should short circuit #{relation}" do
290
+ (@selected_property.must.method(relation).call @model.int_var).should(
291
+ be_kind_of(@constraint_class))
292
+ end
293
+
294
+ it "should short circuit negated #{relation}" do
295
+ (@selected_property.must_not.method(relation).call @model.int_var).should(
296
+ be_kind_of(@constraint_class))
297
+ end
298
+
299
+ it "should short circuit #{relation} when reification is used" do
300
+ (@selected_property.must.method(relation).call(@model.int_var,
301
+ :reify => @model.bool_var)).should(be_kind_of(@constraint_class))
302
+ end
303
+
304
+ it "should short circuit #{relation} even when the right hand side is a fixnum" do
305
+ (@selected_property.must.method(relation).call 2).should(
306
+ be_kind_of(@constraint_class))
307
+ end
308
+
309
+ it "should raise error when the #{relation} right hand side is of illegal type" do
310
+ lambda do
311
+ @selected_property.must.method(relation).call('foo')
312
+ end.should raise_error(TypeError)
313
+ end
314
+ end
315
+
316
+ it_should_behave_like 'property that produces int operand'
317
+ end
318
+
319
+ # Requires @model, @constraint_class, @property_types, @select_property and
320
+ # @selected_property.
321
+ #
322
+ # These properties should only short circuit equality when there is no
323
+ # negation nor reification and the right hand side is a set operand.
324
+ describe 'property that produces set operand by short circuiting equality', :shared => true do
325
+ it 'should produce constraints when short circuited' do
326
+ @constraint_class.superclass.should == Gecode::Constraint
327
+ end
328
+
329
+ it 'should give the same solution regardless of whether short circuit was used' do
330
+ set_operand = @selected_property
331
+ direct_set_var = set_operand.to_set_var
332
+ indirect_set_var = @model.set_var
333
+ @selected_property.must == indirect_set_var
334
+ @model.solve!
335
+
336
+ direct_set_var.should have_bounds(indirect_set_var.lower_bound,
337
+ indirect_set_var.upper_bound)
338
+ end
339
+
340
+ it 'should short circuit equality' do
341
+ (@selected_property.must == @model.set_var).should(
342
+ be_kind_of(@constraint_class))
343
+ end
344
+
345
+ it 'should not short circuit when negation is used' do
346
+ (@selected_property.must_not == @model.set_var).should_not(
347
+ be_kind_of(@constraint_class))
348
+ end
349
+
350
+ it 'should not short circuit when reification is used' do
351
+ (@selected_property.must.equal(@model.set_var,
352
+ :reify => @model.bool_var)).should_not(be_kind_of(@constraint_class))
353
+ end
354
+
355
+ it 'should not short circuit when the right hand side is not a operand' do
356
+ (@selected_property.must == [1,3,5]).should_not(
357
+ be_kind_of(@constraint_class))
358
+ end
359
+
360
+ it 'should not short circuit when equality is not used' do
361
+ (@selected_property.must_be.subset_of(@model.set_var)).should_not(
362
+ be_kind_of(@constraint_class))
363
+ end
364
+
365
+ it 'should raise error when the right hand side is of illegal type' do
366
+ lambda do
367
+ @selected_property.must == 'foo'
368
+ end.should raise_error(TypeError)
369
+ end
370
+
371
+ it_should_behave_like 'property that produces set operand'
372
+ end
373
+
374
+ # Requires @model, @constraint_class, @property_types and @select_property.
375
+ #
376
+ # These properties should only short circuit set relations when neither
377
+ # negation nor reification is used (both for constant sets and set
378
+ # variables).
379
+ describe 'property that produces set operand by short circuiting set relations', :shared => true do
380
+ Gecode::Util::SET_RELATION_TYPES.keys.each do |relation|
381
+ it 'should produce constraints when short circuited' do
382
+ @constraint_class.superclass.should == Gecode::Constraint
383
+ end
384
+
385
+ it "should give the same solution regardless of whether short circuit #{relation} was used" do
386
+ if relation == :complement
387
+ direct_set_var, indirect_set_var = Array.new(2){ @model.set_var }
388
+ else
389
+ direct_set_var, indirect_set_var = Array.new(2) do
390
+ @model.set_var([], -1000..1000)
391
+ end
392
+ end
393
+
394
+ @selected_property.to_set_var.must.method(relation).call direct_set_var
395
+ @selected_property.must.method(relation).call indirect_set_var
396
+ @model.solve!
397
+
398
+ if relation == :complement
399
+ direct_set_var.upper_bound.min.should ==
400
+ indirect_set_var.upper_bound.min
401
+ direct_set_var.upper_bound.max.should ==
402
+ indirect_set_var.upper_bound.max
403
+ direct_set_var.lower_bound.min.should ==
404
+ indirect_set_var.lower_bound.min
405
+ direct_set_var.lower_bound.max.should ==
406
+ indirect_set_var.lower_bound.max
407
+ direct_set_var.lower_bound.size.should ==
408
+ indirect_set_var.lower_bound.size
409
+ else
410
+ direct_set_var.should have_bounds(indirect_set_var.lower_bound,
411
+ indirect_set_var.upper_bound)
412
+ end
413
+ end
414
+
415
+ it "should short circuit #{relation}" do
416
+ @selected_property.must.method(relation).call(@model.set_var).should(
417
+ be_kind_of(@constraint_class))
418
+ end
419
+
420
+ it "should not short circuit negated #{relation}" do
421
+ @selected_property.must_not.method(relation).call(
422
+ @model.set_var).should_not(be_kind_of(@constraint_class))
423
+ end
424
+
425
+ it "should not short circuit reified #{relation}" do
426
+ @selected_property.must.method(relation).call(@model.set_var,
427
+ :reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
428
+ end
429
+
430
+ it "should short circuit #{relation} even when the right hand side is a constant set" do
431
+ @selected_property.must.method(relation).call([1, 2, 3]).should(
432
+ be_kind_of(@constraint_class))
433
+ end
434
+
435
+ it "should raise error when the #{relation} right hand side is of illegal type" do
436
+ lambda do
437
+ @selected_property.must.method(relation).call('foo')
438
+ end.should raise_error(TypeError)
439
+ end
440
+ end
441
+
442
+ it_should_behave_like 'property that produces set operand'
443
+ end
@@ -13,7 +13,7 @@ class ReifSugarSampleProblem < Gecode::Model
13
13
  end
14
14
  end
15
15
 
16
- describe Gecode::Constraints::ReifiableConstraint do
16
+ describe Gecode::ReifiableConstraint do
17
17
  before do
18
18
  @model = ReifSugarSampleProblem.new
19
19
  @x = @model.x
@@ -23,7 +23,7 @@ describe Gecode::Constraints::ReifiableConstraint do
23
23
 
24
24
  it 'should fail disjunctions if neither side can be satisfied' do
25
25
  (@x.must == 3) | (@y.must == 3)
26
- @model.solve!.should be_nil
26
+ lambda{ @model.solve! }.should raise_error(Gecode::NoSolutionError)
27
27
  end
28
28
 
29
29
  it 'should solve disjunctions' do
@@ -35,7 +35,7 @@ describe Gecode::Constraints::ReifiableConstraint do
35
35
 
36
36
  it 'should fail conjunctions if one side can\'t be satisfied' do
37
37
  (@x.must > 3) & (@y.must == 3)
38
- @model.solve!.should be_nil
38
+ lambda{ @model.solve! }.should raise_error(Gecode::NoSolutionError)
39
39
  end
40
40
 
41
41
  it 'should solve conjunctions' do
@@ -64,7 +64,6 @@ describe Gecode::Constraints::ReifiableConstraint do
64
64
 
65
65
  it 'should handle negations' do
66
66
  (@z.must_not == 4) & (@z.must == 4)
67
- sol = @model.solve!
68
- sol.should be_nil
67
+ lambda{ @model.solve! }.should raise_error(Gecode::NoSolutionError)
69
68
  end
70
69
  end