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,72 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../property_helper'
|
2
|
+
|
3
|
+
class IntEnumArithmeticSampleProblem < Gecode::Model
|
4
|
+
attr :numbers
|
5
|
+
attr :var
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@numbers = int_var_array(4, 0..9)
|
9
|
+
@var = int_var(-9..9)
|
10
|
+
branch_on @numbers
|
11
|
+
branch_on @var
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Gecode::IntEnum::Arithmetic, ' (max)' do
|
16
|
+
before do
|
17
|
+
@model = IntEnumArithmeticSampleProblem.new
|
18
|
+
@numbers = @model.numbers
|
19
|
+
@var = @model.var
|
20
|
+
|
21
|
+
@property_types = [:int_enum]
|
22
|
+
@select_property = lambda do |int_enum|
|
23
|
+
int_enum.max
|
24
|
+
end
|
25
|
+
@selected_property = @numbers.max
|
26
|
+
@constraint_class = Gecode::BlockConstraint
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should constrain the maximum value' do
|
30
|
+
@numbers.max.must > 5
|
31
|
+
@model.solve!.numbers.values.max.should > 5
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should translate into a max constraint' do
|
35
|
+
Gecode::Raw.should_receive(:max)
|
36
|
+
@numbers.max.must == 5
|
37
|
+
@model.solve!
|
38
|
+
end
|
39
|
+
|
40
|
+
it_should_behave_like(
|
41
|
+
'property that produces int operand by short circuiting equality')
|
42
|
+
end
|
43
|
+
|
44
|
+
describe Gecode::IntEnum::Arithmetic, ' (min)' do
|
45
|
+
before do
|
46
|
+
@model = IntEnumArithmeticSampleProblem.new
|
47
|
+
@numbers = @model.numbers
|
48
|
+
@var = @model.var
|
49
|
+
|
50
|
+
@property_types = [:int_enum]
|
51
|
+
@select_property = lambda do |int_enum|
|
52
|
+
int_enum.min
|
53
|
+
end
|
54
|
+
@selected_property = @numbers.min
|
55
|
+
@constraint_class = Gecode::BlockConstraint
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should constrain the minimum value' do
|
59
|
+
@numbers.min.must > 5
|
60
|
+
@model.solve!.numbers.values.min.should > 5
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should translate into a min constraint' do
|
64
|
+
Gecode::Raw.should_receive(:min)
|
65
|
+
@numbers.min.must == 5
|
66
|
+
@model.solve!
|
67
|
+
end
|
68
|
+
|
69
|
+
it_should_behave_like(
|
70
|
+
'property that produces int operand by short circuiting equality')
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../constraint_helper'
|
2
|
+
|
3
|
+
class ChannelSampleProblem < Gecode::Model
|
4
|
+
attr :elements
|
5
|
+
attr :positions
|
6
|
+
attr :sets
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@elements = int_var_array(4, 0..3)
|
10
|
+
@elements.must_be.distinct
|
11
|
+
@positions = int_var_array(4, 0..3)
|
12
|
+
@positions.must_be.distinct
|
13
|
+
@sets = set_var_array(4, [], 0..3)
|
14
|
+
branch_on @positions
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Gecode::IntEnum::Channel, ' (two int enums)' do
|
19
|
+
before do
|
20
|
+
@model = ChannelSampleProblem.new
|
21
|
+
@positions = @model.positions
|
22
|
+
@elements = @model.elements
|
23
|
+
|
24
|
+
@types = [:int_enum, :int_enum]
|
25
|
+
@invoke = lambda do |receiver, int_enum, hash|
|
26
|
+
receiver.channel(int_enum, hash)
|
27
|
+
@model.solve!
|
28
|
+
end
|
29
|
+
@expect = lambda do |var1, var2, opts, reif_var|
|
30
|
+
Gecode::Raw.should_receive(:channel).once.with(
|
31
|
+
an_instance_of(Gecode::Raw::Space),
|
32
|
+
var1, var2, *opts)
|
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, Gecode::Raw::PK_DEF)
|
40
|
+
@positions.must.channel @elements
|
41
|
+
@model.solve!
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should constrain variables to be channelled' do
|
45
|
+
@elements.must.channel @positions
|
46
|
+
@model.solve!
|
47
|
+
elements = @model.elements.values
|
48
|
+
positions = @model.elements.values
|
49
|
+
elements.each_with_index do |element, i|
|
50
|
+
element.should equal(positions.index(i))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it_should_behave_like 'non-reifiable constraint'
|
55
|
+
it_should_behave_like 'non-negatable constraint'
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../property_helper'
|
2
|
+
|
3
|
+
class CountSampleProblem < Gecode::Model
|
4
|
+
attr :list
|
5
|
+
attr :element
|
6
|
+
attr :target
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@list = int_var_array(4, 0..3)
|
10
|
+
@element = int_var(0..3)
|
11
|
+
@target = int_var(0..4)
|
12
|
+
branch_on @list
|
13
|
+
branch_on @element
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Gecode::IntEnum::Count, ' (with int var)' do
|
18
|
+
before do
|
19
|
+
@model = CountSampleProblem.new
|
20
|
+
@list = @model.list
|
21
|
+
@element = @model.element
|
22
|
+
@target = @model.target
|
23
|
+
|
24
|
+
# For int operand producing property spec.
|
25
|
+
@property_types = [:int_enum, :int]
|
26
|
+
@select_property = lambda do |int_enum, int|
|
27
|
+
int_enum.count(int)
|
28
|
+
end
|
29
|
+
@selected_property = @list.count(@element)
|
30
|
+
@constraint_class =
|
31
|
+
Gecode::IntEnum::Count::CountConstraint
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should constrain the count' do
|
35
|
+
@list.count(@element).must == 2
|
36
|
+
@model.solve!
|
37
|
+
@list.values.map{ |x| x == @element.value }.inject(0) do |sum, b|
|
38
|
+
sum += b ? 1 : 0
|
39
|
+
end.should == 2
|
40
|
+
end
|
41
|
+
|
42
|
+
it_should_behave_like(
|
43
|
+
'property that produces int operand by short circuiting relations')
|
44
|
+
end
|
45
|
+
|
46
|
+
describe Gecode::IntEnum::Count, ' (with fixnum)' do
|
47
|
+
before do
|
48
|
+
@model = CountSampleProblem.new
|
49
|
+
@list = @model.list
|
50
|
+
@target = @model.target
|
51
|
+
|
52
|
+
# For int operand producing property spec.
|
53
|
+
@property_types = [:int_enum]
|
54
|
+
@select_property = lambda do |int_enum|
|
55
|
+
int_enum.count(1)
|
56
|
+
end
|
57
|
+
@selected_property = @list.count(1)
|
58
|
+
@constraint_class =
|
59
|
+
Gecode::IntEnum::Count::CountConstraint
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should constrain the count' do
|
63
|
+
@list.count(1).must == 2
|
64
|
+
@model.solve!
|
65
|
+
@list.values.map{ |x| x == 1 }.inject(0) do |sum, b|
|
66
|
+
sum += b ? 1 : 0
|
67
|
+
end.should == 2
|
68
|
+
end
|
69
|
+
|
70
|
+
it_should_behave_like(
|
71
|
+
'property that produces int operand by short circuiting relations')
|
72
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../constraint_helper'
|
2
|
+
|
3
|
+
class DistinctSampleProblem < Gecode::Model
|
4
|
+
def initialize
|
5
|
+
vars_is_an int_var_array(2, 0..1)
|
6
|
+
branch_on vars
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Gecode::IntEnum::Distinct do
|
11
|
+
before do
|
12
|
+
@model = DistinctSampleProblem.new
|
13
|
+
|
14
|
+
@types = [:int_enum]
|
15
|
+
@invoke = lambda do |receiver, hash|
|
16
|
+
receiver.distinct(hash)
|
17
|
+
@model.solve!
|
18
|
+
end
|
19
|
+
@expect = lambda do |var, opts, reif_var|
|
20
|
+
Gecode::Raw.should_receive(:distinct).once.with(
|
21
|
+
an_instance_of(Gecode::Raw::Space),
|
22
|
+
var, *opts)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should constrain variables to be distinct' do
|
27
|
+
@model.vars.must_be.distinct
|
28
|
+
@model.solve!
|
29
|
+
@model.vars[0].value.should_not == @model.vars[1].value
|
30
|
+
end
|
31
|
+
|
32
|
+
it_should_behave_like 'non-reifiable constraint'
|
33
|
+
it_should_behave_like 'non-negatable constraint'
|
34
|
+
end
|
35
|
+
|
36
|
+
describe Gecode::IntEnum::Distinct, ' (with offsets)' do
|
37
|
+
before do
|
38
|
+
@model = DistinctSampleProblem.new
|
39
|
+
|
40
|
+
@types = [:int_enum]
|
41
|
+
@invoke = lambda do |receiver, hash|
|
42
|
+
receiver.distinct hash.update(:offsets => [1,2])
|
43
|
+
@model.solve!
|
44
|
+
end
|
45
|
+
@expect = lambda do |var, opts, reif_var|
|
46
|
+
if reif_var.nil?
|
47
|
+
Gecode::Raw.should_receive(:distinct).once.with(
|
48
|
+
an_instance_of(Gecode::Raw::Space),
|
49
|
+
[1,2], var, *opts)
|
50
|
+
else
|
51
|
+
Gecode::Raw.should_receive(:distinct).once.with(
|
52
|
+
an_instance_of(Gecode::Raw::Space),
|
53
|
+
[1,2], var, reif_var, *opts)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should constrain variables to be distinct' do
|
59
|
+
@model.vars.must_be.distinct(:offsets => [-1, 0])
|
60
|
+
x, y = @model.solve!.vars
|
61
|
+
(x.value - 1).should_not == y.value
|
62
|
+
end
|
63
|
+
|
64
|
+
# This tests two distinct in conjunction. It's here because of a bug found.
|
65
|
+
it 'should play nice with normal distinct' do
|
66
|
+
@model.vars.must_be.distinct(:offsets => [-1, 0])
|
67
|
+
@model.vars.must_be.distinct(:offsets => [0, -1])
|
68
|
+
@model.vars.must_be.distinct
|
69
|
+
lambda{ @model.solve! }.should raise_error(Gecode::NoSolutionError)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should raise error if the offsets are of an incorrect type' do
|
73
|
+
lambda do
|
74
|
+
@model.vars.must_be.distinct(:offsets => :foo)
|
75
|
+
end.should raise_error(TypeError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it_should_behave_like 'non-reifiable constraint'
|
79
|
+
it_should_behave_like 'non-negatable constraint'
|
80
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../property_helper'
|
2
|
+
|
3
|
+
class ElementSampleProblem < Gecode::Model
|
4
|
+
attr :prices
|
5
|
+
attr :store
|
6
|
+
attr :price
|
7
|
+
attr :fixnum_prices
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
prices = [17, 63, 45, 63]
|
11
|
+
@fixnum_prices = wrap_enum(prices)
|
12
|
+
@prices = int_var_array(4, prices)
|
13
|
+
@store = int_var(0...prices.size)
|
14
|
+
@price = int_var(prices)
|
15
|
+
branch_on @store
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Gecode::IntEnum::Element do
|
20
|
+
before do
|
21
|
+
@model = ElementSampleProblem.new
|
22
|
+
@prices = @model.prices
|
23
|
+
@target = @price = @model.price
|
24
|
+
@store = @model.store
|
25
|
+
|
26
|
+
# For int operand producing property spec.
|
27
|
+
@property_types = [:int_enum, :int]
|
28
|
+
@select_property = lambda do |int_enum, int|
|
29
|
+
int_enum[int]
|
30
|
+
end
|
31
|
+
@selected_property = @prices[@store]
|
32
|
+
@constraint_class = Gecode::BlockConstraint
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should not disturb normal array access' do
|
36
|
+
@prices[2].should_not be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should constrain the selected element' do
|
40
|
+
@prices[@store].must == 63
|
41
|
+
@prices.values_at(0,2,3).each{ |x| x.must < 50 }
|
42
|
+
@model.solve!.should_not be_nil
|
43
|
+
@store.value.should equal(1)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should be translated into an element constraint' do
|
47
|
+
@prices[@store].must == @price
|
48
|
+
@model.allow_space_access do
|
49
|
+
Gecode::Raw.should_receive(:element).once.with(
|
50
|
+
an_instance_of(Gecode::Raw::Space),
|
51
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
52
|
+
@store.bind, @price.bind,
|
53
|
+
Gecode::Raw::ICL_DEF,
|
54
|
+
Gecode::Raw::PK_DEF)
|
55
|
+
end
|
56
|
+
@model.solve!
|
57
|
+
end
|
58
|
+
|
59
|
+
it_should_behave_like(
|
60
|
+
'property that produces int operand by short circuiting equality')
|
61
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../constraint_helper'
|
2
|
+
|
3
|
+
describe Gecode::IntEnum::Equality do
|
4
|
+
before do
|
5
|
+
@model = Gecode::Model.new
|
6
|
+
@vars = @model.int_var_array(4, -2..2)
|
7
|
+
|
8
|
+
@types = [:int_enum]
|
9
|
+
@invoke = lambda do |receiver, hash|
|
10
|
+
receiver.equal(hash)
|
11
|
+
@model.solve!
|
12
|
+
end
|
13
|
+
@expect = lambda do |var, opts, reif_var|
|
14
|
+
Gecode::Raw.should_receive(:rel).once.with(
|
15
|
+
an_instance_of(Gecode::Raw::Space),
|
16
|
+
var, Gecode::Raw::IRT_EQ, *opts)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should constrain elements to be equal' do
|
21
|
+
@vars[1].must == 1
|
22
|
+
@vars.must_be.equal
|
23
|
+
@model.solve!
|
24
|
+
@vars.values.each{ |x| x.should == 1 }
|
25
|
+
end
|
26
|
+
|
27
|
+
it_should_behave_like 'non-reifiable constraint'
|
28
|
+
it_should_behave_like 'non-negatable constraint'
|
29
|
+
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../constraint_helper'
|
2
|
+
|
3
|
+
# Assumes that @variables, @expected_array and @tuples are defined.
|
4
|
+
describe 'int tuple constraint', :shared => true do
|
5
|
+
it 'should not allow negation' do
|
6
|
+
lambda do
|
7
|
+
@variables.must_not_be.in @tuples
|
8
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should not allow empty tuples' do
|
12
|
+
lambda do
|
13
|
+
@variables.must_be.in []
|
14
|
+
end.should raise_error(ArgumentError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should not allow tuples of sizes other than the number of variables' do
|
18
|
+
lambda do
|
19
|
+
@variables.must_be.in([@tuples.first * 2])
|
20
|
+
end.should raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should raise error if the right hand side does not contain tuples of correct type' do
|
24
|
+
lambda do
|
25
|
+
size = @variables.size
|
26
|
+
@variables.must_be.in ['h'*size, 'i'*size]
|
27
|
+
end.should raise_error(TypeError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Gecode::IntEnum::Extensional, ' (tuple constraint)' do
|
32
|
+
before do
|
33
|
+
@model = Gecode::Model.new
|
34
|
+
@tuples = [[1,7], [5,1]]
|
35
|
+
@variables = @digits = @model.int_var_array(2, 0..9)
|
36
|
+
@model.branch_on @digits
|
37
|
+
|
38
|
+
@types = [:int_enum]
|
39
|
+
@invoke = lambda do |receiver, hash|
|
40
|
+
receiver.in([[1, 7, 5, 3, 0], [8, 9, 9, 9, 0]], hash)
|
41
|
+
@model.solve!
|
42
|
+
end
|
43
|
+
@expect = lambda do |var, opts, reif_var|
|
44
|
+
Gecode::Raw.should_receive(:extensional).once.with(
|
45
|
+
an_instance_of(Gecode::Raw::Space),
|
46
|
+
var, an_instance_of(Gecode::Raw::TupleSet), *opts)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should constrain the domain of all variables' do
|
51
|
+
@digits.must_be.in @tuples
|
52
|
+
|
53
|
+
found_solutions = []
|
54
|
+
@model.each_solution do |m|
|
55
|
+
found_solutions << @digits.values
|
56
|
+
end
|
57
|
+
|
58
|
+
found_solutions.size.should == 2
|
59
|
+
(found_solutions - @tuples).should be_empty
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should raise error if the right hand side is not an enumeration' do
|
63
|
+
lambda{ @digits.must_be.in 4711 }.should raise_error(TypeError)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should raise error if the right hand side does not contain tuples' do
|
67
|
+
lambda{ @digits.must_be.in [17, 4711] }.should raise_error(TypeError)
|
68
|
+
end
|
69
|
+
|
70
|
+
it_should_behave_like 'int tuple constraint'
|
71
|
+
it_should_behave_like 'non-reifiable constraint'
|
72
|
+
end
|
73
|
+
|
74
|
+
# Assumes that @variables, @expected_array, @value1, @value2 (must not
|
75
|
+
# equal @value1) and @regexp are defined.
|
76
|
+
describe 'int regular expression constraint', :shared => true do
|
77
|
+
it 'should handle values grouped in a single array' do
|
78
|
+
@variables.must.match [@value1, @value2, @value1]
|
79
|
+
@model.solve!.should_not be_nil
|
80
|
+
@variables.values.should == [@value1, @value2, @value1]
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should allow nested groups of values' do
|
84
|
+
@variables.must.match [@value1, [@value2, [@value1]]]
|
85
|
+
@model.solve!.should_not be_nil
|
86
|
+
@variables.values.should == [@value1, @value2, @value1]
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should handle the repeat operation' do
|
90
|
+
@variables.must.match [@value1, @model.repeat([@value2], 1, 2)]
|
91
|
+
@model.solve!.should_not be_nil
|
92
|
+
@variables.values.should == [@value1, @value2, @value2]
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should handle repeat operations that do not encase constant values in arrays' do
|
96
|
+
@variables.must.match [@value1, @model.repeat(@value2, 1, 2)]
|
97
|
+
@model.solve!.should_not be_nil
|
98
|
+
@variables.values.should == [@value1, @value2, @value2]
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should handle nested repeat operations' do
|
102
|
+
@variables.must.match [[@model.repeat(@model.repeat([@value2], 1, 3), 1, 2)]]
|
103
|
+
@model.solve!.should_not be_nil
|
104
|
+
@variables.values.should == [@value2, @value2, @value2]
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should handle nested repeat operations (2)' do
|
108
|
+
@variables.must.match [[@model.repeat([@model.repeat(@value2, 1, 3)], 1, 2)]]
|
109
|
+
@model.solve!.should_not be_nil
|
110
|
+
@variables.values.should == [@value2, @value2, @value2]
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should interpret the repeat operation with the last argument omitted as only giving a lower bound' do
|
114
|
+
@variables.must.match [@value1, @model.repeat([@value2], 1)]
|
115
|
+
@model.solve!.should_not be_nil
|
116
|
+
@variables.values.should == [@value1, @value2, @value2]
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should interpret the repeat operation with all but the first argument omitted as not giving any bound' do
|
120
|
+
@variables.must.match [@model.repeat(@value2), @value1, @value1, @value1]
|
121
|
+
@model.solve!.should_not be_nil
|
122
|
+
@variables.values.should == [@value1, @value1, @value1]
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should interpret the repeat operation with all but the first argument omitted as not giving any bound (2)' do
|
126
|
+
@variables.must.match [@model.repeat(@value2)]
|
127
|
+
@model.solve!.should_not be_nil
|
128
|
+
@variables.values.should == [@value2, @value2, @value2]
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should translate at_most_once(reg) to repeat(reg, 0, 1)' do
|
132
|
+
@model.should_receive(:repeat).once.with([@value1], 0, 1)
|
133
|
+
@model.at_most_once [@value1]
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should translate at_least_once(reg) to repeat(reg, 1)' do
|
137
|
+
@model.should_receive(:repeat).once.with([@value1], 1)
|
138
|
+
@model.at_least_once [@value1]
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should raise error if the right hand side is not an enumeration' do
|
142
|
+
lambda do
|
143
|
+
@variables.must.match Object.new
|
144
|
+
end.should raise_error(TypeError)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should raise error if the right hand side does not a regexp of the right type' do
|
148
|
+
lambda do
|
149
|
+
@variables.must.match [@value1, 'foo']
|
150
|
+
end.should raise_error(TypeError)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should raise error if the right hand side contains a nested element of an incorrect type' do
|
154
|
+
lambda do
|
155
|
+
@variables.must.match [@value1, [@value2, 'foo']]
|
156
|
+
end.should raise_error(TypeError)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type (2)' do
|
160
|
+
lambda do
|
161
|
+
@variables.must.match @model.repeat(@value1, [0], 1)
|
162
|
+
end.should raise_error(TypeError)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type (3)' do
|
166
|
+
lambda do
|
167
|
+
@variables.must.match @model.repeat(@value1, 0, [1])
|
168
|
+
end.should raise_error(TypeError)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should raise error if the repeat operation is given arguments of incorrect type' do
|
172
|
+
lambda do
|
173
|
+
@variables.must.match @model.repeat('foo', 0, 1)
|
174
|
+
end.should raise_error(TypeError)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should not allow negation' do
|
178
|
+
lambda do
|
179
|
+
@variables.must_not.match @regexp
|
180
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe Gecode::IntEnum::Extensional, ' (regexp constraint)' do
|
185
|
+
before do
|
186
|
+
@model = Gecode::Model.new
|
187
|
+
@variables = @digits = @model.int_var_array(3, 0..9)
|
188
|
+
@model.branch_on @digits
|
189
|
+
@expected_array = an_instance_of Gecode::Raw::IntVarArray
|
190
|
+
@value1 = 3
|
191
|
+
@value2 = 5
|
192
|
+
@regexp = [1, @model.any(3, 4), @model.at_most_once(5)]
|
193
|
+
|
194
|
+
@types = [:int_enum]
|
195
|
+
@invoke = lambda do |receiver, hash|
|
196
|
+
receiver.match(@regexp, hash)
|
197
|
+
@model.solve!
|
198
|
+
end
|
199
|
+
@expect = lambda do |var, opts, reif_var|
|
200
|
+
Gecode::Raw.should_receive(:extensional).once.with(
|
201
|
+
an_instance_of(Gecode::Raw::Space),
|
202
|
+
var, an_instance_of(Gecode::Raw::REG), *opts)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should handle the any operation' do
|
207
|
+
@digits.must.match [1, @model.any(1, 2, 3), 3]
|
208
|
+
@model.solve!.should_not be_nil
|
209
|
+
values = @digits.values
|
210
|
+
values.size.should == 3
|
211
|
+
values.should == values.sort
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should handle the any operator with nested expressions' do
|
215
|
+
@digits.must.match [1, @model.any(@model.at_least_once(2), [3, 5])]
|
216
|
+
@digits[2].must < 4
|
217
|
+
@model.solve!.should_not be_nil
|
218
|
+
@digits.values.should == [1,2,2]
|
219
|
+
end
|
220
|
+
|
221
|
+
it_should_behave_like 'int regular expression constraint'
|
222
|
+
it_should_behave_like 'non-reifiable constraint'
|
223
|
+
end
|
224
|
+
|