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
@@ -0,0 +1,116 @@
1
+ module Gecode::SetElements
2
+ class SetElementsConstraintReceiver
3
+ # Constrains the set elements to equal +operand+ (either a
4
+ # constant integer or an integer operand).
5
+ #
6
+ # ==== Examples
7
+ #
8
+ # # The elements of +set+ must equal +int+
9
+ # set.elements.must == int
10
+ #
11
+ # # The elements of +set+ must equal 17
12
+ # set.elements.must == 17
13
+ def ==(operand, options = {})
14
+ comparison(:==, operand, options)
15
+ end
16
+
17
+ # Constrains the set elements to be strictly greater than
18
+ # +operand+ (either a constant integer or an integer operand).
19
+ #
20
+ # ==== Examples
21
+ #
22
+ # # The elements of +set+ must be strictly greater than +int+
23
+ # set.elements.must > int
24
+ #
25
+ # # The elements of +set+ must be strictly greater than 17
26
+ # set.elements.must > 17
27
+ def >(operand, options = {})
28
+ comparison(:>, operand, options)
29
+ end
30
+
31
+ # Constrains the set elements to be greater than or equal to
32
+ # +operand+ (either a constant integer or an integer operand).
33
+ #
34
+ # ==== Examples
35
+ #
36
+ # # The elements of +set+ must be greater than or equal to +int+
37
+ # set.elements.must >= int
38
+ #
39
+ # # The elements of +set+ must be greater than or equal to 17
40
+ # set.elements.must >= 17
41
+ def >=(operand, options = {})
42
+ comparison(:>=, operand, options)
43
+ end
44
+
45
+ # Constrains the set elements to be strictly less than
46
+ # +operand+ (either a constant integer or an integer operand).
47
+ #
48
+ # ==== Examples
49
+ #
50
+ # # The elements of +set+ must be strictly less than +int+
51
+ # set.elements.must < int
52
+ #
53
+ # # The elements of +set+ must be strictly less than 17
54
+ # set.elements.must < 17
55
+ def <(operand, options = {})
56
+ comparison(:<, operand, options)
57
+ end
58
+
59
+ # Constrains the set elements to be less than or equal to
60
+ # +operand+ (either a constant integer or an integer operand).
61
+ #
62
+ # ==== Examples
63
+ #
64
+ # # The elements of +set+ must be less than or equal to +int+
65
+ # set.elements.must <= int
66
+ #
67
+ # # The elements of +set+ must be less than or equal to 17
68
+ # set.elements.must <= 17
69
+ def <=(operand, options = {})
70
+ comparison(:<=, operand, options)
71
+ end
72
+
73
+ alias_comparison_methods
74
+
75
+ private
76
+
77
+ # Helper for the comparison methods. The reason that they are not
78
+ # generated in a loop is that it would mess up the RDoc.
79
+ def comparison(name, operand, options)
80
+ unless operand.respond_to?(:to_int_var) or
81
+ operand.kind_of?(Fixnum)
82
+ raise TypeError, "Expected int operand or integer, got " +
83
+ "#{operand.class}."
84
+ end
85
+ unless options[:reify].nil?
86
+ raise ArgumentError, 'Reification is not supported by the elements ' +
87
+ 'relation constraint.'
88
+ end
89
+
90
+ unless @params[:negate]
91
+ relation_type = Gecode::Util::RELATION_TYPES[name]
92
+ else
93
+ relation_type = Gecode::Util::NEGATED_RELATION_TYPES[name]
94
+ end
95
+ @params.update Gecode::Set::Util.decode_options(options)
96
+ @model.add_constraint Relation::RelationConstraint.new(@model,
97
+ @params.update(:relation_type => relation_type, :rhs => operand))
98
+ end
99
+ end
100
+
101
+ module Relation #:nodoc:
102
+ class RelationConstraint < Gecode::Constraint #:nodoc:
103
+ def post
104
+ set_elements, rhs, type = @params.values_at(:lhs, :rhs, :relation_type)
105
+ set = set_elements.to_set_elements
106
+
107
+ if rhs.kind_of? Fixnum
108
+ # Use a proxy int variable to cover.
109
+ rhs = @model.int_var(rhs)
110
+ end
111
+ Gecode::Raw::rel(@model.active_space, set.to_set_var.bind,
112
+ type, rhs.to_int_var.bind)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,97 @@
1
+ # A module containing constraints that have set.elements as left hand
2
+ # side.
3
+ module Gecode::SetElements #:nodoc:
4
+ # A SetElementsOperand is an uncommon operand that results from calling
5
+ # SetOperand#elements. It facilitates placing the constraints defined
6
+ # in SetElementsConstraintReceiver
7
+ #
8
+ # ==== Examples
9
+ #
10
+ # Producing a SetElementsOperand from +set_operand+:
11
+ #
12
+ # set_operand.elements
13
+ #
14
+ class SetElementsOperand
15
+ include Gecode::Operand
16
+
17
+ # Constructs a new set elements operand +set+.
18
+ def initialize(set) #:nodoc:
19
+ unless set.respond_to? :to_set_var
20
+ raise TypeError, "Expected set operand, got #{set.class}."
21
+ end
22
+
23
+ @set = set
24
+ end
25
+
26
+ # Returns the set operand that makes up the set elements operand.
27
+ def to_set_elements #:nodoc:
28
+ return @set
29
+ end
30
+
31
+ def model #:nodoc:
32
+ @set.model
33
+ end
34
+
35
+ private
36
+
37
+ def construct_receiver(params)
38
+ SetElementsConstraintReceiver.new(model, params)
39
+ end
40
+ end
41
+
42
+ # SetElementsConstraintReceiver contains all constraints that can be
43
+ # placed on a SetElementsOperand.
44
+ #
45
+ # Constraints are placed by calling SetElementsOperand#must (or any other
46
+ # of the variations defined in Operand), which produces a
47
+ # SetElementsConstraintReceiver from which the desired constraint can
48
+ # be used.
49
+ #
50
+ # Each constraint accepts a number of options. See ConstraintReceiver
51
+ # for more information.
52
+ #
53
+ # ==== Examples
54
+ #
55
+ # Constrains all elements in +set_operand+ to be strictly greater than 17
56
+ # using SetOperand#elements and SetElementsConstraintReceiver#>:
57
+ #
58
+ # set.elements.must > 17
59
+ #
60
+ # Constrains all elements in +set_operand+ to be strictly greater than
61
+ # +int_operand+ using SetOperand#elements and SetElementsConstraintReceiver#>:
62
+ #
63
+ # set.elements.must > int_operand
64
+ #
65
+ # The same as above, but specifying that strength :domain should be
66
+ # used and that the constraint should be reified with +bool_operand+:
67
+ #
68
+ # set.elements.must_be.greater_than(int_operand, :strength => :domain, :reify => bool_operand)
69
+ #
70
+ class SetElementsConstraintReceiver < Gecode::ConstraintReceiver
71
+ # Raises TypeError unless the left hand side is set elements operand.
72
+ def initialize(model, params) #:nodoc:
73
+ super
74
+
75
+ unless params[:lhs].respond_to? :to_set_elements
76
+ raise TypeError, 'Must have set elements operand as left hand side.'
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ module Gecode::Set #:nodoc:
83
+ module SetOperand
84
+ # Produces a SetElementsOperand on which relation constraints can be placed that
85
+ # constrain all elements in the set.
86
+ #
87
+ # ==== Examples
88
+ #
89
+ # # The elements of +set+.
90
+ # set.elements
91
+ def elements
92
+ Gecode::SetElements::SetElementsOperand.new(self)
93
+ end
94
+ end
95
+ end
96
+
97
+ require 'gecoder/interface/constraints/set_elements/relation.rb'
@@ -1,10 +1,21 @@
1
- module Gecode::Constraints::SetEnum
2
- class Expression
3
- # Posts a channel constraint on the variables in the enum with the specified
4
- # int enum.
1
+ module Gecode::SetEnum
2
+ class SetEnumConstraintReceiver
3
+ # Constrains this set enum to channel +int_enum_operand+. The i:th set
4
+ # in the enumeration of set operands is constrained to includes the value
5
+ # of the j:th integer operand.
6
+ #
7
+ # Neither reification nor negation is supported.
8
+ #
9
+ # ==== Examples
10
+ #
11
+ # # +set_enum+ is constrained to channel +int_enum+.
12
+ # int_enum.must.channel set_enum
13
+ #
14
+ # # This is another way of writing the above.
15
+ # set_enum.must.channel int_enum
5
16
  def channel(enum, options = {})
