Question on the function IsArrow? in the file logic.spad

75 views
Skip to first unread message

Hill Strong

unread,
Feb 9, 2025, 4:33:18 AMFeb 9
to fricas...@googlegroups.com
In the following function, the line row = row + 1 does not appear to be correct

      isArrow?(arr : List(List(Boolean)), a : NNI, b : NNI) : Boolean ==
          row : NNI := 1
          for x in arr repeat
              if row = a then
                  val : Boolean := qelt(x, b)
                  return val
              row = row + 1
          false

Looking at the code, it would appear that this line should be

row := row + 1




Martin Baker

unread,
Feb 9, 2025, 6:24:15 AMFeb 9
to fricas...@googlegroups.com
Yes, I agree, it doesn't look correct.

Let me look into it as my name is on the file as author.

Its an interesting case study for trying to understand my own code after
almost 10 years. I think I should have made the comments more verbose
although I suspect Waldek would disagree?

Martin
> --
> You received this message because you are subscribed to the Google
> Groups "FriCAS - computer algebra system" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to fricas-devel...@googlegroups.com <mailto:fricas-
> devel+un...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/fricas-
> devel/CAEnaMTHRnSJSY6cAQasQ-
> pXdCT9U%2BFRAPEmAHVbdwTDrcuVqdA%40mail.gmail.com <https://
> groups.google.com/d/msgid/fricas-devel/CAEnaMTHRnSJSY6cAQasQ-
> pXdCT9U%2BFRAPEmAHVbdwTDrcuVqdA%40mail.gmail.com?
> utm_medium=email&utm_source=footer>.

Waldek Hebisch

unread,
Feb 9, 2025, 7:58:47 AMFeb 9
to fricas...@googlegroups.com
On Sun, Feb 09, 2025 at 11:24:12AM +0000, Martin Baker wrote:
> Yes, I agree, it doesn't look correct.
>
> Let me look into it as my name is on the file as author.
>
> Its an interesting case study for trying to understand my own code after
> almost 10 years. I think I should have made the comments more verbose
> although I suspect Waldek would disagree?

Well, sometimes things need explanation. But in most cases when
I need a lot of words to explain something, this indicates that
my thinking is not clear enough.

> On 09/02/2025 09:33, Hill Strong wrote:
> > In the following function, the line row = row + 1 does not appear to be
> > correct
> >
> >       isArrow?(arr : List(List(Boolean)), a : NNI, b : NNI) : Boolean ==
> >           row : NNI := 1
> >           for x in arr repeat
> >               if row = a then
> >                   val : Boolean := qelt(x, b)
> >                   return val
> >               row = row + 1
> >           false
> >
> > Looking at the code, it would appear that this line should be
> >
> > row := row + 1

One question is if this code could ever produce intended result.
I think that it works when only first row is non-tivial. Testing
with more then one row should have found the trouble.

Second question is why this code is inside a category? This code
clearly assumes specific representation, so is more appropriate as
part of a domain.

Third question is why the specific representation that you use?
List allows sparse representation, but cases when one of rows is
absent are rather special. OTOH you use indexing on rows, which
forces dense representation. So, List(Boolean) for rows is both
less efficient computationally and takes more space than a vector.
Or to put is differently, code in category should do things independent
of representation. Specific domain could use dense matrix or
sparse matrix or list depending on what is appropriate. Or
possibly use code (an "oracle").

Concerning fixit it, using ':=' should correct functionality.
Better style would be

isArrow?(arr : List(List(Boolean)), a : NNI, b : NNI) : Boolean ==
for x in arr for row in 1.. repeat
if row = a then
return qelt(x, b)
false

There is also question of naming, using 'row' or maybe 'rl' instead of
'x' looks clearer. Of course, then you would need someting like 'rn'
or 'row_number'.

There is a question what should happen when b is out of range?
Currently code returns false when it can not find row, but
when row is present out of range b will give indexing error.

In fact, if you accept error for out of range row number you can
have

isArrow?(arr : List(List(Boolean)), a : NNI, b : NNI) : Boolean ==
qelt(qelt(arr, a), b)

OTOH if you want false instead of error you should add inner loop
instead of 'qelt' in original version. Or possibly simpler
but slightly less efficient:

isArrow?(arr : List(List(Boolean)), a : NNI, b : NNI) : Boolean ==
#arr < a => false
row := qelt(arr, a)
#row < b => false
qelt(row, b)

AFAICS there is similar trouble in 'setArrow!'.

To say the truth, before trying to fix the functions one should ask
if this code is ever used? Function in categories are only used via
inheritance to domains. If a domain provides its own representation,
then it probably also provides all functions depeneding on representation
(doing otherwise risks bugs when code changes). So possibly
simplest fix would just remove the problematic code.

--
Waldek Hebisch

Martin Baker

unread,
Feb 9, 2025, 9:20:58 AMFeb 9
to fricas...@googlegroups.com
On 09/02/2025 12:58, Waldek Hebisch wrote:
> To say the truth, before trying to fix the functions one should ask
> if this code is ever used? Function in categories are only used via
> inheritance to domains. If a domain provides its own representation,
> then it probably also provides all functions depeneding on representation
> (doing otherwise risks bugs when code changes). So possibly
> simplest fix would just remove the problematic code.

Well I often get thrown by the differences between SPAD categories and
say Java interfaces so the code may well be sub optimal.

Recently I have been writing some SPAD code to implement (mostly finite)
topological spaces and the continuous maps between them. What I would
like to do is have links (conversions) between this logic
implementation, topological space implementation and simplicial complex
implementation. So in the longer term I would like to revisit this logic
code after the implementing topological space.

Another thing I have always wanted to do is implement simplicial sets
(degenerate faces and all that) but the point of that is to have nice
topological properties so again I want to implement topological spaces
first.

I don't know what your view of having more of these finite structures in
FriCAS is? I suspect most people here are more interested in fields and
rings and that sort of thing?

When implementing these finite structures like simplicial complexes I
keep getting a vague idea that they might be more efficiently
implemented as databases where the schema is the base space and the
tables are the entire space. Then, maybe it might be possible to
abstract out topological concepts like fibrations and cofibrations and
lifting and extension properties. I haven't thought this though and I
suspect it wouldn't be practical.

So feel free to do whatever you want with IsArrow? and if any of this
topological space stuff seems interesting to anyone I would appreciate
any ideas.

Martin


Ralf Hemmecke

unread,
Feb 9, 2025, 9:41:54 AMFeb 9
to fricas...@googlegroups.com
Hi Martin,

> I don't know what your view of having more of these finite structures in
> FriCAS is? I suspect most people here are more interested in fields and
> rings and that sort of thing?

My view on this is that it makes sense to first write a separate package
outside of FriCAS. I do this with my QEta package.

https://hemmecke.github.io/qeta/

It is a very specialized thing where maybe parts of it could go into
FriCAS. While developing it, I sometimes had to change the interface of
functions, replace some domains by others, refactor, extend etc. I
think, I am much more flexible to do this outside of FriCAS and testing
is also an issue.

Actually, I would be happy, if on the FriCAS homepage we can list many
other such packages. Yes, users would have to compile those packages,
but that shouldn't be a big issue.

Ralf

Waldek Hebisch

unread,
Feb 9, 2025, 12:45:09 PMFeb 9
to fricas...@googlegroups.com
On Sun, Feb 09, 2025 at 02:20:54PM +0000, Martin Baker wrote:
> On 09/02/2025 12:58, Waldek Hebisch wrote:
> > To say the truth, before trying to fix the functions one should ask
> > if this code is ever used? Function in categories are only used via
> > inheritance to domains. If a domain provides its own representation,
> > then it probably also provides all functions depeneding on representation
> > (doing otherwise risks bugs when code changes). So possibly
> > simplest fix would just remove the problematic code.
>
> Well I often get thrown by the differences between SPAD categories and
> say Java interfaces so the code may well be sub optimal.
>
> Recently I have been writing some SPAD code to implement (mostly finite)
> topological spaces and the continuous maps between them.

Finite topological spaces are equivalent to partial orders, so
there is connection to logic. But they are quite different than
infinite topological spaces like simplicial complexes.

> What I would
> like to do is have links (conversions) between this logic
> implementation, topological space implementation and simplicial complex
> implementation. So in the longer term I would like to revisit this logic
> code after the implementing topological space.
>
> Another thing I have always wanted to do is implement simplicial sets
> (degenerate faces and all that) but the point of that is to have nice
> topological properties so again I want to implement topological spaces
> first.
>
> I don't know what your view of having more of these finite structures in
> FriCAS is? I suspect most people here are more interested in fields and
> rings and that sort of thing?

Well, I am interested in more general things. Finite things
frequently are related to combinatorics and there was (and I
hope still is) interest in having good support for combinatorics
in FriCAS.

> When implementing these finite structures like simplicial complexes I
> keep getting a vague idea that they might be more efficiently
> implemented as databases where the schema is the base space and the
> tables are the entire space. Then, maybe it might be possible to
> abstract out topological concepts like fibrations and cofibrations and
> lifting and extension properties. I haven't thought this though and I
> suspect it wouldn't be practical.

