gecoder 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/CHANGES +11 -0
  2. data/README +12 -1
  3. data/example/example_helper.rb +1 -0
  4. data/example/magic_sequence.rb +43 -0
  5. data/example/queens.rb +43 -0
  6. data/example/raw_bindings.rb +42 -0
  7. data/example/send_more_money.rb +43 -0
  8. data/example/sudoku.rb +65 -0
  9. data/ext/missing.cpp +15 -21
  10. data/ext/missing.h +14 -20
  11. data/ext/vararray.cpp +14 -20
  12. data/ext/vararray.h +18 -22
  13. data/lib/gecoder/bindings/bindings.rb +1979 -1969
  14. data/lib/gecoder/interface/binding_changes.rb +123 -2
  15. data/lib/gecoder/interface/constraints/bool/boolean.rb +80 -65
  16. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +59 -0
  17. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
  18. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +42 -0
  19. data/lib/gecoder/interface/constraints/int/arithmetic.rb +21 -44
  20. data/lib/gecoder/interface/constraints/int/domain.rb +6 -4
  21. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +18 -44
  22. data/lib/gecoder/interface/constraints/int_enum/count.rb +3 -18
  23. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +4 -16
  24. data/lib/gecoder/interface/constraints/int_enum/element.rb +9 -20
  25. data/lib/gecoder/interface/constraints/int_var_constraints.rb +28 -0
  26. data/lib/gecoder/interface/constraints/set/cardinality.rb +56 -0
  27. data/lib/gecoder/interface/constraints/set/domain.rb +66 -0
  28. data/lib/gecoder/interface/constraints/set/relation.rb +125 -0
  29. data/lib/gecoder/interface/constraints/set_var_constraints.rb +37 -0
  30. data/lib/gecoder/interface/constraints.rb +229 -65
  31. data/lib/gecoder/interface/enum_wrapper.rb +42 -11
  32. data/lib/gecoder/interface/model.rb +75 -0
  33. data/lib/gecoder/interface/search.rb +4 -9
  34. data/lib/gecoder/interface/variables.rb +36 -2
  35. data/lib/gecoder/version.rb +1 -1
  36. data/specs/bool_var.rb +58 -0
  37. data/specs/constraints/arithmetic.rb +91 -90
  38. data/specs/constraints/bool_enum.rb +130 -0
  39. data/specs/constraints/boolean.rb +95 -2
  40. data/specs/constraints/cardinality.rb +127 -0
  41. data/specs/constraints/constraint_helper.rb +91 -0
  42. data/specs/constraints/constraints.rb +31 -0
  43. data/specs/constraints/element.rb +43 -72
  44. data/specs/constraints/{domain.rb → int_domain.rb} +4 -0
  45. data/specs/constraints/{relation.rb → int_relation.rb} +0 -0
  46. data/specs/constraints/set_domain.rb +165 -0
  47. data/specs/constraints/set_relation.rb +181 -0
  48. data/specs/enum_wrapper.rb +13 -2
  49. data/specs/int_var.rb +33 -1
  50. data/specs/model.rb +80 -0
  51. data/specs/set_var.rb +39 -0
  52. data/specs/spec_helper.rb +35 -0
  53. data/specs/tmp +11 -124
  54. data/tasks/distribution.rake +1 -1
  55. data/vendor/rust/rust/class.rb +10 -10
  56. data/vendor/rust/rust/constants.rb +1 -1
  57. data/vendor/rust/rust/function.rb +5 -5
  58. data/vendor/rust/rust/type.rb +1 -1
  59. data/vendor/rust/test/constants.rb +1 -0
  60. data/vendor/rust/test/cppclass.cc +5 -0
  61. data/vendor/rust/test/cppclass.hh +4 -0
  62. data/vendor/rust/test/lib/extension-test.rb +1 -1
  63. data/vendor/rust/test/operators.cc +41 -0
  64. data/vendor/rust/test/operators.hh +39 -0
  65. data/vendor/rust/test/operators.rb +39 -0
  66. data/vendor/rust/test/test-cwrapper.rb +3 -0
  67. data/vendor/rust/test/test-operators.rb +42 -0
  68. metadata +31 -4