6
- unless enum.respond_to? :to_int_var_array
7
- raise TypeError, "Expected integer variable enum, for #{enum.class}."
17
+ unless enum.respond_to? :to_int_enum
18
+ raise TypeError, "Expected integer enum, for #{enum.class}."
8
19
  end
9
20
  if @params[:negate]
10
21
  raise Gecode::MissingConstraintError, 'A negated channel constraint ' +
@@ -15,35 +26,20 @@ module Gecode::Constraints::SetEnum
15
26
  'reification option.'
16
27
  end
17
28
 
18
- @params.update(Gecode::Constraints::Set::Util.decode_options(options))
29
+ @params.update(Gecode::Set::Util.decode_options(options))
19
30
  @params.update(:rhs => enum)
20
- @model.add_constraint Channel::IntChannelConstraint.new(@model, @params)
31
+ @model.add_constraint Channel::IntEnumChannelConstraint.new(@model, @params)
21
32
  end
22
33
  end
23
34
 
24
35
  # A module that gathers the classes and modules used in channel constraints.
25
36
  module Channel #:nodoc:
26
- # Describes a channel constraint which "channels" one enumeration of
27
- # integer variables with one enumeration of set variables. The i:th set
28
- # in the enumeration of set variables is constrainde to includes the value
29
- # of the j:th integer variable.
30
- #
31
- # Neither reification nor negation is supported.
32
- #
33
- # == Examples
34
- #
35
- # # +set_enum+ is constrained to channel +int_enum+.
36
- # int_enum.must.channel set_enum
37
- #
38
- # # This is another way of saying the above.
39
- # set_enum.must.channel int_enum
40
- #
41
- class IntChannelConstraint < Gecode::Constraints::Constraint
37
+ class IntEnumChannelConstraint < Gecode::Constraint #:nodoc:
42
38
  def post
