(01-21-2019 01:43 PM)compsystems Wrote: [ -> ]2 Crazy ideas =), If it is offtopic, I move it or I eliminate it, there is no problem

Well... not meaning to be rude but yeah, it's far from what we are discussing right now. I would post them in a separate thread, then I'll reply with some ideas that may be more related to those ideas than newRPL.

Yikes, that does seem very involved!

Incidentally, how does one enter subscripts on the keyboard?

(01-22-2019 02:41 PM)The Shadow Wrote: [ -> ]Yikes, that does seem very involved!

Incidentally, how does one enter subscripts on the keyboard?

In Alpha mode, RS_HOLD and a number. It will do superscript in 'C' mode and subscript in 'L' mode.

All ROMs were updated to build 1157.

What's new:

* Rules engine complete rewrite, now it won't miss a case.

* Rules engine also supports attributes

* Added '.oX' and '.eX' to match odd and even numbers (which can also be accomplished using attributes).

* Operator | (given that) was added to properly parse rules and expressions. Rules engine doesn't use it yet.

* Wiki was updated with

more info on rules and attributes (the symbolics section)
* Moved the rules symbol in the keyboard: Now LS-Enter does :-> (instead of ANS), and LS-Hold-Enter does the | operator.

As a reminder: In alpha mode, RS-hold-number does subscript/superscript (when in L and C modes respectively).

As usual, test and report bugs, the rules engine is quite new, so things are expected to go wrong.

AUTOSIMPLIFY still doesn't turn 'X*X' to 'X^2', or 'X/X' to '1'. It does change 'X^2/X' to 'X', though, so that flag must be on. Are those flags somewhere in the menu system, btw? If not, how do we change them?

'SQRT(X)' gets changed to 'X^(1/2)' but not back, as in the original set of rules. What rules does AUTOSIMPLIFY use now?

EDIT: Also, I just noticed that 'X*X^2' gets turned correctly into 'X^3' but 'X^2*X' does not.

(01-25-2019 02:50 PM)The Shadow Wrote: [ -> ]AUTOSIMPLIFY still doesn't turn 'X*X' to 'X^2', or 'X/X' to '1'. It does change 'X^2/X' to 'X', though, so that flag must be on. Are those flags somewhere in the menu system, btw? If not, how do we change them?

Well of course, I finished the engine, tested and released, but didn't get to review and update the AUTOSIMPLIFY rules to actually use the new features. As of right now, there's no rule that would match 'X*X', I did 'm*X+n*X' and 'X+m*X', but forgot to include the simplest case

That's where I need help: to come up with the best rule set possible for all the different commands.

I want 'X/X' simplified to 1 but using attributes to only match real/complex variables that can't be zero. Same for 'X^m/X^n'.

(01-25-2019 02:50 PM)The Shadow Wrote: [ -> ]'SQRT(X)' gets changed to 'X^(1/2)' but not back, as in the original set of rules. What rules does AUTOSIMPLIFY use now?

Below is what I have so far (pasted from the source code, it's plain RPL so there's nothing difficult).

Flags are as follows:

-70 (when set) disables

all rule processing in AUTOSIMPLIFY (it still does only trivial numeric reductions like fraction additions, but no algebraic manipulation)

-71 to -78 (when set) disables rules in groups 1 through 8.

The 8 groups are as defined as per the comments in the source code:

Code:

@ THESE ARE RULES TO PREPARE THE EXPRESSIONS FORO SIMPLIFICATION

@#name lib56_autosimplify_pre

{

'-.vX:→(-1)*.vX' @ REMOVE NEGATIVE SIGN FROM VARIABLES

'√.XX:→.XX^INV(2)' @ ELIMINATE SQUARE ROOT FOR OTHER RULES TO WORK

}

@ GROUP 1 = USER DEFINED SIMPLIFICATION RULES

@#name lib56_autosimplify_group1

{

'AUTOSIMPLIFY.RULES'

}

@ GROUP 2 = BASIC (HARMLESS) SIMPLIFICATIONS

@#name lib56_autosimplify_group2

