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,87 +1,54 @@
1
- module Gecode
2
- module BoolEnumMethods
3
- # Produces an expression that can be handled as if it was a variable
4
- # representing the conjunction of all boolean variables in the enumeration.
1
+ module Gecode::BoolEnum
2
+ module BoolEnumOperand
3
+ # Produces a BoolOperand that represents the conjunction (AND) of all
4
+ # boolean operands in this enumeration.
5
+ #
6
+ # ==== Examples
7
+ #
8
+ # # Conjunction of all elements in +bool_enum+.
9
+ # bool_enum.conjunction
5
10
  def conjunction
6
- return Gecode::Constraints::BoolEnum::Relation::ConjunctionStub.new(
7
- @model, :lhs => self)
11
+ Relation::BoolEnumConjunctionOperand.new(@model, self)
8
12
  end
9
13
 
10
- # Produces an expression that can be handled as if it was a variable
11
- # representing the disjunction of all boolean variables in the enumeration.
14
+ # Produces a BoolOperand that represents the disjunction (OR) of all
15
+ # boolean operands in this enumeration.
16
+ #
17
+ # ==== Examples
18
+ #
19
+ # # Disjunction of all elements in +bool_enum+.
20
+ # bool_enum.disjunction
12
21
  def disjunction
13
- return Gecode::Constraints::BoolEnum::Relation::DisjunctionStub.new(
14
- @model, :lhs => self)
22
+ Relation::BoolEnumDisjunctionOperand.new(@model, self)
15
23
  end
16
24
  end
17
- end
18
25
 
19
- module Gecode::Constraints::BoolEnum
20
26
  # A module that gathers the classes and modules used by boolean enumeration
21
27
  # relation constraints.
22
28
  module Relation #:nodoc:
23
- # Describes a CompositeStub for the conjunction constraint, which constrain
24
- # the conjunction of all boolean variables in an enumeration.
25
- #
26
- # == Example
27
- #
28
- # # The conjunction of all variables in +bool_enum+ must be true. I.e. all
29
- # # boolean variables must take the value true.
30
- # bool_enum.conjunction.must_be.true
31
- #
32
- # # The conjunction of all variables in +bool_enum+ must equal b1.
33
- # bool_enum.conjunction.must == b1
34
- #
35
- # # The conjunction of all variables in +bool_enum+ must not equal b1 and
36
- # # b2. It's reified it with +bool+ and selects the strength +domain+.
37
- # bool_enum.conjunction.must_not.equal(b1 & b2, :reify => bool,
38
- # :strength => :domain)
39
- class ConjunctionStub < Gecode::Constraints::Bool::CompositeStub
40
- def constrain_equal(variable, params, constrain)
41
- enum = @params[:lhs]
42
-
43
- @model.add_interaction do
44
- if variable.respond_to? :bind
45
- bound = variable.bind
46
- else
47
- bound = variable ? 1 : 0
48
- end
49
- Gecode::Raw::rel(@model.active_space, Gecode::Raw::BOT_AND,
50
- enum.to_bool_var_array, bound, *propagation_options)
51
- end
52
- return variable
29
+ class BoolEnumConjunctionOperand < Gecode::Bool::ShortCircuitEqualityOperand #:nodoc:
30
+ def initialize(model, bool_enum)
31
+ super model
32
+ @enum = bool_enum
33
+ end
34
+
35
+ def constrain_equal(bool_operand, constrain_domain, propagation_options)
36
+ Gecode::Raw::rel(@model.active_space, Gecode::Raw::BOT_AND,
37
+ @enum.to_bool_enum.bind_array, bool_operand.to_bool_var.bind,
38
+ *propagation_options)
53
39
  end
54
40
  end
55
41
 
