diff --git a/AlgebraicDataflowArchitectureModel/models/Twitter.model b/AlgebraicDataflowArchitectureModel/models/Twitter.model index 98d391b..f02f134 100644 --- a/AlgebraicDataflowArchitectureModel/models/Twitter.model +++ b/AlgebraicDataflowArchitectureModel/models/Twitter.model @@ -1,53 +1,53 @@ channel a_Tweet { - out a_user_timeline(l:List, a_tweet(t:Str)) == cons(t, l) - out a_user_timeline(l, e) == l + out a_tweets(l:List, a_tweet(t:Str, time:Long)) == cons(tuple(time, t), l) + out a_tweets(l, e) == l } channel a_Follow { - out a_follows(f:List, a_follow(u:Int)) == cons(u, f) - out a_follows(f, e) == f + out a_following(f:List, a_follow(u:Int)) == cons(u, f) + out a_following(f, e) == f } channel a_Home { - in a_user_timeline(la1, update_a(f2, la2, lb2, lc2)) == la2 - in b_user_timeline(lb1, update_a(f2, la2, lb2, lc2)) == lb2 - in c_user_timeline(lc1, update_a(f2, la2, lb2, lc2)) == lc2 - in a_follows(f, update_a(f2, la2, lb2, lc2)) == f2 - out a_home_timeline(t:List, update_a(f2, la2, lb2, lc2)) == merge(la2, if(contains(f2,2), merge(lb2, if(contains(f2,3), lc2, nil)), if(contains(f2,3), lc2, nil))) + in a_tweets(la1, update_a(f2, la2, lb2, lc2)) == la2 + in b_tweets(lb1, update_a(f2, la2, lb2, lc2)) == lb2 + in c_tweets(lc1, update_a(f2, la2, lb2, lc2)) == lc2 + in a_following(f, update_a(f2, la2, lb2, lc2)) == f2 + out a_timeline(t:List, update_a(f2, la2, lb2, lc2)) == merge(la2, if(contains(f2,2), merge(lb2, if(contains(f2,3), lc2, nil)), if(contains(f2,3), lc2, nil))) } channel b_Tweet { - out b_user_timeline(l:List, b_tweet(t:Str)) == cons(t, l) - out b_user_timeline(l, e) == l + out b_tweets(l:List, b_tweet(t:Str, time:Long)) == cons(tuple(time, t), l) + out b_tweets(l, e) == l } channel b_Follow { - out b_follows(f:List, b_follow(u:Int)) == cons(u, f) - out b_follows(f, e) == f + out b_following(f:List, b_follow(u:Int)) == cons(u, f) + out b_following(f, e) == f } channel b_Home { - in a_user_timeline(la1, update_b(f2, la2, lb2, lc2)) == la2 - in b_user_timeline(lb1, update_b(f2, la2, lb2, lc2)) == lb2 - in c_user_timeline(lc1, update_b(f2, la2, lb2, lc2)) == lc2 - in b_follows(f, update_b(f2, la2, lb2, lc2)) == f2 - out b_home_timeline(t:List, update_b(f2, la2, lb2, lc2)) == merge(lb2, if(contains(f2,1), merge(la2, if(contains(f2,3), lc2, nil)), if(contains(f2,3), lc2, nil))) + in a_tweets(la1, update_b(f2, la2, lb2, lc2)) == la2 + in b_tweets(lb1, update_b(f2, la2, lb2, lc2)) == lb2 + in c_tweets(lc1, update_b(f2, la2, lb2, lc2)) == lc2 + in b_following(f, update_b(f2, la2, lb2, lc2)) == f2 + out b_timeline(t:List, update_b(f2, la2, lb2, lc2)) == merge(lb2, if(contains(f2,1), merge(la2, if(contains(f2,3), lc2, nil)), if(contains(f2,3), lc2, nil))) } channel c_Tweet { - out c_user_timeline(l:List, c_tweet(t:Str)) == cons(t, l) - out c_user_timeline(l, e) == l + out c_tweets(l:List, c_tweet(t:Str, time:Long)) == cons(tuple(time, t), l) + out c_tweets(l, e) == l } channel c_Follow { - out c_follows(f:List, c_follow(u:Int)) == cons(u, f) - out c_follows(f, e) == f + out c_following(f:List, c_follow(u:Int)) == cons(u, f) + out c_following(f, e) == f } channel c_Home { - in a_user_timeline(la1, update_c(f2, la2, lb2, lc2)) == la2 - in b_user_timeline(lb1, update_c(f2, la2, lb2, lc2)) == lb2 - in c_user_timeline(lc1, update_c(f2, la2, lb2, lc2)) == lc2 - in c_follows(f, update_c(f2, la2, lb2, lc2)) == f2 - out c_home_timeline(t:List, update_c(f2, la2, lb2, lc2)) == merge(lc2, if(contains(f2,1), merge(la2, if(contains(f2,2), lb2, nil)), if(contains(f2,2), lb2, nil))) + in a_tweets(la1, update_c(f2, la2, lb2, lc2)) == la2 + in b_tweets(lb1, update_c(f2, la2, lb2, lc2)) == lb2 + in c_tweets(lc1, update_c(f2, la2, lb2, lc2)) == lc2 + in c_following(f, update_c(f2, la2, lb2, lc2)) == f2 + out c_timeline(t:List, update_c(f2, la2, lb2, lc2)) == merge(lc2, if(contains(f2,1), merge(la2, if(contains(f2,2), lb2, nil)), if(contains(f2,2), lb2, nil))) } diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java index d061f00..00df97c 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java @@ -22,6 +22,7 @@ import models.algebra.Variable; import models.dataConstraintModel.ChannelGenerator; import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.IdentifierTemplate; import models.dataFlowModel.DataFlowModel; import models.dataFlowModel.DataflowChannelGenerator; @@ -68,6 +69,7 @@ } }); sum.setImplOperatorType(Symbol.Type.GENERATIVE); + sum.setSignature(new Type[] {DataConstraintModel.typeInt, DataConstraintModel.typeList}); // sum.setImplName("stream().mapToInt(x->x).sum"); // sum.setImplOperatorType(Symbol.Type.METHOD); } @@ -91,7 +93,7 @@ } } String idxGetter = ""; - if (compType.startsWith("AbstractMap.SimpleEntry")) { + if (compType.startsWith("Map.Entry")) { idxGetter = ".getKey()"; } count[0]++; @@ -121,6 +123,7 @@ } }); merge.setImplOperatorType(Symbol.Type.GENERATIVE); + merge.setSignature(new Type[] {DataConstraintModel.typeList, DataConstraintModel.typeList, DataConstraintModel.typeList}); } // Create a map from type names (lower case) to their types. diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java index ee6d6de..d0f5f6b 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java @@ -24,6 +24,7 @@ import models.algebra.ValueUndefined; import models.dataConstraintModel.ChannelGenerator; import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; import models.dataFlowModel.DataFlowModel; import models.dataFlowModel.DataflowChannelGenerator; import models.dataFlowModel.PushPullAttribute; @@ -70,6 +71,7 @@ } }); sum.setImplOperatorType(Symbol.Type.GENERATIVE); + sum.setSignature(new Type[] {DataConstraintModel.typeInt, DataConstraintModel.typeList}); // sum.setImplName("stream().mapToInt(x->x).sum"); // sum.setImplOperatorType(Symbol.Type.METHOD); } @@ -123,6 +125,7 @@ } }); merge.setImplOperatorType(Symbol.Type.GENERATIVE); + merge.setSignature(new Type[] {DataConstraintModel.typeList, DataConstraintModel.typeList, DataConstraintModel.typeList}); } // Create a map from type names (lower case) to their types. diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index c831849..7b37323 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -13,6 +13,7 @@ import models.Node; import models.algebra.Expression; import models.algebra.Position; +import models.algebra.Symbol; import models.algebra.Term; import models.algebra.Type; import models.algebra.Variable; @@ -270,14 +271,31 @@ terms.addAll(subTerms.values()); } for (Term t: terms) { - if (t.getSymbol().equals(DataConstraintModel.cons)) { + Symbol symbol = t.getSymbol(); + if (symbol.equals(DataConstraintModel.cons) || (symbol.getSignature() != null && symbol.getSignature()[0] == DataConstraintModel.typeList)) { // If the root symbol of the term is cons. List consExps = new ArrayList<>(); consExps.add(t); expToCons.put(System.identityHashCode(t), consExps); - for (Expression e: t.getChildren()) { - consExps.add(e); - expToCons.put(System.identityHashCode(e), consExps); + if (symbol.equals(DataConstraintModel.cons)) { + for (Expression e: t.getChildren()) { + consExps.add(e); + expToCons.put(System.identityHashCode(e), consExps); + } + } else { + consExps.add(null); // consExps.get(1) + for (int i = 1; i < symbol.getSignature().length; i++) { + Type tc = symbol.getSignature()[i]; + if (tc == DataConstraintModel.typeList) { + Expression e = t.getChildren().get(i - 1); + consExps.add(e); // consExps.get(2) + expToCons.put(System.identityHashCode(e), consExps); + break; + } + } + if (consExps.size() < 2) { + consExps.add(null); + } } Type newType = getExpTypeIfUpdatable(t.getType(), consExps.get(2)); if (newType != null) { @@ -325,7 +343,7 @@ } } cons.put(System.identityHashCode(consExps), t.getType()); - } else if (t.getSymbol().equals(DataConstraintModel.tuple)) { + } else if (symbol.equals(DataConstraintModel.tuple)) { // If the root symbol of the term is tuple. List tupleExps = new ArrayList<>(); List argsTypeList = new ArrayList<>(); @@ -528,10 +546,10 @@ updateExps.put(System.identityHashCode(consComponents.get(2)), consComponents.get(2)); } Type compType = listComponentTypes.get(expType); - if (consComponents.get(1) instanceof Variable) { + 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) instanceof Term) { + } 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)); } @@ -573,10 +591,10 @@ updateExps.put(System.identityHashCode(consComponents.get(0)), consComponents.get(0)); } compType = listComponentTypes.get(expType); - if (consComponents.get(1) instanceof Variable) { + 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) instanceof Term) { + } 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)); }