Re: [EXTERNAL] Re: 1-button calcula tor ~ "all elementary fns from a single operator"

Henry Baker <[email protected]> Sun, 03 May 2026 19:46:31 +0000
Newsgroups gmane.comp.mathematics.maxima.general
Message-ID <[email protected]>
The fellow who wrote the paper has been using this notation to try to *compress* numerical data streams.

There are several motivations:

1. Shorter representations than more traditional forms of data compression -- e.g., FFT's.

2. Better *interpolation* for estimating data not captured originally.

3. Suggestions for new physical laws by examining the structure of these short representations.

---
BTW, just because this "bit-sequence" representation uses only 2 operations doesn't necessarily make it inefficient to interpret.

Modern hardware *instruction caches* have gone far beyond trivial table lookups, and can now perform certain "peephole" optimizations on-the-fly; these may not save instruction *bits*, but still save instruction *execution time*.

For example, an instruction cache for an hypothetical ELM computer would be a long bit-string *shift-register*, and one could do a table lookup on the leftmost 8 or 16 or 24 bits to find a *macro instruction* which would be a pre-compiled *optimized* version of whatever the given instruction bitstream wanted to do. Such precompilation would save an enormous amount of time, and could also preserve *far more bits of precision* than the given instruction bitstream -- e.g., precompiled *constants* could simply be *looked up*, so there would be no loss of precision or time in loading such constants; the complicated expressions for sin,cos,tan,asin,acos,atan etc., would be *recognized* as sin,cos,tan,asin,acos,atan etc., so that there would be no time or precision penalty for any of these common function patterns.

-----Original Message-----
From: Stavros Macrakis <[email protected]>
Sent: May 3, 2026 12:21 PM
To: <[email protected]>
Cc: Barton Willis via Maxima-discuss <[email protected]>
Subject: Re: [Maxima-discuss] [EXTERNAL] Re: 1-button calculator ~ "all elementary fns from a single operator"

Yes, you can recognize common subexpressions in Maxima using optimize. So the CSE version of x^(2/3) is
 
block([%1,%2,%3,%4],%1:E(1,1),%2:E(1,E(%1,1)),%3:E(1,E(E(1,%2),1)),
      %4:E(%2,E(E(%3,%1),1)),
      E(E(E(E(1,
              E(E(1,
                  E(1,
                    E(E(1,
                        E(E(E(1,E(E(1,E(1,E(E(1,%4),1))),1)),
                            E(E(%3,
                                E(E(1,
                                    E(E(1,
                                        E(
                                         E(%3,
                                           E(
                                            E(1,
                                              E(E(1,E(%2,E(E(%3,E(%4,1)),1))),
                                                1)),1)),1)),1)),1)),1)),1)),
                      1))),1)),
            E(E(%3,E(E(1,E(E(1,E(1,E(E(1,x),1))),1)),1)),1)),1),1))$
 
Of course, you can make the representation even more compact if you recognize subparts like, say, exp. And then you're back to conventional representation.
 
I don't know why you'd want to G&ouml;del number expressions via EML when you can just as well look at the linear or tree form of conventional representations as bitstrings.
 
This is not a "model of computation". It is just a notation. Of course Richardson's theorem applies to it, since that only requires sin, rational numbers, arithmetic, and functional composition, a subset of the calculator functions.
 
Has anyone done anything non-trivial with this representation?
 


On Sun, May 3, 2026 at 2:46 PM Henry Baker <[email protected] (mailto:[email protected])> wrote:
Hi Stavros:

You are correct re optimizers; I've already been playing with obvious optimizations.

Also, an ideal compiler would detect (&amp; take advantage of) *common sub-expressions*; otherwise, you're constantly ( :-) re-calculating the simplest things (like constants!). Common subexpressions are trivially recognized in Lisp with so-called "hash consing"; e.g., I believe that the "Maple" symbolic algebra system routinely does hash consing and memoization.

Most stack machines -- e.g., Postscript -- have the capabilities to rearrange and duplicate items on the stack, which enables common subexpressions to avoid recomputation.  (Indeed, I wrote such a compiler for a Lisp-like language to Postscript many years ago!)

Why should someone care about this?

1. The linear instructions for the stack machine are *bit-strings* (i.e., positive integers). For example, the bit-string "110" tells the stack machine to "push 1; push 1; ELM 0(peration)".

So we inherit a natural Godel numbering for every elementary function (obviously not 1-1).

2. Q: does the undecidability of zerop apply to this model of computation ?

