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.
Files changed (142) hide show
  1. data/CHANGES +15 -0
  2. data/README +6 -2
  3. data/example/equation_system.rb +15 -0
  4. data/example/magic_sequence.rb +7 -7
  5. data/example/money.rb +36 -0
  6. data/example/queens.rb +7 -8
  7. data/example/send_most_money.rb +1 -1
  8. data/example/square_tiling.rb +2 -2
  9. data/example/sudoku-set.rb +11 -12
  10. data/example/sudoku.rb +40 -45
  11. data/ext/extconf.rb +0 -0
  12. data/lib/gecoder/bindings.rb +42 -0
  13. data/lib/gecoder/bindings/bindings.rb +16 -0
  14. data/lib/gecoder/interface.rb +2 -1
  15. data/lib/gecoder/interface/branch.rb +16 -9
  16. data/lib/gecoder/interface/constraints.rb +410 -451
  17. data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
  18. data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
  19. data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
  20. data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
  21. data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
  22. data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
  23. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
  24. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
  25. data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
  26. data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
  27. data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
  28. data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
  29. data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
  30. data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
  31. data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
  32. data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
  33. data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
  34. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
  35. data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
  36. data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
  37. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
  38. data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
  39. data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
  40. data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
  41. data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
  42. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
  43. data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
  44. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
  45. data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
  46. data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
  47. data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
  48. data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
  49. data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
  50. data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
  51. data/lib/gecoder/interface/constraints/set/include.rb +36 -0
  52. data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
  53. data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
  54. data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
  55. data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
  56. data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
  57. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
  58. data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
  59. data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
  60. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
  61. data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
  62. data/lib/gecoder/interface/enum_matrix.rb +4 -4
  63. data/lib/gecoder/interface/enum_wrapper.rb +71 -22
  64. data/lib/gecoder/interface/model.rb +167 -12
  65. data/lib/gecoder/interface/model_sugar.rb +84 -0
  66. data/lib/gecoder/interface/search.rb +30 -18
  67. data/lib/gecoder/interface/variables.rb +103 -33
  68. data/lib/gecoder/version.rb +2 -2
  69. data/specs/bool_var.rb +19 -12
  70. data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
  71. data/specs/constraints/bool/boolean_properties.rb +51 -0
  72. data/specs/constraints/bool/linear.rb +213 -0
  73. data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
  74. data/specs/constraints/bool_enum/channel.rb +102 -0
  75. data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
  76. data/specs/constraints/constraint_helper.rb +149 -179
  77. data/specs/constraints/constraint_receivers.rb +103 -0
  78. data/specs/constraints/constraints.rb +6 -63
  79. data/specs/constraints/fixnum_enum/element.rb +58 -0
  80. data/specs/constraints/fixnum_enum/operation.rb +67 -0
  81. data/specs/constraints/int/arithmetic.rb +149 -0
  82. data/specs/constraints/int/channel.rb +101 -0
  83. data/specs/constraints/int/domain.rb +106 -0
  84. data/specs/constraints/int/linear.rb +183 -0
  85. data/specs/constraints/int/linear_properties.rb +97 -0
  86. data/specs/constraints/int/relation.rb +84 -0
  87. data/specs/constraints/int_enum/arithmetic.rb +72 -0
  88. data/specs/constraints/int_enum/channel.rb +57 -0
  89. data/specs/constraints/int_enum/count.rb +72 -0
  90. data/specs/constraints/int_enum/distinct.rb +80 -0
  91. data/specs/constraints/int_enum/element.rb +61 -0
  92. data/specs/constraints/int_enum/equality.rb +29 -0
  93. data/specs/constraints/int_enum/extensional.rb +224 -0
  94. data/specs/constraints/int_enum/sort.rb +167 -0
  95. data/specs/constraints/operands.rb +264 -0
  96. data/specs/constraints/property_helper.rb +443 -0
  97. data/specs/constraints/reification_sugar.rb +4 -5
  98. data/specs/constraints/selected_set/select.rb +56 -0
  99. data/specs/constraints/selected_set/select_properties.rb +157 -0
  100. data/specs/constraints/set/cardinality.rb +58 -0
  101. data/specs/constraints/set/cardinality_properties.rb +46 -0
  102. data/specs/constraints/set/channel.rb +77 -0
  103. data/specs/constraints/set/connection.rb +176 -0
  104. data/specs/constraints/set/domain.rb +197 -0
  105. data/specs/constraints/set/include.rb +36 -0
  106. data/specs/constraints/set/operation.rb +132 -0
  107. data/specs/constraints/set/relation.rb +117 -0
  108. data/specs/constraints/set_elements/relation.rb +84 -0
  109. data/specs/constraints/set_enum/channel.rb +80 -0
  110. data/specs/constraints/set_enum/distinct.rb +59 -0
  111. data/specs/constraints/set_enum/operation.rb +111 -0
  112. data/specs/constraints/set_enum/select.rb +73 -0
  113. data/specs/enum_wrapper.rb +53 -3
  114. data/specs/int_var.rb +44 -25
  115. data/specs/model.rb +58 -1
  116. data/specs/model_sugar.rb +30 -0
  117. data/specs/search.rb +24 -5
  118. data/specs/selected_set.rb +39 -0
  119. data/specs/set_elements.rb +34 -0
  120. data/specs/set_var.rb +22 -8
  121. data/specs/spec_helper.rb +206 -6
  122. data/tasks/distribution.rake +22 -7
  123. data/tasks/svn.rake +3 -1
  124. metadata +218 -134
  125. data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
  126. data/specs/constraints/arithmetic.rb +0 -351
  127. data/specs/constraints/bool_enum_relation.rb +0 -160
  128. data/specs/constraints/cardinality.rb +0 -157
  129. data/specs/constraints/channel.rb +0 -454
  130. data/specs/constraints/connection.rb +0 -369
  131. data/specs/constraints/count.rb +0 -146
  132. data/specs/constraints/distinct.rb +0 -164
  133. data/specs/constraints/element.rb +0 -108
  134. data/specs/constraints/equality.rb +0 -31
  135. data/specs/constraints/int_domain.rb +0 -70
  136. data/specs/constraints/int_relation.rb +0 -82
  137. data/specs/constraints/linear.rb +0 -340
  138. data/specs/constraints/selection.rb +0 -292
  139. data/specs/constraints/set_domain.rb +0 -185
  140. data/specs/constraints/set_operation.rb +0 -285
  141. data/specs/constraints/set_relation.rb +0 -197
  142. data/specs/constraints/sort.rb +0 -179
