//
        // Perpendicular(Segment(A, B), Segment(C, D)), Angle(A, M, D), Angle(D, M, B) -> Congruent(Angle(A, M, D), Angle(D, M, B))
        //
        //                                            B
        //                                           /
        //                              C-----------/-----------D
        //                                         / M
        //                                        /
        //                                       A
        public static List <EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.PERPENDICULAR_IMPLY_CONGRUENT_ADJACENT_ANGLES;

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (!(c is Angle) && !(c is Perpendicular))
            {
                return(newGrounded);
            }

            if (c is Angle)
            {
                Angle newAngle = c as Angle;

                // Find two candidate lines cut by the same transversal
                foreach (Perpendicular perp in candPerpendicular)
                {
                    foreach (Angle oldAngle in candAngles)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(perp, oldAngle, newAngle));
                    }
                }

                candAngles.Add(newAngle);
            }
            else if (c is Perpendicular)
            {
                Perpendicular newPerpendicular = c as Perpendicular;

                // Avoid generating if the situation is:
                //
                //   |
                //   |
                //   |_
                //   |_|_________
                //
                if (newPerpendicular.StandsOnEndpoint())
                {
                    return(newGrounded);
                }

                for (int i = 0; i < candAngles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candAngles.Count; j++)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(newPerpendicular, candAngles[i], candAngles[j]));
                    }
                }

                candPerpendicular.Add(newPerpendicular);
            }

            return(newGrounded);
        }
        //        )  | B
        //         ) |
        // O        )| S
        //         ) |
        //        )  |
        //       )   | A
        // Tangent(Circle(O, R), Segment(A, B)), Intersection(OS, AB) -> Perpendicular(Segment(A,B), Segment(O, S))
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.PERPENDICULAR_TO_RADIUS_IS_TANGENT;

            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is CircleSegmentIntersection)
            {
                CircleSegmentIntersection newInter = clause as CircleSegmentIntersection;

                foreach (Perpendicular oldPerp in candidatePerpendicular)
                {
                    newGrounded.AddRange(InstantiateTheorem(newInter, oldPerp, oldPerp));
                }

                foreach (Strengthened oldStreng in candidateStrengthened)
                {
                    newGrounded.AddRange(InstantiateTheorem(newInter, oldStreng.strengthened as Perpendicular, oldStreng));
                }

                candidateIntersections.Add(newInter);
            }
            else if (clause is Perpendicular)
            {
                Perpendicular newPerp = clause as Perpendicular;

                foreach (CircleSegmentIntersection oldInter in candidateIntersections)
                {
                    newGrounded.AddRange(InstantiateTheorem(oldInter, newPerp, newPerp));
                }

                candidatePerpendicular.Add(newPerp);
            }
            else if (clause is Strengthened)
            {
                Strengthened newStreng = clause as Strengthened;

                if (!(newStreng.strengthened is Perpendicular))
                {
                    return(newGrounded);
                }

                foreach (CircleSegmentIntersection oldInter in candidateIntersections)
                {
                    newGrounded.AddRange(InstantiateTheorem(oldInter, newStreng.strengthened as Perpendicular, newStreng));
                }

                candidateStrengthened.Add(newStreng);
            }

            return(newGrounded);
        }
示例#3
0
        private static List <EdgeAggregator> InstantiateToAltitude(GroundedClause clause)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is Triangle)
            {
                Triangle tri = clause as Triangle;

                foreach (Perpendicular perp in candidatePerpendicular)
                {
                    newGrounded.AddRange(InstantiateToAltitude(tri, perp, perp));
                }

                foreach (Strengthened streng in candidateStrengthened)
                {
                    newGrounded.AddRange(InstantiateToAltitude(tri, streng.strengthened as Perpendicular, streng));
                }

                candidateTriangle.Add(tri);
            }
            else if (clause is Perpendicular)
            {
                Perpendicular perp = clause as Perpendicular;

                foreach (Triangle tri in candidateTriangle)
                {
                    newGrounded.AddRange(InstantiateToAltitude(tri, perp, perp));
                }

                candidatePerpendicular.Add(perp);
            }
            else if (clause is Strengthened)
            {
                Strengthened streng = clause as Strengthened;

                // Only interested in strenghthened intersection -> perpendicular or -> perpendicular bisector
                if (!(streng.strengthened is Perpendicular))
                {
                    return(newGrounded);
                }

                foreach (Triangle tri in candidateTriangle)
                {
                    newGrounded.AddRange(InstantiateToAltitude(tri, streng.strengthened as Perpendicular, streng));
                }

                candidateStrengthened.Add(streng);
            }

            return(newGrounded);
        }
        //
        // Collinear(A, B, C, D, ...) -> Angle(A, B, C), Angle(A, B, D), Angle(A, C, D), Angle(B, C, D),...
        // All angles will have measure 180^o
        // There will be nC3 resulting clauses.
        //
        public static List<KeyValuePair<List<GroundedClause>, GroundedClause>> Instantiate(GroundedClause c)
        {
            if (!(c is Intersection)) return null;

            Intersection pCand = (Intersection)c;
            List<KeyValuePair<List<GroundedClause>, GroundedClause>> newGrounded = new List<KeyValuePair<List<GroundedClause>, GroundedClause>>();

            if (pCand.isPerpendicular == true)
            {
                Perpendicular newPerpendicular = new Perpendicular(pCand.lhs,pCand.rhs, NAME);
                List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(pCand);
                newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, newPerpendicular));
             }

            return newGrounded;
        }
