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.
Files changed (159) hide show
  1. data/CHANGES +81 -0
  2. data/COPYING +17 -0
  3. data/LGPL-LICENSE +458 -0
  4. data/README +45 -0
  5. data/Rakefile +13 -0
  6. data/example/example_helper.rb +1 -0
  7. data/example/magic_sequence.rb +43 -0
  8. data/example/queens.rb +43 -0
  9. data/example/raw_bindings.rb +42 -0
  10. data/example/send_more_money.rb +43 -0
  11. data/example/send_most_money.rb +58 -0
  12. data/example/square_tiling.rb +84 -0
  13. data/example/sudoku-set.rb +110 -0
  14. data/example/sudoku.rb +61 -0
  15. data/lib/gecode.dll +0 -0
  16. data/lib/gecoder.rb +5 -0
  17. data/lib/gecoder/bindings.rb +54 -0
  18. data/lib/gecoder/bindings/bindings.rb +2210 -0
  19. data/lib/gecoder/interface.rb +8 -0
  20. data/lib/gecoder/interface/binding_changes.rb +313 -0
  21. data/lib/gecoder/interface/branch.rb +152 -0
  22. data/lib/gecoder/interface/constraints.rb +397 -0
  23. data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
  24. data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
  25. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
  26. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
  27. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
  28. data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
  29. data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
  30. data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
  31. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
  32. data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
  33. data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
  34. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
  35. data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
  36. data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
  37. data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
  38. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
  39. data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
  40. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
  41. data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
  42. data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
  43. data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
  44. data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
  45. data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
  46. data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
  47. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
  48. data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
  49. data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
  50. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
  51. data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
  52. data/lib/gecoder/interface/enum_matrix.rb +64 -0
  53. data/lib/gecoder/interface/enum_wrapper.rb +153 -0
  54. data/lib/gecoder/interface/model.rb +251 -0
  55. data/lib/gecoder/interface/search.rb +123 -0
  56. data/lib/gecoder/interface/variables.rb +254 -0
  57. data/lib/gecoder/version.rb +4 -0
  58. data/specs/binding_changes.rb +76 -0
  59. data/specs/bool_var.rb +74 -0
  60. data/specs/branch.rb +170 -0
  61. data/specs/constraints/arithmetic.rb +266 -0
  62. data/specs/constraints/bool_enum.rb +140 -0
  63. data/specs/constraints/boolean.rb +232 -0
  64. data/specs/constraints/cardinality.rb +154 -0
  65. data/specs/constraints/channel.rb +126 -0
  66. data/specs/constraints/connection.rb +373 -0
  67. data/specs/constraints/constraint_helper.rb +180 -0
  68. data/specs/constraints/constraints.rb +74 -0
  69. data/specs/constraints/count.rb +139 -0
  70. data/specs/constraints/distinct.rb +218 -0
  71. data/specs/constraints/element.rb +106 -0
  72. data/specs/constraints/equality.rb +31 -0
  73. data/specs/constraints/int_domain.rb +69 -0
  74. data/specs/constraints/int_relation.rb +78 -0
  75. data/specs/constraints/linear.rb +332 -0
  76. data/specs/constraints/reification_sugar.rb +96 -0
  77. data/specs/constraints/selection.rb +292 -0
  78. data/specs/constraints/set_domain.rb +181 -0
  79. data/specs/constraints/set_operation.rb +285 -0
  80. data/specs/constraints/set_relation.rb +201 -0
  81. data/specs/constraints/sort.rb +175 -0
  82. data/specs/distribution.rb +14 -0
  83. data/specs/enum_matrix.rb +43 -0
  84. data/specs/enum_wrapper.rb +122 -0
  85. data/specs/int_var.rb +144 -0
  86. data/specs/logging.rb +24 -0
  87. data/specs/model.rb +190 -0
  88. data/specs/search.rb +246 -0
  89. data/specs/set_var.rb +68 -0
  90. data/specs/spec_helper.rb +93 -0
  91. data/tasks/all_tasks.rb +1 -0
  92. data/tasks/building.howto +65 -0
  93. data/tasks/distribution.rake +156 -0
  94. data/tasks/rcov.rake +17 -0
  95. data/tasks/specs.rake +15 -0
  96. data/tasks/svn.rake +11 -0
  97. data/tasks/website.rake +51 -0
  98. data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
  99. data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
  100. data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
  101. data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
  102. data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
  103. data/vendor/rust/README +28 -0
  104. data/vendor/rust/bin/cxxgenerator.rb +93 -0
  105. data/vendor/rust/include/rust_checks.hh +115 -0
  106. data/vendor/rust/include/rust_conversions.hh +102 -0
  107. data/vendor/rust/rust.rb +67 -0
  108. data/vendor/rust/rust/attribute.rb +51 -0
  109. data/vendor/rust/rust/bindings.rb +172 -0
  110. data/vendor/rust/rust/class.rb +339 -0
  111. data/vendor/rust/rust/constants.rb +48 -0
  112. data/vendor/rust/rust/container.rb +110 -0
  113. data/vendor/rust/rust/cppifaceparser.rb +129 -0
  114. data/vendor/rust/rust/cwrapper.rb +72 -0
  115. data/vendor/rust/rust/cxxclass.rb +98 -0
  116. data/vendor/rust/rust/element.rb +81 -0
  117. data/vendor/rust/rust/enum.rb +63 -0
  118. data/vendor/rust/rust/function.rb +407 -0
  119. data/vendor/rust/rust/namespace.rb +61 -0
  120. data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
  121. data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
  122. data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
  123. data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
  124. data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
  125. data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
  126. data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
  127. data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
  128. data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
  129. data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
  130. data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
  131. data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
  132. data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
  133. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
  134. data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
  135. data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
  136. data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
  137. data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
  138. data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
  139. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
  140. data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
  141. data/vendor/rust/rust/type.rb +98 -0
  142. data/vendor/rust/test/Makefile +4 -0
  143. data/vendor/rust/test/constants.rb +36 -0
  144. data/vendor/rust/test/cppclass.cc +45 -0
  145. data/vendor/rust/test/cppclass.hh +67 -0
  146. data/vendor/rust/test/cppclass.rb +59 -0
  147. data/vendor/rust/test/cwrapper.c +74 -0
  148. data/vendor/rust/test/cwrapper.h +41 -0
  149. data/vendor/rust/test/cwrapper.rb +56 -0
  150. data/vendor/rust/test/dummyclass.hh +31 -0
  151. data/vendor/rust/test/lib/extension-test.rb +98 -0
  152. data/vendor/rust/test/operators.cc +41 -0
  153. data/vendor/rust/test/operators.hh +39 -0
  154. data/vendor/rust/test/operators.rb +39 -0
  155. data/vendor/rust/test/test-constants.rb +43 -0
  156. data/vendor/rust/test/test-cppclass.rb +82 -0
  157. data/vendor/rust/test/test-cwrapper.rb +80 -0
  158. data/vendor/rust/test/test-operators.rb +42 -0
  159. 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