@@ -1,259 +1,251 @@
1
- module Gecode
2
- class FreeBoolVar
3
- # Initiates a boolean constraint with this variable or +var+.
4
- def |(var)
5
- Constraints::Bool::ExpressionNode.new(self, @model) | var
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
- # Initiates a boolean constraint with this variable and +var+.
9
- def &(var)
10
- Constraints::Bool::ExpressionNode.new(self, @model) & var
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
- # Initiates a boolean constraint with this variable exclusive or +var+.
14
- def ^(var)
15
- Constraints::Bool::ExpressionNode.new(self, @model) ^ var
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
- # Initiates a boolean constraint with this variable implies +var+.
19
- def implies(var)
20
- Constraints::Bool::ExpressionNode.new(self, @model).implies var
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
- end
23
-
24
- # A module that gathers the classes and modules used in boolean constraints.
25
- module Constraints::Bool
26
- # Describes a boolean expression (following after must*).
27
- class Expression #:nodoc:
28
- def ==(expression, options = {})
29
- if expression.kind_of? Gecode::Constraints::Int::Linear::ExpressionTree
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
- # Constrains the boolean expression to be false.
56
- def false(options = {})
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
- # Describes a constraint on a boolean expression.
63
- #
64
- # == Boolean expressions
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
- # === Examples
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
- # # (+b1+ and +b2+) or +b3+
80
- # (b1 & b1) | b3
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
- # # (+b1+ and +b2+) or (+b3+ exclusive or +b1+)
83
- # (b1 & b2) | (b3 ^ b1)
84
+ # ==== Examples
84
85
  #
