gecoder 0.8.2 → 0.8.3
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 +14 -0
- data/ext/gecoder.cpp +181 -0
- data/ext/gecoder.h +94 -0
- data/ext/vararray.cpp +3 -3
- data/lib/gecoder/bindings/bindings.rb +104 -46
- data/lib/gecoder/interface/binding_changes.rb +1 -301
- data/lib/gecoder/interface/branch.rb +15 -11
- data/lib/gecoder/interface/constraints/bool/boolean.rb +56 -52
- data/lib/gecoder/interface/constraints/bool/channel.rb +1 -16
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +13 -8
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +48 -0
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +101 -0
- data/lib/gecoder/interface/constraints/int/channel.rb +1 -13
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +15 -35
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +130 -0
- data/lib/gecoder/interface/constraints/set/channel.rb +54 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +37 -6
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +1 -0
- data/lib/gecoder/interface/constraints.rb +38 -0
- data/lib/gecoder/interface/model.rb +110 -85
- data/lib/gecoder/interface/variables.rb +3 -21
- data/lib/gecoder/version.rb +1 -1
- data/specs/branch.rb +16 -1
- data/specs/constraints/bool_enum_relation.rb +6 -6
- data/specs/constraints/boolean.rb +31 -25
- data/specs/constraints/channel.rb +102 -4
- data/specs/constraints/extensional.rb +185 -2
- data/specs/constraints/reification_sugar.rb +2 -46
- data/specs/model.rb +85 -7
- data/tasks/dependencies.txt +1 -0
- data/vendor/rust/rust/class.rb +33 -35
- data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +1 -1
- data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +10 -1
- metadata +185 -184
- data/example/raw_bindings.rb +0 -44
- data/ext/missing.cpp +0 -328
- data/ext/missing.h +0 -120
- data/specs/binding_changes.rb +0 -76
@@ -26,10 +26,23 @@ class BoolChannelSampleProblem < Gecode::Model
|
|
26
26
|
@int = int_var(0..3)
|
27
27
|
@bool = bool_var
|
28
28
|
|
29
|
-
branch_on
|
29
|
+
branch_on @int
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
class SetChannelSampleProblem < Gecode::Model
|
34
|
+
attr :bool_enum
|
35
|
+
attr :set
|
36
|
+
|
37
|
+
def initialize
|
38
|
+
@bool_enum = bool_var_array(4)
|
39
|
+
@set = set_var([], 0..3)
|
40
|
+
|
41
|
+
branch_on @bool_enum
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
33
46
|
describe Gecode::Constraints::IntEnum::Channel, ' (two int enums)' do
|
34
47
|
before do
|
35
48
|
@model = ChannelSampleProblem.new
|
@@ -73,10 +86,10 @@ describe Gecode::Constraints::IntEnum::Channel, ' (two int enums)' do
|
|
73
86
|
lambda{ @elements.must.channel 'hello' }.should raise_error(TypeError)
|
74
87
|
end
|
75
88
|
|
76
|
-
it_should_behave_like 'reifiable constraint'
|
89
|
+
it_should_behave_like 'non-reifiable constraint'
|
77
90
|
end
|
78
91
|
|
79
|
-
describe Gecode::Constraints::
|
92
|
+
describe Gecode::Constraints::SetEnum::Channel::IntChannelConstraint, ' (channel with set as right hand side)' do
|
80
93
|
before do
|
81
94
|
@model = ChannelSampleProblem.new
|
82
95
|
@positions = @model.positions
|
@@ -113,7 +126,7 @@ describe Gecode::Constraints::IntEnum::Channel, ' (one int enum and one set enum
|
|
113
126
|
it_should_behave_like 'non-reifiable set constraint'
|
114
127
|
end
|
115
128
|
|
116
|
-
describe Gecode::Constraints::SetEnum, ' (channel with set as left hand side)' do
|
129
|
+
describe Gecode::Constraints::SetEnum::Channel::IntChannelConstraint, ' (channel with set as left hand side)' do
|
117
130
|
before do
|
118
131
|
@model = ChannelSampleProblem.new
|
119
132
|
@positions = @model.positions
|
@@ -354,3 +367,88 @@ describe Gecode::Constraints::BoolEnum::Channel, ' (int variable as lhs with boo
|
|
354
367
|
|
355
368
|
it_should_behave_like 'channel constraint between bool enum and int variable'
|
356
369
|
end
|
370
|
+
|
371
|
+
# Requires @model, @bool_enum and @set. Also requires @place_constraint which
|
372
|
+
# is a method that takes four variables: a boolean enum, a set variable,
|
373
|
+
# whether or not the constraint should be negated and a hash of options, and
|
374
|
+
# places the channel constraint on them.
|
375
|
+
describe 'channel constraint between set variable and bool enum', :shared => true do
|
376
|
+
before do
|
377
|
+
@invoke_options = lambda do |hash|
|
378
|
+
@place_constraint.call(@bools, @set, false, hash)
|
379
|
+
@model.solve!
|
380
|
+
end
|
381
|
+
@expect_options = option_expectation do |strength, kind, reif_var|
|
382
|
+
Gecode::Raw.should_receive(:channel).once.with(
|
383
|
+
an_instance_of(Gecode::Raw::Space),
|
384
|
+
an_instance_of(Gecode::Raw::BoolVarArray),
|
385
|
+
an_instance_of(Gecode::Raw::SetVar))
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
it 'should channel the bool enum with the set variable' do
|
390
|
+
@set.must_be.superset_of [0, 2]
|
391
|
+
@place_constraint.call(@bools, @set, false, {})
|
392
|
+
@model.solve!.should_not be_nil
|
393
|
+
set_values = @set.value
|
394
|
+
@bools.values.each_with_index do |bool, index|
|
395
|
+
bool.should == set_values.include?(index)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'should not allow negation' do
|
400
|
+
lambda do
|
401
|
+
@place_constraint.call(@bools, @set, true, {})
|
402
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
403
|
+
end
|
404
|
+
|
405
|
+
it_should_behave_like 'non-reifiable set constraint'
|
406
|
+
end
|
407
|
+
|
408
|
+
describe Gecode::Constraints::Set::Channel, ' (set variable as lhs with bool enum)' do
|
409
|
+
before do
|
410
|
+
@model = SetChannelSampleProblem.new
|
411
|
+
@bools = @model.bool_enum
|
412
|
+
@set = @model.set
|
413
|
+
|
414
|
+
@place_constraint = lambda do |bools, set, negate, options|
|
415
|
+
unless negate
|
416
|
+
set.must.channel(bools, options)
|
417
|
+
else
|
418
|
+
set.must_not.channel(bools, options)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
it 'should raise error if a boolean enum is not given as right hand side' do
|
424
|
+
lambda do
|
425
|
+
@set.must.channel 'hello'
|
426
|
+
end.should raise_error(TypeError)
|
427
|
+
end
|
428
|
+
|
429
|
+
it_should_behave_like 'channel constraint between set variable and bool enum'
|
430
|
+
end
|
431
|
+
|
432
|
+
describe Gecode::Constraints::Set::Channel, ' (bool enum as lhs with set variable)' do
|
433
|
+
before do
|
434
|
+
@model = SetChannelSampleProblem.new
|
435
|
+
@bools = @model.bool_enum
|
436
|
+
@set = @model.set
|
437
|
+
|
438
|
+
@place_constraint = lambda do |bools, set, negate, options|
|
439
|
+
unless negate
|
440
|
+
bools.must.channel(set, options)
|
441
|
+
else
|
442
|
+
bools.must_not.channel(set, options)
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
it 'should raise error if an integer variable is not given as right hand side' do
|
448
|
+
lambda do
|
449
|
+
@bools.must.channel 'hello'
|
450
|
+
end.should raise_error(TypeError)
|
451
|
+
end
|
452
|
+
|
453
|
+
it_should_behave_like 'channel constraint between set variable and bool enum'
|
454
|
+
end
|
@@ -44,7 +44,7 @@ describe 'tuple constraint', :shared => true do
|
|
44
44
|
it_should_behave_like 'non-reifiable constraint'
|
45
45
|
end
|
46
46
|
|
47
|
-
describe Gecode::Constraints::IntEnum::Extensional do
|
47
|
+
describe Gecode::Constraints::IntEnum::Extensional, ' (tuple constraint)' do
|
48
48
|
before do
|
49
49
|
@model = Gecode::Model.new
|
50
50
|
@tuples = [[1,7], [5,1]]
|
@@ -77,7 +77,7 @@ describe Gecode::Constraints::IntEnum::Extensional do
|
|
77
77
|
it_should_behave_like 'tuple constraint'
|
78
78
|
end
|
79
79
|
|
80
|
-
describe Gecode::Constraints::BoolEnum::Extensional do
|
80
|
+
describe Gecode::Constraints::BoolEnum::Extensional, ' (tuple constraint)' do
|
81
81
|
before do
|
82
82
|
@model = Gecode::Model.new
|
83
83
|
@tuples = [[true, false, true], [false, false, true]]
|
@@ -109,3 +109,186 @@ describe Gecode::Constraints::BoolEnum::Extensional do
|
|
109
109
|
|
110
110
|
it_should_behave_like 'tuple constraint'
|
111
111
|
end
|
112
|
+
|
113
|
+
# Assumes that @variables, @expected_array, @value1, @value2 (must not
|
114
|
+
# equal @value1) and @regexp are defined.
|
115
|
+
describe 'regular expression constraint', :shared => true do
|
116
|
+
before do
|
117
|
+
@invoke_options = lambda do |hash|
|
118
|
+
@variables.must.match(@regexp, hash)
|
119
|
+
@model.solve!
|
120
|
+
end
|
121
|
+
@expect_options = option_expectation do |strength, kind, reif_var|
|
122
|
+
Gecode::Raw.should_receive(:extensional).once.with(
|
123
|
+
an_instance_of(Gecode::Raw::Space),
|
124
|
+
@expected_array,
|
125
|
+
an_instance_of(Gecode::Raw::REG), strength, kind)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should handle values grouped in a single array' do
|
130
|
+
@variables.must.match [@value1, @value2, @value1]
|
131
|
+
@model.solve!.should_not be_nil
|
132
|
+
@variables.values.should == [@value1, @value2, @value1]
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should allow nested groups of values' do
|
136
|
+
@variables.must.match [@value1, [@value2, [@value1]]]
|
137
|
+
@model.solve!.should_not be_nil
|
138
|
+
@variables.values.should == [@value1, @value2, @value1]
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should handle the repeat operation' do
|
142
|
+
@variables.must.match [@value1, @model.repeat([@value2], 1, 2)]
|
143
|
+
@model.solve!.should_not be_nil
|
144
|
+
@variables.values.should == [@value1, @value2, @value2]
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should handle repeat operations that do not encase constant values in arrays' do
|
148
|
+
@variables.must.match [@value1, @model.repeat(@value2, 1, 2)]
|
149
|
+
@model.solve!.should_not be_nil
|
150
|
+
@variables.values.should == [@value1, @value2, @value2]
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should handle nested repeat operations' do
|
154
|
+
@variables.must.match [[@model.repeat(@model.repeat([@value2], 1, 3), 1, 2)]]
|
155
|
+
@model.solve!.should_not be_nil
|
156
|
+
@variables.values.should == [@value2, @value2, @value2]
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should handle nested repeat operations (2)' do
|
160
|
+
@variables.must.match [[@model.repeat([@model.repeat(@value2, 1, 3)], 1, 2)]]
|
161
|
+
@model.solve!.should_not be_nil
|
162
|
+
@variables.values.should == [@value2, @value2, @value2]
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should interpret the repeat operation with the last argument omitted as only giving a lower bound' do
|
166
|
+
@variables.must.match [@value1, @model.repeat([@value2], 1)]
|
167
|
+
@model.solve!.should_not be_nil
|
168
|
+
@variables.values.should == [@value1, @value2, @value2]
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should interpret the repeat operation with all but the first argument omitted as not giving any bound' do
|
172
|
+
@variables.must.match [@model.repeat(@value2), @value1, @value1, @value1]
|
173
|
+
@model.solve!.should_not be_nil
|
174
|
+
@variables.values.should == [@value1, @value1, @value1]
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should interpret the repeat operation with all but the first argument omitted as not giving any bound (2)' do
|
178
|
+
@variables.must.match [@model.repeat(@value2)]
|
179
|
+
@model.solve!.should_not be_nil
|
180
|
+
@variables.values.should == [@value2, @value2, @value2]
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should translate at_most_once(reg) to repeat(reg, 0, 1)' do
|
184
|
+
@model.should_receive(:repeat).once.with([@value1], 0, 1)
|
185
|
+
@model.at_most_once [@value1]
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should translate at_least_once(reg) to repeat(reg, 1)' do
|
189
|
+
@model.should_receive(:repeat).once.with([@value1], 1)
|
190
|
+
@model.at_least_once [@value1]
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should raise error if the right hand side is not an enumeration' do
|
194
|
+
lambda do
|
195
|
+
@variables.must.match Object.new
|
196
|
+
end.should raise_error(TypeError)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should raise error if the right hand side does not a regexp of the right type' do
|
200
|
+
lambda do
|
201
|
+
@variables.must.match [@value1, 'foo']
|
202
|
+
end.should raise_error(TypeError)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should raise error if the right hand side contains a nested element of an incorrect type' do
|
206
|
+
lambda do
|
207
|
+
@variables.must.match [@value1, [@value2, 'foo']]
|
208
|
+
end.should raise_error(TypeError)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type (2)' do
|
212
|
+
lambda do
|
213
|
+
@variables.must.match @model.repeat(@value1, [0], 1)
|
214
|
+
end.should raise_error(TypeError)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type (3)' do
|
218
|
+
lambda do
|
219
|
+
@variables.must.match @model.repeat(@value1, 0, [1])
|
220
|
+
end.should raise_error(TypeError)
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type' do
|
224
|
+
lambda do
|
225
|
+
@variables.must.match @model.repeat('foo', 0, 1)
|
226
|
+
end.should raise_error(TypeError)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should not allow negation' do
|
230
|
+
lambda do
|
231
|
+
@variables.must_not.match @regexp
|
232
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
233
|
+
end
|
234
|
+
|
235
|
+
it_should_behave_like 'non-reifiable constraint'
|
236
|
+
end
|
237
|
+
|
238
|
+
describe Gecode::Constraints::IntEnum::Extensional, ' (regexp constraint)' do
|
239
|
+
before do
|
240
|
+
@model = Gecode::Model.new
|
241
|
+
@variables = @digits = @model.int_var_array(3, 0..9)
|
242
|
+
@model.branch_on @digits
|
243
|
+
@expected_array = an_instance_of Gecode::Raw::IntVarArray
|
244
|
+
@value1 = 3
|
245
|
+
@value2 = 5
|
246
|
+
@regexp = [1, @model.any(3, 4), @model.at_most_once(5)]
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'should handle the any operation' do
|
250
|
+
@digits.must.match [1, @model.any(1, 2, 3), 3]
|
251
|
+
@model.solve!.should_not be_nil
|
252
|
+
values = @digits.values
|
253
|
+
values.size.should == 3
|
254
|
+
values.should == values.sort
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'should handle the any operator with nested expressions' do
|
258
|
+
@digits.must.match [1, @model.any(@model.at_least_once(2), [3, 5])]
|
259
|
+
@digits[2].must < 4
|
260
|
+
@model.solve!.should_not be_nil
|
261
|
+
@digits.values.should == [1,2,2]
|
262
|
+
end
|
263
|
+
|
264
|
+
it_should_behave_like 'regular expression constraint'
|
265
|
+
end
|
266
|
+
|
267
|
+
describe Gecode::Constraints::BoolEnum::Extensional, ' (regexp constraint)' do
|
268
|
+
before do
|
269
|
+
@model = Gecode::Model.new
|
270
|
+
@variables = @bools = @model.bool_var_array(3)
|
271
|
+
@model.branch_on @bools
|
272
|
+
@expected_array = an_instance_of Gecode::Raw::BoolVarArray
|
273
|
+
@value1 = true
|
274
|
+
@value2 = false
|
275
|
+
@regexp = [true, @model.any(true, false), @model.at_most_once(true)]
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'should handle the any operation' do
|
279
|
+
@bools.must.match [@model.repeat(@model.any(true, false))]
|
280
|
+
@bools[0].must_be.true
|
281
|
+
@bools[1].must_be.false
|
282
|
+
@model.solve!.should_not be_nil
|
283
|
+
@bools[0].value.should be_true
|
284
|
+
@bools[1].value.should be_false
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'should handle the any operator with nested expressions' do
|
288
|
+
@bools.must.match [@model.any(@model.at_least_once(true), [false])]
|
289
|
+
@model.solve!.should_not be_nil
|
290
|
+
@bools.values.should == [true, true, true]
|
291
|
+
end
|
292
|
+
|
293
|
+
it_should_behave_like 'regular expression constraint'
|
294
|
+
end
|
@@ -26,28 +26,6 @@ describe Gecode::Constraints::ReifiableConstraint do
|
|
26
26
|
@model.solve!.should be_nil
|
27
27
|
end
|
28
28
|
|
29
|
-
it 'should translate disjunctions' do
|
30
|
-
Gecode::Raw.should_receive(:rel).once.with(
|
31
|
-
an_instance_of(Gecode::Raw::Space),
|
32
|
-
an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::BOT_OR,
|
33
|
-
an_instance_of(Gecode::Raw::BoolVar),
|
34
|
-
an_instance_of(Gecode::Raw::BoolVar),
|
35
|
-
Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF
|
36
|
-
)
|
37
|
-
Gecode::Raw.should_receive(:rel).once.with(
|
38
|
-
an_instance_of(Gecode::Raw::Space),
|
39
|
-
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR, 0,
|
40
|
-
an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF,
|
41
|
-
Gecode::Raw::PK_DEF)
|
42
|
-
Gecode::Raw.should_receive(:rel).once.with(
|
43
|
-
an_instance_of(Gecode::Raw::Space),
|
44
|
-
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_EQ, 3,
|
45
|
-
an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF,
|
46
|
-
Gecode::Raw::PK_DEF)
|
47
|
-
(@x.must > 0) | (@y.must == 3)
|
48
|
-
sol = @model.solve!
|
49
|
-
end
|
50
|
-
|
51
29
|
it 'should solve disjunctions' do
|
52
30
|
(@x.must > 0) | (@y.must == 3)
|
53
31
|
sol = @model.solve!
|
@@ -59,29 +37,7 @@ describe Gecode::Constraints::ReifiableConstraint do
|
|
59
37
|
(@x.must > 3) & (@y.must == 3)
|
60
38
|
@model.solve!.should be_nil
|
61
39
|
end
|
62
|
-
|
63
|
-
it 'should translate conjunctions' do
|
64
|
-
Gecode::Raw.should_receive(:rel).once.with(
|
65
|
-
an_instance_of(Gecode::Raw::Space),
|
66
|
-
an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::BOT_AND,
|
67
|
-
an_instance_of(Gecode::Raw::BoolVar),
|
68
|
-
an_instance_of(Gecode::Raw::BoolVar),
|
69
|
-
Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF
|
70
|
-
)
|
71
|
-
Gecode::Raw.should_receive(:rel).once.with(
|
72
|
-
an_instance_of(Gecode::Raw::Space),
|
73
|
-
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR, 0,
|
74
|
-
an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF,
|
75
|
-
Gecode::Raw::PK_DEF)
|
76
|
-
Gecode::Raw.should_receive(:rel).once.with(
|
77
|
-
an_instance_of(Gecode::Raw::Space),
|
78
|
-
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_EQ, 2,
|
79
|
-
an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF,
|
80
|
-
Gecode::Raw::PK_DEF)
|
81
|
-
(@x.must > 0) & (@y.must == 2)
|
82
|
-
sol = @model.solve!
|
83
|
-
end
|
84
|
-
|
40
|
+
|
85
41
|
it 'should solve conjunctions' do
|
86
42
|
(@x.must > 0) & (@y.must == 2)
|
87
43
|
sol = @model.solve!
|
@@ -111,4 +67,4 @@ describe Gecode::Constraints::ReifiableConstraint do
|
|
111
67
|
sol = @model.solve!
|
112
68
|
sol.should be_nil
|
113
69
|
end
|
114
|
-
end
|
70
|
+
end
|
data/specs/model.rb
CHANGED
@@ -9,7 +9,7 @@ describe Gecode::Model, ' (integer creation)' do
|
|
9
9
|
range = 0..3
|
10
10
|
@model.int_var(range).should have_domain(range)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it 'should allow the creation of int variables without specified domain' do
|
14
14
|
var = @model.int_var
|
15
15
|
var.should be_range
|
@@ -43,6 +43,17 @@ describe Gecode::Model, ' (integer creation)' do
|
|
43
43
|
vars.each{ |var| var.should have_domain(domain) }
|
44
44
|
end
|
45
45
|
|
46
|
+
it 'should allow the creation of int-var arrays without specified domain' do
|
47
|
+
count = 5
|
48
|
+
vars = @model.int_var_array(count)
|
49
|
+
vars.size.should equal(count)
|
50
|
+
vars.each do |var|
|
51
|
+
var.should be_range
|
52
|
+
var.min.should == Gecode::Raw::IntLimits::MIN
|
53
|
+
var.max.should == Gecode::Raw::IntLimits::MAX
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
46
57
|
it 'should allow the creation of int-var matrices with range domains' do
|
47
58
|
range = 0..3
|
48
59
|
rows = 5
|
@@ -62,6 +73,32 @@ describe Gecode::Model, ' (integer creation)' do
|
|
62
73
|
vars.column_size.should equal(columns)
|
63
74
|
vars.each{ |var| var.should have_domain(domain) }
|
64
75
|
end
|
76
|
+
|
77
|
+
it 'should allow the creation of int-var matrices without specified domain' do
|
78
|
+
rows = 5
|
79
|
+
columns = 4
|
80
|
+
vars = @model.int_var_matrix(rows, columns)
|
81
|
+
vars.row_size.should equal(rows)
|
82
|
+
vars.column_size.should equal(columns)
|
83
|
+
vars.each do |var|
|
84
|
+
var.should be_range
|
85
|
+
var.min.should == Gecode::Raw::IntLimits::MIN
|
86
|
+
var.max.should == Gecode::Raw::IntLimits::MAX
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should raise error if the domain is of incorrect type' do
|
91
|
+
lambda do
|
92
|
+
@model.int_var(nil)
|
93
|
+
end.should raise_error(TypeError)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should gracefully GC a variable that was never accessed' do
|
97
|
+
lambda do
|
98
|
+
@model.int_var 0
|
99
|
+
GC.start
|
100
|
+
end.should_not raise_error
|
101
|
+
end
|
65
102
|
end
|
66
103
|
|
67
104
|
describe Gecode::Model, ' (bool creation)' do
|
@@ -82,6 +119,13 @@ describe Gecode::Model, ' (bool creation)' do
|
|
82
119
|
matrix.row_size.should equal(3)
|
83
120
|
matrix.column_size.should equal(4)
|
84
121
|
end
|
122
|
+
|
123
|
+
it 'should gracefully GC a variable that was never accessed' do
|
124
|
+
lambda do
|
125
|
+
@model.bool_var
|
126
|
+
GC.start
|
127
|
+
end.should_not raise_error
|
128
|
+
end
|
85
129
|
end
|
86
130
|
|
87
131
|
describe Gecode::Model, ' (set creation)' do
|
@@ -143,6 +187,15 @@ describe Gecode::Model, ' (set creation)' do
|
|
143
187
|
end
|
144
188
|
end
|
145
189
|
|
190
|
+
it 'should allow the creation of arrays of set variables without specified bounds' do
|
191
|
+
vars = @model.set_var_array(3)
|
192
|
+
vars.each do |var|
|
193
|
+
var.lower_bound.size.should == 0
|
194
|
+
var.upper_bound.min.should == Gecode::Raw::SetLimits::MIN
|
195
|
+
var.upper_bound.max.should == Gecode::Raw::SetLimits::MAX
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
146
199
|
it 'should allow the creation of matrices of set variables' do
|
147
200
|
matrix = @model.set_var_matrix(4, 5, @glb_enum, @lub_enum,
|
148
201
|
@lower_card..@upper_card)
|
@@ -154,20 +207,45 @@ describe Gecode::Model, ' (set creation)' do
|
|
154
207
|
var.cardinality.begin.should >= @lower_card
|
155
208
|
end
|
156
209
|
end
|
210
|
+
|
211
|
+
it 'should allow the creation of matrices of set variables without specified bounds' do
|
212
|
+
matrix = @model.set_var_matrix(4, 5)
|
213
|
+
matrix.each do |var|
|
214
|
+
var.lower_bound.size.should == 0
|
215
|
+
var.upper_bound.min.should == Gecode::Raw::SetLimits::MIN
|
216
|
+
var.upper_bound.max.should == Gecode::Raw::SetLimits::MAX
|
217
|
+
end
|
218
|
+
end
|
157
219
|
|
158
220
|
it 'should raise error if glb and lub are not valid when they are given as range' do
|
159
|
-
lambda
|
160
|
-
|
221
|
+
lambda do
|
222
|
+
@model.set_var(@lub_range, @glb_range)
|
223
|
+
end.should raise_error(ArgumentError)
|
161
224
|
end
|
162
225
|
|
163
226
|
it 'should raise error if glb and lub are not valid when one is given as enum' do
|
164
|
-
lambda
|
165
|
-
|
227
|
+
lambda do
|
228
|
+
@model.set_var(@lub_range, @glb_enum)
|
229
|
+
end.should raise_error(ArgumentError)
|
166
230
|
end
|
167
231
|
|
168
232
|
it 'should raise error if glb and lub are not valid when both are given as enums' do
|
169
|
-
lambda
|
170
|
-
|
233
|
+
lambda do
|
234
|
+
@model.set_var(@lub_enum, @glb_enum)
|
235
|
+
end.should raise_error(ArgumentError)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should raise error if the glb and lub are of incorrect type' do
|
239
|
+
lambda do
|
240
|
+
@model.set_var("foo\n", "foo\ns")
|
241
|
+
end.should raise_error(TypeError)
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should gracefully GC a variable that was never accessed' do
|
245
|
+
lambda do
|
246
|
+
@model.set_var(@glb_range, @lub_range)
|
247
|
+
GC.start
|
248
|
+
end.should_not raise_error
|
171
249
|
end
|
172
250
|
end
|
173
251
|
|
data/tasks/dependencies.txt
CHANGED
data/vendor/rust/rust/class.rb
CHANGED
@@ -260,7 +260,7 @@ module Rust
|
|
260
260
|
|
261
261
|
private
|
262
262
|
def raw_call(nparam = nil)
|
263
|
-
case @
|
263
|
+
case position(@parameters.size)
|
264
264
|
when 1 # pre
|
265
265
|
"#{@name} (*tmp)"
|
266
266
|
when 2 # mid
|
@@ -272,43 +272,41 @@ module Rust
|
|
272
272
|
end
|
273
273
|
end
|
274
274
|
|
275
|
+
# 1: pre 2: mid 3: post 4: mixed
|
276
|
+
def position(nparam)
|
277
|
+
case @name
|
278
|
+
when "+": (nparam.zero? ? 1 : 3)
|
279
|
+
when "-": 3
|
280
|
+
when "*": (nparam.zero? ? 1 : 3)
|
281
|
+
when "/": 3
|
282
|
+
when /\[\s*\]=/: 4
|
283
|
+
when /\[\s*\]/: 2
|
284
|
+
when "==": 3
|
285
|
+
when "!=": 3
|
286
|
+
when "<<": 3
|
287
|
+
when ">>": 3
|
288
|
+
when "!": 1
|
289
|
+
when "()": 2
|
290
|
+
else
|
291
|
+
3
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
275
295
|
def valid_name
|
276
296
|
case @name
|
277
|
-
when "+"
|
278
|
-
|
279
|
-
|
280
|
-
when "
|
281
|
-
|
282
|
-
|
283
|
-
when "
|
284
|
-
|
285
|
-
|
286
|
-
when "
|
287
|
-
|
288
|
-
|
289
|
-
when /\[\s*\]=/
|
290
|
-
@position = 4
|
291
|
-
"ateqop"
|
292
|
-
when /\[\s*\]/
|
293
|
-
@position = 2
|
294
|
-
"atop"
|
295
|
-
when "=="
|
296
|
-
@position = 3
|
297
|
-
"equalop"
|
298
|
-
when "!="
|
299
|
-
@position = 3
|
300
|
-
"notequalop"
|
301
|
-
when "<<"
|
302
|
-
@position = 3
|
303
|
-
"outstream"
|
304
|
-
when ">>"
|
305
|
-
@position = 3
|
306
|
-
"intstream"
|
307
|
-
when "!"
|
308
|
-
@position = 1
|
309
|
-
"notop"
|
297
|
+
when "+": "plusop"
|
298
|
+
when "-": "minusop"
|
299
|
+
when "*": "multop"
|
300
|
+
when "/": "divop"
|
301
|
+
when /\[\s*\]=/: "ateqop"
|
302
|
+
when /\[\s*\]/: "atop"
|
303
|
+
when "==": "equalop"
|
304
|
+
when "!=": "notequalop"
|
305
|
+
when "<<": "outstream"
|
306
|
+
when ">>": "intstream"
|
307
|
+
when "!": "notop"
|
308
|
+
when "()": "parenthesisop"
|
310
309
|
else
|
311
|
-
@position = 3
|
312
310
|
"undefop_#{@name[0].chr.to_i}#{rand(1024)}"
|
313
311
|
end
|
314
312
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
//-*-c++-*-
|
2
2
|
|
3
3
|
extern VALUE r!class_varname!;
|
4
|
-
VALUE cxx2ruby(!c_class_name!* instance, bool free = false);
|
4
|
+
VALUE cxx2ruby(!c_class_name!* instance, bool free = false, bool create_new_if_needed = true);
|
5
5
|
bool is_!class_varname!(VALUE val);
|
6
6
|
!c_class_name!* ruby2!class_varcname!Ptr(VALUE rval, int argn = -1);
|
7
7
|
!c_class_name!& ruby2!class_varcname!(VALUE rval, int argn = -1);
|
@@ -51,17 +51,26 @@ bool is_!class_varname!(VALUE val)
|
|
51
51
|
return *ruby2!class_varcname!Ptr(rval, argn);
|
52
52
|
}
|
53
53
|
|
54
|
-
VALUE cxx2ruby(!c_class_name!* instance, bool free) {
|
54
|
+
VALUE cxx2ruby(!c_class_name!* instance, bool free, bool create_new_if_needed) {
|
55
55
|
if ( instance == NULL ) return Qnil;
|
56
56
|
|
57
57
|
T!class_ptrmap!::iterator it, eend = !class_ptrmap!.end();
|
58
58
|
|
59
|
+
#ifdef DEBUG
|
60
|
+
fprintf(stderr, "rust: searching for !c_class_name! %p\n", instance);
|
61
|
+
#endif
|
62
|
+
|
59
63
|
for(it = !class_ptrmap!.begin(); it != eend; it++)
|
60
64
|
if ( (*it).second == (!c_class_name!*)instance ) break;
|
61
65
|
|
62
66
|
if ( it != !class_ptrmap!.end() )
|
63
67
|
return (*it).first;
|
64
68
|
else {
|
69
|
+
#ifdef DEBUG
|
70
|
+
fprintf(stderr, "rust: failed to find match for %p\n", instance);
|
71
|
+
#endif
|
72
|
+
if(!create_new_if_needed) return Qnil;
|
73
|
+
|
65
74
|
VALUE klass = r!class_varname!;
|
66
75
|
|
67
76
|
!test_children!
|