43
39
  lhs, rhs = @params.values_at(:lhs, :rhs)
44
- Gecode::Raw::channel(@model.active_space, rhs.to_int_var_array,
45
- lhs.to_set_var_array)
40
+ Gecode::Raw::channel(@model.active_space, rhs.to_int_enum.bind_array,
41
+ lhs.to_set_enum.bind_array)
46
42
  end
47
43
  end
48
44
  end
49
- end
45
+ end
@@ -1,12 +1,21 @@
1
- module Gecode::Constraints::SetEnum
2
- class Expression
3
- # Adds a constraint on the sets that specifies that they must have at most
4
- # one element in common. The "option" :size must be specified, the sets
5
- # will be constrained to that size.
1
+ module Gecode::SetEnum
2
+ class SetEnumConstraintReceiver
3
+ # Constrains all pairs of set operands in the enumeration to at
4
+ # most have one element in common and be of a specified size.
5
+ # Providing a size is not optional.
6
+ #
7
+ # Neither negation nor reification is supported.
8
+ #
9
+ # ==== Examples
10
+ #
11
+ # # All set operands in +sets+ must have cardinality 17 and no pair may
12
+ # # have more than one element in common.
13
+ # sets.must.at_most_share_one_element(:size => 17)
6
14
  def at_most_share_one_element(options = {})
7
15
  unless options.has_key? :size
8
16
  raise ArgumentError, 'Option :size has to be specified.'
9
17
  end
18
+ # TODO can we use Set::Util::decode_options here instead?
10
19
  unless options.size == 1
11
20
  raise ArgumentError, 'Only the option :size is accepted, got ' +
12
21
  "#{options.keys.join(', ')}."
@@ -23,22 +32,12 @@ module Gecode::Constraints::SetEnum
23
32
 
24
33
  # A module that gathers the classes and modules used in distinct constraints.
25
34
  module Distinct #:nodoc:
26
- # Describes an at most one constraint, which constrains all pairs of set
27
- # variables in the enumeration to at most have one element in common and be
28
- # of a specified size. Providing a size is not optional.
29
- #
30
- # Neither negation nor reification is supported.
31
- #
32
- # == Examples
33
- #
34
- # # All set variables in +sets+ must have cardinality 17 and no pair may
35
- # # have more than one element in common.
36
- # sets.must.at_most_share_one_element(:size => 17)
37
- class AtMostOneConstraint < Gecode::Constraints::Constraint
35
+ class AtMostOneConstraint < Gecode::Constraint #:nodoc:
38
36
  def post
39
37
  sets, size = @params.values_at(:lhs, :size)
40
- Gecode::Raw::atmostOne(@model.active_space, sets.to_set_var_array, size)
38
+ Gecode::Raw::atmostOne(@model.active_space,
39
+ sets.to_set_enum.bind_array, size)
41
40
  end
42
41
  end
43
42
  end