@@ -33,70 +33,6 @@ module Gecode
33
33
  end
34
34
  end
35
35
 
36
- # Describes a constraint expressions. An expression is produced by calling
37
- # some form of must on a left hand side. The expression waits for a right
38
- # hand side so that it can post the corresponding constraint.
39
- class Expression
40
- # Constructs a new expression with the specified parameters. The
41
- # parameters shoud at least contain the keys :lhs, and :negate.
42
- #
43
- # Raises ArgumentError if any of those keys are missing.
44
- def initialize(model, params)
45
- unless params.has_key?(:lhs) and params.has_key?(:negate)
46
- raise ArgumentError, 'Expression requires at least :lhs, ' +
47
- "and :negate as parameter keys, got #{params.keys.join(', ')}."
48
- end
49
-
50
- @model = model
51
- @params = params
52
- end
53
-
54
- private
55
-
56
- # Creates aliases for any defined comparison methods.
57
- def self.alias_comparison_methods
58
- Gecode::Constraints::Util::COMPARISON_ALIASES.each_pair do |orig, aliases|
59
- if instance_methods.include?(orig.to_s)
60
- aliases.each do |name|
61
- alias_method(name, orig)
62
- end
63
- end
64
- end
65
- end
66
- end
67
-
68
- # Describes a constraint expression that has yet to be completed. I.e. a
69
- # form of must has not yet been called, but some method has been called to
70
- # initiate the expression. An example is distinct with offsets:
71
- #
72
- # enum.with_offsets(0..n).must_be.distinct
73
- #
74
- # The call of with_offsets initiates the constraint as a stub, even though
75
- # must has not yet been called.
76
- class ExpressionStub
77
- # Constructs a new expression with the specified parameters.
78
- def initialize(model, params)
79
- @model = model
80
- @params = params
81
- end
82
- end
83
-
84
- # Base class for all constraints.
85
- class Constraint
86
- # Creates a constraint with the specified parameters, bound to the
87
- # specified model.
88
- def initialize(model, params)
89
- @model = model
90
- @params = params.clone
91
- end
92
-
93
- # Posts the constraint, adding it to the model. This is an abstract
94
- # method and should be overridden by all sub-classes.
95
- def post
96
- raise NoMethodError, 'Abstract method has not been implemented.'
97
- end
98
- end
99
-
100
36
  # A module that provides some utility-methods for constraints.
101
37
  module Util
102
38
  # Maps the name used in options to the value used in Gecode for
@@ -115,7 +51,8 @@ module Gecode
115
51
  :<= => Gecode::Raw::IRT_LQ,
116
52
  :< => Gecode::Raw::IRT_LE,
117
53
  :>= => Gecode::Raw::IRT_GQ,
118
- :> => Gecode::Raw::IRT_GR }
54
+ :> => Gecode::Raw::IRT_GR
55
+ }
119
56
  # The same as above, but negated.
120
57
  NEGATED_RELATION_TYPES = {
121
58
  :== => Gecode::Raw::IRT_NQ,
@@ -125,6 +62,20 @@ module Gecode
125
62
  :> => Gecode::Raw::IRT_LQ
126
63
  }
127
64
 
65
+ # Maps the names of the methods to the corresponding set relation type in
66
+ # Gecode.
67
+ SET_RELATION_TYPES = {
68
+ :== => Gecode::Raw::SRT_EQ,
69
+ :superset => Gecode::Raw::SRT_SUP,
70
+ :subset => Gecode::Raw::SRT_SUB,
71
+ :disjoint => Gecode::Raw::SRT_DISJ,
72
+ :complement => Gecode::Raw::SRT_CMPL
73
+ }
74
+ # The same as above, but negated.
75
+ NEGATED_SET_RELATION_TYPES = {
76
+ :== => Gecode::Raw::SRT_NQ
77
+ }
78
+
128
79
  # Various method aliases for comparison methods. Maps the original
129
80
  # (symbol) name to an array of aliases.
130
81
  COMPARISON_ALIASES = {
@@ -134,6 +85,13 @@ module Gecode
134
85
  :< => [:less, :less_than],
135
86
  :<= => [:less_or_equal, :less_than_or_equal_to]
136
87
  }
