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,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
|
data/specs/constraints/count.rb
DELETED
@@ -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
|