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.
Files changed (203) hide show
  1. data/CHANGES +137 -0
  2. data/COPYING +17 -0
  3. data/LGPL-LICENSE +458 -0
  4. data/README +58 -0
  5. data/Rakefile +14 -0
  6. data/example/equation_system.rb +15 -0
  7. data/example/example_helper.rb +1 -0
  8. data/example/magic_sequence.rb +43 -0
  9. data/example/money.rb +36 -0
  10. data/example/queens.rb +42 -0
  11. data/example/send_more_money.rb +43 -0
  12. data/example/send_most_money.rb +58 -0
  13. data/example/square_tiling.rb +84 -0
  14. data/example/sudoku-set.rb +106 -0
  15. data/example/sudoku.rb +56 -0
  16. data/lib/gecode.dll +0 -0
  17. data/lib/gecoder.rb +5 -0
  18. data/lib/gecoder/bindings.rb +96 -0
  19. data/lib/gecoder/bindings/bindings.rb +2029 -0
  20. data/lib/gecoder/interface.rb +9 -0
  21. data/lib/gecoder/interface/binding_changes.rb +9 -0
  22. data/lib/gecoder/interface/branch.rb +163 -0
  23. data/lib/gecoder/interface/constraints.rb +471 -0
  24. data/lib/gecoder/interface/constraints/bool/boolean.rb +251 -0
  25. data/lib/gecoder/interface/constraints/bool/channel.rb +7 -0
  26. data/lib/gecoder/interface/constraints/bool/linear.rb +200 -0
  27. data/lib/gecoder/interface/constraints/bool_enum/channel.rb +68 -0
  28. data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +106 -0
  29. data/lib/gecoder/interface/constraints/bool_enum/relation.rb +55 -0
  30. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +84 -0
  31. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +155 -0
  32. data/lib/gecoder/interface/constraints/extensional_regexp.rb +101 -0
  33. data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
  34. data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
  35. data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
  36. data/lib/gecoder/interface/constraints/int/arithmetic.rb +150 -0
  37. data/lib/gecoder/interface/constraints/int/channel.rb +51 -0
  38. data/lib/gecoder/interface/constraints/int/domain.rb +80 -0
  39. data/lib/gecoder/interface/constraints/int/linear.rb +143 -0
  40. data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
  41. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +63 -0
  42. data/lib/gecoder/interface/constraints/int_enum/channel.rb +86 -0
  43. data/lib/gecoder/interface/constraints/int_enum/count.rb +66 -0
  44. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +64 -0
  45. data/lib/gecoder/interface/constraints/int_enum/element.rb +64 -0
  46. data/lib/gecoder/interface/constraints/int_enum/equality.rb +37 -0
  47. data/lib/gecoder/interface/constraints/int_enum/extensional.rb +187 -0
  48. data/lib/gecoder/interface/constraints/int_enum/sort.rb +135 -0
  49. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +95 -0
  50. data/lib/gecoder/interface/constraints/int_var_constraints.rb +230 -0
  51. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
  52. data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
  53. data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
  54. data/lib/gecoder/interface/constraints/set/cardinality.rb +65 -0
  55. data/lib/gecoder/interface/constraints/set/channel.rb +51 -0
  56. data/lib/gecoder/interface/constraints/set/connection.rb +130 -0
  57. data/lib/gecoder/interface/constraints/set/domain.rb +156 -0
  58. data/lib/gecoder/interface/constraints/set/include.rb +36 -0
  59. data/lib/gecoder/interface/constraints/set/operation.rb +118 -0
  60. data/lib/gecoder/interface/constraints/set/relation.rb +155 -0
  61. data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
  62. data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
  63. data/lib/gecoder/interface/constraints/set_enum/channel.rb +45 -0
  64. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +43 -0
  65. data/lib/gecoder/interface/constraints/set_enum/operation.rb +69 -0
  66. data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
  67. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +84 -0
  68. data/lib/gecoder/interface/constraints/set_var_constraints.rb +243 -0
  69. data/lib/gecoder/interface/enum_matrix.rb +64 -0
  70. data/lib/gecoder/interface/enum_wrapper.rb +205 -0
  71. data/lib/gecoder/interface/model.rb +453 -0
  72. data/lib/gecoder/interface/model_sugar.rb +84 -0
  73. data/lib/gecoder/interface/search.rb +197 -0
  74. data/lib/gecoder/interface/variables.rb +306 -0
  75. data/lib/gecoder/version.rb +4 -0
  76. data/specs/bool_var.rb +81 -0
  77. data/specs/branch.rb +185 -0
  78. data/specs/constraints/bool/boolean.rb +317 -0
  79. data/specs/constraints/bool/boolean_properties.rb +51 -0
  80. data/specs/constraints/bool/linear.rb +213 -0
  81. data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
  82. data/specs/constraints/bool_enum/channel.rb +102 -0
  83. data/specs/constraints/bool_enum/extensional.rb +225 -0
  84. data/specs/constraints/constraint_helper.rb +234 -0
  85. data/specs/constraints/constraint_receivers.rb +103 -0
  86. data/specs/constraints/constraints.rb +26 -0
  87. data/specs/constraints/fixnum_enum/element.rb +58 -0
  88. data/specs/constraints/fixnum_enum/operation.rb +67 -0
  89. data/specs/constraints/int/arithmetic.rb +149 -0
  90. data/specs/constraints/int/channel.rb +101 -0
  91. data/specs/constraints/int/domain.rb +106 -0
  92. data/specs/constraints/int/linear.rb +183 -0
  93. data/specs/constraints/int/linear_properties.rb +97 -0
  94. data/specs/constraints/int/relation.rb +84 -0
  95. data/specs/constraints/int_enum/arithmetic.rb +72 -0
  96. data/specs/constraints/int_enum/channel.rb +57 -0
  97. data/specs/constraints/int_enum/count.rb +72 -0
  98. data/specs/constraints/int_enum/distinct.rb +80 -0
  99. data/specs/constraints/int_enum/element.rb +61 -0
  100. data/specs/constraints/int_enum/equality.rb +29 -0
  101. data/specs/constraints/int_enum/extensional.rb +224 -0
  102. data/specs/constraints/int_enum/sort.rb +167 -0
  103. data/specs/constraints/operands.rb +264 -0
  104. data/specs/constraints/property_helper.rb +443 -0
  105. data/specs/constraints/reification_sugar.rb +69 -0
  106. data/specs/constraints/selected_set/select.rb +56 -0
  107. data/specs/constraints/selected_set/select_properties.rb +157 -0
  108. data/specs/constraints/set/cardinality.rb +58 -0
  109. data/specs/constraints/set/cardinality_properties.rb +46 -0
  110. data/specs/constraints/set/channel.rb +77 -0
  111. data/specs/constraints/set/connection.rb +176 -0
  112. data/specs/constraints/set/domain.rb +197 -0
  113. data/specs/constraints/set/include.rb +36 -0
  114. data/specs/constraints/set/operation.rb +132 -0
  115. data/specs/constraints/set/relation.rb +117 -0
  116. data/specs/constraints/set_elements/relation.rb +84 -0
  117. data/specs/constraints/set_enum/channel.rb +80 -0
  118. data/specs/constraints/set_enum/distinct.rb +59 -0
  119. data/specs/constraints/set_enum/operation.rb +111 -0
  120. data/specs/constraints/set_enum/select.rb +73 -0
  121. data/specs/distribution.rb +14 -0
  122. data/specs/enum_matrix.rb +43 -0
  123. data/specs/enum_wrapper.rb +179 -0
  124. data/specs/examples.rb +17 -0
  125. data/specs/int_var.rb +163 -0
  126. data/specs/logging.rb +24 -0
  127. data/specs/model.rb +325 -0
  128. data/specs/model_sugar.rb +30 -0
  129. data/specs/search.rb +383 -0
  130. data/specs/selected_set.rb +39 -0
  131. data/specs/set_elements.rb +34 -0
  132. data/specs/set_var.rb +82 -0
  133. data/specs/spec_helper.rb +265 -0
  134. data/tasks/all_tasks.rb +1 -0
  135. data/tasks/dependencies.txt +22 -0
  136. data/tasks/distribution.rake +194 -0
  137. data/tasks/rcov.rake +18 -0
  138. data/tasks/specs.rake +21 -0
  139. data/tasks/svn.rake +16 -0
  140. data/tasks/website.rake +51 -0
  141. data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
  142. data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
  143. data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
  144. data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
  145. data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
  146. data/vendor/gecode/win32/lib/libgecodesupport.dll +0 -0
  147. data/vendor/rust/README +28 -0
  148. data/vendor/rust/bin/cxxgenerator.rb +93 -0
  149. data/vendor/rust/include/rust_checks.hh +116 -0
  150. data/vendor/rust/include/rust_conversions.hh +102 -0
  151. data/vendor/rust/rust.rb +67 -0
  152. data/vendor/rust/rust/attribute.rb +51 -0
  153. data/vendor/rust/rust/bindings.rb +172 -0
  154. data/vendor/rust/rust/class.rb +337 -0
  155. data/vendor/rust/rust/constants.rb +48 -0
  156. data/vendor/rust/rust/container.rb +110 -0
  157. data/vendor/rust/rust/cppifaceparser.rb +129 -0
  158. data/vendor/rust/rust/cwrapper.rb +72 -0
  159. data/vendor/rust/rust/cxxclass.rb +96 -0
  160. data/vendor/rust/rust/element.rb +81 -0
  161. data/vendor/rust/rust/enum.rb +63 -0
  162. data/vendor/rust/rust/function.rb +407 -0
  163. data/vendor/rust/rust/namespace.rb +61 -0
  164. data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
  165. data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
  166. data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
  167. data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
  168. data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
  169. data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
  170. data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
  171. data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
  172. data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +100 -0
  173. data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
  174. data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
  175. data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
  176. data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
  177. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
  178. data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
  179. data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
  180. data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
  181. data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
  182. data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
  183. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
  184. data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
  185. data/vendor/rust/rust/type.rb +98 -0
  186. data/vendor/rust/test/Makefile +4 -0
  187. data/vendor/rust/test/constants.rb +36 -0
  188. data/vendor/rust/test/cppclass.cc +45 -0
  189. data/vendor/rust/test/cppclass.hh +67 -0
  190. data/vendor/rust/test/cppclass.rb +59 -0
  191. data/vendor/rust/test/cwrapper.c +74 -0
  192. data/vendor/rust/test/cwrapper.h +41 -0
  193. data/vendor/rust/test/cwrapper.rb +56 -0
  194. data/vendor/rust/test/dummyclass.hh +31 -0
  195. data/vendor/rust/test/lib/extension-test.rb +98 -0
  196. data/vendor/rust/test/operators.cc +41 -0
  197. data/vendor/rust/test/operators.hh +39 -0
  198. data/vendor/rust/test/operators.rb +39 -0
  199. data/vendor/rust/test/test-constants.rb +43 -0
  200. data/vendor/rust/test/test-cppclass.rb +82 -0
  201. data/vendor/rust/test/test-cwrapper.rb +80 -0
  202. data/vendor/rust/test/test-operators.rb +42 -0
  203. metadata +393 -0
