diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 1507ea3..3bdb1dd 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -1,9 +1,13 @@ package models.dataConstraintModel; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Stack; import models.algebra.Constant; import models.algebra.Expression; @@ -201,8 +205,7 @@ return children[0] + ".equals(" + children[1] + ")"; } return "(" + children[0] + "==" + children[1] + ")"; - } - + } }, new Symbol.ICalculator() { @Override public Expression calculate(List args) { @@ -246,7 +249,6 @@ } return "(" + children[0] + "!=" + children[1] + ")"; } - }, new Symbol.ICalculator() { @Override public Expression calculate(List args) { @@ -467,13 +469,89 @@ } }); public static final Symbol cons = new Symbol("cons", 2, Symbol.Type.PREFIX, "($x,$y)->$x.add(0, $y)", Symbol.Type.LAMBDA_WITH_SIDE_EFFECT, new int[] {1, 0}); - public static final Symbol append = new Symbol("append", 2, Symbol.Type.PREFIX, "add", Symbol.Type.METHOD_WITH_SIDE_EFFECT); - public static final Symbol remove = new Symbol("remove", 2, Symbol.Type.PREFIX, "remove", Symbol.Type.METHOD_WITH_SIDE_EFFECT); + public static final Symbol append = new Symbol("append", 2, Symbol.Type.PREFIX, "add", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator). + public static final Symbol remove = new Symbol("remove", 2, Symbol.Type.PREFIX, "remove", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator). public static final Symbol head = new Symbol("head", 1, Symbol.Type.PREFIX, "($x)->$x.get(0)", Symbol.Type.LAMBDA); public static final Symbol tail = new Symbol("tail", 1, Symbol.Type.PREFIX, "($x)->$x.subList(1, $x.size())", Symbol.Type.LAMBDA); - public static final Symbol length = new Symbol("length", 1, Symbol.Type.PREFIX, "($x)->$x.size()", Symbol.Type.LAMBDA); - public static final Symbol get = new Symbol("get", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD); - public static final Symbol set = new Symbol("set", 3, Symbol.Type.PREFIX, "set", Symbol.Type.METHOD_WITH_SIDE_EFFECT); + public static final Symbol length = new Symbol("length", 1, Symbol.Type.PREFIX, "($x)->$x.size()", Symbol.Type.LAMBDA, new Symbol.ICalculator() { + @Override + public Expression calculate(List args) { + if (args.get(0).getClass() == Constant.class && ((Constant) args.get(0)).getSymbol().equals(nil)) { + return new Constant("0", typeInt); + } + if (args.get(0) instanceof Term) { + Term term = (Term) args.get(0); + Type type = term.getType(); + if (typeList.isAncestorOf(type)) { + int len = 0; + while (term.getSymbol().equals(DataConstraintModel.append)) { + len++; + term = (Term) term.getChild(0); + } + if (term instanceof ListTerm) { + len += ((ListTerm) term).getChildren().size(); + return new Constant(Integer.toString(len), typeInt); + } + } else if (typeMap.isAncestorOf(type)) { + HashSet keySet = new HashSet<>(); + while (term.getSymbol().equals(DataConstraintModel.insert)) { + if (term.getChild(1).getClass() == Constant.class) { + keySet.add((String) ((Constant) term.getChild(1)).getValue()); + } + term = (Term) term.getChild(0); + } + if (term instanceof MapTerm) { + keySet.addAll(((MapTerm) term).keySet()); + return new Constant(Integer.toString(keySet.size()), typeInt); + } + } else if (typeJson.isAncestorOf(type)) { + HashSet keySet = new HashSet<>(); + while (term.getSymbol().equals(DataConstraintModel.addMember)) { + if (term.getChild(1).getClass() == Constant.class) { + keySet.add((String) ((Constant) term.getChild(1)).getValue()); + } + term = (Term) term.getChild(0); + } + if (term instanceof JsonTerm) { + keySet.addAll(((JsonTerm) term).keySet()); + return new Constant(Integer.toString(keySet.size()), typeInt); + } + } + } + return null; + } + }); + public static final Symbol get = new Symbol("get", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD, new Symbol.ICalculator() { + @Override + public Expression calculate(List args) { + if (args.get(1).getClass() == Constant.class && ((Constant) args.get(1)).getType().equals(typeInt)) { + int idx = Integer.parseInt(((Constant) args.get(1)).toString()); + if (args.get(0) instanceof Term) { + Term term = (Term) args.get(0); + Type type = term.getType(); + if (typeList.isAncestorOf(type)) { + Stack appendedChldren = new Stack<>(); + while (term.getSymbol().equals(DataConstraintModel.append)) { + if (!(term.getChild(0) instanceof Term)) { + return null; + } + appendedChldren.push(term.getChild(1)); + term = (Term) term.getChild(0); + } + if (term instanceof ListTerm) { + ListTerm listTerm = (ListTerm) term.clone(); + for (Expression child: appendedChldren) { + listTerm.append(child); + } + return listTerm.get(idx); + } + } + } + } + return null; + } + }); + public static final Symbol set = new Symbol("set", 3, Symbol.Type.PREFIX, "set", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator). public static final Symbol contains = new Symbol("contains", 2, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { @Override public String generate(Type type, Type[] childrenTypes, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) { @@ -561,6 +639,42 @@ return null; } }); + public static final Symbol indexOf = new Symbol("indexOf", 2, Symbol.Type.PREFIX, "indexOf", Symbol.Type.METHOD, new Symbol.ICalculator() { + @Override + public Expression calculate(List args) { + if (args.get(0) instanceof Term) { + Term term = (Term) args.get(0); + Type type = term.getType(); + if (typeList.isAncestorOf(type)) { + Stack appendedChldren = new Stack<>(); + while (term.getSymbol().equals(DataConstraintModel.append)) { + if (!(term.getChild(0) instanceof Term)) { + return null; + } + appendedChldren.push(term.getChild(1)); + term = (Term) term.getChild(0); + } + if (term instanceof ListTerm) { + int idx = 0; + ListTerm listTerm = (ListTerm) term; + for (Expression child: listTerm.getChildren()) { + if (child.equals(args.get(1))) { + return new Constant(Integer.toString(idx), typeInt); + } + idx++; + } + for (Expression child: appendedChldren) { + if (child.equals(args.get(1))) { + return new Constant(Integer.toString(idx), typeInt); + } + idx++; + } + } + } + } + return null; + } + }); public static final Symbol nil = new Symbol("nil", 0, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { @Override public String generate(Type type, Type[] childrenTypes, String[] children, String[] childrenSideEffects, String[] sideEffect) { @@ -650,26 +764,39 @@ public static final Symbol snd = new Symbol("snd", 1, Symbol.Type.PREFIX, "getValue", Symbol.Type.METHOD); public static final Symbol left = new Symbol("left", 1, Symbol.Type.PREFIX, "getLeft", Symbol.Type.METHOD); public static final Symbol right = new Symbol("right", 1, Symbol.Type.PREFIX, "getRight", Symbol.Type.METHOD); - public static final Symbol insert = new Symbol("insert", 3, Symbol.Type.PREFIX, "put", Symbol.Type.METHOD_WITH_SIDE_EFFECT); - public static final Symbol delete = new Symbol("delete", 2, Symbol.Type.PREFIX, "remove", Symbol.Type.METHOD_WITH_SIDE_EFFECT); - public static final Symbol lookup = new Symbol("lookup", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD); -// public static final Symbol lookup = new Symbol("lookup", 2, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { -// final int count[] = {0}; -// @Override -// public String generate(Type type, String[] childrenImpl, String[] childrenSideEffects, String[] sideEffect) { -// String temp = "temp_get" + count[0]; -// String impl = childrenSideEffects[0] + childrenSideEffects[1]; -// impl += type.getInterfaceTypeName() + " " + temp + ";\n"; -// impl += "if (" + childrenImpl[0] + ".get(" + childrenImpl[1] + ") != null) {\n"; -// impl += "\t" + temp + " = " + childrenImpl[0] + ".get(" + childrenImpl[1] + ");\n"; -// impl += "} else {\n"; -// impl += "\t" + temp + " = " + getDefaultValue(type) + ";\n"; -// impl += "}"; -// sideEffect[0] = impl; -// count[0]++; -// return temp; -// } -// }); + public static final Symbol insert = new Symbol("insert", 3, Symbol.Type.PREFIX, "put", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator). + public static final Symbol delete = new Symbol("delete", 2, Symbol.Type.PREFIX, "remove", Symbol.Type.METHOD_WITH_SIDE_EFFECT); // Don't calculate here (Calculated in simulator). + public static final Symbol lookup = new Symbol("lookup", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD, new Symbol.ICalculator() { + @Override + public Expression calculate(List args) { + if (args.get(1).getClass() == Constant.class && ((Constant) args.get(1)).getType().equals(typeString)) { + String key = (String) ((Constant) args.get(1)).getValue(); + if (args.get(0) instanceof Term) { + Term term = (Term) args.get(0); + Type type = term.getType(); + if (typeMap.isAncestorOf(type)) { + Stack> appendedChldren = new Stack<>(); + while (term.getSymbol().equals(DataConstraintModel.insert)) { + if (!(term.getChild(0) instanceof Term)) { + return null; + } + appendedChldren.push(new AbstractMap.SimpleEntry<>(term.getChild(0), term.getChild(1))); + term = (Term) term.getChild(0); + } + if (term instanceof MapTerm) { + MapTerm mapTerm = (MapTerm) term.clone(); + for (Map.Entry childEnt: appendedChldren) { + if (childEnt.getKey().getClass() == Constant.class) + mapTerm.insert((String) ((Constant) childEnt.getKey()).getValue(), childEnt.getValue()); + } + return mapTerm.get(key); + } + } + } + } + return null; + } + }); public static final Symbol addMember = new Symbol("addMember", 3, Symbol.Type.PREFIX, "put", Symbol.Type.METHOD_WITH_SIDE_EFFECT); public static final Symbol dot = new Symbol(Parser.DOT, 2, Symbol.Type.INFIX, "get", Symbol.Type.METHOD); public static final Symbol dotParam = new Symbol(Parser.DOT, 2, Symbol.Type.INFIX, "get", Symbol.Type.METHOD); @@ -710,6 +837,7 @@ head.setSignature(new Type[] {null, typeList}); tail.setSignature(new Type[] {typeList, typeList}); contains.setSignature(new Type[] {typeBoolean, null, null}); + indexOf.setSignature(new Type[] {typeInt, typeList, null}); length.setSignature(new Type[] {typeInt, null}); get.setSignature(new Type[] {null, typeList, typeInt}); set.setSignature(new Type[] {typeList, typeList, typeInt, null}); @@ -792,6 +920,7 @@ addSymbol(tail); addSymbol(length); addSymbol(contains); + addSymbol(indexOf); addSymbol(get); addSymbol(set); addSymbol(cond); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java index 373fdfc..d1a5359 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java @@ -26,12 +26,14 @@ import models.dataFlowModel.DataTransferChannel; import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor; import simulator.Event.IResourceStateValueProvider; +import simulator.interfaces.INativeInitializer; import simulator.interfaces.INativeReceiver; public class Simulator { private DataTransferModel model; private SystemState curState; private List systemReceivers = new ArrayList<>(); + private List systemInitializers = new ArrayList<>(); private Map> nativeReceivers = new HashMap<>(); private Map nativeChannelReceivers = new HashMap<>(); @@ -63,6 +65,9 @@ for (Channel channel: model.getChannels()) { curState.addChannel((DataTransferChannel) channel); } + for (INativeInitializer initializer: systemInitializers) { + initializer.onInitFromModel(curState); + } return curState; } @@ -100,6 +105,10 @@ systemReceivers.add(receiver); } + public void addSystemInitializer(INativeInitializer initializer) { + systemInitializers.add(initializer); + } + public void addNativeReceiver(INativeReceiver receiver, DataTransferChannel channel) { nativeChannelReceivers.put(channel, receiver); } @@ -117,6 +126,10 @@ systemReceivers.remove(receiver); } + public void removeSystemInitializer(INativeInitializer initializer) { + systemInitializers.remove(initializer); + } + public void removeNativeReceiver(DataTransferChannel channel) { nativeChannelReceivers.remove(channel); } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java index 8ebe150..90a4546 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java @@ -158,7 +158,7 @@ } 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); + if (childInfo != null) createdResources.addAll(childInfo); } } } @@ -193,6 +193,93 @@ ((ListResourceState) state).addChildState(childInfo.getKey()); createdResources.addAll(childInfo.getValue()); return createdResources; + } else if (listValue.getSymbol().equals(DataConstraintModel.set)) { + Expression childIdxExp = listValue.getChild(1); + if (childIdxExp instanceof Term) { + childIdxExp = ((Term) childIdxExp).substitute(curResVar, resCurStateVal); + childIdxExp = ((Term) childIdxExp).reduce(); + } + if (childIdxExp instanceof Constant) { + 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)); + if (childInfo != null) createdResources.addAll(childInfo); + } + } + } + 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(2) instanceof Variable) { + childResType = ((Variable) listValue.getChild(2)).getType(); + } else if (listValue.getChild(2) instanceof Term) { + childResType = ((Term) listValue.getChild(2)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childIdxExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.getChild(2)); + ((ListResourceState) state).replaceChildState(Integer.parseInt(childIdxExp.toString()), childInfo.getKey()); + createdResources.addAll(childInfo.getValue()); + return createdResources; + } + } else if (listValue.getSymbol().equals(DataConstraintModel.remove)) { + Expression childIdxExp = listValue.getChild(1); + if (childIdxExp instanceof Term) { + childIdxExp = ((Term) childIdxExp).substitute(curResVar, resCurStateVal); + childIdxExp = ((Term) childIdxExp).reduce(); + } + if (childIdxExp instanceof Constant) { + 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)); + if (childInfo != null) createdResources.addAll(childInfo); + } + } + } + ((ListResourceState) state).removeChildState(Integer.parseInt(childIdxExp.toString())); + return createdResources; + } } } } else if (resType != null && DataConstraintModel.typeMap.isAncestorOf(resType)) { @@ -278,11 +365,11 @@ 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); + if (childInfo != null) 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 (childInfo != null) createdResources.addAll(childInfo); } } } @@ -315,6 +402,43 @@ createdResources.addAll(childInfo.getValue()); return createdResources; } + } else if (mapValue.getSymbol().equals(DataConstraintModel.delete)) { + Expression childKeyExp = mapValue.getChild(1); + if (childKeyExp instanceof Term) { + childKeyExp = ((Term) childKeyExp).substitute(curResVar, resCurStateVal); + childKeyExp = ((Term) childKeyExp).reduce(); + } + if (childKeyExp instanceof Constant) { + List createdResources = new ArrayList<>(); + 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 + if (childInfo != null) 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)); + if (childInfo != null) createdResources.addAll(childInfo); + } + } + } + String childId = (String) ((Constant) childKeyExp).getValue(); + ((MapResourceState) state).removeChildState(childId); + return createdResources; + } } } } else if (resType != null && DataConstraintModel.typeJson.isAncestorOf(resType)) { @@ -434,7 +558,7 @@ } else if (resStateValue instanceof ListTerm) { ListTerm listValue = (ListTerm) resStateValue; ListResourceState state = new ListResourceState(); - Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(state, new ArrayList<>()); for (int i = 0; i < listValue.size(); i++) { Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); ResourceHierarchy childResourceHierarchy = null; @@ -477,7 +601,7 @@ // 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()); + if (childInfo != null) createdResources.addAll(childInfo.getValue()); } } } @@ -499,6 +623,114 @@ state.addChildState(childInfo.getKey()); createdResources.addAll(childInfo.getValue()); return new AbstractMap.SimpleEntry<>(state, createdResources); + } else if (listValue.getSymbol().equals(DataConstraintModel.set)) { + Expression childIdxExp = listValue.getChild(1); + if (childIdxExp instanceof Term) { + childIdxExp = ((Term) childIdxExp).substitute(curResVar, resCurStateVal); + childIdxExp = ((Term) childIdxExp).reduce(); + } + if (childIdxExp instanceof Constant) { + 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(); + if (childInfo != null) 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 (listValue.getChild(2) instanceof Variable) { + childResType = ((Variable) listValue.getChild(2)).getType(); + } else if (listValue.getChild(2) instanceof Term) { + childResType = ((Term) listValue.getChild(2)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childIdxExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.getChild(2)); + state.replaceChildState(Integer.parseInt(childIdxExp.toString()), childInfo.getKey()); + createdResources.addAll(childInfo.getValue()); + return new AbstractMap.SimpleEntry<>(state, createdResources); + } + } else if (listValue.getSymbol().equals(DataConstraintModel.remove)) { + Expression childIdxExp = listValue.getChild(1); + if (childIdxExp instanceof Term) { + childIdxExp = ((Term) childIdxExp).substitute(curResVar, resCurStateVal); + childIdxExp = ((Term) childIdxExp).reduce(); + } + if (childIdxExp instanceof Constant) { + 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(); + if (childInfo != null) createdResources.addAll(childInfo.getValue()); + } + } + } + ((ListResourceState) state).removeChildState(Integer.parseInt(childIdxExp.toString())); + return new AbstractMap.SimpleEntry<>(state, createdResources); + } + } else { + listValue = listValue.substitute(curResVar, resCurStateVal); + Expression listExp = listValue.reduce(); + if (listExp instanceof ListTerm) { + ListTerm listVal = (ListTerm) listExp; + ListResourceState state = new ListResourceState(); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(state, new ArrayList<>()); + for (int i = 0; i < listVal.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 (listVal.get(i) instanceof Variable) { + childResType = ((Variable) listVal.get(i)).getType(); + } else if (listVal.get(i) instanceof Term) { + childResType = ((Term) listVal.get(i)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listVal.get(i)); + state.addChildState(childInfo.getKey()); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); + } + return createInfo; + } } } } else if (DataConstraintModel.typeMap.isAncestorOf(resType)) { @@ -506,7 +738,7 @@ } else if (resStateValue instanceof JsonTerm) { JsonTerm mapValue = (JsonTerm) resStateValue; MapResourceState state = new MapResourceState(); - Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(state, new ArrayList<>()); for (String key: mapValue.keySet()) { Expression childExp = new Constant(key, DataConstraintModel.typeString); ResourceHierarchy childResourceHierarchy = null; @@ -531,7 +763,7 @@ } else if (resStateValue instanceof MapTerm) { MapTerm mapValue = (MapTerm) resStateValue; MapResourceState state = new MapResourceState(); - Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(state, new ArrayList<>()); for (String key: mapValue.keySet()) { Expression childExp = new Constant(key, DataConstraintModel.typeString); ResourceHierarchy childResourceHierarchy = null; @@ -556,13 +788,17 @@ } else if (resStateValue instanceof Term) { Term mapValue = (Term) resStateValue; if (mapValue.getSymbol().equals(DataConstraintModel.insert)) { - Expression childExp = mapValue.getChild(1); - if (childExp instanceof Constant) { + Expression childKeyExp = mapValue.getChild(1); + if (childKeyExp instanceof Term) { + childKeyExp = ((Term) childKeyExp).substitute(curResVar, resCurStateVal); + childKeyExp = ((Term) childKeyExp).reduce(); + } + if (childKeyExp 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. + // If the child map is nil. } else { Expression childMap = ((Term) mapValue.getChild(0)); childMap = ((Term) childMap).substitute(curResVar, resStateValue); @@ -576,7 +812,7 @@ // 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()); + if (childInfo != null) createdResources.addAll(childInfo.getValue()); } } } @@ -592,13 +828,75 @@ } childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); - String childId = (String) ((Constant) childExp).getValue(); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childKeyExp, childResourceHierarchy); + String childId = (String) ((Constant) childKeyExp).getValue(); 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 (mapValue.getSymbol().equals(DataConstraintModel.delete)) { + Expression childKeyExp = mapValue.getChild(1); + if (childKeyExp instanceof Term) { + childKeyExp = ((Term) childKeyExp).substitute(curResVar, resCurStateVal); + childKeyExp = ((Term) childKeyExp).reduce(); + } + if (childKeyExp 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 map 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(); + if (childInfo != null) createdResources.addAll(childInfo.getValue()); + } + } + } + String childId = (String) ((Constant) childKeyExp).getValue(); + ((MapResourceState) state).removeChildState(childId); + return new AbstractMap.SimpleEntry<>(state, createdResources); + } + } else { + mapValue = mapValue.substitute(curResVar, resCurStateVal); + Expression mapExp = mapValue.reduce(); + if (mapExp instanceof MapTerm) { + MapTerm mapVal = (MapTerm) mapExp; + MapResourceState state = new MapResourceState(); + Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); + for (String key: mapVal.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 (mapVal.get(key) instanceof Variable) { + childResType = ((Variable) mapVal.get(key)).getType(); + } else if (mapVal.get(key) instanceof Term) { + childResType = ((Term) mapVal.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapVal.get(key)); + state.addChildState(key, childInfo.getKey()); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); + } + return createInfo; + } } } } else if (DataConstraintModel.typeJson.isAncestorOf(resType)) { @@ -640,34 +938,71 @@ Term jsonValue = (Term) resStateValue; JsonResourceState state = new JsonResourceState(); Map.Entry> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>()); - while (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) { - Expression childExp = jsonValue.getChild(1); - if (childExp instanceof Constant) { - String memberName = (String) ((Constant) childExp).getValue(); - ResourceHierarchy childResourceHierarchy = null; - for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) { - if (childRes.getResourceName().equals(memberName)) { - childResourceHierarchy = childRes; - break; + if (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) { + while (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) { + Expression childExp = jsonValue.getChild(1); + if (childExp instanceof Constant) { + String memberName = (String) ((Constant) childExp).getValue(); + 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(); + 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); } - childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.getChild(2)); + state.addChildState(memberName, childInfo.getKey()); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); } - ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); - Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.getChild(2)); - state.addChildState(memberName, childInfo.getKey()); - createInfo.getValue().addAll(childInfo.getValue()); - createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); + if (!(jsonValue.getChild(0) instanceof Term)) break; + jsonValue = (Term) jsonValue.getChild(0); } - if (!(jsonValue.getChild(0) instanceof Term)) break; - jsonValue = (Term) jsonValue.getChild(0); + } else { + jsonValue = jsonValue.substitute(curResVar, resCurStateVal); + Expression jsonExp = jsonValue.reduce(); + if (jsonExp instanceof JsonTerm) { + JsonTerm jsonVal = (JsonTerm) jsonExp; + for (String key: jsonVal.keySet()) { + ResourceHierarchy childResourceHierarchy = null; + for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) { + if (childRes.getResourceName().equals(key)) { + childResourceHierarchy = childRes; + break; + } + } + if (childResourceHierarchy == null) { + Type childResType = null; + if (jsonVal.get(key) instanceof Variable) { + childResType = ((Variable) jsonVal.get(key)).getType(); + } else if (jsonVal.get(key) instanceof Term) { + childResType = ((Term) jsonVal.get(key)).getType(); + } + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), key, childResType); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, key, childResourceHierarchy); + Map.Entry> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonVal.get(key)); + ResourceState childState = childInfo.getKey(); + Resource res = getResource(resourceIdentifier); + if (res != null && res.getChildrenMap() != null && res.getChildrenMap().get(key) != null) { + res.getChildrenMap().get(key).changeState(childState); + } + state.addChildState(key, childState); + createInfo.getValue().addAll(childInfo.getValue()); + createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue()); + } + } + } return createInfo; } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/INativeInitializer.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/INativeInitializer.java new file mode 100644 index 0000000..fc73bdc --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/INativeInitializer.java @@ -0,0 +1,7 @@ +package simulator.interfaces; + +import simulator.SystemState; + +public interface INativeInitializer { + public void onInitFromModel(SystemState initialSystemState); +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java index 3ceefea..6ba7256 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java @@ -30,6 +30,10 @@ public void addChildState(String param, ResourceState childState) { children.put(param, childState); } + + public void removeChildState(String param) { + children.remove(param); + } public void clearChildStates() { children.clear(); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java index 9848a4d..d45f9d2 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java @@ -35,6 +35,10 @@ public void addChildState(ResourceState childState) { children.add(childState); } + + public void removeChildState(int idx) { + children.remove(idx); + } public void clearChildStates() { children.clear(); @@ -49,6 +53,10 @@ } } + public void replaceChildState(int idx, ResourceState newState) { + children.set(idx, newState); + } + public Object clone() { ListResourceState newListResourceState = new ListResourceState(); for (ResourceState state: children) { diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java index bee1dd5..6ceecf4 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java @@ -30,6 +30,10 @@ public void addChildState(String param, ResourceState childState) { children.put(param, childState); } + + public void removeChildState(String param) { + children.remove(param); + } public void clearChildStates() { children.clear();