示例#5
0
        private static List <EdgeAggregator> CheckAndGeneratePerpendicular(Perpendicular perp, Parallel parallel, Intersection inter, GroundedClause original)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // The perpendicular intersection must refer to one of the parallel segments
            Segment shared = perp.CommonSegment(parallel);

            if (shared == null)
            {
                return(newGrounded);
            }

            // The other intersection must refer to a segment in the parallel pair
            Segment otherShared = inter.CommonSegment(parallel);

            if (otherShared == null)
            {
                return(newGrounded);
            }

            // The two shared segments must be distinct
            if (shared.Equals(otherShared))
            {
                return(newGrounded);
            }

            // Transversals must align
            if (!inter.OtherSegment(otherShared).Equals(perp.OtherSegment(shared)))
            {
                return(newGrounded);
            }

            // Strengthen the old intersection to be perpendicular
            Strengthened strengthenedPerp = new Strengthened(inter, new Perpendicular(inter));

            // Construct hyperedge
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(original);
            antecedent.Add(parallel);
            antecedent.Add(inter);

            newGrounded.Add(new EdgeAggregator(antecedent, strengthenedPerp, annotation));

            return(newGrounded);
        }
示例#6
0
        //
        // Perpendicular(M, Segment(A,B), Segment(C, D)),
        //                Angle(A, B, D), Angle(C, B, D) -> Complementary(Angle(A, B, D), Angle(C, B, D))
        //
        //       A     D
        //       |    /
        //       |   /
        //       |  /
        //       | /
        //       |/_____________________ C
        //       B
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ADJACENT_ANGLES_PERPENDICULAR_IMPLY_COMPLEMENTARY;

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (!(c is Angle) && !(c is Perpendicular))
            {
                return(newGrounded);
            }

            if (c is Angle)
            {
                Angle newAngle = c as Angle;

                foreach (Perpendicular perp in candPerpendicular)
                {
                    foreach (Angle oldAngle in candAngles)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(perp, oldAngle, newAngle));
                    }
                }

                candAngles.Add(newAngle);
            }
            else if (c is Perpendicular)
            {
                Perpendicular newPerpendicular = c as Perpendicular;

                for (int i = 0; i < candAngles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candAngles.Count; j++)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(newPerpendicular, candAngles[i], candAngles[j]));
                    }
                }

                candPerpendicular.Add(newPerpendicular);
            }

            return(newGrounded);
        }
        //
        // Collinear(A, B, C, D, ...) -> Angle(A, B, C), Angle(A, B, D), Angle(A, C, D), Angle(B, C, D),...
        // All angles will have measure 180^o
        // There will be nC3 resulting clauses.
        //
        public static List <KeyValuePair <List <GroundedClause>, GroundedClause> > Instantiate(GroundedClause c)
        {
            if (!(c is Intersection))
            {
                return(null);
            }

            Intersection pCand = (Intersection)c;
            List <KeyValuePair <List <GroundedClause>, GroundedClause> > newGrounded = new List <KeyValuePair <List <GroundedClause>, GroundedClause> >();

            if (pCand.isPerpendicular == true)
            {
                Perpendicular         newPerpendicular = new Perpendicular(pCand.lhs, pCand.rhs, NAME);
                List <GroundedClause> antecedent       = Utilities.MakeList <GroundedClause>(pCand);
                newGrounded.Add(new KeyValuePair <List <GroundedClause>, GroundedClause>(antecedent, newPerpendicular));
            }



            return(newGrounded);
        }