88
+ SET_ALIASES = {
89
+ :== => [:equal, :equal_to],
90
+ :superset => [:superset_of],
91
+ :subset => [:subset_of],
92
+ :disjoint => [:disjoint_with],
93
+ :complement => [:complement_of]
94
+ }
137
95
 
138
96
  module_function
139
97
 
@@ -167,6 +125,210 @@ module Gecode
167
125
  end
168
126
  return {:strength => PROPAGATION_STRENGTHS[strength], :reif => reif_var}
169
127
  end
128
+
129
+ # Converts the different ways to specify constant sets in the interface
130
+ # to the form that the set should be represented in Gecode (possibly
131
+ # multiple paramters. The different forms accepted are:
132
+ # * Single instance of Fixnum (singleton set).
133
+ # * Range (set containing all numbers in range), treated differently from
134
+ # other enumerations.
135
+ # * Enumeration of integers (set contaning all numbers in set).
136
+ def constant_set_to_params(constant_set)
137
+ if constant_set.kind_of? Range
138
+ return constant_set.first, constant_set.last
139
+ elsif constant_set.kind_of? Fixnum
140
+ return constant_set
141
+ else
142
+ constant_set = constant_set.to_a
143
+ unless constant_set.all?{ |e| e.kind_of? Fixnum }
144
+ raise TypeError, "Not a constant set: #{constant_set}."
145
+ end
146
+ return Gecode::Raw::IntSet.new(constant_set, constant_set.size)
147
+ end
148
+ end
149
+ end
150
+
151
+ # Describes a constraint expressions. An expression is produced by calling
152
+ # some form of must on a left hand side. The expression waits for a right
153
+ # hand side so that it can post the corresponding constraint.
154
+ class Expression
155
+ # Constructs a new expression with the specified parameters. The
156
+ # parameters shoud at least contain the keys :lhs, and :negate.
157
+ #
158
+ # Raises ArgumentError if any of those keys are missing.
159
+ def initialize(model, params)
160
+ unless params.has_key?(:lhs) and params.has_key?(:negate)
161
+ raise ArgumentError, 'Expression requires at least :lhs, ' +
162
+ "and :negate as parameter keys, got #{params.keys.join(', ')}."
163
+ end
164
+
165
+ @model = model
166
+ @params = params
167
+ end
168
+
169
+ private
170
+
171
+ # Creates aliases for any defined comparison methods.
172
+ def self.alias_comparison_methods
173
+ Gecode::Constraints::Util::COMPARISON_ALIASES.each_pair do |orig, aliases|
174
+ if instance_methods.include?(orig.to_s)
175
+ aliases.each do |name|
176
+ alias_method(name, orig)
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ # Creates aliases for any defined set methods.
183
+ def self.alias_set_methods
184
+ Gecode::Constraints::Util::SET_ALIASES.each_pair do |orig, aliases|
185
+ if instance_methods.include?(orig.to_s)
186
+ aliases.each do |name|
187
+ alias_method(name, orig)
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ # A composite expression which is a expression with a left hand side
195
+ # resulting from a previous constraint.
196
+ class CompositeExpression < Gecode::Constraints::Expression
197
+ # The expression class should be the class of the expression delegated to,
198
+ # the variable class the kind of single variable used in the expression.
199
+ # The block given should take three parameters. The first is the variable
200
+ # that should be the left hand side, if it's nil then a new one should be
201
+ # created. The second is the has of parameters. The block should return
202
+ # the variable used as left hand side.
203
+ def initialize(expression_class, variable_class, model, params, &block)
204
+ super(model, params)
205
+ @expression_class = expression_class
206
+ @variable_class = variable_class
207
+ @proc = block
208
+ end
209
+
210
+ # Delegate to an instance of the expression class when we get something
211
+ # that we can't handle.
212
+ def method_missing(name, *args)
213
+ if @expression_class.instance_methods.include? name.to_s
214
+ options = {}
215
+ if args.size >= 2 and args[1].kind_of? Hash
216
+ options = args[1]
217
+ end
218
+ @params.update Gecode::Constraints::Util.decode_options(options.clone)
219
+ @params[:lhs] = @proc.call(nil, @params)
220
+ @expression_class.new(@model, @params).send(name, *args)
221
+ else
222
+ super
223
+ end
224
+ end
225
+
226
+ def ==(expression, options = {})
227
+ if !@params[:negate] and options[:reify].nil? and
228
+ expression.kind_of? @variable_class
229
+ # We don't need any additional constraints.
230
+ @params.update Gecode::Constraints::Util.decode_options(options)
231
+ @proc.call(expression, @params)
232
+ else
233
+ method_missing(:==, expression, options)
234
+ end
235
+ end
236
+ alias_comparison_methods
237
+ end
238
+
239
+ # Describes a constraint expression that has yet to be completed. I.e. a
240
+ # form of must has not yet been called, but some method has been called to
241
+ # initiate the expression. An example is distinct with offsets:
242
+ #
243
+ # enum.with_offsets(0..n).must_be.distinct
244
+ #
245
+ # The call of with_offsets initiates the constraint as a stub, even though
246
+ # must has not yet been called.
247
+ class ExpressionStub
248
+ # Constructs a new expression with the specified parameters.
249
+ def initialize(model, params)
250
+ @model = model
251
+ @params = params
252
+ end
253
+ end
254
+
255
+ # Describes an expression stub which includes left hand side methods and
256
+ # just sends models and parameters through a supplied block to construct the
257
+ # resulting expression.
258
+ class SimpleExpressionStub < ExpressionStub
259
+ include Gecode::Constraints::LeftHandSideMethods
260
+
261
+ # The block provided is executed when the expression demanded by the left
262
+ # hand side methods is to be constructed. The block should take two
263
+ # parameters: model and params (which have been updated with negate and
264
+ # so on). The block should return an expression.
265
+ def initialize(model, params, &block)
266
+ super(model, params)
267
+ @proc = block
268
+ end
269
+
270
+ private
271
+
272
+ # Produces an expression with offsets for the lhs module.
273
+ def expression(params)
274
+ @params.update(params)
275
+ @proc.call(@model, @params)
276
+ end
277
+ end
278
+
279
+ # Describes a stub that produces a variable, which can then be used with
280
+ # that variable's normalconstraints. An example with int variables would be
281
+ # the element constraint.
282
+ #
283
+ # int_enum[int_var].must > rhs
284
+ #
285
+ # The int_enum[int_var] part produces an int variable which the constraint
286
+ # ".must > rhs" is then applied to. In the above case two constraints (and
287
+ # one temporary variable) are required, but in the case of equality only
288
+ # one constraint is required.
289
+ class CompositeStub < Gecode::Constraints::ExpressionStub
290
+ include Gecode::Constraints::LeftHandSideMethods
291
+
292
+ # The composite expression class should be the class that the stub uses
293
+ # when creating its expressions.
294
+ def initialize(composite_expression_class, model, params)
295
+ super(model, params)
296
+ @composite_class = composite_expression_class
297
+ end
298
+
299
+ private
300
+
301
+ # Constrains the result of the stub to be equal to the specified variable
302
+ # with the specified parameters. If the variable given is nil then a new
303
+ # variable should be created for the purpose and returned. This is an
304
+ # abstract method and should be overridden by all sub-classes.
305
+ def constrain_equal(variable, params)
306
+ raise NoMethodError, 'Abstract method has not been implemented.'
307
+ end
308
+
309
+ # Produces an expression with position for the lhs module.
310
+ def expression(params)
311
+ @params.update params
312
+ @composite_class.new(@model, @params) do |var, params|
313
+ constrain_equal(var, params)
314
+ end
315
+ end
316
+ end
317
+
318
+ # Base class for all constraints.
319
+ class Constraint
320
+ # Creates a constraint with the specified parameters, bound to the
321
+ # specified model.
322
+ def initialize(model, params)
323
+ @model = model
324
+ @params = params.clone
325
+ end
326
+
327
+ # Posts the constraint, adding it to the model. This is an abstract
328
+ # method and should be overridden by all sub-classes.
329
+ def post
330
+ raise NoMethodError, 'Abstract method has not been implemented.'
331
+ end
170
332
  end
