gecoder-with-gecode 0.7.1-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +81 -0
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +45 -0
- data/Rakefile +13 -0
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/queens.rb +43 -0
- data/example/raw_bindings.rb +42 -0
- data/example/send_more_money.rb +43 -0
- data/example/send_most_money.rb +58 -0
- data/example/square_tiling.rb +84 -0
- data/example/sudoku-set.rb +110 -0
- data/example/sudoku.rb +61 -0
- data/lib/gecode.dll +0 -0
- data/lib/gecoder.rb +5 -0
- data/lib/gecoder/bindings.rb +54 -0
- data/lib/gecoder/bindings/bindings.rb +2210 -0
- data/lib/gecoder/interface.rb +8 -0
- data/lib/gecoder/interface/binding_changes.rb +313 -0
- data/lib/gecoder/interface/branch.rb +152 -0
- data/lib/gecoder/interface/constraints.rb +397 -0
- data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
- data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
- data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
- data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
- data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
- data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
- data/lib/gecoder/interface/enum_matrix.rb +64 -0
- data/lib/gecoder/interface/enum_wrapper.rb +153 -0
- data/lib/gecoder/interface/model.rb +251 -0
- data/lib/gecoder/interface/search.rb +123 -0
- data/lib/gecoder/interface/variables.rb +254 -0
- data/lib/gecoder/version.rb +4 -0
- data/specs/binding_changes.rb +76 -0
- data/specs/bool_var.rb +74 -0
- data/specs/branch.rb +170 -0
- data/specs/constraints/arithmetic.rb +266 -0
- data/specs/constraints/bool_enum.rb +140 -0
- data/specs/constraints/boolean.rb +232 -0
- data/specs/constraints/cardinality.rb +154 -0
- data/specs/constraints/channel.rb +126 -0
- data/specs/constraints/connection.rb +373 -0
- data/specs/constraints/constraint_helper.rb +180 -0
- data/specs/constraints/constraints.rb +74 -0
- data/specs/constraints/count.rb +139 -0
- data/specs/constraints/distinct.rb +218 -0
- data/specs/constraints/element.rb +106 -0
- data/specs/constraints/equality.rb +31 -0
- data/specs/constraints/int_domain.rb +69 -0
- data/specs/constraints/int_relation.rb +78 -0
- data/specs/constraints/linear.rb +332 -0
- data/specs/constraints/reification_sugar.rb +96 -0
- data/specs/constraints/selection.rb +292 -0
- data/specs/constraints/set_domain.rb +181 -0
- data/specs/constraints/set_operation.rb +285 -0
- data/specs/constraints/set_relation.rb +201 -0
- data/specs/constraints/sort.rb +175 -0
- data/specs/distribution.rb +14 -0
- data/specs/enum_matrix.rb +43 -0
- data/specs/enum_wrapper.rb +122 -0
- data/specs/int_var.rb +144 -0
- data/specs/logging.rb +24 -0
- data/specs/model.rb +190 -0
- data/specs/search.rb +246 -0
- data/specs/set_var.rb +68 -0
- data/specs/spec_helper.rb +93 -0
- data/tasks/all_tasks.rb +1 -0
- data/tasks/building.howto +65 -0
- data/tasks/distribution.rake +156 -0
- data/tasks/rcov.rake +17 -0
- data/tasks/specs.rake +15 -0
- data/tasks/svn.rake +11 -0
- data/tasks/website.rake +51 -0
- data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
- data/vendor/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +115 -0
- data/vendor/rust/include/rust_conversions.hh +102 -0
- data/vendor/rust/rust.rb +67 -0
- data/vendor/rust/rust/attribute.rb +51 -0
- data/vendor/rust/rust/bindings.rb +172 -0
- data/vendor/rust/rust/class.rb +339 -0
- data/vendor/rust/rust/constants.rb +48 -0
- data/vendor/rust/rust/container.rb +110 -0
- data/vendor/rust/rust/cppifaceparser.rb +129 -0
- data/vendor/rust/rust/cwrapper.rb +72 -0
- data/vendor/rust/rust/cxxclass.rb +98 -0
- data/vendor/rust/rust/element.rb +81 -0
- data/vendor/rust/rust/enum.rb +63 -0
- data/vendor/rust/rust/function.rb +407 -0
- data/vendor/rust/rust/namespace.rb +61 -0
- data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
- data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
- data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
- data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
- data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
- data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
- data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
- data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
- data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
- data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
- data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
- data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
- data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
- data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
- data/vendor/rust/rust/type.rb +98 -0
- data/vendor/rust/test/Makefile +4 -0
- data/vendor/rust/test/constants.rb +36 -0
- data/vendor/rust/test/cppclass.cc +45 -0
- data/vendor/rust/test/cppclass.hh +67 -0
- data/vendor/rust/test/cppclass.rb +59 -0
- data/vendor/rust/test/cwrapper.c +74 -0
- data/vendor/rust/test/cwrapper.h +41 -0
- data/vendor/rust/test/cwrapper.rb +56 -0
- data/vendor/rust/test/dummyclass.hh +31 -0
- data/vendor/rust/test/lib/extension-test.rb +98 -0
- data/vendor/rust/test/operators.cc +41 -0
- data/vendor/rust/test/operators.hh +39 -0
- data/vendor/rust/test/operators.rb +39 -0
- data/vendor/rust/test/test-constants.rb +43 -0
- data/vendor/rust/test/test-cppclass.rb +82 -0
- data/vendor/rust/test/test-cwrapper.rb +80 -0
- data/vendor/rust/test/test-operators.rb +42 -0
- metadata +293 -0
@@ -0,0 +1,254 @@
|
|
1
|
+
module Gecode
|
2
|
+
# Describes a variable that is bound to a model, but not to a particular
|
3
|
+
# space.
|
4
|
+
class FreeVarBase #:nodoc:
|
5
|
+
attr_accessor :model
|
6
|
+
|
7
|
+
# Creates an int variable with the specified index.
|
8
|
+
def initialize(model, index)
|
9
|
+
@model = model
|
10
|
+
@index = index
|
11
|
+
@bound_space = @bound_var = nil
|
12
|
+
model.track_variable(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Checks whether the variable is cached, i.e. whether it needs to be
|
16
|
+
# rebound after changes to a space.
|
17
|
+
def cached?
|
18
|
+
not @bound_space.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Forces the variable to refresh itself.
|
22
|
+
def refresh
|
23
|
+
@bound_space = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
if assigned?
|
28
|
+
"#<#{self.class} #{domain}>"
|
29
|
+
else
|
30
|
+
"#<#{self.class} #{domain}>"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Returns the space that the int variable should bind to when needed.
|
37
|
+
def active_space
|
38
|
+
@model.active_space
|
39
|
+
end
|
40
|
+
|
41
|
+
# Sends the specified method name and arguments to the bound variable.
|
42
|
+
def send_bound(method_name, *args)
|
43
|
+
@model.allow_space_access do
|
44
|
+
bind.send(method_name, *args)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Creates a class for a free variable that can be bound into the specified
|
50
|
+
# class using the specified method in a space.
|
51
|
+
def Gecode::FreeVar(bound_class, space_bind_method)
|
52
|
+
clazz = Class.new(FreeVarBase)
|
53
|
+
clazz.class_eval <<-"end_method_definitions"
|
54
|
+
# Binds the int variable to the currently active space of the model,
|
55
|
+
# returning the bound int variable.
|
56
|
+
def bind
|
57
|
+
space = active_space
|
58
|
+
unless @bound_space == space
|
59
|
+
# We have not bound the variable to this space, so we do it now.
|
60
|
+
@bound = space.method(:#{space_bind_method}).call(@index)
|
61
|
+
@bound_space = space
|
62
|
+
end
|
63
|
+
return @bound
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Delegates the method with the specified name to a method with the
|
69
|
+
# specified name when the variable is bound. If the bound method's name
|
70
|
+
# is nil then the same name as the new method's name is assumed.
|
71
|
+
def self.delegate(method_name, bound_method_name = nil)
|
72
|
+
bound_method_name = method_name if bound_method_name.nil?
|
73
|
+
module_eval <<-"end_code"
|
74
|
+
def \#{method_name}(*args)
|
75
|
+
@model.allow_space_access do
|
76
|
+
bind.method(:\#{bound_method_name}).call(*args)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end_code
|
80
|
+
end
|
81
|
+
end_method_definitions
|
82
|
+
return clazz
|
83
|
+
end
|
84
|
+
|
85
|
+
FreeIntVar = FreeVar(Gecode::Raw::IntVar, :int_var)
|
86
|
+
# Describes an integer variable. Each integer variable has a domain of several
|
87
|
+
# integers which represent the possible values that the variable may take.
|
88
|
+
# An integer variable is said to be assigned once the domain only contains a
|
89
|
+
# single element, at which point #value can be used to retrieve the value.
|
90
|
+
class FreeIntVar
|
91
|
+
# Gets the minimum value still in the domain of the variable.
|
92
|
+
delegate :min
|
93
|
+
# Gets the maximum value still in the domain of the variable.
|
94
|
+
delegate :max
|
95
|
+
# Gets the number of elements still in the domain of the variable.
|
96
|
+
delegate :size
|
97
|
+
# Gets the width of the variable's domain, i.e. the distance between the
|
98
|
+
# maximum and minimum values.
|
99
|
+
delegate :width
|
100
|
+
# Gets the degree of the variable. The degree is the number of constraints
|
101
|
+
# that are affected by the variable. So if the variable is used in two
|
102
|
+
# constraints then the value will be 2.
|
103
|
+
delegate :degree
|
104
|
+
# Checks whether the domain is a range, i.e. doesn't contain any holes.
|
105
|
+
delegate :range?, :range
|
106
|
+
# Checks whether the variable has been assigned, i.e. its domain only
|
107
|
+
# contains one element.
|
108
|
+
delegate :assigned?, :assigned
|
109
|
+
# Checks whether a specified integer is in the variable's domain.
|
110
|
+
delegate :include?, :in
|
111
|
+
|
112
|
+
# Gets the value of the assigned integer variable (a Fixnum). The variable
|
113
|
+
# must be assigned, if it isn't then a RuntimeError is raised.
|
114
|
+
def value
|
115
|
+
raise 'No value is assigned.' unless assigned?
|
116
|
+
send_bound(:val)
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
# Returns a string representation of the the range of the variable's domain.
|
122
|
+
def domain #:nodoc:
|
123
|
+
if assigned?
|
124
|
+
"range: #{value.to_s}"
|
125
|
+
else
|
126
|
+
"range: #{min}..#{max}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
FreeBoolVar = FreeVar(Gecode::Raw::BoolVar, :bool_var)
|
132
|
+
# Describes a boolean variable. A boolean variable can be either true or
|
133
|
+
# false.
|
134
|
+
class FreeBoolVar
|
135
|
+
# Checks whether the variable has been assigned.
|
136
|
+
delegate :assigned?, :assigned
|
137
|
+
|
138
|
+
# Gets the values in the assigned boolean variable (true or false). The
|
139
|
+
# variable must be assigned, if it isn't then a RuntimeError is raised.
|
140
|
+
def value
|
141
|
+
raise 'No value is assigned.' unless assigned?
|
142
|
+
send_bound(:val) == 1
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
# Returns a string representation of the the variable's domain.
|
148
|
+
def domain
|
149
|
+
if assigned?
|
150
|
+
value.to_s
|
151
|
+
else
|
152
|
+
'unassigned'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
FreeSetVar = FreeVar(Gecode::Raw::SetVar, :set_var)
|
158
|
+
# Describes a set variable.
|
159
|
+
#
|
160
|
+
# A set variable's domain, i.e. possible values that it can take, are
|
161
|
+
# represented with a greatest lower bound (GLB) and a least upper bound (LUB).
|
162
|
+
# The set variable may then take any set value S such that S is a subset of
|
163
|
+
# the least upper bound and the greatest lower bound is a subset of S.
|
164
|
+
#
|
165
|
+
# If for instance the set has a greatest lower bound {1} and least upper bound
|
166
|
+
# {1,3,5} then the assigned set may be any of the following four sets: {1},
|
167
|
+
# {1,3}, {1,5}, {1,3,5}.
|
168
|
+
#
|
169
|
+
# The domain of a set variable may also specify the cardinality of the set,
|
170
|
+
# i.e. the number of elements that the set may contains.
|
171
|
+
class FreeSetVar
|
172
|
+
# Checks whether the variable has been assigned.
|
173
|
+
delegate :assigned?, :assigned
|
174
|
+
|
175
|
+
# Gets all the elements located in the greatest lower bound of the set (an
|
176
|
+
# Enumerable).
|
177
|
+
def lower_bound
|
178
|
+
min = send_bound(:glbMin)
|
179
|
+
max = send_bound(:glbMax)
|
180
|
+
EnumerableView.new(min, max, send_bound(:glbSize)) do
|
181
|
+
(min..max).to_a.delete_if{ |e| not send_bound(:contains, e) }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Gets all the elements located in the least upper bound of the set (an
|
186
|
+
# Enumerable).
|
187
|
+
def upper_bound
|
188
|
+
min = send_bound(:lubMin)
|
189
|
+
max = send_bound(:lubMax)
|
190
|
+
EnumerableView.new(min, max, send_bound(:lubSize)) do
|
191
|
+
(min..max).to_a.delete_if{ |e| send_bound(:notContains, e) }
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Gets the values in the assigned set variable (an enumerable).
|
196
|
+
def value
|
197
|
+
raise 'No value is assigned.' unless assigned?
|
198
|
+
lower_bound
|
199
|
+
end
|
200
|
+
|
201
|
+
# Returns a range containing the allowed values for the set's cardinality.
|
202
|
+
def cardinality
|
203
|
+
send_bound(:cardMin)..send_bound(:cardMax)
|
204
|
+
end
|
205
|
+
|
206
|
+
private
|
207
|
+
|
208
|
+
# Returns a string representation of the the variable's domain.
|
209
|
+
def domain
|
210
|
+
if assigned?
|
211
|
+
lower_bound.to_a.inspect
|
212
|
+
else
|
213
|
+
"glb-range: #{lower_bound.to_a.inspect}, lub-range: #{upper_bound.to_a.inspect}"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Describes an immutable view of an enumerable.
|
219
|
+
class EnumerableView #:nodoc:
|
220
|
+
# Gets the number of elements in the view.
|
221
|
+
attr :size
|
222
|
+
# Gets the minimum element of the view.
|
223
|
+
attr :min
|
224
|
+
# Gets the maximum element of the view.
|
225
|
+
attr :max
|
226
|
+
include Enumerable
|
227
|
+
|
228
|
+
# Constructs a view with the specified minimum, maximum and size. The block
|
229
|
+
# should construct an enumerable containing the elements of the set.
|
230
|
+
def initialize(min, max, size, &enum_constructor)
|
231
|
+
@min = min
|
232
|
+
@max = max
|
233
|
+
@size = size
|
234
|
+
@constructor = enum_constructor
|
235
|
+
@enum = nil
|
236
|
+
end
|
237
|
+
|
238
|
+
# Iterates over every element in the view.
|
239
|
+
def each(&block)
|
240
|
+
enum.each(&block)
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
|
245
|
+
# Gets the enumeration being viewed.
|
246
|
+
def enum
|
247
|
+
if @enum.nil?
|
248
|
+
@enum = @constructor.call
|
249
|
+
else
|
250
|
+
return @enum
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe 'Space', :shared => true do
|
4
|
+
it 'should give different indices when creating int variables' do
|
5
|
+
@space.new_int_vars([0, 17]).should_not equal(@space.new_int_vars([0, 17]))
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should give different indices when creating bool variables' do
|
9
|
+
@space.new_bool_vars().should_not equal(@space.new_bool_vars())
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should give different indices when creating multiple int variables' do
|
13
|
+
@space.new_int_vars([0, 17], 17).uniq.size.should equal(17)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should give different indices when creating multiple bool variables' do
|
17
|
+
@space.new_bool_vars(17).uniq.size.should equal(17)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should not return nil for created int variables' do
|
21
|
+
@space.new_int_vars([0, 17], 4).each do |i|
|
22
|
+
@space.int_var(i).should_not be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should not return nil for created int variables' do
|
27
|
+
@space.new_bool_vars(4).each do |i|
|
28
|
+
@space.bool_var(i).should_not be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should return nil when requesting int variables with negative indices' do
|
33
|
+
@space.int_var(-1).should be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should return nil when requesting bool variables with negative indices' do
|
37
|
+
@space.bool_var(-1).should be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should raise an error if given a domain of incorrect type' do
|
41
|
+
lambda{ @space.new_int_vars(17) }.should raise_error(TypeError)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe Gecode::Raw::Space, ' (new)' do
|
46
|
+
before do
|
47
|
+
@space = Gecode::Raw::Space.new
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should return nil when requesting int variables' do
|
51
|
+
@space.int_var(0).should be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should return nil when requesting bool variables' do
|
55
|
+
@space.bool_var(0).should be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it_should_behave_like 'Space'
|
59
|
+
end
|
60
|
+
|
61
|
+
describe Gecode::Raw::Space, ' (with items)' do
|
62
|
+
before do
|
63
|
+
@space = Gecode::Raw::Space.new
|
64
|
+
@first = @space.new_int_vars([1, 4]).first
|
65
|
+
@second = @space.new_int_vars([-5, 5]).first
|
66
|
+
end
|
67
|
+
|
68
|
+
it_should_behave_like 'Space'
|
69
|
+
|
70
|
+
it 'should give int variables with the correct domains' do
|
71
|
+
@space.int_var(@first).min.should equal(1)
|
72
|
+
@space.int_var(@first).max.should equal(4)
|
73
|
+
@space.int_var(@second).min.should equal(-5)
|
74
|
+
@space.int_var(@second).max.should equal(5)
|
75
|
+
end
|
76
|
+
end
|
data/specs/bool_var.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe 'non-empty bool variable', :shared => true do
|
4
|
+
it 'should give a NoMethodError when calling a method that doesn\'t exist' do
|
5
|
+
lambda{ @var.this_method_does_not_exists }.should raise_error(NoMethodError)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Gecode::FreeBoolVar, '(not assigned)' do
|
10
|
+
before do
|
11
|
+
model = Gecode::Model.new
|
12
|
+
@var = model.bool_var
|
13
|
+
end
|
14
|
+
|
15
|
+
it_should_behave_like 'non-empty bool variable'
|
16
|
+
|
17
|
+
it 'should not be assigned' do
|
18
|
+
@var.should_not be_assigned
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should say that it's not assigned when inspecting" do
|
22
|
+
@var.inspect.should include('unassigned')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should raise error when trying to access assigned value' do
|
26
|
+
lambda{ @var.value }.should raise_error(RuntimeError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe Gecode::FreeBoolVar, '(assigned true)' do
|
31
|
+
before do
|
32
|
+
model = Gecode::Model.new
|
33
|
+
@var = model.bool_var
|
34
|
+
@var.must_be.true
|
35
|
+
model.solve!
|
36
|
+
end
|
37
|
+
|
38
|
+
it_should_behave_like 'non-empty bool variable'
|
39
|
+
|
40
|
+
it 'should be assigned' do
|
41
|
+
@var.should be_assigned
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should have valye true' do
|
45
|
+
@var.value.should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should say that it's true when inspecting" do
|
49
|
+
@var.inspect.should include('true')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe Gecode::FreeBoolVar, '(assigned false)' do
|
54
|
+
before do
|
55
|
+
model = Gecode::Model.new
|
56
|
+
@var = model.bool_var
|
57
|
+
@var.must_be.false
|
58
|
+
model.solve!
|
59
|
+
end
|
60
|
+
|
61
|
+
it_should_behave_like 'non-empty bool variable'
|
62
|
+
|
63
|
+
it 'should be assigned' do
|
64
|
+
@var.should be_assigned
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should have value false ' do
|
68
|
+
@var.value.should_not be_true
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should say that it's false when inspecting" do
|
72
|
+
@var.inspect.should include('false')
|
73
|
+
end
|
74
|
+
end
|
data/specs/branch.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class BranchSampleProblem < Gecode::Model
|
4
|
+
attr :vars
|
5
|
+
attr :bools
|
6
|
+
attr :sets
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@vars = int_var_array(2, 0..3)
|
10
|
+
@sets = set_var_array(2, [], 0..4)
|
11
|
+
@bools = bool_var_array(2)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Gecode::Model, ' (integer branch)' do
|
16
|
+
before do
|
17
|
+
@model = BranchSampleProblem.new
|
18
|
+
@vars = @model.vars
|
19
|
+
@bools = @model.bools
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should default to :none and :min' do
|
23
|
+
Gecode::Raw.should_receive(:branch).once.with(
|
24
|
+
an_instance_of(Gecode::Raw::Space),
|
25
|
+
anything, Gecode::Raw::BVAR_NONE, Gecode::Raw::BVAL_MIN)
|
26
|
+
@model.branch_on @vars
|
27
|
+
@model.solve!
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should ensure that branched int variables are assigned in a solution' do
|
31
|
+
@model.branch_on @vars
|
32
|
+
@model.solve!.vars.each{ |var| var.should be_assigned }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should ensure that branched bool variables are assigned in a solution' do
|
36
|
+
@model.branch_on @bools
|
37
|
+
@model.solve!.bools.each{ |var| var.should be_assigned }
|
38
|
+
end
|
39
|
+
|
40
|
+
supported_var_selectors = {
|
41
|
+
:none => Gecode::Raw::BVAR_NONE,
|
42
|
+
:smallest_min => Gecode::Raw::BVAR_MIN_MIN,
|
43
|
+
:largest_min => Gecode::Raw::BVAR_MIN_MAX,
|
44
|
+
:smallest_max => Gecode::Raw::BVAR_MAX_MIN,
|
45
|
+
:largest_max => Gecode::Raw::BVAR_MAX_MAX,
|
46
|
+
:smallest_size => Gecode::Raw::BVAR_SIZE_MIN,
|
47
|
+
:largest_size => Gecode::Raw::BVAR_SIZE_MAX,
|
48
|
+
:smallest_degree => Gecode::Raw::BVAR_DEGREE_MIN,
|
49
|
+
:largest_degree => Gecode::Raw::BVAR_DEGREE_MAX,
|
50
|
+
:smallest_min_regret => Gecode::Raw::BVAR_REGRET_MIN_MIN,
|
51
|
+
:largest_min_regret => Gecode::Raw::BVAR_REGRET_MIN_MAX,
|
52
|
+
:smallest_max_regret => Gecode::Raw::BVAR_REGRET_MAX_MIN,
|
53
|
+
:largest_max_regret => Gecode::Raw::BVAR_REGRET_MAX_MAX
|
54
|
+
}.each_pair do |name, gecode_const|
|
55
|
+
it "should support #{name} as variable selection strategy" do
|
56
|
+
Gecode::Raw.should_receive(:branch).once.with(
|
57
|
+
an_instance_of(Gecode::Raw::Space),
|
58
|
+
anything, gecode_const, an_instance_of(Numeric))
|
59
|
+
@model.branch_on @vars, :variable => name
|
60
|
+
@model.solve!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
supported_val_selectors = {
|
65
|
+
:min => Gecode::Raw::BVAL_MIN,
|
66
|
+
:med => Gecode::Raw::BVAL_MED,
|
67
|
+
:max => Gecode::Raw::BVAL_MAX,
|
68
|
+
:split_min => Gecode::Raw::BVAL_SPLIT_MIN,
|
69
|
+
:split_max => Gecode::Raw::BVAL_SPLIT_MAX
|
70
|
+
}.each_pair do |name, gecode_const|
|
71
|
+
it "should support #{name} as value selection strategy" do
|
72
|
+
Gecode::Raw.should_receive(:branch).once.with(
|
73
|
+
an_instance_of(Gecode::Raw::Space),
|
74
|
+
anything, an_instance_of(Numeric), gecode_const)
|
75
|
+
@model.branch_on @vars, :value => name
|
76
|
+
@model.solve!
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should raise errors for unrecognized var selection strategies' do
|
81
|
+
lambda do
|
82
|
+
@model.branch_on @vars, :variable => :foo
|
83
|
+
end.should raise_error(ArgumentError)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should raise errors for unrecognized val selection strategies' do
|
87
|
+
lambda do
|
88
|
+
@model.branch_on @vars, :value => :foo
|
89
|
+
end.should raise_error(ArgumentError)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should raise errors for unrecognized options' do
|
93
|
+
lambda do
|
94
|
+
@model.branch_on @vars, :foo => 5
|
95
|
+
end.should raise_error(ArgumentError)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should raise errors for unrecognized enumerations' do
|
99
|
+
lambda do
|
100
|
+
@model.branch_on [1,2,3]
|
101
|
+
end.should raise_error(TypeError)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe Gecode::Model, ' (set branch)' do
|
106
|
+
before do
|
107
|
+
@model = BranchSampleProblem.new
|
108
|
+
@sets = @model.sets
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should default to :none and :min' do
|
112
|
+
Gecode::Raw.should_receive(:branch).once.with(
|
113
|
+
an_instance_of(Gecode::Raw::Space),
|
114
|
+
anything, Gecode::Raw::SETBVAR_NONE, Gecode::Raw::SETBVAL_MIN)
|
115
|
+
@model.branch_on @sets
|
116
|
+
@model.solve!
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should ensure that branched set variables are assigned in a solution' do
|
120
|
+
@model.branch_on @sets
|
121
|
+
@model.solve!.sets.each{ |var| var.should be_assigned }
|
122
|
+
end
|
123
|
+
|
124
|
+
supported_var_selectors = {
|
125
|
+
:none => Gecode::Raw::SETBVAR_NONE,
|
126
|
+
:smallest_cardinality => Gecode::Raw::SETBVAR_MIN_CARD,
|
127
|
+
:largest_cardinality => Gecode::Raw::SETBVAR_MAX_CARD,
|
128
|
+
:smallest_unknown => Gecode::Raw::SETBVAR_MIN_UNKNOWN_ELEM,
|
129
|
+
:largest_unknown => Gecode::Raw::SETBVAR_MAX_UNKNOWN_ELEM
|
130
|
+
}.each_pair do |name, gecode_const|
|
131
|
+
it "should support #{name} as variable selection strategy" do
|
132
|
+
Gecode::Raw.should_receive(:branch).once.with(
|
133
|
+
an_instance_of(Gecode::Raw::Space),
|
134
|
+
anything, gecode_const, an_instance_of(Numeric))
|
135
|
+
@model.branch_on @sets, :variable => name
|
136
|
+
@model.solve!
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
supported_val_selectors = {
|
141
|
+
:min => Gecode::Raw::SETBVAL_MIN,
|
142
|
+
:max => Gecode::Raw::SETBVAL_MAX
|
143
|
+
}.each_pair do |name, gecode_const|
|
144
|
+
it "should support #{name} as value selection strategy" do
|
145
|
+
Gecode::Raw.should_receive(:branch).once.with(
|
146
|
+
an_instance_of(Gecode::Raw::Space),
|
147
|
+
anything, an_instance_of(Numeric), gecode_const)
|
148
|
+
@model.branch_on @sets, :value => name
|
149
|
+
@model.solve!
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should raise errors for unrecognized var selection strategies' do
|
154
|
+
lambda do
|
155
|
+
@model.branch_on @sets, :variable => :foo
|
156
|
+
end.should raise_error(ArgumentError)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should raise errors for unrecognized val selection strategies' do
|
160
|
+
lambda do
|
161
|
+
@model.branch_on @sets, :value => :foo
|
162
|
+
end.should raise_error(ArgumentError)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should raise errors for unrecognized options' do
|
166
|
+
lambda do
|
167
|
+
@model.branch_on @sets, :foo => 5
|
168
|
+
end.should raise_error(ArgumentError)
|
169
|
+
end
|
170
|
+
end
|