gecoder-with-gecode 0.9.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
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
data/specs/logging.rb ADDED
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Gecode::LoggingLayer do
4
+ before do
5
+ # Enable logging.
6
+ Gecode.instance_eval{ remove_const(:Raw) }
7
+ Gecode.const_set(:Raw, Gecode::LoggingLayer)
8
+ end
9
+
10
+ after do
11
+ # Disable logging.
12
+ Gecode.instance_eval{ remove_const(:Raw) }
13
+ Gecode.const_set(:Raw, GecodeRaw)
14
+ end
15
+
16
+ it "shouldn't interfere with calls through Gecode::Raw" do
17
+ lambda do
18
+ model = Gecode::Model.new
19
+ int_var = model.int_var(0..9)
20
+ int_var.must >= 5
21
+ model.solve!
22
+ end.should_not raise_error
23
+ end
24
+ end
data/specs/model.rb ADDED
@@ -0,0 +1,325 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Gecode::Model, ' (integer creation)' do
4
+ before do
5
+ @model = Gecode::Model.new
6
+ end
7
+
8
+ it 'should allow the creation of int variables with range' do
9
+ range = 0..3
10
+ @model.int_var(range).should have_domain(range)
11
+ end
12
+
13
+ it 'should allow the creation of int variables without specified domain' do
14
+ var = @model.int_var
15
+ var.should be_range
16
+ var.min.should == Gecode::Raw::IntLimits::MIN
17
+ var.max.should == Gecode::Raw::IntLimits::MAX
18
+ end
19
+
20
+ it 'should allow the creation of int variables with non-range domains' do
21
+ domain = [1, 3, 5]
22
+ @model.int_var(domain).should have_domain(domain)
23
+ end
24
+
25
+ it 'should allow the creation of int variables with single element domains' do
26
+ domain = 3
27
+ @model.int_var(domain).should have_domain([domain])
28
+ end
29
+
30
+ it 'should allow the creation of int-var arrays with range domains' do
31
+ range = 0..3
32
+ count = 5
33
+ vars = @model.int_var_array(count, range)
34
+ vars.size.should equal(count)
35
+ vars.each{ |var| var.should have_domain(range) }
36
+ end
37
+
38
+ it 'should allow the creation of int-var arrays with non-range domains' do
39
+ domain = [1,3,5]
40
+ count = 5
41
+ vars = @model.int_var_array(count, domain)
42
+ vars.size.should equal(count)
43
+ vars.each{ |var| var.should have_domain(domain) }
44
+ end
45
+
46
+ it 'should allow the creation of int-var arrays without specified domain' do
47
+ count = 5
48
+ vars = @model.int_var_array(count)
49
+ vars.size.should equal(count)
50
+ vars.each do |var|
51
+ var.should be_range
52
+ var.min.should == Gecode::Raw::IntLimits::MIN
53
+ var.max.should == Gecode::Raw::IntLimits::MAX
54
+ end
55
+ end
56
+
57
+ it 'should allow the creation of int-var matrices with range domains' do
58
+ range = 0..3
59
+ rows = 5
60
+ columns = 4
61
+ vars = @model.int_var_matrix(rows, columns, range)
62
+ vars.row_size.should equal(rows)
63
+ vars.column_size.should equal(columns)
64
+ vars.each{ |var| var.should have_domain(range) }
65
+ end
66
+
67
+ it 'should allow the creation of int-var matrices with non-range domains' do
68
+ domain = [1,3,5]
69
+ rows = 5
70
+ columns = 4
71
+ vars = @model.int_var_matrix(rows, columns, domain)
72
+ vars.row_size.should equal(rows)
73
+ vars.column_size.should equal(columns)
74
+ vars.each{ |var| var.should have_domain(domain) }
75
+ end
76
+
77
+ it 'should allow the creation of int-var matrices without specified domain' do
78
+ rows = 5
79
+ columns = 4
80
+ vars = @model.int_var_matrix(rows, columns)
81
+ vars.row_size.should equal(rows)
82
+ vars.column_size.should equal(columns)
83
+ vars.each do |var|
84
+ var.should be_range
85
+ var.min.should == Gecode::Raw::IntLimits::MIN
86
+ var.max.should == Gecode::Raw::IntLimits::MAX
87
+ end
88
+ end
89
+
90
+ it 'should raise error if the domain is of incorrect type' do
91
+ lambda do
92
+ @model.int_var(nil)
93
+ end.should raise_error(TypeError)
94
+ end
95
+
96
+ it 'should gracefully GC a variable that was never accessed' do
97
+ lambda do
98
+ @model.int_var 0
99
+ GC.start
100
+ end.should_not raise_error
101
+ end
102
+ end
103
+
104
+ describe Gecode::Model, ' (bool creation)' do
105
+ before do
106
+ @model = Gecode::Model.new
107
+ end
108
+
109
+ it 'should allow the creation of boolean variables' do
110
+ @model.bool_var.should_not be_nil
111
+ end
112
+
113
+ it 'should allow the creation of arrays of boolean variables' do
114
+ @model.bool_var_array(3).size.should equal(3)
115
+ end
116
+
117
+ it 'should allow the creation of matrices of boolean variables' do
118
+ matrix = @model.bool_var_matrix(3, 4)
119
+ matrix.row_size.should equal(3)
120
+ matrix.column_size.should equal(4)
121
+ end
122
+
123
+ it 'should gracefully GC a variable that was never accessed' do
124
+ lambda do
125
+ @model.bool_var
126
+ GC.start
127
+ end.should_not raise_error
128
+ end
129
+ end
130
+
131
+ describe Gecode::Model, ' (set creation)' do
132
+ before do
133
+ @model = Gecode::Model.new
134
+ @glb_range = 0..3
135
+ @lub_range = 0..5
136
+ @glb_enum = [0, 3]
137
+ @lub_enum = [0, 1, 2, 3, 5]
138
+ @lower_card = 1
139
+ @upper_card = 3
140
+ end
141
+
142
+ it 'should allow the creation of set variables without specified bounds' do
143
+ var = @model.set_var
144
+ var.lower_bound.size.should == 0
145
+ var.upper_bound.min.should == Gecode::Raw::SetLimits::MIN
146
+ var.upper_bound.max.should == Gecode::Raw::SetLimits::MAX
147
+ end
148
+
149
+ it 'should allow the creation of set variables with glb range and lub range' do
150
+ @model.set_var(@glb_range, @lub_range).should have_bounds(@glb_range,
151
+ @lub_range)
152
+ end
153
+
154
+ it 'should allow the creation of set variables with glb enum and lub range' do
155
+ @model.set_var(@glb_enum, @lub_range).should have_bounds(@glb_enum,
156
+ @lub_range)
157
+ end
158
+
159
+ it 'should allow the creation of set variables with glb range and lub enum' do
160
+ @model.set_var(@glb_range, @lub_enum).should have_bounds(@glb_range,
161
+ @lub_enum)
162
+ end
163
+
164
+ it 'should allow the creation of set variables with glb enum and lub enum' do
165
+ @model.set_var(@glb_enum, @lub_enum).should have_bounds(@glb_enum,
166
+ @lub_enum)
167
+ end
168
+
169
+ it 'should allow the creation of set variables with specified lower cardinality bound' do
170
+ @model.set_var(@glb_range, @lub_range,
171
+ @lower_card).cardinality.begin.should >= @lower_card
172
+ end
173
+
174
+ it 'should allow the creation of set variables with specified cardinality range' do
175
+ var = @model.set_var(@glb_range, @lub_range, @lower_card..@upper_card)
176
+ var.cardinality.end.should <= @upper_card
177
+ var.cardinality.begin.should >= @lower_card
178
+ end
179
+
180
+ it 'should allow the creation of arrays of set variables' do
181
+ arr = @model.set_var_array(3, @glb_enum, @lub_enum, @lower_card..@upper_card)
182
+ arr.size.should == 3
183
+ arr.each do |var|
184
+ var.should have_bounds(@glb_enum, @lub_enum)
185
+ var.cardinality.end.should <= @upper_card
186
+ var.cardinality.begin.should >= @lower_card
187
+ end
188
+ end
189
+
190
+ it 'should allow the creation of arrays of set variables without specified bounds' do
191
+ vars = @model.set_var_array(3)
192
+ vars.each do |var|
193
+ var.lower_bound.size.should == 0
194
+ var.upper_bound.min.should == Gecode::Raw::SetLimits::MIN
195
+ var.upper_bound.max.should == Gecode::Raw::SetLimits::MAX
196
+ end
197
+ end
198
+
199
+ it 'should allow the creation of matrices of set variables' do
200
+ matrix = @model.set_var_matrix(4, 5, @glb_enum, @lub_enum,
201
+ @lower_card..@upper_card)
202
+ matrix.row_size.should == 4
203
+ matrix.column_size.should == 5
204
+ matrix.each do |var|
205
+ var.should have_bounds(@glb_enum, @lub_enum)
206
+ var.cardinality.end.should <= @upper_card
207
+ var.cardinality.begin.should >= @lower_card
208
+ end
209
+ end
210
+
211
+ it 'should allow the creation of matrices of set variables without specified bounds' do
212
+ matrix = @model.set_var_matrix(4, 5)
213
+ matrix.each do |var|
214
+ var.lower_bound.size.should == 0
215
+ var.upper_bound.min.should == Gecode::Raw::SetLimits::MIN
216
+ var.upper_bound.max.should == Gecode::Raw::SetLimits::MAX
217
+ end
218
+ end
219
+
220
+ it 'should raise error if glb and lub are not valid when they are given as range' do
221
+ lambda do
222
+ @model.set_var(@lub_range, @glb_range)
223
+ end.should raise_error(ArgumentError)
224
+ end
225
+
226
+ it 'should raise error if glb and lub are not valid when one is given as enum' do
227
+ lambda do
228
+ @model.set_var(@lub_range, @glb_enum)
229
+ end.should raise_error(ArgumentError)
230
+ end
231
+
232
+ it 'should raise error if glb and lub are not valid when both are given as enums' do
233
+ lambda do
234
+ @model.set_var(@lub_enum, @glb_enum)
235
+ end.should raise_error(ArgumentError)
236
+ end
237
+
238
+ it 'should raise error if the glb and lub are of incorrect type' do
239
+ lambda do
240
+ @model.set_var("foo\n", "foo\ns")
241
+ end.should raise_error(TypeError)
242
+ end
243
+
244
+ it 'should gracefully GC a variable that was never accessed' do
245
+ lambda do
246
+ @model.set_var(@glb_range, @lub_range)
247
+ GC.start
248
+ end.should_not raise_error
249
+ end
250
+ end
251
+
252
+ describe Gecode::Model, ' (space access restriction)' do
253
+ before do
254
+ @model = Gecode::Model.new
255
+ end
256
+
257
+ it 'should raise error if not allowed to access space' do
258
+ lambda{ @model.active_space }.should raise_error(RuntimeError)
259
+ end
260
+
261
+ it 'should not raise error because of space restriction if allowed to access space' do
262
+ lambda do
263
+ @model.allow_space_access do
264
+ @model.active_space
265
+ end
266
+ end.should_not raise_error(RuntimeError)
267
+ end
268
+ end
269
+
270
+ describe Gecode::Model, ' (accessible variable creation)' do
271
+ before do
272
+ @model = Class.new(Gecode::Model).new
273
+ end
274
+
275
+ it 'should allow creation of named variable using #foo_is_a' do
276
+ var = @model.int_var(17)
277
+ lambda{ @model.foo }.should raise_error(NoMethodError)
278
+ @model.instance_eval{ foo_is_a var }
279
+ lambda{ @model.foo }.should_not raise_error
280
+ @model.foo.should == var
281
+ end
282
+
283
+ it 'should allow creation of named variable using #foo_is_an' do
284
+ var = @model.int_var(17)
285
+ lambda{ @model.foo }.should raise_error(NoMethodError)
286
+ @model.instance_eval{ foo_is_an var }
287
+ lambda{ @model.foo }.should_not raise_error
288
+ @model.foo.should == var
289
+ end
290
+
291
+ it 'should only allow one argument to be given to #foo_is_a' do
292
+ lambda do
293
+ @model.instance_eval{ foo_is_a }
294
+ end.should raise_error(ArgumentError)
295
+ lambda do
296
+ @model.instance_eval{ foo_is_a bool_var, bool_var }
297
+ end.should raise_error(ArgumentError)
298
+ end
299
+
300
+ it 'should only define the variable in the current instance' do
301
+ klass = Class.new Gecode::Model
302
+ model_a = klass.new
303
+ model_b = klass.new
304
+
305
+ model_a.instance_eval{ bar_is_a bool_var }
306
+ lambda{ model_a.bar }.should_not raise_error
307
+ lambda{ model_b.bar }.should raise_error(NoMethodError)
308
+ end
309
+
310
+ it 'should raise error if a method would be overwritten' do
311
+ var = @model.int_var(17)
312
+ lambda{ @model.class }.should_not raise_error
313
+ lambda do
314
+ @model.instance_eval{ class_is_an var }
315
+ end.should raise_error(ArgumentError)
316
+ end
317
+
318
+ it 'should raise error if an instance variable would be overwritten' do
319
+ @model.instance_eval{ @foo = 17 }
320
+ var = @model.int_var(17)
321
+ lambda do
322
+ @model.instance_eval{ foo_is_a var }
323
+ end.should raise_error(ArgumentError)
324
+ end
325
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Gecode, ' (Model sugar)' do
4
+ it 'should provide #solve as sugar for constructing a model and running solve!' do
5
+ Gecode.solve do
6
+ numbers_is_an int_var_array(2, 0..5)
7
+ x, y = numbers
8
+ (x * y).must == 25
9
+ branch_on numbers
10
+ end.numbers.values.should == [5,5]
11
+ end
12
+
13
+ it 'should provide #maximize as sugar for constructing a model and running maximize!' do
14
+ Gecode.maximize :z do
15
+ z_is_an int_var
16
+ x, y = vars = int_var_array(2, 0..5)
17
+ (x*2 - y).must == z
18
+ branch_on vars
19
+ end.z.value.should equal(10)
20
+ end
21
+
22
+ it 'should provide #minimize as sugar for constructing a model and running minimize!' do
23
+ Gecode.minimize :z do
24
+ z_is_an int_var
25
+ x, y = vars = int_var_array(2, 0..5)
26
+ (x*2 - y).must == z
27
+ branch_on vars
28
+ end.z.value.should equal(-5)
29
+ end
30
+ end
data/specs/search.rb ADDED
@@ -0,0 +1,383 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'set'
3
+
4
+ class SampleProblem < Gecode::Model
5
+ attr :var
6
+ attr :array
7
+ attr :hash
8
+ attr :nested_enum
9
+
10
+ def initialize(domain)
11
+ vars = self.int_var_array(1,domain)
12
+ @var = vars.first
13
+ @var.must > 1
14
+ @array = [@var]
15
+ @hash = {:a => var}
16
+ @nested_enum = [1,2,[@var],[7, {:b => var}]]
17
+
18
+ branch_on vars, :variable => :smallest_size, :value => :min
19
+ end
20
+ end
21
+
22
+ class SampleOptimizationProblem < Gecode::Model
23
+ attr :x
24
+ attr :y
25
+ attr :z
26
+
27
+ def initialize
28
+ @x,@y = int_var_array(2, 0..5)
29
+ @z = int_var(0..25)
30
+ (@x * @y).must == @z
31
+
32
+ branch_on wrap_enum([@x, @y]), :variable => :smallest_size, :value => :min
33
+ end
34
+ end
35
+
36
+ class SampleOptimizationProblem2 < Gecode::Model
37
+ attr :money
38
+
39
+ def initialize
40
+ @money = int_var_array(3, 0..9)
41
+ @money.must_be.distinct
42
+ @money.to_number.must < 500 # Otherwise it takes some time.
43
+
44
+ branch_on @money, :variable => :smallest_size, :value => :min
45
+ end
46
+ end
47
+
48
+ class Array
49
+ # Computes a number of the specified base using the array's elements as
50
+ # digits.
51
+ def to_number(base = 10)
52
+ inject{ |result, variable| variable + result * base }
53
+ end
54
+ end
55
+
56
+ describe Gecode::Model, ' (with multiple solutions)' do
57
+ before do
58
+ @domain = 0..3
59
+ @solved_domain = [2]
60
+ @model = SampleProblem.new(@domain)
61
+ end
62
+
63
+ it 'should pass a solution to the block given in #solution' do
64
+ @model.solution do |s|
65
+ s.var.should have_domain(@solved_domain)
66
+ end
67
+ end
68
+
69
+ it 'should update the search statistics before yielding to #solution' do
70
+ @model.solution do |s|
71
+ @model.search_stats.should_not be_nil
72
+ end
73
+ end
74
+
75
+ it 'should only evaluate the block for one solution in #solution' do
76
+ i = 0
77
+ @model.solution{ |s| i += 1 }
78
+ i.should equal(1)
79
+ end
80
+
81
+ it 'should return the result of the block when calling #solution' do
82
+ @model.solution{ |s| 'test' }.should == 'test'
83
+ end
84
+
85
+ it 'should pass every solution to #each_solution' do
86
+ solutions = []
87
+ @model.each_solution do |s|
88
+ solutions << s.var.value
89
+ end
90
+ Set.new(solutions).should == Set.new([2,3])
91
+ end
92
+
93
+ it 'should update the search statistics before yielding to #each_solution' do
94
+ solutions = []
95
+ old_stats = @model.search_stats
96
+ old_stats.should be_nil
97
+ @model.each_solution do |s|
98
+ solutions << s.var.value
99
+ @model.search_stats.should_not == old_stats
100
+ @model.search_stats.should_not be_nil
101
+ old_stats = @model.search_stats
102
+ end
103
+ end
104
+ end
105
+
106
+ describe Gecode::Model, ' (after #solve!)' do
107
+ before do
108
+ @domain = 0..3
109
+ @solved_domain = [2]
110
+ @model = SampleProblem.new(@domain)
111
+ @model.solve!
112
+ end
113
+
114
+ it 'should have updated the variables domains' do
115
+ @model.var.should have_domain(@solved_domain)
116
+ end
117
+
118
+ it 'should have updated variables in arrays' do
119
+ @model.array.first.should have_domain(@solved_domain)
120
+ end
121
+
122
+ it 'should have updated variables in hashes' do
123
+ @model.hash.values.first.should have_domain(@solved_domain)
124
+ end
125
+
126
+ it 'should have updated variables in nested enums' do
127
+ enum = @model.solve!.nested_enum
128
+ enum[2].first.should have_domain(@solved_domain)
129
+ enum[3][1][:b].should have_domain(@solved_domain)
130
+
131
+ enum = @model.nested_enum
132
+ enum[2].first.should have_domain(@solved_domain)
133
+ enum[3][1][:b].should have_domain(@solved_domain)
134
+ end
135
+
136
+ it 'should have updated the search statistics' do
137
+ stats = @model.search_stats
138
+ stats[:propagations].should == 0
139
+ stats[:failures].should == 0
140
+ stats[:clones].should_not be_nil
141
+ stats[:commits].should_not be_nil
142
+ stats[:memory].should > 0
143
+ end
144
+ end
145
+
146
+ describe 'reset model', :shared => true do
147
+ it 'should have reset variables' do
148
+ @model.var.should have_domain(@reset_domain)
149
+ end
150
+
151
+ it 'should have reset variables in nested enums' do
152
+ enum = @model.nested_enum
153
+ enum[2].first.should have_domain(@reset_domain)
154
+ enum[3][1][:b].should have_domain(@reset_domain)
155
+ end
156
+
157
+ it 'should have cleared the search statistics' do
158
+ @model.search_stats.should be_nil
159
+ end
160
+ end
161
+
162
+ describe Gecode::Model, ' (after #reset!)' do
163
+ before do
164
+ @domain = 0..3
165
+ @reset_domain = 2..3
166
+ @model = SampleProblem.new(@domain)
167
+ @model.solve!
168
+ @model.reset!
169
+ end
170
+
171
+ it_should_behave_like 'reset model'
172
+ end
173
+
174
+ describe Gecode::Model, ' (after #solution)' do
175
+ before do
176
+ @domain = 0..3
177
+ @reset_domain = 2..3
178
+ @model = SampleProblem.new(@domain)
179
+ @model.solution{ |s| }
180
+ end
181
+
182
+ it_should_behave_like 'reset model'
183
+ end
184
+
185
+ describe Gecode::Model, ' (after #each_solution)' do
186
+ before do
187
+ @domain = 0..3
188
+ @reset_domain = 2..3
189
+ @model = SampleProblem.new(@domain)
190
+ @model.each_solution{ |s| }
191
+ end
192
+
193
+ it_should_behave_like 'reset model'
194
+ end
195
+
196
+ describe Gecode::Model, ' (without solution)' do
197
+ before do
198
+ @domain = 0..3
199
+ @model = SampleProblem.new(@domain)
200
+ @model.var.must < 0
201
+ end
202
+
203
+ it 'should return nil when calling #solution' do
204
+ @model.solution{ |s| 'test' }.should be_nil
205
+ end
206
+
207
+ it 'should not yield anything to #each_solution' do
208
+ @model.each_solution{ |s| violated }
209
+ end
210
+
211
+ it 'should raise NoSolutionError when calling #solve!' do
212
+ lambda do
213
+ @model.solve!
214
+ end.should raise_error(Gecode::NoSolutionError)
215
+ end
216
+
217
+ it 'should raise NoSolutionError when calling #optimize!' do
218
+ lambda do
219
+ @model.optimize!{}
220
+ end.should raise_error(Gecode::NoSolutionError)
221
+ end
222
+
223
+ it 'should raise NoSolutionError when calling #minimize!' do
224
+ lambda do
225
+ @model.optimize!{}
226
+ end.should raise_error(Gecode::NoSolutionError)
227
+ end
228
+
229
+ it 'should raise NoSolutionError when calling #maximize!' do
230
+ lambda do
231
+ @model.maximize!(:var)
232
+ end.should raise_error(Gecode::NoSolutionError)
233
+ end
234
+ end
235
+
236
+ describe Gecode::Model, ' (without constraints)' do
237
+ before do
238
+ @model = Gecode::Model.new
239
+ @x = @model.int_var(0..1)
240
+ end
241
+
242
+ it 'should produce a solution' do
243
+ @model.solve!.should_not be_nil
244
+ end
245
+ end
246
+
247
+ describe Gecode::Model, '(optimization search)' do
248
+ it 'should optimize the solution' do
249
+ solution = SampleOptimizationProblem.new.optimize! do |model, best_so_far|
250
+ model.z.must > best_so_far.z.value
251
+ end
252
+ solution.should_not be_nil
253
+ solution.x.value.should == 5
254
+ solution.y.value.should == 5
255
+ solution.z.value.should == 25
256
+ end
257
+
258
+ it 'should not be bothered by garbage collecting' do
259
+ # This goes through 400+ spaces.
260
+ solution = SampleOptimizationProblem2.new.optimize! do |model, best_so_far|
261
+ model.money.to_number.must > best_so_far.money.values.to_number
262
+ end
263
+ solution.should_not be_nil
264
+ solution.money.values.to_number.should == 498
265
+ end
266
+
267
+ it 'should raise error if no constrain proc has been defined' do
268
+ lambda do
269
+ Gecode::Model.constrain(nil, nil)
270
+ end.should raise_error(NotImplementedError)
271
+ end
272
+
273
+ it 'should not have problems with variables being created in the optimization block' do
274
+ solution = SampleOptimizationProblem.new.optimize! do |model, best_so_far|
275
+ tmp = model.int_var(0..25)
276
+ tmp.must == model.z
277
+ tmp.must > best_so_far.z.value
278
+ end
279
+ solution.should_not be_nil
280
+ solution.x.value.should == 5
281
+ solution.y.value.should == 5
282
+ solution.z.value.should == 25
283
+ end
284
+
285
+ it 'should not have problems with variables being created in the optimization block (2)' do
286
+ solution = SampleOptimizationProblem.new.optimize! do |model, best_so_far|
287
+ tmp = model.int_var(0..25)
288
+ tmp.must == model.z
289
+ (tmp + tmp).must > best_so_far.z.value*2
290
+ end
291
+ solution.should_not be_nil
292
+ solution.x.value.should == 5
293
+ solution.y.value.should == 5
294
+ solution.z.value.should == 25
295
+ end
296
+
297
+ it 'should update the search statistics' do
298
+ model = SampleOptimizationProblem.new
299
+ solution = model.maximize! :z
300
+
301
+ stats = model.search_stats
302
+ stats.should_not be_nil
303
+ stats[:propagations].should be_between(1, 100)
304
+ stats[:failures].should be_between(1, 100)
305
+ stats[:clones].should_not be_nil
306
+ stats[:commits].should_not be_nil
307
+ stats[:memory].should > 0
308
+ end
309
+ end
310
+
311
+ describe 'single variable optimization', :shared => true do
312
+ it "should support #{@method_name} having the variable given as a symbol" do
313
+ solution = @model.method(@method_name).call(@variable_name.to_sym)
314
+ @expect_to_be_correct.call(solution)
315
+ end
316
+
317
+ it "should support #{@method_name} having the variable given as a string" do
318
+ solution = @model.method(@method_name).call(@variable_name.to_s)
319
+ @expect_to_be_correct.call(solution)
320
+ end
321
+
322
+ it "should raise error if #{@method_name} is given a non-existing method" do
323
+ lambda do
324
+ SampleOptimizationProblem.new.method(@method_name).call(:does_not_exist)
325
+ end.should raise_error(NameError)
326
+ end
327
+
328
+ it "should raise error if #{@method_name} is given a method that does not return an integer variable" do
329
+ lambda do
330
+ SampleOptimizationProblem.new.method(@method_name).call(:object_id)
331
+ end.should raise_error(ArgumentError)
332
+ end
333
+
334
+ it 'should update the search statistics' do
335
+ @model.method(@method_name).call(@variable_name.to_sym)
336
+
337
+ stats = @model.search_stats
338
+ stats.should_not be_nil
339
+ stats[:propagations].should be_between(1, 100)
340
+ stats[:failures].should be_between(1, 100)
341
+ stats[:clones].should_not be_nil
342
+ stats[:commits].should_not be_nil
343
+ stats[:memory].should > 0
344
+ end
345
+ end
346
+
347
+ describe Gecode::Model, '(single variable minimization)' do
348
+ before do
349
+ @method_name = 'minimize!'
350
+ @variable_name = 'x'
351
+
352
+ @model = SampleOptimizationProblem.new
353
+ @model.z.must > 2
354
+
355
+ @expect_to_be_correct = lambda do |solution|
356
+ solution.should_not be_nil
357
+ solution.x.value.should == 1
358
+ solution.y.value.should == 3
359
+ solution.z.value.should == 3
360
+ end
361
+ end
362
+
363
+ it_should_behave_like 'single variable optimization'
364
+ end
365
+
366
+ describe Gecode::Model, '(single variable maximization)' do
367
+ before do
368
+ @method_name = 'maximize!'
369
+ @variable_name = 'z'
370
+
371
+ @model = SampleOptimizationProblem.new
372
+
373
+ @expect_to_be_correct = lambda do |solution|
374
+ solution.should_not be_nil
375
+ solution.x.value.should == 5
376
+ solution.y.value.should == 5
377
+ solution.z.value.should == 25
378
+ end
379
+ end
380
+
381
+ it_should_behave_like 'single variable optimization'
382
+ end
383
+