class Top {}

class Middle extends Top {}

class Bottom extends Middle {}

class Up {
def cv(t: Top) = "Up";
def inv(m: Middle) = "Up";
def ctv(b: Bottom) = "Up";
}

class Down extends Up {
def cv(m: Middle) = "Down";
override def inv(m: Middle) = "Down"; //override mandatory
def ctv(m: Middle) = "Down";
}

object Test with Application {
def testcv1(t: Up) = {
Console.println(t.cv(new Top()));
Console.println(t.cv(new Middle()));
Console.println(t.cv(new Bottom()));
}
def testcv2(d: Down) = {
Console.println("type mismatch; found : Top required: Middle");//d.cv(new Top()));
Console.println(d.cv(new Middle()));
Console.println(d.cv(new Bottom()));
}
def testinv1(t: Up) = {
Console.println("type mismatch; found : Top required: Middle");//t.inv(new Top()));
Console.println(t.inv(new Middle()));
Console.println(t.inv(new Bottom()));
}
def testinv2(d: Down) = {
Console.println("type mismatch; found : Top required: Middle");//d.inv(new Top()));
Console.println(d.inv(new Middle()));
Console.println(d.inv(new Bottom()));
}
def testctv1(t: Up) = {
Console.println("type mismatch; found : Top required: Bottom");//t.ctv(new Top()));
Console.println("type mismatch; found : Middle required: Bottom");//t.ctv(new Middle()));
Console.println(t.ctv(new Bottom()));
}
def testctv2(d: Down) = {
Console.println("type mismatch; found : Top required: Middle");//d.ctv(new Top()));
Console.println(d.ctv(new Middle()));
Console.println(d.ctv(new Bottom()));
}
// Fisrt test Suite
Console.println("First column");
testcv1(new Up());
testinv1(new Up());
testctv1(new Up());
// Fisrt test Suite
Console.println("Second column");
testcv2(new Down());
testinv2(new Down());
testctv2(new Down());
// Fisrt test Suite
Console.println("Third column");
testcv1(new Down());
testinv1(new Down());
testctv1(new Down());
}

/* Results

$ scala Test
First column
Up
Up
Up
type mismatch; found : Top required: Middle
Up
Up
type mismatch; found : Top required: Bottom
type mismatch; found : Middle required: Bottom
Up
Second column
type mismatch; found : Top required: Middle
Down
Down
type mismatch; found : Top required: Middle
Down
Down
type mismatch; found : Top required: Middle
Down
Down
Third column
Up
Up
Up
type mismatch; found : Top required: Middle
Down
Down
type mismatch; found : Top required: Bottom
type mismatch; found : Middle required: Bottom
Up

*/