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,185 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/constraint_helper'
3
-
4
- describe Gecode::Constraints::Set::Domain do
5
- include GecodeR::Specs::SetHelper
6
-
7
- before do
8
- @model = Gecode::Model.new
9
- @glb = [0]
10
- @lub = 0..3
11
- @set = @model.set_var(@glb, @lub)
12
- @range = 0..1
13
- @non_range = [0, 2]
14
- @singleton = 0
15
-
16
- @expect = lambda do |relation_type, rhs, reif_var, negated|
17
- @model.allow_space_access do
18
- if reif_var.nil? and !negated
19
- Gecode::Raw.should_receive(:dom).once.with(
20
- an_instance_of(Gecode::Raw::Space),
21
- an_instance_of(Gecode::Raw::SetVar), relation_type,
22
- *expect_constant_set(rhs))
23
- else
24
- params = [an_instance_of(Gecode::Raw::Space),
25
- an_instance_of(Gecode::Raw::SetVar), relation_type]
26
- params << expect_constant_set(rhs)
27
- params << an_instance_of(Gecode::Raw::BoolVar)
28
- Gecode::Raw.should_receive(:dom).once.with(*params.flatten)
29
- end
30
- end
31
- end
32
-
33
- # For options spec.
34
- @invoke_options = lambda do |hash|
35
- @set.must_be.superset_of(@non_range, hash)
36
- @model.solve!
37
- end
38
- @expect_options = option_expectation do |strength, kind, reif_var|
39
- @expect.call(Gecode::Raw::SRT_SUP, @non_range, reif_var, false)
40
- end
41
- end
42
-
43
- Gecode::Constraints::Util::SET_RELATION_TYPES.each_pair do |relation, type|
44
- next if relation == :==
45
-
46
- it "should translate #{relation} with constant range to domain constraint" do
47
- @expect.call(type, @range, nil, false)
48
- @set.must.send(relation, @range)
49
- @model.solve!
50
- end
51
-
52
- it "should translate #{relation} with constant non-range to domain constraint" do
53
- @expect.call(type, @non_range, nil, false)
54
- @set.must.send(relation, @non_range)
55
- @model.solve!
56
- end
57
-
58
- it "should translate #{relation} with constant singleton to domain constraint" do
59
- @expect.call(type, @singleton, nil, false)
60
- @set.must.send(relation, @singleton)
61
- @model.solve!
62
- end
63
-
64
- it "should translate negated #{relation} with constant range to domain constraint" do
65
- @expect.call(type, @range, nil, true)
66
- @set.must_not.send(relation, @range)
67
- @model.solve!
68
- end
69
-
70
- it "should translate negated #{relation} with constant non-range to domain constraint" do
71
- @expect.call(type, @non_range, nil, true)
72
- @set.must_not.send(relation, @non_range)
73
- @model.solve!
74
- end
75
-
76
- it "should translate negated #{relation} with constant singleton to domain constraint" do
77
- @expect.call(type, @singleton, nil, true)
78
- @set.must_not.send(relation, @singleton)
79
- @model.solve!
80
- end
81
- end
82
-
83
- it 'should raise error if the right hand side is not a constant set' do
84
- lambda do
85
- @set.must_be.superset_of('not a constant set')
86
- end.should raise_error(TypeError)
87
- end
88
-
89
- it_should_behave_like 'reifiable set constraint'
90
- end
91
-
92
- describe Gecode::Constraints::Set::Domain, ' (equality)' do
93
- include GecodeR::Specs::SetHelper
94
-
95
- before do
96
- @model = Gecode::Model.new
97
- @glb = [0]
98
- @lub = 0..3
99
- @set = @model.set_var(@glb, @lub)
100
- @range = 0..1
101
- @non_range = [0, 2]
102
- @singleton = 0
103
- @model.branch_on @model.wrap_enum([@set])
104
-
105
- @expect = lambda do |relation_type, rhs, reif_var|
106
- @model.allow_space_access do
107
- if reif_var.nil?
108
- Gecode::Raw.should_receive(:dom).once.with(
109
- an_instance_of(Gecode::Raw::Space),
110
- an_instance_of(Gecode::Raw::SetVar), relation_type,
111
- *expect_constant_set(rhs))
112
- else
113
- params = [an_instance_of(Gecode::Raw::Space),
114
- an_instance_of(Gecode::Raw::SetVar), relation_type]
115
- params << expect_constant_set(rhs)
116
- params << an_instance_of(Gecode::Raw::BoolVar)
117
- Gecode::Raw.should_receive(:dom).once.with(*params.flatten)
118
- end
119
- end
120
- end
121
-
122
- # For options spec.
123
- @invoke_options = lambda do |hash|
124
- @set.must_be.equal_to(@non_range, hash)
125
- @model.solve!
126
- end
127
- @expect_options = option_expectation do |strength, kind, reif_var|
128
- @expect.call(Gecode::Raw::SRT_EQ, @non_range, reif_var)
129
- end
130
- end
131
-
132
- it 'should translate equality with constant range to domain constraint' do
133
- @expect.call(Gecode::Raw::SRT_EQ, @range, nil)
134
- @set.must == @range
135
- @model.solve!
136
- end
137
-
138
- it 'should translate equality with constant non-range to domain constraint' do
139
- @expect.call(Gecode::Raw::SRT_EQ, @non_range, nil)
140
- @set.must == @non_range
141
- @model.solve!
142
- end
143
-
144
- it 'should translate equality with constant singleton to domain constraint' do
145
- @expect.call(Gecode::Raw::SRT_EQ, @singleton, nil)
146
- @set.must == @singleton
147
- @model.solve!
148
- end
149
-
150
- it 'should translate negated equality with constant range to domain constraint' do
151
- @expect.call(Gecode::Raw::SRT_NQ, @range, nil)
152
- @set.must_not == @range
153
- @model.solve!
154
- end
155
-
156
- it 'should translate negated equality with constant non-range to domain constraint' do
157
- @expect.call(Gecode::Raw::SRT_NQ, @non_range, nil)
158
- @set.must_not == @non_range
159
- @model.solve!
160
- end
161
-
162
- it 'should translate negated equality with constant singleton to domain constraint' do
163
- @expect.call(Gecode::Raw::SRT_NQ, @singleton, nil)
164
- @set.must_not == @singleton
165
- @model.solve!
166
- end
167
-
168
- it 'should constrain the domain with equality' do
169
- @set.must == @singleton
170
- @model.solve!
171
- @set.should be_assigned
172
- @set.value.should include(@singleton)
173
- @set.value.size.should == 1
174
- end
175
-
176
- it 'should constrain the domain with inequality' do
177
- @set.must_not == @singleton
178
- @model.solve!
179
- @set.should be_assigned
180
- @set.value.should include(@singleton)
181
- @set.value.size.should > 1
182
- end
183
-
184
- it_should_behave_like 'reifiable set constraint'
185
- end
@@ -1,285 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/constraint_helper'
3
-
4
- describe Gecode::Constraints::Set::Operation do
5
- before do
6
- @model = Gecode::Model.new
7
- @set1 = @model.set_var([], 0..20)
8
- @set2 = @model.set_var([], 0..20)
9
- @rhs = @model.set_var([], 0..20)
10
- @model.branch_on @model.wrap_enum([@set1, @set2, @rhs])
11
- @constant_set = [4,9,17]
12
- @wrapped_constant_set = @model.wrap_enum(@constant_set)
13
-
14
- @expect = lambda do |op1, operation_type, op2, relation_type, rhs, reif_var, negated|
15
- op1, op2, rhs = [op1, op2, rhs].map do |expression|
16
- # Convert the expression to the corresponding expected class.
17
- if expression.respond_to? :bind
18
- an_instance_of(Gecode::Raw::SetVar)
19
- else
20
- an_instance_of(Gecode::Raw::IntSet)
21
- end
22
- end
23
-
24
- Gecode::Raw.should_receive(:rel).once.with(
25
- an_instance_of(Gecode::Raw::Space), op1, operation_type, op2,
26
- relation_type, rhs)
27
- end
28
-
29
- # For options spec.
30
- @invoke_options = lambda do |hash|
31
- @set1.union(@set2).must_be.superset_of(@rhs, hash)
32
- @model.solve!
33
- end
34
- @expect_options = option_expectation do |strength, kind, reif_var|
35
- @expect.call(@set1, Gecode::Raw::SOT_SUP, @set2, Gecode::Raw::SRT_SUP,
36
- @rhs, reif_var, false)
37
- end
38
- end
39
-
40
- Gecode::Constraints::Util::SET_OPERATION_TYPES.each_pair do |relation, type|
41
- it "should translate #{relation} with variable operands and variable rhs" do
42
- @expect.call(@set1, type, @set2, Gecode::Raw::SRT_SUP, @rhs, nil, false)
43
- @set1.send(relation, @set2).must_be.superset_of(@rhs)
44
- @model.solve!
45
- end
46
-
47
- it "should translate #{relation} with variable operands and constant rhs" do
48
- @expect.call(@set1, type, @set2, Gecode::Raw::SRT_SUP, @constant_set,
49
- nil, false)
50
- @set1.send(relation, @set2).must_be.superset_of(@constant_set)
51
- @model.solve!
52
- end
53
-
54
- it "should translate #{relation} with variable lhs, constant operand and variable rhs" do
55
- @expect.call(@set1, type, @constant_set, Gecode::Raw::SRT_SUP, @rhs, nil,
56
- false)
57
- @set1.send(relation, @constant_set).must_be.superset_of(@rhs)
58
- @model.solve!
59
- end
60
-
61
- it "should translate #{relation} with variable lhs, constant operand and constant rhs" do
62
- @expect.call(@set1, type, @constant_set, Gecode::Raw::SRT_SUP,
63
- @constant_set, nil, false)
64
- @set1.send(relation, @constant_set).must_be.superset_of(@constant_set)
65
- @model.solve!
66
- end
67
-
68
- it "should translate #{relation} with constant lhs, variable operand and variable rhs" do
69
- @expect.call(@constant_set, type, @set2, Gecode::Raw::SRT_SUP,
70
- @rhs, nil, false)
71
- @wrapped_constant_set.send(relation, @set2).must_be.superset_of(@rhs)
72
- @model.solve!
73
- end
74
-
75
- it "should translate #{relation} with constant lhs, variable operand and constant rhs" do
76
- @expect.call(@constant_set, type, @set2, Gecode::Raw::SRT_SUP,
77
- @constant_set, nil, false)
78
- @wrapped_constant_set.send(relation, @set2).must_be.superset_of(@constant_set)
79
- @model.solve!
80
- end
81
-
82
- it "should raise error for #{relation} with constant lhs, operand and rhs" do
83
- lambda do
84
- @wrapped_constant_set.send(relation, @constant_set).must_be.superset_of(
85
- @constant_set)
86
- end.should raise_error(ArgumentError)
87
- end
88
- end
89
-
90
- it 'should raise error if negated' do
91
- lambda do
92
- @set1.union(@set2).must_not_be.subset_of(@rhs)
93
- end.should raise_error(Gecode::MissingConstraintError)
94
- end
95
-
96
- it 'should constrain the sets according to the operation (variable operands, variable rhs)' do
97
- @set1.intersection(@set2).must == @rhs
98
- @rhs.must == @constant_set
99
- @model.solve!.should_not be_nil
100
- (@set1.value.to_a & @set2.value.to_a).sort.should == @constant_set
101
- end
102
-
103
- it 'should constrain the sets according to the operation (variable operands, constant rhs)' do
104
- @set1.intersection(@set2).must == @constant_set
105
- @model.solve!.should_not be_nil
106
- (@set1.value.to_a & @set2.value.to_a).sort.should == @constant_set
107
- end
108
-
109
- it 'should constrain the sets according to the operation (variable lhs, constant operand and rhs)' do
110
- @set1.union(@constant_set).must == @constant_set
111
- @model.solve!.should_not be_nil
112
- (@set1.value.to_a + @constant_set).uniq.sort.should == @constant_set.sort
113
- end
114
-
115
- it 'should constrain the sets according to the operation (variable lhs and rhs, constant operand)' do
116
- @set1.union(@constant_set).must == @rhs
117
- @model.solve!.should_not be_nil
118
- (@set1.value.to_a + @constant_set).uniq.sort.should == @rhs.value.to_a.sort
119
- end
120
-
121
- it 'should constrain the sets according to the operation (constant lhs, variable operand and rhs)' do
122
- @wrapped_constant_set.minus(@set2).must == @rhs
123
- @model.solve!.should_not be_nil
124
- (@constant_set - @set2.value.to_a).sort.should == @rhs.value.sort
125
- end
126
-
127
- it 'should constrain the sets according to the operation (constant lhs and rhs, variable operand)' do
128
- @wrapped_constant_set.minus(@set2).must == @constant_set
129
- @model.solve!.should_not be_nil
130
- (@constant_set - @set2.value.to_a).sort.should == @constant_set
131
- end
132
-
133
- it_should_behave_like 'non-reifiable set constraint'
134
- end
135
-
136
- describe 'set enum operation constraint', :shared => true do
137
- include GecodeR::Specs::SetHelper
138
-
139
- before do
140
- @expect = lambda do |enum, operation_type, relation, rhs, reif_var, negated|
141
- if rhs.respond_to? :bind
142
- expected_target = [an_instance_of(Gecode::Raw::SetVar)]
143
- relation_constraint = :rel
144
- else
145
- expected_target = expect_constant_set(rhs)
146
- relation_constraint = :dom
147
- end
148
-
149
- if reif_var.nil?
150
- if !negated and relation == Gecode::Raw::IRT_EQ and
151
- !rhs.kind_of? Enumerable
152
- Gecode::Raw.should_receive(:rel).once.with(
153
- an_instance_of(Gecode::Raw::Space), operation_type,
154
- an_instance_of(Gecode::Raw::SetVarArray),
155
- *expected_target)
156
- Gecode::Raw.should_receive(:dom).exactly(0).times
157
- else
158
- if relation_constraint == :rel
159
- Gecode::Raw.should_receive(:rel).twice
160
- else
161
- Gecode::Raw.should_receive(:rel).once.with(
162
- an_instance_of(Gecode::Raw::Space), operation_type,
163
- an_instance_of(Gecode::Raw::SetVarArray),
164
- an_instance_of(Gecode::Raw::SetVar))
165
- Gecode::Raw.should_receive(relation_constraint).at_most(:twice)
166
- end
167
- end
168
- else
169
- if relation_constraint == :rel
170
- Gecode::Raw.should_receive(:rel).twice
171
- else
172
- Gecode::Raw.should_receive(:rel).once.with(
173
- an_instance_of(Gecode::Raw::Space), operation_type,
174
- an_instance_of(Gecode::Raw::SetVarArray),
175
- an_instance_of(Gecode::Raw::SetVar))
176
- expected_target << an_instance_of(Gecode::Raw::BoolVar)
177
- Gecode::Raw.should_receive(relation_constraint).once.with(
178
- an_instance_of(Gecode::Raw::Space),
179
- an_instance_of(Gecode::Raw::SetVar), relation, *expected_target)
180
- end
181
- end
182
- end
183
-
184
- # For composite spec.
185
- @invoke_relation = lambda do |relation, target, negated|
186
- if negated
187
- @stub.must_not.send(relation, target)
188
- else
189
- @stub.must.send(relation, target)
190
- end
191
- @model.solve!
192
- end
193
- @expect_relation = lambda do |relation, target, negated|
194
- @expect.call(@sets, @operation_type, relation, target, nil, negated)
195
- end
196
-
197
- # For options spec.
198
- @invoke_options = lambda do |hash|
199
- @stub.must_be.superset_of(@rhs, hash)
200
- @model.solve!
201
- end
202
- @expect_options = option_expectation do |strength, kind, reif_var|
203
- @expect.call(@sets, @operation_type, Gecode::Raw::SRT_SUP, @rhs,
204
- reif_var, false)
205
- end
206
- end
207
-
208
- it_should_behave_like 'reifiable set constraint'
209
- it_should_behave_like 'composite set constraint'
210
- end
211
-
212
- describe Gecode::Constraints::SetEnum::Operation, ' (union)' do
213
- before do
214
- @model = Gecode::Model.new
215
- @sets = @model.set_var_array(10, [], 0..20)
216
- @target = @rhs = @model.set_var([], 0..20)
217
- @model.branch_on @sets
218
-
219
- @stub = @sets.union
220
- @operation_type = Gecode::Raw::SOT_UNION
221
- end
222
-
223
- it 'should constrain the union of the sets' do
224
- @sets.union.must_be.subset_of [1,4,17]
225
- @sets.union.must_be.superset_of 1
226
- @model.solve!.should_not be_nil
227
- union = @sets.values.inject([]){ |union, set| union += set.to_a }.uniq
228
- union.should include(1)
229
- (union - [1,4,17]).should be_empty
230
- end
231
-
232
- it_should_behave_like 'set enum operation constraint'
233
- end
234
-
235
- describe Gecode::Constraints::SetEnum::Operation, ' (intersection)' do
236
- before do
237
- @model = Gecode::Model.new
238
- @sets = @model.set_var_array(10, [], 0..20)
239
- @target = @rhs = @model.set_var([], 0..20)
240
- @model.branch_on @sets
241
-
242
- @stub = @sets.intersection
243
- @operation_type = Gecode::Raw::SOT_INTER
244
- end
245
-
246
- it 'should constrain the intersection of the sets' do
247
- @sets.intersection.must_be.subset_of [1,4,17]
248
- @sets.intersection.must_be.superset_of [1]
249
- @model.solve!.should_not be_nil
250
- intersection = @sets.values.inject(nil) do |intersection, set|
251
- next set.to_a if intersection.nil?
252
- intersection &= set.to_a
253
- end.uniq
254
- intersection.should include(1)
255
- (intersection - [1,4,17]).should be_empty
256
- end
257
-
258
- it_should_behave_like 'set enum operation constraint'
259
- end
260
-
261
- describe Gecode::Constraints::SetEnum::Operation, ' (disjoint union)' do
262
- before do
263
- @model = Gecode::Model.new
264
- @sets = @model.set_var_array(10, [], 0..20)
265
- @target = @rhs = @model.set_var([], 0..20)
266
- @model.branch_on @sets
267
-
268
- @stub = @sets.disjoint_union
269
- @operation_type = Gecode::Raw::SOT_DUNION
270
- end
271
-
272
- it 'should constrain the disjoint union of the sets' do
273
- @sets.disjoint_union.must_be.subset_of [1,4,17]
274
- @sets.disjoint_union.must_be.superset_of [1]
275
- @model.solve!.should_not be_nil
276
- disjoint_union = @sets.values.inject([]) do |union, set|
277
- intersection = union & set.to_a
278
- union += set.to_a - intersection
279
- end.uniq
280
- disjoint_union.should include(1)
281
- (disjoint_union - [1,4,17]).should be_empty
282
- end
283
-
284
- it_should_behave_like 'set enum operation constraint'
285
- end