85
- # # (+b1+ implies +b2+) and (+b3+ implies +b2+)
86
- # (b1.implies b2) & (b3.implies b2)
86
+ # # +b1+ must imply +b2+
87
+ # b1.must.imply b2
87
88
  #
88
- # == Domain
89
- #
90
- # A domain constraint just specifies that a boolean expression must be true
91
- # or false. Negation and reification are supported.
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
- # === Examples
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 false.
99
- # ((b1.implies b2) & (b3.implies b2)).must_be.false
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
- # == Equality
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
- # == Implication
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
- # === Examples
126
- #
127
- # # +b1+ must imply +b2+
128
- # b1.must.imply b2
129
- #
130
- # # +b1+ and +b2+ must not imply +b3+. We reify it with +bool+ and select
131
- # # +domain+ as strength.
132
- # (b1 & b2).must_not.imply b3
133
- class BooleanConstraint < Gecode::Constraints::ReifiableConstraint
134
- def post
135
- lhs, rhs, negate, reif_var =
136
- @params.values_at(:lhs, :rhs, :negate, :reif)
137
- space = (lhs.model || rhs.model).active_space
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
- if lhs.kind_of?(Gecode::FreeBoolVar)
140
- lhs = Constraints::Bool::ExpressionNode.new(lhs, @model)
141
- end
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
- bot_eqv = Gecode::Raw::IRT_EQ
144
- bot_xor = Gecode::Raw::IRT_NQ
146
+ bot_eqv = Gecode::Raw::IRT_EQ
147
+ bot_xor = Gecode::Raw::IRT_NQ
145
148
 
146
- if rhs.respond_to? :to_minimodel_bool_expr
147
- if reif_var.nil?
148
- tree = ExpressionTree.new(lhs,
149
- Gecode::Raw::MiniModel::BoolExpr::NT_EQV, rhs)
150
- tree.to_minimodel_bool_expr.post(space, !negate,
151
- *propagation_options)
152
- else
153
- tree = ExpressionTree.new(lhs,
154
- Gecode::Raw::MiniModel::BoolExpr::NT_EQV, rhs)
155
- var = tree.to_minimodel_bool_expr.post(space, *propagation_options)
156
- Gecode::Raw::rel(space, var, (negate ? bot_xor : bot_eqv),
157
- reif_var.bind, *propagation_options)
158
- end
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
- should_hold = !negate & rhs
161
- if reif_var.nil?
162
- lhs.to_minimodel_bool_expr.post(space, should_hold,
163
- *propagation_options)
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
- # A module containing the methods for the basic boolean operations. Depends
175
- # on that the class mixing it in defined #model.
176
- module OperationMethods #:nodoc
177
- include Gecode::Constraints::LeftHandSideMethods
178
-
179
- private
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
- # Maps the names of the methods to the corresponding bool constraint in
182
- # Gecode.
183
- OPERATION_TYPES = {
184
- :| => Gecode::Raw::MiniModel::BoolExpr::NT_OR,
185
- :& => Gecode::Raw::MiniModel::BoolExpr::NT_AND,
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
- # Constructs a new expression with the specified binary operation
218
- # applied to the specified trees.
219
- def initialize(left_tree, operation, right_tree)
220
- @left = left_tree
221
- @operation = operation
222
- @right = right_tree
223
- end
224
-
225
- # Returns a MiniModel boolean expression representing the tree.
226
- def to_minimodel_bool_expr
227
- Gecode::Raw::MiniModel::BoolExpr.new(
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
- def initialize(value, model = nil)
245
- unless value.kind_of?(Gecode::FreeBoolVar)
246
- raise TypeError, 'Invalid type used in boolean equation: ' +
247
- "#{value.class}."
248
- end
249
- @value = value
250
- @model = model
251
- end
252
-
253
- # Returns a MiniModel boolean expression representing the tree.
254
- def to_minimodel_bool_expr
255
- Gecode::Raw::MiniModel::BoolExpr.new(@value.bind)
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