diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index 3eaffde..d2c98ef 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -2,6 +2,7 @@ import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -79,7 +80,7 @@ listComponentTypes.put(DataConstraintModel.typeListStr, DataConstraintModel.typeString); listTypes.put(DataConstraintModel.typeInt, DataConstraintModel.typeListInt); listTypes.put(DataConstraintModel.typeString, DataConstraintModel.typeListStr); - tupleComponentTypes.put(DataConstraintModel.typeTuple, null); + tupleComponentTypes.put(DataConstraintModel.typeTuple, Arrays.asList(new Type[] {null, null})); for (Node n: graph.getNodes()) { ResourceNode resource = (ResourceNode) n; idToRes.put(resource.getIdentifierTemplate(), resource); @@ -382,6 +383,82 @@ updateExps.put(System.identityHashCode(t), t); } tuple.put(System.identityHashCode(tupleExps), t.getType()); + } else if (symbol.equals(DataConstraintModel.fst)) { + // If the root symbol of the term is fst. + List tupleExps = new ArrayList<>(); + Expression arg = t.getChildren().get(0); + tupleExps.add(arg); + expToTuple.put(System.identityHashCode(arg), tupleExps); + tupleExps.add(t); + expToTuple.put(System.identityHashCode(t), tupleExps); + tupleExps.add(null); + Type argType = null; + if (arg instanceof Variable) { + argType = ((Variable) arg).getType(); + } else if (arg instanceof Term) { + argType = ((Term) arg).getType(); + } + Type newTupleType = DataConstraintModel.typeTuple; + if (argType == DataConstraintModel.typeTuple && t.getType() != null) { + List compTypeList = new ArrayList<>(); + compTypeList.add(t.getType()); + compTypeList.add(null); + newTupleType = tupleTypes.get(compTypeList); + if (newTupleType == null) { + // Create new tuple type; + newTupleType = createNewTupleType(compTypeList, DataConstraintModel.typeTuple); + } + } + if (argType != newTupleType && newTupleType != null) { + if (arg instanceof Variable) { + ((Variable) arg).setType(newTupleType); + argType = newTupleType; + } else if (arg instanceof Term) { + ((Term) arg).setType(newTupleType); + argType = newTupleType; + } + Map updateExps = getUpdateSet(updateFromTuple, tupleExps); + updateExps.put(System.identityHashCode(arg), arg); + } + tuple.put(System.identityHashCode(tupleExps), argType); + } else if (symbol.equals(DataConstraintModel.snd)) { + // If the root symbol of the term is snd. + List tupleExps = new ArrayList<>(); + Expression arg = t.getChildren().get(0); + tupleExps.add(arg); + expToTuple.put(System.identityHashCode(arg), tupleExps); + tupleExps.add(null); + tupleExps.add(t); + expToTuple.put(System.identityHashCode(t), tupleExps); + Type argType = null; + if (arg instanceof Variable) { + argType = ((Variable) arg).getType(); + } else if (arg instanceof Term) { + argType = ((Term) arg).getType(); + } + Type newTupleType = DataConstraintModel.typeTuple; + if (argType == DataConstraintModel.typeTuple && t.getType() != null) { + List compTypeList = new ArrayList<>(); + compTypeList.add(null); + compTypeList.add(t.getType()); + newTupleType = tupleTypes.get(compTypeList); + if (newTupleType == null) { + // Create new tuple type; + newTupleType = createNewTupleType(compTypeList, DataConstraintModel.typeTuple); + } + } + if (argType != newTupleType && newTupleType != null) { + if (arg instanceof Variable) { + ((Variable) arg).setType(newTupleType); + argType = newTupleType; + } else if (arg instanceof Term) { + ((Term) arg).setType(newTupleType); + argType = newTupleType; + } + Map updateExps = getUpdateSet(updateFromTuple, tupleExps); + updateExps.put(System.identityHashCode(arg), arg); + } + tuple.put(System.identityHashCode(tupleExps), argType); } else if (symbol.equals(DataConstraintModel.cond)) { // If the root symbol of the term is if function. Expression c1 = t.getChild(1); @@ -431,6 +508,56 @@ } } variables.put(System.identityHashCode(condTerms), condType); + } 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); + Expression c2 = t.getChild(1); + List operands = new ArrayList<>(); + operands.add(t); + operands.add(c1); + operands.add(c2); + expToVariable.put(System.identityHashCode(t), operands); + expToVariable.put(System.identityHashCode(c1), operands); + expToVariable.put(System.identityHashCode(c2), operands); + Type opType = t.getType(); + Map updatedVars = getUpdateSet(updateFromVariable, operands); + Type child1Type = getExpTypeIfUpdatable(opType, c1); + if (child1Type != null) { + opType = child1Type; + t.setType(child1Type); + updatedVars.put(System.identityHashCode(t), t); + } else { + if (c1 instanceof Variable && compareTypes(((Variable) c1).getType(), opType)) { + ((Variable) c1).setType(opType); + updatedVars.put(System.identityHashCode(c1), c1); + } else if (c1 instanceof Term && compareTypes(((Term) c1).getType(), opType)) { + ((Term) c1).setType(opType); + updatedVars.put(System.identityHashCode(c1), c1); + } + } + Type child2Type = getExpTypeIfUpdatable(opType, c2); + if (child2Type != null) { + opType = child2Type; + t.setType(child2Type); + updatedVars.put(System.identityHashCode(t), t); + if (c1 instanceof Variable) { + ((Variable) c1).setType(child2Type); + updatedVars.put(System.identityHashCode(c1), c1); + } else if (c1 instanceof Term) { + ((Term) c1).setType(child2Type); + updatedVars.put(System.identityHashCode(c1), c1); + } + } else { + if (c2 instanceof Variable && compareTypes(((Variable) c2).getType(), opType)) { + ((Variable) c2).setType(opType); + updatedVars.put(System.identityHashCode(c2), c2); + } else if (c2 instanceof Term && compareTypes(((Term) c2).getType(), opType)) { + ((Term) c2).setType(opType); + updatedVars.put(System.identityHashCode(c2), c2); + } + } + 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). List consExps = new ArrayList<>(); @@ -723,16 +850,16 @@ tuple.put(System.identityHashCode(components), newTupleType); List componentTypes = tupleComponentTypes.get(newTupleType); Map updateExps = getUpdateSet(updateFromTuple, components); - for (int i = 0; i < components.size(); i++) { + for (int i = 1; i < components.size(); i++) { Expression compExp = components.get(i); if (compExp instanceof Variable) { - if (compareTypes(((Variable) compExp).getType(), componentTypes.get(i))) { - ((Variable) compExp).setType(componentTypes.get(i)); + if (compareTypes(((Variable) compExp).getType(), componentTypes.get(i - 1))) { + ((Variable) compExp).setType(componentTypes.get(i - 1)); updateExps.put(System.identityHashCode(compExp), compExp); } - }else if (compExp instanceof Term) { - if (compareTypes(((Term) compExp).getType(), componentTypes.get(i))) { - ((Variable) compExp).setType(componentTypes.get(i)); + } else if (compExp instanceof Term) { + if (compareTypes(((Term) compExp).getType(), componentTypes.get(i - 1))) { + ((Term) compExp).setType(componentTypes.get(i - 1)); updateExps.put(System.identityHashCode(compExp), compExp); } } @@ -751,10 +878,15 @@ // Create new tuple type; newTupleType = createNewTupleType(componentTypes, tupleType); } - Term t = (Term) components.get(0); - t.setType(newTupleType); Map updateExps = getUpdateSet(updateFromTuple, components); - updateExps.put(System.identityHashCode(t), t); + Expression tupleExp = components.get(0); + if (tupleExp instanceof Variable) { + ((Variable) tupleExp).setType(newTupleType); + updateExps.put(System.identityHashCode(tupleExp), tupleExp); + } else if (tupleExp instanceof Term) { + ((Term) tupleExp).setType(newTupleType); + updateExps.put(System.identityHashCode(tupleExp), tupleExp); + } tuple.put(System.identityHashCode(components), newTupleType); } } @@ -816,8 +948,24 @@ } private static boolean compareTypes(Type originalType, Type newType) { - if (originalType == null || (originalType != newType && newType != null && originalType.isAncestorOf(newType))) { - 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)) { + List originalCompTypes = tupleComponentTypes.get(originalType); + List newCompTypes = tupleComponentTypes.get(newType); + 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; + } + return true; + } + 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; + return true; + } } return false; }