Querying the algebra hierarchy

4 views
Skip to first unread message

Paul Onions

unread,
Jun 19, 2022, 3:02:02 PM6/19/22
to fricas...@googlegroups.com
Hi All,

I’ve been looking into the SPAD Database and IndexCard domains with a view to adding some “domain explorer” functionality to my “frimacs” Emacs package (the successor to "axiom-environment”, see https://github.com/pdo/frimacs ).

I’ve noticed a couple of problems with the elt operation of IndexCard, one of which is that the ‘condition query (which I assume is for querying the conditional export of an operation by a domain) doesn’t seem to return anything. This seems to be because the “o” lines in the generated libdb.text file do not contain any information in the relevant field.

So my first thought was to look into the Boot code to see how libdb.text is generated and perhaps enhance it to include conditional export info. But then I thought, well, HyperDoc manages to show this information so it can’t be using libdb.text (at least not alone). So now I realise there must be another mechanism implemented that allows querying the algebra hierarchy, and I’m wondering if this other mechanism is to be preferred?

In other words, would I be wasting my time messing around with libdb.text? Should I really be trying to understand the Boot code implementing the HyperDoc browser, and perhaps defining an API to allow non-HyperDoc code to access this information too?

Any insight appreciated,
Paul

Qian Yun

unread,
Jun 21, 2022, 9:21:06 AM6/21/22
to fricas...@googlegroups.com
Hi Paul,

I saw your github PR#93 and tested it, the bug exists and your fix
works.

About "libdb.text", I take a look at src/interp/br-search.boot,
I find HyperDoc searches "libdb.text" when you type a string
and "Search for operations". And it simply construct a grep
string and use "sh" to execute it. (Can exploited to execute
other shell commands, BTW).

About "condition query", can you give an example? What's the
input and what you expect to get? The HyperDoc seems to ignore
the condition part when it "Search for operations".

- Qian

Paul Onions

unread,
Jun 21, 2022, 3:32:06 PM6/21/22
to fricas...@googlegroups.com
Hi Qian,

> I saw your github PR#93 and tested it, the bug exists and your fix
> works.

Thanks.

> About "condition query", can you give an example? What's the
> input and what you expect to get? The HyperDoc seems to ignore
> the condition part when it "Search for operations”.

The information I’m after is what you get when you enter (for example) “QuadraticForm” in the HyperDoc browser page, then press:-

Constructors -> Operations -> Conditions

where you’ll see, at the bottom of the page, an entry for “convert” that shows under what conditions it is exported.

Also, I’d like to get the Origins info so I can show where an operation is implemented, and basically get access to any of the other information that the HyperDoc browser displays. Ideally there would be a well-defined API that would allow me to do this, but after looking at the br-*.boot files I see that it all seems to be mixed in with the HyperDoc page construction code. So I need to spend some more time looking into it to see properly how it all works.

However, I get the feeling that different parts of this algebra database “system” were perhaps developed at different times by different people, and that there is unnecessary overlap and redundancy at play here.

Thanks,
Paul

Qian Yun

unread,
Jun 21, 2022, 9:25:39 PM6/21/22
to fricas...@googlegroups.com


On 6/22/22 03:32, Paul Onions wrote:
> Hi Qian,
>
>> I saw your github PR#93 and tested it, the bug exists and your fix
>> works.
>
> Thanks.
>
>> About "condition query", can you give an example? What's the
>> input and what you expect to get? The HyperDoc seems to ignore
>> the condition part when it "Search for operations”.
>
> The information I’m after is what you get when you enter (for example) “QuadraticForm” in the HyperDoc browser page, then press:-
>
> Constructors -> Operations -> Conditions
>
> where you’ll see, at the bottom of the page, an entry for “convert” that shows under what conditions it is exported.

So the same information as ")show QuadraticForm"? HyperDoc and
command line do use different functions to get this information.

> Also, I’d like to get the Origins info so I can show where an operation is implemented, and basically get access to any of the other information that the HyperDoc browser displays. Ideally there would be a well-defined API that would allow me to do this, but after looking at the br-*.boot files I see that it all seems to be mixed in with the HyperDoc page construction code. So I need to spend some more time looking into it to see properly how it all works.

IIRC, the "Origins" info exists only in HyperDoc and not command line.
This is very long term issue. I do hope it can be available in
command line as well.

> However, I get the feeling that different parts of this algebra database “system” were perhaps developed at different times by different people, and that there is unnecessary overlap and redundancy at play here.
>
> Thanks,
> Paul
>

Yes, there is overlap and redundancy. Cleaning them up at BOOT
level and provide a SPAD interface would be nice.

I can spend some efforts in this direction for next release.

- Qian

Ralf Hemmecke

unread,
Jun 22, 2022, 2:36:15 AM6/22/22
to fricas...@googlegroups.com
> So the same information as ")show QuadraticForm"? HyperDoc and
> command line do use different functions to get this information.

And to make things worse the information at http://fricas.github.io/api
is computed in yet another way.

https://github.com/fricas/fricas/blob/master/src/doc/api.spad

In particular the conditional functions were problematic as I remember.
I currently cannot show a congrete example, but I remember that for some
functions there where a mismatch between HyperDoc and
http://fricas.github.io/api.

> Yes, there is overlap and redundancy.  Cleaning them up at BOOT
> level and provide a SPAD interface would be nice.
>
> I can spend some efforts in this direction for next release.

That's perhaps not interesting for the generic user, but it would be
nice to have that properly and "officially". Maybe then a big part of my
api.spad can go away or maybe you find it useful for the official interface.

Ralf

Waldek Hebisch

unread,
Jun 22, 2022, 4:10:41 AM6/22/22
to fricas...@googlegroups.com
On Tue, Jun 21, 2022 at 08:32:03PM +0100, Paul Onions wrote:
> Hi Qian,
>
> > I saw your github PR#93 and tested it, the bug exists and your fix
> > works.
>
> Thanks.
>
> > About "condition query", can you give an example? What's the
> > input and what you expect to get? The HyperDoc seems to ignore
> > the condition part when it "Search for operations”.
>
> The information I’m after is what you get when you enter (for example) “QuadraticForm” in the HyperDoc browser page, then press:-
>
> Constructors -> Operations -> Conditions
>
> where you’ll see, at the bottom of the page, an entry for “convert” that shows under what conditions it is exported.
>
> Also, I’d like to get the Origins info so I can show where an operation is implemented, and basically get access to any of the other information that the HyperDoc browser displays. Ideally there would be a well-defined API that would allow me to do this, but after looking at the br-*.boot files I see that it all seems to be mixed in with the HyperDoc page construction code. So I need to spend some more time looking into it to see properly how it all works.

Note that Origins is about declaration, not implementation. That is
place which declared given operation. Spad forms set theoretic sum
on signatures, so "the same" signature may be declared in multiple
placses, Origins probably only gives one declaration. AFAICS
Origins sometimes get confused by coditions.

Implemention is separate thing, you get it clicking at Implementions
in view for operations. But it works only for fully determined
domains, that is all parameters must be explicit.

> However, I get the feeling that different parts of this algebra database “system” were perhaps developed at different times by different people, and that there is unnecessary overlap and redundancy at play here.

Well, primary info is in domain vectors. For fully specified domain
one can view it using routines in 'showimp.boot', for example using

)boot showSummary(FreeModule(Integer(), Symbol()))

