private static bool Reify(this LineSegmentSymbol lineSegSymbol,
                                  PointSymbol ps1, PointSymbol ps2)
        {
            //if (!lineSeg.RelationStatus) return false;
            lineSegSymbol.CachedSymbols.Clear(); //re-compute purpose

            var shape1Lst = new List <PointSymbol>();
            var shape2Lst = new List <PointSymbol>();

            #region Caching Point 1
            if (ps1.Shape.Concrete)
            {
                shape1Lst.Add(ps1);
            }
            else
            {
                foreach (var shapeSymbol in ps1.CachedSymbols.ToList())
                {
                    var ptTemp = shapeSymbol as PointSymbol;
                    Debug.Assert(ptTemp != null);
                    if (ptTemp.Shape.Concrete)
                    {
                        shape1Lst.Add(ptTemp);
                    }
                }
            }
            #endregion

            #region Caching Point 2
            if (ps2.Shape.Concrete)
            {
                shape2Lst.Add(ps2);
            }
            else
            {
                foreach (var shapeSymbol in ps2.CachedSymbols.ToList())
                {
                    var ptTemp = shapeSymbol as PointSymbol;
                    Debug.Assert(ptTemp != null);
                    if (ptTemp.Shape.Concrete)
                    {
                        shape2Lst.Add(ptTemp);
                    }
                }
            }
            #endregion

            #region Generate caching linesegment

            if (shape1Lst.Count == 0 || shape2Lst.Count == 0)
            {
                return(false);
            }
            foreach (var gPt1 in shape1Lst)
            {
                foreach (var gPt2 in shape2Lst)
                {
                    Debug.Assert(gPt1 != null);
                    Debug.Assert(gPt2 != null);

                    var gPoint1 = gPt1.Shape as Point;
                    var gPoint2 = gPt2.Shape as Point;
                    Debug.Assert(gPoint1 != null);
                    Debug.Assert(gPoint2 != null);
                    Debug.Assert(gPoint1.Concrete);
                    Debug.Assert(gPoint2.Concrete);

                    var lineTemp = LineSegmentGenerationRule.GenerateLineSegment(gPoint1, gPoint2);
                    if (lineTemp != null)
                    {
                        lineSegSymbol.CachedSymbols.Add(lineTemp);
                    }
                }
            }

            #endregion

            return(true);
        }
        public static LineSegmentSymbol Unify(PointSymbol pt1, PointSymbol pt2)
        {
            //point identify check
            if (pt1.Equals(pt2))
            {
                return(null);
            }
            var point1 = pt1.Shape as Point;
            var point2 = pt2.Shape as Point;

            Debug.Assert(point1 != null);
            Debug.Assert(point2 != null);

            //lazy evaluation
            //Constraint solving on Graph
            var lineSeg = new LineSegment(null); //Ghost Line Segment

            lineSeg.Pt1 = point1;
            lineSeg.Pt2 = point2;
            var lss = new LineSegmentSymbol(lineSeg);

            //Line build process
            if (pt1.Shape.Concrete)
            {
                if (pt2.Shape.Concrete)
                {
                    return(LineSegmentGenerationRule.GenerateLineSegment(point1, point2));
                }

                if (pt2.CachedSymbols.Count != 0)
                {
                    foreach (ShapeSymbol ss in pt2.CachedSymbols)
                    {
                        var ps = ss as PointSymbol;
                        Debug.Assert(ps != null);
                        Debug.Assert(ps.Shape.Concrete);
                        var cachePoint = ps.Shape as Point;
                        Debug.Assert(cachePoint != null);
                        var gLss = LineSegmentGenerationRule.GenerateLineSegment(point1, cachePoint);
                        gLss.Traces.AddRange(ps.Traces);
                        lss.CachedSymbols.Add(gLss);
                    }
                }
                return(lss);
            }
            Debug.Assert(!pt1.Shape.Concrete);
            if (pt2.Shape.Concrete)
            {
                if (pt1.CachedSymbols.Count != 0)
                {
                    foreach (ShapeSymbol ss in pt1.CachedSymbols)
                    {
                        var ps = ss as PointSymbol;
                        Debug.Assert(ps != null);
                        Debug.Assert(ps.Shape.Concrete);
                        var cachePoint = ps.Shape as Point;
                        Debug.Assert(cachePoint != null);
                        var gLss = LineSegmentGenerationRule.GenerateLineSegment(cachePoint, point2);
                        gLss.Traces.AddRange(ps.Traces);
                        lss.CachedSymbols.Add(gLss);
                    }
                }
                return(lss);
            }
            Debug.Assert(!pt2.Shape.Concrete);

            foreach (ShapeSymbol ss1 in pt1.CachedSymbols)
            {
                foreach (ShapeSymbol ss2 in pt2.CachedSymbols)
                {
                    var ps1 = ss1 as PointSymbol;
                    Debug.Assert(ps1 != null);
                    Debug.Assert(ps1.Shape.Concrete);
                    var cachePoint1 = ps1.Shape as Point;
                    Debug.Assert(cachePoint1 != null);
                    var ps2 = ss2 as PointSymbol;
                    Debug.Assert(ps2 != null);
                    Debug.Assert(ps2.Shape.Concrete);
                    var cachePoint2 = ps2.Shape as Point;
                    Debug.Assert(cachePoint2 != null);
                    var gLss = LineSegmentGenerationRule.GenerateLineSegment(cachePoint1, cachePoint2);
                    gLss.Traces.AddRange(ps1.Traces);
                    gLss.Traces.AddRange(ps2.Traces);
                    lss.CachedSymbols.Add(gLss);
                }
            }
            return(lss);
        }