171
333
  end
172
334
  end
@@ -175,3 +337,5 @@ require 'gecoder/interface/constraints/reifiable_constraints'
175
337
  require 'gecoder/interface/constraints/int_var_constraints'
176
338
  require 'gecoder/interface/constraints/int_enum_constraints'
177
339
  require 'gecoder/interface/constraints/bool_var_constraints'
340
+ require 'gecoder/interface/constraints/bool_enum_constraints'
341
+ require 'gecoder/interface/constraints/set_var_constraints'
@@ -11,15 +11,19 @@ module Gecode
11
11
  raise ArgumentError, 'Enumerable must not be empty.'
12
12
  end
13
13
 
14
- if elements.map{ |var| var.kind_of? FreeIntVar }.all?
14
+ if elements.all?{ |var| var.kind_of? FreeIntVar }
15
15
  class <<enum
16
16
  include Gecode::IntEnumMethods
17
17
  end
18
- elsif elements.map{ |var| var.kind_of? FreeBoolVar }.all?
18
+ elsif elements.all?{ |var| var.kind_of? FreeBoolVar }
19
19
  class <<enum
20
20
  include Gecode::BoolEnumMethods
21
21
  end
22
- elsif elements.map{ |var| var.kind_of? Fixnum }.all?
22
+ elsif elements.all?{ |var| var.kind_of? FreeSetVar }
23
+ class <<enum
24
+ include Gecode::SetEnumMethods
25
+ end
26
+ elsif elements.all?{ |var| var.kind_of? Fixnum }
23
27
  class <<enum
