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
@@ -0,0 +1,84 @@
|
|
1
|
+
module Gecode
|
2
|
+
# Provides a convenient way to construct a model and then find a
|
3
|
+
# solution. The model constructed uses the specified block as
|
4
|
+
# initialization method. The first solution to the model is then
|
5
|
+
# returned.
|
6
|
+
#
|
7
|
+
# For instance
|
8
|
+
#
|
9
|
+
# solution = Gecode.solve do
|
10
|
+
# # Do something
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# is equivalent to
|
14
|
+
#
|
15
|
+
# class Foo < Gecode::Model
|
16
|
+
# def initialize
|
17
|
+
# # Do something
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
# solution = Foo.new.solve!
|
21
|
+
def self.solve(&block)
|
22
|
+
create_model(&block).solve!
|
23
|
+
end
|
24
|
+
|
25
|
+
# Provides a convenient way to construct a model and then find the
|
26
|
+
# solution that maximizes a given variable. The model constructed
|
27
|
+
# uses the specified block as initialization method. The solution
|
28
|
+
# that maximizes the specified variable is then returned.
|
29
|
+
#
|
30
|
+
# For instance
|
31
|
+
#
|
32
|
+
# solution = Gecode.maximize :variable_bar do
|
33
|
+
# # Do something
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# is equivalent to
|
37
|
+
#
|
38
|
+
# class Foo < Gecode::Model
|
39
|
+
# def initialize
|
40
|
+
# # Do something
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# solution = Foo.new.maximize :variable_bar
|
44
|
+
def self.maximize(variable_to_maximize, &block)
|
45
|
+
create_model(&block).maximize! variable_to_maximize
|
46
|
+
end
|
47
|
+
|
48
|
+
# Provides a convenient way to construct a model and then find the
|
49
|
+
# solution that minimizes a given variable. The model constructed
|
50
|
+
# uses the specified block as initialization method. The solution
|
51
|
+
# that minimizes the specified variable is then returned.
|
52
|
+
#
|
53
|
+
# For instance
|
54
|
+
#
|
55
|
+
# solution = Gecode.minimize :variable_bar do
|
56
|
+
# # Do something
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# is equivalent to
|
60
|
+
#
|
61
|
+
# class Foo < Gecode::Model
|
62
|
+
# def initialize
|
63
|
+
# # Do something
|
64
|
+
# end
|
65
|
+
# end
|
66
|
+
# solution = Foo.new.minimize :variable_bar
|
67
|
+
def self.minimize(variable_to_minimize, &block)
|
68
|
+
create_model(&block).minimize! variable_to_minimize
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
# Creates an instance of a class that subclasses Model and uses the
|
74
|
+
# specified block as initialization method.
|
75
|
+
def self.create_model(&block)
|
76
|
+
model = Class.new(Gecode::Model)
|
77
|
+
model.class_eval do
|
78
|
+
def initialize(&init_block) #:nodoc:
|
79
|
+
instance_eval &init_block
|
80
|
+
end
|
81
|
+
end
|
82
|
+
model.new(&block)
|
83
|
+
end
|
84
|
+
end
|
@@ -1,19 +1,27 @@
|
|
1
1
|
module Gecode
|
2
|
+
# An exception raised when a search failed because there are no
|
3
|
+
# solutions.
|
4
|
+
class NoSolutionError < RuntimeError
|
5
|
+
def initialize #:nodoc:
|
6
|
+
super('No solution could be found.')
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
2
10
|
class Model
|
3
11
|
# Finds the first solution to the modelled problem and updates the variables
|
4
|
-
# to that solution.
|
5
|
-
#
|
12
|
+
# to that solution. The found solution is also returned. Raises
|
13
|
+
# Gecode::NoSolutionError if no solution can be found.
|
6
14
|
def solve!
|
7
15
|
dfs = dfs_engine
|
8
16
|
space = dfs.next
|
9
17
|
@statistics = dfs.statistics
|
10
|
-
|
18
|
+
raise Gecode::NoSolutionError if space.nil?
|
11
19
|
self.active_space = space
|
12
20
|
return self
|
13
21
|
end
|
14
22
|
|
15
|
-
# Returns to the original state, before any search was made (but
|
16
|
-
# might have been performed). Returns the reset model.
|
23
|
+
# Returns to the original state, before any search was made (but
|
24
|
+
# propagation might have been performed). Returns the reset model.
|
17
25
|
def reset!
|
18
26
|
self.active_space = base_space
|
19
27
|
@statistics = nil
|
@@ -24,10 +32,14 @@ module Gecode
|
|
24
32
|
# then the block is not used. Returns the result of the block (nil in case
|
25
33
|
# the block wasn't run).
|
26
34
|
def solution(&block)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
35
|
+
begin
|
36
|
+
solution = self.solve!
|
37
|
+
res = yield solution
|
38
|
+
self.reset!
|
39
|
+
return res
|
40
|
+
rescue Gecode::NoSolutionError
|
41
|
+
return nil
|
42
|
+
end
|
31
43
|
end
|
32
44
|
|
33
45
|
# Yields each solution that the model has.
|
@@ -44,7 +56,7 @@ module Gecode
|
|
44
56
|
|
45
57
|
# Returns search statistics providing various information from Gecode about
|
46
58
|
# the search that resulted in the model's current variable state. If the
|
47
|
-
# model's variables have not
|
59
|
+
# model's variables have not undergone any search then nil is returned. The
|
48
60
|
# statistics is a hash with the following keys:
|
49
61
|
# [:propagations] The number of propagation steps performed.
|
50
62
|
# [:failures] The number of failed nodes in the search tree.
|
@@ -74,7 +86,7 @@ module Gecode
|
|
74
86
|
# model.price.must < best_so_far.price.val
|
75
87
|
# end
|
76
88
|
#
|
77
|
-
#
|
89
|
+
# Raises Gecode::NoSolutionError if no solution can be found.
|
78
90
|
def optimize!(&block)
|
79
91
|
# Execute constraints.
|
80
92
|
perform_queued_gecode_interactions
|
@@ -106,7 +118,7 @@ module Gecode
|
|
106
118
|
|
107
119
|
# Reset the method used constrain calls and return the result.
|
108
120
|
Model.constrain_proc = nil
|
109
|
-
|
121
|
+
raise Gecode::NoSolutionError if result.nil?
|
110
122
|
|
111
123
|
# Switch to the result.
|
112
124
|
self.active_space = result
|
@@ -115,15 +127,15 @@ module Gecode
|
|
115
127
|
|
116
128
|
# Finds the solution that maximizes a given integer variable. The name of
|
117
129
|
# the method that accesses the variable from the model should be given. To
|
118
|
-
# for instance maximize a variable named "profit", that's accessible
|
119
|
-
# the model, one would use the following.
|
130
|
+
# for instance maximize a variable named "profit", that's accessible
|
131
|
+
# through the model, one would use the following.
|
120
132
|
#
|
121
133
|
# model.maximize! :profit
|
122
134
|
#
|
123
|
-
#
|
135
|
+
# Raises Gecode::NoSolutionError if no solution can be found.
|
124
136
|
def maximize!(var)
|
125
137
|
variable = self.method(var).call
|
126
|
-
unless variable.kind_of? Gecode::
|
138
|
+
unless variable.kind_of? Gecode::IntVar
|
127
139
|
raise ArgumentError.new("Expected integer variable, got #{variable.class}.")
|
128
140
|
end
|
129
141
|
|
@@ -139,10 +151,10 @@ module Gecode
|
|
139
151
|
#
|
140
152
|
# model.minimize! :cost
|
141
153
|
#
|
142
|
-
#
|
154
|
+
# Raises Gecode::NoSolutionError if no solution can be found.
|
143
155
|
def minimize!(var)
|
144
156
|
variable = self.method(var).call
|
145
|
-
unless variable.kind_of? Gecode::
|
157
|
+
unless variable.kind_of? Gecode::IntVar
|
146
158
|
raise ArgumentError.new("Expected integer variable, got #{variable.class}.")
|
147
159
|
end
|
148
160
|
|
@@ -13,9 +13,9 @@ module Gecode
|
|
13
13
|
|
14
14
|
def inspect
|
15
15
|
if assigned?
|
16
|
-
"#<#{self.class} #{
|
16
|
+
"#<#{self.class} #{domain_string}>"
|
17
17
|
else
|
18
|
-
"#<#{self.class} #{
|
18
|
+
"#<#{self.class} #{domain_string}>"
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -36,11 +36,11 @@ module Gecode
|
|
36
36
|
|
37
37
|
# Creates a class for a free variable that can be bound into the specified
|
38
38
|
# class using the specified method in a space.
|
39
|
-
def Gecode::FreeVar(bound_class, space_bind_method)
|
39
|
+
def Gecode::FreeVar(bound_class, space_bind_method) #:nodoc:
|
40
40
|
clazz = Class.new(FreeVarBase)
|
41
41
|
clazz.class_eval <<-"end_method_definitions"
|
42
|
-
# Binds the
|
43
|
-
# returning the bound
|
42
|
+
# Binds the variable to the currently active space of the model,
|
43
|
+
# returning the bound variable.
|
44
44
|
def bind
|
45
45
|
active_space.method(:#{space_bind_method}).call(@index)
|
46
46
|
end
|
@@ -64,12 +64,25 @@ module Gecode
|
|
64
64
|
return clazz
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
# Describes an integer variable.
|
69
|
-
#
|
70
|
-
# An integer variable
|
71
|
-
#
|
72
|
-
|
67
|
+
IntVar = FreeVar(Gecode::Raw::IntVar, :int_var)
|
68
|
+
# Describes an integer variable.
|
69
|
+
#
|
70
|
+
# An integer variable can take the value of any integer in its
|
71
|
+
# domain, which is specified upon constructing the variable and
|
72
|
+
# further constrained by placing constraints on the variable.
|
73
|
+
# An integer variable is said to be assigned once the domain only
|
74
|
+
# contains a single element, at which point #value can be used to
|
75
|
+
# retrieve the value.
|
76
|
+
#
|
77
|
+
# Integer variables are integer operands and hence respond to
|
78
|
+
# everything that Gecode::Int::IntOperand responds to.
|
79
|
+
# Any constraint found in
|
80
|
+
# Gecode::Int::IntConstraintReceiver can thereby be
|
81
|
+
# placed on integer variables.
|
82
|
+
class IntVar
|
83
|
+
include Gecode::Int::IntOperand
|
84
|
+
attr :model
|
85
|
+
|
73
86
|
# Gets the minimum value still in the domain of the variable.
|
74
87
|
delegate :min
|
75
88
|
# Gets the maximum value still in the domain of the variable.
|
@@ -97,11 +110,27 @@ module Gecode
|
|
97
110
|
raise 'No value is assigned.' unless assigned?
|
98
111
|
send_bound(:val)
|
99
112
|
end
|
113
|
+
|
114
|
+
# Returns the receiver.
|
115
|
+
def to_int_var
|
116
|
+
self
|
117
|
+
end
|
100
118
|
|
119
|
+
# Returns an enumeration corresponding to the domain.
|
120
|
+
def domain
|
121
|
+
if range?
|
122
|
+
min..max
|
123
|
+
else
|
124
|
+
(min..max).select do |i|
|
125
|
+
include? i
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
101
130
|
private
|
102
131
|
|
103
|
-
# Returns a string representation of the
|
104
|
-
def
|
132
|
+
# Returns a string representation of the range of the variable's domain.
|
133
|
+
def domain_string #:nodoc:
|
105
134
|
if assigned?
|
106
135
|
"range: #{value.to_s}"
|
107
136
|
else
|
@@ -110,10 +139,20 @@ module Gecode
|
|
110
139
|
end
|
111
140
|
end
|
112
141
|
|
113
|
-
|
114
|
-
# Describes a boolean variable.
|
115
|
-
#
|
116
|
-
|
142
|
+
BoolVar = FreeVar(Gecode::Raw::BoolVar, :bool_var)
|
143
|
+
# Describes a boolean variable.
|
144
|
+
#
|
145
|
+
# A boolean variable can be either true or false.
|
146
|
+
#
|
147
|
+
# Boolean variables are boolean operands and hence respond to
|
148
|
+
# everything that Gecode::Bool::BoolOperand responds to.
|
149
|
+
# Any constraint found in
|
150
|
+
# Gecode::Bool::BoolConstraintReceiver can thereby be
|
151
|
+
# placed on boolean variables.
|
152
|
+
class BoolVar
|
153
|
+
include Gecode::Bool::BoolOperand
|
154
|
+
attr :model
|
155
|
+
|
117
156
|
# Checks whether the variable has been assigned.
|
118
157
|
delegate :assigned?, :assigned
|
119
158
|
|
@@ -123,11 +162,16 @@ module Gecode
|
|
123
162
|
raise 'No value is assigned.' unless assigned?
|
124
163
|
send_bound(:val) == 1
|
125
164
|
end
|
165
|
+
|
166
|
+
# Returns the receiver.
|
167
|
+
def to_bool_var
|
168
|
+
self
|
169
|
+
end
|
126
170
|
|
127
171
|
private
|
128
172
|
|
129
173
|
# Returns a string representation of the the variable's domain.
|
130
|
-
def
|
174
|
+
def domain_string
|
131
175
|
if assigned?
|
132
176
|
value.to_s
|
133
177
|
else
|
@@ -136,24 +180,37 @@ module Gecode
|
|
136
180
|
end
|
137
181
|
end
|
138
182
|
|
139
|
-
|
183
|
+
SetVar = FreeVar(Gecode::Raw::SetVar, :set_var)
|
140
184
|
# Describes a set variable.
|
141
185
|
#
|
142
|
-
# A set variable's domain, i.e. possible values that it can take, are
|
143
|
-
# represented with a greatest lower bound (GLB) and a least upper
|
144
|
-
# The set variable may then take any set value S such
|
145
|
-
# the least upper bound and the greatest lower
|
186
|
+
# A set variable's domain, i.e. possible values that it can take, are
|
187
|
+
# represented with a greatest lower bound (GLB) and a least upper
|
188
|
+
# bound (LUB). The set variable may then take any set value S such
|
189
|
+
# that S is a subset of the least upper bound and the greatest lower
|
190
|
+
# bound is a subset of S.
|
146
191
|
#
|
147
|
-
# If for instance the set has a greatest lower bound {1} and least
|
148
|
-
# {1,3,5} then the assigned set may be any of the
|
149
|
-
# {1,3}, {1,5}, {1,3,5}.
|
192
|
+
# If for instance the set has a greatest lower bound {1} and least
|
193
|
+
# upper bound {1,3,5} then the assigned set may be any of the
|
194
|
+
# following four sets: {1}, {1,3}, {1,5}, {1,3,5}.
|
150
195
|
#
|
151
|
-
# The domain of a set variable may also specify the cardinality of the
|
152
|
-
# i.e. the number of elements that the set may contains.
|
153
|
-
|
196
|
+
# The domain of a set variable may also specify the cardinality of the
|
197
|
+
# set, i.e. the number of elements that the set may contains.
|
198
|
+
#
|
199
|
+
# Set variables are set operands and hence respond to everything that
|
200
|
+
# Gecode::Set::SetOperand responds to. Any constraint
|
201
|
+
# found in Gecode::Set::SetConstraintReceiver can thereby
|
202
|
+
# be placed on set variables.
|
203
|
+
class SetVar
|
204
|
+
include Gecode::Set::SetOperand
|
205
|
+
attr :model
|
206
|
+
|
154
207
|
# Checks whether the variable has been assigned.
|
155
208
|
delegate :assigned?, :assigned
|
156
|
-
|
209
|
+
# Checks whether a value is included in the set.
|
210
|
+
delegate :in_lower_bound?, :contains
|
211
|
+
# Checks whether a value is not included in the set.
|
212
|
+
delegate :not_in_upper_bound?, :notContains
|
213
|
+
|
157
214
|
# Gets all the elements located in the greatest lower bound of the set (an
|
158
215
|
# Enumerable).
|
159
216
|
def lower_bound
|
@@ -185,14 +242,27 @@ module Gecode
|
|
185
242
|
send_bound(:cardMin)..send_bound(:cardMax)
|
186
243
|
end
|
187
244
|
|
245
|
+
# Returns the receiver.
|
246
|
+
def to_set_var
|
247
|
+
self
|
248
|
+
end
|
249
|
+
|
188
250
|
private
|
189
251
|
|
190
252
|
# Returns a string representation of the the variable's domain.
|
191
|
-
def
|
253
|
+
def domain_string
|
192
254
|
if assigned?
|
193
|
-
lower_bound.
|
255
|
+
if lower_bound.size < 100
|
256
|
+
lower_bound.to_a.inspect
|
257
|
+
else
|
258
|
+
"the domain is too large to display"
|
259
|
+
end
|
194
260
|
else
|
195
|
-
|
261
|
+
if upper_bound.size < 100
|
262
|
+
"glb-range: #{lower_bound.to_a.inspect}, lub-range: #{upper_bound.to_a.inspect}"
|
263
|
+
else
|
264
|
+
"the domain is too large to display"
|
265
|
+
end
|
196
266
|
end
|
197
267
|
end
|
198
268
|
end
|
data/lib/gecoder/version.rb
CHANGED
data/specs/bool_var.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraints/property_helper'
|
2
3
|
|
3
4
|
describe 'non-empty bool variable', :shared => true do
|
4
5
|
it 'should give a NoMethodError when calling a method that doesn\'t exist' do
|
@@ -6,10 +7,10 @@ describe 'non-empty bool variable', :shared => true do
|
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
|
-
describe Gecode::
|
10
|
+
describe Gecode::BoolVar, '(not assigned)' do
|
10
11
|
before do
|
11
|
-
model = Gecode::Model.new
|
12
|
-
@var = model.bool_var
|
12
|
+
@model = Gecode::Model.new
|
13
|
+
@operand = @var = @model.bool_var
|
13
14
|
end
|
14
15
|
|
15
16
|
it_should_behave_like 'non-empty bool variable'
|
@@ -25,14 +26,16 @@ describe Gecode::FreeBoolVar, '(not assigned)' do
|
|
25
26
|
it 'should raise error when trying to access assigned value' do
|
26
27
|
lambda{ @var.value }.should raise_error(RuntimeError)
|
27
28
|
end
|
29
|
+
|
30
|
+
it_should_behave_like 'bool var operand'
|
28
31
|
end
|
29
32
|
|
30
|
-
describe Gecode::
|
33
|
+
describe Gecode::BoolVar, '(assigned true)' do
|
31
34
|
before do
|
32
|
-
model = Gecode::Model.new
|
33
|
-
@var = model.bool_var
|
35
|
+
@model = Gecode::Model.new
|
36
|
+
@operand = @var = @model.bool_var
|
34
37
|
@var.must_be.true
|
35
|
-
model.solve!
|
38
|
+
@model.solve!
|
36
39
|
end
|
37
40
|
|
38
41
|
it_should_behave_like 'non-empty bool variable'
|
@@ -48,14 +51,16 @@ describe Gecode::FreeBoolVar, '(assigned true)' do
|
|
48
51
|
it "should say that it's true when inspecting" do
|
49
52
|
@var.inspect.should include('true')
|
50
53
|
end
|
54
|
+
|
55
|
+
it_should_behave_like 'bool var operand'
|
51
56
|
end
|
52
57
|
|
53
|
-
describe Gecode::
|
58
|
+
describe Gecode::BoolVar, '(assigned false)' do
|
54
59
|
before do
|
55
|
-
model = Gecode::Model.new
|
56
|
-
@var = model.bool_var
|
60
|
+
@model = Gecode::Model.new
|
61
|
+
@operand = @var = @model.bool_var
|
57
62
|
@var.must_be.false
|
58
|
-
model.solve!
|
63
|
+
@model.solve!
|
59
64
|
end
|
60
65
|
|
61
66
|
it_should_behave_like 'non-empty bool variable'
|
@@ -71,4 +76,6 @@ describe Gecode::FreeBoolVar, '(assigned false)' do
|
|
71
76
|
it "should say that it's false when inspecting" do
|
72
77
|
@var.inspect.should include('false')
|
73
78
|
end
|
74
|
-
|
79
|
+
|
80
|
+
it_should_behave_like 'bool var operand'
|
81
|
+
end
|