lib/gecoder/interface/constraints/int/arithmetic.rb in gecoder-0.8.1 vs lib/gecoder/interface/constraints/int/arithmetic.rb in gecoder-0.8.2

- old
+ new

@@ -2,11 +2,25 @@ # Initiates an arithmetic absolute value constraint. def abs Gecode::Constraints::Int::Arithmetic::AbsExpressionStub.new(@model, :lhs => self) end + + # Initiates an arithmetic squared value constraint. + def squared + Gecode::Constraints::Int::Arithmetic::SquaredExpressionStub.new(@model, + :lhs => self) + end + # Initiates an arithmetic squared root constraint. + def sqrt + Gecode::Constraints::Int::Arithmetic::SquareRootExpressionStub.new(@model, + :lhs => self) + end + alias_method :square_root, :sqrt + + alias_method :pre_arith_mult, :* if instance_methods.include? '*' # Begins a multiplication constraint involving the two int variable. def *(var) if var.kind_of? Gecode::FreeIntVar @@ -50,11 +64,11 @@ # == Examples # # # The value of +x*y+ must be equal to their sum. # (x*y).must == x + y # - # # The valye of +x*y+ must be less than 17, with +bool+ as reification + # # The value of +x*y+ must be less than 17, with +bool+ as reification # # variable and +domain+ as strength. # (x*y).must_be.less_than(17, :reify => bool, :strength => :domain) class MultExpressionStub < Gecode::Constraints::Int::CompositeStub def constrain_equal(variable, params, constrain) lhs, lhs2 = @params.values_at(:lhs, :var) @@ -65,8 +79,71 @@ variable.must_be.in products.min..products.max end Gecode::Raw::mult(@model.active_space, lhs.bind, lhs2.bind, variable.bind, *propagation_options) + end + end + + # Describes a CompositeStub for the squared constraint, which constrain + # the squared value of the variable. + # + # == Examples + # + # # The value of +x*x+ must be equal to y. + # x.squared.must == y + # + # # The value of +x*x+ must be less than or equal to 16, with +bool+ as + # # reification variable and +domain+ as strength. + # x.squared.must_be.less_or_equal(16, :reify => bool, :strength => :domain) + class SquaredExpressionStub < Gecode::Constraints::Int::CompositeStub + def constrain_equal(variable, params, constrain) + lhs = @params[:lhs] + if constrain + min = lhs.min; max = lhs.max + products = [min*max, min*min, max*max] + variable.must_be.in products.min..products.max + end + + Gecode::Raw::sqr(@model.active_space, lhs.bind, variable.bind, + *propagation_options) + end + end + + # Describes a CompositeStub for the square root constraint, which constrain + # the rounded down square root of the variable. + # + # == Examples + # + # # The square root of +x+, rounded down, must equal y. + # x.square_root.must == y + # + # # The square root of +x+, rounded down, must be larger than 17, with + # # +bool+ as reification variable and +domain+ as strength. + # x.square_root.must_be.larger_than(17, :reify => bool, :strength => :domain) + class SquareRootExpressionStub < Gecode::Constraints::Int::CompositeStub + def constrain_equal(variable, params, constrain) + lhs = @params[:lhs] + if constrain + max = lhs.max + if max < 0 + # The left hand side does not have a real valued square root. + upper_bound = 0 + else + upper_bound = Math.sqrt(max).floor; + end + + min = lhs.min + if min < 0 + lower_bound = 0 + else + lower_bound = Math.sqrt(min).floor; + end + + variable.must_be.in lower_bound..upper_bound + end + + Gecode::Raw::sqrt(@model.active_space, lhs.bind, variable.bind, + *propagation_options) end end end