gecoder-with-gecode 0.9.0-x86-mswin32-60
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 +137 -0
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +58 -0
- data/Rakefile +14 -0
- data/example/equation_system.rb +15 -0
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/money.rb +36 -0
- data/example/queens.rb +42 -0
- data/example/send_more_money.rb +43 -0
- data/example/send_most_money.rb +58 -0
- data/example/square_tiling.rb +84 -0
- data/example/sudoku-set.rb +106 -0
- data/example/sudoku.rb +56 -0
- data/lib/gecode.dll +0 -0
- data/lib/gecoder.rb +5 -0
- data/lib/gecoder/bindings.rb +96 -0
- data/lib/gecoder/bindings/bindings.rb +2029 -0
- data/lib/gecoder/interface.rb +9 -0
- data/lib/gecoder/interface/binding_changes.rb +9 -0
- data/lib/gecoder/interface/branch.rb +163 -0
- data/lib/gecoder/interface/constraints.rb +471 -0
- data/lib/gecoder/interface/constraints/bool/boolean.rb +251 -0
- data/lib/gecoder/interface/constraints/bool/channel.rb +7 -0
- data/lib/gecoder/interface/constraints/bool/linear.rb +200 -0
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +68 -0
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +106 -0
- data/lib/gecoder/interface/constraints/bool_enum/relation.rb +55 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +84 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +155 -0
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +101 -0
- 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 +150 -0
- data/lib/gecoder/interface/constraints/int/channel.rb +51 -0
- data/lib/gecoder/interface/constraints/int/domain.rb +80 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +143 -0
- data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +63 -0
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +86 -0
- data/lib/gecoder/interface/constraints/int_enum/count.rb +66 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +64 -0
- data/lib/gecoder/interface/constraints/int_enum/element.rb +64 -0
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +37 -0
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +187 -0
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +135 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +95 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +230 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
- 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 +65 -0
- data/lib/gecoder/interface/constraints/set/channel.rb +51 -0
- data/lib/gecoder/interface/constraints/set/connection.rb +130 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +156 -0
- data/lib/gecoder/interface/constraints/set/include.rb +36 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +118 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +155 -0
- 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 +45 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +43 -0
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +69 -0
- data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +84 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +243 -0
- data/lib/gecoder/interface/enum_matrix.rb +64 -0
- data/lib/gecoder/interface/enum_wrapper.rb +205 -0
- data/lib/gecoder/interface/model.rb +453 -0
- data/lib/gecoder/interface/model_sugar.rb +84 -0
- data/lib/gecoder/interface/search.rb +197 -0
- data/lib/gecoder/interface/variables.rb +306 -0
- data/lib/gecoder/version.rb +4 -0
- data/specs/bool_var.rb +81 -0
- data/specs/branch.rb +185 -0
- data/specs/constraints/bool/boolean.rb +317 -0
- 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/bool_enum/extensional.rb +225 -0
- data/specs/constraints/constraint_helper.rb +234 -0
- data/specs/constraints/constraint_receivers.rb +103 -0
- data/specs/constraints/constraints.rb +26 -0
- 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 +69 -0
- 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/distribution.rb +14 -0
- data/specs/enum_matrix.rb +43 -0
- data/specs/enum_wrapper.rb +179 -0
- data/specs/examples.rb +17 -0
- data/specs/int_var.rb +163 -0
- data/specs/logging.rb +24 -0
- data/specs/model.rb +325 -0
- data/specs/model_sugar.rb +30 -0
- data/specs/search.rb +383 -0
- data/specs/selected_set.rb +39 -0
- data/specs/set_elements.rb +34 -0
- data/specs/set_var.rb +82 -0
- data/specs/spec_helper.rb +265 -0
- data/tasks/all_tasks.rb +1 -0
- data/tasks/dependencies.txt +22 -0
- data/tasks/distribution.rake +194 -0
- data/tasks/rcov.rake +18 -0
- data/tasks/specs.rake +21 -0
- data/tasks/svn.rake +16 -0
- data/tasks/website.rake +51 -0
- data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodesupport.dll +0 -0
- data/vendor/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +116 -0
- data/vendor/rust/include/rust_conversions.hh +102 -0
- data/vendor/rust/rust.rb +67 -0
- data/vendor/rust/rust/attribute.rb +51 -0
- data/vendor/rust/rust/bindings.rb +172 -0
- data/vendor/rust/rust/class.rb +337 -0
- data/vendor/rust/rust/constants.rb +48 -0
- data/vendor/rust/rust/container.rb +110 -0
- data/vendor/rust/rust/cppifaceparser.rb +129 -0
- data/vendor/rust/rust/cwrapper.rb +72 -0
- data/vendor/rust/rust/cxxclass.rb +96 -0
- data/vendor/rust/rust/element.rb +81 -0
- data/vendor/rust/rust/enum.rb +63 -0
- data/vendor/rust/rust/function.rb +407 -0
- data/vendor/rust/rust/namespace.rb +61 -0
- data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
- data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
- data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
- data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
- data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
- data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
- data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +100 -0
- data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
- data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
- data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
- data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
- data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
- data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
- data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
- data/vendor/rust/rust/type.rb +98 -0
- data/vendor/rust/test/Makefile +4 -0
- data/vendor/rust/test/constants.rb +36 -0
- data/vendor/rust/test/cppclass.cc +45 -0
- data/vendor/rust/test/cppclass.hh +67 -0
- data/vendor/rust/test/cppclass.rb +59 -0
- data/vendor/rust/test/cwrapper.c +74 -0
- data/vendor/rust/test/cwrapper.h +41 -0
- data/vendor/rust/test/cwrapper.rb +56 -0
- data/vendor/rust/test/dummyclass.hh +31 -0
- data/vendor/rust/test/lib/extension-test.rb +98 -0
- data/vendor/rust/test/operators.cc +41 -0
- data/vendor/rust/test/operators.hh +39 -0
- data/vendor/rust/test/operators.rb +39 -0
- data/vendor/rust/test/test-constants.rb +43 -0
- data/vendor/rust/test/test-cppclass.rb +82 -0
- data/vendor/rust/test/test-cwrapper.rb +80 -0
- data/vendor/rust/test/test-operators.rb +42 -0
- metadata +393 -0
@@ -0,0 +1,225 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../constraint_helper'
|
2
|
+
|
3
|
+
# Assumes that @variables, @expected_array and @tuples are defined.
|
4
|
+
describe 'bool tuple constraint', :shared => true do
|
5
|
+
it 'should not allow negation' do
|
6
|
+
lambda do
|
7
|
+
@variables.must_not_be.in @tuples
|
8
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should not allow empty tuples' do
|
12
|
+
lambda do
|
13
|
+
@variables.must_be.in []
|
14
|
+
end.should raise_error(ArgumentError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should not allow tuples of sizes other than the number of variables' do
|
18
|
+
lambda do
|
19
|
+
@variables.must_be.in([@tuples.first * 2])
|
20
|
+
end.should raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should raise error if the right hand side does not contain tuples of correct type' do
|
24
|
+
lambda do
|
25
|
+
size = @variables.size
|
26
|
+
@variables.must_be.in ['h'*size, 'i'*size]
|
27
|
+
end.should raise_error(TypeError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Gecode::BoolEnum::Extensional, ' (tuple constraint)' do
|
32
|
+
before do
|
33
|
+
@model = Gecode::Model.new
|
34
|
+
@tuples = [[true, false, true], [false, false, true]]
|
35
|
+
@variables = @bools = @model.bool_var_array(3)
|
36
|
+
@model.branch_on @bools
|
37
|
+
|
38
|
+
@types = [:bool_enum]
|
39
|
+
@invoke = lambda do |receiver, hash|
|
40
|
+
receiver.in([[true, false, true, false, true],
|
41
|
+
[false, true, true, true, true]], hash)
|
42
|
+
@model.solve!
|
43
|
+
end
|
44
|
+
@expect = lambda do |var, opts, reif_var|
|
45
|
+
Gecode::Raw.should_receive(:extensional).once.with(
|
46
|
+
an_instance_of(Gecode::Raw::Space),
|
47
|
+
var, an_instance_of(Gecode::Raw::TupleSet), *opts)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should constrain the domain of all variables' do
|
52
|
+
@bools.must_be.in @tuples
|
53
|
+
|
54
|
+
found_solutions = []
|
55
|
+
@model.each_solution do |m|
|
56
|
+
found_solutions << @bools.values
|
57
|
+
end
|
58
|
+
|
59
|
+
found_solutions.size.should == 2
|
60
|
+
(found_solutions - @tuples).should be_empty
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should raise error if the right hand side is not an enumeration' do
|
64
|
+
lambda{ @bools.must_be.in true }.should raise_error(TypeError)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should raise error if the right hand side does not contain tuples' do
|
68
|
+
lambda{ @bools.must_be.in [true, false] }.should raise_error(TypeError)
|
69
|
+
end
|
70
|
+
|
71
|
+
it_should_behave_like 'bool tuple constraint'
|
72
|
+
it_should_behave_like 'non-reifiable constraint'
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Assumes that @variables, @expected_array, @value1, @value2 (must not
|
77
|
+
# equal @value1) and @regexp are defined.
|
78
|
+
describe 'bool regular expression constraint', :shared => true do
|
79
|
+
it 'should handle values grouped in a single array' do
|
80
|
+
@variables.must.match [@value1, @value2, @value1]
|
81
|
+
@model.solve!.should_not be_nil
|
82
|
+
@variables.values.should == [@value1, @value2, @value1]
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should allow nested groups of values' do
|
86
|
+
@variables.must.match [@value1, [@value2, [@value1]]]
|
87
|
+
@model.solve!.should_not be_nil
|
88
|
+
@variables.values.should == [@value1, @value2, @value1]
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should handle the repeat operation' do
|
92
|
+
@variables.must.match [@value1, @model.repeat([@value2], 1, 2)]
|
93
|
+
@model.solve!.should_not be_nil
|
94
|
+
@variables.values.should == [@value1, @value2, @value2]
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should handle repeat operations that do not encase constant values in arrays' do
|
98
|
+
@variables.must.match [@value1, @model.repeat(@value2, 1, 2)]
|
99
|
+
@model.solve!.should_not be_nil
|
100
|
+
@variables.values.should == [@value1, @value2, @value2]
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should handle nested repeat operations' do
|
104
|
+
@variables.must.match [[@model.repeat(@model.repeat([@value2], 1, 3), 1, 2)]]
|
105
|
+
@model.solve!.should_not be_nil
|
106
|
+
@variables.values.should == [@value2, @value2, @value2]
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should handle nested repeat operations (2)' do
|
110
|
+
@variables.must.match [[@model.repeat([@model.repeat(@value2, 1, 3)], 1, 2)]]
|
111
|
+
@model.solve!.should_not be_nil
|
112
|
+
@variables.values.should == [@value2, @value2, @value2]
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should interpret the repeat operation with the last argument omitted as only giving a lower bound' do
|
116
|
+
@variables.must.match [@value1, @model.repeat([@value2], 1)]
|
117
|
+
@model.solve!.should_not be_nil
|
118
|
+
@variables.values.should == [@value1, @value2, @value2]
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should interpret the repeat operation with all but the first argument omitted as not giving any bound' do
|
122
|
+
@variables.must.match [@model.repeat(@value2), @value1, @value1, @value1]
|
123
|
+
@model.solve!.should_not be_nil
|
124
|
+
@variables.values.should == [@value1, @value1, @value1]
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should interpret the repeat operation with all but the first argument omitted as not giving any bound (2)' do
|
128
|
+
@variables.must.match [@model.repeat(@value2)]
|
129
|
+
@model.solve!.should_not be_nil
|
130
|
+
@variables.values.should == [@value2, @value2, @value2]
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should translate at_most_once(reg) to repeat(reg, 0, 1)' do
|
134
|
+
@model.should_receive(:repeat).once.with([@value1], 0, 1)
|
135
|
+
@model.at_most_once [@value1]
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should translate at_least_once(reg) to repeat(reg, 1)' do
|
139
|
+
@model.should_receive(:repeat).once.with([@value1], 1)
|
140
|
+
@model.at_least_once [@value1]
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should raise error if the right hand side is not an enumeration' do
|
144
|
+
lambda do
|
145
|
+
@variables.must.match Object.new
|
146
|
+
end.should raise_error(TypeError)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should raise error if the right hand side does not a regexp of the right type' do
|
150
|
+
lambda do
|
151
|
+
@variables.must.match [@value1, 'foo']
|
152
|
+
end.should raise_error(TypeError)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should raise error if the right hand side contains a nested element of an incorrect type' do
|
156
|
+
lambda do
|
157
|
+
@variables.must.match [@value1, [@value2, 'foo']]
|
158
|
+
end.should raise_error(TypeError)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type (2)' do
|
162
|
+
lambda do
|
163
|
+
@variables.must.match @model.repeat(@value1, [0], 1)
|
164
|
+
end.should raise_error(TypeError)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type (3)' do
|
168
|
+
lambda do
|
169
|
+
@variables.must.match @model.repeat(@value1, 0, [1])
|
170
|
+
end.should raise_error(TypeError)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type' do
|
174
|
+
lambda do
|
175
|
+
@variables.must.match @model.repeat('foo', 0, 1)
|
176
|
+
end.should raise_error(TypeError)
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should not allow negation' do
|
180
|
+
lambda do
|
181
|
+
@variables.must_not.match @regexp
|
182
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe Gecode::BoolEnum::Extensional, ' (regexp constraint)' do
|
187
|
+
before do
|
188
|
+
@model = Gecode::Model.new
|
189
|
+
@variables = @bools = @model.bool_var_array(3)
|
190
|
+
@model.branch_on @bools
|
191
|
+
@expected_array = an_instance_of Gecode::Raw::BoolVarArray
|
192
|
+
@value1 = true
|
193
|
+
@value2 = false
|
194
|
+
@regexp = [true, @model.any(true, false), @model.at_most_once(true)]
|
195
|
+
|
196
|
+
@types = [:bool_enum]
|
197
|
+
@invoke = lambda do |receiver, hash|
|
198
|
+
receiver.match(@regexp, hash)
|
199
|
+
@model.solve!
|
200
|
+
end
|
201
|
+
@expect = lambda do |var, opts, reif_var|
|
202
|
+
Gecode::Raw.should_receive(:extensional).once.with(
|
203
|
+
an_instance_of(Gecode::Raw::Space),
|
204
|
+
var, an_instance_of(Gecode::Raw::REG), *opts)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'should handle the any operation' do
|
209
|
+
@bools.must.match [@model.repeat(@model.any(true, false))]
|
210
|
+
@bools[0].must_be.true
|
211
|
+
@bools[1].must_be.false
|
212
|
+
@model.solve!.should_not be_nil
|
213
|
+
@bools[0].value.should be_true
|
214
|
+
@bools[1].value.should be_false
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should handle the any operator with nested expressions' do
|
218
|
+
@bools.must.match [@model.any(@model.at_least_once(true), [false])]
|
219
|
+
@model.solve!.should_not be_nil
|
220
|
+
@bools.values.should == [true, true, true]
|
221
|
+
end
|
222
|
+
|
223
|
+
it_should_behave_like 'bool regular expression constraint'
|
224
|
+
it_should_behave_like 'non-reifiable constraint'
|
225
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
# Every constraint should have a spec that specs the following:
|
4
|
+
#
|
5
|
+
# * An example where the constraint is used to constrain a sample
|
6
|
+
# problem (and one for negation if deemed necessary).
|
7
|
+
# * should_behave_like [non-reifiable|reifiable] constraint (possibly
|
8
|
+
# indirect).
|
9
|
+
# * Those constraints that do not support negation must
|
10
|
+
# should_behave_like 'non-negatable constraint'
|
11
|
+
#
|
12
|
+
|
13
|
+
|
14
|
+
# These specs assume that the following variables are defined:
|
15
|
+
# [@expect] A proc that creates an expectation corresponding to
|
16
|
+
# constraint. It should take three parameter. The
|
17
|
+
# first is an array of operands of types specified by
|
18
|
+
# @types. The second is whether or not the constraint
|
19
|
+
# should be negated. The third is a hash that can
|
20
|
+
# have values for the keys :icl (ICL_*), :pk (PK_*),
|
21
|
+
# and :bool (bound reification variable). Any values
|
22
|
+
# not provided are assumed to be default values (nil
|
23
|
+
# in the case of :bool).
|
24
|
+
# [@invoke] A proc that invokes the constraint to be tested, It
|
25
|
+
# should have arity arity(@types) + 1. The first
|
26
|
+
# parameter is a constraint receiver (type decided by
|
27
|
+
# @types). The next arity(@types)-1 parameters are
|
28
|
+
# given operands of types specified by @types. The
|
29
|
+
# last parameter is a hash of options (with at most
|
30
|
+
# the keys :strength, :kind and :reify)..
|
31
|
+
# [@types] An array of symbols signaling what types of
|
32
|
+
# arguments @ accepts. The symbols
|
33
|
+
# must be one of: :int, :bool, :set, :int_enum,
|
34
|
+
# :bool_enum, :set_enum, :fixnum_enum.
|
35
|
+
# [@model] The model instance that contains the aspects being tested.
|
36
|
+
|
37
|
+
def expect(variables, options)
|
38
|
+
bool = options[:bool]
|
39
|
+
bool = @model.allow_space_access{ bool.bind } unless bool.nil?
|
40
|
+
args = @model.allow_space_access do
|
41
|
+
variables.map do |var|
|
42
|
+
if var.respond_to? :bind
|
43
|
+
var.bind
|
44
|
+
else
|
45
|
+
var.bind_array
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
args << [options[:icl] || Gecode::Raw::ICL_DEF,
|
50
|
+
options[:pk] || Gecode::Raw::PK_DEF]
|
51
|
+
args << bool
|
52
|
+
@expect.call(*args)
|
53
|
+
end
|
54
|
+
|
55
|
+
def invoke(operands, options)
|
56
|
+
base_op = operands.first
|
57
|
+
if options.delete(:negate)
|
58
|
+
receiver = base_op.must_not
|
59
|
+
else
|
60
|
+
receiver = base_op.must
|
61
|
+
end
|
62
|
+
args = ([receiver] + operands[1..-1]) << options
|
63
|
+
@invoke.call(*args)
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'reifiable constraint', :shared => true do
|
67
|
+
it_should_behave_like 'constraint with default options'
|
68
|
+
it_should_behave_like 'constraint with reification option'
|
69
|
+
it_should_behave_like 'constraint'
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'non-reifiable constraint', :shared => true do
|
73
|
+
it 'should raise errors if reification is used' do
|
74
|
+
operands, variables = produce_general_arguments(@types)
|
75
|
+
lambda do
|
76
|
+
invoke(operands, :reify => @model.bool_var)
|
77
|
+
end.should raise_error(ArgumentError)
|
78
|
+
end
|
79
|
+
|
80
|
+
it_should_behave_like 'constraint with default options'
|
81
|
+
it_should_behave_like 'constraint'
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'non-negatable constraint', :shared => true do
|
85
|
+
it 'should raise errors if negation is used' do
|
86
|
+
operands, variables = produce_general_arguments(@types)
|
87
|
+
lambda do
|
88
|
+
invoke(operands, :negate => true)
|
89
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'constraint', :shared => true do
|
94
|
+
it 'should raise errors if parameters of the incorrect type are given' do
|
95
|
+
operands, variables = produce_general_arguments(@types)
|
96
|
+
(1...operands.size).each do |i|
|
97
|
+
bogus_operands = operands.clone
|
98
|
+
bogus_operands[i] = Object.new
|
99
|
+
lambda do
|
100
|
+
invoke(bogus_operands, {})
|
101
|
+
end.should raise_error(TypeError)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'constraint with reification option', :shared => true do
|
107
|
+
it 'should translate reification' do
|
108
|
+
operands, variables = produce_general_arguments(@types)
|
109
|
+
var = @model.bool_var
|
110
|
+
expect(variables, :bool => var)
|
111
|
+
invoke(operands, :reify => var)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should translate reification with arbitrary bool operand' do
|
115
|
+
operands, variables = produce_general_arguments(@types)
|
116
|
+
op, bool_var = general_bool_operand(@model)
|
117
|
+
expect(variables, :bool => bool_var)
|
118
|
+
invoke(operands, :reify => op)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should raise errors for reification variables of incorrect type' do
|
122
|
+
operands, variables = produce_general_arguments(@types)
|
123
|
+
lambda do
|
124
|
+
invoke(operands, :reify => 'foo')
|
125
|
+
end.should raise_error(TypeError)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'constraint with default options', :shared => true do
|
130
|
+
it 'should raise errors for unrecognized options' do
|
131
|
+
operands, variables = produce_general_arguments(@types)
|
132
|
+
lambda do
|
133
|
+
invoke(operands, :does_not_exist => :foo)
|
134
|
+
end.should raise_error(ArgumentError)
|
135
|
+
end
|
136
|
+
|
137
|
+
it_should_behave_like 'constraint with strength option'
|
138
|
+
it_should_behave_like 'constraint with kind option'
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'constraint with strength option', :shared => true do
|
142
|
+
{ :default => Gecode::Raw::ICL_DEF,
|
143
|
+
:value => Gecode::Raw::ICL_VAL,
|
144
|
+
:bounds => Gecode::Raw::ICL_BND,
|
145
|
+
:domain => Gecode::Raw::ICL_DOM
|
146
|
+
}.each_pair do |name, gecode_value|
|
147
|
+
it "should translate propagation strength #{name}" do
|
148
|
+
operands, variables = produce_general_arguments(@types)
|
149
|
+
expect(variables, :icl => gecode_value)
|
150
|
+
invoke(operands, :strength => name)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should default to using default as propagation strength' do
|
155
|
+
operands, variables = produce_general_arguments(@types)
|
156
|
+
expect(variables, {})
|
157
|
+
invoke(operands, {})
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should raise errors for unrecognized propagation strengths' do
|
161
|
+
operands, variables = produce_general_arguments(@types)
|
162
|
+
lambda do
|
163
|
+
invoke(operands, :strength => :does_not_exist)
|
164
|
+
end.should raise_error(ArgumentError)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe 'constraint with kind option', :shared => true do
|
169
|
+
{ :default => Gecode::Raw::PK_DEF,
|
170
|
+
:speed => Gecode::Raw::PK_SPEED,
|
171
|
+
:memory => Gecode::Raw::PK_MEMORY
|
172
|
+
}.each_pair do |name, gecode_value|
|
173
|
+
it "should translate propagation kind #{name}" do
|
174
|
+
operands, variables = produce_general_arguments(@types)
|
175
|
+
expect(variables, :pk => gecode_value)
|
176
|
+
invoke(operands, :kind => name)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should default to using default as propagation kind' do
|
181
|
+
operands, variables = produce_general_arguments(@types)
|
182
|
+
expect(variables, {})
|
183
|
+
invoke(operands, {})
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should raise errors for unrecognized propagation kinds' do
|
187
|
+
operands, variables = produce_general_arguments(@types)
|
188
|
+
lambda do
|
189
|
+
invoke(operands, :kind => :does_not_exist)
|
190
|
+
end.should raise_error(ArgumentError)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe 'set constraint', :shared => true do
|
195
|
+
it 'should not accept strength option' do
|
196
|
+
operands, variables = produce_general_arguments(@types)
|
197
|
+
lambda do
|
198
|
+
invoke(operands, :strength => :default)
|
199
|
+
end.should raise_error(ArgumentError)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'should not accept kind option' do
|
203
|
+
operands, variables = produce_general_arguments(@types)
|
204
|
+
lambda do
|
205
|
+
invoke(operands, :kind => :default)
|
206
|
+
end.should raise_error(ArgumentError)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'should raise errors for unrecognized options' do
|
210
|
+
operands, variables = produce_general_arguments(@types)
|
211
|
+
lambda do
|
212
|
+
invoke(operands, :does_not_exist => :foo)
|
213
|
+
end.should raise_error(ArgumentError)
|
214
|
+
end
|
215
|
+
|
216
|
+
it_should_behave_like 'constraint'
|
217
|
+
end
|
218
|
+
|
219
|
+
describe 'non-reifiable set constraint', :shared => true do
|
220
|
+
it 'should not accept reification option' do
|
221
|
+
bool = @model.bool_var
|
222
|
+
operands, variables = produce_general_arguments(@types)
|
223
|
+
lambda do
|
224
|
+
invoke(operands, :reify => bool)
|
225
|
+
end.should raise_error(ArgumentError)
|
226
|
+
end
|
227
|
+
|
228
|
+
it_should_behave_like 'set constraint'
|
229
|
+
end
|
230
|
+
|
231
|
+
describe 'reifiable set constraint', :shared => true do
|
232
|
+
it_should_behave_like 'set constraint'
|
233
|
+
it_should_behave_like 'constraint with reification option'
|
234
|
+
end
|