Пример #1
0
        /// <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);
        }
Пример #2
0
        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 == 1)
            {
                // New Activity
                phylum.ActivityCount += 1;
                int currentID = phylum.ActivityCount;
                // Compile
                innerActivities[0].Compile(phylum);
                // Connect
                phylum.Merge(p1, currentID + ".internal.initialized");
                phylum.Merge(currentID + ".internal.closed", p2);
            }
            else if (innerActivities.Count > 1)
            {
                Transition split = phylum.NewTransition(prefix + "split");
                Transition join  = phylum.NewTransition(prefix + "join");
                phylum.NewArc(p1, split);
                phylum.NewArc(join, p2);

                for (int i = 1; i <= innerActivities.Count; i++)
                {
                    // New Activity
                    phylum.ActivityCount += 1;
                    int currentID = phylum.ActivityCount;
                    // Compile
                    innerActivities[i - 1].Compile(phylum);
                    // Connect
                    phylum.NewArc(split, currentID + ".internal.initialized");
                    phylum.NewArc(currentID + ".internal.closed", join);
                }
            }
            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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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 (branches.Count != 0)
            {
                for (int i = 1; i <= branches.Count; i++)
                {
                    // Trigger
                    phylum.ActivityCount += 1;
                    int triggerID = phylum.ActivityCount;
                    // Compile
                    branches[i - 1].Trigger.Compile(phylum);
                    // Connect
                    phylum.Merge(p1, triggerID + ".internal.initialized");

                    if (branches[i - 1].Action != null)
                    {
                        // New Activity
                        phylum.ActivityCount += 1;
                        int currentID = phylum.ActivityCount;
                        // Compile
                        branches[i - 1].Action.Compile(phylum);
                        // Connect
                        phylum.Merge(triggerID + ".internal.closed", currentID + ".internal.initialized");
                        phylum.Merge(p2, currentID + ".internal.closed");
                    }
                    else
                    {
                        // Empty
                        phylum.Merge(triggerID + ".internal.closed", p2);
                    }
                }
            }
            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);
        }
Пример #5
0
        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 init          = phylum.NewTransition(prefix + "initactivity");
            Transition end           = phylum.NewTransition(prefix + "endwhile");

            phylum.NewArc(p1, evalCondition);
            phylum.NewArc(evalCondition, condition);
            phylum.NewArc(condition, init);
            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
                phylum.NewArc(init, currentID + ".internal.initialized");
                // Merge
                phylum.Merge(p1, currentID + ".internal.closed");
            }
            else
            {
                // Empty
                phylum.NewArc(init, p1);
            }

            return(phylum);
        }
