Class: Gecode::BoolEnum::BoolEnumConstraintReceiver

Inherits:
ConstraintReceiver show all
Defined in:
lib/gecoder/interface/constraints/bool_enum_constraints.rb,
lib/gecoder/interface/constraints/bool_enum/channel.rb,
lib/gecoder/interface/constraints/bool_enum/extensional.rb

Overview

BoolEnumConstraintReceiver contains all constraints that can be placed on a BoolEnumOperand.

Constraints are placed by calling BoolEnumOperand#must (or any other of the variations defined in Operand), which produces a BoolEnumConstraintReceiver from which the desired constraint can be used.

Examples

Constrains bool_enum, with three boolean operands, to take the value of the tuples [false, true, false] or [true, false, true] using BoolEnumConstraintReceiver#in:

bool_enum.must_be.in [[false, true, false], [true, false, true]]

Constrains bool_enum to channel int_operand using BoolEnumConstraintReceiver#channel:

bool_enum.must.channel int_operand

Instance Method Summary collapse

Constructor Details

#initialize(model, params) ⇒ BoolEnumConstraintReceiver

Raises TypeError unless the left hand side is an bool enum operand.



72
73
74
75
76
77
78
# File 'lib/gecoder/interface/constraints/bool_enum_constraints.rb', line 72

def initialize(model, params) #:nodoc:
  super

  unless params[:lhs].respond_to? :to_bool_enum
    raise TypeError, 'Must have bool enum operand as left hand side.'
  end
end

Instance Method Details

#channel(integer_operand, options = {}) ⇒ Object

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 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


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/gecoder/interface/constraints/bool_enum/channel.rb', line 32

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 integer_operand.respond_to? :to_int_var
    raise TypeError, 'Expected an integer operand, got ' + 
      "#{integer_operand.class}."
  end
  
  @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

#in(tuples, options = {}) ⇒ Object

Constrains all the operands in this enumeration to be equal to one of the specified tuples. Neither negation nor reification is supported.

Examples

# Constrains the three boolean operands in +bools+ to either
# be true, false, true, or false, false, true.
bools.must_be.in [[true, false, true], [false, false, true]]

# The same as above, but preferring speed over low memory usage.
bools.must_be.in([[true, false, true], [false, false, true]], 
  :kind => :speed)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/gecoder/interface/constraints/bool_enum/extensional.rb', line 16

def in(tuples, options = {})
  if @params[:negate]
    raise Gecode::MissingConstraintError, 'A negated tuple constraint is ' +
      'not implemented.'
  end
  unless options[:reify].nil?
    raise ArgumentError, 'Reification is not supported by the tuple ' + 
      'constraint.'
  end
  
  util = Gecode::Util
  
  # Check that the tuples are correct.
  expected_size = @params[:lhs].size
  util::Extensional.perform_tuple_checks(tuples, expected_size) do |tuple|
    unless tuple.all?{ |x| x.kind_of?(TrueClass) or x.kind_of?(FalseClass) }
      raise TypeError, 'All tuples must contain booleans.'
    end
  end
  
  @params[:tuples] = tuples
  @model.add_constraint Extensional::TupleConstraint.new(@model, 
    @params.update(Gecode::Util.decode_options(options)))
end

#match(regexp, options = {}) ⇒ Object

Constrains the sequence of operands in this enumeration to match a specified regexp in the boolean domain. Neither negation nor reification is supported.

The regular expressions are specified as described in IntEnumConstraintReceiver#match but true and false can be used instead of integers.

Examples

# Constrains the two boolean operands in +bools+ to be false
# and true respectively.
bools.must.match [false, true]

# Constrains the boolean operands in +bools+ to be false,
# except for three consecutive operands which should be true
# followed by false followed by true.
bools.must.match [repeat(false), true, false, true, repeat(false)]]


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/gecoder/interface/constraints/bool_enum/extensional.rb', line 60

def match(regexp, options = {})
  if @params[:negate]
    raise Gecode::MissingConstraintError, 'A negated regexp constraint ' +
      'is not implemented.'
  end
  unless options[:reify].nil?
    raise ArgumentError, 'Reification is not supported by the regexp ' + 
      'constraint.'
  end

  @params[:regexp] = 
    Gecode::Util::Extensional.parse_regexp regexp
  @params.update Gecode::Util.decode_options(options)
  @model.add_constraint Extensional::RegexpConstraint.new(@model, @params)
end