\documentclass{article}
\usepackage{open-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 == Join(SetCategory,ConvertibleFrom Str, ConvertibleFrom Sym,_
              ConvertibleFrom Int, ConvertibleFrom Flt,_
                ConvertibleFrom Flt, ConvertibleFrom Expr,_
                  ConvertibleFrom List %, Eltable(Integer,%),_
                    Eltable(List Integer, %)) with
        eq:        (%,%) -> Boolean
          ++ eq(s, t) is true if %peq(s,t) is true for pointers.
        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.
        car:       % -> %
          ++ car((a1,...,an)) returns a1.
        cdr:       % -> %
          ++ cdr((a1,...,an)) returns \spad{(a2,...,an)}.
        #:       % -> Integer
          ++ #((a1,...,an)) returns n.

@
\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
        import %integer?: % -> Boolean  from Foreign Builtin
        import %string?: % -> Boolean   from Foreign Builtin
        import %ident?: % -> Boolean    from Foreign Builtin
        import %pair?: % -> Boolean     from Foreign Builtin
        import %peq: (%,%) -> Boolean   from Foreign Builtin
        import %head: % -> %            from Foreign Builtin
        import %tail: % -> %            from Foreign Builtin
        import %llength: % -> Integer   from Foreign Builtin
        import %nil: %                  from Foreign Builtin
        import %equal: (%,%) -> Boolean from Foreign Builtin

        Rep := Expr

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

        coerce(b:%):OutputForm ==
            null? b => paren empty()
            string? b => string(b)::OutputForm
            atom? b => coerce(b)$Rep
            r := b
            while not atom? r repeat r := cdr r
            l : List %
            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)
        eq(b1, b2)     == %peq(b1,b2)

        null? b      == %peq(b,%nil)
        atom? b      == not pair? b
        pair? b      == %pair? b

        list?    b   == pair? b or null? b
        string?  b   == %string? b
        symbol?  b   == %ident? b
        integer? b   == %integer? b
        float?   b   == RNUMP(b)$Lisp

        destruct b == (list? b    => b pretend List %; error "Non-list")
        string b == (%string? b => b pretend Str; error "Non-string")
        symbol b == (%ident? b => b pretend Sym;error "Non-symbol")
        float   b == (RNUMP(b)$Lisp  => b pretend Flt;error "Non-float")
        integer b == (INTP(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        == %head b
        cdr b        == %tail b
        #   b        == %llength b
        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}