\documentclass{book} %\usepackage{axiom} \usepackage{graphicx} % struggle with latex figure-floating behavior \renewcommand\floatpagefraction{.9} \renewcommand\topfraction{.9} \renewcommand\bottomfraction{.9} \renewcommand\textfraction{.1} \setcounter{totalnumber}{50} \setcounter{topnumber}{50} \setcounter{bottomnumber}{50} % spadcommands are the actual text that you type at the axiom prompt \newcommand{\spadcommand}[1]% {\begin{flushleft}{\tt #1}\end{flushleft}\vskip .1cm } % spadgraph are the actual text that you type at the axiom prompt for draw \newcommand{\spadgraph}[1]% {\begin{flushleft}{\tt #1}\end{flushleft}\vskip .1cm } % returnType is the type signature returned by the axiom interpreter \newcommand{\returnType}[1]% {\begin{flushright}{\tt #1}\end{flushright}\vskip .1cm} % spadsig gives the standard -> notation for signatures \newcommand{\spadsig}[2]{{\sf #1 $\rightarrow$ #2}} % The book begins with some introductory material that is not really % listed as a chapter. This creates a header similar to \chapter. \newcommand{\pseudoChapter}[1]% {\vskip .5in \noindent {\Large{\bf #1}}\vskip .5in} % The book begins with some introductory material that is not really % listed as a section. This creates a header similar to \section. \newcommand{\pseudoSection}[1]% {\vskip .25in \noindent {\large{\bf #1}}\vskip .25in} % spadofFrom records the operation in the index and the domain in the index \newcommand{\spadopFrom}[2]{\index{library!operations!#1 @\begingroup \string\tt{} #1 \endgroup}\index{#2}``{\tt #1}''} % spadfunFrom records the function name and domain in the index \newcommand{\spadfunFrom}[2]{{\bf #1}\index{#1 @\begingroup \string\bf{} #1 \endgroup}\index{#2}} % special meanings for math characters \newcommand{\N}{\mbox{\bbold N}} \newcommand{\Natural}{\mbox{\bbold N}} \newcommand{\Z}{\mbox{\bbold Z}} \newcommand{\Integer}{\mbox{\bbold Z}} \newcommand{\Rational}{\mbox{\bbold Q}} \newcommand{\Q}{\mbox{\bbold Q}} \newcommand{\Complex}{\mbox{\bbold C}} \newcommand{\C}{{\mathcal C}} \newcommand{\Real}{\mbox{\bbold R}} \newcommand{\F}{{\mathcal F}} \newcommand{\R}{{\mathcal R}} % draw a box around a text block \newcommand\boxed[2]{% \begin{center} \begin{tabular}{|c|} \hline \begin{minipage}{#1} \normalsize {#2} \end{minipage}\\ \hline \end{tabular} \end{center}} \newcommand{\optArg}[1]{{{\tt [}{#1}{\tt ]}}} \newcommand{\argDef}[1]{{\tt ({#1})}} \newcommand{\funSyntax}[2]{{\bf #1}{\tt ({\small\it{#2}})}} \newcommand{\funArgs}[1]{{\tt ({\small\it {#1}})}\newline} \newcommand{\condata}[4]{{\bf #1} {\bf #2} {\bf #3} {\bf #4}} \def\glossaryTerm#1{{\bf #1}\index{#1}} \def\glossaryTermNoIndex#1{{\bf #1}} \def\glossarySyntaxTerm#1{{\tt #1}\index{#1}} \long\def\ourGloss#1#2{\par\pagebreak[3]{#1}\newline{#2}} \def\csch{\mathop{\rm csch}\nolimits} \def\erf{\mathop{\rm erf}\nolimits} \def\zag#1#2{ {{\hfill \left. {#1} \right|} \over {\left| {#2} \right. \hfill} } } % these bitmaps are used by HyperDoc \newdimen\commentWidth \commentWidth=11pc \newdimen\colGutterWidth \colGutterWidth=1pc \newdimen\baseLeftSkip \baseLeftSkip=\commentWidth \advance\baseLeftSkip by \colGutterWidth \newcommand\ExitBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/exit.ps}\end{picture}}} \newcommand\ReturnBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/home.ps}\end{picture}}} \newcommand\HelpBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/help.ps}\end{picture}}} \newcommand\UpBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/up.ps}\end{picture}}} \newcommand{\tpd}[5]{{\setlength{\unitlength}{0.01in}\begin{picture}(#1,#2)(#3,#4)\special{psfile=#5}\end{picture}}} \begin{document} \begin{titlepage} \center{\includegraphics{ps/axiomFront.ps}} \vskip 0.1in \includegraphics{ps/bluebayou.ps}\\ \vskip 0.1in {\Huge{The 30 Year Horizon}} \vskip 0.1in $$ \begin{array}{lll} Manuel\ Bronstein & William\ Burge & Timothy\ Daly \\ James\ Davenport & Michael\ Dewar & Martin\ Dunstan \\ Albrecht\ Fortenbacher & Patrizia\ Gianni & Johannes\ Grabmeier \\ Jocelyn\ Guidry & Richard\ Jenks & Larry\ Lambe \\ Michael\ Monagan & Scott\ Morrison & William\ Sit \\ Jonathan\ Steinbach & Robert\ Sutor & Barry\ Trager \\ Stephen\ Watt & Jim\ Wen & Clifton\ Williamson \end{array} $$ \center{\large{VOLUME 4: DEVELOPERS GUIDE}} \end{titlepage} \pagenumbering{roman} \begin{verbatim} The Blue Bayou image Copyright (c) 2004 Jocelyn Guidry Portions Copyright (c) 2004 Martin Dunstan Portions Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. All rights reserved. This book and the Axiom software is licensed as follows: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of The Numerical ALgorithms Group Ltd. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \end{verbatim} \tableofcontents \vfill \eject \setlength{\parindent}{0em} \setlength{\parskip}{1ex} {\Large{\bf New Foreword}} \vskip .25in On October 1, 2001 Axiom was withdrawn from the market and ended life as a commercial product. On September 3, 2002 Axiom was released under the Modified BSD license, including this document. On August 27, 2003 Axiom was released as free and open source software available for download from the Free Software Foundation's website, Savannah. Work on Axiom has had the generous support of the Center for Algorithms and Interactive Scientific Computation (CAISS) at City College of New York. Special thanks go to Dr. Gilbert Baumslag for his support of the long term goal. The online version of this documentation is roughly 1000 pages. In order to make printed versions we've broken it up into three volumes. The first volume is tutorial in nature. The second volume is for programmers. The third volume is reference material. We've also added a fourth volume for developers. All of these changes represent an experiment in print-on-demand delivery of documentation. Time will tell whether the experiment succeeded. Axiom has been in existence for over thirty years. It is estimated to contain about three hundred man-years of research and has, as of September 3, 2003, 143 people listed in the credits. All of these people have contributed directly or indirectly to making Axiom available. Axiom is being passed to the next generation. I'm looking forward to future milestones. With that in mind I've introduced the theme of the ``30 year horizon''. We must invent the tools that support the Computational Mathematician working 30 years from now. How will research be done when every bit of mathematical knowledge is online and instantly available? What happens when we scale Axiom by a factor of 100, giving us 1.1 million domains? How can we integrate theory with code? How will we integrate theorems and proofs of the mathematics with space-time complexity proofs and running code? What visualization tools are needed? How do we support the conceptual structures and semantics of mathematics in effective ways? How do we support results from the sciences? How do we teach the next generation to be effective Computational Mathematicians? The ``30 year horizon'' is much nearer than it appears. \vskip .25in %\noindent Tim Daly\\ CAISS, City College of New York\\ November 10, 2003 ((iHy)) \vfill \eject \pagenumbering{arabic} \setcounter{chapter}{0} % Chapter 1 \chapter{Getting Axiom} \section{The savannah website} \section{The axiom-developer website} \chapter{Building Axiom} \section{Makefiles} \section{Noweb} \section{Directory Structure} \section{Packages in zip} \section{Lisp} \section{Boot Compiler} \section{Interpreter} \section{Share} \section{Algebra} \section{Etc} \section{Clef} \section{Doc} \section{Graph} \section{Sman} \section{Input} \chapter{Modifying Axiom} \chapter{Becoming a Developer} \section{Using Arch} \chapter{THINGS TO BE INTEGRATED} \section{email 2} \begin{verbatim} There is something called the "add-chain formed by domain extensions" which is described in the Glossary of the Axiom book: "add-chain a hierarchy formed by domain extensions. If domain A extends domain B and domain B extends domain C, then A has add-chain B-C." and "domain extension a domain constructor A is said to extend a domain constructor B if A's definition has the form A == Badd.... This intuitively means "functions not defined by A are assumed to come from B." Successive domain extensions form add-chains affecting the search order for functions not implemented directly by the domain during dynamic lookup. "dynamic lookup In Axiom, a domain may or may not explicitly provide function definitions for all its exported operations. These definitions may instead come from domains in the add-chain or from default packages. When a function call is made for an operation in the domain, up to five steps are carried out. 1. If the domain itself implements a function for the operation, that function is returned. 2. Each of the domains in the add-chain are searched; if one of these domains implements the function, that function is returned. 3. Each of the default packages for the domain are searched in order of the lineage. If any of the default packages implements the function, the first one found is returned. 4. Each of the default packages for each of the domains in the add-chain are searched in the order of their lineage. If any of the default packages implements the function, the first one found is returned. 5. If all of the above steps fail, an error message is reported. --------- \end{verbatim} \section{email 2} \begin{verbatim} > > > The list of prerequisites for running axiom is huge, and > > getting worse it seems! > ... > > So in the interest of having something people can download > > that is functional with a minimum of effort, I think axiom > > (and any help system or hyperdoc) should be decoupled from > > zope and zwiki. A download (think windoze users here) which > > included zope, zwiki, latex, ghostscript, python, PIL, gcl, > > gcc, *and* axiom, is too much, methinks. > > Heh - even I agree there. Perhaps it would be best to > acknowledge the reality that if one wants to take advantage > of all the vast possibilities of open source software, that's > going to be at odds with having the full power of the system > available on all platforms, particularly Windows, as a single > package. Surely power users who are willing and able to use > the full web-like setup, instead of just a TeXmacs or Mathematica > like document interface, would be willing to set it up or at > the very least boot a live Linux CD loaded with the full set > of Axiom tools and dependencies. > Personally, although I have tried knoppix and some variants on several occasions I have always been a little disappointed and frustrated. The problem is that I live in linux about 1/2 the time and windows the other 1/2 and when I boot one of these "live" things I feel like I am in neither. It's fun to play for an hour or so but then it goes in the desk draw with all the other things that once fascinated me but I haven't looked at for so long that they are now collecting dust. So I am quite sceptical about the utility of a "live" Axiom/Doyen CD except as a kind of conference "promotional gimmick". Let's put the list in the following order and fill it in a few more: gcc / | \ gcl latex python / | | \ / noweb | zope / / | | / axiom ghostscript PIL zwiki \ \ | / \ LatexWiki \ / MathAction Add your favourite text editor and browser and set it all up in Linux/Unix or Windows. There. Now that doesn't seem so large and complex does it? (: At least not if you compare it to the list of capabilities that this remarkable combination of entirely open source software provides... :) I am quite sure that this would all easily fit on one-side of a Cdrom, including documentation. And of course we can add as many more optional add-on packages as we want, such as Reduce, Aldor, Maxima, ... eventually all integrated with a common web interface. What this gives you a fully web-integrated, collaborative mathematical research and development, hyper-linked publishing environment right on your desktop, or even in your pocket (I run almost all of this on a Zaurus 5600). This is all easily doable right now for free. I would have given my left arm for something like this back when I was a student! \end{verbatim} \section{email 4} \begin{verbatim} > > Next we see the transition to compiling the non-BOOTSTRAP algebra. > > This is done in the interpsys image. It is also done in an image > > that has access to only the BOOTSTRAP algebra code. Thus the > > new compiler might not have all of the algebra-defined replacements > > available at compile time. Notice the autoload files that contain > > the optimizations. > > > > What do you mean by "algebra-defined replacements". Where are > these replacements defined? How are they different than the > "optimizations" contained in the autoload files? The BOOTSTRAP files contain lsp and spad code. The build steps for the initial BOOTSTRAP layer use "depsys" to compile the lisp code. So, in this case, we see VECTOR.lsp being compiled in the depsys image. VECTOR.lsp is the last algebra file that contains BOOTSTRAP code. So in this phase we see: VECTOR.lsp (BOOTSTRAP) -> VECTOR.o Once we leave the phase (shown in the printout) we start using an "interpsys" image to compile spad code. Much later in the console VECTOR.spad will be compiled and replaces the lisp. However the "interpsys" environment in VECTOR.spad differs significantly from the "depsys" environment that compiles VECTOR.lsp BOOSTRAP code. So we see VECTOR.spad + SINT.NRLIB -> VECTOR.lsp -> VECTOR.o (replaced previous version) Suppose VECTOR.spad used something from SINT.spad. When the VECTOR.lsp BOOTSTRAP file is compiled by depsys it contains (+ ... ...) and generates untyped and unoptimized code. Later when VECTOR.spad is compiled and SINT.o is available then the spad compiler will use the optimization information to generate (QSADD1 ... ...) > What do you mean by "expose". Why does this cause interpsys to > be re-built? That is necessary if code is going to be generated > based on new optimizations isn't it? expose == make available Due to my lack of foresight in choosing the VECTOR.lsp BOOTSTRAP code I did not use the most highly optimized version. But in the algebra recompile of VECTOR.spad later in the build this gets corrected because the operations are made available (exposed) by previously compiled .spad code. So: VECTOR.lsp (BOOTSTRAP) uses SINT.o But the VECTOR.lsp has (+ ... ...) instead of (QSADD1 ... ...) because the rewriting of "+" to "QSADD1" is done by the spad compiler, not the GCL compiler and we are not yet in a position to use the spad compiler. Later when VECTOR.spad -> VECTOR.lsp -> VECTOR.o (replaced previous version) the spad compiler was invoked and it gets a chance to change "+" to "QSADD1". Because I grabbed the wrong version of .lsp file for BOOTSTRAP code you are able to see this difference. The work you and steve are doing is to find stable versions of the .lsp files. > > Since these are only optimizations the final results should not > > be affected. > > > > But it could have an impact on overall performance, right? Oh, clearly. (QSADD1 ... ...) is faster than (+ ... ...) Furthermore, there is another optimization step we could take during the build but we do not (yet). When the GCL compiler compiles VECTOR.lsp it generates VECTOR.fn. If you look in these .fn files you'll find exact type information for each function call. VECTOR.lsp -> VECTOR.o + VECTOR.fn (unoptimized, but type generated) If this exact type information was available at compile time then the GCL compiler can lay down faster code. However there is a bootstrap problem here also since the GCL compiler has to compile the code one time in order to generate the .fn file. VECTOR.lsp + VECTOR.fn -> VECTOR.o (type optimized) So the full, proper procedure, which I have yet to do, would actually call the GCL compile once to generate the .fn file with exact type information for function calls, load the .fn file, and the recompile the lisp file. Since the second compile has exact type information the generated code will be (potentially much) shorter. For each lisp file do ( VECTOR.lsp -> VECTOR.o + VECTOR.fn (unoptimized, but type generated) VECTOR.lsp + VECTOR.fn -> VECTOR.o (type optimized) ) > Still after reading the interp and algebra Makefiles again, > I do not see why interpsys is being rebuilt after I delete > all the *.NRLIB's and repeat the 'make'. I am still missing > something somewhere. Is there some "missing link" that still > connects the algebra/Makefile back to the inter/Makefile? I have to think about this (I'm getting ready for work so I'll give it some "drive-time cycles") but I believe that the issue is related to using fresh databases. The databases are used during the algebra compiles to resolve algebra calls. However recompiling the algebra generates NRLIBs and, from these NRLIBs a fresh database is built thus: DATABASES -> NRLIBs -> FRESH DATABASES This is yet a third bootstrap issue. There are more but not with the algebra files. \end{verbatim} \section{email 4} \begin{verbatim} Yet one other opportunity for speed optimization is available at build time.... Remember that every lisp file generates a .fn file: foo.lsp -> foo.o + foo.fn and that a second compile with the .fn file loaded is faster: foo.lsp + foo.fn -> faster foo.o However if we look at the type information in the foo.fn file we find that it only contains type information for functions defined in foo.lsp. But suppose there are two lisp files with functions from one using functions from the other. The sub-optimal sequence is: foo.lsp -> foo.o + foo.fn foo.lsp + foo.fn -> faster foo.o bar.lsp -> bar.o + bar.fn bar.lsp + bar.fn -> faster bar.o The optimal sequence is: foo.lsp -> foo.o + foo.fn bar.lsp -> bar.o + bar.fn foo.lsp + (foo.fn + bar.fn) -> even faster foo.o bar.lsp + (foo.fn + bar.fn) -> even faster bar.o So, really what we should do is cache ALL of the .fn files from all of the compiles, batch them into a big file, and the completely rebuild the system with the batched .fn files loaded. I've started this process but have not yet completed it. See the file src/boot/boot-proclaims.lisp So there is a faster Axiom coming in the future but the build complexity will be even greater. And Camm, I believe, is doing even more with type propagation which will improve things more. \end{verbatim} \section{email 5} \begin{verbatim} How I Built Axiom on Windows I installed a completely new MinGW/MSYS configuration from the 'current' file list at: http://www.mingw.org/download.shtml#hdr2 In the following order: 1 MinGW-3.1.0-1.exe http://prdownloads.sf.net/mingw/MinGW-3.1.0-1.exe?download 2 MSYS-1.0.10.exe http://prdownloads.sf.net/mingw/MSYS-1.0.10.exe?download 3 msysDTK-1.0.1.exe http://prdownloads.sf.net/mingw/msysDTK-1.0.1.exe?download 4 Then untarred the following: cd /mingw; tar xzvf /home/bpage/... gcc-core-3.4.2-20040916-1.tar.gz http://prdownloads.sf.net/mingw/gcc-core-3.4.2-20040916-1.tar.gz?download 5 binutils-2.15.91-20040904-1.tar.gz http://prdownloads.sf.net/mingw/binutils-2.15.91-20040904-1.tar.gz?download 6 w32api-3.1.tar.gz http://prdownloads.sf.net/mingw/w32api-3.1.tar.gz?download 7 mingw-runtime-3.5.tar.gz http://prdownloads.sf.net/mingw/mingw-runtime-3.5.tar.gz?download 8 You will also need tla for windows from http://download.sipsolutions.de/tla-setup.exe 9 and the windows LaTeX packaged called MikTex http://www.miktex.org/setup.html The "Small MiKTeX" package is sufficient if your windows box is connected to the Internet. Or if you want you can install the complete system. 10 download the axiom--windows--1 branch See deteails instructions at ArchUsage 1 tla my-id "First Last
" 2 tla register-archive address@bogus.example.com http://axiom-developer.org/archive/axiom 3 tla my-default-archive address@bogus.example.com 4 tla get axiom--windows--1 axiom--windows--1 Or see ArchUsage to use 'sftp://' protocol if you intend to submit changes. 11 configure and make cd axiom--windows--1 ./configure -- Cut-and-paste environmnet variables to avoid typing errors make -- the build takes between 3 to 6 hours on 2.4 GHz Windows XP \end{verbatim} \section{email 6} \begin{verbatim} What is MinGW? MinGW ("Minimalistic GNU for Windows") refers to a set of runtime headers, used in building a compiler system based on the GNU GCC and binutils projects. It compiles and links code to be run on Win32 platforms... providing C, C++ and Fortran compilers plus other related tools. If you see references to "mingw32" instead of "MinGW", they are referring to the same compiler system. The project's name changed from mingw32 to MinGW is to prevent the implication that MinGW will only works on 32 bit systems (as 64 and higher bit machines become more common, MinGW will evolve to work with them). MinGW uses the Microsoft runtime libraries, distributed with the Windows operating system. Unlike other ports of GCC to Windows, the runtime libraries are not distributed using Gnu's General Public License (GPL). You, therefore, do not have to distribute your source code with your programs unless, of course, you use a GPL library in your programs. What is MSYS? MSYS or Minimal SYStem is a POSIX and Bourne shell environment use with MinGW. It provides a hand picked set of tools to allow a typical configuration script with Bourne syntax to execute. This allows most of the GNU packages to create a Makefile just from executing the typical configure script which can then be used to build the package using the native MinGW version of GCC. The POSIX layer used by MSYS is a fork of the 1.3.3 version of Cygwin . Cygwin is a full POSIX layer and UNIX-like environment for Win32 providing both server and client utilites. \end{verbatim} \section{email 7} \begin{verbatim} The build sequence should be: obj/linux/bin/lisp ... contains the socket extensions obj/linux/bin/bootsys ... contains the boot -> lisp compiler used to compile the interp/*.boot files obj/linux/bin/depsys ... contains macros used by axiom used for compiling the intermediate lisp files obj/linux/bin/interpsys ... contains the final image used to compile the algebra obj/linux/bin/AXIOMsys contains the final image a clean copy for the end user I've attached the interesting part of a console log. At this point the Axiom build is making the transition from building the BOOTSTRAP algebra to building the non-BOOTSTRAP algebra. Notice that the BOOTSTRAP algebra is just lisp code. This code is compiled in a DEPSYS image so that macros are properly expanded. However it is clear that the BOOTSTRAP lisp code was not compiled by the "new" compiler. Next we see the transition to compiling the non-BOOTSTRAP algebra. This is done in the interpsys image. It is also done in an image that has access to only the BOOTSTRAP algebra code. Thus the new compiler might not have all of the algebra-defined replacements available at compile time. Notice the autoload files that contain the optimizations. A second or third round of compiles will expose the algebra-based optimizations and these will be compiled into the code. Since these are only optimizations the final results should not be affected. Also note that the BOOTSTRAP algebra is recompiled as the last step of building the algebra from scratch so that it can use the circular definitions. ========================================================================== ==== running DEPSYS image =============================================== ========================================================================== BOOT>0 making /home/arch/axiom--hyperdoc--1--base-0/int/algebra/VECTOR.lsp from /home/arch/axiom--hyperdoc--1--base-0/src/algebra/vector.spad.pamphlet 0 making /home/arch/axiom--hyperdoc--1--base-0/int/algebra/VECTOR.o from /home/arch/axiom--hyperdoc--1--base-0/int/algebra/VECTOR.lsp > Compiling VECTOR.lsp. End of Pass 1. End of Pass 2. OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3 Finished compiling VECTOR.o. #p"VECTOR.o" BOOT>0 making /home/arch/axiom--hyperdoc--1--base-0/int/algebra/AHYP.spad from /home/arch/axiom--hyperdoc--1--base-0/src/algebra/trigcat.spad.pamphlet ========================================================================== ==== running AXIOMSYS image ============================================= ========================================================================== 0 making /home/arch/axiom--hyperdoc--1--base-0/int/algebra/AHYP.NRLIB from /home/arch/axiom--hyperdoc--1--base-0/int/algebra/AHYP.spad AXIOM Computer Algebra System Version of Friday November 19, 2004 at 16:36:16 ----------------------------------------------------------------------------- Issue )copyright to view copyright notices. Issue )summary for a summary of useful system commands. Issue )quit to leave AXIOM and return to shell. ----------------------------------------------------------------------------- Using local database /home/arch/axiom--hyperdoc--1--base-0/src/share/algebra/compress.daase.. Using local database /home/arch/axiom--hyperdoc--1--base-0/src/share/algebra/interp.daase.. Using local database /home/arch/axiom--hyperdoc--1--base-0/src/share/algebra/operation.daase.. Using local database /home/arch/axiom--hyperdoc--1--base-0/src/share/algebra/category.daase.. Using local database /home/arch/axiom--hyperdoc--1--base-0/src/share/algebra/browse.daase.. (1) -> Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/apply. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/c-doc. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/c-util. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/profile. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/category. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/compiler. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/define. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/functor. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/info. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/iterator. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/modemap. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/nruncomp. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/package. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/htcheck. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/xruncomp. Compiling AXIOM source code from file /home/arch/axiom--hyperdoc--1--base-0/int/algebra/AHYP.spad using old system compiler. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/parsing. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/bootlex. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/def. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/fnewmeta. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/metalex. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/metameta. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/parse. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/postpar. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/postprop. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/preparse. AHYP abbreviates category ArcHyperbolicFunctionCategory ------------------------------------------------------------------------ initializing NRLIB AHYP for ArcHyperbolicFunctionCategory compiling into NRLIB AHYP ;;; *** |ArcHyperbolicFunctionCategory| REDEFINED Time: 0 SEC. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/bc-matrix. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/bc-misc. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/bc-solve. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/bc-util. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/ht-util. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/htsetvar. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/ht-root. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/br-con. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/br-data. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/showimp. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/br-op1. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/br-op2. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/br-search. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/br-util. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/topics. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/br-prof. Loading /home/arch/axiom--hyperdoc--1--base-0/mnt/linux/autoload/br-saturn. finalizing NRLIB AHYP Processing ArcHyperbolicFunctionCategory for Browser database: --------(acosh ($ $))--------- --------(acoth ($ $))--------- --------(acsch ($ $))--------- --------(asech ($ $))--------- --------(asinh ($ $))--------- --------(atanh ($ $))--------- --------constructor--------- Compiling /home/arch/axiom--hyperdoc--1--base-0/int/algebra/AHYP.NRLIB/code.lsp. \end{verbatim} \section{email 8} \begin{verbatim} MiKTeX is an up-to-date TeX implementation for the Windows operating system. TeX is a typesetting system written by Donald E. Knuth, who says that it is "intended for the creation of beautiful books - and especially for books that contain a lot of mathematics". MiKTeX offers a complete set of utilities, macro packages and fonts, e.g., LaTeX, pdfTeX, ConTeXt, just to name a few. http://www.miktex.org\end{verbatim} \section{email 9} \begin{verbatim} > > Next we see the transition to compiling the non-BOOTSTRAP algebra. > > This is done in the interpsys image. It is also done in an image > > that has access to only the BOOTSTRAP algebra code. Thus the > > new compiler might not have all of the algebra-defined replacements > > available at compile time. Notice the autoload files that contain > > the optimizations. > > > > What do you mean by "algebra-defined replacements". Where are > these replacements defined? How are they different than the > "optimizations" contained in the autoload files? The BOOTSTRAP files contain lsp and spad code. The build steps for the initial BOOTSTRAP layer use "depsys" to compile the lisp code. So, in this case, we see VECTOR.lsp being compiled in the depsys image. VECTOR.lsp is the last algebra file that contains BOOTSTRAP code. So in this phase we see: VECTOR.lsp (BOOTSTRAP) -> VECTOR.o Once we leave the phase (shown in the printout) we start using an "interpsys" image to compile spad code. Much later in the console VECTOR.spad will be compiled and replaces the lisp. However the "interpsys" environment in VECTOR.spad differs significantly from the "depsys" environment that compiles VECTOR.lsp BOOSTRAP code. So we see VECTOR.spad + SINT.NRLIB -> VECTOR.lsp -> VECTOR.o (replaced previous version) Suppose VECTOR.spad used something from SINT.spad. When the VECTOR.lsp BOOTSTRAP file is compiled by depsys it contains (+ ... ...) and generates untyped and unoptimized code. Later when VECTOR.spad is compiled and SINT.o is available then the spad compiler will use the optimization information to generate (QSADD1 ... ...) > What do you mean by "expose". Why does this cause interpsys to > be re-built? That is necessary if code is going to be generated > based on new optimizations isn't it? expose == make available Due to my lack of foresight in choosing the VECTOR.lsp BOOTSTRAP code I did not use the most highly optimized version. But in the algebra recompile of VECTOR.spad later in the build this gets corrected because the operations are made available (exposed) by previously compiled .spad code. So: VECTOR.lsp (BOOTSTRAP) uses SINT.o But the VECTOR.lsp has (+ ... ...) instead of (QSADD1 ... ...) because the rewriting of "+" to "QSADD1" is done by the spad compiler, not the GCL compiler and we are not yet in a position to use the spad compiler. Later when VECTOR.spad -> VECTOR.lsp -> VECTOR.o (replaced previous version) the spad compiler was invoked and it gets a chance to change "+" to "QSADD1". Because I grabbed the wrong version of .lsp file for BOOTSTRAP code you are able to see this difference. The work you and steve are doing is to find stable versions of the .lsp files. > > Since these are only optimizations the final results should not > > be affected. > > > > But it could have an impact on overall performance, right? Oh, clearly. (QSADD1 ... ...) is faster than (+ ... ...) Furthermore, there is another optimization step we could take during the build but we do not (yet). When the GCL compiler compiles VECTOR.lsp it generates VECTOR.fn. If you look in these .fn files you'll find exact type information for each function call. VECTOR.lsp -> VECTOR.o + VECTOR.fn (unoptimized, but type generated) If this exact type information was available at compile time then the GCL compiler can lay down faster code. However there is a bootstrap problem here also since the GCL compiler has to compile the code one time in order to generate the .fn file. VECTOR.lsp + VECTOR.fn -> VECTOR.o (type optimized) So the full, proper procedure, which I have yet to do, would actually call the GCL compile once to generate the .fn file with exact type information for function calls, load the .fn file, and the recompile the lisp file. Since the second compile has exact type information the generated code will be (potentially much) shorter. For each lisp file do ( VECTOR.lsp -> VECTOR.o + VECTOR.fn (unoptimized, but type generated) VECTOR.lsp + VECTOR.fn -> VECTOR.o (type optimized) ) > Still after reading the interp and algebra Makefiles again, > I do not see why interpsys is being rebuilt after I delete > all the *.NRLIB's and repeat the 'make'. I am still missing > something somewhere. Is there some "missing link" that still > connects the algebra/Makefile back to the inter/Makefile? I have to think about this (I'm getting ready for work so I'll give it some "drive-time cycles") but I believe that the issue is related to using fresh databases. The databases are used during the algebra compiles to resolve algebra calls. However recompiling the algebra generates NRLIBs and, from these NRLIBs a fresh database is built thus: DATABASES -> NRLIBs -> FRESH DATABASES This is yet a third bootstrap issue. There are more but not with the algebra files. \end{verbatim} \section{email 9} \begin{verbatim} Yet one other opportunity for speed optimization is available at build time.... Remember that every lisp file generates a .fn file: foo.lsp -> foo.o + foo.fn and that a second compile with the .fn file loaded is faster: foo.lsp + foo.fn -> faster foo.o However if we look at the type information in the foo.fn file we find that it only contains type information for functions defined in foo.lsp. But suppose there are two lisp files with functions from one using functions from the other. The sub-optimal sequence is: foo.lsp -> foo.o + foo.fn foo.lsp + foo.fn -> faster foo.o bar.lsp -> bar.o + bar.fn bar.lsp + bar.fn -> faster bar.o The optimal sequence is: foo.lsp -> foo.o + foo.fn bar.lsp -> bar.o + bar.fn foo.lsp + (foo.fn + bar.fn) -> even faster foo.o bar.lsp + (foo.fn + bar.fn) -> even faster bar.o So, really what we should do is cache ALL of the .fn files from all of the compiles, batch them into a big file, and the completely rebuild the system with the batched .fn files loaded. I've started this process but have not yet completed it. See the file src/boot/boot-proclaims.lisp So there is a faster Axiom coming in the future but the build complexity will be even greater. And Camm, I believe, is doing even more with type propagation which will improve things more. \end{verbatim} \section{email 10} \begin{verbatim} I am no longer baffled. The explanation for the generic arith vs. fixnum arith is in macros.lisp. In the following code from -REPEAT, X is bound to a form such as '((STEP |i| 3 1)): (COND ((AND (EQ (CAAR X) 'STEP) (|member| (CADDAR X) '(2 1 0 (|One|) (|Zero|))) (|member| (CADR (CDDAR X)) '(1 (|One|)))) (SETQ X (CONS (CONS 'ISTEP (CDAR X)) (CDR X))) )) ; A hack to increase the likelihood of small integers So, one `rule' is, if you iterate with a sequence with lower bound 0,1, or 2, with an increment of 1, you get fixnum arith. Otherwise you get generic arithmetic. However, this is not a hard and fast rule, since the compiler can say '(ISTEP |i| 5 23) [say] during code generation and force fixnum arith. This leads to a question. Tim, in interp/wi2.boot we have a redefinition of compIterator (default implementation is in iterator.boot). This new definition makes an attempt at deciding when fixnum stepping code should be generated. Do you have an explanation as to why is this not the default definition? The original version of the code in iterator.boot is what gets called. I'm wondering if it is possible that during the fixedPoint build if some of the new definitions (particularly those in wi2.boot, xruncomp.boot) are being autoloaded during compilation. The changes which I have already noted in the generated lisp seem to support this (fixnum arith vs. generic arith, inlining of trivial coercions, etc). All the changes make sense if they are the result of calling one of the `improved' functions which these files redefine. Sincerely, Steve On Mon, Jan 17, 2005 at 01:39:45PM -0500, Stephen Wilson wrote: > > Tim, > > I compleatly fine with the fixnum declaration. We just need to make > sure it is a rule programmers can rely on. Consider: > > )abbrev package ITER Iter > Iter(): E == I where > E == with > iter: () -> Void > I == add > iter(): Void == > for i in 2.. repeat > print(i::OutputForm) > > > The relavent lisp decalres we are using fixnums: > > (LETT |i| (QSADD1 |i|) |ITER;iter;V;1|) > > > Now compile the above with a lower bound of 3: > > for i in 3.. repeat > print(i::OutputForm) > > > We get generic arithmetic: > > (LETT |i| (+ |i| 1) |ITER;iter;V;1|) > > > Baffled, > Steve > > > On Mon, Jan 17, 2005 at 12:23:36PM -0500, root wrote: > > Steve, > > > > I don't know if there is an actual statement to the effect that > > the upper bound on a loop would be a register-sized number (32 > > or 64 bits) but at 6Mhz it seemed impossible that one could > > run a loop of any consequence for greater than 2^32 or 2^64 > > iterations. If you wanted to do that you'd have to do the > > looping using some other construct. In general it is safe to > > assume that the upper bound of the register size cannot be > > exceeded. There is a practical performance difference to > > be gained by using (declare (fixnum as the compiler can, > > in the best case, assign a register to the loop variable. > > > > t \end{verbatim} \section{email 11} \begin{verbatim} I installed "Aldor version 1.0.2 for LINUX(glibc2.3)" on axiom-developer.org several months ago. The date on the aldor tarball in /home/page is May 19 2004. Aldor should be accessible to you when you log in at axiom-developer. Just add export ALDORROOT=/usr/local/aldor/linux/1.0.2 export PATH=$ALDORROOT/bin:$PATH to your .bashrc, do . .bashrc and your should be able to type aldor ... You should find the libaries in the standard locations. There is apparently a fairly up to date windows binary version as well, but I haven't had much time to play with this yet. At the time I was planning to implement a MathAction- Aldor web interface that would look something like this \begin{aldor} ... aldor code ... \end{aldor} and which could be intermixed with Axiom code on the MathAction website. I got distracted by other things and so have not yet completed the integration with MathAction but there is not a lot more to do. Recent discussions here about getting Axiom and Aldor working together again suggest that it might be time for me to raise the priority to make this possible. Ralf Hemmecke wrote: > > If you mean cvs.aldor.org, then it might be that May 16 2004 > is a bit late. The libraries have changed since then. > > You could however download the latest precompiled version > 1.0.2 from > > http://www.aldor.org/downl.html > > If you really want to compile the libraries yourself, ask > me again. I think the newest cvs-version should compile, > but if they don't ... There has been some work on the > Makefiles since May 16. > > Ralf > > root wrote: > > Martin, Peter, > > > > I tried to build aldor last night. I succeeded in building > > the compiler but not the libraries. I have a CVS checkout > > from May 16. > > > > I've been reading the Makefiles but they all seem to dissolve > > into home-grown tools (makeon, docc, etc) which undermines my > > ability to figure out what is happening. It's been years since > > I built aldor. > > > > Peter, could you provide the required steps to build a working > > compiler? e.g. > > > > edit Makefile.globals to change.... make aldorcompiler > > .... > > \end{verbatim} \section{email 12} \begin{verbatim} Oops, sorry that I have not read the documentation of Any. I had a look at Any now. Well, from that I just got the feeling that a programmer should never use Any if there are better types around (and often there are). Any seems to be connected to the interpreter. Since everything must have a type and the interpreter cannot figure out something reasonable, it falls back to Any. I'd rather be happy if the interpreter is clearly separated from the compiler. The interpreter is for working with Axiom, so it could help the (lazy) user and find/guesss appropriate types for him/her. However there should be NO guessing when it comes to writing new library code. Looking at the code of Any reminds me much of the things I have suggested here address@bogus.example.com">http://page.axiom-developer.org/zope/mathaction/address@bogus.example.com The code is in cvs.aldor.org/aldor/aldorug/samples/object*.as. The problem I still have with any is that it says Rep := Record(dm: SExpression, ob: None) dom x == x.dm which looks very near to some LISP thing. So I can ask for the domain a: Any by calling dom(a). Then I will get an SExpression which makes me feel lost. Unfortunately, I have no runnig Axiom at the moment :-( And I cannot compile axim--main--1 (bfd.h is missing and I have no idea what to install). So I tested on http://page.axiom-developer.org/zope/mathaction/AxiomInterface i: Integer := 1 Type: Integer a: Any := i::Any Type: Integer <----- very interesting!!! dom a Type: SExpression obj a Type: None j: Integer := a :: Integer Type: Integer It seems the interpreter is quite smart. s: String := "I am a string" Type: String b: Any := s::Any Type: String dom b Type: SExpression? obj b Type: None k: Integer := b :: Integer Cannot convert from type Any to Integer for value "I am a string" This Error is OK. And I think for manually working with Axiom, one just needs to type dom(...) and then coerce to the now known type. But how to use Any in a program is totally unclear to me. I have no idea to get the domain back from the SExpression. \end{verbatim} \section{email 13} \begin{verbatim} > ... > I am, however, very much against the Any type. It is like > building a strongly typed language and than trying to forget > about types. > Well that is more or less what I naively thought as well but from the ANY.spad file I read that: )abbrev domain ANY Any ++ Author: Robert S. Sutor ++ Basic Functions: any, domainOf, objectOf, dom, obj, ++ showTypeInOutput ++ Related Constructors: AnyFunctions1 ++ Description: ++ \spadtype{Any} implements a type that packages up objects and ++ their types in objects of \spadtype{Any}. Roughly speaking ++ that means that if \spad{s : S} then when converted to ++ \spadtype{Any}, the new object will include both the original ++ object and its type. This is a way of converting arbitrary ++ objects into a single type **without losing any** of the ++ original information. Any object can be converted to one of ++ \spadtype{Any}. and in the related file ANY1.spad )abbrev package ANY1 AnyFunctions1 ++ Basic Functions: coerce, retractIfCan, retractable?, retract ++ Description: ++ \spadtype{AnyFunctions1} implements several utility functions ++ for working with \spadtype{Any}. These functions are used to ++ go back and forth between objects of \spadtype{Any} and objects ++ of other types. So the situation is not quiet so simple. Apparently Any does not mean Any in the sense of throwing away essential information. \end{verbatim} \section{email 14} \begin{verbatim} Ralf Hemmecke wrote: > > Hi Bill, > > >>Foo: with { g: (n: PositiveInteger, k: PositiveInteger) -> > >>PrimeField(n) } == add { > >>g(n: PositiveInteger, k: PositiveInteger ): PrimeField(n) == > >> k::Integer::PrimeField(n) } > > > Ok, I will work with this example. Yes, it is better. > > Well, I haven't checked whether it should really work, but > shouldn't be > > Foo: with { > g: (n: PositiveInteger, k: PositiveInteger) -> > (P: PrimeFieldCategory, x: P) > } == add { > g(n: PositiveInteger, k: PositiveInteger ): > (P: PrimeFieldCategory, x:P) == { > (PrimeField(n), k::Integer::PrimeField(n) > } > } > > be even better? In fact you just pointed a way to solve the problem! Notice that you are in effect constructing a domain! So first create this domain (call this anything else you like): --%PointedPrimeField )abbrev domain PPF PointedPrimeField PointedPrimeField(n:PositiveInteger):Cat==Dog where Cat == FiniteFieldCategory with foo:PositiveInteger->PrimeField(n) Dog == PrimeField(n) add foo(k)==k::Integer::PrimeField(n) After compiling, define in the interpreter g(n,k)==foo(k)$PPF(n) and it works (in Axiom)! (Do not declare the types for g because n is not defined). But I have trouble with path in windows: Processing PointedPrimeField for Browser database: --->-->PointedPrimeField((foo ((PrimeField n) (PositiveInteger)))): Not document ed!!!! --->-->PointedPrimeField(constructor): Not documented!!!! --->-->PointedPrimeField(): Missing Description h:/dostools/rm.exe: j:/program: No such file or directory h:/dostools/rm.exe: j:/progra~1/axiom/mnt/windows/lib/files/axiom/mnt/windows/li b/ppf.nrlib: No such file or directory >> System error: Cannot rename the file #P"j:/Program Files/axiom/mnt/windows/lib/PPF.erlib" t o #P"j:/Program Files/axiom/mnt/windows/lib/PPF.NRLIB". protected-symbol-warn called with (NIL) But that is just because "Program Files" need be in quotes? \end{verbatim} \section{email 15} \begin{verbatim} Foo: with { g: (n: PositiveInteger, k: PositiveInteger) -> PrimeField(n) } == add { g(n: PositiveInteger, k: PositiveInteger ): PrimeField(n) == k::Integer::PrimeField(n) } Ok, I will work with this example. Yes, it is better. Well, I haven't checked whether it should really work, but shouldn't be Foo: with { g: (n: PositiveInteger, k: PositiveInteger) -> (P: PrimeFieldCategory, x: P) } == add { g(n: PositiveInteger, k: PositiveInteger ): (P: PrimeFieldCategory, x:P) == { (PrimeField(n), k::Integer::PrimeField(n) } } be even better? The above code will not compile in Aldor, since it does not have PositiveInteger. And maybe it will even not compile with appropriate substitutions since the compiler cannot handle such a construction. I am, however, very much against the Any type. It is like building a strongly typed language and than trying to forget about types. For the interpreter it maybe OK, but not for the compiler. Programming in Axiom should mean writing programs for the compiler. I would say that programming in the interpreter is just writing short scripts but not real programs. See also http://www.aldor.org/docs/HTML/chap23.html#10\end{verbatim} \section{email 16} \begin{verbatim} On Wednesday, January 12, 2005 8:30 AM you wrote: > Bill Page wrote: > > > > I don't really understand when the use of parameterized > > return types on functions would be useful. What information > > is being returned as part of the type of the result that is > > not already known because of it's value? > > The above is an example. Perhaps, more convincing: > > Foo: with { g: (n: PositiveInteger, k: PositiveInteger) -> > PrimeField(n) } == add { > g(n: PositiveInteger, k: PositiveInteger ): PrimeField(n) == > k::Integer::PrimeField(n) } > Ok, I will work with this example. Yes, it is better. > Another example is Marcus Better's problem, more examples > are in expr2ups.spad, where Any is used a lot. Ok. > The type tells you in what domain to interpret the value. > But sometimes, the type will have to depend on a parameter > of the function, as above. That is still now clear to me, at least when it is possible to use a Union. > > > As I see it the concept does considerable damage to the > > notion of the 'domain' of a function. How should we > > interpret the expressioin `PrimeField(n)' when n is > > unknown? Does it represent the Union over all values n? > > We can no longer write the signature of a function in > > the simple form: > > > > f: PositiveInteger -> PrimeField > > Yes you can: Aldor does it. The signature is > > f: (n: PositiveInteger) -> PrimeField n > That does not look like a *signature* to me. What is the value of n? If you can't tell me, then how can I interpret `PrimeField n'? A signature should specify the domains of the function, but `PrimeField n' is not a domain until `n' is replaced with some PositiveInteger. The only interpretation of `PrimeField n' as a domain that I can think of would be to claim that it represents some kind of Union over the primes. Union(PrimeField n for n=1.. | prime? n) But of course we can't write it quite this nicely right now in Axiom... This is similar to Axiom's insistence that A:Integer can not be used in the expression A+1 until A is assigned a value. I this case I think it should be ok to say that if A has no assigned value then it represents the domain {+/-n for n=0..} > > Can you explain again why you don't find the usual > > Axiom solution to this situation acceptible? I.e. the > > use of the `Any' domain: > > > > f:PositiveInteger->Any > > f(n) == n::PrimeField(n) > > Because you cannot use it in compiled code and because you > are using all of the type information, which is the main > point of Axiom. But as you said, `Any' is used extensively in expr2ups.spad. > Of course, the example you just gave doesn't > make any sense, the result is always zero, but given the > function > > Bar: with { h: (n: PositiveInteger, k: PositiveInteger) -> Any } > == add { g(n: PositiveInteger, k: PositiveInteger ): Any == > k::Any } > > you cannot use this function in compiled code anymore. The > interpreter can deal with it, not the compiler. I would write it something like this: (2) -> h:(PositiveInteger,PositiveInteger)->Union( _ PrimeField(2),PrimeField(3),PrimeField(5),PrimeField(7)) Type: Void (3) -> h(n,k)==k::PrimeField(n) Type: Void (4) -> x:=h(7,2) (4) 2 Type: Union(PrimeField 7,...) (5) -> trace x (5) 2 Type: PrimeField 7 > > Look at Marcus code for a really convincing example: He wants > to construct recursively an algebraic extension of a ring, > adding elements one at the time. At the end of the process > he wants to return an element of the final ring. It is tricky > to do this in Axiom currently. I will take a closer look at the emails from Marcus. > > Note, for example, if you have a signature > > f: Integer -> Any > > but really, f returns a SimpleAlgebraicExtension of some > ring, you cannot do any calculations with the result in > compiled code anymore, unless you know *exactly* the defining > polynomial of the ring. I agree that Any throws away too much information, except in the interpreter where it tries to do a better job. But I think even there Any is (usually) not a good choice for the domain. > > So one way out -- in this specific case -- would be to > return a record containing the result of type Any and > the defining polynomial. I hope you admit that this is > ugly. I agree that that is ugly. Using an explicit "streaming Union" (iterator) domain would be my (future) choice. Unfortunately for now: (6) -> Union(PrimeField(i) for i in 1..10) Local variable or parameter used in type We will attempt to interpret the code. Category, domain or package constructor COLLECT is not available. (6) -> Union(PrimeField(i) for i in 1..) Loading C:/Program Files/axiom/mnt/windows/algebra/UNISEG.o for domain UniversalSegment Loading C:/Program Files/axiom/mnt/windows/algebra/INCRMAPS.o for package IncrementingMaps Loading C:/Program Files/axiom/mnt/windows/algebra/ITUPLE.o for domain InfiniteTuple Loading C:/Program Files/axiom/mnt/windows/algebra/STREAM.o for domain Stream Local variable or parameter used in type We will attempt to interpret the code. Interpret-Code mode is not supported for stream bodies. (6) -> \end{verbatim} \section{email 17} \begin{verbatim} > > #include "axiom" > > > > Test: with { f: (n: PositiveInteger) -> PrimeField(n) } > > == add { f(n: PositiveInteger): PrimeField(n) == > > 10::Integer::PrimeField(n) } > > > > Note that such a construction -- the resulting domain depending on the > > function parameter -- is currently illegal in Axiom. In Aldor it is fine. > > I don't really understand when the use of parameterized return types on > functions would be useful. What information is being returned as part of the > type of the result that is not already known because of it's value? The above is an example. Perhaps, more convincing: Foo: with { g: (n: PositiveInteger, k: PositiveInteger) -> PrimeField(n) } == add { g(n: PositiveInteger, k: PositiveInteger ): PrimeField(n) == k::Integer::PrimeField(n) } Another example is Marcus Better's problem, more examples are in expr2ups.spad, where Any is used a lot. The type tells you in what domain to interpret the value. But sometimes, the type will have to depend on a parameter of the function, as above. > As I see it the concept does considerable damage to the notion of the > 'domain' of a function. How should we interpret the expressioin > `PrimeField(n)' when n is unknown? Does it represent the Union over all > values n? We can no longer write the signature of a function in the simple > form: > > f: PositiveInteger -> PrimeField Yes you can: Aldor does it. The signature is f: (n: PositiveInteger) -> PrimeField n > Can you explain again why you don't find the usual Axiom solution to this > situation acceptible? I.e. the use of the `Any' domain: > > f:PositiveInteger->Any > f(n) == n::PrimeField(n) Because you cannot use it in compiled code and because you are using all of the type information, which is the main point of Axiom. Of course, the example you just gave doesn't make any sense, the result is always zero, but given the function Bar: with { h: (n: PositiveInteger, k: PositiveInteger) -> Any } == add { g(n: PositiveInteger, k: PositiveInteger ): Any == k::Any } you cannot use this function in compiled code anymore. The interpreter can deal with it, not the compiler. Look at Marcus code for a really convincing example: He wants to construct recursively an algebraic extension of a ring, adding elements one at the time. At the end of the process he wants to return an element of the final ring. It is tricky to do this in Axiom currently. Note, for example, if you have a signature f: Integer -> Any but really, f returns a SimpleAlgebraicExtension of some ring, you cannot do any calculations with the result in compiled code anymore, unless you know *exactly* the defining polynomial of the ring. So one way out -- in this specific case -- would be to return a record containing the result of type Any and the defining polynomial. I hope you admit that this is ugly.\end{verbatim} \section{email 18} \begin{verbatim} I have been thinking about your example code. On Tuesday, January 11, 2005 9:44 AM you wrote: > ... > I just tried another example, which is in fact the reason > why I would love to have Aldor working. I did not expect > it to work, and it does not, but it works *almost*. The > code is as follows: > > #include "axiom" > > Test: with { f: (n: PositiveInteger) -> PrimeField(n) } > == add { f(n: PositiveInteger): PrimeField(n) == > 10::Integer::PrimeField(n) } > > Note that such a construction -- the resulting domain > depending on the function parameter -- is currently > illegal in Axiom. In Aldor it is fine. I don't really understand when the use of parameterized return types on functions would be useful. What information is being returned as part of the type of the result that is not already known because of it's value? As I see it the concept does considerable damage to the notion of the 'domain' of a function. How should we interpret the expressioin `PrimeField(n)' when n is unknown? Does it represent the Union over all values n? We can no longer write the signature of a function in the simple form: f: PositiveInteger -> PrimeField Can you explain again why you don't find the usual Axiom solution to this situation acceptible? I.e. the use of the `Any' domain: f:PositiveInteger->Any f(n) == n::PrimeField(n) Perhaps in some cases the use of a Union might even be better: f:PositiveInteger->Union(PrimeField(2),PrimeField(3), PrimeField(5), ...) f(n) == n::PrimeField(n) The union allows a 'case' construction like this: f(3) case PrimeField(3) In fact this sort of thing works in Axiom: (1) -> f:PositiveInteger->Union(PrimeField(2),PrimeField(3), _ PrimeField(5),PrimeField(7),"Failed") f(n) == ( prime? n and n<=7 => n::PrimeField(n); "Failed") Function declaration f : PositiveInteger -> Union(PrimeField 2, PrimeField 3,PrimeField 5,PrimeField 7,Failed) has been added to workspace. Type: Void (2) -> f(2) Cannot compile conversion for types involving local variables. In particular, could not compile the expression involving :: PrimeField #1 AXIOM will attempt to step through and interpret the code. Compiling function f with type PositiveInteger -> Union(PrimeField 2 ,PrimeField 3,PrimeField 5,PrimeField 7,Failed) (2) 0 Type: Union(PrimeField 2,...) (3) -> f(3) (3) 0 Type: Union(PrimeField 3,...) (4) -> f(4) (4) Failed Type: Union(Failed,...) (5) -> f(5) (5) 0 Type: Union(PrimeField 5,...) (6) -> x:=f(5) (6) 0 Type: Union(PrimeField 5,...) (7) -> x case PrimeField(5) (7) true Type: Boolean (8) -> x case PrimeField(3) (8) false Type: Boolean etc.\end{verbatim} \section{email 19} \begin{verbatim} Peter Broadbery writes: > On Tue, 2005-01-11 at 14:30 +0100, Martin Rubey wrote: > > Dear Peter, > > > > this is just great stuff -- nearly... I had to try it out right away, but I > > experienced two problems. > > > > the minor one is, that )co inside axiom still does not work: > > > > (1) -> > > (1) -> )co test.as > > Compiling AXIOM source code from file > > /home/rubey/martin/Axiom/test.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. > > > > >> System error: > > NIL is not of type STRING. > > > ln -s $ALDORROOT $AXIOM/compiler may help here. fixing i-syscmd.boot to > produce a nice error would be nice, I guess. I tried that, but it won't work. Tim, is there a way to trace what's happening? Note that both $ALDORROOT and $AXIOM were set correctly. In other words, the link above produced a directory "compiler" in "axiom/mnt/linux", containing the following directories of Aldor: bin/ doc/ include/ lib/ src/ tests/ > The .as file isn't in CVS (the file is compiled - don't be fooled by the > readable coding style) Sorry, my mistake. Only lsp files. By the way, there i *lots* of stuff in the directories under /lsp/ccl/src, some look like they could be really useful... Tim: could you rename them to .pamphlet and correct the \usepackage line in each one of them? Thanks! > > (1) -> fact(5)$Test > > > > (1) 120 > > Type: > > PositiveInteger > > (2) -> fact(4)$Test > > > > >> System error: > > #