示例#8
0
        /// <summary>
        /// Алгорит распознавания круговых движений
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MouseBox_MouseMove(object sender, MouseEventArgs e)
        {
            // Отображаем координаты позиции курсора мыши
            labelCoord.Text = e.Location.ToString();

            // Проверяем можем ли мы рисовать
            if (isPaintEntry && e.Button == MouseButtons.Left)
            {
                // Добавляем позицию мыши в список точек
                path.Add(e.Location);

                // Отрисовка траектории движения курсора мыши
                if (isDrawTrajectory && path.Count > 2)
                {
                    g.DrawLines(blPen, path.ToArray());
                }

                // Проводим вычисления с заданной точночтью аппроксимации
                if (path.Count % step == 0)
                {
                    ///
                    /// Инициализация
                    ///

                    // Аппроксимация сегмента AB траекториии движения курсора мыши
                    PointF A = path[path.Count - (int)step];
                    PointF B = path[path.Count - 1];

                    // Средняя точка R сегмента AB траектории движения курсора мыши
                    PointF R = path[path.Count - ((int)step / 2)];

                    // Точка M - середина отрезка AB
                    PointF M = new PointF((A.X + B.X) / 2f, (A.Y + B.Y) / 2f);

                    // Прямая AB
                    Straight straightAB = new Straight(A.X, A.Y, B.X, B.Y);

                    // Перпендикуляр к прямой AB в точке M
                    Perpendicular perpendicularMK = new Perpendicular(M.X, M.Y, straightAB.K);

                    // Перпендикуляр к прмяой MK в точке R
                    Perpendicular perpendicularRO = new Perpendicular(R.X, R.Y, perpendicularMK.K);

                    // Точка пересечения MK и RO
                    PointF O = GetIntersectionPoint(perpendicularMK.K, perpendicularMK.B, perpendicularRO.K, perpendicularRO.B);

                    // Если точки совпадают пропускаем итерацию
                    if (O.X == M.X)
                    {
                        return;
                    }

                    // Точка для определения коэффициента для нахождения точки радиуса
                    PointF K1 = new PointF(M.X + ((O.X < M.X) ? (-5f) : (+5f)), perpendicularMK.getY(M.X + ((O.X < M.X) ? (-5f) : (+5f))));

                    // Вычисляем длину отрезка MK1
                    float lengthMK1 = (float)Math.Sqrt(((K1.X - M.X) * (K1.X - M.X)) + ((K1.Y - M.Y) * (K1.Y - M.Y)));

                    // Вычисляем отношение длин MK к MK1
                    float k = radiusСurvature / lengthMK1;

                    // Вычисляем координаты точки K
                    PointF K = new PointF(
                        M.X - ((K1.X - M.X) * k),
                        perpendicularMK.getY(M.X - ((K1.X - M.X) * k))
                        );

                    // Определяем допустимые координаты x для перпендикуляра
                    PointF startPointMK = new PointF();
                    startPointMK.X = Math.Min(K.X, M.X);
                    startPointMK.Y = perpendicularMK.getY(startPointMK.X);

                    PointF endPointMK = new PointF();
                    endPointMK.X = Math.Max(K.X, M.X);
                    endPointMK.Y = perpendicularMK.getY(endPointMK.X);

                    if (!oldStartpointMK.IsEmpty && !oldStartpointMK.IsEmpty &&
                        IntersectionSegments(startPointMK, endPointMK, oldStartpointMK, oldEndPointMK))
                    {
                        status = true;
                        this.OnMoveMouseCircularPath(EventArgs.Empty);
                    }
                    else
                    {
                        status = false;
                        this.OnMoveMouseCircularPath(EventArgs.Empty);
                    }

                    oldStartpointMK = startPointMK;
                    oldEndPointMK   = endPointMK;

                    ///
                    /// Отрисовка
                    ///

                    // Отрисовываем отрезок AB
                    if (isDrawAB)
                    {
                        g.DrawLine(rPen, A, B);
                    }

                    // Отрисовка прямой MK
                    if (isDrawPMK)
                    {
                        g.DrawLine(dsgPen,
                                   new PointF(0f, perpendicularMK.getY(0f)),
                                   new PointF(300f, perpendicularMK.getY(300f))
                                   );
                    }

                    // Отрисовываем отрезок MK
                    if (isDrawSMK)
                    {
                        g.DrawLine(gPen, startPointMK, endPointMK);
                    }

                    // Отрисовываем перпендикуляр RO
                    if (isDrawPRO)
                    {
                        g.DrawLine(bPen,
                                   new PointF(0f, perpendicularRO.getY(0f)),
                                   new PointF(300f, perpendicularRO.getY(300f))
                                   );
                    }

                    // Отсрисовка точек M & R
                    if (isDrawPointA)
                    {
                        g.FillEllipse(rBrush, A.X - ((float)sizePoint / 2f), A.Y - ((float)sizePoint / 2f), sizePoint, sizePoint);
                    }
                    if (isDrawPointB)
                    {
                        g.FillEllipse(rBrush, B.X - ((float)sizePoint / 2f), B.Y - ((float)sizePoint / 2f), sizePoint, sizePoint);
                    }
                    if (isDrawPointM)
                    {
                        g.FillEllipse(rBrush, M.X - ((float)sizePoint / 2f), M.Y - ((float)sizePoint / 2f), sizePoint, sizePoint);
                    }
                    if (isDrawPointR)
                    {
                        g.FillEllipse(bBrush, R.X - ((float)sizePoint / 2f), R.Y - ((float)sizePoint / 2f), sizePoint, sizePoint);
                    }
                    if (isDrawPointO)
                    {
                        g.FillEllipse(gBrush, O.X - ((float)sizePoint / 2f), O.Y - ((float)sizePoint / 2f), sizePoint, sizePoint);
                    }
                    if (isDrawPointK)
                    {
                        g.FillEllipse(gBrush, K.X - ((float)sizePoint / 2f), K.Y - ((float)sizePoint / 2f), sizePoint, sizePoint);
                    }
                }
            }
        }
