diff --git a/AlgebraicDataflowArchitectureModel/models/Algolike.model b/AlgebraicDataflowArchitectureModel/models/Algolike.model new file mode 100644 index 0000000..97aef04 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/models/Algolike.model @@ -0,0 +1,113 @@ +init { + deck := nil + handsA := nil + handsB := nil + guessA := 0 + guessB := 0 +} +channel targetAInput{ + out targetA(t:Int, setTargetA(a:Int)) == a +} +channel targetBInput{ + out targetB(t:Int, setTargetB(b:Int)) == b +} +channel attackerAInput{ + out attackerA(t:Int, setAttackerA(a:Int)) == a +} +channel attackerBInput{ + out attackerB(t:Int, setAttackerB(b:Int)) == b +} +channel guessAInput{ + out guessA(t:Int, setGuessA(a:Int)) == a +} +channel guessBInput{ + out guessB(t:Int, setGuessB(b:Int)) == b +} +channel addDeck{ + out deck(d:List, addCard(num:Integer)) == cons(tuple(num, false), d) +} + +channel drawAInput{ + + ref targetA(t:Int, drawAndAttackA(t, g, b)) + ref guessA(g:Int, drawAndAttackA(t, g, b)) + ref handsB(b:List, drawAndAttackA(t, g, b)) + out resultByDrawingA(sda:Tuple, drawAndAttackA(t, g, b)) == tuple(eq(fst(get(b, t)), g), t) +} + +channel inputDrawArgsA{ + in resultByDrawingA(sda:Tuple, drawA(sucTrg, d)) == sucTrg + ref deck(d:List, drawA(sucTrg, d)) + + out handsA(outA:List, drawA(sucTrg, d)) == if(fst(sucTrg), + sortByKey(cons(tuple(fst(head(d)),false), outA)), + sortByKey(cons(tuple(fst(head(d)), true), outA))) + + out handsB(outB:List, drawA(sucTrg, d)) == if(fst(sucTrg), + set(outB, snd(sucTrg), tuple(fst(get(outB, snd(sucTrg))), true)), + outB) + out deck(t:List, drawA(sucTrg, d)) == tail(t) +} + +channel selectAInput{ + ref attackerA(a:Int, selectAndAttackA(a, t, g, b)) + ref targetA(t:Int, selectAndAttackA(a, t, g, b)) + ref guessA(g:Int, selectAndAttackA(a, t, g, b)) + ref handsB(b:List, selectAndAttackA(a, t, g, b)) + out resultBySelectingA(ssa:Tuple, selectAndAttackA(a, t, g, b)) == tuple(eq(fst(get(b, t)), g), t, a) +} +channel inputSelectArgA{ + in resultBySelectingA(ssa, selectA(sucTrgAtk)) == sucTrgAtk + out handsA(outA, selectA(sucTrgAtk)) == if(fst(sucTrgAtk), + outA, + set(outA, snd(snd(sucTrgAtk)), tuple(fst(get(outA, snd(snd(sucTrgAtk)))), true))) + out handsB(outB, selectA(sucTrgAtk)) == if(fst(sucTrgAtk), + set(outB, fst(snd(sucTrgAtk)), tuple(fst(get(outB, fst(snd(sucTrgAtk)))), true)), + outB) +} +channel drawBInput{ + ref targetB(t:Int, drawAndAttackB(t, g, a)) + ref guessB(g:Int, drawAndAttackB(t, g, a)) + ref handsA(a:List, drawAndAttackB(t, g, a)) + out resultByDrawingB(sdb:Tuple, drawAndAttackB(t, g, a)) == tuple(eq(fst(get(a, t)), g), t) +} + +channel inputDrawArgsB{ + in resultByDrawingB(sdb:Tuple, drawB(sucTrg, d)) == sucTrg + ref deck(d:List, drawB(sucTrg, d)) + + out handsB(outB:List, drawB(sucTrg, d)) == if(fst(sucTrg), + sortByKey(cons(tuple(fst(head(d)),false), outB)), + sortByKey(cons(tuple(fst(head(d)), true), outB))) + + out handsA(outA:List, drawB(sucTrg, d)) == if(fst(sucTrg), + set(outA, snd(sucTrg), tuple(fst(get(outA, snd(sucTrg))), true)), + outA) + out deck(t:List, drawB(sucTrg, d)) == tail(t) +} + +channel selectBInput{ + ref attackerB(atk:Int, selectAndAttackB(atk, t, g, a)) + ref targetB(t:Int, selectAndAttackB(atk, t, g, a)) + ref guessB(g:Int, selectAndAttackB(atk, t, g, a)) + ref handsA(a:List, selectAndAttackB(atk, t, g, a)) + out resultBySelectingB(ssb:Tuple, selectAndAttackB(atk, t, g, a)) == tuple(eq(fst(get(a, t)), g), t, atk) +} +channel inputSelectArgB{ + in resultBySelectingB(ssb, selectB(sucTrgAtk)) == sucTrgAtk + out handsB(outB, selectB(sucTrgAtk)) == if(fst(sucTrgAtk), + outB, + set(outB, snd(snd(sucTrgAtk)), tuple(fst(get(outB, snd(snd(sucTrgAtk)))), true))) + out handsA(outA, selectB(sucTrgAtk)) == if(fst(sucTrgAtk), + set(outA, fst(snd(sucTrgAtk)), tuple(fst(get(outA, fst(snd(sucTrgAtk)))), true)), + outA) +} + +channel judgeA{ + in handsA(a:List, judge(j)) == j + out loseA(la:Bool, judge(j)) == eq(length(extractFaceDown(j)), 0) +} +channel judgeB{ + in handsB(b:List, judge(j)) == j + out loseB(lb:Bool, judge(j)) == eq(length(extractFaceDown(j)), 0) +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index 706841f..a890ad3 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -82,14 +82,14 @@ Map> resources = new HashMap<>(); Map variables = new HashMap<>(); Map, Type>>> messages = new HashMap<>(); - Map cons = 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>> expToConsOrSet = new HashMap<>(); Map>> expToTuple = new HashMap<>(); Map>> expToPair = new HashMap<>(); Map>> expToMap = new HashMap<>(); @@ -98,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<>(); @@ -340,55 +340,62 @@ } for (Term t : terms) { Symbol symbol = t.getSymbol(); - if (symbol.equals(DataConstraintModel.cons)) { - // If the root symbol of the term is cons. + if (symbol.equals(DataConstraintModel.cons) || symbol.equals(DataConstraintModel.set)) { + // If the root symbol of the term is cons or set. List consExps = new ArrayList<>(); consExps.add(t); - updateExpressionBelonging(expToCons, t, consExps); - for (Expression e : t.getChildren()) { + 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(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(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); @@ -398,7 +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(expToConsOrSet, e, consExps); + consExps.add(t); + updateExpressionBelonging(expToConsOrSet, t, consExps); + consExps.add(null); + Type listType = listTypes.get(t.getType()); + 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 1st argument is more concrete than the type of the term. + Type newCompType = listComponentTypes.get(newListType); + 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 1st argument. + if (consExps.get(0) != null && consExps.get(0) instanceof Variable) { + ((Variable) consExps.get(0)).setType(listType); + 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(updateFromConsOrSet, consExps); + updateCons.put(System.identityHashCode(consExps.get(0)), consExps.get(0)); + } + consOrSet.put(System.identityHashCode(consExps), listType); + } + } 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<>(); @@ -849,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(); @@ -859,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); @@ -875,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); @@ -890,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); @@ -922,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); @@ -938,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); @@ -954,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); @@ -1079,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) { @@ -1120,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)); } } } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java new file mode 100644 index 0000000..db8bb5d --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java @@ -0,0 +1,17 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; +import graphicalrefactor.editor.Editor; + +public class DAGLayoutAction extends AbstractEditorAction { + + public DAGLayoutAction(Editor editor) { + super("DAG Layout", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + editor.setDAGLayout(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java index 3ddc0c5..9a0a8a0 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java @@ -10,6 +10,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -18,9 +19,11 @@ import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGeometry; import com.mxgraph.model.mxGraphModel; +import com.mxgraph.model.mxIGraphModel; import com.mxgraph.util.mxConstants; import com.mxgraph.util.mxPoint; import com.mxgraph.view.mxCellState; +import com.mxgraph.util.mxRectangle; import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxGraphView; @@ -28,6 +31,7 @@ import algorithms.SelectableDataTransfers; import algorithms.UpdateConflictCheck; import code.ast.CompilationUnit; +import graphicalrefactor.layouts.*; import models.Edge; import models.EdgeAttribute; import models.Node; @@ -372,6 +376,17 @@ return graph; } + + public void setDAGLayout() { + Object parent = graph.getDefaultParent(); + graph.getModel().beginUpdate(); + try { + DAGLayout ctl = new DAGLayout(graph); + ctl.execute(parent); + } finally { + graph.getModel().endUpdate(); + } + } public void updateEdgeAttiributes(ResourceDependencyGraph resourceDependencyGraph) { Object parent = graph.getDefaultParent(); diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/layouts/DAGLayout.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/layouts/DAGLayout.java new file mode 100644 index 0000000..c09178c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/layouts/DAGLayout.java @@ -0,0 +1,148 @@ +package graphicalrefactor.layouts; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.mxgraph.layout.mxGraphLayout; +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGeometry; +import com.mxgraph.model.mxICell; +import com.mxgraph.model.mxIGraphModel; +import com.mxgraph.util.mxRectangle; +import com.mxgraph.view.mxCellState; +import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; + +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.IdentifierTemplate; + +public class DAGLayout extends mxGraphLayout { + + public DAGLayout(mxGraph arg0) { + super(arg0); + } + + public void execute(Object parent) { + mxIGraphModel model = graph.getModel(); + + model.beginUpdate(); + try { + List> map = new ArrayList>(); + List moved = new ArrayList<>(); + + for (int i = 0; i < model.getChildCount(parent); i++) { + + mxCell cell = (mxCell) model.getChildAt(parent, i); + + if (model.isVertex(cell)) { + mxGraphView view = graph.getView(); + mxCellState state = view.getState(cell); + + if (!"ellipse".equals(state.getStyle().get("shape")) && (cell.getEdgeCount() == 1)) { + List newline = new ArrayList(); + map.add(newline); + lines(map, cell); + } + } + } + + // ���בւ� + sort(map, 0, false); + + // layout + int count; + int skip = 0; + mxGraphView view = graph.getView(); + for (int i = 0; i < map.size(); i++) { + count = 0; + for (int j = 0; j < map.get(i).size(); j++) { + mxGeometry geom = (mxGeometry) map.get(i).get(j).getGeometry().clone(); + mxCellState state = view.getState(map.get(i).get(j)); + if (checkmoved(moved, map.get(i).get(j))) { + if ("ellipse".equals(state.getStyle().get("shape"))){ + geom.setX(50 + j*200); + } else { + geom.setX(100 + j*200); + } + geom.setY(100 + (i-skip)*100); + model.setGeometry(map.get(i).get(j), geom); + moved.add(map.get(i).get(j).getId()); + } else if (geom.getX() < 100 + j*150) { + if ("ellipse".equals(state.getStyle().get("shape"))){ + geom.setX(50 + j*200); + } else { + geom.setX(100 + j*200); + } + geom.setY(100 + (i-skip)*100); + model.setGeometry(map.get(i).get(j), geom); + } else { + count++; + } + } + if (count >= map.get(i).size())skip++; + } + + } finally { + model.endUpdate(); + } + } + + + public void lines(List> mapping, mxCell next) { + mapping.get(mapping.size()-1).add(next); + int tagcount = 0; + mxCell edge; + for (int i = 0; i < next.getEdgeCount(); i++) { + edge = (mxCell) next.getEdgeAt(i); + if (next != (mxCell) edge.getTarget() && ((mxCell) edge.getTarget() != null)) { + tagcount++; + if (tagcount > 1) { + List newline = new ArrayList(mapping.get(mapping.size()-1)); + while (newline.get(newline.size()-1).getId() != next.getId()) { + newline.remove(newline.size()-1); + } + mapping.add(newline); + lines(mapping, (mxCell) edge.getTarget()); + + } else { + lines(mapping, (mxCell) edge.getTarget()); + } + } + } + } + + public boolean checkmoved(List list, mxCell cell) { + for (int i = 0; i < list.size(); i++) { + if (list.get(i).equals(cell.getId()))return false; + } + return true; + } + + public void sort(List> map, int n, boolean check) { + int msize = -1; + int mnum = -1; + if (check) { + for (int i = n; i < map.size(); i++) { + if (map.get(i).size() > msize && (map.get(n-1).get(0).getId().equals(map.get(i).get(0).getId()))) { + mnum = i; + } + } + } else { + for (int i = n; i < map.size(); i++) { + if (map.get(i).size() > msize) { + mnum = i; + } + } + } + if (mnum >= 0) { + Collections.swap(map, n, mnum); + sort(map, n+1, true); + } else if(n < map.size()) { + sort(map, n+1, false); + } + } + + +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java index 43ab6ca..1e29a75 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java @@ -5,6 +5,7 @@ import graphicalrefactor.actions.CircleLayoutAction; import graphicalrefactor.actions.DeleteAction; +import graphicalrefactor.actions.DAGLayoutAction; import graphicalrefactor.actions.ExitAction; import graphicalrefactor.actions.OpenAction; import graphicalrefactor.actions.JavaPrototypeGenerateAction; @@ -32,6 +33,7 @@ private DeleteAction deleteAction = null; private JavaPrototypeGenerateAction javaPrototypeGenerateAction = null; private JerseyPrototypeGenerateAction jerseyPrototypeGenerateAction = null; + private DAGLayoutAction dagLayoutAction = null; private TreeLayoutAction treeLayoutAction = null; private CircleLayoutAction circleLayoutAction = null; @@ -58,6 +60,7 @@ menu = add(new JMenu("Layout")); + menu.add(dagLayoutAction = new DAGLayoutAction(graphicalModelRefactor.getEditor())); menu.add(treeLayoutAction = new TreeLayoutAction(graphicalModelRefactor.getEditor())); menu.add(circleLayoutAction = new CircleLayoutAction(graphicalModelRefactor.getEditor())); diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index d8987b3..c6fb2ea 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -36,6 +36,7 @@ public static final Symbol cons = new Symbol("cons", 2, Symbol.Type.PREFIX, "($x,$y)->$x.add(0, $y)", Symbol.Type.LAMBDA_WITH_SIDE_EFFECT, new int[] {1, 0}); public static final Symbol head = new Symbol("head", 1, Symbol.Type.PREFIX, "($x)->$x.get(0)", Symbol.Type.LAMBDA); public static final Symbol tail = new Symbol("tail", 1, Symbol.Type.PREFIX, "($x)->$x.subList(1, $x.size())", Symbol.Type.LAMBDA); + public static final Symbol length = new Symbol("length", 1, Symbol.Type.PREFIX, "($x)->$x.size()", Symbol.Type.LAMBDA); public static final Symbol get = new Symbol("get", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD); public static final Symbol set = new Symbol("set", 3, Symbol.Type.PREFIX, "set", Symbol.Type.METHOD_WITH_SIDE_EFFECT); public static final Symbol contains = new Symbol("contains", 2, Symbol.Type.PREFIX, "contains", Symbol.Type.METHOD); @@ -81,6 +82,8 @@ return temp; } }); + + public static final Symbol mod = new Symbol("mod", 2, Symbol.Type.PREFIX, "%", Symbol.Type.INFIX); public static final Symbol eq = new Symbol("eq", 2, Symbol.Type.PREFIX, "==", Symbol.Type.INFIX); public static final Symbol neq = new Symbol("neq", 2, Symbol.Type.PREFIX, "!=", Symbol.Type.INFIX); @@ -151,6 +154,7 @@ cons.setInverses(new Symbol[] {head, tail}); cons.setSignature(new Type[] {typeList, null, typeList}); contains.setSignature(new Type[] {typeBoolean, typeList, null}); + length.setSignature(new Type[] {typeInt, null}); get.setSignature(new Type[] {null, typeList, typeInt}); set.setSignature(new Type[] {typeList, typeList, typeInt, null}); eq.setSignature(new Type[] {typeBoolean, null, null}); @@ -202,6 +206,7 @@ addSymbol(cons); addSymbol(head); addSymbol(tail); + addSymbol(length); addSymbol(contains); addSymbol(get); addSymbol(set); diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ModelExtension.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ModelExtension.java index 0666fa2..06468f0 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ModelExtension.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ModelExtension.java @@ -8,6 +8,8 @@ private static Symbol.Memento floorMem; private static Symbol.Memento sumMem; private static Symbol.Memento mergeMem; + private static Symbol.Memento extractFaceDownMem; + private static Symbol.Memento sortByKeyMem; public static void extendModel(DataFlowModel model) { Symbol floor = model.getSymbol("floor"); @@ -100,6 +102,52 @@ merge.setImplOperatorType(Symbol.Type.GENERATIVE); merge.setSignature(new Type[] {DataConstraintModel.typeList, DataConstraintModel.typeList, DataConstraintModel.typeList}); } + Symbol extractFaceDown = model.getSymbol("extractFaceDown"); + extractFaceDownMem = null; + if (extractFaceDown != null) { + extractFaceDownMem = extractFaceDown.createMemento(); + extractFaceDown.setArity(1); + extractFaceDown.setGenerator(new Symbol.IImplGenerator() { + @Override + public String generate(Type type, String[] children, String[] childrenSideEffects, String[] sideEffect) { + return children[0]+".stream().filter(item -> item.getValue()==false).collect(Collectors.toList())"; + } + }); + extractFaceDown.setImplOperatorType(Symbol.Type.GENERATIVE); + extractFaceDown.setSignature(new Type[] {DataConstraintModel.typeList, null}); + } + + Symbol sortByKey = model.getSymbol("sortByKey"); + sortByKeyMem = null; + if(sortByKey != null) { + sortByKeyMem = sortByKey.createMemento(); + sortByKey.setArity(1); + sortByKey.setGenerator(new Symbol.IImplGenerator() { + @Override + public String generate(Type type, String[] children, String[] childrenSideEffects, String[] sideEffect) { + String compType = ""; + String temp_sort="temp_sort"; + if (type != null) { + String interfaceType = type.getInterfaceTypeName(); + if (interfaceType.contains("<")) { + compType = interfaceType.substring(interfaceType.indexOf("<") + 1, interfaceType.lastIndexOf(">")); + } + String implType = type.getImplementationTypeName(); + if (implType.indexOf('<') >= 0) { + implType = implType.substring(0, implType.indexOf('<')); + } + + } + for (String s: childrenSideEffects) { + sideEffect[0] += s; + } + temp_sort=children[0]+".sort(Comparator.comparing("+compType+"::getKey));\n"; + return temp_sort; + } + }); + sortByKey.setSignature(new Type[] {DataConstraintModel.typeList, DataConstraintModel.typeList}); + sortByKey.setImplOperatorType(Symbol.Type.GENERATIVE); + } } public static void recoverModel(DataFlowModel model) { @@ -109,5 +157,9 @@ if (sum != null) sum.setMemento(sumMem); Symbol merge = model.getSymbol("merge"); if (merge != null) merge.setMemento(mergeMem); + Symbol extractFaceDown = model.getSymbol("extractFaceDown"); + if (extractFaceDown != null) extractFaceDown.setMemento(extractFaceDownMem); + Symbol sortByKey = model.getSymbol("sortByKey"); + if (sortByKey != null) sortByKey.setMemento(sortByKeyMem); } }