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