(this is probably intended as help for people developing Spad
compiler).

There are separate routines for viewing info without giving
parameters (in 'nruncomp.boot') like:

)boot dcAll('Expression)

To speed up searching for declarations/documentaion we have
databases. Basic routine here is GETDATABSE which takes
two arguments, one is name of thing (symbol), the second
is kind of requested information. In 'daase.lisp' there
is description what various kinds mean. One can also use
SHOWDATABASE to get all information about constructor.
Actual information is kept in four files: interp.daase,
browse.daase, operation.daase and category.daase.
HyperDoc also uses 'USERS.DAASE' and 'DEPENDENTS.DAASE'.

HyperDoc and ')show' mostly give higher level info based
on databases. But there is a lot of filtering, reformatting,
and some manipulation with conditions.

Certanly I would like to expose useful information to
allow better reuse. And ultimately convert all this
code to Spad.

--
Waldek Hebisch

Paul Onions

unread,
Jun 22, 2022, 3:32:09 PM6/22/22
to fricas...@googlegroups.com
Hi Waldek,

On 22 Jun 2022, at 09:10, Waldek Hebisch <de...@fricas.math.uni.wroc.pl> wrote:
>
> On Tue, Jun 21, 2022 at 08:32:03PM +0100, Paul Onions wrote:
>>
>> Also, I’d like to get the Origins info so I can show where an operation is implemented, and basically get access to any of the other information that the HyperDoc browser displays. Ideally there would be a well-defined API that would allow me to do this, but after looking at the br-*.boot files I see that it all seems to be mixed in with the HyperDoc page construction code. So I need to spend some more time looking into it to see properly how it all works.
>
> Note that Origins is about declaration, not implementation. That is
> place which declared given operation. Spad forms set theoretic sum
> on signatures, so "the same" signature may be declared in multiple
> placses, Origins probably only gives one declaration. AFAICS
> Origins sometimes get confused by coditions.
>
> Implemention is separate thing, you get it clicking at Implementions
> in view for operations. But it works only for fully determined
> domains, that is all parameters must be explicit.

My understanding is that a domain brings with it a collection of operations, each one implemented either in the domain itself or in a category referenced by the domain (directly or indirectly). So for any given domain I was expecting it to be possible to list all the operations and to be able to indicate the source of each one explicitly, so we would know how each operation is implemented in that domain.


I think you are saying that this can be done, but it requires all domain parameters to be explicitly specified, and that this is called “Implementation” in HyperDoc. That’s understandable I guess, but it also means that “Origins” is of limited value if it just picks arbitrarily one place where the operation is declared?

>> However, I get the feeling that different parts of this algebra database “system” were perhaps developed at different times by different people, and that there is unnecessary overlap and redundancy at play here.
>
> Well, primary info is in domain vectors. For fully specified domain
> one can view it using routines in 'showimp.boot', for example using
>
> )boot showSummary(FreeModule(Integer(), Symbol()))
>
> (this is probably intended as help for people developing Spad
> compiler).
>
> There are separate routines for viewing info without giving
> parameters (in 'nruncomp.boot') like:
>
> )boot dcAll('Expression)
>
> To speed up searching for declarations/documentaion we have
> databases. Basic routine here is GETDATABSE which takes
> two arguments, one is name of thing (symbol), the second
> is kind of requested information. In 'daase.lisp' there
> is description what various kinds mean. One can also use
> SHOWDATABASE to get all information about constructor.
> Actual information is kept in four files: interp.daase,
> browse.daase, operation.daase and category.daase.
> HyperDoc also uses 'USERS.DAASE' and 'DEPENDENTS.DAASE’.

Thanks Waldek, lots of useful info here.

Paul


Waldek Hebisch

unread,
Jun 25, 2022, 8:41:20 AM6/25/22
to fricas...@googlegroups.com
On Wed, Jun 22, 2022 at 08:32:06PM +0100, Paul Onions wrote:
> Hi Waldek,
>
> On 22 Jun 2022, at 09:10, Waldek Hebisch <de...@fricas.math.uni.wroc.pl> wrote:
> >
> > On Tue, Jun 21, 2022 at 08:32:03PM +0100, Paul Onions wrote:
> >>
> >> Also, I’d like to get the Origins info so I can show where an operation is implemented, and basically get access to any of the other information that the HyperDoc browser displays. Ideally there would be a well-defined API that would allow me to do this, but after looking at the br-*.boot files I see that it all seems to be mixed in with the HyperDoc page construction code. So I need to spend some more time looking into it to see properly how it all works.
> >
> > Note that Origins is about declaration, not implementation. That is
> > place which declared given operation. Spad forms set theoretic sum
> > on signatures, so "the same" signature may be declared in multiple
> > placses, Origins probably only gives one declaration. AFAICS
> > Origins sometimes get confused by coditions.
> >
> > Implemention is separate thing, you get it clicking at Implementions
> > in view for operations. But it works only for fully determined
> > domains, that is all parameters must be explicit.
>
> My understanding is that a domain brings with it a collection of operations, each one implemented either in the domain itself or in a category referenced by the domain (directly or indirectly).

Not exactly. At low level domain has operations that it implements
itself, in a sense it "brings with" those operations. But domain
also have set interfaces (categories). And there is so call 'add
chain': domain may inherit unimplemented operations from another
domain. Actual operation to use is determined at runtime, there
is complicated procedure that examines conditions and decides
which of implementations to use (it looks at operations implemented
in categories and at 'add chain').

The point is that this information is dynamic and distributed, most
is not in the domain. In particular, as long as interface parts
does not change the same binary domain could use implementation
from differnet place after other domains are modified.

> So for any given domain I was expecting it to be possible to list all the operations and to be able to indicate the source of each one explicitly, so we would know how each operation is implemented in that domain.
>
>
> I think you are saying that this can be done, but it requires all domain parameters to be explicitly specified, and that this is called “Implementation” in HyperDoc.

Currently yes. Basically this simulates runtime call and tells you
which operation would be used. Actually, it reuses code used
by runtime calls. But before you can run code domain must be
"instantiated", that is parameters must be known.

People want more info about implementation and in principle we
could provide more: naively search could look at about 15000
implementations (this is rough estimate of number of different
implementation that we have). Actual search is smarter, but
must look at lot of data. We could simulate search, prune
all operations that can not apply and get decision tree
with hopefully small number of alternatives. I wrote
"decision tree" because availability of operations depends
on conditions and conditions depend on parameters. We
could try to simplify conditions, but without parameters
the best we can hope is decision tree. And "simplest form"
of conditions is undecidable, so we need to accept some
redundancy.

However, even such moderate goal, that is getting reasonably
sized decision tree with possibly reduntant conditions
remain unimplemented. One aspect here is that to be
useful it should agree with what runtime search is doing,
so implementer has to be quite careful do exactly what
runtime search is doing, but in "generic way", that is
without evaluationg conditions.

There is extra complication caused by Aldor interface: FriCAS
treats Aldor stuff as black box with small number of contact
points. And IIUC Aldor treats FriCAS stuff mostly as black
box. Difficulty here is that interface can do "find operation
with given signature from fully specified domain", but can not
"give decision tree for signature from generic domain". So
any such extra would break down if there is possiblity that
Aldor code is involved.

> That’s understandable I guess, but it also means that “Origins” is of limited value if it just picks arbitrarily one place where the operation is declared?

Well, it depends on your goal. "Origins" correspond to static
point of view: you look at signature and who _declared_ it.
In principle that is all what you need to know if you want to
use operation or generalize existing code.

Info about implementations is of different spirit: it tells you
what will happen at runtime.

--
Waldek Hebisch

Paul Onions

unread,
Jun 25, 2022, 3:53:04 PM6/25/22
to fricas...@googlegroups.com
On 25 Jun 2022, at 13:41, Waldek Hebisch <de...@fricas.math.uni.wroc.pl> wrote:

On Wed, Jun 22, 2022 at 08:32:06PM +0100, Paul Onions wrote:
My understanding is that a domain brings with it a collection of operations, each one implemented either in the domain itself or in a category referenced by the domain (directly or indirectly).

Not exactly. At low level domain has operations that it implements
itself, in a sense it "brings with" those operations. But domain
also have set interfaces (categories). And there is so call 'add
chain': domain may inherit unimplemented operations from another
domain.

Ah yes, I forgot about the “add chain”.

Actual operation to use is determined at runtime, there
is complicated procedure that examines conditions and decides
which of implementations to use (it looks at operations implemented
in categories and at 'add chain').

Okay, this has prompted me to go back to the documentation and re-read chapter 13 again.  There is a useful description of the mechanism used for operation lookup there, thanks.

The point is that this information is dynamic and distributed, most
is not in the domain. In particular, as long as interface parts
does not change the same binary domain could use implementation
from differnet place after other domains are modified.

Yes, it’s much more complicated than I initially thought, so trying to come up with a simple way of visualising this is not easy :-(

I can see why HyperDoc is the way it is!
It needs to be shared code to ensure that the help system agrees with the runtime.

Maybe two successive stages:-

Stage 1: analyse source to derive a decision-tree.  Does not evaluate constructor parameters.  Code shared by compiler and help system.

Stage 2: evaluate constructor parameters to allow traversing of decision-tree to find implementations.  Code shared by runtime and help system.

Probably need some kind of limitation on the conditional inclusion mechanism to make it all tractable.  Sounds like an interesting research project! :-)

There is extra complication caused by Aldor interface: FriCAS
treats Aldor stuff as black box with small number of contact
points. And IIUC Aldor treats FriCAS stuff mostly as black
box. Difficulty here is that interface can do "find operation
with given signature from fully specified domain", but can not
"give decision tree for signature from generic domain". So
any such extra would break down if there is possiblity that
Aldor code is involved.

Yes, I think to create a “disciplined” type-safe, statically analysable system it is not possible to have such “black box” entities in it.  It is an “all or nothing” approach.

That’s understandable I guess, but it also means that “Origins” is of limited value if it just picks arbitrarily one place where the operation is declared?

Well, it depends on your goal. "Origins" correspond to static
point of view: you look at signature and who _declared_ it.
In principle that is all what you need to know if you want to
use operation or generalize existing code.

Info about implementations is of different spirit: it tells you
what will happen at runtime.

Which, to my mind, is the most important thing.  You cannot write software without understanding what is likely to happen :-)