24
28
  include Gecode::FixnumEnumMethods
25
29
  end
@@ -48,10 +52,14 @@ module Gecode
48
52
 
49
53
  # Returns an int variable array with all the bound variables.
50
54
  def to_int_var_array
51
- elements = to_a
52
- arr = Gecode::Raw::IntVarArray.new(active_space, elements.size)
53
- elements.each_with_index{ |var, index| arr[index] = var.bind }
54
- return arr
55
+ space = @model.active_space
56
+ unless @bound_space == space
57
+ elements = to_a
58
+ @bound_arr = Gecode::Raw::IntVarArray.new(active_space, elements.size)
59
+ elements.each_with_index{ |var, index| @bound_arr[index] = var.bind }
60
+ @bound_space = space
61
+ end
62
+ return @bound_arr
55
63
  end
56
64
  alias_method :to_var_array, :to_int_var_array
57
65
 
@@ -76,14 +84,37 @@ module Gecode
76
84
 
77
85
  # Returns a bool variable array with all the bound variables.
78
86
  def to_bool_var_array
79
- elements = to_a
80
- arr = Gecode::Raw::BoolVarArray.new(active_space, elements.size)
81
- elements.each_with_index{ |var, index| arr[index] = var.bind }
82
- return arr
87
+ space = @model.active_space
88
+ unless @bound_space == space
89
+ elements = to_a
90
+ @bound_arr = Gecode::Raw::BoolVarArray.new(active_space, elements.size)
91
+ elements.each_with_index{ |var, index| @bound_arr[index] = var.bind }
92
+ @bound_space = space
93
+ end
94
+ return @bound_arr
83
95
  end
84
96
  alias_method :to_var_array, :to_bool_var_array
85
97
  end
86
98
 
99
+ # A module containing the methods needed by enumerations containing set
100
+ # variables. Requires that it's included in an enumerable.
101
+ module SetEnumMethods
102
+ include EnumMethods
103
+
104
+ # Returns a set variable array with all the bound variables.
105
+ def to_set_var_array
106
+ space = @model.active_space
107
+ unless @bound_space == space
108
+ elements = to_a
109
+ @bound_arr = Gecode::Raw::SetVarArray.new(active_space, elements.size)
110
+ elements.each_with_index{ |var, index| @bound_arr[index] = var.bind }
111
+ @bound_space = space
112
+ end
113
+ return @bound_arr
114
+ end
115
+ alias_method :to_var_array, :to_set_var_array
116
+ end
117
+
87
118
  # A module containing the methods needed by enumerations containing fixnums.
88
119
  # Requires that it's included in an enumerable.
89
120
  module FixnumEnumMethods
@@ -72,6 +72,51 @@ module Gecode
72
72
  return wrap_enum(Util::EnumMatrix.rows(rows, false))
