# A module that deals with the operands, properties and constraints of # integer variables. module Gecode::Int #:nodoc: # A IntOperand is a combination of variables on which the # constraints defined in IntConstraintReceiver can be placed. # # Integer operands can be created either by using # Gecode::Mixin#int_var et al, or by using properties that produce # integer operands. The operands, no matter how they were created, # all respond to the properties defined by IntOperand. # # ==== Examples # # Produces a single integer operand (more specifically an IntVar) with # domain 0..9 inside a problem formulation, using # Gecode::Mixin#int_var: # # int_operand = int_var(0..9) # # Uses the IntOperand#+ property to produce a new integer # operand representing +int_operand1+ plus +int_operand2+: # # new_int_operand = int_operand1 + int_operand2 # # Uses the IntEnumOperand#max property to produce a new # integer operand representing the maximum value of the integer operands # in the enumeration +int_enum+: # # new_int_operand = int_enum.max # # Uses the IntEnumOperand#[] property to produce a new integer operand # representing the integer operand at the index decided by # +int_operand+ (which can change during search) in the enumeration # +int_enum+: # # new_int_operand = int_enum[int_operand] # # Uses the SetOperand#size property to produce a new integer operand # representing the size of +set_operand+: # # new_int_operand = set_operand.size # #-- # Classes that mix in IntOperand must define #model and #to_int_var . module IntOperand include Gecode::Operand def method_missing(method, *args) #:nodoc: if Gecode::IntVar.instance_methods.include? method.to_s # Delegate to the int var. to_int_var.method(method).call(*args) else super end end private def construct_receiver(params) IntConstraintReceiver.new(model, params) end end # An operand that short circuits integer equality. class ShortCircuitEqualityOperand #:nodoc: include Gecode::Int::IntOperand attr :model def initialize(model) @model = model end def construct_receiver(params) params.update(:lhs => self) receiver = IntConstraintReceiver.new(@model, params) op = self receiver.instance_eval{ @short_circuit = op } class <: # # int_operand.must > 5 # # Constrains +int_operand1+ plus +int_operand2+ to be strictly # greater than 5 using the IntOperand#+ property and # IntConstraintReceiver#>: # # (int_operand1 + int_operand2).must > 5 # # Constrains the maximum value of the integer operands in +int_enum+ to # _not_ be in the range 3..7 using the IntEnumOperand#max property and # IntConstraintReceiver#in: # # int_enum.max.must_not_be.in 3..7 # # Constrains the integer operand at position +int_operand+ in # +int_enum+, an enumeration of integer operands, to be greater than # or equal to +int_operand2+. This uses the IntEnumOperand#[] property # and IntConstraintReceiver#>=: # # int_enum[int_operand].must >= int_operand2 # # The same as above, but specifying that strength :domain should be # used and that the constraint should be reified with +bool_operand+: # # int_enum[int_operand].must_be.greater_or_equal(int_operand2, :strength => :domain, :reify => bool_operand) # class IntConstraintReceiver < Gecode::ConstraintReceiver # Raises TypeError unless the left hand side is an int operand. def initialize(model, params) #:nodoc: super unless params[:lhs].respond_to? :to_int_var raise TypeError, 'Must have int operand as left hand side.' end end end end require 'gecoder/interface/constraints/int/relation' require 'gecoder/interface/constraints/int/linear' require 'gecoder/interface/constraints/int/domain' require 'gecoder/interface/constraints/int/arithmetic' require 'gecoder/interface/constraints/int/channel'