@@ -0,0 +1,167 @@
1
+ require File.dirname(__FILE__) + '/../constraint_helper'
2
+
3
+ class SortSampleProblem < Gecode::Model
4
+ attr :vars
5
+ attr :sorted
6
+ attr :indices
7
+
8
+ def initialize
9
+ @vars = int_var_array(4, 10..19)
10
+ @sorted = int_var_array(4, 10..19)
11
+ @indices = int_var_array(4, 0..9)
12
+
13
+ # To make it more interesting
14
+ @vars.must_be.distinct
15
+
16
+ branch_on @vars
17
+ end
18
+ end
19
+
20
+ describe Gecode::IntEnum::Sort, ' (without :as and :order)' do
21
+ before do
22
+ @model = SortSampleProblem.new
23
+ @vars = @model.vars
24
+ @sorted = @model.sorted
25
+
26
+ @types = [:int_enum]
27
+ @invoke = lambda do |receiver, hash|
28
+ receiver.sorted(hash)
29
+ @model.solve!
30
+ end
31
+ @expect = lambda do |var, opts, reif_var|
32
+ if reif_var.nil?
33
+ Gecode::Raw.should_receive(:rel).exactly(var.size - 1).times.with(
34
+ an_instance_of(Gecode::Raw::Space),
35
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_LQ,
36
+ an_instance_of(Gecode::Raw::IntVar), *opts)
37
+ else
38
+ Gecode::Raw.should_receive(:rel).once.with(
39
+ an_instance_of(Gecode::Raw::Space), anything,
40
+ an_instance_of(Gecode::Raw::BoolVarArray),
41
+ anything, anything, anything)
42
+ Gecode::Raw.should_receive(:rel).exactly(var.size - 1).times.with(
43
+ an_instance_of(Gecode::Raw::Space),
44
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_LQ,
45
+ an_instance_of(Gecode::Raw::IntVar),
46
+ an_instance_of(Gecode::Raw::BoolVar), *opts)
47
+ end
48
+ end
49
+ end
50
+
51
+ it 'should constraint variables to be sorted' do
52
+ @vars.must_be.sorted
53
+ values = @model.solve!.vars.values
54
+ values.should == values.sort
55
+ end
56
+
57
+ it 'should allow negation' do
58
+ @vars.must_not_be.sorted
59
+ @model.solve!
60
+ values = @vars.values
61
+ values.should_not == values.sort
62
+ end
63
+
64
+ it_should_behave_like 'reifiable constraint'
65
+ end
66
+
67
+ describe Gecode::IntEnum::Sort, ' (with :as)' do
68
+ before do
69
+ @model = SortSampleProblem.new
70
+ @vars = @model.vars
71
+ @sorted = @model.sorted
72
+
73
+ # Make it a bit more interesting.
74
+ @vars[0].must > @vars[3] + 1
75
+
76
+ @types = [:int_enum, :int_enum]
77
+ @invoke = lambda do |receiver, int_enum, hash|
78
+ receiver.sorted hash.update(:as => int_enum)
79
+ @model.solve!
80
+ end
81
+ @expect = lambda do |var1, var2, opts, reif_var|
82
+ Gecode::Raw.should_receive(:sorted).once.with(
83
+ an_instance_of(Gecode::Raw::Space),
84
+ var1, var2, *opts)
85
+ end
86
+ end
87
+
88
+ it 'should constraint variables to be sorted' do
89
+ @vars.must_be.sorted(:as => @sorted)
90
+ @model.solve!
91
+ values = @sorted.values
92
+ values.should == values.sort
93
+ end
94
+
95
+ it_should_behave_like 'non-reifiable constraint'
96
+ it_should_behave_like 'non-negatable constraint'
97
+ end
98
+
99
+ describe Gecode::IntEnum::Sort, ' (with :order)' do
100
+ before do
101
+ @model = SortSampleProblem.new
102
+ @vars = @model.vars
103
+ @sorted = @model.sorted
104
+ @indices = @model.indices
105
+
106
+ # Make it a bit more interesting.
107
+ @vars[0].must > @vars[3] + 1
108
+
109
+ @types = [:int_enum, :int_enum]
110
+ @invoke = lambda do |receiver, int_enum, hash|
111
+ receiver.sorted hash.update(:order => int_enum)
112
+ @model.solve!
113
+ end
114
+ @expect = lambda do |var1, var2, opts, reif_var|
115
+ Gecode::Raw.should_receive(:sorted).once.with(
116
+ an_instance_of(Gecode::Raw::Space),
117
+ var1, an_instance_of(Gecode::Raw::IntVarArray), var2,
118
+ *opts)
119
+ end
120
+ end
121
+
122
+ it 'should constraint variables to be sorted with the specified indices' do
123
+ @vars.must_be.sorted(:order => @indices)
124
+ @model.solve!
125
+ sorted_values = @vars.values.sort
126
+ expected_indices = @vars.map{ |v| sorted_values.index(v.value) }
127
+ @indices.values.should == expected_indices
128
+ end
129
+
130
+ it_should_behave_like 'non-reifiable constraint'
131
+ it_should_behave_like 'non-negatable constraint'
132
+ end
133
+
134
+ describe Gecode::IntEnum::Sort, ' (with :order and :as)' do
135
+ before do
136
+ @model = SortSampleProblem.new
137
+ @vars = @model.vars
138
+ @sorted = @model.sorted
139
+ @indices = @model.indices
140
+
141
+ # Make it a bit more interesting.
142
+ @vars[0].must > @vars[3] + 1
143
+
144
+ @types = [:int_enum, :int_enum, :int_enum]
145
+ @invoke = lambda do |receiver, int_enum1, int_enum2, hash|
146
+ receiver.sorted hash.update(:as => int_enum1, :order => int_enum2)
147
+ @model.solve!
148
+ end
149
+ @expect = lambda do |var1, var2, var3, opts, reif_var|
150
+ Gecode::Raw.should_receive(:sorted).once.with(
151
+ an_instance_of(Gecode::Raw::Space),
152
+ var1, var2, var3, *opts)
153
+ end
154
+ end
155
+
156
+ it 'should constraint variables to be sorted with the specified indices' do
157
+ @vars.must_be.sorted(:as => @sorted, :order => @indices)
158
+ @model.solve!
159
+ sorted_values = @sorted.values
160
+ sorted_values.should == sorted_values.sort
161
+ expected_indices = @vars.map{ |v| sorted_values.index(v.value) }
162
+ @indices.values.should == expected_indices
163
+ end
164
+
165
+ it_should_behave_like 'non-reifiable constraint'
166
+ it_should_behave_like 'non-negatable constraint'
167
+ end
@@ -0,0 +1,264 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'operand', :shared => true do
4
+ it 'should not shadow method missing' do
5
+ lambda do
6
+ @operand.does_not_exist
7
+ end.should raise_error(NoMethodError)
8
+ end
9
+ end
10
+
11
+ describe 'variable operand', :shared => true do
12
+ it 'should fall back to the underlying variable' do
13
+ lambda do
14
+ @operand.assigned?
15
+ end.should_not raise_error
16
+ end
17
+
18
+ it_should_behave_like 'operand'
19
+ end
20
+
21
+ describe 'enum operand', :shared => true do
22
+ it 'should fall back to the underlying enum' do
23
+ lambda do
24
+ @operand[0]
25
+ end.should_not raise_error
26
+ end
27
+
28
+ it_should_behave_like 'operand'
29
+ end
30
+
31
+ describe Gecode::Operand do
32
+ before do
33
+ model = Gecode::Model.new
34
+ @operand = Object.new
35
+ class <<@operand
36
+ include Gecode::Operand
37
+ end
38
+ end
39
+
40
+ it 'should raise error if #model is not defined' do
41
+ lambda do
42
+ @operand.model
43
+ end.should raise_error(NotImplementedError)
44
+ end
45
+
46
+ it 'should raise error if #construct_receiver is not defined' do
47
+ lambda do
48
+ @operand.must
49
+ end.should raise_error(NotImplementedError)
50
+ end
51
+ end
52
+
53
+ describe Gecode::Int::IntOperand do
54
+ before do
55
+ model = Gecode::Model.new
56
+ @operand, _ = general_int_operand(model)
57
+ end
58
+
59
+ it_should_behave_like 'variable operand'
60
+ end
61
+
62
+ describe Gecode::Int::ShortCircuitEqualityOperand, ' (not subclassed)' do
63
+ before do
64
+ @model = Gecode::Model.new
65
+ @operand = Gecode::Int::ShortCircuitEqualityOperand.new(@model)
66
+ end
67
+
68
+ it 'should raise error if #constrain_equal is called' do
69
+ lambda do
70
+ @operand.to_int_var
71
+ @model.solve!
72
+ end.should raise_error(NotImplementedError)
73
+ end
74
+ end
75
+
76
+ describe Gecode::Int::ShortCircuitRelationsOperand, ' (not subclassed)' do
77
+ before do
78
+ @model = Gecode::Model.new
79
+ @operand = Gecode::Int::ShortCircuitRelationsOperand.new(@model)
80
+ end
81
+
82
+ it 'should raise error if #constrain_equal is called' do
83
+ lambda do
84
+ @operand.to_int_var
85
+ @model.solve!
86
+ end.should raise_error(NotImplementedError)
87
+ end
88
+ end
89
+
90
+ describe Gecode::IntEnum::IntEnumOperand do
91
+ before do
92
+ model = Gecode::Model.new
93
+ @operand, _ = general_int_enum_operand(model)
94
+ end
95
+
96
+ it_should_behave_like 'enum operand'
97
+ end
98
+
99
+ describe Gecode::Bool::BoolOperand do
100
+ before do
101
+ model = Gecode::Model.new
102
+ @operand, _ = general_bool_operand(model)
103
+ end
104
+
105
+ it_should_behave_like 'variable operand'
106
+ end
107
+
108
+ describe Gecode::Bool::ShortCircuitEqualityOperand, ' (not subclassed)' do
109
+ before do
110
+ @model = Gecode::Model.new
111
+ @operand = Gecode::Bool::ShortCircuitEqualityOperand.new(@model)
112
+ end
113
+
114
+ it 'should raise error if #constrain_equal is called' do
115
+ lambda do
116
+ @operand.to_bool_var
117
+ @model.solve!
118
+ end.should raise_error(NotImplementedError)
119
+ end
120
+ end
121
+
122
+ describe Gecode::BoolEnum::BoolEnumOperand do
123
+ before do
124
+ model = Gecode::Model.new
125
+ @operand, _ = general_bool_enum_operand(model)
126
+ end
127
+
128
+ it_should_behave_like 'enum operand'
129
+ end
130
+
131
+ describe Gecode::Set::SetOperand do
132
+ before do
133
+ model = Gecode::Model.new
134
+ @operand, _ = general_set_operand(model)
135
+ end
136
+
137
+ it_should_behave_like 'variable operand'
138
+ end
139
+
140
+ describe Gecode::Set::ShortCircuitEqualityOperand, ' (not subclassed)' do
141
+ before do
142
+ @model = Gecode::Model.new
143
+ @operand = Gecode::Set::ShortCircuitEqualityOperand.new(@model)
144
+ end
145
+
146
+ it 'should raise error if #constrain_equal is called' do
147
+ lambda do
148
+ @operand.to_set_var
149
+ @model.solve!
150
+ end.should raise_error(NotImplementedError)
151
+ end
152
+ end
153
+
154
+ describe Gecode::Set::ShortCircuitRelationsOperand, ' (not subclassed)' do
155
+ before do
156
+ @model = Gecode::Model.new
157
+ @operand = Gecode::Set::ShortCircuitRelationsOperand.new(@model)
158
+ end
159
+
160
+ it 'should raise error if #constrain_equal is called' do
161
+ lambda do
162
+ @operand.to_set_var
163
+ @model.solve!
164
+ end.should raise_error(NotImplementedError)
165
+ end
166
+ end
167
+
168
+ describe Gecode::SelectedSet::SelectedSetOperand do
169
+ before do
170
+ model = Gecode::Model.new
171
+ @operand, ops = general_selected_set_operand(model)
172
+ @enum, @set = ops
173
+ end
174
+
175
+ it 'should raise error if set enum operand is not given' do
176
+ lambda do
177
+ Gecode::SelectedSet::SelectedSetOperand.new(:foo, @set)
178
+ end.should raise_error(TypeError)
179
+ end
180
+
181
+ it 'should raise error if set operand is not given' do
182
+ lambda do
183
+ Gecode::SelectedSet::SelectedSetOperand.new(@enum, :foo)
184
+ end.should raise_error(TypeError)
185
+ end
186
+
187
+ it_should_behave_like 'operand'
188
+ end
189
+
190
+ describe Gecode::SetElements::SetElementsOperand do
191
+ before do
192
+ model = Gecode::Model.new
193
+ @operand, @set = general_set_elements_operand(model)
194
+ end
195
+
196
+ it 'should raise error if set operand is not given' do
197
+ lambda do
198
+ Gecode::SetElements::SetElementsOperand.new(:foo)
199
+ end.should raise_error(TypeError)
200
+ end
201
+
202
+ it_should_behave_like 'operand'
203
+ end
204
+
205
+ describe Gecode::SetEnum::SetEnumOperand do
206
+ before do
207
+ model = Gecode::Model.new
208
+ @operand, _ = general_set_enum_operand(model)
209
+ end
210
+
211
+ it_should_behave_like 'enum operand'
212
+ end
213
+
214
+ describe Gecode::FixnumEnum::FixnumEnumOperand do
215
+ before do
216
+ model = Gecode::Model.new
217
+ @operand, _ = general_fixnum_enum_operand(model)
218
+ end
219
+
220
+ it 'should raise error if constraint receiver is called' do
221
+ lambda do
222
+ @operand.must
223
+ end.should raise_error(NotImplementedError)
224
+ end
225
+
226
+ it_should_behave_like 'enum operand'
227
+ end
228
+
229
+ # High level sanity check.
230
+ describe 'operand combination' do
231
+ it 'should allow placing constraints on complicated combinations of operands' do
232
+ model = Gecode::Model.new
233
+ sets = model.set_var_array(2, [], 0..9)
234
+ set1, set2 = sets
235
+ (set1.size + set2.size).must == 5
236
+ set1.size.must > 1
237
+ set2.size.must > 1
238
+ model.branch_on sets
239
+
240
+ model.solve!
241
+
242
+ (set1.value.size + set2.value.size).should == 5
243
+ set1.value.size.should > 1
244
+ set2.value.size.should > 1
245
+ end
246
+
247
+ it 'should allow placing constraints on complicated combinations of operands (2)' do
248
+ model = Gecode::Model.new
249
+ sets = model.set_var_array(3, [], 0..9)
250
+ set1, set2, set3 = sets
251
+ (set1.size + set2.size).must == (set3.size - set1.max)
252
+ set3.size.must > 3
253
+ set2.size.must < 3
254
+ set1.size.must > 0
255
+ model.branch_on sets
256
+
257
+ model.solve!
258
+
259
+ (set1.value.size + set2.value.size).should == (set3.value.size - set1.value.max)
260
+ set3.value.size.should > 3
261
+ set2.value.size.should < 3
262
+ set1.value.size.should > 0
263
+ end
264
+ end
@@ -0,0 +1,443 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ # Every property should have a spec that specs the following:
4
+ #
5
+ # * An example where the property is used to constrain a sample problem.
6
+ # * should_behave_like foo operand
7
+ # * A test that the property is translated to the correct Gecode
8
+ # constraint if deemed necessary.
9
+
10
+ # Several of these shared specs requires one or more of the following instance
11
+ # variables to be used:
12
+ # [@operand] The operand that is being tested.
13
+ # [@model] The model that defines the context in which the test is
14
+ # conducted.
15
+ # [@property_types] An array of symbols signaling what types of
16
+ # arguments @select_property accepts. The symbols
17
+ # must be one of: :int, :bool, :set, :int_enum,
18
+ # :bool_enum, :set_enum, :fixnum_enum.
19
+ # [@select_property] A proc that selects the property under test. It
20
+ # should take at least one argument: the operand that
21
+ # the property should be selected from.
22
+ # [@selected_property] The resulting operand of the property. It should
23
+ # be constrained to the degree that it has a
24
+ # non-maximal domain.
25
+ # [@constraint_class] The class of the constraints that are expected to be
26
+ # produced when a constraint is short circuited.
27
+ #
28
+
29
+
30
+ # Requires @operand and @model.
31
+ describe 'int var operand', :shared => true do
32
+ it 'should implement #model' do
33
+ @operand.model.should be_kind_of(Gecode::Model)
34
+ end
35
+
36
+ it 'should implement #to_int_var' do
37
+ int_var = @operand.to_int_var
38
+ int_var.should be_kind_of(Gecode::IntVar)
39
+ @model.solve!
40
+ (int_var.min..int_var.max).should_not equal(Gecode::Model::LARGEST_INT_DOMAIN)
41
+ end
42
+
43
+ it 'should implement #must' do
44
+ receiver = @operand.must
45
+ receiver.should be_kind_of(
46
+ Gecode::Int::IntConstraintReceiver)
47
+ end
48
+ end
49
+
50
+ # Requires @operand and @model.
51
+ describe 'bool var operand', :shared => true do
52
+ it 'should implement #model' do
53
+ @operand.model.should be_kind_of(Gecode::Model)
54
+ end
55
+
56
+ it 'should implement #to_bool_var' do
57
+ bool_var = @operand.to_bool_var
58
+ bool_var.should be_kind_of(Gecode::BoolVar)
59
+ end
60
+
61
+ it 'should implement #must' do
62
+ receiver = @operand.must
63
+ receiver.should be_kind_of(
64
+ Gecode::Bool::BoolConstraintReceiver)
65
+ end
66
+ end
67
+
68
+ # Requires @operand and @model.
69
+ describe 'set var operand', :shared => true do
70
+ it 'should implement #model' do
71
+ @operand.model.should be_kind_of(Gecode::Model)
72
+ end
73
+
74
+ it 'should implement #to_set_var' do
75
+ set_var = @operand.to_set_var
76
+ set_var.should be_kind_of(Gecode::SetVar)
77
+ @model.solve!
78
+ ((set_var.lower_bound == []) &&
79
+ (set_var.upper_bound == Gecode::Model::LARGEST_SET_BOUND)).should_not(
80
+ be_true)
81
+ end
82
+
83
+ it 'should implement #must' do
84
+ receiver = @operand.must
85
+ receiver.should be_kind_of(
86
+ Gecode::Set::SetConstraintReceiver)
87
+ end
88
+ end
89
+
90
+ # Requires @model, @property_types and @select_property.
91
+ describe 'property that produces operand', :shared => true do
92
+ it 'should raise errors if parameters of the incorrect type are given' do
93
+ operands, variables = produce_general_arguments(@property_types)
94
+ (1...operands.size).each do |i|
95
+ bogus_operands = operands.clone
96
+ bogus_operands[i] = Object.new
97
+ lambda do
98
+ @select_property.call(*bogus_operands)
99
+ end.should raise_error(TypeError)
100
+ end
101
+ end
102
+ end
103
+
104
+ # Requires @model, @property_types and @select_property.
105
+ describe 'property that produces int operand', :shared => true do
106
+ it 'should produce int operand' do
107
+ operands, variables = produce_general_arguments(@property_types)
108
+ operand = @select_property.call(*operands)
109
+
110
+ # Test the same invariants as in the test for int var operands.
111
+ operand.model.should be_kind_of(Gecode::Model)
112
+
113
+ int_var = operand.to_int_var
114
+ int_var.should be_kind_of(Gecode::IntVar)
115
+
116
+ receiver = operand.must
117
+ receiver.should be_kind_of(
118
+ Gecode::Int::IntConstraintReceiver)
119
+ end
120
+
121
+ it_should_behave_like 'property that produces operand'
122
+ end
123
+
124
+ # Requires @model, @property_types and @select_property.
125
+ describe 'property that produces bool operand', :shared => true do
126
+ it 'should produce bool operand' do
127
+ operands, variables = produce_general_arguments(@property_types)
128
+ operand = @select_property.call(*operands)
129
+
130
+ # Test the same invariants as in the test for bool var operands.
131
+ operand.model.should be_kind_of(Gecode::Model)
132
+
133
+ bool_var = operand.to_bool_var
134
+ bool_var.should be_kind_of(Gecode::BoolVar)
135
+
136
+ receiver = operand.must
137
+ receiver.should be_kind_of(
138
+ Gecode::Bool::BoolConstraintReceiver)
139
+ end
140
+
141
+ it_should_behave_like 'property that produces operand'
142
+ end
143
+
144
+ # Requires @model, @property_types and @select_property.
145
+ describe 'property that produces set operand', :shared => true do
146
+ it 'should produce set operand' do
147
+ operands, variables = produce_general_arguments(@property_types)
148
+ operand = @select_property.call(*operands)
149
+
150
+ # Test the same invariants as in the test for int var operands.
151
+ operand.model.should be_kind_of(Gecode::Model)
152
+
153
+ set_var = operand.to_set_var
154
+ set_var.should be_kind_of(Gecode::SetVar)
155
+
156
+ receiver = operand.must
157
+ receiver.should be_kind_of(
158
+ Gecode::Set::SetConstraintReceiver)
159
+ end
160
+
161
+ it_should_behave_like 'property that produces operand'
162
+ end
163
+
164
+ # Requires @model, @constraint_class, @property_types, @select_property and
165
+ # @selected_property.
166
+ #
167
+ # These properties should only short circuit equality when there is no
168
+ # negation nor reification and the right hand side is an int operand.
169
+ describe 'property that produces int operand by short circuiting equality', :shared => true do
170
+ it 'should produce constraints when short circuited' do
171
+ @constraint_class.superclass.should == Gecode::Constraint
172
+ end
173
+
174
+ it 'should give the same solution regardless of whether short circuit was used' do
175
+ int_operand = @selected_property
176
+ direct_int_var = int_operand.to_int_var
177
+ indirect_int_op, _ = general_int_operand(@model)
178
+ @selected_property.must == indirect_int_op
179
+ @model.solve!
180
+
181
+ direct_int_var.should_not have_domain(Gecode::Model::LARGEST_INT_DOMAIN)
182
+ direct_int_var.should have_domain(indirect_int_op.domain)
183
+ end
184
+
185
+ it 'should short circuit equality' do
186
+ (@selected_property.must == @model.int_var).should(
187
+ be_kind_of(@constraint_class))
188
+ end
189
+
190
+ it 'should not short circuit when negation is used' do
191
+ (@selected_property.must_not == @model.int_var).should_not(
192
+ be_kind_of(@constraint_class))
193
+ end
194
+
195
+ it 'should not short circuit when reification is used' do
196
+ @selected_property.must.equal(@model.int_var,
197
+ :reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
198
+ end
199
+
200
+ it 'should not short circuit when the right hand side is not a operand' do
201
+ @selected_property.must.equal(2).should_not(be_kind_of(@constraint_class))
202
+ end
203
+
204
+ it 'should not short circuit when equality is not used' do
205
+ (@selected_property.must > @model.int_var).should_not(
206
+ be_kind_of(@constraint_class))
207
+ end
208
+
209
+ it 'should raise error when the right hand side is of illegal type' do
210
+ lambda do
211
+ @selected_property.must == 'foo'
212
+ end.should raise_error(TypeError)
213
+ end
214
+
215
+ it_should_behave_like 'property that produces int operand'
216
+ end
217
+
218
+ # Requires @model, @constraint_class, @property_types, @select_property and
219
+ # @selected_property.
220
+ #
221
+ # These properties should only short circuit equality when there is no
222
+ # negation nor reification and the right hand side is a bool operand.
223
+ describe 'property that produces bool operand by short circuiting equality', :shared => true do
224
+ it 'should produce constraints when short circuited' do
225
+ @constraint_class.superclass.should == Gecode::Constraint
226
+ end
227
+
228
+ it 'should give the same solution regardless of whether short circuit was used' do
229
+ bool_operand = @selected_property
230
+ direct_bool_var = bool_operand.to_bool_var
231
+ indirect_bool_var = @model.bool_var
232
+ @selected_property.must == indirect_bool_var
233
+ @model.solve!
234
+
235
+ direct_bool_var.value.should == indirect_bool_var.value
236
+ end
237
+
238
+ it 'should short circuit equality' do
239
+ (@selected_property.must == @model.bool_var).should(
240
+ be_kind_of(@constraint_class))
241
+ end
242
+
243
+ it 'should not short circuit when negation is used' do
244
+ (@selected_property.must_not == @model.bool_var).should_not(
245
+ be_kind_of(@constraint_class))
246
+ end
247
+
248
+ it 'should not short circuit when reification is used' do
249
+ @selected_property.must.equal(@model.bool_var,
250
+ :reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
251
+ end
252
+
253
+ it 'should not short circuit when equality is not used' do
254
+ (@selected_property.must.imply @model.bool_var).should_not(
255
+ be_kind_of(@constraint_class))
256
+ end
257
+
258
+ it 'should raise error when the right hand side is of illegal type' do
259
+ lambda do
260
+ @selected_property.must == 'foo'
261
+ end.should raise_error(TypeError)
262
+ end
263
+
264
+ it_should_behave_like 'property that produces bool operand'
265
+ end
266
+
267
+ # Requires @model, @constraint_class, @property_types and @select_property.
268
+ #
269
+ # These properties should short circuit all comparison relations
270
+ # even when negated and when fixnums are used as right hand side.
271
+ describe 'property that produces int operand by short circuiting relations', :shared => true do
272
+ it 'should produce reifiable constraints when short circuited' do
273
+ @constraint_class.superclass.should ==
274
+ Gecode::ReifiableConstraint
275
+ end
276
+
277
+ Gecode::Util::RELATION_TYPES.keys.each do |relation|
278
+ it "should give the same solution regardless of whether short circuit #{relation} was used" do
279
+ direct_int_var = @model.int_var
280
+ @selected_property.to_int_var.must.method(relation).call direct_int_var
281
+ indirect_int_var = @model.int_var
282
+ @selected_property.must.method(relation).call indirect_int_var
283
+ @model.solve!
284
+
285
+ direct_int_var.should_not have_domain(Gecode::Model::LARGEST_INT_DOMAIN)
286
+ direct_int_var.should have_domain(indirect_int_var.domain)
287
+ end
288
+
289
+ it "should short circuit #{relation}" do
290
+ (@selected_property.must.method(relation).call @model.int_var).should(
291
+ be_kind_of(@constraint_class))
292
+ end
293
+
294
+ it "should short circuit negated #{relation}" do
295
+ (@selected_property.must_not.method(relation).call @model.int_var).should(
296
+ be_kind_of(@constraint_class))
297
+ end
298
+
299
+ it "should short circuit #{relation} when reification is used" do
300
+ (@selected_property.must.method(relation).call(@model.int_var,
301
+ :reify => @model.bool_var)).should(be_kind_of(@constraint_class))
302
+ end
303
+
304
+ it "should short circuit #{relation} even when the right hand side is a fixnum" do
305
+ (@selected_property.must.method(relation).call 2).should(
306
+ be_kind_of(@constraint_class))
307
+ end
308
+
309
+ it "should raise error when the #{relation} right hand side is of illegal type" do
310
+ lambda do
311
+ @selected_property.must.method(relation).call('foo')
312
+ end.should raise_error(TypeError)
313
+ end
314
+ end
315
+
316
+ it_should_behave_like 'property that produces int operand'
317
+ end
318
+
319
+ # Requires @model, @constraint_class, @property_types, @select_property and
320
+ # @selected_property.
321
+ #
322
+ # These properties should only short circuit equality when there is no
323
+ # negation nor reification and the right hand side is a set operand.
324
+ describe 'property that produces set operand by short circuiting equality', :shared => true do
325
+ it 'should produce constraints when short circuited' do
326
+ @constraint_class.superclass.should == Gecode::Constraint
327
+ end
328
+
329
+ it 'should give the same solution regardless of whether short circuit was used' do
330
+ set_operand = @selected_property
331
+ direct_set_var = set_operand.to_set_var
332
+ indirect_set_var = @model.set_var
333
+ @selected_property.must == indirect_set_var
334
+ @model.solve!
335
+
336
+ direct_set_var.should have_bounds(indirect_set_var.lower_bound,
337
+ indirect_set_var.upper_bound)
338
+ end
339
+
340
+ it 'should short circuit equality' do
341
+ (@selected_property.must == @model.set_var).should(
342
+ be_kind_of(@constraint_class))
343
+ end
344
+
345
+ it 'should not short circuit when negation is used' do
346
+ (@selected_property.must_not == @model.set_var).should_not(
347
+ be_kind_of(@constraint_class))
348
+ end
349
+
350
+ it 'should not short circuit when reification is used' do
351
+ (@selected_property.must.equal(@model.set_var,
352
+ :reify => @model.bool_var)).should_not(be_kind_of(@constraint_class))
353
+ end
354
+
355
+ it 'should not short circuit when the right hand side is not a operand' do
356
+ (@selected_property.must == [1,3,5]).should_not(
357
+ be_kind_of(@constraint_class))
358
+ end
359
+
360
+ it 'should not short circuit when equality is not used' do
361
+ (@selected_property.must_be.subset_of(@model.set_var)).should_not(
362
+ be_kind_of(@constraint_class))
363
+ end
364
+
365
+ it 'should raise error when the right hand side is of illegal type' do
366
+ lambda do
367
+ @selected_property.must == 'foo'
368
+ end.should raise_error(TypeError)
369
+ end
370
+
371
+ it_should_behave_like 'property that produces set operand'
372
+ end
373
+
374
+ # Requires @model, @constraint_class, @property_types and @select_property.
375
+ #
376
+ # These properties should only short circuit set relations when neither
377
+ # negation nor reification is used (both for constant sets and set
378
+ # variables).
379
+ describe 'property that produces set operand by short circuiting set relations', :shared => true do
380
+ Gecode::Util::SET_RELATION_TYPES.keys.each do |relation|
381
+ it 'should produce constraints when short circuited' do
382
+ @constraint_class.superclass.should == Gecode::Constraint
383
+ end
384
+
385
+ it "should give the same solution regardless of whether short circuit #{relation} was used" do
386
+ if relation == :complement
387
+ direct_set_var, indirect_set_var = Array.new(2){ @model.set_var }
388
+ else
389
+ direct_set_var, indirect_set_var = Array.new(2) do
390
+ @model.set_var([], -1000..1000)
391
+ end
392
+ end
393
+
394
+ @selected_property.to_set_var.must.method(relation).call direct_set_var
395
+ @selected_property.must.method(relation).call indirect_set_var
396
+ @model.solve!
397
+
398
+ if relation == :complement
399
+ direct_set_var.upper_bound.min.should ==
400
+ indirect_set_var.upper_bound.min
401
+ direct_set_var.upper_bound.max.should ==
402
+ indirect_set_var.upper_bound.max
403
+ direct_set_var.lower_bound.min.should ==
404
+ indirect_set_var.lower_bound.min
405
+ direct_set_var.lower_bound.max.should ==
406
+ indirect_set_var.lower_bound.max
407
+ direct_set_var.lower_bound.size.should ==
408
+ indirect_set_var.lower_bound.size
409
+ else
410
+ direct_set_var.should have_bounds(indirect_set_var.lower_bound,
411
+ indirect_set_var.upper_bound)
412
+ end
413
+ end
414
+
415
+ it "should short circuit #{relation}" do
416
+ @selected_property.must.method(relation).call(@model.set_var).should(
417
+ be_kind_of(@constraint_class))
418
+ end
419
+
420
+ it "should not short circuit negated #{relation}" do
421
+ @selected_property.must_not.method(relation).call(
422
+ @model.set_var).should_not(be_kind_of(@constraint_class))
423
+ end
424
+
425
+ it "should not short circuit reified #{relation}" do
426
+ @selected_property.must.method(relation).call(@model.set_var,
427
+ :reify => @model.bool_var).should_not(be_kind_of(@constraint_class))
428
+ end
429
+
430
+ it "should short circuit #{relation} even when the right hand side is a constant set" do
431
+ @selected_property.must.method(relation).call([1, 2, 3]).should(
432
+ be_kind_of(@constraint_class))
433
+ end
434
+
435
+ it "should raise error when the #{relation} right hand side is of illegal type" do
436
+ lambda do
437
+ @selected_property.must.method(relation).call('foo')
438
+ end.should raise_error(TypeError)
439
+ end
440
+ end
441
+
442
+ it_should_behave_like 'property that produces set operand'
443
+ end