#!/usr/bin/ruby $:.unshift File.join(File.dirname(__FILE__), "..", "lib") require 'test/unit' require 'TupleConstraint' require 'Variable' require 'Domain' module ConstraintSolver class TupleConstraintTest < Test::Unit::TestCase def setup @x = Variable.new("x", Domain.new([ 1, 2 ].to_set)) @y = Variable.new("y", Domain.new([ 1, 2 ].to_set)) @tuples = [ [ 1, 1 ], [ 2, 2 ] ] @constraint = TupleConstraint.new([ @x, @y ], @tuples) end def testConstructor assert_raise(ArgumentError) { TupleConstraint.new } assert_raise(ArgumentError) { TupleConstraint.new([ @x, @y ], [ [ 1, 2 ], [ 1 ] ]) } assert_nothing_raised { TupleConstraint.new([ @x, @y ], @tuples) } assert_nothing_raised { TupleConstraint.new([ @x, @y ], @tuples, false) } assert_nothing_raised { TupleConstraint.new([ @x, @y ], @tuples, 0) } end def testAssigned assert_equal(false, @constraint.allAssigned?) @x.value = 1 assert_equal(false, @constraint.allAssigned?) @y.value = 1 assert_equal(true, @constraint.allAssigned?) @x.reset @y.reset end def testInclude assert_equal(true, @constraint.include?(@x)) assert_equal(true, @constraint.include?(@y)) assert_equal(false, @constraint.include?(Variable.new("2", [ 3 ].to_set))) end def testHoldsAllowed assert_equal(true, @constraint.holds?) @x.value = 1 @y.value = 1 assert_equal(true, @constraint.holds?) @x.value = 2 @y.value = 2 assert_equal(true, @constraint.holds?) @x.value = 1 @y.value = 2 assert_equal(false, @constraint.holds?) @x.value = 2 @y.value = 1 assert_equal(false, @constraint.holds?) @y.reset @x.value = 2 assert_equal(true, @constraint.holds?) @x.reset @y.value = 1 assert_equal(true, @constraint.holds?) @y.reset end def testHoldsDisallowed constraint = TupleConstraint.new([ @x, @y ], @tuples, false) assert_equal(true, constraint.holds?) @x.value = 1 @y.value = 1 assert_equal(false, constraint.holds?) @x.value = 2 @y.value = 2 assert_equal(false, constraint.holds?) @x.value = 1 @y.value = 2 assert_equal(true, constraint.holds?) @x.value = 2 @y.value = 1 assert_equal(true, constraint.holds?) @y.reset @x.value = 2 assert_equal(true, constraint.holds?) @x.reset @y.value = 1 assert_equal(true, constraint.holds?) end def testEquals assert_equal(TupleConstraint.new([ @x, @y ], @tuples), @constraint) assert_not_equal(TupleConstraint.new([ Variable.new("z", Domain.new([ 1, 2 ].to_set)), @y ], @tuples), @constraint) assert_not_equal(TupleConstraint.new([ @x, @y ], [ [ 1, 1 ] ]), @constraint) end def testReviseAllowed x = Variable.new("x", Domain.new([ 1, 2, 3 ].to_set)) y = Variable.new("y", Domain.new([ 1, 2, 3 ].to_set)) z = Variable.new("z", Domain.new([ 1, 2, 3 ].to_set)) constraint = TupleConstraint.new([ x, y, z ], [ [ 1, 2, 3 ], [ 3, 2, 1 ], [ 3, 3, 3 ] ]) assert_equal([ [ x, y, z ], 0, false ], constraint.revise) assert_equal([ 1, 3 ].to_set, x.domain.values) assert_equal([ 2, 3 ].to_set, y.domain.values) assert_equal([ 1, 3 ].to_set, z.domain.values) x.domain.undoPruning y.domain.undoPruning z.domain.undoPruning x.value = 1 assert_equal([ [ y, z ], 0, false ], constraint.revise) assert_equal([ 2 ].to_set, y.domain.values) assert_equal([ 3 ].to_set, z.domain.values) x.reset y.domain.undoPruning z.domain.undoPruning z.value = 3 assert_equal([ [ x, y ], 0, false ], constraint.revise) assert_equal([ 1, 3 ].to_set, x.domain.values) assert_equal([ 2, 3 ].to_set, y.domain.values) z.reset x.domain.undoPruning y.domain.undoPruning x.value = 2 assert_equal([ [ y ], 0, true ], constraint.revise) end def testReviseDisallowed x = Variable.new("x", Domain.new([ 1, 2, 3 ].to_set)) y = Variable.new("y", Domain.new([ 1, 2, 3 ].to_set)) z = Variable.new("z", Domain.new([ 1, 2, 3 ].to_set)) constraint = TupleConstraint.new([ x, y, z ], [ [ 1, 2, 3 ], [ 3, 2, 1 ], [ 3, 3, 3 ] ], false) assert_equal([ [], 0, false ], constraint.revise) x.value = 1 assert_equal([ [ y, z ], 0, false ], constraint.revise) assert_equal([ 1, 3 ].to_set, y.domain.values) assert_equal([ 1, 2 ].to_set, z.domain.values) y.domain.undoPruning z.domain.undoPruning x.reset z.value = 3 assert_equal([ [ x, y ], 0, false ], constraint.revise) assert_equal([ 2 ].to_set, x.domain.values) assert_equal([ 1 ].to_set, y.domain.values) x.domain.undoPruning y.domain.undoPruning z.reset end end end