Пример #1
0
        public void ContractChains()
        {
            HasseNodeCollection VisitedNodes = new HasseNodeCollection();
            // identify vertices with one edge in and one edge out, put them on remove list
            List <HasseNode> ToBeRemoved = new List <HasseNode>();

            foreach (HasseNode Node in HasseDiagramNodes.Values)
            {
                if (!VisitedNodes.ContainsKey(Node.KeyString))
                {
                    if (Node.EdgesToCovered.Count == 1 && Node.EdgesToCovering.Count == 1)
                    {
                        ToBeRemoved.Add(Node);
                    }
                    VisitedNodes.Add(Node.KeyString, Node);
                }
            }

            //now contract nodes A-B-C to form A-C, then throw away B
            foreach (HasseNode Node in ToBeRemoved)
            {
                HasseNode Node1 = Node.EdgesToCovered[0].LowerNode;
                HasseNode Node2 = Node.EdgesToCovering[0].UpperNode;
                this.MakeEdge(Node1, Node2);
                this.RemoveEdge(Node.EdgesToCovered[0]);
                this.RemoveEdge(Node.EdgesToCovering[0]);
                HasseDiagramNodes.Remove(Node.KeyString);
            }
        }
Пример #2
0
        public static HasseNodeCollection FindLub(HasseNode ReferenceNode, HasseNodeCollection AllNodes)
        {
            bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_DEBUG_MAKE_LUB);
            HasseNodeCollection lub = new HasseNodeCollection();
            //List<string> ToBeRemoved = new List<string>();
            HashSet <string> ToBeRemoved = new HashSet <string>();

            foreach (HasseNode Node in AllNodes.Values)
            {
                if (!ToBeRemoved.Contains(Node.KeyString))
                {
                    System.Diagnostics.Debug.WriteLineIf(dbg, "test if " + Node.KeyString + " is larger than " + ReferenceNode.KeyString);


                    // debug:
                    //HasseNode[] subobj = ReferenceNode.getElementarySubobjects().Values.ToArray();
                    //if (!Node.HasElements(subobj) &&
                    //    (Node.IsLargerThan(ReferenceNode)))
                    //{
                    //    System.Diagnostics.Debugger.Break();
                    //}


                    if (Node.IsLargerThan(ReferenceNode))
                    {
                        System.Diagnostics.Debug.WriteLineIf(dbg, " yes - is lub candidate, delete above...");
                        lub.Add(Node.KeyString, Node);
                        FindNodesAbove(Node, ToBeRemoved, 0);
                    }

                    /*
                     * else if (ReferenceNode.IsLargerThan(Node))
                     * {
                     *  DeleteNodesBelow(Node, ToBeRemoved, 0);
                     * }
                     */
                    else
                    {
                        ToBeRemoved.Add(Node.KeyString);
                    }
                }
            }

            foreach (string key in ToBeRemoved)
            {
                lub.Remove(key);
            }

            return(lub);
        }
Пример #3
0
        public void ContractChains2()
        {
            // identify vertices with one edge out, put them on remove list
            HasseNodeCollection VisitedNodes = new HasseNodeCollection();
            List <HasseNode>    ToBeRemoved  = new List <HasseNode>();

            foreach (HasseNode Node in HasseDiagramNodes.Values)
            {
                if (!VisitedNodes.ContainsKey(Node.KeyString))
                {
                    if (Node.EdgesToCovering.Count == 1)
                    {
                        foreach (HasseEdge TheCoveringEdge in Node.EdgesToCovering)
                        {
                            if (TheCoveringEdge.UpperNode.EdgesToCovered.Count == 1)
                            {
                                ToBeRemoved.Add(Node);
                            }
                        }
                    }
                    VisitedNodes.Add(Node.KeyString, Node);
                }
            }

            //now contract nodes A-B to form B
            // B must inherit innodes as into A, then throw away A
            foreach (HasseNode Node in ToBeRemoved)
            {
                HasseEdge EdgeUpToCovering = Node.EdgesToCovering[0];
                HasseNode NodeCovering     = EdgeUpToCovering.UpperNode;
                //HasseNode Node2 = null;

                System.Diagnostics.Debug.WriteLine("contract  [" + Node.KeyString + "]-[" + NodeCovering.KeyString + "]");
                RemoveEdge(EdgeUpToCovering);

                // make list of edges to covered
                HasseEdge[] EdgesToCovered = Node.EdgesToCovered.ToArray();

                foreach (HasseEdge E2 in EdgesToCovered)
                {
                    HasseNode Node2 = E2.LowerNode;
                    // inherit edges from those that Node covers
                    this.MakeEdge(Node2, NodeCovering);
                    this.RemoveEdge(E2);
                }
                HasseDiagramNodes.Remove(Node.KeyString);
            }
        }