Let me present my view here. What does it mean "doing mathematics
in computer"? One aspect is to support notation analogus to used
in literature, allowing creation and manipulation of statements/
expressions. In particular this means reasonably nice output.
Basicaly this would be "programmable editor", so transformation
could be specified by hand. Nontrivial mathematical statements
may be hard or impossible to decide, so I do _not_ expect
general domain of this sort to be able to say decide mathematical
equality. But hopefully user should be able to specify
transformations and see their effect.

Different aspect is examples. I would like to see domains allowing
work with small parts of corresponding mathematical domain, allowing
deciding various problems within such a small part.

> So feel free to do whatever you want with IsArrow? and if any of this
> topological space stuff seems interesting to anyone I would appreciate
> any ideas.

For classical topological spaces people care about homotopies and
homology. Homology for simplicial complexes essentially reduces to
linear algebra over integers, so is relatively easy. First homotopy
group is in general uncomputable. Assuming that first homotopy
group is trivial, there is old result about higher homotopy groups,
namely there is relation to homology of loop spaces. Loop spaces
as normally defined are not simpilical complexes, but it is
relatively easy to give infinite simpilical complex which is
homotopy equvalent to loop space of a simplical complex. So
one needs to tame infinity. One step here was done by E. Brown,
who proved that to compute homotopy of given order is is enough
to look at finite part of infinite simpilical complex equivalent
to loop space. Complex given by Brown is quite large. F. Sergeraert
showed that one can use much smaller finite complex, which allowed
practical computations. AFAICS there is rather heavy theory
behind this and implementation needs a lot of coding.

Vector bundles over simplicial complexes have rather natural
representation: over each simplex you have vector space
of given dimension, so by choosing basis you can just take
R^n. On intersection of simplexes there is change of base,
so you need a transition matrix. In general this transition
matrix may be an arbitrary continous matrix function, subject
to agreement rules. But you should be able to do with
matrix valued polynomials (or rational functions since we need
inverses). And AFAICS homotopic sets of transition matrices
give isomorphic bundles, so there is more possibilities to
limiot form of transition matrices. If transition matrices
take values in orthogonal matrices you should be able to
represent bundles of spheres in similar way. If transition
matrices have integer entries and determinant +-1 you will
get bundles of toruses.

In somewhat different direction you may consider algebraic
sets. CAD (implementd by CylindricalAlgebraicDecompositionPackage)
give you decomposition of real algebraic set into cells,
so you should be able to produce a simplicial complex from
such decomposition. If the set is smooth you may consider
tanget bundle or normal bundle.

I think that analog of cylindrical algebraic decomposition
works for more general sets, defined by elementary equations
and inequalities (with reasonable regularity assumptions needed
to avoid uncomputability). But again, this probaly would
require working out details of theory (I am not aware of
precise description) and coding is likely to be rather
involved.

I would suggest to start with relatively simple things and
make them work well, so simplicial complexes rather than
generalizations, functions which are as simple as possible
(for mappings one gets nontrivial theory already from
piecewise linear maps).

--
Waldek Hebisch

Waldek Hebisch

unread,
Feb 9, 2025, 3:04:00 PMFeb 9
to fricas...@googlegroups.com
On Sun, Feb 09, 2025 at 02:20:54PM +0000, Martin Baker wrote:
> On 09/02/2025 12:58, Waldek Hebisch wrote:
> > To say the truth, before trying to fix the functions one should ask
> > if this code is ever used? Function in categories are only used via
> > inheritance to domains. If a domain provides its own representation,
> > then it probably also provides all functions depeneding on representation
> > (doing otherwise risks bugs when code changes). So possibly
> > simplest fix would just remove the problematic code.
>
> Well I often get thrown by the differences between SPAD categories and
> say Java interfaces so the code may well be sub optimal.

I have no deep knowledge of Java, but I do not think there are big
conceptual differences between Spad categories and Java interfaces.
Spad category lists signatures (functions) that should be available
in all domains declared to belong to given category. Implementation
part of category gives default implementation. IIUC the same thing
holds in Java: interface specifies functions and may give default
implementation. Spad categories can do a bit more. In Spad there
are parameters. In old Java there were no parameters (later Java
added generics which probably changed that). If you want analogy
with other languages, Spad parametrized domains and categories
are similar to C++ templates (there are also differences). But
this difference is in a sense not essential: to use a domain you
plug in values for parameters. So you may think of parameters as
a shortcut way to define many similar categories or domains.
In practice it would be possible to use say macros to expand
single parametized source into several variants (parameters are
more flexible than this, but there is little paractical difference).

OTOH you may be confused by Spad terminology. At least your
usage is less usual compared to other parts of FriCAS.
Namely, a domain of category Group is a _single_ group.
AFAICS your domain FinitePoset(S) is intended to be a domain of
all finite posets withe elements form S. In other words, domain
of category Poset(S) is actually a set of posets (with elements
from S), not a single poset. But once this is stated explicitely,
there should be no confusion.

Concerning confusion: IIUC the intent is to deal with posets
having elements from S. So natural functions would be
for example:

addArrow! : (%, S, S)
++ addArrow!(p, a, b) adds to p arrow from a to b

Actually, I mentioned this function because it appears close to
start of list of functions. However, such signature actually
promises more than a poset: it promises mutable poset. This
difference is significant for two reasons. One, most mathematical
objects in FriCAS are immutable, and without immutably normal
mathematical reasoning does not work (intead one needs to work
with states and consider how assignment changes state before
into state after). Second, bulk operations on posets may be
more efficient if result is not modified after creation
(for example most operations would be faster if you used
array as representation, but adding nodes forces use of
flexible arrays and we currently only have one dimensional
flexible arrays).

Anyway, coming back to signature above, instead of elements of
S you have integer indices. So anybody using your domain must
deal with integers. So really, from point of view of a user
this is poset on subset of integers and relation to S is
somewhat fuzzy.

Coming back to basics: notion of poset is rather fundamental and
having operations on posets is desirable. There is natural
connection to graphs. But it is undesirable to force essentially
presentational aspects on _all_ posets. Rather, I would expect
mathematical Poset and separate say PosetVisualisation to handle
presentational aspects.

> So feel free to do whatever you want with IsArrow?

Well, from the above you can see that I would write rather different
categories and domains that you did. But I do not want to break
what works, so I will probably do only minimal changes.

--
Waldek Hebisch

Waldek Hebisch

unread,
Feb 9, 2025, 8:07:43 PMFeb 9
to fricas...@googlegroups.com
On Sun, Feb 09, 2025 at 09:03:57PM +0100, Waldek Hebisch wrote:
>
> > So feel free to do whatever you want with IsArrow?
>
> Well, from the above you can see that I would write rather different
> categories and domains that you did. But I do not want to break
> what works, so I will probably do only minimal changes.

Attached is my proposed diff to logic.spad. I removed 'setVert'
and 'setArr': setting things separately may easily break properties
of a poset, so it is probably better not to have them. Removed
'completeReflexivity', 'completeTransitivity' and 'isAntisymmetric?':
poset is supposet to be reflexive and transitive, so those
should be no-ops for posets. Poset is supposed to be antisymmetric,
so 'isAntisymmetric?' should always return true, and conseqently
'isAntisymmetric?' does not give any new information.

I added internal function to compute transitive closure and called
it from 'addArrow!' so that we always get a poset. I also added
internal function for checking antisymmetry, so 'addArrow!' can
check if we still have a poset (and signal error otherwise).
Also, added internal functions for convertion between list of list
of booleans and boolean matrices: operations on matrices are
easier and more efficient.

Ater changes the following gives sensible result:

i1 := initial()$FinitePoset(Integer)
g1 := addObject!(i1, 1)$FinitePoset(Integer)
i1
g2 := addObject!(g1, 2)$FinitePoset(Integer)
t2 := addArrow!(g2, 1, 2)
g3 := addObject!(t2, 3)$FinitePoset(Integer)
addArrow!(g3, 2, 3)
addArrow!(g3, 1, 3)

Trying the same with current trunk shows that i1 is modified,
(so despite docstring 'addObject!' were modifying i1),
also operations in trunk leads to non posets.

Also I removed bunch of duplicate implementations.

Possible changes that I did not do:
- changing declaration of addArrow! so that it takes elements of
S instead of integer indices
- several functions (like kgraph) are really not applicable to posets,
optimaly their declaration should be removed, worse possiblity but
still better than current one is to signal errors on any attempt
to use them
- AFAICS bunch of functions makes sense for posets, but has fake
implementations which return different thing than promised
- non-mutating functions would be normally called 'addObject'
and 'addArrow' (that is without exclamation sign).

Also, most of things declared in FiniteGraph are given fake implementation,
as I wrote, it would be better avoid declaring FiniteGraph in Poset,
but intead, declare FiniteGraph in places when you can really
implement it.

One more thing: ATM there is bunch of internal functions, some
are potentially reusable. If reuse is desirable we could move
reusable functions to a separate package and use to either from
Poset or from FinitePoset.

In slightly different spirit: there are resonably natural functions
that Poset does not declare.

--
Waldek Hebisch
log.dii1

Martin Baker

