\documentclass{book}
%\newcommand{\VolumeName}{Volume 2: Axiom Users Guide}
%\input{bookheader.tex}
\pagenumbering{arabic}
\mainmatter
\setcounter{chapter}{0} % Chapter 1

\usepackage{makeidx}
\makeindex
\begin{document}
\begin{verbatim}
\start
Date: Sun, 01 Nov 2009 19:04:09 -0500
From: Tim Daly
To: Franz Lehner, Bertfried Fauser
Subject: listOfTerms

Your tensor code uses the function "listOfTerms" but I do not see
it among the exports of any category, domain, or package.
Where is this defined?

\start
Date: Mon, 2 Nov 2009 08:43:31 +0100 (CET)
From: Franz Lehner
To: Tim Daly
Subject: Re: listOfTerms
Cc: Bertfried Fauser

On Sun, 1 Nov 2009, Tim Daly wrote:
> Your tensor code uses the function "listOfTerms" but I do not see
> it among the exports of any category, domain, or package.
> Where is this defined?

Some time ago I merged "FreeModule" and "FreeModule1", renamed
"FreeModuleCat" to FreeModuleCategory" and made "FreeModule" export
"FreeModuleCategory" as it should be.  I also renamed ListOfTerms to
listOfTerms in "IndexedDirectProductCategory" and all entities which
inherit the latter.

\start
Date: Mon, 02 Nov 2009 11:42:35 -0500
From: Tim Daly
To: Franz Lehner
Subject: Re: listOfTerms
Cc: Bertfried Fauser

Franz Lehner wrote:
> On Sun, 1 Nov 2009, Tim Daly wrote:
>> Your tensor code uses the function "listOfTerms" but I do not see
>> it among the exports of any category, domain, or package.
>> Where is this defined?
> Some time ago I merged "FreeModule" and "FreeModule1",
> renamed "FreeModuleCat" to FreeModuleCategory" and
> made "FreeModule" export "FreeModuleCategory" as it should be.
> I also renamed ListOfTerms to listOfTerms in 
> "IndexedDirectProductCategory"
> and all entities which inherit the latter.
>
> Franz
>
Yes, I saw the renames. But listOfTerms does not seem to be
exported anywhere in Fricas. Try
  )d op listOfTerms

\start
Date: Mon, 2 Nov 2009 17:11:45 +0000
From: Bertfried Fauser
To: list
Subject: listOfTerms

if I naively do the below attached things, I get in FriCAS an export
of listOfTerms,
also )d op listOfTerms guids me to IDPC and )sh IDPC shows the export...

fauser@selfmaint-145:~> fricas
Checking for foreign routines
AXIOM="/usr/local/lib/fricas/target/i686-suse-linux"
spad-lib="/usr/local/lib/fricas/target/i686-suse-linux/lib/libspad.so"
foreign routines found
openServer result 0
                 FriCAS (AXIOM fork) Computer Algebra System
                         Version: FriCAS 2009-10-26
               Timestamp: Sunday November 1, 2009 at 22:23:01
-----------------------------------------------------------------------------
   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) ->
(1) -> )d op listOfTerms

There is one exposed function called listOfTerms :
   [1] D -> List(Record(k: D3,c: D2)) from D
            if D has IDPC(D2,D3) and D2 has SETCAT and D3 has ORDSET


There are 2 unexposed functions called listOfTerms :
   [1] LieExponentials(D2,D3,D4) -> List(Record(k:
            PoincareBirkhoffWittLyndonBasis(D2),c: D3))
            from LieExponentials(D2,D3,D4)
            if D2 has ORDSET and D3 has Join(CommutativeRing,Module(
            Fraction(Integer))) and D4: PI
   [2] PoincareBirkhoffWittLyndonBasis(D2) -> List(LyndonWord(D2))
            from PoincareBirkhoffWittLyndonBasis(D2) if D2 has ORDSET

(1) -> )sh IDPC
 IndexedDirectProductCategory(A: SetCategory,S: OrderedSet)  is a
category constructor
 Abbreviation for IndexedDirectProductCategory is IDPC
 This constructor is exposed in this frame.
------------------------------- Operations --------------------------------
 ?=? : (%,%) -> Boolean                coerce : % -> OutputForm
 hash : % -> SingleInteger             latex : % -> String
 leadingCoefficient : % -> A           leadingSupport : % -> S
 map : ((A -> A),%) -> %               monomial : (A,S) -> %
 reductum : % -> %                     ?~=? : (%,%) -> Boolean
 construct : List(Record(k: S,c: A)) -> %
 constructOrdered : List(Record(k: S,c: A)) -> %
 leadingTerm : % -> Record(k: S,c: A)
 listOfTerms : % -> List(Record(k: S,c: A))

\start
Date: Mon, 2 Nov 2009 19:28:02 +0100 (CET)
From: Franz Lehner
To: Bertfried Fauser
Subject: Re: listOfTerms

Dear Tim and Bertfried,
On Mon, 2 Nov 2009, Bertfried Fauser wrote:
> There is one exposed function called listOfTerms :
>   [1] D -> List(Record(k: D3,c: D2)) from D
>            if D has IDPC(D2,D3) and D2 has SETCAT and D3 has ORDSET

yes, that's the one.

\start
Date: Tue, 3 Nov 2009 17:27:24 +0000
From: Martin Baker
To: Bertfried Fauser
Subject: Re: Clifford Algebra Requirements

Thank you very much to the very helpful replies to my earlier messages, they 
give me a much clearer idea of the issues and complexities involved. I have 
been re-reading your messages to try to understand how to generate the 
multiplication rules from the quadratic form (as well as trying to understand 
Axiom in general). I'm afraid that the Rota Stein Hopf algebra method and the 
Chevalley recursive definition go over my head, at the moment, so I am unsure 
how to proceed.

The only approach I could think of is to further impinge on your patience by 
writing down what I think I understand and then hoping that you will give me 
some hints about how I can take it forward and understand it better.

Flavours of algebra being discussed
-----------------------------------
We are discussing algebras under the banner of Clifford algebra but there are 
different flavours of this:

* Grassman Algebra - vectors square to zero (exterior product '^').

* Clifford Algebra with Clifford bases - vector bases square to scalar value, 
usually +1 or -1 (equivalent to Grassman bases where quadratic form from 
diagonal matrix).

* Clifford Algebra with Grassman bases - vectors square to scalar value, bases 
can be rotated, specified by quadratic form (tensor product V (x) V^*).

* Geometric Algebra - Hestenes terminology (widely used) for Clifford Algebra 
(over reals) used in geometric context. 

In all cases pure vectors and pure bivectors anticommute.
Since the Grassman algebra underpins the other Algebras, as the exterior 
product, it makes the terminology very messy. It is hard to see a naming 
convention that won't be confusing. Most books on the subject use 'Geometric 
Algebra' and 'Clifford Algebra' is the second most popular. The book by John 
Browne, mentioned by Bill Page seems to put everything under the category of 
Grassman Algebra?

The John Browne book also seems to have a different terminology. It seems to 
use 'reciprocal bases' to do things in a tensor like way. It seems to derive 
all product types from the exterior and interior (defined as the dual of 
exterior) products.
It seems to have a 'metric palette' which is a square matrix for each grade. 
For instance the metric palette for 2D vectors is:
grade 0: [1]
grade 1: [[g(1,1),g(1,2)],[g(1,2),g(2,2)]]
grade 2: [ -g(1,2)^2 + g(1,1)g(2,2)]

Current Implementation
----------------------
The current implementation in Axiom implements Clifford Algebra with Clifford 
bases, however the constructor uses a quadratic form so implementation could 
be upgraded to Grassman bases without changing the external interface 
(although I guess it would slow it down a lot). Although a better solution is 
to create GrassmanSuperHopfAlegbra from graedFreeModule(Ring,Basis) or 
GrassmannSuperHopfAlgebraWithBasis which is what Bertfried is working on.

Getting back to the current implementation, taking an example based on 2D 
vectors and creating quadratic form from:

a 0
0 c

The multiplication table could be generated from these rules:

<e1, e2 | e1*e1=a, e2*e2=c, e1*e2= -e2*e1>

(and e1*e2 = e1^e2)

The current implementation generates table terms every time they are used when 
* operation is called (the table is not generated when a Clifford type is 
defined or instantiated: performance issue).

The way that this is calculated in the code is not really documented but as 
far as I can work out these rules are implemented by representing bases as non 
negative integers (NNI) representing a binary value where a bit position is an 
individual vector base, for example e1^e2 would be 00000011. These represent 
words, the words for each operand are effectively concatenated and the rules 
are applied to reduce to a valid base. This is done to determine the scalar 
(sign) as the basis type could have been found from the exclusive-or of the 
binary values. This is all done using specific code in the addMonomProd 
procedure rather than using any rule mechanism built into Axiom.

Change required
---------------
Grassman bases are required for many important applications such as modelling 
conformal space.

So how can we generate the multiplication table from any quadratic form?

a b
b c

Originally I thought this would have to be done by rotating the bases to make 
this diagonal, then apply method above, then rotate back by the same amount. 
However Bertfried has pointed out that this is not necessary and the table can 
be generated directly. I am trying to work out do this and Bertfried hinted 
that this can be worked out from the square of the vector.
So since the vector squares to a scalar:

a*e1**2 + b*e1*e2 + b*e2*e1 + c*e2**2 = scalar

so if we take an example:

0 1
1 0

we get

e1*e2 + e2*e1 = scalar

I can't work out to get any further, I think the rules would be something like 
this (but I can't work out how to get there):

<e1, e2 | e1*e1=0, e2*e2=0, e1*e2= -1+e1^e2, e2*e1= -1-e1^e2>

(so e1*e2 is not e1^e2)

I can't even work out an extremely simple case, more powerful mathematics is 
required, so I need an introduction to the Rota Stein Hopf algebra method and 
the Chevalley recursive definition.

\start
Date: Fri, 6 Nov 2009 17:03:16 +0000
From: Martin Baker
To: list
Subject: Axiom compiling - newbie questions

How do I get started modifying some of the spad code in axiom?

What I wanted to do is add exterior and inner products to the clifford code in 
Axiom.  At this stage I just want to try things out and experiment with the 
minimum of fuss. I therefore cut and pasted the spad code from the clifford 
spad code in pamphlet 10.3 into a file I created called grassman.spad. I then 
renamed all occurrences of CliffordAlgebra to GrassmanAlgebra just so that the 
names did not clash with the existing code otherwise it is the existing 
working code.

I then tried compiling it:

(1) -> )compile axiom/grassman.spad

This almost worked, it created a directory called GRAS.nrlib with some files 
in it, but there were some errors listed in it like this:

   finalizing nrlib GRAS                                
   Processing GrassmanAlgebra for Browser database:     
--------(e (% PI))---------                             
--->-->GrassmanAlgebra((e (% PI))): Unexpected HT command: \spad
"\\spad{e(n)} produces the appropriate unit element." 

I think this comes from this part of the source code:

    T ==> Join(Ring, Algebra(K), VectorSpace(K)) with
        e: PI -> %
          ++ e(n) produces the appropriate unit element.

I thought that this might be because I was using an old version of the 
compiler? So I renamed the file as: grassman.as

Then I tried this:

(1) -> )compile axiom/grassman.as
   Compiling AXIOM source code from file axiom/grassman.as using
      AXIOM-XL compiler and options
-O -Fasy -Fao -Flsp -laxiom -Mno-AXL_W_WillObsolete -DAxiom -Y $AXIOM/algebra
      Use the system command )set compiler args to change these
      options.
sh: NIL/bin/aldor: No such file or directory

I assume the axiom that I downloaded does not contain aldor?

So my questions are:
Is this the best approach to take for a Axiom newbie? Is there an easier way?
Do I need to use Aldor? Is there a binary version for opensuse? Where do I 
install it?

Note: I am using the Axiom May 2009 code for openSUSE downloaded from:
http://www.axiom-developer.org/axiom-website/download.html

\start
Date: Fri, 6 Nov 2009 21:05:02 -0500
From: Bill Page
To: Martin Baker
Subject: Re: Axiom compiling - newbie questions

I think you are going about this the right way ... but you do have a
lot to learn. Programming in Spad in Axiom has a steep learning curve
but it does start to flatten out after a few years ... :-)  No, it's
not that bad but the output of the Spad compiler is simply atrocious.
I don't think there ever was a compiler in my worst nightmare that
produced such obscure and unhelpful output! The language though (if
you can learn to love strongly typed languages) is, in my opinion,
worth all the effort.

The message "Unexpected HT command" is really just a warning that
something in a comment (doc string) does not conform to requirements
for HyperTex processing. If the compile completed successfully you
will see a message about GrassmanAlgebra being "exposed" in your
session. If you get this you should try something like

  )show GrassmanAlgebra

to verify that it really is there.  Then just proceed to use it as you
would CliffordAlgebra.

Aldor is a whole other story and I recommend you read up on it at
http://axiom-wiki.newsynthesis.org and/or consult the email archives.
To use it you definitely have to install additional software,
specifically Aldor itself which is not included in Axiom for licensing
reasons. There is also specific Aldor interface that needs to be
compiled if you want to use Aldor from inside Axiom.  Aldor itself can
be run as a stand alone general purpose language in addition to
serving as a potential replacement for Spad in Axiom.

Good luck and keep asking ...

Regards,
Bill Page.

On Fri, Nov 6, 2009 at 12:03 PM, Martin Baker wrote:
> How do I get started modifying some of the spad code in axiom?
>
> What I wanted to do is add exterior and inner products to the clifford co=
de in
> Axiom. At this stage I just want to try things out and experiment with=
 the
> minimum of fuss. I therefore cut and pasted the spad code from the cliffo=
rd
> spad code in pamphlet 10.3 into a file I created called grassman.spad. I =
then
> renamed all occurrences of CliffordAlgebra to GrassmanAlgebra just so tha=
t the
> names did not clash with the existing code otherwise it is the existing
> working code.
>
> I then tried compiling it:
>
> (1) -> )compile axiom/grassman.spad
>
> This almost worked, it created a directory called GRAS.nrlib with some fi=
les
> in it, but there were some errors listed in it like this:
>
>  finalizing nrlib GRAS
>  Processing GrassmanAlgebra for Browser database:
> --------(e (% PI))---------
> --->-->GrassmanAlgebra((e (% PI))): Unexpected HT command: \spad
> "\\spad{e(n)} produces the appropriate unit element."
>
> I think this comes from this part of the source code:
>
>  T ==> Join(Ring, Algebra(K), VectorSpace(K)) with
>    e: PI -> %
>     ++ e(n) produces the appropriate unit element.
>
> I thought that this might be because I was using an old version of the
> compiler? So I renamed the file as: grassman.as
>
> Then I tried this:
>
> (1) -> )compile axiom/grassman.as
>  Compiling AXIOM source code from file axiom/grassman.as using
>   AXIOM-XL compiler and options
> -O -Fasy -Fao -Flsp -laxiom -Mno-AXL_W_WillObsolete -DAxiom -Y $AXIOM/alg=
ebra
>   Use the system command )set compiler args to change these
>   options.
> sh: NIL/bin/aldor: No such file or directory
>
> I assume the axiom that I downloaded does not contain aldor?
>
> So my questions are:
> Is this the best approach to take for a Axiom newbie? Is there an easier =
way?
> Do I need to use Aldor? Is there a binary version for opensuse? Where do =
I
> install it?
>
> Note: I am using the Axiom May 2009 code for openSUSE downloaded from:
> http://www.axiom-developer.org/axiom-website/download.html

\start
Date: Sat, 7 Nov 2009 17:02:15 +0000
From: Martin Baker
To: Bill Page
Subject: Re: Axiom compiling - newbie questions

Thanks very much for your reply, this gives me a clearer idea of the issues 
involved.

In view of what you said and having looked at the Aldor site I think I will 
stay with the Spad compiler.

I tried:
)show GrassmanAlgebra
and the output looked reasonable.

I thought that the problems that I saw were related to the compiler error 
messages or to this message:
"Compiling AXIOM source code from file axiom/grassman.spad using old system 
compiler." 

However, after more trial and error, I think the problems that I am seeing 
must be due to some kind of name clash?
The problem I am seeing is this: 

(4) -> j: H2 := e(2)

   >> System error:
   Unknown bfd format

Full sequence below.

I am guessing that 'e' is exposed by both the existing CliffordAlgebra and by 
GrassmanAlgebra which I created. I tried:

)set expose drop constructor CliffordAlgebra

but that only hides the constructor, is there a way to hide the variables and 
functions also?

Thanks,

Martin
------------------------------------------------------------------                                                       
(1) -> )set mes auto off
(1) -> K := Fraction Polynomial Integer

   (1)  Fraction Polynomial Integer
                                                                 Type: Domain
(2) -> m := matrix[[-1,0],[0,-1]]

        +- 1   0 +
   (2)  |        |
        + 0   - 1+
                                                         Type: Matrix Integer
(3) -> )library GRAS
   GrassmanAlgebra is now explicitly exposed in frame frame0
   GrassmanAlgebra will be automatically loaded when needed from
      /home/martin/GRAS.nrlib/code
(3) -> )set expose drop constructor CliffordAlgebra
   CliffordAlgebra is now explicitly hidden in frame frame0
(3) -> H2 := GrassmanAlgebra(2, K, quadraticForm m)

   (3)  GrassmanAlgebra(2,Fraction Polynomial Integer,MATRIX)
                                                                 Type: Domain
(4) -> j: H2 := e(2)

   >> System error:
   Unknown bfd format

(4) -> )set expose drop group CliffordAlgebra
   CliffordAlgebra is not a known exposure group name.
(4) -> j: H2 := e(2)$GrassmanAlgebra(2,Fraction Polynomial Integer,MATRIX)

   Although Matrix is the name of a constructor, a full type must be
      specified in the context you have used it. Issue )show Matrix for
      more information.
(4) ->j: H2 := e(2)$GrassmanAlgebra(2,Fraction Polynomial 
Integer,QuadraticForm(2,Fraction Polynomial Integer))

   Cannot convert from type Domain to QuadraticForm(2,Fraction
      Polynomial Integer) for value
   QuadraticForm(2,Fraction(Polynomial(Integer())))

\start
Date: Sat, 7 Nov 2009 18:36:02 +0100 (CET)
From: Waldek Hebisch
To: list
Subject: Re: Axiom compiling - newbie questions

Martin Baker wrote:
> Bill,
> 
> Thanks very much for your reply, this gives me a clearer idea of the issues 
> involved.
> 
> In view of what you said and having looked at the Aldor site I think I will 
> stay with the Spad compiler.
> 
> I tried:
> )show GrassmanAlgebra
> and the output looked reasonable.
> 
> I thought that the problems that I saw were related to the compiler error 
> messages or to this message:
> "Compiling AXIOM source code from file axiom/grassman.spad using old system 
> compiler." 
> 
> However, after more trial and error, I think the problems that I am seeing 
> must be due to some kind of name clash?
> The problem I am seeing is this: 
> 
> (4) -> j: H2 := e(2)
> 
>    >> System error:
>    Unknown bfd format
> 

The message means that Axiom binary you got is incompatible with
your system.  More precisely, Axiom tries to load (use) your 
freshly compiled code and failed.

\start
Date: Mon, 09 Nov 2009 19:51:45 -0500
From: Tim Daly
To: Bertfried Fauser
Subject: pointers

You can get a memory pointer to a lisp object.

a:=Fraction(Integer)

returns the "memory location of Fraction(Integer)"
You can prove this with

b:=Fraction(Integer)
EQ(a,b)$Lisp

The lisp function EQ compares memory pointers.

There is a lisp function to get the hash value of any object
call sxhash. You can call it.

SXHASH(a)$Lisp

Note that if

c:=Integer

then
EQ(a,c)$Lisp is false
SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp

Thus the hash function you seek already exists.
You just have to accept the fact that Spad is only syntactic
sugar for lisp code and lisp is not evil.

\start
Date: Mon, 09 Nov 2009 20:09:30 -0500
From: William Sit
To: Tim Daly, Bertfried Fauser
Subject: Re: pointers

Interesting. Is there a similar function that is more 
structural? say, can I test whether some domain (which may 
be passed as a parameter of type Field) is of the form 
Fraction(something) and if so, extract "something" (that 
is, assign it to a variable and further test it), sort of 
a deconstruction?

William

On Mon, 09 Nov 2009 19:51:45 -0500
  Tim Daly wrote:
>You can get a memory pointer to a lisp object.
>
>a:=Fraction(Integer)
>
>returns the "memory location of Fraction(Integer)"
>You can prove this with
>
>b:=Fraction(Integer)
>EQ(a,b)$Lisp
>
>The lisp function EQ compares memory pointers.
>
>There is a lisp function to get the hash value of any 
>object
>call sxhash. You can call it.
>
>SXHASH(a)$Lisp
>
>Note that if
>
>c:=Integer
>
>then
>EQ(a,c)$Lisp is false
>SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>
>Thus the hash function you seek already exists.
>You just have to accept the fact that Spad is only 
>syntactic
>sugar for lisp code and lisp is not evil.

\start
Date: Mon, 9 Nov 2009 20:18:51 -0500
From: Bill Page
To: Tim Daly
Subject: Re: pointers
Cc: Bertfried Fauser

Besides the fact that from the standard we only have that

  (equal x y) implies (= (sxhash x) (sxhash y)).

Do you see any reason why SXHASH is not used by default in SetCategory?

Note: OpenAxiom currently defines this default:

  add
      hash(s : %):  SingleInteger == SXHASH(s)$Lisp

Regards,
Bill Page.

On Mon, Nov 9, 2009 at 7:51 PM, Tim Daly wrote:
> ...
> There is a lisp function to get the hash value of any object
> call sxhash. You can call it.
>
> SXHASH(a)$Lisp
>
> Note that if
>
> c:=Integer
>
> then
> EQ(a,c)$Lisp is false
> SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>
> Thus the hash function you seek already exists.
> You just have to accept the fact that Spad is only syntactic
> sugar for lisp code and lisp is not evil.

\start
Date: Mon, 09 Nov 2009 21:24:48 -0500
From: Tim Daly
To: William Sit
Subject: Re: pointers
Cc: Bertfried Fauser

I'm not sure what you want. Perhaps you'd like to say:

a:=Fraction(Polynomial(Integer))
b:=devaluate(a)$Lisp

which returns the list (actually of type SExpression)

 (Fraction (Polynomial (Integer)))

c:=destruct(b)
c.2

which returns (Polynomial (Integer))

Does that help?

Tim


William Sit wrote:
> Tim:
>
> Interesting. Is there a similar function that is more structural? say, 
> can I test whether some domain (which may be passed as a parameter of 
> type Field) is of the form Fraction(something) and if so, extract 
> "something" (that is, assign it to a variable and further test it), 
> sort of a deconstruction?
>
> William
>
> On Mon, 09 Nov 2009 19:51:45 -0500
>  Tim Daly wrote:
>> You can get a memory pointer to a lisp object.
>>
>> a:=Fraction(Integer)
>>
>> returns the "memory location of Fraction(Integer)"
>> You can prove this with
>>
>> b:=Fraction(Integer)
>> EQ(a,b)$Lisp
>>
>> The lisp function EQ compares memory pointers.
>>
>> There is a lisp function to get the hash value of any object
>> call sxhash. You can call it.
>>
>> SXHASH(a)$Lisp
>>
>> Note that if
>>
>> c:=Integer
>>
>> then
>> EQ(a,c)$Lisp is false
>> SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>>
>> Thus the hash function you seek already exists.
>> You just have to accept the fact that Spad is only syntactic
>> sugar for lisp code and lisp is not evil.

\start
Date: Mon, 09 Nov 2009 21:38:26 -0500
From: Tim Daly
To: Bill Page
Subject: Re: pointers
Cc: Bertfried Fauser

OpenAxiom's choice is perfectly rational as far as I can tell.
The only issue would be that Aldor hashing would not equal Spad hashing.
I do not know where hashing is used at the Spad level.

Spad domains are stored in $ConstructorCache, once they are created.
In a newly started session do:

)lisp (gethash '|Fraction| |$ConstructorCache|)   ==> nil

then do

a:=1/2
)lisp (gethash '|Fraction| |$ConstructorCache|) ==> ((((|Integer|)) 2 . 
#<vector 08beb9f4>))

So spad domains are hashed internally.

I recommend that we follow OpenAxiom's lead on this provided nothing breaks.

Tim


Bill Page wrote:
> Tim,
>
> Besides the fact that from the standard we only have that
>
>   (equal x y) implies (= (sxhash x) (sxhash y)).
>
> Do you see any reason why SXHASH is not used by default in SetCategory?
>
> Note: OpenAxiom currently defines this default:
>
>   add
>       hash(s : %):  SingleInteger == SXHASH(s)$Lisp
>
> Regards,
> Bill Page.
>
> On Mon, Nov 9, 2009 at 7:51 PM, Tim Daly wrote:
>   
>> ...
>> There is a lisp function to get the hash value of any object
>> call sxhash. You can call it.
>>
>> SXHASH(a)$Lisp
>>
>> Note that if
>>
>> c:=Integer
>>
>> then
>> EQ(a,c)$Lisp is false
>> SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>>
>> Thus the hash function you seek already exists.
>> You just have to accept the fact that Spad is only syntactic
>> sugar for lisp code and lisp is not evil.

\start
Date: Mon, 9 Nov 2009 21:21:28 -0600
From: Gabriel Dos Reis
To: William Sit
Subject: Re: pointers
Cc: Bertfried Fauser

On Mon, Nov 9, 2009 at 7:09 PM, William Sit wrote:
> Tim:
>
> Interesting. Is there a similar function that is more structural? say, can I
> test whether some domain (which may be passed as a parameter of type Field)
> is of the form Fraction(something) and if so, extract "something" (that is,
> assign it to a variable and further test it), sort of a deconstruction?

William --

   In OpenAxiom, when you get a domain, you can reify it, and
ask for the arguments that were used to instantiate it:

(1) -> reify Fraction Integer
   (1)  Fraction Integer
                                      Type: ConstructorCall DomainConstructor
(2) -> arguments reify Fraction Integer
   (2)  [(Integer)]
                                                            Type: List Syntax
\start
Date: Tue, 10 Nov 2009 00:33:39 -0500
From: Tim Daly
To: Bill Page
Subject: Re: pointers
Cc: Gabriel Dos Reis, Bertfried Fauser

Note that, under this definition

a:Dequeue(Integer):= dequeue [1,2,3,4,5]
b:Queue(Integer):= queue [1,2,3,4,5]

hash(a) == hash(b)

This is because the internal data representation of both objects is:

  ((1 2 3 4 5))

Nevertheless, this is a perfectly reasonable hash function.

Tim


Bill Page wrote:
> Tim,
>
> Besides the fact that from the standard we only have that
>
>   (equal x y) implies (= (sxhash x) (sxhash y)).
>
> Do you see any reason why SXHASH is not used by default in SetCategory?
>
> Note: OpenAxiom currently defines this default:
>
>   add
>       hash(s : %):  SingleInteger == SXHASH(s)$Lisp
>
> Regards,
> Bill Page.
>
> On Mon, Nov 9, 2009 at 7:51 PM, Tim Daly wrote:
>   
>> ...
>> There is a lisp function to get the hash value of any object
>> call sxhash. You can call it.
>>
>> SXHASH(a)$Lisp
>>
>> Note that if
>>
>> c:=Integer
>>
>> then
>> EQ(a,c)$Lisp is false
>> SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>>
>> Thus the hash function you seek already exists.
>> You just have to accept the fact that Spad is only syntactic
>> sugar for lisp code and lisp is not evil.

\start
Date: Tue, 10 Nov 2009 01:42:51 -0600
From: Gabriel Dos Reis
To: Tim Daly
Subject: Re: pointers
Cc: Bertfried Fauser

Tim Daly writes:

| Note that, under this definition
| 
| a:Dequeue(Integer):= dequeue [1,2,3,4,5]
| b:Queue(Integer):= queue [1,2,3,4,5]
| 
| hash(a) == hash(b)
          ^^
I suspect you meant '='.

In any case, unless you have a hash function that is a bijection of the
whole universe onto the finite set SingleInteger, you're going to get
different objects/values mapped to the same hash value no matter what.

OpenAxiom being strongly typed, I'm not worried that you're going to put
both a and b in the same HashTable and not being able to avoid the
collision. 

\start
Date: Tue, 10 Nov 2009 11:38:25 -0500
From: William Sit
To: list
Subject: Re: pointers
Cc: Bertfried Fauser

Thanks, Tim. That is exactly what I am looking for. Now I 
would like to compare c.1 with some known constructor, say 
Fraction. (In other words, given a domain of category 
Field, I would like to know if it comes from the 
constructor Fraction). I tried a few variations and each 
time, Axiom says:

Although Fraction is the name of a constructor, a full 
type must be specified in the context you have used it. 
Issue )show Fraction for more information.