Пример #4
0
        // ==========================================


        public HasseDiagram(HasseNodeFactory.NodeType t)
        {
            // construct new HasseDiagram
            HasseDiagramNodes = new HasseNodeCollection();  //collection nodes in diagram
            DifferenceNodes   = new HasseNodeCollection();  //collection of objects expressing difference
            //ElementaryHasseNodes = new HasseNodeCollection(); // collection of elements

            // factory for nodes, set its nodetype and let it have access to global elements collection
            diagramNodeFactory    = new HasseNodeFactory(t);
            differenceNodeFactory = new HasseNodeFactory(t);

            // a queue for nodes to be created after current node is fully processed
            FragmentInsertionQueue = new HasseFragmentInsertionQueue(HasseDiagramNodes);

            // create the root node as part of construction
            RootNode = diagramNodeFactory.NewNode("", HasseNode.HasseNodeTypes.ROOT, "");
            HasseDiagramNodes.Add("{}", RootNode);
        }
Пример #5
0
        public static HasseNodeCollection BruteForceFindGlb(HasseNode @ref, HasseNodeCollection AllNodes)
        {
            if (@ref.KeyString.Equals("x"))
            {
                System.Diagnostics.Debugger.Break();
            }

            HasseNodeCollection glb         = new HasseNodeCollection();
            List <string>       ToBeRemoved = new List <string>();

            foreach (HasseNode Node in AllNodes.Values)
            {
                if (@ref.IsLargerThan(Node))
                {
                    glb.Add(Node.KeyString, Node);
                }
            }


            foreach (HasseNode Node in glb.Values)
            {
                foreach (HasseNode Node2 in glb.Values)
                {
                    if (Node != Node2)
                    {
                        if (Node.IsLargerThan(Node2))
                        {
                            ToBeRemoved.Add(Node2.KeyString);
                        }
                        //           break;
                    }
                }
            }
            foreach (string key in ToBeRemoved)
            {
                glb.Remove(key);
            }

            return(glb);
        }
Пример #6
0
        public static HasseNodeCollection FindGlb(HasseNode ReferenceNode, HasseNodeCollection AllNodes)
        {
            bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_DEBUG_MAKE_GLB);
            HasseNodeCollection glb = new HasseNodeCollection();
            //List<string> ToBeRemoved = new List<string>();
            HashSet <string> ToBeRemoved = new HashSet <string>();

            foreach (HasseNode Node in AllNodes.Values)
            {
                if (!ToBeRemoved.Contains(Node.KeyString))
                {
                    System.Diagnostics.Debug.WriteLineIf(dbg, "test if " + ReferenceNode.KeyString + " is larger than " + Node.KeyString);
                    if (ReferenceNode.IsLargerThan(Node))
                    {
                        System.Diagnostics.Debug.WriteLineIf(dbg, " yes - is glb candidate, delete below...");
                        glb.Add(Node.KeyString, Node);
                        FindNodesBelow(Node, ToBeRemoved, 0);
                    }

                    /*   else if (Node.IsLargerThan(ReferenceNode))
                     * {
                     *     DeleteNodesAbove(Node, ToBeRemoved, 0);
                     * }
                     */
                    else
                    {
                        ToBeRemoved.Add(Node.KeyString);
                    }
                }
            }

            foreach (string key in ToBeRemoved)
            {
                glb.Remove(key);
            }

            return(glb);
        }
Пример #7
0
        public static HasseNodeCollection BruteForceFindLub(HasseNode @ref, HasseNodeCollection AllNodes)
        {
#if DEBUG
            // if (@ref.UniqueString.Equals("*B*")) {
            //    System.Diagnostics.Debugger.Break();
            // }
#endif

            HasseNodeCollection lub         = new HasseNodeCollection();
            List <string>       ToBeRemoved = new List <string>();
            foreach (HasseNode Node in AllNodes.Values)
            {
                if (Node.IsLargerThan(@ref))
                {
                    lub.Add(Node.KeyString, Node);
                }
            }

            foreach (HasseNode Node in lub.Values)
            {
                foreach (HasseNode Node2 in lub.Values)
                {
                    if (Node2.IsLargerThan(Node))
                    {
                        ToBeRemoved.Add(Node2.KeyString);
                        //break;
                    }
                }
            }
            foreach (string key in ToBeRemoved)
            {
                lub.Remove(key);
            }

            return(lub);
        }
