Example #1
0
        /// <summary>
        /// Merge two nodes. Both of them become equiualent.
        ///
        /// In complex situation, 'secondary' node becomes reference to 'main' node, if it is possible
        /// </summary>
        public static void MergeInplace(TicNode main, TicNode secondary)
        {
            if (main == secondary)
            {
                return;
            }
            if (main.State is StateRefTo)
            {
                var nonreferenceMain      = main.GetNonReference();
                var nonreferenceSecondary = secondary.GetNonReference();
                MergeInplace(nonreferenceMain, nonreferenceSecondary);
                return;
            }
            if (secondary.GetNonReference() == main)
            {
                return;
            }
            var res = GetMergedStateOrNull(main.State, secondary.State);

            if (res == null)
            {
                throw TicErrors.CannotMerge(main, secondary);
            }

            main.State = res;
            if (res is ITypeState t && t.IsSolved)
            {
                secondary.State = res;
                return;
            }
            main.AddAncestors(secondary.Ancestors.Where(a => a != main));
            secondary.ClearAncestors();
            secondary.State = new StateRefTo(main);
        }
Example #2
0
        private TicNode GetNonReferenceNodeOrNull(TicNode node)
        {
            if (node.VisitMark == _nodeInListMark)
            {
                return(node);
            }
            if (!(node.State is StateRefTo refTo))
            {
                return(node);
            }
            if (node.VisitMark == RefVisitingMark)
            {
                return(null);
            }
            node.VisitMark = RefVisitingMark;
            var res = GetNonReferenceNodeOrNull(refTo.Node);

            if (res == null)
            {
                _refRoute.Push(node);
            }
            else
            {
                node.VisitMark = -1;
                //merge
                if (node.Ancestors.Any())
                {
                    res.AddAncestors(node.Ancestors);
                    node.ClearAncestors();
                }
            }
            return(res);
        }