lib/gecoder/interface/constraints/set_enum/operation.rb in gecoder-0.8.3 vs lib/gecoder/interface/constraints/set_enum/operation.rb in gecoder-0.9.0

- old
+ new

@@ -1,60 +1,69 @@ -module Gecode::SetEnumMethods - Gecode::Constraints::Util::SET_OPERATION_TYPES.each_pair do |name, type| - next if type == Gecode::Raw::SOT_MINUS # Does not support this constraint? +module Gecode::SetEnum + module SetEnumOperand + # Produces a SetOperand representing the union of all sets in this + # enumeration. + # + # ==== Examples + # + # # The union of all sets in +set_enum+. + # set_enum.union + def union + set_operation(:union) + end - module_eval <<-"end_code" - # Starts a constraint on the #{name} of the sets. - def #{name} - params = {:lhs => self, :operation => #{type}} - Gecode::Constraints::SetEnum::Operation::ExpressionStub.new( - @model, params) - end - end_code + # Produces a SetOperand representing the intersection of all sets in this + # enumeration. + # + # ==== Examples + # + # # The intersection of all sets in +set_enum+. + # set_enum.intersection + def intersection + set_operation(:intersection) + end + + # Produces a SetOperand representing the disjoint union of all sets + # in this enumeration. + # + # ==== Examples + # + # # The disjoint union of all sets in +set_enum+. + # set_enum.disjoint_union + def disjoint_union + set_operation(:disjoint_union) + end + + private + + # Produces the SetOperand resulting from +operator+ applied to this + # operand. + def set_operation(operator) + Operation::OperationSetOperand.new(model, self, operator) + end end -end -# A module that gathers the classes and modules used by operation constaints. -module Gecode::Constraints::SetEnum::Operation #:nodoc: - # Describes a CompositeStub for the enumeration operation constraint, which - # constrains the result of applying an operation between all set variables in - # a set enumeration. - # - # The supported operations are: - # * union - # * disjoint_union - # * intersection - # * minus - # - # == Example - # - # # The union of all set variables in +sets+ must be subset of 1..17. - # sets.union.must_be.subset_of 1..17 - # - # # The intersection of all set variables must equal [1,3,5]. - # sets.intersection.must == [1,3,5] - # - # # The union of all set variable must be a subset of the set variable - # # +universe+. - # sets.union.must_be.subset_of universe - # - # # The same as above, but reified with the boolean variable - # # +is_within_universe+. - # sets.union.must_be.subset_of(universe, :reify => is_within_universe) - class ExpressionStub < Gecode::Constraints::Set::CompositeStub - def constrain_equal(variable, params, constrain) - enum, operation = @params.values_at(:lhs, :operation) - - if constrain - if operation == Gecode::Raw::SOT_INTER or - operation == Gecode::Raw::SOT_MINUS - variable.must_be.subset_of enum.first.upper_bound - else - variable.must_be.subset_of enum.upper_bound_range + # A module that gathers the classes and modules used in operation constraints. + module Operation #:nodoc: + class OperationSetOperand < Gecode::Set::ShortCircuitEqualityOperand #:nodoc: + def initialize(model, enum, operator) + super model + @enum = enum + @operator = operator + end + + def constrain_equal(set_operand, constrain_domain, propagation_options) + operation = Gecode::Util::SET_OPERATION_TYPES[@operator] + if constrain_domain + if operation == Gecode::Raw::SOT_INTER + set_operand.must_be.subset_of @enum.first.upper_bound + else + set_operand.must_be.subset_of @enum.upper_bound_range + end end + + Gecode::Raw::rel(@model.active_space, operation, + @enum.to_set_enum.bind_array, set_operand.to_set_var.bind) end - - Gecode::Raw::rel(@model.active_space, operation, enum.to_set_var_array, - variable.bind) end end -end \ No newline at end of file +end