gecoder-with-gecode 0.7.1-mswin32
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 +81 -0
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +45 -0
- data/Rakefile +13 -0
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/queens.rb +43 -0
- data/example/raw_bindings.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 +110 -0
- data/example/sudoku.rb +61 -0
- data/lib/gecode.dll +0 -0
- data/lib/gecoder.rb +5 -0
- data/lib/gecoder/bindings.rb +54 -0
- data/lib/gecoder/bindings/bindings.rb +2210 -0
- data/lib/gecoder/interface.rb +8 -0
- data/lib/gecoder/interface/binding_changes.rb +313 -0
- data/lib/gecoder/interface/branch.rb +152 -0
- data/lib/gecoder/interface/constraints.rb +397 -0
- data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
- data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
- data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
- data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
- data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
- data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
- data/lib/gecoder/interface/enum_matrix.rb +64 -0
- data/lib/gecoder/interface/enum_wrapper.rb +153 -0
- data/lib/gecoder/interface/model.rb +251 -0
- data/lib/gecoder/interface/search.rb +123 -0
- data/lib/gecoder/interface/variables.rb +254 -0
- data/lib/gecoder/version.rb +4 -0
- data/specs/binding_changes.rb +76 -0
- data/specs/bool_var.rb +74 -0
- data/specs/branch.rb +170 -0
- data/specs/constraints/arithmetic.rb +266 -0
- data/specs/constraints/bool_enum.rb +140 -0
- data/specs/constraints/boolean.rb +232 -0
- data/specs/constraints/cardinality.rb +154 -0
- data/specs/constraints/channel.rb +126 -0
- data/specs/constraints/connection.rb +373 -0
- data/specs/constraints/constraint_helper.rb +180 -0
- data/specs/constraints/constraints.rb +74 -0
- data/specs/constraints/count.rb +139 -0
- data/specs/constraints/distinct.rb +218 -0
- data/specs/constraints/element.rb +106 -0
- data/specs/constraints/equality.rb +31 -0
- data/specs/constraints/int_domain.rb +69 -0
- data/specs/constraints/int_relation.rb +78 -0
- data/specs/constraints/linear.rb +332 -0
- data/specs/constraints/reification_sugar.rb +96 -0
- data/specs/constraints/selection.rb +292 -0
- data/specs/constraints/set_domain.rb +181 -0
- data/specs/constraints/set_operation.rb +285 -0
- data/specs/constraints/set_relation.rb +201 -0
- data/specs/constraints/sort.rb +175 -0
- data/specs/distribution.rb +14 -0
- data/specs/enum_matrix.rb +43 -0
- data/specs/enum_wrapper.rb +122 -0
- data/specs/int_var.rb +144 -0
- data/specs/logging.rb +24 -0
- data/specs/model.rb +190 -0
- data/specs/search.rb +246 -0
- data/specs/set_var.rb +68 -0
- data/specs/spec_helper.rb +93 -0
- data/tasks/all_tasks.rb +1 -0
- data/tasks/building.howto +65 -0
- data/tasks/distribution.rake +156 -0
- data/tasks/rcov.rake +17 -0
- data/tasks/specs.rake +15 -0
- data/tasks/svn.rake +11 -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/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +115 -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 +339 -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 +98 -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 +91 -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 +293 -0
@@ -0,0 +1,154 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
describe Gecode::Constraints::Set::Cardinality, ' (range)' do
|
5
|
+
before do
|
6
|
+
@model = Gecode::Model.new
|
7
|
+
@set = @model.set_var([], 0..10)
|
8
|
+
@model.branch_on @model.wrap_enum([@set])
|
9
|
+
@range = 1..2
|
10
|
+
@three_dot_range = 1...2
|
11
|
+
|
12
|
+
@invoke_options = lambda do |hash|
|
13
|
+
@set.size.must_be.in(@range, hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
@invoke = lambda do |rhs|
|
17
|
+
@set.size.must_be.in(rhs)
|
18
|
+
@model.solve!
|
19
|
+
end
|
20
|
+
@expect = lambda do |rhs|
|
21
|
+
@model.allow_space_access do
|
22
|
+
Gecode::Raw.should_receive(:cardinality).once.with(
|
23
|
+
an_instance_of(Gecode::Raw::Space),
|
24
|
+
an_instance_of(Gecode::Raw::SetVar), rhs.first, rhs.last)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should translate cardinality constraints with ranges' do
|
30
|
+
@expect.call(@range)
|
31
|
+
@invoke.call(@range)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should translate cardinality constraints with three dot range domains' do
|
35
|
+
@expect.call(@three_dot_range)
|
36
|
+
@invoke.call(@three_dot_range)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should constrain the cardinality of a set' do
|
40
|
+
@set.size.must_be.in @range
|
41
|
+
@model.solve!
|
42
|
+
@range.should include(@set.value.size)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should raise error if the right hand side is not a range' do
|
46
|
+
lambda{ @set.size.must_be.in 'hello' }.should raise_error(TypeError)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should not shadow the integer variable domain constrain' do
|
50
|
+
Gecode::Raw.should_receive(:dom).with(
|
51
|
+
an_instance_of(Gecode::Raw::Space),
|
52
|
+
an_instance_of(Gecode::Raw::IntVar), 0, 11, Gecode::Raw::ICL_DEF)
|
53
|
+
Gecode::Raw.should_receive(:dom).with(
|
54
|
+
an_instance_of(Gecode::Raw::Space),
|
55
|
+
an_instance_of(Gecode::Raw::IntVar), an_instance_of(Gecode::Raw::IntSet),
|
56
|
+
an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF)
|
57
|
+
@set.size.must_not_be.in [1,3]
|
58
|
+
@model.solve!
|
59
|
+
end
|
60
|
+
|
61
|
+
it_should_behave_like 'non-reifiable set constraint'
|
62
|
+
end
|
63
|
+
|
64
|
+
describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
|
65
|
+
before do
|
66
|
+
@model = Gecode::Model.new
|
67
|
+
@set = @model.set_var([], 0..10)
|
68
|
+
@target = @var = @model.int_var(0..11)
|
69
|
+
@model.branch_on @model.wrap_enum([@set])
|
70
|
+
@model.branch_on @model.wrap_enum([@var])
|
71
|
+
|
72
|
+
@invoke = lambda do |rhs|
|
73
|
+
@set.size.must == rhs
|
74
|
+
@model.solve!
|
75
|
+
end
|
76
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
77
|
+
@model.allow_space_access do
|
78
|
+
rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
|
79
|
+
if reif_var.nil?
|
80
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
81
|
+
!rhs.kind_of? Fixnum
|
82
|
+
Gecode::Raw.should_receive(:cardinality).once.with(
|
83
|
+
an_instance_of(Gecode::Raw::Space),
|
84
|
+
an_instance_of(Gecode::Raw::SetVar), rhs)
|
85
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
86
|
+
else
|
87
|
+
Gecode::Raw.should_receive(:cardinality).once.with(
|
88
|
+
an_instance_of(Gecode::Raw::Space),
|
89
|
+
an_instance_of(Gecode::Raw::SetVar),
|
90
|
+
an_instance_of(Gecode::Raw::IntVar))
|
91
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
92
|
+
an_instance_of(Gecode::Raw::Space),
|
93
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
94
|
+
strength)
|
95
|
+
end
|
96
|
+
else
|
97
|
+
Gecode::Raw.should_receive(:cardinality).once.with(
|
98
|
+
an_instance_of(Gecode::Raw::Space),
|
99
|
+
an_instance_of(Gecode::Raw::SetVar),
|
100
|
+
an_instance_of(Gecode::Raw::IntVar))
|
101
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
102
|
+
an_instance_of(Gecode::Raw::Space),
|
103
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
104
|
+
an_instance_of(Gecode::Raw::BoolVar),
|
105
|
+
strength)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# For composite spec.
|
111
|
+
@invoke_relation = lambda do |relation, target, negated|
|
112
|
+
if negated
|
113
|
+
@set.size.must_not.send(relation, target)
|
114
|
+
else
|
115
|
+
@set.size.must.send(relation, target)
|
116
|
+
end
|
117
|
+
@model.solve!
|
118
|
+
end
|
119
|
+
@expect_relation = lambda do |relation, target, negated|
|
120
|
+
@expect.call(relation, target, Gecode::Raw::ICL_DEF, nil, negated)
|
121
|
+
end
|
122
|
+
|
123
|
+
# For options spec.
|
124
|
+
@invoke_options = lambda do |hash|
|
125
|
+
@set.size.must_be.less_than_or_equal_to(17, hash)
|
126
|
+
@model.solve!
|
127
|
+
end
|
128
|
+
@expect_options = lambda do |strength, reif_var|
|
129
|
+
@expect.call(Gecode::Raw::IRT_LQ, 17, strength, reif_var, false)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should constrain the cardinality of a set' do
|
134
|
+
@set.size.must == @var
|
135
|
+
@model.solve!
|
136
|
+
@set.value.size.should == @var.value
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should constrain the cardinality of a set (2)' do
|
140
|
+
@set.size.must == 2
|
141
|
+
@model.solve!.should_not be_nil
|
142
|
+
@set.value.size.should == 2
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should constrain the cardinality of a set (3)' do
|
146
|
+
@set.size.must == @var
|
147
|
+
@var.must == 2
|
148
|
+
@model.solve!
|
149
|
+
@set.value.size.should == 2
|
150
|
+
end
|
151
|
+
|
152
|
+
it_should_behave_like 'constraint with options'
|
153
|
+
it_should_behave_like 'composite constraint'
|
154
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
class ChannelSampleProblem < Gecode::Model
|
5
|
+
attr :elements
|
6
|
+
attr :positions
|
7
|
+
attr :sets
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@elements = int_var_array(4, 0..3)
|
11
|
+
@elements.must_be.distinct
|
12
|
+
@positions = int_var_array(4, 0..3)
|
13
|
+
@positions.must_be.distinct
|
14
|
+
@sets = set_var_array(4, [], 0..3)
|
15
|
+
branch_on @positions
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Gecode::Constraints::IntEnum::Channel, ' (two int enums)' do
|
20
|
+
before do
|
21
|
+
@model = ChannelSampleProblem.new
|
22
|
+
@positions = @model.positions
|
23
|
+
@elements = @model.elements
|
24
|
+
@invoke_options = lambda do |hash|
|
25
|
+
@positions.must.channel @elements, hash
|
26
|
+
@model.solve!
|
27
|
+
end
|
28
|
+
@expect_options = lambda do |strength, reif_var|
|
29
|
+
Gecode::Raw.should_receive(:channel).once.with(
|
30
|
+
an_instance_of(Gecode::Raw::Space),
|
31
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
32
|
+
an_instance_of(Gecode::Raw::IntVarArray), strength)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should translate into a channel constraint' do
|
37
|
+
Gecode::Raw.should_receive(:channel).once.with(
|
38
|
+
an_instance_of(Gecode::Raw::Space),
|
39
|
+
anything, anything, Gecode::Raw::ICL_DEF)
|
40
|
+
@invoke_options.call({})
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should constrain variables to be channelled' do
|
44
|
+
@elements.must.channel @positions
|
45
|
+
@model.solve!
|
46
|
+
elements = @model.elements.values
|
47
|
+
positions = @model.elements.values
|
48
|
+
elements.each_with_index do |element, i|
|
49
|
+
element.should equal(positions.index(i))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should not allow negation' do
|
54
|
+
lambda{ @elements.must_not.channel @positions }.should raise_error(
|
55
|
+
Gecode::MissingConstraintError)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should raise error for unsupported right hand sides' do
|
59
|
+
lambda{ @elements.must.channel 'hello' }.should raise_error(TypeError)
|
60
|
+
end
|
61
|
+
|
62
|
+
it_should_behave_like 'constraint with strength option'
|
63
|
+
end
|
64
|
+
|
65
|
+
describe Gecode::Constraints::IntEnum::Channel, ' (one int enum and one set enum)' do
|
66
|
+
before do
|
67
|
+
@model = ChannelSampleProblem.new
|
68
|
+
@positions = @model.positions
|
69
|
+
@sets = @model.sets
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should translate into a channel constraint' do
|
73
|
+
Gecode::Raw.should_receive(:channel).once.with(
|
74
|
+
an_instance_of(Gecode::Raw::Space),
|
75
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
76
|
+
an_instance_of(Gecode::Raw::SetVarArray))
|
77
|
+
@positions.must.channel @sets
|
78
|
+
@model.solve!
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should constrain variables to be channelled' do
|
82
|
+
@positions.must.channel @sets
|
83
|
+
@model.solve!
|
84
|
+
sets = @model.sets
|
85
|
+
positions = @model.positions.values
|
86
|
+
positions.each_with_index do |position, i|
|
87
|
+
sets[position].value.should include(i)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe Gecode::Constraints::SetEnum, ' (channel with set as left hand side)' do
|
93
|
+
before do
|
94
|
+
@model = ChannelSampleProblem.new
|
95
|
+
@positions = @model.positions
|
96
|
+
@sets = @model.sets
|
97
|
+
|
98
|
+
@invoke_options = lambda do |hash|
|
99
|
+
@sets.must.channel @positions, hash
|
100
|
+
@model.solve!
|
101
|
+
end
|
102
|
+
@expect_options = lambda do |strength, reif_var|
|
103
|
+
Gecode::Raw.should_receive(:channel).once.with(
|
104
|
+
an_instance_of(Gecode::Raw::Space),
|
105
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
106
|
+
an_instance_of(Gecode::Raw::SetVarArray))
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should translate into a channel constraint' do
|
111
|
+
@expect_options.call(Gecode::Raw::ICL_DEF, nil)
|
112
|
+
@sets.must.channel @positions
|
113
|
+
@model.solve!
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should not allow negation' do
|
117
|
+
lambda{ @sets.must_not.channel @positions }.should raise_error(
|
118
|
+
Gecode::MissingConstraintError)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should raise error for unsupported right hand sides' do
|
122
|
+
lambda{ @sets.must.channel 'hello' }.should raise_error(TypeError)
|
123
|
+
end
|
124
|
+
|
125
|
+
it_should_behave_like 'non-reifiable set constraint'
|
126
|
+
end
|
@@ -0,0 +1,373 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
# Requires @expect, @model, @stub, @target.
|
5
|
+
describe 'connection constraint', :shared => true do
|
6
|
+
before do
|
7
|
+
@invoke = lambda do |rhs|
|
8
|
+
@stub.must == rhs
|
9
|
+
@model.solve!
|
10
|
+
end
|
11
|
+
|
12
|
+
# For composite spec.
|
13
|
+
@invoke_relation = lambda do |relation, target, negated|
|
14
|
+
if negated
|
15
|
+
@stub.must_not.send(relation, target)
|
16
|
+
else
|
17
|
+
@stub.must.send(relation, target)
|
18
|
+
end
|
19
|
+
@model.solve!
|
20
|
+
end
|
21
|
+
@expect_relation = lambda do |relation, target, negated|
|
22
|
+
@expect.call(relation, target, Gecode::Raw::ICL_DEF, nil, negated)
|
23
|
+
end
|
24
|
+
|
25
|
+
# For options spec.
|
26
|
+
@invoke_options = lambda do |hash|
|
27
|
+
@stub.must_be.less_than_or_equal_to(17, hash)
|
28
|
+
@model.solve!
|
29
|
+
end
|
30
|
+
@expect_options = lambda do |strength, reif_var|
|
31
|
+
@expect.call(Gecode::Raw::IRT_LQ, 17, strength, reif_var, false)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it_should_behave_like 'constraint with options'
|
36
|
+
it_should_behave_like 'composite constraint'
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Gecode::Constraints::Set::Connection, ' (min)' do
|
40
|
+
before do
|
41
|
+
@model = Gecode::Model.new
|
42
|
+
@set = @model.set_var([], 0..9)
|
43
|
+
@target = @var = @model.int_var(0..10)
|
44
|
+
@model.branch_on @model.wrap_enum([@set])
|
45
|
+
@stub = @set.min
|
46
|
+
|
47
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
48
|
+
@model.allow_space_access do
|
49
|
+
rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
|
50
|
+
if reif_var.nil?
|
51
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
52
|
+
!rhs.kind_of? Fixnum
|
53
|
+
Gecode::Raw.should_receive(:min).once.with(
|
54
|
+
an_instance_of(Gecode::Raw::Space),
|
55
|
+
an_instance_of(Gecode::Raw::SetVar), rhs)
|
56
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
57
|
+
else
|
58
|
+
Gecode::Raw.should_receive(:min).once.with(
|
59
|
+
an_instance_of(Gecode::Raw::Space),
|
60
|
+
an_instance_of(Gecode::Raw::SetVar),
|
61
|
+
an_instance_of(Gecode::Raw::IntVar))
|
62
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
63
|
+
an_instance_of(Gecode::Raw::Space),
|
64
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
65
|
+
strength)
|
66
|
+
end
|
67
|
+
else
|
68
|
+
Gecode::Raw.should_receive(:min).once.with(
|
69
|
+
an_instance_of(Gecode::Raw::Space),
|
70
|
+
an_instance_of(Gecode::Raw::SetVar),
|
71
|
+
an_instance_of(Gecode::Raw::IntVar))
|
72
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
73
|
+
an_instance_of(Gecode::Raw::Space),
|
74
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
75
|
+
an_instance_of(Gecode::Raw::BoolVar),
|
76
|
+
strength)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should constrain the min of a set' do
|
83
|
+
@set.min.must == 3
|
84
|
+
@model.solve!
|
85
|
+
@set.lower_bound.min.should == 3
|
86
|
+
end
|
87
|
+
|
88
|
+
it_should_behave_like 'connection constraint'
|
89
|
+
end
|
90
|
+
|
91
|
+
describe Gecode::Constraints::Set::Connection, ' (max)' do
|
92
|
+
before do
|
93
|
+
@model = Gecode::Model.new
|
94
|
+
@set = @model.set_var([], 0..9)
|
95
|
+
@target = @var = @model.int_var(0..10)
|
96
|
+
@model.branch_on @model.wrap_enum([@set])
|
97
|
+
@stub = @set.max
|
98
|
+
|
99
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
100
|
+
@model.allow_space_access do
|
101
|
+
rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
|
102
|
+
if reif_var.nil?
|
103
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
104
|
+
!rhs.kind_of? Fixnum
|
105
|
+
Gecode::Raw.should_receive(:max).once.with(
|
106
|
+
an_instance_of(Gecode::Raw::Space),
|
107
|
+
an_instance_of(Gecode::Raw::SetVar), rhs)
|
108
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
109
|
+
else
|
110
|
+
Gecode::Raw.should_receive(:max).once.with(
|
111
|
+
an_instance_of(Gecode::Raw::Space),
|
112
|
+
an_instance_of(Gecode::Raw::SetVar),
|
113
|
+
an_instance_of(Gecode::Raw::IntVar))
|
114
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
115
|
+
an_instance_of(Gecode::Raw::Space),
|
116
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
117
|
+
strength)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
Gecode::Raw.should_receive(:max).once.with(
|
121
|
+
an_instance_of(Gecode::Raw::Space),
|
122
|
+
an_instance_of(Gecode::Raw::SetVar),
|
123
|
+
an_instance_of(Gecode::Raw::IntVar))
|
124
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
125
|
+
an_instance_of(Gecode::Raw::Space),
|
126
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
127
|
+
an_instance_of(Gecode::Raw::BoolVar),
|
128
|
+
strength)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should constrain the max of a set' do
|
135
|
+
@set.max.must == 3
|
136
|
+
@model.solve!
|
137
|
+
@set.lower_bound.max.should == 3
|
138
|
+
end
|
139
|
+
|
140
|
+
it_should_behave_like 'connection constraint'
|
141
|
+
end
|
142
|
+
|
143
|
+
describe Gecode::Constraints::Set::Connection, ' (sum)' do
|
144
|
+
before do
|
145
|
+
@model = Gecode::Model.new
|
146
|
+
@set = @model.set_var([], 0..9)
|
147
|
+
@target = @var = @model.int_var(0..20)
|
148
|
+
@model.branch_on @model.wrap_enum([@set])
|
149
|
+
@stub = @set.sum
|
150
|
+
|
151
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
152
|
+
@model.allow_space_access do
|
153
|
+
rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
|
154
|
+
if reif_var.nil?
|
155
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
156
|
+
!rhs.kind_of? Fixnum
|
157
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
158
|
+
an_instance_of(Gecode::Raw::Space), anything, anything,
|
159
|
+
an_instance_of(Gecode::Raw::SetVar),
|
160
|
+
rhs)
|
161
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
162
|
+
else
|
163
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
164
|
+
an_instance_of(Gecode::Raw::Space), anything, anything,
|
165
|
+
an_instance_of(Gecode::Raw::SetVar),
|
166
|
+
an_instance_of(Gecode::Raw::IntVar))
|
167
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
168
|
+
an_instance_of(Gecode::Raw::Space),
|
169
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
170
|
+
strength)
|
171
|
+
end
|
172
|
+
else
|
173
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
174
|
+
an_instance_of(Gecode::Raw::Space),
|
175
|
+
anything, anything, an_instance_of(Gecode::Raw::SetVar),
|
176
|
+
an_instance_of(Gecode::Raw::IntVar))
|
177
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
178
|
+
an_instance_of(Gecode::Raw::Space),
|
179
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
180
|
+
an_instance_of(Gecode::Raw::BoolVar),
|
181
|
+
strength)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'should constrain the sum of a set' do
|
188
|
+
@set.sum.must == 7
|
189
|
+
@model.solve!.should_not be_nil
|
190
|
+
@set.value.inject(0){ |x, y| x + y }.should == 7
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should raise error if unsupported options is given' do
|
194
|
+
lambda do
|
195
|
+
@set.sum(:does_not_exist => :foo).must == @var
|
196
|
+
end.should raise_error(ArgumentError)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should raise error if multiple options are given' do
|
200
|
+
lambda do
|
201
|
+
@set.sum(:weights => {}, :substitutions => {}).must == @var
|
202
|
+
end.should raise_error(ArgumentError)
|
203
|
+
end
|
204
|
+
|
205
|
+
it_should_behave_like 'connection constraint'
|
206
|
+
end
|
207
|
+
|
208
|
+
describe Gecode::Constraints::Set::Connection, ' (sum with weights)' do
|
209
|
+
before do
|
210
|
+
@model = Gecode::Model.new
|
211
|
+
@set = @model.set_var([], 0..9)
|
212
|
+
@target = @var = @model.int_var(-20..20)
|
213
|
+
@model.branch_on @model.wrap_enum([@set])
|
214
|
+
@weights = Hash[*(0..9).zip((-9..-0).to_a.reverse).flatten]
|
215
|
+
@stub = @set.sum(:weights => @weights)
|
216
|
+
|
217
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
218
|
+
@model.allow_space_access do
|
219
|
+
rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
|
220
|
+
if reif_var.nil?
|
221
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
222
|
+
!rhs.kind_of? Fixnum
|
223
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
224
|
+
an_instance_of(Gecode::Raw::Space), anything, anything,
|
225
|
+
an_instance_of(Gecode::Raw::SetVar), rhs)
|
226
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
227
|
+
else
|
228
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
229
|
+
an_instance_of(Gecode::Raw::Space), anything, anything,
|
230
|
+
an_instance_of(Gecode::Raw::SetVar),
|
231
|
+
an_instance_of(Gecode::Raw::IntVar))
|
232
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
233
|
+
an_instance_of(Gecode::Raw::Space),
|
234
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
235
|
+
strength)
|
236
|
+
end
|
237
|
+
else
|
238
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
239
|
+
an_instance_of(Gecode::Raw::Space),
|
240
|
+
anything, anything, an_instance_of(Gecode::Raw::SetVar),
|
241
|
+
an_instance_of(Gecode::Raw::IntVar))
|
242
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
243
|
+
an_instance_of(Gecode::Raw::Space),
|
244
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
245
|
+
an_instance_of(Gecode::Raw::BoolVar),
|
246
|
+
strength)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should constrain the sum of a set' do
|
253
|
+
@stub.must_be.in(-10..-1)
|
254
|
+
@model.solve!.should_not be_nil
|
255
|
+
weighted_sum = @set.value.inject(0){ |sum, x| sum - x**2 }
|
256
|
+
weighted_sum.should >= -10
|
257
|
+
weighted_sum.should <= -1
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'should remove any elements not in the weight hash' do
|
261
|
+
@set.sum(:weights => {}).must_be == 0
|
262
|
+
@model.solve!.should_not be_nil
|
263
|
+
@set.value.size.should be_zero
|
264
|
+
end
|
265
|
+
|
266
|
+
it_should_behave_like 'connection constraint'
|
267
|
+
end
|
268
|
+
|
269
|
+
describe Gecode::Constraints::Set::Connection, ' (sum with substitutions)' do
|
270
|
+
before do
|
271
|
+
@model = Gecode::Model.new
|
272
|
+
@set = @model.set_var([], 0..9)
|
273
|
+
@target = @var = @model.int_var(-20..20)
|
274
|
+
@model.branch_on @model.wrap_enum([@set])
|
275
|
+
@subs = Hash[*(0..9).zip((-9..-0).to_a.reverse).flatten]
|
276
|
+
@stub = @set.sum(:substitutions => @subs)
|
277
|
+
|
278
|
+
@expect = lambda do |relation, rhs, strength, reif_var, negated|
|
279
|
+
@model.allow_space_access do
|
280
|
+
rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
|
281
|
+
if reif_var.nil?
|
282
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
283
|
+
!rhs.kind_of? Fixnum
|
284
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
285
|
+
an_instance_of(Gecode::Raw::Space), anything, anything,
|
286
|
+
an_instance_of(Gecode::Raw::SetVar), rhs)
|
287
|
+
Gecode::Raw.should_receive(:rel).exactly(0).times
|
288
|
+
else
|
289
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
290
|
+
an_instance_of(Gecode::Raw::Space), anything, anything,
|
291
|
+
an_instance_of(Gecode::Raw::SetVar),
|
292
|
+
an_instance_of(Gecode::Raw::IntVar))
|
293
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
294
|
+
an_instance_of(Gecode::Raw::Space),
|
295
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
296
|
+
strength)
|
297
|
+
end
|
298
|
+
else
|
299
|
+
Gecode::Raw.should_receive(:weights).once.with(
|
300
|
+
an_instance_of(Gecode::Raw::Space),
|
301
|
+
anything, anything, an_instance_of(Gecode::Raw::SetVar),
|
302
|
+
an_instance_of(Gecode::Raw::IntVar))
|
303
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
304
|
+
an_instance_of(Gecode::Raw::Space),
|
305
|
+
an_instance_of(Gecode::Raw::IntVar), relation, rhs,
|
306
|
+
an_instance_of(Gecode::Raw::BoolVar),
|
307
|
+
strength)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'should constrain the sum of a set' do
|
314
|
+
@stub.must_be.in(-10..-1)
|
315
|
+
@model.solve!.should_not be_nil
|
316
|
+
substituted_sum = @set.value.inject{ |sum, x| sum + @subs[x] }
|
317
|
+
substituted_sum.should >= -10
|
318
|
+
substituted_sum.should <= -1
|
319
|
+
end
|
320
|
+
|
321
|
+
it_should_behave_like 'connection constraint'
|
322
|
+
end
|
323
|
+
|
324
|
+
describe Gecode::Constraints::Set::Connection, ' (include)' do
|
325
|
+
before do
|
326
|
+
@model = Gecode::Model.new
|
327
|
+
@set = @model.set_var([], 2..5)
|
328
|
+
@array = @model.int_var_array(4, 0..9)
|
329
|
+
@array.must_be.distinct
|
330
|
+
@model.branch_on @array
|
331
|
+
#@model.branch_on @model.wrap_enum([@set])
|
332
|
+
|
333
|
+
@expect = lambda do |rhs, strength, reif_var|
|
334
|
+
@model.allow_space_access do
|
335
|
+
Gecode::Raw.should_receive(:match).once.with(
|
336
|
+
an_instance_of(Gecode::Raw::Space),
|
337
|
+
an_instance_of(Gecode::Raw::SetVar),
|
338
|
+
an_instance_of(Gecode::Raw::IntVarArray))
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
@expect_options = lambda do |strength, reif_var|
|
343
|
+
@expect.call(@array, strength, reif_var)
|
344
|
+
end
|
345
|
+
@invoke_options = lambda do |hash|
|
346
|
+
@set.must.include(@array, hash)
|
347
|
+
@model.solve!
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'should translate to a match constraint' do
|
352
|
+
@expect_options.call(Gecode::Raw::ICL_DEF, nil)
|
353
|
+
@set.must.include @array
|
354
|
+
@model.solve!
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'should constrain the variables to be included in the set' do
|
358
|
+
@set.must.include @array
|
359
|
+
@model.solve!.should_not be_nil
|
360
|
+
@array.all?{ |x| @set.lower_bound.include? x.value }.should be_true
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'should raise error if the right hand side is not an array of variables' do
|
364
|
+
lambda{ @set.must.include 'hello' }.should raise_error(TypeError)
|
365
|
+
end
|
366
|
+
|
367
|
+
it 'should raise error if negated' do
|
368
|
+
lambda{ @set.must_not.include @array }.should raise_error(
|
369
|
+
Gecode::MissingConstraintError)
|
370
|
+
end
|
371
|
+
|
372
|
+
it_should_behave_like 'non-reifiable set constraint'
|
373
|
+
end
|