//
        // 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);
        }
        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);
        }