56
- # Describes a CompositeStub for the disjunction constraint, which constrain
57
- # the disjunction of all boolean variables in an enumeration.
58
- #
59
- # == Example
60
- #
61
- # # The disjunction of all variables in +bool_enum+ must be true. I.e. at
62
- # # least one of the boolean variables must take the value true.
63
- # bool_enum.disjunction.must_be.true
64
- #
65
- # # The disjunction of all variables in +bool_enum+ must equal b1.
66
- # bool_enum.conjunction.must == b1
67
- #
68
- # # The disjunction of all variables in +bool_enum+ must not equal b1 and
69
- # # b2. It's reified it with +bool+ and selects the strength +domain+.
70
- # bool_enum.disjunction.must_not.equal(b1 & b2, :reify => bool,
71
- # :strength => :domain)
72
- class DisjunctionStub < Gecode::Constraints::Bool::CompositeStub
73
- def constrain_equal(variable, params, constrain)
74
- enum = @params[:lhs]
75
-
76
- @model.add_interaction do
77
- if variable.respond_to? :bind
78
- bound = variable.bind
79
- else
80
- bound = variable ? 1 : 0
81
- end
82
- Gecode::Raw::rel(@model.active_space, Gecode::Raw::BOT_OR,
83
- enum.to_bool_var_array, bound, *propagation_options)
84
- end
42
+ class BoolEnumDisjunctionOperand < Gecode::Bool::ShortCircuitEqualityOperand #:nodoc:
43
+ def initialize(model, bool_enum)
44
+ super model
45
+ @enum = bool_enum
46
+ end
47
+
48
+ def constrain_equal(bool_operand, constrain_domain, propagation_options)
49
+ Gecode::Raw::rel(@model.active_space, Gecode::Raw::BOT_OR,
50
+ @enum.to_bool_enum.bind_array, bool_operand.to_bool_var.bind,
51
+ *propagation_options)
85
52
  end
86
53
  end
87
54
  end
@@ -1,28 +1,79 @@
1
- module Gecode
2
- module BoolEnumMethods
3
- include Gecode::Constraints::LeftHandSideMethods
4
-
1
+ # A module containing constraints that have enumerations of boolean
2
+ # operands as left hand side.
3
+ module Gecode::BoolEnum #:nodoc:
4
+ # A BoolEnumOperand is a enumeration of BoolOperand on which the
5
+ # constraints defined in BoolEnumConstraintReceiver can be placed.
6
+ #
7
+ # Enumerations of boolean operands can be created either by using
8
+ # Gecode::Model#bool_var_array and Gecode::Model#bool_var_matrix, or
9
+ # by wrapping an existing enumeration containing BoolOperand using
10
+ # Gecode::Model#wrap_enum. The enumerations, no matter how they were
11
+ # created, all respond to the properties defined by BoolEnumOperand.
12
+ #
13
+ # ==== Examples
14
+ #
15
+ # Produces an array of five boolean operands inside a problem formulation
16
+ # using Gecode::Model#bool_var_array:
17
+ #
18
+ # bool_enum = bool_var_array(5)
19
+ #
20
+ # Uses Gecode::Model#wrap_enum inside a problem formulation to create
21
+ # a BoolEnumOperand from an existing enumeration containing the
22
+ # boolean operands +bool_operand1+ and +bool_operand2+:
23
+ #
24
+ # bool_enum = wrap_enum([bool_operand1, bool_operand2])
25
+ #
26
+ #--
27
+ # Classes that mix in BoolEnumOperand must define #model and
28
+ # #to_bool_enum .
29
+ module BoolEnumOperand
30
+ include Gecode::Operand
31
+
32
+ def method_missing(method, *args) #:nodoc:
33
+ if Gecode::BoolEnum::Dummy.instance_methods.include? method.to_s
34
+ # Delegate to the bool enum.
35
+ to_bool_enum.method(method).call(*args)
36
+ else
37
+ super
38
+ end
39
+ end
40
+
5
41
  private
6
-
7
- # Produces an expression for the lhs module.
8
- def expression(params)
9
- params.update(:lhs => self)
10
- Constraints::BoolEnum::Expression.new(@model, params)
42
+
43
+ def construct_receiver(params)
44
+ BoolEnumConstraintReceiver.new(@model, params)
11
45
  end
12
46
  end
