gecoder 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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