use of com.rockwellcollins.atc.agree.AgreeTypeSystem.TypeDef in project AGREE by loonwerks.
the class AgreeValidator method checkAssume.
@Check(CheckType.FAST)
public void checkAssume(AssumeStatement assume) {
Classifier comp = assume.getContainingClassifier();
if (!(comp instanceof ComponentType)) {
error(assume, "Assume statements are allowed only in component types");
}
// the expression could be null if a pattern is used
Expr expr = assume.getExpr();
if (expr != null) {
TypeDef exprType = AgreeTypeSystem.infer(expr);
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.BoolTypeDef, exprType)) {
error(assume, "Expression for assume statement is of type '" + nameOfTypeDef(exprType) + "' but must be of type 'bool'");
}
}
if (assume.getName() == null) {
info(assume, "It is recommended that assume statements be named." + " (Hint: an identifier may be placed between the \"assume\" keyword and the quoted description.)");
}
}
use of com.rockwellcollins.atc.agree.AgreeTypeSystem.TypeDef in project AGREE by loonwerks.
the class AgreeValidator method checkConstStatement.
@Check(CheckType.FAST)
public void checkConstStatement(ConstStatement constStat) {
TypeDef expected = AgreeTypeSystem.typeDefFromType(constStat.getType());
TypeDef actual = AgreeTypeSystem.infer(constStat.getExpr());
if (!AgreeTypeSystem.typesEqual(expected, actual)) {
error(constStat, "The assumed type of constant statement '" + constStat.getName() + "' is '" + expected + "' but the actual type is '" + actual + "'");
}
// check for constant cycles
Set<ConstStatement> constClosure = new HashSet<>();
Set<ConstStatement> prevClosure;
constClosure.add(constStat);
// quick and dirty cycle check
do {
prevClosure = new HashSet<>(constClosure);
for (ConstStatement constFrontElem : prevClosure) {
List<SelectionExpr> nestIds = EcoreUtil2.getAllContentsOfType(constFrontElem, SelectionExpr.class);
for (Expr nestId : nestIds) {
while (nestId instanceof SelectionExpr) {
NamedElement base = ((SelectionExpr) nestId).getField();
if (base instanceof ConstStatement) {
ConstStatement closConst = (ConstStatement) base;
if (closConst.equals(constStat)) {
error(constStat, "The expression for constant statment '" + constStat.getName() + "' is part of a cyclic definition");
break;
}
constClosure.add(closConst);
}
nestId = ((SelectionExpr) nestId).getTarget();
}
NamedElement base = ((NamedElmExpr) nestId).getElm();
if (base instanceof ConstStatement) {
ConstStatement closConst = (ConstStatement) base;
if (closConst.equals(constStat)) {
error(constStat, "The expression for constant statment '" + constStat.getName() + "' is part of a cyclic definition");
break;
}
constClosure.add(closConst);
}
}
}
} while (!prevClosure.equals(constClosure));
for (Expr e : EcoreUtil2.getAllContentsOfType(constStat.getExpr(), Expr.class)) {
if (!exprIsConstant(e)) {
error(e, "Non-constant expression in constant declaration");
return;
}
}
}
use of com.rockwellcollins.atc.agree.AgreeTypeSystem.TypeDef in project AGREE by loonwerks.
the class AgreeValidator method checkBinaryExpr.
@Check(CheckType.FAST)
public void checkBinaryExpr(BinaryExpr binExpr) {
checkTypeExists(binExpr.getLeft());
checkTypeExists(binExpr.getRight());
TypeDef typeLeft = AgreeTypeSystem.infer(binExpr.getLeft());
TypeDef typeRight = AgreeTypeSystem.infer(binExpr.getRight());
String op = binExpr.getOp();
Expr rightSide = binExpr.getRight();
Expr leftSide = binExpr.getLeft();
boolean isInLinearizationBodyExpr = isInLinearizationBody(binExpr);
boolean rightSideConst = exprIsConst(rightSide);
boolean leftSideConst = exprIsConst(leftSide);
switch(op) {
case "->":
if (isInLinearizationBodyExpr) {
error(binExpr, "Arrow '->' expressions are not allowed in linearization body expressions.");
} else {
if (!AgreeTypeSystem.typesEqual(typeRight, typeLeft)) {
error(binExpr, "left and right sides of binary expression '" + op + "' are of type '" + nameOfTypeDef(typeLeft) + "' and '" + nameOfTypeDef(typeRight) + "', but must be of the same type");
}
}
return;
case "=>":
case "<=>":
case "and":
case "or":
if (isInLinearizationBodyExpr) {
error(binExpr, "Logical expressions (like '" + op + "') are not allowed in linearization body expressions.");
} else {
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.BoolTypeDef, typeLeft)) {
error(binExpr, "left side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeLeft) + "' but must be of " + "type 'bool'");
}
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.BoolTypeDef, typeRight)) {
error(binExpr, "right side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeRight) + "' but must be of" + " type 'bool'");
}
}
return;
case "=":
case "<>":
case "!=":
if (isInLinearizationBodyExpr) {
error(binExpr, "Logical comparison expressions (like '" + op + "') are not allowed in linearization body expressions.");
} else {
if (!AgreeTypeSystem.typesEqual(typeRight, typeLeft)) {
error(binExpr, "left and right sides of binary expression '" + op + "' are of type '" + nameOfTypeDef(typeLeft) + "' and '" + nameOfTypeDef(typeRight) + "', but must be of the same type");
}
}
return;
case "<":
case "<=":
case ">":
case ">=":
if (isInLinearizationBodyExpr) {
error(binExpr, "Comparison expressions (like '" + op + "') are not allowed in linearization body expressions.");
} else {
if (!AgreeTypeSystem.typesEqual(typeRight, typeLeft)) {
error(binExpr, "left and right sides of binary expression '" + op + "' are of type '" + nameOfTypeDef(typeLeft) + "' and '" + nameOfTypeDef(typeRight) + "', but must be of the same type");
}
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.IntTypeDef, typeLeft) && !AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.RealTypeDef, typeLeft)) {
error(binExpr, "left side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeLeft) + "' but must be of type" + "'int' or 'real'");
}
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.IntTypeDef, typeRight) && !AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.RealTypeDef, typeRight)) {
error(binExpr, "right side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeRight) + "' but must be of type" + "'int' or 'real'");
}
}
return;
case "+":
case "-":
case "*":
if (!AgreeTypeSystem.typesEqual(typeRight, typeLeft)) {
error(binExpr, "left and right sides of binary expression '" + op + "' are of type '" + nameOfTypeDef(typeLeft) + "' and '" + nameOfTypeDef(typeRight) + "', but must be of the same type");
}
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.IntTypeDef, typeLeft) && !AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.RealTypeDef, typeLeft)) {
error(binExpr, "left side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeLeft) + "' but must be of type" + "'int' or 'real'");
}
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.IntTypeDef, typeRight) && !AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.RealTypeDef, typeRight)) {
error(binExpr, "right side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeRight) + "' but must be of type" + "'int' or 'real'");
}
if (op.equals("*") && !isInLinearizationBodyExpr) {
if (!rightSideConst && !leftSideConst) {
warning(binExpr, "neither the right nor the left side of binary expression '" + op + "' is constant'. Non-linear expressions are allowed only with z3 and dReal." + " With z3 they are not recomended.");
}
}
return;
case "mod":
case "div":
if (isInLinearizationBodyExpr) {
error(binExpr, "Integer operation expressions (like '" + op + "') are not allowed in linearization body expressions.");
} else {
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.IntTypeDef, typeLeft)) {
error(binExpr, "left side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeLeft) + "' but must be of type 'int'");
}
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.IntTypeDef, typeRight)) {
error(binExpr, "right side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeRight) + "' but must be of type 'int'");
}
if (!rightSideConst) {
warning(binExpr, "right side of binary expression '" + op + "' is not constant." + " Non-linear expressions are allowed only with z3." + " Even with z3 they are not recomended...");
}
}
return;
case "/":
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.RealTypeDef, typeLeft)) {
error(binExpr, "left side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeLeft) + "' but must be of type 'real'");
}
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.RealTypeDef, typeRight)) {
error(binExpr, "right side of binary expression '" + op + "' is of type '" + nameOfTypeDef(typeRight) + "' but must be of type 'real'");
}
if (!rightSideConst && !isInLinearizationBodyExpr) {
warning(binExpr, "right side of binary expression '" + op + "' is not constant." + " Non-linear expressions are allowed only with z3." + " Even with z3 they are not recomended...");
}
return;
default:
assert (false);
}
}
use of com.rockwellcollins.atc.agree.AgreeTypeSystem.TypeDef in project AGREE by loonwerks.
the class AgreeValidator method checkMultiAssignEq.
private void checkMultiAssignEq(EObject src, List<Arg> lhsArgs, Expr rhsExpr) {
if (rhsExpr == null) {
return;
}
if (lhsArgs.size() == 1) {
// we should only need to check for cycles for single equations
String name = lhsArgs.get(0).getName();
ExprCycleVisitor cycleVisitor = new ExprCycleVisitor(name);
Set<EObject> cycleObjects = cycleVisitor.doSwitch(rhsExpr);
if (cycleObjects == null) {
throw new IllegalArgumentException("something went wrong with the cycle checker");
}
for (EObject obj : cycleObjects) {
error(obj, "Cyclic reference to variable '" + name + "'");
}
}
if (argsContainRangeValue(lhsArgs)) {
error(src, "Equation statements cannot contain a ranged value and a right hand side expression");
}
List<TypeDef> agreeLhsTypes = new ArrayList<>();
for (Arg arg : lhsArgs) {
agreeLhsTypes.add(AgreeTypeSystem.typeDefFromType(arg.getType()));
}
List<TypeDef> agreeRhsTypes = new ArrayList<>();
if (rhsExpr instanceof CallExpr) {
NamedElement namedEl = ((CallExpr) rhsExpr).getRef().getElm();
if (namedEl instanceof NodeDef) {
NodeDef nodeDef = (NodeDef) namedEl;
for (Arg var : nodeDef.getRets()) {
agreeRhsTypes.add(AgreeTypeSystem.typeDefFromType(var.getType()));
}
} else if (namedEl instanceof FnDef) {
FnDef fnDef = (FnDef) namedEl;
agreeRhsTypes.add(AgreeTypeSystem.typeDefFromType(fnDef.getType()));
} else if (namedEl instanceof UninterpretedFnDef) {
UninterpretedFnDef uninterpretedFnDef = (UninterpretedFnDef) namedEl;
agreeRhsTypes.add(AgreeTypeSystem.typeDefFromType(uninterpretedFnDef.getType()));
} else {
// parse error
return;
}
} else {
checkTypeExists(rhsExpr);
TypeDef rhsType = AgreeTypeSystem.infer(rhsExpr);
agreeRhsTypes.add(rhsType);
}
if (agreeLhsTypes.size() != agreeRhsTypes.size()) {
error(src, "Equation assigns " + agreeLhsTypes.size() + " variables, but right side returns " + agreeRhsTypes.size() + " values");
return;
}
for (int i = 0; i < agreeLhsTypes.size(); i++) {
TypeDef lhsType = agreeLhsTypes.get(i);
TypeDef rhsType = agreeRhsTypes.get(i);
if (!AgreeTypeSystem.typesEqual(rhsType, lhsType)) {
error(src, "The variable '" + lhsArgs.get(i).getName() + "' on the left side of equation is of type '" + nameOfTypeDef(lhsType) + "' but must be of type '" + nameOfTypeDef(rhsType) + "'");
}
}
}
use of com.rockwellcollins.atc.agree.AgreeTypeSystem.TypeDef in project AGREE by loonwerks.
the class AgreeValidator method checkPropertyStatement.
@Check(CheckType.FAST)
public void checkPropertyStatement(PropertyStatement propStat) {
AnnexLibrary library = EcoreUtil2.getContainerOfType(propStat, AnnexLibrary.class);
if (library != null) {
error(propStat, "Property statments are allowed only in component annexes");
}
TypeDef exprType = AgreeTypeSystem.infer(propStat.getExpr());
if (!AgreeTypeSystem.typesEqual(AgreeTypeSystem.Prim.BoolTypeDef, exprType)) {
error(propStat, "Property statement '" + propStat.getName() + "' is of type '" + exprType + "' but must be of type 'bool'");
}
}
Aggregations