示例#9
0
        //
        // Perpendicular(Segment(E, F), Segment(C, D)),
        // Parallel(Segment(E, F), Segment(A, B)),
        // Intersection(M, Segment(A, B), Segment(C, D)) -> Perpendicular(Segment(A, B), Segment(C, D))
        //
        //                                   E       B
        //                                   |       |
        //                              C----|-------|--------D
        //                                   | N     | M
        //                                   |       |
        //                                   F       A
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.TRANSVERSAL_PERPENDICULAR_TO_PARALLEL_IMPLY_BOTH_PERPENDICULAR;

            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is Parallel)
            {
                Parallel newParallel = clause as Parallel;

                foreach (Perpendicular perp in candidatePerpendicular)
                {
                    foreach (Intersection inter in candidateIntersection)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicular(perp, newParallel, inter, perp));
                    }
                }

                foreach (Strengthened streng in candidateStrengthened)
                {
                    foreach (Intersection inter in candidateIntersection)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicular(streng.strengthened as Perpendicular, newParallel, inter, streng));
                    }
                }

                candidateParallel.Add(newParallel);
            }
            else if (clause is Perpendicular)
            {
                Perpendicular newPerp = clause as Perpendicular;

                foreach (Parallel parallel in candidateParallel)
                {
                    foreach (Intersection inter in candidateIntersection)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicular(newPerp, parallel, inter, newPerp));
                    }
                }

                candidatePerpendicular.Add(newPerp);
            }
            else if (clause is Intersection)
            {
                Intersection newIntersection = clause as Intersection;

                foreach (Parallel parallel in candidateParallel)
                {
                    foreach (Perpendicular perp in candidatePerpendicular)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicular(perp, parallel, newIntersection, perp));
                    }
                }

                foreach (Parallel parallel in candidateParallel)
                {
                    foreach (Strengthened streng in candidateStrengthened)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicular(streng.strengthened as Perpendicular, parallel, newIntersection, streng));
                    }
                }

                candidateIntersection.Add(newIntersection);
            }
            else if (clause is Strengthened)
            {
                Strengthened streng = clause as Strengthened;

                if (!(streng.strengthened is Perpendicular))
                {
                    return(newGrounded);
                }

                foreach (Parallel parallel in candidateParallel)
                {
                    foreach (Intersection inter in candidateIntersection)
                    {
                        if (!inter.Equals(streng.original))
                        {
                            newGrounded.AddRange(CheckAndGeneratePerpendicular(streng.strengthened as Perpendicular, parallel, inter, streng));
                        }
                    }
                }

                candidateStrengthened.Add(streng);
            }

            return(newGrounded);
        }
示例#10
0
        //
        // Perpendicular(B, Segment(A, B), Segment(B, C)) -> RightAngle(), RightAngle()
        //
        private static List <EdgeAggregator> InstantiateFromPerpendicular(GroundedClause original, Perpendicular perp)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();
            List <GroundedClause> antecedent  = new List <GroundedClause>();

            antecedent.Add(original);

            //          top
            //           |
            //           |_
            //           |_|____ right
            if (perp.StandsOnEndpoint())
            {
                Point top   = perp.lhs.OtherPoint(perp.intersect);
                Point right = perp.rhs.OtherPoint(perp.intersect);

                Strengthened streng = new Strengthened(new Angle(top, perp.intersect, right), new RightAngle(top, perp.intersect, right));

                newGrounded.Add(new EdgeAggregator(antecedent, streng, annotation));
            }
            //          top
            //           |
            //           |_
            // left  ____|_|____ right
            else if (perp.StandsOn())
            {
                Point top    = perp.lhs.Point1;
                Point center = perp.intersect;
                Point left   = perp.rhs.Point1;
                Point right  = perp.rhs.Point2;
                if (perp.lhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect))
                {
                    left  = perp.lhs.Point1;
                    right = perp.lhs.Point2;
                    top   = perp.rhs.OtherPoint(perp.intersect);
                }
                else if (perp.rhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect))
                {
                    left  = perp.rhs.Point1;
                    right = perp.rhs.Point2;
                    top   = perp.lhs.OtherPoint(perp.intersect);
                }
                else
                {
                    return(newGrounded);
                }

                Strengthened topRight = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right));
                Strengthened topLeft  = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left));

                newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation));
            }
            //          top
            //           |
            //           |_
            // left  ____|_|____ right
            //           |
            //           |
            //         bottom
            else if (perp.Crossing())
            {
                Point top    = perp.lhs.Point1;
                Point bottom = perp.lhs.Point2;
                Point center = perp.intersect;
                Point left   = perp.rhs.Point1;
                Point right  = perp.rhs.Point2;

                Strengthened topRight    = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right));
                Strengthened bottomRight = new Strengthened(new Angle(right, center, bottom), new RightAngle(right, center, bottom));
                Strengthened bottomLeft  = new Strengthened(new Angle(left, center, bottom), new RightAngle(left, center, bottom));
                Strengthened topLeft     = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left));

                newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, bottomRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, bottomLeft, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation));
            }
            else
            {
                return(newGrounded);
            }

            return(newGrounded);
        }
