Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix part of #4044: Add support for computing polynomials from math ex…
…pressions (#4056) ## Explanation Fix part of #4044 Originally copied from #2173 when it was in proof-of-concept form Introduces support for computing polynomials from algebraic expressions (represented using the ``MathExpression`` proto). At a high-level, most algebraic expression representations of polynomials should be convertible to the proto ``Polynomial`` structure by the converter, but there's a main limitation: cases when polynomial factoring is needed (such as a root power) isn't currently supported, though single term polynomials can be rooted if they result in a valid root. Beyond that, any case where a non-integer or negative power occurs (such as variables in denominators or remainders during polynomial division) will result in a failure. Otherwise, full polynomial arithmetic is supported including: negation, addition, subtraction, multiplication, division (via long division), and exponentiation. Like past PRs, the converter attempts to retain maximum precision by attempting to keep integers and fraction representation as long as possible. There are also a lot of edge cases which is why the tests are so long. Some general notes: - PolynomialExtensionsTest was exempted to utilize parameterization for a few test cases - ``RealExtensions`` was updated to return a nullable result for square roots & powers to replace exceptional cases with null results so that they can be ignored similar to other failure cases - A new reverse sort function was added for iterables in ComparatorExtensions (to ensure polynomial sorting is correct) ## Essential Checklist - [x] The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".) - [x] Any changes to [scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets) files have their rationale included in the PR explanation. - [x] The PR follows the [style guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide). - [x] The PR does not contain any unnecessary code changes from Android Studio ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)). - [x] The PR is made from a branch that's **not** called "develop" and is up-to-date with "develop". - [x] The PR is **assigned** to the appropriate reviewers ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)). ## For UI-specific PRs only N/A -- This does not have user-facing changes, though it will be used as the base logic for future domain classifiers that will be added. Commit history: * Copy proto-based changes from #2173. * Introduce math.proto & refactor math extensions. Much of this is copied from #2173. * Migrate tests & remove unneeded prefix. * Add needed newline. * Some needed Fraction changes. * Introduce math expression + equation protos. Also adds testing libraries for both + fractions & reals (new structure). Most of this is copied from #2173. * Add protos + testing lib for commutative exprs. * Add protos & test libs for polynomials. * Lint fix. * Lint fixes. * Add math tokenizer + utility & tests. This is mostly copied from #2173. * Add math expression/equation parsing support. This includes full error detection, and specific test suites for each parsing case. Much revisement is needed in the tests, and some additional issues may yet need to be fixed in the parser and/or error-detection logic. This is copied from #2173 with revisement & reduction since it's part of a multi-PR split. * Add exp evaluation & LaTeX conversion support. This is mainly copied from #2173. * Remove unneeded comment lines. * Add expr->comparable operation list conv support. This enables the ability to compare two expressions such that operation associativity and commutativity is considered (i.e. items can be rearranged using those rules without breaking expression equality). This is mostly copied from #2173. * Add support for expression->polynomial conversion. This is mostly copied from #2173. * Fix broken test post-refactor. * Add reasonable import for abs(). * Fix equals errors for equations. This splits the current error into two: one for no equals being present (& adds it), and one for too many equals. This better supports the UI errors that need to be displayed to the user in these cases. * Fix rational^rational powers. This generifies the sqrt algorithm to support n-roots so that rationals raised by rationals can actually work & retain the rational (in cases where the root can actually be taken). * Ensure rational terms reduce to ints. This ensures cases like 8/1 become just '8' coefficients rather than staying as an irrational (for simplification). * Post-merge fix. * Add regex check, docs, and resolve TODOs. This also changes regex handling in the check to be more generic for better flexibility when matching files. * Lint fix. * Fix failing static checks. * Fix broken CI checks. Adds missing KDocs, test file exemptions, and fixes the Gradle build. * Lint fixes. * Add docs & exempted tests. * Remove blank line. * Add docs + tests. * Add parameterized test runner. This commit introduces a new parameterized test runner that allows proper combinations of parameterized & non-parameterized tests in the same suite, and in a way that should work on both Robolectric & Espresso (though the latter isn't currently verified). Further, this commit also introduces a TokenSubject that will be used more explicitly by the follow-up commit for verifying MathTokenizer. * Add & update tests. This introduces tests for PeekableIterator, and reimplements all of MathTokenizer's tests to be more structured, thorough, and a bit more maintainable (i.e. by leveraging parameterized tests). * Lint fixes. This includes a fix for 'fun interface' not working with ktlint (see #4122). * Remove internals that broke things. * Add regex exemptions. * Post-merge fix. * Add error tests. These tests are more or less comprehensive based on existing tests and some new ideas. All errors are now covered by MathExpressionParserTest. Error ordering is not tested. A new Truth subject was added for easier testing, as well (for MathParsingError). * Finish algebraic equation tests. * Reimplement numeric expression tests. This is almost a full replacement. The new tests are more structured and intentional to cover key high-level concepts. More tests may be added in the future, but this is a sensible initial test offering. This also updates MathExpressionSubject to support checking specifically for implicit multiplication (and it's now required for such cases since explicit is otherwise assumed). * Finish algebraic expression tests. These largely rely on numeric expression tests (since they focus on verifying specific variable scenarios). * Add missing tests for better coverage. * Add KDocs & test exemptions. * Lint fixes. * Remove temporary TODOs. * Add tests. * Split StringToFractionParser. This is a temporary change that will be finished upstream (since there's an earlier PR that's a better fit for this change). * Address reviewer comments + other stuff. This also fixes a typo and incorrectly ordered exemptions list I noticed during development of downstream PRs. * Move StringExtensions & fraction parsing. This splits fraction parsing between UI & utility components. * Address reviewer comments. * Alphabetize test exemptions. * Fix typo & add regex check. The new regex check makes it so that all parameterized testing can be more easily tracked by the Android TL. * Add missing KDocs. * Post-merge cleanups. Also, fix text file exemption ordering. * Add new test for negation with math symbol. * Post-merge fixes. * Add KDocs. Also, add new regex exemption for new parameterized tests in this branch. * Refactor & simplify real ext impl. Also, fix/clarify some KDocs. * Lint fixes. * Simplify operation list converter a lot. This inlines three recursive operations to be done during the actual computation to simplify the overall converter complexity (and to make determining the test matrix easier). * Prepare for new tests. * Remove the ComparableOperationList wrapper. * Change parameterized method delimiter. * Use utility directly in test. * Post-merge fixes. This adjusts for the removal of ComparableOperationList (i.e. no wrapper proto). * Add first round of tests. This includes fixes to the converter itself as it wasn't distributing both product inversions and negation correctly in several cases. Tests should now be covering these cases. * Finish initial test suite. Still needs to be cleaned up, but after converter refactoring attempts. * Simplify operation sorting comparators. * Remove old tests. * Add remaining missing tests. * KDocs & test exemption. * Renames & lint fixes. * Post-merge fixes. * Add tests. * KDocs + exemptions. Also, clean up polynomial sorting. * Lint fixes. * Use more intentional epsilons for float comparing. * Treat en-dash as a subtraction symbol. * Add explicit platform selection for paramerized. This adds explicit platform selection support rather than it being automatic based on deps. While less flexible for shared tests, this offers better control for tests that don't want to to use Robolectric for local tests. This also adds a JUnit-only test runner, and updates MathTokenizerTest to use it (which led to an almost 40x decrease in runtime). * Exemption fixes. Also, fix name for the AndroidJUnit4 runner. * Remove failing test. * Fix unary expression precedence. Also, use ParameterizedJunitTestRunner for MathExpressionParserTest. * Fixes & add more test cases. * Post-merge fixes & test changes. Also, update RealExtensionsTest to use the faster JUnit runner. * Use utility directly in LaTeX tests. * Post-merge fixes. Also, update ExpressionToComparableOperationConverterTest to use the fast JUnit-only runner. * Post-merge fixes. Also, update PolynomialExtensionsTest to use fast JUnit-only runner. * Address reviewer comment. Clarifies the documentation in the test runner around parameter injection. * Fix broken build. * Fix broken build post-merge. * Post-merge fix. * More post-merge fixes. * Fix TODO comment.
- Loading branch information