gecoder 0.8.3 → 0.9.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.
- data/CHANGES +15 -0
- data/README +6 -2
- data/example/equation_system.rb +15 -0
- data/example/magic_sequence.rb +7 -7
- data/example/money.rb +36 -0
- data/example/queens.rb +7 -8
- data/example/send_most_money.rb +1 -1
- data/example/square_tiling.rb +2 -2
- data/example/sudoku-set.rb +11 -12
- data/example/sudoku.rb +40 -45
- data/ext/extconf.rb +0 -0
- data/lib/gecoder/bindings.rb +42 -0
- data/lib/gecoder/bindings/bindings.rb +16 -0
- data/lib/gecoder/interface.rb +2 -1
- data/lib/gecoder/interface/branch.rb +16 -9
- data/lib/gecoder/interface/constraints.rb +410 -451
- data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
- data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
- data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
- data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
- data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
- data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
- data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
- data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
- data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
- data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
- data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
- data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
- data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
- data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
- data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
- data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
- data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
- data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
- data/lib/gecoder/interface/constraints/set/include.rb +36 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
- data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
- data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
- data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
- data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
- data/lib/gecoder/interface/enum_matrix.rb +4 -4
- data/lib/gecoder/interface/enum_wrapper.rb +71 -22
- data/lib/gecoder/interface/model.rb +167 -12
- data/lib/gecoder/interface/model_sugar.rb +84 -0
- data/lib/gecoder/interface/search.rb +30 -18
- data/lib/gecoder/interface/variables.rb +103 -33
- data/lib/gecoder/version.rb +2 -2
- data/specs/bool_var.rb +19 -12
- data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
- data/specs/constraints/bool/boolean_properties.rb +51 -0
- data/specs/constraints/bool/linear.rb +213 -0
- data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
- data/specs/constraints/bool_enum/channel.rb +102 -0
- data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
- data/specs/constraints/constraint_helper.rb +149 -179
- data/specs/constraints/constraint_receivers.rb +103 -0
- data/specs/constraints/constraints.rb +6 -63
- data/specs/constraints/fixnum_enum/element.rb +58 -0
- data/specs/constraints/fixnum_enum/operation.rb +67 -0
- data/specs/constraints/int/arithmetic.rb +149 -0
- data/specs/constraints/int/channel.rb +101 -0
- data/specs/constraints/int/domain.rb +106 -0
- data/specs/constraints/int/linear.rb +183 -0
- data/specs/constraints/int/linear_properties.rb +97 -0
- data/specs/constraints/int/relation.rb +84 -0
- data/specs/constraints/int_enum/arithmetic.rb +72 -0
- data/specs/constraints/int_enum/channel.rb +57 -0
- data/specs/constraints/int_enum/count.rb +72 -0
- data/specs/constraints/int_enum/distinct.rb +80 -0
- data/specs/constraints/int_enum/element.rb +61 -0
- data/specs/constraints/int_enum/equality.rb +29 -0
- data/specs/constraints/int_enum/extensional.rb +224 -0
- data/specs/constraints/int_enum/sort.rb +167 -0
- data/specs/constraints/operands.rb +264 -0
- data/specs/constraints/property_helper.rb +443 -0
- data/specs/constraints/reification_sugar.rb +4 -5
- data/specs/constraints/selected_set/select.rb +56 -0
- data/specs/constraints/selected_set/select_properties.rb +157 -0
- data/specs/constraints/set/cardinality.rb +58 -0
- data/specs/constraints/set/cardinality_properties.rb +46 -0
- data/specs/constraints/set/channel.rb +77 -0
- data/specs/constraints/set/connection.rb +176 -0
- data/specs/constraints/set/domain.rb +197 -0
- data/specs/constraints/set/include.rb +36 -0
- data/specs/constraints/set/operation.rb +132 -0
- data/specs/constraints/set/relation.rb +117 -0
- data/specs/constraints/set_elements/relation.rb +84 -0
- data/specs/constraints/set_enum/channel.rb +80 -0
- data/specs/constraints/set_enum/distinct.rb +59 -0
- data/specs/constraints/set_enum/operation.rb +111 -0
- data/specs/constraints/set_enum/select.rb +73 -0
- data/specs/enum_wrapper.rb +53 -3
- data/specs/int_var.rb +44 -25
- data/specs/model.rb +58 -1
- data/specs/model_sugar.rb +30 -0
- data/specs/search.rb +24 -5
- data/specs/selected_set.rb +39 -0
- data/specs/set_elements.rb +34 -0
- data/specs/set_var.rb +22 -8
- data/specs/spec_helper.rb +206 -6
- data/tasks/distribution.rake +22 -7
- data/tasks/svn.rake +3 -1
- metadata +218 -134
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
- data/specs/constraints/arithmetic.rb +0 -351
- data/specs/constraints/bool_enum_relation.rb +0 -160
- data/specs/constraints/cardinality.rb +0 -157
- data/specs/constraints/channel.rb +0 -454
- data/specs/constraints/connection.rb +0 -369
- data/specs/constraints/count.rb +0 -146
- data/specs/constraints/distinct.rb +0 -164
- data/specs/constraints/element.rb +0 -108
- data/specs/constraints/equality.rb +0 -31
- data/specs/constraints/int_domain.rb +0 -70
- data/specs/constraints/int_relation.rb +0 -82
- data/specs/constraints/linear.rb +0 -340
- data/specs/constraints/selection.rb +0 -292
- data/specs/constraints/set_domain.rb +0 -185
- data/specs/constraints/set_operation.rb +0 -285
- data/specs/constraints/set_relation.rb +0 -197
- data/specs/constraints/sort.rb +0 -179
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'matrix'
|
2
2
|
|
3
|
-
module Gecode::Util
|
3
|
+
module Gecode::Util #:nodoc:
|
4
4
|
# Methods that make a matrix an enumerable.
|
5
|
-
module MatrixEnumMethods
|
5
|
+
module MatrixEnumMethods #:nodoc:
|
6
6
|
include Enumerable
|
7
7
|
|
8
8
|
# Iterates over every element in the matrix.
|
@@ -16,7 +16,7 @@ module Gecode::Util
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# Extends Matrix so that it's an enumerable.
|
19
|
-
class EnumMatrix < Matrix
|
19
|
+
class EnumMatrix < Matrix #:nodoc:
|
20
20
|
include MatrixEnumMethods
|
21
21
|
|
22
22
|
def row(i)
|
@@ -61,4 +61,4 @@ module Gecode::Util
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
@@ -14,15 +14,18 @@ module Gecode
|
|
14
14
|
raise ArgumentError, 'Enumerable must not be empty.'
|
15
15
|
end
|
16
16
|
|
17
|
-
if elements.all?{ |var| var.
|
17
|
+
if elements.all?{ |var| var.respond_to? :to_int_var }
|
18
|
+
elements.map!{ |var| var.to_int_var }
|
18
19
|
class <<enum
|
19
20
|
include Gecode::IntEnumMethods
|
20
21
|
end
|
21
|
-
elsif elements.all?{ |var| var.
|
22
|
+
elsif elements.all?{ |var| var.respond_to? :to_bool_var }
|
23
|
+
elements.map!{ |var| var.to_bool_var }
|
22
24
|
class <<enum
|
23
25
|
include Gecode::BoolEnumMethods
|
24
26
|
end
|
25
|
-
elsif elements.all?{ |var| var.
|
27
|
+
elsif elements.all?{ |var| var.respond_to? :to_set_var }
|
28
|
+
elements.map!{ |var| var.to_set_var }
|
26
29
|
class <<enum
|
27
30
|
include Gecode::SetEnumMethods
|
28
31
|
end
|
@@ -31,7 +34,7 @@ module Gecode
|
|
31
34
|
include Gecode::FixnumEnumMethods
|
32
35
|
end
|
33
36
|
else
|
34
|
-
raise TypeError, "Enumerable doesn't contain
|
37
|
+
raise TypeError, "Enumerable doesn't contain operands #{enum.inspect}."
|
35
38
|
end
|
36
39
|
|
37
40
|
enum.model = self
|
@@ -39,8 +42,9 @@ module Gecode
|
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
42
|
-
# A module containing the methods needed by enumerations containing
|
43
|
-
|
45
|
+
# A module containing the methods needed by enumerations containing
|
46
|
+
# operands.
|
47
|
+
module EnumMethods #:nodoc:
|
44
48
|
attr_accessor :model
|
45
49
|
# Gets the current space of the model the array is connected to.
|
46
50
|
def active_space
|
@@ -48,22 +52,23 @@ module Gecode
|
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
51
|
-
module VariableEnumMethods
|
55
|
+
module VariableEnumMethods #:nodoc:
|
52
56
|
include EnumMethods
|
53
57
|
|
54
|
-
# Gets the values of all the
|
58
|
+
# Gets the values of all the operands in the enum.
|
55
59
|
def values
|
56
60
|
map{ |var| var.value }
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
64
|
# A module containing the methods needed by enumerations containing int
|
61
|
-
#
|
62
|
-
module IntEnumMethods
|
65
|
+
# operands. Requires that it's included in an enumerable.
|
66
|
+
module IntEnumMethods #:nodoc:
|
67
|
+
include IntEnum::IntEnumOperand
|
63
68
|
include VariableEnumMethods
|
64
69
|
|
65
70
|
# Returns an int variable array with all the bound variables.
|
66
|
-
def
|
71
|
+
def bind_array
|
67
72
|
space = @model.active_space
|
68
73
|
unless @bound_space == space
|
69
74
|
elements = to_a
|
@@ -73,7 +78,11 @@ module Gecode
|
|
73
78
|
end
|
74
79
|
return @bound_arr
|
75
80
|
end
|
76
|
-
|
81
|
+
|
82
|
+
# Returns the receiver.
|
83
|
+
def to_int_enum
|
84
|
+
self
|
85
|
+
end
|
77
86
|
|
78
87
|
# Returns the smallest range that contains the domains of all integer
|
79
88
|
# variables involved.
|
@@ -89,14 +98,21 @@ module Gecode
|
|
89
98
|
end
|
90
99
|
end
|
91
100
|
end
|
101
|
+
|
102
|
+
# A dummy class that just shows what methods an int enum responds to.
|
103
|
+
class IntEnum::Dummy < Array #:nodoc:
|
104
|
+
include IntEnum::IntEnumOperand
|
105
|
+
include VariableEnumMethods
|
106
|
+
end
|
92
107
|
|
93
108
|
# A module containing the methods needed by enumerations containing boolean
|
94
|
-
#
|
95
|
-
module BoolEnumMethods
|
109
|
+
# operands. Requires that it's included in an enumerable.
|
110
|
+
module BoolEnumMethods #:nodoc:
|
111
|
+
include BoolEnum::BoolEnumOperand
|
96
112
|
include VariableEnumMethods
|
97
113
|
|
98
114
|
# Returns a bool variable array with all the bound variables.
|
99
|
-
def
|
115
|
+
def bind_array
|
100
116
|
space = @model.active_space
|
101
117
|
unless @bound_space == space
|
102
118
|
elements = to_a
|
@@ -106,16 +122,27 @@ module Gecode
|
|
106
122
|
end
|
107
123
|
return @bound_arr
|
108
124
|
end
|
109
|
-
|
125
|
+
|
126
|
+
# Returns the receiver.
|
127
|
+
def to_bool_enum
|
128
|
+
self
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# A dummy class that just shows what methods a bool enum responds to.
|
133
|
+
class BoolEnum::Dummy < Array #:nodoc:
|
134
|
+
include BoolEnum::BoolEnumOperand
|
135
|
+
include VariableEnumMethods
|
110
136
|
end
|
111
137
|
|
112
138
|
# A module containing the methods needed by enumerations containing set
|
113
|
-
#
|
114
|
-
module SetEnumMethods
|
139
|
+
# operands. Requires that it's included in an enumerable.
|
140
|
+
module SetEnumMethods #:nodoc:
|
141
|
+
include SetEnum::SetEnumOperand
|
115
142
|
include VariableEnumMethods
|
116
143
|
|
117
144
|
# Returns a set variable array with all the bound variables.
|
118
|
-
def
|
145
|
+
def bind_array
|
119
146
|
space = @model.active_space
|
120
147
|
unless @bound_space == space
|
121
148
|
elements = to_a
|
@@ -125,8 +152,12 @@ module Gecode
|
|
125
152
|
end
|
126
153
|
return @bound_arr
|
127
154
|
end
|
128
|
-
alias_method :to_var_array, :to_set_var_array
|
129
155
|
|
156
|
+
# Returns the receiver.
|
157
|
+
def to_set_enum
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
130
161
|
# Returns the range of the union of the contained sets' upper bounds.
|
131
162
|
def upper_bound_range
|
132
163
|
inject(nil) do |range, var|
|
@@ -141,16 +172,34 @@ module Gecode
|
|
141
172
|
end
|
142
173
|
end
|
143
174
|
end
|
175
|
+
|
176
|
+
# A dummy class that just shows what methods a set enum responds to.
|
177
|
+
class SetEnum::Dummy < Array #:nodoc:
|
178
|
+
include SetEnum::SetEnumOperand
|
179
|
+
include VariableEnumMethods
|
180
|
+
end
|
144
181
|
|
145
182
|
# A module containing the methods needed by enumerations containing fixnums.
|
146
183
|
# Requires that it's included in an enumerable.
|
147
|
-
module FixnumEnumMethods
|
184
|
+
module FixnumEnumMethods #:nodoc:
|
185
|
+
include FixnumEnum::FixnumEnumOperand
|
148
186
|
include EnumMethods
|
149
187
|
|
188
|
+
# Returns the receiver.
|
189
|
+
def to_fixnum_enum
|
190
|
+
self
|
191
|
+
end
|
192
|
+
|
150
193
|
# Returns the smallest range that contains the domains of all integer
|
151
194
|
# variables involved.
|
152
195
|
def domain_range
|
153
196
|
min..max
|
154
197
|
end
|
155
198
|
end
|
156
|
-
|
199
|
+
|
200
|
+
# A dummy class that just shows what methods a fixnum enum responds to.
|
201
|
+
class FixnumEnum::Dummy < Array #:nodoc:
|
202
|
+
include FixnumEnum::FixnumEnumOperand
|
203
|
+
include VariableEnumMethods
|
204
|
+
end
|
205
|
+
end
|
@@ -1,5 +1,113 @@
|
|
1
1
|
module Gecode
|
2
2
|
# Model is the base class that all models must inherit from.
|
3
|
+
#
|
4
|
+
# == Formulating problems
|
5
|
+
#
|
6
|
+
# Models are used to formulate the problems that Gecode should solve.
|
7
|
+
# Below is an example of a model that formulates the problem of finding
|
8
|
+
# a solution to the following equation system.
|
9
|
+
#
|
10
|
+
# Equation system:
|
11
|
+
# x + y = z
|
12
|
+
# x = y - 3
|
13
|
+
# 0 <= x,y,z <= 9
|
14
|
+
#
|
15
|
+
# Model:
|
16
|
+
# class EquationProblem < Gecode::Model
|
17
|
+
# attr :vars
|
18
|
+
#
|
19
|
+
# def initialize
|
20
|
+
# x, y, z = @vars = int_var_array(3, 0..9)
|
21
|
+
#
|
22
|
+
# (x + y).must == z
|
23
|
+
# x.must == y - 3
|
24
|
+
#
|
25
|
+
# branch_on @vars
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# A model typically consists of three main parts:
|
30
|
+
# [Variables] Variables specify how to view the problem. A solution is an
|
31
|
+
# assignment of the variables. In the example above we created
|
32
|
+
# an array of three integer variables with domains 0..9 and gave
|
33
|
+
# it the name +variables+.
|
34
|
+
#
|
35
|
+
# There are three types of variables: integer variables
|
36
|
+
# (Gecode::IntVar, can be assigned one of many
|
37
|
+
# possible integer values), boolean variables
|
38
|
+
# (Gecode::BoolVar, can be assigned either true or
|
39
|
+
# false) and set variables (Gecode::SetVar, can be
|
40
|
+
# assigned a set of integers). Variables of the different
|
41
|
+
# types are constructed using #int_var, #int_var_array,
|
42
|
+
# #int_var_matrix, #bool_var, #bool_var_array,
|
43
|
+
# #bool_var_matrix, #set_var, #set_var_array and
|
44
|
+
# #set_var_matrix .
|
45
|
+
#
|
46
|
+
# The various variables all have the functionality of Operand
|
47
|
+
# and have many properties depending on their type. For
|
48
|
+
# instance integer variables have the properties defined
|
49
|
+
# in Gecode::Int::IntOperand and
|
50
|
+
# enumerations of integer variables (such as the array
|
51
|
+
# +variables+ we used) have the properties defined in
|
52
|
+
# Gecode::IntEnum::IntEnumOperand .
|
53
|
+
#
|
54
|
+
# [Constraints] Constraints are placed on the variables to ensure that a
|
55
|
+
# valid assignment of the variables must also be a solution.
|
56
|
+
# In the example above we constrained the variables so
|
57
|
+
# that all equations were satisfied (which is exactly when
|
58
|
+
# we have found a solution).
|
59
|
+
#
|
60
|
+
# The various constraints that can be placed on the various
|
61
|
+
# kinds of operands are found in the respective
|
62
|
+
# constraint receivers. For instance, the constraints
|
63
|
+
# that can be placed on integer operands are found in
|
64
|
+
# Gecode::Int::IntConstraintReceiver and
|
65
|
+
# the constraints that can be placed on enumerations of
|
66
|
+
# integer operands are found in
|
67
|
+
# Gecode::IntEnum::IntEnumConstraintReceiver .
|
68
|
+
#
|
69
|
+
# [Branching] "branch_on variables" in the example tells Gecode that
|
70
|
+
# it should explore the search space until it has assigned
|
71
|
+
# +variables+ (or exhausted the search space). It also
|
72
|
+
# tells Gecode in what order the search space should be
|
73
|
+
# explore, which can have a big effect on the search
|
74
|
+
# performance. See #branch_on for details.
|
75
|
+
#
|
76
|
+
# == Finding solutions
|
77
|
+
#
|
78
|
+
# Solutions to a formulated problem are found are found by using
|
79
|
+
# methods such as #solve!, #solution, #each_solution . If one wants to
|
80
|
+
# find a solution that optimizes a certain quantity (i.e. maximizes a
|
81
|
+
# certain variable) then one should have a look at #maximize!,
|
82
|
+
# #minimize! and #optimize! .
|
83
|
+
#
|
84
|
+
# The first solution to the example above could for instance be found
|
85
|
+
# using
|
86
|
+
#
|
87
|
+
# puts EquationProblem.new.solve!.vars.values.join(', ')
|
88
|
+
#
|
89
|
+
# which would find the first solution to the problem, access the
|
90
|
+
# assigned values of +variables+ and print them (in order x, y, z).
|
91
|
+
#
|
92
|
+
# == Shorter ways of formulating problems
|
93
|
+
#
|
94
|
+
# Problems can also be formulated without defining a new class by
|
95
|
+
# using Gecode#solve et al.
|
96
|
+
#
|
97
|
+
# Additionally one can use "foo_is_an ..." to create an accessor of
|
98
|
+
# name foo, without having to use instance variables. The above
|
99
|
+
# problem becomes
|
100
|
+
# class EquationProblem < Gecode::Model
|
101
|
+
# def initialize
|
102
|
+
# x, y, z = vars_is_an int_var_array(3, 0..9)
|
103
|
+
#
|
104
|
+
# (x + y).must == z
|
105
|
+
# x.must == y - 3
|
106
|
+
#
|
107
|
+
# branch_on vars
|
108
|
+
# end
|
109
|
+
# end
|
110
|
+
#
|
3
111
|
class Model
|
4
112
|
# The largest integer allowed in the domain of an integer variable.
|
5
113
|
MAX_INT = Gecode::Raw::IntLimits::MAX
|
@@ -25,7 +133,7 @@ module Gecode
|
|
25
133
|
# domain is specified then the largest possible domain is used.
|
26
134
|
def int_var(domain = LARGEST_INT_DOMAIN)
|
27
135
|
args = domain_arguments(domain)
|
28
|
-
|
136
|
+
IntVar.new(self, variable_creation_space.new_int_var(*args))
|
29
137
|
end
|
30
138
|
|
31
139
|
# Creates an array containing the specified number of integer variables
|
@@ -35,7 +143,7 @@ module Gecode
|
|
35
143
|
def int_var_array(count, domain = LARGEST_INT_DOMAIN)
|
36
144
|
args = domain_arguments(domain)
|
37
145
|
build_var_array(count) do
|
38
|
-
|
146
|
+
IntVar.new(self, variable_creation_space.new_int_var(*args))
|
39
147
|
end
|
40
148
|
end
|
41
149
|
|
@@ -46,19 +154,19 @@ module Gecode
|
|
46
154
|
def int_var_matrix(row_count, col_count, domain = LARGEST_INT_DOMAIN)
|
47
155
|
args = domain_arguments(domain)
|
48
156
|
build_var_matrix(row_count, col_count) do
|
49
|
-
|
157
|
+
IntVar.new(self, variable_creation_space.new_int_var(*args))
|
50
158
|
end
|
51
159
|
end
|
52
160
|
|
53
161
|
# Creates a new boolean variable.
|
54
162
|
def bool_var
|
55
|
-
|
163
|
+
BoolVar.new(self, variable_creation_space.new_bool_var)
|
56
164
|
end
|
57
165
|
|
58
166
|
# Creates an array containing the specified number of boolean variables.
|
59
167
|
def bool_var_array(count)
|
60
168
|
build_var_array(count) do
|
61
|
-
|
169
|
+
BoolVar.new(self, variable_creation_space.new_bool_var)
|
62
170
|
end
|
63
171
|
end
|
64
172
|
|
@@ -66,7 +174,7 @@ module Gecode
|
|
66
174
|
# boolean variables.
|
67
175
|
def bool_var_matrix(row_count, col_count)
|
68
176
|
build_var_matrix(row_count, col_count) do
|
69
|
-
|
177
|
+
BoolVar.new(self, variable_creation_space.new_bool_var)
|
70
178
|
end
|
71
179
|
end
|
72
180
|
|
@@ -82,7 +190,7 @@ module Gecode
|
|
82
190
|
def set_var(glb_domain = [], lub_domain = LARGEST_SET_BOUND,
|
83
191
|
cardinality_range = nil)
|
84
192
|
args = set_bounds_to_parameters(glb_domain, lub_domain, cardinality_range)
|
85
|
-
|
193
|
+
SetVar.new(self, variable_creation_space.new_set_var(*args))
|
86
194
|
end
|
87
195
|
|
88
196
|
# Creates an array containing the specified number of set variables. The
|
@@ -91,7 +199,7 @@ module Gecode
|
|
91
199
|
cardinality_range = nil)
|
92
200
|
args = set_bounds_to_parameters(glb_domain, lub_domain, cardinality_range)
|
93
201
|
build_var_array(count) do
|
94
|
-
|
202
|
+
SetVar.new(self, variable_creation_space.new_set_var(*args))
|
95
203
|
end
|
96
204
|
end
|
97
205
|
|
@@ -102,7 +210,7 @@ module Gecode
|
|
102
210
|
lub_domain = LARGEST_SET_BOUND, cardinality_range = nil)
|
103
211
|
args = set_bounds_to_parameters(glb_domain, lub_domain, cardinality_range)
|
104
212
|
build_var_matrix(row_count, col_count) do
|
105
|
-
|
213
|
+
SetVar.new(self, variable_creation_space.new_set_var(*args))
|
106
214
|
end
|
107
215
|
end
|
108
216
|
|
@@ -157,7 +265,54 @@ module Gecode
|
|
157
265
|
def track_variable(variable) #:nodoc:
|
158
266
|
(@variables ||= []) << variable
|
159
267
|
end
|
160
|
-
|
268
|
+
|
269
|
+
# Wraps method missing to handle #foo_is_a and #foo_is_an .
|
270
|
+
#
|
271
|
+
# "<variable_name>_is_a <variable>" or "<variable_name>_is_an <variable>",
|
272
|
+
# replacing "<variable_name>" with the variable's name and
|
273
|
+
# "<variable>" with the variable, adds an instance variable and
|
274
|
+
# accessor with the specified name.
|
275
|
+
#
|
276
|
+
# The method also returns the variable given.
|
277
|
+
#
|
278
|
+
# ==== Example
|
279
|
+
#
|
280
|
+
# # Add an instance variable and accessor named "foo" that return
|
281
|
+
# # the integer variable.
|
282
|
+
# foo_is_an int_var(0..9)
|
283
|
+
#
|
284
|
+
# # Add an instance variable and accessor named "bar" that return
|
285
|
+
# # the boolean variable array.
|
286
|
+
# bar_is_a bool_var_array(2)
|
287
|
+
def method_missing(name_symbol, *args)
|
288
|
+
name = name_symbol.to_s
|
289
|
+
if name =~ /._is_an?$/
|
290
|
+
name.sub!(/_is_an?$/, '')
|
291
|
+
unless args.size == 1
|
292
|
+
raise ArgumentError, "Wrong number of argmuments (#{args.size} for 1)."
|
293
|
+
end
|
294
|
+
if respond_to? name
|
295
|
+
raise ArgumentError, "Method with name #{name} already exists."
|
296
|
+
end
|
297
|
+
if instance_variable_defined? "@#{name}"
|
298
|
+
raise ArgumentError,
|
299
|
+
"Instance variable with name @#{name} already exists."
|
300
|
+
end
|
301
|
+
|
302
|
+
# We use the meta class to avoid defining the variable in all
|
303
|
+
# other instances of the class.
|
304
|
+
eval <<-"end_eval"
|
305
|
+
@#{name} = args.first
|
306
|
+
class <<self
|
307
|
+
attr :#{name}
|
308
|
+
end
|
309
|
+
end_eval
|
310
|
+
return args.first
|
311
|
+
else
|
312
|
+
super
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
161
316
|
protected
|
162
317
|
|
163
318
|
# Gets a queue of objects that can be posted to the model's active_space
|
@@ -231,8 +386,8 @@ module Gecode
|
|
231
386
|
def set_bounds_to_parameters(glb_domain, lub_domain, cardinality_range)
|
232
387
|
check_set_bounds(glb_domain, lub_domain)
|
233
388
|
args = []
|
234
|
-
args << Gecode::
|
235
|
-
args << Gecode::
|
389
|
+
args << Gecode::Util.constant_set_to_int_set(glb_domain)
|
390
|
+
args << Gecode::Util.constant_set_to_int_set(lub_domain)
|
236
391
|
card_range = to_set_cardinality_range(cardinality_range)
|
237
392
|
if card_range.nil?
|
238
393
|
card_range = 0..Gecode::Raw::SetLimits::CARD
|