unread,
Feb 11, 2025, 9:44:25 AMFeb 11
to fricas...@googlegroups.com
On 09/02/2025 17:45, Waldek Hebisch wrote:
> Finite topological spaces are equivalent to partial orders, so
> there is connection to logic. But they are quite different than
> infinite topological spaces like simplicial complexes.

I hope there is a way to implement a 'geometric realization' function,
that is an algorithm to embed a finite topological space in a vector
space (which is a Euclidean space, which is a topological space). In the
opposite direction I would also like to implement a 'nerve
construction'. I would also like to link these to logic/frames as in
Steven Vickers book 'Topology via Logic' but at this stage I am just
trying to work out what's possible.

> Let me present my view here. What does it mean "doing mathematics
> in computer"? One aspect is to support notation analogus to used
> in literature, allowing creation and manipulation of statements/
> expressions. In particular this means reasonably nice output.
> Basicaly this would be "programmable editor", so transformation
> could be specified by hand.

Are you talking about a graphical editor for Topology/Geometry that
would give an equation editor and draw the result in real time? This
would be very nice but not the sort of thing that could be written in SPAD?

> Nontrivial mathematical statements
> may be hard or impossible to decide, so I do _not_ expect
> general domain of this sort to be able to say decide mathematical
> equality. But hopefully user should be able to specify
> transformations and see their effect.

Well for finite topology code (as opposed to the existing simplicial
complex code in alg_top.spad) I would like the 'equalities' to be
Homeomorphism (a cup is the same as a doughnut) and homotopy equivalence
(a line is the same as a point). Since these are defined like
isomorphism with maps in both directions I would like some way to
create, combine and use continuous maps. So I think I would need a
domain to represent a continuous map. Presumably as a subset of a
product, that is, a set of (input,output) pairs for the points combined
with something similar in the reverse direction for the open set
preimage. This all seems very messy and unwieldy which is why I like the
idea of implementing it as database tables. I know there is a database
domain in FriCAS but I think that's just for internal FriCAS metadata?
One advantage of having a database is that it makes it easier to
implement a pullback which seems to be the fundamental construct where a
lot of this structure comes from. So this would be a database search
which would only enable the inputs which go to the same place when they
go different ways around the square. Perhaps a full database
implementation is a bit ambitious maybe a more lightweight construct
might work like the concept of Dictionaries in Python which are used to
store data values in key:value pairs.
Are you saying that the existing simplicial complex code in alg_top.spad
needs reworking? I would like to improve this and add simplicial sets
(like simplicial complex but based on a weak order). Before I look at
this I want to learn more about the fundamentals of finite topological
spaces and implement some code for that.

I am interested in the link to cylindrical algebraic decomposition you
mention so I will investigate that more and see if it can be linked to
the structures in alg_top.spad or new topology code. I assume there are
no tutorials for the CAD package? Also I will try to find out more about
the loop spaces you mention.

My personal motivation is to learn more about these powerful and
beautiful mathematical structures and if any code that comes out of that
is useful to others that would also be good. I find self study difficult
when text books have exercises to prove something and I get stuck. Since
programs have similarities to proofs (in a Curry-Howard sort of way) I
find it better to work with code. At least programs are easier to debug
than proofs.
The ultimate example of this would be if I could implement Homotopy Type
Theory or Cubical Type Theory in FriCAS (I know that's an impossible goal).

Martin

Martin Baker

unread,
Feb 11, 2025, 10:49:58 AMFeb 11
to fricas...@googlegroups.com
On 09/02/2025 20:03, Waldek Hebisch wrote:
>> Well I often get thrown by the differences between SPAD categories and
>> say Java interfaces so the code may well be sub optimal.
> I have no deep knowledge of Java, but I do not think there are big
> conceptual differences between Spad categories and Java interfaces.
> Spad category lists signatures (functions) that should be available
> in all domains declared to belong to given category. Implementation
> part of category gives default implementation. IIUC the same thing
> holds in Java: interface specifies functions and may give default
> implementation.

There was some difference that always used to cause me problems because
categories are more statically defined than interfaces but I have
forgotten the details now. That's the problem when concepts are so
similar but important details are different.

For example, in Java you might have an interface called 'shape' and this
interface has functions such as 'draw' so classes that implement shape
such as 'square' and 'circle' all have there own implementations of 'draw'.
Some other part of the code may have a List of 'shape' and if you call
'draw' on each of the elements it would call the appropriate version of
draw depending on whether it is a 'square' or a 'circle'.

I don't think you can do that with categories because they are more
statically defined so you cant have 'List shape' and this makes a big
difference to how you would go about constructing such a programming task.

I mention this just as a reminder of the sort of problems new users may
have when coming to SPAD from other languages. I think it would be good
if there was something on fricas.github.io listing potential issues like
this for new users (and me).

Martin

Martin Baker

unread,
Feb 12, 2025, 11:23:34 AMFeb 12
to fricas...@googlegroups.com
On 10/02/2025 01:07, Waldek Hebisch wrote:
> On Sun, Feb 09, 2025 at 09:03:57PM +0100, Waldek Hebisch wrote:
>>
>>> So feel free to do whatever you want with IsArrow?
>> Well, from the above you can see that I would write rather different
>> categories and domains that you did. But I do not want to break
>> what works, so I will probably do only minimal changes.
> Attached is my proposed diff to logic.spad.

Looks good to me. I find its useful to have instances (models) of Poset,
Preorder, Lattice and similar structures in addition to their categories.

In order to implement simplicial sets I would also like a Weak Total
Order implementation.

I only mention this here as it is a potential similar example and I just
wanted to get some indication if it might be a potential addition to
FriCAS at some stage in the future. As I'm sure you can tell I have not
thought this through so don't take it too seriously.

I was thinking of using List NNI for the Rep but that does have more
information than is needed. All that is needed is how many entries and
how many duplicates of each one. I'm not sure of the most efficient way
to represent that. Then they would need to be used to index and compare
in two ways: With degeneracies included and with degeneracies excluded.

Then they would have the following functions defined on them:

)abbrev category OPF OrderPreservingFunctions
++ Order preserving functions can be decomposed into face maps d(i)
++ and degeneracy maps s(i) and they obey the following identities:
++ if i < j then d(i)*d(j) = d(j-1)*d(i)
++ if i < j then d(i)*s(j) = s(j-1)*d(i)
++ d(j)*s(j) = id = d(j+1)*s(j)
++ if i > j+1 then d(i)*s(j) = s(j)*d(i-1)
++ if i <= j then s(i)*s(j) = s(j+1)*s(i)
++ where i and j are NNI indexes and * is composition operator
OrderPreservingFunctions() : Category == Definition where
Definition ==> ???? with
d : (index : NNI, input : %) -> %
++ face maps
++ remove entry at given index.
s : (index : NNI, input : %) -> %
++ degeneracy maps
++ duplicate entry at given index

Martin




Ralf Hemmecke

unread,
Feb 12, 2025, 11:39:39 AMFeb 12
to fricas...@googlegroups.com
On 2/11/25 15:44, Martin Baker wrote:
> might work like the concept of Dictionaries in Python which are used
> to store data values in key:value pairs.

Is already available in FriCAS in several domains.

http://fricas.github.io/api/AssociationList.html
http://fricas.github.io/api/HashTable.html
http://fricas.github.io/api/XHashTable.html

> There was some difference that always used to cause me problems
> because categories are more statically defined than interfaces but I
> have forgotten the details now.

I suggest you read the Aldor User Guide.

http://www.aldor.org/docs/aldorug.pdf

> For example, in Java you might have an interface called 'shape' and
> this interface has functions such as 'draw' so classes that
> implement shape such as 'square' and 'circle' all have there own
> implementations of 'draw'.

But that is exactly the same as in SPAD.
Categories can provide implementations of some functions.
One should, however, take care that such implementations do not rely on
any representation details of an element. Such implementations can be
overridden by an respective domain, but the general idea is that
categories do not know about the representation. It's just an abstract
collection of function signatures without the notion of the concrete
carrier set is one speaks in terms of universal algebras (or rather
multisorted algebras).

> Some other part of the code may have a List of 'shape' and if you
> call 'draw' on each of the elements it would call the appropriate
> version of draw depending on whether it is a 'square' or a 'circle'.

That you can also do in FriCAS, but it is not exactly the way you do it
in Java. A list must have elements of the same type, i.e. in FriCAS you
can only have List(T) for a concrete type T. If you have Circle and
Square as domains realizing the category Shape, then you can either have
List(Circle) or List(Square), but not a mixture of them. What you need
is a domain, that "represents" both of them. You find such a general
domain describe in Section 21.10 in aldorug.pdf, the domain "Object".
That domain is also in FriCAS and is called "Any". And yes, it bundles
an element together with its type information. (That is what all
object-oriented programming languages do per default.)
In FriCAS/Aldor an element (i.e. its representation in memory) usually
does not know its type, (i.e. there is no reference to the respective
domain). The "Any", "Object" construction makes this explicit. In that
sense, FriCAS/Aldor is different from other OO programming languages.

> I mention this just as a reminder of the sort of problems new users
> may have when coming to SPAD from other languages. I think it would
> be good if there was something on fricas.github.io listing potential
> issues like this for new users (and me).
Maybe I should add such an explanation into some help section if the
above at least helps you. (Feedback appreciated.)

