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,259 +1,251 @@
|
|
1
|
-
module Gecode
|
2
|
-
|
3
|
-
#
|
4
|
-
|
5
|
-
|
1
|
+
module Gecode::Bool
|
2
|
+
module BoolOperand
|
3
|
+
# Produces a new BoolOperand representing this operand OR +bool_op+.
|
4
|
+
#
|
5
|
+
# ==== Examples
|
6
|
+
#
|
7
|
+
# # +b1+ and +b2+
|
8
|
+
# b1 & b2
|
9
|
+
def |(bool_op)
|
10
|
+
bool_expression_operation(:|, bool_op)
|
6
11
|
end
|
7
12
|
|
8
|
-
#
|
9
|
-
|
10
|
-
|
13
|
+
# Produces a new BoolOperand representing this operand AND +bool_op+.
|
14
|
+
#
|
15
|
+
# ==== Examples
|
16
|
+
#
|
17
|
+
# # (+b1+ and +b2+) or +b3+
|
18
|
+
# (b1 & b1) | b3
|
19
|
+
def &(bool_op)
|
20
|
+
bool_expression_operation(:&, bool_op)
|
11
21
|
end
|
12
22
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
23
|
+
# Produces a new BoolOperand representing this operand XOR +bool_op+.
|
24
|
+
#
|
25
|
+
# ==== Examples
|
26
|
+
#
|
27
|
+
# # (+b1+ and +b2+) or (+b3+ exclusive or +b1+)
|
28
|
+
# (b1 & b2) | (b3 ^ b1)
|
29
|
+
def ^(bool_op)
|
30
|
+
bool_expression_operation(:^, bool_op)
|
16
31
|
end
|
17
32
|
|
18
|
-
#
|
19
|
-
|
20
|
-
|
33
|
+
# Produces a new BoolOperand representing that this operand implies
|
34
|
+
# +bool_op+.
|
35
|
+
#
|
36
|
+
# ==== Examples
|
37
|
+
#
|
38
|
+
# # (+b1+ implies +b2+) and (+b3+ implies +b2+)
|
39
|
+
# (b1.implies b2) & (b3.implies b2)
|
40
|
+
def implies(bool_op)
|
41
|
+
bool_expression_operation(:implies, bool_op)
|
21
42
|
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
return expression.must == @params[:lhs]
|
31
|
-
end
|
32
|
-
unless expression.respond_to? :to_minimodel_bool_expr
|
33
|
-
expression = Constraints::Bool::ExpressionNode.new(expression, @model)
|
34
|
-
end
|
35
|
-
@params.update Gecode::Constraints::Util.decode_options(options)
|
36
|
-
@params.update(:lhs => @params[:lhs], :rhs => expression)
|
37
|
-
@model.add_constraint BooleanConstraint.new(@model, @params)
|
38
|
-
end
|
39
|
-
alias_comparison_methods
|
40
|
-
|
41
|
-
# Constrains the boolean expression to imply the specified expression.
|
42
|
-
def imply(expression, options = {})
|
43
|
-
@params.update Gecode::Constraints::Util.decode_options(options)
|
44
|
-
@params.update(:lhs => @params[:lhs].implies(expression), :rhs => true)
|
45
|
-
@model.add_constraint BooleanConstraint.new(@model, @params)
|
46
|
-
end
|
47
|
-
|
48
|
-
# Constrains the boolean expression to be true.
|
49
|
-
def true(options = {})
|
50
|
-
@params.update Gecode::Constraints::Util.decode_options(options)
|
51
|
-
@model.add_constraint BooleanConstraint.new(@model,
|
52
|
-
@params.update(:rhs => true))
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Performs the bool expression operation +operator+ on self
|
47
|
+
# and +operand2+.
|
48
|
+
def bool_expression_operation(operator, operand2)
|
49
|
+
unless operand2.respond_to? :to_minimodel_bool_expr
|
50
|
+
operand2 = ExpressionNode.new operand2
|
53
51
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
@params[:negate] = !@params[:negate]
|
58
|
-
self.true
|
52
|
+
operand1 = self
|
53
|
+
unless operand1.respond_to? :to_minimodel_bool_expr
|
54
|
+
operand1 = ExpressionNode.new(self, @model)
|
59
55
|
end
|
56
|
+
ExpressionTree.new(operand1, operator, operand2)
|
60
57
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
#
|
65
|
-
#
|
66
|
-
# A boolean expression consists of several boolean variable with various
|
67
|
-
# boolean operators. The available operators are:
|
68
|
-
#
|
69
|
-
# [<tt>|</tt>] Or
|
70
|
-
# [<tt>&</tt>] And
|
71
|
-
# [<tt>^</tt>] Exclusive or
|
72
|
-
# [+implies+] Implication
|
58
|
+
end
|
59
|
+
|
60
|
+
class BoolConstraintReceiver
|
61
|
+
# Constrains the boolean operand to be equal to +bool_op+. Any of
|
62
|
+
# <tt>==</tt>, +equal+ and +equal_to+ may be used for equality.
|
73
63
|
#
|
74
|
-
#
|
64
|
+
# ==== Examples
|
75
65
|
#
|
76
|
-
# # +b1+ and +b2+
|
77
|
-
# b1 & b2
|
66
|
+
# # +b1+ and +b2+ must equal +b1+ or +b2+.
|
67
|
+
# (b1 & b2).must == (b1 | b2)
|
78
68
|
#
|
79
|
-
# #
|
80
|
-
#
|
69
|
+
# # +b1+ and +b2+ must not equal +b3+. We reify it with +bool+ and select
|
70
|
+
# # the strength +domain+.
|
71
|
+
# (b1 & b2).must_not.equal(b3, :reify => bool, :select => :domain)
|
72
|
+
def ==(bool_op, options = {})
|
73
|
+
unless bool_op.respond_to? :to_minimodel_bool_expr
|
74
|
+
bool_op = ExpressionNode.new(bool_op, @model)
|
75
|
+
end
|
76
|
+
@params.update Gecode::Util.decode_options(options)
|
77
|
+
@params.update(:lhs => @params[:lhs], :rhs => bool_op)
|
78
|
+
@model.add_constraint BooleanConstraint.new(@model, @params)
|
79
|
+
end
|
80
|
+
alias_comparison_methods
|
81
|
+
|
82
|
+
# Constrains the boolean operand to imply +bool_op+.
|
81
83
|
#
|
82
|
-
#
|
83
|
-
# (b1 & b2) | (b3 ^ b1)
|
84
|
+
# ==== Examples
|
84
85
|
#
|
85
|
-
# #
|
86
|
-
#
|
86
|
+
# # +b1+ must imply +b2+
|
87
|
+
# b1.must.imply b2
|
87
88
|
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
|
89
|
+
# # +b1+ and +b2+ must not imply +b3+. We reify it with +bool+ and select
|
90
|
+
# # +domain+ as strength.
|
91
|
+
# (b1 & b2).must_not.imply(b3, :reify => bool, :strength => :domain)
|
92
|
+
def imply(bool_op, options = {})
|
93
|
+
@params.update Gecode::Util.decode_options(options)
|
94
|
+
@params.update(:lhs => @params[:lhs].implies(bool_op), :rhs => true)
|
95
|
+
@model.add_constraint BooleanConstraint.new(@model, @params)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Constrains the boolean operand to be true.
|
92
99
|
#
|
93
|
-
#
|
100
|
+
# ==== Examples
|
94
101
|
#
|
95
102
|
# # +b1+ and +b2+ must be true.
|
96
103
|
# (b1 & b2).must_be.true
|
97
104
|
#
|
98
|
-
# # (+b1+ implies +b2+) and (+b3+ implies +b2+) must be
|
99
|
-
# ((b1.implies b2) & (b3.implies b2)).must_be.
|
105
|
+
# # (+b1+ implies +b2+) and (+b3+ implies +b2+) must be true.
|
106
|
+
# ((b1.implies b2) & (b3.implies b2)).must_be.true
|
100
107
|
#
|
101
108
|
# # +b1+ and +b2+ must be true. We reify it with +bool+ and select the
|
102
109
|
# # strength +domain+.
|
103
110
|
# (b1 & b2).must_be.true(:reify => bool, :strength => :domain)
|
111
|
+
def true(options = {})
|
112
|
+
@params.update Gecode::Util.decode_options(options)
|
113
|
+
@model.add_constraint BooleanConstraint.new(@model,
|
114
|
+
@params.update(:rhs => true))
|
115
|
+
end
|
116
|
+
|
117
|
+
# Constrains the boolean operand to be false.
|
118
|
+
#
|
119
|
+
# ==== Examples
|
104
120
|
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
# A constraint with equality specifies that two boolean expressions must be
|
108
|
-
# equal. Negation and reification are supported. Any of <tt>==</tt>,
|
109
|
-
# +equal+ and +equal_to+ may be used for equality.
|
110
|
-
#
|
111
|
-
# === Examples
|
112
|
-
#
|
113
|
-
# # +b1+ and +b2+ must equal +b1+ or +b2+.
|
114
|
-
# (b1 & b2).must == (b1 | b2)
|
115
|
-
#
|
116
|
-
# # +b1+ and +b2+ must not equal +b3+. We reify it with +bool+ and select
|
117
|
-
# # the strength +domain+.
|
118
|
-
# (b1 & b2).must_not.equal(b3, :reify => bool, :select => :domain)
|
121
|
+
# # +b1+ and +b2+ must be false.
|
122
|
+
# (b1 & b2).must_be.false
|
119
123
|
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
# A constraint using +imply+ specified that one boolean expression must
|
123
|
-
# imply the other. Negation and reification are supported.
|
124
|
+
# # (+b1+ implies +b2+) and (+b3+ implies +b2+) must be false.
|
125
|
+
# ((b1.implies b2) & (b3.implies b2)).must_be.false
|
124
126
|
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
127
|
+
# # +b1+ and +b2+ must be false. We reify it with +bool+ and select the
|
128
|
+
# # strength +domain+.
|
129
|
+
# (b1 & b2).must_be.false(:reify => bool, :strength => :domain)
|
130
|
+
def false(options = {})
|
131
|
+
@params[:negate] = !@params[:negate]
|
132
|
+
self.true(options)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class BooleanConstraint < Gecode::ReifiableConstraint #:nodoc:
|
137
|
+
def post
|
138
|
+
lhs, rhs, negate, reif_var =
|
139
|
+
@params.values_at(:lhs, :rhs, :negate, :reif)
|
138
140
|
|
139
|
-
|
140
|
-
|
141
|
-
|
141
|
+
if lhs.respond_to? :to_bool_var
|
142
|
+
lhs = ExpressionNode.new(lhs, @model)
|
143
|
+
end
|
144
|
+
space = (lhs.model || rhs.model).active_space
|
142
145
|
|
143
|
-
|
144
|
-
|
146
|
+
bot_eqv = Gecode::Raw::IRT_EQ
|
147
|
+
bot_xor = Gecode::Raw::IRT_NQ
|
145
148
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
149
|
+
if rhs.respond_to? :to_minimodel_bool_expr
|
150
|
+
if reif_var.nil?
|
151
|
+
tree = ExpressionTree.new(lhs, :==, rhs)
|
152
|
+
tree.to_minimodel_bool_expr.post(space, !negate,
|
153
|
+
*propagation_options)
|
154
|
+
else
|
155
|
+
tree = ExpressionTree.new(lhs, :==, rhs)
|
156
|
+
var = tree.to_minimodel_bool_expr.post(space, *propagation_options)
|
157
|
+
Gecode::Raw::rel(space, var, (negate ? bot_xor : bot_eqv),
|
158
|
+
reif_var.to_bool_var.bind, *propagation_options)
|
159
|
+
end
|
160
|
+
else
|
161
|
+
should_hold = !negate & rhs
|
162
|
+
if reif_var.nil?
|
163
|
+
lhs.to_minimodel_bool_expr.post(space, should_hold,
|
164
|
+
*propagation_options)
|
159
165
|
else
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
else
|
165
|
-
var = lhs.to_minimodel_bool_expr.post(space, *propagation_options)
|
166
|
-
Gecode::Raw::rel(space, var,
|
167
|
-
(should_hold ? bot_eqv : bot_xor),
|
168
|
-
reif_var.bind, *propagation_options)
|
169
|
-
end
|
166
|
+
var = lhs.to_minimodel_bool_expr.post(space, *propagation_options)
|
167
|
+
Gecode::Raw::rel(space, var,
|
168
|
+
(should_hold ? bot_eqv : bot_xor),
|
169
|
+
reif_var.to_bool_var.bind, *propagation_options)
|
170
170
|
end
|
171
171
|
end
|
172
172
|
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Describes a binary tree of expression nodes which together form a boolean
|
176
|
+
# expression.
|
177
|
+
class ExpressionTree #:nodoc:
|
178
|
+
include BoolOperand
|
179
|
+
|
180
|
+
private
|
173
181
|
|
174
|
-
#
|
175
|
-
#
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
182
|
+
# Maps the names of the methods to the corresponding bool constraint in
|
183
|
+
# Gecode.
|
184
|
+
OPERATION_TYPES = {
|
185
|
+
:| => Gecode::Raw::MiniModel::BoolExpr::NT_OR,
|
186
|
+
:& => Gecode::Raw::MiniModel::BoolExpr::NT_AND,
|
187
|
+
:^ => Gecode::Raw::MiniModel::BoolExpr::NT_XOR,
|
188
|
+
:implies => Gecode::Raw::MiniModel::BoolExpr::NT_IMP,
|
189
|
+
:== => Gecode::Raw::MiniModel::BoolExpr::NT_EQV
|
190
|
+
}
|
191
|
+
|
192
|
+
public
|
193
|
+
|
194
|
+
# Constructs a new expression with the specified binary operation
|
195
|
+
# applied to the specified trees.
|
196
|
+
def initialize(left_tree, operation, right_tree)
|
197
|
+
@left = left_tree
|
198
|
+
@operation = operation
|
199
|
+
@right = right_tree
|
200
|
+
end
|
180
201
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
:^ => Gecode::Raw::MiniModel::BoolExpr::NT_XOR,
|
187
|
-
:implies => Gecode::Raw::MiniModel::BoolExpr::NT_IMP
|
188
|
-
}
|
189
|
-
|
190
|
-
public
|
191
|
-
|
192
|
-
OPERATION_TYPES.each_pair do |name, operation|
|
193
|
-
module_eval <<-"end_code"
|
194
|
-
def #{name}(expression)
|
195
|
-
unless expression.kind_of? ExpressionTree
|
196
|
-
expression = ExpressionNode.new(expression)
|
197
|
-
end
|
198
|
-
ExpressionTree.new(self, #{operation}, expression)
|
199
|
-
end
|
200
|
-
end_code
|
201
|
-
end
|
202
|
-
|
203
|
-
private
|
204
|
-
|
205
|
-
# Produces an expression for the lhs module.
|
206
|
-
def expression(params)
|
207
|
-
params.update(:lhs => self)
|
208
|
-
Gecode::Constraints::Bool::Expression.new(model, params)
|
209
|
-
end
|
202
|
+
# Returns a MiniModel boolean expression representing the tree.
|
203
|
+
def to_minimodel_bool_expr
|
204
|
+
Gecode::Raw::MiniModel::BoolExpr.new(
|
205
|
+
@left.to_minimodel_bool_expr, OPERATION_TYPES[@operation],
|
206
|
+
@right.to_minimodel_bool_expr)
|
210
207
|
end
|
211
|
-
|
212
|
-
# Describes a binary tree of expression nodes which together form a boolean
|
213
|
-
# expression.
|
214
|
-
class ExpressionTree #:nodoc:
|
215
|
-
include OperationMethods
|
216
208
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
@left.to_minimodel_bool_expr, @operation,
|
229
|
-
@right.to_minimodel_bool_expr)
|
230
|
-
end
|
231
|
-
|
232
|
-
# Fetches the space that the expression's variables is in.
|
233
|
-
def model
|
234
|
-
@left.model || @right.model
|
209
|
+
# Fetches the space that the expression's variables is in.
|
210
|
+
def model
|
211
|
+
@left.model || @right.model
|
212
|
+
end
|
213
|
+
|
214
|
+
def to_bool_var
|
215
|
+
bool_var = model.bool_var
|
216
|
+
tree = ExpressionTree.new(self, :==, ExpressionNode.new(bool_var))
|
217
|
+
model.add_interaction do
|
218
|
+
tree.to_minimodel_bool_expr.post(model.active_space, true,
|
219
|
+
Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF)
|
235
220
|
end
|
221
|
+
return bool_var
|
236
222
|
end
|
237
|
-
|
238
|
-
# Describes a single node in a boolean expression.
|
239
|
-
class ExpressionNode #:nodoc:
|
240
|
-
include OperationMethods
|
241
|
-
|
242
|
-
attr :model
|
243
223
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
224
|
+
private
|
225
|
+
|
226
|
+
# Produces a receiver (for the BoolOperand module).
|
227
|
+
def construct_receiver(params)
|
228
|
+
params.update(:lhs => self)
|
229
|
+
BoolConstraintReceiver.new(model, params)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# Describes a single node in a boolean expression.
|
234
|
+
class ExpressionNode #:nodoc:
|
235
|
+
attr :model
|
236
|
+
|
237
|
+
def initialize(value, model = nil)
|
238
|
+
unless value.respond_to? :to_bool_var
|
239
|
+
raise TypeError, 'Invalid type used in boolean equation: ' +
|
240
|
+
"#{value.class}."
|
256
241
|
end
|
242
|
+
@value = value
|
243
|
+
@model = model
|
244
|
+
end
|
245
|
+
|
246
|
+
# Returns a MiniModel boolean expression representing the tree.
|
247
|
+
def to_minimodel_bool_expr
|
248
|
+
Gecode::Raw::MiniModel::BoolExpr.new(@value.to_bool_var.bind)
|
257
249
|
end
|
258
250
|
end
|
259
251
|
end
|