use of jkind.lustre.Type in project AGREE by loonwerks.
the class AgreeASTBuilder method getAgreeNode.
private AgreeNode getAgreeNode(ComponentInstance compInst, boolean isTop) {
List<AgreeVar> inputs = new ArrayList<>();
List<AgreeVar> outputs = new ArrayList<>();
List<AgreeVar> locals = new ArrayList<>();
List<AgreeAADLConnection> aadlConnections = new ArrayList<>();
List<AgreeOverriddenConnection> userDefinedConections = new ArrayList<>();
List<AgreeConnection> connections = new ArrayList<>();
List<AgreeNode> subNodes = new ArrayList<>();
List<AgreeStatement> assertions = new ArrayList<>();
List<AgreeStatement> assumptions = new ArrayList<>();
List<AgreeStatement> guarantees = new ArrayList<>();
List<AgreeStatement> lemmas = new ArrayList<>();
List<AgreeEquation> localEquations = new ArrayList<>();
List<AgreeStatement> patternProps = Collections.emptyList();
timeOfVarMap = new HashMap<>();
timeRiseVarMap = new HashMap<>();
timeFallVarMap = new HashMap<>();
unspecifiedAadlProperties = new HashMap<>();
Expr clockConstraint = new BoolExpr(true);
Expr initialConstraint = new BoolExpr(true);
String id = compInst.getName();
AgreeVar clockVar = new AgreeVar(id + clockIDSuffix, NamedType.BOOL, compInst.getSubcomponent(), compInst, null);
EObject reference = isTop ? compInst.getComponentClassifier() : compInst.getSubcomponent();
TimingModel timing = null;
boolean foundSubNode = false;
boolean hasDirectAnnex = false;
boolean hasSubcomponents = false;
ComponentClassifier compClass = compInst.getComponentClassifier();
Set<ComponentType> effectiveTypes = new HashSet<>();
Map<String, jkind.lustre.Expr> portRewriteMap = new HashMap<>();
if (compClass instanceof ComponentImplementation) {
boolean latched = false;
ComponentImplementation cc = (ComponentImplementation) compClass;
effectiveTypes.addAll(getEffectiveComponentTypes(cc.getType()));
if (isTop || isMonolithic) {
while (cc != null) {
AgreeContractSubclause annex = getAgreeAnnex(cc);
for (ComponentInstance subInst : compInst.getComponentInstances()) {
hasSubcomponents = true;
curInst = subInst;
AgreeNode subNode = getAgreeNode(subInst, false);
if (subNode != null && subNodes.stream().noneMatch(it -> it.reference.equals(subNode.reference))) {
foundSubNode = true;
subNodes.add(subNode);
}
}
if (annex != null) {
hasDirectAnnex = true;
AgreeContract contract = (AgreeContract) annex.getContract();
curInst = compInst;
assertions.addAll(getAssertionStatements(contract.getSpecs()));
getEquationStatements(contract.getSpecs(), portRewriteMap).addAllTo(locals, assertions, guarantees);
assertions.addAll(getPropertyStatements(contract.getSpecs()));
assertions.addAll(getAssignmentStatements(contract.getSpecs()));
userDefinedConections.addAll(getConnectionStatements(contract.getSpecs()));
lemmas.addAll(getLemmaStatements(contract.getSpecs()));
lemmas.addAll(getReachableStatements(contract.getSpecs(), portRewriteMap));
addLustreNodes(contract.getSpecs());
gatherLustreTypes(contract.getSpecs());
// the clock constraints contain other nodes that we add
clockConstraint = getClockConstraint(contract.getSpecs(), subNodes);
timing = getTimingModel(contract.getSpecs());
outputs.addAll(getEquationVars(contract.getSpecs(), compInst));
for (SpecStatement spec : contract.getSpecs()) {
if (spec instanceof LatchedStatement) {
latched = true;
break;
}
}
}
// Find extended effective types
effectiveTypes.addAll(getEffectiveComponentTypes(cc.getType()));
cc = cc.getExtended();
}
EList<ConnectionInstance> connectionInstances = compInst.getAllEnclosingConnectionInstances();
List<ConnectionInstance> foo = new ArrayList<>();
compInst.getAllComponentInstances().forEach(ci -> ci.allEnclosingConnectionInstances().forEach(foo::add));
aadlConnections.addAll(getConnectionsFromInstances(connectionInstances, compInst, subNodes, latched));
connections.addAll(filterConnections(aadlConnections, userDefinedConections));
}
ComponentType compType = ((ComponentImplementation) compClass).getType();
AgreeContractSubclause compImpAnnex = getAgreeAnnex(compClass);
if (compImpAnnex != null) {
AgreeContract contract = (AgreeContract) compImpAnnex.getContract();
for (SpecStatement spec : contract.getSpecs()) {
if (spec instanceof LiftContractStatement) {
Subcomponent sub = ((ComponentImplementation) compClass).getOwnedSubcomponents().get(0);
ComponentType ct = sub.getComponentType();
for (Connection conn : ((ComponentImplementation) compClass).getAllConnections()) {
NamedElement sourceNe = conn.getSource().getConnectionEnd();
NamedElement destNe = conn.getDestination().getConnectionEnd();
String sourceStr = sourceNe.getName().replace("::", "__");
String destStr = destNe.getName().replace("::", "__");
if (ct == sourceNe.getContainingClassifier()) {
portRewriteMap.put(sourceStr, new IdExpr(destStr));
} else if (ct == destNe.getContainingClassifier()) {
portRewriteMap.put(destStr, new IdExpr(sourceStr));
}
}
effectiveTypes.addAll(getEffectiveComponentTypes(ct));
}
}
}
// make compClass the type so we can get it's other contract elements
compClass = compType;
} else if (compClass instanceof ComponentType) {
effectiveTypes.addAll(getEffectiveComponentTypes((ComponentType) compClass));
} else {
throw new AgreeException("Internal error: attempt to run AGREE analysis on instance " + compInst.getFullName() + " not instance of ComponentImplementation or ComponentType.");
}
curInst = compInst;
if (timing == null) {
timing = TimingModel.SYNC;
}
for (ComponentType compType : effectiveTypes) {
AgreeContractSubclause annex = getAgreeAnnex(compType);
if (annex != null) {
hasDirectAnnex = true;
AgreeContract contract = (AgreeContract) annex.getContract();
// this makes files for monolithic verification a bit smaller
if (!isMonolithic || isTop || !hasSubcomponents) {
assumptions.addAll(getAssumptionStatements(contract.getSpecs(), portRewriteMap));
guarantees.addAll(getGuaranteeStatements(contract.getSpecs(), portRewriteMap));
lemmas.addAll(getReachableStatements(contract.getSpecs(), portRewriteMap));
}
// Count eq statements with expressions as assertions
getEquationStatements(contract.getSpecs(), portRewriteMap).addAllTo(locals, assertions, guarantees);
assertions.addAll(getPropertyStatements(contract.getSpecs()));
outputs.addAll(getEquationVars(contract.getSpecs(), compInst));
getAgreeInputVars(contract.getSpecs(), compInst).addAllTo(inputs, assumptions, guarantees);
initialConstraint = getInitialConstraint(contract.getSpecs());
addLustreNodes(contract.getSpecs());
gatherLustreTypes(contract.getSpecs());
}
}
gatherUnspecifiedAadlProperties(unspecifiedAadlProperties, inputs, assumptions, guarantees);
if (!(foundSubNode || hasDirectAnnex)) {
return null;
}
gatherOutputsInputsAndTypes(outputs, inputs, compInst.getFeatureInstances(), assumptions, guarantees);
AgreeNodeBuilder builder = new AgreeNodeBuilder(id);
builder.addInput(inputs);
builder.addOutput(outputs);
builder.addLocal(locals);
builder.addLocalEquation(localEquations);
builder.addConnection(connections);
builder.addSubNode(subNodes);
// Clean up any vacuous true predicates
Predicate<AgreeStatement> isBoolExprAndisTrue = st -> (st.expr instanceof BoolExpr) && ((BoolExpr) st.expr).value;
assertions.removeIf(isBoolExprAndisTrue);
assumptions.removeIf(isBoolExprAndisTrue);
guarantees.removeIf(isBoolExprAndisTrue);
builder.addAssertion(assertions);
builder.addAssumption(assumptions);
builder.addGuarantee(guarantees);
builder.addLemma(lemmas);
builder.addPatternProp(patternProps);
builder.setClockConstraint(clockConstraint);
builder.setInitialConstraint(initialConstraint);
builder.setClockVar(clockVar);
builder.setReference(reference);
builder.setTiming(timing);
builder.setCompInst(compInst);
builder.addTimeOf(timeOfVarMap);
builder.addTimeRise(timeRiseVarMap);
builder.addTimeFall(timeFallVarMap);
AgreeNode result = builder.build();
renamings.put(id, compInst.getName());
refMap.put(id, compInst);
return linearizationRewriter.visit(result);
}
use of jkind.lustre.Type in project AGREE by loonwerks.
the class AgreeASTBuilder method getConnectionEndType.
private Type getConnectionEndType(ConnectionEnd port) {
NamedElement dataClass = getConnectionEndDataClass(port);
if (dataClass == null) {
return null;
}
// EGM: array-backend
// Type lustreType = AgreeTypeUtils.getType(dataClass, typeMap, globalTypes);
Type lustreType = symbolTable.updateLustreTypeMap(AgreeTypeSystem.typeDefFromNE(dataClass));
return lustreType;
}
use of jkind.lustre.Type in project AGREE by loonwerks.
the class AgreeASTMapVisitor method visit.
@Override
public AgreeVar visit(AgreeVar e) {
String name = e.id;
Type type = e.type.accept(lustreTypeMapVisitor);
EObject reference = e.reference;
ComponentInstance compInst = e.compInst;
FeatureInstance featInst = e.featInst;
return new AgreeVar(name, type, reference, compInst, featInst);
}
use of jkind.lustre.Type in project AGREE by loonwerks.
the class LustreToMATLABTranslator method translate.
public static MATLABPrimaryFunction translate(Node lustreNode, AgreeProgram agreeProgram) {
IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
intTypeStr = prefs.getString(PreferenceConstants.PREF_INT);
realTypeStr = prefs.getString(PreferenceConstants.PREF_REAL);
List<MATLABIdExpr> inputs = new ArrayList<>();
List<MATLABStatement> statements = new ArrayList<>();
List<MATLABFunction> functions = new ArrayList<>();
List<MATLABPersistentVarDecl> persistentVarDecl = new ArrayList<>();
List<MATLABPort> ports = new ArrayList<>();
LustreToMATLABExprVisitor exprVisitor = new LustreToMATLABExprVisitor();
LustreToMATLABTypeVisitor typeVisitor = new LustreToMATLABTypeVisitor();
// get function name
String functionName = "check_" + lustreNode.id;
// add record types
for (Type type : agreeProgram.globalTypes) {
if (type instanceof RecordType) {
RecordType recordType = (RecordType) type;
SortedMap<String, MATLABType> fields = new TreeMap<>(new StringNaturalOrdering());
Iterator<Entry<String, Type>> iterator = recordType.fields.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Type> entry = iterator.next();
fields.put(exprVisitor.updateName(entry.getKey(), recordType.id), entry.getValue().accept(typeVisitor));
}
exprVisitor.recordTypeMap.put(recordType.id, fields);
}
}
// add input and output ports for subsystem to verify
for (VarDecl inputVar : lustreNode.inputs) {
String varName = null;
if (!inputVar.id.equals("time")) {
// update name
varName = exprVisitor.updateName(inputVar.id, "");
// add inputs
inputs.add(new MATLABIdExpr(varName));
// translate the Lustre expression to MATLAB expression
// add input Ids to inputList of the exprVisitor
// to help identify local variables
exprVisitor.inputSet.add(inputVar.id);
// get inputVar and type
AgreeVar agreeVar = (AgreeVar) inputVar;
Type type = agreeVar.type;
if (type instanceof RecordType || type instanceof NamedType) {
MATLABType portType = (agreeVar.type).accept(typeVisitor);
SortedMap<String, MATLABType> fields = null;
// get the fields if it is a RecordType
if (type instanceof RecordType) {
fields = exprVisitor.recordTypeMap.get(((RecordType) type).id);
}
// if it is from AADL feature, get the feature instance
if (agreeVar.featInst != null) {
FeatureInstance featInst = agreeVar.featInst;
ports.add(new MATLABPort(featInst.getName(), featInst.getDirection().getName(), portType, fields));
} else // if it is not from AADL feature, but an eq variable from
// AGREE
// set them as output variables from the subsystem
{
ports.add(new MATLABPort(inputVar.id, "out", portType, fields));
}
}
}
}
// add local variable and their types
for (VarDecl localVar : lustreNode.locals) {
// get local var Name and Type
exprVisitor.localVarTypeMap.put(exprVisitor.updateName(localVar.id, ""), localVar.type.accept(typeVisitor));
}
// translate equations to assignments
if (!lustreNode.equations.isEmpty()) {
for (Equation equation : lustreNode.equations) {
// get the variable to assign
String varId = exprVisitor.updateName(equation.lhs.get(0).id, "");
MATLABIdExpr varToAssign = new MATLABIdExpr(varId);
// get the type for the local variable
// MATLABType type = exprVisitor.localVarTypeMap.get(varId);
// translate expressions
MATLABExpr expr = exprVisitor.visit(equation.expr);
// conduct explicit type cast if it's a constant of double type or int type
// no need to type cast for assignment from an input variable
// or operations (including functions) involving known types
MATLABTypeCastExprVisitor typeCastVisitor = new MATLABTypeCastExprVisitor();
expr = typeCastVisitor.visit(expr);
// add any new preVar init from exprVisitor
Iterator<MATLABPersistentVarInit> persistentVarInitIterator = exprVisitor.persistentVarInits.iterator();
while (persistentVarInitIterator.hasNext()) {
MATLABPersistentVarInit persistentVarInit = persistentVarInitIterator.next();
// add new preVar init to the statements before the assignment
statements.add(persistentVarInit);
// remove the new preVar init from exprVisitor
persistentVarInitIterator.remove();
}
// add any new local Bus var init from exprVisitor
Iterator<MATLABLocalBusVarInit> busVarInitIterator = exprVisitor.localBusVarInits.iterator();
while (busVarInitIterator.hasNext()) {
MATLABLocalBusVarInit busVarInit = busVarInitIterator.next();
// add new local Bus var init to the statements before the assignment
statements.add(busVarInit);
// remove the new local Bus var init from exprVisitor
busVarInitIterator.remove();
}
// add assignment
MATLABAssignment assignment = new MATLABAssignment(varToAssign, expr);
statements.add(assignment);
}
}
// add persistentVar decl and assignments
Iterator<Entry<String, MATLABExpr>> it = exprVisitor.persistentVarMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, MATLABExpr> pair = it.next();
String varToAssign = pair.getKey();
MATLABExpr expr = pair.getValue();
statements.add(new MATLABAssignment(new MATLABIdExpr(varToAssign), expr));
persistentVarDecl.add(new MATLABPersistentVarDecl(varToAssign));
}
// translate assertions
for (Expr assertionExpr : lustreNode.assertions) {
MATLABExpr expr = exprVisitor.visit(assertionExpr);
// add assertions
MATLABAssumption assumption = new MATLABAssumption(expr);
statements.add(assumption);
}
// translate properties
for (String propertyStr : lustreNode.properties) {
propertyStr = exprVisitor.updateName(propertyStr, "");
MATLABProperty property = new MATLABProperty(propertyStr);
statements.add(property);
}
// add definitions for the functions that have been called
for (Map.Entry<String, MATLABFunction> functionEntry : exprVisitor.functionMap.entrySet()) {
MATLABFunction function = functionEntry.getValue();
if (function.functionCalled) {
functions.add(function);
}
}
// Create primary function AST
MATLABPrimaryFunction primaryFunction = new MATLABPrimaryFunction(functionName, inputs, persistentVarDecl, statements, functions, ports);
return primaryFunction;
}
use of jkind.lustre.Type in project AGREE by loonwerks.
the class VariableMap method addRelatedExpression.
private void addRelatedExpression(final Expr idExpr, final BinaryExpr relatedExpr) {
Objects.requireNonNull(relatedExpr, "relatedExpr must not be null");
final Type type = idExpr.accept(typeReconstructor);
if (type instanceof NamedType) {
// Only add the related expression if the expression can be used to solve the variable.
if ((type != NamedType.BOOL && !leftOfCurrentRelatedExpressionIsBoolean) || (type == NamedType.BOOL && leftOfCurrentRelatedExpressionIsBoolean)) {
final Variable var = getOrCreate(idExpr, (NamedType) type);
var.relatedExpressions.add(relatedExpr);
markVariableMapAsDirty();
}
}
}
Aggregations