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,106 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
class ElementSampleProblem < Gecode::Model
|
5
|
+
attr :prices
|
6
|
+
attr :store
|
7
|
+
attr :price
|
8
|
+
attr :fixnum_prices
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
prices = [17, 63, 45, 63]
|
12
|
+
@fixnum_prices = wrap_enum(prices)
|
13
|
+
@prices = int_var_array(4, prices)
|
14
|
+
@store = int_var(0...prices.size)
|
15
|
+
@price = int_var(prices)
|
16
|
+
branch_on wrap_enum([@store])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Gecode::Constraints::IntEnum::Element do
|
21
|
+
before do
|
22
|
+
@model = ElementSampleProblem.new
|
23
|
+
@prices = @model.prices
|
24
|
+
@target = @price = @model.price
|
25
|
+
@store = @model.store
|
26
|
+
@fixnum_prices = @model.fixnum_prices
|
27
|
+
|
28
|
+
# Creates an expectation corresponding to the specified input.
|
29
|
+
@expect = lambda do |element, relation, target, strength, reif_var, negated|
|
30
|
+
@model.allow_space_access do
|
31
|
+
target = an_instance_of(Gecode::Raw::IntVar) if target.respond_to? :bind
|
32
|
+
element = an_instance_of(Gecode::Raw::IntVar) if element.respond_to? :bind
|
33
|
+
if reif_var.nil?
|
34
|
+
if !negated and relation == Gecode::Raw::IRT_EQ and
|
35
|
+
!target.kind_of? Fixnum
|
36
|
+
Gecode::Raw.should_receive(:element).once.with(
|
37
|
+
an_instance_of(Gecode::Raw::Space),
|
38
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
39
|
+
element, target, strength)
|
40
|
+
else
|
41
|
+
Gecode::Raw.should_receive(:element).once.with(
|
42
|
+
an_instance_of(Gecode::Raw::Space),
|
43
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
44
|
+
element, an_instance_of(Gecode::Raw::IntVar), strength)
|
45
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
46
|
+
an_instance_of(Gecode::Raw::Space),
|
47
|
+
an_instance_of(Gecode::Raw::IntVar), relation, target, strength)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
Gecode::Raw.should_receive(:element).once.with(
|
51
|
+
an_instance_of(Gecode::Raw::Space),
|
52
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
53
|
+
element, an_instance_of(Gecode::Raw::IntVar), strength)
|
54
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
55
|
+
an_instance_of(Gecode::Raw::Space),
|
56
|
+
an_instance_of(Gecode::Raw::IntVar), relation, target,
|
57
|
+
an_instance_of(Gecode::Raw::BoolVar), strength)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# For constraint option spec.
|
63
|
+
@invoke_options = lambda do |hash|
|
64
|
+
@prices[@store].must_be.greater_than(@price, hash)
|
65
|
+
@model.solve!
|
66
|
+
end
|
67
|
+
@expect_options = lambda do |strength, reif_var|
|
68
|
+
@expect.call(@store, Gecode::Raw::IRT_GR, @price, strength, reif_var,
|
69
|
+
false)
|
70
|
+
end
|
71
|
+
|
72
|
+
# For composite spec.
|
73
|
+
@invoke_relation = lambda do |relation, target, negated|
|
74
|
+
if negated
|
75
|
+
@prices[@store].must_not.send(relation, target)
|
76
|
+
else
|
77
|
+
@prices[@store].must.send(relation, target)
|
78
|
+
end
|
79
|
+
@model.solve!
|
80
|
+
end
|
81
|
+
@expect_relation = lambda do |relation, target, negated|
|
82
|
+
@expect.call(@store, relation, target, Gecode::Raw::ICL_DEF, nil, negated)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should not disturb normal array access' do
|
87
|
+
@fixnum_prices[2].should_not be_nil
|
88
|
+
@prices[2].should_not be_nil
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should handle fixnum enums as enumeration' do
|
92
|
+
@fixnum_prices[@store].must == @fixnum_prices[2]
|
93
|
+
@model.solve!.store.value.should equal(2)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should translate reification when using equality' do
|
97
|
+
bool_var = @model.bool_var
|
98
|
+
@expect.call(@store, Gecode::Raw::IRT_EQ, @target, Gecode::Raw::ICL_DEF,
|
99
|
+
bool_var, false)
|
100
|
+
@prices[@store].must_be.equal_to(@target, :reify => bool_var)
|
101
|
+
@model.solve!
|
102
|
+
end
|
103
|
+
|
104
|
+
it_should_behave_like 'composite constraint'
|
105
|
+
it_should_behave_like 'constraint with options'
|
106
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
describe Gecode::Constraints::IntEnum::Equality do
|
5
|
+
before do
|
6
|
+
@model = Gecode::Model.new
|
7
|
+
@vars = @model.int_var_array(4, -2..2)
|
8
|
+
@invoke_options = lambda do |hash|
|
9
|
+
@vars.must_be.equal(hash)
|
10
|
+
@model.solve!
|
11
|
+
end
|
12
|
+
@expect_options = lambda do |strength, reif_var|
|
13
|
+
Gecode::Raw.should_receive(:eq).once.with(
|
14
|
+
an_instance_of(Gecode::Raw::Space),
|
15
|
+
anything, strength)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should translate equality constraints' do
|
20
|
+
@expect_options.call(Gecode::Raw::ICL_DEF, nil)
|
21
|
+
@invoke_options.call({})
|
22
|
+
@vars.must_be.equal
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should not allow negation' do
|
26
|
+
lambda{ @vars.must_not_be.equal }.should raise_error(
|
27
|
+
Gecode::MissingConstraintError)
|
28
|
+
end
|
29
|
+
|
30
|
+
it_should_behave_like 'constraint with strength option'
|
31
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
describe Gecode::Constraints::Int::Domain do
|
5
|
+
before do
|
6
|
+
@model = Gecode::Model.new
|
7
|
+
@domain = 0..3
|
8
|
+
@x = @model.int_var(@domain)
|
9
|
+
@range_domain = 1..2
|
10
|
+
@three_dot_range_domain = 1...2
|
11
|
+
@non_range_domain = [1, 3]
|
12
|
+
|
13
|
+
@invoke_options = lambda do |hash|
|
14
|
+
@x.must_be.in(@non_range_domain, hash)
|
15
|
+
@model.solve!
|
16
|
+
end
|
17
|
+
@expect_options = lambda do |strength, reif_var|
|
18
|
+
@model.allow_space_access do
|
19
|
+
if reif_var.nil?
|
20
|
+
Gecode::Raw.should_receive(:dom).once.with(
|
21
|
+
an_instance_of(Gecode::Raw::Space),
|
22
|
+
an_instance_of(Gecode::Raw::IntVar),
|
23
|
+
an_instance_of(Gecode::Raw::IntSet), strength)
|
24
|
+
else
|
25
|
+
Gecode::Raw.should_receive(:dom).once.with(
|
26
|
+
an_instance_of(Gecode::Raw::Space),
|
27
|
+
an_instance_of(Gecode::Raw::IntVar),
|
28
|
+
an_instance_of(Gecode::Raw::IntSet),
|
29
|
+
an_instance_of(Gecode::Raw::BoolVar), strength)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should translate domain constraints with range domains' do
|
36
|
+
Gecode::Raw.should_receive(:dom).once.with(
|
37
|
+
an_instance_of(Gecode::Raw::Space),
|
38
|
+
an_instance_of(Gecode::Raw::IntVar), @range_domain.first,
|
39
|
+
@range_domain.last, Gecode::Raw::ICL_DEF)
|
40
|
+
@x.must_be.in @range_domain
|
41
|
+
@model.solve!
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should translate domain constraints with three dot range domains' do
|
45
|
+
Gecode::Raw.should_receive(:dom).once.with(
|
46
|
+
an_instance_of(Gecode::Raw::Space),
|
47
|
+
an_instance_of(Gecode::Raw::IntVar), @three_dot_range_domain.first,
|
48
|
+
@three_dot_range_domain.last, Gecode::Raw::ICL_DEF)
|
49
|
+
@x.must_be.in @three_dot_range_domain
|
50
|
+
@model.solve!
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should translate domain constraints with non-range domains' do
|
54
|
+
@expect_options.call(Gecode::Raw::ICL_DEF, nil)
|
55
|
+
@invoke_options.call({})
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should handle negation' do
|
59
|
+
@x.must_not_be.in @range_domain
|
60
|
+
@model.solve!
|
61
|
+
@x.should have_domain(@domain.to_a - @range_domain.to_a)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should raise error if the right hand side is not an enumeration' do
|
65
|
+
lambda{ @x.must_be.in 'hello' }.should raise_error(TypeError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it_should_behave_like 'constraint with options'
|
69
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
describe Gecode::Constraints::Int::Linear, ' (simple ones)' do
|
5
|
+
before do
|
6
|
+
@model = Gecode::Model.new
|
7
|
+
@x = @model.int_var(1..2)
|
8
|
+
@int = 4
|
9
|
+
@y = @model.int_var(1..2)
|
10
|
+
|
11
|
+
# For constraint option spec.
|
12
|
+
@invoke_options = lambda do |hash|
|
13
|
+
@x.must_be.greater_than(3, hash)
|
14
|
+
@model.solve!
|
15
|
+
end
|
16
|
+
@expect_options = lambda do |strength, reif_var|
|
17
|
+
if reif_var.nil?
|
18
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
19
|
+
an_instance_of(Gecode::Raw::Space),
|
20
|
+
anything, Gecode::Raw::IRT_GR, anything,
|
21
|
+
strength)
|
22
|
+
else
|
23
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
24
|
+
an_instance_of(Gecode::Raw::Space),
|
25
|
+
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR, anything,
|
26
|
+
an_instance_of(Gecode::Raw::BoolVar), strength)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
|
32
|
+
it "should translate #{relation} with constant to simple relation" do
|
33
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
34
|
+
an_instance_of(Gecode::Raw::Space),
|
35
|
+
an_instance_of(Gecode::Raw::IntVar), type, @int, Gecode::Raw::ICL_DEF)
|
36
|
+
@x.must.send(relation, @int)
|
37
|
+
@model.solve!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
|
42
|
+
it "should translate negated #{relation} with constant to simple relation" do
|
43
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
44
|
+
an_instance_of(Gecode::Raw::Space),
|
45
|
+
an_instance_of(Gecode::Raw::IntVar), type, @int, Gecode::Raw::ICL_DEF)
|
46
|
+
@x.must_not.send(relation, @int)
|
47
|
+
@model.solve!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
|
52
|
+
it "should translate #{relation} with variables to simple relation" do
|
53
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
54
|
+
an_instance_of(Gecode::Raw::Space),
|
55
|
+
an_instance_of(Gecode::Raw::IntVar), type,
|
56
|
+
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
|
57
|
+
@x.must.send(relation, @y)
|
58
|
+
@model.solve!
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
|
63
|
+
it "should translate negated #{relation} with variable to simple relation" do
|
64
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
65
|
+
an_instance_of(Gecode::Raw::Space),
|
66
|
+
an_instance_of(Gecode::Raw::IntVar), type,
|
67
|
+
an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
|
68
|
+
@x.must_not.send(relation, @y)
|
69
|
+
@model.solve!
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should raise error on arguments of the wrong type' do
|
74
|
+
lambda{ @x.must == 'hello' }.should raise_error(TypeError)
|
75
|
+
end
|
76
|
+
|
77
|
+
it_should_behave_like 'constraint with options'
|
78
|
+
end
|
@@ -0,0 +1,332 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
class LinearSampleProblem < Gecode::Model
|
5
|
+
attr :x
|
6
|
+
attr :y
|
7
|
+
attr :z
|
8
|
+
|
9
|
+
def initialize(x_dom, y_dom, z_dom)
|
10
|
+
@x = self.int_var(x_dom)
|
11
|
+
@y = self.int_var(y_dom)
|
12
|
+
@z = self.int_var(z_dom)
|
13
|
+
branch_on wrap_enum([@x, @y, @z])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class BoolLinearSampleProblem < Gecode::Model
|
18
|
+
attr :x
|
19
|
+
attr :y
|
20
|
+
attr :z
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@x = self.bool_var
|
24
|
+
@y = self.bool_var
|
25
|
+
@z = self.bool_var
|
26
|
+
branch_on wrap_enum([@x, @y, @z])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class TrueClass
|
31
|
+
def to_i
|
32
|
+
1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class FalseClass
|
37
|
+
def to_i
|
38
|
+
0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe Gecode::Constraints::Int::Linear do
|
43
|
+
before do
|
44
|
+
@x_dom = 0..2
|
45
|
+
@y_dom = -3..3
|
46
|
+
@z_dom = 0..10
|
47
|
+
@model = LinearSampleProblem.new(@x_dom, @y_dom, @z_dom)
|
48
|
+
@x = @model.x
|
49
|
+
@y = @model.y
|
50
|
+
@z = @model.z
|
51
|
+
|
52
|
+
# For constraint option spec.
|
53
|
+
@invoke_options = lambda do |hash|
|
54
|
+
(@x + @y).must_be.greater_than(@z, hash)
|
55
|
+
@model.solve!
|
56
|
+
end
|
57
|
+
@expect_options = lambda do |strength, reif_var|
|
58
|
+
# TODO: this is hard to spec from this level.
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should handle addition with a variable' do
|
63
|
+
(@x + @y).must == 0
|
64
|
+
sol = @model.solve!
|
65
|
+
x = sol.x.value
|
66
|
+
y = sol.y.value
|
67
|
+
(x + y).should be_zero
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should handle addition with multiple variables' do
|
71
|
+
(@x + @y + @z).must == 0
|
72
|
+
sol = @model.solve!
|
73
|
+
x = sol.x.value
|
74
|
+
y = sol.y.value
|
75
|
+
z = sol.z.value
|
76
|
+
(x + y + z).should be_zero
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should handle subtraction with a variable' do
|
80
|
+
(@x - @y).must == 0
|
81
|
+
sol = @model.solve!
|
82
|
+
x = sol.x.value
|
83
|
+
y = sol.y.value
|
84
|
+
(x - y).should be_zero
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should handle non-zero constants as right hand side' do
|
88
|
+
(@x + @y).must == 1
|
89
|
+
sol = @model.solve!
|
90
|
+
x = sol.x.value
|
91
|
+
y = sol.y.value
|
92
|
+
(x + y).should equal(1)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should handle variables as right hand side' do
|
96
|
+
(@x + @y).must == @z
|
97
|
+
sol = @model.solve!
|
98
|
+
x = sol.x.value
|
99
|
+
y = sol.y.value
|
100
|
+
z = sol.z.value
|
101
|
+
(x + y).should equal(z)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should handle linear expressions as right hand side' do
|
105
|
+
(@x + @y).must == @z + @y
|
106
|
+
sol = @model.solve!
|
107
|
+
x = sol.x.value
|
108
|
+
y = sol.y.value
|
109
|
+
z = sol.z.value
|
110
|
+
(x + y).should equal(z + y)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should raise error on invalid right hand sides' do
|
114
|
+
lambda{ ((@x + @y).must == 'z') }.should raise_error(TypeError)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should handle coefficients other than 1' do
|
118
|
+
(@x * 2 + @y).must == 0
|
119
|
+
sol = @model.solve!
|
120
|
+
x = sol.x.value
|
121
|
+
y = sol.y.value
|
122
|
+
(2*x + y).should equal(0)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should handle addition with constants' do
|
126
|
+
(@y + 2).must == 1
|
127
|
+
sol = @model.solve!
|
128
|
+
y = sol.y.value
|
129
|
+
(y + 2).should equal(1)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should handle subtraction with a constant' do
|
133
|
+
(@x - 2).must == 0
|
134
|
+
sol = @model.solve!
|
135
|
+
x = sol.x.value
|
136
|
+
(x - 2).should be_zero
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should a single variable as left hande side' do
|
140
|
+
@x.must == @y + @z
|
141
|
+
sol = @model.solve!
|
142
|
+
x = sol.x.value
|
143
|
+
y = sol.y.value
|
144
|
+
z = sol.z.value
|
145
|
+
x.should equal(y + z)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should handle parenthesis' do
|
149
|
+
(@x - (@y + @z)).must == 1
|
150
|
+
sol = @model.solve!
|
151
|
+
x = sol.x.value
|
152
|
+
y = sol.y.value
|
153
|
+
z = sol.z.value
|
154
|
+
(x - (y + z)).should equal(1)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should handle multiplication of parenthesis' do
|
158
|
+
(((@x + @y*10)*10 + @z)*10).must == 0
|
159
|
+
sol = @model.solve!
|
160
|
+
x = sol.x.value
|
161
|
+
y = sol.y.value
|
162
|
+
z = sol.z.value
|
163
|
+
(((x + y*10)*10 + z)*10).should equal(0)
|
164
|
+
end
|
165
|
+
|
166
|
+
relations = ['>', '>=', '<', '<=', '==']
|
167
|
+
|
168
|
+
relations.each do |relation|
|
169
|
+
it "should handle #{relation} with constant integers" do
|
170
|
+
(@x + @y).must.send(relation, 1)
|
171
|
+
sol = @model.solve!
|
172
|
+
sol.should_not be_nil
|
173
|
+
(sol.x.value + sol.y.value).should.send(relation, 1)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
relations.each do |relation|
|
178
|
+
it "should handle negated #{relation} with constant integers" do
|
179
|
+
(@x + @y).must_not.send(relation, 1)
|
180
|
+
sol = @model.solve!
|
181
|
+
sol.should_not be_nil
|
182
|
+
(sol.x.value + sol.y.value).should_not.send(relation, 1)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should not interfere with other defined multiplication methods' do
|
187
|
+
(@x * :foo).should be_nil
|
188
|
+
end
|
189
|
+
|
190
|
+
it_should_behave_like 'constraint with options'
|
191
|
+
end
|
192
|
+
|
193
|
+
describe Gecode::Constraints::Int::Linear, '(with booleans)' do
|
194
|
+
before do
|
195
|
+
@model = BoolLinearSampleProblem.new
|
196
|
+
@x = @model.x
|
197
|
+
@y = @model.y
|
198
|
+
@z = @model.z
|
199
|
+
|
200
|
+
# For constraint option spec.
|
201
|
+
@invoke_options = lambda do |hash|
|
202
|
+
(@x + @y).must_be.greater_than(@z, hash)
|
203
|
+
@model.solve!
|
204
|
+
end
|
205
|
+
@expect_options = lambda do |strength, reif_var|
|
206
|
+
# TODO: this is hard to spec from this level.
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should handle addition with a variable' do
|
211
|
+
(@x + @y).must == 0
|
212
|
+
sol = @model.solve!
|
213
|
+
x = sol.x.value.to_i
|
214
|
+
y = sol.y.value.to_i
|
215
|
+
(x + y).should be_zero
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should handle addition with multiple variables' do
|
219
|
+
(@x + @y + @z).must == 0
|
220
|
+
sol = @model.solve!
|
221
|
+
x = sol.x.value.to_i
|
222
|
+
y = sol.y.value.to_i
|
223
|
+
z = sol.z.value.to_i
|
224
|
+
(x + y + z).should be_zero
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should handle subtraction with a variable' do
|
228
|
+
(@x - @y).must == 0
|
229
|
+
sol = @model.solve!
|
230
|
+
x = sol.x.value.to_i
|
231
|
+
y = sol.y.value.to_i
|
232
|
+
(x - y).should be_zero
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'should handle non-zero constants as right hand side' do
|
236
|
+
(@x + @y).must == 1
|
237
|
+
sol = @model.solve!
|
238
|
+
x = sol.x.value.to_i
|
239
|
+
y = sol.y.value.to_i
|
240
|
+
(x + y).should equal(1)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should handle variables as right hand side' do
|
244
|
+
(@x + @y).must == @z
|
245
|
+
sol = @model.solve!
|
246
|
+
x = sol.x.value.to_i
|
247
|
+
y = sol.y.value.to_i
|
248
|
+
z = sol.z.value.to_i
|
249
|
+
(x + y).should equal(z)
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should handle linear expressions as right hand side' do
|
253
|
+
(@x + @y).must == @z + @y
|
254
|
+
sol = @model.solve!
|
255
|
+
x = sol.x.value.to_i
|
256
|
+
y = sol.y.value.to_i
|
257
|
+
z = sol.z.value.to_i
|
258
|
+
(x + y).should equal(z + y)
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'should raise error on invalid right hand sides' do
|
262
|
+
lambda{ ((@x + @y).must == 'z') }.should raise_error(TypeError)
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'should handle coefficients other than 1' do
|
266
|
+
(@x * 2 + @y).must == 0
|
267
|
+
sol = @model.solve!
|
268
|
+
x = sol.x.value.to_i
|
269
|
+
y = sol.y.value.to_i
|
270
|
+
(2*x + y).should equal(0)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should handle addition with constants' do
|
274
|
+
(@y + 1).must == 1
|
275
|
+
sol = @model.solve!
|
276
|
+
y = sol.y.value.to_i
|
277
|
+
(y + 1).should equal(1)
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'should handle subtraction with a constant' do
|
281
|
+
(@x - 1).must == 0
|
282
|
+
sol = @model.solve!
|
283
|
+
x = sol.x.value.to_i
|
284
|
+
(x - 1).should be_zero
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'should handle parenthesis' do
|
288
|
+
(@x - (@y + @z)).must == 1
|
289
|
+
sol = @model.solve!
|
290
|
+
x = sol.x.value.to_i
|
291
|
+
y = sol.y.value.to_i
|
292
|
+
z = sol.z.value.to_i
|
293
|
+
(x - (y + z)).should equal(1)
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'should handle multiplication of parenthesis' do
|
297
|
+
(((@x + @y*10)*10 + @z)*10).must == 0
|
298
|
+
sol = @model.solve!
|
299
|
+
x = sol.x.value.to_i
|
300
|
+
y = sol.y.value.to_i
|
301
|
+
z = sol.z.value.to_i
|
302
|
+
(((x + y*10)*10 + z)*10).should equal(0)
|
303
|
+
end
|
304
|
+
|
305
|
+
relations = ['>', '>=', '<', '<=', '==']
|
306
|
+
|
307
|
+
relations.each do |relation|
|
308
|
+
it "should handle #{relation} with constant integers" do
|
309
|
+
(@x + @y).must.send(relation, 1)
|
310
|
+
sol = @model.solve!
|
311
|
+
sol.should_not be_nil
|
312
|
+
(sol.x.value.to_i + sol.y.value.to_i).should.send(relation, 1)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
relations.each do |relation|
|
317
|
+
it "should handle negated #{relation} with constant integers" do
|
318
|
+
(@x + @y).must_not.send(relation, 1)
|
319
|
+
sol = @model.solve!
|
320
|
+
sol.should_not be_nil
|
321
|
+
(sol.x.value.to_i + sol.y.value.to_i).should_not.send(relation, 1)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'should not interfere with other defined multiplication methods' do
|
326
|
+
(@x * :foo).should be_nil
|
327
|
+
end
|
328
|
+
|
329
|
+
it_should_behave_like 'constraint with options'
|
330
|
+
end
|
331
|
+
|
332
|
+
|