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.
- data/CHANGES +15 -0
- data/README +6 -2
- data/example/equation_system.rb +15 -0
- data/example/magic_sequence.rb +7 -7
- data/example/money.rb +36 -0
- data/example/queens.rb +7 -8
- data/example/send_most_money.rb +1 -1
- data/example/square_tiling.rb +2 -2
- data/example/sudoku-set.rb +11 -12
- data/example/sudoku.rb +40 -45
- data/ext/extconf.rb +0 -0
- data/lib/gecoder/bindings.rb +42 -0
- data/lib/gecoder/bindings/bindings.rb +16 -0
- data/lib/gecoder/interface.rb +2 -1
- data/lib/gecoder/interface/branch.rb +16 -9
- data/lib/gecoder/interface/constraints.rb +410 -451
- data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
- data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
- data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
- data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
- data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
- data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
- data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
- data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
- data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
- data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
- data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
- data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
- data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
- data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
- data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
- data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
- data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
- data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
- data/lib/gecoder/interface/constraints/set/include.rb +36 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
- data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
- data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
- data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
- data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
- data/lib/gecoder/interface/enum_matrix.rb +4 -4
- data/lib/gecoder/interface/enum_wrapper.rb +71 -22
- data/lib/gecoder/interface/model.rb +167 -12
- data/lib/gecoder/interface/model_sugar.rb +84 -0
- data/lib/gecoder/interface/search.rb +30 -18
- data/lib/gecoder/interface/variables.rb +103 -33
- data/lib/gecoder/version.rb +2 -2
- data/specs/bool_var.rb +19 -12
- data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
- data/specs/constraints/bool/boolean_properties.rb +51 -0
- data/specs/constraints/bool/linear.rb +213 -0
- data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
- data/specs/constraints/bool_enum/channel.rb +102 -0
- data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
- data/specs/constraints/constraint_helper.rb +149 -179
- data/specs/constraints/constraint_receivers.rb +103 -0
- data/specs/constraints/constraints.rb +6 -63
- data/specs/constraints/fixnum_enum/element.rb +58 -0
- data/specs/constraints/fixnum_enum/operation.rb +67 -0
- data/specs/constraints/int/arithmetic.rb +149 -0
- data/specs/constraints/int/channel.rb +101 -0
- data/specs/constraints/int/domain.rb +106 -0
- data/specs/constraints/int/linear.rb +183 -0
- data/specs/constraints/int/linear_properties.rb +97 -0
- data/specs/constraints/int/relation.rb +84 -0
- data/specs/constraints/int_enum/arithmetic.rb +72 -0
- data/specs/constraints/int_enum/channel.rb +57 -0
- data/specs/constraints/int_enum/count.rb +72 -0
- data/specs/constraints/int_enum/distinct.rb +80 -0
- data/specs/constraints/int_enum/element.rb +61 -0
- data/specs/constraints/int_enum/equality.rb +29 -0
- data/specs/constraints/int_enum/extensional.rb +224 -0
- data/specs/constraints/int_enum/sort.rb +167 -0
- data/specs/constraints/operands.rb +264 -0
- data/specs/constraints/property_helper.rb +443 -0
- data/specs/constraints/reification_sugar.rb +4 -5
- data/specs/constraints/selected_set/select.rb +56 -0
- data/specs/constraints/selected_set/select_properties.rb +157 -0
- data/specs/constraints/set/cardinality.rb +58 -0
- data/specs/constraints/set/cardinality_properties.rb +46 -0
- data/specs/constraints/set/channel.rb +77 -0
- data/specs/constraints/set/connection.rb +176 -0
- data/specs/constraints/set/domain.rb +197 -0
- data/specs/constraints/set/include.rb +36 -0
- data/specs/constraints/set/operation.rb +132 -0
- data/specs/constraints/set/relation.rb +117 -0
- data/specs/constraints/set_elements/relation.rb +84 -0
- data/specs/constraints/set_enum/channel.rb +80 -0
- data/specs/constraints/set_enum/distinct.rb +59 -0
- data/specs/constraints/set_enum/operation.rb +111 -0
- data/specs/constraints/set_enum/select.rb +73 -0
- data/specs/enum_wrapper.rb +53 -3
- data/specs/int_var.rb +44 -25
- data/specs/model.rb +58 -1
- data/specs/model_sugar.rb +30 -0
- data/specs/search.rb +24 -5
- data/specs/selected_set.rb +39 -0
- data/specs/set_elements.rb +34 -0
- data/specs/set_var.rb +22 -8
- data/specs/spec_helper.rb +206 -6
- data/tasks/distribution.rake +22 -7
- data/tasks/svn.rake +3 -1
- metadata +218 -134
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
- data/specs/constraints/arithmetic.rb +0 -351
- data/specs/constraints/bool_enum_relation.rb +0 -160
- data/specs/constraints/cardinality.rb +0 -157
- data/specs/constraints/channel.rb +0 -454
- data/specs/constraints/connection.rb +0 -369
- data/specs/constraints/count.rb +0 -146
- data/specs/constraints/distinct.rb +0 -164
- data/specs/constraints/element.rb +0 -108
- data/specs/constraints/equality.rb +0 -31
- data/specs/constraints/int_domain.rb +0 -70
- data/specs/constraints/int_relation.rb +0 -82
- data/specs/constraints/linear.rb +0 -340
- data/specs/constraints/selection.rb +0 -292
- data/specs/constraints/set_domain.rb +0 -185
- data/specs/constraints/set_operation.rb +0 -285
- data/specs/constraints/set_relation.rb +0 -197
- 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
|