\documentclass{article}
\usepackage{axiom}
\begin{document}
\title{\$SPAD/src/algebra alql.spad}
\author{The Axiom Team}
\maketitle
\begin{abstract}
\end{abstract}
\eject
\tableofcontents
\eject
\section{domain DLIST DataList}
<<domain DLIST DataList>>=
)abbrev domain DLIST DataList
++ This domain provides some nice functions on lists
DataList(S:OrderedSet) : Exports == Implementation where
  Exports == ListAggregate(S) with
    coerce: List S -> %
      ++ coerce(l) creates a datalist from l  	
    coerce: % -> List S
      ++ coerce(x) returns the list of elements in x
    datalist: List S -> %
      ++ datalist(l) creates a datalist from l 
    elt: (%,"unique") -> %
      ++ \axiom{l.unique} returns \axiom{l} with duplicates removed.
      ++ Note: \axiom{l.unique = removeDuplicates(l)}.
    elt: (%,"sort") -> %
      ++ \axiom{l.sort} returns \axiom{l} with elements sorted.
      ++ Note: \axiom{l.sort = sort(l)}
    elt: (%,"count") -> NonNegativeInteger
      ++ \axiom{l."count"} returns the number of elements in \axiom{l}.
  Implementation == List(S) add
    elt(x,"unique") == removeDuplicates(x)
    elt(x,"sort") == sort(x)
    elt(x,"count") == #x
    coerce(x:List S) == x pretend %
    coerce(x:%):List S == x pretend (List S)
    coerce(x:%): OutputForm == (x :: List S) :: OutputForm
    datalist(x:List S) == x::%

@
\section{domain ICARD IndexCard}
<<domain ICARD IndexCard>>=
)abbrev domain ICARD IndexCard
++ This domain implements a container of information
++ about the AXIOM library
IndexCard() : Exports == Implementation where
  Exports == OrderedSet with
    elt: (%,Symbol) -> String
      ++ elt(ic,s) selects a particular field from \axiom{ic}.  Valid fields
      ++ are \axiom{name, nargs, exposed, type, abbreviation, kind, origin,
      ++ params, condition, doc}.
    display: % -> Void
      ++ display(ic) prints a summary of the information contained in \axiom{ic}.
    fullDisplay: % -> Void
      ++ fullDisplay(ic) prints all of the information contained in \axiom{ic}.
    coerce: String -> %
      ++ coerce(s) converts \axiom{s} into an \axiom{IndexCard}.  Warning: if
      ++ \axiom{s} is not of the right format then an error will occur when using
      ++ it.
  Implementation == add
    Rep == String

    x<y == rep x < rep y

    x=y == rep x = rep y

    display(x) ==
      name : OutputForm := dbName(x)$Lisp
      type : OutputForm := dbPart(x,4,1$Lisp)$Lisp
      output(hconcat(name,hconcat(" : ",type)))$OutputPackage

    fullDisplay(x) ==
      name : OutputForm := dbName(x)$Lisp
      type : OutputForm := dbPart(x,4,1$Lisp)$Lisp
      origin:OutputForm := hconcat(alqlGetOrigin(x$Lisp)$Lisp,alqlGetParams(x$Lisp)$Lisp)
      fromPart : OutputForm := hconcat(" from ",origin)
      condition : String := dbPart(x,6,1$Lisp)$Lisp
      ifPart : OutputForm :=
        condition = "" => empty()
        hconcat(" if ",condition::OutputForm)
      exposed? : String := SUBSTRING(dbPart(x,3,1)$Lisp,0,1)$Lisp 
      exposedPart : OutputForm := 
        exposed? = "n" => " (unexposed)"
        empty()       
      firstPart := hconcat(name,hconcat(" : ",type))
      secondPart := hconcat(fromPart,hconcat(ifPart,exposedPart))
      output(hconcat(firstPart,secondPart))$OutputPackage

    coerce(s:String): % == per s 

    coerce(x): OutputForm == rep(x)::OutputForm

    elt(x,sel) ==
      sel = 'name => dbName(x)$Lisp
      sel = 'nargs => dbPart(x,2,1$Lisp)$Lisp
      sel = 'exposed => SUBSTRING(dbPart(x,3,1)$Lisp,0,1)$Lisp 
      sel = 'type => dbPart(x,4,1$Lisp)$Lisp
      sel = 'abbreviation => dbPart(x,5,1$Lisp)$Lisp
      sel = 'kind => alqlGetKindString(x)$Lisp
      sel = 'origin => alqlGetOrigin(x)$Lisp
      sel = 'params => alqlGetParams(x)$Lisp
      sel = 'condition => dbPart(x,6,1$Lisp)$Lisp
      sel = 'doc => dbComments(x)$Lisp
      userError "unknown selector"