Пример #8
0
        private HasseEdge MakeEdge(HasseNode N1, HasseNode N2)
        {
            // returns new edge. If already exists, returns null
            if ((N1 == null) || (N2 == null))
            {
                throw new Exception("MakeEdge with null argument");
            }
            if (ExistsEdge(N1, N2))
            {
                return(null);
            }

            HasseEdge E = new HasseEdge();

            E.LowerNode = N1;
            E.UpperNode = N2;
            N1.EdgesToCovering.Add(E);
            N2.EdgesToCovered.Add(E);

            // analyse difference between smaller and larger.
            // output can be the *-marked smaller node + all difference fragments
            // or can be partial
            if ((LABEL_EDGES_WITH_DIFFERENCE) && (N1 != RootNode))
            {
                string[] EdgeLabels = N1.GetDifferenceString(N2);
                E.LabelText = String.Join(", ", EdgeLabels);


                foreach (string s in EdgeLabels)
                {
                    if (E.LabelText.Contains("~~~")) //for debug
                    {
                        System.Diagnostics.Debugger.Break();
                    }


                    // For difference fragments, add link between fragment and those
                    // edges giving this Node as difference.
                    // The link is for efficient updates of difference items, it is not an edge in hasse diagram

                    //if (N1 != RootNode) // do not make difference here
                    //{
                    HasseNode DifferenceNode = null;
                    if (DifferenceNodes.ContainsKey(s))      // if such node already exists in differenc nodes
                    {
                        DifferenceNode = DifferenceNodes[s]; //  get that node
                    }
                    else
                    if (HasseDiagramNodes.ContainsKey(s))          // if already exists in diagram nodes
                    {
                        DifferenceNode = HasseDiagramNodes[s];     // get reference
                        // add difference type
                        DifferenceNode.AddNodeType(HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT);
                        // and add to difference catalog
                        DifferenceNodes.Add(DifferenceNode.KeyString, DifferenceNode);
                    }
                    else         // not exist anywhere
                    {
                        // create and add to differene node catalog

                        // need to create to get keystring - not same as s!
                        DifferenceNode = this.differenceNodeFactory.NewNode(s, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT, "diff");
                        if (DifferenceNodes.ContainsKey(DifferenceNode.KeyString))
                        {
                            DifferenceNode = DifferenceNodes[DifferenceNode.KeyString];
                        }
                        else
                        {
                            DifferenceNodes.Add(DifferenceNode.KeyString, DifferenceNode);
                        }
                        // DifferenceNode = new StringHasseNode(HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT,this.ElementaryHasseNodes);
                        //      s, HasseNode.HasseNodeTypes.FRAGMENT | HasseNode.HasseNodeTypes.DIFFERENCE_FRAGMENT,
                        //      this.ElementaryHasseNodes);
                    }

                    DifferenceNode.AddLinkToEdge(E);     // create the link
                    //}
                }
            }
            return(E);
        }