3. I'm not convinced that this gentleman has found the most elegant set of primitives; there may be other primitives with more natural properties.  For example, the proof of the commutativity of + and * does not appear to be simple.  Neither would any of the other standard properties of this class of functions be easy to prove -- e.g., distribution of * over +.

4. The expansion of traditional mathematical expressions into EML form does not appear to "blow up", and if the interconversion can be done quickly/efficiently, then this EML form might become a *standard representation* of such expressions -- even an "ISO" and/or "IEEE" standard -- making it easier to communicate between different languages, symbolic algebra systems, etc.

5. A standard representation could nail down the *default* interpretations of expressions like log(0), etc., so that different systems could avoid the messiness of so many different switches/parameters.



-----Original Message-----
From: Stavros Macrakis <[email protected] (mailto:[email protected])>
Sent: May 3, 2026 10:18 AM
To: Henry Baker <[email protected] (mailto:[email protected])>
Cc: Barton Willis via Maxima-discuss <[email protected] (mailto:[email protected])>
Subject: Re: [Maxima-discuss] [EXTERNAL] Re: 1-button calculator ~ "all elementary fns from a single operator"

 
Thanks for sharing the Python code. It is strange that the author calls straightforward macro-expansion a "compiler", but I guess these days you can get a degree in CS without taking a compiler class....
 
This translates easily into Mazima (see end of post). Careful! This does not guarantee the minimal EML expression, or even a reasonable approximation to it. For example, exp(x)-log(y) is minimally expressed as e(x,y), not
 