73
73
  end
74
74
 
75
+ # Creates a set variable with the specified domain for greatest lower bound
76
+ # and least upper bound (specified as either a range or enum). A range for
77
+ # the allowed cardinality of the set can also be specified, if none is
78
+ # specified, or nil is given, then the default range (anything) will be
79
+ # used. If only a single Fixnum is specified as cardinality_range then it's
80
+ # used as lower bound.
81
+ def set_var(glb_domain, lub_domain, cardinality_range = nil)
82
+ check_set_bounds(glb_domain, lub_domain)
83
+
84
+ index = active_space.new_set_vars(glb_domain, lub_domain,
85
+ to_set_cardinality_range(cardinality_range)).first
86
+ FreeSetVar.new(self, index)
87
+ end
88
+
89
+ # Creates an array containing the specified number of set variables. The
90
+ # parameters beyond count are the same as for #set_var .
91
+ def set_var_array(count, glb_domain, lub_domain, cardinality_range = nil)
92
+ check_set_bounds(glb_domain, lub_domain)
93
+
94
+ variables = []
95
+ active_space.new_set_vars(glb_domain, lub_domain,
96
+ to_set_cardinality_range(cardinality_range), count).each do |index|
97
+ variables << FreeSetVar.new(self, index)
98
+ end
99
+ return wrap_enum(variables)
100
+ end
101
+
102
+ # Creates a matrix containing the specified number of rows and columns
103
+ # filled with set variables. The parameters beyond row and column counts are
104
+ # the same as for #set_var .
105
+ def set_var_matrix(row_count, col_count, glb_domain, lub_domain,
106
+ cardinality_range = nil)
107
+ check_set_bounds(glb_domain, lub_domain)
108
+
109
+ indices = active_space.new_set_vars(glb_domain, lub_domain,
110
+ to_set_cardinality_range(cardinality_range), row_count*col_count)
111
+ rows = []
112
+ row_count.times do |i|
113
+ rows << indices[(i*col_count)...(i.succ*col_count)].map! do |index|
114
+ FreeSetVar.new(self, index)
115
+ end
116
+ end
117
+ return wrap_enum(Util::EnumMatrix.rows(rows, false))
118
+ end
119
+
75
120
  # Retrieves the currently active space (the one which variables refer to).
76
121
  def active_space
77
122
  @active_space ||= base_space
@@ -121,6 +166,36 @@ module Gecode
121
166
  return min..max
122
167
  end
123
168
 
169
+ # Transforms the argument to a set cardinality range, returns nil if the
170
+ # default range should be used. If arg is a range then that's used,
171
+ # otherwise if the argument is a fixnum it's used as lower bound.
172
+ def to_set_cardinality_range(arg)
173
+ if arg.kind_of? Fixnum
174
+ arg..Gecode::Raw::Limits::Set::CARD_MAX
175
+ else
176
+ arg
177
+ end
178
+ end
179
+
180
+ # Checks whether the specified greatest lower bound is a subset of least
181
+ # upper bound. Raises ArgumentError if that is not the case.
182
+ def check_set_bounds(glb, lub)
183
+ unless valid_set_bounds?(glb, lub)
184
+ raise ArgumentError,
185
+ "Invalid set bounds: #{glb} is not a subset of #{lub}."
186
+ end
187
+ end
188
+
189
+ # Returns whether the greatest lower bound is a subset of least upper
190
+ # bound.
191
+ def valid_set_bounds?(glb, lub)
192
+ if glb.kind_of?(Range) and lub.kind_of?(Range)
193
+ glb.first >= lub.first and glb.last <= lub.last
194
+ else
195
+ (glb.to_a - lub.to_a).empty?
196
+ end
197
+ end
198
+
124
199
  # Creates an integer variable from the specified index and domain. The
125
200
  # domain can either be given as a range or as a number of elements.
126
201
  def construct_int_var(index, *domain_args)
@@ -1,13 +1,5 @@
1
1
  module Gecode
2
2
  class Model
3
- private
4
-
5
- # Used during the search.
6
- COPY_DIST = 16
7
- ADAPTATION_DIST = 4
8
-
9
- public
10
-
11
3
  # Finds the first solution to the modelled problem and updates the variables
