This release contains a lot of groundwork in preparation for future work on
symbolic expressions, symbolic solving and symbolic integration, as well as to
improve compatibility with HP calculators. In particular, `rewrite` has been
replaced with the HP equivalents, `↑Match` and `↓Match`, allowing top-down and
bottom-up replacement, as well as support for conditions. Also, these commands
return the number of replacements performed instead of just `0` or `1`.
THe other major user-visible new feature is the addition of a polynomials data
type, which does not exist on HP calculators, exposing polynomial features in a
way that is more consistent with the spirit of RPL. For example, Euclidean
division of polynomials can be achieved using the regular `/` operation on
polynomials instead of requiring a dedicated `DIV2` command.
**New features**
* Support for polynomials as a data type, including Euclidean division
* Arithmetic operations on polynomials, including `sq` and `cubed`
* Conversion functions `→Poly` and `Poly→` to convert to and from polynomials
* Optional case-sensitive symbol matching
* Algebra configuration directory (like `CASDIR` on HP calculators)
* rewrites: Replace `rewrite` command with HP-compatible `↑Match` and `↓Match`
* rewrites: Add `ExplicitWildcards` option to match HP syntax (`&A`)
* rewrites: Add rules to expand powers
* rewrites: Add support for conditions when matching patterns
* rewrites: Add support for step-by-step rewrites
* rewrites: Add support for bottom-up rewrites
* flags: `Purge` now resets system flags to default value
**Bug fixes**
* editor: Fix unresponsive keys after using `EXIT` key while searching
* complex: Avoid emitting syntax errors while parsing
* rewrites: Avoid potential garbage collection corruption problem
* rewrites: Disable auto-simplification during rewrites
* rewrites: Factor out rewrite loop
* expressions: Encode expressions with type ID >= 128 correctly
* arithmetic: Add space around `mod` and `rem` in rendering
* graph: Do not add parentheses for `X*(Y/Z)`
* functions: Make percentage operations binary functions
* functions: Turn `min` and `max` into algebraic functions
* cycle: For expressions, cycle graphic/text rendering correctly
* menus: Replace `EquationsMenu` with `ExpressionMenu` in other menus
* ui: Insert space when inserting array inside function
**Improvements**
* menus: Updates to `PolynomialMenu` to enter polynomials and for conversions
* menus: Add product and sum to symbolic and algebra menus
* menus: Make `ToolsMenu` select `SymbolicMenu` for symbols
* expressions: Reorganize the code for rewrites
* rewrites: Add recorders for rewrites that are actually done
* tests: Some adjustments on color images
* rewrites: Convert algebraics into expression as needed
* complex: Parse `3i` and `i3` in addition to `i`
* tests: Add support for more characters
* simulator: Separator color and dm32 support
* graph: Add space when rendering simple function
* keyboard: Updated SVG files with latest menu labeling changes
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Since HP calculators are case-sensitive for symbols, add a setting
`DistinguishSymbolCase` to make symbol-matching case-sensitive.
The default DB48X behaviour is to ignore symbol case, and can be
activated using `IgnoreSymbolCase`
Fixes: #918
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add operations on algebra variables and configuration to `AlgebraMenu`
Also add the corresponding characters to the menus for testing purpose
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
When subtracting a polynomial from another one with same value, we end
up with an empty polynomial, and we need to special-case this.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The calls to `is_one` were using the implicit argument `true` that
caused them to emit incorrect type errors.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
We were not correctly clearing the `searching` flag in `clear_error`,
and as a result we were stuck in search mode even when the editor was
not active.
Fixes: #917
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
While parsing complex numbers, we were emitting actual syntax errors
instead of deferring them by returning `WARN`.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
We were temporarily using an inverted form to identify polynomials.
Replace it with final version, which is to not display anything by
default, unless either editing or setting the `PrefixPolynomialRender`
setting, which causes a `[poly]` to show up before polynomials on the
stack as well.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add rendering and editing of polynomials.
On the command line, a polynommial is identified by a prefix `Ⓟ`
(which displays as `[poly]` inverted).
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Deal with square and cubes of polynomials, as well as when converting
from expression to polynomial.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
We optimize `1` away in general, but we should not if all exponents
are 0, meaning we have a constant 1 we need to show.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Implement polynomial euclidean division, which gives a meaning to
divide and remainder for polynomials.
Polynomial division is only well-defined with a single variable.
On HP calculators, this is configured by the `VX` variable in the
`CASDIR` directory. A similar mechanism is provided allowing the
creation of an algebraic configuration directory.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
When multiplying `(A-B)` by `(A+B)` polynomials, the cross-terms
cancel out and should be correctly accounted for.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add the `sum` and `product` functions to relevant menu entries, now
that they are implemented.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
There was one scenario where we would incorrectly return a nullptr,
which manifested as the polynomial rendering as text (or as an error
when using `Show`).
When we have an oversized graphic rendering, this was incorrectly
interpreted as the beginning of a sum, so we were only doing a partial
render instead of falling back to text-only rendering.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
When parsing, we never generate naked symbols, they are always wrapped
in expressions. However, it's legitimate to have one on the stack, and
in that case, we should use the `SymbolicMenu`.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Enough algorithms need a separate notion of polynomials.
Devise a space-efficient representation for them.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Add new types for wildcards, including testing for names,
zero vs. non-zero integers, etc.
The rewritten expand and collect are not better than before,
we need to connect them to polynomials first.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Use GC pointers inside `match` because garbage collection can be
triggered by evaluation of operations when `compute` is set.
Also enable `u`, `v`, `w` wildcards to sort non-names.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
By enabling `-trewrites_done`, you only see the rewrites that are
successful, which is much less noisy.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
If we explicitly write a rule like `sq(x)` -> `x*x`, we don't want
auto-simplification to give us `sq(x)` back, otherwise we are going to
loop forever without making forward progress.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
Factor out the many variants of rewrite loop for multiple expressions,
in order to be able to introduce conditionals in rewrite sequences.
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
When we are building an equation that has a type that does not fit in
one byte, like `cbrt`, we now use `std::conditional` to automatically
select a two-byte encoding for the expression.
Fixes: #916
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The `ExplicitWildcards` flag requires a `&` sign at the beginning of
wilcards like on HP calculators. When the flag is clear, variable
names in patterns are wildcards by default.
Fixes: #913
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
The result of `↓Match` and `↑Match` on HP calculators is `0` for no
rewrites, or `1` if a replacement occured.
However, it's possible (rarely) for more than one rewrite to occur
even on HP (it's difficult because the algorithm appears to be
single-pass). DB48X can perform multiple rewrites on the same
expression, so it makes sense to enhance `↓Match` and `↑Match` to
return the number of replacements performed. This can still be used as
a test.
Also document the differences in terms of pattern.
Fixes: #912
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
In order to be able to run the example page 3-142 of the HP50G
advanced reference manual, which applies `↓Match` to a decimal number,
we need to transparently convert all the non-expression algebraic
values to expressions.
Fixes: #910
Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>