e(e(1,e(e(1,e(x,1)),1)),

  e(e(1,e(e(1,y),1)),1)
 
which is what you get by direct expansion.
 
What next? "optimizers" for eml expressions?
 
I still don't see the point. How is it helpful to write x^(2/3) as
 
E(E(E(E(1,
        E(E(1,
            E(1,
              E(E(1,
                  E(E(E(1,E(E(1,E(1,E(E(1,E(E(1,E(E(1,1),1)),E(E(E(1,E(E(1,E(1,E(E(1,1),1))),1)),E(1,1)),1))),1))),1)),
                      E(E(E(1,E(E(1,E(1,E(E(1,1),1))),1)),
                          E(E(1,
                              E(E(1,
                                  E(E(E(1,E(E(1,E(1,E(E(1,1),1))),1)),
                                      E(E(1,
                                          E(E(1,
                                              E(E(1,E(E(1,1),1)),
                                                E(E(E(1,E(E(1,E(1,E(E(1,1),1))),1)),
                                                    E(E(E(1,E(E(1,1),1)),E(E(E(1,E(E(1,E(1,E(E(1,1),1))),1)),E(1,1)),1)),1)),1))),1)),1)),1)),1)),
                            1)),1)),1)),1))),1)),E(E(E(1,E(E(1,E(1,E(E(1,1),1))),1)),E(E(1,E(E(1,E(1,E(E(1,x),1))),1)),1)),1)),1),1)
 
 
--------------------------
 
 /* write expression using eml */

eml_exp(z):= e(z, 1) ;
eml_log(z):= e(1, eml_exp(e(1, z))) ;
eml_zero():= eml_log(1) ;
eml_sub(a, b):= e(eml_log(a), eml_exp(b)) ;
eml_neg(z):= eml_sub(eml_zero(), z) ;
eml_add(a, b):= eml_sub(a, eml_neg(b)) ;
eml_inv(z):= eml_exp(eml_neg(eml_log(z))) ;
eml_mul(a, b):= eml_exp(eml_add(eml_log(a), eml_log(b))) ;
eml_div(a, b):= eml_mul(a, eml_inv(b)) ;
eml_pow(a, b):= eml_exp(eml_mul(b, eml_log(a))) ;
eml_one():= 1;
eml_two():= eml_add(1, 1);
eml_double(z):= eml_add(z, z);


/* expand back */

eml(a,b):=eexp(a)-elog(b);
eexp(a):=if a=inf then inf elseif a=minf then 0 else exp(a);
elog(a):= if a=inf then inf elseif a=0 then minf else log(a);

load("opsubst");
expand_eml(expr) := block([sub: opsubst('eml,'e,expr)], ev(sub,nouns));


 
On Sun, May 3, 2026 at 12:33 PM Henry Baker <[email protected] (mailto:[email protected])> wrote:

OK, I looked at the Python3 code for the EML compiler, and it looks like it would be trivial to translate its formulae into Maxima using pattern matching.

For example, here are some of the Python3 functions:

def EML(a, b): return f"EML[{a},{b}]"
def eml_exp(z): return EML(z, "1") # Exp[z]
def eml_log(z): return EML("1", eml_exp(EML("1", z))) # Log[z]
def eml_zero(): return eml_log("1") # 0 = Log[1]
def eml_sub(a, b): return EML(eml_log(a), eml_exp(b)) # a - b
def eml_neg(z): return eml_sub(eml_zero(), z) # -z
def eml_add(a, b): return eml_sub(a, eml_neg(b)) # a + b
def eml_inv(z): return eml_exp(eml_neg(eml_log(z))) # 1/z
def eml_mul(a, b): return eml_exp(eml_add(eml_log(a), eml_log(b))) # a*b
def eml_div(a, b): return eml_mul(a, eml_inv(b)) # a/b
def eml_pow(a, b): return eml_exp(eml_mul(b, eml_log(a))) # a^b
def eml_one(): return "1"
def eml_two(): return eml_add("1", "1")
def eml_double(z): return eml_add(z, z)

Thus, in Maxima
matchdeclare(z,all);
tellsimp(exp(z),EML(z,1));
tellsimp(log(z),EML(1,exp(EML(1,z))));

However, such a pattern-matching compiler would have a bigger problem with sums and products, and an even bigger problem with converting constants -- e.g., integers, rationals, floats.

The good news: EML compiling and simplification provide a pretty decent workout for Maxima, and would likely make some pretty good test cases and/or benchmarks.

-----Original Message-----
From: Henry Baker <[email protected] (mailto:[email protected])>
Sent: May 2, 2026 8:53 AM
To: Przemek Klosowski via Maxima-discuss <[email protected] (mailto:[email protected])>
Subject: Re: [Maxima-discuss] [EXTERNAL] Re: 1-button calculator ~ "all elementary fns from a single operator"

OK, I downloaded the "EML compiler" from here:

https://github.com/VA00/SymbolicRegressionPackage/tree/master

The EML compiler requires python3 &amp;amp; numpy (and probably other stuff that I might already have installed).

I then did a trivial script to convert from Mathematica expressions to Maxima expressions.

EML requires that log(0)=minf, so I defined mylog(x):=if (x=0) then minf else log(x), and used mylog(x) instead of log(x) in the definition of eml.

However, I now require that %e^minf = 0.

What is the magic in Maxima to make this happen? I did "? minf", but that didn't provide any help.

-----Original Message-----
From: Henry Baker
Sent: May 1, 2026 11:23 AM
To: Przemek Klosowski via Maxima-discuss
Subject: Re: [Maxima-discuss] [EXTERNAL] Re: 1-button calculator ~ "all elementary fns from a single operator"

Obviously, Google was confused.

Q: If z = exp(x)-log(y), then x = log(z + log(y)) might look a tad better ? Is this log(z+log(y)) function universal in the same sense as eml() ?

Q: if we have a 1BC expression for f(x)=y, can we then trivially compute x=f^-1(y) ?

Q: The 1BC paper seems to want to rely on functions defined over the reals; I suspect that functions defined over the complex numbers might give additional 1BC results that might be prettier ? Perhaps the constant %pi*%i might work to force things into the complex plane ?

Q: I've always had a fondness for asinh(x), as it is bijective onto the reals, and has many of the same properties/characteristics as "gradual underflow" floating point numbers. I'm wondering if it could be part of a universal 1BC function ?

-----Original Message-----
From: Przemek Klosowski via Maxima-discuss
Sent: May 1, 2026 9:24 AM
To:
Subject: Re: [Maxima-discuss] [EXTERNAL] Re: 1-button calculator ~ "all elementary fns from a single operator"

> BTW, Google just told me that the obvious differential equation for > eml(x,y) is
>
> dy/dx = y*exp(x)

(%i1) eq:'diff(y,x)=y*exp(x);
dy x
(%o1) ── = %e y
dx
(%i2) ode2(eq,y,x);
x
%e
(%o2) y = %e %c

what am I missing?



_______________________________________________
Maxima-discuss mailing list
[email protected] (mailto:[email protected])
https://lists.sourceforge.net/lists/listinfo/maxima-discuss




_______________________________________________
Maxima-discuss mailing list
[email protected] (mailto:[email protected])
https://lists.sourceforge.net/lists/listinfo/maxima-discuss




_______________________________________________
Maxima-discuss mailing list
[email protected] (mailto:[email protected])
https://lists.sourceforge.net/lists/listinfo/maxima-discuss




_______________________________________________
Maxima-discuss mailing list
[email protected] (mailto:[email protected])
https://lists.sourceforge.net/lists/listinfo/maxima-discuss

_______________________________________________
Maxima-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/maxima-discuss