gecoder 0.8.3 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,7 @@
|
|
1
|
-
module Gecode::
|
2
|
-
class
|
3
|
-
#
|
4
|
-
|
5
|
-
provide_commutivity(:==){ |rhs, _| rhs.kind_of?(Gecode::FreeIntVar) }
|
1
|
+
module Gecode::Bool
|
2
|
+
class BoolConstraintReceiver
|
3
|
+
# Provides commutivity with IntVarReceiver#==
|
4
|
+
provide_commutativity(:==){ |rhs, _| rhs.respond_to? :to_int_var }
|
6
5
|
alias_comparison_methods
|
7
6
|
end
|
8
7
|
end
|
@@ -1,29 +1,200 @@
|
|
1
|
-
module Gecode
|
2
|
-
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Gecode::Bool
|
2
|
+
module BoolLinearOperations #:nodoc:
|
3
|
+
# Produces an IntOperand representing the value of this boolean
|
4
|
+
# operand (0 or 1) plus +op2+.
|
5
|
+
#
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# # +bool1+ plus +bool2+
|
9
|
+
# bool1 + bool2
|
10
|
+
def +(op2)
|
11
|
+
bool_linear_expression_operation(:+, op2)
|
7
12
|
end
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
#
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
# Produces an IntOperand representing the value of this boolean
|
15
|
+
# operand (0 or 1) times a constant.
|
16
|
+
#
|
17
|
+
# ==== Examples
|
18
|
+
#
|
19
|
+
# # +bool+ times 17
|
20
|
+
# bool * 17
|
21
|
+
def *(fixnum)
|
22
|
+
if fixnum.kind_of? Fixnum
|
23
|
+
bool_linear_expression_operation(:*, fixnum)
|
17
24
|
else
|
18
|
-
|
25
|
+
raise TypeError, "Expected fixnum, got #{fixnum.class}."
|
19
26
|
end
|
20
27
|
end
|
21
28
|
|
22
|
-
#
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
# Produces an IntOperand representing the value of this boolean
|
30
|
+
# operand (0 or 1) minus +op2+.
|
31
|
+
#
|
32
|
+
# ==== Examples
|
33
|
+
#
|
34
|
+
# # +bool1+ minus +bool2+
|
35
|
+
# bool1 - bool2
|
36
|
+
def -(op2)
|
37
|
+
bool_linear_expression_operation(:-, op2)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Performs the bool linear expression operation +operator+ on self
|
43
|
+
# and +operand2+.
|
44
|
+
def bool_linear_expression_operation(operator, operand2)
|
45
|
+
linear_module = Linear
|
46
|
+
unless operand2.respond_to? :to_minimodel_lin_exp
|
47
|
+
operand2 = linear_module::ExpressionNode.new operand2
|
48
|
+
end
|
49
|
+
operand1 = self
|
50
|
+
unless operand1.respond_to? :to_minimodel_lin_exp
|
51
|
+
operand1 = linear_module::ExpressionNode.new(self, @model)
|
52
|
+
end
|
53
|
+
linear_module::ExpressionTree.new(operand1, operand2, operator)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module BoolOperand
|
58
|
+
# We include the operations and then redefine them so that they show
|
59
|
+
# up in the documentation.
|
60
|
+
include BoolLinearOperations
|
61
|
+
|
62
|
+
# Produces an IntOperand representing the value of this boolean
|
63
|
+
# operand (0 or 1) plus +op2+.
|
64
|
+
#
|
65
|
+
# ==== Examples
|
66
|
+
#
|
67
|
+
# # +bool1+ plus +bool2+
|
68
|
+
# bool1 + bool2
|
69
|
+
def +(op2)
|
70
|
+
bool_linear_expression_operation(:+, op2)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Produces an IntOperand representing the value of this boolean
|
74
|
+
# operand (0 or 1) times a constant.
|
75
|
+
#
|
76
|
+
# ==== Examples
|
77
|
+
#
|
78
|
+
# # +bool+ times 17
|
79
|
+
# bool * 17
|
80
|
+
def *(fixnum)
|
81
|
+
if fixnum.kind_of? Fixnum
|
82
|
+
bool_linear_expression_operation(:*, fixnum)
|
83
|
+
else
|
84
|
+
raise TypeError, "Expected fixnum, got #{fixnum.class}."
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Produces an IntOperand representing the value of this boolean
|
89
|
+
# operand (0 or 1) minus +op2+.
|
90
|
+
#
|
91
|
+
# ==== Examples
|
92
|
+
#
|
93
|
+
# # +bool1+ minus +bool2+
|
94
|
+
# bool1 - bool2
|
95
|
+
def -(op2)
|
96
|
+
bool_linear_expression_operation(:-, op2)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# A module that gathers the classes and modules used in linear constraints.
|
101
|
+
module Linear #:nodoc:
|
102
|
+
class LinearRelationConstraint < Gecode::ReifiableConstraint #:nodoc:
|
103
|
+
def post
|
104
|
+
lhs, rhs, relation_type, reif_var =
|
105
|
+
@params.values_at(:lhs, :rhs, :relation_type, :reif)
|
106
|
+
reif_var = reif_var.to_bool_var.bind if reif_var.respond_to? :to_bool_var
|
107
|
+
final_exp = (lhs.to_minimodel_lin_exp - rhs.to_minimodel_lin_exp)
|
108
|
+
if reif_var.nil?
|
109
|
+
final_exp.post(@model.active_space, relation_type,
|
110
|
+
*propagation_options)
|
111
|
+
else
|
112
|
+
final_exp.post(@model.active_space, relation_type, reif_var,
|
113
|
+
*propagation_options)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Describes a binary tree of expression nodes which together form a linear
|
119
|
+
# expression.
|
120
|
+
class ExpressionTree < Gecode::Int::ShortCircuitRelationsOperand #:nodoc:
|
121
|
+
include Gecode::Bool::BoolLinearOperations
|
122
|
+
attr :model
|
123
|
+
|
124
|
+
# Constructs a new expression with the specified operands.
|
125
|
+
def initialize(left_node, right_node, operation)
|
126
|
+
super(left_node.model || right_node.model)
|
127
|
+
@left = left_node
|
128
|
+
@right = right_node
|
129
|
+
@operation = operation
|
130
|
+
@model = @left.model || @right.model
|
131
|
+
end
|
132
|
+
|
133
|
+
# Converts the linear expression to an instance of
|
134
|
+
# Gecode::Raw::MiniModel::LinExpr
|
135
|
+
def to_minimodel_lin_exp
|
136
|
+
@left.to_minimodel_lin_exp.send(@operation, @right.to_minimodel_lin_exp)
|
137
|
+
end
|
138
|
+
|
139
|
+
alias_method :pre_bool_construct_receiver, :construct_receiver
|
140
|
+
def construct_receiver(params)
|
141
|
+
receiver = pre_bool_construct_receiver(params)
|
142
|
+
lhs = self
|
143
|
+
receiver.instance_eval{ @lhs = lhs }
|
144
|
+
class <<receiver
|
145
|
+
alias_method :pre_bool_equality, :==
|
146
|
+
def ==(op, options = {})
|
147
|
+
if op.respond_to? :to_bool_var
|
148
|
+
(@lhs - op).must.equal(0, options)
|
149
|
+
else
|
150
|
+
pre_bool_equality(op, options)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
alias_comparison_methods
|
154
|
+
end
|
155
|
+
return receiver
|
156
|
+
end
|
157
|
+
|
158
|
+
def relation_constraint(relation, bool_operand_or_fix, params)
|
159
|
+
unless params[:negate]
|
160
|
+
relation_type =
|
161
|
+
Gecode::Util::RELATION_TYPES[relation]
|
162
|
+
else
|
163
|
+
relation_type =
|
164
|
+
Gecode::Util::NEGATED_RELATION_TYPES[relation]
|
165
|
+
end
|
166
|
+
|
167
|
+
unless bool_operand_or_fix.respond_to? :to_minimodel_lin_exp
|
168
|
+
bool_operand_or_fix = Linear::ExpressionNode.new(bool_operand_or_fix);
|
169
|
+
end
|
170
|
+
|
171
|
+
params.update(:rhs => bool_operand_or_fix, :relation_type => relation_type)
|
172
|
+
LinearRelationConstraint.new(model, params)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Describes a single node in a linear expression.
|
177
|
+
class ExpressionNode #:nodoc:
|
178
|
+
attr :model
|
179
|
+
|
180
|
+
def initialize(value, model = nil)
|
181
|
+
unless value.respond_to?(:to_bool_var) or value.kind_of?(Fixnum)
|
182
|
+
raise TypeError, 'Expected bool operand or ' +
|
183
|
+
"fixnum, got #{value.class}."
|
184
|
+
end
|
185
|
+
@value = value
|
186
|
+
@model = model
|
187
|
+
end
|
188
|
+
|
189
|
+
# Converts the linear expression to an instance of
|
190
|
+
# Gecode::Raw::MiniModel::LinExpr
|
191
|
+
def to_minimodel_lin_exp
|
192
|
+
expression = @value
|
193
|
+
if expression.respond_to? :to_bool_var
|
194
|
+
expression = expression.to_bool_var.bind * 1
|
195
|
+
end
|
196
|
+
expression
|
197
|
+
end
|
27
198
|
end
|
28
199
|
end
|
29
|
-
end
|
200
|
+
end
|
@@ -1,14 +1,35 @@
|
|
1
|
-
module Gecode::
|
2
|
-
class
|
3
|
-
#
|
4
|
-
# integer
|
1
|
+
module Gecode::BoolEnum
|
2
|
+
class BoolEnumConstraintReceiver
|
3
|
+
# Constrains this enumeration to "channel" +integer_operand+. This
|
4
|
+
# constrains the integer operand to take value i exactly when the
|
5
|
+
# operand at index i in the boolean enumeration is true and the others
|
6
|
+
# are false.
|
7
|
+
#
|
8
|
+
# Beyond the common options the channel constraint can
|
5
9
|
# also take the following option:
|
6
10
|
#
|
7
|
-
# [:offset] Specifies an offset for the integer
|
8
|
-
# set to k then the integer
|
9
|
-
# when the
|
10
|
-
# and the rest are false.
|
11
|
-
|
11
|
+
# [:offset] Specifies an offset for the integer operand. If the offset is
|
12
|
+
# set to k then the integer operand takes value i+k exactly
|
13
|
+
# when the operand at index i in the boolean enumeration is
|
14
|
+
# true and the rest are false.
|
15
|
+
#
|
16
|
+
# Neither reification nor negation is supported. The int operand
|
17
|
+
# and the enumeration can be interchanged.
|
18
|
+
#
|
19
|
+
# ==== Examples
|
20
|
+
#
|
21
|
+
# # Constrains the enumeration called +option_is_selected+ to be false
|
22
|
+
# # in the first four positions and have exactly one true operand in
|
23
|
+
# # the other.
|
24
|
+
# option_is_selected.must.channel selected_option_index
|
25
|
+
# selected_option_index.must_be > 3
|
26
|
+
#
|
27
|
+
# # Constrains the enumeration called +option_is_selected+ to be false
|
28
|
+
# # in the first five positions and have exactly one true operand in
|
29
|
+
# # the other.
|
30
|
+
# selected_option_index.must.channel(option_is_selected, :offset => 1)
|
31
|
+
# selected_option_index.must_be > 3
|
32
|
+
def channel(integer_operand, options = {})
|
12
33
|
if @params[:negate]
|
13
34
|
raise Gecode::MissingConstraintError, 'A negated channel constraint ' +
|
14
35
|
'is not implemented.'
|
@@ -17,47 +38,30 @@ module Gecode::Constraints::BoolEnum
|
|
17
38
|
raise ArgumentError, 'The channel constraint does not support the ' +
|
18
39
|
'reification option.'
|
19
40
|
end
|
20
|
-
unless
|
21
|
-
raise TypeError,
|
41
|
+
unless integer_operand.respond_to? :to_int_var
|
42
|
+
raise TypeError, 'Expected an integer operand, got ' +
|
43
|
+
"#{integer_operand.class}."
|
22
44
|
end
|
23
45
|
|
24
|
-
@params.update(:rhs =>
|
25
|
-
|
46
|
+
@params.update(:rhs => integer_operand,
|
47
|
+
:offset => options.delete(:offset) || 0)
|
48
|
+
@params.update(Gecode::Util.decode_options(options))
|
26
49
|
@model.add_constraint Channel::ChannelConstraint.new(@model, @params)
|
27
50
|
end
|
28
51
|
|
29
|
-
#
|
30
|
-
|
31
|
-
provide_commutivity(:channel){ |rhs, _| rhs.kind_of? Gecode::FreeSetVar }
|
52
|
+
# Provides commutativity with SetConstraintReceiver#channel
|
53
|
+
provide_commutativity(:channel){ |rhs, _| rhs.respond_to? :to_set_var }
|
32
54
|
end
|
33
55
|
|
34
56
|
# A module that gathers the classes and modules used in channel constraints
|
35
|
-
# involving one boolean enum and one integer
|
57
|
+
# involving one boolean enum and one integer operand.
|
36
58
|
module Channel #:nodoc:
|
37
|
-
|
38
|
-
# boolean variables with an integer variable. This constrains the integer
|
39
|
-
# variable to take value i exactly when the variable at index i in the
|
40
|
-
# boolean enumeration is true and the others are false.
|
41
|
-
#
|
42
|
-
# Neither reification nor negation is supported. The int variable
|
43
|
-
# and the enumeration can be interchanged.
|
44
|
-
#
|
45
|
-
# == Examples
|
46
|
-
#
|
47
|
-
# # Constrains the enumeration called +option_is_selected+ to be false in the
|
48
|
-
# # first four positions and have exactly one true variable in the other.
|
49
|
-
# option_is_selected.must.channel selected_option_index
|
50
|
-
# selected_option_index.must_be > 3
|
51
|
-
#
|
52
|
-
# # Constrains the enumeration called +option_is_selected+ to be false in the
|
53
|
-
# # first five positions and have exactly one true variable in the other.
|
54
|
-
# selected_option_index.must.channel(option_is_selected, :offset => 1)
|
55
|
-
# selected_option_index.must_be > 3
|
56
|
-
class ChannelConstraint < Gecode::Constraints::Constraint
|
59
|
+
class ChannelConstraint < Gecode::Constraint #:nodoc:
|
57
60
|
def post
|
58
61
|
lhs, rhs, offset = @params.values_at(:lhs, :rhs, :offset)
|
59
|
-
Gecode::Raw::channel(@model.active_space,
|
60
|
-
rhs.bind,
|
62
|
+
Gecode::Raw::channel(@model.active_space,
|
63
|
+
lhs.to_bool_enum.bind_array, rhs.to_int_var.bind,
|
64
|
+
offset, *propagation_options)
|
61
65
|
end
|
62
66
|
end
|
63
67
|
end
|
@@ -1,6 +1,18 @@
|
|
1
|
-
module Gecode::
|
2
|
-
class
|
3
|
-
#
|
1
|
+
module Gecode::BoolEnum
|
2
|
+
class BoolEnumConstraintReceiver
|
3
|
+
# Constrains all the operands in this enumeration to be equal to
|
4
|
+
# one of the specified tuples. Neither negation nor reification is
|
5
|
+
# supported.
|
6
|
+
#
|
7
|
+
# ==== Examples
|
8
|
+
#
|
9
|
+
# # Constrains the three boolean operands in +bools+ to either
|
10
|
+
# # be true, false, true, or false, false, true.
|
11
|
+
# bools.must_be.in [[true, false, true], [false, false, true]]
|
12
|
+
#
|
13
|
+
# # The same as above, but preferring speed over low memory usage.
|
14
|
+
# bools.must_be.in([[true, false, true], [false, false, true]],
|
15
|
+
# :kind => :speed)
|
4
16
|
def in(tuples, options = {})
|
5
17
|
if @params[:negate]
|
6
18
|
raise Gecode::MissingConstraintError, 'A negated tuple constraint is ' +
|
@@ -11,7 +23,7 @@ module Gecode::Constraints::BoolEnum
|
|
11
23
|
'constraint.'
|
12
24
|
end
|
13
25
|
|
14
|
-
util = Gecode::
|
26
|
+
util = Gecode::Util
|
15
27
|
|
16
28
|
# Check that the tuples are correct.
|
17
29
|
expected_size = @params[:lhs].size
|
@@ -23,14 +35,28 @@ module Gecode::Constraints::BoolEnum
|
|
23
35
|
|
24
36
|
@params[:tuples] = tuples
|
25
37
|
@model.add_constraint Extensional::TupleConstraint.new(@model,
|
26
|
-
@params.update(Gecode::
|
38
|
+
@params.update(Gecode::Util.decode_options(options)))
|
27
39
|
end
|
28
40
|
|
29
|
-
#
|
30
|
-
# specified
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
41
|
+
# Constrains the sequence of operands in this enumeration to match
|
42
|
+
# a specified regexp in the boolean domain. Neither negation nor
|
43
|
+
# reification is supported.
|
44
|
+
#
|
45
|
+
# The regular expressions are specified as described in
|
46
|
+
# IntEnumConstraintReceiver#match but true and false can be
|
47
|
+
# used instead of integers.
|
48
|
+
#
|
49
|
+
# ==== Examples
|
50
|
+
#
|
51
|
+
# # Constrains the two boolean operands in +bools+ to be false
|
52
|
+
# # and true respectively.
|
53
|
+
# bools.must.match [false, true]
|
54
|
+
#
|
55
|
+
# # Constrains the boolean operands in +bools+ to be false,
|
56
|
+
# # except for three consecutive operands which should be true
|
57
|
+
# # followed by false followed by true.
|
58
|
+
# bools.must.match [repeat(false), true, false, true, repeat(false)]]
|
59
|
+
#
|
34
60
|
def match(regexp, options = {})
|
35
61
|
if @params[:negate]
|
36
62
|
raise Gecode::MissingConstraintError, 'A negated regexp constraint ' +
|
@@ -42,8 +68,8 @@ module Gecode::Constraints::BoolEnum
|
|
42
68
|
end
|
43
69
|
|
44
70
|
@params[:regexp] =
|
45
|
-
Gecode::
|
46
|
-
@params.update Gecode::
|
71
|
+
Gecode::Util::Extensional.parse_regexp regexp
|
72
|
+
@params.update Gecode::Util.decode_options(options)
|
47
73
|
@model.add_constraint Extensional::RegexpConstraint.new(@model, @params)
|
48
74
|
end
|
49
75
|
end
|
@@ -51,23 +77,10 @@ module Gecode::Constraints::BoolEnum
|
|
51
77
|
# A module that gathers the classes and modules used in extensional
|
52
78
|
# constraints.
|
53
79
|
module Extensional #:nodoc:
|
54
|
-
|
55
|
-
# boolean enumeration to be equal to one of the specified tuples. Neither
|
56
|
-
# negation nor reification is supported.
|
57
|
-
#
|
58
|
-
# == Example
|
59
|
-
#
|
60
|
-
# # Constrains the three boolean variables in +bools+ to either
|
61
|
-
# # be true, false, true, or false, false, true.
|
62
|
-
# bools.must_be.in [[true, false, true], [false, false, true]]
|
63
|
-
#
|
64
|
-
# # The same as above, but preferring speed over low memory usage.
|
65
|
-
# bools.must_be.in([[true, false, true], [false, false, true]],
|
66
|
-
# :kind => :speed)
|
67
|
-
class TupleConstraint < Gecode::Constraints::Constraint
|
80
|
+
class TupleConstraint < Gecode::Constraint #:nodoc:
|
68
81
|
def post
|
69
82
|
# Bind lhs.
|
70
|
-
lhs = @params[:lhs].
|
83
|
+
lhs = @params[:lhs].to_bool_enum.bind_array
|
71
84
|
|
72
85
|
# Create the tuple set.
|
73
86
|
tuple_set = Gecode::Raw::TupleSet.new
|
@@ -82,30 +95,11 @@ module Gecode::Constraints::BoolEnum
|
|
82
95
|
end
|
83
96
|
end
|
84
97
|
|
85
|
-
|
86
|
-
# boolean variables to match a specified regexp in the boolean
|
87
|
-
# domain. Neither negation nor reification is supported.
|
88
|
-
#
|
89
|
-
# The regular expressions are specified as described in
|
90
|
-
# IntEnum::Extensional::RegexpConstraint but true and false can be
|
91
|
-
# used instead of integers.
|
92
|
-
#
|
93
|
-
# == Example
|
94
|
-
#
|
95
|
-
# # Constrains the two boolean variables in +bools+ to be false
|
96
|
-
# # and true respectively.
|
97
|
-
# bools.must.match [false, true]
|
98
|
-
#
|
99
|
-
# # Constrains the boolean variables in +bools+ to be false,
|
100
|
-
# # except for three consecutive variables which should be true
|
101
|
-
# # followed by false followed by true.
|
102
|
-
# bools.must.match [repeat(false), true, false, true, repeat(false)]]
|
103
|
-
#
|
104
|
-
class RegexpConstraint < Gecode::Constraints::Constraint
|
98
|
+
class RegexpConstraint < Gecode::Constraint #:nodoc:
|
105
99
|
def post
|
106
100
|
lhs, regexp = @params.values_at(:lhs, :regexp)
|
107
|
-
Gecode::Raw::extensional(@model.active_space,
|
108
|
-
regexp, *propagation_options)
|
101
|
+
Gecode::Raw::extensional(@model.active_space,
|
102
|
+
lhs.to_bool_enum.bind_array, regexp, *propagation_options)
|
109
103
|
end
|
110
104
|
end
|
111
105
|
end
|