Paul

Paul Onions

unread,
Jul 10, 2022, 4:59:15 AM7/10/22
to fricas...@googlegroups.com
Hi Waldek,

On 22 Jun 2022, at 09:10, Waldek Hebisch <de...@fricas.math.uni.wroc.pl> wrote:

Well, primary info is in domain vectors. For fully specified domain
one can view it using routines in 'showimp.boot', for example using

)boot showSummary(FreeModule(Integer(), Symbol()))

I’d like to be able to invoke the showImp boot function from Frimacs by passing a fully specified domain name that the user supplies.  However, the problem I have is that showImp, like your showSummary example above, expects empty trailing parenthesis on parameter-less domain names.  This is rather unnatural for a user to do — it’s not natural SPAD code.

I think there must be some existing boot code somewhere that will help me parse a SPAD-like type expression and convert it into something that showImp would accept, but I’m having trouble finding such a thing.

I considered doing it myself in elisp, but I expect there are corner cases to consider.

Is it possible for you to point me in the right direction?

Thanks,
Paul

Waldek Hebisch

unread,
Jul 10, 2022, 9:28:16 AM7/10/22
to fricas...@googlegroups.com
Well, 'postAtom' in 'postpar.boot' has as last two lines:

IDENTP x and GETDATABASE(x,'NILADIC) => LIST x
x

ATM valid type expression is always Lisp list. Wrapping
non-types in list would mangle values. The code above
essentialy makes parameterless constructor names reserved:
if symbol names a parameterless constructor constructor
(this is what GETDATABASE(x,'NILADIC) is checking) it
will be wrapped in list.

However, 'showSummary' really expects a Spad type. In
my example type expression works because arguments
are evaluated by Boot before calling 'showSummary'.
'showSummary' will work with many unevaluated type
expressions but using it in such way really is abuse
and will fail in corner cases.

At Spad level one could do:

show_imp_summary(t : Type) : Void == showSummary(t)$Lisp

(wrapping it in appropriate package).

Big (and still not full resolved) trouble with type
expressions is that there may be type errors inside
type expression. So we can not depend on type
expression being well-formed and we can not use
normal type rules to exclude wrong stuff.
Related trouble is that Boot code in several
places passes junk to various routines. Due
to small number of checks junk goes trough
and in simple cases look "working". But there
a lot of work to make our type machinery
really robust.

Anyway, once you have type, it passed all checks
that we have so you can be resonably confident
that type is correct (there are known bugs in
corner cases). With type expression all this
work to check type is before you. You could
probably cop out and use interpreter to evaluate
types, but ATM there are some traps, interpreter
is handling types slightly different than Spad
compiler (and our runtime system).

--
Waldek Hebisch

Paul Onions

unread,
Jul 10, 2022, 2:59:12 PM7/10/22
to fricas...@googlegroups.com
On 10 Jul 2022, at 14:28, Waldek Hebisch <de...@fricas.math.uni.wroc.pl> wrote:

...

However, 'showSummary' really expects a Spad type. In
my example type expression works because arguments
are evaluated by Boot before calling 'showSummary'.
'showSummary' will work with many unevaluated type
expressions but using it in such way really is abuse
and will fail in corner cases.

At Spad level one could do:

show_imp_summary(t : Type) : Void == showSummary(t)$Lisp

(wrapping it in appropriate package).

Okay, looks like the SPAD route is the most robust route and so should be the route I take.  It’s a bit annoying because I was hoping to use Boot/Lisp, but only because I can then do “background” queries from Frimacs without upsetting the prompt number in the REPL.

I don’t suppose there’s an easy way to freeze the prompt number for a single SPAD evaluation?

Big (and still not full resolved) trouble with type
expressions is that there may be type errors inside
type expression. So we can not depend on type
expression being well-formed and we can not use
normal type rules to exclude wrong stuff.
Related trouble is that Boot code in several
places passes junk to various routines. Due
to small number of checks junk goes trough
and in simple cases look "working". But there
a lot of work to make our type machinery
really robust.

For me the Boot codebase is difficult to understand because it looks like a big, amorphous collection of functions.  I get lost, not knowing which way is up, or down.  Maybe it would benefit by introducing some kind of module structure, with well-defined interfaces to limit cross-module linkage?  Just something as simple as Common Lisp’s package system perhaps?

Anyway, once you have type, it passed all checks
that we have so you can be resonably confident
that type is correct (there are known bugs in
corner cases). With type expression all this
work to check type is before you. You could
probably cop out and use interpreter to evaluate
types, but ATM there are some traps, interpreter
is handling types slightly different than Spad
compiler (and our runtime system).

I’ve seen you mention before that you are trying to bring together interpreter and compiler behaviours, which is a very worthy goal, but I imagine is an awful lot of work :-(

Paul


Waldek Hebisch

unread,
Jul 10, 2022, 4:29:02 PM7/10/22
to fricas...@googlegroups.com
On Sun, Jul 10, 2022 at 07:59:08PM +0100, Paul Onions wrote:
> On 10 Jul 2022, at 14:28, Waldek Hebisch <de...@fricas.math.uni.wroc.pl> wrote:
> >
> > ...
> >
> > However, 'showSummary' really expects a Spad type. In
> > my example type expression works because arguments
> > are evaluated by Boot before calling 'showSummary'.
> > 'showSummary' will work with many unevaluated type
> > expressions but using it in such way really is abuse
> > and will fail in corner cases.
> >
> > At Spad level one could do:
> >
> > show_imp_summary(t : Type) : Void == showSummary(t)$Lisp
> >
> > (wrapping it in appropriate package).
>
> Okay, looks like the SPAD route is the most robust route and so should be the route I take. It’s a bit annoying because I was hoping to use Boot/Lisp, but only because I can then do “background” queries from Frimacs without upsetting the prompt number in the REPL.
>
> I don’t suppose there’s an easy way to freeze the prompt number for a single SPAD evaluation?

Hmm, if you do:

)boot parseAndEvalToString('"1 + 1")

the effect is to execute what is in argument given to parseAndEvalToString,
but without change to step number. Changes to variables and
functions definitions are still visible. If you wish better isolation
from current computation you could use frames. Unfortunately
the interace to frame machinery is somewhat clumsy, to make
it easier to use we probably could add frame stack, so that
one would be able to push current frame on the stack, do some
computations in new frame and then pop frame from stack to
restore user state.

> > Big (and still not full resolved) trouble with type
> > expressions is that there may be type errors inside
> > type expression. So we can not depend on type
> > expression being well-formed and we can not use
> > normal type rules to exclude wrong stuff.
> > Related trouble is that Boot code in several
> > places passes junk to various routines. Due
> > to small number of checks junk goes trough
> > and in simple cases look "working". But there
> > a lot of work to make our type machinery
> > really robust.
>
> For me the Boot codebase is difficult to understand because it looks like a big, amorphous collection of functions. I get lost, not knowing which way is up, or down. Maybe it would benefit by introducing some kind of module structure, with well-defined interfaces to limit cross-module linkage? Just something as simple as Common Lisp’s package system perhaps?

Well, James Davenport said about interpreter code: "it is a mess".
Lack of packages is just small part of the problem.
ATM main main tools is 'grep', it allows to find out uses/users
of given routine. You will see that routines are divided
thematically between files (there is Spad compiler group,
browser group, Aldor interface group, runtime support group,
utilities and interpreter proper). OTOH there were several
transitions and there are still traces of old things.
And structure is logical from historical point of view,
but subotimal for current use.

--
Waldek Hebisch

Qian Yun

unread,
Jul 11, 2022, 6:06:00 AM7/11/22
to fricas...@googlegroups.com
Hi Paul,

I have this idea for a while and might interest you:

I wonder if it is possible to load a subset of FriCAS's
interp/ code into Emacs directly. Basically a Emacs Lisp
port of FriCAS.

Since we do not use that much of Common Lisp's features,
I think with some tweaking, this is doable.

The first step is, to identify a minimal subset of
functions/files of "SPAD runtime", to support loading
and calling SPAD functions.

The next step is, to find a minimal subset of functions/files
of "SPAD interpreter", with that loaded into Emacs,
the possibility is unimaginable...

Again, I haven't pursue further in this direction,
hopefully I can get some time and test this idea soon.

(BTW, have you tried to navigate compiled BOOT codebase
with SLIME? I tried it briefly, the "slime-list-callers"/
"slime-list-callees" doesn't work yet, but the jump to
sources functionality works.)

- Qian

Paul Onions

unread,
Jul 11, 2022, 2:55:10 PM7/11/22
to fricas...@googlegroups.com
On 10 Jul 2022, at 21:29, Waldek Hebisch <de...@fricas.math.uni.wroc.pl> wrote:

)boot parseAndEvalToString('"1 + 1")

Thanks, I’ll go take a look at how this works and play around a bit.

Well, James Davenport said about interpreter code: "it is a mess".
Lack of packages is just small part of the problem.
ATM main main tools is 'grep', it allows to find out uses/users
of given routine. You will see that routines are divided
thematically between files (there is Spad compiler group,
browser group, Aldor interface group, runtime support group,
utilities and interpreter proper). OTOH there were several
transitions and there are still traces of old things.
And structure is logical from historical point of view,
but subotimal for current use.

Yes, I guess once you are familiar with it all you will see the underlying structure, but to get to that point is an uphill struggle :-(

Paul

Paul Onions

unread,
Jul 11, 2022, 3:17:33 PM7/11/22
to fricas...@googlegroups.com
On 11 Jul 2022, at 11:05, Qian Yun <oldk...@gmail.com> wrote:
>
> Hi Paul,
>
> I have this idea for a while and might interest you:
>
> I wonder if it is possible to load a subset of FriCAS's
> interp/ code into Emacs directly. Basically a Emacs Lisp
> port of FriCAS.

This sounds like a very ambitious undertaking!

To be honest though, I’m not sure of the value of such a project, mainly because it will be tied to Emacs and not everybody likes Emacs (shocking I know :-).

Also, I’m sure you’ll run into lots of annoying problems to do with subtle incompatibilities between Common Lisp and Emacs Lisp. Things that would really annoy me anyway, but as they say, YMMV.

> Since we do not use that much of Common Lisp's features,
> I think with some tweaking, this is doable.
>
> The first step is, to identify a minimal subset of
> functions/files of "SPAD runtime", to support loading
> and calling SPAD functions.
>
> The next step is, to find a minimal subset of functions/files
> of "SPAD interpreter", with that loaded into Emacs,
> the possibility is unimaginable...
>
> Again, I haven't pursue further in this direction,
> hopefully I can get some time and test this idea soon.

Another idea may be just to try isolating the fragment of Common Lisp that is used and trying to define some sort of VM that would help to isolate the SPAD environment from the underlying implementation language.

> (BTW, have you tried to navigate compiled BOOT codebase
> with SLIME? I tried it briefly, the "slime-list-callers"/
> "slime-list-callees" doesn't work yet, but the jump to
> sources functionality works.)

I think I tried that a long time ago but ran into problems. Recently I’ve just added some ETAGS support functionality to my Frimacs Boot mode and I use that to help me navigate the codebase.

Paul

Paul Onions

unread,
Jul 23, 2022, 2:45:17 PM7/23/22
to fricas...@googlegroups.com
On 10 Jul 2022, at 14:28, Waldek Hebisch <de...@fricas.math.uni.wroc.pl> wrote:

Anyway, once you have type, it passed all checks
that we have so you can be resonably confident
that type is correct (there are known bugs in
corner cases). With type expression all this
work to check type is before you. You could
probably cop out and use interpreter to evaluate
types, but ATM there are some traps, interpreter
is handling types slightly different than Spad
compiler (and our runtime system).

I think I found one of those traps.  Consider the package:-

  )abbrev package FRIMACS Frimacs
  Frimacs: Exports == Implementation where
    Exports ==> with
      showOpImpSummary : (t:Type) -> Void
    Implementation ==> add
      showOpImpSummary(t) == showImp(t)$Lisp

this seems to work okay, for example, in the REPL:-

  showOpImpSummary(Expression(Integer))$Frimacs

prints out a nice summary showing where each operation is implemented.  However, it fails if you give it a domain that uses a symbol as parameter, for example:-

  showOpImpSummary(Variable(‘z))$Frimacs

gives:-

  System error:
   The variable |z| is unbound.

On the other hand, supplying the type as a package parameter seems to work:-

  )abbrev package FRIMACS2 Frimacs2
  Frimacs2(t:Type): Exports == Implementation where
    Exports ==> with
      showOpImpSummary : () -> Void
    Implementation ==> add
      showOpImpSummary() == showImp(t)$Lisp

so that now:-

  showOpImpSummary()$Frimacs2(Variable(‘z))

gives a nice summary description, as it does for every other type I’ve tried so far.

Paul

Reply all
Reply to author
Forward
0 new messages