diff --git a/AlgebraicDataflowArchitectureModel/models/SimpleUI.model b/AlgebraicDataflowArchitectureModel/models/SimpleUI.model index 0825942..6aedfa6 100644 --- a/AlgebraicDataflowArchitectureModel/models/SimpleUI.model +++ b/AlgebraicDataflowArchitectureModel/models/SimpleUI.model @@ -1,10 +1,10 @@ init { screenTemplates := { - "000": {"widgets": {"001": {"type": "textInput", "text": "", "state": 0, "visible": true}, - "002": {"type": "button", "text": "Next", "state": 0, "visible": true}}, + "000": {"widgets": {"001": {"type": "textInput", "text": "", "visible": true}, + "002": {"type": "button", "text": "Next", "visible": true}}, "layout": true}, - "001": {"widgets": {"003": {"type": "label", "text": "label", "state": 0, "visible": true}, - "004": {"type": "button", "text": "Back", "state": 0, "visible": true}}, + "001": {"widgets": {"003": {"type": "label", "text": "label", "visible": true}, + "004": {"type": "button", "text": "Back", "visible": true}}, "layout": true} } } @@ -59,20 +59,14 @@ out screen(curS, transScreen(nextScId, screen)) = screen } -channel EventDispatch(wid: Str) { - in screen.widgets.{wid}.state(curState: Int, dispatchEvent(curScId, wid, nextState)) = nextState - ref curScreen(curScId: Str, dispatchEvent(curScId, wid, nextState)) - out screenTemplates.{curScId}.widgets.{wid}.state(curState: Int, dispatchEvent(curScId, wid, nextState)) = nextState +channel EventHandler1(wid: Str) { + in screen.widgets.{wid="002"}.state(curState: Int, handleEvent1(nextState)) = nextState + out curScreen(curScId: Str, handleEvent1(nextState)) = if((curScId == "000") && (nextState == 0), "001", curScId) } -channel EventHandler1(scId: Str, wid: Str) { - in screenTemplates.{scId="000"}.widgets.{wid="002"}.state(curState: Int, handleEvent1(nextState)) = nextState - out curScreen(curScId: Str, handleEvent1(nextState)) = if(nextState == 0, "001", curScId) -} - -channel EventHandler2(scId: Str, wid: Str) { - in screenTemplates.{scId="001"}.widgets.{wid="004"}.state(curState: Int, handleEvent2(nextState)) = nextState - out curScreen(curScId: Str, handleEvent2(nextState)) = if(nextState == 0, "000", curScId) +channel EventHandler2(wid: Str) { + in screen.widgets.{wid="004"}.state(curState: Int, handleEvent2(nextState)) = nextState + out curScreen(curScId: Str, handleEvent2(nextState)) = if((curScId == "001") && (nextState == 0), "000", curScId) } channel ChangeLayout { diff --git a/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java b/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java index bf59db4..9200de6 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java +++ b/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java @@ -21,18 +21,18 @@ private mxIGraphModel graphModel; private mxGraphView view; private Map> dotEdges; - private List> lines; + private List> paths; private List order; - private Map> hierarchicalRecursionOrder; - private Set usedLineIndex; + private Map> orderInResourceHierarchy; + private Set usedPathIndex; private List cells; private Set roots; - private Map myRoot; + private Map resourceToRoot; private Set resources; private Set channels; private Set eventChannels; - private Map> vertexToDist; - private Map> cellToLineIndex; + private Map> vertexToDepths; + private Map> cellToPathIndex; private Map> cellGeo; final double MOVE_X = 100; final double MOVE_Y = 50; @@ -50,45 +50,45 @@ graphModel = graph.getModel(); view = graph.getView(); dotEdges = new HashMap<>(); - lines = new ArrayList<>(); + paths = new ArrayList<>(); order = new ArrayList<>(); - hierarchicalRecursionOrder = new HashMap<>(); - usedLineIndex = new HashSet<>(); + orderInResourceHierarchy = new HashMap<>(); + usedPathIndex = new HashSet<>(); cells = new ArrayList<>(); roots = new HashSet<>(); - myRoot = new HashMap<>(); + resourceToRoot = new HashMap<>(); resources = new HashSet<>(); channels = new HashSet<>(); eventChannels = new HashSet<>(); - vertexToDist = new HashMap<>(); - cellToLineIndex = new HashMap<>(); + vertexToDepths = new HashMap<>(); + cellToPathIndex = new HashMap<>(); cellGeo = new HashMap<>(); } - public void execute(Object parent) { + public void execute(Object rootCell) { graphModel.beginUpdate(); try { - // 繝「繝�繝ォ縺九iresource, channel, eventChannel縺ォ蛻�縺代k - for (int i = 0; i < graphModel.getChildCount(parent); i++) { - mxCell cell = (mxCell) graphModel.getChildAt(parent, i); + // Initialize cells, roots, channels and eventChannels fields. + for (int i = 0; i < graphModel.getChildCount(rootCell); i++) { + mxCell cell = (mxCell) graphModel.getChildAt(rootCell, i); if (graphModel.isVertex(cell)) { mxCellState state = view.getState(cell); cells.add(cell); - // cell縺罫esource縺ァ縺ゅk if ("ellipse".equals(state.getStyle().get("shape"))) { + // If the cell represents a root resource. roots.add(cell); - hierarchicalRecursionOrder.put(cell, new ArrayList<>()); - familySearch(cell, cell, 0); + orderInResourceHierarchy.put(cell, new ArrayList<>()); + traverseResourceHierarchy(cell, cell, 0); } if ("rectangle".equals(state.getStyle().get("shape"))) { + // If the cell represents a root channel. if ("true".equals(state.getStyle().get("dashed"))) { continue; } - // cell縺憩ventChannel縺ァ縺ゅk縺句愛螳� boolean bEventChannel = true; for (int j = 0; j < cell.getEdgeCount(); j++) { mxCell edge = (mxCell) cell.getEdgeAt(j); @@ -97,241 +97,213 @@ } } - // cell縺憩ventChannel縺ァ縺ゅk if (bEventChannel) { + // If the cell represents a root event channel. eventChannels.add(cell); - // cell縺慶hannel縺ァ縺ゅk } else { channels.add(cell); } - hierarchicalRecursionOrder.put(cell, new ArrayList<>()); + orderInResourceHierarchy.put(cell, new ArrayList<>()); } } } - // 蜈ィ縺ヲ縺ョcell縺ョ蠎ァ讓吶�∝、ァ縺阪&縺ェ縺ゥ繧貞�晄悄蛹� + // For all cells for (mxCell c : cells) { c.getGeometry().setX(0); c.getGeometry().setY(0); if (resources.contains(c)) { + // For a resource cell. view.getState(c).getStyle().put("verticalAlign", "top"); c.getGeometry().setWidth(WIDTH); c.getGeometry().setHeight(HEIGHT); } } - // dotEdges繧貞�晄悄蛹� + // Initialize dotEdges. for (mxCell c : cells) { dotEdges.put(c, new HashSet<>()); } - // line繧呈ァ狗ッ峨☆繧� - for (mxCell ec : eventChannels) { - List newline = new ArrayList(); - lines.add(newline); - constructionLine(ec, 0); + for (mxCell eventCh : eventChannels) { + List newPath = new ArrayList(); + paths.add(newPath); + constructPaths(eventCh, 0); } - // cell縺ョ霍晞屬繧貞�崎ィ育ョ� - reculcDist(); + recalcDepths(); - // cell縺悟ア槭☆繧詰ine縺ョindex繧呈アゅa繧� - for (int i = 0; i < lines.size(); i++) { - for (mxCell cell : lines.get(i)) { - if (cellToLineIndex.get(cell) == null) { - cellToLineIndex.put(cell, new ArrayList<>()); + for (int i = 0; i < paths.size(); i++) { + for (mxCell cell : paths.get(i)) { + if (cellToPathIndex.get(cell) == null) { + cellToPathIndex.put(cell, new ArrayList<>()); } - cellToLineIndex.get(cell).add(i); + cellToPathIndex.get(cell).add(i); } } - // 荳ヲ縺ケ繧詰ine縺ョ鬆�逡ェ繧偵た繝シ繝医☆繧� - sortLines(); + sortPaths(); - Boolean isVersion1 = true; + boolean isVersion1 = true; - System.out.println(vertexToDist); - // cell繧帝�咲スョ縺吶k + System.out.println(vertexToDepths); if (isVersion1) { - // channel縺ョ謇�螳壹�ョ菴咲スョ縺碁嚴螻、讒矩��蜀�驛ィ縺ォ縺ェ繧九→縺阪�∽ク九↓縺壹i縺励※驟咲スョ縺吶k繝ャ繧、繧「繧ヲ繝� - layout1((mxCell) parent); + layout1((mxCell) rootCell); } else { - // channel繧帝嚴螻、讒矩��蜀�驛ィ縺ァ繧よ園螳壹�ョ菴咲スョ縺ォ驟咲スョ縺吶k繝ャ繧、繧「繧ヲ繝� - layout2((mxCell) parent); + layout2((mxCell) rootCell); } } finally { graphModel.endUpdate(); } } - // 髫主ア、讒矩��繧貞�榊クー逧�縺ォ謗「邏「 - public void familySearch(mxCell r, mxCell p, int d) { - int childNum = graphModel.getChildCount(p); - - myRoot.put(p, r); - resources.add(p); - if (r != p) { - hierarchicalRecursionOrder.get(r).add(p); + public void traverseResourceHierarchy(mxCell rootResourceCell, mxCell curResourceCell, int layer) { + resourceToRoot.put(curResourceCell, rootResourceCell); + resources.add(curResourceCell); + if (rootResourceCell != curResourceCell) { + orderInResourceHierarchy.get(rootResourceCell).add(curResourceCell); } + int childNum = graphModel.getChildCount(curResourceCell); for (int i = 0; i < childNum; i++) { - mxCell child = (mxCell) graphModel.getChildAt(p, i); - cells.add(child); - resources.add(child); - familySearch(r, child, d + 1); + mxCell childCell = (mxCell) graphModel.getChildAt(curResourceCell, i); + cells.add(childCell); + resources.add(childCell); + traverseResourceHierarchy(rootResourceCell, childCell, layer + 1); } } - // line繧呈ァ狗ッ峨☆繧� - public void constructionLine(mxCell cur, int d) { - // vertexToDist{key : cell, value : [霍晞屬縺ョ譛�蟆丞�、, 霍晞屬縺ョ譛�螟ァ蛟、]} 繧貞�晄悄蛹� - if (vertexToDist.get(cur) == null) { - vertexToDist.put(cur, Arrays.asList(d, d)); + public void constructPaths(mxCell curCell, int depth) { + if (vertexToDepths.get(curCell) == null) { + vertexToDepths.put(curCell, Arrays.asList(depth, depth)); } else { - // 閾ェ霄ォ縺悟性縺セ繧後kline縺ョ荳ュ縺ァ荳�逡ェ螟ァ縺阪>霍晞屬繧剃ソ晏ュ� - List dists = vertexToDist.get(cur); - dists.set(0, Math.max(dists.get(0), d)); - dists.set(1, dists.get(0)); + List depths = vertexToDepths.get(curCell); + depths.set(0, Math.max(depths.get(0), depth)); + depths.set(1, depths.get(0)); } - lines.get(lines.size() - 1).add(cur); + paths.get(paths.size() - 1).add(curCell); - int tagCount = 0; // edge縺ョ蟋狗せ縺ィ縺ェ繧議ell縺ィ縺励※蜿ら�ァ縺輔l縺溷屓謨ー - for (int i = 0; i < cur.getEdgeCount(); i++) { - mxCell edge = (mxCell) cur.getEdgeAt(i); + int branchCount = 0; + for (int i = 0; i < curCell.getEdgeCount(); i++) { + mxCell edge = (mxCell) curCell.getEdgeAt(i); mxCellState state = view.getState(edge); - mxCell target = (mxCell) edge.getTarget(); + mxCell dstCell = (mxCell) edge.getTarget(); - // cur縺悟ァ狗せ縺ィ縺ェ繧菊dge縺ョ邨らせ縺ィ縺ェ繧逆arget縺瑚�ェ霄ォ縲√b縺励¥縺ッ蟄伜惠縺励↑縺�蝣エ蜷医r髯、縺� - if ((cur != target) && (target != null)) { - // edge縺ョ遞ョ鬘槭′"dashed"縺ョ蝣エ蜷� + if ((curCell != dstCell) && (dstCell != null)) { if ("true".equals(state.getStyle().get("dashed"))) { - state.getStyle().put("strokeColor", "#800080"); // edge縺ョ濶イ繧貞、画峩 - dotEdges.get(cur).add(target); // dotEdges{key : 蟋狗せ縺ィ縺ェ繧議ell, value : 邨らせ縺ィ縺ェ繧議ell} + state.getStyle().put("strokeColor", "#800080"); + dotEdges.get(curCell).add(dstCell); } else { - tagCount++; - // 蟋狗せ縺ィ縺励※隍�謨ー蝗槫盾辣ァ縺輔l縺ヲ縺�繧句�エ蜷� - if (tagCount > 1) { - // cur縺セ縺ァ縺ョline縺ョ諠�蝣ア繧貞�肴ァ狗ッ峨@縺ヲ縲√◎縺薙°繧画眠縺励>line繧呈ァ狗ッ峨☆繧� - List newline = new ArrayList(lines.get(lines.size() - 1)); - while (newline.get(newline.size() - 1).getId() != cur.getId()) { - newline.remove(newline.size() - 1); + branchCount++; + if (branchCount > 1) { + // If a branch is found. + List newPath = new ArrayList(paths.get(paths.size() - 1)); + while (newPath.get(newPath.size() - 1).getId() != curCell.getId()) { + newPath.remove(newPath.size() - 1); } - lines.add(newline); - constructionLine(target, d + 1); - // 蟋狗せ縺ィ縺励※蛻昴a縺ヲ蜿ら�ァ縺輔l縺溷�エ蜷� + paths.add(newPath); + constructPaths(dstCell, depth + 1); } else { - constructionLine(target, d + 1); + constructPaths(dstCell, depth + 1); } } } } } - // cell縺ョ霍晞屬繧貞�崎ィ育ョ励☆繧� - public void reculcDist() { - // 霍晞屬縺ョ譖エ譁ー縺瑚。後o繧後↑縺上↑繧九∪縺ァ郢ー繧願ソ斐☆ + public void recalcDepths() { while (true) { - boolean isChanging = false; + boolean isUpdated = false; - // 蜷御ク�縺ョline縺ォ蜷ォ縺セ繧後k閾ェ霄ォ縺ョ1縺、謇句燕縺ョ霍晞屬縺ィ閾ェ霄ォ縺ョ霍晞屬繧呈ッ碑シ�縺励※縲∵ュ」縺励>霍晞屬繧定ィ育ョ� - for (List line : lines) { - for (int i = 1; i < line.size(); i++) { - mxCell cur = line.get(i); - mxCell pre = line.get(i - 1); - if (!(resources.contains(cur) && resources.contains(pre))) { - if (vertexToDist.get(cur).get(0) < vertexToDist.get(pre).get(1) + 1) { - List dists = vertexToDist.get(cur); - dists.set(0, Math.max(dists.get(0), vertexToDist.get(pre).get(1) + 1)); + for (List path : paths) { + for (int i = 1; i < path.size(); i++) { + mxCell curCell = path.get(i); + mxCell prevCell = path.get(i - 1); + if (!(resources.contains(curCell) && resources.contains(prevCell))) { + // An edge from a resource to a channel + if (vertexToDepths.get(curCell).get(0) < vertexToDepths.get(prevCell).get(1) + 1) { + List dists = vertexToDepths.get(curCell); dists.set(1, Math.max(dists.get(0), dists.get(1))); - isChanging = true; + dists.set(0, vertexToDepths.get(prevCell).get(1) + 1); + isUpdated = true; } } } } - // 髫主ア、讒矩��繧定��諷ョ縺励◆cell縺ョ霍晞屬繧定ィ育ョ� - for (mxCell r : roots) { - for (mxCell c : hierarchicalRecursionOrder.get(r)) { - mxCell p = (mxCell) graphModel.getParent(c); - if (!vertexToDist.containsKey(c)) { - vertexToDist.put(c, Arrays.asList(vertexToDist.get(p).get(0), vertexToDist.get(p).get(0))); + for (mxCell rootCell : roots) { + + // For all resource cells included in (under) the root resource cell. + for (mxCell cell : orderInResourceHierarchy.get(rootCell)) { + mxCell parentCell = (mxCell) graphModel.getParent(cell); + if (!vertexToDepths.containsKey(cell)) { + if (vertexToDepths.get(parentCell) != null) vertexToDepths.put(cell, Arrays.asList(vertexToDepths.get(parentCell).get(0), vertexToDepths.get(parentCell).get(0))); } else { - if (vertexToDist.get(p).get(0) > vertexToDist.get(c).get(0)) { - List dists = vertexToDist.get(c); - dists.set(0, vertexToDist.get(p).get(0)); + if (vertexToDepths.get(parentCell) != null && vertexToDepths.get(parentCell).get(0) > vertexToDepths.get(cell).get(0)) { + List dists = vertexToDepths.get(cell); dists.set(1, Math.max(dists.get(0), dists.get(1))); - isChanging = true; + dists.set(0, vertexToDepths.get(parentCell).get(0)); + isUpdated = true; } - if (vertexToDist.get(p).get(1) < vertexToDist.get(c).get(1)) { - List dists = vertexToDist.get(p); - dists.set(1, vertexToDist.get(c).get(1)); - isChanging = true; + if (vertexToDepths.get(parentCell) != null && vertexToDepths.get(parentCell).get(1) < vertexToDepths.get(cell).get(1)) { + List dists = vertexToDepths.get(parentCell); + dists.set(1, vertexToDepths.get(cell).get(1)); + isUpdated = true; } } } } - // 1蠎ヲ繧ょ、画峩縺檎┌縺�縺ィ繝ォ繝シ繝励r謚懊¢繧� - if (!isChanging) { + if (!isUpdated) { break; } } } - // line繧偵た繝シ繝医☆繧�(縺溘□縺励�∝ョ滄圀縺ォ縺ッlines蜀�縺ョ隕∫エ�縺ョ鬆�逡ェ縺ッ蜈・繧梧崛縺医★縲∝他縺ウ蜃コ縺咎��逡ェ繧剃ソ晏ュ倥@縺殪rder繧剃ス懈��) - public void sortLines() { - for (int i = 0; i < lines.size(); i++) { - List line = lines.get(i); + public void sortPaths() { + for (int i = 0; i < paths.size(); i++) { + List path = paths.get(i); - // eventChannel縺九i縺ョ蜃コ蜉帛�医′root縺ァ縺ゅk蝣エ蜷� - if (roots.contains(line.get(1))) { - for (mxCell c : line) { - addLine(c); // order縺ォline縺ョindex繧呈�シ邏阪☆繧� + if (path.size() > 1 && roots.contains(path.get(1))) { + for (mxCell c : path) { + addPath(c); } } } } - // order縺ォline縺ョindex繧呈�シ邏阪☆繧� - public void addLine(mxCell c) { - if (cellToLineIndex.get(c) != null) { - for (int i : cellToLineIndex.get(c)) { - if (!usedLineIndex.contains(i)) { + public void addPath(mxCell c) { + if (cellToPathIndex.get(c) != null) { + for (int i : cellToPathIndex.get(c)) { + if (!usedPathIndex.contains(i)) { order.add(i); } - usedLineIndex.add(i); + usedPathIndex.add(i); } } - // root縺悟ア槭☆繧詰ine縺ョindex繧呈�シ邏阪@縺溷セ後�∝ュ仙ュォ縺悟ア槭☆繧詰ine縺ョindex繧帝��谺。譬シ邏阪☆繧� for (int i = 0; i < graphModel.getChildCount(c); i++) { mxCell child = (mxCell) graphModel.getChildAt(c, i); - addLine(child); + addPath(child); } } - // cell繧帝�咲スョ縺吶k public void layout1(mxCell s) { - /* cell縺ョ蠎ァ讓吶�ッ縲…ell縺ョparent縺ョ蟾ヲ荳翫�ョ蠎ァ讓吶r蝓コ貅悶↓x縺ィy繧偵←繧後□縺代★繧峨☆縺九〒螳夂セゥ縺輔l縺ヲ縺�繧� - 繧医▲縺ヲ險育ョ励�ョ驛ス蜷井ク翫�(d=1 縺ョcell(繝ャ繧、繧「繧ヲ繝育判髱「)縺ョ蟾ヲ荳翫r蝓コ貅悶↓縺励◆蠎ァ讓吶rcellGeo縺ォ菫晏ュ倥@縺ヲ縺翫¥ */ - - Set movedSet = new HashSet<>(); // 驟咲スョ貂医∩縺ョcell繧堤ョ。逅� - Map> movedMap = new TreeMap<>(); // 驟咲スョ貂医∩縺ョcell縺ョ霍晞屬縺斐→縺ョ驟咲スョ鬆�繧堤ョ。逅� - Map distToMaxX = new HashMap<>(); // 霍晞屬縺斐→縺ョcell縺ョ蜿ウ遶ッ縺ョx蠎ァ讓吶�ョ譛�螟ァ蛟、繧堤ョ。逅� + Set movedSet = new HashSet<>(); + Map> movedMap = new TreeMap<>(); + Map distToMaxX = new HashMap<>(); double maxY = 0; int maxD = 0; putCellGeo(s, 0, 0); - // 霍晞屬縺ョ譛�螟ァ蛟、繧呈アゅa繧� for (mxCell c : cells) { - maxD = Math.max(maxD, vertexToDist.get(c).get(1)); + if (vertexToDepths.get(c) != null) maxD = Math.max(maxD, vertexToDepths.get(c).get(1)); } - // 蛻晄悄蛹� distToMaxX.put(-1, 0.0); for (int d = 0; d <= maxD; d++) { movedMap.put(d, new ArrayList<>()); @@ -339,28 +311,25 @@ } for (int i : order) { - double centerY = -1; // 驟咲スョ莠亥ョ壹�ョy蠎ァ讓�(荳ュ螟ョ) - for (mxCell cur : lines.get(i)) { - // 譌「縺ォ驟咲スョ貂医∩縺ェ繧峨せ繧ュ繝�繝� + double centerY = -1; + for (mxCell cur : paths.get(i)) { if (movedSet.contains(cur)) { continue; } - int d = vertexToDist.get(cur).get(0); // cur縺ョ霍晞屬 - double x = distToMaxX.get(d - 1) + MOVE_X; // 驟咲スョ莠亥ョ壹�ョx蠎ァ讓� - double endX = 0; // 驟咲スョ縺励◆cell縺ョ蜿ウ遶ッ縺ョx蠎ァ讓� - double endY = 0; // 驟咲スョ縺励◆cell縺ョ荳狗ォッ縺ョy蠎ァ讓� + int d = vertexToDepths.get(cur).get(0); + double x = distToMaxX.get(d - 1) + MOVE_X; + double endX = 0; + double endY = 0; - // cur縺罫oot, channel, eventChannel縺ォ螻槭☆繧議ell縺ァ縺ゅk蝣エ蜷� if (roots.contains(cur) || channels.contains(cur) || eventChannels.contains(cur)) { if (centerY == -1) { centerY = maxY + MOVE_Y + cur.getGeometry().getHeight() / 2; } - double y = centerY - cur.getGeometry().getHeight() / 2; // 驟咲スョ莠亥ョ壹�ョy蠎ァ讓� + double y = centerY - cur.getGeometry().getHeight() / 2; double ny = y; double nx = x; - // 莠亥ョ壹@縺ヲ縺�繧句コァ讓吶↓驟咲スョ縺吶k縺ィ莉悶�ョ繝ェ繧ス繝シ繧ケ蜀�驛ィ縺ォ驟咲スョ縺輔l縺ヲ縺励∪縺�蝣エ蜷医�∽ク九↓縺壹i縺� for (mxCell m : movedSet) { if (roots.contains(m) || channels.contains(m)) { if (cellOverlap(m.getGeometry().getX(), m.getGeometry().getY(), m.getGeometry().getWidth(), m.getGeometry().getHeight(), x, y, cur.getGeometry().getWidth(), cur.getGeometry().getHeight())) { @@ -369,7 +338,6 @@ } } - // 莠亥ョ壹�ョ蠎ァ讓吶↓驟咲スョ縺励※縲∝推遞ョ蜃ヲ逅�繧定。後≧ cur.getGeometry().setX(nx); cur.getGeometry().setY(ny); endX = nx + cur.getGeometry().getWidth(); @@ -378,26 +346,23 @@ addMoved(movedSet, movedMap, cur, d); graphModel.setGeometry(cur, (mxGeometry) cur.getGeometry().clone()); - // 霍晞屬縺慧縺ョ譛�螟ァ縺ョx蠎ァ讓吶′譖エ譁ー縺輔l繧句�エ蜷医�∵里縺ォ驟咲スョ貂医∩縺ョcell繧偵◎繧後↓蠢懊§縺ヲ蜿ウ縺ォ縺壹i縺� if (distToMaxX.get(d) < endX) { updateDistToMaxX(distToMaxX, movedSet, movedMap, d, maxD, endX); } - maxY = Math.max(maxY, endY); // 驟咲スョ貂医∩縺ョcell縺ョ荳ュ縺ァ縺ョ荳狗ォッ縺ョ蠎ァ讓吶�ョ譛�螟ァ + maxY = Math.max(maxY, endY); - // root縺ョ蟄仙ュォ繧偵∪縺ィ繧√※驟咲スョ縺吶k - for (mxCell c : hierarchicalRecursionOrder.get(cur)) { - d = vertexToDist.get(c).get(0); - nx = x; // 驟咲スョ莠亥ョ壹�ョx蠎ァ讓� + // For all resource cells included in (under) the root resource cell. + for (mxCell c : orderInResourceHierarchy.get(cur)) { + d = vertexToDepths.get(c).get(0); + nx = x; mxCell parent = (mxCell) graphModel.getParent(c); - // 霍晞屬縺瑚ヲェ縺ィ遲峨@縺�蝣エ蜷医�∬ヲェ縺ョx蠎ァ讓吶h繧雁ー代@螟ァ縺阪¥縺吶k - if (d == vertexToDist.get(parent).get(0)) { + if (d == vertexToDepths.get(parent).get(0)) { nx = cellGeo.get(parent).get("x") + MARGIN_WIDTH; } else { nx = distToMaxX.get(d - 1) + MOVE_X; } - // 驥阪↑縺」縺ヲ縺励∪縺�蜈�蠑溘Μ繧ス繝シ繧ケ縺悟ュ伜惠縺吶k蝣エ蜷医�∽ク九↓縺壹i縺� double brotherMaxY = MOVE_Y; for (int k = 0; k < graphModel.getChildCount(parent); k++) { mxCell child = (mxCell) graphModel.getChildAt(parent, k); @@ -405,12 +370,11 @@ continue; } - if (movedSet.contains(child) && (vertexToDist.get(child).get(0) <= d && d <= vertexToDist.get(child).get(1))) { + if (movedSet.contains(child) && (vertexToDepths.get(child).get(0) <= d && d <= vertexToDepths.get(child).get(1))) { brotherMaxY = Math.max(brotherMaxY, child.getGeometry().getY() + child.getGeometry().getHeight() + SPACE); } } - // 莠亥ョ壹�ョ蠎ァ讓吶↓驟咲スョ縺励※縲∝推遞ョ蜃ヲ逅�繧定。後≧ c.getGeometry().setX(nx - cellGeo.get(parent).get("x")); c.getGeometry().setY(brotherMaxY); graphModel.setGeometry(c, (mxGeometry) c.getGeometry().clone()); @@ -419,9 +383,8 @@ endX = cellGeo.get(c).get("x") + c.getGeometry().getWidth(); endY = cellGeo.get(c).get("y") + c.getGeometry().getHeight(); - endY = resize(parent, endX, endY); // 蟄仙ュォ縺瑚ヲェ縺ョ蜀�驛ィ縺ォ蜷ォ縺セ繧後↑縺�蝣エ蜷医�∬ヲェ縺ョ螟ァ縺阪&繧貞、画峩縺吶k + endY = resize(parent, endX, endY); - // 霍晞屬縺慧縺ョ譛�螟ァ縺ョx蠎ァ讓吶′譖エ譁ー縺輔l繧句�エ蜷医�∵里縺ォ驟咲スョ貂医∩縺ョcell繧偵◎繧後↓蠢懊§縺ヲ蜿ウ縺ォ縺壹i縺� if (distToMaxX.get(d) < endX) { updateDistToMaxX(distToMaxX, movedSet, movedMap, d, maxD, endX); } @@ -431,13 +394,11 @@ } } - // 轤ケ邱壹�ョ霎コ縺碁㍾縺ェ縺」縺ヲ縺�繧句�エ蜷医�∝承縺ォ縺壹i縺� for (mxCell c : resources) { for (mxCell cc : dotEdges.get(c)) { for (Map.Entry> entry : dotEdges.entrySet()) { mxCell u = entry.getKey(); for (mxCell v : entry.getValue()) { - // c-cc, u-v縺悟酔縺賄otEdge繧貞盾辣ァ縺励※縺�繧句�エ蜷� if ((c == u && cc == v) || (c == v && cc == u)) { continue; } @@ -460,13 +421,12 @@ } } - // eventChannel繧貞�コ蜉帛�医�ョy蠎ァ讓吶↓謠�縺医k for (int i : order) { - mxCell cur = lines.get(i).get(1); + mxCell cur = paths.get(i).get(1); List ecs = new ArrayList<>(); - for (int j : cellToLineIndex.get(cur)) { - if (!ecs.contains(lines.get(j).get(0)) && cur == lines.get(j).get(1)) { - ecs.add(lines.get(j).get(0)); + for (int j : cellToPathIndex.get(cur)) { + if (!ecs.contains(paths.get(j).get(0)) && cur == paths.get(j).get(1)) { + ecs.add(paths.get(j).get(0)); } } @@ -479,7 +439,7 @@ } for (int j : order) { - mxCell other = lines.get(j).get(0); + mxCell other = paths.get(j).get(0); if (ecs.contains(other)) { continue; } @@ -493,7 +453,6 @@ } } - // eventChannel繧馳蠎ァ讓吶↓縺、縺�縺ヲ譏�鬆�縺ォ繧ス繝シ繝医☆繧� List sortedEcs = new ArrayList<>(); Set usedEcs = new HashSet<>(); for (int i = 0; i < eventChannels.size(); i++) { @@ -512,7 +471,6 @@ usedEcs.add(minEc); } - // 繧ス繝シ繝医�ョ鬆�逡ェ縺ォ蠢懊§縺ヲ縲�驥阪↑縺」縺ヲ縺�繧菊ventChannel繧剃ク九↓縺壹i縺� for (int i = 1; i < sortedEcs.size(); i++) { mxCell cur = sortedEcs.get(i); mxCell pre = sortedEcs.get(i - 1); @@ -526,25 +484,19 @@ } } - // cell繧帝�咲スョ縺吶k - public void layout2(mxCell s) { - /* cell縺ョ蠎ァ讓吶�ッ縲…ell縺ョparent縺ョ蟾ヲ荳翫�ョ蠎ァ讓吶r蝓コ貅悶↓x縺ィy繧偵←繧後□縺代★繧峨☆縺九〒螳夂セゥ縺輔l縺ヲ縺�繧� - 繧医▲縺ヲ險育ョ励�ョ驛ス蜷井ク翫�(d=1 縺ョcell(繝ャ繧、繧「繧ヲ繝育判髱「)縺ョ蟾ヲ荳翫r蝓コ貅悶↓縺励◆蠎ァ讓吶rcellGeo縺ォ菫晏ュ倥@縺ヲ縺翫¥ */ - - Set movedSet = new HashSet<>(); // 驟咲スョ貂医∩縺ョcell繧堤ョ。逅� - Map> movedMap = new TreeMap<>(); // 驟咲スョ貂医∩縺ョcell縺ョ霍晞屬縺斐→縺ョ驟咲スョ鬆�繧堤ョ。逅� - Map distToMaxX = new HashMap<>(); // 霍晞屬縺斐→縺ョcell縺ョ蜿ウ遶ッ縺ョx蠎ァ讓吶�ョ譛�螟ァ蛟、繧堤ョ。逅� + public void layout2(mxCell s) { + Set movedSet = new HashSet<>(); + Map> movedMap = new TreeMap<>(); + Map distToMaxX = new HashMap<>(); double maxY = 0; int maxD = 0; putCellGeo(s, 0, 0); - // 霍晞屬縺ョ譛�螟ァ蛟、繧呈アゅa繧� for (mxCell c : cells) { - maxD = Math.max(maxD, vertexToDist.get(c).get(1)); + maxD = Math.max(maxD, vertexToDepths.get(c).get(1)); } - // 蛻晄悄蛹� distToMaxX.put(-1, 0.0); for (int d = 0; d <= maxD; d++) { movedMap.put(d, new ArrayList<>()); @@ -552,30 +504,27 @@ } for (int i : order) { - double centerY = -1; // 驟咲スョ莠亥ョ壹�ョy蠎ァ讓�(荳ュ螟ョ) - for (int j = 0; j < lines.get(i).size(); j++) { - mxCell cur = lines.get(i).get(j); + double centerY = -1; + for (int j = 0; j < paths.get(i).size(); j++) { + mxCell cur = paths.get(i).get(j); - // 譌「縺ォ驟咲スョ貂医∩縺ェ繧峨せ繧ュ繝�繝� if (movedSet.contains(cur)) { continue; } - int d = vertexToDist.get(cur).get(0); // cur縺ョ霍晞屬 - double x = distToMaxX.get(d - 1) + MOVE_X; // 驟咲スョ莠亥ョ壹�ョx蠎ァ讓� - double endX = 0; // 驟咲スョ縺励◆cell縺ョ蜿ウ遶ッ縺ョx蠎ァ讓� - double endY = 0; // 驟咲スョ縺励◆cell縺ョ荳狗ォッ縺ョy蠎ァ讓� + int d = vertexToDepths.get(cur).get(0); + double x = distToMaxX.get(d - 1) + MOVE_X; + double endX = 0; + double endY = 0; - // cur縺罫oots縺ィeventChannel縺ォ螻槭☆繧九→縺阪�ョcell縺ョ驟咲スョ if (roots.contains(cur) || eventChannels.contains(cur)) { if (centerY == -1) { centerY = maxY + MOVE_Y + cur.getGeometry().getHeight() / 2; } - double y = centerY - cur.getGeometry().getHeight() / 2; // 驟咲スョ莠亥ョ壹�ョy蠎ァ讓� + double y = centerY - cur.getGeometry().getHeight() / 2; double ny = y; double nx = x; - // 莠亥ョ壹�ョ蠎ァ讓吶↓驟咲スョ縺励※縲∝推遞ョ蜃ヲ逅�繧定。後≧ cur.getGeometry().setX(nx); cur.getGeometry().setY(ny); endX = nx + cur.getGeometry().getWidth(); @@ -584,26 +533,22 @@ addMoved(movedSet, movedMap, cur, d); graphModel.setGeometry(cur, (mxGeometry) cur.getGeometry().clone()); - // 霍晞屬縺慧縺ョ譛�螟ァ縺ョx蠎ァ讓吶′譖エ譁ー縺輔l繧句�エ蜷医�∵里縺ォ驟咲スョ貂医∩縺ョcell繧偵◎繧後↓蠢懊§縺ヲ蜿ウ縺ォ縺壹i縺� if (distToMaxX.get(d) < endX) { updateDistToMaxX(distToMaxX, movedSet, movedMap, d, maxD, endX); } - maxY = Math.max(maxY, endY); // 驟咲スョ貂医∩縺ョcell縺ョ荳ュ縺ァ縺ョ荳狗ォッ縺ョ蠎ァ讓吶�ョ譛�螟ァ + maxY = Math.max(maxY, endY); - // root縺ョ蟄仙ュォ繧偵∪縺ィ繧√※驟咲スョ縺吶k - for (mxCell c : hierarchicalRecursionOrder.get(cur)) { - d = vertexToDist.get(c).get(0); - nx = x; // 驟咲スョ莠亥ョ壹�ョx蠎ァ讓� + for (mxCell c : orderInResourceHierarchy.get(cur)) { + d = vertexToDepths.get(c).get(0); + nx = x; mxCell parent = (mxCell) graphModel.getParent(c); - // 霍晞屬縺瑚ヲェ縺ィ遲峨@縺�蝣エ蜷医�∬ヲェ縺ョx蠎ァ讓吶h繧雁ー代@螟ァ縺阪¥縺吶k - if (d == vertexToDist.get(parent).get(0)) { + if (d == vertexToDepths.get(parent).get(0)) { nx = cellGeo.get(parent).get("x") + MARGIN_WIDTH; } else { nx = distToMaxX.get(d - 1) + MOVE_X; } - // 驥阪↑縺」縺ヲ縺励∪縺�蜈�蠑溘Μ繧ス繝シ繧ケ縺悟ュ伜惠縺吶k蝣エ蜷医�∽ク九↓縺壹i縺� double brotherMaxY = MOVE_Y; for (int k = 0; k < graphModel.getChildCount(parent); k++) { mxCell child = (mxCell) graphModel.getChildAt(parent, k); @@ -611,12 +556,11 @@ continue; } - if (movedSet.contains(child) && (vertexToDist.get(child).get(0) <= d && d <= vertexToDist.get(child).get(1))) { + if (movedSet.contains(child) && (vertexToDepths.get(child).get(0) <= d && d <= vertexToDepths.get(child).get(1))) { brotherMaxY = Math.max(brotherMaxY, child.getGeometry().getY() + child.getGeometry().getHeight() + SPACE); } } - // 莠亥ョ壹�ョ蠎ァ讓吶↓驟咲スョ縺励※縲∝推遞ョ蜃ヲ逅�繧定。後≧ c.getGeometry().setX(nx - cellGeo.get(parent).get("x")); c.getGeometry().setY(brotherMaxY); graphModel.setGeometry(c, (mxGeometry) c.getGeometry().clone()); @@ -625,19 +569,17 @@ endX = cellGeo.get(c).get("x") + c.getGeometry().getWidth(); endY = cellGeo.get(c).get("y") + c.getGeometry().getHeight(); - endY = resize(parent, endX, endY); // 蟄仙ュォ縺瑚ヲェ縺ョ蜀�驛ィ縺ォ蜷ォ縺セ繧後↑縺�蝣エ蜷医�∬ヲェ縺ョ螟ァ縺阪&繧貞、画峩縺吶k + endY = resize(parent, endX, endY); - // 霍晞屬縺慧縺ョ譛�螟ァ縺ョx蠎ァ讓吶′譖エ譁ー縺輔l繧句�エ蜷医�∵里縺ォ驟咲スョ貂医∩縺ョcell繧偵◎繧後↓蠢懊§縺ヲ蜿ウ縺ォ縺壹i縺� if (distToMaxX.get(d) < endX) { updateDistToMaxX(distToMaxX, movedSet, movedMap, d, maxD, endX); } - maxY = Math.max(maxY, endY); // 驟咲スョ貂医∩縺ョcell縺ョ荳ュ縺ァ縺ョ荳狗ォッ縺ョ蠎ァ讓吶�ョ譛�螟ァ + maxY = Math.max(maxY, endY); } } - // cur縺慶hannel縺ォ螻槭☆繧九→縺阪�ョcell縺ョ驟咲スョ if (channels.contains(cur)) { - mxCell pre = lines.get(i).get(j - 1); + mxCell pre = paths.get(i).get(j - 1); centerY = cellGeo.get(pre).get("y") + pre.getGeometry().getHeight() / 2; double y = centerY - cur.getGeometry().getHeight() / 2; @@ -649,16 +591,14 @@ addMoved(movedSet, movedMap, cur, d); graphModel.setGeometry(cur, (mxGeometry) cur.getGeometry().clone()); - // 霍晞屬縺慧縺ョ譛�螟ァ縺ョx蠎ァ讓吶′譖エ譁ー縺輔l繧句�エ蜷医�∵里縺ォ驟咲スョ貂医∩縺ョcell繧偵◎繧後↓蠢懊§縺ヲ蜿ウ縺ォ縺壹i縺� if (distToMaxX.get(d) < endX) { updateDistToMaxX(distToMaxX, movedSet, movedMap, d, maxD, endX); } - maxY = Math.max(maxY, endY); // 驟咲スョ貂医∩縺ョcell縺ョ荳ュ縺ァ縺ョ荳狗ォッ縺ョ蠎ァ讓吶�ョ譛�螟ァ + maxY = Math.max(maxY, endY); } } } - // 轤ケ邱壹�ョ霎コ縺碁㍾縺ェ縺」縺ヲ縺�繧句�エ蜷医�∝承縺ォ縺壹i縺� for (mxCell c : resources) { for (mxCell cc : dotEdges.get(c)) { for (Map.Entry> entry : dotEdges.entrySet()) { @@ -686,13 +626,12 @@ } } - // eventChannel繧貞�コ蜉帛�医�ョy蠎ァ讓吶↓謠�縺医k for (int i : order) { - mxCell cur = lines.get(i).get(1); + mxCell cur = paths.get(i).get(1); List ecs = new ArrayList<>(); - for (int j : cellToLineIndex.get(cur)) { - if (!ecs.contains(lines.get(j).get(0)) && cur == lines.get(j).get(1)) { - ecs.add(lines.get(j).get(0)); + for (int j : cellToPathIndex.get(cur)) { + if (!ecs.contains(paths.get(j).get(0)) && cur == paths.get(j).get(1)) { + ecs.add(paths.get(j).get(0)); } } @@ -705,7 +644,7 @@ } for (int j : order) { - mxCell other = lines.get(j).get(0); + mxCell other = paths.get(j).get(0); if (ecs.contains(other)) { continue; } @@ -719,7 +658,6 @@ } } - // eventChannel繧馳蠎ァ讓吶↓縺、縺�縺ヲ譏�鬆�縺ォ繧ス繝シ繝医☆繧� List sortedEcs = new ArrayList<>(); Set usedEcs = new HashSet<>(); for (int i = 0; i < eventChannels.size(); i++) { @@ -738,7 +676,6 @@ usedEcs.add(minEc); } - // 繧ス繝シ繝医�ョ鬆�逡ェ縺ォ蠢懊§縺ヲ縲�驥阪↑縺」縺ヲ縺�繧菊ventChannel繧剃ク九↓縺壹i縺� for (int i = 1; i < sortedEcs.size(); i++) { mxCell cur = sortedEcs.get(i); mxCell pre = sortedEcs.get(i - 1); @@ -752,20 +689,17 @@ } } - // cell縺ョ蠎ァ讓吶r逋サ骭イ public void putCellGeo(mxCell c, double x, double y) { cellGeo.put(c, new HashMap<>()); cellGeo.get(c).put("x", x); cellGeo.get(c).put("y", y); } - // movedSet, movedMap縺ォ驟咲スョ貂医∩縺ョcell繧定ソス蜉� public void addMoved(Set ms, Map> mm, mxCell c, int d) { ms.add(c); mm.get(d).add(c); } - // 2縺、縺ョ霎コ縺碁㍾縺ェ縺」縺ヲ縺�繧九°蛻、螳� public boolean isStraightLine(double []u1, double []v1, double []u2, double []v2) { double gradient1 = 0; double length1 = Math.pow(u1[0] - v1[0], 2) + Math.pow(u1[1] - v1[1], 2); @@ -826,7 +760,6 @@ } } - // 2縺、縺ョcell縺碁㍾縺ェ縺」縺ヲ縺�繧九°蛻、螳� public boolean cellOverlap(double ax, double ay, double aw, double ah, double bx, double by, double bw, double bh) { if (((ax <= bx) && (bx <= ax + aw)) || ((bx <= ax) && (ax <= bx + bw))) { if (((ay <= by) && (by <= ay + ah)) || ((by <= ay) && (ay <= by + bh))) { @@ -836,7 +769,6 @@ return false; } - // 豺ア縺輔′d縺ョdistToMaxX縺ォ譖エ譁ー縺悟�・繧九→縲∵キア縺輔′d繧医j螟ァ縺阪>驟咲スョ貂医∩縺ョcell繧貞承縺ォ縺壹i縺� public void updateDistToMaxX(Map distToMaxX, Set movedSet, Map> movedMap, int d, int md, double endX) { double preEndX = distToMaxX.get(d); distToMaxX.replace(d, endX); @@ -872,7 +804,6 @@ } } - // 蟄舌r隕�縺�繧医≧縺ォ隕ェ縺ョ螟ァ縺阪&繧貞、画峩 public double resize(mxCell ancestor, double endX, double endY) { while (true) { boolean isChanging = false; @@ -901,7 +832,6 @@ return endY; } - // x蠎ァ讓吶r螟画峩 public void relocateX(mxCell c, double nx, double dx) { c.getGeometry().setX(nx - dx); graphModel.setGeometry(c, (mxGeometry) c.getGeometry().clone()); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java index 7528793..869aaec 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java @@ -51,12 +51,12 @@ // root resource Resource resource = new Resource(res); curState.addResource(resource); - Expression initilValue = res.getInitialValue(); - if (initilValue != null) { - if (initilValue instanceof Term) { - initilValue = ((Term) initilValue).reduce(); + Expression initialValue = res.getInitialValue(); + if (initialValue != null) { + if (initialValue instanceof Term) { + initialValue = ((Term) initialValue).reduce(); } - curState.updateResourceState(resource.getResourceIdentifier(), initilValue); + curState.updateResourceState(resource.getResourceIdentifier(), null, null, initialValue); } } } @@ -145,9 +145,12 @@ */ private void fireEvent(final Event event, final SystemState curSystemState, final SystemState nextSystemState) throws ParameterizedIdentifierIsFutureWork, ResolvingMultipleDefinitionIsFutureWork, InvalidMessage, UnificationFailed, ValueUndefined { + final ChannelMember[] outTarget = new ChannelMember[1]; + final Variable[] outResVar = new Variable[1]; IResourceStateAccessor resouceStateAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + if (target == outTarget[0]) return outResVar[0]; // the current state of each output resource is not to be replaced with its value. ResourceIdentifier resId = event.getResourceIdentifier(target.getResource()); Resource res = curSystemState.getResource(resId); if (res == null) return null; @@ -176,7 +179,9 @@ // For each output resource, calculate the next state. for (ChannelMember out: channel.getOutputChannelMembers()) { // Calculate the next state expression. - Expression nextResState = null; + Expression nextResState = null; + outTarget[0] = out; + outResVar[0] = new Variable(channel.getChannelName() + "$" + out.getResource().toString() + "$this"); // A special variable to represent the current state of each output resource. if (!event.isInput()) { nextResState = channel.deriveUpdateExpressionOf(out, resouceStateAccessor).getKey(); } else { @@ -189,18 +194,25 @@ nextResState = ((Term) nextResState).substitute((Variable) selExp, selestorAndVal.getValue()); } } - if (nextResState instanceof Term) { - nextResState = ((Term) nextResState).reduce(); - } // Update the resource state. ResourceIdentifier outResId = event.getOutputResourceIdentifier(out.getResource()); - ResourceIdentifier updatedOutResId = nextSystemState.updateResourceState(outResId, nextResState); - while (updatedOutResId != null) { // In addition to the target state, its descendants' states are also changed. - for (Event nextEvent: getNextEvents(updatedOutResId, curSystemState, nextSystemState)) { - fireEvent(nextEvent, curSystemState, nextSystemState); + Expression curResState = null; + if (curSystemState.getResource(outResId) != null) { + curResState = curSystemState.getResource(outResId).getState().getValue(); + } + List updatedOutResIds = nextSystemState.updateResourceState(outResId, outResVar[0], curResState, nextResState); + if (updatedOutResIds != null) { + Set ancestors = new HashSet<>(); + for (ResourceIdentifier updatedOutResId: updatedOutResIds) { + while (updatedOutResId != null && !ancestors.contains(updatedOutResId)) { // In addition to the target state, its ancestors' states are also changed. + ancestors.add(updatedOutResId); + for (Event nextEvent: getNextEvents(updatedOutResId, curSystemState, nextSystemState)) { + fireEvent(nextEvent, curSystemState, nextSystemState); + } + if (channel.isNative()) break; // To avoid multiple updates of the same resource. + updatedOutResId = (ResourceIdentifier) updatedOutResId.getParent(); + } } - if (channel.isNative()) break; // To avoid multiple updates of the same resource. - updatedOutResId = (ResourceIdentifier) updatedOutResId.getParent(); } } } else if (channel.isNative()) { @@ -342,9 +354,13 @@ for (int i = 0; i < resPath.getPathParamsAndConstraints().size(); i++) { Expression val = resId.getPathParamsAndConstraints().get(i).getKey(); Expression constraint = resPath.getPathParamsAndConstraints().get(i).getValue(); - if (constraint != null && !constraint.equals(val)) { - // The value of the path parameter does not satisfy the constraint defined for the parameter. - return false; // Not to fire this event. + if (constraint != null) { + String valStr = val.toString(); + String constStr = constraint.toString().replace("\"", ""); + if (!constStr.equals(valStr)) { + // The value of the path parameter does not satisfy the constraint defined for the parameter. + return false; // Not to fire this event. + } } } return true; diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java index 98f752e..a1a0806 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java @@ -75,43 +75,93 @@ * update the state of a specified resource * * @param resourceIdentifier a resource identifier to identify the resource - * @param resStateValue a new state of the resource - * @return + * @param curResVar a variable to represent the current state of the resource (may be replaced with resCurStateVal) + * @param resCurStateVal the value of the current state of the resource + * @param resNextStateVal the value of the new state of the resource (may contain curResVar) + * @return the identifier of the deepest resource created by this update. */ - public ResourceIdentifier updateResourceState(ResourceIdentifier resourceIdentifier, Expression resStateValue) { + public List updateResourceState(ResourceIdentifier resourceIdentifier, Variable curResVar, Expression resCurStateVal, Expression resNextStateVal) { Type resType = resourceIdentifier.getResourceStateType(); + if (resNextStateVal instanceof Term) { + Term termValue = (Term) resNextStateVal; + if (termValue.getSymbol().equals(DataConstraintModel.cond)) { + // If resNextStateVal is a conditional term, then calculates it here. + Expression condExp = termValue.getChild(0); + if (condExp instanceof Term) { + condExp = ((Term) condExp).substitute(curResVar, resCurStateVal); + condExp = ((Term) condExp).reduce(); + } + List condArgs = new ArrayList<>(); + condArgs.add(condExp); + condArgs.add(termValue.getChild(1)); + condArgs.add(termValue.getChild(2)); + resNextStateVal = DataConstraintModel.cond.calculate(condArgs); + if (resNextStateVal != null) { + return updateResourceState(resourceIdentifier, curResVar, resCurStateVal, resNextStateVal); + } + return null; + } + } if (resType != null && DataConstraintModel.typeList.isAncestorOf(resType)) { - if (resStateValue instanceof Constant) { - } else if (resStateValue instanceof ListTerm) { - ListTerm listValue = (ListTerm) resStateValue; + if (resNextStateVal instanceof Constant) { + } else if (resNextStateVal instanceof ListTerm) { + ListTerm listValue = (ListTerm) resNextStateVal; Resource res = getResource(resourceIdentifier); ResourceState state = res.getState(); - ResourceIdentifier createdResource = null; - for (int i = 0; i < listValue.size(); i++) { - Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); - ResourceHierarchy childResourceHierarchy = null; - if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { - childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); - } else { - Type childResType = null; - if (listValue.get(i) instanceof Variable) { - childResType = ((Variable) listValue.get(i)).getType(); - } else if (listValue.get(i) instanceof Term) { - childResType = ((Term) listValue.get(i)).getType(); + if (state instanceof ListResourceState) { + List createdResources = new ArrayList<>(); + ((ListResourceState) state).clearChildStates(); + for (int i = 0; i < listValue.size(); i++) { + Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (listValue.get(i) instanceof Variable) { + childResType = ((Variable) listValue.get(i)).getType(); + } else if (listValue.get(i) instanceof Term) { + childResType = ((Term) listValue.get(i)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.get(i)); + ((ListResourceState) state).addChildState(childInfo.getKey()); + createdResources.addAll(childInfo.getValue()); } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.get(i)); - ((ListResourceState) state).addChildState(childInfo.getKey()); - createdResource = childInfo.getValue(); + return createdResources; } - return createdResource; - } else if (resStateValue instanceof Term) { - Term listValue = (Term) resStateValue; + return null; + } else if (resNextStateVal instanceof Term) { + Term listValue = (Term) resNextStateVal; if (listValue.getSymbol().equals(DataConstraintModel.append)) { + List createdResources = new ArrayList<>(); Resource res = getResource(resourceIdentifier); ResourceState state = res.getState(); + if (listValue.getChild(0) instanceof Term) { + if (listValue.getChild(0) instanceof Constant && ((Constant) listValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) { + // If the child list is nil. + ResourceState parentState = res.getParent().getState(); + ResourceState newState = new ListResourceState(); + if (parentState instanceof CompositeResourceState) { + ((CompositeResourceState) parentState).replaceChildState(state, newState); + } + state = newState; + res.changeState(state); + } else { + Expression childList = ((Term) listValue.getChild(0)).reduce(); + if (childList instanceof ListTerm) { + // If the child list is a list literal. + List childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, childList); // one more recursion. + if (childInfo != null) createdResources.addAll(childInfo); + } else if (childList instanceof Term) { + // There may or may not be the current state of the resource (curResVar) under the child. + List childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, listValue.getChild(0)); + createdResources.addAll(childInfo); + } + } + } Expression childExp = null; if (state instanceof ListResourceState) { childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size()), DataConstraintModel.typeInt); @@ -139,18 +189,48 @@ childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.getChild(1)); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.getChild(1)); ((ListResourceState) state).addChildState(childInfo.getKey()); - return childInfo.getValue(); + createdResources.addAll(childInfo.getValue()); + return createdResources; } } } else if (resType != null && DataConstraintModel.typeMap.isAncestorOf(resType)) { - if (resStateValue instanceof Constant) { - } else if (resStateValue instanceof JsonTerm) { - JsonTerm mapValue = (JsonTerm) resStateValue; + if (resNextStateVal instanceof Constant) { + } else if (resNextStateVal instanceof JsonTerm) { + JsonTerm mapValue = (JsonTerm) resNextStateVal; Resource res = getResource(resourceIdentifier); ResourceState state = res.getState(); - ResourceIdentifier createdResource = null; + if (state instanceof MapResourceState) { + List createdResources = new ArrayList<>(); + ((MapResourceState) state).clearChildStates(); + for (String key: mapValue.keySet()) { + Expression childExp = new Constant(key, DataConstraintModel.typeString); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.get(key) instanceof Variable) { + childResType = ((Variable) mapValue.get(key)).getType(); + } else if (mapValue.get(key) instanceof Term) { + childResType = ((Term) mapValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.get(key)); + ((MapResourceState) state).addChildState(key, childInfo.getKey()); + createdResources.addAll(childInfo.getValue()); + } + return createdResources; + } + return null; + } else if (resNextStateVal instanceof MapTerm) { + MapTerm mapValue = (MapTerm) resNextStateVal; + Resource res = getResource(resourceIdentifier); + ResourceState state = res.getState(); + List createdResources = new ArrayList<>(); for (String key: mapValue.keySet()) { Expression childExp = new Constant(key, DataConstraintModel.typeString); ResourceHierarchy childResourceHierarchy = null; @@ -166,43 +246,46 @@ childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.get(key)); ((MapResourceState) state).addChildState(key, childInfo.getKey()); - createdResource = childInfo.getValue(); + createdResources.addAll(childInfo.getValue()); } - return createdResource; - } else if (resStateValue instanceof MapTerm) { - MapTerm mapValue = (MapTerm) resStateValue; - Resource res = getResource(resourceIdentifier); - ResourceState state = res.getState(); - ResourceIdentifier createdResource = null; - for (String key: mapValue.keySet()) { - Expression childExp = new Constant(key, DataConstraintModel.typeString); - ResourceHierarchy childResourceHierarchy = null; - if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { - childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); - } else { - Type childResType = null; - if (mapValue.get(key) instanceof Variable) { - childResType = ((Variable) mapValue.get(key)).getType(); - } else if (mapValue.get(key) instanceof Term) { - childResType = ((Term) mapValue.get(key)).getType(); - } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); - } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); - ((MapResourceState) state).addChildState(key, childInfo.getKey()); - createdResource = childInfo.getValue(); - } - return createdResource; - } else if (resStateValue instanceof Term) { - Term mapValue = (Term) resStateValue; + return createdResources; + } else if (resNextStateVal instanceof Term) { + Term mapValue = (Term) resNextStateVal; if (mapValue.getSymbol().equals(DataConstraintModel.insert)) { - Expression childExp = mapValue.getChild(1); - if (childExp instanceof Constant) { + List createdResources = new ArrayList<>(); + Expression childKeyExp = mapValue.getChild(1); + if (childKeyExp instanceof Term) { + childKeyExp = ((Term) childKeyExp).substitute(curResVar, resCurStateVal); + childKeyExp = ((Term) childKeyExp).reduce(); + } + if (childKeyExp instanceof Constant) { Resource res = getResource(resourceIdentifier); ResourceState state = res.getState(); + if (mapValue.getChild(0) instanceof Term) { + if (mapValue.getChild(0) instanceof Constant && ((Constant) mapValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) { + // If the child map is nil. + ResourceState parentState = res.getParent().getState(); + ResourceState newState = new MapResourceState(); + if (parentState instanceof CompositeResourceState) { + ((CompositeResourceState) parentState).replaceChildState(state, newState); + } + state = newState; + res.changeState(state); + } else { + Expression childMap = ((Term) mapValue.getChild(0)).reduce(); + if (childMap instanceof MapTerm) { + // If the child map is a map literal. + List childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, childMap); // one more recursion + createdResources.addAll(childInfo); + } else if (childMap instanceof Term) { + // There may or may not be the current state of the resource (curResVar) under the child. + List childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(0)); + createdResources.addAll(childInfo); + } + } + } if (state instanceof PrimitiveResourceState && ((PrimitiveResourceState) state).getValue().getSymbol().equals(DataConstraintModel.nil)) { // If the value of state is nil. ResourceState parentState = res.getParent().getState(); @@ -225,248 +308,23 @@ } childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - String childId = ((Constant) childExp).toString(); - Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.getChild(2)); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childKeyExp, childResourceHierarchy); + String childId = ((Constant) childKeyExp).toString(); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(2)); ((MapResourceState) state).addChildState(childId, childInfo.getKey()); - return childInfo.getValue(); + createdResources.addAll(childInfo.getValue()); + return createdResources; } } } } else if (resType != null && DataConstraintModel.typeJson.isAncestorOf(resType)) { - if (resStateValue instanceof Constant) { - } else if (resStateValue instanceof JsonTerm) { - JsonTerm jsonValue = (JsonTerm) resStateValue; + if (resNextStateVal instanceof Constant) { + } else if (resNextStateVal instanceof JsonTerm) { + JsonTerm jsonValue = (JsonTerm) resNextStateVal; Resource res = getResource(resourceIdentifier); ResourceState state = res.getState(); - ResourceIdentifier createdResource = null; - for (String key: jsonValue.keySet()) { - String memberName = key.replace("\"", ""); - ResourceHierarchy childResourceHierarchy = null; - for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) { - if (childRes.getResourceName().equals(memberName)) { - childResourceHierarchy = childRes; - break; - } - } - if (childResourceHierarchy == null) { - Type childResType = null; - if (jsonValue.get(key) instanceof Variable) { - childResType = ((Variable) jsonValue.get(key)).getType(); - } else if (jsonValue.get(key) instanceof Term) { - childResType = ((Term) jsonValue.get(key)).getType(); - } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); - } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, jsonValue.get(key)); - ResourceState childState = childInfo.getKey(); - if (res.getChildrenMap() != null && res.getChildrenMap().get(memberName) != null) { - res.getChildrenMap().get(memberName).changeState(childState); - } - ((JsonResourceState) state).addChildState(memberName, childState); - createdResource = childInfo.getValue(); - } - return createdResource; - } else if (resStateValue instanceof Term) { - Term jsonValue = (Term) resStateValue; - Resource res = getResource(resourceIdentifier); - ResourceState state = res.getState(); - ResourceIdentifier createdResource = null; - while (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) { - Expression childExp = jsonValue.getChild(1); - if (childExp instanceof Constant) { - String memberName = ((Constant) childExp).getSymbol().getName().replace("\"", ""); - ResourceHierarchy childResourceHierarchy = null; - for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) { - if (childRes.getResourceName().equals(memberName)) { - childResourceHierarchy = childRes; - break; - } - } - if (childResourceHierarchy == null) { - Type childResType = null; - if (jsonValue.getChild(2) instanceof Variable) { - childResType = ((Variable) jsonValue.getChild(2)).getType(); - } else if (jsonValue.getChild(2) instanceof Term) { - childResType = ((Term) jsonValue.getChild(2)).getType(); - } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); - } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); - String childId = ((Constant) childExp).toString(); - Map.Entry childInfo = createResourceState(childResourceIdentifier, jsonValue.getChild(2)); - ((JsonResourceState) state).addChildState(childId, childInfo.getKey()); - createdResource = childInfo.getValue(); - } - if (!(jsonValue.getChild(0) instanceof Term)) break; - jsonValue = (Term) jsonValue.getChild(0); - } - return createdResource; - } - } else { - if (resStateValue instanceof Constant) { - Resource res = getResource(resourceIdentifier); - ResourceState state = null; - if (res != null) { - state = res.getState(); - ((PrimitiveResourceState) state).setValue((Constant) resStateValue); - } else { - ResourceIdentifier parentResId = (ResourceIdentifier) resourceIdentifier.getParent(); - Type parentResType = parentResId.getResourceStateType(); - if (parentResType != null && DataConstraintModel.typeList.isAncestorOf(parentResType)) { - } else if (parentResType != null && DataConstraintModel.typeMap.isAncestorOf(parentResType)) { - JsonResourceState parentState = (JsonResourceState) getResource(parentResId).getState(); - parentState.addChildState(((Constant) resourceIdentifier.getLastParam()).toString(), new PrimitiveResourceState((Constant) resStateValue)); - } else if (parentResType != null && DataConstraintModel.typeJson.isAncestorOf(parentResType)) { - JsonResourceState parentState = (JsonResourceState) getResource(parentResId).getState(); - parentState.addChildState("\"" + resourceIdentifier.getLeafResourceName() + "\"", new PrimitiveResourceState((Constant) resStateValue)); - } - } - return resourceIdentifier; - } - } - return resourceIdentifier; - } - - public Map.Entry createResourceState(ResourceIdentifier resourceIdentifier, Expression resStateValue) { - Type resType = resourceIdentifier.getResourceStateType(); - if (resType == null && resStateValue instanceof Term) { - resType = ((Term) resStateValue).getType(); - resStateValue = ((Term) resStateValue).reduce(); - } - if (resType != null) { - if (DataConstraintModel.typeList.isAncestorOf(resType)) { - if (resStateValue instanceof Constant) { - } else if (resStateValue instanceof ListTerm) { - ListTerm listValue = (ListTerm) resStateValue; - ListResourceState state = new ListResourceState(); - Map.Entry createInfo = null; - for (int i = 0; i < listValue.size(); i++) { - Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); - ResourceHierarchy childResourceHierarchy = null; - if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { - childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); - } else { - Type childResType = null; - if (listValue.get(i) instanceof Variable) { - childResType = ((Variable) listValue.get(i)).getType(); - } else if (listValue.get(i) instanceof Term) { - childResType = ((Term) listValue.get(i)).getType(); - } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); - } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.get(i)); - state.addChildState(childInfo.getKey()); - createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); - } - return createInfo; - } else if (resStateValue instanceof Term) { - Term listValue = (Term) resStateValue; - if (listValue.getSymbol().equals(DataConstraintModel.append)) { - ListResourceState state = new ListResourceState(); - Expression childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size()), DataConstraintModel.typeInt); - ResourceHierarchy childResourceHierarchy = null; - if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { - childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); - } else { - Type childResType = null; - if (listValue.getChild(1) instanceof Variable) { - childResType = ((Variable) listValue.getChild(1)).getType(); - } else if (listValue.getChild(1) instanceof Term) { - childResType = ((Term) listValue.getChild(1)).getType(); - } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); - } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.getChild(1)); - state.addChildState(childInfo.getKey()); - return new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); - } - } - } else if (DataConstraintModel.typeMap.isAncestorOf(resType)) { - if (resStateValue instanceof Constant) { - } else if (resStateValue instanceof JsonTerm) { - JsonTerm mapValue = (JsonTerm) resStateValue; - MapResourceState state = new MapResourceState(); - Map.Entry createInfo = null; - for (String key: mapValue.keySet()) { - Expression childExp = new Constant(key, DataConstraintModel.typeString); - ResourceHierarchy childResourceHierarchy = null; - if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { - childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); - } else { - Type childResType = null; - if (mapValue.get(key) instanceof Variable) { - childResType = ((Variable) mapValue.get(key)).getType(); - } else if (mapValue.get(key) instanceof Term) { - childResType = ((Term) mapValue.get(key)).getType(); - } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); - } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); - state.addChildState(key, childInfo.getKey()); - createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); - } - return createInfo; - } else if (resStateValue instanceof MapTerm) { - MapTerm mapValue = (MapTerm) resStateValue; - MapResourceState state = new MapResourceState(); - Map.Entry createInfo = null; - for (String key: mapValue.keySet()) { - Expression childExp = new Constant(key, DataConstraintModel.typeString); - ResourceHierarchy childResourceHierarchy = null; - if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { - childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); - } else { - Type childResType = null; - if (mapValue.get(key) instanceof Variable) { - childResType = ((Variable) mapValue.get(key)).getType(); - } else if (mapValue.get(key) instanceof Term) { - childResType = ((Term) mapValue.get(key)).getType(); - } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); - } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); - state.addChildState(key, childInfo.getKey()); - createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); - } - return createInfo; - } else if (resStateValue instanceof Term) { - Term mapValue = (Term) resStateValue; - if (mapValue.getSymbol().equals(DataConstraintModel.insert)) { - Expression childExp = mapValue.getChild(1); - if (childExp instanceof Constant) { - MapResourceState state = new MapResourceState(); - ResourceHierarchy childResourceHierarchy = null; - if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { - childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); - } else { - Type childResType = null; - if (mapValue.getChild(2) instanceof Variable) { - childResType = ((Variable) mapValue.getChild(2)).getType(); - } else if (mapValue.getChild(2) instanceof Term) { - childResType = ((Term) mapValue.getChild(2)).getType(); - } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); - } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - String childId = ((Constant) childExp).toString(); - Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.getChild(2)); - state.addChildState(childId, childInfo.getKey()); - return new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); - } - } - } - } else if (DataConstraintModel.typeJson.isAncestorOf(resType)) { - if (resStateValue instanceof Constant) { - } else if (resStateValue instanceof JsonTerm) { - JsonTerm jsonValue = (JsonTerm) resStateValue; - JsonResourceState state = new JsonResourceState(); - Map.Entry createInfo = null; + if (state instanceof JsonResourceState) { + List createdResources = new ArrayList<>(); for (String key: jsonValue.keySet()) { String memberName = key.replace("\"", ""); ResourceHierarchy childResourceHierarchy = null; @@ -486,20 +344,305 @@ childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); - Map.Entry childInfo = createResourceState(childResourceIdentifier, jsonValue.get(key)); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.get(key)); + ResourceState childState = childInfo.getKey(); + if (res.getChildrenMap() != null && res.getChildrenMap().get(memberName) != null) { + res.getChildrenMap().get(memberName).changeState(childState); + } + ((JsonResourceState) state).addChildState(memberName, childState); + createdResources.addAll(childInfo.getValue()); + } + return createdResources; + } + return null; + } else if (resNextStateVal instanceof Term) { + Term jsonValue = (Term) resNextStateVal; + Resource res = getResource(resourceIdentifier); + ResourceState state = res.getState(); + List createdResources = new ArrayList<>(); + while (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) { + Expression childKeyExp = jsonValue.getChild(1); + if (childKeyExp instanceof Constant) { + String memberName = ((Constant) childKeyExp).getSymbol().getName().replace("\"", ""); + ResourceHierarchy childResourceHierarchy = null; + for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) { + if (childRes.getResourceName().equals(memberName)) { + childResourceHierarchy = childRes; + break; + } + } + if (childResourceHierarchy == null) { + Type childResType = null; + if (jsonValue.getChild(2) instanceof Variable) { + childResType = ((Variable) jsonValue.getChild(2)).getType(); + } else if (jsonValue.getChild(2) instanceof Term) { + childResType = ((Term) jsonValue.getChild(2)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); + String childId = ((Constant) childKeyExp).toString(); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.getChild(2)); + ((JsonResourceState) state).addChildState(childId, childInfo.getKey()); + createdResources.addAll(childInfo.getValue()); + } + if (!(jsonValue.getChild(0) instanceof Term)) break; + jsonValue = (Term) jsonValue.getChild(0); + } + return createdResources; + } + } else { + if (curResVar != null && resCurStateVal != null) { + if (resNextStateVal instanceof Term) { + resNextStateVal = ((Term) resNextStateVal).substitute(curResVar, resCurStateVal); + resNextStateVal = ((Term) resNextStateVal).reduce(); + } + } + if (resNextStateVal instanceof Constant) { + Resource res = getResource(resourceIdentifier); + ResourceState state = null; + if (res != null) { + state = res.getState(); + ((PrimitiveResourceState) state).setValue((Constant) resNextStateVal); + } else { + ResourceIdentifier parentResId = (ResourceIdentifier) resourceIdentifier.getParent(); + Type parentResType = parentResId.getResourceStateType(); + if (parentResType != null && DataConstraintModel.typeList.isAncestorOf(parentResType)) { + } else if (parentResType != null && DataConstraintModel.typeMap.isAncestorOf(parentResType)) { + JsonResourceState parentState = (JsonResourceState) getResource(parentResId).getState(); + parentState.addChildState(((Constant) resourceIdentifier.getLastParam()).toString(), new PrimitiveResourceState((Constant) resNextStateVal)); + } else if (parentResType != null && DataConstraintModel.typeJson.isAncestorOf(parentResType)) { + JsonResourceState parentState = (JsonResourceState) getResource(parentResId).getState(); + parentState.addChildState("\"" + resourceIdentifier.getLeafResourceName() + "\"", new PrimitiveResourceState((Constant) resNextStateVal)); + } + } + List updatedResources = new ArrayList<>(); + updatedResources.add(resourceIdentifier); + return updatedResources; + } + } + return null; + } + + public Map.Entry> createResourceState(ResourceIdentifier resourceIdentifier, Variable curResVar, Expression resCurStateVal, Expression resStateValue) { + Type resType = resourceIdentifier.getResourceStateType(); + if (resType == null && resStateValue instanceof Term) { + resType = ((Term) resStateValue).getType(); + resStateValue = ((Term) resStateValue).reduce(); + } + if (resType != null) { + if (DataConstraintModel.typeList.isAncestorOf(resType)) { + if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof ListTerm) { + ListTerm listValue = (ListTerm) resStateValue; + ListResourceState state = new ListResourceState(); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); + for (int i = 0; i < listValue.size(); i++) { + Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (listValue.get(i) instanceof Variable) { + childResType = ((Variable) listValue.get(i)).getType(); + } else if (listValue.get(i) instanceof Term) { + childResType = ((Term) listValue.get(i)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.get(i)); + state.addChildState(childInfo.getKey()); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); + } + return createInfo; + } else if (resStateValue instanceof Term) { + Term listValue = (Term) resStateValue; + if (listValue.getSymbol().equals(DataConstraintModel.append)) { + List createdResources = new ArrayList<>(); + ListResourceState state = new ListResourceState(); + if (listValue.getChild(0) instanceof Term) { + if (listValue.getChild(0) instanceof Constant && ((Constant) listValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) { + // If the child list is nil. + } else { + Expression childList = ((Term) listValue.getChild(0)); + childList = ((Term) childList).substitute(curResVar, resStateValue); + childList = ((Term) childList).reduce(); + if (childList instanceof ListTerm) { + // If the child list is a list literal. + Map.Entry> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, childList); // one more recursion. + state = (ListResourceState) childInfo.getKey(); + if (childInfo != null) createdResources.addAll(childInfo.getValue()); + } else if (childList instanceof Term) { + // If the child list is a list term. + Map.Entry> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, listValue.getChild(0)); + state = (ListResourceState) childInfo.getKey(); + createdResources.addAll(childInfo.getValue()); + } + } + } + Expression childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size()), DataConstraintModel.typeInt); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (listValue.getChild(1) instanceof Variable) { + childResType = ((Variable) listValue.getChild(1)).getType(); + } else if (listValue.getChild(1) instanceof Term) { + childResType = ((Term) listValue.getChild(1)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.getChild(1)); + state.addChildState(childInfo.getKey()); + createdResources.addAll(childInfo.getValue()); + return new AbstractMap.SimpleEntry<>(state, createdResources); + } + } + } else if (DataConstraintModel.typeMap.isAncestorOf(resType)) { + if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof JsonTerm) { + JsonTerm mapValue = (JsonTerm) resStateValue; + MapResourceState state = new MapResourceState(); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); + for (String key: mapValue.keySet()) { + Expression childExp = new Constant(key, DataConstraintModel.typeString); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.get(key) instanceof Variable) { + childResType = ((Variable) mapValue.get(key)).getType(); + } else if (mapValue.get(key) instanceof Term) { + childResType = ((Term) mapValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.get(key)); + state.addChildState(key, childInfo.getKey()); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); + } + return createInfo; + } else if (resStateValue instanceof MapTerm) { + MapTerm mapValue = (MapTerm) resStateValue; + MapResourceState state = new MapResourceState(); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); + for (String key: mapValue.keySet()) { + Expression childExp = new Constant(key, DataConstraintModel.typeString); + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.get(key) instanceof Variable) { + childResType = ((Variable) mapValue.get(key)).getType(); + } else if (mapValue.get(key) instanceof Term) { + childResType = ((Term) mapValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.get(key)); + state.addChildState(key, childInfo.getKey()); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); + } + return createInfo; + } else if (resStateValue instanceof Term) { + Term mapValue = (Term) resStateValue; + if (mapValue.getSymbol().equals(DataConstraintModel.insert)) { + Expression childExp = mapValue.getChild(1); + if (childExp instanceof Constant) { + List createdResources = new ArrayList<>(); + MapResourceState state = new MapResourceState(); + if (mapValue.getChild(0) instanceof Term) { + if (mapValue.getChild(0) instanceof Constant && ((Constant) mapValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) { + // If the child list is nil. + } else { + Expression childMap = ((Term) mapValue.getChild(0)); + childMap = ((Term) childMap).substitute(curResVar, resStateValue); + childMap = ((Term) childMap).reduce(); + if (childMap instanceof MapTerm) { + // If the child map is a map literal. + Map.Entry> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, childMap); // one more recursion. + state = (MapResourceState) childInfo.getKey(); + if (childInfo != null) createdResources.addAll(childInfo.getValue()); + } else if (childMap instanceof Term) { + // If the child map is a map term. + Map.Entry> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(0)); + state = (MapResourceState) childInfo.getKey(); + createdResources.addAll(childInfo.getValue()); + } + } + } + ResourceHierarchy childResourceHierarchy = null; + if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) { + childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next(); + } else { + Type childResType = null; + if (mapValue.getChild(2) instanceof Variable) { + childResType = ((Variable) mapValue.getChild(2)).getType(); + } else if (mapValue.getChild(2) instanceof Term) { + childResType = ((Term) mapValue.getChild(2)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + String childId = ((Constant) childExp).toString(); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(2)); + state.addChildState(childId, childInfo.getKey()); + createdResources.addAll(childInfo.getValue()); + return new AbstractMap.SimpleEntry<>(state, createdResources); + } + } + } + } else if (DataConstraintModel.typeJson.isAncestorOf(resType)) { + if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof JsonTerm) { + JsonTerm jsonValue = (JsonTerm) resStateValue; + JsonResourceState state = new JsonResourceState(); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); + for (String key: jsonValue.keySet()) { + String memberName = key.replace("\"", ""); + ResourceHierarchy childResourceHierarchy = null; + for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) { + if (childRes.getResourceName().equals(memberName)) { + childResourceHierarchy = childRes; + break; + } + } + if (childResourceHierarchy == null) { + Type childResType = null; + if (jsonValue.get(key) instanceof Variable) { + childResType = ((Variable) jsonValue.get(key)).getType(); + } else if (jsonValue.get(key) instanceof Term) { + childResType = ((Term) jsonValue.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.get(key)); ResourceState childState = childInfo.getKey(); Resource res = getResource(resourceIdentifier); if (res != null && res.getChildrenMap() != null && res.getChildrenMap().get(memberName) != null) { res.getChildrenMap().get(memberName).changeState(childState); } state.addChildState(memberName, childState); - createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); } return createInfo; } else if (resStateValue instanceof Term) { Term jsonValue = (Term) resStateValue; JsonResourceState state = new JsonResourceState(); - Map.Entry createInfo = null; + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); while (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) { Expression childExp = jsonValue.getChild(1); if (childExp instanceof Constant) { @@ -522,9 +665,10 @@ } ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); String childId = ((Constant) childExp).toString(); - Map.Entry childInfo = createResourceState(childResourceIdentifier, jsonValue.getChild(2)); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.getChild(2)); state.addChildState(childId, childInfo.getKey()); - createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); } if (!(jsonValue.getChild(0) instanceof Term)) break; jsonValue = (Term) jsonValue.getChild(0); @@ -542,7 +686,9 @@ } else { state = new PrimitiveResourceState((Constant) resStateValue); } - return new AbstractMap.SimpleEntry<>(state, resourceIdentifier); + List updatedResources = new ArrayList<>(); + updatedResources.add(resourceIdentifier); + return new AbstractMap.SimpleEntry<>(state, updatedResources); } return null; } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/CompositeResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/CompositeResourceState.java index 5e6311f..b445d14 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/CompositeResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/CompositeResourceState.java @@ -9,6 +9,6 @@ } public abstract Map getChildStates(); - + public abstract void clearChildStates(); public abstract void replaceChildState(ResourceState state, ResourceState newState); } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java index 20909c6..3ceefea 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java @@ -31,6 +31,10 @@ children.put(param, childState); } + public void clearChildStates() { + children.clear(); + } + @Override public void replaceChildState(ResourceState state, ResourceState newState) { for (Map.Entry childEnt: children.entrySet()) { diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java index 34eff54..9848a4d 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java @@ -36,6 +36,9 @@ children.add(childState); } + public void clearChildStates() { + children.clear(); + } @Override public void replaceChildState(ResourceState state, ResourceState newState) { diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java index 6071c51..bee1dd5 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java @@ -31,6 +31,10 @@ children.put(param, childState); } + public void clearChildStates() { + children.clear(); + } + @Override public void replaceChildState(ResourceState state, ResourceState newState) { for (Map.Entry childEnt: children.entrySet()) {