示例#11
0
        //
        public static List <KeyValuePair <List <GroundedClause>, GroundedClause> > Instantiate(GroundedClause c)
        {
            //Exit if c is neither a parallel set nor an intersection
            if (!(c is Parallel) && !(c is Intersection))
            {
                return(new List <KeyValuePair <List <GroundedClause>, GroundedClause> >());
            }

            List <Intersection> foundCand = new List <Intersection>(); //Variable holding intersections that will used for theorem

            // The list of new grounded clauses if they are deduced
            List <KeyValuePair <List <GroundedClause>, GroundedClause> > newGrounded = new List <KeyValuePair <List <GroundedClause>, GroundedClause> >();

            if (c is Parallel)
            {
                Parallel newParallel = (Parallel)c;
                candParallel.Add((Parallel)c);

                //Create a list of all segments in the intersection list by individual segment and list of intersecting segments
                var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs));

                //Iterate through all segments intersected by each key segment
                foreach (var group in query1)
                {
                    if (group.Contains(newParallel.segment1) && group.Contains(newParallel.segment2))
                    {
                        //If a segment that intersected both parallel lines was found, find the intersection objects.
                        var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key)));
                        var query3 = query2.Where(m => m.lhs.Equals(newParallel.segment1) || m.lhs.Equals(newParallel.segment2) || m.rhs.Equals(newParallel.segment1) || m.rhs.Equals(newParallel.segment2));
                        if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false))
                        {
                            //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular
                            foundCand.AddRange(query3);
                        }
                        antecedent = Utilities.MakeList <GroundedClause>(newParallel); //Add parallel set to antecedents
                    }
                }
            }
            else if (c is Intersection)
            {
                candIntersection.Add((Intersection)c);
                Intersection newintersect = (Intersection)c;

                var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs));

                foreach (Parallel p in candParallel)
                {
                    foreach (var group in query1)
                    {
                        if (group.Contains(p.segment1) && group.Contains(p.segment2))
                        {
                            //list intersections involving intersecting segement and two paralell segments
                            var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key)));
                            var query3 = query2.Where(m => m.lhs.Equals(p.segment1) || m.lhs.Equals(p.segment2) || m.rhs.Equals(p.segment1) || m.rhs.Equals(p.segment2));

                            if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false))
                            {
                                //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular
                                foundCand.AddRange(query3);
                            }

                            antecedent = Utilities.MakeList <GroundedClause>(p);
                        }
                    }
                }
            }


            //TODO: Make sure there will only be one set of intersections found at a time
            if (foundCand.Count() > 1)
            {
                antecedent.AddRange((IEnumerable <GroundedClause>)(foundCand));  //Add the two intersections to antecedent

                int index;

                index = (foundCand[0].isPerpendicular == false) ? 0 : 1;
                foundCand[index].setPerpendicular(true);
                Perpendicular newPerpendicular = new Perpendicular(foundCand[index].lhs, foundCand[index].rhs, NAME);


                //Add the new perpendicular set
                newGrounded.Add(new KeyValuePair <List <GroundedClause>, GroundedClause>(antecedent, newPerpendicular));
            }

            return(newGrounded);
        }
示例#12
0
        private static List <EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (!Utilities.CompareValues(angle1.measure + angle2.measure, 90))
            {
                return(newGrounded);
            }

            // The perpendicular intersection must occur at the same vertex of both angles (we only need check one).
            if (!(angle1.GetVertex().Equals(perp.intersect) && angle2.GetVertex().Equals(perp.intersect)))
            {
                return(newGrounded);
            }

            // Are the angles adjacent?
            Segment sharedRay = angle1.IsAdjacentTo(angle2);

            if (sharedRay == null)
            {
                return(newGrounded);
            }

            // Do the non-shared rays for both angles align with the segments defined by the perpendicular intersection?
            if (!perp.DefinesBothRays(angle1.OtherRayEquates(sharedRay), angle2.OtherRayEquates(sharedRay)))
            {
                return(newGrounded);
            }

            //
            // Now we have perpendicular -> complementary angles scenario
            //
            Complementary cas = new Complementary(angle1, angle2);

            // Construct hyperedge
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(perp);
            antecedent.Add(angle1);
            antecedent.Add(angle2);

            newGrounded.Add(new EdgeAggregator(antecedent, cas, annotation));

            return(newGrounded);
        }
