diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index e2be926..a890ad3 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -82,16 +82,14 @@ Map> resources = new HashMap<>(); Map variables = new HashMap<>(); Map, Type>>> messages = new HashMap<>(); - Map cons = new HashMap<>(); - Map get = new HashMap<>(); + Map consOrSet = new HashMap<>(); Map tuple = new HashMap<>(); Map pair = new HashMap<>(); Map map = new HashMap<>(); Map> expToResource = new HashMap<>(); Map> expToVariable = new HashMap<>(); Map> expToMessage = new HashMap<>(); - Map>> expToCons = new HashMap<>(); - Map>> expToGet = new HashMap<>(); + Map>> expToConsOrSet = new HashMap<>(); Map>> expToTuple = new HashMap<>(); Map>> expToPair = new HashMap<>(); Map>> expToMap = new HashMap<>(); @@ -100,7 +98,7 @@ Map> updateFromResource = new HashMap<>(); Map> updateFromVariable = new HashMap<>(); Map> updateFromMessage = new HashMap<>(); - Map> updateFromCons = new HashMap<>(); + Map> updateFromConsOrSet = new HashMap<>(); Map> updateFromTuple = new HashMap<>(); Map> updateFromPair = new HashMap<>(); Map> updateFromMap = new HashMap<>(); @@ -346,62 +344,58 @@ // If the root symbol of the term is cons or set. List consExps = new ArrayList<>(); consExps.add(t); - updateExpressionBelonging(expToCons, t, consExps); + updateExpressionBelonging(expToConsOrSet, t, consExps); if (symbol.equals(DataConstraintModel.cons)) { // If the root symbol of the term is cons. for (Expression e : t.getChildren()) { consExps.add(e); - updateExpressionBelonging(expToCons, e, consExps); + updateExpressionBelonging(expToConsOrSet, e, consExps); } } else { // If the root symbol of the term is set. Expression e = t.getChildren().get(2); consExps.add(e); - updateExpressionBelonging(expToCons, e, consExps); + updateExpressionBelonging(expToConsOrSet, e, consExps); e = t.getChildren().get(0); consExps.add(e); - updateExpressionBelonging(expToCons, e, consExps); + updateExpressionBelonging(expToConsOrSet, 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 2nd argument of cons (1st argument of set) is more concrete than the type of the term. t.setType(newType); - Map updateCons = getUpdateSet(updateFromCons, consExps); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); updateCons.put(System.identityHashCode(t), t); } else { Type arg2Type = null; 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 2nd argument of cons (1st argument of set). ((Variable) consExps.get(2)).setType(t.getType()); - Map updateCons = getUpdateSet(updateFromCons, consExps); + Map updateCons = getUpdateSet(updateFromConsOrSet, 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(); 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 2nd argument of cons (1st argument of set). ((Term) consExps.get(2)).setType(t.getType()); - Map updateCons = getUpdateSet(updateFromCons, consExps); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); updateCons.put(System.identityHashCode(consExps.get(2)), consExps.get(2)); } } } 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 1st argument of cons (3rd argument of set) is more concrete than the type of list component. Type newListType = listTypes.get(newCompType); if (newListType == null) { // Create new list type. newListType = createNewListType(newCompType, DataConstraintModel.typeList); } t.setType(newListType); - Map updateCons = getUpdateSet(updateFromCons, consExps); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); updateCons.put(System.identityHashCode(t), t); if (consExps.get(2) != null && consExps.get(2) instanceof Variable) { ((Variable) consExps.get(2)).setType(newListType); @@ -411,41 +405,80 @@ updateCons.put(System.identityHashCode(consExps.get(2)), consExps.get(2)); } } - cons.put(System.identityHashCode(consExps), t.getType()); + consOrSet.put(System.identityHashCode(consExps), t.getType()); } else if (symbol.equals(DataConstraintModel.head) || symbol.equals(DataConstraintModel.get)) { // If the root symbol of the term is head or get. List consExps = new ArrayList<>(); Expression e = t.getChildren().get(0); consExps.add(e); - updateExpressionBelonging(expToCons, e, consExps); + updateExpressionBelonging(expToConsOrSet, e, consExps); consExps.add(t); - updateExpressionBelonging(expToCons, t, consExps); + updateExpressionBelonging(expToConsOrSet, t, consExps); consExps.add(null); Type listType = listTypes.get(t.getType()); - if (listType == null) { + if (listType == null && t.getType() != null) { // Create a new list type. listType = createNewListType(t.getType(), DataConstraintModel.typeList); } Type newListType = getExpTypeIfUpdatable(listType, consExps.get(0)); if (newListType != null) { - // If the type of the component of the first argument is more concrete than the type of the term. + // If the type of the component of the 1st argument is more concrete than the type of the term. Type newCompType = listComponentTypes.get(newListType); - t.setType(newCompType); - Map updateCons = getUpdateSet(updateFromCons, consExps); - updateCons.put(System.identityHashCode(t), t); + if (newCompType != null) { + t.setType(newCompType); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); + updateCons.put(System.identityHashCode(t), t); + } + consOrSet.put(System.identityHashCode(consExps), newListType); } else { - // If the type of the term is more concrete than the type of the component of the first argument. + // If the type of the term is more concrete than the type of the component of the 1st argument. if (consExps.get(0) != null && consExps.get(0) instanceof Variable) { ((Variable) consExps.get(0)).setType(listType); - Map updateCons = getUpdateSet(updateFromCons, consExps); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); updateCons.put(System.identityHashCode(consExps.get(0)), consExps.get(0)); } else if (consExps.get(0) != null && consExps.get(0) instanceof Term) { ((Term) consExps.get(0)).setType(listType); - Map updateCons = getUpdateSet(updateFromCons, consExps); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); updateCons.put(System.identityHashCode(consExps.get(0)), consExps.get(0)); } + consOrSet.put(System.identityHashCode(consExps), listType); } - cons.put(System.identityHashCode(consExps), t.getType()); + } else if (symbol.equals(DataConstraintModel.tail)) { + // If the root symbol of the term is tail. + List consExps = new ArrayList<>(); + consExps.add(t); + updateExpressionBelonging(expToConsOrSet, t, consExps); + consExps.add(null); + Expression e = t.getChildren().get(0); + consExps.add(e); + updateExpressionBelonging(expToConsOrSet, e, consExps); + Type newType = getExpTypeIfUpdatable(t.getType(), consExps.get(2)); + if (newType != null) { + // If the type of the argument is more concrete than the type of the term. + t.setType(newType); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); + updateCons.put(System.identityHashCode(t), t); + } else { + Type argType = null; + if (consExps.get(2) != null && consExps.get(2) instanceof Variable) { + argType = ((Variable) consExps.get(2)).getType(); + if (compareTypes(argType, t.getType())) { + // If the type of the term is more concrete than the type of the argument. + ((Variable) consExps.get(2)).setType(t.getType()); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); + updateCons.put(System.identityHashCode(consExps.get(2)), consExps.get(2)); + } + } else if (consExps.get(2) != null && consExps.get(2) instanceof Term) { + argType = ((Term) consExps.get(2)).getType(); + if (compareTypes(argType, t.getType())) { + // If the type of the term is more concrete than the type of the argument. + ((Term) consExps.get(2)).setType(t.getType()); + Map updateCons = getUpdateSet(updateFromConsOrSet, consExps); + updateCons.put(System.identityHashCode(consExps.get(2)), consExps.get(2)); + } + } + } + consOrSet.put(System.identityHashCode(consExps), t.getType()); } else if (symbol.equals(DataConstraintModel.tuple)) { // If the root symbol of the term is tuple. List tupleExps = new ArrayList<>(); @@ -896,7 +929,7 @@ // 2. Propagate type information. while (updateFromResource.size() > 0 || updateFromVariable.size() > 0 || updateFromMessage.size() > 0 - || updateFromCons.size() > 0 || updateFromTuple.size() > 0 || updateFromPair.size() > 0 || updateFromMap.size() > 0) { + || updateFromConsOrSet.size() > 0 || updateFromTuple.size() > 0 || updateFromPair.size() > 0 || updateFromMap.size() > 0) { if (updateFromResource.size() > 0) { Set resourceKeys = updateFromResource.keySet(); Integer resourceKey = resourceKeys.iterator().next(); @@ -906,7 +939,7 @@ Expression resExp = resourceValue.get(i); updateVaribleTypes(resExp, variables, expToVariable, updateFromVariable); updateMessageTypes(resExp, messages, expToMessage, updateFromMessage); - updateConsTypes(resExp, cons, expToCons, updateFromCons); + updateConsOrSetTypes(resExp, consOrSet, expToConsOrSet, updateFromConsOrSet); updateTupleTypes(resExp, tuple, expToTuple, updateFromTuple); updatePairTypes(resExp, pair, expToPair, updateFromPair); updateMapTypes(resExp, map, expToMap, updateFromMap); @@ -922,7 +955,7 @@ updateResourceTypes(var, resources, expToResource, updateFromResource); updateVaribleTypes(var, variables, expToVariable, updateFromVariable); updateMessageTypes(var, messages, expToMessage, updateFromMessage); - updateConsTypes(var, cons, expToCons, updateFromCons); + updateConsOrSetTypes(var, consOrSet, expToConsOrSet, updateFromConsOrSet); updateTupleTypes(var, tuple, expToTuple, updateFromTuple); updatePairTypes(var, pair, expToPair, updateFromPair); updateMapTypes(var, map, expToMap, updateFromMap); @@ -937,23 +970,23 @@ Expression mesExp = messageValue.get(i); updateResourceTypes(mesExp, resources, expToResource, updateFromResource); updateVaribleTypes(mesExp, variables, expToVariable, updateFromVariable); - updateConsTypes(mesExp, cons, expToCons, updateFromCons); + updateConsOrSetTypes(mesExp, consOrSet, expToConsOrSet, updateFromConsOrSet); updateTupleTypes(mesExp, tuple, expToTuple, updateFromTuple); updatePairTypes(mesExp, pair, expToPair, updateFromPair); updateMapTypes(mesExp, map, expToMap, updateFromMap); } } - if (updateFromCons.size() > 0) { - Set consKeys = updateFromCons.keySet(); + if (updateFromConsOrSet.size() > 0) { + Set consKeys = updateFromConsOrSet.keySet(); Integer consKey = consKeys.iterator().next(); - Map consValue = updateFromCons.get(consKey); - updateFromCons.remove(consKey); + Map consValue = updateFromConsOrSet.get(consKey); + updateFromConsOrSet.remove(consKey); 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); + updateConsOrSetTypes(consExp, consOrSet, expToConsOrSet, updateFromConsOrSet); updateTupleTypes(consExp, tuple, expToTuple, updateFromTuple); updatePairTypes(consExp, pair, expToPair, updateFromPair); updateMapTypes(consExp, map, expToMap, updateFromMap); @@ -969,7 +1002,7 @@ updateResourceTypes(tupleExp, resources, expToResource, updateFromResource); updateVaribleTypes(tupleExp, variables, expToVariable, updateFromVariable); updateMessageTypes(tupleExp, messages, expToMessage, updateFromMessage); - updateConsTypes(tupleExp, cons, expToCons, updateFromCons); + updateConsOrSetTypes(tupleExp, consOrSet, expToConsOrSet, updateFromConsOrSet); updateTupleTypes(tupleExp, tuple, expToTuple, updateFromTuple); updatePairTypes(tupleExp, pair, expToPair, updateFromPair); updateMapTypes(tupleExp, map, expToMap, updateFromMap); @@ -985,7 +1018,7 @@ updateResourceTypes(pairExp, resources, expToResource, updateFromResource); updateVaribleTypes(pairExp, variables, expToVariable, updateFromVariable); updateMessageTypes(pairExp, messages, expToMessage, updateFromMessage); - updateConsTypes(pairExp, cons, expToCons, updateFromCons); + updateConsOrSetTypes(pairExp, consOrSet, expToConsOrSet, updateFromConsOrSet); updateTupleTypes(pairExp, tuple, expToTuple, updateFromTuple); updatePairTypes(pairExp, pair, expToPair, updateFromPair); updateMapTypes(pairExp, map, expToMap, updateFromMap); @@ -1001,7 +1034,7 @@ updateResourceTypes(mapExp, resources, expToResource, updateFromResource); updateVaribleTypes(mapExp, variables, expToVariable, updateFromVariable); updateMessageTypes(mapExp, messages, expToMessage, updateFromMessage); - updateConsTypes(mapExp, cons, expToCons, updateFromCons); + updateConsOrSetTypes(mapExp, consOrSet, expToConsOrSet, updateFromConsOrSet); updateTupleTypes(mapExp, tuple, expToTuple, updateFromTuple); updatePairTypes(mapExp, pair, expToPair, updateFromPair); updateMapTypes(mapExp, map, expToMap, updateFromMap); @@ -1126,39 +1159,39 @@ } } - private static void updateConsTypes(Expression exp, Map cons, - Map>> expToCons, Map> updateFromCons) { - Set> consComponentGroups = expToCons.get(System.identityHashCode(exp)); + private static void updateConsOrSetTypes(Expression exp, Map consOrSet, + Map>> expToConsOrSet, Map> updateFromConsOrSet) { + Set> consComponentGroups = expToConsOrSet.get(System.identityHashCode(exp)); if (consComponentGroups == null) return; - for (List consComponentGroup: consComponentGroups) { - int idx = consComponentGroup.indexOf(exp); + for (List consOrSetComponentGroup: consComponentGroups) { + int idx = consOrSetComponentGroup.indexOf(exp); switch (idx) { case 0: if (!(exp instanceof Term)) break; - Type listType = cons.get(System.identityHashCode(consComponentGroup)); + Type listType = consOrSet.get(System.identityHashCode(consOrSetComponentGroup)); Type expType = getExpTypeIfUpdatable(listType, exp); if (expType != null) { - cons.put(System.identityHashCode(consComponentGroup), expType); - Map updateExps = getUpdateSet(updateFromCons, consComponentGroup); - if (consComponentGroup.get(2) instanceof Variable) { - ((Variable) consComponentGroup.get(2)).setType(expType); - updateExps.put(System.identityHashCode(consComponentGroup.get(2)), consComponentGroup.get(2)); - } else if (consComponentGroup.get(2) instanceof Term) { - ((Term) consComponentGroup.get(2)).setType(expType); - updateExps.put(System.identityHashCode(consComponentGroup.get(2)), consComponentGroup.get(2)); + consOrSet.put(System.identityHashCode(consOrSetComponentGroup), expType); + Map updateExps = getUpdateSet(updateFromConsOrSet, consOrSetComponentGroup); + if (consOrSetComponentGroup.get(2) instanceof Variable) { + ((Variable) consOrSetComponentGroup.get(2)).setType(expType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(2)), consOrSetComponentGroup.get(2)); + } else if (consOrSetComponentGroup.get(2) instanceof Term) { + ((Term) consOrSetComponentGroup.get(2)).setType(expType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(2)), consOrSetComponentGroup.get(2)); } Type compType = listComponentTypes.get(expType); - if (consComponentGroup.get(1) != null && consComponentGroup.get(1) instanceof Variable) { - ((Variable) consComponentGroup.get(1)).setType(compType); - updateExps.put(System.identityHashCode(consComponentGroup.get(1)), consComponentGroup.get(1)); - } else if (consComponentGroup.get(1) != null && consComponentGroup.get(1) instanceof Term) { - ((Term) consComponentGroup.get(1)).setType(compType); - updateExps.put(System.identityHashCode(consComponentGroup.get(1)), consComponentGroup.get(1)); + if (consOrSetComponentGroup.get(1) != null && consOrSetComponentGroup.get(1) instanceof Variable) { + ((Variable) consOrSetComponentGroup.get(1)).setType(compType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(1)), consOrSetComponentGroup.get(1)); + } else if (consOrSetComponentGroup.get(1) != null && consOrSetComponentGroup.get(1) instanceof Term) { + ((Term) consOrSetComponentGroup.get(1)).setType(compType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(1)), consOrSetComponentGroup.get(1)); } } break; case 1: - listType = cons.get(System.identityHashCode(consComponentGroup)); + listType = consOrSet.get(System.identityHashCode(consOrSetComponentGroup)); Type compType = listComponentTypes.get(listType); Type newCompType = getExpTypeIfUpdatable(compType, exp); if (newCompType != null) { @@ -1167,38 +1200,38 @@ // Create new list type. newListType = createNewListType(newCompType, listType); } - cons.put(System.identityHashCode(consComponentGroup), newListType); - Map updateExps = getUpdateSet(updateFromCons, consComponentGroup); - if (consComponentGroup.get(0) instanceof Term) { - ((Term) consComponentGroup.get(0)).setType(newListType); - updateExps.put(System.identityHashCode(consComponentGroup.get(0)), consComponentGroup.get(0)); + consOrSet.put(System.identityHashCode(consOrSetComponentGroup), newListType); + Map updateExps = getUpdateSet(updateFromConsOrSet, consOrSetComponentGroup); + if (consOrSetComponentGroup.get(0) instanceof Term) { + ((Term) consOrSetComponentGroup.get(0)).setType(newListType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(0)), consOrSetComponentGroup.get(0)); } - if (consComponentGroup.get(2) instanceof Variable) { - ((Variable) consComponentGroup.get(2)).setType(newListType); - updateExps.put(System.identityHashCode(consComponentGroup.get(2)), consComponentGroup.get(2)); - } else if (consComponentGroup.get(2) instanceof Term) { - ((Term) consComponentGroup.get(2)).setType(newListType); - updateExps.put(System.identityHashCode(consComponentGroup.get(2)), consComponentGroup.get(2)); + if (consOrSetComponentGroup.get(2) instanceof Variable) { + ((Variable) consOrSetComponentGroup.get(2)).setType(newListType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(2)), consOrSetComponentGroup.get(2)); + } else if (consOrSetComponentGroup.get(2) instanceof Term) { + ((Term) consOrSetComponentGroup.get(2)).setType(newListType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(2)), consOrSetComponentGroup.get(2)); } } break; case 2: - listType = cons.get(System.identityHashCode(consComponentGroup)); + listType = consOrSet.get(System.identityHashCode(consOrSetComponentGroup)); expType = getExpTypeIfUpdatable(listType, exp); if (expType != null) { - cons.put(System.identityHashCode(consComponentGroup), expType); - Map updateExps = getUpdateSet(updateFromCons, consComponentGroup); - if (consComponentGroup.get(0) instanceof Term) { - ((Term) consComponentGroup.get(0)).setType(expType); - updateExps.put(System.identityHashCode(consComponentGroup.get(0)), consComponentGroup.get(0)); + consOrSet.put(System.identityHashCode(consOrSetComponentGroup), expType); + Map updateExps = getUpdateSet(updateFromConsOrSet, consOrSetComponentGroup); + if (consOrSetComponentGroup.get(0) instanceof Term) { + ((Term) consOrSetComponentGroup.get(0)).setType(expType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(0)), consOrSetComponentGroup.get(0)); } compType = listComponentTypes.get(expType); - if (consComponentGroup.get(1) != null && consComponentGroup.get(1) instanceof Variable) { - ((Variable) consComponentGroup.get(1)).setType(compType); - updateExps.put(System.identityHashCode(consComponentGroup.get(1)), consComponentGroup.get(1)); - } else if (consComponentGroup.get(1) != null && consComponentGroup.get(1) instanceof Term) { - ((Term) consComponentGroup.get(1)).setType(compType); - updateExps.put(System.identityHashCode(consComponentGroup.get(1)), consComponentGroup.get(1)); + if (consOrSetComponentGroup.get(1) != null && consOrSetComponentGroup.get(1) instanceof Variable) { + ((Variable) consOrSetComponentGroup.get(1)).setType(compType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(1)), consOrSetComponentGroup.get(1)); + } else if (consOrSetComponentGroup.get(1) != null && consOrSetComponentGroup.get(1) instanceof Term) { + ((Term) consOrSetComponentGroup.get(1)).setType(compType); + updateExps.put(System.identityHashCode(consOrSetComponentGroup.get(1)), consOrSetComponentGroup.get(1)); } } }