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,193 +1,130 @@
|
|
1
|
-
module Gecode
|
2
|
-
|
3
|
-
#
|
1
|
+
module Gecode::Set
|
2
|
+
module SetOperand
|
3
|
+
# Produces an IntOperand representing the minimum of the set.
|
4
|
+
#
|
5
|
+
# ==== Examples
|
6
|
+
#
|
7
|
+
# # The minimum of +set+.
|
8
|
+
# set.min
|
4
9
|
def min
|
5
|
-
|
6
|
-
Gecode::Constraints::Set::Connection::MinExpressionStub.new(@model, params)
|
10
|
+
Connection::SetMinOperand.new(@model, self)
|
7
11
|
end
|
8
12
|
|
9
|
-
#
|
13
|
+
# Produces an IntOperand representing the maximum of the set.
|
14
|
+
#
|
15
|
+
# ==== Examples
|
16
|
+
#
|
17
|
+
# # The maximum of +set+.
|
18
|
+
# set.max
|
10
19
|
def max
|
11
|
-
|
12
|
-
Gecode::Constraints::Set::Connection::MaxExpressionStub.new(@model, params)
|
20
|
+
Connection::SetMaxOperand.new(@model, self)
|
13
21
|
end
|
14
22
|
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# weighted sum
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
+
# Produces an IntOperand representing the sum of the values in the
|
24
|
+
# set. One of the following options may also be given:
|
25
|
+
# [:weights] Produces the weighted sum using the specified hash
|
26
|
+
# of weights. The hash should map each value to
|
27
|
+
# that value's weight.
|
28
|
+
# [:substitutions] Produces the sum of the set with all elements
|
29
|
+
# replaced according to the hash.
|
30
|
+
#
|
31
|
+
# Elements not included in the weights or substitutions hash are
|
32
|
+
# removed from the upper bound of the set.
|
33
|
+
#
|
34
|
+
# ==== Examples
|
35
|
+
#
|
36
|
+
# # The sum of +set+.
|
37
|
+
# set.sum
|
38
|
+
#
|
39
|
+
# # The sum of +set+ with primes < 10 given twice the weight.
|
40
|
+
# set.sum(:weights => {2 => 2, 3 => 2, 5 => 2, 7 => 2})
|
41
|
+
#
|
42
|
+
# # The sum of +set+ with odd values in [1,6] being counted as 1.
|
43
|
+
# set.sum(:substitutions => {1 => 1, 3 => 1, 5 => 1})
|
23
44
|
def sum(options = {:weights => weights = Hash.new(1)})
|
24
45
|
if options.empty? or options.keys.size > 1
|
25
|
-
raise ArgumentError, '
|
26
|
-
'
|
27
|
-
end
|
28
|
-
params = {:lhs => self}
|
29
|
-
unless options.empty?
|
30
|
-
case options.keys.first
|
31
|
-
when :substitutions: params.update(options)
|
32
|
-
when :weights:
|
33
|
-
weights = options[:weights]
|
34
|
-
substitutions = Hash.new do |hash, key|
|
35
|
-
if weights[key].nil?
|
36
|
-
hash[key] = nil
|
37
|
-
else
|
38
|
-
hash[key] = key * weights[key]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
params.update(:substitutions => substitutions)
|
42
|
-
else raise ArgumentError, "Unrecognized option #{options.keys.first}."
|
43
|
-
end
|
46
|
+
raise ArgumentError, 'At most one of the options :weights and ' +
|
47
|
+
':substitutions may be specified.'
|
44
48
|
end
|
45
|
-
Gecode::Constraints::Set::Connection::SumExpressionStub.new(@model, params)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
50
|
+
case options.keys.first
|
51
|
+
when :substitutions: subs = options[:substitutions]
|
52
|
+
when :weights:
|
53
|
+
weights = options[:weights]
|
54
|
+
subs = Hash.new do |hash, key|
|
55
|
+
if weights[key].nil?
|
56
|
+
hash[key] = nil
|
57
|
+
else
|
58
|
+
hash[key] = key * weights[key]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
else raise ArgumentError, "Unrecognized option #{options.keys.first}."
|
62
62
|
end
|
63
|
-
|
64
|
-
@params.update(:variables => variables)
|
65
|
-
@model.add_constraint Connection::IncludeConstraint.new(@model, @params)
|
63
|
+
Connection::SetSumOperand.new(@model, self, subs)
|
66
64
|
end
|
67
65
|
end
|
68
|
-
|
66
|
+
|
69
67
|
# A module that gathers the classes and modules used in connection
|
70
68
|
# constraints.
|
71
69
|
module Connection #:nodoc:
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
# # Constrains the minimum value of +set+ to equal the integer variable
|
81
|
-
# # +min+.
|
82
|
-
# set.min.must == min
|
83
|
-
#
|
84
|
-
# # Constrains the minimum value of +set+ to not be larger than the
|
85
|
-
# # integer variable +ceil+.
|
86
|
-
# set.min.must_not > ceil
|
87
|
-
#
|
88
|
-
# # The same as above but reified with the boolean variable
|
89
|
-
# # +is_not_above_ceiling+ and with the strength +domain+ applied.
|
90
|
-
# set.min.must_not_be.larger_than(ceil, :reify => :is_not_above_ceiling,
|
91
|
-
# :strength => :domain)
|
92
|
-
class MinExpressionStub < Gecode::Constraints::Int::CompositeStub
|
93
|
-
def constrain_equal(variable, params, constrain)
|
94
|
-
set = params[:lhs]
|
70
|
+
class SetMinOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
|
71
|
+
def initialize(model, set_op)
|
72
|
+
super model
|
73
|
+
@set = set_op
|
74
|
+
end
|
75
|
+
|
76
|
+
def constrain_equal(int_operand, constrain, propagation_options)
|
77
|
+
set = @set.to_set_var
|
95
78
|
if constrain
|
96
|
-
|
79
|
+
int_operand.must_be.in set.upper_bound.min..set.lower_bound.min
|
97
80
|
end
|
98
81
|
|
99
|
-
Gecode::Raw::min(@model.active_space, set.bind,
|
82
|
+
Gecode::Raw::min(@model.active_space, set.bind,
|
83
|
+
int_operand.to_int_var.bind)
|
100
84
|
end
|
101
85
|
end
|
102
86
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
# # Constrains the maximum value of +set+ to equal the integer variable
|
112
|
-
# # +max+.
|
113
|
-
# set.max.must == max
|
114
|
-
#
|
115
|
-
# # Constrains the maximum value of +set+ to not be less than the
|
116
|
-
# # integer variable +floor+.
|
117
|
-
# set.max.must_not < floor
|
118
|
-
#
|
119
|
-
# # The same as above but reified with the boolean variable
|
120
|
-
# # +is_not_below_floor+ and with the strength +domain+ applied.
|
121
|
-
# set.max.must_not_be.less_than(ceil, :reify => :is_not_below_floor,
|
122
|
-
# :strength => :domain)
|
123
|
-
class MaxExpressionStub < Gecode::Constraints::Int::CompositeStub
|
124
|
-
def constrain_equal(variable, params, constrain)
|
125
|
-
set = params[:lhs]
|
87
|
+
class SetMaxOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
|
88
|
+
def initialize(model, set_op)
|
89
|
+
super model
|
90
|
+
@set = set_op
|
91
|
+
end
|
92
|
+
|
93
|
+
def constrain_equal(int_operand, constrain, propagation_options)
|
94
|
+
set = @set.to_set_var
|
126
95
|
if constrain
|
127
|
-
|
96
|
+
int_operand.must_be.in set.upper_bound.min..set.lower_bound.min
|
128
97
|
end
|
129
98
|
|
130
|
-
Gecode::Raw::max(@model.active_space, set.bind,
|
99
|
+
Gecode::Raw::max(@model.active_space, set.bind,
|
100
|
+
int_operand.to_int_var.bind)
|
131
101
|
end
|
132
102
|
end
|
133
103
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
# # variable +sum+.
|
144
|
-
# set.sum.must == sum
|
145
|
-
#
|
146
|
-
# # Constrains the sum of all values in +set+ to not be larger than the
|
147
|
-
# # integer variable +resources+.
|
148
|
-
# set.sum.must_not > resources
|
149
|
-
#
|
150
|
-
# # The same as above but reified with the boolean variable
|
151
|
-
# # +not_over_budget+ and with the strength +domain+ applied.
|
152
|
-
# set.sum.must_not_be.larger_than(resources, :reify => :not_over_budget,
|
153
|
-
# :strength => :domain)
|
154
|
-
class SumExpressionStub < Gecode::Constraints::Int::CompositeStub
|
155
|
-
def constrain_equal(variable, params, constrain)
|
156
|
-
set, subs = params.values_at(:lhs, :substitutions)
|
104
|
+
class SetSumOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
|
105
|
+
def initialize(model, set_op, subs)
|
106
|
+
super model
|
107
|
+
@set = set_op
|
108
|
+
@subs = subs
|
109
|
+
end
|
110
|
+
|
111
|
+
def constrain_equal(int_operand, constrain, propagation_options)
|
112
|
+
set = @set.to_set_var
|
157
113
|
lub = set.upper_bound.to_a
|
158
|
-
lub.delete_if{ |e| subs[e].nil? }
|
159
|
-
substituted_lub = lub.map{ |e| subs[e] }
|
114
|
+
lub.delete_if{ |e| @subs[e].nil? }
|
115
|
+
substituted_lub = lub.map{ |e| @subs[e] }
|
160
116
|
if constrain
|
161
117
|
# Compute the theoretical bounds of the weighted sum. This is slightly
|
162
118
|
# sloppy since we could also use the contents of the greatest lower
|
163
119
|
# bound.
|
164
120
|
min = substituted_lub.find_all{ |e| e < 0}.inject(0){ |x, y| x + y }
|
165
121
|
max = substituted_lub.find_all{ |e| e > 0}.inject(0){ |x, y| x + y }
|
166
|
-
|
122
|
+
int_operand.must_be.in min..max
|
167
123
|
end
|
168
124
|
|
169
125
|
Gecode::Raw::weights(@model.active_space, lub, substituted_lub,
|
170
|
-
set.bind,
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
# Describes an include constraint, which constrains the set to include the
|
175
|
-
# values of the specified enumeration of integer variables.
|
176
|
-
#
|
177
|
-
# The constraint has the side effect of sorting the integer variables in a
|
178
|
-
# non-descending order. It does not support reification nor negation.
|
179
|
-
#
|
180
|
-
# == Examples
|
181
|
-
#
|
182
|
-
# # Constrain +set+ to include the values of all variables in
|
183
|
-
# # +int_enum+.
|
184
|
-
# set.must.include int_enum
|
185
|
-
class IncludeConstraint < Gecode::Constraints::Constraint
|
186
|
-
def post
|
187
|
-
set, variables = @params.values_at(:lhs, :variables)
|
188
|
-
Gecode::Raw::match(@model.active_space, set.bind,
|
189
|
-
variables.to_int_var_array)
|
126
|
+
set.bind, int_operand.to_int_var.bind)
|
190
127
|
end
|
191
128
|
end
|
192
129
|
end
|
193
|
-
end
|
130
|
+
end
|
@@ -1,13 +1,102 @@
|
|
1
|
-
module Gecode::
|
2
|
-
class
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
module Gecode::Set
|
2
|
+
class SetConstraintReceiver
|
3
|
+
# Constrains the set operand to have a domain equal to +constant_set+.
|
4
|
+
#
|
5
|
+
# ==== Examples
|
6
|
+
#
|
7
|
+
# # +set+ must equal [1,2,5]
|
8
|
+
# set.must == [1,2,5]
|
9
|
+
#
|
10
|
+
# # +set+ must not equal 1..67
|
11
|
+
# set.must_not == 1..67
|
12
|
+
#
|
13
|
+
# # +set+ must equal the singleton set 0. The constraint is reified with
|
14
|
+
# # the boolean operand +is_singleton_zero+.
|
15
|
+
# set.must.equal(0, :reify => is_singleton_zero)
|
16
|
+
def ==(constant_set, options = {})
|
17
|
+
add_domain_constraint(:==, constant_set, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Constrains the set operand to be a superset of +constant_set+.
|
21
|
+
#
|
22
|
+
# ==== Examples
|
23
|
+
#
|
24
|
+
# # +set+ must be a superset of [1,2,5]
|
25
|
+
# set.must_be.superset_of [1,2,5]
|
26
|
+
#
|
27
|
+
# # +set+ must be a superset of 1..67
|
28
|
+
# set.must_be.superset_of 1..67
|
29
|
+
#
|
30
|
+
# # +set+ must not be a superset of [0].
|
31
|
+
# set.must_not_be.superset_of 0
|
32
|
+
#
|
33
|
+
# # +set+ must be a superset of [1,3,5,7]. The constraint is reified with
|
34
|
+
# # the boolean operand +bool+.
|
35
|
+
# set.must_be.superset_of([1.3.5.7], :reify => bool)
|
36
|
+
def superset(constant_set, options = {})
|
37
|
+
add_domain_constraint(:superset, constant_set, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Constrains the set operand to be a subset of +constant_set+.
|
41
|
+
#
|
42
|
+
# ==== Examples
|
43
|
+
#
|
44
|
+
# # +set+ must be a subset of [1,2,5]
|
45
|
+
# set.must_be.subset_of [1,2,5]
|
46
|
+
#
|
47
|
+
# # +set+ must be a subset of 1..67
|
48
|
+
# set.must_be.subset_of 1..67
|
49
|
+
#
|
50
|
+
# # +set+ must not be a subset of [0].
|
51
|
+
# set.must_not_be.subset_of 0
|
52
|
+
#
|
53
|
+
# # +set+ must be a subset of [1,3,5,7]. The constraint is reified with
|
54
|
+
# # the boolean operand +bool+.
|
55
|
+
# set.must_be.subset_of([1.3.5.7], :reify => bool)
|
56
|
+
def subset(constant_set, options = {})
|
57
|
+
add_domain_constraint(:subset, constant_set, options)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Constrains the set operand to be disjoint with +constant_set+.
|
61
|
+
#
|
62
|
+
# ==== Examples
|
63
|
+
#
|
64
|
+
# # +set+ must be disjoint with [1,2,5]
|
65
|
+
# set.must_be.disjoint_with [1,2,5]
|
66
|
+
#
|
67
|
+
# # +set+ must be disjoint with 1..67
|
68
|
+
# set.must_be.disjoint_with 1..67
|
69
|
+
#
|
70
|
+
# # +set+ must not be disjoint with [0].
|
71
|
+
# set.must_not_be.disjoint_with 0
|
72
|
+
#
|
73
|
+
# # +set+ must be disjoint with [1,3,5,7]. The constraint is reified with
|
74
|
+
# # the boolean operand +bool+.
|
75
|
+
# set.must_be.disjoint_with([1.3.5.7], :reify => bool)
|
76
|
+
def disjoint(constant_set, options = {})
|
77
|
+
add_domain_constraint(:disjoint, constant_set, options)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Constrains the set operand to be the complement of +constant_set+.
|
81
|
+
#
|
82
|
+
# ==== Examples
|
83
|
+
#
|
84
|
+
# # +set+ must be the complement of [1,2,5]
|
85
|
+
# set.must_be.complement_of [1,2,5]
|
86
|
+
#
|
87
|
+
# # +set+ must be the complement of 1..67
|
88
|
+
# set.must_be.complement_of 1..67
|
89
|
+
#
|
90
|
+
# # +set+ must not be the complement of [0].
|
91
|
+
# set.must_not_be.complement_of 0
|
92
|
+
#
|
93
|
+
# # +set+ must be the complement of [1,3,5,7]. The constraint is
|
94
|
+
# # reified with the boolean operand +bool+.
|
95
|
+
# set.must_be.complement_of([1.3.5.7], :reify => bool)
|
96
|
+
def complement(constant_set, options = {})
|
97
|
+
add_domain_constraint(:complement, constant_set, options)
|
10
98
|
end
|
99
|
+
|
11
100
|
alias_set_methods
|
12
101
|
|
13
102
|
private
|
@@ -15,12 +104,12 @@ module Gecode::Constraints::Set
|
|
15
104
|
# Adds a domain constraint for the specified relation name, constant set
|
16
105
|
# and options.
|
17
106
|
def add_domain_constraint(relation_name, constant_set, options)
|
18
|
-
unless Gecode::
|
107
|
+
unless Gecode::Util.constant_set? constant_set
|
19
108
|
raise TypeError, "Expected constant set, got #{constant_set.class}."
|
20
109
|
end
|
21
110
|
@params[:rhs] = constant_set
|
22
111
|
@params[:relation] = relation_name
|
23
|
-
@params.update Gecode::
|
112
|
+
@params.update Gecode::Set::Util.decode_options(options)
|
24
113
|
if relation_name == :==
|
25
114
|
@model.add_constraint Domain::EqualityDomainConstraint.new(@model,
|
26
115
|
@params)
|
@@ -32,78 +121,36 @@ module Gecode::Constraints::Set
|
|
32
121
|
|
33
122
|
# A module that gathers the classes and modules used in domain constraints.
|
34
123
|
module Domain #:nodoc:
|
35
|
-
|
36
|
-
# constant set.
|
37
|
-
#
|
38
|
-
# == Examples
|
39
|
-
#
|
40
|
-
# # +set+ must equal [1,2,5]
|
41
|
-
# set.must == [1,2,5]
|
42
|
-
#
|
43
|
-
# # +set+ must not equal 1..67
|
44
|
-
# set.must_not == 1..67
|
45
|
-
#
|
46
|
-
# # +set+ must equal the singleton set 0. The constraint is reified with
|
47
|
-
# # the boolean varaible +is_singleton_zero+.
|
48
|
-
# set.must.equal(0, :reify => is_singleton_zero)
|
49
|
-
class EqualityDomainConstraint < Gecode::Constraints::ReifiableConstraint
|
124
|
+
class EqualityDomainConstraint < Gecode::ReifiableConstraint #:nodoc:
|
50
125
|
def post
|
51
126
|
var, domain, reif_var, negate = @params.values_at(:lhs, :rhs, :reif,
|
52
127
|
:negate)
|
53
128
|
if negate
|
54
|
-
rel_type = Gecode::
|
129
|
+
rel_type = Gecode::Util::NEGATED_SET_RELATION_TYPES[:==]
|
55
130
|
else
|
56
|
-
rel_type = Gecode::
|
131
|
+
rel_type = Gecode::Util::SET_RELATION_TYPES[:==]
|
57
132
|
end
|
58
133
|
|
59
|
-
(params = []) << var.bind
|
134
|
+
(params = []) << var.to_set_var.bind
|
60
135
|
params << rel_type
|
61
|
-
params << Gecode::
|
62
|
-
params << reif_var.bind if reif_var.respond_to? :
|
136
|
+
params << Gecode::Util.constant_set_to_params(domain)
|
137
|
+
params << reif_var.to_bool_var.bind if reif_var.respond_to? :to_bool_var
|
63
138
|
Gecode::Raw::dom(@model.active_space, *params.flatten)
|
64
139
|
end
|
65
140
|
end
|
66
141
|
|
67
|
-
|
68
|
-
# relation to a constant set. A constant set may be specified in three ways
|
69
|
-
#
|
70
|
-
# [Fixnum] Represents a singleton set.
|
71
|
-
# [Range] Represents a set containing all elements in the
|
72
|
-
# range. This represents the set more efficiently
|
73
|
-
# than when another enumeration with the same
|
74
|
-
# elements are used.
|
75
|
-
# [Enumeration of Fixnum] Represents a set containing the enumeration’s
|
76
|
-
# elements.
|
77
|
-
#
|
78
|
-
# The relations allowed are the same as in
|
79
|
-
# <tt>Set::Relation::RelationConstraint</tt>.
|
80
|
-
#
|
81
|
-
# == Examples
|
82
|
-
#
|
83
|
-
# # +set+ must be subset of [1,2,5]
|
84
|
-
# set.must_be.subset_of [1,2,5]
|
85
|
-
#
|
86
|
-
# # +set+ must be disjoint with 1..67
|
87
|
-
# set.must_be.disjoint_with 1..67
|
88
|
-
#
|
89
|
-
# # +set+ must not be a superset of [0].
|
90
|
-
# set.must_not_be.superset_of 0
|
91
|
-
#
|
92
|
-
# # +set+ must be subset of [1,3,5,7]. The constraint is reified with
|
93
|
-
# # the boolean varaible +only_constains_odd_values+.
|
94
|
-
# set.must_be.subset_of([1.3.5.7], :reify => only_contains_odd_values)
|
95
|
-
class DomainConstraint < Gecode::Constraints::ReifiableConstraint
|
142
|
+
class DomainConstraint < Gecode::ReifiableConstraint #:nodoc:
|
96
143
|
def post
|
97
144
|
var, domain, reif_var, relation = @params.values_at(:lhs, :rhs, :reif,
|
98
145
|
:relation)
|
99
146
|
|
100
|
-
(params = []) << var.bind
|
101
|
-
params << Gecode::
|
102
|
-
params << Gecode::
|
103
|
-
params << reif_var.bind if reif_var.respond_to? :
|
147
|
+
(params = []) << var.to_set_var.bind
|
148
|
+
params << Gecode::Util::SET_RELATION_TYPES[relation]
|
149
|
+
params << Gecode::Util.constant_set_to_params(domain)
|
150
|
+
params << reif_var.to_bool_var.bind if reif_var.respond_to? :to_bool_var
|
104
151
|
Gecode::Raw::dom(@model.active_space, *params.flatten)
|
105
152
|
end
|
106
153
|
negate_using_reification
|
107
154
|
end
|
108
155
|
end
|
109
|
-
end
|
156
|
+
end
|