//
        // RightAngle(A, B, C), Angle(A, B, X) + Angle(X, B, C) = 90 -> Complementary(Angle(A, B, X), Angle(X, B, C))
        //
        public static List <EdgeAggregator> InstantiateToComplementary(AngleEquation eq, RightAngle ra, GroundedClause original)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // Acquire the two angles from the equation
            //
            KeyValuePair <int, int> cards     = eq.GetCardinalities();
            List <GroundedClause>   terms     = cards.Key == 2 ? eq.lhs.CollectTerms() : eq.rhs.CollectTerms();
            List <GroundedClause>   singleton = cards.Key == 1 ? eq.lhs.CollectTerms() : eq.rhs.CollectTerms();

            Angle angle1 = terms[0] as Angle;
            Angle angle2 = terms[1] as Angle;

            // Create the resultant angle to compare to the input right angle
            Segment shared = angle1.IsAdjacentTo(angle2);

            if (!ra.HasSegment(angle1.OtherRayEquates(shared)) || !ra.HasSegment(angle2.OtherRayEquates(shared)))
            {
                return(newGrounded);
            }

            // Success, we have correspondence
            Complementary comp = new Complementary(angle1, angle2);

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

            antecedent.Add(original);

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

            return(newGrounded);
        }
示例#2
0
        // Acquire the angle and its measure from the equation
        private static KeyValuePair <Angle, double> ExtractFromEquation(AngleEquation eq)
        {
            NumericValue numeral = null;
            Angle        angle   = null;

            // Split the sides
            if (eq.lhs is NumericValue)
            {
                numeral = eq.lhs as NumericValue;
                angle   = eq.rhs as Angle;
            }
            else if (eq.rhs is NumericValue)
            {
                numeral = eq.rhs as NumericValue;
                angle   = eq.lhs as Angle;
            }

            if (numeral == null || angle == null)
            {
                return(new KeyValuePair <Angle, double>(null, 0));
            }

            // The multiplier must be one for: 2mABC = 45, not acceptable; something weird happened anyway
            if (angle.multiplier != 1)
            {
                return(new KeyValuePair <Angle, double>(angle, numeral.DoubleValue * (1.0 / angle.multiplier)));
            }

            return(new KeyValuePair <Angle, double>(angle, numeral.DoubleValue));
        }