Ralf

Martin Baker

unread,
Feb 12, 2025, 1:38:08 PMFeb 12
to fricas...@googlegroups.com
Ralf,

Yes, thank you, that is very interesting and useful.
I did not know about 'Any'. I wish I had come across this earlier (but
how would I?). I do think you should put an explanation into some help
section where potential new users are likely to find it, especially
people starting to program in SPAD who have come from other languages.

I find this type of paradigm very powerful where you do some operation
on a whole collection by calling the same function on all its parts,
even if they are different types. I think that other people would try to
do this if they came from other languages. At first glance, it looks
like there is more boilerplate in SPAD but at least it can be done.

I will also look in AssociationList.html etc to look at key:value pairs
and see if this could be extended to implement something like database
tables.

Thanks again, Martin

On 12/02/2025 16:39, 'Ralf Hemmecke' via FriCAS - computer algebra

Waldek Hebisch

unread,
Feb 12, 2025, 1:52:03 PMFeb 12
to fricas...@googlegroups.com
On Tue, Feb 11, 2025 at 02:44:20PM +0000, Martin Baker wrote:
> On 09/02/2025 17:45, Waldek Hebisch wrote:
> > Finite topological spaces are equivalent to partial orders, so
> > there is connection to logic. But they are quite different than
> > infinite topological spaces like simplicial complexes.
>
> I hope there is a way to implement a 'geometric realization' function,
> that is an algorithm to embed a finite topological space in a vector
> space (which is a Euclidean space, which is a topological space).

I am affraid there is confusion what "finite topological space"
means. By this I mean finite set with topology. Simplest
nontrivial example is two element set {a, b}, with topology
{{}, {a}, {a, b}}. Nontrival here means that this in neither
discrete topology nor anti-discrete one. There is a theorem
saying that any finite subset of euclidean space has discrete
topology. So, to have non-trivial topology on a subset of
euclidean space you must have an infinite set. So
'geometric realization' can only work for "nice" spaces
and gives interesting results only for infinite ones.
Actually, there is notion of topological dimension which
for separable metric spaces say that space of dimension n
can be topologically embedded in euclidean space of
dimension 2*n + 1.

Note that "finite simplicial complexes" are typicall
infinite topological spaces, the word "finite" means
that there is finite number of pieces, but typicall
some pieces are infinite.

> In the
> opposite direction I would also like to implement a 'nerve
> construction'. I would also like to link these to logic/frames as in
> Steven Vickers book 'Topology via Logic' but at this stage I am just
> trying to work out what's possible.

I have not seen Vickers book.

> > Let me present my view here. What does it mean "doing mathematics
> > in computer"? One aspect is to support notation analogus to used
> > in literature, allowing creation and manipulation of statements/
> > expressions. In particular this means reasonably nice output.
> > Basicaly this would be "programmable editor", so transformation
> > could be specified by hand.
>
> Are you talking about a graphical editor for Topology/Geometry that
> would give an equation editor and draw the result in real time? This
> would be very nice but not the sort of thing that could be written in SPAD?

I had in mind symbolic/textual representation (and going beyond
Geometry). It would be nice to have grapical presentaion and
editor, but to sensibly connect this to other parts of FriCAS
the core representation should be symbolic. And currently we
have limited support for graphic in Spad, in particular
interaction is limited to a handful of special cases. So
going graphical here would be a big project.

> > Nontrivial mathematical statements
> > may be hard or impossible to decide, so I do _not_ expect
> > general domain of this sort to be able to say decide mathematical
> > equality. But hopefully user should be able to specify
> > transformations and see their effect.
>
> Well for finite topology code (as opposed to the existing simplicial
> complex code in alg_top.spad) I would like the 'equalities' to be
> Homeomorphism (a cup is the same as a doughnut) and homotopy equivalence
> (a line is the same as a point). Since these are defined like
> isomorphism with maps in both directions I would like some way to
> create, combine and use continuous maps. So I think I would need a
> domain to represent a continuous map. Presumably as a subset of a
> product, that is, a set of (input,output) pairs for the points combined
> with something similar in the reverse direction for the open set
> preimage. This all seems very messy and unwieldy which is why I like the
> idea of implementing it as database tables.

Well, you write "finite", but in fact main point here is that
you need handle infinte spaces. More precisely, you want to
avoid actual infinity, so you need to represent things that
mathematically are infinite using finite amout of information.

Already fact that finite amout of information is enough is
mathematically quite non-trivial and one needs smart approach
to get results using managable ampount of information, that
is why I mentioned Sergeraert below.

Mathematically, databases are trivial. They embody large
number of tricks to speed up typical business data processing,
but are unlikely to be relevant for the problem. At best
thinking about databases is premature optimization.

> I know there is a database
> domain in FriCAS but I think that's just for internal FriCAS metadata?

The Database domain is general, but it is essentially association
list with some tweaks. As Ralf wrote, for fast access to largish
amount of data hash tables are typically better (lists are faster
for small number of entries).

Traditionally FriCAS uses term "database" when speaking about
internal data, but this is want is usually called "symbol table".
ATM FriCAS has no true databases (but hash tables may be better
for ypur problem).

> One advantage of having a database is that it makes it easier to
> implement a pullback which seems to be the fundamental construct where a
> lot of this structure comes from. So this would be a database search
> which would only enable the inputs which go to the same place when they
> go different ways around the square.

Actually, pullback is rather easy: you have a function f from
S1 to S2 and some data associated to points in S2. You want
to get data corresponding to point s in S1. To get it you
just apply f to s getting f(s) \in S2. And then you look up
appropiate data in S2. Push-forward is more tricky, as you
may be forced to find counterimages of point s \in S2. And
actually main work here is to sensibly represent functions and
spaces and whatever data you need to associate with points.
In fact, in many cases data is associated with subsets and doing
such thing naively (as table giving value for each subset)
leads to trouble even if you consider moderatly large finite
spaces.

Just as an example, consider lattice of subgroups of a finite
group G. One naive approach could be: consider all subsets
of G, for each subset compute group generated by this subset,
getting collection (list) of subgoups of G. Trouble is, that
group having 60 elements is quite small, but set of subsets is
too large to enumenrate is reasonable time on current machines.
OTOH number of subgroups seem to be much smaller and for
groups having less than 100 elements it is probably not too
hard to create list of all subgroups. I do not know if there
are good methods working for bigger groups, but worst case
that I found are vector spaces over Z_2, where number of
subgroups is of order N log(N), where N is number of elemnts
of the group (and in such very special case it is easy to
generate list of subgroups).
I think that simplicial complexes work quite well. OTOH cubical
and delta complexes were not really finished and there were little
progress after they were commited. Based on what is already
implemented for simplicial complexes one can do more things.

I suggest avoid small variations which add only a little functionality,
but may cause significant extra work (AFAIR it turned out that
_correct_ implementation of some aspects of cubical and delta
complexes is more tricky than for simplical ones). Also, do
not be too ambitious, setting to far goal is good recipe for
failure. Finally, things really should be tested with reasonable
coverage.


> I am interested in the link to cylindrical algebraic decomposition you
> mention so I will investigate that more and see if it can be linked to
> the structures in alg_top.spad or new topology code. I assume there are
> no tutorials for the CAD package?

Classic CAD (that is algebraic case) is well covered in literature.
Basic idea is explaned in Davenport book on computer algebra
available from his webpage (and from other places). We have a
test file in the repo and an example in wiki. To say the
truth, current code is geared toward problem of deciding validity
of statements. To conveniently solve other problems we need
more code, probably exposing some data that is computed inside
CAD package, but not shown in final result. And we need to
wrap it in convenience domain/packages for easier use in other
problems.

--
Waldek Hebisch

Ralf Hemmecke

unread,
Feb 12, 2025, 2:51:06 PMFeb 12
to fricas...@googlegroups.com
On 2/12/25 19:38, Martin Baker wrote:
> I find this type of paradigm very powerful where you do some operation
> on a whole collection by calling the same function on all its parts,
> even if they are different types.

Yes, maybe. But note that this paradigm, I would say, is NOT what one
usually does in FriCAS/Aldor. Admittedly, your shape example rather
calls for an object-oriented approach, but the main idea of the SPAD
language is driven by multi-sorted algebras
https://core.ac.uk/download/pdf/161922276.pdf .
That thesis even relates to AXIOM and explains the coercion model.

Maybe it would make sense to discuss the category/domain structure
design of your package in private to fit more to the FriCAS programming
style than to usual OOP programming styles. Probably every style has
pros and cons, but since most part of FriCAS uses the category/domain
style it makes sense to think about whether you really need to follow
the OOP paradigm.

Ralf

Dima Pasechnik

unread,
Feb 12, 2025, 5:06:50 PMFeb 12
to fricas...@googlegroups.com
the basic notion is an "abstract" simplicial complex.
It should not be confused with a "geometric simplicial complex" (an
embedding of an abstract one into a space of some sort, e.g an
Euclidean space.)

