Class | ConstraintSolver::BinaryConstraint |
In: |
lib/BinaryConstraint.rb
|
Parent: | AbstractConstraint |
Represents a binary constraint.
lhs | [R] | |
relation | [R] | |
rhs | [R] |
Initialises a new binary constraint. The arguments are the variable at the left hand side of the relation, the variable at the right hand side of the relation and the relation itself.
# File lib/BinaryConstraint.rb, line 13 def initialize(lhs, rhs, relation) if relation.arity != 2 raise ArgumentError, "The relation given must take two arguments!" end @lhs = lhs @rhs = rhs @relation = relation end
# File lib/BinaryConstraint.rb, line 49 def ==(constraint) return false unless constraint.kind_of?(BinaryConstraint) (@lhs == constraint.lhs) and (@rhs == constraint.rhs) and (@relation == constraint.relation) end
# File lib/BinaryConstraint.rb, line 54 def each [ @lhs, @rhs ].each { |variable| yield variable } end
Checks whether the relation returns true when called with the values assigned to left hand side and right hand side.
# File lib/BinaryConstraint.rb, line 24 def holds? if allAssigned? @relation.call(@lhs.value, @rhs.value) else raise RuntimeError, "Cannot check whether " + self.to_s + " holds because not all variables have been assigned values!" end end
# File lib/BinaryConstraint.rb, line 37 def include?(variable) (@lhs == variable) or (@rhs == variable) end
# File lib/BinaryConstraint.rb, line 60 def revise # TODO: check bounds consistency rather than everything explicitly checks = 0 revisedVariables = Array.new pruneList = Set.new assigned = [ @lhs, @rhs ].find { |var| var.assigned? } if assigned.nil? pruneList = @lhs.values.clone pruneListRight = @rhs.values.clone @lhs.domain.each { |lvalue| @lhs.value = lvalue @rhs.domain.each { |rvalue| @rhs.value = rvalue checks += 1 if self.holds? pruneList.delete(lvalue) pruneListRight.delete(rvalue) end } @rhs.reset } @lhs.reset unless pruneList.empty? @lhs.domain.prune(pruneList) revisedVariables << @lhs end unless pruneListRight.empty? @rhs.domain.prune(pruneListRight) revisedVariables << @rhs end else unassigned = ([ @lhs, @rhs ] - [ assigned ]).first unassigned.domain.each { |value| unassigned.value = value checks += 1 pruneList << value unless self.holds? } unassigned.reset unless pruneList.empty? unassigned.domain.prune(pruneList) revisedVariables << unassigned end end return revisedVariables, checks end
# File lib/BinaryConstraint.rb, line 41 def to_s @lhs.name + " " + @relation.to_s + " " + @rhs.name end