{

'0+.XX:→.XX' @ REMOVE TERMS WITH ZERO

'INV(1):→1' @ ELIMINATE OPERATION ON ONE

'INV(-1):→-1' @ ELIMINATE OPERATION ON MINUS ONE

'1*.XX:→.XX' @ REMOVE MULTIPLY BY ONE

'.XX^1:→.XX' @ REMOVE EXPONENT OF 1

'.MN*.mX+.MM*.mX:→(.MN+.MM)*.mX' @ ASSOCIATE TO THE LEFT (NON-COMMUTATIVE)

'.MN*.mX+.mX:→(.MN+1)*.mX' @ ASSOCIATE TO THE LEFT (NON-COMMUTATIVE)

'.mX*.MN+.mX*.MM:→.mX*(.MN+.MM)' @ ASSOCIATE TO THE RIGHT (NON-COMMUTATIVE)

'.mX*.MN+.mX:→.mX*(.MN+1)' @ ASSOCIATE TO THE RIGHT (NON-COMMUTATIVE)

'.xX+.xX:→2*.xX' @ ADD TERMS WITH NO NUMERIC FACTOR

'.NN*.xX^.Nexp+.NM*.xX^.Nexp:→(.NN+.NM)*.xX^.Nexp' @ ADD TERMS IN THE SAME VARIABLE AS LONG AS THE REST IS NUMERIC

'.xX^.Nexp+.NM*.xX^.Nexp:→(1+.NM)*.xX^.Nexp' @ ADD TERMS IN THE SAME VARIABLE AS LONG AS THE REST IS NUMERIC

}

@ GROUP 3 = CANCEL TERMS IN DIVISION (MAY REMOVE POLES)

@#name lib56_autosimplify_group3

{

'.xX^.NN*INV(.xX^.NM):→.xX^(.NN-.NM)' @ CANCEL OUT TERMS WITH EXPONENTS

'.xX^.NN*INV(.xX):→.xX^(.NN-1)' @ CANCEL OUT TERMS WITHOUT EXPONENT IN DENOMINATOR

'.xX*INV(.xX^.NM):→.xX^(1-.NM)' @ CANCEL OUT TERMS WITHOUT EXPONENT IN NUMERATOR

'.xX^.NN*.xX^.NM:→.xX^(.NN+.NM)' @ ADD EXPONENTS IN MULTIPLYING TERMS

'.mX*.mX^.NM:→.mX^(1+.NM)' @ ADD EXPONENTS WITH IMPLICIT EXPONENT 1

}

@ GROUP 4 = CANCEL TERMS WITH VARIABLES (k*X-k*X) (INVALID WHEN k*X REACHES INFINITY, OK WHEN THEY ARE FINITE NUMBERS)

@#name lib56_autosimplify_group4

{

'0*.XX:→0'

}

@ GROUP 5 =

@#name lib56_autosimplify_group5

{

}

@ GROUP 6 =

@#name lib56_autosimplify_group6

{

}

@ GROUP 7 =

@#name lib56_autosimplify_group7

{

}

@ GROUP 8 =

@#name lib56_autosimplify_group8

{

}

@ THESE ARE RULES TO BEAUTIFY AN EXPRESSION AFTER ALL OTHER SIMPLIFICATIONS ARE DONE

@#name lib56_autosimplify_post

{

'(-1)*.xX:→-.xX' @ REMOVE MINUS ONE MULTIPLICAND

'.XX^INV(2):→√.XX' @ BACK TO SQUARE ROOTS

}

Updated all ROMs to 1158.

I realized that the bit for the "infinity" attribute had inverted logic to all the rest. All attributes express a constraint (a restriction) on the set of values, so that for example a value that if a rule requires a value to be >=0, values that are >0 also meet this requirement by being a more specific subset. I achieved this by making the attribute be "cannot be zero" rather than "can be zero", but I had the infinity bit logic reversed, which resulted in real numbers + Infinity to be a subset of finite real numbers.

Anyway, I reversed the logic and published 1158. I also played a bit with the AUTOSIMPLIFY rules, so I'm not even sure what rules I have active anymore.

In the new version, 'X*X' now becomes 'X^2'. Whew!

However, while 'X^2*X' becomes 'X^3', 'X*X^2' does not. If that's because you're using non-commutative multiplication, you needn't bother for that case - it takes quite a lot of warping and spindling of the multiplication operator before powers stop making sense. Even sedenions, for which multiplication isn't commutative, associative, or even alternative have well-defined powers which are the same from the left and from the right (or indeed, in any order with any set of parentheses). True, rectangular matrices don't have powers, but then those expressions would error in any case.

I'm also a little puzzled by the parity attribute. What is the difference between a number being 'known to be odd' and being 'known to be an odd integer'? Are there non-integers for which parity is defined? I suppose you could define half-integers (ie, '1/2', '3/2', '5/2' and so on) to be odd in some sense, but I've never run across it before.