A finite abstract simplicial complex is a purely combinatorial object.
One can study its homology groups, over a finite field (e.g.
Z_2-homology is very common)
without resorting to Euclidean spaces.
E.g. SageMath can compute such things:

S = SimplicialComplex([[0,1], [1,2], [0,2]]) # circle
T = S.product(S) # torus
Simplicial complex with 9 vertices and 18 facets
sage: T.homology(base_ring=GF(2))
{0: Vector space of dimension 0 over Finite Field of size 2,
1: Vector space of dimension 2 over Finite Field of size 2,
2: Vector space of dimension 1 over Finite Field of size 2}

Just in case,
Dima
> --
> You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/fricas-devel/Z6ztzxmPCF3p9WJs%40fricas.org.

Waldek Hebisch

unread,
Feb 12, 2025, 5:31:00 PMFeb 12
to fricas...@googlegroups.com
Sure. Martin was writing about finite topological spaces.
I hope you are not considering the finite complex above as
a topological space.

--
Waldek Hebisch

Dima Pasechnik

unread,
Feb 12, 2025, 10:17:56 PMFeb 12
to fricas...@googlegroups.com
Sure, an abstract finite simplicial complex A is a combinatorial model
of a finite triangulation of whatever space S we're studying,
in other words, of a geometric simplicial complex homeomorphic (or
perhaps only homotopy equivalent) to S.
A is not a finite topological space by itself (finite topological
spaces are kind of boring).
My point was that often one can extract a lot of info from A, without
dealing with S itself.

Dima



>
> --
> Waldek Hebisch
>
> --
> You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/fricas-devel/Z60hIW87PVzUyiL1%40fricas.org.

Martin Baker

unread,
Feb 13, 2025, 5:59:24 AMFeb 13
to fricas...@googlegroups.com
The attached file contains my first tentative experiments with what I
thought of as Finite Topology. Could you take a quick glance at it to
see if that's what you would describe as Finite Topology, if not could
you suggest an alternative name?

Anyway its the subject that interests me at the moment and I think it
should keep me busy for a few years.

Despite what you say about the usefulness of 'geometric realization' I
would still like to attempt to implement it, just for completeness and
my own education. I realise that n points will produce 2*n+1 dimensions
but FriCAS can handle high dimensional matrix algebra, right? That's one
of the advantages of doing this on a CAS.

My reason for looking at databases for the representation was not
performance but because the database structure seems to match the
mathematical structure better. For instance a minimal complex might be a
graph which is two tables (nodes and edges) and you could use common
keys or indexes for the source and target relations between the tables.
But more importantly I am looking for a way to abstract out topological
constructs such as sheaf and fibration.

It will take me some time to work though the other issues you mention.

As Ralf suggests I will email him off this list about the 'style guide'
issues in case my questions here are getting annoying.

Martin
topology.spad

Kurt Pagani

unread,
Feb 13, 2025, 6:04:57 AMFeb 13
to FriCAS - computer algebra system
Indeed. I recently read Moebius' barycentric calculus and Grassmann's extension theory where you simply start with (abstract) points A,B,C ... 
then building products AB , ABC and so on (semantic: oriented line, triangle, simplex and so on). Adding the boundary operator bdry(AB)=B-A,
bdry(AX)=X - A bdry(X) recursively, and using Moebius's addition pA+qB=(p+q)S (whenever p+q \neq 0) one gets all the stuff (includng vector calculus  ;-)  almost for free without boring 50  pages of introduction.

BTW, it's also very easy to implement in fricas:

Kurt Pagani

unread,
Feb 13, 2025, 6:47:32 AMFeb 13
to FriCAS - computer algebra system
I suggest to read chapter 12 of the "Weyl" user manual, where a viable attempt has been described:

Kurt Pagani

unread,
Feb 13, 2025, 7:10:37 AMFeb 13
to FriCAS - computer algebra system
I forgot to mention KENZO:

Anything useful to include in FriCAS on this topic  has to compete with it because it's easy to interface  ;-) 

On Thursday, 13 February 2025 at 11:59:24 UTC+1 Martin Baker wrote:

Martin Baker

unread,
Feb 13, 2025, 10:47:56 AMFeb 13
to fricas...@googlegroups.com
I find Lisp very hard to follow. I'm not criticising the language or
trying to start a debate about it. I just find, for me personally, after
a few lines of Lisp code I tend to loose track of whats happening and
give up.

The documentation looks like it could be possibly be interesting:
https://github.com/gheber/kenzo/blob/master/doc/Kenzo-Doc.pdf
but I can't read it because it only displays the first page. The only
option then seems to be to hit 'more' at the bottom which shows a few
more pages but after clicking 'more' a few times it then locks up.
What am I missing? Have you found a way to read the pdf file?

Martin

Martin Baker

unread,
Feb 13, 2025, 10:57:09 AMFeb 13
to fricas...@googlegroups.com
OK, ignore my comment about the documentation, I just realised I need to
download the raw pdf file.

Martin

Dima Pasechnik

unread,
Feb 13, 2025, 11:47:55 AMFeb 13
to fricas...@googlegroups.com


On 13 February 2025 09:47:52 GMT-06:00, Martin Baker <ax8...@martinb.com> wrote:
>I find Lisp very hard to follow. I'm not criticising the language or
>trying to start a debate about it. I just find, for me personally, after
>a few lines of Lisp code I tend to loose track of whats happening and
>give up.
>
>The documentation looks like it could be possibly be interesting:
>https://github.com/gheber/kenzo/blob/master/doc/Kenzo-Doc.pdf
>but I can't read it because it only displays the first page. The only
>option then seems to be to hit 'more' at the bottom which shows a few
>more pages but after clicking 'more' a few times it then locks up.
>What am I missing? Have you found a way to read the pdf file?

Download the pdf file and read the pdf offline. GitHub makes it hard to read pdfs hosted there.

Kurt Pagani

unread,
Feb 14, 2025, 5:51:05 AMFeb 14
to FriCAS - computer algebra system
On Thursday, 13 February 2025 at 16:47:56 UTC+1 Martin Baker wrote:
I find Lisp very hard to follow. I'm not criticising the language or
trying to start a debate about it. I just find, for me personally, after
a few lines of Lisp code I tend to loose track of whats happening and
give up.

As a disciple of Wirth i can understand that  ... never learned it thoroughly, however, I survive with:
Apparently any lang ends up in lambda or even (amazing, I find) https://en.wikipedia.org/wiki/Iota_and_Jot, eventually.

Waldek Hebisch

unread,
Feb 18, 2025, 5:08:03 PMFeb 18
to fricas...@googlegroups.com
On Thu, Feb 13, 2025 at 10:59:20AM +0000, Martin Baker wrote:
> The attached file contains my first tentative experiments with what I
> thought of as Finite Topology. Could you take a quick glance at it to
> see if that's what you would describe as Finite Topology, if not could
> you suggest an alternative name?

The 'OpenSet' domain is confusing/confused. First, you do not say
what is the meaning. Just saying 'open set' is almost meanigless,
set is open or not depending on topology. Second, looking
at imlemented functions it looks like Set(NonNegativeInteger),
with one or two added operations and missing several other
operations.

'TopologyFinite' looks like reasonable attempt to implement
topology on a finite set. But there are some warts. First,
implementation of 'intersection' and 'union' is clearly
bogus. Normal practice when you do not have reasonable
implemntation is to leave function unimplemented. Or
possibly write:

intersection(a:%, b:%) : % == error "intersection: unimplemented"

and similarly for all other functions without good implementation.

Second, 'setTopologyFromList' "on faith" treats given list as
a correct topology. Normal practice in FriCAS is either to
check that this is really a topology or generate topology
from given list (assiming that this is list of open sets,
we can take intersections and than sums of intersections to
obtain topology). Third, {{}, {1}, {1, 12}, {1, 20}, {1, 12, 20}}
gives a topology on set {1, 12, 20}, but your code seem to
assume that the space is really interval from 0 to 20.

It is not clear to me what TopoSpaceFinite is supposed to mean?
Do you want points of your space to be symbols? If yes, you
can just take type of points as parameter of constructor, no
need to repeat definition. If you want something else, then what
really want?

> Anyway its the subject that interests me at the moment and I think it
> should keep me busy for a few years.
>
> Despite what you say about the usefulness of 'geometric realization' I
> would still like to attempt to implement it, just for completeness and
> my own education. I realise that n points will produce 2*n+1 dimensions
> but FriCAS can handle high dimensional matrix algebra, right? That's one
> of the advantages of doing this on a CAS.

You can do something, but since there is no embedding for general
finite topology, you can not implement embedding. To make it a
bit stronger, consider topolony on {0, 1} where open sets are
{{}, {1}, {0, 1}}. Every continuous function from this space
to euklidean space is constant. You probably can "unnerve" your
space, that is find collection C of open sets such nerve of C
is the same as your space. But that is different than
embedding and in mathematics such differences matter quite a lot.

--
Waldek Hebisch

Camm Maguire

unread,
Feb 26, 2025, 9:33:41 PMFeb 26
to Waldek Hebisch, ca...@maguirefamily.org, fricas...@googlegroups.com
Greetings! In general, do macosx users use macports, homebrew, or
compile on their own? Likewise do windows users use cygwin or compile
on their own?

