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,167 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../constraint_helper'
|
2
|
+
|
3
|
+
class SortSampleProblem < Gecode::Model
|
4
|
+
attr :vars
|
5
|
+
attr :sorted
|
6
|
+
attr :indices
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@vars = int_var_array(4, 10..19)
|
10
|
+
@sorted = int_var_array(4, 10..19)
|
11
|
+
@indices = int_var_array(4, 0..9)
|
12
|
+
|
13
|
+
# To make it more interesting
|
14
|
+
@vars.must_be.distinct
|
15
|
+
|
16
|
+
branch_on @vars
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Gecode::IntEnum::Sort, ' (without :as and :order)' do
|
21
|
+
before do
|
22
|
+
@model = SortSampleProblem.new
|
23
|
+
@vars = @model.vars
|
24
|
+
@sorted = @model.sorted
|
25
|
+
|
26
|
+
@types = [:int_enum]
|
27
|
+
@invoke = lambda do |receiver, hash|
|
28
|
+
receiver.sorted(hash)
|
29
|
+
@model.solve!
|
30
|
+
end
|
31
|
+
@expect = lambda do |var, opts, reif_var|
|
32
|
+
if reif_var.nil?
|
33
|
+
Gecode::Raw.should_receive(:rel).exactly(var.size - 1).times.with(
|
34
|
+
an_instance_of(Gecode::Raw::Space),
|
35
|
+
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_LQ,
|
36
|
+
an_instance_of(Gecode::Raw::IntVar), *opts)
|
37
|
+
else
|
38
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
39
|
+
an_instance_of(Gecode::Raw::Space), anything,
|
40
|
+
an_instance_of(Gecode::Raw::BoolVarArray),
|
41
|
+
anything, anything, anything)
|
42
|
+
Gecode::Raw.should_receive(:rel).exactly(var.size - 1).times.with(
|
43
|
+
an_instance_of(Gecode::Raw::Space),
|
44
|
+
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_LQ,
|
45
|
+
an_instance_of(Gecode::Raw::IntVar),
|
46
|
+
an_instance_of(Gecode::Raw::BoolVar), *opts)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should constraint variables to be sorted' do
|
52
|
+
@vars.must_be.sorted
|
53
|
+
values = @model.solve!.vars.values
|
54
|
+
values.should == values.sort
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should allow negation' do
|
58
|
+
@vars.must_not_be.sorted
|
59
|
+
@model.solve!
|
60
|
+
values = @vars.values
|
61
|
+
values.should_not == values.sort
|
62
|
+
end
|
63
|
+
|
64
|
+
it_should_behave_like 'reifiable constraint'
|
65
|
+
end
|
66
|
+
|
67
|
+
describe Gecode::IntEnum::Sort, ' (with :as)' do
|
68
|
+
before do
|
69
|
+
@model = SortSampleProblem.new
|
70
|
+
@vars = @model.vars
|
71
|
+
@sorted = @model.sorted
|
72
|
+
|
73
|
+
# Make it a bit more interesting.
|
74
|
+
@vars[0].must > @vars[3] + 1
|
75
|
+
|
76
|
+
@types = [:int_enum, :int_enum]
|
77
|
+
@invoke = lambda do |receiver, int_enum, hash|
|
78
|
+
receiver.sorted hash.update(:as => int_enum)
|
79
|
+
@model.solve!
|
80
|
+
end
|
81
|
+
@expect = lambda do |var1, var2, opts, reif_var|
|
82
|
+
Gecode::Raw.should_receive(:sorted).once.with(
|
83
|
+
an_instance_of(Gecode::Raw::Space),
|
84
|
+
var1, var2, *opts)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should constraint variables to be sorted' do
|
89
|
+
@vars.must_be.sorted(:as => @sorted)
|
90
|
+
@model.solve!
|
91
|
+
values = @sorted.values
|
92
|
+
values.should == values.sort
|
93
|
+
end
|
94
|
+
|
95
|
+
it_should_behave_like 'non-reifiable constraint'
|
96
|
+
it_should_behave_like 'non-negatable constraint'
|
97
|
+
end
|
98
|
+
|
99
|
+
describe Gecode::IntEnum::Sort, ' (with :order)' do
|
100
|
+
before do
|
101
|
+
@model = SortSampleProblem.new
|
102
|
+
@vars = @model.vars
|
103
|
+
@sorted = @model.sorted
|
104
|
+
@indices = @model.indices
|
105
|
+
|
106
|
+
# Make it a bit more interesting.
|
107
|
+
@vars[0].must > @vars[3] + 1
|
108
|
+
|
109
|
+
@types = [:int_enum, :int_enum]
|
110
|
+
@invoke = lambda do |receiver, int_enum, hash|
|
111
|
+
receiver.sorted hash.update(:order => int_enum)
|
112
|
+
@model.solve!
|
113
|
+
end
|
114
|
+
@expect = lambda do |var1, var2, opts, reif_var|
|
115
|
+
Gecode::Raw.should_receive(:sorted).once.with(
|
116
|
+
an_instance_of(Gecode::Raw::Space),
|
117
|
+
var1, an_instance_of(Gecode::Raw::IntVarArray), var2,
|
118
|
+
*opts)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should constraint variables to be sorted with the specified indices' do
|
123
|
+
@vars.must_be.sorted(:order => @indices)
|
124
|
+
@model.solve!
|
125
|
+
sorted_values = @vars.values.sort
|
126
|
+
expected_indices = @vars.map{ |v| sorted_values.index(v.value) }
|
127
|
+
@indices.values.should == expected_indices
|
128
|
+
end
|
129
|
+
|
130
|
+
it_should_behave_like 'non-reifiable constraint'
|
131
|
+
it_should_behave_like 'non-negatable constraint'
|
132
|
+
end
|
133
|
+
|
134
|
+
describe Gecode::IntEnum::Sort, ' (with :order and :as)' do
|
135
|
+
before do
|
136
|
+
@model = SortSampleProblem.new
|
137
|
+
@vars = @model.vars
|
138
|
+
@sorted = @model.sorted
|
139
|
+
@indices = @model.indices
|
140
|
+
|
141
|
+
# Make it a bit more interesting.
|
142
|
+
@vars[0].must > @vars[3] + 1
|
143
|
+
|
144
|
+
@types = [:int_enum, :int_enum, :int_enum]
|
145
|
+
@invoke = lambda do |receiver, int_enum1, int_enum2, hash|
|
146
|
+
receiver.sorted hash.update(:as => int_enum1, :order => int_enum2)
|
147
|
+
@model.solve!
|
148
|
+
end
|
149
|
+
@expect = lambda do |var1, var2, var3, opts, reif_var|
|
150
|
+
Gecode::Raw.should_receive(:sorted).once.with(
|
151
|
+
an_instance_of(Gecode::Raw::Space),
|
152
|
+
var1, var2, var3, *opts)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should constraint variables to be sorted with the specified indices' do
|
157
|
+
@vars.must_be.sorted(:as => @sorted, :order => @indices)
|
158
|
+
@model.solve!
|
159
|
+
sorted_values = @sorted.values
|
160
|
+
sorted_values.should == sorted_values.sort
|
161
|
+
expected_indices = @vars.map{ |v| sorted_values.index(v.value) }
|
162
|
+
@indices.values.should == expected_indices
|
163
|
+
end
|
164
|
+
|
165
|
+
it_should_behave_like 'non-reifiable constraint'
|
166
|
+
it_should_behave_like 'non-negatable constraint'
|
167
|
+
end
|
@@ -0,0 +1,264 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe 'operand', :shared => true do
|
4
|
+
it 'should not shadow method missing' do
|
5
|
+
lambda do
|
6
|
+
@operand.does_not_exist
|
7
|
+
end.should raise_error(NoMethodError)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'variable operand', :shared => true do
|
12
|
+
it 'should fall back to the underlying variable' do
|
13
|
+
lambda do
|
14
|
+
@operand.assigned?
|
15
|
+
end.should_not raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it_should_behave_like 'operand'
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'enum operand', :shared => true do
|
22
|
+
it 'should fall back to the underlying enum' do
|
23
|
+
lambda do
|
24
|
+
@operand[0]
|
25
|
+
end.should_not raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it_should_behave_like 'operand'
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Gecode::Operand do
|
32
|
+
before do
|
33
|
+
model = Gecode::Model.new
|
34
|
+
@operand = Object.new
|
35
|
+
class <<@operand
|
36
|
+
include Gecode::Operand
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should raise error if #model is not defined' do
|
41
|
+
lambda do
|
42
|
+
@operand.model
|
43
|
+
end.should raise_error(NotImplementedError)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should raise error if #construct_receiver is not defined' do
|
47
|
+
lambda do
|
48
|
+
@operand.must
|
49
|
+
end.should raise_error(NotImplementedError)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe Gecode::Int::IntOperand do
|
54
|
+
before do
|
55
|
+
model = Gecode::Model.new
|
56
|
+
@operand, _ = general_int_operand(model)
|
57
|
+
end
|
58
|
+
|
59
|
+
it_should_behave_like 'variable operand'
|
60
|
+
end
|
61
|
+
|
62
|
+
describe Gecode::Int::ShortCircuitEqualityOperand, ' (not subclassed)' do
|
63
|
+
before do
|
64
|
+
@model = Gecode::Model.new
|
65
|
+
@operand = Gecode::Int::ShortCircuitEqualityOperand.new(@model)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should raise error if #constrain_equal is called' do
|
69
|
+
lambda do
|
70
|
+
@operand.to_int_var
|
71
|
+
@model.solve!
|
72
|
+
end.should raise_error(NotImplementedError)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe Gecode::Int::ShortCircuitRelationsOperand, ' (not subclassed)' do
|
77
|
+
before do
|
78
|
+
@model = Gecode::Model.new
|
79
|
+
@operand = Gecode::Int::ShortCircuitRelationsOperand.new(@model)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should raise error if #constrain_equal is called' do
|
83
|
+
lambda do
|
84
|
+
@operand.to_int_var
|
85
|
+
@model.solve!
|
86
|
+
end.should raise_error(NotImplementedError)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe Gecode::IntEnum::IntEnumOperand do
|
91
|
+
before do
|
92
|
+
model = Gecode::Model.new
|
93
|
+
@operand, _ = general_int_enum_operand(model)
|
94
|
+
end
|
95
|
+
|
96
|
+
it_should_behave_like 'enum operand'
|
97
|
+
end
|
98
|
+
|
99
|
+
describe Gecode::Bool::BoolOperand do
|
100
|
+
before do
|
101
|
+
model = Gecode::Model.new
|
102
|
+
@operand, _ = general_bool_operand(model)
|
103
|
+
end
|
104
|
+
|
105
|
+
it_should_behave_like 'variable operand'
|
106
|
+
end
|
107
|
+
|
108
|
+
describe Gecode::Bool::ShortCircuitEqualityOperand, ' (not subclassed)' do
|
109
|
+
before do
|
110
|
+
@model = Gecode::Model.new
|
111
|
+
@operand = Gecode::Bool::ShortCircuitEqualityOperand.new(@model)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should raise error if #constrain_equal is called' do
|
115
|
+
lambda do
|
116
|
+
@operand.to_bool_var
|
117
|
+
@model.solve!
|
118
|
+
end.should raise_error(NotImplementedError)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe Gecode::BoolEnum::BoolEnumOperand do
|
123
|
+
before do
|
124
|
+
model = Gecode::Model.new
|
125
|
+
@operand, _ = general_bool_enum_operand(model)
|
126
|
+
end
|
127
|
+
|
128
|
+
it_should_behave_like 'enum operand'
|
129
|
+
end
|
130
|
+
|
131
|
+
describe Gecode::Set::SetOperand do
|
132
|
+
before do
|
133
|
+
model = Gecode::Model.new
|
134
|
+
@operand, _ = general_set_operand(model)
|
135
|
+
end
|
136
|
+
|
137
|
+
it_should_behave_like 'variable operand'
|
138
|
+
end
|
139
|
+
|
140
|
+
describe Gecode::Set::ShortCircuitEqualityOperand, ' (not subclassed)' do
|
141
|
+
before do
|
142
|
+
@model = Gecode::Model.new
|
143
|
+
@operand = Gecode::Set::ShortCircuitEqualityOperand.new(@model)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should raise error if #constrain_equal is called' do
|
147
|
+
lambda do
|
148
|
+
@operand.to_set_var
|
149
|
+
@model.solve!
|
150
|
+
end.should raise_error(NotImplementedError)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe Gecode::Set::ShortCircuitRelationsOperand, ' (not subclassed)' do
|
155
|
+
before do
|
156
|
+
@model = Gecode::Model.new
|
157
|
+
@operand = Gecode::Set::ShortCircuitRelationsOperand.new(@model)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should raise error if #constrain_equal is called' do
|
161
|
+
lambda do
|
162
|
+
@operand.to_set_var
|
163
|
+
@model.solve!
|
164
|
+
end.should raise_error(NotImplementedError)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe Gecode::SelectedSet::SelectedSetOperand do
|
169
|
+
before do
|
170
|
+
model = Gecode::Model.new
|
171
|
+
@operand, ops = general_selected_set_operand(model)
|
172
|
+
@enum, @set = ops
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should raise error if set enum operand is not given' do
|
176
|
+
lambda do
|
177
|
+
Gecode::SelectedSet::SelectedSetOperand.new(:foo, @set)
|
178
|
+
end.should raise_error(TypeError)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should raise error if set operand is not given' do
|
182
|
+
lambda do
|
183
|
+
Gecode::SelectedSet::SelectedSetOperand.new(@enum, :foo)
|
184
|
+
end.should raise_error(TypeError)
|
185
|
+
end
|
186
|
+
|
187
|
+
it_should_behave_like 'operand'
|
188
|
+
end
|
189
|
+
|
190
|
+
describe Gecode::SetElements::SetElementsOperand do
|
191
|
+
before do
|
192
|
+
model = Gecode::Model.new
|
193
|
+
@operand, @set = general_set_elements_operand(model)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'should raise error if set operand is not given' do
|
197
|
+
lambda do
|
198
|
+
Gecode::SetElements::SetElementsOperand.new(:foo)
|
199
|
+
end.should raise_error(TypeError)
|
200
|
+
end
|
201
|
+
|
202
|
+
it_should_behave_like 'operand'
|
203
|
+
end
|
204
|
+
|
205
|
+
describe Gecode::SetEnum::SetEnumOperand do
|
206
|
+
before do
|
207
|
+
model = Gecode::Model.new
|
208
|
+
@operand, _ = general_set_enum_operand(model)
|
209
|
+
end
|
210
|
+
|
211
|
+
it_should_behave_like 'enum operand'
|
212
|
+
end
|
213
|
+
|
214
|
+
describe Gecode::FixnumEnum::FixnumEnumOperand do
|
215
|
+
before do
|
216
|
+
model = Gecode::Model.new
|
217
|
+
@operand, _ = general_fixnum_enum_operand(model)
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should raise error if constraint receiver is called' do
|
221
|
+
lambda do
|
222
|
+
@operand.must
|
223
|
+
end.should raise_error(NotImplementedError)
|
224
|
+
end
|
225
|
+
|
226
|
+
it_should_behave_like 'enum operand'
|
227
|
+
end
|
228
|
+
|
229
|
+
# High level sanity check.
|
230
|
+
describe 'operand combination' do
|
231
|
+
it 'should allow placing constraints on complicated combinations of operands' do
|
232
|
+
model = Gecode::Model.new
|
233
|
+
sets = model.set_var_array(2, [], 0..9)
|
234
|
+
set1, set2 = sets
|
235
|
+
(set1.size + set2.size).must == 5
|
236
|
+
set1.size.must > 1
|
237
|
+
set2.size.must > 1
|
238
|
+
model.branch_on sets
|
239
|
+
|
240
|
+
model.solve!
|
241
|
+
|
242
|
+
(set1.value.size + set2.value.size).should == 5
|
243
|
+
set1.value.size.should > 1
|
244
|
+
set2.value.size.should > 1
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should allow placing constraints on complicated combinations of operands (2)' do
|
248
|
+
model = Gecode::Model.new
|
249
|
+
sets = model.set_var_array(3, [], 0..9)
|
250
|
+
set1, set2, set3 = sets
|
251
|
+
(set1.size + set2.size).must == (set3.size - set1.max)
|
252
|
+
set3.size.must > 3
|
253
|
+
set2.size.must < 3
|
254
|
+
set1.size.must > 0
|
255
|
+
model.branch_on sets
|
256
|
+
|
257
|
+
model.solve!
|
258
|
+
|
259
|
+
(set1.value.size + set2.value.size).should == (set3.value.size - set1.value.max)
|
260
|
+
set3.value.size.should > 3
|
261
|
+
set2.value.size.should < 3
|
262
|
+
set1.value.size.should > 0
|
263
|
+
end
|
264
|
+
end
|
@@ -0,0 +1,443 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
# Every property should have a spec that specs the following:
|
4
|
+
#
|
5
|
+
# * An example where the property is used to constrain a sample problem.
|
6
|
+
# * should_behave_like foo operand
|
7
|
+
# * A test that the property is translated to the correct Gecode
|
8
|
+
# constraint if deemed necessary.
|
9
|
+
|
10
|
+
# Several of these shared specs requires one or more of the following instance
|
11
|
+
# variables to be used:
|
12
|
+
# [@operand] The operand that is being tested.
|
13
|
+
# [@model] The model that defines the context in which the test is
|
14
|
+
# conducted.
|
15
|
+
# [@property_types] An array of symbols signaling what types of
|
16
|
+
# arguments @select_property accepts. The symbols
|
17
|
+
# must be one of: :int, :bool, :set, :int_enum,
|
18
|
+
# :bool_enum, :set_enum, :fixnum_enum.
|
19
|
+
# [@select_property] A proc that selects the property under test. It
|
20
|
+
# should take at least one argument: the operand that
|
21
|
+
# the property should be selected from.
|
22
|
+
# [@selected_property] The resulting operand of the property. It should
|
23
|
+
# be constrained to the degree that it has a
|
24
|
+
# non-maximal domain.
|
25
|
+
# [@constraint_class] The class of the constraints that are expected to be
|
26
|
+
# produced when a constraint is short circuited.
|
27
|
+
#
|
28
|
+
|
29
|
+
|
30
|
+
# Requires @operand and @model.
|
31
|
+
describe 'int var operand', :shared => true do
|
32
|
+
it 'should implement #model' do
|
33
|
+
@operand.model.should be_kind_of(Gecode::Model)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should implement #to_int_var' do
|
37
|
+
int_var = @operand.to_int_var
|
38
|
+
int_var.should be_kind_of(Gecode::IntVar)
|
39
|
+
@model.solve!
|
40
|
+
(int_var.min..int_var.max).should_not equal(Gecode::Model::LARGEST_INT_DOMAIN)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should implement #must' do
|
44
|
+
receiver = @operand.must
|
45
|
+
receiver.should be_kind_of(
|
46
|
+
Gecode::Int::IntConstraintReceiver)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Requires @operand and @model.
|
51
|
+
describe 'bool var operand', :shared => true do
|
52
|
+
it 'should implement #model' do
|
53
|
+
@operand.model.should be_kind_of(Gecode::Model)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should implement #to_bool_var' do
|
57
|
+
bool_var = @operand.to_bool_var
|
58
|
+
bool_var.should be_kind_of(Gecode::BoolVar)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should implement #must' do
|
62
|
+
receiver = @operand.must
|
63
|
+
receiver.should be_kind_of(
|
64
|
+
Gecode::Bool::BoolConstraintReceiver)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Requires @operand and @model.
|
69
|
+
describe 'set var operand', :shared => true do
|
70
|
+
it 'should implement #model' do
|
71
|
+
@operand.model.should be_kind_of(Gecode::Model)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should implement #to_set_var' do
|
75
|
+
set_var = @operand.to_set_var
|
76
|
+
set_var.should be_kind_of(Gecode::SetVar)
|
77
|
+
@model.solve!
|
78
|
+
((set_var.lower_bound == []) &&
|
79
|
+
(set_var.upper_bound == Gecode::Model::LARGEST_SET_BOUND)).should_not(
|
80
|
+
be_true)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should implement #must' do
|
84
|
+
receiver = @operand.must
|
85
|
+
receiver.should be_kind_of(
|
86
|
+
Gecode::Set::SetConstraintReceiver)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Requires @model, @property_types and @select_property.
|
91
|
+
describe 'property that produces operand', :shared => true do
|
92
|
+
it 'should raise errors if parameters of the incorrect type are given' do
|
93
|
+
operands, variables = produce_general_arguments(@property_types)
|
94
|
+
(1...operands.size).each do |i|
|
95
|
+
bogus_operands = operands.clone
|
96
|
+
bogus_operands[i] = Object.new
|
97
|
+
lambda do
|
98
|
+
@select_property.call(*bogus_operands)
|
99
|
+
end.should raise_error(TypeError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Requires @model, @property_types and @select_property.
|
105
|
+
describe 'property that produces int operand', :shared => true do
|
106
|
+
it 'should produce int operand' do
|
107
|
+
operands, variables = produce_general_arguments(@property_types)
|
108
|
+
operand = @select_property.call(*operands)
|
109
|
+
|
110
|
+
# Test the same invariants as in the test for int var operands.
|
111
|
+
operand.model.should be_kind_of(Gecode::Model)
|
112
|
+
|
113
|
+
int_var = operand.to_int_var
|
114
|
+
int_var.should be_kind_of(Gecode::IntVar)
|
115
|
+
|
116
|
+
receiver = operand.must
|
117
|
+
receiver.should be_kind_of(
|
118
|
+
Gecode::Int::IntConstraintReceiver)
|
119
|
+
end
|
120
|
+
|
121
|
+
it_should_behave_like 'property that produces operand'
|
122
|
+
end
|
123
|
+
|
124
|
+
# Requires @model, @property_types and @select_property.
|
125
|
+
describe 'property that produces bool operand', :shared => true do
|
126
|
+
it 'should produce bool operand' do
|
127
|
+
operands, variables = produce_general_arguments(@property_types)
|
128
|
+
operand = @select_property.call(*operands)
|
129
|
+
|
130
|
+
# Test the same invariants as in the test for bool var operands.
|
131
|
+
operand.model.should be_kind_of(Gecode::Model)
|
132
|
+
|
133
|
+
bool_var = operand.to_bool_var
|
134
|
+
bool_var.should be_kind_of(Gecode::BoolVar)
|
135
|
+
|
136
|
+
receiver = operand.must
|
137
|
+
receiver.should be_kind_of(
|
138
|
+
Gecode::Bool::BoolConstraintReceiver)
|
139
|
+
end
|
140
|
+
|
141
|
+
it_should_behave_like 'property that produces operand'
|
142
|
+
end
|
143
|
+
|
144
|
+
# Requires @model, @property_types and @select_property.
|
145
|
+
describe 'property that produces set operand', :shared => true do
|
146
|
+
it 'should produce set operand' do
|
147
|
+
operands, variables = produce_general_arguments(@property_types)
|
148
|
+
operand = @select_property.call(*operands)
|
149
|
+
|
150
|
+
# Test the same invariants as in the test for int var operands.
|
151
|
+
operand.model.should be_kind_of(Gecode::Model)
|
152
|
+
|
153
|
+
set_var = operand.to_set_var
|
154
|
+
set_var.should be_kind_of(Gecode::SetVar)
|
155
|
+
|
156
|
+
receiver = operand.must
|
157
|
+
receiver.should be_kind_of(
|
158
|
+
Gecode::Set::SetConstraintReceiver)
|
159
|
+
end
|
160
|
+
|
161
|
+
it_should_behave_like 'property that produces operand'
|
162
|
+
end
|
163
|
+
|
164
|
+
# Requires @model, @constraint_class, @property_types, @select_property and
|
165
|
+
# @selected_property.
|
166
|
+
#
|
167
|
+
# These properties should only short circuit equality when there is no
|
168
|
+
# negation nor reification and the right hand side is an int operand.
|
169
|
+
describe 'property that produces int operand by short circuiting equality', :shared => true do
|
170
|
+
it 'should produce constraints when short circuited' do
|
171
|
+
@constraint_class.superclass.should == Gecode::Constraint
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'should give the same solution regardless of whether short circuit was used' do
|
175
|
+
int_operand = @selected_property
|
176
|
+
direct_int_var = int_operand.to_int_var
|
177
|
+
indirect_int_op, _ = general_int_operand(@model)
|
178
|
+
@selected_property.must == indirect_int_op
|
179
|
+
@model.solve!
|
180
|
+
|
181
|
+
direct_int_var.should_not have_domain(Gecode::Model::LARGEST_INT_DOMAIN)
|
182
|
+
direct_int_var.should have_domain(indirect_int_op.domain)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should short circuit equality' do
|
186
|
+
(@selected_property.must == @model.int_var).should(
|
187
|
+
be_kind_of(@constraint_class))
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should not short circuit when negation is used' do
|
191
|
+
(@selected_property.must_not == @model.int_var).should_not(
|
192
|
+
be_kind_of(@constraint_class))
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should not short circuit when reification is used' do
|
196
|
+
@selected_property.must.equal(@model.int_var,
|
197
|
+
:reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should not short circuit when the right hand side is not a operand' do
|
201
|
+
@selected_property.must.equal(2).should_not(be_kind_of(@constraint_class))
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'should not short circuit when equality is not used' do
|
205
|
+
(@selected_property.must > @model.int_var).should_not(
|
206
|
+
be_kind_of(@constraint_class))
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'should raise error when the right hand side is of illegal type' do
|
210
|
+
lambda do
|
211
|
+
@selected_property.must == 'foo'
|
212
|
+
end.should raise_error(TypeError)
|
213
|
+
end
|
214
|
+
|
215
|
+
it_should_behave_like 'property that produces int operand'
|
216
|
+
end
|
217
|
+
|
218
|
+
# Requires @model, @constraint_class, @property_types, @select_property and
|
219
|
+
# @selected_property.
|
220
|
+
#
|
221
|
+
# These properties should only short circuit equality when there is no
|
222
|
+
# negation nor reification and the right hand side is a bool operand.
|
223
|
+
describe 'property that produces bool operand by short circuiting equality', :shared => true do
|
224
|
+
it 'should produce constraints when short circuited' do
|
225
|
+
@constraint_class.superclass.should == Gecode::Constraint
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'should give the same solution regardless of whether short circuit was used' do
|
229
|
+
bool_operand = @selected_property
|
230
|
+
direct_bool_var = bool_operand.to_bool_var
|
231
|
+
indirect_bool_var = @model.bool_var
|
232
|
+
@selected_property.must == indirect_bool_var
|
233
|
+
@model.solve!
|
234
|
+
|
235
|
+
direct_bool_var.value.should == indirect_bool_var.value
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should short circuit equality' do
|
239
|
+
(@selected_property.must == @model.bool_var).should(
|
240
|
+
be_kind_of(@constraint_class))
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should not short circuit when negation is used' do
|
244
|
+
(@selected_property.must_not == @model.bool_var).should_not(
|
245
|
+
be_kind_of(@constraint_class))
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'should not short circuit when reification is used' do
|
249
|
+
@selected_property.must.equal(@model.bool_var,
|
250
|
+
:reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'should not short circuit when equality is not used' do
|
254
|
+
(@selected_property.must.imply @model.bool_var).should_not(
|
255
|
+
be_kind_of(@constraint_class))
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'should raise error when the right hand side is of illegal type' do
|
259
|
+
lambda do
|
260
|
+
@selected_property.must == 'foo'
|
261
|
+
end.should raise_error(TypeError)
|
262
|
+
end
|
263
|
+
|
264
|
+
it_should_behave_like 'property that produces bool operand'
|
265
|
+
end
|
266
|
+
|
267
|
+
# Requires @model, @constraint_class, @property_types and @select_property.
|
268
|
+
#
|
269
|
+
# These properties should short circuit all comparison relations
|
270
|
+
# even when negated and when fixnums are used as right hand side.
|
271
|
+
describe 'property that produces int operand by short circuiting relations', :shared => true do
|
272
|
+
it 'should produce reifiable constraints when short circuited' do
|
273
|
+
@constraint_class.superclass.should ==
|
274
|
+
Gecode::ReifiableConstraint
|
275
|
+
end
|
276
|
+
|
277
|
+
Gecode::Util::RELATION_TYPES.keys.each do |relation|
|
278
|
+
it "should give the same solution regardless of whether short circuit #{relation} was used" do
|
279
|
+
direct_int_var = @model.int_var
|
280
|
+
@selected_property.to_int_var.must.method(relation).call direct_int_var
|
281
|
+
indirect_int_var = @model.int_var
|
282
|
+
@selected_property.must.method(relation).call indirect_int_var
|
283
|
+
@model.solve!
|
284
|
+
|
285
|
+
direct_int_var.should_not have_domain(Gecode::Model::LARGEST_INT_DOMAIN)
|
286
|
+
direct_int_var.should have_domain(indirect_int_var.domain)
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should short circuit #{relation}" do
|
290
|
+
(@selected_property.must.method(relation).call @model.int_var).should(
|
291
|
+
be_kind_of(@constraint_class))
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should short circuit negated #{relation}" do
|
295
|
+
(@selected_property.must_not.method(relation).call @model.int_var).should(
|
296
|
+
be_kind_of(@constraint_class))
|
297
|
+
end
|
298
|
+
|
299
|
+
it "should short circuit #{relation} when reification is used" do
|
300
|
+
(@selected_property.must.method(relation).call(@model.int_var,
|
301
|
+
:reify => @model.bool_var)).should(be_kind_of(@constraint_class))
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should short circuit #{relation} even when the right hand side is a fixnum" do
|
305
|
+
(@selected_property.must.method(relation).call 2).should(
|
306
|
+
be_kind_of(@constraint_class))
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should raise error when the #{relation} right hand side is of illegal type" do
|
310
|
+
lambda do
|
311
|
+
@selected_property.must.method(relation).call('foo')
|
312
|
+
end.should raise_error(TypeError)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
it_should_behave_like 'property that produces int operand'
|
317
|
+
end
|
318
|
+
|
319
|
+
# Requires @model, @constraint_class, @property_types, @select_property and
|
320
|
+
# @selected_property.
|
321
|
+
#
|
322
|
+
# These properties should only short circuit equality when there is no
|
323
|
+
# negation nor reification and the right hand side is a set operand.
|
324
|
+
describe 'property that produces set operand by short circuiting equality', :shared => true do
|
325
|
+
it 'should produce constraints when short circuited' do
|
326
|
+
@constraint_class.superclass.should == Gecode::Constraint
|
327
|
+
end
|
328
|
+
|
329
|
+
it 'should give the same solution regardless of whether short circuit was used' do
|
330
|
+
set_operand = @selected_property
|
331
|
+
direct_set_var = set_operand.to_set_var
|
332
|
+
indirect_set_var = @model.set_var
|
333
|
+
@selected_property.must == indirect_set_var
|
334
|
+
@model.solve!
|
335
|
+
|
336
|
+
direct_set_var.should have_bounds(indirect_set_var.lower_bound,
|
337
|
+
indirect_set_var.upper_bound)
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'should short circuit equality' do
|
341
|
+
(@selected_property.must == @model.set_var).should(
|
342
|
+
be_kind_of(@constraint_class))
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'should not short circuit when negation is used' do
|
346
|
+
(@selected_property.must_not == @model.set_var).should_not(
|
347
|
+
be_kind_of(@constraint_class))
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'should not short circuit when reification is used' do
|
351
|
+
(@selected_property.must.equal(@model.set_var,
|
352
|
+
:reify => @model.bool_var)).should_not(be_kind_of(@constraint_class))
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'should not short circuit when the right hand side is not a operand' do
|
356
|
+
(@selected_property.must == [1,3,5]).should_not(
|
357
|
+
be_kind_of(@constraint_class))
|
358
|
+
end
|
359
|
+
|
360
|
+
it 'should not short circuit when equality is not used' do
|
361
|
+
(@selected_property.must_be.subset_of(@model.set_var)).should_not(
|
362
|
+
be_kind_of(@constraint_class))
|
363
|
+
end
|
364
|
+
|
365
|
+
it 'should raise error when the right hand side is of illegal type' do
|
366
|
+
lambda do
|
367
|
+
@selected_property.must == 'foo'
|
368
|
+
end.should raise_error(TypeError)
|
369
|
+
end
|
370
|
+
|
371
|
+
it_should_behave_like 'property that produces set operand'
|
372
|
+
end
|
373
|
+
|
374
|
+
# Requires @model, @constraint_class, @property_types and @select_property.
|
375
|
+
#
|
376
|
+
# These properties should only short circuit set relations when neither
|
377
|
+
# negation nor reification is used (both for constant sets and set
|
378
|
+
# variables).
|
379
|
+
describe 'property that produces set operand by short circuiting set relations', :shared => true do
|
380
|
+
Gecode::Util::SET_RELATION_TYPES.keys.each do |relation|
|
381
|
+
it 'should produce constraints when short circuited' do
|
382
|
+
@constraint_class.superclass.should == Gecode::Constraint
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should give the same solution regardless of whether short circuit #{relation} was used" do
|
386
|
+
if relation == :complement
|
387
|
+
direct_set_var, indirect_set_var = Array.new(2){ @model.set_var }
|
388
|
+
else
|
389
|
+
direct_set_var, indirect_set_var = Array.new(2) do
|
390
|
+
@model.set_var([], -1000..1000)
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
@selected_property.to_set_var.must.method(relation).call direct_set_var
|
395
|
+
@selected_property.must.method(relation).call indirect_set_var
|
396
|
+
@model.solve!
|
397
|
+
|
398
|
+
if relation == :complement
|
399
|
+
direct_set_var.upper_bound.min.should ==
|
400
|
+
indirect_set_var.upper_bound.min
|
401
|
+
direct_set_var.upper_bound.max.should ==
|
402
|
+
indirect_set_var.upper_bound.max
|
403
|
+
direct_set_var.lower_bound.min.should ==
|
404
|
+
indirect_set_var.lower_bound.min
|
405
|
+
direct_set_var.lower_bound.max.should ==
|
406
|
+
indirect_set_var.lower_bound.max
|
407
|
+
direct_set_var.lower_bound.size.should ==
|
408
|
+
indirect_set_var.lower_bound.size
|
409
|
+
else
|
410
|
+
direct_set_var.should have_bounds(indirect_set_var.lower_bound,
|
411
|
+
indirect_set_var.upper_bound)
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
it "should short circuit #{relation}" do
|
416
|
+
@selected_property.must.method(relation).call(@model.set_var).should(
|
417
|
+
be_kind_of(@constraint_class))
|
418
|
+
end
|
419
|
+
|
420
|
+
it "should not short circuit negated #{relation}" do
|
421
|
+
@selected_property.must_not.method(relation).call(
|
422
|
+
@model.set_var).should_not(be_kind_of(@constraint_class))
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should not short circuit reified #{relation}" do
|
426
|
+
@selected_property.must.method(relation).call(@model.set_var,
|
427
|
+
:reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
|
428
|
+
end
|
429
|
+
|
430
|
+
it "should short circuit #{relation} even when the right hand side is a constant set" do
|
431
|
+
@selected_property.must.method(relation).call([1, 2, 3]).should(
|
432
|
+
be_kind_of(@constraint_class))
|
433
|
+
end
|
434
|
+
|
435
|
+
it "should raise error when the #{relation} right hand side is of illegal type" do
|
436
|
+
lambda do
|
437
|
+
@selected_property.must.method(relation).call('foo')
|
438
|
+
end.should raise_error(TypeError)
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
it_should_behave_like 'property that produces set operand'
|
443
|
+
end
|