By the way, parity can be defined for complex numbers too - at least in the Gaussian integers. Anything divisible by '1+i' (which has a norm of 2) is even, all other Gaussian integers are odd. That works out to, "If the real and imaginary parts have the same parity, the complex number is even. If they have different parity, it's odd." For the real integers, that gives the usual parity, but in the Gaussian integers as a whole, you get a checkerboard pattern.

Of course, there are many ways to define 'integers' in the complex plane, of which the Gaussian integers are only one. (Though the simplest.)

(01-26-2019 04:55 PM)The Shadow Wrote: [ -> ]In the new version, 'X*X' now becomes 'X^2'. Whew! However, while 'X^2*X' becomes 'X^3', 'X*X^2' does not. If that's because you're using non-commutative multiplication, you needn't bother for that case - it takes quite a lot of warping and spindling of the multiplication operator before powers stop making sense. Even sedenions, for which multiplication isn't commutative, associative, or even alternative have well-defined powers which are the same from the left and from the right (or indeed, in any order with any set of parentheses). True, rectangular matrices don't have powers, but then those expressions would error in any case.

You are correct but you are missing the case with more factors. If we accept commutative multiplication it will shuffle all factors until it matches, so X*Y*X^2 will also match and become Y*X^3 which is incorrect for matrices. I just need to add the other non-commutative cases

(01-26-2019 04:55 PM)The Shadow Wrote: [ -> ]I'm also a little puzzled by the parity attribute. What is the difference between a number being 'known to be odd' and being 'known to be an odd integer'? Are there non-integers for which parity is defined? I suppose you could define half-integers (ie, '1/2', '3/2', '5/2' and so on) to be odd in some sense, but I've never run across it before.

It needs to be a separate bit, so that odd integers are a subset of integers when you AND their attributes. As a result, some weird combinations can result like numbers with the odd bit set but not the integer bit.

Whether we ignore those cases mathematically or not doesn't really matter. It's a way to keep performance to a decent level. I just AND the attributes and check the result to determine if the expression matches or not.

(01-26-2019 04:55 PM)The Shadow Wrote: [ -> ]By the way, parity can be defined for complex numbers too - at least in the Gaussian integers. Anything divisible by '1+i' (which has a norm of 2) is even, all other Gaussian integers are odd. That works out to, "If the real and imaginary parts have the same parity, the complex number is even. If they have different parity, it's odd." For the real integers, that gives the usual parity, but in the Gaussian integers as a whole, you get a checkerboard pattern.

Of course, there are many ways to define 'integers' in the complex plane, of which the Gaussian integers are only one. (Though the simplest.)

Is there a simple way to check if a complex is odd or even? If it won't perform I can't add it. For real numbers I just get the last digit and test one bit, that's fast enough so it doesn't bog the system (the idea is that some commands will be running hundreds of rules, so this needs to be fast).

(01-26-2019 05:23 PM)Claudio L. Wrote: [ -> ]You are correct but you are missing the case with more factors. If we accept commutative multiplication it will shuffle all factors until it matches, so X*Y*X^2 will also match and become Y*X^3 which is incorrect for matrices. I just need to add the other non-commutative cases

Sigh. Curses, foiled again!

Claudio Wrote:Is there a simple way to check if a complex is odd or even? If it won't perform I can't add it. For real numbers I just get the last digit and test one bit, that's fast enough so it doesn't bog the system (the idea is that some commands will be running hundreds of rules, so this needs to be fast).

I don't know if it's fast enough for your purposes, but you could XOR the parities of the real and imaginary parts. Upon further reflection, though, I'm not sure it's worth implementing... I'm having trouble thinking of rules or conditions that would use Gaussian parity.

(01-26-2019 06:09 PM)The Shadow Wrote: [ -> ]I don't know if it's fast enough for your purposes, but you could XOR the parities of the real and imaginary parts. Upon further reflection, though, I'm not sure it's worth implementing... I'm having trouble thinking of rules or conditions that would use Gaussian parity.

I've been reading a little about it (I don't claim to have any authority in the matter, though). For reals, it's clear that odd/even exponents are useful for simplifications, but I don't see any rules that could require identifying parity in complex numbers, so I'll leave it be.

All ROMs were updated to 1171.

Warning: Due to big internal changes, it is required to ARCHIVE your data first, update the firmware, then RESTORE it (either via USB or SD card). In general, you won't lose your data if you don't do it this way, but your settings will be lost (fonts, flags, current precision, etc.).

What's new:

* Rules engine is finally stable for general use.

* New constants library, adds pi, e, i and j for now (i and j are both defined as (0,1), so no quaternions)

