diff --git a/build.gradle b/build.gradle index 4c1ac5edabe59b8118e9c9252bdb13137f901acd..f794746784b7cdd9b8ba3b80e026f737a690210e 100644 --- a/build.gradle +++ b/build.gradle @@ -108,7 +108,7 @@ def ecoreInputFiles = [ecoreFile] def ecoreOutputFiles = [ecoreRelastAspect, ecoreRelastGrammar] -def relastInputFiles = [ecoreRelastGrammar, './src/main/jastadd/base/marking/Marking.relast', './src/main/jastadd/engine/balloonMarking/BalloonMarking.relast', './src/main/jastadd/base/io/IoPN.relast', './src/main/jastadd/base/clauses/expressions.relast'] +def relastInputFiles = [ecoreRelastGrammar, './src/main/jastadd/base/marking/Marking.relast', './src/main/jastadd/engine/balloonMarking/BalloonMarking.relast', './src/main/jastadd/engine/balloonMarking/BalloonExecution.relast', './src/main/jastadd/base/io/IoPN.relast', './src/main/jastadd/base/clauses/expressions.relast'] def relastOutputFiles = ['src/gen/jastadd/pnml/placeTransition.ast', 'src/gen/jastadd/pnml/placeTransition.jadd'] task ecoreToRelast(type: JavaExec) { diff --git a/src/main/jastadd/engine/balloonMarking/BalloonExecution.jadd b/src/main/jastadd/engine/balloonMarking/BalloonExecution.jadd index a5659cabd5e7317dc27960dad697873b0b3e619a..89db56086b409145c440ce24c5687c29cc988a2a 100644 --- a/src/main/jastadd/engine/balloonMarking/BalloonExecution.jadd +++ b/src/main/jastadd/engine/balloonMarking/BalloonExecution.jadd @@ -1,3 +1,77 @@ aspect BalloonExecution { + public Optional<BalloonMarking> BalloonMarking.fireTransition(Transition transition, BalloonCallbackStorage callbackStorage, boolean requireFlush) { + + if(enabledBalloonTransitions().isEmpty()) return Optional.empty(); + + List<BalloonToken> inToken = new ArrayList<>(); + + // take a token from each incoming place + for(Place place : transition.incomingPlaces()){ + + BalloonMarkedPlace bmp = this.resolveBalloonPlace(place); + + Random rand = new Random(); + int randVal = rand.nextInt(bmp.getNumBalloonMarking()); + BalloonToken bt = bmp.getBalloonMarking(randVal); + + inToken.add(bt); + bmp.getBalloonMarking(randVal).removeSelf(); + } + + BalloonTransition balloonTransition = callbackStorage.resolveBalloonTransition(transition); + + BalloonToken result = de.tudresden.inf.st.pnml.engine.execution.TransitionCallbackExecutor.execute(inToken, balloonTransition.getBalloonCallbacks()); + + // place a token in each outgoing place + for(Place place : transition.outgoingPlaces()){ + BalloonMarkedPlace bmp = this.resolveBalloonPlace(place); + bmp.getBalloonMarkingList().add(result); + } + + if (requireFlush) { + // flush the entire marking tree + this.flushTreeCache(); + } + + return Optional.of(this); + } + + public Optional<BalloonMarking> BalloonMarking.fireTopicSubscriberTransition(java.util.Random random, Transition transition, BalloonCallbackStorage callbackStorage, boolean requireFlush) { + return null; + } + + public Optional<BalloonMarking> BalloonMarking.fireServiceClientTransition(java.util.Random random, Transition transition, BalloonCallbackStorage callbackStorage, boolean requireFlush) { + return null; + } + + public BalloonCallbackStorage PetriNet.initializeCallbackStorage() { + + BalloonCallbackStorage storage = new BalloonCallbackStorage(); + storage.setPetriNet(this); + + for (Transition transition : allTransitions()){ + + if(transition.asInputSignalTransition().getStaticTransitionInformation().isDefaultTransitionInformation()) { + + BalloonTransition balloonTransition = new BalloonTransition(); + balloonTransition.setTransition(transition); + storage.addTransition(balloonTransition); + } + } + + return storage; + } + + syn BalloonTransition BalloonCallbackStorage.resolveBalloonTransition(Transition transition) = execMap().get(transition); + + syn lazy java.util.Map<Transition, BalloonTransition> BalloonCallbackStorage.execMap() { + + java.util.Map<Transition, BalloonTransition> map = new java.util.HashMap<>(); + + for (BalloonTransition balloonTransition : getTransitionList()) { + map.put(balloonTransition.getTransition(), balloonTransition); + } + return map; + } } \ No newline at end of file diff --git a/src/main/jastadd/engine/balloonMarking/BalloonExecution.relast b/src/main/jastadd/engine/balloonMarking/BalloonExecution.relast new file mode 100644 index 0000000000000000000000000000000000000000..43915b349ed48beeb0dada40e1891ff743fdf4b5 --- /dev/null +++ b/src/main/jastadd/engine/balloonMarking/BalloonExecution.relast @@ -0,0 +1,4 @@ +BalloonCallbackStorage ::= PetriNet:PetriNet Transition:BalloonTransition*; +BalloonTransition ::= <BalloonCallbacks:java.util.List<de.tudresden.inf.st.pnml.engine.execution.TransitionCallback>>; + +rel BalloonTransition.Transition -> Transition; \ No newline at end of file diff --git a/src/main/jastadd/engine/balloonMarking/BalloonMarking.jrag b/src/main/jastadd/engine/balloonMarking/BalloonMarking.jrag index cee2ae35037c41356325d740308ea7674332391c..a6f087897dfee8e6882cfd421c5df32394d01cf5 100644 --- a/src/main/jastadd/engine/balloonMarking/BalloonMarking.jrag +++ b/src/main/jastadd/engine/balloonMarking/BalloonMarking.jrag @@ -1,9 +1,13 @@ aspect BalloonMarking { - public BalloonMarking PetriNet.initialBalloonMarking(PetriNet pn) throws IOException, SAXException, ParserConfigurationException { + eq BalloonCallbackStorage.getPetriNet().marking() = null; + + eq BalloonMarking.getPetriNet().marking() = null; + + public BalloonMarking PetriNet.initializeBalloonMarking() throws IOException, SAXException, ParserConfigurationException { BalloonMarking marking = new BalloonMarking(); - marking.setPetriNet(pn); + marking.setPetriNet(this); for (Place place : allPlaces()) { @@ -16,12 +20,14 @@ aspect BalloonMarking { token.setValue(val); markedPlace.getBalloonMarkingList().add(token); } + + marking.addPlace(markedPlace); } return marking; } - syn BalloonMarkedPlace BalloonMarking.resolvePlace(Place place) = balloonPlaceMap().get(place); + syn BalloonMarkedPlace BalloonMarking.resolveBalloonPlace(Place place) = balloonPlaceMap().get(place); syn lazy java.util.Map<Place, BalloonMarkedPlace> BalloonMarking.balloonPlaceMap() { @@ -33,7 +39,7 @@ aspect BalloonMarking { return map; } - syn BalloonMarkedPlace BalloonMarking.resolvePlaceById(String placeID) { + syn BalloonMarkedPlace BalloonMarking.resolveBalloonPlaceById(String placeID) { for (BalloonMarkedPlace markedPlace : getPlaceList()) { if(markedPlace.getPlace().getId().equals(placeID)){ @@ -46,13 +52,13 @@ aspect BalloonMarking { syn java.util.List<String> BalloonMarking.marking(Place place) { java.util.List<String> marking = new ArrayList<>(); - for(BalloonToken bt : resolvePlace(place).getBalloonMarkingList()){ + for(BalloonToken bt : resolveBalloonPlace(place).getBalloonMarkingList()){ marking.add(bt.getValue()); } return marking; } - syn boolean BalloonMarking.isEnabled(Transition t) { + syn boolean BalloonMarking.isBalloonEnabled(Transition t) { for (Place place : t.incomingPlaces()) { if (marking(place).size() == 0) return false; @@ -63,13 +69,13 @@ aspect BalloonMarking { syn boolean BalloonMarking.isDead() { for (Transition transition : getPetriNet().allTransitions()) { - if (isEnabled(transition)) return false; + if (isBalloonEnabled(transition)) return false; } return true; } - syn java.util.Set<Transition> BalloonMarking.enabledTransitions() + syn java.util.Set<Transition> BalloonMarking.enabledBalloonTransitions() = getPetriNet().allTransitions().stream() - .filter(t -> isEnabled(t)) + .filter(t -> isBalloonEnabled(t)) .collect(Collectors.toSet()); } \ No newline at end of file diff --git a/src/main/jastadd/engine/balloonMarking/BalloonPrinting.jrag b/src/main/jastadd/engine/balloonMarking/BalloonPrinting.jrag new file mode 100644 index 0000000000000000000000000000000000000000..302c84ce8033e95d8d319fa5a27b3893221ea66e --- /dev/null +++ b/src/main/jastadd/engine/balloonMarking/BalloonPrinting.jrag @@ -0,0 +1,25 @@ +aspect BalloonPrinting { + + syn String BalloonMarking.print() { + + StringBuilder b = new StringBuilder(); + b.append("Marking for Petri net '").append(getPetriNet().name()).append("':\n"); + + for (BalloonMarkedPlace place : getPlaceList()) { + b.append(" ").append(place.getPlace().name()).append(": \n"); + + for(BalloonToken bt : place.getBalloonMarkingList()){ + b.append(bt.getValue()).append("\n"); + } + + } + + b.append("Transitions for Petri net '").append(getPetriNet().name()).append("':\n"); + + for (Transition trans : getPetriNet().allTransitions()) { + + b.append(" ").append(trans.name()).append(": ").append(isBalloonEnabled(trans)?"true":"false").append("\n"); + } + return b.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/de/tudresden/inf/st/pnml/engine/Main.java b/src/main/java/de/tudresden/inf/st/pnml/engine/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..4856622d850b83324cd489f22891a58535927ad0 --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/engine/Main.java @@ -0,0 +1,45 @@ +package de.tudresden.inf.st.pnml.engine; + +import de.tudresden.inf.st.pnml.engine.execution.DefaultFinalTransitionCallback; +import de.tudresden.inf.st.pnml.engine.execution.TransitionCallback; +import de.tudresden.inf.st.pnml.jastadd.model.*; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class Main { + + public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { + + String pnmlPath = "../pnml-relast-nets/src/main/resources/balloonTestNets/balloon-correct-2.pnml"; + PetriNet petriNet = PnmlParser.parsePnml(pnmlPath).get(0); + + BalloonMarking bm = petriNet.initializeBalloonMarking(); + BalloonCallbackStorage bcs = petriNet.initializeCallbackStorage(); + + TransitionCallback tc = new DefaultFinalTransitionCallback("default_final_cb", 1); + List<TransitionCallback> tcl = new ArrayList<>(); + tcl.add(tc); + + System.out.println("----- BEFORE -----"); + System.out.println(bm.print()); + + for(Transition t : petriNet.allTransitions()){ + bcs.resolveBalloonTransition(t).setBalloonCallbacks(tcl); + } + + for(Transition t : petriNet.allTransitions()){ + + if(bm.isBalloonEnabled(t)){ + bm.fireTransition(t, bcs, false); + break; + } + } + + System.out.println("----- AFTER -----"); + System.out.println(bm.print()); + } +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/engine/execution/DefaultFinalTransitionCallback.java b/src/main/java/de/tudresden/inf/st/pnml/engine/execution/DefaultFinalTransitionCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..ba99fa6771b2065e1f785a99e8350b35b3035585 --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/engine/execution/DefaultFinalTransitionCallback.java @@ -0,0 +1,21 @@ +package de.tudresden.inf.st.pnml.engine.execution; + +import de.tudresden.inf.st.pnml.jastadd.model.BalloonToken; + +import java.util.ArrayList; +import java.util.List; + +public class DefaultFinalTransitionCallback extends TransitionCallback{ + + public DefaultFinalTransitionCallback(String id, int priority) { + super(id, priority); + } + + @Override + public List<BalloonToken> processToken(List<BalloonToken> tokens) { + + List<BalloonToken> tl = new ArrayList<>(); + tl.add(tokens.get(0)); + return tl; + } +} \ No newline at end of file diff --git a/src/main/java/de/tudresden/inf/st/pnml/engine/execution/DefaultTransitionCallback.java b/src/main/java/de/tudresden/inf/st/pnml/engine/execution/DefaultTransitionCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..0a321751e107967041f66849a8c60cf6bfa4d9c5 --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/engine/execution/DefaultTransitionCallback.java @@ -0,0 +1,17 @@ +package de.tudresden.inf.st.pnml.engine.execution; + +import de.tudresden.inf.st.pnml.jastadd.model.BalloonToken; + +import java.util.List; + +public class DefaultTransitionCallback extends TransitionCallback{ + + public DefaultTransitionCallback(String id, int priority) { + super(id, priority); + } + + @Override + public List<BalloonToken> processToken(List<BalloonToken> tokens) { + return tokens; + } +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/engine/execution/TransitionCallback.java b/src/main/java/de/tudresden/inf/st/pnml/engine/execution/TransitionCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..cce1f5d05969ad74808e8b12baeb16d464268341 --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/engine/execution/TransitionCallback.java @@ -0,0 +1,32 @@ +package de.tudresden.inf.st.pnml.engine.execution; + +import de.tudresden.inf.st.pnml.jastadd.model.BalloonToken; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public abstract class TransitionCallback { + + protected static final Logger logger = LoggerFactory.getLogger(TransitionCallback.class); + + private String id; + private int priority; + + public TransitionCallback(String id, int priority) { + this.id = id; + this.priority = priority; + } + + public String getId() { + return id; + } + + public int getPriority() { + return priority; + } + + public List<BalloonToken> processToken(List<BalloonToken> tokens) { + return tokens; + } +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/engine/execution/TransitionCallbackExecutor.java b/src/main/java/de/tudresden/inf/st/pnml/engine/execution/TransitionCallbackExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..54541430099e26465d76ea2274884c35eadab739 --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/engine/execution/TransitionCallbackExecutor.java @@ -0,0 +1,45 @@ +package de.tudresden.inf.st.pnml.engine.execution; + +import de.tudresden.inf.st.pnml.jastadd.model.BalloonToken; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Automatically sort and call the callbacks. + */ +public class TransitionCallbackExecutor { + + protected static final Logger logger = LoggerFactory.getLogger(TransitionCallbackExecutor.class); + + public static final BalloonToken execute(List<BalloonToken> inTokens, List<TransitionCallback> callbacks){ + + List<TransitionCallback> callbacksSorted = new ArrayList<>(); + List<BalloonToken> outTokens = new ArrayList<>(); + outTokens.addAll(inTokens); + callbacks.addAll(callbacks); + + Collections.sort(callbacksSorted, Comparator.comparingInt(TransitionCallback::getPriority)); + + for(int i = 0; i < callbacksSorted.size(); i++){ + if(i < callbacksSorted.size() - 1){ + outTokens = callbacksSorted.get(i).processToken(outTokens); + } else { + outTokens = new ArrayList<>(); + outTokens.add(callbacksSorted.get(i).processToken(outTokens).get(0)); + } + } + + if(outTokens.size() != 1){ + logger.error("Error! Wrong output token size."); + } + + logger.info("Created new output token: " + outTokens.get(0)); + + return outTokens.get(0); + } +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/engine/parsing/BalloonTokenParsing.java b/src/main/java/de/tudresden/inf/st/pnml/engine/parsing/BalloonTokenParsing.java index 5bc590b7c0a3ce6815599772a12cf47a2205acba..20ef66a3a9444d4e0d58d42a966d77252d2bcb9f 100644 --- a/src/main/java/de/tudresden/inf/st/pnml/engine/parsing/BalloonTokenParsing.java +++ b/src/main/java/de/tudresden/inf/st/pnml/engine/parsing/BalloonTokenParsing.java @@ -21,7 +21,7 @@ public class BalloonTokenParsing { List<String> marking = new ArrayList<>(); for (ToolInfo ti : place.getToolspecifics()) { - if (ti.getFormattedXMLBuffer().lastIndexOf(BalloonConstants.BALLOON_MARKING) == -1) { + if (ti.getFormattedXMLBuffer().lastIndexOf(BalloonConstants.BALLOON_MARKING) != -1) { StringBuffer toolInfoStringBuffer = ti.getFormattedXMLBuffer();