diff --git a/AlgebraicDataflowArchitectureModel/models/StockManagement.model b/AlgebraicDataflowArchitectureModel/models/StockManagement.model index d3ed3f2..131b7ef 100644 --- a/AlgebraicDataflowArchitectureModel/models/StockManagement.model +++ b/AlgebraicDataflowArchitectureModel/models/StockManagement.model @@ -2,46 +2,45 @@ stock := nil shortage := nil } + +channel CIO_enter { + out arrival(s:Tuple, arrive(item:Str, num:Int)) == tuple(item, num) +} + channel CIO_req { out request(r:Tuple, req(item:Str, num:Int)) == tuple(item, num) } -channel CIO_enter { - out entering(e:Tuple, enter(item:Str, num:Int)) == tuple(item, num) -} - channel C1 { - in request(r, update1(r2)) == r2 - out stock(st:Map, update1(r2)) == if(le(snd(r2), lookup(st, fst(r2))), - insert(st, fst(r2), lookup(st, fst(r2)) - snd(r2)), - st) - out shortage(sh:Map, update1(r2)) == if(le(snd(r2), lookup(sh, fst(r2))), - sh, - insert(sh, fst(r2), lookup(sh, fst(r2)) + snd(r2))) + in arrival(ar, update1(ar2, st)) == ar2 + ref stock(st:Map, update1(ar2, st)) + out available(av:Tuple, update1(ar2, st)) == tuple(fst(ar2), snd(ar2) + lookup(st, fst(ar2))) } channel C2 { - in entering(e, update2(e2, st)) == e2 - ref stock(st, update2(e2, st)) - out shortage(sh, update2(e2, st)) == if(ge(snd(e2) + lookup(st, fst(e2)), lookup(sh, fst(e2))), - insert(sh, fst(e2), 0), - sh) + in available(av, update2(av2, sh)) == av2 + ref shortage(sh, update2(av2, sh)) + out deriver(dr:Tuple, update2(av2, sh)) == if(ge(snd(av2), lookup(sh, fst(av2))), + tuple(fst(av2), lookup(sh, fst(av2)), snd(av2) - lookup(sh, fst(av2))), + tuple(fst(av2), 0, snd(av2))) + out shortage(s, update2(av2, sh)) == if(ge(snd(av2), lookup(s, fst(av2))), + insert(s, fst(av2), 0), + s) } channel C3 { - in entering(e, update3(e2, sh)) == e2 - ref shortage(sh, update3(e2, sh)) - out stock(st, update3(e2, sh)) == if(ge(snd(e2) + lookup(st, fst(e2)), lookup(sh, fst(e2))), - insert(st, fst(e2), snd(e2) + lookup(st, fst(e2)) - lookup(sh, fst(e2))), - insert(st, fst(e2), snd(e2) + lookup(st, fst(e2)))) + in deriver(dr, update3(dr2)) == dr2 + out stock(st, update3(dr2)) == insert(st, fst(dr2), snd(snd(dr2))) + out shipping(sp:Tuple, update3(dr2)) == tuple(fst(dr2), fst(snd(dr2))) } channel C4 { - in entering(e, update4(e2, sh, st)) == e2 - ref shortage(sh, update4(e2, sh, st)) - ref stock(st, update4(e2, sh, st)) - out dispatching(d:Tuple, update4(e2, sh, st)) == if(and(gt(lookup(sh, fst(e2)), 0), ge(snd(e2) + lookup(st, fst(e2)), lookup(sh, fst(e2)))), - tuple(fst(e2), lookup(sh, fst(e2))), - null) -} - + in request(rq, update4(rq2, st)) == rq2 + ref stock(st, update4(rq2, st)) + out deriver(dr, update4(rq2, st)) == if(ge(lookup(st, fst(rq2)), snd(rq2)), + tuple(fst(rq2), snd(rq2), lookup(st, fst(rq2)) - snd(rq2)), + tuple(fst(rq2), 0, lookup(st, fst(rq2)))) + out shortage(sh, update4(rq2, st)) == if(ge(lookup(st, fst(rq2)), snd(rq2)), + sh, + insert(sh, fst(rq2), lookup(sh, fst(rq2)) + snd(rq2))) +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index df93e13..b07fa4b 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -513,7 +513,18 @@ if (argType == DataConstraintModel.typeTuple && t.getType() != null) { List compTypeList = new ArrayList<>(); compTypeList.add(null); - compTypeList.add(t.getType()); + if (DataConstraintModel.typeTuple.isAncestorOf(t.getType())) { + List sndTypes = tupleComponentTypes.get(t.getType()); + if (sndTypes != null) { + for (Type t2: sndTypes) { + compTypeList.add(t2); + } + } else { + compTypeList.add(t.getType()); + } + } else { + compTypeList.add(t.getType()); + } newTupleType = tupleTypes.get(compTypeList); if (newTupleType == null) { // Create new tuple type; @@ -1012,6 +1023,23 @@ } } } + } else { + Map updateVars = getUpdateSet(updateFromVariable, sameVariable); + for (Expression v : sameVariable) { + if (v instanceof Variable) { + Type orgVarType = ((Variable) v).getType(); + if (orgVarType != varType && compareTypes(orgVarType, varType)) { + ((Variable) v).setType(varType); + updateVars.put(System.identityHashCode(v), v); + } + } else if (v instanceof Term) { + Type orgVarType = ((Term) v).getType(); + if (orgVarType != varType && compareTypes(orgVarType, varType)) { + ((Term) v).setType(varType); + updateVars.put(System.identityHashCode(v), v); + } + } + } } } @@ -1147,14 +1175,58 @@ 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); + Type compType = ((Variable) compExp).getType(); + if (compType != null && DataConstraintModel.typeTuple.isAncestorOf(compType)) { + // If the type of one component (compExp) is also tuple. + Type newExpType = tupleTypes.get(componentTypes.subList(i - 1, componentTypes.size())); + if (newExpType == null) { + // Create new tuple type; + newExpType = createNewTupleType(componentTypes.subList(i - 1, componentTypes.size()), compType); + } + if (compareTypes(compType, newExpType)) { + ((Variable) compExp).setType(newExpType); + updateExps.put(System.identityHashCode(compExp), compExp); + } + } else { + if (i - 1 < componentTypes.size()) { + if (compareTypes(compType, componentTypes.get(i - 1))) { + ((Variable) compExp).setType(componentTypes.get(i - 1)); + updateExps.put(System.identityHashCode(compExp), compExp); + } + } else { + // for insert + if (compareTypes(compType, newTupleType)) { + ((Variable) compExp).setType(newTupleType); + 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); + Type compType = ((Term) compExp).getType(); + if (compType != null && DataConstraintModel.typeTuple.isAncestorOf(compType)) { + // If the type of one component (compExp) is also tuple. + Type newExpType = tupleTypes.get(componentTypes.subList(i - 1, componentTypes.size())); + if (newExpType == null) { + // Create new tuple type; + newExpType = createNewTupleType(componentTypes.subList(i - 1, componentTypes.size()), compType); + } + if (compareTypes(compType, newExpType)) { + ((Term) compExp).setType(newExpType); + updateExps.put(System.identityHashCode(compExp), compExp); + } + } else { + if (i - 1 < componentTypes.size()) { + if (compareTypes(compType, componentTypes.get(i - 1))) { + ((Term) compExp).setType(componentTypes.get(i - 1)); + updateExps.put(System.identityHashCode(compExp), compExp); + } + } else { + // for insert + if (compareTypes(compType, newTupleType)) { + ((Variable) compExp).setType(newTupleType); + updateExps.put(System.identityHashCode(compExp), compExp); + } + } } } } @@ -1162,12 +1234,47 @@ } else { Type tupleType = tuple.get(System.identityHashCode(tupleComponentGroup)); List componentTypes = tupleComponentTypes.get(tupleType); - Type compType = componentTypes.get(idx - 1); - Type newCompType = getExpTypeIfUpdatable(compType, exp); - if (newCompType != null) { + boolean updated = false; + if (idx == 1) { + Type compType = componentTypes.get(idx - 1); + Type newCompType = getExpTypeIfUpdatable(compType, exp); + if (newCompType != null) { + componentTypes = new ArrayList<>(componentTypes); + componentTypes.set(idx - 1, newCompType); + updated = true; + } + } else { + Type expType = null; + if (exp instanceof Term) { + expType = ((Term) exp).getType(); + } else if (exp instanceof Variable) { + expType = ((Variable) exp).getType(); + } + if (expType != null && DataConstraintModel.typeTuple.isAncestorOf(expType)) { + // If the type of the updated component (exp) is also tuple. + List subCompTypes = tupleComponentTypes.get(expType); + componentTypes = new ArrayList<>(componentTypes); + for (int i = 0; i < subCompTypes.size(); i++) { + if (componentTypes.size() < i + 2) { + componentTypes.add(subCompTypes.get(i)); + updated = true; + } else if (compareTypes(componentTypes.get(i + 1), subCompTypes.get(i))) { + componentTypes.set(i + 1, subCompTypes.get(i)); + updated = true; + } + } + } else { + Type compType = componentTypes.get(idx - 1); + Type newCompType = getExpTypeIfUpdatable(compType, exp); + if (newCompType != null) { + componentTypes = new ArrayList<>(componentTypes); + componentTypes.set(idx - 1, newCompType); + updated = true; + } + } + } + if (updated) { // 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; @@ -1271,7 +1378,7 @@ } // Propagate an update of a map's type to another map's type. Expression compExp = null; - if (idx == 0 && mapComponentGroup.size() == 4) { // for lookup + if (idx == 0 && mapComponentGroup.size() == 4) { // for insert compExp = mapComponentGroup.get(3); } else if (idx == 3) { compExp = mapComponentGroup.get(0); @@ -1313,7 +1420,7 @@ ((Term) mapExp).setType(newMapType); updateExps.put(System.identityHashCode(mapExp), mapExp); } - if (mapComponentGroup.size() == 4) { // for lookup + if (mapComponentGroup.size() == 4) { // for insert mapExp = mapComponentGroup.get(3); if (mapExp instanceof Variable) { ((Variable) mapExp).setType(newMapType); @@ -1471,21 +1578,18 @@ * of the new type, false: otherwise */ private static boolean compareTypes(Type originalType, Type newType) { - if (originalType == null) - return true; + if (originalType == null) return true; if (originalType != newType && newType != null) { - if (originalType.isAncestorOf(newType)) - return true; + if (originalType.isAncestorOf(newType)) return true; + if (newType.isAncestorOf(originalType)) return false; if (DataConstraintModel.typeMap.isAncestorOf(originalType) && DataConstraintModel.typeMap.isAncestorOf(newType)) { List originalCompTypes = mapComponentTypes.get(originalType); List newCompTypes = mapComponentTypes.get(newType); - if (originalCompTypes == null) - return true; + if (originalCompTypes == null) return true; for (int i = 0; i < originalCompTypes.size(); i++) { - if (originalCompTypes.get(i) != null && (newCompTypes.get(i) == null - || !originalCompTypes.get(i).isAncestorOf(newCompTypes.get(i)))) - return false; + if (originalCompTypes.get(i) != null && + (newCompTypes.get(i) == null || !originalCompTypes.get(i).isAncestorOf(newCompTypes.get(i)))) return false; } return true; } @@ -1493,12 +1597,26 @@ && DataConstraintModel.typeTuple.isAncestorOf(newType)) { List originalCompTypes = tupleComponentTypes.get(originalType); List newCompTypes = tupleComponentTypes.get(newType); - if (originalCompTypes == null) - return true; + if (originalCompTypes == null) return true; + originalCompTypes = new ArrayList<>(originalCompTypes); + newCompTypes = new ArrayList<>(newCompTypes); for (int i = 0; i < originalCompTypes.size(); i++) { - if (originalCompTypes.get(i) != null && (newCompTypes.get(i) == null - || !originalCompTypes.get(i).isAncestorOf(newCompTypes.get(i)))) - return false; + if (originalCompTypes.get(i) != null) { + if (DataConstraintModel.typeTuple.isAncestorOf(originalCompTypes.get(i))) { + Type tupleType = originalCompTypes.remove(i); + for (Type t: tupleComponentTypes.get(tupleType)) { + originalCompTypes.add(t); + } + } + if (newCompTypes.size() - 1 < i) return false; + if (newCompTypes.get(i) != null && DataConstraintModel.typeTuple.isAncestorOf(newCompTypes.get(i))) { + Type tupleType = newCompTypes.remove(i); + for (Type t: tupleComponentTypes.get(tupleType)) { + newCompTypes.add(t); + } + } + if (newCompTypes.get(i) == null || !originalCompTypes.get(i).isAncestorOf(newCompTypes.get(i))) return false; + } } return true; } @@ -1506,8 +1624,7 @@ && DataConstraintModel.typeList.isAncestorOf(newType)) { Type originalCompType = listComponentTypes.get(originalType); Type newCompType = listComponentTypes.get(newType); - if (originalCompType != null && (newCompType == null || !originalCompType.isAncestorOf(newCompType))) - return false; + if (originalCompType != null && (newCompType == null || !originalCompType.isAncestorOf(newCompType))) return false; return true; } }