* New "case" list type. Prepending a 'c' before the list it becomes a case-list. It only differs from regular lists in how overloaded operators work. Case-lists elements are considered alternative values of the same result. A variable X that contains c{ 1 2 }, means that X could take either the value of 1 or 2. For example, adding { 1 2 } { 3 4 } + would normally result in { 4 6 } (addition element-by-element). with case-lists, c{ 1 2 } c{ 3 4 } + results in c{ 4 5 5 6 }, which represents all possible combinations adding A+B where A could be 1 or 2 and B could be 3 or 4. Therefore A+B can be either: (1+3) (1+4) (2+3) or (2+4). Now the big question: WHY??? so that functions can return alternative results. For example √4 could return c{ -2 2 }, and if that's embedded within a larger expression, computations will carry on normally.

* New command ALLROOTS: Doing '√4+3' ALLROOTS returns c{ 5 1 } after ->NUM, as expected.

* Bug fix: Added argument checks for NUMINT

* Added support for lists, case-lists and angle objects compiled within symbolic expressions.

* Added a 10-pixel font (somebody requested one for the 50g in another thread, and I thought it was a good idea to have one).

These latest additions might still be a little glitchy. Please test and report.

Oooh! I *like* the idea of case lists!! I'm going to have to sit down and do some serious pondering about how to take best advantage of them.

Is there a ->CLIST command or equivalent?

c{ 1 -1 } might be worth adding as a constant, not sure yet. It probably comes up more often than any other set of cases, though.

I won't be able to test until I get home from work, but I'll dive right in at that point!

Is there any way to add to the constant library?

(02-15-2019 06:58 PM)Claudio L. Wrote: [ -> ]...* New constants library, adds pi, e, i and j for now (i and j are both defined as (0,1), so no quaternions)

In electrical and electronic engineering we use the j letter as the imaginary unit =)

How is the character i / j of the imaginary unit defined in newrpl? and if it is possible to assign it to another variable name to use it, for example, as counters i, j in the for cycle.

(02-15-2019 08:24 PM)The Shadow Wrote: [ -> ]Oooh! I *like* the idea of case lists!! I'm going to have to sit down and do some serious pondering about how to take best advantage of them.

Is there a ->CLIST command or equivalent?

c{ 1 -1 } might be worth adding as a constant, not sure yet. It probably comes up more often than any other set of cases, though.

I won't be able to test until I get home from work, but I'll dive right in at that point!

Is there any way to add to the constant library?

There's no ->CLIST command at the moment. For now you can type them in, I added only one command RANGE(start, end,step) similar to the python range() function that I needed to implement ALLROOTS rules. It returns a case list.

Regarding adding to the constant library, if you mean add constants in ROM yes you can, the source code is plain RPL. If you want to add user constants, just store the value in a variable and make it read only with LOCKVAR. It will essentially become a constant, I'm not sure there's any practical difference with doing it as a constant object.

(02-15-2019 09:48 PM)compsystems Wrote: [ -> ] (02-15-2019 06:58 PM)Claudio L. Wrote: [ -> ]...* New constants library, adds pi, e, i and j for now (i and j are both defined as (0,1), so no quaternions)

In electrical and electronic engineering we use the j letter as the imaginary unit =)

How is the character i / j of the imaginary unit defined in newrpl? and if it is possible to assign it to another variable name to use it, for example, as counters i, j in the for cycle.

For now i and j are both identical, because some people prefer different designation, they are the same imaginary unit.

The constants e, i and j use symbols from the Cyrillic alphabet, so there's no conflict with the normal letters.

e is in the e^x key, alpha plane and the white shift as expected.

The imaginary constants are in the number 7 key, I forgot what shift planes, try all of them but it's quite intuitive once you get used to.

The rules system does indeed seem more robust, however 'X-X' causes a crash when EVAL'd, and 'X-2*X' gives '-X' twice for some reason. And 'X/X' still doesn't become '1', even though all other divisions simplify correctly when the flags allow for it.

ALLROOTS doesn't work properly on square roots of negative numbers. For example, sqrt(-3) gives the same result as sqrt(3) when ALLROOTS is used on it. EDIT: On the other hand, it does a really nifty job on things like '(-1)^(1/3)'!

The case-lists work beautifully. One oddity, though - they have the same extended type as regular lists. I'd suggest giving them an extension of their own.

Also, the 'case' property is perhaps a shade too fragile - it gets lost if you ADD two case-lists together, which seems like something worth doing. Likewise if you PUT something in one.

It could be interesting to produce other list variants. One that immediately comes to mind is sets: Basically lists that can't have more than one of a given element. ADDing them would do union.