Take care,
--
Camm Maguire ca...@maguirefamily.org
==========================================================================
"The earth is but one country, and mankind its citizens." -- Baha'u'llah

Qian Yun

unread,
Feb 26, 2025, 9:46:19 PMFeb 26
to fricas...@googlegroups.com
For windows, there's packaged binary to download directly.
That binary is compiled with sbcl on mingw64.

As for cygwin, sbcl does not run on it, ecl worked on it,
I have not tried for a long time. The advantage of cygwin
is to have X11 support.

IIRC that GCL supports mingw (not mingw64!), which is really
outdated.

(BTW, in my mailbox, your mail is not a standalone thread,
instead it is a reply to "Finite Topological Space".)

- Qian

Dima Pasechnik

unread,
Feb 27, 2025, 12:00:16 AMFeb 27
to fricas...@googlegroups.com, Waldek Hebisch, ca...@maguirefamily.org
On Wed, Feb 26, 2025 at 8:33 PM Camm Maguire <ca...@maguirefamily.org> wrote:
>
> Greetings! In general, do macosx users use macports, homebrew, or
> compile on their own? Likewise do windows users use cygwin or compile
> on their own?

I'm not a big macOS fun or user myself, but SageMath and GAP are quite
popular among Mac users, and
they basically are either Homebrew users, or more of compiling on
their own (the latter are the worst, support-wise,
as their machines are often a huge mess, toolchain-wise)

Macports lag behind in may ways, and are more popular among
retrocomputing people.

We (SageMath) tell Windows users to use WSL, as cygwin is a huge mess,
and not very active,
but we need more Unix than things like mingw64 provide.

Dima

>
> Take care,
> --
> Camm Maguire ca...@maguirefamily.org
> ==========================================================================
> "The earth is but one country, and mankind its citizens." -- Baha'u'llah
>
> --
> You received this message because you are subscribed to the Google Groups "FriCAS - computer algebra system" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to fricas-devel...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/fricas-devel/87ikow3ym8.fsf_-_%40maguirefamily.org.

Camm Maguire

unread,
Feb 28, 2025, 9:52:09 AMFeb 28
to Dima Pasechnik, ca...@maguirefamily.org, <maxima-discuss@lists.sourceforge.net>, gcl-...@gnu.org, fricas...@googlegroups.com, Waldek Hebisch
Greetings, and thanks for your helpful reply!

Dima Pasechnik <dim...@gmail.com> writes:

> On Wed, Feb 26, 2025 at 8:33 PM Camm Maguire <ca...@maguirefamily.org> wrote:
>>
> We (SageMath) tell Windows users to use WSL, as cygwin is a huge mess,
> and not very active,
> but we need more Unix than things like mingw64 provide.
>
> Dima
>

Now here is a useful question -- has WSL made cygwin and mingw obsolete?
Would love to hear from real actual users.

Camm Maguire

unread,
Feb 28, 2025, 9:53:05 AMFeb 28
to Qian Yun, ca...@maguirefamiy.org, fricas...@googlegroups.com
Greetings, and thanks!

Qian Yun <oldk...@gmail.com> writes:

> For windows, there's packaged binary to download directly.
> That binary is compiled with sbcl on mingw64.
>
> As for cygwin, sbcl does not run on it, ecl worked on it,
> I have not tried for a long time. The advantage of cygwin
> is to have X11 support.
>

Pending the answer to my earlier query regarding WSL making cygin and
mingw obsolete, GCL 2.6 and 2.7 supports cygwin, in case you want the
X11 support.

> IIRC that GCL supports mingw (not mingw64!), which is really
> outdated.

Supporting this does not appear too difficult, but honestly I would like
one windows target, preferably the simplest.

>
> (BTW, in my mailbox, your mail is not a standalone thread,
> instead it is a reply to "Finite Topological Space".)
>

My apologies, yes, replied to an older thread.

Take care,

> - Qian
>
> On 2/27/25 10:33 AM, Camm Maguire wrote:
>> Greetings! In general, do macosx users use macports, homebrew, or
>> compile on their own? Likewise do windows users use cygwin or compile
>> on their own?
>>

Prof. Dr. Johannes Grabmeier

unread,
Feb 28, 2025, 2:56:58 PMFeb 28
to fricas...@googlegroups.com
using this since yesterday on sbcl 2.5.0

but now (don't whether this is responsible, as I have changed the code) a complicated spad-File now no longer compiles because of heap exhausted.
Any idea, no idea how to use the LDB. How can I increase the memory?


; --> PROGN SB-IMPL::%DEFUN SB-IMPL::%DEFUN SB-INT:NAMED-LAMBDA
; ==>
; #'(SB-INT:NAMED-LAMBDA BOOT::|SWTOURN;zeroAscending;PiV;13|
; (BOOT::|k| BOOT::%)
; (DECLARE (SB-C::TOP-LEVEL-FORM))
; (DECLARE (TYPE (INTEGER 1 *) BOOT::|k|))
; (BLOCK BOOT::|SWTOURN;zeroAscending;PiV;13|
; (BOOT::SPROG ((#:G2251 NIL) (BOOT::|r| NIL) (#:G2250 NIL))
; (BOOT::SEQ (PROGN # # #:G2250)))))
;
; caught STYLE-WARNING:
; The variable % is defined but never used.
Heap exhausted during garbage collection: 32752 bytes available, 32784 requested.
| Immobile Objects |
Gen layout symbol code Boxed Cons Raw Code SmMix Mixed LgRaw LgCode LgMix Waste% Alloc Trig Dirty GCs Mem-age
1 0 0 0 246 64 28549 0 8 17 0 0 0 49.4 956898448 64584056 28884 1 1.2163
2 0 0 0 205 49 17968 0 8 4 0 0 0 49.3 606036048 42949672 18227 0 0.0357
3 0 0 0 3194 658 13186 5 40 550 0 0 86 34.9 755679200 2000000 13265 0 0.3770
4 0 0 0 0 0 0 0 0 0 0 0 0 0.0 0 2000000 0 0 0.0000
5 0 0 0 0 0 0 0 0 0 0 0 0 0.0 0 2000000 0 0 0.0000
6 0 0 0 146 65 150 256 50 12 15 0 5 3.0 44453040 2000000 13 0 0.0000
Tot 0 0 0 3791 836 59853 261 106 583 15 0 91 45.0 2363065872 [55.0% of 4294967296 max]
GC control variables:
*GC-INHIBIT* = true
*GC-PENDING* = true
*STOP-FOR-GC-PENDING* = false
Collection trigger variables:
dynamic_space_size = 4294967296
bytes_allocated = 2363065872
auto_gc_trigger = 1873832988
bytes_consed_between_gcs = 214748364
fatal error encountered in SBCL pid 47251 pthread 0x1e0d19c40:
Heap exhausted, game over.

Welcome to LDB, a low-level debugger for the Lisp runtime environment.
(GC in progress, oldspace=1, newspace=2)
ldb>
ldb>



Mit freundlichen Grüßen

Johannes Grabmeier

Prof. Dr. Johannes Grabmeier,
Köckstraße 1, D-94469 Deggendorf
Tel. +49-(0)-991-2979584, Tel. +49-(0)-151-681-70756
Fax: +49-(0)-991-2979592

Qian Yun

unread,
Feb 28, 2025, 6:42:31 PMFeb 28
to fricas...@googlegroups.com
The most simple way I can think of is this:

fricas -nosman --dynamic-space-size 8096
(This gives 8GB memory, you can change to whatever you like.)


The downside is that you lose hyperdoc, graphics and command line
shortcuts.

The proper solution should be allowing passing extra Lisp arguments
in the "fricas" shell script.

- Qian

On 3/1/25 3:56 AM, 'Prof. Dr. Johannes Grabmeier' via FriCAS - computer

Qian Yun

unread,
Feb 28, 2025, 6:46:08 PMFeb 28
to Camm Maguire, ca...@maguirefamiy.org, fricas...@googlegroups.com
On 2/28/25 10:53 PM, Camm Maguire wrote:
> Greetings, and thanks!
>
> Qian Yun <oldk...@gmail.com> writes:
>
>> For windows, there's packaged binary to download directly.
>> That binary is compiled with sbcl on mingw64.
>>
>> As for cygwin, sbcl does not run on it, ecl worked on it,
>> I have not tried for a long time. The advantage of cygwin
>> is to have X11 support.
>>
>
> Pending the answer to my earlier query regarding WSL making cygin and
> mingw obsolete, GCL 2.6 and 2.7 supports cygwin, in case you want the
> X11 support.
>

WSL is pure Linux, windows is doing the emulation.

Cygwin is an emulation layer, you can consider Cygwin as a quirky
Linux distribution.

Mingw is obsolete, but Mingw-w64 is not. This provides a *native*
windows executable. Which I consider as the most valuable target
if you are considering windows support, because it provides the best
user experience.

- Qian

Martin Baker

unread,
Mar 1, 2025, 8:46:51 AMMar 1
to fricas...@googlegroups.com
Can anyone help me with a bug I see when compiling and running my code?
I don't know if this is a bug in my code or FriCAS code, probably both,
at least the error message could be better.

I can compile and run my code and it works as I want, but if I compile
and run it again (even if I don't change the source) it will compile but
gives an error when I run it. This continues until I do )clear all.

I assume something in the code is corrupting my setup but I don't know
where to look for it.

This bug started happening when I replaced my OpenSet domain with Set
(as you suggested) but there were a lot of changes and it might have
been some other tidy up that I did at the same time. So I can't work out
what change caused it.

This is how to see the bug:

my code is here:
https://github.com/martinbaker/fricasAlgTop/blob/topology/topology.spad

I then type:
)co fricas/topology.spad
source := topoSpaceFiniteLeftOrder(["a","b","c"])
target := topoSpaceFiniteLeftOrder(["d","e"])
h : Homset(source,target) := homset()

This works as I expected (giving all possible continuous maps between
these topological spaces)
but if I type the exact sequence again I get the error message below,
until I type )clear all.

Here it is in detail:

Checking for foreign routines
FRICAS="/usr/local/lib/fricas/target/x86_64-linux-gnu"
spad-lib="/usr/local/lib/fricas/target/x86_64-linux-gnu//lib/libspad.so"
foreign routines found
openServer result 0
FriCAS Computer Algebra System
Version: FriCAS 1.3.11 built with sbcl 1.4.16
Timestamp: Sat Jun 29 21:21:31 UTC 2024
-----------------------------------------------------------------------------
Issue )copyright to view copyright notices.
Issue )summary for a summary of useful system commands.
Issue )quit to leave FriCAS and return to shell.
-----------------------------------------------------------------------------


(1) -> )co fricas/topology.spad
<snip>

(1) -> source := topoSpaceFiniteLeftOrder(["a","b","c"])

(1) [[a, b, c], topology=[{1}, {1, 2}, {1, 2, 3}]]
Type:
TopoSpaceFinite
(2) -> target := topoSpaceFiniteLeftOrder(["d","e"])

(2) [[d, e], topology=[{1}, {1, 2}]]
Type:
TopoSpaceFinite
(3) -> h : Homset(source,target) := homset()

(3)
homset
[map image=[1, 1, 1] preimage=[3, 3], map image=[1, 1, 2]
preimage=[2, 3],
map image=[1, 2, 2] preimage=[1, 3]]
Type:
Homset([[a,b,c],CONCAT(topology=,[BRACE(1),BRACE(1,2),BRACE(1,2,3)])],[[d,e],CONCAT(topology=,[BRACE(1),BRACE(1,2)])])

So far this does exactly what I want (giving all possible continuous
maps between these topological spaces)
but if I type the exact sequence again I get the error message:

(4) -> )co fricas/topology.spad
<snip>