Things I tried:

a:=FiniteField(5,2)
b:=devaluate(a)$Lisp
c:=destruct(b)
c.1
d:="Fraction"::SExpression
e:Boolean
e:=EQ(c.1,d)  -- message above
e:=(c.1=Fraction)  -- message above
e:= (c.1=d$Lisp) -- message above
a1:=Fraction Integer
b1:=devaluate(a1)$Lisp
c1:=destruct(b1)
e:=(c.1=c1.1) -- message above

I confess that I'm still using a very old Window version 
(Version of Tuesday November 30, 2004 at 21:11:14) but I 
don't think that makes a difference in these examples.

William

On Mon, 09 Nov 2009 21:24:48 -0500
  Tim Daly wrote:
>I'm not sure what you want. Perhaps you'd like to say:
>
>a:=Fraction(Polynomial(Integer))
>b:=devaluate(a)$Lisp
>
>which returns the list (actually of type SExpression)
>
>(Fraction (Polynomial (Integer)))
>
>c:=destruct(b)
>c.2
>
>which returns (Polynomial (Integer))
>
>Does that help?
>
>Tim
>
>
>William Sit wrote:
>>Tim:
>>
>>Interesting. Is there a similar function that is more 
>>structural? say, 
>>can I test whether some domain (which may be passed as a 
>>parameter of 
>>type Field) is of the form Fraction(something) and if so, 
>>extract 
>>"something" (that is, assign it to a variable and further 
>>test it), 
>>sort of a deconstruction?
>>
>>William
>>
>>On Mon, 09 Nov 2009 19:51:45 -0500
>> Tim Daly wrote:
>>>You can get a memory pointer to a lisp object.
>>>
>>>a:=Fraction(Integer)
>>>
>>>returns the "memory location of Fraction(Integer)"
>>>You can prove this with
>>>
>>>b:=Fraction(Integer)
>>>EQ(a,b)$Lisp
>>>
>>>The lisp function EQ compares memory pointers.
>>>
>>>There is a lisp function to get the hash value of any 
>>>object
>>>call sxhash. You can call it.
>>>
>>>SXHASH(a)$Lisp
>>>
>>>Note that if
>>>
>>>c:=Integer
>>>
>>>then
>>>EQ(a,c)$Lisp is false
>>>SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>>>
>>>Thus the hash function you seek already exists.
>>>You just have to accept the fact that Spad is only 
>>>syntactic
>>>sugar for lisp code and lisp is not evil.

\start
Date: Tue, 10 Nov 2009 11:45:15 -0500
From: William Sit
To: Gabriel Dos Reis
Subject: Re: pointers
Cc: Bertfried Fauser

Thanks for the response. Your script shows how to get the 
parameters, not the constructor. I do not have OpenAxiom 
installed (sorry). The question is whether I can test that 
the constructor is Fraction, or otherwise (like 
FiniteField) when the domain belongs to the category 
Field.

I came across this requirement in algorithms that may take 
advantage of special knowledge of how the coefficient 
field is constructed.

William

On Mon, 9 Nov 2009 21:21:28 -0600
  Gabriel Dos Reis wrote:
>On Mon, Nov 9, 2009 at 7:09 PM, William Sit 
>William Sit wrote:
>> Tim:
>>
>> Interesting. Is there a similar function that is more 
>>structural? say, can I
>> test whether some domain (which may be passed as a 
>>parameter of type Field)
>> is of the form Fraction(something) and if so, extract 
>>"something" (that is,
>> assign it to a variable and further test it), sort of a 
>>deconstruction?
>
>William --
>
>    In OpenAxiom, when you get a domain, you can reify 
>it, and
>ask for the arguments that were used to instantiate it:
>
>(1) -> reify Fraction Integer
>    (1)  Fraction Integer
>                                       Type: 
>ConstructorCall DomainConstructor
>(2) -> arguments reify Fraction Integer
>    (2)  [(Integer)]
>                                                           
>  Type: List Syntax

\start
Date: Tue, 10 Nov 2009 12:00:58 -0500
From: William Sit
To: list
Subject: Re: pointers
Cc: Bertfried Fauser

Tim:

Sorry about the last message, please ignore.
The problem is solved (I was simply not being careful) and 
made some false claims on the results.

(16) -> )clear all
    All user variables and function definitions have been 
cleared.
(1) -> a:=FiniteField(5,2)

    (1)  FiniteField(5,2)
                                                            
      Type: Domain
(2) -> b:=devaluate(a)$Lisp

    (2)  (FiniteField 5 2)
                                                            
 Type: SExpression
(3) -> c:=destruct(b)

    (3)  [FiniteField,5,2]
                                                        Type: 
List SExpression
(4) -> c.1

    (4)  FiniteField
                                                            
 Type: SExpression
(5) -> d:="Fraction"::SExpression

    (5)  Fraction
                                                            
 Type: SExpression
(6) -> e:Boolean
                                                            
        Type: Void
(7) -> e:=EQ(c.1,d)$Lisp

    (7) ()
                                                     Type: 
SExpression
(7) -> e:=(c.1=Fraction) -- message above

    Although Fraction is the name of a constructor, a full 
type must be
       specified in the context you have used it. Issue 
)show Fraction
       for more information.
(7) -> e:= (c.1=d$Lisp)

    >> System error:
    The variable |d| is unbound.

protected-symbol-warn called with (NIL)
(7) -> a1:=Fraction Integer

    (7)  Fraction Integer
                                                            
      Type: Domain
(8) -> b1:=devaluate(a1)$Lisp

    (8)  (Fraction (Integer))
                                                            
 Type: SExpression
(9) -> c1:=destruct(b1)

    (9)  [Fraction,(Integer)]
                                                        Type: 
List SExpression
(10) -> e:=(c.1=c1.1)

    (10)  false
                                                            
     Type: Boolean

William
----

On Tue, 10 Nov 2009 11:38:25 -0500
  William Sit wrote:
>Thanks, Tim. That is exactly what I am looking for. Now I 
>would like to compare c.1 with some known constructor, 
>say Fraction. (In other words, given a domain of category 
>Field, I would like to know if it comes from the 
>constructor Fraction). I tried a few variations and each 
>time, Axiom says:
>
>Although Fraction is the name of a constructor, a full 
>type must be specified in the context you have used it. 
>Issue )show Fraction for more information.
>
>Things I tried:
>
>a:=FiniteField(5,2)
>b:=devaluate(a)$Lisp
>c:=destruct(b)
>c.1
>d:="Fraction"::SExpression
>e:Boolean
>e:=EQ(c.1,d)  -- message above
>e:=(c.1=Fraction)  -- message above
>e:= (c.1=d$Lisp) -- message above
>a1:=Fraction Integer
>b1:=devaluate(a1)$Lisp
>c1:=destruct(b1)
>e:=(c.1=c1.1) -- message above
>
>I confess that I'm still using a very old Window version 
>(Version of Tuesday November 30, 2004 at 21:11:14) but I 
>don't think that makes a difference in these examples.
>
>William
>
>On Mon, 09 Nov 2009 21:24:48 -0500
>  Tim Daly wrote:
>>I'm not sure what you want. Perhaps you'd like to say:
>>
>>a:=Fraction(Polynomial(Integer))
>>b:=devaluate(a)$Lisp
>>
>>which returns the list (actually of type SExpression)
>>
>>(Fraction (Polynomial (Integer)))
>>
>>c:=destruct(b)
>>c.2
>>
>>which returns (Polynomial (Integer))
>>
>>Does that help?
>>
>>Tim
>>
>>
>>William Sit wrote:
>>>Tim:
>>>
>>>Interesting. Is there a similar function that is more 
>>>structural? say, can I test whether some domain (which 
>>>may be passed as a parameter of type Field) is of the 
>>>form Fraction(something) and if so, extract "something" 
>>>(that is, assign it to a variable and further test it), 
>>>sort of a deconstruction?
>>>
>>>William
>>>
>>>On Mon, 09 Nov 2009 19:51:45 -0500
>>>Tim Daly wrote:
>>>>You can get a memory pointer to a lisp object.
>>>>
>>>>a:=Fraction(Integer)
>>>>
>>>>returns the "memory location of Fraction(Integer)"
>>>>You can prove this with
>>>>
>>>>b:=Fraction(Integer)
>>>>EQ(a,b)$Lisp
>>>>
>>>>The lisp function EQ compares memory pointers.
>>>>
>>>>There is a lisp function to get the hash value of any 
>>>>object
>>>>call sxhash. You can call it.
>>>>
>>>>SXHASH(a)$Lisp
>>>>
>>>>Note that if
>>>>
>>>>c:=Integer
>>>>
>>>>then
>>>>EQ(a,c)$Lisp is false
>>>>SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>>>>
>>>>Thus the hash function you seek already exists.
>>>>You just have to accept the fact that Spad is only 
>>>>syntactic
>>>>sugar for lisp code and lisp is not evil.

\start
Date: Tue, 10 Nov 2009 12:22:51 -0500
From: William Sit
To: list
Subject: Re: pointers
Cc: Bertfried Fauser

It appears that to test the constructor, one must test a 
candidate against a known one via the constructor itself, 
and not be "fiat" by using a SExpression. Is this related 
to hashing of pointers? Continuing with script in the 
previous email (attached):

(11) -> EQ(c.1,d)$Lisp

    (11)  ()
                                                            
 Type: SExpression
(12) -> EQ(c1.1,d)$Lisp

    (12)  ()

Type: SExpression
-- So EQ$Lisp returns () in both cases, even for 
-- EQ(c.1,c1.1)$Lisp

-- (19)  ()
                                                            
 --Type: SExpression
                                                            
 
(13) -> e:=(c.1=d)

    (13)  false
                                                            
     Type: Boolean

(14) -> e:=(c1.1=d)

    (14)  false
                                                            
    Type: Boolean
-- same problem with = using SExpression. 

15) -> e:=(c1.1=c1.1)

    (15)  true
                                                            
     Type: Boolean
(16) -> d

    (16)  Fraction
                                                            
 Type: SExpression
(17) -> c1.1

    (17)  Fraction
                                                            
 Type: SExpression

So it seems there is some distinction: d (defined 
explicitly as Fraction::SExpression) is different from 
c1.1 defined using devaluate/destruct from a domain. A 
user should not need to know the various way "equal" is 
tested if the two arguments for "equal" come from the same 
domain SExpression. So is this a bug?

William

On Tue, 10 Nov 2009 12:00:58 -0500
  William Sit wrote:
>Tim:
>
>Sorry about the last message, please ignore.
>The problem is solved (I was simply not being careful) 
>and made some false claims on the results.
>
>(16) -> )clear all
>    All user variables and function definitions have been 
>cleared.
>(1) -> a:=FiniteField(5,2)
>
>    (1)  FiniteField(5,2)
>                                                           
> 
>      Type: Domain
>(2) -> b:=devaluate(a)$Lisp
>
>    (2)  (FiniteField 5 2)
>                                                           
> 
>  Type: SExpression
>(3) -> c:=destruct(b)
>
>    (3)  [FiniteField,5,2]
>                                                        Type: 
>List SExpression
>(4) -> c.1
>
>    (4)  FiniteField
>                                                           
> 
>  Type: SExpression
>(5) -> d:="Fraction"::SExpression
>
>    (5)  Fraction
>                                                           
> 
>  Type: SExpression
>(6) -> e:Boolean
>                                                           
> 
>        Type: Void
>(7) -> e:=EQ(c.1,d)$Lisp
>
>    (7) ()
>                                                     Type: 
>SExpression
>(7) -> e:=(c.1=Fraction) -- message above
>
>    Although Fraction is the name of a constructor, a 
>full 
>type must be
>       specified in the context you have used it. Issue 
>)show Fraction
>       for more information.
>(7) -> e:= (c.1=d$Lisp)
>
>    >> System error:
>    The variable |d| is unbound.
>
>protected-symbol-warn called with (NIL)
>(7) -> a1:=Fraction Integer
>
>    (7)  Fraction Integer
>                                                           
> 
>      Type: Domain
>(8) -> b1:=devaluate(a1)$Lisp
>
>    (8)  (Fraction (Integer))
>                                                           
> 
>  Type: SExpression
>(9) -> c1:=destruct(b1)
>
>    (9)  [Fraction,(Integer)]
>                                                        Type: 
>List SExpression
>(10) -> e:=(c.1=c1.1)
>
>    (10)  false
>                                                           
> 
>     Type: Boolean
>
>William
>----
>
>On Tue, 10 Nov 2009 11:38:25 -0500
>  William Sit wrote:
>>Thanks, Tim. That is exactly what I am looking for. Now I 
>>would like to compare c.1 with some known constructor, 
>>say Fraction. (In other words, given a domain of category 
>>Field, I would like to know if it comes from the 
>>constructor Fraction). I tried a few variations and each 
>>time, Axiom says:
>>
>>Although Fraction is the name of a constructor, a full 
>>type must be specified in the context you have used it. 
>>Issue )show Fraction for more information.
>>
>>Things I tried:
>>
>>a:=FiniteField(5,2)
>>b:=devaluate(a)$Lisp
>>c:=destruct(b)
>>c.1
>>d:="Fraction"::SExpression
>>e:Boolean
>>e:=EQ(c.1,d)  -- message above
>>e:=(c.1=Fraction)  -- message above
>>e:= (c.1=d$Lisp) -- message above
>>a1:=Fraction Integer
>>b1:=devaluate(a1)$Lisp
>>c1:=destruct(b1)
>>e:=(c.1=c1.1) -- message above
>>
>>I confess that I'm still using a very old Window version 
>>(Version of Tuesday November 30, 2004 at 21:11:14) but I 
>>don't think that makes a difference in these examples.
>>
>>William
>>
>>On Mon, 09 Nov 2009 21:24:48 -0500
>> Tim Daly wrote:
>>>I'm not sure what you want. Perhaps you'd like to say:
>>>
>>>a:=Fraction(Polynomial(Integer))
>>>b:=devaluate(a)$Lisp
>>>
>>>which returns the list (actually of type SExpression)
>>>
>>>(Fraction (Polynomial (Integer)))
>>>
>>>c:=destruct(b)
>>>c.2
>>>
>>>which returns (Polynomial (Integer))
>>>
>>>Does that help?
>>>
>>>Tim
>>>
>>>
>>>William Sit wrote:
>>>>Tim:
>>>>
>>>>Interesting. Is there a similar function that is more 
>>>>structural? say, can I test whether some domain (which 
>>>>may be passed as a parameter of type Field) is of the 
>>>>form Fraction(something) and if so, extract "something" 
>>>>(that is, assign it to a variable and further test it), 
>>>>sort of a deconstruction?
>>>>
>>>>William
>>>>
>>>>On Mon, 09 Nov 2009 19:51:45 -0500
>>>>Tim Daly wrote:
>>>>>You can get a memory pointer to a lisp object.
>>>>>
>>>>>a:=Fraction(Integer)
>>>>>
>>>>>returns the "memory location of Fraction(Integer)"
>>>>>You can prove this with
>>>>>
>>>>>b:=Fraction(Integer)
>>>>>EQ(a,b)$Lisp
>>>>>
>>>>>The lisp function EQ compares memory pointers.
>>>>>
>>>>>There is a lisp function to get the hash value of any 
>>>>>object
>>>>>call sxhash. You can call it.
>>>>>
>>>>>SXHASH(a)$Lisp
>>>>>
>>>>>Note that if
>>>>>
>>>>>c:=Integer
>>>>>
>>>>>then
>>>>>EQ(a,c)$Lisp is false
>>>>>SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>>>>>
>>>>>Thus the hash function you seek already exists.
>>>>>You just have to accept the fact that Spad is only 
>>>>>syntactic
>>>>>sugar for lisp code and lisp is not evil.

\start
Date: Tue, 10 Nov 2009 12:49:17 -0500
From: Tim Daly
To: William Sit
Subject: Re: pointers
Cc: Bertfried Fauser

I'm not sure what you are asking. Are you having trouble with working in 
the SExpression domain?
You can move the SExpressions out to other domains. Sometimes it is 
painful but it works. So:

a:=FiniteField(5,2)
b:=devaluate(a)
string(SYMBOL_-NAME(b.1)$Lisp) ==> "FiniteField" (of type String)
integer(b.1) ==> 5  (of type PositiveInteger)

Does this help?

William Sit wrote:
> It appears that to test the constructor, one must test a candidate 
> against a known one via the constructor itself, and not be "fiat" by 
> using a SExpression. Is this related to hashing of pointers? 
> Continuing with script in the previous email (attached):
>
> (11) -> EQ(c.1,d)$Lisp
>
>    (11)  ()
>                                                            Type: 
> SExpression
> (12) -> EQ(c1.1,d)$Lisp
>
>    (12)  ()
>
> Type: SExpression
> -- So EQ$Lisp returns () in both cases, even for -- EQ(c.1,c1.1)$Lisp
>
> -- (19)  ()
>                                                            --Type: 
> SExpression
>                                                           
> (13) -> e:=(c.1=d)
>
>    (13)  false
>                                                                Type: 
> Boolean
>
> (14) -> e:=(c1.1=d)
>
>    (14)  false
>                                                               Type: 
> Boolean
> -- same problem with = using SExpression.
> 15) -> e:=(c1.1=c1.1)
>
>    (15)  true
>                                                                Type: 
> Boolean
> (16) -> d
>
>    (16)  Fraction
>                                                            Type: 
> SExpression
> (17) -> c1.1
>
>    (17)  Fraction
>                                                            Type: 
> SExpression
>
> So it seems there is some distinction: d (defined explicitly as 
> Fraction::SExpression) is different from c1.1 defined using 
> devaluate/destruct from a domain. A user should not need to know the 
> various way "equal" is tested if the two arguments for "equal" come 
> from the same domain SExpression. So is this a bug?
>
> William
>
> On Tue, 10 Nov 2009 12:00:58 -0500
>  William Sit wrote:
>> Tim:
>>
>> Sorry about the last message, please ignore.
>> The problem is solved (I was simply not being careful) and made some 
>> false claims on the results.
>>
>> (16) -> )clear all
>>    All user variables and function definitions have been cleared.
>> (1) -> a:=FiniteField(5,2)
>>
>>    (1)  FiniteField(5,2)
>>                                                          
>>      Type: Domain
>> (2) -> b:=devaluate(a)$Lisp
>>
>>    (2)  (FiniteField 5 2)
>>                                                          
>>  Type: SExpression
>> (3) -> c:=destruct(b)
>>
>>    (3)  [FiniteField,5,2]
>>                                                        Type: List 
>> SExpression
>> (4) -> c.1
>>
>>    (4)  FiniteField
>>                                                          
>>  Type: SExpression
>> (5) -> d:="Fraction"::SExpression
>>
>>    (5)  Fraction
>>                                                          
>>  Type: SExpression
>> (6) -> e:Boolean
>>                                                          
>>        Type: Void
>> (7) -> e:=EQ(c.1,d)$Lisp
>>
>>    (7) ()
>>                                                     Type: SExpression
>> (7) -> e:=(c.1=Fraction) -- message above
>>
>>    Although Fraction is the name of a constructor, a full type must be
>>       specified in the context you have used it. Issue )show Fraction
>>       for more information.
>> (7) -> e:= (c.1=d$Lisp)
>>
>>    >> System error:
>>    The variable |d| is unbound.
>>
>> protected-symbol-warn called with (NIL)
>> (7) -> a1:=Fraction Integer
>>
>>    (7)  Fraction Integer
>>                                                          
>>      Type: Domain
>> (8) -> b1:=devaluate(a1)$Lisp
>>
>>    (8)  (Fraction (Integer))
>>                                                          
>>  Type: SExpression
>> (9) -> c1:=destruct(b1)
>>
>>    (9)  [Fraction,(Integer)]
>>                                                        Type: List 
>> SExpression
>> (10) -> e:=(c.1=c1.1)
>>
>>    (10)  false
>>                                                          
>>     Type: Boolean
>>
>> William
>> ----
>>
>> On Tue, 10 Nov 2009 11:38:25 -0500
>>  William Sit wrote:
>>> Thanks, Tim. That is exactly what I am looking for. Now I would like 
>>> to compare c.1 with some known constructor, say Fraction. (In other 
>>> words, given a domain of category Field, I would like to know if it 
>>> comes from the constructor Fraction). I tried a few variations and 
>>> each time, Axiom says:
>>>
>>> Although Fraction is the name of a constructor, a full type must be 
>>> specified in the context you have used it. Issue )show Fraction for 
>>> more information.
>>>
>>> Things I tried:
>>>
>>> a:=FiniteField(5,2)
>>> b:=devaluate(a)$Lisp
>>> c:=destruct(b)
>>> c.1
>>> d:="Fraction"::SExpression
>>> e:Boolean
>>> e:=EQ(c.1,d)  -- message above
>>> e:=(c.1=Fraction)  -- message above
>>> e:= (c.1=d$Lisp) -- message above
>>> a1:=Fraction Integer
>>> b1:=devaluate(a1)$Lisp
>>> c1:=destruct(b1)
>>> e:=(c.1=c1.1) -- message above
>>>
>>> I confess that I'm still using a very old Window version (Version of 
>>> Tuesday November 30, 2004 at 21:11:14) but I don't think that makes 
>>> a difference in these examples.
>>>
>>> William
>>>
>>> On Mon, 09 Nov 2009 21:24:48 -0500
>>> Tim Daly wrote:
>>>> I'm not sure what you want. Perhaps you'd like to say:
>>>>
>>>> a:=Fraction(Polynomial(Integer))
>>>> b:=devaluate(a)$Lisp
>>>>
>>>> which returns the list (actually of type SExpression)
>>>>
>>>> (Fraction (Polynomial (Integer)))
>>>>
>>>> c:=destruct(b)
>>>> c.2
>>>>
>>>> which returns (Polynomial (Integer))
>>>>
>>>> Does that help?
>>>>
>>>> Tim
>>>>
>>>>
>>>> William Sit wrote:
>>>>> Tim:
>>>>>
>>>>> Interesting. Is there a similar function that is more structural? 
>>>>> say, can I test whether some domain (which may be passed as a 
>>>>> parameter of type Field) is of the form Fraction(something) and if 
>>>>> so, extract "something" (that is, assign it to a variable and 
>>>>> further test it), sort of a deconstruction?
>>>>>
>>>>> William
>>>>>
>>>>> On Mon, 09 Nov 2009 19:51:45 -0500
>>>>> Tim Daly wrote:
>>>>>> You can get a memory pointer to a lisp object.
>>>>>>
>>>>>> a:=Fraction(Integer)
>>>>>>
>>>>>> returns the "memory location of Fraction(Integer)"
>>>>>> You can prove this with
>>>>>>
>>>>>> b:=Fraction(Integer)
>>>>>> EQ(a,b)$Lisp
>>>>>>
>>>>>> The lisp function EQ compares memory pointers.
>>>>>>
>>>>>> There is a lisp function to get the hash value of any object
>>>>>> call sxhash. You can call it.
>>>>>>
>>>>>> SXHASH(a)$Lisp
>>>>>>
>>>>>> Note that if
>>>>>>
>>>>>> c:=Integer
>>>>>>
>>>>>> then
>>>>>> EQ(a,c)$Lisp is false
>>>>>> SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>>>>>>
>>>>>> Thus the hash function you seek already exists.
>>>>>> You just have to accept the fact that Spad is only syntactic
>>>>>> sugar for lisp code and lisp is not evil.

\start
Date: Tue, 10 Nov 2009 19:21:17 +0100 (CET)
From: Waldek Hebisch
To: list
Subject: Re: pointers

William Sit wrote:
> Gabriel:
> 
> Thanks for the response. Your script shows how to get the 
> parameters, not the constructor. I do not have OpenAxiom 
> installed (sorry). The question is whether I can test that 
> the constructor is Fraction, or otherwise (like 
> FiniteField) when the domain belongs to the category 
> Field.
>

Do you want something like this?

(10) -> a := Fraction(Integer)

   (10)  Fraction Integer
                                                                 Type: Domain
