/// <summary> /// Compiles the given AST <code>ast</code> into a oWFN petri net /// </summary> /// <exception cref="System.NullReferenceException">Thrown when the AST <c>ast</c> is null</exception> /// <returns>An equivalent <c>PetriNet</c> representation</returns> public PetriNet Compile() { if (this.ast == null) { throw new NullReferenceException("AST cannot be null"); } // Phylum net = new PetriNet(); String prefix = net.ActivityCount + ".internal."; Place p1 = net.NewPlace(prefix + "initialized"); Place p2 = net.NewPlace(prefix + "closed"); // Initial Marking p1.Tokens = 1; // Final Marking HashSet<Place> final = new HashSet<Place>(); final.Add(p2); net.AddFinalSet(final); // Compile inner activities int newID = ++net.ActivityCount; net = ast.Compile(net); // Merge final net net.Merge(p1, newID + ".internal.initialized"); net.Merge(p2, newID + ".internal.closed"); return net; }
public PetriNet Compile(PetriNet phylum) { String prefix = phylum.ActivityCount + ".internal."; Place p1 = phylum.NewPlace(prefix + "initialized"); Place p2 = phylum.NewPlace(prefix + "closed"); // Inner Petri Net if (innerActivities.Count != 0) { int lastID = 0; for (int i = 1; i <= innerActivities.Count; i++ ) { // New Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; // Compile innerActivities[i-1].Compile(phylum); // Connect if (i == 1) { // Initialized phylum.Merge(p1, currentID + ".internal.initialized"); } else { // Activities phylum.Merge(lastID + ".internal.closed", currentID + ".internal.initialized"); } if (i == innerActivities.Count) { // Closed phylum.Merge(p2, currentID + ".internal.closed"); } lastID = currentID; } } else { // Empty Sequence phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; // Compile new Empty().Compile(phylum); // Connect phylum.Merge(p1, currentID + ".internal.initialized"); phylum.Merge(p2, currentID + ".internal.closed"); } return phylum; }
public PetriNet Compile(PetriNet phylum) { String prefix = phylum.ActivityCount + ".internal."; // Places Place p1 = phylum.NewPlace(prefix + "initialized"); Place p2 = phylum.NewPlace(prefix + "closed"); // Transitions Transition empty = phylum.NewTransition(prefix + "empty"); // Arcs phylum.NewArc(p1, empty); phylum.NewArc(empty, p2); return phylum; }
public PetriNet Compile(PetriNet phylum) { String prefix = phylum.ActivityCount + ".internal."; // Places Place p1 = phylum.NewPlace(prefix + "initialized"); Place p2 = phylum.NewPlace(prefix + "closed"); // Place exists? Place message = phylum.Find("out." + phylum.ActivityCount + ".message"); if(message == null) { message = phylum.NewPlace("out." + phylum.ActivityCount + ".message", PetriNet.CommunicationType.Output); } // Transitions Transition send = phylum.NewTransition(prefix + "sendreply"); // Arcs phylum.NewArc(p1, send); phylum.NewArc(send, p2); phylum.NewArc(send, message); return phylum; }
public PetriNet Compile(PetriNet phylum) { String prefix = phylum.ActivityCount + ".internal."; Place p1 = phylum.NewPlace(prefix + "initialized"); Place p2 = phylum.NewPlace(prefix + "closed"); // Inner Petri Net Place condition = phylum.NewPlace(prefix + "condition"); Transition evalCondition = phylum.NewTransition(prefix + "evalcondition"); Transition repeat = phylum.NewTransition(prefix + "repeatactivity"); Transition end = phylum.NewTransition(prefix + "enddowhile"); phylum.NewArc(evalCondition, condition); phylum.NewArc(condition, repeat); phylum.NewArc(repeat, p1); phylum.NewArc(condition, end); phylum.NewArc(end, p2); int currentID = 0; // Inner Activity if (innerActivity != null) { // New Activity phylum.ActivityCount += 1; currentID = phylum.ActivityCount; // Compile innerActivity.Compile(phylum); // Connect & Merge phylum.NewArc(currentID + ".internal.closed", evalCondition); phylum.Merge(p1, currentID + ".internal.initialized"); } else { // Connect phylum.NewArc(p1, evalCondition); } return phylum; }
public PetriNet Compile(PetriNet phylum) { String prefix = phylum.ActivityCount + ".internal."; Place p1 = phylum.NewPlace(prefix + "initialized"); Place p2 = phylum.NewPlace(prefix + "closed"); // Inner Petri Net Place lastState = p1; IList<int> mergeIds = new List<int>(); for (int i = 1; i <= caseActivities.Count + 1; i++) { if (i <= caseActivities.Count) { Place state = phylum.NewPlace(prefix + "case" + i); Transition evalCase = phylum.NewTransition(prefix + "evalcase" + i); Transition initCase = phylum.NewTransition(prefix + "initcase" + i); phylum.NewArc(lastState, evalCase); phylum.NewArc(evalCase, state); phylum.NewArc(state, initCase); // Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; caseActivities[i - 1].Compile(phylum); // Connect phylum.NewArc(initCase, currentID + ".internal.initialized"); // LastState lastState = state; // Merge ID mergeIds.Add(currentID); } else { Transition initDefault = phylum.NewTransition(prefix + "initdefault"); phylum.NewArc(lastState, initDefault); if (defaultActivity != null) { // Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; defaultActivity.Compile(phylum); // Connect phylum.NewArc(initDefault, currentID + ".internal.initialized"); // Merge ID mergeIds.Add(currentID); } else { // Empty Connect phylum.NewArc(initDefault, p2); } } } // Merge foreach(int id in mergeIds) { phylum.Merge(p2, id + ".internal.closed"); } return phylum; }
public PetriNet Compile(PetriNet phylum) { String prefix = phylum.ActivityCount + ".internal."; Place p1 = phylum.NewPlace(prefix + "initialized"); Place p2 = phylum.NewPlace(prefix + "closed"); // Create States foreach (SMState state in states) { String prefixState = prefix + state.Id + "."; IList<Place> actions = new List<Place>(); // Entry Place closed int entryClosed; Place stp1 = phylum.NewPlace(prefixState + "initialized"); if (state.Final) { // Closed Place stp2 = phylum.NewPlace(prefixState + "closed"); // Activity if (state.Entry is Empty) { // Empty phylum.ActivityCount += 1; entryClosed = phylum.ActivityCount; Place entryP2 = phylum.NewPlace(prefix + "internal.closed"); phylum.Merge(stp1, entryP2); phylum.Merge(stp1, stp2); } else { // Entry Place entryP1 = phylum.NewPlace(prefixState + "entry.initialized"); Place entryP2 = phylum.NewPlace(prefixState + "entry.closed"); phylum.ActivityCount += 1; entryClosed = phylum.ActivityCount; state.Entry.Compile(phylum); // Merge phylum.Merge(entryP1, entryClosed + ".internal.initialized"); phylum.Merge(entryP2, entryClosed + ".internal.closed"); phylum.Merge(stp1, entryP1); phylum.Merge(entryP2, stp2); } } else { // Entry if(state.Entry is Empty) { phylum.ActivityCount += 1; entryClosed = phylum.ActivityCount; Place entryP2 = phylum.NewPlace(entryClosed + ".internal.closed"); phylum.Merge(stp1, entryP2); } else { // Entry Place entryP1 = phylum.NewPlace(prefixState + "entry.initialized"); Place entryP2 = phylum.NewPlace(prefixState + "entry.closed"); phylum.ActivityCount += 1; entryClosed = phylum.ActivityCount; state.Entry.Compile(phylum); // Merge phylum.Merge(entryP1, entryClosed + ".internal.initialized"); phylum.Merge(entryP2, entryClosed + ".internal.closed"); phylum.Merge(stp1, entryP1); } // Exit Place exitP1; Place exitP2; if (state.Exit is Empty) { exitP1 = phylum.NewPlace(prefixState + "exit"); exitP2 = exitP1; } else { exitP1 = phylum.NewPlace(prefixState + "exit.initialized"); exitP2 = phylum.NewPlace(prefixState + "exit.closed"); // Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; state.Exit.Compile(phylum); // Merge phylum.Merge(exitP1, currentID + ".internal.initialized"); phylum.Merge(exitP2, currentID + ".internal.closed"); } // Transitions for (int i = 1; i <= state.Transitions.Count; i++) { SMTransition transition = state.Transitions[i - 1]; // To Output Places Transition tsplit = phylum.NewTransition(prefixState + "t" + i); Place wait = phylum.NewPlace(prefixState + "t" + i + "wait"); Place to = phylum.NewPlace(prefix + state.Id + ".to" + i + "." + transition.To); // Actions Place actionP1; Place actionP2; if (transition.Action is Empty) { actionP1 = phylum.NewPlace(prefixState + transition.To + i + ".action.initialized"); actionP2 = actionP1; } else { actionP1 = phylum.NewPlace(prefixState + transition.To + i + ".action.initialized"); actionP2 = phylum.NewPlace(prefixState + transition.To + i + ".action.closed"); actions.Add(actionP1); // Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; transition.Action.Compile(phylum); // Merge phylum.Merge(actionP1, currentID + ".internal.initialized"); phylum.Merge(actionP2, currentID + ".internal.closed"); } // Connect Transition split = phylum.NewTransition(prefixState + transition.To + ".split" + i); phylum.NewArc(actionP2, split); phylum.NewArc(split, exitP1); phylum.NewArc(split, wait); phylum.NewArc(wait, tsplit); // Exit Split phylum.NewArc(exitP2, tsplit); phylum.NewArc(tsplit, to); } // Create Trigger foreach (String key in triggers.Keys) { SMTrigger trigger = triggers[key]; if (trigger.Transitions.Any(t => state.Transitions.Contains(t))) { // Trigger Place triggerIn = phylum.NewPlace(prefixState + "trigger" + key + ".in"); Place triggerOut = phylum.NewPlace(prefixState + "trigger" + key + ".out"); // Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; trigger.Trigger.Compile(phylum); // Merge phylum.Merge(triggerIn, currentID + ".internal.initialized"); phylum.Merge(triggerOut, currentID + ".internal.closed"); // Connect phylum.Merge(entryClosed + ".internal.closed", triggerIn); Transition on = phylum.NewTransition(prefixState + "ontrigger" + key); phylum.NewArc(triggerOut, on); Place runCondition = phylum.NewPlace(prefixState + "runcondition1" + key); phylum.NewArc(on, runCondition); // Conditions Place lastCondition = runCondition; for (int i = 1; i <= trigger.Transitions.Count; i++) { // Null Trigger if (!trigger.Transitions[i - 1].Condition) { Transition start = phylum.NewTransition(prefixState + "astart" + i + key); phylum.NewArc(lastCondition, start); // Connect Action int id = state.Transitions.IndexOf(trigger.Transitions[i - 1]) + 1; phylum.NewArc(start, prefixState + trigger.Transitions[i - 1].To + id + ".action.initialized"); // Flag Transition state.Transitions.First(t => t.Equals(trigger.Transitions[i - 1])).Flag = true; } else { Transition eval = phylum.NewTransition(prefixState + "eval" + i + key); phylum.NewArc(lastCondition, eval); Place condition = phylum.NewPlace(prefixState + "condition" + i + key); phylum.NewArc(eval, condition); // False Transition wrong = phylum.NewTransition(prefixState + "wrong" + i + key); phylum.NewArc(condition, wrong); // Reset if (i == trigger.Transitions.Count) { phylum.NewArc(wrong, triggerIn); } else { Place newRun = phylum.NewPlace(prefixState + "runcondition" + (i + 1) + key); phylum.NewArc(wrong, newRun); lastCondition = newRun; } // True Transition right = phylum.NewTransition(prefixState + "astart" + i + key); phylum.NewArc(condition, right); // Connect Action int id = state.Transitions.IndexOf(trigger.Transitions[i - 1]) + 1; phylum.NewArc(right, prefixState + trigger.Transitions[i - 1].To + id + ".action.initialized"); // Flag Transition state.Transitions.First(t => t.Equals(trigger.Transitions[i - 1])).Flag = true; } } } } // Empty Trigger int emptyTrigger = countEmptyTrigger(state.Transitions); if (emptyTrigger > 0) { // Connect Transition on = phylum.NewTransition(prefixState + "onemptytrigger"); Place trigger = phylum.NewPlace(prefixState + "trigger"); phylum.Merge(entryClosed + ".internal.closed", trigger); phylum.NewArc(trigger, on); Place runCondition = phylum.NewPlace(prefixState + "runcondition1"); phylum.NewArc(on, runCondition); // Conditions Place lastCondition = runCondition; for (int i = 1; i <= state.Transitions.Count; i++) { if (!state.Transitions[i - 1].Flag) { // Null Trigger if (!state.Transitions[i - 1].Condition) { int id = state.Transitions.IndexOf(state.Transitions[i - 1]) + 1; Transition start = phylum.NewTransition(prefixState + "bstart" + i + id); phylum.NewArc(lastCondition, start); // Connect Action phylum.NewArc(start, prefixState + state.Transitions[i - 1].To + id + ".action.initialized"); } else { Transition eval = phylum.NewTransition(prefixState + "eval" + i); phylum.NewArc(lastCondition, eval); Place condition = phylum.NewPlace(prefixState + "condition" + i); phylum.NewArc(eval, condition); // False Transition wrong = phylum.NewTransition(prefixState + "wrong" + i); phylum.NewArc(condition, wrong); // Reset if (i == emptyTrigger) { phylum.NewArc(wrong, trigger); } else { Place newRun = phylum.NewPlace(prefixState + "runcondition" + (i + 1)); phylum.NewArc(wrong, newRun); lastCondition = newRun; } // True int id = i; Transition right = phylum.NewTransition(prefixState + "bstart" + i + id); phylum.NewArc(condition, right); // Connect Action phylum.NewArc(right, prefixState + state.Transitions[i - 1].To + id + ".action.initialized"); } } } } } } // Connect States // Initial State phylum.Merge(p1, prefix + states.First(s => s.Id.Equals(initialState)).Id + ".initialized"); // Final States IList<SMState> finalStates = new List<SMState>(states.Where(s => s.Final == true)); foreach (SMState finalState in finalStates) { phylum.Merge(p2, prefix + finalState.Id + ".closed"); } // Transitions foreach (SMState state in states) { for (int i = 1; i <= state.Transitions.Count; i++) { SMTransition transition = state.Transitions[i - 1]; phylum.Merge(prefix + state.Id + ".to" + i + "." +transition.To, prefix + transition.To + ".initialized"); } } return phylum; }