(4) -> source := topoSpaceFiniteLeftOrder(["a","b","c"])

(4) [[a, b, c], topology=[{1}, {1, 2}, {1, 2, 3}]]
Type:
TopoSpaceFinite
(5) -> target := topoSpaceFiniteLeftOrder(["d","e"])

(5) [[d, e], topology=[{1}, {1, 2}]]
Type:
TopoSpaceFinite
(6) -> h : Homset(source,target) := homset()

You cannot declare h to be of type Homset([[a,b,c],CONCAT(topology=,
[BRACE(1),BRACE(1,2),BRACE(1,2,3)])],[[d,e],CONCAT(topology=,[
BRACE(1),BRACE(1,2)])]) because either the declared type of h or
the type of the value of h is different from Homset([[a,b,c],
CONCAT(topology=,[BRACE(1),BRACE(1,2),BRACE(1,2,3)])],[[d,e],
CONCAT(topology=,[BRACE(1),BRACE(1,2)])]) .


Pieter van Oostrum

unread,
Mar 1, 2025, 9:25:08 AMMar 1
to fricas...@googlegroups.com
Camm Maguire <ca...@maguirefamily.org> writes:

> Greetings! In general, do macosx users use macports, homebrew, or
> compile on their own? Likewise do windows users use cygwin or compile
> on their own?

I use macports.

Greetings
--
Pieter van Oostrum <pie...@vanoostrum.org>
www: http://pieter.vanoostrum.org/
PGP key: [8DAE142BE17999C4]

Ralf Hemmecke

unread,
Mar 1, 2025, 9:31:39 AMMar 1
to fricas...@googlegroups.com
Hi Martin,

without looking into topology.spad I guess the reason for you problem
comes from the line

h : Homset(source,target) := homset()

The interpreter remembers now the type of h. And this cannot change in a
session unless you say

)clear prop h

)co fricas/topology.spad
source := topoSpaceFiniteLeftOrder(["a","b","c"])
target := topoSpaceFiniteLeftOrder(["d","e"])
h : Homset(source,target) := homset()

)co fricas/topology.spad
source := topoSpaceFiniteLeftOrder(["a","b","c"])
target := topoSpaceFiniteLeftOrder(["d","e"])
h : Homset(source,target) := homset()

You declare a new variable "source" (no, it is not the same as in the
first definition/assignment). Well, it's the same variable, but it value
changed in the sense that it now points to a different memory location.

Then you use it in "h : Homset(source,target) := homset()". Fine,
but after the second "source := ...", "Homset(source,target)" and the
one you used before are "two different types".

FriCAS ensures that, for example Polynomial(Integer) and
Polynomial(Integer) are the same types, but not that Foo(v1) is the same
as Foo(v2) even if v1 and v2 represent the same value (that is NOT a
domain or category).

Maybe I am wrong, but I have seen such errors

>    You cannot declare h to be of type Homset([[a,b,c],CONCAT(topology=,
>       [BRACE(1),BRACE(1,2),BRACE(1,2,3)])],[[d,e],CONCAT(topology=,[
>       BRACE(1),BRACE(1,2)])]) because either the declared type of h or
>       the type of the value of h is different from Homset([[a,b,c],
>       CONCAT(topology=,[BRACE(1),BRACE(1,2),BRACE(1,2,3)])],[[d,e],
>       CONCAT(topology=,[BRACE(1),BRACE(1,2)])]) .

several times.

The way around this is that you do not declare h to be of a certain
type, but rather put the type onto the right-hand side.

I guess

h := homset() $ Homset(source,target)

should do the trick. (I haven't actually tested it locally.)

Ralf

Martin Baker

unread,
Mar 1, 2025, 11:10:18 AMMar 1
to fricas...@googlegroups.com
On 01/03/2025 14:31, 'Ralf Hemmecke' via FriCAS - computer algebra
system wrote:
> Hi Martin,
>
> without looking into topology.spad I guess the reason for you problem
> comes from the line
>
> h : Homset(source,target) := homset()

Thanks Ralf,

I have just tried what you suggested and I think you are correct.

As you suspected, this cleared the problem once it happened:
)clear prop h

and calling it this way:
h := homset() $ Homset(source,target)
does not create the problem.

I would never have worked this out without your help. Are there any
resources that would help SPAD programmers solve issues like this? It
would be good if there was information to help with debugging on
fricas.github.io
Many years ago, I tried to collect information that would help me with
debugging and put it here as I found it:
https://www.euclideanspace.com/prog/scratchpad/spad/debug/index.htm
But that is just my random notes which may be incorrect and out-of-date,
if there is anything useful to others it would be good if you could put
it on fricas.github.io

Thanks again,

Martin

Waldek Hebisch

unread,
Mar 1, 2025, 12:23:05 PMMar 1
to fricas...@googlegroups.com
On Sat, Mar 01, 2025 at 04:10:15PM +0000, Martin Baker wrote:
> On 01/03/2025 14:31, 'Ralf Hemmecke' via FriCAS - computer algebra
> system wrote:
> > Hi Martin,
> >
> > without looking into topology.spad I guess the reason for you problem
> > comes from the line
> >
> > h : Homset(source,target) := homset()
>
> Thanks Ralf,
>
> I have just tried what you suggested and I think you are correct.
>
> As you suspected, this cleared the problem once it happened:
> )clear prop h
>
> and calling it this way:
> h := homset() $ Homset(source,target)
> does not create the problem.
>
> I would never have worked this out without your help. Are there any
> resources that would help SPAD programmers solve issues like this?

We probably should have somewhere information that:

h : Homset(source, target) := homset()

may lead to breakage when code is modified, while

h := homset()$Homset(source, target)

simply uses new type.

Beyond that, FriCAS told you that there is type mismatch, so normal
rule is to look at variable declaration. While it is not obvious
_why_ type does not match, removing declaration fixes the problem.

Arguably, interpreter should notice that type really did not change,
but similar problems _are_ expected when you change types. The
second variant adapts to changed types, while the first one leads
to trouble. So, when developing code I prefer the second way
(but many online examples show the first one).

In introductory part of FriCAS book we have:

: A variable initially has no restrictions on the kinds of
: values to which it can refer.

: To restrict the types of objects that can be assigned to a variable,
: use a declaration
:
: y : Integer
:
: After a variable is declared to be of some type, only values
: of that type can be assigned to that variable.

...

: A type declaration can also be given together with an assignment.
: The declaration can assist FriCAS in choosing the correct
: operations to apply.

But @ or $ are more specific, so there is really no reason to
declare type of variable when all what you need is proper choice
of operation.

