\documentclass{article}
\usepackage{axiom}
\begin{document}
\title{\$SPAD/src/algebra sex.spad}
\author{Stephen M. Watt}
\maketitle
\begin{abstract}
\end{abstract}
\eject
\tableofcontents
\eject
\section{category SEXCAT SExpressionCategory}
<<category SEXCAT SExpressionCategory>>=
)abbrev category SEXCAT SExpressionCategory
++ Category for Lisp values
++ Author: S.M.Watt
++ Date Created: July 1987
++ Date Last Modified: 23 May 1991
++ Description:
++  This category allows the manipulation of Lisp values while keeping
++  the grunge fairly localized.
--  The coerce to expression lets the
--  values be displayed in the usual parenthesized way (displaying
--  them as type Expression can cause the formatter to die, since
--  certain magic cookies are in unexpected places).
--  SMW July 87
SExpressionCategory(Str, Sym, Int, Flt, Expr): Category == Decl where
    Str, Sym, Int, Flt, Expr: SetCategory

    Decl ==> SetCategory with
        eq:        (%,%) -> Boolean
          ++ eq(s, t) is true if EQ(s,t) is true in Lisp.
        null?:     % -> Boolean
          ++ null?(s) is true if s is the S-expression ().
        atom?:     % -> Boolean
          ++ atom?(s) is true if s is a Lisp atom.
        pair?:     % -> Boolean
          ++ pair?(s) is true if s has is a non-null Lisp list.
        list?:     % -> Boolean
          ++ list?(s) is true if s is a Lisp list, possibly ().
        string?:   % -> Boolean
          ++ string?(s) is true if s is an atom and belong to Str.
        symbol?:   % -> Boolean
          ++ symbol?(s) is true if s is an atom and belong to Sym.
        integer?:  % -> Boolean
          ++ integer?(s) is true if s is an atom and belong to Int.
        float?:    % -> Boolean
          ++ float?(s) is true if s is an atom and belong to Flt.
        destruct:  % -> List %
          ++ destruct((a1,...,an)) returns the list [a1,...,an].
        string:    % -> Str
          ++ string(s) returns s as an element of Str.
          ++ Error: if s is not an atom that also belongs to Str.
        symbol:    % -> Sym
          ++ symbol(s) returns s as an element of Sym.
          ++ Error: if s is not an atom that also belongs to Sym.
        integer:   % -> Int
          ++ integer(s) returns s as an element of Int.
          ++ Error: if s is not an atom that also belongs to Int.
        float:     % -> Flt
          ++ float(s) returns s as an element of Flt;
          ++ Error: if s is not an atom that also belongs to Flt.
        expr:      % -> Expr
          ++ expr(s) returns s as an element of Expr;
          ++ Error: if s is not an atom that also belongs to Expr.
        convert:   List % -> %
          ++ convert([a1,...,an]) returns the S-expression \spad{(a1,...,an)}.
        convert:   Str    -> %
          ++ convert(x) returns the Lisp atom x;
        convert:   Sym    -> %
          ++ convert(x) returns the Lisp atom x.
        convert:   Int    -> %
          ++ convert(x) returns the Lisp atom x.
        convert:   Flt    -> %
          ++ convert(x) returns the Lisp atom x.
        convert:   Expr   -> %
          ++ convert(x) returns the Lisp atom x.
        car:       % -> %
          ++ car((a1,...,an)) returns a1.
        cdr:       % -> %
          ++ cdr((a1,...,an)) returns \spad{(a2,...,an)}.
        "#":       % -> Integer
          ++ #((a1,...,an)) returns n.
        elt:       (%, Integer)      -> %
          ++ elt((a1,...,an), i) returns \spad{ai}.
        elt:       (%, List Integer) -> %
          ++ elt((a1,...,an), [i1,...,im]) returns \spad{(a_i1,...,a_im)}.

@
\section{domain SEXOF SExpressionOf}
<<domain SEXOF SExpressionOf>>=
)abbrev domain SEXOF SExpressionOf
++ Domain for Lisp values over arbitrary atomic types
++ Author: S.M.Watt
++ Date Created: July 1987
++ Date Last Modified: 23 May 1991
++ Description:
++  This domain allows the manipulation of Lisp values over
++  arbitrary atomic types.
-- Allows the names of the atomic types to be chosen.
-- ^* Warning ^* Although the parameters are declared only to be Sets,
-- ^* Warning ^* they must have the appropriate representations.
SExpressionOf(Str, Sym, Int, Flt, Expr): Decl == Body where
    Str, Sym, Int, Flt, Expr: SetCategory

    Decl ==> SExpressionCategory(Str, Sym, Int, Flt, Expr)

    Body ==> add

        dotex:OutputForm := INTERN(".")$Lisp

        coerce(b:%):OutputForm ==
            null? b => paren empty()
            atom? b => b pretend OutputForm
            r := b
            while not atom? r repeat r := cdr r
            l1 := [b1::OutputForm for b1 in (l := destruct b)]
            not null? r =>
              paren blankSeparate concat_!(l1, [dotex, r::OutputForm])
            #l = 2 and (first(l1) = QUOTE)@Boolean => quote first rest l1
            paren blankSeparate l1

        b1 = b2        == EQUAL(b1,b2)$Lisp
        eq(b1, b2)     == EQ(b1,b2)$Lisp

        null? b      == NULL(b)$Lisp
        atom? b      == ATOM(b)$Lisp
        pair? b      == PAIRP(b)$Lisp

        list?    b   == PAIRP(b)$Lisp or NULL(b)$Lisp
        string?  b   == STRINGP(b)$Lisp
        symbol?  b   == IDENTP(b)$Lisp
        integer? b   == INTEGERP(b)$Lisp
        float?   b   == FLOATP(b)$Lisp

        destruct b == (list? b    => b pretend List %; error "Non-list")
        string b == (STRINGP(b)$Lisp=> b pretend Str;error "Non-string")
        symbol b == (IDENTP(b)$Lisp => b pretend Sym;error "Non-symbol")
        float   b == (FLOATP(b)$Lisp  => b pretend Flt;error "Non-float")
        integer b == (INTEGERP(b)$Lisp => b pretend Int;error "Non-integer")
        expr    b == b pretend Expr

        convert(l:  List %) == l  pretend %
        convert(st: Str)    == st pretend %
        convert(sy: Sym)    == sy pretend %
        convert(n:  Int)    == n  pretend %
        convert(f:  Flt)    == f  pretend %
        convert(e:  Expr)   == e  pretend %

        car b        == CAR(b)$Lisp
        cdr b        == CDR(b)$Lisp
        #   b        == LENGTH(b)$Lisp
        elt(b:%, i:Integer)       == destruct(b).i
        elt(b:%, li:List Integer) ==
          for i in li repeat b := destruct(b).i
          b

@
\section{domain SEX SExpression}
<<domain SEX SExpression>>=
)abbrev domain SEX SExpression
++ Domain for the standard Lisp values
++ Author: S.M.Watt
++ Date Created: July 1987
++ Date Last Modified: 23 May 1991
++ Description:
++  This domain allows the manipulation of the usual Lisp values;
SExpression()
       == SExpressionOf(String, Symbol, Integer, DoubleFloat, OutputForm)

@
\section{License}
<<license>>=
--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--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.
@
<<*>>=
<<license>>

<<category SEXCAT SExpressionCategory>>
<<domain SEXOF SExpressionOf>>
<<domain SEX SExpression>>
@
\eject
\begin{thebibliography}{99}
\bibitem{1} nothing
\end{thebibliography}
\end{document}
