diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index 45a82b9..1a8cadd 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -148,8 +148,8 @@ // 1. Collect type information from the architecture model. Collection channels = new HashSet<>(model.getInputChannels()); channels.addAll(model.getChannels()); - for (Channel c : channels) { - for (ChannelMember cm : c.getChannelMembers()) { + for (Channel ch : channels) { + for (ChannelMember cm : ch.getChannelMembers()) { StateTransition st = cm.getStateTransition(); ResourceHierarchy res = cm.getResource().getResourceHierarchy(); @@ -232,7 +232,7 @@ if (st.getNextStateExpression() != null) { allVariables.addAll(st.getNextStateExpression().getVariables().values()); } - for (Selector s: c.getSelectors()) { // add channel selectors + for (Selector s: ch.getSelectors()) { // add channel selectors if (s.getExpression() instanceof Variable) { allVariables.add((Variable) s.getExpression()); } @@ -281,88 +281,115 @@ // 1.3 Group expressions by message. Expression message = st.getMessageExpression(); if (message instanceof Variable) { - Type msgType = ((Variable) message).getType(); - Map, Type>> msgTypeMap = messages.get(c); - if (msgTypeMap == null) { - msgTypeMap = new HashMap<>(); - messages.put(c, msgTypeMap); - } - Map.Entry, Type> typeAndExps = msgTypeMap.get(0); - if (typeAndExps == null) { - List exps = new ArrayList<>(); - exps.add(message); - typeAndExps = new AbstractMap.SimpleEntry<>(exps, msgType); - msgTypeMap.put(0, typeAndExps); - expToMessage.put(System.identityHashCode(message), exps); - } else { - typeAndExps.getKey().add(message); - expToMessage.put(System.identityHashCode(message), typeAndExps.getKey()); - Map updateExps = getUpdateSet(updateFromMessage, typeAndExps.getKey()); - if (compareTypes(typeAndExps.getValue(), msgType)) { - typeAndExps.setValue(msgType); - for (Expression e : typeAndExps.getKey()) { - if (e != message) { - if (e instanceof Variable) { - ((Variable) e).setType(msgType); - updateExps.put(System.identityHashCode(e), e); + IRecurseForMessageVariable resurceForVar = new IRecurseForMessageVariable() { + public void recurse(Channel rootCh, Channel ch, Expression message, + Map, Type>>> messages, + Map> expToMessage, + Map> updateFromMessage) { + Type msgType = ((Variable) message).getType(); + Map, Type>> msgTypeMap = messages.get(rootCh); + if (msgTypeMap == null) { + msgTypeMap = new HashMap<>(); + messages.put(rootCh, msgTypeMap); + } + Map.Entry, Type> typeAndExps = msgTypeMap.get(0); + if (typeAndExps == null) { + List exps = new ArrayList<>(); + exps.add(message); + typeAndExps = new AbstractMap.SimpleEntry<>(exps, msgType); + msgTypeMap.put(0, typeAndExps); + expToMessage.put(System.identityHashCode(message), exps); + } else { + typeAndExps.getKey().add(message); + expToMessage.put(System.identityHashCode(message), typeAndExps.getKey()); + Map updateExps = getUpdateSet(updateFromMessage, typeAndExps.getKey()); + if (compareTypes(typeAndExps.getValue(), msgType)) { + typeAndExps.setValue(msgType); + for (Expression e : typeAndExps.getKey()) { + if (e != message) { + if (e instanceof Variable) { + ((Variable) e).setType(msgType); + updateExps.put(System.identityHashCode(e), e); + } + } } + } else if (compareTypes(msgType, typeAndExps.getValue())) { + ((Variable) message).setType(typeAndExps.getValue()); + updateExps.put(System.identityHashCode(message), message); } } - } else if (compareTypes(msgType, typeAndExps.getValue())) { - ((Variable) message).setType(typeAndExps.getValue()); - updateExps.put(System.identityHashCode(message), message); + for (Channel childCh: ch.getChildren()) { + for (ChannelMember cm: childCh.getChannelMembers()) { + Expression childMessage = cm.getStateTransition().getMessageExpression(); + recurse(rootCh, childCh, childMessage, messages, expToMessage, updateFromMessage); + } + } } - } + }; + resurceForVar.recurse(ch, ch, message, messages, expToMessage, updateFromMessage); } else if (message instanceof Term) { - Map, Type>> msgTypeMap = messages.get(c); - if (msgTypeMap == null) { - msgTypeMap = new HashMap<>(); - messages.put(c, msgTypeMap); - } - for (int i = 0; i < ((Term) message).getArity(); i++) { - Expression arg = ((Term) message).getChild(i); - Type argType = null; - if (arg instanceof Variable) { - argType = ((Variable) arg).getType(); - } else if (arg instanceof Term) { - argType = ((Term) arg).getType(); - } else { - continue; - } - Map.Entry, Type> typeAndExps = msgTypeMap.get(i); - if (typeAndExps == null) { - List exps = new ArrayList<>(); - exps.add(arg); - typeAndExps = new AbstractMap.SimpleEntry<>(exps, argType); - msgTypeMap.put(i, typeAndExps); - expToMessage.put(System.identityHashCode(arg), exps); - } else { - typeAndExps.getKey().add(arg); - expToMessage.put(System.identityHashCode(arg), typeAndExps.getKey()); - Map updateExps = getUpdateSet(updateFromMessage, typeAndExps.getKey()); - if (compareTypes(typeAndExps.getValue(), argType)) { - typeAndExps.setValue(argType); - for (Expression e : typeAndExps.getKey()) { - if (e != arg) { - if (e instanceof Variable) { - ((Variable) e).setType(argType); - updateExps.put(System.identityHashCode(e), e); + IRecurseForMessageTerm resurceForTerm = new IRecurseForMessageTerm() { + public void recurse(Channel rootCh, Channel ch, Expression message, + Map, Type>>> messages, + Map> expToMessage, + Map> updateFromMessage) { + Map, Type>> msgTypeMap = messages.get(rootCh); + if (msgTypeMap == null) { + msgTypeMap = new HashMap<>(); + messages.put(rootCh, msgTypeMap); + } + for (int i = 0; i < ((Term) message).getArity(); i++) { + Expression arg = ((Term) message).getChild(i); + Type argType = null; + if (arg instanceof Variable) { + argType = ((Variable) arg).getType(); + } else if (arg instanceof Term) { + argType = ((Term) arg).getType(); + } else { + continue; + } + Map.Entry, Type> typeAndExps = msgTypeMap.get(i); + if (typeAndExps == null) { + List exps = new ArrayList<>(); + exps.add(arg); + typeAndExps = new AbstractMap.SimpleEntry<>(exps, argType); + msgTypeMap.put(i, typeAndExps); + expToMessage.put(System.identityHashCode(arg), exps); + } else { + typeAndExps.getKey().add(arg); + expToMessage.put(System.identityHashCode(arg), typeAndExps.getKey()); + Map updateExps = getUpdateSet(updateFromMessage, typeAndExps.getKey()); + if (compareTypes(typeAndExps.getValue(), argType)) { + typeAndExps.setValue(argType); + for (Expression e : typeAndExps.getKey()) { + if (e != arg) { + if (e instanceof Variable) { + ((Variable) e).setType(argType); + updateExps.put(System.identityHashCode(e), e); + } + } + } + } else if (compareTypes(argType, typeAndExps.getValue())) { + if (arg instanceof Variable) { + ((Variable) arg).setType(typeAndExps.getValue()); + updateExps.put(System.identityHashCode(arg), arg); + } else if (arg instanceof Term) { + ((Term) arg).setType(typeAndExps.getValue()); + updateExps.put(System.identityHashCode(arg), arg); } } } - } else if (compareTypes(argType, typeAndExps.getValue())) { - if (arg instanceof Variable) { - ((Variable) arg).setType(typeAndExps.getValue()); - updateExps.put(System.identityHashCode(arg), arg); - } else if (arg instanceof Term) { - ((Term) arg).setType(typeAndExps.getValue()); - updateExps.put(System.identityHashCode(arg), arg); + } + for (Channel childCh: ch.getChildren()) { + for (ChannelMember cm: childCh.getChannelMembers()) { + Expression childMessage = cm.getStateTransition().getMessageExpression(); + recurse(rootCh, childCh, childMessage, messages, expToMessage, updateFromMessage); } } } - } + }; + resurceForTerm.recurse(ch, ch, message, messages, expToMessage, updateFromMessage); } - // 1.4 Extract constraints on expressions in each term. List terms = new ArrayList<>(); if (st.getCurStateExpression() instanceof Term) { @@ -2331,4 +2358,18 @@ } return false; } + + private static interface IRecurseForMessageVariable { + public void recurse(Channel rootCh, Channel ch, Expression message, + Map, Type>>> messages, + Map> expToMessage, + Map> updateFromMessage); + } + + private static interface IRecurseForMessageTerm { + public void recurse(Channel rootCh, Channel ch, Expression message, + Map, Type>>> messages, + Map> expToMessage, + Map> updateFromMessage); + } }