gecoder-with-gecode 0.7.1-mswin32

Sign up to get free protection for your applications and to get access to all the features.
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,180 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ # This requires that the constraint spec has instance variables @invoke_options
4
+ # and @expect_options .
5
+ describe 'constraint with strength option', :shared => true do
6
+ { :default => Gecode::Raw::ICL_DEF,
7
+ :value => Gecode::Raw::ICL_VAL,
8
+ :bounds => Gecode::Raw::ICL_BND,
9
+ :domain => Gecode::Raw::ICL_DOM
10
+ }.each_pair do |name, gecode_value|
11
+ it "should translate propagation strength #{name}" do
12
+ @expect_options.call(gecode_value, nil)
13
+ @invoke_options.call(:strength => name)
14
+ end
15
+ end
16
+
17
+ it 'should default to using default as propagation strength' do
18
+ @expect_options.call(Gecode::Raw::ICL_DEF, nil)
19
+ @invoke_options.call({})
20
+ end
21
+
22
+ it 'should raise errors for unrecognized options' do
23
+ lambda{ @invoke_options.call(:does_not_exist => :foo) }.should(
24
+ raise_error(ArgumentError))
25
+ end
26
+
27
+ it 'should raise errors for unrecognized propagation strengths' do
28
+ lambda{ @invoke_options.call(:strength => :does_not_exist) }.should(
29
+ raise_error(ArgumentError))
30
+ end
31
+
32
+ it 'should raise errors for reification variables of incorrect type' do
33
+ lambda{ @invoke_options.call(:reify => 'foo') }.should(
34
+ raise_error(TypeError))
35
+ end
36
+ end
37
+
38
+ # This requires that the constraint spec has instance variables @invoke_options
39
+ # and @expect_options .
40
+ describe 'constraint with options', :shared => true do
41
+ it 'should translate reification' do
42
+ var = @model.bool_var
43
+ @expect_options.call(Gecode::Raw::ICL_DEF, var)
44
+ @invoke_options.call(:reify => var)
45
+ end
46
+
47
+ it_should_behave_like 'constraint with strength option'
48
+ end
49
+
50
+ # This requires that the constraint spec has the instance variable
51
+ # @expect_relation which takes a relation, right hand side and whether it's
52
+ # negated as arguments and sets up the corresponding expectations. It also
53
+ # requires @invoke_relation with the same arguments. The spec is also required
54
+ # to provide a variable @target.
55
+ describe 'composite constraint', :shared => true do
56
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
57
+ it "should translate #{relation} with constant target" do
58
+ @expect_relation.call(type, 1, false)
59
+ @invoke_relation.call(relation, 1, false)
60
+ end
61
+ end
62
+
63
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
64
+ it "should translate #{relation} with variable target" do
65
+ @expect_relation.call(type, @target, false)
66
+ @invoke_relation.call(relation, @target, false)
67
+ end
68
+ end
69
+
70
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
71
+ it "should translate negated #{relation} with constant target" do
72
+ @expect_relation.call(type, 1, true)
73
+ @invoke_relation.call(relation, 1, true)
74
+ end
75
+ end
76
+
77
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
78
+ it "should translate negated #{relation} with variable target" do
79
+ @expect_relation.call(type, @target, true)
80
+ @invoke_relation.call(relation, @target, true)
81
+ end
82
+ end
83
+
84
+ it 'should raise error if the target is of the wrong type' do
85
+ lambda do
86
+ @invoke_relation.call(:==, 'hello', false)
87
+ end.should raise_error(TypeError)
88
+ end
89
+ end
90
+
91
+ # This requires that the constraint spec has the instance variable
92
+ # @expect_relation which takes a relation, right hand side and whether it's
93
+ # negated as arguments and sets up the corresponding expectations. It also
94
+ # requires @invoke_relation with the same arguments. The spec is also required
95
+ # to provide a variable @target.
96
+ describe 'composite set constraint', :shared => true do
97
+ Gecode::Constraints::Util::SET_RELATION_TYPES.each_pair do |relation, type|
98
+ it "should translate #{relation} with constant target" do
99
+ @expect_relation.call(type, [1], false)
100
+ @invoke_relation.call(relation, [1], false)
101
+ end
102
+ end
103
+
104
+ Gecode::Constraints::Util::SET_RELATION_TYPES.each_pair do |relation, type|
105
+ it "should translate #{relation} with variable target" do
106
+ @expect_relation.call(type, @target, false)
107
+ @invoke_relation.call(relation, @target, false)
108
+ end
109
+ end
110
+
111
+ Gecode::Constraints::Util::NEGATED_SET_RELATION_TYPES.each_pair do |relation, type|
112
+ it "should translate negated #{relation} with constant target" do
113
+ @expect_relation.call(type, [1], true)
114
+ @invoke_relation.call(relation, [1], true)
115
+ end
116
+ end
117
+
118
+ Gecode::Constraints::Util::NEGATED_SET_RELATION_TYPES.each_pair do |relation, type|
119
+ it "should translate negated #{relation} with variable target" do
120
+ @expect_relation.call(type, @target, true)
121
+ @invoke_relation.call(relation, @target, true)
122
+ end
123
+ end
124
+
125
+ it 'should raise error if the target is of the wrong type' do
126
+ lambda do
127
+ @invoke_relation.call(:==, 'hello', false)
128
+ end.should raise_error(TypeError)
129
+ end
130
+ end
131
+
132
+ # Requires @invoke_options and @model.
133
+ describe 'non-reifiable set constraint', :shared => true do
134
+ it 'should not accept strength option' do
135
+ lambda do
136
+ @invoke_options.call(:strength => :default)
137
+ end.should raise_error(ArgumentError)
138
+ end
139
+
140
+ it 'should not accept reification option' do
141
+ bool = @model.bool_var
142
+ lambda do
143
+ @invoke_options.call(:reify => bool)
144
+ end.should raise_error(ArgumentError)
145
+ end
146
+ end
147
+
148
+ # Requires @invoke_options, @expect_options and @model.
149
+ describe 'reifiable set constraint', :shared => true do
150
+ it 'should not accept strength option' do
151
+ lambda do
152
+ @invoke_options.call(:strength => :default)
153
+ end.should raise_error(ArgumentError)
154
+ end
155
+
156
+ it 'should accept reification option' do
157
+ bool = @model.bool_var
158
+ @expect_options.call(nil, bool)
159
+ @invoke_options.call(:reify => bool)
160
+ end
161
+ end
162
+
163
+ # Help methods for the GecodeR specs.
164
+ module GecodeR::Specs
165
+ module SetHelper
166
+ module_function
167
+
168
+ # Returns the arguments that should be used in a partial mock to expect the
169
+ # specified constant set (possibly an array of arguments).
170
+ def expect_constant_set(constant_set)
171
+ if constant_set.kind_of? Range
172
+ return constant_set.first, constant_set.last
173
+ elsif constant_set.kind_of? Fixnum
174
+ constant_set
175
+ else
176
+ an_instance_of(Gecode::Raw::IntSet)
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,74 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Gecode::Constraints::Expression do
4
+ it 'should raise error if it doesn\'t get all parameters for initialization' do
5
+ lambda do
6
+ Gecode::Constraints::Expression.new(Gecode::Model.new, :negate => false)
7
+ end.should raise_error(ArgumentError)
8
+ end
9
+ end
10
+
11
+ describe Gecode::Constraints::IntEnum::Expression do
12
+ it 'should raise error unless lhs is an int enum' do
13
+ lambda do
14
+ Gecode::Constraints::IntEnum::Expression.new(Gecode::Model.new,
15
+ :lhs => 'foo', :negate => false)
16
+ end.should raise_error(TypeError)
17
+ end
18
+ end
19
+
20
+ describe Gecode::Constraints::SetEnum::Expression do
21
+ it 'should raise error unless lhs is a set enum' do
22
+ lambda do
23
+ Gecode::Constraints::SetEnum::Expression.new(Gecode::Model.new,
24
+ :lhs => 'foo', :negate => false)
25
+ end.should raise_error(TypeError)
26
+ end
27
+ end
28
+
29
+ describe Gecode::Constraints::Int::CompositeStub, ' (not subclassed)' do
30
+ before do
31
+ @con = Gecode::Constraints::Int::CompositeStub.new(Gecode::Model.new, {})
32
+ end
33
+
34
+ it 'should raise error when calling #constrain_equal' do
35
+ lambda do
36
+ @con.instance_eval{ constrain_equal(nil, {}, false) }
37
+ end.should raise_error(NoMethodError)
38
+ end
39
+ end
40
+
41
+ describe Gecode::Constraints::Constraint, ' (not subclassed)' do
42
+ before do
43
+ @con = Gecode::Constraints::Constraint.new(Gecode::Model.new, {})
44
+ end
45
+
46
+ it 'should raise error when calling #post because it\'s not overridden' do
47
+ lambda{ @con.post }.should raise_error(NoMethodError)
48
+ end
49
+ end
50
+
51
+ describe Gecode::Constraints::Util do
52
+ it 'should raise error when giving incorrect set to #constant_set_to_params' do
53
+ lambda do
54
+ Gecode::Constraints::Util.constant_set_to_params('hello')
55
+ end.should raise_error(TypeError)
56
+ end
57
+
58
+ it 'should raise error when giving incorrect set to #constant_set_to_int_set' do
59
+ lambda do
60
+ Gecode::Constraints::Util.constant_set_to_int_set('hello')
61
+ end.should raise_error(TypeError)
62
+ end
63
+ end
64
+
65
+ describe Gecode::Constraints::CompositeExpression do
66
+ it 'should raise error if a method doesn\'t exist' do
67
+ expression = Gecode::Constraints::CompositeExpression.new(
68
+ Gecode::Constraints::Int::Expression, Gecode::FreeIntVar,
69
+ lambda{ }, Gecode::Model.new, {:lhs => nil, :negate => false}){}
70
+ lambda do
71
+ expression.this_method_does_not_exist
72
+ end.should raise_error(NoMethodError)
73
+ end
74
+ end
@@ -0,0 +1,139 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/constraint_helper'
3
+
4
+ class CountSampleProblem < Gecode::Model
5
+ attr :list
6
+ attr :element
7
+ attr :target
8
+
9
+ def initialize
10
+ @list = int_var_array(4, 0..3)
11
+ @element = int_var(0..3)
12
+ @target = int_var(0..4)
13
+ branch_on @list
14
+ end
15
+ end
16
+
17
+ describe Gecode::Constraints::IntEnum::Count do
18
+ before do
19
+ @model = CountSampleProblem.new
20
+ @list = @model.list
21
+ @element = @model.element
22
+ @target = @model.target
23
+
24
+ # Creates an expectation corresponding to the specified input.
25
+ @expect = lambda do |element, relation, target, strength, reif_var|
26
+ @model.allow_space_access do
27
+ target = an_instance_of(Gecode::Raw::IntVar) if target.respond_to? :bind
28
+ element = an_instance_of(Gecode::Raw::IntVar) if element.respond_to? :bind
29
+ if reif_var.nil?
30
+ Gecode::Raw.should_receive(:count).once.with(
31
+ an_instance_of(Gecode::Raw::Space),
32
+ an_instance_of(Gecode::Raw::IntVarArray),
33
+ element, relation, target, strength)
34
+ else
35
+ Gecode::Raw.should_receive(:count).once.with(
36
+ an_instance_of(Gecode::Raw::Space),
37
+ an_instance_of(Gecode::Raw::IntVarArray),
38
+ element, Gecode::Raw::IRT_EQ,
39
+ an_instance_of(Gecode::Raw::IntVar), strength)
40
+ Gecode::Raw.should_receive(:rel).once.with(
41
+ an_instance_of(Gecode::Raw::Space),
42
+ an_instance_of(Gecode::Raw::IntVar), relation,
43
+ target, an_instance_of(Gecode::Raw::BoolVar), strength)
44
+ end
45
+ end
46
+ end
47
+
48
+ # For constraint option spec.
49
+ @invoke_options = lambda do |hash|
50
+ @list.count(@element).must_be.greater_than(@target, hash)
51
+ @model.solve!
52
+ end
53
+ @expect_options = lambda do |strength, reif_var|
54
+ @expect.call(@element, Gecode::Raw::IRT_GR, @target, strength, reif_var)
55
+ end
56
+ end
57
+
58
+ # Various situations that must be handled (4*2 in total). This was originally
59
+ # written without the repetition (r269), but that interfered with the spec
60
+ # somehow.
61
+
62
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
63
+ it "should translate #{relation} with variable element and target" do
64
+ @expect.call(@element, type, @target, Gecode::Raw::ICL_DEF, nil)
65
+ @list.count(@element).must.send(relation, @target)
66
+ @model.solve!
67
+ end
68
+ end
69
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
70
+ it "should translate negated #{relation} with variable element and target" do
71
+ @expect.call(@element, type, @target, Gecode::Raw::ICL_DEF, nil)
72
+ @list.count(@element).must_not.send(relation, @target)
73
+ @model.solve!
74
+ end
75
+ end
76
+
77
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
78
+ it "should translate #{relation} with variable element and constant target" do
79
+ @expect.call(@element, type, 2, Gecode::Raw::ICL_DEF, nil)
80
+ @list.count(@element).must.send(relation, 2)
81
+ @model.solve!
82
+ end
83
+ end
84
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
85
+ it "should translate negated #{relation} with variable element and constant target" do
86
+ @expect.call(@element, type, 2, Gecode::Raw::ICL_DEF, nil)
87
+ @list.count(@element).must_not.send(relation, 2)
88
+ @model.solve!
89
+ end
90
+ end
91
+
92
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
93
+ it "should translate #{relation} with constant element and constant target" do
94
+ @expect.call(1, type, 2, Gecode::Raw::ICL_DEF, nil)
95
+ @list.count(1).must.send(relation, 2)
96
+ @model.solve!
97
+ end
98
+ end
99
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
100
+ it "should translate negated #{relation} with constant element and constant target" do
101
+ @expect.call(1, type, 2, Gecode::Raw::ICL_DEF, nil)
102
+ @list.count(1).must_not.send(relation, 2)
103
+ @model.solve!
104
+ end
105
+ end
106
+
107
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
108
+ it "should translate #{relation} with constant element and variable target" do
109
+ @expect.call(1, type, @target, Gecode::Raw::ICL_DEF, nil)
110
+ @list.count(1).must.send(relation, @target)
111
+ @model.solve!
112
+ end
113
+ end
114
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
115
+ it "should translate negated #{relation} with constant element and variable target" do
116
+ @expect.call(1, type, @target, Gecode::Raw::ICL_DEF, nil)
117
+ @list.count(1).must_not.send(relation, @target)
118
+ @model.solve!
119
+ end
120
+ end
121
+
122
+ it 'should raise error if the target is of the wrong type' do
123
+ lambda{ @list.count(@element).must == 'hello' }.should raise_error(
124
+ TypeError)
125
+ end
126
+
127
+ it 'should raise error on element is of the wrong type' do
128
+ lambda{ @list.count('foo').must == @target }.should raise_error(
129
+ TypeError)
130
+ end
131
+
132
+ it 'should constrain the count' do
133
+ @list.must_be.distinct
134
+ @list.count(0).must <= 0
135
+ @model.solve!.should be_nil
136
+ end
137
+
138
+ it_should_behave_like 'constraint with options'
139
+ end
@@ -0,0 +1,218 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/constraint_helper'
3
+
4
+ class DistinctSampleProblem < Gecode::Model
5
+ attr :vars
6
+ attr :sets
7
+
8
+ def initialize
9
+ @vars = int_var_array(2, 1)
10
+ @sets = set_var_array(2, [], 0..2)
11
+ branch_on wrap_enum(@sets)
12
+ end
13
+ end
14
+
15
+ describe Gecode::Constraints::IntEnum::Distinct do
16
+ before do
17
+ @model = DistinctSampleProblem.new
18
+ @invoke_options = lambda do |hash|
19
+ @model.vars.must_be.distinct(hash)
20
+ @model.solve!
21
+ end
22
+ @expect_options = lambda do |strength, reif_var|
23
+ Gecode::Raw.should_receive(:distinct).once.with(
24
+ an_instance_of(Gecode::Raw::Space),
25
+ an_instance_of(Gecode::Raw::IntVarArray), strength)
26
+ end
27
+ end
28
+
29
+ it 'should translate into a distinct constraint' do
30
+ Gecode::Raw.should_receive(:distinct).once.with(
31
+ an_instance_of(Gecode::Raw::Space),
32
+ anything, Gecode::Raw::ICL_DEF)
33
+ @invoke_options.call({})
34
+ end
35
+
36
+ it 'should constrain variables to be distinct' do
37
+ # This won't work well without branching or propagation strengths. So this
38
+ # just shows that the distinct constraint will cause trivially unsolvable
39
+ # problems to directly fail.
40
+ @model.vars.must_be.distinct
41
+ @model.solve!.should be_nil
42
+ end
43
+
44
+ it 'should not allow negation' do
45
+ lambda{ @model.vars.must_not_be.distinct }.should raise_error(
46
+ Gecode::MissingConstraintError)
47
+ end
48
+
49
+ it_should_behave_like 'constraint with strength option'
50
+ end
51
+
52
+ describe Gecode::Constraints::IntEnum::Distinct, ' (with offsets)' do
53
+ before do
54
+ @model = DistinctSampleProblem.new
55
+ @invoke_options = lambda do |hash|
56
+ @model.vars.with_offsets(1,2).must_be.distinct(hash)
57
+ @model.solve!
58
+ end
59
+ @expect_options = lambda do |strength, reif_var|
60
+ if reif_var.nil?
61
+ Gecode::Raw.should_receive(:distinct).once.with(
62
+ an_instance_of(Gecode::Raw::Space),
63
+ anything, an_instance_of(Gecode::Raw::IntVarArray), strength)
64
+ else
65
+ Gecode::Raw.should_receive(:distinct).once.with(
66
+ an_instance_of(Gecode::Raw::Space),
67
+ anything, an_instance_of(Gecode::Raw::IntVarArray), strength,
68
+ an_instance_of(Gecode::Raw::BoolVar))
69
+ end
70
+ end
71
+ end
72
+
73
+ it 'should translate into a distinct constraint with offsets' do
74
+ Gecode::Raw.should_receive(:distinct).once.with(
75
+ an_instance_of(Gecode::Raw::Space),
76
+ anything, anything, Gecode::Raw::ICL_DEF)
77
+ @invoke_options.call({})
78
+ end
79
+
80
+ it 'should consider offsets when making variables distinct' do
81
+ @model.vars.with_offsets(-1,0).must_be.distinct
82
+ x,y = @model.solve!.vars
83
+ x.value.should equal(1)
84
+ y.value.should equal(1)
85
+ end
86
+
87
+ # This tests two distinct in conjunction. It's here because of a bug found.
88
+ it 'should play nice with normal distinct' do
89
+ @model.vars.with_offsets(-1,0).must_be.distinct
90
+ @model.vars.must_be.distinct
91
+ @model.solve!.should be_nil
92
+ end
93
+
94
+ it 'should accept an array as offsets' do
95
+ @model.vars.with_offsets([-1,0]).must_be.distinct
96
+ x,y = @model.solve!.vars
97
+ x.value.should equal(1)
98
+ y.value.should equal(1)
99
+ end
100
+
101
+ it 'should not allow negation' do
102
+ lambda{ @model.vars.with_offsets(1,2).must_not_be.distinct }.should
103
+ raise_error(Gecode::MissingConstraintError)
104
+ end
105
+
106
+ it_should_behave_like 'constraint with strength option'
107
+ end
108
+
109
+ describe Gecode::Constraints::SetEnum::Distinct do
110
+ before do
111
+ @model = DistinctSampleProblem.new
112
+ @sets = @model.sets
113
+ @size = 1
114
+
115
+ @invoke_options = lambda do |hash|
116
+ @sets.must_be.distinct(hash.update(:size => @size))
117
+ @model.solve!
118
+ end
119
+ @expect_options = lambda do |strength, reif_var|
120
+ Gecode::Raw.should_receive(:distinct).once.with(
121
+ an_instance_of(Gecode::Raw::Space),
122
+ an_instance_of(Gecode::Raw::SetVarArray), @size)
123
+ end
124
+ end
125
+
126
+ it 'should translate into a distinct constraint' do
127
+ Gecode::Raw.should_receive(:distinct).once.with(
128
+ an_instance_of(Gecode::Raw::Space),
129
+ an_instance_of(Gecode::Raw::SetVarArray), @size)
130
+ @sets.must_be.distinct(:size => @size)
131
+ @model.solve!
132
+ end
133
+
134
+ it 'should constrain sets to be distinct' do
135
+ @sets.must_be.distinct(:size => @size)
136
+ @sets[0].must_be.superset_of 0
137
+ solution = @model.solve!
138
+ solution.should_not be_nil
139
+ set1, set2 = solution.sets
140
+ set1.value.size.should == @size
141
+ set2.value.size.should == @size
142
+ set1.value.should_not == set2.value
143
+ end
144
+
145
+ it 'should not allow negation' do
146
+ lambda{ @sets.must_not_be.distinct(:size => @size) }.should raise_error(
147
+ Gecode::MissingConstraintError)
148
+ end
149
+
150
+ it 'should not allow options other than :size' do
151
+ lambda do
152
+ @sets.must_be.distinct(:size => @size, :foo => 17)
153
+ end.should raise_error(ArgumentError)
154
+ end
155
+
156
+ it 'should raise error if :size is not specified' do
157
+ lambda{ @sets.must_be.distinct }.should raise_error(ArgumentError)
158
+ end
159
+
160
+ it_should_behave_like 'non-reifiable set constraint'
161
+ end
162
+
163
+ describe Gecode::Constraints::SetEnum::Distinct, ' (at most one)' do
164
+ before do
165
+ @model = DistinctSampleProblem.new
166
+ @sets = @model.sets
167
+ @size = 2
168
+
169
+ @invoke_options = lambda do |hash|
170
+ @sets.must.at_most_share_one_element hash.update(:size => @size)
171
+ @model.solve!
172
+ end
173
+ @expect_options = lambda do |strength, reif_var|
174
+ Gecode::Raw.should_receive(:atmostOne).once.with(
175
+ an_instance_of(Gecode::Raw::Space),
176
+ an_instance_of(Gecode::Raw::SetVarArray), @size)
177
+ end
178
+ end
179
+
180
+ it 'should translate into a atmostOne constraint' do
181
+ Gecode::Raw.should_receive(:atmostOne).once.with(
182
+ an_instance_of(Gecode::Raw::Space),
183
+ an_instance_of(Gecode::Raw::SetVarArray), @size)
184
+ @sets.must.at_most_share_one_element(:size => @size)
185
+ @model.solve!
186
+ end
187
+
188
+ it 'should constrain sets to have at most one element in common' do
189
+ @sets.must.at_most_share_one_element(:size => @size)
190
+ @sets[0].must_not_be.superset_of 0
191
+ solution = @model.solve!
192
+ solution.should_not be_nil
193
+ set1, set2 = solution.sets
194
+ set1.value.size.should == @size
195
+ set2.value.size.should == @size
196
+ (set1.value.to_a & set2.value.to_a).size.should <= 1
197
+ end
198
+
199
+ it 'should not allow negation' do
200
+ lambda do
201
+ @sets.must_not.at_most_share_one_element(:size => @size)
202
+ end.should raise_error(Gecode::MissingConstraintError)
203
+ end
204
+
205
+ it 'should not allow options other than :size' do
206
+ lambda do
207
+ @sets.must.at_most_share_one_element(:size => @size, :foo => 17)
208
+ end.should raise_error(ArgumentError)
209
+ end
210
+
211
+ it 'should raise error if :size is not specified' do
212
+ lambda do
213
+ @sets.must.at_most_share_one_element
214
+ end.should raise_error(ArgumentError)
215
+ end
216
+
217
+ it_should_behave_like 'non-reifiable set constraint'
218
+ end