Beispiel #1
0
        //private bool AllBackwardPathsContain(IPfcNode from, IPfcNode target, Stack<IPfcNode> path) {
        //    if (from.PredecessorNodes.Count() == 0) {
        //        return false;
        //    } else if (from == target) {
        //        return true;
        //    } else {
        //        foreach (IPfcNode pred in from.PredecessorNodes) {
        //            if (!path.Contains(pred)) {
        //                path.Push(pred);
        //                if (!AllBackwardPathsContain(pred, target, path))
        //                    return false;
        //                path.Pop();
        //            }
        //        }
        //        return true;
        //    }
        //}

        private IPfcNode DivergenceNodeFor(IPfcNode closure)
        {
            NodeValidationData nvd = GetValidationData(closure);
            //if (nvd.DivergenceNode != null)
            //    return nvd.DivergenceNode;

            List <IPfcNode> possibles = new List <IPfcNode>();

            foreach (IPfcTransitionNode trans in m_pfc.Transitions)
            {
                if (Node1DependsOnNode2(closure, trans))
                {
                    possibles.Add(trans);
                }
            }
            possibles.Sort(new PfcNode.NodeComparer());
            possibles.Reverse();

            foreach (IPfcNode possible in possibles)
            {
                m_pfc.Nodes.ForEach(n => GetValidationData(n).IsInPath = null);
                if (AllBackwardPathsContain(closure, possible))
                {
                    return(possible);
                }
            }
            return(null);
        }
