diff --git a/AlgebraicDataflowArchitectureModel/models/JumpGame.model b/AlgebraicDataflowArchitectureModel/models/JumpGame.model index 4db5282..d8b002b 100644 --- a/AlgebraicDataflowArchitectureModel/models/JumpGame.model +++ b/AlgebraicDataflowArchitectureModel/models/JumpGame.model @@ -1,10 +1,10 @@ channel CIO { - out force(f:Tuple, gravity(y:Double)) == tuple(0.0, y) + out force(f:Pair, gravity(y:Double)) == pair(0.0, y) out time(t:Double, gravity(y)) == t + 0.01 } channel CIO2 { - out move(v:Tuple, moveX(x:Double)) == tuple(x, snd(v)) - out move(v, moveY(y:Double)) == tuple(fst(v), y) + out move(v:Pair, moveX(x:Double)) == pair(x, snd(v)) + out move(v, moveY(y:Double)) == pair(fst(v), y) } channel CIO3 { out mass(m:Double, setMass(x:Double)) == x @@ -17,26 +17,26 @@ ref onground(o, update1(f2, m2, o)) in force(f, update1(f2, m2, o)) == f2 in mass(m, update1(f2, m2, o)) == m2 - out acceleration(a:Tuple, update1(f2, m2, o)) == if(o, tuple(fst(f2) / m2, 0.0), tuple(fst(f2) / m2, snd(f2) / m2)) + out acceleration(a:Pair, update1(f2, m2, o)) == if(o, pair(fst(f2) / m2, 0.0), pair(fst(f2) / m2, snd(f2) / m2)) } channel C2 { ref onground(o, update3(a2, o)) in acceleration(a, update3(a2, o)) == a2 - out velocity(v:Tuple, update3(a2, o)) == if(and(o, lt(snd(v), 0.0)), - tuple(fst(v) + 0.01 * fst(a2), 0.0), - tuple(fst(v) + 0.01 * fst(a2), snd(v) + 0.01 * snd(a2))) + out velocity(v:Pair, update3(a2, o)) == if(and(o, lt(snd(v), 0.0)), + pair(fst(v) + 0.01 * fst(a2), 0.0), + pair(fst(v) + 0.01 * fst(a2), snd(v) + 0.01 * snd(a2))) } channel C3 { ref onground(o, update4(m2, o)) in move(m, update4(m2, o)) == m2 - out velocity(v:Tuple, update4(m2, o)) == if(and(o, ge(snd(m2), 0.0)), m2, v) + out velocity(v:Pair, update4(m2, o)) == if(and(o, ge(snd(m2), 0.0)), m2, v) } channel C4 { in velocity(v, update5(v2, g)) == v2 ref ground(g, update5(v2, g)) - out position(p:Tuple, update5(v2, g)) == if(and(eq(g, true), lt(snd(p) + 0.01 * snd(v2), 0.0)), - tuple(fst(p) + 0.01 * fst(v2), 0.0), - tuple(fst(p) + 0.01 * fst(v2), snd(p) + 0.01 * snd(v2))) + out position(p:Pair, update5(v2, g)) == if(and(eq(g, true), lt(snd(p) + 0.01 * snd(v2), 0.0)), + pair(fst(p) + 0.01 * fst(v2), 0.0), + pair(fst(p) + 0.01 * fst(v2), snd(p) + 0.01 * snd(v2))) } channel C5 { in position(p, update2(p2, g2)) == p2 diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java index eea3398..92b0f8c 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java @@ -243,25 +243,35 @@ cu.addImport(new ImportDeclaration("java.util.*")); codes.add(cu); } - + + // Declare the Pair class. - TypeDeclaration type = new TypeDeclaration("Pair"); - type.addField(new FieldDeclaration(new Type("Double","double"), "first")); - type.addField(new FieldDeclaration(new Type("Double","double"), "second")); - - for(FieldDeclaration field : type.getFields()) { - MethodDeclaration getter = new MethodDeclaration( - "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1), - new Type("Double","double")); - getter.setBody(new Block()); - getter.getBody().addStatement("return " + field.getName() + ";"); - type.addMethod(getter); + boolean isCreatedPair = false; + + for(ResourceNode rn : resources) { + if(isCreatedPair) continue; + if(model.getType("Pair").isAncestorOf(rn.getIdentifierTemplate().getResourceStateType())) { + TypeDeclaration type = new TypeDeclaration("Pair"); + type.addField(new FieldDeclaration(new Type("Double","T"), "first")); + type.addField(new FieldDeclaration(new Type("Double","T"), "second")); + + for(FieldDeclaration field : type.getFields()) { + MethodDeclaration getter = new MethodDeclaration( + "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1), + new Type("Double","T")); + getter.setBody(new Block()); + getter.getBody().addStatement("return " + field.getName() + ";"); + type.addMethod(getter); + } + + CompilationUnit cu = new CompilationUnit(type); + cu.addImport(new ImportDeclaration("java.util.*")); + codes.add(cu); + + isCreatedPair = true; + } } - CompilationUnit cu = new CompilationUnit(type); - cu.addImport(new ImportDeclaration("java.util.*")); - codes.add(cu); - diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index 7b6de77..73f9ef3 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -10,6 +10,8 @@ import java.util.Map; import java.util.Set; +import javax.xml.crypto.Data; + import models.Node; import models.algebra.Expression; import models.algebra.Position; @@ -31,11 +33,13 @@ static private Map listComponentTypes = new HashMap<>(); static private Map, Type> tupleTypes = new HashMap<>(); static private Map> tupleComponentTypes = new HashMap<>(); - + static private Map pairTypes = new HashMap<>(); + static private Map pairComponentTypes = new HashMap<>(); + public static Type getListType(Type compType) { return listTypes.get(compType); } - + public static Type getListComponentType(Type listType) { return listComponentTypes.get(listType); } @@ -43,11 +47,11 @@ public static Collection getListTypes() { return listTypes.values(); } - + public static Type getTupleType(List compTypes) { return tupleTypes.get(compTypes); } - + public static List getTupleComponentTypes(Type tupleType) { return tupleComponentTypes.get(tupleType); } @@ -56,46 +60,64 @@ return tupleTypes.values(); } + public static Type getPairType(Type compType) { + return pairTypes.get(compType); + } + + public static Type getPairComponentType(Type pairType) { + return pairComponentTypes.get(pairType); + } + static public void infer(ResourceDependencyGraph graph, DataFlowModel model) { Map> resources = new HashMap<>(); Map variables = new HashMap<>(); Map, Type>>> messages = new HashMap<>(); Map cons = new HashMap<>(); Map tuple = new HashMap<>(); + Map pair = new HashMap<>(); Map> expToResource = new HashMap<>(); Map> expToVariable = new HashMap<>(); Map> expToMessage = new HashMap<>(); Map> expToCons = new HashMap<>(); - Map> expToTuple = new HashMap<>(); - + Map> expToTuple = new HashMap<>(); + Map> expToPair = new HashMap<>(); + Map idToRes = new HashMap<>(); Map> updateFromResource = new HashMap<>(); Map> updateFromVariable = new HashMap<>(); Map> updateFromMessage = new HashMap<>(); Map> updateFromCons = new HashMap<>(); Map> updateFromTuple = new HashMap<>(); - + Map> updateFromPair = new HashMap<>(); + listComponentTypes.put(DataConstraintModel.typeList, null); listComponentTypes.put(DataConstraintModel.typeListInt, DataConstraintModel.typeInt); listComponentTypes.put(DataConstraintModel.typeListStr, DataConstraintModel.typeString); listTypes.put(DataConstraintModel.typeInt, DataConstraintModel.typeListInt); listTypes.put(DataConstraintModel.typeString, DataConstraintModel.typeListStr); - tupleComponentTypes.put(DataConstraintModel.typeTuple, Arrays.asList(new Type[] {null, null})); - for (Node n: graph.getNodes()) { + pairComponentTypes.put(DataConstraintModel.typePair, null); + pairComponentTypes.put(DataConstraintModel.typePairInt, DataConstraintModel.typeInt); + pairComponentTypes.put(DataConstraintModel.typePairStr, DataConstraintModel.typeString); + pairComponentTypes.put(DataConstraintModel.typePairDouble, DataConstraintModel.typeDouble); + pairTypes.put(DataConstraintModel.typeInt, DataConstraintModel.typePairInt); + pairTypes.put(DataConstraintModel.typeString, DataConstraintModel.typePairStr); + pairTypes.put(DataConstraintModel.typeDouble, DataConstraintModel.typePairDouble); + tupleComponentTypes.put(DataConstraintModel.typeTuple, Arrays.asList(new Type[] { null, null })); + for (Node n : graph.getNodes()) { ResourceNode resource = (ResourceNode) n; idToRes.put(resource.getIdentifierTemplate(), resource); } - + // Collect type information from the architecture model. Collection channels = new HashSet<>(model.getIOChannelGenerators()); channels.addAll(model.getChannelGenerators()); - for (ChannelGenerator c: channels) { - for (ChannelMember cm: c.getChannelMembers()) { - StateTransition st = cm.getStateTransition(); + for (ChannelGenerator c : channels) { + for (ChannelMember cm : c.getChannelMembers()) { + StateTransition st = cm.getStateTransition(); IdentifierTemplate id = cm.getIdentifierTemplate(); - + // Group expressions by resources. - List sameResource = resources.get(id); + List sameResource = resources.get(id); if (sameResource == null) { sameResource = new ArrayList<>(); resources.put(id, sameResource); @@ -110,7 +132,7 @@ Type expType = getExpTypeIfUpdatable(resType, exp); if (expType != null) { id.setResourceStateType(expType); - for (Expression resExp: sameResource) { + for (Expression resExp : sameResource) { if (resExp != exp) { if (resExp instanceof Variable && compareTypes(((Variable) resExp).getType(), expType)) { ((Variable) resExp).setType(expType); @@ -137,7 +159,7 @@ expType = getExpTypeIfUpdatable(resType, exp); if (expType != null) { id.setResourceStateType(expType); - for (Expression resExp: sameResource) { + for (Expression resExp : sameResource) { if (resExp != exp) { if (resExp instanceof Variable && compareTypes(((Variable) resExp).getType(), expType)) { ((Variable) resExp).setType(expType); @@ -159,15 +181,16 @@ updatedExps.put(System.identityHashCode(exp), exp); } } - + // Group expressions by variable. Map> locals = new HashMap<>(); Map localTypes = new HashMap<>(); List allVariables = new ArrayList<>(); allVariables.addAll(st.getCurStateExpression().getVariables().values()); allVariables.addAll(st.getMessageExpression().getVariables().values()); - if (st.getNextStateExpression() != null) allVariables.addAll(st.getNextStateExpression().getVariables().values()); - for (Variable var: allVariables) { + if (st.getNextStateExpression() != null) + allVariables.addAll(st.getNextStateExpression().getVariables().values()); + for (Variable var : allVariables) { List sameVariable = locals.get(var.getName()); if (sameVariable == null) { sameVariable = new ArrayList<>(); @@ -182,7 +205,7 @@ Map updatedVars = getUpdateSet(updateFromVariable, sameVariable); if (compareTypes(varType, var.getType())) { localTypes.put(var.getName(), var.getType()); - for (Expression v: sameVariable) { + for (Expression v : sameVariable) { if (v != var) { if (compareTypes(((Variable) v).getType(), var.getType())) { ((Variable) v).setType(var.getType()); @@ -196,95 +219,95 @@ } } } - for (String varName: locals.keySet()) { + for (String varName : locals.keySet()) { variables.put(System.identityHashCode(locals.get(varName)), localTypes.get(varName)); } - + // Group expressions by message. Expression message = st.getMessageExpression(); if (message instanceof Variable) { Type msgType = ((Variable) message).getType(); - Map, Type>> msgTypeMap = messages.get(c); - if (msgTypeMap == null) { - msgTypeMap = new HashMap<>(); - messages.put(c, msgTypeMap); - } - Map.Entry, Type> typeAndExps = msgTypeMap.get(0); - if (typeAndExps == null) { - List exps = new ArrayList<>(); - exps.add(message); - typeAndExps = new AbstractMap.SimpleEntry<>(exps, msgType); - msgTypeMap.put(0, typeAndExps); - expToMessage.put(System.identityHashCode(message), exps); - } else { - typeAndExps.getKey().add(message); - expToMessage.put(System.identityHashCode(message), typeAndExps.getKey()); + Map, Type>> msgTypeMap = messages.get(c); + if (msgTypeMap == null) { + msgTypeMap = new HashMap<>(); + messages.put(c, msgTypeMap); + } + Map.Entry, Type> typeAndExps = msgTypeMap.get(0); + if (typeAndExps == null) { + List exps = new ArrayList<>(); + exps.add(message); + typeAndExps = new AbstractMap.SimpleEntry<>(exps, msgType); + msgTypeMap.put(0, typeAndExps); + expToMessage.put(System.identityHashCode(message), exps); + } else { + typeAndExps.getKey().add(message); + expToMessage.put(System.identityHashCode(message), typeAndExps.getKey()); Map updateExps = getUpdateSet(updateFromMessage, typeAndExps.getKey()); - if (compareTypes(typeAndExps.getValue(), msgType)) { - typeAndExps.setValue(msgType); - for (Expression e: typeAndExps.getKey()) { - if (e != message) { - if (e instanceof Variable) { - ((Variable) e).setType(msgType); - updateExps.put(System.identityHashCode(e), e); - } - } - } - } else if (compareTypes(msgType, typeAndExps.getValue())) { - ((Variable) message).setType(typeAndExps.getValue()); + if (compareTypes(typeAndExps.getValue(), msgType)) { + typeAndExps.setValue(msgType); + for (Expression e : typeAndExps.getKey()) { + if (e != message) { + if (e instanceof Variable) { + ((Variable) e).setType(msgType); + updateExps.put(System.identityHashCode(e), e); + } + } + } + } else if (compareTypes(msgType, typeAndExps.getValue())) { + ((Variable) message).setType(typeAndExps.getValue()); updateExps.put(System.identityHashCode(message), message); - } - } + } + } } else if (message instanceof Term) { - Map, Type>> msgTypeMap = messages.get(c); - if (msgTypeMap == null) { - msgTypeMap = new HashMap<>(); - messages.put(c, msgTypeMap); - } - for (int i = 0; i < ((Term) message).getArity(); i++) { - Expression arg = ((Term) message).getChild(i); - Type argType = null; - if (arg instanceof Variable) { - argType = ((Variable) arg).getType(); - } else if (arg instanceof Term) { - argType = ((Term) arg).getType(); - } else { - continue; - } - Map.Entry, Type> typeAndExps = msgTypeMap.get(i); - if (typeAndExps == null) { - List exps = new ArrayList<>(); - exps.add(arg); - typeAndExps = new AbstractMap.SimpleEntry<>(exps, argType); - msgTypeMap.put(i, typeAndExps); - expToMessage.put(System.identityHashCode(arg), exps); - } else { - typeAndExps.getKey().add(arg); - expToMessage.put(System.identityHashCode(arg), typeAndExps.getKey()); - Map updateExps = getUpdateSet(updateFromMessage, typeAndExps.getKey()); - if (compareTypes(typeAndExps.getValue(), argType)) { - typeAndExps.setValue(argType); - for (Expression e: typeAndExps.getKey()) { - if (e != arg) { - if (e instanceof Variable) { - ((Variable) e).setType(argType); - updateExps.put(System.identityHashCode(e), e); - } - } - } - } else if (compareTypes(argType, typeAndExps.getValue())) { - if (arg instanceof Variable) { - ((Variable) arg).setType(typeAndExps.getValue()); - updateExps.put(System.identityHashCode(arg), arg); - } else if (arg instanceof Term) { - ((Term) arg).setType(typeAndExps.getValue()); - updateExps.put(System.identityHashCode(arg), arg); - } - } - } - } + Map, Type>> msgTypeMap = messages.get(c); + if (msgTypeMap == null) { + msgTypeMap = new HashMap<>(); + messages.put(c, msgTypeMap); + } + for (int i = 0; i < ((Term) message).getArity(); i++) { + Expression arg = ((Term) message).getChild(i); + Type argType = null; + if (arg instanceof Variable) { + argType = ((Variable) arg).getType(); + } else if (arg instanceof Term) { + argType = ((Term) arg).getType(); + } else { + continue; + } + Map.Entry, Type> typeAndExps = msgTypeMap.get(i); + if (typeAndExps == null) { + List exps = new ArrayList<>(); + exps.add(arg); + typeAndExps = new AbstractMap.SimpleEntry<>(exps, argType); + msgTypeMap.put(i, typeAndExps); + expToMessage.put(System.identityHashCode(arg), exps); + } else { + typeAndExps.getKey().add(arg); + expToMessage.put(System.identityHashCode(arg), typeAndExps.getKey()); + Map updateExps = getUpdateSet(updateFromMessage, typeAndExps.getKey()); + if (compareTypes(typeAndExps.getValue(), argType)) { + typeAndExps.setValue(argType); + for (Expression e : typeAndExps.getKey()) { + if (e != arg) { + if (e instanceof Variable) { + ((Variable) e).setType(argType); + updateExps.put(System.identityHashCode(e), e); + } + } + } + } else if (compareTypes(argType, typeAndExps.getValue())) { + if (arg instanceof Variable) { + ((Variable) arg).setType(typeAndExps.getValue()); + updateExps.put(System.identityHashCode(arg), arg); + } else if (arg instanceof Term) { + ((Term) arg).setType(typeAndExps.getValue()); + updateExps.put(System.identityHashCode(arg), arg); + } + } + } + } } - + List terms = new ArrayList<>(); if (st.getCurStateExpression() instanceof Term) { Map subTerms = ((Term) st.getCurStateExpression()).getSubTerms(Term.class); @@ -298,20 +321,21 @@ Map subTerms = ((Term) st.getNextStateExpression()).getSubTerms(Term.class); terms.addAll(subTerms.values()); } - for (Term t: terms) { + for (Term t : terms) { Symbol symbol = t.getSymbol(); if (symbol.equals(DataConstraintModel.cons)) { // If the root symbol of the term is cons. List consExps = new ArrayList<>(); consExps.add(t); expToCons.put(System.identityHashCode(t), consExps); - for (Expression e: t.getChildren()) { + for (Expression e : t.getChildren()) { consExps.add(e); expToCons.put(System.identityHashCode(e), consExps); } Type newType = getExpTypeIfUpdatable(t.getType(), consExps.get(2)); if (newType != null) { - // If the type of the second argument is more concrete than the type of the term. + // If the type of the second argument is more concrete than the type of the + // term. t.setType(newType); Map updateCons = getUpdateSet(updateFromCons, consExps); updateCons.put(System.identityHashCode(t), t); @@ -320,15 +344,17 @@ if (consExps.get(2) != null && consExps.get(2) instanceof Variable) { arg2Type = ((Variable) consExps.get(2)).getType(); if (compareTypes(arg2Type, t.getType())) { - // If the type of the term is more concrete than the type of the second argument. + // If the type of the term is more concrete than the type of the second + // argument. ((Variable) consExps.get(2)).setType(t.getType()); Map updateCons = getUpdateSet(updateFromCons, consExps); updateCons.put(System.identityHashCode(consExps.get(2)), consExps.get(2)); } } else if (consExps.get(2) != null && consExps.get(2) instanceof Term) { - arg2Type = ((Term) consExps.get(2)).getType(); + arg2Type = ((Term) consExps.get(2)).getType(); if (compareTypes(arg2Type, t.getType())) { - // If the type of the term is more concrete than the type of the second argument. + // If the type of the term is more concrete than the type of the second + // argument. ((Term) consExps.get(2)).setType(t.getType()); Map updateCons = getUpdateSet(updateFromCons, consExps); updateCons.put(System.identityHashCode(consExps.get(2)), consExps.get(2)); @@ -337,7 +363,8 @@ } Type newCompType = getExpTypeIfUpdatable(listComponentTypes.get(t.getType()), consExps.get(1)); if (newCompType != null) { - // If the type of the first argument is more concrete than the type of list component. + // If the type of the first argument is more concrete than the type of list + // component. Type newListType = listTypes.get(newCompType); if (newListType == null) { // Create new list type. @@ -361,7 +388,7 @@ List argsTypeList = new ArrayList<>(); tupleExps.add(t); expToTuple.put(System.identityHashCode(t), tupleExps); - for (Expression e: t.getChildren()) { + for (Expression e : t.getChildren()) { tupleExps.add(e); expToTuple.put(System.identityHashCode(e), tupleExps); if (e instanceof Variable) { @@ -379,10 +406,41 @@ newTupleType = createNewTupleType(argsTypeList, DataConstraintModel.typeTuple); } t.setType(newTupleType); - Map updateExps = getUpdateSet(updateFromTuple, tupleExps); + Map updateExps = getUpdateSet(updateFromTuple, tupleExps); updateExps.put(System.identityHashCode(t), t); } tuple.put(System.identityHashCode(tupleExps), t.getType()); + } else if (symbol.equals(DataConstraintModel.pair)) { + // If the root symbol of the term is pair. + List pairExps = new ArrayList<>(); + pairExps.add(t); + expToPair.put(System.identityHashCode(t), pairExps); + + if (t.getType() == DataConstraintModel.typePair) { + for (Expression e : t.getChildren()) { + pairExps.add(e); + expToPair.put(System.identityHashCode(e), pairExps); + + Type argType = null; + if (e instanceof Variable) { + argType = (((Variable) e).getType()); + + } else if (e instanceof Term) { + argType = (((Term) e).getType()); + } + + if (argType != null) { + Type newPairType = pairTypes.get(argType); + if (newPairType != null) { + t.setType(newPairType); + Map updateExps = getUpdateSet(updateFromPair, pairExps); + updateExps.put(System.identityHashCode(t), t); + } + } + } + pair.put(System.identityHashCode(pairExps), t.getType()); + + } } else if (symbol.equals(DataConstraintModel.fst)) { // If the root symbol of the term is fst. List tupleExps = new ArrayList<>(); @@ -417,7 +475,7 @@ ((Term) arg).setType(newTupleType); argType = newTupleType; } - Map updateExps = getUpdateSet(updateFromTuple, tupleExps); + Map updateExps = getUpdateSet(updateFromTuple, tupleExps); updateExps.put(System.identityHashCode(arg), arg); } tuple.put(System.identityHashCode(tupleExps), argType); @@ -455,7 +513,7 @@ ((Term) arg).setType(newTupleType); argType = newTupleType; } - Map updateExps = getUpdateSet(updateFromTuple, tupleExps); + Map updateExps = getUpdateSet(updateFromTuple, tupleExps); updateExps.put(System.identityHashCode(arg), arg); } tuple.put(System.identityHashCode(tupleExps), argType); @@ -508,7 +566,7 @@ } } variables.put(System.identityHashCode(condTerms), condType); - } else if (symbol.equals(DataConstraintModel.add) || symbol.equals(DataConstraintModel.sub) + } else if (symbol.equals(DataConstraintModel.add) || symbol.equals(DataConstraintModel.sub) || symbol.equals(DataConstraintModel.mul) || symbol.equals(DataConstraintModel.div)) { // If the root symbol of the term is arithmetic operators. Expression c1 = t.getChild(0); @@ -519,7 +577,7 @@ operands.add(c2); expToVariable.put(System.identityHashCode(t), operands); expToVariable.put(System.identityHashCode(c1), operands); - expToVariable.put(System.identityHashCode(c2), operands); + expToVariable.put(System.identityHashCode(c2), operands); Type opType = t.getType(); Map updatedVars = getUpdateSet(updateFromVariable, operands); Type child1Type = getExpTypeIfUpdatable(opType, c1); @@ -558,8 +616,10 @@ } } variables.put(System.identityHashCode(operands), opType); - } else if (symbol.getSignature() != null && symbol.getSignature()[0] == DataConstraintModel.typeList) { - // If the root symbol of the term is the list type (except for the cons function). + } else if (symbol.getSignature() != null + && symbol.getSignature()[0] == DataConstraintModel.typeList) { + // If the root symbol of the term is the list type (except for the cons + // function). List consExps = new ArrayList<>(); consExps.add(t); expToVariable.put(System.identityHashCode(t), consExps); @@ -572,7 +632,7 @@ Type newType = getExpTypeIfUpdatable(condType, e); if (newType != null) { condType = newType; - for (Expression e2: consExps) { + for (Expression e2 : consExps) { if (e2 instanceof Variable) { ((Variable) e2).setType(newType); updatedVars.put(System.identityHashCode(e2), e2); @@ -599,20 +659,22 @@ } } } - + // Propagate type information. - while (updateFromResource.size() > 0 || updateFromVariable.size() > 0 || updateFromMessage.size() > 0 || updateFromCons.size() > 0 || updateFromTuple.size() > 0) { + while (updateFromResource.size() > 0 || updateFromVariable.size() > 0 || updateFromMessage.size() > 0 + || updateFromCons.size() > 0 || updateFromTuple.size() > 0 || updateFromPair.size() > 0) { if (updateFromResource.size() > 0) { Set resourceKeys = updateFromResource.keySet(); Integer resourceKey = resourceKeys.iterator().next(); Map resourceValue = updateFromResource.get(resourceKey); updateFromResource.remove(resourceKey); - for (int i: resourceValue.keySet()) { + for (int i : resourceValue.keySet()) { Expression resExp = resourceValue.get(i); updateVaribleTypes(resExp, variables, expToVariable, updateFromVariable); updateMessageTypes(resExp, messages, expToMessage, updateFromMessage); updateConsTypes(resExp, cons, expToCons, updateFromCons); updateTupleTypes(resExp, tuple, expToTuple, updateFromTuple); + updatePairTypes(resExp, pair, expToPair, updateFromPair); } } if (updateFromVariable.size() > 0) { @@ -620,13 +682,14 @@ Integer variableKey = variableKeys.iterator().next(); Map variableValue = updateFromVariable.get(variableKey); updateFromVariable.remove(variableKey); - for (int i: variableValue.keySet()) { + for (int i : variableValue.keySet()) { Expression var = variableValue.get(i); updateResourceTypes(var, resources, expToResource, updateFromResource); updateVaribleTypes(var, variables, expToVariable, updateFromVariable); updateMessageTypes(var, messages, expToMessage, updateFromMessage); updateConsTypes(var, cons, expToCons, updateFromCons); updateTupleTypes(var, tuple, expToTuple, updateFromTuple); + updatePairTypes(var, pair, expToPair, updateFromPair); } } if (updateFromMessage.size() > 0) { @@ -634,12 +697,13 @@ Integer messageKey = messageKeys.iterator().next(); Map messageValue = updateFromMessage.get(messageKey); updateFromMessage.remove(messageKey); - for (int i: messageValue.keySet()) { + for (int i : messageValue.keySet()) { Expression mesExp = messageValue.get(i); updateResourceTypes(mesExp, resources, expToResource, updateFromResource); updateVaribleTypes(mesExp, variables, expToVariable, updateFromVariable); updateConsTypes(mesExp, cons, expToCons, updateFromCons); updateTupleTypes(mesExp, tuple, expToTuple, updateFromTuple); + updatePairTypes(mesExp, pair, expToPair, updateFromPair); } } if (updateFromCons.size() > 0) { @@ -647,13 +711,14 @@ Integer consKey = consKeys.iterator().next(); Map consValue = updateFromCons.get(consKey); updateFromCons.remove(consKey); - for (int i: consValue.keySet()) { + for (int i : consValue.keySet()) { Expression consExp = consValue.get(i); updateResourceTypes(consExp, resources, expToResource, updateFromResource); updateVaribleTypes(consExp, variables, expToVariable, updateFromVariable); updateMessageTypes(consExp, messages, expToMessage, updateFromMessage); updateConsTypes(consExp, cons, expToCons, updateFromCons); updateTupleTypes(consExp, tuple, expToTuple, updateFromTuple); + updatePairTypes(consExp, pair, expToPair, updateFromPair); } } if (updateFromTuple.size() > 0) { @@ -661,29 +726,49 @@ Integer tupleKey = tupleKeys.iterator().next(); Map tupleValue = updateFromTuple.get(tupleKey); updateFromTuple.remove(tupleKey); - for (int i: tupleValue.keySet()) { + for (int i : tupleValue.keySet()) { Expression tupleExp = tupleValue.get(i); updateResourceTypes(tupleExp, resources, expToResource, updateFromResource); updateVaribleTypes(tupleExp, variables, expToVariable, updateFromVariable); updateMessageTypes(tupleExp, messages, expToMessage, updateFromMessage); updateConsTypes(tupleExp, cons, expToCons, updateFromCons); updateTupleTypes(tupleExp, tuple, expToTuple, updateFromTuple); + updatePairTypes(tupleExp, pair, expToPair, updateFromPair); } } + + if (updateFromPair.size() > 0) { + Set pairKeys = updateFromPair.keySet(); + Integer pairKey = pairKeys.iterator().next(); + Map pairValue = updateFromPair.get(pairKey); + updateFromPair.remove(pairKey); + for (int i : pairValue.keySet()) { + Expression pairExp = pairValue.get(i); + updateResourceTypes(pairExp, resources, expToResource, updateFromResource); + updateVaribleTypes(pairExp, variables, expToVariable, updateFromVariable); + updateMessageTypes(pairExp, messages, expToMessage, updateFromMessage); + updateConsTypes(pairExp, cons, expToCons, updateFromCons); + updateTupleTypes(pairExp, tuple, expToTuple, updateFromTuple); + updatePairTypes(pairExp, pair, expToPair, updateFromPair); + } + + } } } - - private static void updateResourceTypes(Expression exp, Map> resources, Map> expToResource, Map> updateFromResource) { + + private static void updateResourceTypes(Expression exp, Map> resources, + Map> expToResource, Map> updateFromResource) { List sameResource = expToResource.get(System.identityHashCode(exp)); - if (sameResource == null) return; - for (IdentifierTemplate id: resources.keySet()) { + if (sameResource == null) + return; + for (IdentifierTemplate id : resources.keySet()) { if (resources.get(id) == sameResource) { Type resType = id.getResourceStateType(); Type newResType = getExpTypeIfUpdatable(resType, exp); if (newResType != null) { id.setResourceStateType(newResType); Map updateExps = getUpdateSet(updateFromResource, sameResource); - for (Expression resExp: sameResource) { + for (Expression resExp : sameResource) { if (resExp != exp) { if (resExp instanceof Variable) { ((Variable) resExp).setType(newResType); @@ -699,15 +784,17 @@ } } - private static void updateVaribleTypes(Expression exp, Map variables, Map> expToVariable, Map> updateFromVariable) { + private static void updateVaribleTypes(Expression exp, Map variables, + Map> expToVariable, Map> updateFromVariable) { List sameVariable = expToVariable.get(System.identityHashCode(exp)); - if (sameVariable == null) return; + if (sameVariable == null) + return; Type varType = variables.get(System.identityHashCode(sameVariable)); Type newVarType = getExpTypeIfUpdatable(varType, exp); if (newVarType != null) { variables.put(System.identityHashCode(sameVariable), newVarType); Map updateVars = getUpdateSet(updateFromVariable, sameVariable); - for (Expression v: sameVariable) { + for (Expression v : sameVariable) { if (v != exp) { if (v instanceof Variable) { ((Variable) v).setType(newVarType); @@ -721,27 +808,32 @@ } } - private static void updateMessageTypes(Expression exp, Map, Type>>> messages, Map> expToMessage, Map> updateFromMessage) { + private static void updateMessageTypes(Expression exp, + Map, Type>>> messages, + Map> expToMessage, Map> updateFromMessage) { List messageExps = expToMessage.get(System.identityHashCode(exp)); - if (messageExps == null) return; + if (messageExps == null) + return; Type msgType = null; Map.Entry, Type> expsAndType = null; - for (ChannelGenerator c: messages.keySet()) { - for (int i: messages.get(c).keySet()) { + for (ChannelGenerator c : messages.keySet()) { + for (int i : messages.get(c).keySet()) { expsAndType = messages.get(c).get(i); if (expsAndType.getKey() == messageExps) { msgType = expsAndType.getValue(); break; } } - if (msgType != null) break; + if (msgType != null) + break; } - if (msgType == null) return; + if (msgType == null) + return; Type newMsgType = getExpTypeIfUpdatable(msgType, exp); if (newMsgType != null) { expsAndType.setValue(newMsgType); Map updateExps = getUpdateSet(updateFromMessage, messageExps); - for (Expression e: messageExps) { + for (Expression e : messageExps) { if (e != exp) { if (e instanceof Variable) { ((Variable) e).setType(newMsgType); @@ -755,13 +847,16 @@ } } - private static void updateConsTypes(Expression exp, Map cons, Map> expToCons, Map> updateFromCons) { + private static void updateConsTypes(Expression exp, Map cons, + Map> expToCons, Map> updateFromCons) { List consComponents = expToCons.get(System.identityHashCode(exp)); - if (consComponents == null) return; + if (consComponents == null) + return; int idx = consComponents.indexOf(exp); switch (idx) { case 0: - if (!(exp instanceof Term)) return; + if (!(exp instanceof Term)) + return; Type listType = cons.get(System.identityHashCode(consComponents)); Type expType = getExpTypeIfUpdatable(listType, exp); if (expType != null) { @@ -837,7 +932,7 @@ Type newListType = new Type("List", "ArrayList<>", "List<" + compTypeName + ">", parentType); listTypes.put(compType, newListType); listComponentTypes.put(newListType, compType); - for (Type childType: childrenTypes) { + for (Type childType : childrenTypes) { if (compareTypes(childType, newListType)) { if (newListType.getParentTypes().contains(parentType)) { newListType.replaceParentType(parentType, childType); @@ -846,14 +941,14 @@ } } else if (compareTypes(newListType, childType)) { childType.replaceParentType(parentType, newListType); - } + } } return newListType; } - + private static List getChildrenTypesOfList(Type parentListType) { List childrenTypes = new ArrayList<>(); - for (Type listType: listComponentTypes.keySet()) { + for (Type listType : listComponentTypes.keySet()) { if (listType.getParentTypes().contains(parentListType)) { childrenTypes.add(listType); } @@ -861,9 +956,11 @@ return childrenTypes; } - private static void updateTupleTypes(Expression exp, Map tuple, Map> expToTuple, Map> updateFromTuple) { + private static void updateTupleTypes(Expression exp, Map tuple, + Map> expToTuple, Map> updateFromTuple) { List components = expToTuple.get(System.identityHashCode(exp)); - if (components == null) return; + if (components == null) + return; int idx = components.indexOf(exp); if (idx == 0) { Type tupleType = tuple.get(System.identityHashCode(components)); @@ -872,7 +969,7 @@ // Propagate an update of a tuple's type to its components' types. tuple.put(System.identityHashCode(components), newTupleType); List componentTypes = tupleComponentTypes.get(newTupleType); - Map updateExps = getUpdateSet(updateFromTuple, components); + Map updateExps = getUpdateSet(updateFromTuple, components); for (int i = 1; i < components.size(); i++) { Expression compExp = components.get(i); if (compExp instanceof Variable) { @@ -902,10 +999,10 @@ // Create new tuple type; newTupleType = createNewTupleType(componentTypes, tupleType); } - Map updateExps = getUpdateSet(updateFromTuple, components); + Map updateExps = getUpdateSet(updateFromTuple, components); Expression tupleExp = components.get(0); if (tupleExp instanceof Variable) { - ((Variable) tupleExp).setType(newTupleType); + ((Variable) tupleExp).setType(newTupleType); updateExps.put(System.identityHashCode(tupleExp), tupleExp); } else if (tupleExp instanceof Term) { ((Term) tupleExp).setType(newTupleType); @@ -916,24 +1013,80 @@ } } + private static void updatePairTypes(Expression exp, Map pair, + Map> expToPair, Map> updateFromPair) { + List components = expToPair.get(System.identityHashCode(exp)); + if (components == null) + return; + int idx = components.indexOf(exp); + if (idx == 0) { + Type pairType = pair.get(System.identityHashCode(components)); + Type newPairType = getExpTypeIfUpdatable(pairType, exp); + if (newPairType != null) { + // Propagate an update of a pair's type to its components' types. + pair.put(System.identityHashCode(components), newPairType); + Type componentType = pairComponentTypes.get(newPairType); + Map updateExps = getUpdateSet(updateFromPair, components); + for (int i = 1; i < components.size(); i++) { + Expression compExp = components.get(i); + if (compExp instanceof Variable) { + if (compareTypes(((Variable) compExp).getType(), componentType)) { + ((Variable) compExp).setType(componentType); + updateExps.put(System.identityHashCode(compExp), compExp); + } + } else if (compExp instanceof Term) { + if (compareTypes(((Term) compExp).getType(), componentType)) { + ((Term) compExp).setType(componentType); + updateExps.put(System.identityHashCode(compExp), compExp); + } + } + } + } + } else { + Type pairType = pair.get(System.identityHashCode(components)); + Type compType = pairComponentTypes.get(pairType); + Type newCompType = getExpTypeIfUpdatable(compType, exp); + if (newCompType != null) { + // Propagate an update of a component's type to its container's (pair's) type. + Type newPairType = pairTypes.get(compType); + if (newPairType != null) { + Map updateExps = getUpdateSet(updateFromPair, components); + Expression pairExp = components.get(0); + if (pairExp instanceof Variable) { + ((Variable) pairExp).setType(newPairType); + updateExps.put(System.identityHashCode(pairExp), pairExp); + } else if (pairExp instanceof Term) { + ((Term) pairExp).setType(newPairType); + updateExps.put(System.identityHashCode(pairExp), pairExp); + } + pair.put(System.identityHashCode(components), newPairType); + } + } + } + } + private static Type createNewTupleType(List componentTypes, Type parentTupleType) { String implTypeName = "AbstractMap.SimpleEntry<>"; String interfaceTypeName = "Map.Entry<$x>"; if (componentTypes.size() >= 2) { - implTypeName = implTypeName.replace("$x", getImplementationTypeName(componentTypes.get(0))+ "$x"); + implTypeName = implTypeName.replace("$x", getImplementationTypeName(componentTypes.get(0)) + "$x"); interfaceTypeName = interfaceTypeName.replace("$x", getInterfaceTypeName(componentTypes.get(0)) + "$x"); - for (Type argType: componentTypes.subList(1, componentTypes.size() - 1)) { - implTypeName = implTypeName.replace("$x", ", AbstractMap.SimpleEntry<" + getImplementationTypeName(argType)+ "$x>"); - interfaceTypeName = interfaceTypeName.replace("$x", ", Map.Entry<" + getInterfaceTypeName(argType) + "$x>"); + for (Type argType : componentTypes.subList(1, componentTypes.size() - 1)) { + implTypeName = implTypeName.replace("$x", + ", AbstractMap.SimpleEntry<" + getImplementationTypeName(argType) + "$x>"); + interfaceTypeName = interfaceTypeName.replace("$x", + ", Map.Entry<" + getInterfaceTypeName(argType) + "$x>"); } - implTypeName = implTypeName.replace("$x", ", " + getImplementationTypeName(componentTypes.get(componentTypes.size() - 1))); - interfaceTypeName = interfaceTypeName.replace("$x", ", " + getInterfaceTypeName(componentTypes.get(componentTypes.size() - 1))); + implTypeName = implTypeName.replace("$x", + ", " + getImplementationTypeName(componentTypes.get(componentTypes.size() - 1))); + interfaceTypeName = interfaceTypeName.replace("$x", + ", " + getInterfaceTypeName(componentTypes.get(componentTypes.size() - 1))); } List childrenTypes = getChildrenTypesOfTuple(parentTupleType); Type newTupleType = new Type("Tuple", implTypeName, interfaceTypeName, parentTupleType); tupleTypes.put(componentTypes, newTupleType); tupleComponentTypes.put(newTupleType, componentTypes); - for (Type childType: childrenTypes) { + for (Type childType : childrenTypes) { if (compareTypes(childType, newTupleType)) { if (newTupleType.getParentTypes().contains(parentTupleType)) { newTupleType.replaceParentType(parentTupleType, childType); @@ -946,32 +1099,37 @@ } return newTupleType; } - + private static List getChildrenTypesOfTuple(Type parentTupleType) { List childrenTypes = new ArrayList<>(); - for (Type tupleType: tupleComponentTypes.keySet()) { + for (Type tupleType : tupleComponentTypes.keySet()) { if (tupleType.getParentTypes().contains(parentTupleType)) { childrenTypes.add(tupleType); } } return childrenTypes; } - + private static String getImplementationTypeName(Type type) { - if (type == null) return "Integer"; - String wrapperType = DataConstraintModel.getWrapperType(type); - if (wrapperType != null) return wrapperType; + if (type == null) + return "Integer"; + String wrapperType = DataConstraintModel.getWrapperType(type); + if (wrapperType != null) + return wrapperType; return type.getImplementationTypeName(); } - + private static String getInterfaceTypeName(Type type) { - if (type == null) return "Integer"; - String wrapperType = DataConstraintModel.getWrapperType(type); - if (wrapperType != null) return wrapperType; + if (type == null) + return "Integer"; + String wrapperType = DataConstraintModel.getWrapperType(type); + if (wrapperType != null) + return wrapperType; return type.getInterfaceTypeName(); } - private static > Map getUpdateSet(Map> updateSets, U keySet) { + private static > Map getUpdateSet( + Map> updateSets, U keySet) { Map updatedExps = updateSets.get(System.identityHashCode(keySet)); if (updatedExps == null) { updatedExps = new HashMap<>(); @@ -979,7 +1137,7 @@ } return updatedExps; } - + private static Type getExpTypeIfUpdatable(Type originalType, Expression newExp) { Type expType = null; if (newExp instanceof Term) { @@ -995,27 +1153,37 @@ /** * Is an given original type an ancestor of a given new type? + * * @param originalType original type - * @param newType new type (may not have been registered) - * @return true: if the original type equals to the new type or is an ancestor of the new type, false: otherwise + * @param newType new type (may not have been registered) + * @return true: if the original type equals to the new type or is an ancestor + * of the new type, false: otherwise */ private static boolean compareTypes(Type originalType, Type newType) { - if (originalType == null) return true; + if (originalType == null) + return true; if (originalType != newType && newType != null) { - if (originalType.isAncestorOf(newType)) return true; - if (DataConstraintModel.typeTuple.isAncestorOf(originalType) && DataConstraintModel.typeTuple.isAncestorOf(newType)) { + if (originalType.isAncestorOf(newType)) + return true; + if (DataConstraintModel.typeTuple.isAncestorOf(originalType) + && DataConstraintModel.typeTuple.isAncestorOf(newType)) { List originalCompTypes = tupleComponentTypes.get(originalType); List newCompTypes = tupleComponentTypes.get(newType); - if (originalCompTypes == null) return true; + if (originalCompTypes == null) + return true; for (int i = 0; i < originalCompTypes.size(); i++) { - if (originalCompTypes.get(i) != null && (newCompTypes.get(i) == null || !originalCompTypes.get(i).isAncestorOf(newCompTypes.get(i)))) return false; + if (originalCompTypes.get(i) != null && (newCompTypes.get(i) == null + || !originalCompTypes.get(i).isAncestorOf(newCompTypes.get(i)))) + return false; } return true; } - if (DataConstraintModel.typeList.isAncestorOf(originalType) && DataConstraintModel.typeList.isAncestorOf(newType)) { + if (DataConstraintModel.typeList.isAncestorOf(originalType) + && DataConstraintModel.typeList.isAncestorOf(newType)) { Type originalCompType = listComponentTypes.get(originalType); Type newCompType = listComponentTypes.get(newType); - if (originalCompType != null && (newCompType == null || !originalCompType.isAncestorOf(newCompType))) return false; + if (originalCompType != null && (newCompType == null || !originalCompType.isAncestorOf(newCompType))) + return false; return true; } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/CompilationUnit.java b/AlgebraicDataflowArchitectureModel/src/code/ast/CompilationUnit.java index 5e66684..9a5a58a 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/CompilationUnit.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/CompilationUnit.java @@ -10,7 +10,10 @@ public CompilationUnit(TypeDeclaration type) { types.add(type); - fileName = type.getTypeName() + ".java"; + if(type.getTypeName().contains("<")) + fileName = type.getTypeName().split("<")[0] + ".java"; + else + fileName = type.getTypeName() + ".java"; } public List imports() { diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 04aa0bc..9939c59 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -25,6 +25,10 @@ public static final Type typeListInt = new Type("List", "ArrayList<>", "List", typeList); public static final Type typeListStr = new Type("List", "ArrayList<>", "List", typeList); public static final Type typeTuple = new Type("Tuple", "AbstractMap.SimpleEntry", "Map.Entry"); + public static final Type typePair = new Type("Pair", "Pair", "Pair"); + public static final Type typePairInt = new Type("Pair", "Pair", "Pair",typePair); + public static final Type typePairStr = new Type("Pair", "Pair", "Pair",typePair); + public static final Type typePairDouble = new Type("Pair", "Pair", "Pair",typePair); public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX); public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX);; public static final Symbol sub = new Symbol(Parser.SUB, 2, Symbol.Type.INFIX); @@ -81,6 +85,13 @@ public static final Symbol neg = new Symbol("neg", 1, Symbol.Type.PREFIX, "!", Symbol.Type.PREFIX); public static final Symbol true_ = new Symbol("true", 0, Symbol.Type.PREFIX, "true", Symbol.Type.PREFIX); public static final Symbol false_ = new Symbol("false", 0, Symbol.Type.PREFIX, "false", Symbol.Type.PREFIX); + public static final Symbol pair = new Symbol("pair", -1, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { + @Override + public String generate(Type type, String[] childrenImpl, String[] sideEffects) { + String impl = "new Pair<>(" + childrenImpl[0] + "," + childrenImpl[1] + ")"; + return impl; + } + }); public static final Symbol tuple = new Symbol("tuple", -1, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { @Override public String generate(Type type, String[] childrenImpl, String[] sideEffects) { @@ -117,6 +128,8 @@ neg.setSignature(new Type[] {typeBoolean, typeBoolean}); true_.setSignature(new Type[] {typeBoolean}); false_.setSignature(new Type[] {typeBoolean}); + pair.setSignature(new Type[] {typePair,null,null}); + pair.setInverses(new Symbol[] {fst, snd}); tuple.setSignature(new Type[] {typeTuple, null, null}); tuple.setInverses(new Symbol[] {fst, snd}); fst.setSignature(new Type[] {null, typeTuple}); @@ -135,6 +148,7 @@ addType(typeBoolean); addType(typeString); addType(typeList); + addType(typePair); addType(typeTuple); symbols = new HashMap<>(); addSymbol(add); @@ -161,6 +175,7 @@ addSymbol(neg); addSymbol(true_); addSymbol(false_); + addSymbol(pair); addSymbol(tuple); addSymbol(fst); addSymbol(snd);