示例#3
0
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ANGLES_OF_EQUAL_MEASUREARE_CONGRUENT;

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

            AngleEquation newAngEq = clause as AngleEquation;

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

            // One side must be atomic
            int atomicity = newAngEq.GetAtomicity();

            if (atomicity != Equation.BOTH_ATOMIC)
            {
                return(newGrounded);
            }

            // Split the information into the angle and its measure
            KeyValuePair <Angle, double> newAngleAndMeasure = ExtractFromEquation(newAngEq);

            // If splitting failed, we are not interested in the equation
            if (newAngleAndMeasure.Key == null)
            {
                return(newGrounded);
            }

            // Can we create any new congruence relationships comparing numeric (deduced angle measure) values?
            foreach (AngleEquation oldEq in candiateAngleEquations)
            {
                KeyValuePair <Angle, double> oldEqAngle = ExtractFromEquation(oldEq);

                // Avoid generating equivalent angles
                if (!newAngleAndMeasure.Key.Equates(oldEqAngle.Key))
                {
                    // Do the angles have the same measure
                    if (Utilities.CompareValues(newAngleAndMeasure.Value, oldEqAngle.Value))
                    {
                        AlgebraicCongruentAngles acas = new AlgebraicCongruentAngles(newAngleAndMeasure.Key, oldEqAngle.Key);

                        // For hypergraph construction
                        List <GroundedClause> antecedent = new List <GroundedClause>();
                        antecedent.Add(newAngEq);
                        antecedent.Add(oldEq);

                        newGrounded.Add(new EdgeAggregator(antecedent, acas, annotation));
                    }
                }
            }

            // Add to the list for future reference
            candiateAngleEquations.Add(newAngEq);

            return(newGrounded);
        }
        public static List <EdgeAggregator> InstantiateToComplementary(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.COMPLEMENTARY_DEFINITION;

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

            if (clause is AngleEquation)
            {
                AngleEquation eq = clause as AngleEquation;

                //
                // Filter only acceptable equations; one side has two values, the other one
                //
                // Check basic size of the sides
                int atomicity = eq.GetAtomicity();
                if (atomicity == Equation.BOTH_ATOMIC || atomicity == Equation.NONE_ATOMIC)
                {
                    return(newGrounded);
                }

                // Now check more involved cardinalities of each side
                KeyValuePair <int, int> cards = eq.GetCardinalities();
                if (!(cards.Key == 1 && cards.Value == 2) && !(cards.Key == 2 && cards.Value == 1))
                {
                    return(newGrounded);
                }
                List <GroundedClause> terms     = cards.Key == 2 ? eq.lhs.CollectTerms() : eq.rhs.CollectTerms();
                List <GroundedClause> singleton = cards.Key == 1 ? eq.lhs.CollectTerms() : eq.rhs.CollectTerms();

                // Coefficients need to be 1
                foreach (GroundedClause gc in terms)
                {
                    if (gc.multiplier != 1)
                    {
                        return(newGrounded);
                    }
                }

                // Require the constant to be 90
                NumericValue numeral = singleton[0] as NumericValue;
                if (numeral == null || Utilities.CompareValues(numeral.IntValue, 90))
                {
                    return(newGrounded);
                }

                // Require adjacent angles
                Angle angle1 = terms[0] as Angle;
                Angle angle2 = terms[1] as Angle;
                if (angle1.IsAdjacentTo(angle2) == null)
                {
                    return(newGrounded);
                }

                foreach (RightAngle ra in candidateRightAngles)
                {
                    newGrounded.AddRange(InstantiateToComplementary(eq, ra, ra));
                }

                foreach (Strengthened streng in candidateStrengthened)
                {
                    newGrounded.AddRange(InstantiateToComplementary(eq, streng.strengthened as RightAngle, streng));
                }

                candidateAngleEquations.Add(eq);
            }
            else if (clause is RightAngle)
            {
                RightAngle newRa = clause as RightAngle;

                foreach (AngleEquation eq in candidateAngleEquations)
                {
                    newGrounded.AddRange(InstantiateToComplementary(eq, newRa, newRa));
                }

                candidateRightAngles.Add(newRa);
            }
            else if (clause is Strengthened)
            {
                Strengthened newStreng = clause as Strengthened;

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

                foreach (AngleEquation eq in candidateAngleEquations)
                {
                    newGrounded.AddRange(InstantiateToComplementary(eq, newStreng.strengthened as RightAngle, newStreng));
                }

                candidateStrengthened.Add(newStreng);
            }

            return(newGrounded);
        }
        public static List <EdgeAggregator> InstantiateToRightAngle(GroundedClause clause)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is AngleEquation)
            {
                AngleEquation eq = clause as AngleEquation;
                //Filter for acceptable equations - both sides atomic
                int atomicity = eq.GetAtomicity();
                if (atomicity != Equation.BOTH_ATOMIC)
                {
                    return(newGrounded);
                }

                //Check that the terms equate an angle to a measure
                List <GroundedClause> lhs = eq.lhs.CollectTerms();
                List <GroundedClause> rhs = eq.rhs.CollectTerms();

                Angle        angle = null;
                NumericValue value = null;
                if (lhs[0] is Angle && rhs[0] is NumericValue)
                {
                    angle = lhs[0] as Angle;
                    value = rhs[0] as NumericValue;
                }
                else if (rhs[0] is Angle && lhs[0] is NumericValue)
                {
                    angle = rhs[0] as Angle;
                    value = lhs[0] as NumericValue;
                }
                else
                {
                    return(newGrounded);
                }

                //Verify that the angle is a right angle
                if (!Utilities.CompareValues(value.DoubleValue, 90.0))
                {
                    return(newGrounded);
                }

                Strengthened newRightAngle = new Strengthened(angle, new RightAngle(angle));

                List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(clause);

                newGrounded.Add(new EdgeAggregator(antecedent, newRightAngle, defAnnotation));

                return(newGrounded);
            }
            else if (clause is CongruentAngles)
            {
                CongruentAngles cas = clause as CongruentAngles;

                // Not interested in reflexive relationships in this case
                if (cas.IsReflexive())
                {
                    return(newGrounded);
                }

                foreach (RightAngle ra in candidateRightAngles)
                {
                    newGrounded.AddRange(InstantiateToRightAngle(ra, cas, ra));
                }

                foreach (Strengthened streng in candidateStrengthened)
                {
                    newGrounded.AddRange(InstantiateToRightAngle(streng.strengthened as RightAngle, cas, streng));
                }

                candidateCongruentAngles.Add(clause as CongruentAngles);
            }
            else if (clause is RightAngle)
            {
                RightAngle ra = clause as RightAngle;

                foreach (CongruentAngles oldCas in candidateCongruentAngles)
                {
                    newGrounded.AddRange(InstantiateToRightAngle(ra, oldCas, ra));
                }

                candidateRightAngles.Add(ra);
            }
            else if (clause is Strengthened)
            {
                Strengthened streng = clause as Strengthened;

                // Only intrerested in right angles
                if (!(streng.strengthened is RightAngle))
                {
                    return(newGrounded);
                }

                foreach (CongruentAngles oldCas in candidateCongruentAngles)
                {
                    newGrounded.AddRange(InstantiateToRightAngle(streng.strengthened as RightAngle, oldCas, streng));
                }

                candidateStrengthened.Add(streng);
            }

            return(newGrounded);
        }
        private static bool HandleSimpleAngleEquation(KnownMeasurementsAggregator known, AngleEquation theEq)
        {
            if (theEq.GetAtomicity() != Equation.BOTH_ATOMIC)
            {
                return(false);
            }

            Angle  unknownAngle = null;
            double angleValue   = -1;

            if (theEq.lhs is NumericValue)
            {
                unknownAngle = theEq.rhs as Angle;
                angleValue   = (theEq.lhs as NumericValue).DoubleValue;
            }
            else if (theEq.rhs is NumericValue)
            {
                unknownAngle = theEq.lhs as Angle;
                angleValue   = (theEq.rhs as NumericValue).DoubleValue;
            }
            else
            {
                return(false);
            }

            //
            // (7) Add to the list of knowns
            //
            return(known.AddAngleMeasureDegree(unknownAngle, angleValue));
        }
        //
        // (1) Make a copy
        // (2) Collect the equation terms.
        // (3) Are all but one known?
        // (4) Substitute
        // (5) Simplify
        // (6) Acquire the unknown and its value.
        // (7) Add to the list of knowns.
        //
        private static bool HandleAngleEquation(KnownMeasurementsAggregator known, List <GroundedClause> clauses, AngleEquation theEq)
        {
            if (theEq.GetAtomicity() == Equation.BOTH_ATOMIC)
            {
                return(HandleSimpleAngleEquation(known, theEq));
            }

            // CTA: Verify this calls the correct Equation deep copy mechanism.
            // (1) Make a copy
            AngleEquation copy = (AngleEquation)theEq.DeepCopy();

            // (2) Collect the equation terms.
            List <GroundedClause> left = copy.lhs.CollectTerms();

            double[] leftVal            = new double[left.Count];
            List <GroundedClause> right = copy.rhs.CollectTerms();

            double[] rightVal = new double[right.Count];

            // (3) Are all but one term known?
            int unknownCount = 0;

            for (int ell = 0; ell < left.Count; ell++)
            {
                if (left[ell] is NumericValue)
                {
                    leftVal[ell] = (left[ell] as NumericValue).DoubleValue;
                }
                else
                {
                    leftVal[ell] = known.GetAngleMeasure(left[ell] as Angle);
                    if (leftVal[ell] <= 0)
                    {
                        unknownCount++;
                    }
                }
            }
            for (int r = 0; r < right.Count; r++)
            {
                if (right[r] is NumericValue)
                {
                    rightVal[r] = (right[r] as NumericValue).DoubleValue;
                }
                else
                {
                    rightVal[r] = known.GetAngleMeasure(right[r] as Angle);
                    if (rightVal[r] <= 0)
                    {
                        unknownCount++;
                    }
                }
            }

            // We can't solve for more or less than one unknown.
            if (unknownCount != 1)
            {
                return(false);
            }

            //
            // (4) Substitute
            //
            for (int ell = 0; ell < left.Count; ell++)
            {
                if (leftVal[ell] > 0)
                {
                    copy.Substitute(left[ell], new NumericValue(leftVal[ell]));
                }
            }
            for (int r = 0; r < right.Count; r++)
            {
                if (rightVal[r] > 0)
                {
                    copy.Substitute(right[r], new NumericValue(rightVal[r]));
                }
            }

            //
            // (5) Simplify
            //
            AngleEquation simplified = (AngleEquation)GenericInstantiator.Simplification.Simplify(copy);

            return(HandleSimpleAngleEquation(known, simplified));
        }