12
4
  # to that solution. Returns the model if a solution was found, nil
13
5
  # otherwise.
@@ -54,7 +46,10 @@ module Gecode
54
46
  constraints.clear # Empty the queue.
55
47
 
56
48
  stop = Gecode::Raw::Search::Stop.new
57
- Gecode::Raw::DFS.new(active_space, COPY_DIST, ADAPTATION_DIST, stop)
49
+ Gecode::Raw::DFS.new(active_space,
50
+ Gecode::Raw::Search::Config::MINIMAL_DISTANCE,
51
+ Gecode::Raw::Search::Config::ADAPTIVE_DISTANCE,
52
+ stop)
58
53
  end
59
54
  end
60
55
  end
@@ -46,9 +46,9 @@ module Gecode
46
46
 
47
47
  def inspect
48
48
  if assigned?
49
- "#<#{bound_class} range: \#{val.to_s}>"
49
+ "#<\#{self.class} \#{domain}>"
50
50
  else
51
- "#<#{bound_class} range: \#{min}..\#{max}>"
51
+ "#<\#{self.class} \#{domain}>"
52
52
  end
53
53
  end
54
54
  end_method_definitions
@@ -57,6 +57,40 @@ module Gecode
57
57
 
58
58
  # Int variables.
59
59
  FreeIntVar = FreeVar(Gecode::Raw::IntVar, :int_var)
60
+ class FreeIntVar
61
+ # Returns a string representation of the the range of the variable's domain.
62
+ def domain
63
+ if assigned?
64
+ "range: #{val.to_s}"
65
+ else
66
+ "range: #{min}..#{max}"
67
+ end
68
+ end
69
+ end
70
+
60
71
  # Bool variables.
61
72
  FreeBoolVar = FreeVar(Gecode::Raw::BoolVar, :bool_var)
73
+ class FreeBoolVar
74
+ # Returns a string representation of the the variable's domain.
75
+ def domain
76
+ if assigned?
77
+ true?.to_s
78
+ else
79
+ 'unassigned'
80
+ end
81
+ end
82
+ end
83
+
84
+ # Set variables.
85
+ FreeSetVar = FreeVar(Gecode::Raw::SetVar, :set_var)
86
+ class FreeSetVar
87
+ # Returns a string representation of the the variable's domain.
88
+ def domain
89
+ if assigned?
90
+ "#{glb_min}..#{lub_min}"
91
+ else
92
+ "glb-range: #{glb_min}..#{glb_max}, lub-range: #{lub_min}..#{lub_max}"
93
+ end
94
+ end
95
+ end
62
96
  end
@@ -1,4 +1,4 @@
1
1
  module GecodeR
2
2
  # A string representation of the Gecode/R version.
3
- VERSION = '0.4.0'
3
+ VERSION = '0.5.0'
4
4
  end
data/specs/bool_var.rb CHANGED
@@ -17,4 +17,62 @@ describe Gecode::FreeBoolVar, '(not assigned)' do
17
17
  it 'should not be assigned' do
18
18
  @var.should_not be_assigned
19
19
  end
20
+
21
+ it "should say that it's not assigned when inspecting" do
22
+ @var.inspect.should include('unassigned')
23
+ end
24
+ end
25
+
26
+ describe Gecode::FreeBoolVar, '(assigned true)' do
27
+ before do
28
+ model = Gecode::Model.new
29
+ @var = model.bool_var
30
+ @var.must_be.true
31
+ model.solve!
32
+ end
33
+
34
+ it_should_behave_like 'non-empty bool variable'
35
+
36
+ it 'should be assigned' do
37
+ @var.should be_assigned
38
+ end
39
+
40
+ it 'should respond true to true?' do
41
+ @var.true?.should be_true
42
+ end
43
+
44
+ it 'should not respond true to false?' do
45
+ @var.false?.should_not 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 respond not true to true?' do
68
+ @var.true?.should_not be_true
69
+ end
70
+
71
+ it 'should respond true to false?' do
72
+ @var.false?.should be_true
73
+ end
74
+
75
+ it "should say that it's false when inspecting" do
76
+ @var.inspect.should include('false')
77
+ end
20
78
  end