13
-
14
- # A module containing constraints that have enumerations of boolean variables
15
- # as left hand side.
16
- module Constraints::BoolEnum
17
- # Expressions with bool enums as left hand sides.
18
- class Expression < Gecode::Constraints::Expression #:nodoc:
19
- # Raises TypeError unless the left hand side is a bool enum.
20
- def initialize(model, params)
21
- super
22
-
23
- unless params[:lhs].respond_to? :to_bool_var_array
24
- raise TypeError, 'Must have bool enum as left hand side.'
25
- end
47
+
48
+ # BoolEnumConstraintReceiver contains all constraints that can be
49
+ # placed on a BoolEnumOperand.
50
+ #
51
+ # Constraints are placed by calling BoolEnumOperand#must (or any other
52
+ # of the variations defined in Operand), which produces a
53
+ # BoolEnumConstraintReceiver from which the desired constraint can be
54
+ # used.
55
+ #
56
+ # ==== Examples
57
+ #
58
+ # Constrains +bool_enum+, with three boolean operands, to take the
59
+ # value of the tuples [false, true, false] or [true, false, true]
60
+ # using BoolEnumConstraintReceiver#in:
61
+ #
62
+ # bool_enum.must_be.in [[false, true, false], [true, false, true]]
63
+ #
64
+ # Constrains +bool_enum+ to channel +int_operand+ using
65
+ # BoolEnumConstraintReceiver#channel:
66
+ #
67
+ # bool_enum.must.channel int_operand
68
+ #
69
+ class BoolEnumConstraintReceiver < Gecode::ConstraintReceiver
70
+ # Raises TypeError unless the left hand side is an bool enum
71
+ # operand.
72
+ def initialize(model, params) #:nodoc:
73
+ super
74
+
75
+ unless params[:lhs].respond_to? :to_bool_enum
76
+ raise TypeError, 'Must have bool enum operand as left hand side.'
26
77
  end
27
78
  end
28
79
  end
@@ -1,72 +1,151 @@
1
- module Gecode
2
- class FreeBoolVar
3
- include Gecode::Constraints::LeftHandSideMethods
4
-
1
+ # A module that deals with the operands, properties and constraints of
2
+ # boolean operands.
3
+ module Gecode::Bool #:nodoc:
4
+ # A BoolOperand is a combination of variables on which the
5
+ # constraints defined in BoolConstraintReceiver can be placed.
6
+ #
7
+ # Boolean operands can be created either by using
8
+ # Gecode::Model#bool_var et al, or by using properties that produce
9
+ # boolean operands. The operands, no matter how they were created,
10
+ # all respond to the properties defined by BoolOperand.
11
+ #
12
+ # ==== Examples
13
+ #
14
+ # Produces a single boolean operand (more specifically a BoolVar)
15
+ # inside a problem formulation, using Gecode::Model#bool_var:
16
+ #
17
+ # bool_operand = bool_var
18
+ #
19
+ # Uses the BoolOperand#& property to produce a new boolean
20
+ # operand representing +bool_operand1+ AND +bool_operand2+:
21
+ #
22
+ # new_bool_operand = bool_operand1 & bool_operand2
23
+ #
24
+ # Uses the BoolEnumOperand#conjunction property to produce a new
25
+ # boolean operand representing the conjunction of all boolean operands
26
+ # in the enumeration +bool_enum+:
27
+ #
28
+ # new_bool_operand = bool_enum.conjunction
29
+ #
30
+ #--
31
+ # Classes that mix in BoolOperand must define #model and #to_bool_var .
32
+ module BoolOperand
33
+ include Gecode::Operand
34
+
35
+ def method_missing(method, *args) #:nodoc:
36
+ if Gecode::BoolVar.instance_methods.include? method.to_s
37
+ # Delegate to the bool var.
38
+ to_bool_var.method(method).call(*args)
39
+ else
40
+ super
41
+ end
42
+ end
43
+
5
44
  private