Пример #6
0
        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");

            phylum.NewArc(p1, evalCondition);
            phylum.NewArc(evalCondition, condition);

            // Empty
            if (innerThen == null && innerElse == null)
            {
                Transition finish = phylum.NewTransition(prefix + "finish");
                phylum.NewArc(condition, finish);
                phylum.NewArc(finish, p2);

                return(phylum);
            }

            Transition initThen = phylum.NewTransition(prefix + "initthen");
            Transition initElse = phylum.NewTransition(prefix + "inittelse");

            phylum.NewArc(condition, initThen);
            phylum.NewArc(condition, initElse);

            // Then
            if (innerThen != null)
            {
                // New Activity
                phylum.ActivityCount += 1;
                int thenID = phylum.ActivityCount;
                // Compile
                innerThen.Compile(phylum);
                // Connect
                phylum.NewArc(initThen, thenID + ".internal.initialized");
                // Merge
                phylum.Merge(p2, thenID + ".internal.closed");
            }
            else
            {
                // Empty
                phylum.NewArc(initThen, p2);
            }

            // Else
            if (innerElse != null)
            {
                // New Activity
                phylum.ActivityCount += 1;
                int elseID = phylum.ActivityCount;
                // Compile
                innerElse.Compile(phylum);
                // Connect
                phylum.NewArc(initElse, elseID + ".internal.initialized");
                // Merge
                phylum.Merge(p2, elseID + ".internal.closed");
            }
            else
            {
                // Empty
                phylum.NewArc(initElse, p2);
            }

            return(phylum);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        public PetriNet Compile(PetriNet phylum)
        {
            String prefix = phylum.ActivityCount + ".internal.";

            Place p1 = phylum.NewPlace(prefix + "initialized");
            Place p2 = phylum.NewPlace(prefix + "closed");

            if (startNode == null)
            {
                // New Activity
                phylum.ActivityCount += 1;
                int currentID = phylum.ActivityCount;
                // Compile
                new Empty().Compile(phylum);
                // Merge
                phylum.Merge(p1, currentID + ".internal.initialized");
                phylum.Merge(p2, currentID + ".internal.closed");

                return(phylum);
            }

            // Create Steps
            foreach (FlowNode node in steps)
            {
                if (node is FlowStep)
                {
                    FlowStep step       = (FlowStep)node;
                    String   prefixStep = prefix + step.Id + ".";

                    Place stp1 = phylum.NewPlace(prefixStep + "start");
                    Place stp2 = phylum.NewPlace(prefixStep + "next");

                    phylum.ActivityCount += 1;
                    int currentID = phylum.ActivityCount;
                    // Action Activity
                    step.Action.Compile(phylum);
                    // Connect
                    phylum.Merge(stp1, currentID + ".internal.initialized");
                    phylum.Merge(stp2, currentID + ".internal.closed");
                }
                else if (node is FlowDecision)
                {
                    FlowDecision dec        = (FlowDecision)node;
                    String       prefixStep = prefix + dec.Id + ".";

                    Place      dp1           = phylum.NewPlace(prefixStep + "start");
                    Place      condition     = phylum.NewPlace(prefixStep + "condition");
                    Place      right         = phylum.NewPlace(prefixStep + "true");
                    Place      wrong         = phylum.NewPlace(prefixStep + "false");
                    Transition evalCondition = phylum.NewTransition(prefixStep + "evalcondition");
                    Transition startTrue     = phylum.NewTransition(prefixStep + "starttrue");
                    Transition startFalse    = phylum.NewTransition(prefixStep + "startfalse");
                    // Connect
                    phylum.NewArc(dp1, evalCondition);
                    phylum.NewArc(evalCondition, condition);
                    phylum.NewArc(condition, startTrue);
                    phylum.NewArc(condition, startFalse);
                    phylum.NewArc(startTrue, right);
                    phylum.NewArc(startFalse, wrong);
                }
                else if (node is FlowSwitch)
                {
                    FlowSwitch swtch      = (FlowSwitch)node;
                    String     prefixStep = prefix + swtch.Id + ".";

                    Place sp1      = phylum.NewPlace(prefixStep + "start");
                    Place sdefault = phylum.NewPlace(prefixStep + "default");

                    // Inner Petri Net
                    Place lastState = sp1;

                    for (int i = 1; i <= swtch.Branches.Count + 1; i++)
                    {
                        if (i <= swtch.Branches.Count)
                        {
                            Place      cond     = phylum.NewPlace(prefixStep + "condition" + i);
                            Place      state    = phylum.NewPlace(prefixStep + "case" + i);
                            Transition evalCase = phylum.NewTransition(prefixStep + "evalcase" + i);
                            Transition initCase = phylum.NewTransition(prefixStep + "initcase" + i);
                            phylum.NewArc(lastState, evalCase);
                            phylum.NewArc(evalCase, cond);
                            phylum.NewArc(cond, initCase);
                            phylum.NewArc(initCase, state);
                            // LastState
                            lastState = cond;
                        }
                        else
                        {
                            Transition initDefault = phylum.NewTransition(prefixStep + "initdefault");
                            phylum.NewArc(lastState, initDefault);
                            phylum.NewArc(initDefault, sdefault);
                        }
                    }
                }
            }
            // Merge
            // StartNode
            phylum.Merge(p1, prefix + steps.First(e => e.Id.Equals(startNode)).Id + ".start");

            foreach (FlowNode node in steps)
            {
                if (node is FlowStep)
                {
                    FlowStep step       = (FlowStep)node;
                    String   prefixStep = prefix + step.Id + ".";

                    if (step.Next != null)
                    {
                        phylum.Merge(prefixStep + "next", prefix + step.Next + ".start");
                    }
                    else
                    {
                        phylum.Merge(p2, prefixStep + "next");
                    }
                }
                else if (node is FlowDecision)
                {
                    FlowDecision dec            = (FlowDecision)node;
                    String       prefixDecision = prefix + dec.Id + ".";

                    if (dec.Right != null)
                    {
                        phylum.Merge(prefixDecision + "true", prefix + dec.Right + ".start");
                    }
                    else
                    {
                        phylum.Merge(p2, prefixDecision + "true");
                    }

                    if (dec.Wrong != null)
                    {
                        phylum.Merge(prefixDecision + "false", prefix + dec.Wrong + ".start");
                    }
                    else
                    {
                        phylum.Merge(p2, prefixDecision + "false");
                    }
                }
                else if (node is FlowSwitch)
                {
                    FlowSwitch swtch        = (FlowSwitch)node;
                    String     prefixSwitch = prefix + swtch.Id + ".";

                    //Default
                    if (swtch.Default != null)
                    {
                        phylum.Merge(prefixSwitch + "default", prefix + swtch.Default + ".start");
                    }
                    else
                    {
                        phylum.Merge(p2, prefixSwitch + "default");
                    }
                    // Branches
                    for (int i = 1; i <= swtch.Branches.Count; i++)
                    {
                        phylum.Merge(prefixSwitch + "case" + i, prefix + swtch.Branches[i - 1] + ".start");
                    }
                }
            }

            return(phylum);
        }