lib/gecoder/interface/constraints/bool_enum/channel.rb in gecoder-0.8.3 vs lib/gecoder/interface/constraints/bool_enum/channel.rb in gecoder-0.9.0

- old
+ new

@@ -1,64 +1,68 @@ -module Gecode::Constraints::BoolEnum - class Expression - # Adds a channel constraint on the variables in the enum with the specified - # integer variable. Beyond the common options the channel constraint can +module Gecode::BoolEnum + class BoolEnumConstraintReceiver + # Constrains this enumeration to "channel" +integer_operand+. This + # constrains the integer operand to take value i exactly when the + # operand at index i in the boolean enumeration is true and the others + # are false. + # + # Beyond the common options the channel constraint can # also take the following option: # - # [:offset] Specifies an offset for the integer variable. If the offset is - # set to k then the integer variable takes value i+k exactly - # when the variable at index i in the boolean enumeration is true - # and the rest are false. - def channel(int_var, options = {}) + # [:offset] Specifies an offset for the integer operand. If the offset is + # set to k then the integer operand takes value i+k exactly + # when the operand at index i in the boolean enumeration is + # true and the rest are false. + # + # Neither reification nor negation is supported. The int operand + # and the enumeration can be interchanged. + # + # ==== Examples + # + # # Constrains the enumeration called +option_is_selected+ to be false + # # in the first four positions and have exactly one true operand in + # # the other. + # option_is_selected.must.channel selected_option_index + # selected_option_index.must_be > 3 + # + # # Constrains the enumeration called +option_is_selected+ to be false + # # in the first five positions and have exactly one true operand in + # # the other. + # selected_option_index.must.channel(option_is_selected, :offset => 1) + # selected_option_index.must_be > 3 + def channel(integer_operand, options = {}) if @params[:negate] raise Gecode::MissingConstraintError, 'A negated channel constraint ' + 'is not implemented.' end if options.has_key? :reify raise ArgumentError, 'The channel constraint does not support the ' + 'reification option.' end - unless int_var.kind_of? Gecode::FreeIntVar - raise TypeError, "Expected an integer variable, got #{int_var.class}." + unless integer_operand.respond_to? :to_int_var + raise TypeError, 'Expected an integer operand, got ' + + "#{integer_operand.class}." end - @params.update(:rhs => int_var, :offset => options.delete(:offset) || 0) - @params.update(Gecode::Constraints::Util.decode_options(options)) + @params.update(:rhs => integer_operand, + :offset => options.delete(:offset) || 0) + @params.update(Gecode::Util.decode_options(options)) @model.add_constraint Channel::ChannelConstraint.new(@model, @params) end - # Adds a channel constraint on the variables in the enum with the specified - # set variable. - provide_commutivity(:channel){ |rhs, _| rhs.kind_of? Gecode::FreeSetVar } + # Provides commutativity with SetConstraintReceiver#channel + provide_commutativity(:channel){ |rhs, _| rhs.respond_to? :to_set_var } end # A module that gathers the classes and modules used in channel constraints - # involving one boolean enum and one integer variable. + # involving one boolean enum and one integer operand. module Channel #:nodoc: - # Describes a channel constraint that "channels" an enumeration of - # boolean variables with an integer variable. This constrains the integer - # variable to take value i exactly when the variable at index i in the - # boolean enumeration is true and the others are false. - # - # Neither reification nor negation is supported. The int variable - # and the enumeration can be interchanged. - # - # == Examples - # - # # Constrains the enumeration called +option_is_selected+ to be false in the - # # first four positions and have exactly one true variable in the other. - # option_is_selected.must.channel selected_option_index - # selected_option_index.must_be > 3 - # - # # Constrains the enumeration called +option_is_selected+ to be false in the - # # first five positions and have exactly one true variable in the other. - # selected_option_index.must.channel(option_is_selected, :offset => 1) - # selected_option_index.must_be > 3 - class ChannelConstraint < Gecode::Constraints::Constraint + class ChannelConstraint < Gecode::Constraint #:nodoc: def post lhs, rhs, offset = @params.values_at(:lhs, :rhs, :offset) - Gecode::Raw::channel(@model.active_space, lhs.to_bool_var_array, - rhs.bind, offset, *propagation_options) + Gecode::Raw::channel(@model.active_space, + lhs.to_bool_enum.bind_array, rhs.to_int_var.bind, + offset, *propagation_options) end end end end