6
-
7
- # Produces an expression for the lhs module.
8
- def expression(params)
9
- params.update(:lhs => self)
10
- Constraints::Bool::Expression.new(@model, params)
45
+
46
+ def construct_receiver(params)
47
+ BoolConstraintReceiver.new(@model, params)
11
48
  end
12
49
  end
13
-
14
- # A module containing constraints that have int variables as left hand side
15
- # (but not enumerations).
16
- module Constraints::Bool
17
- # Describes a boolean expression.
18
- class Expression < Gecode::Constraints::Expression #:nodoc:
19
- end
20
-
21
- # A composite expression which is an bool expression with a left hand side
22
- # resulting from a previous constraint.
23
- class CompositeExpression < Gecode::Constraints::CompositeExpression #:nodoc:
24
- # The block given should take three parameters. The first is the variable
25
- # that should be the left hand side, if it's nil then a new one should be
26
- # created. The second is the has of parameters. The block should return
27
- # the variable used as left hand side.
28
- def initialize(model, params, &block)
29
- super(Expression, Gecode::FreeBoolVar, lambda{ model.bool_var }, model,
30
- params, &block)
31
- end
32
-
33
- # Override to also deal with constant booleans.
34
- def true(options = {})
35
- # We don't need any additional constraints.
36
- @params.update Gecode::Constraints::Util.decode_options(options)
37
- @model.add_interaction do
38
- @constrain_equal_proc.call(!@params[:negate], @params)
39
- end
50
+
51
+ # BoolConstraintReceiver contains all constraints that can be
52
+ # placed on a BoolOperand.
53
+ #
54
+ # Constraints are placed by calling BoolOperand#must (or any other
55
+ # of the variations defined in Operand), which produces a
56
+ # BoolConstraintReceiver from which the desired constraint can be used.
57
+ #
58
+ # Each constraint accepts a number of options. See ConstraintReceiver
59
+ # for more information.
60
+ #
61
+ # ==== Examples
62
+ #
63
+ # Constrains +bool_operand+ to be true using
64
+ # BoolConstraintReceiver#true:
65
+ #
66
+ # bool_operand.must_be.true
67
+ #
68
+ # Constrains +bool_operand1+ AND +bool_operand2+ to be true using
69
+ # the BoolOperand#& property and BoolConstraintReceiver#true:
70
+ #
71
+ # (bool_operand1 & bool_operand2).must_be.true
72
+ #
73
+ # Constrains the conjunction of all boolean operands in +bool_enum+ to
74
+ # _not_ imply +bool_operand+ using the
75
+ # BoolEnumOperand#conjunction property and BoolConstraintReceiver#imply:
76
+ #
77
+ # bool_enum.conjunction.must_not.imply bool_operand
78
+ #
79
+ # The same as above, but specifying that strength :domain should be
80
+ # used and that the constraint should be reified with +bool_operand2+:
81
+ #
82
+ # bool_enum.conjunction.must_not.imply(bool_operand, :strength => :domain, :reify => bool_operand2)
83
+ #
84
+ class BoolConstraintReceiver < Gecode::ConstraintReceiver
85
+ # Raises TypeError unless the left hand side is an bool operand.
86
+ def initialize(model, params) #:nodoc:
87
+ super
88
+
89
+ unless params[:lhs].respond_to? :to_bool_var
90
+ raise TypeError, 'Must have bool operand as left hand side.'
40
91
  end
41
-
42
- # Override to also deal with constant booleans.
43
- def false(options = {})
44
- # We don't need any additional constraints.
45
- @params.update Gecode::Constraints::Util.decode_options(options)
46
- @model.add_interaction do
47
- @constrain_equal_proc.call(@params[:negate], @params)
92
+ end
93
+ end
94
+
95
+ # An operand that short circuits boolean equality.
96
+ class ShortCircuitEqualityOperand #:nodoc:
97
+ include Gecode::Bool::BoolOperand
98
+ attr :model
99
+
100
+ def initialize(model)
101
+ @model = model
102
+ end
103
+
104
+ def construct_receiver(params)
105
+ params.update(:lhs => self)
106
+ receiver = BoolConstraintReceiver.new(@model, params)
107
+ op = self
108
+ receiver.instance_eval{ @short_circuit = op }
109
+ class <<receiver
110
+ alias_method :equality_without_short_circuit, :==
111
+ def ==(operand, options = {})
112
+ if !@params[:negate] and options[:reify].nil? and
113
+ operand.respond_to? :to_bool_var
114
+ # Short circuit the constraint.
115
+ @params.update Gecode::Util.decode_options(options)
116
+ @model.add_constraint(Gecode::BlockConstraint.new(
117
+ @model, @params) do
118
+ @short_circuit.constrain_equal(operand, false,
119
+ @params.values_at(:strength, :kind))
120
+ end)
121
+ else
122
+ equality_without_short_circuit(operand, options)
123
+ end
48
124
  end
