gecoder 0.4.0 → 0.5.0

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 (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