/******************************************************************************* * Copyright (c) 2009-2011 CWI * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * * Anastasia Izmaylova - A.Izmaylova@cwi.nl - CWI *******************************************************************************/ package org.rascalmpl.test.library; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.HashSet; import java.util.Set; import org.junit.Test; import org.rascalmpl.interpreter.types.FunctionType; import org.rascalmpl.library.cobra.RandomType; import org.rascalmpl.test.infrastructure.TestFramework; import org.rascalmpl.value.type.Type; public class RascalTypes extends TestFramework { @Test public void testLubAndGlb() { Set<Type> types = new HashSet<Type>(); RandomType rg = new RandomType(); rg.plusRascalTypes(true); for(int i = 0; i <= 1000; i++) { types.add(rg.getFunctionType(2)); types.add(rg.getReifiedType(5)); types.add(rg.getOverloadedFunctionType(2)); } for (Type t : types) { if (t.lub(t) != t) { fail("lub should be idempotent: " + t + " != " + t.lub(t)); } } for(Type t1 : types) { for(Type t2 : types) { Type lub1 = t1.lub(t2); Type lub2 = t2.lub(t1); if(lub1 != lub2) { System.err.println("Failure:"); System.err.println(t1 + ".lub(" + t2 + ") = " + lub1); System.err.println(t2 + ".lub(" + t1 + ") = " + lub2); fail("lub should be commutative"); } if(t1.comparable(t2)) { if (t1.isSubtypeOf(t2)) { assertTrue(t1.lub(t2).equivalent(t2)); } if(t2.isSubtypeOf(t1)) { assertTrue(t1.lub(t2).equivalent(t1)); } } if(t1 instanceof FunctionType && t2 instanceof FunctionType && t1 != t2) { FunctionType f1 = (FunctionType) t1; FunctionType f2 = (FunctionType) t2; Type lub = f1.lub(f2); Type glb = f1.glb(f2); // System.out.println("Checking subtyping: " + f1 + " and " + f2 + "; lub and glb: " + lub + ", " + glb); if(f1.isSubtypeOf(f2)) { assertTrue(f1.getReturnType().isSubtypeOf(f2.getReturnType())); assertTrue(f2.getArgumentTypes().isSubtypeOf(f1.getArgumentTypes())); } if(f2.isSubtypeOf(f1)) { assertTrue(f2.getReturnType().isSubtypeOf(f1.getReturnType())); assertTrue(f1.getArgumentTypes().isSubtypeOf(f2.getArgumentTypes())); } if(lub instanceof FunctionType) { FunctionType flub = (FunctionType) lub; assertTrue(f1.getReturnType().isSubtypeOf(flub.getReturnType())); assertTrue(flub.getArgumentTypes().isSubtypeOf(f1.getArgumentTypes())); assertTrue(f2.getReturnType().isSubtypeOf(flub.getReturnType())); assertTrue(flub.getArgumentTypes().isSubtypeOf(f2.getArgumentTypes())); } if(glb instanceof FunctionType) { FunctionType fglb = (FunctionType) glb; assertTrue(fglb.getReturnType().isSubtypeOf(f1.getReturnType())); assertTrue(f1.getArgumentTypes().isSubtypeOf(fglb.getArgumentTypes())); assertTrue(fglb.getReturnType().isSubtypeOf(f2.getReturnType())); assertTrue(f2.getArgumentTypes().isSubtypeOf(fglb.getArgumentTypes())); } } } } for(Type t : types) { if (t.glb(t) != t) { fail("glb should be idempotent: " + t + " != " + t.glb(t)); } } for(Type t1 : types) { for(Type t2 : types) { Type glb1 = t1.glb(t2); Type glb2 = t2.glb(t1); if(glb1 != glb2) { System.err.println("Failure:"); System.err.println(t1 + ".glb(" + t2 + ") = " + glb1); System.err.println(t2 + ".glb(" + t1 + ") = " + glb2); fail("glb should be commutative"); } if(t1.comparable(t2)) { if(t1.isSubtypeOf(t2)) { assertTrue(t1.glb(t2).equivalent(t1)); } if(t2.isSubtypeOf(t1)) { assertTrue(t1.glb(t2).equivalent(t2)); } } } } } }