Once tagged objects are in, a Python-style 'dictionary' list might also be useful.

For future reference, the Cyrillic 'i' is Alpha-LS-7, and the Cyrillic 'j' is Alpha-LS-Hold-7. Adding a Cyrillic 'k' would be appreciated, so I can program in quaternions without them looking funny.

(Though I suppose I could get away with just calling it 'i*j', or even 'ij'.)

Where is the constant library located? I haven't seen it yet.

P.S. Is there a 'plus or minus' symbol on the calculator? That'd be perfect for c{1 -1}.

(02-17-2019 05:13 AM)The Shadow Wrote: [ -> ]It could be interesting to produce other list variants. One that immediately comes to mind is sets: Basically lists that can't have more than one of a given element. ADDing them would do union.

Once tagged objects are in, a Python-style 'dictionary' list might also be useful.

Enthusiastic yes to both!

Oh, and now that we have symbolic imaginary units, it'd be nice to see RE and IM interact with them. They *kind of* do now, but you have to follow up with ->NUM.

Perhaps a flag could control whether Cyrillic 'i' or 'j' is used as the imaginary unit? It's a bit awkward having them both in play at the same time. And it's a similar sort of preference thing as, for example, which month/day/year format to use.

(02-17-2019 05:13 AM)The Shadow Wrote: [ -> ]The rules system does indeed seem more robust, however 'X-X' causes a crash when EVAL'd, and 'X-2*X' gives '-X' twice for some reason. And 'X/X' still doesn't become '1', even though all other divisions simplify correctly when the flags allow for it.

I must've broken something, that was working before... I'll investigate, thanks for the report.

(02-17-2019 05:13 AM)The Shadow Wrote: [ -> ]ALLROOTS doesn't work properly on square roots of negative numbers. For example, sqrt(-3) gives the same result as sqrt(3) when ALLROOTS is used on it. EDIT: On the other hand, it does a really nifty job on things like '(-1)^(1/3)'!

I'll check the rules, I think I need a separate rule to transform sqrt(-.xX) into i*sqrt(.xX).

(02-17-2019 05:13 AM)The Shadow Wrote: [ -> ]The case-lists work beautifully. One oddity, though - they have the same extended type as regular lists. I'd suggest giving them an extension of their own.

That's a bug, they have a different library number, should report a different type. I'll check that as well, thanks!

(02-17-2019 05:13 AM)The Shadow Wrote: [ -> ]Also, the 'case' property is perhaps a shade too fragile - it gets lost if you ADD two case-lists together, which seems like something worth doing. Likewise if you PUT something in one.

There's many existing commands that are not case-list aware yet. They do recognize a list but I need to updaste them to keep the type of the list given untouched.

(02-17-2019 05:13 AM)The Shadow Wrote: [ -> ]It could be interesting to produce other list variants. One that immediately comes to mind is sets: Basically lists that can't have more than one of a given element. ADDing them would do union.

Once tagged objects are in, a Python-style 'dictionary' list might also be useful.

Yes, except I want them more flexible than Python. Lua tables are good examples, this would also make it simple too add a Lua2RPL library to allow people to code in Lua within the newRPL environment. That's a future improvement...

For future reference, the Cyrillic 'i' is Alpha-LS-7, and the Cyrillic 'j' is Alpha-LS-Hold-7. Adding a Cyrillic 'k' would be appreciated, so I can program in quaternions without them looking funny.

(Though I suppose I could get away with just calling it 'i*j', or even 'ij'.)

Where is the constant library located? I haven't seen it yet.

P.S. Is there a 'plus or minus' symbol on the calculator? That'd be perfect for c{1 -1}.

[/quote]

(02-17-2019 04:53 PM)John Keith Wrote: [ -> ]Enthusiastic yes to both!

I'm feeling the pressure now...

(02-17-2019 09:48 PM)The Shadow Wrote: [ -> ]Oh, and now that we have symbolic imaginary units, it'd be nice to see RE and IM interact with them. They *kind of* do now, but you have to follow up with ->NUM.

Perhaps a flag could control whether Cyrillic 'i' or 'j' is used as the imaginary unit? It's a bit awkward having them both in play at the same time. And it's a similar sort of preference thing as, for example, which month/day/year format to use.

Many commands need to also be updated to better interact with constants as well. Adding a new type when there's 400 commands already implemented is hard...

Regarding the letter choice. I think:

* People who like I or j typically use them consistently

* Having i and j at the same equation is still useful for people who want to define rules on them to try to implement quaternions for example. As long as you don't use ->NUM, they are two different things.