(11) -> (opOf(devaluate(a)$Lisp)$Lisp = 'Fraction::SEX)@Boolean

   (11)  true
                                                                Type: Boolean
(12) -> (opOf(devaluate(a)$Lisp)$Lisp = 'FiniteField::SEX)@Boolean

   (12)  false
                                                                Type: Boolean
(13) -> a :=FiniteField(5,2)

   (13)  FiniteField(5,2)
                                                                 Type: Domain
(14) -> (opOf(devaluate(a)$Lisp)$Lisp = 'Fraction::SEX)@Boolean

   (14)  false
                                                                Type: Boolean
(15) -> (opOf(devaluate(a)$Lisp)$Lisp = 'FiniteField::SEX)@Boolean

   (15)  true
                                                                Type: Boolean

\start
Date: Tue, 10 Nov 2009 14:37:17 -0500
From: William Sit
To: Waldek Hebisch
Subject: Re: pointers

Hi Waldek:

Thanks. That is exactly what I want. Good solution. So the
"trick" is to use ' instead of the string. So is the
following a bug?

a:='Fraction::SEX
  Fraction  Type:SExpression
b:="Fraction"::SEX
  Fraction  Type:SExpression
(a=b)@Boolean
  false     Type Boolean

That is, I was deceived by the output which looked the same.
Perhaps the output should have been ('Fraction) and
("Fraction") ??

Also,

destruct(a) or destruct(b) leads to an Error:

 Function Selection for destruct
      Arguments: SEX

 [1]  signature:   SEX -> LIST SEX
      implemented: slot (List $)$ from SEX


   >> Error detected within library code:
   Non-list

protected-symbol-warn called with (NIL)

William


Waldek Hebisch wrote:
> 
> William Sit wrote:
> > Gabriel:
> >
> > Thanks for the response. Your script shows how to get the
> > parameters, not the constructor. I do not have OpenAxiom
> > installed (sorry). The question is whether I can test that
> > the constructor is Fraction, or otherwise (like
> > FiniteField) when the domain belongs to the category
> > Field.
> >
> 
> Do you want something like this?
> 
> (10) -> a := Fraction(Integer)
> 
>    (10)  Fraction Integer
>                                                                  Type: Domain
> (11) -> (opOf(devaluate(a)$Lisp)$Lisp = 'Fraction::SEX)@Boolean
> 
>    (11)  true
>                                                                 Type: Boolean
> (12) -> (opOf(devaluate(a)$Lisp)$Lisp = 'FiniteField::SEX)@Boolean
> 
>    (12)  false
>                                                                 Type: Boolean
> (13) -> a :=FiniteField(5,2)
> 
>    (13)  FiniteField(5,2)
>                                                                  Type: Domain
> (14) -> (opOf(devaluate(a)$Lisp)$Lisp = 'Fraction::SEX)@Boolean
> 
>    (14)  false
>                                                                 Type: Boolean
> (15) -> (opOf(devaluate(a)$Lisp)$Lisp = 'FiniteField::SEX)@Boolean
> 
>    (15)  true
>                                                                 Type: Boolean
> 

\start
Date: Tue, 10 Nov 2009 14:48:03 -0500
From: Tim Daly
To: William Sit
Subject: Re: pointers

a:='Fraction::SEX

is a lisp symbol. A lisp symbol is essentially the address of a data 
structure
which is approximately
    struct
       symbol-function (pointer to code)
       symbol-name (a string representation of the symbol)
       symbol-package (the lisp package (a hash table pointer))
       symbol-value (the value of the symbol)
       symbol-plist (an association list hanging on the symbol)

a:="Fraction"::Sex

is a lisp string, a contiguous set of bytes containing character code

So
a:=SYMBOL_-NAME('Fraction::SEX)$Lisp       (get the symbol-name from the 
fraction struct)
b:="Fraction"::SEX                                               (make a 
string of bytes containing "Fraction")
EQ(a,b)$Lisp ==> ()                                            (are they 
the same storage location? no)
c:=STRING_-EQUAL(a,b)$Lisp ==> T              (are they the same 
sequence of bytes? yes)

William Sit wrote:
> Hi Waldek:
>
> Thanks. That is exactly what I want. Good solution. So the
> "trick" is to use ' instead of the string. So is the
> following a bug?
>
> a:='Fraction::SEX
>   Fraction  Type:SExpression
> b:="Fraction"::SEX
>   Fraction  Type:SExpression
> (a=b)@Boolean
>   false     Type Boolean
>
> That is, I was deceived by the output which looked the same.
> Perhaps the output should have been ('Fraction) and
> ("Fraction") ??
>
> Also,
>
> destruct(a) or destruct(b) leads to an Error:
>
>  Function Selection for destruct
>       Arguments: SEX
>
>  [1]  signature:   SEX -> LIST SEX
>       implemented: slot (List $)$ from SEX
>
>
>    >> Error detected within library code:
>    Non-list
>
> protected-symbol-warn called with (NIL)
>
> William
>
>
> Waldek Hebisch wrote:
>   
>> William Sit wrote:
>>     
>>> Gabriel:
>>>
>>> Thanks for the response. Your script shows how to get the
>>> parameters, not the constructor. I do not have OpenAxiom
>>> installed (sorry). The question is whether I can test that
>>> the constructor is Fraction, or otherwise (like
>>> FiniteField) when the domain belongs to the category
>>> Field.
>>>
>>>       
>> Do you want something like this?
>>
>> (10) -> a := Fraction(Integer)
>>
>>    (10)  Fraction Integer
>>                                                                  Type: Domain
>> (11) -> (opOf(devaluate(a)$Lisp)$Lisp = 'Fraction::SEX)@Boolean
>>
>>    (11)  true
>>                                                                 Type: Boolean
>> (12) -> (opOf(devaluate(a)$Lisp)$Lisp = 'FiniteField::SEX)@Boolean
>>
>>    (12)  false
>>                                                                 Type: Boolean
>> (13) -> a :=FiniteField(5,2)
>>
>>    (13)  FiniteField(5,2)
>>                                                                  Type: Domain
>> (14) -> (opOf(devaluate(a)$Lisp)$Lisp = 'Fraction::SEX)@Boolean
>>
>>    (14)  false
>>                                                                 Type: Boolean
>> (15) -> (opOf(devaluate(a)$Lisp)$Lisp = 'FiniteField::SEX)@Boolean
>>
>>    (15)  true
>>                                                                 Type: Boolean

\start
Date: Tue, 10 Nov 2009 15:12:39 -0500
From: William Sit
To: Tim Daly
Subject: Re: pointers//Decontructing domains
Cc: Bertfried Fauser

Thanks, your method works. For me at least, it is much
easier to handle strings than SExpression.

Waldek also provided a working method using opOf (but that
involves SExpression, and the output in SExpression can be
misleading), which is perhaps a bug (see my reply to
Waldek).

To summarize:
It is possible to deconstruct a domain (that is, trace its
constructor and the parameters to that constructor) using
Lisp primitives. Given an identifier whose value at turn
time is an Axiom domain, the function devaluate$Lisp returns
its value as an SExpression, and the function deconstrut
further turns the result into a list of SExpressions (which
may be useful to extract the first level of parameters, but
not necessary). The components can then be analyzed.
However, testing for equality of SExpressions can be
hazardous when the SExpressions are constructed in different
ways but the outputForms look identical. There are (at
least?) two ways to get around the problem. Assume we have
a, b defined below (but the value of the identifier a is not
really assumed known at compile time):

a:=Fraction Integer
b:=devaluate(a)$Lisp
  (Fraction (Integer))   Type SExpression

(1) (Waldek): use opOF to pick out the constructor of the
domain and test against a candidate using a quote expression
in Lisp coerced to an SExpression:

testW:='Fraction::SEX
c:=opOf(b)$Lisp
(c=testW)@Boolean

(2) (Tim): use a Lisp function SYMBOL_-NAME and then convert
the result into a string before testing:

testT:="Fraction"
c:=string(SYMBOL_-NAME(b.1)$Lisp)
(c=testT)@Boolean

In either method, do not set testW or testT to
"Fraction"::SEX, which would not test correctly.


William

Tim Daly wrote:
> 
> I'm not sure what you are asking. Are you having trouble with working in
> the SExpression domain?
> You can move the SExpressions out to other domains. Sometimes it is
> painful but it works. So:
> 
> a:=FiniteField(5,2)
> b:=devaluate(a)
> string(SYMBOL_-NAME(b.1)$Lisp) ==> "FiniteField" (of type String)
> integer(b.1) ==> 5  (of type PositiveInteger)
> 
> Does this help?
> 
> Tim
> 
> William Sit wrote:
> > It appears that to test the constructor, one must test a candidate
> > against a known one via the constructor itself, and not be "fiat" by
> > using a SExpression. Is this related to hashing of pointers?
> > Continuing with script in the previous email (attached):
> >
> > (11) -> EQ(c.1,d)$Lisp
> >
> >    (11)  ()
> >                                                            Type:
> > SExpression
> > (12) -> EQ(c1.1,d)$Lisp
> >
> >    (12)  ()
> >
> > Type: SExpression
> > -- So EQ$Lisp returns () in both cases, even for -- EQ(c.1,c1.1)$Lisp
> >
> > -- (19)  ()
> >                                                            --Type:
> > SExpression
> >
> > (13) -> e:=(c.1=d)
> >
> >    (13)  false
> >                                                                Type:
> > Boolean
> >
> > (14) -> e:=(c1.1=d)
> >
> >    (14)  false
> >                                                               Type:
> > Boolean
> > -- same problem with = using SExpression.
> > 15) -> e:=(c1.1=c1.1)
> >
> >    (15)  true
> >                                                                Type:
> > Boolean
> > (16) -> d
> >
> >    (16)  Fraction
> >                                                            Type:
> > SExpression
> > (17) -> c1.1
> >
> >    (17)  Fraction
> >                                                            Type:
> > SExpression
> >
> > So it seems there is some distinction: d (defined explicitly as
> > Fraction::SExpression) is different from c1.1 defined using
> > devaluate/destruct from a domain. A user should not need to know the
> > various way "equal" is tested if the two arguments for "equal" come
> > from the same domain SExpression. So is this a bug?
> >
> > William
> >
> > On Tue, 10 Nov 2009 12:00:58 -0500
> >  William Sit wrote:
> >> Tim:
> >>
> >> Sorry about the last message, please ignore.
> >> The problem is solved (I was simply not being careful) and made some
> >> false claims on the results.
> >>
> >> (16) -> )clear all
> >>    All user variables and function definitions have been cleared.
> >> (1) -> a:=FiniteField(5,2)
> >>
> >>    (1)  FiniteField(5,2)
> >>
> >>      Type: Domain
> >> (2) -> b:=devaluate(a)$Lisp
> >>
> >>    (2)  (FiniteField 5 2)
> >>
> >>  Type: SExpression
> >> (3) -> c:=destruct(b)
> >>
> >>    (3)  [FiniteField,5,2]
> >>                                                        Type: List
> >> SExpression
> >> (4) -> c.1
> >>
> >>    (4)  FiniteField
> >>
> >>  Type: SExpression
> >> (5) -> d:="Fraction"::SExpression
> >>
> >>    (5)  Fraction
> >>
> >>  Type: SExpression
> >> (6) -> e:Boolean
> >>
> >>        Type: Void
> >> (7) -> e:=EQ(c.1,d)$Lisp
> >>
> >>    (7) ()
> >>                                                     Type: SExpression
> >> (7) -> e:=(c.1=Fraction) -- message above
> >>
> >>    Although Fraction is the name of a constructor, a full type must be
> >>       specified in the context you have used it. Issue )show Fraction
> >>       for more information.
> >> (7) -> e:= (c.1=d$Lisp)
> >>
> >>    >> System error:
> >>    The variable |d| is unbound.
> >>
> >> protected-symbol-warn called with (NIL)
> >> (7) -> a1:=Fraction Integer
> >>
> >>    (7)  Fraction Integer
> >>
> >>      Type: Domain
> >> (8) -> b1:=devaluate(a1)$Lisp
> >>
> >>    (8)  (Fraction (Integer))
> >>
> >>  Type: SExpression
> >> (9) -> c1:=destruct(b1)
> >>
> >>    (9)  [Fraction,(Integer)]
> >>                                                        Type: List
> >> SExpression
> >> (10) -> e:=(c.1=c1.1)
> >>
> >>    (10)  false
> >>
> >>     Type: Boolean
> >>
> >> William
> >> ----
> >>
> >> On Tue, 10 Nov 2009 11:38:25 -0500
> >>  William Sit wrote:
> >>> Thanks, Tim. That is exactly what I am looking for. Now I would like
> >>> to compare c.1 with some known constructor, say Fraction. (In other
> >>> words, given a domain of category Field, I would like to know if it
> >>> comes from the constructor Fraction). I tried a few variations and
> >>> each time, Axiom says:
> >>>
> >>> Although Fraction is the name of a constructor, a full type must be
> >>> specified in the context you have used it. Issue )show Fraction for
> >>> more information.
> >>>
> >>> Things I tried:
> >>>
> >>> a:=FiniteField(5,2)
> >>> b:=devaluate(a)$Lisp
> >>> c:=destruct(b)
> >>> c.1
> >>> d:="Fraction"::SExpression
> >>> e:Boolean
> >>> e:=EQ(c.1,d)  -- message above
> >>> e:=(c.1=Fraction)  -- message above
> >>> e:= (c.1=d$Lisp) -- message above
> >>> a1:=Fraction Integer
> >>> b1:=devaluate(a1)$Lisp
> >>> c1:=destruct(b1)
> >>> e:=(c.1=c1.1) -- message above
> >>>
> >>> I confess that I'm still using a very old Window version (Version of
> >>> Tuesday November 30, 2004 at 21:11:14) but I don't think that makes
> >>> a difference in these examples.
> >>>
> >>> William
> >>>
> >>> On Mon, 09 Nov 2009 21:24:48 -0500
> >>> Tim Daly wrote:
> >>>> I'm not sure what you want. Perhaps you'd like to say:
> >>>>
> >>>> a:=Fraction(Polynomial(Integer))
> >>>> b:=devaluate(a)$Lisp
> >>>>
> >>>> which returns the list (actually of type SExpression)
> >>>>
> >>>> (Fraction (Polynomial (Integer)))
> >>>>
> >>>> c:=destruct(b)
> >>>> c.2
> >>>>
> >>>> which returns (Polynomial (Integer))
> >>>>
> >>>> Does that help?
> >>>>
> >>>> Tim
> >>>>
> >>>>
> >>>> William Sit wrote:
> >>>>> Tim:
> >>>>>
> >>>>> Interesting. Is there a similar function that is more structural?
> >>>>> say, can I test whether some domain (which may be passed as a
> >>>>> parameter of type Field) is of the form Fraction(something) and if
> >>>>> so, extract "something" (that is, assign it to a variable and
> >>>>> further test it), sort of a deconstruction?
> >>>>>
> >>>>> William
> >>>>>
> >>>>> On Mon, 09 Nov 2009 19:51:45 -0500
> >>>>> Tim Daly wrote:
> >>>>>> You can get a memory pointer to a lisp object.
> >>>>>>
> >>>>>> a:=Fraction(Integer)
> >>>>>>
> >>>>>> returns the "memory location of Fraction(Integer)"
> >>>>>> You can prove this with
> >>>>>>
> >>>>>> b:=Fraction(Integer)
> >>>>>> EQ(a,b)$Lisp
> >>>>>>
> >>>>>> The lisp function EQ compares memory pointers.
> >>>>>>
> >>>>>> There is a lisp function to get the hash value of any object
> >>>>>> call sxhash. You can call it.
> >>>>>>
> >>>>>> SXHASH(a)$Lisp
> >>>>>>
> >>>>>> Note that if
> >>>>>>
> >>>>>> c:=Integer
> >>>>>>
> >>>>>> then
> >>>>>> EQ(a,c)$Lisp is false
> >>>>>> SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
> >>>>>>
> >>>>>> Thus the hash function you seek already exists.
> >>>>>> You just have to accept the fact that Spad is only syntactic
> >>>>>> sugar for lisp code and lisp is not evil.

\start
Date: Tue, 10 Nov 2009 15:19:34 -0600
From: Gabriel Dos Reis
To: William Sit
Subject: Re: pointers
Cc: Bertfried Fauser

On Tue, Nov 10, 2009 at 10:45 AM, William Sit wrote:
> Gabriel:
>
> Thanks for the response. Your script shows how to get the parameters, not
> the constructor. I do not have OpenAxiom installed (sorry). The question is
> whether I can test that the constructor is Fraction, or otherwise (like
> FiniteField) when the domain belongs to the category Field.

You can get the constructors too

(1) -> constructor Fraction Integer

   (1)  Fraction
                                                      Type: DomainConstructor
(2) -> constructor Integer

   (2)  Integer
                                                      Type: DomainConstructor
(3) -> constructor Field

   (3)  Field
                                                    Type: CategoryConstructor


There is a prepackaged Windows binary for OpenAxiom from the download
area and it can co-exist with any other AXIOM flavour.

Category constructors and domain constructors satisfy SetCategory:

(4) -> DomainConstructor has SetCategory

   (4)  true
                                                                Type: Boolean
(5) -> CategoryConstructor has SetCategory

   (5)  true
                                                                Type: Boolean


so, you can use the equality comparator.


>
> I came across this requirement in algorithms that may take advantage of
> special knowledge of how the coefficient field is constructed.

\start
Date: Tue, 10 Nov 2009 15:25:08 -0600
From: Gabriel Dos Reis
To: William Sit
Subject: Re: pointers

On Tue, Nov 10, 2009 at 1:37 PM, William Sit wrote:
> Hi Waldek:
>
> Thanks. That is exactly what I want. Good solution. So the
> "trick" is to use ' instead of the string. So is the
> following a bug?

In OpenAxiom, you can get the name of a constructor as an Identifier:

(7) -> name constructor Fraction Integer

   (7)  Fraction
                                                             Type: Identifier
\start
Date: Tue, 10 Nov 2009 17:52:10 -0500
From: Tim Daly
To: William Sit
Subject: Re: pointers//Decontructing domains
Cc: Bertfried Fauser

Axiom now has an "API" (ApplicationProgramInterface) domain
(similar in spirit to Aldor's Builtin domain).
I will add devaluate to it.
I will also change the SExpression domain to export the symbol-*
functions from lisp with proper conversion functions.


William Sit wrote:
> Tim: 
>
> Thanks, your method works. For me at least, it is much
> easier to handle strings than SExpression.
>
> Waldek also provided a working method using opOf (but that
> involves SExpression, and the output in SExpression can be
> misleading), which is perhaps a bug (see my reply to
> Waldek).
>
> To summarize:
> It is possible to deconstruct a domain (that is, trace its
> constructor and the parameters to that constructor) using
> Lisp primitives. Given an identifier whose value at turn
> time is an Axiom domain, the function devaluate$Lisp returns
> its value as an SExpression, and the function deconstrut
> further turns the result into a list of SExpressions (which
> may be useful to extract the first level of parameters, but
> not necessary). The components can then be analyzed.
> However, testing for equality of SExpressions can be
> hazardous when the SExpressions are constructed in different
> ways but the outputForms look identical. There are (at
> least?) two ways to get around the problem. Assume we have
> a, b defined below (but the value of the identifier a is not
> really assumed known at compile time):
>
> a:=Fraction Integer
> b:=devaluate(a)$Lisp
>   (Fraction (Integer))   Type SExpression
>
> (1) (Waldek): use opOF to pick out the constructor of the
> domain and test against a candidate using a quote expression
> in Lisp coerced to an SExpression:
>
> testW:='Fraction::SEX
> c:=opOf(b)$Lisp
> (c=testW)@Boolean
>
> (2) (Tim): use a Lisp function SYMBOL_-NAME and then convert
> the result into a string before testing:
>
> testT:="Fraction"
> c:=string(SYMBOL_-NAME(b.1)$Lisp)
> (c=testT)@Boolean
>
> In either method, do not set testW or testT to
> "Fraction"::SEX, which would not test correctly.
>
>
> William
>
> Tim Daly wrote:
>   
>> I'm not sure what you are asking. Are you having trouble with working in
>> the SExpression domain?
>> You can move the SExpressions out to other domains. Sometimes it is
>> painful but it works. So:
>>
>> a:=FiniteField(5,2)
>> b:=devaluate(a)
>> string(SYMBOL_-NAME(b.1)$Lisp) ==> "FiniteField" (of type String)
>> integer(b.1) ==> 5  (of type PositiveInteger)
>>
>> Does this help?
>>
>> Tim
>>
>> William Sit wrote:
>>     
>>> It appears that to test the constructor, one must test a candidate
>>> against a known one via the constructor itself, and not be "fiat" by
>>> using a SExpression. Is this related to hashing of pointers?
>>> Continuing with script in the previous email (attached):
>>>
>>> (11) -> EQ(c.1,d)$Lisp
>>>
>>>    (11)  ()
>>>                                                            Type:
>>> SExpression
>>> (12) -> EQ(c1.1,d)$Lisp
>>>
>>>    (12)  ()
>>>
>>> Type: SExpression
>>> -- So EQ$Lisp returns () in both cases, even for -- EQ(c.1,c1.1)$Lisp
>>>
>>> -- (19)  ()
>>>                                                            --Type:
>>> SExpression
>>>
>>> (13) -> e:=(c.1=d)
>>>
>>>    (13)  false
>>>                                                                Type:
>>> Boolean
>>>
>>> (14) -> e:=(c1.1=d)
>>>
>>>    (14)  false
>>>                                                               Type:
>>> Boolean
>>> -- same problem with = using SExpression.
>>> 15) -> e:=(c1.1=c1.1)
>>>
>>>    (15)  true
>>>                                                                Type:
>>> Boolean
>>> (16) -> d
>>>
>>>    (16)  Fraction
>>>                                                            Type:
>>> SExpression
>>> (17) -> c1.1
>>>
>>>    (17)  Fraction
>>>                                                            Type:
>>> SExpression
>>>
>>> So it seems there is some distinction: d (defined explicitly as
>>> Fraction::SExpression) is different from c1.1 defined using
>>> devaluate/destruct from a domain. A user should not need to know the
>>> various way "equal" is tested if the two arguments for "equal" come
>>> from the same domain SExpression. So is this a bug?
>>>
>>> William
>>>
>>> On Tue, 10 Nov 2009 12:00:58 -0500
>>>  William Sit wrote:
>>>       
>>>> Tim:
>>>>
>>>> Sorry about the last message, please ignore.
>>>> The problem is solved (I was simply not being careful) and made some
>>>> false claims on the results.
>>>>
>>>> (16) -> )clear all
>>>>    All user variables and function definitions have been cleared.
>>>> (1) -> a:=FiniteField(5,2)
>>>>
>>>>    (1)  FiniteField(5,2)
>>>>
>>>>      Type: Domain
>>>> (2) -> b:=devaluate(a)$Lisp
>>>>
>>>>    (2)  (FiniteField 5 2)
>>>>
>>>>  Type: SExpression
>>>> (3) -> c:=destruct(b)
>>>>
>>>>    (3)  [FiniteField,5,2]
>>>>                                                        Type: List
>>>> SExpression
>>>> (4) -> c.1
>>>>
>>>>    (4)  FiniteField
>>>>
>>>>  Type: SExpression
>>>> (5) -> d:="Fraction"::SExpression
>>>>
>>>>    (5)  Fraction
>>>>
>>>>  Type: SExpression
>>>> (6) -> e:Boolean
>>>>
>>>>        Type: Void
>>>> (7) -> e:=EQ(c.1,d)$Lisp
>>>>
>>>>    (7) ()
>>>>                                                     Type: SExpression
>>>> (7) -> e:=(c.1=Fraction) -- message above
>>>>
>>>>    Although Fraction is the name of a constructor, a full type must be
>>>>       specified in the context you have used it. Issue )show Fraction
>>>>       for more information.
>>>> (7) -> e:= (c.1=d$Lisp)
>>>>
>>>>    >> System error:
>>>>    The variable |d| is unbound.
>>>>
>>>> protected-symbol-warn called with (NIL)
>>>> (7) -> a1:=Fraction Integer
>>>>
>>>>    (7)  Fraction Integer
>>>>
>>>>      Type: Domain
>>>> (8) -> b1:=devaluate(a1)$Lisp
>>>>
>>>>    (8)  (Fraction (Integer))
>>>>
>>>>  Type: SExpression
>>>> (9) -> c1:=destruct(b1)
>>>>
>>>>    (9)  [Fraction,(Integer)]
>>>>                                                        Type: List
>>>> SExpression
>>>> (10) -> e:=(c.1=c1.1)
>>>>
>>>>    (10)  false
>>>>
>>>>     Type: Boolean
>>>>
>>>> William
>>>> ----
>>>>
>>>> On Tue, 10 Nov 2009 11:38:25 -0500
>>>>  William Sit wrote:
>>>>         
>>>>> Thanks, Tim. That is exactly what I am looking for. Now I would like
>>>>> to compare c.1 with some known constructor, say Fraction. (In other
>>>>> words, given a domain of category Field, I would like to know if it
>>>>> comes from the constructor Fraction). I tried a few variations and
>>>>> each time, Axiom says:
>>>>>
>>>>> Although Fraction is the name of a constructor, a full type must be
>>>>> specified in the context you have used it. Issue )show Fraction for
>>>>> more information.
>>>>>
>>>>> Things I tried:
>>>>>
>>>>> a:=FiniteField(5,2)
>>>>> b:=devaluate(a)$Lisp
>>>>> c:=destruct(b)
>>>>> c.1
>>>>> d:="Fraction"::SExpression
>>>>> e:Boolean
>>>>> e:=EQ(c.1,d)  -- message above
>>>>> e:=(c.1=Fraction)  -- message above
>>>>> e:= (c.1=d$Lisp) -- message above
>>>>> a1:=Fraction Integer
>>>>> b1:=devaluate(a1)$Lisp
>>>>> c1:=destruct(b1)
>>>>> e:=(c.1=c1.1) -- message above
>>>>>
>>>>> I confess that I'm still using a very old Window version (Version of
>>>>> Tuesday November 30, 2004 at 21:11:14) but I don't think that makes
>>>>> a difference in these examples.
>>>>>
>>>>> William
>>>>>
>>>>> On Mon, 09 Nov 2009 21:24:48 -0500
>>>>> Tim Daly wrote:
>>>>>           
>>>>>> I'm not sure what you want. Perhaps you'd like to say:
>>>>>>
>>>>>> a:=Fraction(Polynomial(Integer))
>>>>>> b:=devaluate(a)$Lisp
>>>>>>
>>>>>> which returns the list (actually of type SExpression)
>>>>>>
>>>>>> (Fraction (Polynomial (Integer)))
>>>>>>
>>>>>> c:=destruct(b)
>>>>>> c.2
>>>>>>
>>>>>> which returns (Polynomial (Integer))
>>>>>>
>>>>>> Does that help?
>>>>>>
>>>>>> Tim
>>>>>>
>>>>>>
>>>>>> William Sit wrote:
>>>>>>             
>>>>>>> Tim:
>>>>>>>
>>>>>>> Interesting. Is there a similar function that is more structural?
>>>>>>> say, can I test whether some domain (which may be passed as a
>>>>>>> parameter of type Field) is of the form Fraction(something) and if
>>>>>>> so, extract "something" (that is, assign it to a variable and
>>>>>>> further test it), sort of a deconstruction?
>>>>>>>
>>>>>>> William
>>>>>>>
>>>>>>> On Mon, 09 Nov 2009 19:51:45 -0500
>>>>>>> Tim Daly wrote:
>>>>>>>               
>>>>>>>> You can get a memory pointer to a lisp object.
>>>>>>>>
>>>>>>>> a:=Fraction(Integer)
>>>>>>>>
>>>>>>>> returns the "memory location of Fraction(Integer)"
>>>>>>>> You can prove this with
>>>>>>>>
>>>>>>>> b:=Fraction(Integer)
>>>>>>>> EQ(a,b)$Lisp
>>>>>>>>
>>>>>>>> The lisp function EQ compares memory pointers.
>>>>>>>>
>>>>>>>> There is a lisp function to get the hash value of any object
>>>>>>>> call sxhash. You can call it.
>>>>>>>>
>>>>>>>> SXHASH(a)$Lisp
>>>>>>>>
>>>>>>>> Note that if
>>>>>>>>
>>>>>>>> c:=Integer
>>>>>>>>
>>>>>>>> then
>>>>>>>> EQ(a,c)$Lisp is false
>>>>>>>> SXHASH(a)$Lisp is not equal to SXHASH(c)$Lisp
>>>>>>>>
>>>>>>>> Thus the hash function you seek already exists.
>>>>>>>> You just have to accept the fact that Spad is only syntactic
>>>>>>>> sugar for lisp code and lisp is not evil.

\start
Date: Wed, 11 Nov 2009 02:09:38 -0500
From: William Sit
To: Gabriel Dos Reis
Subject: Re: pointers

Thanks again for all the help. I'll download the OpenAxiom 
version and try it.

William

On Tue, 10 Nov 2009 15:25:08 -0600
  Gabriel Dos Reis wrote:
>On Tue, Nov 10, 2009 at 1:37 PM, William Sit 
>William Sit wrote:
>> Hi Waldek:
>>
>> Thanks. That is exactly what I want. Good solution. So 
>>the
>> "trick" is to use ' instead of the string. So is the
>> following a bug?
>
>In OpenAxiom, you can get the name of a constructor as an 
>Identifier:
>
>(7) -> name constructor Fraction Integer
>
>    (7)  Fraction
>                                                           
>   Type: Identifier

\start
Date: Sun, 15 Nov 2009 13:56:45 -0500
From: Tim Daly
To: Bertfried Fauser
Subject: Function cache in Axiom

As I recall you were interested in creating a cache of values in Axiom.
I just remembered that you can do this dynamically with:

   )set functions cache

Sorry for the lag in remembering but my memory is still using
mercury delay lines and has long access times.

\start
Date: Sun, 15 Nov 2009 22:52:27 +0100 (CET)
From: Franz Lehner
To: Tim Daly
Subject: Re: Function cache in Axiom
Cc: Bertfried Fauser

On Sun, 15 Nov 2009, Tim Daly wrote:
> As I recall you were interested in creating a cache of values in Axiom.
> I just remembered that you can do this dynamically with:
>
>  )set functions cache
but that's only for interpreter functions if I understand correctly?

\start
Date: Sun, 15 Nov 2009 17:14:23 -0500
From: Tim Daly
To: Franz Lehner
Subject: Re: Function cache in Axiom
Cc: Bertfried Fauser

Franz Lehner wrote:
> On Sun, 15 Nov 2009, Tim Daly wrote:
>> As I recall you were interested in creating a cache of values in Axiom.
>> I just remembered that you can do this dynamically with:
>>
>>  )set functions cache
> but that's only for interpreter functions if I understand correctly?
>
> Franz
>
I don't see why it needs to be.
I'll read the code and see if it can be applied to algebra.

\start
Date: Sun, 15 Nov 2009 23:35:00 -0500
From: Tim Daly
To: list
Subject: Embedding Axiom

This is a request for design discussion for those who are interested.

I am rewriting Axiom into literate form. This involves understanding
Axiom in a very deep way. One of the insights of my current understanding
is that Axiom needs to be restructured internally.

I have to say that if you are not a lisp programmer most of this will
not make sense. If you are a lisp programmer it should be obvious.

For the non-lispers, a few comments are in order. As pointed out in
Structure and Interpretation of Computer Programs, a properly formed
lisp program "embeds" in lisp. When carefully designed, a lisp
program is not "on top of lisp", but the result is "just lisp".
That is, the new code is layered so that Spad becomes something like
a domain-specific language. If this does not seem like a deep
philosophical design issue then I highly recommend "On Lisp" by
Paul Graham.

The current state of Axiom internals is more like a history museum
than a robust layered design. There are code fragments dating back
to the late 60s along with clever research algorithms (for the time)
about zipper-parsing and CLU-capsules. There are maxima and vmlisp
concepts left over from prior ports. There are non-standard interfaces
to networks, C, and Fortran. There is a broken attempt at a python-like
syntax. Axiom was a research project of many interests and it shows.

Those who have been following Axiom releases know that I've been rewriting
the lisp code and so I've been spending some time rethinking the whole
of the internals.

I believe that there needs to be clearly defined layers of abstraction
that build up to full support of the algebra library. I have several
motives for this, including native support for literate documents and
a more robust platform for my proviso research.

Some primary design goals are:
  * the algebra and interpreter semantics should be identical, as far as 
possible.
   
  * the embedded design should target the lisp compiler as "the compiler",
    that is, the existing algebra code should just be a layered-syntax 
on the
    embedded lisp implementation. This would allow further layering of the
    system since a Spad "integrate(sin(x),x)" is really just a lisp-form
    "(integrate (sin x) x)". Note, however, that this is NOT the boot-code
    cheeseball idea of "pretty piles". Rather this would be isomorphic
    mappings between Spad and Lisp so all of the concepts of one are in
    the other.

  * the system structure should be designed to allow a "different direction"
    for the algebra since another research goal is to provide a way to
    "prove" (philosophical caveats here) that the algorithms are correct.
    Ideally this would just amount to more surface syntax layered on the
    underlying structures that a reasoning engine like COQ or ACL2 could 
use.

  * the layering should be "natural enough" so that it can be explained in
    literate text. A long term goal of the Axiom project is to make the 
whole
    system into a literate document that can be taught to the next 
generation.


All of the computer algebra systems I've seen are really just "stuck onto"
their underlying systems. You can see the struggle to marry the algebra to
the platform aka "algebra by accretion".

Instead I want to see the Axiom category/domain/package hierarchy be a 
natural
embedding on a prior layer that is prepared to "express the concepts" in the
hierarchy in natural ways. That layer embeds on a prior layer, which 
embeds on
a prior layer.... it is turtles all the way down. (Since it is an embedding,
"down" is the wrong concept but...)

I have some plans on how to get "from here to there" in a slow, incremental
fashion. These plans involve things like finding the basis-set of the 
algebra
in terms of lisp functions and then trying to find a closure of this 
basis set
so that the algebra embeds cleanly in this set. The compiler should compile
that basis set into an embedding in the prior layer. Lisp can support this
by defining domain-specific languages for each layer and macros from one 
layer
to another.

I have no idea what the final form will be. I do know that you should be 
able to
look at any layer of code and know immediately what it means in terms of the
next layer down. The compiler and interpreter should be able to walk the 
same
layers and generate the code that supports the understanding.

When it is done in this properly embedded fashion you should be able to
(mapcar #'(lambda (f) (integrate f x)) '((sin x) (cos x) ...
or use the Spad surface syntax to generate the same results.

At which point we can climb upward to a category-theoretic form...

And perform computational-mathematical proofs of algorithms...

And re-express the whole of the algebra in program transformations,
like transforming generalized grassmann expressions into efficient
linear algebra forms when the compiler knows the provisos...

And computational mathematics that involve simple classroom exercises
using the intermediate languages from their literate textbooks...

And have the open-source research supported by NSF funding...

oops...that last one is pure fantasy :-)

\start
Date: Mon, 16 Nov 2009 09:35:55 +0000
From: Martin Baker
To: list
Subject: Re: Embedding Axiom

On Monday 16 November 2009 04:35:00 Tim Daly wrote:
> This is a request for design discussion for those who are interested.

Tim,

Can I ask a nieve question? If you were starting from scratch would you write 
Axiom in lisp? I've no special axe to grind and no special technical 
knowledge, I'm just asking out of curiosity.

It just seems to me that for Axiom to hit the bigtime:

* potential programmers and advanced users would want a modern graphical IDE 
and useful error messages.
* non-advanced users would want a html-like interface that changes with the 
fashion of the time (the look seems to be important these days).

I just wondered how practical it is to do all these things on top of lisp? As 
opposed to say another functional language supported by something like the 
Eclipse framework? When I first came across the spad language, a few weeks ago 
now! I was really surprised how similar it is to the language Scala, without 
knowing what the technical issues might be it would be interesting to know if 
spad could be built on top of Scala?

\start
Date: Mon, 16 Nov 2009 11:59:51 -0500
From: Tim Daly
To: Martin Baker
Subject: Re: Embedding Axiom

Martin Baker wrote:
> On Monday 16 November 2009 04:35:00 Tim Daly wrote:
>   
>> This is a request for design discussion for those who are interested.
>>     
>
> Tim,
>
> Can I ask a nieve question? If you were starting from scratch would you write 
> Axiom in lisp? I've no special axe to grind and no special technical 
> knowledge, I'm just asking out of curiosity.
   
Axiom depends heavily on lisp's ability to write programs which write
programs. No other language seems to have this ability. The macro
facility in lisp gives Axiom the ability to "get inside the compiler"
at compile time to perform needed optimizations. It can do this
because lisp macros are source-to-source transformations on the syntax
tree that occur at compile time. Axiom uses closures and passes them
around as first-class objects so you can create stateful objects
in-context on the fly, pass them around and call them in other
contexts. Unlike other languages, lisp programs are data which are
programs.

If I were starting from scratch I don't know what other language could
be used.  Python/Java/Scala cannot dynamically create program text and
use it immediately.  They do not have a macro facility that is
source-to-source.  They cannot create useful runtime closures.

I qualify my "cannot" remarks with Greenspun's Law which states that
"Any sufficiently complicated C or Fortran (Python/Java/Scala) program 
contains an ad-hoc,
informally-specified bug-ridden slow implementation of half of common lisp."

> It just seems to me that for Axiom to hit the bigtime:
>
> * potential programmers and advanced users would want a modern graphical IDE 
> and useful error messages.
> * non-advanced users would want a html-like interface that changes with the 
> fashion of the time (the look seems to be important these days).
   
Axiom is re-targetting the user interface to use the browser (nod to
Bill Page).  The browser only recently supports needed elements like
the <canvas> object but Axiom can already create dynamic browser pages
that allow inline computations (supported by Ajax calls).  The
hyperdoc help system is already partially rewritten to be
browser-based.  The graphics subsystem is being redesigned to work on
html canvas objects in browsers.  All of this works from lisp.

As for "hitting the bigtime".... Axiom is not trying to achieve
success in the way you are thinking.  Your definition of success has
an element of "lots of people use it".

Axiom's definition of success involves being the basis for
computational mathematics, which is a small intersection between
mathematicians and programmers. The total number of people in this set
would likely fill a small parking lot, assuming you could get them out
of doors.

Success means that computational mathematicians are able to build
upward from the existing system in a mathematically correct
way. Success involves making the system into something that can be
taught to the next generation so they can move further with
confidence. So what does it take to provide reasonable guarantees that
Axiom is mathematically correct (insert philosophical debate here)?
What does it take to teach the next generation to think like
computational mathematicians (insert literate programming debate
here)?

> I just wondered how practical it is to do all these things on top of lisp? As 
> opposed to say another functional language supported by something like the 
> Eclipse framework? When I first came across the spad language, a few weeks ago 
> now! I was really surprised how similar it is to the language Scala, without 
> knowing what the technical issues might be it would be interesting to know if 
> spad could be built on top of Scala?
>   

Unfortunately nothing I can possibly say will be meaningful if you
aren't a lisper.  Lisp is an "epiphany experience"

Epiphany languages change the way you think. Other examples worth
learning are APL, Forth, Snobol, Prolog, OPS5,
etc.Python/Ruby/Scala/Java are weak implementations of Algol 68.

Ultimately, there is a gap between the problem you are trying to solve
and the machine that will execute the solution. I call this the
"impedance gap" (impedance is resistance because of a
mismatch... think of a soda straw connected to a fire hydrant).  This
gap is very wide if you are trying to solve a complex problem on a
microprocessor. A computer language that is close to the machine
(e.g. assembler) means you have to move your concepts from your head
to the machine. A computer language that is close to the problem
(e.g. AutoCAD for solid models) means you need only small programs to
express your problem but you need a lot of special-purpose machinery
to "cross the gap" to the microprocessor.

Lisp is the only language I know that operates at all levels across
the impedance gap.  (e.g (integrate (car x) .... uses a heavy
algorithm on a machine pointer)

You could build spad on top of Scala but it would be painful. You
would end up using "factory objects" to create "eq pointers" to unique
instances which is dirt trivial in lisp.  You would have to build a
Scala parser to a special internal data representation, a Scala macro
language that could manipulate the internal data representation, a
Scala interpreter so you could call Scala functions on the internal
data representation, a Scala compiler so you could compile the
internal data representation, and an internal-to-Scala printer
program. In short, you would have to build "an ad-hoc,
informally-specified bug-ridden slow implementation of half of common
lisp." And when you are done you still have a language that sits on
top of a virtual machine that does not support tail-recursion.

The REAL question is why we don't all rewrite everything in Go :-)

Methinks I'm becoming something of a curmudgeon.

\start
Date: Mon, 16 Nov 2009 09:29:20 -0800 (PST)
From: Tim Daly
To: list
Subject: Re: Is your CAS no a weakling anymore?

On Oct 19, 5:16pm, cliclic...@freenet.de wrote:
> Richard Fateman schrieb:
>
>
>
> > cliclic...@freenet.de wrote:

> > >...  they claim to deliver the antiderivative of any elementary
> > > function i= f it can also be written in terms of elementary
> > > functions...

> > At least Maxima / Macsyma makes no such claims, and in particular
> > neither implements completely the algebraic case of the Risch
> > algorithm= .  Undoubtedly simpler examples will stump these
> > programs.

> Errh. Ok. Alright. Maxima users are excused for the time being - they
> may hand in their answers after the next integrator overhaul. On the
> other hand, Derive also makes do with less than 1000 general
> integration rules like
>  INT(F((a+b*x)^(1/n),x),x) ->
>  n/b*SUBST(INT(x^(n-1)*F(x,(x^n-a)/b),x),x,(a+b*x)^(1/n)),
> or
>  INT(x^m*LN((a*x^n)^q),x) ->
>  x^(m+1)*LN((a*x^n)^q)/(m+1)-n*q*x^(m+1)/(m+1)^2.
> What counts in the end is the ability to handle real-life integrals like
> the problem posed. Maybe Risch's is not the best way?
>
> And now pssss. They are all crouched over their screens. No sound but
> the occasional keyboard click and slurp of coffee. Papa Wolfram looks
> particularly grave. Will he and his crew flunk again?
>
> Martin ;)

Interesting. Where do you find such patterns?
Do you have a catalog of them I can try?

\start
Date: Mon, 16 Nov 2009 13:38:12 -0500
From: Tim Daly
To: Martin Baker
Subject: Re: Embedding Axiom

I re-read what I wrote and it is likely to not be very meaningful to you.
Let me try to demonstrate the point.

Suppose you wanted to implement an "if-only" statement in Scala.
Is this possible? I don't know Scala so I can't say but I would guess not.

In Python (which I do know) a statement like

   if-only x > 0:
      pass

would require a change to the compiler. A similar statement in Java
would also require a compiler change. An if-only statement in lisp is 
trivial
to implement and would work with every other part of the language, as in:

(if-only (> x 0) (pass))

This would be a trivial in-class quiz for a lisp course.

When designing and developing lisp code it is common to create the
language you would like to implement by creating the language you
would like to implement but doing it in such a way that the language
is embedded in lisp in a "first-class operations" way. Macros allow you
to dynamically extend the compiler so "if-only" is new, first-class syntax.

The Axiom redesign question amounts to understanding the language
we would like to have to implement the support for Spad.... and then
understanding the language we would like to have to implement the
language that supports Spad... and then recursively repeating the process.

Tim

Martin Baker wrote:
> On Monday 16 November 2009 04:35:00 Tim Daly wrote:
>   
>> This is a request for design discussion for those who are interested.
>>     
>
> Tim,
>
> Can I ask a nieve question? If you were starting from scratch would you write 
> Axiom in lisp? I've no special axe to grind and no special technical 
> knowledge, I'm just asking out of curiosity.
>
> It just seems to me that for Axiom to hit the bigtime:

> * potential programmers and advanced users would want a modern
> graphical IDE and useful error messages.  * non-advanced users would
> want a html-like interface that changes with the fashion of the time
> (the look seems to be important these days).

> I just wondered how practical it is to do all these things on top of
> lisp? As opposed to say another functional language supported by
> something like the Eclipse framework? When I first came across the
> spad language, a few weeks ago now! I was really surprised how
> similar it is to the language Scala, without knowing what the
> technical issues might be it would be interesting to know if spad
> could be built on top of Scala?

\start
Date: Mon, 16 Nov 2009 15:04:26 -0800 (PST)
From: Cliff Yapp
To: list
Subject: Re: Embedding Axiom

 
On Sunday 15 November 2009 23:35:00 Tim Daly wrote:
> This is a request for design discussion for those who are interested.
> When it is done in this properly embedded fashion you should be able to
> (mapcar #'(lambda (f) (integrate f x)) '((sin x) (cos x) ...
> or use the Spad surface syntax to generate the same results.
> 
> At which point we can climb upward to a category-theoretic form...

> And perform computational-mathematical proofs of algorithms...

Tim, a question here.  As I understand it (which I readily admit I
 don't well) the notion of what an "integral" is or for that matter
 what sine, cosine and even "x" are more or less "lives" at the
 category theory level.  Or, put another way, the category-theoretic
 level is where the "type" rules of category theory determine what is
 and is not a legal expansion of "integrate(sqrt(x),x)" - for example,
 if "x" is the set of positive real numbers integrating sqrt(x) may
 look a tad different in expansion to a "verbose" category theory
 typed set of calls than (say) negative real numbers (where sqrt is
 going to result in something not a real number).Axiom's user
 environment does some "type deduction" now as I understand it, to
 make user interaction more manageable, although the programming
 environment requires non-ambiguous specification of types.  Doesn't
 that imply that rather than "building up" to category-theoretic form
 the specification of the algebra needs to start at the
 category-theoretic form and have the requirements of that form
 dictate the required support structure(s) at the higher level
 language and Lisp levels?  And that other "simpler" expressions of
 mathematics for users would have to be layered on top of the robust
 category-theoretic foundation to support "translating" more casual
 user supplied problems (like integrate(sin(x),x) ) into statements
 with the rigor to be subject to formal proof? If I understand
 correctly, mathematical statements are made within the context of a
 series of axioms, such as (for example) the ZFC set theory axioms.
 Category Theory provides (among other things) a framework with which
 to manage the axioms being used and what can be deduced based on the
 current operating set of axioms.  It seems to me like this conceptual
 framework and the language definitions being used to express concepts
 within that framework would need to be laid out before algebraic
 logic could really be "properly" defined in the system, but I could
 be wrong - have I misunderstood what is required for proof
 robustness?

That would lead to a hierarchy something like:

User-level syntax

|

Intermediate Layer(s)

|

Category Theoretic High Level Language (Spad?)
 
|

Lisp

where the Category Theoretic Language would depend on Lisp behaviors,
which would in turn depend on the machine assembly language level
behaviors, etc.

This of course lends itself to the idea of languages within languages
that Lisp provides, but the "rules" of the Category Theoretic language
would essentially have to be the rules of category theory itself,
which I'm guessing are probably some subset of the behaviors allowed
by Lisp.

 Am I thinking about the problem incorrectly?

\start
Date: Mon, 16 Nov 2009 18:19:28 -0500
From: Tim Daly
To: Cliff Yapp
Subject: Re: Embedding Axiom

C Y wrote:
> 
> On Sunday 15 November 2009 23:35:00 Tim Daly wrote:
>  
>> This is a request for design discussion for those who are interested.
>> When it is done in this properly embedded fashion you should be able t=
o
>> (mapcar #'(lambda (f) (integrate f x)) '((sin x) (cos x) ...
>> or use the Spad surface syntax to generate the same results.
>>
>> At which point we can climb upward to a category-theoretic form...
>>    
>
>  
>> And perform computational-mathematical proofs of algorithms...
>>    

> Tim, a question here.  As I understand it (which I readily admit I
don't well) the notion of what an "integral" is or for that matter
what sine, cosine and even "x" are more or less "lives" at the
category theory level.  Or, put another way, the category-theoretic
level is where the "type" rules of category theory determine what is
and is not a legal expansion of "integrate(sqrt(x),x)" - for example,
if "x" is the set of positive real numbers integrating sqrt(x) may
look a tad different in expansion to a "verbose" category theory typed
set of calls than (say) negative real numbers (where sqrt is going to
result in something not a real number).Axiom's user environment does
some "type deduction" now as I understand it, to make user interaction
more manageable, although the programming environment requires
non-ambiguous specification of types.  Doesn't that imply that rather
than "building up" to category-theoretic form the specification of the
algebra needs to start at the category-theoretic form and have the
requirements of that form dictate the required support structure(s) at
the higher level language and Lisp levels?  And that other "simpler"
expressions of mathematics for users would have to be layered on top
of the robust category-theoretic foundation to support "translating"
more casual user supplied problems (like integrate(sin(x),x) ) into
statements with the rigor to be subject to formal proof? If I
understand correctly, mathematical statements are made within the
context of a series of axioms, such as (for example) the ZFC set
theory axioms.  Category Theory provides (among other things) a
framework with which to manage the axioms being used and what can be
deduced based on the current operating set of axioms.  It seems to me
like this conceptual framework and the language definitions being used
to express concepts within that framework would need to be laid out
before algebraic logic could really be "properly" defined in the
system, but I could be wrong - have I misunderstood what is required
for proof robustness?

> That would lead to a hierarchy something like:
>
> User-level syntax
>
> |
>
> Intermediate Layer(s)
>
> |
>
> Category Theoretic High Level Language (Spad?)
> 
> |
>
> Lisp

> where the Category Theoretic Language would depend on Lisp
  behaviors, which would in turn depend on the machine assembly
  language level behaviors, etc.

> This of course lends itself to the idea of languages within
  languages that Lisp provides, but the "rules" of the Category
  Theoretic language would essentially have to be the rules of
  category theory itself, which I'm guessing are probably some subset
  of the behaviors allowed by Lisp.

>  Am I thinking about the problem incorrectly?

You are correct that category theory should underlie the Axiom type
hierarchy.  My thought about "layering it above" is related to using
the theory as part of the proof process. Properly speaking it should
instead be used for defining functors and mappings. I am not nearly
strong enough in category theory to try to architect Axiom on top of
it. I think that such a rebasing would be a PhD thesis or two. You'd
have to start way down deep with records as products and unions as
co-products.

\start
Date: Mon, 16 Nov 2009 17:32:11 -0800 (PST)
From: Tim Daly
To: list
Subject: Re: Is your CAS no a weakling anymore?

On Nov 16, 6:50pm, cliclic...@freenet.de wrote:
> TimDaly schrieb:
>
>
>
>
>
> > On Oct 19, 5:16 pm, cliclic...@freenet.de wrote:
> > > Richard Fateman schrieb:
>
> > > > cliclic...@freenet.de wrote:

> > > > > they claim to deliver the antiderivative of any elementary function if
> > > > > it can also be written in terms of elementary functions...

> > > > At least Maxima / Macsyma makes no such claims, and in particular
> > > > neither implements completely the algebraic case of the Risch algorithm.
> > > > Undoubtedly simpler examples will stump these programs.

> > > Errh. Ok. Alright. Maxima users are excused for the time being - they
> > > may hand in their answers after the next integrator overhaul. On the
> > > other hand, Derive also makes do with less than 1000 general
> > > integration rules like
> > >  INT(F((a+b*x)^(1/n),x),x) ->
> > >  n/b*SUBST(INT(x^(n-1)*F(x,(x^n-a)/b),x),x,(a+b*x)^(1/n)),
> > > or
> > >  INT(x^m*LN((a*x^n)^q),x) ->
> > >  x^(m+1)*LN((a*x^n)^q)/(m+1)-n*q*x^(m+1)/(m+1)^2.
> > > What counts in the end is the ability to handle real-life integrals like
> > > the problem posed. Maybe Risch's is not the best way?
>
> > > And now pssss. They are all crouched over their screens. No sound but
> > > the occasional keyboard click and slurp of coffee. Papa Wolfram looks
> > > particularly grave. Will he and his crew flunk again?
>
> > > Martin ;)
>
> > Interesting. Where do you find such patterns?
> > Do you have a catalog of them I can try?
>
> Could you be more specific? Does your "catalog of patterns" refer to my
> integration problems, or perhaps to my associative memory connecting
> attempts to solve them with concepts like "coffee" and "Wolfram" (which
> is further linked to "Papa") and "trance"?
>
> Martin.

Do you have a catalog of patterns (in source code) of the form:
  INT(F((a+b*x)^(1/n),x),x) ->
  n/b*SUBST(INT(x^(n-1)*F(x,(x^n-a)/b),x),x,(a+b*x)^(1/n)),

I would like to see what patterns you have and compare them against
the integration test suite that Axiom uses.

\start
Date: Mon, 16 Nov 2009 22:46:15 -0500
From: Stephen Wilson
To: Tim Daly
Subject: Re: Embedding Axiom

On Sun, Nov 15, 2009 at 11:35:00PM -0500, Tim Daly wrote:
> This is a request for design discussion for those who are interested.

Your message is very interesting.

> I have some plans on how to get "from here to there" in a slow, incremental
> fashion. These plans involve things like finding the basis-set of the algebra
> in terms of lisp functions and then trying to find a closure of this basis set
> so that the algebra embeds cleanly in this set. The compiler should compile
> that basis set into an embedding in the prior layer. Lisp can support this by
> defining domain-specific languages for each layer and macros from one layer to
> another.

Could you please expand on this point?  How do you propose to do this
incrementally from an implementation point of view?  I am asking these questions
from an engineering standpoint.  In particular, are you suggesting a rewrite
(essentially from scratch, using the current implementation as a guide)?

\start
Date: Tue, 17 Nov 2009 00:26:59 -0500
From: Tim Daly
To: Stephen Wilson
Subject: Re: Embedding Axiom

Stephen Wilson wrote:
> Hi Tim,
>
> On Sun, Nov 15, 2009 at 11:35:00PM -0500, Tim Daly wrote:
>   
>> This is a request for design discussion for those who are interested.
>>     
>
> Your message is very interesting.
>
   
>> I have some plans on how to get "from here to there" in a slow,
>> incremental fashion. These plans involve things like finding the
>> basis-set of the algebra in terms of lisp functions and then trying
>> to find a closure of this basis set so that the algebra embeds
>> cleanly in this set. The compiler should compile that basis set
>> into an embedding in the prior layer. Lisp can support this by
>> defining domain-specific languages for each layer and macros from
>> one layer to another.


> Could you please expand on this point?  How do you propose to do
> this incrementally from an implementation point of view?  I am
> asking these questions from an engineering standpoint.  In
> particular, are you suggesting a rewrite (essentially from scratch,
> using the current implementation as a guide)?


A rewrite from scratch? Well, more like a "remolding of the clay" than
a rewrite.  The idea is to move from a working system to a working
system with each change, but eventually restructure the internals
cleanly. At the moment I am in the process of restructuring the
interpreter/compiler into literate form (book volume 5). As I do this
I am rewriting the code to be functionally equivalent.

The above comment about finding the basis set for the algebra amounts
to finding every lisp-source-level function call from every lisp
algebra object. I wrote a "calls" function to walk lisp code and
extract the non-common-lisp function calls.

This set will be gathered, arranged, and studied. The idea is to find
the "right level" of abstraction (ala "On Lisp" and "Structure and
Interpretation"). This level of abstraction forms the current base
language hosting the algebra. It forms a design target for the top
level embedded layer. Next we re-arrange the system to make this layer
explicit (define an API, so to speak). Then we recurse the process
with the new layer.

Code in the system that uses nothing but common lisp calls forms the
other end of the spectrum. The game is to build the two layers toward
each other in a disciplined way so that each layer embeds properly in
the prior one. Because Axiom was written by so many different people
the internals are more like "tent poles" of functionality where each
one builds from nothing all the way to the top, reproducing common
ideas in different ways.

Along the way the code needs major cleanup work. On Lisp and SICP
stress using functional programming but the Axiom internals are wildly
coupled through the use of special variables. Some of these can be
eliminated with extra arguments and most of those that cannot will
still be able to be limited using lexical closures.

In addition, the use of Boot code led to a fantastic amount of list
processing where it is not appropriate. Major structures in the system
should be defstruct objects or some other kind of structuring. Because
of the Boot idioms it is next to impossible to find all the places a
data structure is modified.  Side-effecting global state happens all
over the place. Now that the boot code is gone the data can take a
more natural and better disciplined shape.

Even better for the long term would be to make each structure
immutable (see "Purely Functional Data Structure" by Chris
Okasaki). This would make it much easier to move the system to a
parallel base of code. This level of rewrite is on the queue to think
about and study but might take some experimenting.

I have roughly 140 files still to merge into the interpreter volume
and it takes about a week of
moving/testing/documenting/rewriting/xrefing/latexing for each one so
this is going to take a while.

\start
Date: Tue, 17 Nov 2009 12:54:56 -0800
From: Ed Borasky
To: list
Subject: Re: Embedding Axiom

So:

a. Is it to be Common Lisp rather than Scheme? Should it work (and be
tested) with all three major open-source platforms (clisp, sbcl and
gcl)?

b. The kind of test / behavior driven development such a massive
refactoring requires is "usually" done in Ruby these days. Are there
Lisp-based tools for this so the project could "eat its own dog food",
or would there need to be some "scaffolding" built in a "scripting
language" like Ruby or Python?

c. Aren't there more "Lisp-like" theories of mathematics and
implementations of them? I'm thinking of Automath, but I suspect there
are others. And there are certainly Prolog-like systems, proof
engines, etc. The current crop of "functional" languages (Haskell,
Erlang, OCaml, etc.) does seem like a better platform for this sort of
thing than Common Lisp. Scheme would make sense if we wanted to push
this into undergrad / high school curricula, though. Summer of Code??

d. Hardware? This stuff needs lots of cores and RAM - maybe another
reason to use a more modern language like Erlang with explicit and
"provably correct" concurrency primitives.

Speaking of all of this, have you all seen Jeff Bone's "rant":

Programming languages, operating systems, despair and anger http://bit.ly/1xtACU

Perhaps computational mathematics should be designing their own
operating system and programming language for computational
mathematics, using something like the LLVM (low-level virtual machine)
or DROPS (Dresden Real-time OPerating System) kernel. Or the
Intellasys Forth-based SEAforth array processor? http://bit.ly/2t4e3C

> A rewrite from scratch? Well, more like a "remolding of the clay"
> than a rewrite.  The idea is to move from a working system to a
> working system with each change, but eventually restructure the
> internals cleanly. At the moment I am in the process of
> restructuring the interpreter/compiler into literate form (book
> volume 5).  As I do this I am rewriting the code to be functionally
> equivalent.

> The above comment about finding the basis set for the algebra
> amounts to finding every lisp-source-level function call from every
> lisp algebra object. I wrote a "calls" function to walk lisp code
> and extract the non-common-lisp function calls.

> This set will be gathered, arranged, and studied. The idea is to
> find the "right level" of abstraction (ala "On Lisp" and "Structure
> and Interpretation"). This level of abstraction forms the current
> base language hosting the algebra. It forms a design target for the
> top level embedded layer. Next we re-arrange the system to make this
> layer explicit (define an API, so to speak). Then we recurse the
> process with the new layer.

> Code in the system that uses nothing but common lisp calls forms the
> other end of the spectrum. The game is to build the two layers
> toward each other in a disciplined way so that each layer embeds
> properly in the prior one. Because Axiom was written by so many
> different people the internals are more like "tent poles" of
> functionality where each one builds from nothing all the way to the
> top, reproducing common ideas in different ways.

> Along the way the code needs major cleanup work. On Lisp and SICP
> stress using functional programming but the Axiom internals are
> wildly coupled through the use of special variables. Some of these
> can be eliminated with extra arguments and most of those that cannot
> will still be able to be limited using lexical closures.

> In addition, the use of Boot code led to a fantastic amount of list
> processing where it is not appropriate. Major structures in the
> system should be defstruct objects or some other kind of
> structuring. Because of the Boot idioms it is next to impossible to
> find all the places a data structure is modified.  Side-effecting
> global state happens all over the place. Now that the boot code is
> gone the data can take a more natural and better disciplined shape.

> Even better for the long term would be to make each structure
> immutable (see "Purely Functional Data Structure" by Chris
> Okasaki). This would make it much easier to move the system to a
> parallel base of code. This level of rewrite is on the queue to
> think about and study but might take some experimenting.

> I have roughly 140 files still to merge into the interpreter volume
> and it takes about a week of
> moving/testing/documenting/rewriting/xrefing/latexing for each one
> so this is going to take a while.

\start
Date: Tue, 17 Nov 2009 21:26:33 +0000
From: Bertfried Fauser
To: Edward Borasky
Subject: Re: Embedding Axiom

if you do the rewrite, feel free to choose....

\start
Date: Tue, 17 Nov 2009 18:24:20 -0500
From: Tim Daly
To: Edward Borasky
Subject: Re: Embedding Axiom

Ed Borasky wrote:
> So:
>
> a. Is it to be Common Lisp rather than Scheme? Should it work (and be
> tested) with all three major open-source platforms (clisp, sbcl and
> gcl)?
   
Common lisp. For the simple reason that a slow transition from a
working version to a working version on a daily basis does not lend
itself to a complete language transition. The rewrite will move to
ANSI lisp as a simple side-effect of newly written code so it should
not matter what Common lisp you use to host it.

> b. The kind of test / behavior driven development such a massive
> refactoring requires is "usually" done in Ruby these days. Are there
> Lisp-based tools for this so the project could "eat its own dog food",
> or would there need to be some "scaffolding" built in a "scripting
> language" like Ruby or Python?
>   

I am building unit-tests for the internal routines as I rewrite them so 
that I can verify that the
rewrite is reasonably correct. The idea of refactoring code is much 
older than Ruby. See the
"On Lisp" book.

Axiom already has a complete test system built into the build. I rebuild the
system from scratch several times a day, usually after every few 
routines are merged.

I have spent a little time on the idea of "fuzz testing" Axiom but the
pseudo-random generator is a challenge. On possible approach I'm
studying is to use a hidden markov model against the Axiom test files
to generate "random-but-nearly-valid" inputs. Especially challenging
are random inputs that pass the parser and are mathematically "near
valid". I think there is a PhD thesis topic sneaking around in this
problem.

> c. Aren't there more "Lisp-like" theories of mathematics and
> implementations of them? I'm thinking of Automath, but I suspect there
> are others. And there are certainly Prolog-like systems, proof
> engines, etc. The current crop of "functional" languages (Haskell,
> Erlang, OCaml, etc.) does seem like a better platform for this sort of
> thing than Common Lisp. Scheme would make sense if we wanted to push
> this into undergrad / high school curricula, though. Summer of Code??
>   

ACL2 is written in lisp and there has been a project goal of embedding
ACL2 inside the Axiom machinery. There has been some discussion of
this topic on this mailing list. ACL2 calls could be made on function
definitions using an inherited set of mathematical decorations.  Thus,
the Group axioms could be added to the Group category and functions
implementing operations on the elements could be shown to obey the
Group laws (half a dozen PhD thesis topics a year hidden here)

Why would Haskell be a better platform? Because Haskell is functional?
Again, see the book "On Lisp" where the functional programming style
is stressed. It was written in 1993.

A Scheme implementation would end up creating Common lisp on Scheme
which would be time consuming.

> d. Hardware? This stuff needs lots of cores and RAM - maybe another
> reason to use a more modern language like Erlang with explicit and
> "provably correct" concurrency primitives.
>   

There was a recent conference on parallel lisp systems (in Japan I
think). There is no reason why an independent lisp system could not
run each core. That is essentially the same technique as the
Java-per-core implementations. A large portion of the lisp system can
live in shared, read-only memory as it works off separate
heaps/stacks.

The "new idea" in Go about passing channels on channels is basically
just passing closures, a very old lisp trick. Using a message passing
paradigm (where objects can be shared or serialized through the
message) is easy to do between lisps. Go "parallelism" appears to be
implemented by lightweight programs added to a queue which managed
dispatch. Go is not really running on all of the processors but the
lightweight threads are.

> Speaking of all of this, have you all seen Jeff Bone's "rant":
>
> Programming languages, operating systems, despair and anger http://bit.ly/1xtACU
>   

Yes, I saw Jeff's rant and, as an Elder of the Internet, and a very
long-time programmer (nearly 39 years) I have to agree with him. I
have a hard time finding a new technique that wasn't done in lisp
years ago.

Python claims to be lisp-like but they have no clue about macros,
program-data equivalence, the cons-nil-()-false equivalence, dynamic
environments, real closures, and a host of other useful things.  Even
their python command-line interpreter doesn't seem to allow techniques
that have been available in the lisp break loop. Try modifying a
python function on the fly and continuing from the breakpoint. And
forget about creating your own syntactic elements.

Haskell has "lazy evaluation" (see the function "Delay" in the Axiom
sources), monads (stateful pseudo-functional programs) which are
trivial to write, pattern matching of arguments (see the partial
function definition sequence in Axiom or any prolog-in-lisp).

Go has interfaces without inheritance, a very old idea in Common
lisp. I can't wait until they introduce wrappers and whoppers.

Lisp can modify the compiler internals at compile time by supplying
code to manipulate the compiler internal data structures (lisp is a
self-syntax tree and macros are source-to-source transforms done at
compile time). Lisp programs usually write lisp programs on the fly
since programs and data are the same. Try that in Ruby. Or construct
programs that learn by self-modification, growing organically to adapt
to the input stream by permanent change. Without writing a whole
parser/compiler chain I have no idea how to write self-modifying
Python programs.

Languages limit what you can think. Ask any Java programmer about
their program and you are likely to hear "design patterns". Ask any
lisp programmer about design patterns and be prepared for a laugh.

In any case, Axiom is firmly in the Common lisp camp for the forseeable 
future.

> Perhaps computational mathematics should be designing their own
> operating system and programming language for computational
> mathematics, using something like the LLVM (low-level virtual machine)
> or DROPS (Dresden Real-time OPerating System) kernel. Or the
> Intellasys Forth-based SEAforth array processor? http://bit.ly/2t4e3C
>   

I looked at the Clojure language running on the Java virtual machine
and at the Azul system which is designed to host hundreds of Java VMs
in parallel. But the question is, if you're going to use Java VMs why
not use Lisp VMs? Lisp compiles to machine code, so why not not host
hundreds of Lisps?  With a proper implementation you only need
separate stacks (or a spaghetti stack) and separate heaps or "clades
within a common heap". A Clade-heap modification would allow object
sharing or object transport between processes. Immutable data
structures is a very interesting idea here.

As for the Axiom internals rewrite/refactor, the intention is to
define "semantic layers" that make it perfectly clear where certain
functionality should be supported. Algebra concepts should be fairly
near the top of the tower with a gradual transition to raw lisp. I
would ideally like to be able to write each "layer" in only a few
pages of code expressed in the concepts of the previous layer.

If that can be done than it would be possible to teach Axiom by
starting at a few-page pile of code and working your way upward or
downward as appropriate. A perfect example of this is the standard
definition of lisp in lisp code. Such elegance and brevity is the soul
of the design.  Imagine understanding all of the algebra support code
in two pages.

\start
Date: Tue, 17 Nov 2009 21:18:21 -0500
From: Tim Daly
To: list
Subject: re: Elder of the Internet

This is a term first used in a british sitcom "The IT Crowd"...highly 
recommended.
http://www.youtube.com/watch?v=QAUyaELfwBo&feature=related

\start
Date: Wed, 18 Nov 2009 13:13:04 -0500
From: Tim Daly
To: Martin Baker
Subject: grassman.spad

I'm trying to install your code in Axiom.
Do I have your permission to use text from your webpage as documentation?

\start
Date: Wed, 18 Nov 2009 18:35:17 +0000
From: Martin Baker
To: Tim Daly
Subject: Re: grassman.spad

On Wednesday 18 November 2009 18:13:04 Tim Daly wrote:

> I'm trying to install your code in Axiom.
> Do I have your permission to use text from your webpage as documentation?
> 
Tim,

Yes, please feel free to use anything from:
http://www.euclideanspace.com/maths/standards/program/clifford/

Since I am new to literate programming I am not sure of the preferred format. 
So the web page is a bit of a mixture of User Guide, Programmers Guide, 
Requirements, test results and calls for help. 

I get the impression that the documentation in pamphlets is closer to a User 
Guide?

Since the code is currently an extension and bug fix to CliffordAlgebra it 
should not break existing applications although that might change. So I don't 
know if it should be called CliffordAlgebra or GrassmanAlgebra?

\start
Date: Wed, 18 Nov 2009 13:47:09 -0500
From: Tim Daly
To: Martin Baker
Subject: Re: grassman.spad

Martin,

Don't worry about the literate programming aspect. I'll handle that part.
I just want to be sure that I can track your changes using your web page.

As for the package name, you can call it anything you like.
I have seen Grassmann algebras called Clifford (Geometric) Algebras
that covers some of the same topics with different names.

William Sit and someone from Rutgers had what seemed to me to be an
amazingly clever generalization. I don't know what happened with that.

Martin Baker wrote:
> On Wednesday 18 November 2009 18:13:04 Tim Daly wrote:
>   
>> Martin,
>>
>> I'm trying to install your code in Axiom.
>> Do I have your permission to use text from your webpage as documentation?
>>
>> Tim
>>     
>
> Tim,
>
> Yes, please feel free to use anything from:
> http://www.euclideanspace.com/maths/standards/program/clifford/
>
> Since I am new to literate programming I am not sure of the preferred format. 
> So the web page is a bit of a mixture of User Guide, Programmers Guide, 
> Requirements, test results and calls for help. 
>
> I get the impression that the documentation in pamphlets is closer to a User 
> Guide?
>
> Since the code is currently an extension and bug fix to CliffordAlgebra it 
> should not break existing applications although that might change. So I don't 
> know if it should be called CliffordAlgebra or GrassmanAlgebra?

\start
Date: Wed, 18 Nov 2009 15:49:34 -0500
From: William Sit
To: Tim Daly
Subject: Re: grassman.spad

Tim:

You wrote: "William Sit and someone from Rutgers had what
seemed to me to be an amazingly clever generalization. I
don't know what happened with that."

--

I don't think what Li Guo (Rutgers, Newark) and I proposed is, at
least mathematically speaking, anything like "amazingly clever
generalization".  Moreover, we did not invent the concept of operads
(which is I think what you are referring to; for explanation of what
an operad is, see http://en.wikipedia.org/wiki/Operad_theory).

What you read about was from an NSF proposal that was not funded, in
which Guo and I proposed to base the algebra hierarchy in Axiom on the
idea of operads. Various algebraic structures, like Clifford or
Grassmann algebras, would then be descendents. The operads concept is
I believe closely related to lambda-calculus and so should not be
difficult to implement in Lisp. In the grand scheme of things, it
would be also useful for the proviso project, which would require
real-time manipulation of the Axiom compiler (in a way more involved
than what Tim recently described, for example, there has to a new
embedded language to make conditionals and indefinite iterations
native).

Many years ago (in the 1980's), another researcher from Rutgers (New
Brunswick), Joseph Johnson, had a Theory of Universes that was built
on the idea of partially defined functions as first-class objects (he
did not use that term, but I think it is a close description of the
objective) and this purely algebraic theory works across several
categories like complex analysis, algebraic geometry, differential
geometry, and differential algebraic geometry.  Unfortunately, he had
a stroke and his work was not completed. To summarize this is what is
roughly Johnson's own work: functions are just objects in which you
can plug in anyting that makes sense and then evaluate (like
physicists do, without worrying about domains of definition and
singularities explicitly). In some ways, there is a built-in algebra
for domains of definition that handles provisos transparently and
automatically.

\start
Date: Wed, 18 Nov 2009 13:08:41 -0800 (PST)
From: Tim Daly
To: list
Subject: Literate Common Lisp

Using this code you can write literate common lisp programs.
Note that the literate file you create is PURE latex so a "weave"
program is not needed. This will accept noweb-style <<chunk>>=
syntax or \begin{chunk}{chunkname}....\end{chunk} latex code.

Removing the weave program and using a literate-aware
load program you can make lisp aware of this file format
without using any external tools.

;  0 AUTHOR and LICENSE
;  1 ABSTRACT
;  2 THE LATEX SUPPORT CODE
;  3 GLOBALS
;  4 THE TANGLE COMMAND
;  5 THE TANGLE FUNCTION
;  6 GCL-READ-FILE (aka read-sequence)
;  7 GCL-HASHCHUNKS
;  8 GCL-EXPAND
;  9 ISCHUNK-LATEX
; 10 ISCHUNK-NOWEB



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 0 AUTHOR and LICENSE

;;; Timothy Daly (Tim Daly)
;;; License: Public Domain

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 1 ABSTRACT

;;; This program will extract the source code from a literate file

;;; A literate lisp file contains a mixture of latex and lisp sources
code.
;;; The file is intended to be in one of two formats, either in latex
;;; format or, for legacy reasons, in noweb format.

;;; Latex format files defines a newenvironment so that code chunks
;;; can be delimited by \begin{chunk}{name} .... \end{chunk} blocks
;;; This is supported by the following latex code.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 2 THE LATEX SUPPORT CODE

;;; The verbatim package quotes everything within its grasp and is
used to
;;; hide and quote the source code during latex formatting. The
verbatim
;;; environment is built in but the package form lets us use it in our
;;; chunk environment and it lets us change the font.
;;;
;;; \usepackage{verbatim}
;;;
;;; Make the verbatim font smaller
;;; Note that we have to temporarily change the '@' to be just a
character
;;; because the \verbatim@font name uses it as a character
;;;
;;; \chardef\atcode=\catcode`\@
;;; \catcode`\@=11
;;; \renewcommand{\verbatim@font}{\ttfamily\small}
;;; \catcode`\@=\atcode

;;; This declares a new environment named ``chunk'' which has one
;;; argument that is the name of the chunk. All code needs to live
;;; between the \begin{chunk}{name} and the \end{chunk}
;;; The ``name'' is used to define the chunk.
;;; Reuse of the same chunk name later concatenates the chunks

;;; For those of you who can't read latex this says:
;;; Make a new environment named chunk with one argument
;;; The first block is the code for the \begin{chunk}{name}
;;; The second block is the code for the \end{chunk}
;;; The % is the latex comment character

;;; We have two alternate markers, a lightweight one using dashes
;;; and a heavyweight one using the \begin and \end syntax
;;; You can choose either one by changing the comment char in column 1

;;; \newenvironment{chunk}[1]{%   we need the chunkname as an argument
;;; {\ }\newline\noindent%                    make sure we are in
column 1
;;; %{\small $\backslash{}$begin\{chunk\}\{{\bf #1}\}}% alternate
begin mark
;;; \hbox{\hskip 2.0cm}{\bf --- #1 ---}%      mark the beginning
;;; \verbatim}%                               say exactly what we see
;;; {\endverbatim%                            process \end{chunk}
;;; \par{}%                                   we add a newline
;;; \noindent{}%                              start in column 1
;;; \hbox{\hskip 2.0cm}{\bf ----------}%      mark the end
;;; %$\backslash{}$end\{chunk\}%              alternate end mark
(commented)
;;; \par%                                     and a newline
;;; \normalsize\noindent}%                    and return to the
document

;;; This declares the place where we want to expand a chunk
;;; Technically we don't need this because a getchunk must always
;;; be properly nested within a chunk and will be verbatim.

;;; \providecommand{\getchunk}[1]{%
;;; \noindent%
;;; {\small $\backslash{}$begin\{chunk\}\{{\bf #1}\}}}% mark the
reference

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 3 GLOBALS

;;; The *chunkhash* variable will hold the hash table of chunks.
;;;
;;; Every time we find a \begin{chunk}{name} ... \end{chunk} we look
;;; in this hash table. If the ``name'' is not found we add it.
;;; If the name is found, we concatentate it to the existing chunk.

(defvar *chunkhash* nil "this hash table contains the chunks found")

;;; This shows critical information for debugging purposes
(defvar *chunknoise* nil "turn this on to debug internals")


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 4 THE TANGLE COMMAND

;;;
;;; The tangle command does all of the work of extracting code.
;;; For legacy reasons we support 2 syntax forms, latex and noweb
;;;
;;; In latex form the code blocks are delimited by
;;;     \begin{chunk}{name}
;;;     ... (code for name)...
;;;     \end{chunk}
;;;
;;; and referenced by \getchunk{name} which gets replaced by the code

;;; In noweb form the code blocks are delimited by
;;;     <<name>>=
;;;     ... (code for name)...
;;;     @
;;;
;;; and referenced by <<name>> which gets replaced by the code

:;; There are several ways to invoke the tangle function.
;;;
;;; The first argument is always the file from which to extract code
;;;
;;; The second argument is the name of the chunk to extract
;;;    If the name starts with < then we assume noweb format as in:
;;;        (tangle "clweb.pamphlet" "<<name>>")  <== noweb syntax
;;;    Otherwise we assume latex format as in:
;;;        (tangle "clweb.pamphlet "name")       <== latex syntax
(default)
;;;
;;; The standard noweb chunk name is ``*'' but any name can be used.
;;;
;;; The third arument is the name of an output file:
;;;  (tangle "clweb.pamphlet" "clweb.chunk" "clweb.spadfile")



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 5 THE TANGLE FUNCTION

;;; This routine looks at the first character of the chunk name.
;;; If it is a $<$ character then we assume noweb syntax otherwise
;;; we assume latex syntax.
;;;
;;; We initialize the chunk hashtable
;;; then read the file and store each chunk
;;; then we recursively expand the ``topchunk'' to the output stream

(defun tangle (filename topchunk &optional file)
 "Extract the source code from a pamphlet file"
 (let ((noweb? (char= (schar topchunk 0) #\<)))
  (setq *chunkhash* (make-hash-table :test #'equal))
  (when *chunknoise* (format t "PASS 1~%"))
  (gcl-hashchunks (gcl-read-file filename) noweb?)
  (when *chunknoise* (format t "PASS 2~%"))
  (if (and file (stringp file))
   (with-open-file (out file :direction :output)
     (gcl-expand topchunk noweb? out))
   (gcl-expand topchunk noweb? t))))



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 6 GCL-READ-FILE (aka read-sequence)

;;; This would be read-sequence in ansi common lisp. Here we read
;;; a line, push it onto a stack and then reverse the stack. The
;;; net effect is a list of strings, one per line of the file.

(defun gcl-read-file (streamname)
 "Implement read-sequence in GCL"
 (let (result)
  (with-open-file (stream (open streamname))
   (do (line eof)
      ((eq line 'done) (nreverse result))
    (multiple-value-setq (line eof) (read-line stream nil 'done))
    (unless (eq line 'done) (push line result))))))



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 7 GCL-HASHCHUNKS

;;; gcl-hashchunks gathers the chunks and puts them in the hash table
;;;
;;; if we find the chunk syntax and it is a
;;;   define ==> parse the chunkname and start gathering lines onto a
stack
;;;   end    ==> push the completed list of lines into a stack of
chunks
;;;              already in the hash table
;;;   otherwise ==> if we are gathering, push the line onto the stack

;;; a hash table entry is a list of lists such as
;;; (("6" "5") ("4" "3") ("2" "1"))
;;; each of the sublists is a set of lines in reverse (stack) order
;;; each sublist is a single chunk of lines.
;;; there is a new sublist for each reuse of the same chunkname

;;; If the noweb argument is non-nil we assume that we are parsing
;;; using the noweb syntax. A nil argument implies latex syntax.

(defun gcl-hashchunks (lines noweb)
 "Gather all of the chunks and put them into a hash table"
 (let (type name chunkname oldchunks chunk gather)
  (dolist (line lines)
   (if noweb
    (multiple-value-setq (type name) (ischunk-noweb line))
    (multiple-value-setq (type name) (ischunk-latex line)))
   (cond
    ((eq type 'define)
      (when *chunknoise* (format t "DEFINE name=~a~%" name))
      (setq chunkname name)
      (setq gather t))
    ((eq type 'end)
      (when *chunknoise*
       (format t "END name= ~a chunk=~s~%" chunkname (reverse chunk)))
      (setq oldchunks (gethash chunkname *chunkhash*))
      (setf (gethash chunkname *chunkhash*) (push chunk oldchunks))
      (setq gather nil)
      (setq chunk nil))
    (gather ;; collect lines into the chunk while gather is true
      (push line chunk))))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 8 GCL-EXPAND

;;; gcl-expand will recursively expand chunks in the hash table
;;;
;;; latex chunk names are just the chunkname itself e.g. chunkname
;;; noweb chunk names include the delimiters, e.g: <<chunkname>>

;;; a hash table entry is a list of lists such as
;;; (("6" "5") ("4" "3") ("2" "1"))
;;; so to process the chunk we reverse the main list and
;;; for each sublist we reverse the sublist and process the lines

;;; if a chunk name reference is encountered in a line we call expand
;;; recursively to expand the inner chunkname.

(defun gcl-expand (chunk noweb? file)
 "Recursively expand a chunk into the output stream"
 (let ((chunklist (gethash chunk *chunkhash*)) type name)
  (dolist (chunk (reverse chunklist))
   (dolist (line (reverse chunk))
    (if noweb?
     (multiple-value-setq (type name) (ischunk-noweb line))
     (multiple-value-setq (type name) (ischunk-latex line)))
    (if (eq type 'refer)
      (progn
       (when *chunknoise* (format t "REFER name=~a~%" name))
       (gcl-expand name noweb? file))
      (format file "~a~%" line))))))



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 9 ISCHUNK-LATEX

;;; There is a built-in assumption (in the ischunk-* functions)
;;; that the chunks occur on separate lines and that the indentation
;;; of the chunk reference has no meaning.
;;;
;;; ischunk-latex  recognizes chunk names in latex convention
;;;
;;; There are 3 cases to recognize:
;;;  \begin{chunk}{thechunkname}  ==> 'define thechunkname
;;;  \end{chunk}                  ==> 'end nil
;;;  \getchunk{thechunkname}      ==> 'refer thechunkname

(defun ischunk-latex (line)
 "Find chunks delimited by latex syntax"
 (let ((mark (search "chunk" line))      ; is this a line we care
about?
       (point 0)
       name
       (beginstring "\\begin{chunk}{")   ; this is the define marker
string
       beginlength
       (endstring "\end{chunk}")         ; this is the end marker
string
       (referstring "\getchunk{")        ; this is the refer string
       referlength)
  (setq beginlength (length beginstring))
  (setq referlength (length referstring))
  (when mark
   (cond
    ((setq mark (search beginstring line)) ; recognize define
      (setq point (position #\} line :start (+ mark beginlength)))
      (cond
       ((null point) (values nil nil))
       ((= point 0)  (values nil nil))
       (t
         (setq name (subseq line (+ mark beginlength) point))
         ;(print (list 'ischunk-latex 'define name))
         (values 'define name))))
    ((setq mark (search endstring line))     ; recognize end
       ;(print (list 'ischunk-latex 'end))
       (values 'end nil))
    ((setq mark (search referstring line))         ; recognize
reference
      (setq point (position #\} line :start (+ mark referlength)))
      (cond
       ((null point) (values nil nil))
       ((= point 0)  (values nil nil))
       (t
         (setq name (subseq line (+ mark referlength) point))
         ;(print (list 'ischunk-latex 'refer name))
         (values 'refer name))))
    (t (values nil nil))))))



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 10 ISCHUNK-NOWEB

;;; ischunk-noweb recognizes chunk names using the noweb convention
;;;
;;; There are 3 cases to recognize:
;;;  <<thechunkname>>=  ==> 'define thechunkname
;;;  @                  ==> 'end nil
;;;  <<thechunkname>>   ==> 'refer thechunkname

(defun ischunk-noweb (line)
 "Find chunks delimited by noweb syntax"
 (let ((len (length line)) (mark (position #\> line)) (point 0))
  (cond
   ((and mark                    ; recognize define
         (> len (+ mark 2))
         (char= #\< (schar line 0))
         (char= #\< (schar line 1))
         (char= #\> (schar line (+ mark 1)))
         (char= #\= (schar line (+ mark 2))))
     ;(print (list 'define (subseq line 0 (+ mark 2))))
     (values 'define (subseq line 0 (+ mark 2))))
   ((and mark                    ; recognize reference
         (> len (+ mark 1))
         (char= #\> (schar line (+ mark 1))))
     (setq point (position #\< line))
     (if
      (and point
           (< point (- mark 2))
           (char= #\< (schar line (+ point 1))))
        (values 'refer (subseq line point (+ mark 2)))
        (values 'noise nil)))
    ((and (> len 0)                ; end chunk
          (char= #\@ (schar line 0)))
      (values 'end nil))
    (t (values nil nil)))))

\start
Date: Wed, 18 Nov 2009 16:24:05 -0500
From: Tim Daly
To: William Sit
Subject: Re: grassman.spad

Ok, so perhaps "an amazingly clever generalization" is possibly
over-the-top but the fact that it could form a basis for all of the
algebra certainly captured my imagination. I did not know of Operad
theory but I'll add it to the study queue. I still feel that what you
and Li proposed was very elegant. I really liked the fact that
Clifford and Grassmann algebras are subcases.

William Sit wrote:
> Tim:
>
> You wrote: "William Sit and someone from Rutgers had what
> seemed to me to be an amazingly clever generalization. I
> don't know what happened with that."
>
> --
> I don't think what Li Guo (Rutgers, Newark) and I proposed
> is, at least mathematically speaking, anything like
> "amazingly clever generalization".  Moreover, we did not
> invent the concept of operads (which is I think what you are
> referring to; for explanation of what an operad is, see
> http://en.wikipedia.org/wiki/Operad_theory).
>
> What you read about was from an NSF proposal that was not
> funded, in which Guo and I proposed to base the algebra
> hierarchy in Axiom on the idea of operads. Various algebraic
> structures, like Clifford or Grassmann algebras, would then
> be descendents. The operads concept is I believe closely
> related to lambda-calculus and so should not be difficult to
> implement in Lisp. In the grand scheme of things, it would
> be also useful for the proviso project, which would require
> real-time manipulation of the Axiom compiler (in a way more
> involved than what Tim recently described, for example,
> there has to a new embedded language to make conditionals
> and indefinite iterations native).
>
> Many years ago (in the 1980's), another researcher from
> Rutgers (New Brunswick), Joseph Johnson, had a Theory of
> Universes that was built on the idea of partially defined
> functions as first-class objects (he did not use that term,
> but I think it is a close description of the objective) and
> this purely algebraic theory works across several categories
> like complex analysis, algebraic geometry, differential
> geometry, and differential algebraic geometry.
> Unfortunately, he had a stroke and his work was not
> completed. To summarize this is what is roughly Johnson's
> own work: functions are just objects in which you can plug
> in anyting that makes sense and then evaluate (like
> physicists do, without worrying about domains of definition
> and singularities explicitly). In some ways, there is a
> built-in algebra for domains of definition that handles
> provisos transparently and automatically.

\start
Date: Wed, 18 Nov 2009 23:24:38 -0500
From: Tim Daly
To: Bertfried Fauser, Franz Lehner
Subject: Function cache in Axiom (Memoizing)

Bertfried, Franz,

I have been giving some thought to your need for caching.
There is a technique in lisp called memoizing which basically
creates a new hash table in a closure and then defines a function
which closes over it and wraps the original function.

So when you call
(memoize originalfunction)
then you get back a new function to replace the original.
This new function first looks in the locally created cache
and returns what it finds. If it does not have a cached value
then it calls the original function, caches the result and
returns the result. Hash tables are local to the function so
there can be no collisions with values from other domains.

I know you're not common lisp readers but knowing what it does
should make this code obvious:

(defun memoize (fn)
  (let ((cache (make-hash-table :test #'equal)))    ;local hashtable
    #'(lambda (&rest args)                                   ;function 
to return
        (multiple-value-bind (val win)                     ;win is true 
if found
          (gethash args cache)                                ;is it in 
the cache?
          (if win                                                     
              val                                                      
;yes, return cache
              (setf (gethash args cache) (apply fn args))))))) ;no. do call

In my more clever moments it might be possible to create a new function
in the API domain called memoize that could be applied to other spad
functions. This isn't one of those moments, unfortunately.

\start
Date: Thu, 19 Nov 2009 06:54:10 -0800 (PST)
From: Tim Daly
To: list
Subject: Re: A bit of statistics trivia for Maple and	Mathematica

On Nov 19, 8:55am, "Nasser M. Abbasi" <n...@12000.org> wrote:
> I did a count of the number of functions in Mathematica 7 the other day, =
and
> I figured I should do one like this for Maple as well. So, here are some
> stats, maybe some might find them interesting.
>
> Mathematica 7:
> ============
> The System (i.e kernel) contains 1,920 functions.
> It comes with additional 35 standard packages that can be loaded using
> Get[];
> Total number of functions in the system and the packages combined is 2,56=
1
>
> Maple 12:
> =======
> System top level commands and what is called the standard libraries: 678
> It comes with additional 116 packages that can be loaded using with();
> Total number of functions in all of the above combined is 3,902
>
> For the complete listing showing package and what functions in it in both
> system are here
>
> Maple 12http://12000.org/my_notes/maple_functions/final.html
>
> Mathematica 7http://12000.org/my_notes/compare_mathematica/mma7_functions=
/process....
>
> I do not claim the above does not contain any errors. I am just a user.
>
> May be we can get a count for some of the other CAS systems out there?
>
> Yes, I know, counting number of functions can be misleading as an indication
> of the functionality provided by the system. As one function can be
> implemented to have many different options which ends up doing the work of
> 50 other smaller functions...but still, useful to get an idea about this.
>
> Notice, this is just for functions that come with the system out of the box.
> no third-party stuff.
>
> --Nasser

Well, the question is not well-formed in Axiom terms since names are
overloaded by inheritance. So + for Integers is not the same function
as + for Polynomials. However, a count of the user-exposed functions
available from the top level can be shown by the command
   )d op
with no chosen operation. The raw counts are:
 5434 Unique functions
 3052 Unique function names (e.g. + Integer, + Poly)

\start
Date: Thu, 19 Nov 2009 11:06:57 -0800 (PST)
From: Tim Daly
To: list
Subject: Re: A bit of statistics trivia for Maple and Mathematica

On Nov 19, 1:55pm, Roman Pearce <rpear...@gmail.com> wrote:
> On Nov 19, 5:55am, "Nasser M. Abbasi" <n...@12000.org> wrote:
>
> > I did a count of the number of functions in Mathematica 7 the other day=
, and
> > I figured I should do one like this for Maple as well.
> ...
> > Yes, I know, counting number of functions can be misleading as an indic=
ation
> > of the functionality provided by the system. As one function can be
> > implemented to have many different options which ends up doing the work=
 of
> > 50 other smaller functions...but still, useful to get an idea about thi=
s.
>
> My knowledge of both is limited, but Mathematica does seem to put a
> lot of its core functionality into options. For example, the Groebner
> Walk algorithm is an option to the GroebnerBasis command (not sure
> about FGLM). Maple has this as well, but there are also separate
> commands to run the FGLM or Groebner walk algorithms, assuming the
> input is a Groebner basis. I prefer this approach, but the option
> routine is not bad either because people complain all the time that
> Maple has too many commands :)
>
> What I would love to see is a side-by-side comparison of algorithms,
> organized into different domains, with some kind of subjective
> rankings for generality and speed. Call it "the world's longest
> flamewar" :) It would be useful and interesting though.

A side-by-side comparison of algorithms would be excellent.
Even a function-to-function rosetta-stone translation is great.
There are lots of fascinating things to be found.

I have compared the answers to integration for Axiom, Maple,
MMA, and Maxima on the issue of branch cuts. Curiously it
seems that Axiom and Maple make the same choice and
MMA and Maxima make the same choice, different from the
Axiom/Maple choice. Since the choice is somewhat arbitrary
it would be nice to have some flame in this area. In fact,
there seems to be no reason why this can't be a dynamic
choice.

Sage is claiming an effort to reimplement some of the
integration algorithms. I do not know in which camp they
will end up but hopefully it won't be a third camp.

How would such an effort be organized?

\start
Date: Thu, 19 Nov 2009 19:07:25 +0000
From: Bertfried Fauser
To: Tim Daly
Subject: Re: Function cache in Axiom (Memoizing)
Cc: Franz Lehner

thank you for the lisp code, I will store it and try it as soon as I
have functioning code for the symmetric functions.

\start
Date: Fri, 20 Nov 2009 17:10:28 +0000
From: Martin Baker
To: list
Subject: Re: grassman.spad

Bertfried,

Thank you for your reply.

I will correct the spelling of Grassmann (although without using =DF).

I have been thinking about the naming of the domain. I think it would be
better to use the name 'Multivector', which seems to me to represent what it
is, then the names Grassmann and Clifford can be reserved for the
multiplication types. What do you think? If you agree I will change it now.

No need to apologise about feature requests, I will keep adding to the list of
requirements on the webpage here:
http://www.euclideanspace.com/maths/standards/program/clifford/

I don't know how efficiently sparse multivectors will be stored, when an
instance of the multivector is created a PrimitiveArray of instances of a
field is created. The length of this PrimitiveArray is fixed n^2 so that the
position in the array indicates the type. I must admit that I have not looked
at PrimitiveArray to see what happens internally when a given index is not
set, but when a index that was not specifically set is then read then zero is
returned. I therefore assume that it takes space with instances of the field
set to zero.

I can think of a number of alternative designs, for instance, we could create
2 domains:
Multivector - contains multiple MultivectorElements, just the non-zero,
position not significant.
MultivectorElement - contains one instance of a field and an integer to
indicate the bases.

Or another design could be:
Multivector - contains just the non-zero MultivectorGrades, position not
significant.
MultivectorGrade - contains one instance of a grade, for instance a complete
vector or a complete bivector and so on.

On the requirement for symbolic indexes, I can't see how this can be done in
the current sort of design, which uses algorithms where the presence of e1,
e2, etc. are indicated by bits in a word? Would this require an approach more
like an equation solver? Where it is given a set of rules, rather than a fixed
algorithm?

I think the whole design may need to be changed in the future but I don't
think I have the expertise to do that yet. I would be interested to know the
sort of top level design approach you took to the maple package or your
current Hopf algebra work?

\start
Date: Fri, 20 Nov 2009 18:17:25 -0500
From: Tim Daly
To: list
Subject: Embedding Axiom (Hickey and fold/unfold)

There is an excellent talk by Rich Hickey about modelling time, 
identity, values,
perception, state, memory, etc.

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey


I think it adds quite a bit to the Embedded Axiom idea set. If we kept 
immutable
intermediate states we could easily run a  computation forward and backward.

We can combine that immutable idea with the fold/unfold idea from functional
programming. The idea is that you can do program proofs by expanding
a definition by unfolding and contracting a definition by folding.

http://www.cs.nott.ac.uk/~gmh/bib.html#semantics

The analog of this idea, at least as I perceive it, is the same as doing
operations on both sides of an equation. If we want to prove things
about a computation we could work backward from the result by
unfolding to some intermediate point, and forward from the input by
unfolding to the same intermediate point. If they match then there is
a fold/unfold path between them.

\start
Date: Sat, 21 Nov 2009 09:56:42 +0000
From: Martin Baker
To: list
Subject: Re: Embedding Axiom (Hickey and fold/unfold)

On Friday 20 November 2009 23:17:25 Tim Daly wrote:
> There is an excellent talk by Rich Hickey about modelling time, 
> identity, values,
> perception, state, memory, etc.

Tim,

While I was watching this talk I was wondering about the difference between 
the mainstream computing issues verses mathematical computing issues.

I get the impression that the mainstream issue, from this talk, is about how 
to run multiple algorithms in parallel?

If we are trying to solve a set of equations, is there a natural parallelism ? 
For the reasons discussed in the talk, should a rule based method be preferred 
wherever possible and explicit coding of algorithms be discouraged?

\start
Date: Sat, 21 Nov 2009 11:58:54 -0500
From: Tim Daly
To: Martin Baker
Subject: Embedding Axiom (Hickey and fold/unfold) and rule based programming

Martin Baker wrote:
> On Friday 20 November 2009 23:17:25 Tim Daly wrote:
>   
>> There is an excellent talk by Rich Hickey about modelling time, 
>> identity, values,
>> perception, state, memory, etc.
>>     
>
> Tim,
>
> While I was watching this talk I was wondering about the difference between 
> the mainstream computing issues verses mathematical computing issues.
>
> I get the impression that the mainstream issue, from this talk, is about how 
> to run multiple algorithms in parallel?
>
> If we are trying to solve a set of equations, is there a natural parallelism ? 
> For the reasons discussed in the talk, should a rule based method be preferred 
> wherever possible and explicit coding of algorithms be discouraged?
>
> Martin Baker
>
>   
Martin,

I don't know but I have some thoughts on the subject.

The first comment is that I have deep experience in rule based
programming (I was a team member on a commercial rule-based
programming product at IBM, we also built a huge expert system (FAME)
on a combination rule-based/knowedge-rep system I built (KROPS), one
of my two thesis topics was on the subject of rules, I use them in
work on our current Function Extraction project, etc)

I fear rule-based programming. It has the siren-song subtle appeal of
being very easy to state "WHEN this DO thisthing". When you get into a
problem, the solution is to add another rule to solve that particular
case. Ultimately, you end up in a situation like the dinosaur in the
tarpit... he can lift any leg but he cannot get out of the pit.

Rule based systems are subject to two general classes of
failure. Either they simply stop because no rule applies or they go
into an infinite loop because a prior state repeats.  I do not know of
a general way to verify and validate a rule based program (which was
the subject of the thesis). In fact, they are extremely hard to debug.
You can't use "print" statements or debuggers. Tracing is a swamp of
output. Every rule could be perfectly correct and the program is still
wrong (witness the dinosaur).

Worse yet, the whole system working system can become unhinged by the
addition of just one "obviously correct" rule.

The second problem with rule-based programming is that they are not
generally designed to be "theory-aware". For instance, you can write
rules in Axiom to do simplification by pattern matching. You could
write rules such as "divide each side by a constant". The problem is
"what if the constant is zero?".... Ok, we can fix that with a
rule... But now someone wants to use your simplification ruleset in a
different domain (e.g. a domain which is non-associative for
instance)... where does your ruleset assume associative?  How does
that assumption affect other rules? What if I want to apply "obviously
correct" formulas (e.g. x = sqrt(x^2))? But is this correct if x=-1?
Theory-aware systems need to be built on a consistent world based on
consistent axioms. This kind of effort feels like a "Principia"
approach which Godel undermined.

I don't think rules will operate correctly in parallel either
(although I have not tried).  For rules to operate effectively they
need to perceive (to use Hickey's term) the world in some consistent
state. But a parallel system will undermine that assumption. A
parallel dinosaur could be in a state with all of its feet out of the
tar since each process is "lifting" one foot, (the dinosaur
effectively "jumped") but the problem isn't solved.

Hickey is advocating pure functions which move from state to state,
which look a lot like rules but they can be much more theory aware and
they can be applied in a procedural way.

Curiously, Hickey does not define functions on Identities, claiming
they are an emergent property of states. But we do reason about
Identities also (they are meta-states, I guess). The river may not be
the same from moment to moment except before the river flows and after
the river dries up. The Identity of a river has a lifetime above and
beyond its states.

\start
Date: Sat, 21 Nov 2009 12:00:21 -0500
From: Tim Daly
To: Martin Baker
Subject: Embedding Axiom (Hickey and fold/unfold) and Reifying time

Martin Baker wrote:
> On Friday 20 November 2009 23:17:25 Tim Daly wrote:
>   
>> There is an excellent talk by Rich Hickey about modelling time, 
>> identity, values,
>> perception, state, memory, etc.
>>     
>
> Tim,
>
> While I was watching this talk I was wondering about the difference between 
> the mainstream computing issues verses mathematical computing issues.
>
> I get the impression that the mainstream issue, from this talk, is about how 
> to run multiple algorithms in parallel?
>
> If we are trying to solve a set of equations, is there a natural parallelism ? 
> For the reasons discussed in the talk, should a rule based method be preferred 
> wherever possible and explicit coding of algorithms be discouraged?
>
> Martin Baker
>
>   
Reifying time...

All of that being said, I think that there is a lot to learn from
Hickey. There is certainly a lot to be gained by writing in a
functional programming style (which Axiom is not using internally
now).

I found his idea of reifying time interesting. Time, according to
Hickey, is not a flow but an ordering on a set so you cannot measure
A-B but you can decide A<B.  I would use this "reify time" idea and
combine it with locking primitives. The lock variable could be a
timestamp. That would be unique and it would enable me to know if A
was changed before B. Access to the system clock could be made unique
so that no two timestamps can be equal unless they were performed by
the same process.

I really love his immutable data structures work. I am sorely tempted
to rewrite some of the internals to use these.

\start
Date: Sat, 21 Nov 2009 12:15:37 -0500
From: Tim Daly
To: Martin Baker
Subject: Embedding Axiom (Hickey and fold/unfold) Folding and generalization

Martin Baker wrote:
> On Friday 20 November 2009 23:17:25 Tim Daly wrote:
>   
>> There is an excellent talk by Rich Hickey about modelling time, 
>> identity, values,
>> perception, state, memory, etc.
>>     
>
> Tim,
>
> While I was watching this talk I was wondering about the difference between 
> the mainstream computing issues verses mathematical computing issues.

> I get the impression that the mainstream issue, from this talk, is about how 
> to run multiple algorithms in parallel?

> If we are trying to solve a set of equations, is there a natural
> parallelism ?  For the reasons discussed in the talk, should a rule
> based method be preferred wherever possible and explicit coding of
> algorithms be discouraged?

> Martin Baker
>
>   

Folding and Unfolding via pattern matching....

On the second point, which is the subject of folding and unfolding I
think that rules would be very useful here. Consider two statements
(function calls) that you would like to prove are equal. The
suggestion is to unfold them both by doing substitution of definitions
until they are both "the same".... where "the same" means that they
exhibit the same pattern with substitution e.g.

  (x^2) == (y^2) where x->y

If two functions unfold to the same pattern then we can re-fold them 
into each other.

I think that this might be a key step in Axiom's development. I am
trying to discover a way to prove Axiom programs correct. In
particular, it would be good to prove that the operations in the
domain Group actually follow from the "group axioms".  Can
mathematical group axioms be unfolded into domain Group operations?
Can ACL2 be used to prove that each unfolding step is correct? (insert
PhD students here).

The really clever trick is to do folding without knowing
anything. This would be a form of "generalization". You are trying to
find a way to recognize that a particular sequence of code "is a SORT
routine", for instance. After all, if you can recognize a "SWAP"
sequence, a "CONDITIONAL" sequence, and an "ITERATION" sequence, can
you know that

  SORT == ITERATED CONDITIONAL SWAP

This is a subject of a paper I'm going to present at HICSS in January.
An early video of the project ideas is at:
http://daly.axiom-developer.org/CONCORDIA.html

(The talk is in the context of function extraction and malware but the
ideas are motivated by my "prove computational math" struggles)

Generalization by folding would amount to finding the formula from an
instance.  The formula has much less information than the instances of
the formula so all types of generalization involve deliberately losing
information.

It is not possible (well...caveats) to generalize from a single
instance. The single instance can be generalized in many
directions. Multiple instances give a way to generalize by comparing
the instances to their fit in the generalized pattern.

\start
Date: Sat, 21 Nov 2009 22:44:44 +0000
From: Martin Baker
To: Tim Daly
Subject: Re: Embedding Axiom (Hickey and fold/unfold) Folding and generalization

Tim,

Thank you for these replies, I am learning a lot here.

I think it helps to get a wider perspective.

Part of what prompted my question is when I was thinking about how to
implement the exterior product I thought about possible options, for instan=
ce
rules:

<e1, e2=E2=80=A6en | ei/\ei=0, ei/\ej= -ej/\ei>

or an algorithm:

And(b1::SINT,b2::SINT) ~= 0 => z
c := c1 * c2
bz := Or(b1::SINT,b2::SINT)
for i in 0..n-1 | bit?(b1,i) repeat
  k := 0
  for j in i+1..n-1 | bit?(b1, j) repeat k := k+1
  for j in 0..i-1   | bit?(bz, j) repeat k := k+1
  if odd? k then c := -c
  z.bz := z.bz + c
z

or a multiplication table:

0      e1^e2
=2De1^e2 0

Out of these options, the rules just seems to be operating at a higher
leve= l?  In that it would seem relatively easy to translate from the
rules to the algorithm but a lot more difficult to go from the
algorithm to the rules (could Concordia do it?).  Also, unlike the
algorithm, there is no need to introduce the concept of time. I wonder
which type would be the best for making a test for equivalence?

I take your point that the rules are not necessarily better for parallel
processing and they don't scale up very well, I wonder if there would be some
way to get the best of all these approaches? lots of small rule bases or
something like that?

Another point is that there are no 'side effects' to this function but we are
trying to add one in by caching the multiplication table!

I don't have any answers but its interesting to speculate,

\start
Date: Sat, 21 Nov 2009 21:07:13 -0500
From: Tim Daly
To: Martin Baker
Subject: Re: Embedding Axiom (Hickey and fold/unfold) Folding and generalization

Martin Baker wrote:
> Tim,
>
> Thank you for these replies, I am learning a lot here.
>   

Yeah, Hickey is really an insightful chap. He sets the bar pretty high.

Many centuries ago I had to make the transition from using goto in
general to using goto in a structured form (Fortran did not have an
else clause on If).  The hard part was the mental shift needed to do
"structured programming" since I had to discover the correct,
disciplined control structures myself.  There were no textbooks as it
was a "new" idea that unstructured goto was bad.

Now Hickey basically said "do not use loops". Hmmm... that's gonna be
another stretch, although I see why he suggests it and I agree with
him. We have to learn to use map/fold/take/etc. in disciplined ways to
process Axiom's internal data.

And we need "reconsing" versions that return immutable but shared
copies of the list/vector/struct/etc., with versions that (per On
Lisp) embed properly.

And we need to write in pure function form (not a stretch because I
try to do this now).

And we need (per SICP) to write embedded layering, fully factored forms.

I think all of these ideas will greatly benefit Axiom's internal
restructuring, including possibly making a parallel implementation
much easier to achieve.  If nothing else at least the "coupling" will
drop considerably as we stop using special variables for maintaining
mutable global state.

\start
Date: Sat, 21 Nov 2009 21:08:40 -0500
From: Tim Daly
To: Martin Baker
Subject: Re: Embedding Axiom (Hickey and fold/unfold) Folding and generalization

Martin Baker wrote:
> I think it helps to get a wider perspective.
>
> Part of what prompted my question is when I was thinking about how to
> implement the exterior product I thought about possible options, for instance
> rules:
>
> <e1, e2=E2=80=A6en | ei/\ei=0, ei/\ej= -ej/\ei>
>
> or an algorithm:
>
> And(b1::SINT,b2::SINT) ~= 0 => z
> c := c1 * c2
> bz := Or(b1::SINT,b2::SINT)
> for i in 0..n-1 | bit?(b1,i) repeat
>   k := 0
>   for j in i+1..n-1 | bit?(b1, j) repeat k := k+1
>   for j in 0..i-1   | bit?(bz, j) repeat k := k+1
>   if odd? k then c := -c
>   z.bz := z.bz + c
> z
>
> or a multiplication table:
>
> 0      e1^e2
> -e1^e2 0

> Out of these options, the rules just seems to be operating at a
higher = level?  > In that it would seem relatively easy to translate
from the rules to th= e > algorithm but a lot more difficult to go
from the algorithm to the rule= s > (could Concordia do it?).  Also,
unlike the algorithm, there is no need= to > introduce the concept of
time. I wonder which type would be the best fo= r > making a test for
equivalence?

> I take your point that the rules are not necessarily better for parallel
> processing and they don't scale up very well, I wonder if there would be some
> way to get the best of all these approaches? lots of small rule bases or
> something like that?

> Another point is that there are no 'side effects' to this function but we are
> trying to add one in by caching the multiplication table!
>
> I don't have any answers but its interesting to speculate,
>  

I like the declarative form a lot, which would fit rules rather
well. I think you understand my feelings on rules being non-algebraic,
though, and I'd advise against it.

The table form could get very large (unless you only cache computed
entries).  The table form would also require some matching since "e1"
could be something more complex than a symbol.

I think that the procedural form gives you the most flexible version
sinc= e (a) it fits into the spad coding scheme and (b) allows you to
manipulate = the internal representations in efficient ways that can
"violate causality" within the function without being visible to the
user. It also gives you the opportunity to coerce to more specific
forms (like linear algebra forms) in special cases.

In addition, the coding form will force you to be explicit about the
categories that need to be defined. I think one of the key strengths
of Axiom is the organization of the system into categories. If you
started with Operads (per William Sit's comments) as categories and
derived your Grassmann/Clifford/Octonion forms in a disciplined way
then everyone wins. I will admit that this is VERY hard. I tried to do
this for the Infinite Group Theory area and failed. (Hardly a surprise
since I'm not an Infinite Group Theorist by any stretch of the
imagination.)

William may have some useful insights here as he is a mathematician and an
Axiom algebra author.

\start
Date: Sun, 22 Nov 2009 21:23:44 +0000
From: Bertfried Fauser
To: Martin Baker
Subject: Re: CliffordPackage

Hi Martin,

my posts to fricas-devel are currently rejected by google, so I write
this also directly to you.

> These changes make good sense to me. I will just note for the record that they
> change the user interface and would therefore break any applications already
> using CliffordAlgebra but the changes are important enough to justify that.

Since the Clifford code was broken from the outset, the only place
where it actually shows up is the AXIOM book, which would then also
need an update,
I doubt threre is any other place (and I will see if I can chack that,
a grep over the code should do, I found CliffordAlgebra mentioned in

* browse.daase
* category.daase
* operation.daase
* compres.daase
* interp.daase
* exposed.lsp.pamphlet.svn-base
* clifford.spad.pamphlet
* abbrevs.input
* extract-spad.mk
* comdb.text
* libdb.text
* DEPENDENTS.DAASE
* CLIF.spad
* /USERS.DAASE/index.KA
* hyper/pages/.svn/text-base/CLIF.ht.svn-base
* hyper/pages/.svn/text-base/QUAT.ht.svn-base
* hyper/pages/QUAT.ht
* hyper/pages/QUAT2.ht
* hyper/pages/xmpexp.ht
* hyper/pages/ug02.ht
* hyper/pages/ug13.ht
* hyper/pages/CLIF.ht
* input/clifford.input.pamphlet
* paste/CLIF.input
* paste/CLIF.phts
* padhelp/Quaternion.help
* spadhelp/CliffordAlgebra.help
* topics.data
* command.list
)

I am not a grep expert, so things may have sliped through, otherwise I
think the above given list proves that CliffordAlgebra is not used by
any other package.

> OK, I will check if division or swapping of operands is done.

That was just a feature request, forget about noncommutytive rings at
the moment.

> the domain constructor as 'List List Ring', 'SquareMatrix Ring' or create a
> custom domain called BilinearForm ? Would I be correct in thinking that Matrix
> or a custom domain would not add much value so I might as well use a List of
> Lists for efficiency?

I would be happy with List List Ring, but since its a map between
vector spaces or modules, some popele on the list (if this mail gets
through) will have different oppinions. A square matrix could do, but
actually you only want to read out the elements, nothing else is done
with this array, so I would look (ask on teh list) what data structure
has the best random acess performance, List List is possibly slow, but
on the other hand such arrays will be in practice something like up to
10x10, so no hassle.

> Yes please, this would be very helpful, no rush though, as it will take me
> some time to absorb all this good information that you have given me.

OK, as soon as my maple is up again, I'll produce some test cases for you
(and we need to do AXIOM test cases for Tim ;-))

\start
Date: Mon, 23 Nov 2009 15:13:05 +0100
From: Martin Rubey
To: Bertfried Fauser
Subject: re: CliffordPackage
Cc: Martin Baker

Bertfried Fauser writes:


> I doubt threre is any other place (and I will see if I can chack that,
> a grep over the code should do, I found CliffordAlgebra mentioned in
>
> * browse.daase
> * category.daase
> * operation.daase
> * compres.daase
> * interp.daase
> * exposed.lsp.pamphlet.svn-base
> * clifford.spad.pamphlet
> * abbrevs.input
> * extract-spad.mk
> * comdb.text
> * libdb.text
> * DEPENDENTS.DAASE
> * CLIF.spad
> * /USERS.DAASE/index.KA
> * hyper/pages/.svn/text-base/CLIF.ht.svn-base
> * hyper/pages/.svn/text-base/QUAT.ht.svn-base
> * hyper/pages/QUAT.ht
> * hyper/pages/QUAT2.ht
> * hyper/pages/xmpexp.ht
> * hyper/pages/ug02.ht
> * hyper/pages/ug13.ht
> * hyper/pages/CLIF.ht
> * input/clifford.input.pamphlet
> * paste/CLIF.input
> * paste/CLIF.phts
> * padhelp/Quaternion.help
> * spadhelp/CliffordAlgebra.help
> * topics.data
> * command.list
> )
>
> I am not a grep expert, so things may have sliped through, otherwise I
> think the above given list proves that CliffordAlgebra is not used by
> any other package.

It's not a proof, unfortunately (only a strong hint), because the
compiler tries to be smart: packages and domains do not necessarily need
to be mentioned, if the name of the operation or the types of the
arguments determine the operation uniquely.

\start
Date: Wed, 25 Nov 2009 00:27:33 -0500
From: Tim Daly
To: list
Subject: A new command ")describe"

There is a new command

  )describe [category | domain | package ] <name> [ | internal ]

You can ask for the comments from the algebra source code
which are contained in the Description: section at the top
of each Category, Domain, or Package.

You can type
 
  )help describe for the man page

Details for writing the Description: section for new algebra code
are in Volume 2 (User Guide)



For example,


(1) -> )describe domain AlgebraGivenByStructuralConstants

 
AlgebraGivenByStructuralConstants implements finite rank algebras
over a commutative ring, given by the structural constants gamma with
respect to a fixed basis [a1,..,an], where gamma is an n-vector of n
by n matrices [(gammaijk) for k in 1..rank()] defined by ai * aj =
gammaij1 * a1 + ... + gammaijn * an. The symbols for the fixed basis
have to be given as a list of symbols.




You can also ask for a very detailed description of the internal
structure (only for Domains and Packages). For instance:


(1) -> )describe domain AlgebraGivenByStructuralConstants internal
----------------Template-----------------
 5 lazy DirectProduct(local #2,local #1)
 6 lazy local #1
 7 lazy local #2
 8 lazy local #3
 9 lazy local #4
 10 lazy QUOTE Rep
 11 lazy Union($,QUOTE failed)
 12 lazy FiniteRankNonAssociativeAlgebra&($$,local #1)
 13 latch recip : % -> Union(%,QUOTE failed) from 
FiniteRankNonAssociativeAlgebra&($$,local #1)
 14 fun  ALGSC;recip;$U;1
 15 lazy Matrix local #1
 16 lazy SquareMatrix(local #2,local #1)
 17 latch coerce : % -> Matrix local #1 from SquareMatrix(local #2,local #1)
 18 latch apply : (Matrix local #1,%) -> % from %
 19 fun  ALGSC;*;Sm2$;2
 20 lazy Vector local #1
 21 latch directProduct : Vector local #1 -> % from QUOTE Rep
 22 fun  ALGSC;coerce;V$;3
 23 lazy Vector Matrix local #1
 24 fun  ALGSC;structuralConstants;V;4
 25 lazy List local #1
 26 latch entries : % -> List local #1 from QUOTE Rep
 27 latch vector : List local #1 -> % from Vector local #1
 28 fun  ALGSC;coordinates;$V;5
 29 lazy Integer
 30 lazy Vector $$
 31 latch maxIndex : % -> Integer from Vector $$
 32 latch 0 : () -> % from local #1
 33 lazy NonNegativeInteger
 34 latch new : (NonNegativeInteger,NonNegativeInteger,local #1) -> % 
from Matrix local #1
 35 latch elt : (%,Integer) -> $$ from Vector $$
 36 latch setColumn! : (%,Integer,Vector local #1) -> % from Matrix local #1
 37 lazy Union(Vector local #1,QUOTE failed)
 38 lazy Record(particular: Union(Vector local #1,QUOTE failed),basis: 
List Vector local #1)
 39 lazy LinearSystemMatrixPackage(local #1,Vector local #1,Vector local 
#1,Matrix local #1)
 40 latch solve : (Matrix local #1,Vector local #1) -> 
Record(particular: Union(Vector local #1,QUOTE failed),basis: List 
Vector local #1) from LinearSystemMatrixPackage(local #1,Vector local 
#1,Vector local #1,Matrix local #1)
 41 lazy Boolean
 42 latch zero? : % -> Boolean from local #1
 43 lazy Vector $
 44 fun  ALGSC;basis;V;7
 45 lazy (local #1 -> Boolean)
 46 latch every? : ((local #1 -> Boolean),%) -> Boolean from Vector local #1
 47 fun  ALGSC;coordinates;$VV;6
 48 lazy PositiveInteger
 49 latch unitVector : PositiveInteger -> % from QUOTE Rep
 50 fun  ALGSC;someBasis;V;8
 51 fun  ALGSC;rank;Pi;9
 52 latch elt : (%,Integer) -> local #1 from QUOTE Rep
 53 fun  ALGSC;elt;$IR;10
 54 latch zero? : % -> Boolean from QUOTE Rep
 55 lazy OutputForm
 56 latch coerce : % -> OutputForm from local #1
 57 latch 1 : () -> % from local #1
 58 latch ?=? : (%,%) -> Boolean from local #1
 59 lazy Symbol
 60 lazy List Symbol
 61 latch elt : (%,Integer) -> Symbol from List Symbol
 62 latch coerce : % -> OutputForm from Symbol
 63 latch ?*? : (%,%) -> % from OutputForm
 64 latch ?+? : (%,%) -> % from OutputForm
 65 lazy ((OutputForm,OutputForm) -> OutputForm)
 66 lazy List OutputForm
 67 latch reduce : (((OutputForm,OutputForm) -> OutputForm),%) -> 
OutputForm from List OutputForm
 68 fun  ALGSC;coerce;$Of;11
 69 latch new : (NonNegativeInteger,local #1) -> % from Vector local #1
 70 latch ?*? : (%,%) -> % from local #1
 71 latch elt : (%,Integer) -> Matrix local #1 from Vector Matrix local #1
 72 latch elt : (%,Integer,Integer) -> local #1 from Matrix local #1
 73 latch ?+? : (%,%) -> % from local #1
 74 latch setelt : (%,Integer,local #1) -> local #1 from Vector local #1
 75 fun  ALGSC;*;3$;12
 76 latch ?-? : (%,%) -> % from local #1
 77 lazy Void
 78 lazy String
 79 latch messagePrint : String -> Void from OutputForm
 80 fun  ALGSC;alternative?;B;13
 81 fun  ALGSC;associative?;B;14
 82 fun  ALGSC;antiAssociative?;B;15
 83 fun  ALGSC;commutative?;B;16
 84 fun  ALGSC;antiCommutative?;B;17
 85 fun  ALGSC;leftAlternative?;B;18
 86 fun  ALGSC;rightAlternative?;B;19
 87 fun  ALGSC;flexible?;B;20
 88 fun  ALGSC;lieAdmissible?;B;21
 89 latch ?*? : (PositiveInteger,%) -> % from local #1
 90 latch recip : % -> Union(%,QUOTE failed) from local #1
 91 fun  ALGSC;jordanAdmissible?;B;22
 92 fun  ALGSC;jordanAlgebra?;B;23
 93 fun  ALGSC;jacobiIdentity?;B;24
 94 lazy SparseUnivariatePolynomial Polynomial local #1
 95 lazy Record(particular: $,basis: List $)
 96 lazy Union(Record(particular: $,basis: List $),QUOTE failed)
 97 lazy SparseUnivariatePolynomial local #1
 98 lazy List Vector local #1
 99 lazy List Polynomial local #1
 100 lazy SingleInteger
----------Complete Ops----------------
 ?~=? : (%,%) -> Boolean missing
 zero? : % -> Boolean missing
 unit : () -> Union(%,QUOTE failed) missing  if #1 has IntegralDomain
 subtractIfCan : (%,%) -> Union(%,QUOTE failed) missing
 structuralConstants : () -> Vector Matrix local #1 
ALGSC;structuralConstants;V;4
 structuralConstants : Vector % -> Vector Matrix local #1 missing
 someBasis : () -> Vector % ALGSC;someBasis;V;8
 sample : () -> % missing
 rightUnits : () -> Union(Record(particular: %,basis: List %),QUOTE 
failed) missing  if #1 has IntegralDomain
 rightUnit : () -> Union(%,QUOTE failed) missing  if #1 has IntegralDomain
 rightTraceMatrix : () -> Matrix local #1 missing
 rightTraceMatrix : Vector % -> Matrix local #1 missing
 rightTrace : % -> local #1 missing
 rightRegularRepresentation : % -> Matrix local #1 missing
 rightRegularRepresentation : (%,Vector %) -> Matrix local #1 missing
 rightRecip : % -> Union(%,QUOTE failed) missing  if #1 has IntegralDomain
 rightRankPolynomial : () -> SparseUnivariatePolynomial Polynomial local 
#1 missing  if #1 has Field
 rightPower : (%,PositiveInteger) -> % missing
 rightNorm : % -> local #1 missing
 rightMinimalPolynomial : % -> SparseUnivariatePolynomial local #1 
missing  if #1 has IntegralDomain
 rightDiscriminant : () -> local #1 missing
 rightDiscriminant : Vector % -> local #1 missing
 rightCharacteristicPolynomial : % -> SparseUnivariatePolynomial local 
#1 missing
 rightAlternative? : () -> Boolean ALGSC;rightAlternative?;B;19
 represents : Vector local #1 -> % missing
 represents : (Vector local #1,Vector %) -> % missing
 recip : % -> Union(%,QUOTE failed) ALGSC;recip;$U;1  if #1 has 
IntegralDomain
 rank : () -> PositiveInteger ALGSC;rank;Pi;9
 powerAssociative? : () -> Boolean missing
 plenaryPower : (%,PositiveInteger) -> % missing
 noncommutativeJordanAlgebra? : () -> Boolean missing
 lieAlgebra? : () -> Boolean missing
 lieAdmissible? : () -> Boolean ALGSC;lieAdmissible?;B;21
 leftUnits : () -> Union(Record(particular: %,basis: List %),QUOTE 
failed) missing  if #1 has IntegralDomain
 leftUnit : () -> Union(%,QUOTE failed) missing  if #1 has IntegralDomain
 leftTraceMatrix : () -> Matrix local #1 missing
 leftTraceMatrix : Vector % -> Matrix local #1 missing
 leftTrace : % -> local #1 missing
 leftRegularRepresentation : % -> Matrix local #1 missing
 leftRegularRepresentation : (%,Vector %) -> Matrix local #1 missing
 leftRecip : % -> Union(%,QUOTE failed) missing  if #1 has IntegralDomain
 leftRankPolynomial : () -> SparseUnivariatePolynomial Polynomial local 
#1 missing  if #1 has Field
 leftPower : (%,PositiveInteger) -> % missing
 leftNorm : % -> local #1 missing
 leftMinimalPolynomial : % -> SparseUnivariatePolynomial local #1 
missing  if #1 has IntegralDomain
 leftDiscriminant : () -> local #1 missing
 leftDiscriminant : Vector % -> local #1 missing
 leftCharacteristicPolynomial : % -> SparseUnivariatePolynomial local #1 
missing
 leftAlternative? : () -> Boolean ALGSC;leftAlternative?;B;18
 latex : % -> String missing
 jordanAlgebra? : () -> Boolean ALGSC;jordanAlgebra?;B;23
 jordanAdmissible? : () -> Boolean ALGSC;jordanAdmissible?;B;22
 jacobiIdentity? : () -> Boolean ALGSC;jacobiIdentity?;B;24
 hash : % -> SingleInteger missing
 flexible? : () -> Boolean ALGSC;flexible?;B;20
 elt : (%,Integer) -> local #1 ALGSC;elt;$IR;10
 coordinates : % -> Vector local #1 ALGSC;coordinates;$V;5
 coordinates : Vector % -> Matrix local #1 missing
 coordinates : (Vector %,Vector %) -> Matrix local #1 missing
 coordinates : (%,Vector %) -> Vector local #1 ALGSC;coordinates;$VV;6
 convert : % -> Vector local #1 missing
 convert : Vector local #1 -> % missing
 conditionsForIdempotents : () -> List Polynomial local #1 missing
 conditionsForIdempotents : Vector % -> List Polynomial local #1 missing
 commutator : (%,%) -> % missing
 commutative? : () -> Boolean ALGSC;commutative?;B;16
 coerce : Vector local #1 -> % ALGSC;coerce;V$;3
 coerce : % -> OutputForm ALGSC;coerce;$Of;11
 basis : () -> Vector % ALGSC;basis;V;7
 associatorDependence : () -> List Vector local #1 missing  if #1 has 
IntegralDomain
 associator : (%,%,%) -> % missing
 associative? : () -> Boolean ALGSC;associative?;B;14
 apply : (Matrix local #1,%) -> % looked up
 antiCommutator : (%,%) -> % missing
 antiCommutative? : () -> Boolean ALGSC;antiCommutative?;B;17
 antiAssociative? : () -> Boolean ALGSC;antiAssociative?;B;15
 alternative? : () -> Boolean ALGSC;alternative?;B;13
 0 : () -> % missing
 ?=? : (%,%) -> Boolean missing
 -? : % -> % missing
 ?-? : (%,%) -> % missing
 ?+? : (%,%) -> % missing
 ?**? : (%,PositiveInteger) -> % missing
 ?*? : (SquareMatrix(local #2,local #1),%) -> % ALGSC;*;Sm2$;2
 ?*? : (local #1,%) -> % missing
 ?*? : (%,local #1) -> % missing
 ?*? : (%,%) -> % ALGSC;*;3$;12
 ?*? : (Integer,%) -> % missing
 ?*? : (NonNegativeInteger,%) -> % missing
 ?*? : (PositiveInteger,%) -> % missing
----------------Atts-----------------
 0 unitsKnown if #1 has IntegralDomain
 1 leftUnitary
 2 rightUnitary
----------------Preds-----------------
 1 #1 has Field
 2 #1 has IntegralDomain
----------------Cats-----------------
 0 FramedNonAssociativeAlgebra local #1 package
 1 FiniteRankNonAssociativeAlgebra local #1 package
 2 NonAssociativeAlgebra local #1 package
 3 Module local #1 package
 4 BiModule(local #1,local #1)
 5 NonAssociativeRng package
 6 LeftModule SquareMatrix(local #2,local #1)
 7 RightModule local #1
 8 LeftModule local #1
 9 AbelianGroup package
 10 CancellationAbelianMonoid
 11 AbelianMonoid package
 12 AbelianSemiGroup package
 13 Monad package
 14 SetCategory package
 15 BasicType package
 16 CoercibleTo OutputForm
----------------Data------------------
Operation data from slot 1

#(~= 197 |zero?| 203 |unit| 208 |subtractIfCan| 212 
|structuralConstants| 218 |someBasis| 227 |sample| 231 |rightUnits| 235 
|rightUnit| 239 |rightTraceMatrix| 243 |rightTrace| 252 
|rightRegularRepresentation| 257 |rightRecip| 268 |rightRankPolynomial| 
273 |rightPower| 277 |rightNorm| 283 |rightMinimalPolynomial| 288 
|rightDiscriminant| 293 |rightCharacteristicPolynomial| 302 
|rightAlternative?| 307 |represents| 311 |recip| 322 |rank| 327 
|powerAssociative?| 331 |plenaryPower| 335 
|noncommutativeJordanAlgebra?| 341 |lieAlgebra?| 345 |lieAdmissible?| 
349 |leftUnits| 353 |leftUnit| 357 |leftTraceMatrix| 361 |leftTrace| 370 
|leftRegularRepresentation| 375 |leftRecip| 386 |leftRankPolynomial| 391 
|leftPower| 395 |leftNorm| 401 |leftMinimalPolynomial| 406 
|leftDiscriminant| 411 |leftCharacteristicPolynomial| 420 
|leftAlternative?| 425 |latex| 429 |jordanAlgebra?| 434 
|jordanAdmissible?| 438 |jacobiIdentity?| 442 |hash| 446 |flexible?| 451 
|elt| 455 |coordinates| 461 |convert| 483 |conditionsForIdempotents| 493 
|commutator| 502 |commutative?| 508 |coerce| 512 |basis| 522 
|associatorDependence| 526 |associator| 530 |associative?| 537 |apply| 
541 |antiCommutator| 547 |antiCommutative?| 553 |antiAssociative?| 557 
|alternative?| 561 |Zero| 565 = 569 - 575 + 586 ** 592 * 598)
Information vector has 640 entries
     0  |     1    12    11     0    13     1    16    15     0    17
    10  |     2     0     0    15     0    18     1    10     0    20
    20  |    21     1    10    25     0    26     1    20     0    25
    30  |    27     1    30    29     0    31     0     6     0    32
    40  |     3    15     0    33    33     6    34     2    30     2
    50  |     0    29    35     3    15     0     0    29    20    36
    60  |     2    39    38    15    20    40     1     6    41     0
    70  |    42     2    20    41    45     0    46     1    10     0
    80  |    48    49     2    10     6     0    29    52     1    10
    90  |    41     0    54     1     6    55     0    56     0     6
   100  |     0    57     2     6    41     0     0    58     2    60
   110  |    59     0    29    61     1    59    55     0    62     2
   120  |    55     0     0     0    63     2    55     0     0     0
   130  |    64     2    66    55    65     0    67     2    20     0
   140  |    33     6    69     2     6     0     0     0    70     2
   150  |    23    15     0    29    71     3    15     6     0    29
   160  |    29    72     2     6     0     0     0    73     3    20
   170  |     6     0    29     6    74     2     6     0     0     0
   180  |    76     1    55    77    78    79     2     6     0    48
   190  |     0    89     1     6    11     0    90     2     0    41
   200  |     0     0     1     1     0    41     0     1     0     2
   210  |    11     1     2     0    11     0     0     1     0     0
   220  |    23    24     1     0    23    43     1     0     0    43
   230  |    50     0     0     0     1     0     2    96     1     0
   240  |     2    11     1     0     0    15     1     1     0    15
   250  |    43     1     1     0     6     0     1     1     0    15
   260  |     0     1     2     0    15     0    43     1     1     2
   270  |    11     0     1     0     1    94     1     2     0     0
   280  |     0    48     1     1     0     6     0     1     1     2
   290  |    97     0     1     0     0     6     1     1     0     6
   300  |    43     1     1     0    97     0     1     0     0    41
   310  |    86     1     0     0    20     1     2     0     0    20
   320  |    43     1     1     2    11     0    14     0     0    48
   330  |    51     0     0    41     1     2     0     0     0    48
   340  |     1     0     0    41     1     0     0    41     1     0
   350  |     0    41    88     0     2    96     1     0     2    11
   360  |     1     0     0    15     1     1     0    15    43     1
   370  |     1     0     6     0     1     1     0    15     0     1
   380  |     2     0    15     0    43     1     1     2    11     0
   390  |     1     0     1    94     1     2     0     0     0    48
   400  |     1     1     0     6     0     1     1     2    97     0
   410  |     1     0     0     6     1     1     0     6    43     1
   420  |     1     0    97     0     1     0     0    41    85     1
   430  |     0    78     0     1     0     0    41    92     0     0
   440  |    41    91     0     0    41    93     1     0   100     0
   450  |     1     0     0    41    87     2     0     6     0    29
   460  |    53     1     0    20     0    28     1     0    15    43
   470  |     1     2     0    15    43    43     1     2     0    20
   480  |     0    43    47     1     0    20     0     1     1     0
   490  |     0    20     1     0     0    99     1     1     0    99
   500  |    43     1     2     0     0     0     0     1     0     0
   510  |    41    83     1     0     0    20    22     1     0    55
   520  |     0    68     0     0    43    44     0     2    98     1
   530  |     3     0     0     0     0     0     1     0     0    41
   540  |    81     2     0     0    15     0    18     2     0     0
   550  |     0     0     1     0     0    41    84     0     0    41
   560  |    82     0     0    41    80     0     0     0     1     2
   570  |     0    41     0     0     1     1     0     0     0     1
   580  |     2     0     0     0     0     1     2     0     0     0
   590  |     0     1     2     0     0     0    48     1     2     0
   600  |     0    16     0    19     2     0     0     6     0     1
   610  |     2     0     0     0     6     1     2     0     0     0
   620  |     0    75     2     0     0    29     0     1     2     0
   630  |     0    33     0     1     2     0     0    48     0     1
----------------Size------------------
infovec total = 4434 BYTES
template    = 2064
operations  = 556 (complete)
attributes  = 6
categories  = 528
data vector = 1280
number of function slots (one extra node) = 24
number of latch slots (2 extra nodes) = 35
number of lazy slots (no extra nodes) = 37
size of domain vectors = 101 slots
domain size = 5562 BYTES
cost per instantiation = 1536 BYTES
(1) ->

\start
Date: Wed, 25 Nov 2009 00:43:22 -0500
From: Tim Daly
To: list
Subject: Axiom release for November 2009

Summary: November 2009 release

The major changes are:
   A new )describe command, boot language removal, and more motion
   toward a fully literate system.

The )describe command was added.

   The )describe function was added to Volume 5 (Interpreter)
   The )describe function was documented in Volume 2 (Users Guide)
   The Description field for the Categories, Domains, and Packages
   were cleanup up and reformatted in Volumes 10.2 (Categories)
   10.3 (Domains) and 10.4 (Packages)
 

Boot Language removal

    All of the boot-converted lisp files were reformatted from their
    compiler generated output. These files are being merged into
    Volume 5 (Interpreter) and Volume 9 (Compiler) as appropriate.
    This work will continue for the next few releases.

    All or portions of the following files were merged into
    Volume 5 (Interpreter):
      astr, cstream.lisp, dq, incl, int-top, i-syscmd, msg, nci,
      obey, osyscmd, parini, patches, pile, scan

    The src/boot subdirectory is gone, including the files:
      Makefile, boot-proclaims, boothdr, bootload, btincl2, btpile2,
      btscan2, ccl-bootsys, ccl-depsys.lsp, exports.lisp, npextras, ptyout,
      tyextra, typars, typrops, tytree1, sys-pkg, vmlisp, ptrees, wi2

    The bootsys image is no longer part of the build process


Patch ports from Fricas and Open-Axiom

    The Tuples patch was picked up and applied.

    The SXHASH function is the hash default in SetCategory

    The function ListOfTerms was renamed to listOfTerms


Input file changes

    New input files have been added to show how to compute
    results using Axiom or to create regression tests for fixes:
      complexfactor, rubey, zimmbron, branchcut, cachedf, finitegraph,
      newtonlisp, nonlinhomodiffeq, distexpr, numericgamma, donsimple
      solveperf, tuplebug, unit-macro, testprob, unittest2

    lexp was removed and moved to the LEXP algebra file

    dop and gstbl had minor fixes

New Help files and Function examples were added

    There are new help files:
      describe, AlgebraicallyClosedField, RationalFunctionSum,
      RadicalSolvePackage, PartialFractionPackage, Product,
      OrderedFreeMonoid

Website update:

  The developer.html page was rewritten. An old Scratchpad group
  photo was added to the site.

  Work continues on re-hosting the axiom-developer.org domain.

  We now own axiom-developer.com and axiom-developer.net which will
  be retargetted to the new host as soon as it is available

Interpreter changes:

    Axiom will sit in a single package in the near future.
    The VMLISP package was partially removed from the system.
    Work continues on this path.

    The util.ht file is created earlier in the parallel build
    so there are fewer compiler messages about documentation.

Research:
 
    A Cohen algebra domain is being developed to enable symbolic
    manipulation of expressions with explanations and controlled
    simplification.

\start
Date: Wed, 25 Nov 2009 11:54:37 +0000
From: Martin Baker
To: list
Subject: Spad for OO Programmers

I am still trying to properly understand the Spad language properly, what I 
would like is a introduction for people who have object oriented experience. 
In other words to point out the differences that may confuse and also a crib 
sheet for the syntax.

I have not yet found such a document (by the way, the link to st-andrews 
website on Axiom documentation page is broken).

Since I have not found this I have been making some notes for my own benefit:
http://www.euclideanspace.com/maths/standards/program/spad/
Any corrections welcome.

\start
Date: Thu, 26 Nov 2009 00:49:31 -0500
From: Tim Daly
To: Martin Baker, Bertfried Fauser, Ralf Hemmecke, Arthur Ralfs
Subject: large PDFs

You might be pleasantly surprised that the Axiom PDFs
actually are heavily cross-referenced. If you have a
recent version of any pdf viewer you'll see that there
are hyperlinks in the pdf. The index is also hyperlinked
so you can look things up in the index and jump to the
most interesting point.

The algebra PDFs (volume 10.2, 10.3, and 10.4) are all
hyperlinked. This makes it easy to find algebra. In
addition, the two algebra graphs on the webpage are
hyperlinked into the correct pdfs so you can walk the
algebra graph and see the corresponding code.

The Interpreter (volume 5) even includes both forward
(calls) and backward hyperlinks (called by) so you can
find callers and callees making it very easy to walk
the lisp code. The compiler (volume 9) will be the same.

The hypertex pages (volume 7.1) has pictures of the pages
that the code describes so you can "hyperdoc browse" in
the pdf viewer.

Eventually all of the volumes will be fully hyperlinked.
The Jenks book (volume 0) and the tutorial (volume 1) are
"in the queue".

Yes, the PDFs are large but they are easy to navigate.

\start
Date: Thu, 26 Nov 2009 17:11:17 +0000
From: Martin Baker
To: Bertfried Fauser
Subject: Re: Clifford Algebra examples:

Bertfried,

Thanks this looks very useful.

Can I ask about the definitions of the involutions:

gradeInvolution == reversion? sign=(-1)^(d(d-1)/2) symbol= ~
Cliplus clirev == ? symbol=multiply by pseudoscalar? symbol=
Clifford conjugation: scalar part minus non-scalar part? symbol=

I know these are wrong but I just made a guess!

I expect I had better ignore the Spinors for now although I am curious about 
how they should be added on later. Upto now I have thought of spinors as an 
even subalgebra of Clifford algebras? (rotation by 2*pi multiplies by -1) but 
this does not seem to be the case here? Would spinors require a new type of 
multiplication or a new domain?

\start
Date: Thu, 26 Nov 2009 18:29:16 +0000
From: Bertfried Fauser
To: Martin Baker
Subject: Re: Clifford Algebra examples:
Cc: Rafal Ablamowicz

Dear Martin,

> Can I ask about the definitions of the involutions:
Yes, please ask, I'll answer if I know and time permits.

> gradeInvolution == reversion? sign=(-1)^(d(d-1)/2) symbol= ~
> Cliplus clirev == ? symbol=multiply by pseudoscalar? symbol=
> Clifford conjugation: scalar part minus non-scalar part? symbol=

The involutions you give are again assuming a diagonal (orthonormal)
basis for the quadratic (bilinear) form. Since this is bad for applications,
it has to be avoided. Of course if you know you are in a diagonal basis
you can use faster algorithms (like defining a cmulDiag)

Grade involution:
Any (Grassmann-) Clifford algebra is built up from a base space V (of dimension
dim V = n) You have two natural transformations on V which generalize
to the whole space W=/\V of dim W = 2^n.
a) The identity map (does nothing on W)
b) The map sending every vector v \in V to its additiove inverse (negative)
    barV : V -> V :: v |--> -v
    This will send any basis vector to its negative (regardless of the bilinear
    form). So iff your basis is like the grBasis :=[Id, e1, e2, e1we2, e3,...]
    barW will send all elements eiw..wej to (-)^number of basis
elements eiw..wej
c) Iff the basis is more general (like in the case with an antisymmetric part in
    the bilinear form, you always fing a new basis (inhomgeous in the old
    generators) such that the involution does the trick for the new
basis elements.
    Eg: B:= matrix [[1,q],[-q ,1]] you would liek tto define a new
Grassmann basis
   grBasWf = [Id, f1(=e1),f2(=e2), f1wf2 ( f1wf2-q*Id), f3 (=e3),...] etc
   In this case you will see that the new basis is graded (only even or odd
   elements appear) so the involution still works as expected.

Whta you technically do is the following:
* Take a vector space V
* build the free algebra over it, that is the tensor algebra TV, its product is
   concatenation it is noncommutative
* You are only intersted in antisymmetric tensors, hence factor out
all symmetric
   ones. That is you identify all terms of the form
   (v1 (x)... (x) vi (x) vi (x) ... (x) vd) = 0
   [One can check that this is a graded ideal I_gr and one can therefor factor
  the tensor algebra TV/I_gr = /\V
  (for the generators this means you impose ei^2=0. From that you conclude that
   0=(ei+ej)^(x)2 = ei^2+ei (x) ej + ej (x) ei + ej^2
     = ei (x) ej + ej (x) ej
   calling the projectet tensor /\ you get
   ei /\ ej = -  ej /\ ei )

Reversion:
   This is quite different. The reversion needs to know about the Clifford
   multiplication, so its actually defined in the Clifford basis
   cliBas:= [Id, e(1), e(2), e(12):=e(1)*e(2), e(3),... ]
   and it reverses the order of the Clifford multiplication (which depends on
   the quadratic (bilinear) form. Hence you have (eij) Grassmann ,
e(ij) Clifford
   basis elements)
   reversion e12 = reversion (e(12)-B(e1,e2)*Id) = e(21)-B(e1,e2)*Id
       = e2/\e1 +(B(e2,e1)-B(e1,e2))*Id
       = -e12 - 2F(e1,e2)
   where F(e1,e2) is the antisymmetric part of B, hence this difficulty will
   _only_ appear when there is an antisymmetric part. Since not many people
   have looked at that, its rarely described in literature, but see my
joint papers
   with Rafal Ablamowicz:
#
Mathematics of CLIFFORD - A Maple package for Clifford and Grassmann algebras
Rafal Ablamowicz, B. Fauser: Adv. in Appl. Clifford Alg. 15 No. 2, 2005:157-181

#
arXiv:math-ph/0212032
Clifford and Grassmann Hopf algebras via the BIGEBRA package for Maple
Rafal Ablamowicz, B. Fauser: Comp. Physics Comm. 170, 2005:115--130
  available from the arXiv (or I can send you pdf's).

Technically the reversion comes from the dualising the vector space V -> V*
and building the tensor algebra over the dualised vector space V* and
identifying
V* ~= V canonically. The project onto antisymmetric tensors. You see
that the symmetric group acts on tensors by permuting the 'list' ov
vectors a tensor is forms of. The reverison is the unique larget
permutation (usually called w)
with the most inversions (in reduced notation). So reversion is not
just adding a sign, its really reversing the list of all vectors
(generators) and then reorder them using the antisymmetry and collect
the minus signs.

conjugation is just the composition of recerion and grade involution:

conjugation x == reversion gradeinvolution x
                      (== gradeinvolution reversion x) -- oder does not matter

So first thing is to implement:

Grassmann wedge
Grassmann meet (note that the meet is a sort of wedge but with the roles
  of the grades inverted)
Clifford product for a bilinear form (this is not hard, its the same routine
which calculates the Clifford product for a symmetric bilinear form or an
arbitrary bilinear form)

> I expect I had better ignore the Spinors for now although I am curious about
> how they should be added on later.

Indeed, forget about them for now. I just added the spinor things to
make sure there are matrix analogs which show that the algebra
computes correctly. It is
just a way to convince yourself that everything works right. It was not meant
(yet) as a feature request. (Spinors come in handy when describing
linear complexes in projective space)

> Upto now I have thought of spinors as an even subalgebra of Clifford
> algebras?

There are many ways to look at spinors. Every way has its own benefit.
Indeed the weakest is to go for matrix representations and confuse
those with the abstract algebra. In the examples you see that all
three Clifford algebras Cl(2,0), CL(1,1)
and CL(0,2) finally can be modelled by 2x2 matrices, but how to
identify them if only the matrices are given?
  The spinors in the examples are (left) idela spinors, that is they
are elements of a minimal left ideal of the Clifford algebra and
therefore them self representable as Clifford numbers (as clearly can
be seen by inspecting the lists calld spinorSpace). If represented in
the (same) spinor basis, these elements make up a matrix with a single
non-zero column, forgetting about the zero columns gives what you see
usually (but it gets more complicated if the ring is no longer the
reals, even complex conjugation is then a differently presented
operation).
  Some of the matrix concepts are difficult to translate back into the
algebra, eg transposition if the bilinear form is not
diagonal/symmetric... this is a reseach
subject (and I hope there will be soon a paper comming out clarifying
this partly).

> (rotation by 2*pi multiplies by -1) but
> this does not seem to be the case here? Would spinors require a new type of
> multiplication or a new domain?

If a spinor is represented _inside_ of the Clifford algebra, no new
multiplications are needed. That's the nice feature of unifying these
things. Interpreting spinors as rotations can be done by constructing
so called operator spinors, well described eg in Perrti Lounesto's
boon Clifford algebras and spinors. Also this is not yet important.
(And will not need new algebra).

What you need to implement at the moment is:

a) A Grassmann basis (module over some (commutative) ring, field)
   [Clifford has some undocumented features which allow a q-deformation here
    but I guess you should ignore that too]

b) the wedge and meet products, and some helper functions, like
   extraction of the coefficient of the identiy, the volume elemenet etc
   gradeinvolution, Grassmann reversion (that is the above reversion where
   all terms comming from the bilinear form are absent), so this is
just the sign
   factor (or better (-1)^{number of involutions of the permutatiosn which
   reorders the rerm} this would allow to replace -1 by generic q).

a) and b) make up a GrassmannAlgebra (and with very little effort could be
turned into a Grassmann Hopf algebra by adding a wedge corproduct, and
an antipode)

c) The Clifford product, based on a correctly implemented
leftContraction and rightContraction. This is done easily by a
recursion, as I tried to explain in a previous mail.

With x,y in V u,v,w in W=/\V you have

i) x * y =  lc(x,y) + x/\y  and 1*1=1
ii) x * (u /\ v) = x /\ u /\ v + lc(x, u/\v)
                     = x/\u/\v + lc(x,u)/\v + gradeinvolution(u) /\ lc(x, v)
   (same for (u/\v) * y using right contraction)
iii) Since every term u can be recursively be decomposed as a Clifford product
   you can finally evaluate u * v by
   u = w*x  (where the grade of w is strictly less than that of u
   u * v = (w*x)*v = w*(x*v)  and use the above recursion with 1*1=1

I am sorry to have to less time currently to sit down and just provide the code,
I have some other things on my table which are urgent.

Hope this helps, otherwise feel free to ask.

\start
Date: Thu, 26 Nov 2009 13:52:43 -0500
From: Tim Daly
To: Bertfried Fauser
Subject: re: Clifford Algebra examples:
Cc: Rafal Ablamowicz

 From an Axiom point of view this is stunningly good documentation.
I've downloaded the paper and added it to the reading queue.
I thought I had a grip on the Clifford Algebra stuff but clearly I do not.
Thanks.

Tim

There is no such thing as a simple job.

> Dear Martin,
>
>   
>> Can I ask about the definitions of the involutions:
>>     
> Yes, please ask, I'll answer if I know and time permits.
>
>   
>> gradeInvolution == reversion? sign=(-1)^(d(d-1)/2) symbol= ~
>> Cliplus clirev == ? symbol=multiply by pseudoscalar? symbol=
>> Clifford conjugation: scalar part minus non-scalar part? symbol=
>>     
>
> The involutions you give are again assuming a diagonal (orthonormal)
> basis for the quadratic (bilinear) form. Since this is bad for applications,
> it has to be avoided. Of course if you know you are in a diagonal basis
> you can use faster algorithms (like defining a cmulDiag)
>
> Grade involution:
> Any (Grassmann-) Clifford algebra is built up from a base space V (of dimension
> dim V = n) You have two natural transformations on V which generalize
> to the whole space W=/\V of dim W = 2^n.
> a) The identity map (does nothing on W)
> b) The map sending every vector v \in V to its additiove inverse (negative)
>     barV : V -> V :: v |--> -v
>     This will send any basis vector to its negative (regardless of the bilinear
>     form). So iff your basis is like the grBasis :=[Id, e1, e2, e1we2, e3,...]
>     barW will send all elements eiw..wej to (-)^number of basis
> elements eiw..wej
> c) Iff the basis is more general (like in the case with an antisymmetric part in
>     the bilinear form, you always fing a new basis (inhomgeous in the old
>     generators) such that the involution does the trick for the new
> basis elements.
>     Eg: B:= matrix [[1,q],[-q ,1]] you would liek tto define a new
> Grassmann basis
>    grBasWf = [Id, f1(=e1),f2(=e2), f1wf2 ( f1wf2-q*Id), f3 (=e3),...] etc
>    In this case you will see that the new basis is graded (only even or odd
>    elements appear) so the involution still works as expected.
>
> Whta you technically do is the following:
> * Take a vector space V
> * build the free algebra over it, that is the tensor algebra TV, its product is
>    concatenation it is noncommutative
> * You are only intersted in antisymmetric tensors, hence factor out
> all symmetric
>    ones. That is you identify all terms of the form
>    (v1 (x)... (x) vi (x) vi (x) ... (x) vd) = 0
>    [One can check that this is a graded ideal I_gr and one can therefor factor
>   the tensor algebra TV/I_gr = /\V
>   (for the generators this means you impose ei^2=0. From that you conclude that
>    0=(ei+ej)^(x)2 = ei^2+ei (x) ej + ej (x) ei + ej^2
>      = ei (x) ej + ej (x) ej
>    calling the projectet tensor /\ you get
>    ei /\ ej = -  ej /\ ei )
>
> Reversion:
>    This is quite different. The reversion needs to know about the Clifford
>    multiplication, so its actually defined in the Clifford basis
>    cliBas:= [Id, e(1), e(2), e(12):=e(1)*e(2), e(3),... ]
>    and it reverses the order of the Clifford multiplication (which depends on
>    the quadratic (bilinear) form. Hence you have (eij) Grassmann ,
> e(ij) Clifford
>    basis elements)
>    reversion e12 = reversion (e(12)-B(e1,e2)*Id) = e(21)-B(e1,e2)*Id
>        = e2/\e1 +(B(e2,e1)-B(e1,e2))*Id
>        = -e12 - 2F(e1,e2)
>    where F(e1,e2) is the antisymmetric part of B, hence this difficulty will
>    _only_ appear when there is an antisymmetric part. Since not many people
>    have looked at that, its rarely described in literature, but see my
> joint papers
>    with Rafal Ablamowicz:
> #
> Mathematics of CLIFFORD - A Maple package for Clifford and Grassmann algebras
> Rafal Ablamowicz, B. Fauser: Adv. in Appl. Clifford Alg. 15 No. 2, 2005:157-181
>
> #
> arXiv:math-ph/0212032
> Clifford and Grassmann Hopf algebras via the BIGEBRA package for Maple
> Rafal Ablamowicz, B. Fauser: Comp. Physics Comm. 170, 2005:115--130
>   available from the arXiv (or I can send you pdf's).
>   
> Technically the reversion comes from the dualising the vector space V -> V*
> and building the tensor algebra over the dualised vector space V* and
> identifying
> V* ~= V canonically. The project onto antisymmetric tensors. You see
> that the symmetric group acts on tensors by permuting the 'list' ov
> vectors a tensor is forms of. The reverison is the unique larget
> permutation (usually called w)
> with the most inversions (in reduced notation). So reversion is not
> just adding a sign, its really reversing the list of all vectors
> (generators) and then reorder them using the antisymmetry and collect
> the minus signs.
>
> conjugation is just the composition of recerion and grade involution:
>
> conjugation x == reversion gradeinvolution x
>                       (== gradeinvolution reversion x) -- oder does not matter
>
> So first thing is to implement:
>
> Grassmann wedge
> Grassmann meet (note that the meet is a sort of wedge but with the roles
>   of the grades inverted)
> Clifford product for a bilinear form (this is not hard, its the same routine
> which calculates the Clifford product for a symmetric bilinear form or an
> arbitrary bilinear form)
>
>   
>> I expect I had better ignore the Spinors for now although I am curious about
>> how they should be added on later.
>>     
>
> Indeed, forget about them for now. I just added the spinor things to
> make sure there are matrix analogs which show that the algebra
> computes correctly. It is
> just a way to convince yourself that everything works right. It was not meant
> (yet) as a feature request. (Spinors come in handy when describing
> linear complexes in projective space)
>
>   
>> Upto now I have thought of spinors as an even subalgebra of Clifford
>> algebras?
>>     
>
> There are many ways to look at spinors. Every way has its own benefit.
> Indeed the weakest is to go for matrix representations and confuse
> those with the abstract algebra. In the examples you see that all
> three Clifford algebras Cl(2,0), CL(1,1)
> and CL(0,2) finally can be modelled by 2x2 matrices, but how to
> identify them if only the matrices are given?
>   The spinors in the examples are (left) idela spinors, that is they
> are elements of a minimal left ideal of the Clifford algebra and
> therefore them self representable as Clifford numbers (as clearly can
> be seen by inspecting the lists calld spinorSpace). If represented in
> the (same) spinor basis, these elements make up a matrix with a single
> non-zero column, forgetting about the zero columns gives what you see
> usually (but it gets more complicated if the ring is no longer the
> reals, even complex conjugation is then a differently presented
> operation).
>   Some of the matrix concepts are difficult to translate back into the
> algebra, eg transposition if the bilinear form is not
> diagonal/symmetric... this is a reseach
> subject (and I hope there will be soon a paper comming out clarifying
> this partly).
>
>   
>> (rotation by 2*pi multiplies by -1) but
>> this does not seem to be the case here? Would spinors require a new type of
>> multiplication or a new domain?
>>     
>
> If a spinor is represented _inside_ of the Clifford algebra, no new
> multiplications are needed. That's the nice feature of unifying these
> things. Interpreting spinors as rotations can be done by constructing
> so called operator spinors, well described eg in Perrti Lounesto's
> boon Clifford algebras and spinors. Also this is not yet important.
> (And will not need new algebra).
>
> What you need to implement at the moment is:
>
> a) A Grassmann basis (module over some (commutative) ring, field)
>    [Clifford has some undocumented features which allow a q-deformation here
>     but I guess you should ignore that too]
>
> b) the wedge and meet products, and some helper functions, like
>    extraction of the coefficient of the identiy, the volume elemenet etc
>    gradeinvolution, Grassmann reversion (that is the above reversion where
>    all terms comming from the bilinear form are absent), so this is
> just the sign
>    factor (or better (-1)^{number of involutions of the permutatiosn which
>    reorders the rerm} this would allow to replace -1 by generic q).
>
> a) and b) make up a GrassmannAlgebra (and with very little effort could be
> turned into a Grassmann Hopf algebra by adding a wedge corproduct, and
> an antipode)
>
> c) The Clifford product, based on a correctly implemented
> leftContraction and rightContraction. This is done easily by a
> recursion, as I tried to explain in a previous mail.
>
> With x,y in V u,v,w in W=/\V you have
>
> i) x * y =  lc(x,y) + x/\y  and 1*1=1
> ii) x * (u /\ v) = x /\ u /\ v + lc(x, u/\v)
>                      = x/\u/\v + lc(x,u)/\v + gradeinvolution(u) /\ lc(x, v)
>    (same for (u/\v) * y using right contraction)
> iii) Since every term u can be recursively be decomposed as a Clifford product
>    you can finally evaluate u * v by
>    u = w*x  (where the grade of w is strictly less than that of u
>    u * v = (w*x)*v = w*(x*v)  and use the above recursion with 1*1=1
>
> I am sorry to have to less time currently to sit down and just provide the code,
> I have some other things on my table which are urgent.
>
> Hope this helps, otherwise feel free to ask.

\start
Date: Sat, 28 Nov 2009 00:51:02 -0500
From: Tim Daly
To: Christoph Egger
Subject: Re: [Bug 387255] Axiom in Debian

Christoph Egger wrote:
> Hi!
>
> 	I'm currently having a look at this open RC Bug in Debian and
> Ubuntu. You said you know how this is to be solved, can you provide a
> patch or instructions on how to fix it?
>
> Thanks
>
>         Christoph
>
>   
Christoph,

I downloaded debian-503-i386-netinst.iso and used it to build a clean
version of debian.

I set up the prerequired packages (not all are required but....) and
then built the latest release (November 2009)

I did the following steps:

apt-get -y install gcc build-essential debhelper gcl gettext gs-gpl 
html2text
apt-get -y install intltool-debian libgmp3-dev libice-dev libxau-dev 
libxaw7-dev
apt-get -y install po-debconf x-dev x11proto-input-dev x11proto-kb-dev
apt-get -y install libncurses5-dev libreadline5-dev libstdc++6-4.1-dev gawk
apt-get -y install texlive-pstricks git-core texlive
git clone git://axiom.git.sourceforge.net/gitroot/axiom/axiom
cd axiom
export AXIOM=`pwd`/mnt/debian
export PATH=$AXIOM/bin:$PATH
make

I uploaded the binary as
http://daly.axiom-developer.org/axiom-debian-nov2009-bin.tgz

To run it do:
wget http://daly.axiom-developer.org/axiom-debian-nov2009-bin.tgz
tar -zxf axiom-debian-nov2009-bin.tgz
cd axiom
export AXIOM=`pwd`/mnt/debian
export PATH=$AXIOM/bin:$PATH
axiom

In the hyperdoc window you can click on

Basic Commands -> Draw -> A function of two variables -> Continue -> Do It

and you should see a 3D graphics

At the Axiom comand line you can type:

integrate(sin(x),x)

and get back "- cos(x)"

Let me know if it works for you.

\start
Date: Sat, 28 Nov 2009 01:46:44 -0500
From: Tim Daly
To: Christoph Egger
Subject: Re: [Bug 387255] Axiom in Debian

I would like to replace the Debian version (from 2005)
to be a later version. How do I go about doing this?

\start
Date: Sun, 29 Nov 2009 19:22:04 -0500
From: Tim Daly
To: list
Subject: Knuth talks about Literate Programming

http://stanford-online.stanford.edu/seminars/knuth/871021-knuth-100.asx
http://stanford-online.stanford.edu/seminars/knuth/871023-knuth-100.asx

\start
Date: Mon, 30 Nov 2009 07:12:26 -0500
From: Tim Daly
To: list
Subject: Embedding Axiom

Another trend that is important is the development of parallelism.
Berkeley has a group dedicated to this it seems[1]. Assuming that
today's uniprocessor power is the peak speed for the future we
need to architect the system to take advantage of parallelism.

My view of the natural embedding of parallelism in Axiom is
tightly coupled to provisos. The proviso mechanism holds, manages,
and carries the assumptions that each branch of a computation will
use to constrain the answer. Thus if you have
   f(x) | x > 0
   f(x) | x = 0
   f(x) | x < 0
then you have the ability to perform all three computations in
parallel. I am assuming functional programming and immutable
data structures. These three computations can be forked into their
own images and then the results can be joined. This is a "natural"
parallelism for mathematics computation.

Thus some thought needs to be given to re-architecting the system
to support provisos in a natural way.

Tim

[1] http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-183.pdf



\end{verbatim}
\eject
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cleardoublepage
%\phantomsection
\addcontentsline{toc}{chapter}{Bibliography}
\bibliographystyle{axiom}
\bibliography{axiom}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cleardoublepage
%\phantomsection
\addcontentsline{toc}{chapter}{Index}
\printindex
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