> It
> would be good if there was information to help with debugging on
> fricas.github.io

There is info about debugging:

http://wiki.fricas.org/DebuggingFriCAS

and

doc/debug.txt

int the source tree. However, it does not cover cases like yours.

> Many years ago, I tried to collect information that would help me with
> debugging and put it here as I found it:
> https://www.euclideanspace.com/prog/scratchpad/spad/debug/index.htm
> But that is just my random notes which may be incorrect and out-of-date,

At the start there is some confusion: you write that mode is Spad
jargon for type. But that is more subtle. Spad compiler does not
use modes, only types. Modes are used by the interpreter. Modes
differ from type in an important aspect: type is fully determined,
while mode contain undetermined part. This is explained in
section 2.2.4 of the FriCAS book.

--
Waldek Hebisch

Martin Baker

unread,
Mar 3, 2025, 12:06:35 PMMar 3
to fricas...@googlegroups.com
I am finding my working code is producing a lot of compiler warnings.
The code is working OK so should I take any notice of these warnings?

I have distilled the most common ones to the test cases below:

test1 says "x has no value". I've got a hazy memory that there is some
issue with a function returning a value that may not be valid outside
the scope of the function. Is it something like that? Although the code
does run as I would expect so should I make some change just to
eliminate the warning?

Why does test3 produce an warning and not test2?
I have commented out test3 because the "The variable % is defined but
never used." warning masks out the "x has no value" warning.

Martin

)abbrev package MJBTEST1 MJBTest1
NNI==> NonNegativeInteger

++ code to show compiler warnings
MJBTest1() : with
test1 : (im:List NNI) -> List NNI
++ test1: x has no value
test2 : (List NNI) -> List NNI
++ no warnings
test3 : (List NNI) -> List NNI
++ Caught STYLE-WARNING:
++ The variable % is defined but never used.

== add

test1(im:List NNI) : List NNI ==
x:List NNI := [4,5,6]
for p in im repeat
if p=3 then
x := concat(x,p)
x

test2(a : List NNI) : List NNI ==
b : List NNI := []
for a1 in a repeat
b := concat(b,a1+1)
b

-- test3(c : List NNI) : List NNI ==
-- d : List NNI := []
-- for c1 in c repeat
-- d := concat(c1+1,d)
-- d

Waldek Hebisch

unread,
Mar 3, 2025, 10:02:06 PMMar 3
to fricas...@googlegroups.com
On Mon, Mar 03, 2025 at 05:06:31PM +0000, Martin Baker wrote:
> I am finding my working code is producing a lot of compiler warnings.
> The code is working OK so should I take any notice of these warnings?
>
> I have distilled the most common ones to the test cases below:
>
> test1 says "x has no value". I've got a hazy memory that there is some
> issue with a function returning a value that may not be valid outside
> the scope of the function. Is it something like that? Although the code
> does run as I would expect so should I make some change just to
> eliminate the warning?

This warning looks like a bug in the Spad compiler. Namely
it looks that 'if' is loosing information that 'x' has initial
value. I will try to fix this, but in the mean time you can
safely ignore this one.

> Why does test3 produce an warning and not test2?
> I have commented out test3 because the "The variable % is defined but
> never used." warning masks out the "x has no value" warning.

I am not sure what you mean saying "masks out". The "The variable
% is defined but never used." warning comes from Lisp compiler (sbcl).
This warning is true, but useless one: '%' is an extra (hidden)
parameter added to Spad functions and is passed by each Spad function
call. It is necessary, because when doing call we do not know
if the function will use it.

Actually this warning indicates good thing: in 'test3' all operations
are inlined, so it is much more efficient than 'test2' (also, 'test2'
has quadratic complexity while 'test3' has linear complexity).

When 'test3' is uncommented I see the "x has no value" warning.
Simply, it is earlier: all diagnostics from Spad compiler come
before diagonstics from Lisp compiler. One needs to scroll back
a bit to see this diagnostics.

Concerning code style, the first two functions can be written
in shorter and more efficient way:

test1a(im : List NNI) : List NNI ==
concat([4, 5, 6], [p for p in im | p = 3])

test2a(a : List NNI) : List NNI == map(a1 +-> a1 + 1, a)

test2b(a : List NNI) : List NNI == [a1 + 1 for a1 in a]

Note: adding things element by element to the end of a list
is inherently slow, as each 'concat' needs to copy first part
of the list. 'test1a' contains only single call to 'concat',
so it makes at most one copy of the initial list.

'map' in 'test2a' makes a single pass over the list, so
typically is faster then 'test2'. 'test2b' is doing all
work by inline code, so should be faster than both 'test2a'
and 'test2'.

'test3' adds elements to start of the list, this is typical
pattern when we need somewhat more complex processing and
efficiency. However, I would advise against using 'concat'
here and using 'cons' instead. That is:

test3a(c : List NNI) : List NNI ==
d : List NNI := []
for c1 in c repeat
d := cons(c1 + 1, d)
d

The reason is that 'concat' is overloaded and in case of
list of lists we may get wrong resolution of overload
doing something like 'concat([], d)'. While this is
rather special case, it is easier to remeber to use 'cons'
to add elements to the start of the list, than to watch
out for special cases. In particular, normally one can
modify Spad code without troubles, but when using 'concat'
plugging in known value of variable may lead to different
overload resolution and consequently to trouble. So
using 'cons' is much safer.

--
Waldek Hebisch

Kurt Pagani

unread,
Mar 4, 2025, 5:24:13 AMMar 4
to FriCAS - computer algebra system
On Tuesday, 4 March 2025 at 04:02:06 UTC+1 Waldek Hebisch wrote:
On Mon, Mar 03, 2025 at 05:06:31PM +0000, Martin Baker wrote:
> I am finding my working code is producing a lot of compiler warnings.
> The code is working OK so should I take any notice of these warnings?
>
> I have distilled the most common ones to the test cases below:
>
> test1 says "x has no value". I've got a hazy memory that there is some
> issue with a function returning a value that may not be valid outside
> the scope of the function. Is it something like that? Although the code
> does run as I would expect so should I make some change just to
> eliminate the warning?

This warning looks like a bug in the Spad compiler. Namely
it looks that 'if' is loosing information that 'x' has initial
value. I will try to fix this, but in the mean time you can
safely ignore this one.

A simple 'else x:=x' avoids the warning.

test1(im:List NNI) : List NNI ==
      x:List NNI := [4,5,6]
      for p in im repeat
        if p=3 then
          x := concat(x,p)
        else
          x := x
      x

Maybe it can be seen as a bug, however, the compiler isn't a clairvoyant either ...
Aside from style as remarked below, it's better to complete if ... then ... else anyway whenever possible.

Martin Baker

unread,
Mar 4, 2025, 1:35:07 PMMar 4
to fricas...@googlegroups.com
On 04/03/2025 03:02, Waldek Hebisch wrote:
> This warning looks like a bug in the Spad compiler. Namely
> it looks that 'if' is loosing information that 'x' has initial
> value. I will try to fix this, but in the mean time you can
> safely ignore this one.

Thank you for your very helpful and useful reply.

Although you have explained what I need for coding, just for my own
curiosity, I am curious about the root cause of the issues with compiler
warnings. Is it because FriCAS uses a 'Pratt parser' and therefore does
not have a formal syntax and so the warnings can only be generated from
a set of ad hoc rules?

Martin

Waldek Hebisch

unread,
Mar 4, 2025, 3:07:25 PMMar 4
to fricas...@googlegroups.com
On Tue, Mar 04, 2025 at 06:35:03PM +0000, Martin Baker wrote:
>
> Although you have explained what I need for coding, just for my own
> curiosity, I am curious about the root cause of the issues with compiler
> warnings. Is it because FriCAS uses a 'Pratt parser' and therefore does
> not have a formal syntax and so the warnings can only be generated from
> a set of ad hoc rules?

It is due to simplicity or rather lack of information in compiler
data structures. For example modern compiler typicaly when seeing
an identifier remember its position in source text. Spad compiler
does not store positions. In case of 'if' is it matter of managing
compiler data structurs. Each assignment first checks that variable
is known and appropriate type, this is done via lookup in compiler
symbol table. The assigment adds information that variable is
initialized. At the end of 'if' compiler needs to combine
information from both branches of 'if'. Apparently this code
has a bug, only using information coming from 'if' (namely that
in one branch there is no assignment to 'x') and misses fact
that 'x' has global definition.

Contributing factor is that compiler works in recursive way
and sometimes must backtrack, that throw away part of work
and restart from earlier place. Since in many cases compiler
uses destructive modificantion in principle it is possible
that failed case did some modifications to compiler data
structures and this modification is not valid for the case
after backtracking.

Concerning Spad syntax, while it is rather inconvenient to
specify Spad syntax using a context free grammar, syntax
is precisely defined by priorities. Parser produces parse
tree and for later stages syntax is mostly irrelevant, for
example in principle users could write syntax tree as a Lisp
S-expression (however, later stages depend on getting correct
syntax tree, there are no checks for malformed systax tree
after parsing).

--
Waldek Hebisch
Reply all
Reply to author
Forward
0 new messages