public static List <GenericInstantiator.EdgeAggregator> InstantiateProportion(GroundedClause clause) { List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>(); ProportionalAngles propAngs = clause as ProportionalAngles; if (propAngs == null) { return(newGrounded); } // Do not generate equations based on 'forced' proportions if (propAngs.proportion.Key == -1 || propAngs.proportion.Value == -1) { return(newGrounded); } // Create a product on the left hand side Multiplication productLHS = new Multiplication(new NumericValue(propAngs.proportion.Key), propAngs.smallerAngle.DeepCopy()); // Create a product on the right hand side, if it applies. GroundedClause rhs = propAngs.largerAngle.DeepCopy(); if (propAngs.proportion.Value > 1) { rhs = new Multiplication(new NumericValue(propAngs.proportion.Key), rhs); } // // Create the equation // Equation newEquation = null; if (propAngs is AlgebraicProportionalAngles) { newEquation = new AlgebraicAngleEquation(productLHS, rhs); } else if (propAngs is GeometricProportionalAngles) { newEquation = new GeometricAngleEquation(productLHS, rhs); } List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(propAngs); newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newEquation, defAnnotation)); return(newGrounded); }
//private static readonly string NAME = "Simplification"; // // Given an equation, simplify algebraically using the following notions: // A + A = B -> 2A = B // A + B = B + C -> A = C // A + B = 2B + C -> A = B + C // public static Equation Simplify(Equation original) { // Do we have an equation? if (original == null) throw new ArgumentException(); // Is the equation 0 = 0? This should be allowed at it indicates a tautology if (original.lhs.Equals(new NumericValue(0)) && original.rhs.Equals(new NumericValue(0))) { throw new ArgumentException("Should not have an equation that is 0 = 0: " + original.ToString()); } // // Ideally, flattening would: // Remove all subtractions -> adding a negative instead // Distribute subtraction or multiplication over addition // // Flatten the equation so that each side is a sum of atomic expressions Equation copyEq = (Equation)original.DeepCopy(); FlatEquation flattened = new FlatEquation(copyEq.lhs.CollectTerms(), copyEq.rhs.CollectTerms()); //Debug.WriteLine("Equation prior to simplification: " + flattened.ToString()); // Combine terms only on each side (do not cross =) FlatEquation combined = CombineLikeTerms(flattened); //Debug.WriteLine("Equation after like terms combined on both sides: " + combined); // Combine terms across the equal sign FlatEquation across = CombineLikeTermsAcrossEqual(combined); //Debug.WriteLine("Equation after simplifying both sides: " + across); FlatEquation constSimplify = SimplifyForMultipliersAndConstants(across); // // Inflate the equation // Equation inflated = null; GroundedClause singleLeftExp = InflateEntireSide(constSimplify.lhsExps); GroundedClause singleRightExp = InflateEntireSide(constSimplify.rhsExps); if (original is AlgebraicSegmentEquation) { inflated = new AlgebraicSegmentEquation(singleLeftExp, singleRightExp); } else if (original is GeometricSegmentEquation) { inflated = new GeometricSegmentEquation(singleLeftExp, singleRightExp); } else if (original is AlgebraicAngleEquation) { inflated = new AlgebraicAngleEquation(singleLeftExp, singleRightExp); } else if (original is GeometricAngleEquation) { inflated = new GeometricAngleEquation(singleLeftExp, singleRightExp); } else if (original is AlgebraicArcEquation) { inflated = new AlgebraicArcEquation(singleLeftExp, singleRightExp); } else if (original is GeometricArcEquation) { inflated = new GeometricArcEquation(singleLeftExp, singleRightExp); } else if (original is AlgebraicAngleArcEquation) { inflated = new AlgebraicAngleArcEquation(singleLeftExp, singleRightExp); } else if (original is GeometricAngleArcEquation) { inflated = new GeometricAngleArcEquation(singleLeftExp, singleRightExp); } // If simplifying didn't do anything, return the original equation if (inflated.Equals(original)) { return original; } // // 0 = 0 should not be allowable. // if (inflated.lhs.Equals(new NumericValue(0)) && inflated.rhs.Equals(new NumericValue(0))) { return null; } return inflated; }
public static List<GenericInstantiator.EdgeAggregator> InstantiateProportion(GroundedClause clause) { List<GenericInstantiator.EdgeAggregator> newGrounded = new List<GenericInstantiator.EdgeAggregator>(); ProportionalAngles propAngs = clause as ProportionalAngles; if (propAngs == null) return newGrounded; // Do not generate equations based on 'forced' proportions if (propAngs.proportion.Key == -1 || propAngs.proportion.Value == -1) return newGrounded; // Create a product on the left hand side Multiplication productLHS = new Multiplication(new NumericValue(propAngs.proportion.Key), propAngs.smallerAngle.DeepCopy()); // Create a product on the right hand side, if it applies. GroundedClause rhs = propAngs.largerAngle.DeepCopy(); if (propAngs.proportion.Value > 1) { rhs = new Multiplication(new NumericValue(propAngs.proportion.Key), rhs); } // // Create the equation // Equation newEquation = null; if (propAngs is AlgebraicProportionalAngles) { newEquation = new AlgebraicAngleEquation(productLHS, rhs); } else if (propAngs is GeometricProportionalAngles) { newEquation = new GeometricAngleEquation(productLHS, rhs); } List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(propAngs); newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newEquation, defAnnotation)); return newGrounded; }