| |
---|
| | Map<Integer, Type> map = new HashMap<>(); |
---|
| | Map<Integer, List<Expression>> expToResource = new HashMap<>(); |
---|
| | Map<Integer, List<Expression>> expToVariable = new HashMap<>(); |
---|
| | Map<Integer, List<Expression>> expToMessage = new HashMap<>(); |
---|
| | Map<Integer, List<Expression>> expToCons = new HashMap<>(); |
---|
| | Map<Integer, List<Expression>> expToTuple = new HashMap<>(); |
---|
| | Map<Integer, List<Expression>> expToPair = new HashMap<>(); |
---|
| | Map<Integer, List<Expression>> expToMap = new HashMap<>(); |
---|
| | Map<Integer, Set<List<Expression>>> expToCons = new HashMap<>(); |
---|
| | Map<Integer, Set<List<Expression>>> expToTuple = new HashMap<>(); |
---|
| | Map<Integer, Set<List<Expression>>> expToPair = new HashMap<>(); |
---|
| | Map<Integer, Set<List<Expression>>> expToMap = new HashMap<>(); |
---|
| | |
---|
| | Map<IdentifierTemplate, ResourceNode> idToRes = new HashMap<>(); |
---|
| | Map<Integer, Map<Integer, Expression>> updateFromResource = new HashMap<>(); |
---|
| | Map<Integer, Map<Integer, Expression>> updateFromVariable = new HashMap<>(); |
---|
| |
---|
| | if (symbol.equals(DataConstraintModel.cons)) { |
---|
| | // If the root symbol of the term is cons. |
---|
| | List<Expression> 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) { |
---|
| | // If the type of the second argument is more concrete than the type of the |
---|
| |
---|
| | // If the root symbol of the term is tuple. |
---|
| | List<Expression> tupleExps = new ArrayList<>(); |
---|
| | List<Type> 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) { |
---|
| | argsTypeList.add(((Term) e).getType()); |
---|
| |
---|
| | } else if (symbol.equals(DataConstraintModel.pair)) { |
---|
| | // If the root symbol of the term is pair. |
---|
| | List<Expression> 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()); |
---|
| | |
---|
| |
---|
| | // If the root symbol of the term is fst. |
---|
| | List<Expression> 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) { |
---|
| | argType = ((Variable) arg).getType(); |
---|
| |
---|
| | // If the root symbol of the term is snd. |
---|
| | List<Expression> 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(); |
---|
| | } else if (arg instanceof Term) { |
---|
| |
---|
| | // If the root symbol of the term is left. |
---|
| | List<Expression> 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) { |
---|
| | argType = ((Variable) arg).getType(); |
---|
| |
---|
| | // If the root symbol of the term is right. |
---|
| | List<Expression> 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(); |
---|
| | } else if (arg instanceof Term) { |
---|
| |
---|
| | // If the root symbol of the term is lookup. |
---|
| | List<Expression> 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(); |
---|
| | } else if (arg1 instanceof Term) { |
---|
| |
---|
| | } else if (symbol.equals(DataConstraintModel.insert)) { |
---|
| | // If the root symbol of the term is insert. |
---|
| | List<Expression> 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<Type> compTypeList = new ArrayList<>(); |
---|
| | if (arg1 instanceof Variable) { |
---|
| | compTypeList.add(((Variable) arg1).getType()); |
---|
| |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | private static void updateExpressionBelonging(Map<Integer, Set<List<Expression>>> belonging, Expression exp, List<Expression> group) { |
---|
| | Set<List<Expression>> 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<IdentifierTemplate, List<Expression>> resources, |
---|
| | Map<Integer, List<Expression>> expToResource, Map<Integer, Map<Integer, Expression>> updateFromResource) { |
---|
| | List<Expression> 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(); |
---|
| | Type newResType = getExpTypeIfUpdatable(resType, exp); |
---|
| |
---|
| | |
---|
| | private static void updateVaribleTypes(Expression exp, Map<Integer, Type> variables, |
---|
| | Map<Integer, List<Expression>> expToVariable, Map<Integer, Map<Integer, Expression>> updateFromVariable) { |
---|
| | List<Expression> 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); |
---|
| |
---|
| | private static void updateMessageTypes(Expression exp, |
---|
| | Map<ChannelGenerator, Map<Integer, Map.Entry<List<Expression>, Type>>> messages, |
---|
| | Map<Integer, List<Expression>> expToMessage, Map<Integer, Map<Integer, Expression>> updateFromMessage) { |
---|
| | List<Expression> messageExps = expToMessage.get(System.identityHashCode(exp)); |
---|
| | if (messageExps == null) |
---|
| | return; |
---|
| | if (messageExps == null) return; |
---|
| | Type msgType = null; |
---|
| | Map.Entry<List<Expression>, Type> expsAndType = null; |
---|
| | for (ChannelGenerator c : messages.keySet()) { |
---|
| | for (int i : messages.get(c).keySet()) { |
---|
| |
---|
| | msgType = expsAndType.getValue(); |
---|
| | break; |
---|
| | } |
---|
| | } |
---|
| | if (msgType != null) |
---|
| | break; |
---|
| | } |
---|
| | if (msgType == null) |
---|
| | return; |
---|
| | if (msgType != null) break; |
---|
| | } |
---|
| | if (msgType == null) return; |
---|
| | Type newMsgType = getExpTypeIfUpdatable(msgType, exp); |
---|
| | if (newMsgType != null) { |
---|
| | expsAndType.setValue(newMsgType); |
---|
| | Map<Integer, Expression> updateExps = getUpdateSet(updateFromMessage, messageExps); |
---|
| |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | private static void updateConsTypes(Expression exp, Map<Integer, Type> cons, |
---|
| | Map<Integer, List<Expression>> expToCons, Map<Integer, Map<Integer, Expression>> updateFromCons) { |
---|
| | List<Expression> 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<Integer, Expression> 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)); |
---|
| | } |
---|
| | 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(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<Integer, Expression> 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<Integer, Expression> 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)); |
---|
| | Map<Integer, Set<List<Expression>>> expToCons, Map<Integer, Map<Integer, Expression>> updateFromCons) { |
---|
| | Set<List<Expression>> consComponentGroups = expToCons.get(System.identityHashCode(exp)); |
---|
| | if (consComponentGroups == null) return; |
---|
| | for (List<Expression> 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<Integer, Expression> 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)); |
---|
| | } |
---|
| | } |
---|
| | 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<Integer, Expression> 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 2: |
---|
| | listType = cons.get(System.identityHashCode(consComponentGroup)); |
---|
| | expType = getExpTypeIfUpdatable(listType, exp); |
---|
| | if (expType != null) { |
---|
| | cons.put(System.identityHashCode(consComponentGroup), expType); |
---|
| | Map<Integer, Expression> 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<Integer, Type> tuple, |
---|
| | Map<Integer, List<Expression>> expToTuple, Map<Integer, Map<Integer, Expression>> updateFromTuple) { |
---|
| | List<Expression> 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<Type> componentTypes = tupleComponentTypes.get(newTupleType); |
---|
| | Map<Integer, Expression> 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); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } else { |
---|
| | Type tupleType = tuple.get(System.identityHashCode(components)); |
---|
| | List<Type> 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<Integer, Expression> 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); |
---|
| | Map<Integer, Set<List<Expression>>> expToTuple, Map<Integer, Map<Integer, Expression>> updateFromTuple) { |
---|
| | Set<List<Expression>> tupleComponentGroups = expToTuple.get(System.identityHashCode(exp)); |
---|
| | if (tupleComponentGroups == null) return; |
---|
| | for (List<Expression> 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<Type> componentTypes = tupleComponentTypes.get(newTupleType); |
---|
| | Map<Integer, Expression> 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(tupleComponentGroup)); |
---|
| | List<Type> 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<Integer, Expression> 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); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | private static void updatePairTypes(Expression exp, Map<Integer, Type> pair, |
---|
| | Map<Integer, List<Expression>> expToPair, Map<Integer, Map<Integer, Expression>> updateFromPair) { |
---|
| | List<Expression> 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<Integer, Expression> 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); |
---|
| | Map<Integer, Set<List<Expression>>> expToPair, Map<Integer, Map<Integer, Expression>> updateFromPair) { |
---|
| | Set<List<Expression>> pairComponentGroups = expToPair.get(System.identityHashCode(exp)); |
---|
| | if (pairComponentGroups == null) return; |
---|
| | for (List<Expression> 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) { |
---|
| | Map<Integer, Expression> 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); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | // Propagate an update of a pair's type to its components' types. |
---|
| | pair.put(System.identityHashCode(pairComponentGroup), newPairType); |
---|
| | Type componentType = pairComponentTypes.get(newPairType); |
---|
| | Map<Integer, Expression> 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(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<Integer, Expression> 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); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | private static void updateMapTypes(Expression exp, Map<Integer, Type> map, |
---|
| | Map<Integer, List<Expression>> expToMap, Map<Integer, Map<Integer, Expression>> updateFromMap) { |
---|
| | List<Expression> 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<Type> componentTypes = mapComponentTypes.get(newMapType); |
---|
| | Map<Integer, Expression> 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); |
---|
| | } |
---|
| | } 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 && 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(components)); |
---|
| | List<Type> 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<Integer, Expression> 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<Integer, Set<List<Expression>>> expToMap, Map<Integer, Map<Integer, Expression>> updateFromMap) { |
---|
| | Set<List<Expression>> mapComponentGroups = expToMap.get(System.identityHashCode(exp)); |
---|
| | if (mapComponentGroups == null) return; |
---|
| | for (List<Expression> 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<Type> componentTypes = mapComponentTypes.get(newMapType); |
---|
| | Map<Integer, Expression> 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); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | // 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); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } else { |
---|
| | Type mapType = map.get(System.identityHashCode(mapComponentGroup)); |
---|
| | List<Type> 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<Integer, Expression> 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); |
---|
| | } |
---|
| | } |
---|
| | map.put(System.identityHashCode(components), newMapType); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | 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); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | private static Type createNewListType(Type compType, Type parentType) { |
---|
| | String compTypeName = getInterfaceTypeName(compType); |
---|
| | List<Type> childrenTypes = getChildrenTypes(parentType, listComponentTypes.keySet()); |
---|
| |
---|
| | |