diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index 4386f2c..df93e13 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -89,10 +89,10 @@ Map> expToResource = new HashMap<>(); Map> expToVariable = new HashMap<>(); Map> expToMessage = new HashMap<>(); - Map> expToCons = new HashMap<>(); - Map> expToTuple = new HashMap<>(); - Map> expToPair = new HashMap<>(); - Map> expToMap = new HashMap<>(); + Map>> expToCons = new HashMap<>(); + Map>> expToTuple = new HashMap<>(); + Map>> expToPair = new HashMap<>(); + Map>> expToMap = new HashMap<>(); Map idToRes = new HashMap<>(); Map> updateFromResource = new HashMap<>(); @@ -344,10 +344,10 @@ // If the root symbol of the term is cons. List consExps = new ArrayList<>(); consExps.add(t); - expToCons.put(System.identityHashCode(t), consExps); + updateExpressionBelonging(expToCons, t, consExps); for (Expression e : t.getChildren()) { consExps.add(e); - expToCons.put(System.identityHashCode(e), consExps); + updateExpressionBelonging(expToCons, e, consExps); } Type newType = getExpTypeIfUpdatable(t.getType(), consExps.get(2)); if (newType != null) { @@ -404,10 +404,10 @@ List tupleExps = new ArrayList<>(); List argsTypeList = new ArrayList<>(); tupleExps.add(t); - expToTuple.put(System.identityHashCode(t), tupleExps); + updateExpressionBelonging(expToTuple, t, tupleExps); for (Expression e : t.getChildren()) { tupleExps.add(e); - expToTuple.put(System.identityHashCode(e), tupleExps); + updateExpressionBelonging(expToTuple, e, tupleExps); if (e instanceof Variable) { argsTypeList.add(((Variable) e).getType()); } else if (e instanceof Term) { @@ -431,13 +431,11 @@ // If the root symbol of the term is pair. List pairExps = new ArrayList<>(); pairExps.add(t); - expToPair.put(System.identityHashCode(t), pairExps); - + updateExpressionBelonging(expToPair, t, pairExps); if (t.getType() == DataConstraintModel.typePair) { for (Expression e : t.getChildren()) { pairExps.add(e); - expToPair.put(System.identityHashCode(e), pairExps); - + updateExpressionBelonging(expToPair, e, pairExps); Type argType = null; if (e instanceof Variable) { argType = (((Variable) e).getType()); @@ -463,9 +461,9 @@ List tupleExps = new ArrayList<>(); Expression arg = t.getChildren().get(0); tupleExps.add(arg); - expToTuple.put(System.identityHashCode(arg), tupleExps); + updateExpressionBelonging(expToTuple, arg, tupleExps); tupleExps.add(t); - expToTuple.put(System.identityHashCode(t), tupleExps); + updateExpressionBelonging(expToTuple, t, tupleExps); tupleExps.add(null); Type argType = null; if (arg instanceof Variable) { @@ -501,10 +499,10 @@ List tupleExps = new ArrayList<>(); Expression arg = t.getChildren().get(0); tupleExps.add(arg); - expToTuple.put(System.identityHashCode(arg), tupleExps); + updateExpressionBelonging(expToTuple, arg, tupleExps); tupleExps.add(null); tupleExps.add(t); - expToTuple.put(System.identityHashCode(t), tupleExps); + updateExpressionBelonging(expToTuple, t, tupleExps); Type argType = null; if (arg instanceof Variable) { argType = ((Variable) arg).getType(); @@ -539,9 +537,9 @@ List pairExps = new ArrayList<>(); Expression arg = t.getChildren().get(0); pairExps.add(arg); - expToPair.put(System.identityHashCode(arg), pairExps); + updateExpressionBelonging(expToPair, arg, pairExps); pairExps.add(t); - expToPair.put(System.identityHashCode(t), pairExps); + updateExpressionBelonging(expToPair, t, pairExps); pairExps.add(null); Type argType = null; if (arg instanceof Variable) { @@ -577,10 +575,10 @@ List pairExps = new ArrayList<>(); Expression arg = t.getChildren().get(0); pairExps.add(arg); - expToPair.put(System.identityHashCode(arg), pairExps); + updateExpressionBelonging(expToPair, arg, pairExps); pairExps.add(null); pairExps.add(t); - expToPair.put(System.identityHashCode(t), pairExps); + updateExpressionBelonging(expToPair, t, pairExps); Type argType = null; if (arg instanceof Variable) { argType = ((Variable) arg).getType(); @@ -615,12 +613,12 @@ List mapExps = new ArrayList<>(); Expression arg1 = t.getChildren().get(0); // map mapExps.add(arg1); - expToMap.put(System.identityHashCode(arg1), mapExps); + updateExpressionBelonging(expToMap, arg1, mapExps); Expression arg2 = t.getChildren().get(1); // key mapExps.add(arg2); - expToMap.put(System.identityHashCode(arg2), mapExps); + updateExpressionBelonging(expToMap, arg2, mapExps); mapExps.add(t); // value - expToMap.put(System.identityHashCode(t), mapExps); + updateExpressionBelonging(expToMap, t, mapExps); Type arg1Type = null; if (arg1 instanceof Variable) { arg1Type = ((Variable) arg1).getType(); @@ -657,16 +655,16 @@ // If the root symbol of the term is insert. List mapExps = new ArrayList<>(); mapExps.add(t); // map - expToMap.put(System.identityHashCode(t), mapExps); + updateExpressionBelonging(expToMap, t, mapExps); Expression arg1 = t.getChildren().get(1); // key mapExps.add(arg1); - expToMap.put(System.identityHashCode(arg1), mapExps); + updateExpressionBelonging(expToMap, arg1, mapExps); Expression arg2 = t.getChildren().get(2); // value mapExps.add(arg2); - expToMap.put(System.identityHashCode(arg2), mapExps); + updateExpressionBelonging(expToMap, arg2, mapExps); Expression arg0 = t.getChildren().get(0); // map mapExps.add(arg0); - expToMap.put(System.identityHashCode(arg0), mapExps); + updateExpressionBelonging(expToMap, arg0, mapExps); Type termType = t.getType(); List compTypeList = new ArrayList<>(); if (arg1 instanceof Variable) { @@ -954,11 +952,23 @@ } } + private static void updateExpressionBelonging(Map>> belonging, Expression exp, List group) { + Set> groups = belonging.get(System.identityHashCode(exp)); + if (groups == null) { + groups = new HashSet<>(); + belonging.put(System.identityHashCode(exp), groups); + groups.add(group); + return; + } + if (!groups.contains(group)) { + groups.add(group); + } + } + private static void updateResourceTypes(Expression exp, Map> resources, Map> expToResource, Map> updateFromResource) { List sameResource = expToResource.get(System.identityHashCode(exp)); - if (sameResource == null) - return; + if (sameResource == null) return; for (IdentifierTemplate id : resources.keySet()) { if (resources.get(id) == sameResource) { Type resType = id.getResourceStateType(); @@ -985,8 +995,7 @@ 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) { @@ -1010,8 +1019,7 @@ 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()) { @@ -1022,11 +1030,9 @@ 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); @@ -1046,276 +1052,279 @@ } private static void updateConsTypes(Expression exp, Map cons, - Map> expToCons, Map> updateFromCons) { - List consComponents = expToCons.get(System.identityHashCode(exp)); - if (consComponents == null) - return; - int idx = consComponents.indexOf(exp); - switch (idx) { - case 0: - if (!(exp instanceof Term)) - return; - Type listType = cons.get(System.identityHashCode(consComponents)); - Type expType = getExpTypeIfUpdatable(listType, exp); - if (expType != null) { - cons.put(System.identityHashCode(consComponents), expType); - Map updateExps = getUpdateSet(updateFromCons, consComponents); - if (consComponents.get(2) instanceof Variable) { - ((Variable) consComponents.get(2)).setType(expType); - updateExps.put(System.identityHashCode(consComponents.get(2)), consComponents.get(2)); - } else if (consComponents.get(2) instanceof Term) { - ((Term) consComponents.get(2)).setType(expType); - updateExps.put(System.identityHashCode(consComponents.get(2)), consComponents.get(2)); + Map>> expToCons, Map> updateFromCons) { + Set> consComponentGroups = expToCons.get(System.identityHashCode(exp)); + if (consComponentGroups == null) return; + for (List consComponentGroup: consComponentGroups) { + int idx = consComponentGroup.indexOf(exp); + switch (idx) { + case 0: + if (!(exp instanceof Term)) break; + Type listType = cons.get(System.identityHashCode(consComponentGroup)); + 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)); + } + 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)); + } } - Type compType = listComponentTypes.get(expType); - if (consComponents.get(1) != null && consComponents.get(1) instanceof Variable) { - ((Variable) consComponents.get(1)).setType(compType); - updateExps.put(System.identityHashCode(consComponents.get(1)), consComponents.get(1)); - } else if (consComponents.get(1) != null && consComponents.get(1) instanceof Term) { - ((Term) consComponents.get(1)).setType(compType); - updateExps.put(System.identityHashCode(consComponents.get(1)), consComponents.get(1)); + break; + case 1: + listType = cons.get(System.identityHashCode(consComponentGroup)); + Type compType = listComponentTypes.get(listType); + Type newCompType = getExpTypeIfUpdatable(compType, exp); + if (newCompType != null) { + Type newListType = listTypes.get(newCompType); + if (newListType == null) { + // 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)); + } + 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)); + } } - } - break; - case 1: - listType = cons.get(System.identityHashCode(consComponents)); - Type compType = listComponentTypes.get(listType); - Type newCompType = getExpTypeIfUpdatable(compType, exp); - if (newCompType != null) { - Type newListType = listTypes.get(newCompType); - if (newListType == null) { - // Create new list type. - newListType = createNewListType(newCompType, listType); - } - cons.put(System.identityHashCode(consComponents), newListType); - Map updateExps = getUpdateSet(updateFromCons, consComponents); - if (consComponents.get(0) instanceof Term) { - ((Term) consComponents.get(0)).setType(newListType); - updateExps.put(System.identityHashCode(consComponents.get(0)), consComponents.get(0)); - } - if (consComponents.get(2) instanceof Variable) { - ((Variable) consComponents.get(2)).setType(newListType); - updateExps.put(System.identityHashCode(consComponents.get(2)), consComponents.get(2)); - } else if (consComponents.get(2) instanceof Term) { - ((Term) consComponents.get(2)).setType(newListType); - updateExps.put(System.identityHashCode(consComponents.get(2)), consComponents.get(2)); - } - } - break; - case 2: - listType = cons.get(System.identityHashCode(consComponents)); - expType = getExpTypeIfUpdatable(listType, exp); - if (expType != null) { - cons.put(System.identityHashCode(consComponents), expType); - Map updateExps = getUpdateSet(updateFromCons, consComponents); - if (consComponents.get(0) instanceof Term) { - ((Term) consComponents.get(0)).setType(expType); - updateExps.put(System.identityHashCode(consComponents.get(0)), consComponents.get(0)); - } - compType = listComponentTypes.get(expType); - if (consComponents.get(1) != null && consComponents.get(1) instanceof Variable) { - ((Variable) consComponents.get(1)).setType(compType); - updateExps.put(System.identityHashCode(consComponents.get(1)), consComponents.get(1)); - } else if (consComponents.get(1) != null && consComponents.get(1) instanceof Term) { - ((Term) consComponents.get(1)).setType(compType); - updateExps.put(System.identityHashCode(consComponents.get(1)), consComponents.get(1)); + break; + case 2: + listType = cons.get(System.identityHashCode(consComponentGroup)); + 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)); + } + 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)); + } } } } } private static void updateTupleTypes(Expression exp, Map tuple, - Map> expToTuple, Map> updateFromTuple) { - List components = expToTuple.get(System.identityHashCode(exp)); - if (components == null) - return; - int idx = components.indexOf(exp); - if (idx == 0) { - Type tupleType = tuple.get(System.identityHashCode(components)); - Type newTupleType = getExpTypeIfUpdatable(tupleType, exp); - if (newTupleType != null) { - // 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); - 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 - 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 - 1))) { - ((Term) compExp).setType(componentTypes.get(i - 1)); - updateExps.put(System.identityHashCode(compExp), compExp); + Map>> expToTuple, Map> updateFromTuple) { + Set> tupleComponentGroups = expToTuple.get(System.identityHashCode(exp)); + if (tupleComponentGroups == null) return; + for (List tupleComponentGroup: tupleComponentGroups) { + int idx = tupleComponentGroup.indexOf(exp); + if (idx == 0) { + Type tupleType = tuple.get(System.identityHashCode(tupleComponentGroup)); + Type newTupleType = getExpTypeIfUpdatable(tupleType, exp); + if (newTupleType != null) { + // Propagate an update of a tuple's type to its components' types. + tuple.put(System.identityHashCode(tupleComponentGroup), newTupleType); + List componentTypes = tupleComponentTypes.get(newTupleType); + Map updateExps = getUpdateSet(updateFromTuple, tupleComponentGroup); + for (int i = 1; i < tupleComponentGroup.size(); i++) { + Expression compExp = tupleComponentGroup.get(i); + if (compExp instanceof Variable) { + 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 - 1))) { + ((Term) compExp).setType(componentTypes.get(i - 1)); + updateExps.put(System.identityHashCode(compExp), compExp); + } } } } - } - } else { - Type tupleType = tuple.get(System.identityHashCode(components)); - List componentTypes = tupleComponentTypes.get(tupleType); - Type compType = componentTypes.get(idx - 1); - Type newCompType = getExpTypeIfUpdatable(compType, exp); - if (newCompType != null) { - // Propagate an update of a component's type to its container's (tuple's) type. - componentTypes = new ArrayList<>(componentTypes); - componentTypes.set(idx - 1, newCompType); - Type newTupleType = tupleTypes.get(componentTypes); - if (newTupleType == null) { - // Create new tuple type; - newTupleType = createNewTupleType(componentTypes, tupleType); + } else { + Type tupleType = tuple.get(System.identityHashCode(tupleComponentGroup)); + List componentTypes = tupleComponentTypes.get(tupleType); + Type compType = componentTypes.get(idx - 1); + Type newCompType = getExpTypeIfUpdatable(compType, exp); + if (newCompType != null) { + // Propagate an update of a component's type to its container's (tuple's) type. + componentTypes = new ArrayList<>(componentTypes); + componentTypes.set(idx - 1, newCompType); + Type newTupleType = tupleTypes.get(componentTypes); + if (newTupleType == null) { + // Create new tuple type; + newTupleType = createNewTupleType(componentTypes, tupleType); + } + Map updateExps = getUpdateSet(updateFromTuple, tupleComponentGroup); + Expression tupleExp = tupleComponentGroup.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(tupleComponentGroup), newTupleType); } - Map updateExps = getUpdateSet(updateFromTuple, components); - 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); } } } 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); + Map>> expToPair, Map> updateFromPair) { + Set> pairComponentGroups = expToPair.get(System.identityHashCode(exp)); + if (pairComponentGroups == null) return; + for (List pairComponentGroup: pairComponentGroups) { + int idx = pairComponentGroup.indexOf(exp); + if (idx == 0) { + Type pairType = pair.get(System.identityHashCode(pairComponentGroup)); + Type newPairType = getExpTypeIfUpdatable(pairType, exp); + if (newPairType != null) { + // Propagate an update of a pair's type to its components' types. + pair.put(System.identityHashCode(pairComponentGroup), newPairType); + Type componentType = pairComponentTypes.get(newPairType); + Map updateExps = getUpdateSet(updateFromPair, pairComponentGroup); + for (int i = 1; i < pairComponentGroup.size(); i++) { + Expression compExp = pairComponentGroup.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); + } else { + Type pairType = pair.get(System.identityHashCode(pairComponentGroup)); + 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, pairComponentGroup); + Expression pairExp = pairComponentGroup.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(pairComponentGroup), newPairType); } - pair.put(System.identityHashCode(components), newPairType); } } } } private static void updateMapTypes(Expression exp, Map map, - Map> expToMap, Map> updateFromMap) { - List components = expToMap.get(System.identityHashCode(exp)); - if (components == null) - return; - int idx = components.indexOf(exp); - if (idx == 0 || idx == 3) { - Type mapType = map.get(System.identityHashCode(components)); - Type newMapType = getExpTypeIfUpdatable(mapType, exp); - if (newMapType != null) { - // Propagate an update of a map's type to its components' types. - map.put(System.identityHashCode(components), newMapType); - List componentTypes = mapComponentTypes.get(newMapType); - Map updateExps = getUpdateSet(updateFromMap, components); - for (int i = 1; i < components.size() && i < 3; i++) { - Expression compExp = components.get(i); - if (compExp instanceof Variable) { - if (compareTypes(((Variable) compExp).getType(), componentTypes.get(i - 1))) { - ((Variable) compExp).setType(componentTypes.get(i - 1)); - updateExps.put(System.identityHashCode(compExp), compExp); + Map>> expToMap, Map> updateFromMap) { + Set> mapComponentGroups = expToMap.get(System.identityHashCode(exp)); + if (mapComponentGroups == null) return; + for (List mapComponentGroup: mapComponentGroups) { + int idx = mapComponentGroup.indexOf(exp); + if (idx == 0 || idx == 3) { + Type mapType = map.get(System.identityHashCode(mapComponentGroup)); + Type newMapType = getExpTypeIfUpdatable(mapType, exp); + if (newMapType != null) { + // Propagate an update of a map's type to its components' types. + map.put(System.identityHashCode(mapComponentGroup), newMapType); + List componentTypes = mapComponentTypes.get(newMapType); + Map updateExps = getUpdateSet(updateFromMap, mapComponentGroup); + for (int i = 1; i < mapComponentGroup.size() && i < 3; i++) { + Expression compExp = mapComponentGroup.get(i); + if (compExp instanceof Variable) { + 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 - 1))) { + ((Term) 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 - 1))) { - ((Term) compExp).setType(componentTypes.get(i - 1)); - updateExps.put(System.identityHashCode(compExp), compExp); + } + // Propagate an update of a map's type to another map's type. + Expression compExp = null; + if (idx == 0 && mapComponentGroup.size() == 4) { // for lookup + compExp = mapComponentGroup.get(3); + } else if (idx == 3) { + compExp = mapComponentGroup.get(0); + } + if (compExp != null) { + if (compExp instanceof Variable) { + if (compareTypes(((Variable) compExp).getType(), newMapType)) { + ((Variable) compExp).setType(newMapType); + updateExps.put(System.identityHashCode(compExp), compExp); + } + } else if (compExp instanceof Term) { + if (compareTypes(((Term) compExp).getType(), newMapType)) { + ((Term) compExp).setType(newMapType); + updateExps.put(System.identityHashCode(compExp), compExp); + } } } } - // Propagate an update of a map's type to another map's type. - Expression compExp = null; - if (idx == 0 && components.size() == 4) { // for lookup - compExp = components.get(3); - } else if (idx == 3) { - compExp = components.get(0); - } - if (compExp != null) { - if (compExp instanceof Variable) { - if (compareTypes(((Variable) compExp).getType(), newMapType)) { - ((Variable) compExp).setType(newMapType); - updateExps.put(System.identityHashCode(compExp), compExp); - } - } else if (compExp instanceof Term) { - if (compareTypes(((Term) compExp).getType(), newMapType)) { - ((Term) compExp).setType(newMapType); - updateExps.put(System.identityHashCode(compExp), compExp); - } + } else { + Type mapType = map.get(System.identityHashCode(mapComponentGroup)); + List componentTypes = mapComponentTypes.get(mapType); + Type compType = componentTypes.get(idx - 1); + Type newCompType = getExpTypeIfUpdatable(compType, exp); + if (newCompType != null) { + // Propagate an update of a component's type to its container's (map's) type. + componentTypes = new ArrayList<>(componentTypes); + componentTypes.set(idx - 1, newCompType); + Type newMapType = mapTypes.get(componentTypes); + if (newMapType == null) { + // Create new map type; + newMapType = createNewMapType(componentTypes, mapType); } - } - } - } else { - Type mapType = map.get(System.identityHashCode(components)); - List componentTypes = mapComponentTypes.get(mapType); - Type compType = componentTypes.get(idx - 1); - Type newCompType = getExpTypeIfUpdatable(compType, exp); - if (newCompType != null) { - // Propagate an update of a component's type to its container's (map's) type. - componentTypes = new ArrayList<>(componentTypes); - componentTypes.set(idx - 1, newCompType); - Type newMapType = mapTypes.get(componentTypes); - if (newMapType == null) { - // Create new map type; - newMapType = createNewMapType(componentTypes, mapType); - } - Map updateExps = getUpdateSet(updateFromMap, components); - Expression mapExp = components.get(0); - if (mapExp instanceof Variable) { - ((Variable) mapExp).setType(newMapType); - updateExps.put(System.identityHashCode(mapExp), mapExp); - } else if (mapExp instanceof Term) { - ((Term) mapExp).setType(newMapType); - updateExps.put(System.identityHashCode(mapExp), mapExp); - } - if (components.size() == 4) { // for lookup - mapExp = components.get(3); + Map updateExps = getUpdateSet(updateFromMap, mapComponentGroup); + Expression mapExp = mapComponentGroup.get(0); if (mapExp instanceof Variable) { ((Variable) mapExp).setType(newMapType); updateExps.put(System.identityHashCode(mapExp), mapExp); } else if (mapExp instanceof Term) { ((Term) mapExp).setType(newMapType); updateExps.put(System.identityHashCode(mapExp), mapExp); - } + } + if (mapComponentGroup.size() == 4) { // for lookup + mapExp = mapComponentGroup.get(3); + if (mapExp instanceof Variable) { + ((Variable) mapExp).setType(newMapType); + updateExps.put(System.identityHashCode(mapExp), mapExp); + } else if (mapExp instanceof Term) { + ((Term) mapExp).setType(newMapType); + updateExps.put(System.identityHashCode(mapExp), mapExp); + } + } + map.put(System.identityHashCode(mapComponentGroup), newMapType); } - map.put(System.identityHashCode(components), newMapType); } } }