package it.xsemantics.example.lambda.tests;
import it.xsemantics.example.lambda.lambda.Abstraction;
import it.xsemantics.example.lambda.lambda.Application;
import it.xsemantics.example.lambda.lambda.ArrowType;
import it.xsemantics.example.lambda.lambda.IntType;
import it.xsemantics.example.lambda.lambda.Parameter;
import it.xsemantics.example.lambda.lambda.Program;
import it.xsemantics.example.lambda.lambda.StringType;
import it.xsemantics.example.lambda.lambda.Term;
import it.xsemantics.example.lambda.lambda.Type;
import it.xsemantics.example.lambda.lambda.Variable;
import it.xtypes.runtime.TypeSystemResult;
import it.xtypes.runtime.TypingJudgmentEnvironment;
import static it.xsemantics.example.lambda.tests.util.LambdaTestsUtil.*;
public class LambdaTypeTest extends LambdaAbstractTests {
public void testParamSameType() throws Exception {
String programString = "lambda x : int . x x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Parameter parameter = abstraction.getParam();
TypeSystemResult<Type> result = typeSystem.typeAsType(parameter);
assertEquals(parameter.getType(), result.getValue());
TypingJudgmentEnvironment environment = new TypingJudgmentEnvironment();
environment.add(parameter, parameter.getType());
Application application = getApplication(abstraction.getTerm());
Variable x = getVariable(application.getFun());
result = typeSystem.typeAsType(environment, x);
assertEquals(parameter.getType(), result.getValue());
x = getVariable(application.getArg());
result = typeSystem.typeAsType(environment, x);
assertEquals(parameter.getType(), result.getValue());
}
public void testParamSameType2() throws Exception {
String programString = "lambda x . x x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Parameter parameter = abstraction.getParam();
TypeSystemResult<Type> result = typeSystem.typeAsType(parameter);
Type typeResult = result.getValue();
String typeVariable = getTypeVariable(typeResult).getTypevarName();
assertEquals("X1", typeVariable);
TypingJudgmentEnvironment environment = new TypingJudgmentEnvironment();
environment.add(parameter, typeResult);
Application application = getApplication(abstraction.getTerm());
Variable x = getVariable(application.getFun());
result = typeSystem.typeAsType(environment, x);
assertEquals(typeResult, result.getValue());
x = getVariable(application.getArg());
result = typeSystem.typeAsType(environment, x);
assertEquals(typeResult, result.getValue());
}
public void testParamWithType() throws Exception {
String programString = "lambda x : int . x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Parameter parameter = abstraction.getParam();
TypeSystemResult<Type> result = typeSystem.typeAsType(parameter);
assertEquals(parameter.getType(), result.getValue());
}
public void testParamWithNoType() throws Exception {
String programString = "lambda x . x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Parameter parameter = abstraction.getParam();
TypeSystemResult<Type> result = typeSystem.typeAsType(parameter);
assertEquals("X1", getTypeVariable(result.getValue()).getTypevarName());
}
public void testIntConstantResult() throws Exception {
String programString = "lambda x . 10";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
TypeSystemResult<Type> result = typeSystem.typeAsType(abstraction);
assertEquals("a -> int", rep(result.getValue()));
}
public void testInferIntArrowTypeFromBody() throws Exception {
String programString = "lambda x . -x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
TypeSystemResult<Type> result = typeSystem.typeAsType(abstraction);
assertEquals("int -> int", rep(result.getValue()));
assertApplicationTrace("./output/testInferIntArrowTypeFromBody.txt",
result);
}
public void testIntConstant() throws Exception {
String programString = "lambda x : X . 10";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction.getTerm();
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
printApplicationTrace(result);
assertTrue(result.getValue() instanceof IntType);
}
public void testStringConstant() throws Exception {
String programString = "lambda x : X . 'foo'";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction.getTerm();
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
printApplicationTrace(result);
assertTrue(result.getValue() instanceof StringType);
}
public void testTypeAbstractionWithNoType() throws Exception {
String programString = "lambda x . x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertApplicationTrace("./output/testTypeAbstractionWithNoType.txt",
result);
Type type = result.getValue();
ArrowType arrowType = getArrowType(type);
assertEquals("X1", getTypeVariable(arrowType.getLeft()).getTypevarName());
assertEquals("X1", getTypeVariable(arrowType.getRight()).getTypevarName());
}
public void testTypeAbstractionWithType() throws Exception {
String programString = "lambda x : string . x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertApplicationTrace("./output/testTypeAbstractionWithType.txt",
result);
ArrowType arrowType = getArrowType(result.getValue());
assertTrue(arrowType.getLeft() instanceof StringType);
assertTrue(arrowType.getRight() instanceof StringType);
}
public void testTypeAbstractionNested() throws Exception {
String programString = "lambda x . lambda y. x y";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertApplicationTrace("./output/testTypeAbstractionNested.txt", result);
assertEquals("(a -> b) -> a -> b", rep(result.getValue()));
}
public void testTypeAbstractionNested2() throws Exception {
String programString = "lambda x . lambda y. y x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
// assertApplicationTrace("./output/testTypeAbstractionNested.txt",
// result);
assertEquals("a -> (a -> b) -> b", rep(result.getValue()));
}
public void testTypeVarBodyWithNoEnv() throws Exception {
String programString = "lambda x . x";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction.getTerm();
// try to type body with no mapping for the param in the environment
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertFailureOutput("./output/testTypeVarBodyWithNoEnv.txt", result);
}
public void testTypeApplication() throws Exception {
String programString = "(lambda x . x) 10";
Program program = getLambdaProgram(programString);
Application application = getApplication(program.getTerm());
Term term = application;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
// printFailureTrace(result);
repOut(result.getValue());
assertApplicationTrace("./output/testTypeApplication.txt", result);
assertTrue(result.getValue() instanceof IntType);
}
public void testTypeApplicationNested() throws Exception {
String programString = "(lambda x . lambda y . y) 10";
Program program = getLambdaProgram(programString);
Application application = getApplication(program.getTerm());
Term term = application;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertApplicationTrace("./output/testTypeApplicationNested.txt", result);
assertEquals("a -> a", rep(result.getValue()));
}
public void testOmega() throws Exception {
String programString = "lambda x . x x";
Program program = getLambdaProgram(programString);
Term term = program.getTerm();
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
// should fail
assertFailureContainsStringInTrace(
result,
"rule UnifyVariableArrow failed: [X1 -> (TypeVariable 'X2' -> TypeVariable 'X3'), x -> TypeVariable 'X1'] |- TypeVariable 'X2' == (TypeVariable 'X2' -> TypeVariable 'X3')");
assertFailureContainsStringInTrace(
result,
"NotOccurVarInArrow [X1 -> (TypeVariable 'X2' -> TypeVariable 'X3'), x -> TypeVariable 'X1'] |- TypeVariable 'X2' !- (TypeVariable 'X2' -> TypeVariable 'X3')");
}
public void testInferArgFunType() throws Exception {
String programString = "lambda f . f 10";
Program program = getLambdaProgram(programString);
Term term = program.getTerm();
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(int -> a) -> a", rep(result.getValue()));
}
public void testInferArgFunType2() throws Exception {
String programString = "lambda f . -(f 10)";
Program program = getLambdaProgram(programString);
Term term = program.getTerm();
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(int -> int) -> int", rep(result.getValue()));
}
public void testTypeIntArgFunType() throws Exception {
String programString = "lambda f : int -> int . -(f 10)";
Program program = getLambdaProgram(programString);
Term term = program.getTerm();
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(int -> int) -> int", rep(result.getValue()));
}
public void testTypeDouble() throws Exception {
String programString = "lambda f . (lambda x. (f (f x)))";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(a -> a) -> a -> a", rep(result.getValue()));
}
public void testTypeCompose() throws Exception {
String programString = "lambda f . lambda g. lambda x. (f (g x))";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(a -> b) -> (c -> a) -> c -> b", rep(result.getValue()));
}
public void testTypeCompose2() throws Exception {
String programString = "lambda f . lambda g. lambda x. (g (f x))";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(a -> b) -> (b -> c) -> a -> c", rep(result.getValue()));
}
public void testTypeComposeWithInferredInt() throws Exception {
String programString = "lambda f . lambda g. lambda x. (g (f -x))";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(int -> a) -> (a -> b) -> int -> b",
rep(result.getValue()));
}
public void testTypeComposeWithInferredInt2() throws Exception {
String programString = "lambda f . lambda g. lambda x. (g -(f x))";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(a -> int) -> (int -> b) -> a -> b",
rep(result.getValue()));
}
public void testTypeComposeWithInferredInt3() throws Exception {
String programString = "lambda f . lambda g. lambda x. -(g (f x))";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(a -> b) -> (b -> int) -> a -> int",
rep(result.getValue()));
}
public void testTypeComposeWithInferredInt4() throws Exception {
String programString = "lambda f . lambda g. f (g 2)";
Program program = getLambdaProgram(programString);
Abstraction abstraction = getAbstraction(program.getTerm());
Term term = abstraction;
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("(a -> b) -> (int -> a) -> b",
rep(result.getValue()));
}
public void testTypeAbstractionAbstraction() throws Exception {
String programString = "lambda x . lambda y . y";
Program program = getLambdaProgram(programString);
Term term = program.getTerm();
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("a -> b -> b", rep(result.getValue()));
}
public void testTypeAbstractionAbstraction2() throws Exception {
String programString = "lambda x . lambda y . x";
Program program = getLambdaProgram(programString);
Term term = program.getTerm();
TypeSystemResult<Type> result = typeSystem.typeAsType(term);
assertEquals("a -> b -> a", rep(result.getValue()));
}
}