Пример #9
0
        private bool addNode(HasseNode newNode, HasseNode[] AboveTheseNodes, HasseNode[] BelowTheseNodes)
        {
            // should return true if node was inserted
            // or false if corresponding node already exist

            bool debug      = Convert.ToBoolean(DEBUGLEVEL & LOG_INSERTIONS);
            bool dbgTimings = Convert.ToBoolean(DEBUGLEVEL & LOG_ALL_TIMINGS);

            sw.Reset();
            sw.Start();

            if (newNode.Size() < MINIMUM_FRAGMENT_SIZE)
            {
                return(false);
            }

            // do not add identical objects
            if (HasseDiagramNodes.ContainsKey(newNode.KeyString))
            {
                // is already there - we will update type, set name, redraw image, then return.
                HasseDiagramNodes[newNode.KeyString].AddNodeType(newNode.NodeType);
                if (newNode.HasNodeType(HasseNode.HasseNodeTypes.REAL))
                {
                    string n = newNode.GetName();
                    HasseDiagramNodes[newNode.KeyString].SetName(n);
                    //if (CREATE_NODE_IMAGE) HasseDiagramNodes[newNode.KeyString].CreateImage();
                    System.Diagnostics.Debug.WriteLineIf(debug, " Skipping add of " + newNode.KeyString);
                }
                return(false);
            }
            //if (CREATE_NODE_IMAGE) newNode.CreateImage();
            CountAdditions += 1;

            if (DEBUGLEVEL > 0)
            {
                System.Diagnostics.Debug.WriteLine("Add Node " + newNode.KeyString + " " + CountAdditions.ToString());
            }


            // loop elements of new object

            /*
             * foreach (HasseNode Element in newNode.getElementarySubobjects().Values)
             *   {
             *       if (USE_ELEMENTS)
             *       {
             *           // add to diagram nodes list if not already there
             *           if (!HasseDiagramNodes.ContainsKey(Element.KeyString))
             *           {
             *               HasseDiagramNodes.Add(Element.KeyString, Element);
             *               //Element.CreateImage();
             *               this.MakeEdge(RootNode, Element);
             *           }
             *       }
             *       // add to elements collection if not there already
             *       if (!ElementaryHasseNodes.ContainsKey(Element.KeyString))
             *           ElementaryHasseNodes.Add(Element.KeyString, Element);
             *   }
             */


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks add 1 (init) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();

            System.Diagnostics.Debug.WriteLineIf(debug, "=== Start LUB and GLB for " + newNode.KeyString + " ===");

            if (CountAdditions == -1)
            {
                System.Diagnostics.Debugger.Break();
            }

            HasseNodeCollection NodesInGreatestLowerBound = null;
            HasseNodeCollection NodesInLeastUpperBound    = null;

            FindLUBAndGLB(newNode, ref NodesInLeastUpperBound, ref NodesInGreatestLowerBound);


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 2 (got lub and glb) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();
            System.Diagnostics.Debug.WriteLineIf(debug, "=== Done LUB and GLB =======");

            List <HasseEdge> NewlyFormedEdges = InsertNodeBetweenGlbAndLub(
                newNode, NodesInLeastUpperBound, NodesInGreatestLowerBound, debug);

            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 3 (inserted new) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();

            if (Convert.ToBoolean(CHECK_LEVEL & CHECK_ALL))
            {
                newNode.validate();
            }

            if (MAKE_MCS_AT_ONCE)
            {
                FindCommonFragments(newNode);
            }


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 4 (made MCS)" + sw.ElapsedTicks.ToString());
            // The node may be there already, just added, as element if it is both element and real
            // if (!newNode.HasNodeType(HasseNode.HasseNodeTypes.ELEMENT))
            HasseDiagramNodes.Add(newNode.KeyString, newNode);
            return(true);
        }
        public static String Report(HasseNodeCollection nodes, HasseNode rootNode)
        {
            int countLeaves = 0;
            int countReals  = 0;

            foreach (HasseNode node in nodes.Values)
            {
                if (node.IsLeafNode())
                {
                    countLeaves++;
                }
                if (node.HasNodeType(HasseNode.HasseNodeTypes.REAL))
                {
                    countReals++;
                }
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Leaf count: " + countLeaves.ToString());
            sb.AppendLine("REAL count: " + countReals.ToString());

            // how selective are the root nodes?
            // the average root node, how many parents, of all?


            List <HasseNodeCollection> NodesInLevel = new List <HasseNodeCollection>();
            int CountUpwardEdges = 0;
            int CountLeafNodes   = 0;
            int countAllLeaves   = 0;
            HasseNodeCollection NodesOnThisLevel = new HasseNodeCollection();

            NodesOnThisLevel.Add(rootNode.KeyString, rootNode);

            HasseNodeCollection NodesOnThisLevelPlusOne = new HasseNodeCollection();

            for (int level = 1; ; level++)
            {
                CountUpwardEdges = 0;
                CountLeafNodes   = 0;
                foreach (HasseNode node in NodesOnThisLevel.Values)
                {
                    node.LevelFromRoot = level;
                    foreach (HasseEdge EdgeUpToParent in node.EdgesToCovering)
                    {
                        HasseNode Parent = EdgeUpToParent.UpperNode;
                        CountUpwardEdges++;
                        if (!NodesOnThisLevelPlusOne.ContainsKey(Parent.KeyString))
                        {
                            NodesOnThisLevelPlusOne.Add(Parent.KeyString, Parent);
                        }
                    }
                    if (node.EdgesToCovering.Count == 0)
                    {
                        CountLeafNodes++; countAllLeaves++;
                    }
                }

                sb.AppendLine("at level " + level.ToString() + ";\tnodes: " + NodesOnThisLevel.Count.ToString() + "\tsum upward edges: " + CountUpwardEdges.ToString() + "\t count leaf nodes: " + CountLeafNodes.ToString());

                NodesInLevel.Add(NodesOnThisLevel);
                if (NodesOnThisLevelPlusOne.Count == 0)
                {
                    break;
                }
                NodesOnThisLevel        = NodesOnThisLevelPlusOne;
                NodesOnThisLevelPlusOne = new  HasseNodeCollection();
            }
            sb.AppendLine("total node count: " + nodes.Count.ToString());
            sb.AppendLine("total leaves count: " + countAllLeaves.ToString());

            return(sb.ToString());
        }