Beispiel #2
0
        /// <summary>
        /// Validates the PFC in this instance, and sets (MUST SET) the m_pfcIsValid to true or false.
        /// </summary>
        private void Validate()
        {
            try
            {
                m_activePath = new Queue <QueueData>();

                foreach (IPfcNode node in m_pfc.Nodes)
                {
                    NodeValidationData.Attach(node);
                }
                foreach (IPfcLinkElement link in m_pfc.Links)
                {
                    LinkValidationData.Attach(link);
                }
                BuildDependencies();
                Propagate();
                Check();

                DateTime finish = DateTime.Now;
                foreach (IPfcNode node in m_pfc.Nodes)
                {
                    NodeValidationData.Detach(node);
                }
                foreach (IPfcLinkElement link in m_pfc.Links)
                {
                    LinkValidationData.Detach(link);
                }
            }
            catch (Exception e)
            {
                m_errorList.Add(new PfcValidationError("Exception while validating.", e.Message, null));
                m_pfcIsValid = false;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Determines whether all backward paths from 'from' contain the node 'target.' If they do,
        /// and it is the first such encounter for a specific 'from' then it may be said that target
        /// is the divergence node for 'from.'
        /// </summary>
        /// <param name="from">From.</param>
        /// <param name="target">The target.</param>
        /// <returns></returns>
        private bool AllBackwardPathsContain(IPfcNode from, IPfcNode target)
        {
            NodeValidationData nvd = GetValidationData(from);

            if (nvd.IsInPath == null)
            {
                if (!from.PredecessorNodes.Any())
                {
                    nvd.IsInPath = false;
                }
                else if (from == target)
                {
                    nvd.IsInPath = true;
                }
                else
                {
                    nvd.IsInPath = true;
                    foreach (IPfcNode predecessorNode in from.PredecessorNodes)
                    {
                        if (!AllBackwardPathsContain(predecessorNode, target))
                        {
                            nvd.IsInPath = false;
                            break;
                        }
                    }
                }
            }
            return(nvd.IsInPath.Value);
        }
Beispiel #4
0
        private bool AllForwardPathsContain(IPfcNode from, IPfcNode target, Stack <IPfcNode> path)
        {
            NodeValidationData nvd = GetValidationData(from);

            if (nvd.IsInPath == null)
            {
                if (from.SuccessorNodes.Count() == 0)
                {
                    nvd.IsInPath = false;
                }
                else if (from == target)
                {
                    nvd.IsInPath = true;
                }
                else
                {
                    nvd.IsInPath = true;
                    foreach (IPfcNode succ in from.SuccessorNodes)
                    {
                        if (!AllForwardPathsContain(succ, target, path))
                        {
                            nvd.IsInPath = false;
                            break;
                        }
                    }
                }
            }
            return(nvd.IsInPath.Value);
        }
Beispiel #5
0
            public static void Detach(IPfcNode node)
            {
                NodeValidationData vd = node.UserData as NodeValidationData;

                if (vd != null)
                {
                    node.UserData = vd.m_userData;
                }
            }
Beispiel #6
0
        private void Enqueue(IPfcNode from, IPfcNode node, ValidationToken vt)
        {
            NodeValidationData vd = GetValidationData(node);

            if (vd.InputRole == InputRole.ParallelConvergence)
            {
                GetValidationData(from).ValidationToken.DecrementAlternatePathsOpen();
            }
            vd.ValidationToken = vt;
            m_activePath.Enqueue(new QueueData(from, node));
            if (m_diagnostics)
            {
                Console.WriteLine("\tEnqueueing {0} with {1} ({2}).", node.Name, vt, vt.AlternatePathsOpen);
            }
        }
Beispiel #7
0
        private bool AllParallelAndAtLeastOneOfEachSetOfSerialPathsContain(IPfcNode from, IPfcNode target)
        {
            NodeValidationData nvd = GetValidationData(from);

            if (nvd.IsInPath == null)
            {
                if (!from.SuccessorNodes.Any())
                {
                    nvd.IsInPath = false;
                }
                else if (from == target)
                {
                    nvd.IsInPath = true;
                }
                else if (from.SuccessorNodes.Count == 1)
                {
                    return(AllParallelAndAtLeastOneOfEachSetOfSerialPathsContain(from.SuccessorNodes[0], target));
                }
                else // It's a divergence.
                {
                    if (from is IPfcStepNode)
                    { // serial divergence.
                        bool retval = false;
                        foreach (IPfcNode successorNode in from.SuccessorNodes)
                        {
                            retval |= AllParallelAndAtLeastOneOfEachSetOfSerialPathsContain(successorNode, target);
                        }
                        return(retval);
                    }
                    else
                    { // parallel divergence.
                        bool retval = true;
                        foreach (IPfcNode successorNode in from.SuccessorNodes)
                        {
                            retval &= AllParallelAndAtLeastOneOfEachSetOfSerialPathsContain(successorNode, target);
                        }
                        return(retval);
                    }
                }
            }
            return(nvd.IsInPath.Value);
        }
Beispiel #8
0
        private void Check()
        {
            m_errorList = new List <PfcValidationError>();
            List <ValidationToken> tokensWithLiveChildren         = new List <ValidationToken>();
            List <ValidationToken> tokensWithOpenAlternates       = new List <ValidationToken>();
            List <IPfcNode>        unreachableNodes               = new List <IPfcNode>();
            List <IPfcNode>        unexecutedNodes                = new List <IPfcNode>();
            List <IPfcStepNode>    inconsistentSerialConvergences = new List <IPfcStepNode>();

            #region Collect errors

            foreach (IPfcNode node in m_pfc.Nodes)
            {
                NodeValidationData nodeVd = GetValidationData(node);
                ValidationToken    nodeVt = nodeVd.ValidationToken;
                if (nodeVt == null)
                {
                    unreachableNodes.Add(node);
                    unexecutedNodes.Add(node);
                }
                else
                {
                    if (nodeVt.AlternatePathsOpen > 0 && !tokensWithOpenAlternates.Contains(nodeVt))
                    {
                        tokensWithOpenAlternates.Add(GetValidationData(node).ValidationToken);
                    }
                    if (!nodeVd.NodeHasRun)
                    {
                        unexecutedNodes.Add(node);
                    }

                    if (node.ElementType == PfcElementType.Step && node.PredecessorNodes.Count() > 1)
                    {
                        ValidationToken vt = GetValidationData(node.PredecessorNodes[0]).ValidationToken;
                        if (!node.PredecessorNodes.TrueForAll(n => GetValidationData(n).ValidationToken.Equals(vt)))
                        {
                            inconsistentSerialConvergences.Add((IPfcStepNode)node);
                        }
                    }

                    if (nodeVt.AnyChildLive)
                    {
                        tokensWithLiveChildren.Add(nodeVt);
                    }
                }
            }

            #endregion

            m_pfcIsValid = tokensWithLiveChildren.Count() == 0 &&
                           tokensWithOpenAlternates.Count() == 0 &&
                           unreachableNodes.Count() == 0 &&
                           unexecutedNodes.Count() == 0 &&
                           inconsistentSerialConvergences.Count() == 0;

            StringBuilder sb = null;
            sb = new StringBuilder();

            unreachableNodes.Sort(m_nodeByName);
            unexecutedNodes.Sort(m_nodeByName);
            inconsistentSerialConvergences.Sort(m_stepNodeByName);

            foreach (IPfcNode node in unreachableNodes)
            {
                if (!node.PredecessorNodes.TrueForAll(n => GetValidationData(n).ValidationToken == null))
                {
                    string narrative = string.Format("Node {0}, along with others that follow it, is unreachable.",
                                                     node.Name);
                    m_errorList.Add(new PfcValidationError("Unreachable PFC Node", narrative, node));
                    sb.AppendLine(narrative);
                }
            }

            foreach (IPfcNode node in unexecutedNodes)
            {
                if (!node.PredecessorNodes.TrueForAll(n => GetValidationData(n).ValidationToken == null))
                {
                    string narrative = string.Format("Node {0} failed to run.", node.Name);
                    m_errorList.Add(new PfcValidationError("Unexecuted PFC Node", narrative, node));
                    sb.AppendLine(narrative);
                }
            }

            inconsistentSerialConvergences.Sort((n1, n2) => Comparer.Default.Compare(n1.Name, n2.Name));

            foreach (IPfcStepNode node in inconsistentSerialConvergences)
            {
                string narrative =
                    string.Format(
                        "Branch paths (serial convergences) into {0} do not all have the same validation token, meaning they came from different branches (serial divergences).",
                        node.Name);
                m_errorList.Add(new PfcValidationError("Serial Di/Convergence Mismatch", narrative, node));
                sb.AppendLine(narrative);
            }

            foreach (ValidationToken vt in tokensWithLiveChildren)
            {
                List <IPfcNode> liveNodes = new List <IPfcNode>();
                foreach (ValidationToken vt2 in vt.ChildNodes.Where(n => n.AlternatePathsOpen > 0))
                {
                    liveNodes.Add(vt2.Origin);
                }

                int nParallelsOpen = vt.ChildNodes.Count();

                string narrative =
                    string.Format(
                        "Under {0}, there {1} {2} parallel branch{3} that did not complete - {4} began at {5}.",
                        vt.Origin.Name,
                        nParallelsOpen == 1 ? "is" : "are",
                        nParallelsOpen,
                        nParallelsOpen == 1 ? "" : "es",
                        nParallelsOpen == 1 ? "it" : "they",
                        StringOperations.ToCommasAndAndedList <IPfcNode>(liveNodes, n => n.Name)
                        );

                m_errorList.Add(new PfcValidationError("Uncompleted Parallel Branches", narrative, vt.Origin));
                sb.AppendLine();
            }

            if (m_diagnostics)
            {
                Console.WriteLine(sb.ToString());
            }
        }