44
- end
43
+ end
@@ -1,60 +1,69 @@
1
- module Gecode::SetEnumMethods
2
- Gecode::Constraints::Util::SET_OPERATION_TYPES.each_pair do |name, type|
3
- next if type == Gecode::Raw::SOT_MINUS # Does not support this constraint?
1
+ module Gecode::SetEnum
2
+ module SetEnumOperand
3
+ # Produces a SetOperand representing the union of all sets in this
4
+ # enumeration.
5
+ #
6
+ # ==== Examples
7
+ #
8
+ # # The union of all sets in +set_enum+.
9
+ # set_enum.union
10
+ def union
11
+ set_operation(:union)
12
+ end
4
13
 
5
- module_eval <<-"end_code"
6
- # Starts a constraint on the #{name} of the sets.
7
- def #{name}
8
- params = {:lhs => self, :operation => #{type}}
9
- Gecode::Constraints::SetEnum::Operation::ExpressionStub.new(
10
- @model, params)
11
- end
12
- end_code
14
+ # Produces a SetOperand representing the intersection of all sets in this
15
+ # enumeration.
16
+ #
17
+ # ==== Examples
18
+ #
19
+ # # The intersection of all sets in +set_enum+.
20
+ # set_enum.intersection
21
+ def intersection
22
+ set_operation(:intersection)
23
+ end
24
+
25
+ # Produces a SetOperand representing the disjoint union of all sets
26
+ # in this enumeration.
27
+ #
28
+ # ==== Examples
29
+ #
30
+ # # The disjoint union of all sets in +set_enum+.
31
+ # set_enum.disjoint_union
32
+ def disjoint_union
33
+ set_operation(:disjoint_union)
34
+ end
35
+
36
+ private
37
+
38
+ # Produces the SetOperand resulting from +operator+ applied to this
39
+ # operand.
40
+ def set_operation(operator)
41
+ Operation::OperationSetOperand.new(model, self, operator)
42
+ end
13
43
  end
14
- end
15
44
 
16
- # A module that gathers the classes and modules used by operation constaints.
17
- module Gecode::Constraints::SetEnum::Operation #:nodoc:
18
- # Describes a CompositeStub for the enumeration operation constraint, which
19
- # constrains the result of applying an operation between all set variables in
20
- # a set enumeration.
21
- #
22
- # The supported operations are:
23
- # * union
24
- # * disjoint_union
25
- # * intersection
26
- # * minus
27
- #
28
- # == Example
29
- #
30
- # # The union of all set variables in +sets+ must be subset of 1..17.
31
- # sets.union.must_be.subset_of 1..17
32
- #
33
- # # The intersection of all set variables must equal [1,3,5].
34
- # sets.intersection.must == [1,3,5]
35
- #
36
- # # The union of all set variable must be a subset of the set variable
37
- # # +universe+.
38
- # sets.union.must_be.subset_of universe
39
- #
40
- # # The same as above, but reified with the boolean variable
41
- # # +is_within_universe+.
42
- # sets.union.must_be.subset_of(universe, :reify => is_within_universe)
43
- class ExpressionStub < Gecode::Constraints::Set::CompositeStub
44
- def constrain_equal(variable, params, constrain)
45
- enum, operation = @params.values_at(:lhs, :operation)
46
-
47
- if constrain
48
- if operation == Gecode::Raw::SOT_INTER or
49
- operation == Gecode::Raw::SOT_MINUS
50
- variable.must_be.subset_of enum.first.upper_bound
51
- else
52
- variable.must_be.subset_of enum.upper_bound_range
45
+ # A module that gathers the classes and modules used in operation constraints.
46
+ module Operation #:nodoc:
47
+ class OperationSetOperand < Gecode::Set::ShortCircuitEqualityOperand #:nodoc:
48
+ def initialize(model, enum, operator)
49
+ super model
50
+ @enum = enum
51
+ @operator = operator
52
+ end
53
+
54
+ def constrain_equal(set_operand, constrain_domain, propagation_options)
55
+ operation = Gecode::Util::SET_OPERATION_TYPES[@operator]
56
+ if constrain_domain
57
+ if operation == Gecode::Raw::SOT_INTER
58
+ set_operand.must_be.subset_of @enum.first.upper_bound
59
+ else
60
+ set_operand.must_be.subset_of @enum.upper_bound_range
61
+ end
53
62
  end
63
+
64
+ Gecode::Raw::rel(@model.active_space, operation,
65
+ @enum.to_set_enum.bind_array, set_operand.to_set_var.bind)
54
66
  end
55
-
56
- Gecode::Raw::rel(@model.active_space, operation, enum.to_set_var_array,
57
- variable.bind)
58
67
  end
59
68
  end
60
- end
69
+ end