@
\section{domain DBASE Database}
<<domain DBASE Database>>=
)abbrev domain DBASE Database
++ This domain implements a simple view of a database whose fields are 
++ indexed by symbols
Database(S): Exports == Implementation where
  S: OrderedSet with 
    elt: (%,Symbol) -> String
	++ elt(x,s) returns an element of x indexed by s
    display: % -> Void
	++ display(x) displays x in some form
    fullDisplay: % -> Void
	++ fullDisplay(x) displays x in detail
  Exports == SetCategory with
    elt: (%,QueryEquation) -> %
      ++ elt(db,q) returns all elements of \axiom{db} which satisfy \axiom{q}.
    elt: (%,Symbol) -> DataList String
      ++ elt(db,s) returns the \axiom{s} field of each element of \axiom{db}.
    _+: (%,%) -> %
      ++ db1+db2 returns the merge of databases db1 and db2
    _-: (%,%) -> %
      ++ db1-db2 returns the difference of databases db1 and db2 i.e. consisting
      ++ of elements in db1 but not in db2 
    coerce: List S -> %
      ++ coerce(l) makes a database out of a list
    display: % -> Void
      ++ display(db) prints a summary line for each entry in \axiom{db}.
    fullDisplay: % -> Void
      ++ fullDisplay(db) prints full details of each entry in \axiom{db}.
    fullDisplay: (%,PositiveInteger,PositiveInteger) -> Void
      ++ fullDisplay(db,start,end ) prints full details of entries in the range
      ++ \axiom{start..end} in \axiom{db}.
  Implementation == List S add
    s: Symbol
    Rep := List S
    coerce(u: List S):% == u@%
    elt(data: %,s: Symbol) == [x.s for x in data] :: DataList(String)
    elt(data: %,eq: QueryEquation) ==
      field := variable eq
      val := value eq
      [x for x in data | stringMatches?(val,x.field)$Lisp]
    x+y==removeDuplicates_! merge(x,y)
    x-y==mergeDifference(copy(x::Rep),y::Rep)$MergeThing(S)
    coerce(data): OutputForm == (#data):: OutputForm
    display(data) ==  for x in data repeat display x
    fullDisplay(data) == for x in data repeat fullDisplay x
    fullDisplay(data,n,m) == for x in data for i in 1..m repeat
      if i >= n then fullDisplay x

@
\section{domain QEQUAT QueryEquation}
<<domain QEQUAT QueryEquation>>=
)abbrev domain QEQUAT QueryEquation
++ This domain implements simple database queries 
QueryEquation(): Exports == Implementation where
  Exports == CoercibleTo(OutputForm) with
    equation: (Symbol,String) -> %
      ++ equation(s,"a") creates a new equation.
    variable: % -> Symbol
      ++ variable(q) returns the variable (i.e. left hand side) of \axiom{q}.
    value: % -> String
      ++ value(q) returns the value (i.e. right hand side) of \axiom{q}.
  Implementation == add
    Rep := Record(var:Symbol, val:String)
    coerce(u) == coerce(u.var)$Symbol = coerce(u.val)$String
    equation(x,s) == [x,s]
    variable q == q.var
    value q == q.val

@
\section{package MTHING MergeThing}
<<package MTHING MergeThing>>=
)abbrev package MTHING MergeThing
++ This package exports tools for merging lists
MergeThing(S:OrderedSet): Exports == Implementation where
  Exports == with
    mergeDifference: (List(S),List(S)) -> List(S)
	++ mergeDifference(l1,l2) returns a list of elements in l1 not present in l2.
	++ Assumes lists are ordered and all x in l2 are also in l1.
  Implementation == add
    mergeDifference1: (List S,S,List S) -> List S
    mergeDifference(x,y) == 
      null x or null y => x
      mergeDifference1(x,y.first,y.rest)
      x.first=y.first => x.rest
      x
    mergeDifference1(x,fy,ry) ==  
      rx := x
      while not null rx repeat
        rx := rx.rest
        frx := rx.first
        while fy < frx repeat
          null ry => return x
          fy := first ry
          ry := rest ry
        frx = fy =>
          x.rest := rx.rest
          null ry => return x
          fy := ry.first
          ry := ry.rest
        x := rx

@
\section{package OPQUERY OperationsQuery}
<<package OPQUERY OperationsQuery>>=
)abbrev package OPQUERY OperationsQuery
++ This package exports tools to create AXIOM Library information databases.
OperationsQuery(): Exports == Implementation where
  Exports == with
    getDatabase: String -> Database(IndexCard)
      ++ getDatabase("char") returns a list of appropriate entries in the
      ++ browser database.  The legal values for "char" are "o" (operations),
      ++ "k" (constructors), "d" (domains), "c" (categories) or "p" (packages).
  Implementation == add
    getDatabase(s) == getBrowseDatabase(s)$Lisp

@
\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>>

<<domain DLIST DataList>>
<<domain ICARD IndexCard>>
<<domain DBASE Database>>
<<domain QEQUAT QueryEquation>>
<<package MTHING MergeThing>>
<<package OPQUERY OperationsQuery>>
@
\eject
\begin{thebibliography}{99}
\bibitem{1} nothing
\end{thebibliography}
\end{document}