示例#13
0
        private static List <EdgeAggregator> InstantiateToAltitude(Triangle triangle, Perpendicular perp, GroundedClause original)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // Acquire the side of the triangle containing the intersection point
            // This point may or may not be directly on the triangle side
            Segment baseSegment = triangle.GetSegmentWithPointOnOrExtends(perp.intersect);

            if (baseSegment == null)
            {
                return(newGrounded);
            }

            // The altitude must pass through the intersection point as well as the opposing vertex
            Point oppositeVertex = triangle.OtherPoint(baseSegment);

            Segment altitude = new Segment(perp.intersect, oppositeVertex);

            // The alitude must alig with the intersection
            if (!perp.ImpliesRay(altitude))
            {
                return(newGrounded);
            }

            // The opposing side must align with the intersection
            if (!perp.OtherSegment(altitude).IsCollinearWith(baseSegment))
            {
                return(newGrounded);
            }


            //
            // Create the new Altitude object
            //
            Altitude newAltitude = new Altitude(triangle, altitude);

            // For hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(triangle);
            antecedent.Add(original);

            newGrounded.Add(new EdgeAggregator(antecedent, newAltitude, annotation));

            //
            // Check if this induces a second altitude for a right triangle (although we don't know this is a strengthened triangle)
            // The intersection must be on the vertex of the triangle
            if (triangle.HasPoint(perp.intersect))
            {
                Angle possRightAngle = new Angle(triangle.OtherPoint(new Segment(perp.intersect, oppositeVertex)), perp.intersect, oppositeVertex);

                if (triangle.HasAngle(possRightAngle))
                {
                    Altitude secondAltitude = new Altitude(triangle, new Segment(perp.intersect, oppositeVertex));
                    newGrounded.Add(new EdgeAggregator(antecedent, secondAltitude, annotation));
                }
            }

            return(newGrounded);
        }
        private static List <EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (!Utilities.CompareValues(angle1.measure, angle2.measure))
            {
                return(newGrounded);
            }

            // The given angles must belong to the intersection. That is, the vertex must align and all rays must overlay the intersection.
            if (!(perp.InducesNonStraightAngle(angle1) && perp.InducesNonStraightAngle(angle1)))
            {
                return(newGrounded);
            }

            //
            // Now we have perpendicular -> congruent angles scenario
            //
            GeometricCongruentAngles gcas = new GeometricCongruentAngles(angle1, angle2);

            // Construct hyperedge
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(perp);
            antecedent.Add(angle1);
            antecedent.Add(angle2);

            newGrounded.Add(new EdgeAggregator(antecedent, gcas, annotation));

            return(newGrounded);
        }
        //        )  | B
        //         ) |
        // O        )| S
        //         ) |
        //        )  |
        //       )   | A
        // Tangent(Circle(O, R), Segment(A, B)), Intersection(OS, AB) -> Perpendicular(Segment(A,B), Segment(O, S))
        //
        private static List <EdgeAggregator> InstantiateTheorem(CircleSegmentIntersection inter, Perpendicular perp, GroundedClause original)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // The intersection points must be the same.
            if (!inter.intersect.StructurallyEquals(perp.intersect))
            {
                return(newGrounded);
            }

            // Get the radius - if it exists
            Segment radius  = null;
            Segment garbage = null;

            inter.GetRadii(out radius, out garbage);

            if (radius == null)
            {
                return(newGrounded);
            }

            // Two intersections, not a tangent situation.
            if (garbage != null)
            {
                return(newGrounded);
            }

            // The radius can't be the same as the Circ-Inter segment.
            if (inter.segment.HasSubSegment(radius))
            {
                return(newGrounded);
            }

            // Does this perpendicular apply to this Arc intersection?
            if (!perp.HasSegment(radius) || !perp.HasSegment(inter.segment))
            {
                return(newGrounded);
            }

            Strengthened newTangent = new Strengthened(inter, new Tangent(inter));

            // For hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(original);
            antecedent.Add(inter);

            newGrounded.Add(new EdgeAggregator(antecedent, newTangent, annotation));

            return(newGrounded);
        }
        public void Do(Dictionary <MyTuple <IntelItemType, long>, IFleetIntelligence> IntelItems, TimeSpan canonicalTime, Profiler profiler)
        {
            if (canonicalTime == TimeSpan.Zero)
            {
                return;
            }
            if (MiningSystem.Recalling > 0 || currentPosition > 120)
            {
                Recalling = true;
            }
            if (Recalling && state < 3)
            {
                state = 3;
            }
            if (state == 1) // Diving to surface of asteroid
            {
                MineTask.Do(IntelItems, canonicalTime, profiler);
                MineTask.Destination.MaxSpeed = Autopilot.GetMaxSpeedFromBrakingDistance(kFarSensorDist);

                if (MineTask.Status == TaskStatus.Complete || !MiningSystem.SensorsFarClear())
                {
                    EntryPoint = Autopilot.Reference.WorldMatrix.Translation + MineTask.Destination.Direction * (kFarSensorDist - 10);
                    MineTask.Destination.MaxSpeed = 1f;
                    state = 2;
                }
            }
            else if (state == 2) // Boring tunnel
            {
                bool   sampleHome      = false;
                double distToMiningEnd = (Autopilot.Reference.WorldMatrix.Translation - MiningEnd).Length();
                if (MiningSystem.SensorsClear())
                {
                    MineTask.Destination.Position = MiningEnd;
                }
                else if (MiningSystem.SensorsBack())
                {
                    MineTask.Destination.Position = EntryPoint;
                }
                else
                {
                    MineTask.Destination.Position = Vector3D.Zero;
                    if (SampleCount <= 0)
                    {
                        SampleCount = kSampleFrequency;
                        var cargoPercentage = MonitorSubsystem.GetPercentage(MonitorOptions.Cargo);
                        if (LastSampleCargoPercentages.Count >= kMaxSampleCount)
                        {
                            LastSampleCargoPercentages.Enqueue(cargoPercentage);

                            var sampleGreater     = 0;
                            var sampleLesser      = 0;
                            var comparePercentage = LastSampleCargoPercentages.Dequeue() + 0.00001;
                            foreach (var percentage in LastSampleCargoPercentages)
                            {
                                if (percentage > comparePercentage)
                                {
                                    sampleGreater++;
                                }
                                else
                                {
                                    sampleLesser++;
                                }
                            }

                            if (sampleGreater > sampleLesser)
                            {
                                if (!HitOre)
                                {
                                    HitOre = true;
                                    var currentCoords = GetMiningPosition(currentPosition);
                                    miningMatrix[currentCoords.X + 5, currentCoords.Y + 5] = 1;
                                }
                                if (LowestExpectedOreDist == -1)
                                {
                                    LowestExpectedOreDist = (float)distToMiningEnd - 5;
                                }
                            }
                            else
                            {
                                if (HitOre || distToMiningEnd < LowestExpectedOreDist)
                                {
                                    sampleHome = true;

                                    if (!HitOre)
                                    {
                                        var currentCoords = GetMiningPosition(currentPosition);
                                        miningMatrix[currentCoords.X + 5, currentCoords.Y + 5] = 2;
                                    }
                                }
                            }
                        }
                        else
                        {
                            LastSampleCargoPercentages.Enqueue(cargoPercentage);
                        }
                    }
                    else
                    {
                        SampleCount--;
                    }
                }

                MiningSystem.Drill();
                MineTask.Do(IntelItems, canonicalTime, profiler);

                if (GoHomeCheck() || MiningSystem.SensorsFarClear() || distToMiningEnd < 4 || sampleHome)
                {
                    if (MiningSystem.SensorsFarClear() || distToMiningEnd < 4 || sampleHome)
                    {
                        UpdateMiningMatrix(currentPosition);
                        IncrementCurrentPosition();
                        HitOre = false;
                    }
                    state = 3;
                    MineTask.Destination.MaxSpeed = 2;
                    LastSampleCargoPercentages.Clear();
                }
            }
            else if (state == 3) // Exiting tunnel
            {
                MiningSystem.StopDrill();
                if (MineTask.Destination.Position != ExitPoint)
                {
                    MineTask.Destination.Position = EntryPoint;
                }
                MineTask.Do(IntelItems, canonicalTime, profiler);
                if (MineTask.Status == TaskStatus.Complete)
                {
                    if (MineTask.Destination.Position == EntryPoint)
                    {
                        MineTask.Destination.Position = ExitPoint;
                        MineTask.Destination.MaxSpeed = 100;
                    }
                    else
                    {
                        state = 10;
                    }
                }
            }
            else if (state == 10) // Resuming to approach point
            {
                if (GoHomeCheck() || Recalling)
                {
                    state = 4;
                }
                else
                {
                    LeadTask.Destination.Position = ApproachPoint;
                    LeadTask.Do(IntelItems, canonicalTime, profiler);
                    if (LeadTask.Status == TaskStatus.Complete)
                    {
                        var position = GetMiningPosition(currentPosition);
                        LeadTask.Destination.Position = ApproachPoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist);
                        LeadTask.Destination.MaxSpeed = 10;
                        ExitPoint = LeadTask.Destination.Position;
                        state     = 11;
                    }
                }
            }
            else if (state == 11) // Search for the digging spot
            {
                if (GoHomeCheck() || Recalling)
                {
                    state = 4;
                }
                else
                {
                    LeadTask.Do(IntelItems, canonicalTime, profiler);
                    if (LeadTask.Status == TaskStatus.Complete)
                    {
                        state = 1;
                        MiningSystem.SensorsOn();
                        var position = GetMiningPosition(currentPosition);
                        MineTask.Destination.Position = SurfacePoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist) - MineTask.Destination.Direction * MiningSystem.CloseDist;
                        MiningEnd = SurfacePoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist) + MineTask.Destination.Direction * MiningDepth;
                    }
                }
            }
            else if (state == 4) // Going home
            {
                if (DockingSubsystem == null || DockingSubsystem.HomeID == -1 || DockTaskGenerator == null || UndockTaskGenerator == null)
                {
                    state = 9999;
                }
                else
                {
                    if (HomeTask == null)
                    {
                        HomeTask = DockTaskGenerator.GenerateMoveToAndDockTask(MyTuple.Create(IntelItemType.NONE, (long)0), IntelItems, 40);
                    }
                    HomeTask.Do(IntelItems, canonicalTime, profiler);
                    if (HomeTask.Status != TaskStatus.Incomplete)
                    {
                        HomeTask  = null;
                        homeCheck = false;
                        state     = 5;
                    }
                }
            }
            else if (state == 5) // Waiting for refuel/unload
            {
                if (Recalling)
                {
                    state = 9999;
                }
                if ((Program.Me.WorldMatrix.Translation - EntryPoint).LengthSquared() > MiningSystem.CancelDist * MiningSystem.CancelDist)
                {
                    state = 9999;
                }
                if (LeaveHomeCheck())
                {
                    state = 6;
                }
            }
            else if (state == 6) // Undocking
            {
                if (DockingSubsystem != null && DockingSubsystem.Connector.Status == MyShipConnectorStatus.Connected)
                {
                    if (UndockTask == null)
                    {
                        UndockTask = UndockTaskGenerator.GenerateUndockTask(canonicalTime);
                    }
                }

                if (UndockTask != null)
                {
                    UndockTask.Do(IntelItems, canonicalTime, profiler);
                    if (UndockTask.Status != TaskStatus.Incomplete)
                    {
                        UndockTask = null;
                        state      = 10;
                    }
                }
                else
                {
                    state = 10;
                }
            }
            else if (state == 9999)
            {
                Status = TaskStatus.Complete;
            }
        }
        //               A
        //              |)
        //              | )
        //              |  )
        // Q------- O---X---) D
        //              |  )
        //              | )
        //              |)
        //               C
        //
        // Perpendicular(Segment(Q, D), Segment(A, C)) -> Congruent(Arc(A, D), Arc(D, C)) -> Congruent(Segment(AX), Segment(XC))
        //
        private static List <EdgeAggregator> InstantiateTheorem(Intersection inter, CircleSegmentIntersection arcInter, Perpendicular perp, GroundedClause original)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // Does this intersection apply to this perpendicular?
            //
            if (!inter.intersect.StructurallyEquals(perp.intersect))
            {
                return(newGrounded);
            }

            // Is this too restrictive?
            if (!((inter.HasSegment(perp.lhs) && inter.HasSegment(perp.rhs)) && (perp.HasSegment(inter.lhs) && perp.HasSegment(inter.rhs))))
            {
                return(newGrounded);
            }

            //
            // Does this perpendicular intersection apply to a given circle?
            //
            // Acquire the circles for which the segments are secants.
            List <Circle> secantCircles1 = Circle.GetSecantCircles(perp.lhs);
            List <Circle> secantCircles2 = Circle.GetSecantCircles(perp.rhs);

            List <Circle> intersection = Utilities.Intersection <Circle>(secantCircles1, secantCircles2);

            if (!intersection.Any())
            {
                return(newGrounded);
            }

            //
            // Find the single, unique circle that has as chords the components of the perpendicular intersection
            //
            Circle  theCircle = null;
            Segment chord1    = null;
            Segment chord2    = null;

            foreach (Circle circle in intersection)
            {
                chord1 = circle.GetChord(perp.lhs);
                chord2 = circle.GetChord(perp.rhs);
                if (chord1 != null && chord2 != null)
                {
                    theCircle = circle;
                    break;
                }
            }

            Segment diameter = chord1.Length > chord2.Length ? chord1 : chord2;
            Segment chord    = chord1.Length < chord2.Length ? chord1 : chord2;

            //
            // Does the arc intersection apply?
            //
            if (!arcInter.HasSegment(diameter))
            {
                return(newGrounded);
            }
            if (!theCircle.StructurallyEquals(arcInter.theCircle))
            {
                return(newGrounded);
            }

            //
            // Create the bisector
            //
            Strengthened sb = new Strengthened(inter, new SegmentBisector(inter, diameter));
            Strengthened ab = new Strengthened(arcInter, new ArcSegmentBisector(arcInter));

            // For hypergraph
            List <GroundedClause> antecedentArc = new List <GroundedClause>();

            antecedentArc.Add(arcInter);
            antecedentArc.Add(original);
            antecedentArc.Add(theCircle);

            newGrounded.Add(new EdgeAggregator(antecedentArc, ab, annotation));

            List <GroundedClause> antecedentSegment = new List <GroundedClause>();

            antecedentSegment.Add(inter);
            antecedentSegment.Add(original);
            antecedentSegment.Add(theCircle);

            newGrounded.Add(new EdgeAggregator(antecedentSegment, sb, annotation));

            return(newGrounded);
        }
        //
        public static List<KeyValuePair<List<GroundedClause>, GroundedClause>> Instantiate(GroundedClause c)
        {
            //Exit if c is neither a parallel set nor an intersection
            if (!(c is Parallel) && !(c is Intersection)) return new List<KeyValuePair<List<GroundedClause>, GroundedClause>>();

            List<Intersection> foundCand = new List<Intersection>(); //Variable holding intersections that will used for theorem

            // The list of new grounded clauses if they are deduced
            List<KeyValuePair<List<GroundedClause>, GroundedClause>> newGrounded = new List<KeyValuePair<List<GroundedClause>, GroundedClause>>();

            if (c is Parallel)
            {
                Parallel newParallel = (Parallel)c;
                candParallel.Add((Parallel)c);

                //Create a list of all segments in the intersection list by individual segment and list of intersecting segments
                var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs));

                //Iterate through all segments intersected by each key segment
                foreach (var group in query1)
                {
                    if (group.Contains(newParallel.segment1) && group.Contains(newParallel.segment2))
                    {
                        //If a segment that intersected both parallel lines was found, find the intersection objects.
                        var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key)));
                        var query3 = query2.Where(m => m.lhs.Equals(newParallel.segment1) || m.lhs.Equals(newParallel.segment2) || m.rhs.Equals(newParallel.segment1) || m.rhs.Equals(newParallel.segment2));
                        if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false))
                        {
                            //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular
                            foundCand.AddRange(query3);
                        }
                        antecedent = Utilities.MakeList<GroundedClause>(newParallel); //Add parallel set to antecedents

                    }
                }

            }
            else if (c is Intersection)
            {

                candIntersection.Add((Intersection)c);
                Intersection newintersect = (Intersection)c;

                var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs));

                foreach (Parallel p in candParallel)
                {
                    foreach (var group in query1)
                    {
                        if (group.Contains(p.segment1) && group.Contains(p.segment2))
                        {
                            //list intersections involving intersecting segement and two paralell segments
                            var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key)));
                            var query3 = query2.Where(m => m.lhs.Equals(p.segment1) || m.lhs.Equals(p.segment2) || m.rhs.Equals(p.segment1) || m.rhs.Equals(p.segment2));

                        if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false))
                        {
                            //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular
                            foundCand.AddRange(query3);
                        }

                            antecedent = Utilities.MakeList<GroundedClause>(p);

                        }
                    }
                }

            }

            //TODO: Make sure there will only be one set of intersections found at a time
            if (foundCand.Count() > 1)
            {
                antecedent.AddRange((IEnumerable<GroundedClause>)(foundCand));  //Add the two intersections to antecedent

                int index;

                index = (foundCand[0].isPerpendicular == false) ? 0 : 1;
                foundCand[index].setPerpendicular(true);
                Perpendicular newPerpendicular = new Perpendicular(foundCand[index].lhs,foundCand[index].rhs, NAME);

                //Add the new perpendicular set
                newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, newPerpendicular));

            }

            return newGrounded;
        }