125
+ alias_comparison_methods
49
126
  end
127
+
128
+ return receiver
50
129
  end
51
-
52
- # Describes a stub that produces an int variable, which can then be used
53
- # with the normal int variable constraints. An example would be the
54
- # conjunction constraint.
55
- #
56
- # bools.conjunction.must == b1 | b2
57
- #
58
- # <tt>bools.conjunction</tt> produces a boolean variable which the
59
- # constraint <tt>.must == b1 | b2</tt> is then applied to. In the above
60
- # case two constraints (and one temporary variable) are required, but in
61
- # the case of equality only one constraint is required.
62
- #
63
- # Whether a constraint involving a reification stub supports negation,
64
- # reification, strength options and so on depends on the constraint on the
65
- # right hand side.
66
- class CompositeStub < Gecode::Constraints::CompositeStub
67
- def initialize(model, params)
68
- super(CompositeExpression, model, params)
130
+
131
+ def to_bool_var
132
+ variable = model.bool_var
133
+ options =
134
+ Gecode::Util.decode_options({}).values_at(:strength, :kind)
135
+ model.add_interaction do
136
+ constrain_equal(variable, true, options)
69
137
  end
138
+ return variable
139
+ end
140
+
141
+ private
142
+
143
+ # Constrains this operand to equal +bool_operand+ using the
144
+ # specified +propagation_options+. If +constrain_domain+ is true
145
+ # then the method should also attempt to constrain the bounds of the
146
+ # domain of +bool_operand+.
147
+ def constrain_equal(bool_operand, constrain_domain, propagation_options)
148
+ raise NotImplementedError, 'Abstract method has not been implemented.'
70
149
  end
71
150
  end
72
151
  end
@@ -5,7 +5,7 @@ module Gecode
5
5
  # omitted then no upper bound is placed. If both +at_least+ and
6
6
  # +at_most+ are omitted then no bounds are placed.
7
7
  #
8
- # See Constraints::IntEnum::Extensional::RegexpConstraint for the
8
+ # See IntEnum::Extensional::RegexpConstraint for the
9
9
  # allowed syntax of +regexp+.
10
10
  def repeat(regexp, at_least = nil, at_most = nil)
11
11
  unless at_least.nil? or at_least.kind_of? Fixnum
@@ -17,7 +17,7 @@ module Gecode
17
17
  "Expected the at_most argument to be a Fixnum, got #{at_most.class}"
18
18
  end
19
19
 
20
- reg = Constraints::Util::Extensional.parse_regexp regexp
20
+ reg = Util::Extensional.parse_regexp regexp
21
21
  if at_most.nil?
22
22
  if at_least.nil?
23
23
  reg.send '*'
@@ -48,12 +48,12 @@ module Gecode
48
48
  # Matches any of the specified +regexps+.
49
49
  def any(*regexps)
50
50
  regexps.inject(Gecode::Raw::REG.new) do |result, regexp|
51
- result | Constraints::Util::Extensional.parse_regexp(regexp)
51
+ result | Util::Extensional.parse_regexp(regexp)
52
52
  end
53
53
  end
54
54
  end
55
55
 
56
- module Constraints::Util::Extensional
56
+ module Util::Extensional
57
57
  module_function
58
58
 
59
59
  # Parses a regular expression over the integer domain, returning