aboutsummaryrefslogtreecommitdiff
path: root/src/algebra/aggcat.spad.pamphlet
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
committerdos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
commitab8cc85adde879fb963c94d15675783f2cf4b183 (patch)
treec202482327f474583b750b2c45dedfc4e4312b1d /src/algebra/aggcat.spad.pamphlet
downloadopen-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz
Initial population.
Diffstat (limited to 'src/algebra/aggcat.spad.pamphlet')
-rw-r--r--src/algebra/aggcat.spad.pamphlet3227
1 files changed, 3227 insertions, 0 deletions
diff --git a/src/algebra/aggcat.spad.pamphlet b/src/algebra/aggcat.spad.pamphlet
new file mode 100644
index 00000000..1363c020
--- /dev/null
+++ b/src/algebra/aggcat.spad.pamphlet
@@ -0,0 +1,3227 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra aggcat.spad}
+\author{Michael Monagan, Manuel Bronstein, Richard Jenks, Stephen Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category AGG Aggregate}
+<<category AGG Aggregate>>=
+
+)abbrev category AGG Aggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The notion of aggregate serves to model any data structure aggregate,
+++ designating any collection of objects,
+++ with heterogenous or homogeneous members,
+++ with a finite or infinite number
+++ of members, explicitly or implicitly represented.
+++ An aggregate can in principle
+++ represent everything from a string of characters to abstract sets such
+++ as "the set of x satisfying relation {\em r(x)}"
+++ An attribute \spadatt{finiteAggregate} is used to assert that a domain
+++ has a finite number of elements.
+Aggregate: Category == Type with
+ eq?: (%,%) -> Boolean
+ ++ eq?(u,v) tests if u and v are same objects.
+ copy: % -> %
+ ++ copy(u) returns a top-level (non-recursive) copy of u.
+ ++ Note: for collections, \axiom{copy(u) == [x for x in u]}.
+ empty: () -> %
+ ++ empty()$D creates an aggregate of type D with 0 elements.
+ ++ Note: The {\em $D} can be dropped if understood by context,
+ ++ e.g. \axiom{u: D := empty()}.
+ empty?: % -> Boolean
+ ++ empty?(u) tests if u has 0 elements.
+ less?: (%,NonNegativeInteger) -> Boolean
+ ++ less?(u,n) tests if u has less than n elements.
+ more?: (%,NonNegativeInteger) -> Boolean
+ ++ more?(u,n) tests if u has greater than n elements.
+ size?: (%,NonNegativeInteger) -> Boolean
+ ++ size?(u,n) tests if u has exactly n elements.
+ sample: constant -> % ++ sample yields a value of type %
+ if % has finiteAggregate then
+ "#": % -> NonNegativeInteger ++ # u returns the number of items in u.
+ add
+ eq?(a,b) == EQ(a,b)$Lisp
+ sample() == empty()
+ if % has finiteAggregate then
+ empty? a == #a = 0
+ less?(a,n) == #a < n
+ more?(a,n) == #a > n
+ size?(a,n) == #a = n
+
+@
+\section{category HOAGG HomogeneousAggregate}
+<<category HOAGG HomogeneousAggregate>>=
+)abbrev category HOAGG HomogeneousAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991, May 1995
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A homogeneous aggregate is an aggregate of elements all of the
+++ same type.
+++ In the current system, all aggregates are homogeneous.
+++ Two attributes characterize classes of aggregates.
+++ Aggregates from domains with attribute \spadatt{finiteAggregate}
+++ have a finite number of members.
+++ Those with attribute \spadatt{shallowlyMutable} allow an element
+++ to be modified or updated without changing its overall value.
+HomogeneousAggregate(S:Type): Category == Aggregate with
+ if S has SetCategory then SetCategory
+ if S has SetCategory then
+ if S has Evalable S then Evalable S
+ map : (S->S,%) -> %
+ ++ map(f,u) returns a copy of u with each element x replaced by f(x).
+ ++ For collections, \axiom{map(f,u) = [f(x) for x in u]}.
+ if % has shallowlyMutable then
+ map_!: (S->S,%) -> %
+ ++ map!(f,u) destructively replaces each element x of u by \axiom{f(x)}.
+ if % has finiteAggregate then
+ any?: (S->Boolean,%) -> Boolean
+ ++ any?(p,u) tests if \axiom{p(x)} is true for any element x of u.
+ ++ Note: for collections,
+ ++ \axiom{any?(p,u) = reduce(or,map(f,u),false,true)}.
+ every?: (S->Boolean,%) -> Boolean
+ ++ every?(f,u) tests if p(x) is true for all elements x of u.
+ ++ Note: for collections,
+ ++ \axiom{every?(p,u) = reduce(and,map(f,u),true,false)}.
+ count: (S->Boolean,%) -> NonNegativeInteger
+ ++ count(p,u) returns the number of elements x in u
+ ++ such that \axiom{p(x)} is true. For collections,
+ ++ \axiom{count(p,u) = reduce(+,[1 for x in u | p(x)],0)}.
+ parts: % -> List S
+ ++ parts(u) returns a list of the consecutive elements of u.
+ ++ For collections, \axiom{parts([x,y,...,z]) = (x,y,...,z)}.
+ members: % -> List S
+ ++ members(u) returns a list of the consecutive elements of u.
+ ++ For collections, \axiom{parts([x,y,...,z]) = (x,y,...,z)}.
+ if S has SetCategory then
+ count: (S,%) -> NonNegativeInteger
+ ++ count(x,u) returns the number of occurrences of x in u.
+ ++ For collections, \axiom{count(x,u) = reduce(+,[x=y for y in u],0)}.
+ member?: (S,%) -> Boolean
+ ++ member?(x,u) tests if x is a member of u.
+ ++ For collections,
+ ++ \axiom{member?(x,u) = reduce(or,[x=y for y in u],false)}.
+ add
+ if S has Evalable S then
+ eval(u:%,l:List Equation S):% == map(eval(#1,l),u)
+ if % has finiteAggregate then
+ #c == # parts c
+ any?(f, c) == _or/[f x for x in parts c]
+ every?(f, c) == _and/[f x for x in parts c]
+ count(f:S -> Boolean, c:%) == _+/[1 for x in parts c | f x]
+ members x == parts x
+ if S has SetCategory then
+ count(s:S, x:%) == count(s = #1, x)
+ member?(e, c) == any?(e = #1,c)
+ x = y ==
+ size?(x, #y) and _and/[a = b for a in parts x for b in parts y]
+ coerce(x:%):OutputForm ==
+ bracket
+ commaSeparate [a::OutputForm for a in parts x]$List(OutputForm)
+
+@
+\section{HOAGG.lsp BOOTSTRAP}
+{\bf HOAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf HOAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf HOAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<HOAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |HomogeneousAggregate;CAT| (QUOTE NIL))
+
+(SETQ |HomogeneousAggregate;AL| (QUOTE NIL))
+
+(DEFUN |HomogeneousAggregate| (#1=#:G82375)
+ (LET (#2=#:G82376)
+ (COND
+ ((SETQ #2# (|assoc| (|devaluate| #1#) |HomogeneousAggregate;AL|))
+ (CDR #2#))
+ (T
+ (SETQ |HomogeneousAggregate;AL|
+ (|cons5|
+ (CONS (|devaluate| #1#) (SETQ #2# (|HomogeneousAggregate;| #1#)))
+ |HomogeneousAggregate;AL|))
+ #2#))))
+
+(DEFUN |HomogeneousAggregate;| (|t#1|)
+ (PROG (#1=#:G82374)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|sublisV|
+ (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|)))
+ (COND
+ (|HomogeneousAggregate;CAT|)
+ ((QUOTE T)
+ (LETT |HomogeneousAggregate;CAT|
+ (|Join|
+ (|Aggregate|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|map| (|$| (|Mapping| |t#1| |t#1|) |$|)) T)
+ ((|map!| (|$| (|Mapping| |t#1| |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |shallowlyMutable|)))
+ ((|any?|
+ ((|Boolean|) (|Mapping| (|Boolean|) |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|every?|
+ ((|Boolean|) (|Mapping| (|Boolean|) |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|count|
+ ((|NonNegativeInteger|)
+ (|Mapping| (|Boolean|) |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|parts| ((|List| |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|members| ((|List| |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|count| ((|NonNegativeInteger|) |t#1| |$|))
+ (AND
+ (|has| |t#1| (|SetCategory|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|))))
+ ((|member?| ((|Boolean|) |t#1| |$|))
+ (AND
+ (|has| |t#1| (|SetCategory|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|))))))
+ (QUOTE (
+ ((|SetCategory|) (|has| |t#1| (|SetCategory|)))
+ ((|Evalable| |t#1|)
+ (AND
+ (|has| |t#1| (|Evalable| |t#1|))
+ (|has| |t#1| (|SetCategory|))))))
+ (QUOTE (
+ (|Boolean|)
+ (|NonNegativeInteger|)
+ (|List| |t#1|)))
+ NIL))
+ . #2=(|HomogeneousAggregate|))))) . #2#)
+ (SETELT #1# 0
+ (LIST (QUOTE |HomogeneousAggregate|) (|devaluate| |t#1|)))))))
+
+@
+\section{HOAGG-.lsp BOOTSTRAP}
+{\bf HOAGG-} depends on {\bf HOAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf HOAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf HOAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<HOAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |HOAGG-;eval;ALA;1| (|u| |l| |$|) (SPADCALL (CONS (FUNCTION |HOAGG-;eval;ALA;1!0|) (VECTOR |$| |l|)) |u| (QREFELT |$| 11)))
+
+(DEFUN |HOAGG-;eval;ALA;1!0| (|#1| |$$|) (SPADCALL |#1| (QREFELT |$$| 1) (QREFELT (QREFELT |$$| 0) 9)))
+
+(DEFUN |HOAGG-;#;ANni;2| (|c| |$|) (LENGTH (SPADCALL |c| (QREFELT |$| 14))))
+
+(DEFUN |HOAGG-;any?;MAB;3| (|f| |c| |$|) (PROG (|x| #1=#:G82396 #2=#:G82393 #3=#:G82391 #4=#:G82392) (RETURN (SEQ (PROGN (LETT #4# NIL |HOAGG-;any?;MAB;3|) (SEQ (LETT |x| NIL |HOAGG-;any?;MAB;3|) (LETT #1# (SPADCALL |c| (QREFELT |$| 14)) |HOAGG-;any?;MAB;3|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |HOAGG-;any?;MAB;3|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |x| |f|) |HOAGG-;any?;MAB;3|) (COND (#4# (LETT #3# (COND (#3# (QUOTE T)) ((QUOTE T) #2#)) |HOAGG-;any?;MAB;3|)) ((QUOTE T) (PROGN (LETT #3# #2# |HOAGG-;any?;MAB;3|) (LETT #4# (QUOTE T) |HOAGG-;any?;MAB;3|))))))) (LETT #1# (CDR #1#) |HOAGG-;any?;MAB;3|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |HOAGG-;every?;MAB;4| (|f| |c| |$|) (PROG (|x| #1=#:G82401 #2=#:G82399 #3=#:G82397 #4=#:G82398) (RETURN (SEQ (PROGN (LETT #4# NIL |HOAGG-;every?;MAB;4|) (SEQ (LETT |x| NIL |HOAGG-;every?;MAB;4|) (LETT #1# (SPADCALL |c| (QREFELT |$| 14)) |HOAGG-;every?;MAB;4|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |HOAGG-;every?;MAB;4|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |x| |f|) |HOAGG-;every?;MAB;4|) (COND (#4# (LETT #3# (COND (#3# #2#) ((QUOTE T) (QUOTE NIL))) |HOAGG-;every?;MAB;4|)) ((QUOTE T) (PROGN (LETT #3# #2# |HOAGG-;every?;MAB;4|) (LETT #4# (QUOTE T) |HOAGG-;every?;MAB;4|))))))) (LETT #1# (CDR #1#) |HOAGG-;every?;MAB;4|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (QUOTE T))))))))
+
+(DEFUN |HOAGG-;count;MANni;5| (|f| |c| |$|) (PROG (|x| #1=#:G82406 #2=#:G82404 #3=#:G82402 #4=#:G82403) (RETURN (SEQ (PROGN (LETT #4# NIL |HOAGG-;count;MANni;5|) (SEQ (LETT |x| NIL |HOAGG-;count;MANni;5|) (LETT #1# (SPADCALL |c| (QREFELT |$| 14)) |HOAGG-;count;MANni;5|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |HOAGG-;count;MANni;5|) NIL)) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |x| |f|) (PROGN (LETT #2# 1 |HOAGG-;count;MANni;5|) (COND (#4# (LETT #3# (|+| #3# #2#) |HOAGG-;count;MANni;5|)) ((QUOTE T) (PROGN (LETT #3# #2# |HOAGG-;count;MANni;5|) (LETT #4# (QUOTE T) |HOAGG-;count;MANni;5|))))))))) (LETT #1# (CDR #1#) |HOAGG-;count;MANni;5|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) 0)))))))
+
+(DEFUN |HOAGG-;members;AL;6| (|x| |$|) (SPADCALL |x| (QREFELT |$| 14)))
+
+(DEFUN |HOAGG-;count;SANni;7| (|s| |x| |$|) (SPADCALL (CONS (FUNCTION |HOAGG-;count;SANni;7!0|) (VECTOR |$| |s|)) |x| (QREFELT |$| 24)))
+
+(DEFUN |HOAGG-;count;SANni;7!0| (|#1| |$$|) (SPADCALL (QREFELT |$$| 1) |#1| (QREFELT (QREFELT |$$| 0) 23)))
+
+(DEFUN |HOAGG-;member?;SAB;8| (|e| |c| |$|) (SPADCALL (CONS (FUNCTION |HOAGG-;member?;SAB;8!0|) (VECTOR |$| |e|)) |c| (QREFELT |$| 26)))
+
+(DEFUN |HOAGG-;member?;SAB;8!0| (|#1| |$$|) (SPADCALL (QREFELT |$$| 1) |#1| (QREFELT (QREFELT |$$| 0) 23)))
+
+(DEFUN |HOAGG-;=;2AB;9| (|x| |y| |$|) (PROG (|b| #1=#:G82416 |a| #2=#:G82415 #3=#:G82412 #4=#:G82410 #5=#:G82411) (RETURN (SEQ (COND ((SPADCALL |x| (SPADCALL |y| (QREFELT |$| 28)) (QREFELT |$| 29)) (PROGN (LETT #5# NIL |HOAGG-;=;2AB;9|) (SEQ (LETT |b| NIL |HOAGG-;=;2AB;9|) (LETT #1# (SPADCALL |y| (QREFELT |$| 14)) |HOAGG-;=;2AB;9|) (LETT |a| NIL |HOAGG-;=;2AB;9|) (LETT #2# (SPADCALL |x| (QREFELT |$| 14)) |HOAGG-;=;2AB;9|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |a| (CAR #2#) |HOAGG-;=;2AB;9|) NIL) (ATOM #1#) (PROGN (LETT |b| (CAR #1#) |HOAGG-;=;2AB;9|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #3# (SPADCALL |a| |b| (QREFELT |$| 23)) |HOAGG-;=;2AB;9|) (COND (#5# (LETT #4# (COND (#4# #3#) ((QUOTE T) (QUOTE NIL))) |HOAGG-;=;2AB;9|)) ((QUOTE T) (PROGN (LETT #4# #3# |HOAGG-;=;2AB;9|) (LETT #5# (QUOTE T) |HOAGG-;=;2AB;9|))))))) (LETT #2# (PROG1 (CDR #2#) (LETT #1# (CDR #1#) |HOAGG-;=;2AB;9|)) |HOAGG-;=;2AB;9|) (GO G190) G191 (EXIT NIL)) (COND (#5# #4#) ((QUOTE T) (QUOTE T))))) ((QUOTE T) (QUOTE NIL)))))))
+
+(DEFUN |HOAGG-;coerce;AOf;10| (|x| |$|) (PROG (#1=#:G82420 |a| #2=#:G82421) (RETURN (SEQ (SPADCALL (SPADCALL (PROGN (LETT #1# NIL |HOAGG-;coerce;AOf;10|) (SEQ (LETT |a| NIL |HOAGG-;coerce;AOf;10|) (LETT #2# (SPADCALL |x| (QREFELT |$| 14)) |HOAGG-;coerce;AOf;10|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |a| (CAR #2#) |HOAGG-;coerce;AOf;10|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |a| (QREFELT |$| 32)) #1#) |HOAGG-;coerce;AOf;10|))) (LETT #2# (CDR #2#) |HOAGG-;coerce;AOf;10|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 34)) (QREFELT |$| 35))))))
+
+(DEFUN |HomogeneousAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|HomogeneousAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |HomogeneousAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 38) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasAttribute| |#1| (QUOTE |finiteAggregate|)) (|HasAttribute| |#1| (QUOTE |shallowlyMutable|)) (|HasCategory| |#2| (LIST (QUOTE |Evalable|) (|devaluate| |#2|))) (|HasCategory| |#2| (QUOTE (|SetCategory|))))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|testBitVector| |pv$| 3) (QSETREFV |$| 12 (CONS (|dispatchFunction| |HOAGG-;eval;ALA;1|) |$|)))) (COND ((|testBitVector| |pv$| 1) (PROGN (QSETREFV |$| 16 (CONS (|dispatchFunction| |HOAGG-;#;ANni;2|) |$|)) (QSETREFV |$| 19 (CONS (|dispatchFunction| |HOAGG-;any?;MAB;3|) |$|)) (QSETREFV |$| 20 (CONS (|dispatchFunction| |HOAGG-;every?;MAB;4|) |$|)) (QSETREFV |$| 21 (CONS (|dispatchFunction| |HOAGG-;count;MANni;5|) |$|)) (QSETREFV |$| 22 (CONS (|dispatchFunction| |HOAGG-;members;AL;6|) |$|)) (COND ((|testBitVector| |pv$| 4) (PROGN (QSETREFV |$| 25 (CONS (|dispatchFunction| |HOAGG-;count;SANni;7|) |$|)) (QSETREFV |$| 27 (CONS (|dispatchFunction| |HOAGG-;member?;SAB;8|) |$|)) (QSETREFV |$| 30 (CONS (|dispatchFunction| |HOAGG-;=;2AB;9|) |$|)) (QSETREFV |$| 36 (CONS (|dispatchFunction| |HOAGG-;coerce;AOf;10|) |$|)))))))) |$|))))
+
+(MAKEPROP (QUOTE |HomogeneousAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|List| 37) (0 . |eval|) (|Mapping| 7 7) (6 . |map|) (12 . |eval|) (|List| 7) (18 . |parts|) (|NonNegativeInteger|) (23 . |#|) (|Boolean|) (|Mapping| 17 7) (28 . |any?|) (34 . |every?|) (40 . |count|) (46 . |members|) (51 . |=|) (57 . |count|) (63 . |count|) (69 . |any?|) (75 . |member?|) (81 . |#|) (86 . |size?|) (92 . |=|) (|OutputForm|) (98 . |coerce|) (|List| |$|) (103 . |commaSeparate|) (108 . |bracket|) (113 . |coerce|) (|Equation| 7))) (QUOTE #(|members| 118 |member?| 123 |every?| 129 |eval| 135 |count| 141 |coerce| 153 |any?| 158 |=| 164 |#| 170)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 36 (QUOTE (2 7 0 0 8 9 2 6 0 10 0 11 2 0 0 0 8 12 1 6 13 0 14 1 0 15 0 16 2 0 17 18 0 19 2 0 17 18 0 20 2 0 15 18 0 21 1 0 13 0 22 2 7 17 0 0 23 2 6 15 18 0 24 2 0 15 7 0 25 2 6 17 18 0 26 2 0 17 7 0 27 1 6 15 0 28 2 6 17 0 15 29 2 0 17 0 0 30 1 7 31 0 32 1 31 0 33 34 1 31 0 0 35 1 0 31 0 36 1 0 13 0 22 2 0 17 7 0 27 2 0 17 18 0 20 2 0 0 0 8 12 2 0 15 7 0 25 2 0 15 18 0 21 1 0 31 0 36 2 0 17 18 0 19 2 0 17 0 0 30 1 0 15 0 16)))))) (QUOTE |lookupComplete|)))
+@
+\section{category CLAGG Collection}
+<<category CLAGG Collection>>=
+)abbrev category CLAGG Collection
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A collection is a homogeneous aggregate which can built from
+++ list of members. The operation used to build the aggregate is
+++ generically named \spadfun{construct}. However, each collection
+++ provides its own special function with the same name as the
+++ data type, except with an initial lower case letter, e.g.
+++ \spadfun{list} for \spadtype{List},
+++ \spadfun{flexibleArray} for \spadtype{FlexibleArray}, and so on.
+Collection(S:Type): Category == HomogeneousAggregate(S) with
+ construct: List S -> %
+ ++ \axiom{construct(x,y,...,z)} returns the collection of elements \axiom{x,y,...,z}
+ ++ ordered as given. Equivalently written as \axiom{[x,y,...,z]$D}, where
+ ++ D is the domain. D may be omitted for those of type List.
+ find: (S->Boolean, %) -> Union(S, "failed")
+ ++ find(p,u) returns the first x in u such that \axiom{p(x)} is true, and
+ ++ "failed" otherwise.
+ if % has finiteAggregate then
+ reduce: ((S,S)->S,%) -> S
+ ++ reduce(f,u) reduces the binary operation f across u. For example,
+ ++ if u is \axiom{[x,y,...,z]} then \axiom{reduce(f,u)} returns \axiom{f(..f(f(x,y),...),z)}.
+ ++ Note: if u has one element x, \axiom{reduce(f,u)} returns x.
+ ++ Error: if u is empty.
+ reduce: ((S,S)->S,%,S) -> S
+ ++ reduce(f,u,x) reduces the binary operation f across u, where x is
+ ++ the identity operation of f.
+ ++ Same as \axiom{reduce(f,u)} if u has 2 or more elements.
+ ++ Returns \axiom{f(x,y)} if u has one element y,
+ ++ x if u is empty.
+ ++ For example, \axiom{reduce(+,u,0)} returns the
+ ++ sum of the elements of u.
+ remove: (S->Boolean,%) -> %
+ ++ remove(p,u) returns a copy of u removing all elements x such that
+ ++ \axiom{p(x)} is true.
+ ++ Note: \axiom{remove(p,u) == [x for x in u | not p(x)]}.
+ select: (S->Boolean,%) -> %
+ ++ select(p,u) returns a copy of u containing only those elements such
+ ++ \axiom{p(x)} is true.
+ ++ Note: \axiom{select(p,u) == [x for x in u | p(x)]}.
+ if S has SetCategory then
+ reduce: ((S,S)->S,%,S,S) -> S
+ ++ reduce(f,u,x,z) reduces the binary operation f across u, stopping
+ ++ when an "absorbing element" z is encountered.
+ ++ As for \axiom{reduce(f,u,x)}, x is the identity operation of f.
+ ++ Same as \axiom{reduce(f,u,x)} when u contains no element z.
+ ++ Thus the third argument x is returned when u is empty.
+ remove: (S,%) -> %
+ ++ remove(x,u) returns a copy of u with all
+ ++ elements \axiom{y = x} removed.
+ ++ Note: \axiom{remove(y,c) == [x for x in c | x ^= y]}.
+ removeDuplicates: % -> %
+ ++ removeDuplicates(u) returns a copy of u with all duplicates removed.
+ if S has ConvertibleTo InputForm then ConvertibleTo InputForm
+ add
+ if % has finiteAggregate then
+ #c == # parts c
+ count(f:S -> Boolean, c:%) == _+/[1 for x in parts c | f x]
+ any?(f, c) == _or/[f x for x in parts c]
+ every?(f, c) == _and/[f x for x in parts c]
+ find(f:S -> Boolean, c:%) == find(f, parts c)
+ reduce(f:(S,S)->S, x:%) == reduce(f, parts x)
+ reduce(f:(S,S)->S, x:%, s:S) == reduce(f, parts x, s)
+ remove(f:S->Boolean, x:%) ==
+ construct remove(f, parts x)
+ select(f:S->Boolean, x:%) ==
+ construct select(f, parts x)
+
+ if S has SetCategory then
+ remove(s:S, x:%) == remove(#1 = s, x)
+ reduce(f:(S,S)->S, x:%, s1:S, s2:S) == reduce(f, parts x, s1, s2)
+ removeDuplicates(x) == construct removeDuplicates parts x
+
+@
+\section{CLAGG.lsp BOOTSTRAP}
+{\bf CLAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf CLAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf CLAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<CLAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |Collection;CAT| (QUOTE NIL))
+
+(SETQ |Collection;AL| (QUOTE NIL))
+
+(DEFUN |Collection| (#1=#:G82618) (LET (#2=#:G82619) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |Collection;AL|)) (CDR #2#)) (T (SETQ |Collection;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|Collection;| #1#))) |Collection;AL|)) #2#))))
+
+(DEFUN |Collection;| (|t#1|) (PROG (#1=#:G82617) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|Collection;CAT|) ((QUOTE T) (LETT |Collection;CAT| (|Join| (|HomogeneousAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|construct| (|$| (|List| |t#1|))) T) ((|find| ((|Union| |t#1| "failed") (|Mapping| (|Boolean|) |t#1|) |$|)) T) ((|reduce| (|t#1| (|Mapping| |t#1| |t#1| |t#1|) |$|)) (|has| |$| (ATTRIBUTE |finiteAggregate|))) ((|reduce| (|t#1| (|Mapping| |t#1| |t#1| |t#1|) |$| |t#1|)) (|has| |$| (ATTRIBUTE |finiteAggregate|))) ((|remove| (|$| (|Mapping| (|Boolean|) |t#1|) |$|)) (|has| |$| (ATTRIBUTE |finiteAggregate|))) ((|select| (|$| (|Mapping| (|Boolean|) |t#1|) |$|)) (|has| |$| (ATTRIBUTE |finiteAggregate|))) ((|reduce| (|t#1| (|Mapping| |t#1| |t#1| |t#1|) |$| |t#1| |t#1|)) (AND (|has| |t#1| (|SetCategory|)) (|has| |$| (ATTRIBUTE |finiteAggregate|)))) ((|remove| (|$| |t#1| |$|)) (AND (|has| |t#1| (|SetCategory|)) (|has| |$| (ATTRIBUTE |finiteAggregate|)))) ((|removeDuplicates| (|$| |$|)) (AND (|has| |t#1| (|SetCategory|)) (|has| |$| (ATTRIBUTE |finiteAggregate|)))))) (QUOTE (((|ConvertibleTo| (|InputForm|)) (|has| |t#1| (|ConvertibleTo| (|InputForm|)))))) (QUOTE ((|List| |t#1|))) NIL)) . #2=(|Collection|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |Collection|) (|devaluate| |t#1|)))))))
+@
+\section{CLAGG-.lsp BOOTSTRAP}
+{\bf CLAGG-} depends on {\bf CLAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf CLAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf CLAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<CLAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |CLAGG-;#;ANni;1| (|c| |$|) (LENGTH (SPADCALL |c| (QREFELT |$| 9))))
+
+(DEFUN |CLAGG-;count;MANni;2| (|f| |c| |$|) (PROG (|x| #1=#:G82637 #2=#:G82634 #3=#:G82632 #4=#:G82633) (RETURN (SEQ (PROGN (LETT #4# NIL |CLAGG-;count;MANni;2|) (SEQ (LETT |x| NIL |CLAGG-;count;MANni;2|) (LETT #1# (SPADCALL |c| (QREFELT |$| 9)) |CLAGG-;count;MANni;2|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |CLAGG-;count;MANni;2|) NIL)) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |x| |f|) (PROGN (LETT #2# 1 |CLAGG-;count;MANni;2|) (COND (#4# (LETT #3# (|+| #3# #2#) |CLAGG-;count;MANni;2|)) ((QUOTE T) (PROGN (LETT #3# #2# |CLAGG-;count;MANni;2|) (LETT #4# (QUOTE T) |CLAGG-;count;MANni;2|))))))))) (LETT #1# (CDR #1#) |CLAGG-;count;MANni;2|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) 0)))))))
+
+(DEFUN |CLAGG-;any?;MAB;3| (|f| |c| |$|) (PROG (|x| #1=#:G82642 #2=#:G82640 #3=#:G82638 #4=#:G82639) (RETURN (SEQ (PROGN (LETT #4# NIL |CLAGG-;any?;MAB;3|) (SEQ (LETT |x| NIL |CLAGG-;any?;MAB;3|) (LETT #1# (SPADCALL |c| (QREFELT |$| 9)) |CLAGG-;any?;MAB;3|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |CLAGG-;any?;MAB;3|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |x| |f|) |CLAGG-;any?;MAB;3|) (COND (#4# (LETT #3# (COND (#3# (QUOTE T)) ((QUOTE T) #2#)) |CLAGG-;any?;MAB;3|)) ((QUOTE T) (PROGN (LETT #3# #2# |CLAGG-;any?;MAB;3|) (LETT #4# (QUOTE T) |CLAGG-;any?;MAB;3|))))))) (LETT #1# (CDR #1#) |CLAGG-;any?;MAB;3|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |CLAGG-;every?;MAB;4| (|f| |c| |$|) (PROG (|x| #1=#:G82647 #2=#:G82645 #3=#:G82643 #4=#:G82644) (RETURN (SEQ (PROGN (LETT #4# NIL |CLAGG-;every?;MAB;4|) (SEQ (LETT |x| NIL |CLAGG-;every?;MAB;4|) (LETT #1# (SPADCALL |c| (QREFELT |$| 9)) |CLAGG-;every?;MAB;4|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |CLAGG-;every?;MAB;4|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |x| |f|) |CLAGG-;every?;MAB;4|) (COND (#4# (LETT #3# (COND (#3# #2#) ((QUOTE T) (QUOTE NIL))) |CLAGG-;every?;MAB;4|)) ((QUOTE T) (PROGN (LETT #3# #2# |CLAGG-;every?;MAB;4|) (LETT #4# (QUOTE T) |CLAGG-;every?;MAB;4|))))))) (LETT #1# (CDR #1#) |CLAGG-;every?;MAB;4|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (QUOTE T))))))))
+
+(DEFUN |CLAGG-;find;MAU;5| (|f| |c| |$|) (SPADCALL |f| (SPADCALL |c| (QREFELT |$| 9)) (QREFELT |$| 18)))
+
+(DEFUN |CLAGG-;reduce;MAS;6| (|f| |x| |$|) (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 21)))
+
+(DEFUN |CLAGG-;reduce;MA2S;7| (|f| |x| |s| |$|) (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) |s| (QREFELT |$| 23)))
+
+(DEFUN |CLAGG-;remove;M2A;8| (|f| |x| |$|) (SPADCALL (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 25)) (QREFELT |$| 26)))
+
+(DEFUN |CLAGG-;select;M2A;9| (|f| |x| |$|) (SPADCALL (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 28)) (QREFELT |$| 26)))
+
+(DEFUN |CLAGG-;remove;S2A;10| (|s| |x| |$|) (SPADCALL (CONS (FUNCTION |CLAGG-;remove;S2A;10!0|) (VECTOR |$| |s|)) |x| (QREFELT |$| 31)))
+
+(DEFUN |CLAGG-;remove;S2A;10!0| (|#1| |$$|) (SPADCALL |#1| (QREFELT |$$| 1) (QREFELT (QREFELT |$$| 0) 30)))
+
+(DEFUN |CLAGG-;reduce;MA3S;11| (|f| |x| |s1| |s2| |$|) (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) |s1| |s2| (QREFELT |$| 33)))
+
+(DEFUN |CLAGG-;removeDuplicates;2A;12| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 35)) (QREFELT |$| 26)))
+
+(DEFUN |Collection&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|Collection&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |Collection&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 37) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#2| (QUOTE (|ConvertibleTo| (|InputForm|)))) (|HasCategory| |#2| (QUOTE (|SetCategory|))) (|HasAttribute| |#1| (QUOTE |finiteAggregate|)))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|testBitVector| |pv$| 3) (PROGN (QSETREFV |$| 11 (CONS (|dispatchFunction| |CLAGG-;#;ANni;1|) |$|)) (QSETREFV |$| 13 (CONS (|dispatchFunction| |CLAGG-;count;MANni;2|) |$|)) (QSETREFV |$| 15 (CONS (|dispatchFunction| |CLAGG-;any?;MAB;3|) |$|)) (QSETREFV |$| 16 (CONS (|dispatchFunction| |CLAGG-;every?;MAB;4|) |$|)) (QSETREFV |$| 19 (CONS (|dispatchFunction| |CLAGG-;find;MAU;5|) |$|)) (QSETREFV |$| 22 (CONS (|dispatchFunction| |CLAGG-;reduce;MAS;6|) |$|)) (QSETREFV |$| 24 (CONS (|dispatchFunction| |CLAGG-;reduce;MA2S;7|) |$|)) (QSETREFV |$| 27 (CONS (|dispatchFunction| |CLAGG-;remove;M2A;8|) |$|)) (QSETREFV |$| 29 (CONS (|dispatchFunction| |CLAGG-;select;M2A;9|) |$|)) (COND ((|testBitVector| |pv$| 2) (PROGN (QSETREFV |$| 32 (CONS (|dispatchFunction| |CLAGG-;remove;S2A;10|) |$|)) (QSETREFV |$| 34 (CONS (|dispatchFunction| |CLAGG-;reduce;MA3S;11|) |$|)) (QSETREFV |$| 36 (CONS (|dispatchFunction| |CLAGG-;removeDuplicates;2A;12|) |$|)))))))) |$|))))
+
+(MAKEPROP (QUOTE |Collection&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|List| 7) (0 . |parts|) (|NonNegativeInteger|) (5 . |#|) (|Mapping| 14 7) (10 . |count|) (|Boolean|) (16 . |any?|) (22 . |every?|) (|Union| 7 (QUOTE "failed")) (28 . |find|) (34 . |find|) (|Mapping| 7 7 7) (40 . |reduce|) (46 . |reduce|) (52 . |reduce|) (59 . |reduce|) (66 . |remove|) (72 . |construct|) (77 . |remove|) (83 . |select|) (89 . |select|) (95 . |=|) (101 . |remove|) (107 . |remove|) (113 . |reduce|) (121 . |reduce|) (129 . |removeDuplicates|) (134 . |removeDuplicates|))) (QUOTE #(|select| 139 |removeDuplicates| 145 |remove| 150 |reduce| 162 |find| 183 |every?| 189 |count| 195 |any?| 201 |#| 207)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 36 (QUOTE (1 6 8 0 9 1 0 10 0 11 2 0 10 12 0 13 2 0 14 12 0 15 2 0 14 12 0 16 2 8 17 12 0 18 2 0 17 12 0 19 2 8 7 20 0 21 2 0 7 20 0 22 3 8 7 20 0 7 23 3 0 7 20 0 7 24 2 8 0 12 0 25 1 6 0 8 26 2 0 0 12 0 27 2 8 0 12 0 28 2 0 0 12 0 29 2 7 14 0 0 30 2 6 0 12 0 31 2 0 0 7 0 32 4 8 7 20 0 7 7 33 4 0 7 20 0 7 7 34 1 8 0 0 35 1 0 0 0 36 2 0 0 12 0 29 1 0 0 0 36 2 0 0 7 0 32 2 0 0 12 0 27 4 0 7 20 0 7 7 34 3 0 7 20 0 7 24 2 0 7 20 0 22 2 0 17 12 0 19 2 0 14 12 0 16 2 0 10 12 0 13 2 0 14 12 0 15 1 0 10 0 11)))))) (QUOTE |lookupComplete|)))
+@
+\section{category BGAGG BagAggregate}
+<<category BGAGG BagAggregate>>=
+)abbrev category BGAGG BagAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A bag aggregate is an aggregate for which one can insert and extract objects,
+++ and where the order in which objects are inserted determines the order
+++ of extraction.
+++ Examples of bags are stacks, queues, and dequeues.
+BagAggregate(S:Type): Category == HomogeneousAggregate S with
+ shallowlyMutable
+ ++ shallowlyMutable means that elements of bags may be destructively changed.
+ bag: List S -> %
+ ++ bag([x,y,...,z]) creates a bag with elements x,y,...,z.
+ extract_!: % -> S
+ ++ extract!(u) destructively removes a (random) item from bag u.
+ insert_!: (S,%) -> %
+ ++ insert!(x,u) inserts item x into bag u.
+ inspect: % -> S
+ ++ inspect(u) returns an (random) element from a bag.
+ add
+ bag(l) ==
+ x:=empty()
+ for s in l repeat x:=insert_!(s,x)
+ x
+
+@
+\section{category SKAGG StackAggregate}
+<<category SKAGG StackAggregate>>=
+)abbrev category SKAGG StackAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A stack is a bag where the last item inserted is the first item extracted.
+StackAggregate(S:Type): Category == BagAggregate S with
+ finiteAggregate
+ push_!: (S,%) -> S
+ ++ push!(x,s) pushes x onto stack s, i.e. destructively changing s
+ ++ so as to have a new first (top) element x.
+ ++ Afterwards, pop!(s) produces x and pop!(s) produces the original s.
+ pop_!: % -> S
+ ++ pop!(s) returns the top element x, destructively removing x from s.
+ ++ Note: Use \axiom{top(s)} to obtain x without removing it from s.
+ ++ Error: if s is empty.
+ top: % -> S
+ ++ top(s) returns the top element x from s; s remains unchanged.
+ ++ Note: Use \axiom{pop!(s)} to obtain x and remove it from s.
+ depth: % -> NonNegativeInteger
+ ++ depth(s) returns the number of elements of stack s.
+ ++ Note: \axiom{depth(s) = #s}.
+
+
+@
+\section{category QUAGG QueueAggregate}
+<<category QUAGG QueueAggregate>>=
+)abbrev category QUAGG QueueAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A queue is a bag where the first item inserted is the first item extracted.
+QueueAggregate(S:Type): Category == BagAggregate S with
+ finiteAggregate
+ enqueue_!: (S, %) -> S
+ ++ enqueue!(x,q) inserts x into the queue q at the back end.
+ dequeue_!: % -> S
+ ++ dequeue! s destructively extracts the first (top) element from queue q.
+ ++ The element previously second in the queue becomes the first element.
+ ++ Error: if q is empty.
+ rotate_!: % -> %
+ ++ rotate! q rotates queue q so that the element at the front of
+ ++ the queue goes to the back of the queue.
+ ++ Note: rotate! q is equivalent to enqueue!(dequeue!(q)).
+ length: % -> NonNegativeInteger
+ ++ length(q) returns the number of elements in the queue.
+ ++ Note: \axiom{length(q) = #q}.
+ front: % -> S
+ ++ front(q) returns the element at the front of the queue.
+ ++ The queue q is unchanged by this operation.
+ ++ Error: if q is empty.
+ back: % -> S
+ ++ back(q) returns the element at the back of the queue.
+ ++ The queue q is unchanged by this operation.
+ ++ Error: if q is empty.
+
+@
+\section{category DQAGG DequeueAggregate}
+<<category DQAGG DequeueAggregate>>=
+)abbrev category DQAGG DequeueAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A dequeue is a doubly ended stack, that is, a bag where first items
+++ inserted are the first items extracted, at either the front or the back end
+++ of the data structure.
+DequeueAggregate(S:Type):
+ Category == Join(StackAggregate S,QueueAggregate S) with
+ dequeue: () -> %
+ ++ dequeue()$D creates an empty dequeue of type D.
+ dequeue: List S -> %
+ ++ dequeue([x,y,...,z]) creates a dequeue with first (top or front)
+ ++ element x, second element y,...,and last (bottom or back) element z.
+ height: % -> NonNegativeInteger
+ ++ height(d) returns the number of elements in dequeue d.
+ ++ Note: \axiom{height(d) = # d}.
+ top_!: % -> S
+ ++ top!(d) returns the element at the top (front) of the dequeue.
+ bottom_!: % -> S
+ ++ bottom!(d) returns the element at the bottom (back) of the dequeue.
+ insertTop_!: (S,%) -> S
+ ++ insertTop!(x,d) destructively inserts x into the dequeue d, that is,
+ ++ at the top (front) of the dequeue.
+ ++ The element previously at the top of the dequeue becomes the
+ ++ second in the dequeue, and so on.
+ insertBottom_!: (S,%) -> S
+ ++ insertBottom!(x,d) destructively inserts x into the dequeue d
+ ++ at the bottom (back) of the dequeue.
+ extractTop_!: % -> S
+ ++ extractTop!(d) destructively extracts the top (front) element
+ ++ from the dequeue d.
+ ++ Error: if d is empty.
+ extractBottom_!: % -> S
+ ++ extractBottom!(d) destructively extracts the bottom (back) element
+ ++ from the dequeue d.
+ ++ Error: if d is empty.
+ reverse_!: % -> %
+ ++ reverse!(d) destructively replaces d by its reverse dequeue, i.e.
+ ++ the top (front) element is now the bottom (back) element, and so on.
+
+@
+\section{category PRQAGG PriorityQueueAggregate}
+<<category PRQAGG PriorityQueueAggregate>>=
+)abbrev category PRQAGG PriorityQueueAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A priority queue is a bag of items from an ordered set where the item
+++ extracted is always the maximum element.
+PriorityQueueAggregate(S:OrderedSet): Category == BagAggregate S with
+ finiteAggregate
+ max: % -> S
+ ++ max(q) returns the maximum element of priority queue q.
+ merge: (%,%) -> %
+ ++ merge(q1,q2) returns combines priority queues q1 and q2 to return
+ ++ a single priority queue q.
+ merge_!: (%,%) -> %
+ ++ merge!(q,q1) destructively changes priority queue q to include the
+ ++ values from priority queue q1.
+
+@
+\section{category DIOPS DictionaryOperations}
+<<category DIOPS DictionaryOperations>>=
+)abbrev category DIOPS DictionaryOperations
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This category is a collection of operations common to both
+++ categories \spadtype{Dictionary} and \spadtype{MultiDictionary}
+DictionaryOperations(S:SetCategory): Category ==
+ Join(BagAggregate S, Collection(S)) with
+ dictionary: () -> %
+ ++ dictionary()$D creates an empty dictionary of type D.
+ dictionary: List S -> %
+ ++ dictionary([x,y,...,z]) creates a dictionary consisting of
+ ++ entries \axiom{x,y,...,z}.
+-- insert: (S,%) -> S ++ insert an entry
+-- member?: (S,%) -> Boolean ++ search for an entry
+-- remove_!: (S,%,NonNegativeInteger) -> %
+-- ++ remove!(x,d,n) destructively changes dictionary d by removing
+-- ++ up to n entries y such that \axiom{y = x}.
+-- remove_!: (S->Boolean,%,NonNegativeInteger) -> %
+-- ++ remove!(p,d,n) destructively changes dictionary d by removing
+-- ++ up to n entries x such that \axiom{p(x)} is true.
+ if % has finiteAggregate then
+ remove_!: (S,%) -> %
+ ++ remove!(x,d) destructively changes dictionary d by removing
+ ++ all entries y such that \axiom{y = x}.
+ remove_!: (S->Boolean,%) -> %
+ ++ remove!(p,d) destructively changes dictionary d by removeing
+ ++ all entries x such that \axiom{p(x)} is true.
+ select_!: (S->Boolean,%) -> %
+ ++ select!(p,d) destructively changes dictionary d by removing
+ ++ all entries x such that \axiom{p(x)} is not true.
+ add
+ construct l == dictionary l
+ dictionary() == empty()
+ if % has finiteAggregate then
+ copy d == dictionary parts d
+ coerce(s:%):OutputForm ==
+ prefix("dictionary"@String :: OutputForm,
+ [x::OutputForm for x in parts s])
+
+@
+\section{category DIAGG Dictionary}
+<<category DIAGG Dictionary>>=
+)abbrev category DIAGG Dictionary
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A dictionary is an aggregate in which entries can be inserted,
+++ searched for and removed. Duplicates are thrown away on insertion.
+++ This category models the usual notion of dictionary which involves
+++ large amounts of data where copying is impractical.
+++ Principal operations are thus destructive (non-copying) ones.
+Dictionary(S:SetCategory): Category ==
+ DictionaryOperations S add
+ dictionary l ==
+ d := dictionary()
+ for x in l repeat insert_!(x, d)
+ d
+
+ if % has finiteAggregate then
+ -- remove(f:S->Boolean,t:%) == remove_!(f, copy t)
+ -- select(f, t) == select_!(f, copy t)
+ select_!(f, t) == remove_!(not f #1, t)
+
+ --extract_! d ==
+ -- empty? d => error "empty dictionary"
+ -- remove_!(x := first parts d, d, 1)
+ -- x
+
+ s = t ==
+ eq?(s,t) => true
+ #s ^= #t => false
+ _and/[member?(x, t) for x in parts s]
+
+ remove_!(f:S->Boolean, t:%) ==
+ for m in parts t repeat if f m then remove_!(m, t)
+ t
+
+@
+\section{category MDAGG MultiDictionary}
+<<category MDAGG MultiDictionary>>=
+)abbrev category MDAGG MultiDictionary
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A multi-dictionary is a dictionary which may contain duplicates.
+++ As for any dictionary, its size is assumed large so that
+++ copying (non-destructive) operations are generally to be avoided.
+MultiDictionary(S:SetCategory): Category == DictionaryOperations S with
+-- count: (S,%) -> NonNegativeInteger ++ multiplicity count
+ insert_!: (S,%,NonNegativeInteger) -> %
+ ++ insert!(x,d,n) destructively inserts n copies of x into dictionary d.
+-- remove_!: (S,%,NonNegativeInteger) -> %
+-- ++ remove!(x,d,n) destructively removes (up to) n copies of x from
+-- ++ dictionary d.
+ removeDuplicates_!: % -> %
+ ++ removeDuplicates!(d) destructively removes any duplicate values
+ ++ in dictionary d.
+ duplicates: % -> List Record(entry:S,count:NonNegativeInteger)
+ ++ duplicates(d) returns a list of values which have duplicates in d
+-- ++ duplicates(d) returns a list of ++ duplicates iterator
+-- to become duplicates: % -> Iterator(D,D)
+
+@
+\section{category SETAGG SetAggregate}
+<<category SETAGG SetAggregate>>=
+)abbrev category SETAGG SetAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: 14 Oct, 1993 by RSS
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A set category lists a collection of set-theoretic operations
+++ useful for both finite sets and multisets.
+++ Note however that finite sets are distinct from multisets.
+++ Although the operations defined for set categories are
+++ common to both, the relationship between the two cannot
+++ be described by inclusion or inheritance.
+SetAggregate(S:SetCategory):
+ Category == Join(SetCategory, Collection(S)) with
+ partiallyOrderedSet
+ "<" : (%, %) -> Boolean
+ ++ s < t returns true if all elements of set aggregate s are also
+ ++ elements of set aggregate t.
+ brace : () -> %
+ ++ brace()$D (otherwise written {}$D)
+ ++ creates an empty set aggregate of type D.
+ ++ This form is considered obsolete. Use \axiomFun{set} instead.
+ brace : List S -> %
+ ++ brace([x,y,...,z])
+ ++ creates a set aggregate containing items x,y,...,z.
+ ++ This form is considered obsolete. Use \axiomFun{set} instead.
+ set : () -> %
+ ++ set()$D creates an empty set aggregate of type D.
+ set : List S -> %
+ ++ set([x,y,...,z]) creates a set aggregate containing items x,y,...,z.
+ intersect: (%, %) -> %
+ ++ intersect(u,v) returns the set aggregate w consisting of
+ ++ elements common to both set aggregates u and v.
+ ++ Note: equivalent to the notation (not currently supported)
+ ++ {x for x in u | member?(x,v)}.
+ difference : (%, %) -> %
+ ++ difference(u,v) returns the set aggregate w consisting of
+ ++ elements in set aggregate u but not in set aggregate v.
+ ++ If u and v have no elements in common, \axiom{difference(u,v)}
+ ++ returns a copy of u.
+ ++ Note: equivalent to the notation (not currently supported)
+ ++ \axiom{{x for x in u | not member?(x,v)}}.
+ difference : (%, S) -> %
+ ++ difference(u,x) returns the set aggregate u with element x removed.
+ ++ If u does not contain x, a copy of u is returned.
+ ++ Note: \axiom{difference(s, x) = difference(s, {x})}.
+ symmetricDifference : (%, %) -> %
+ ++ symmetricDifference(u,v) returns the set aggregate of elements x which
+ ++ are members of set aggregate u or set aggregate v but not both.
+ ++ If u and v have no elements in common, \axiom{symmetricDifference(u,v)}
+ ++ returns a copy of u.
+ ++ Note: \axiom{symmetricDifference(u,v) = union(difference(u,v),difference(v,u))}
+ subset? : (%, %) -> Boolean
+ ++ subset?(u,v) tests if u is a subset of v.
+ ++ Note: equivalent to
+ ++ \axiom{reduce(and,{member?(x,v) for x in u},true,false)}.
+ union : (%, %) -> %
+ ++ union(u,v) returns the set aggregate of elements which are members
+ ++ of either set aggregate u or v.
+ union : (%, S) -> %
+ ++ union(u,x) returns the set aggregate u with the element x added.
+ ++ If u already contains x, \axiom{union(u,x)} returns a copy of u.
+ union : (S, %) -> %
+ ++ union(x,u) returns the set aggregate u with the element x added.
+ ++ If u already contains x, \axiom{union(x,u)} returns a copy of u.
+ add
+ symmetricDifference(x, y) == union(difference(x, y), difference(y, x))
+ union(s:%, x:S) == union(s, {x})
+ union(x:S, s:%) == union(s, {x})
+ difference(s:%, x:S) == difference(s, {x})
+
+@
+\section{SETAGG.lsp BOOTSTRAP}
+{\bf SETAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf SETAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf SETAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<SETAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |SetAggregate;CAT| (QUOTE NIL))
+
+(SETQ |SetAggregate;AL| (QUOTE NIL))
+
+(DEFUN |SetAggregate| (#1=#:G83200) (LET (#2=#:G83201) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |SetAggregate;AL|)) (CDR #2#)) (T (SETQ |SetAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|SetAggregate;| #1#))) |SetAggregate;AL|)) #2#))))
+
+(DEFUN |SetAggregate;| (|t#1|) (PROG (#1=#:G83199) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|SetAggregate;CAT|) ((QUOTE T) (LETT |SetAggregate;CAT| (|Join| (|SetCategory|) (|Collection| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|<| ((|Boolean|) |$| |$|)) T) ((|brace| (|$|)) T) ((|brace| (|$| (|List| |t#1|))) T) ((|set| (|$|)) T) ((|set| (|$| (|List| |t#1|))) T) ((|intersect| (|$| |$| |$|)) T) ((|difference| (|$| |$| |$|)) T) ((|difference| (|$| |$| |t#1|)) T) ((|symmetricDifference| (|$| |$| |$|)) T) ((|subset?| ((|Boolean|) |$| |$|)) T) ((|union| (|$| |$| |$|)) T) ((|union| (|$| |$| |t#1|)) T) ((|union| (|$| |t#1| |$|)) T))) (QUOTE ((|partiallyOrderedSet| T))) (QUOTE ((|Boolean|) (|List| |t#1|))) NIL)) . #2=(|SetAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |SetAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{SETAGG-.lsp BOOTSTRAP}
+{\bf SETAGG-} depends on {\bf SETAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf SETAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf SETAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<SETAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |SETAGG-;symmetricDifference;3A;1| (|x| |y| |$|) (SPADCALL (SPADCALL |x| |y| (QREFELT |$| 8)) (SPADCALL |y| |x| (QREFELT |$| 8)) (QREFELT |$| 9)))
+
+(DEFUN |SETAGG-;union;ASA;2| (|s| |x| |$|) (SPADCALL |s| (SPADCALL (LIST |x|) (QREFELT |$| 12)) (QREFELT |$| 9)))
+
+(DEFUN |SETAGG-;union;S2A;3| (|x| |s| |$|) (SPADCALL |s| (SPADCALL (LIST |x|) (QREFELT |$| 12)) (QREFELT |$| 9)))
+
+(DEFUN |SETAGG-;difference;ASA;4| (|s| |x| |$|) (SPADCALL |s| (SPADCALL (LIST |x|) (QREFELT |$| 12)) (QREFELT |$| 8)))
+
+(DEFUN |SetAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|SetAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |SetAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 16) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) |$|))))
+
+(MAKEPROP (QUOTE |SetAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (0 . |difference|) (6 . |union|) |SETAGG-;symmetricDifference;3A;1| (|List| 7) (12 . |brace|) |SETAGG-;union;ASA;2| |SETAGG-;union;S2A;3| |SETAGG-;difference;ASA;4|)) (QUOTE #(|union| 17 |symmetricDifference| 29 |difference| 35)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 15 (QUOTE (2 6 0 0 0 8 2 6 0 0 0 9 1 6 0 11 12 2 0 0 7 0 14 2 0 0 0 7 13 2 0 0 0 0 10 2 0 0 0 7 15)))))) (QUOTE |lookupComplete|)))
+@
+\section{category FSAGG FiniteSetAggregate}
+<<category FSAGG FiniteSetAggregate>>=
+)abbrev category FSAGG FiniteSetAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: 14 Oct, 1993 by RSS
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A finite-set aggregate models the notion of a finite set, that is,
+++ a collection of elements characterized by membership, but not
+++ by order or multiplicity.
+++ See \spadtype{Set} for an example.
+FiniteSetAggregate(S:SetCategory): Category ==
+ Join(Dictionary S, SetAggregate S) with
+ finiteAggregate
+ cardinality: % -> NonNegativeInteger
+ ++ cardinality(u) returns the number of elements of u.
+ ++ Note: \axiom{cardinality(u) = #u}.
+ if S has Finite then
+ Finite
+ complement: % -> %
+ ++ complement(u) returns the complement of the set u,
+ ++ i.e. the set of all values not in u.
+ universe: () -> %
+ ++ universe()$D returns the universal set for finite set aggregate D.
+ if S has OrderedSet then
+ max: % -> S
+ ++ max(u) returns the largest element of aggregate u.
+ min: % -> S
+ ++ min(u) returns the smallest element of aggregate u.
+
+ add
+ s < t == #s < #t and s = intersect(s,t)
+ s = t == #s = #t and empty? difference(s,t)
+ brace l == construct l
+ set l == construct l
+ cardinality s == #s
+ construct l == (s := set(); for x in l repeat insert_!(x,s); s)
+ count(x:S, s:%) == (member?(x, s) => 1; 0)
+ subset?(s, t) == #s < #t and _and/[member?(x, t) for x in parts s]
+
+ coerce(s:%):OutputForm ==
+ brace [x::OutputForm for x in parts s]$List(OutputForm)
+
+ intersect(s, t) ==
+ i := {}
+ for x in parts s | member?(x, t) repeat insert_!(x, i)
+ i
+
+ difference(s:%, t:%) ==
+ m := copy s
+ for x in parts t repeat remove_!(x, m)
+ m
+
+ symmetricDifference(s, t) ==
+ d := copy s
+ for x in parts t repeat
+ if member?(x, s) then remove_!(x, d) else insert_!(x, d)
+ d
+
+ union(s:%, t:%) ==
+ u := copy s
+ for x in parts t repeat insert_!(x, u)
+ u
+
+ if S has Finite then
+ universe() == {index(i::PositiveInteger) for i in 1..size()$S}
+ complement s == difference(universe(), s )
+ size() == 2 ** size()$S
+ index i == {index(j::PositiveInteger)$S for j in 1..size()$S | bit?(i-1,j-1)}
+ random() == index((random()$Integer rem (size()$% + 1))::PositiveInteger)
+
+ lookup s ==
+ n:PositiveInteger := 1
+ for x in parts s repeat n := n + 2 ** ((lookup(x) - 1)::NonNegativeInteger)
+ n
+
+ if S has OrderedSet then
+ max s ==
+ empty?(l := parts s) => error "Empty set"
+ reduce("max", l)
+
+ min s ==
+ empty?(l := parts s) => error "Empty set"
+ reduce("min", l)
+
+@
+\section{category MSETAGG MultisetAggregate}
+<<category MSETAGG MultisetAggregate>>=
+)abbrev category MSETAGG MultisetAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A multi-set aggregate is a set which keeps track of the multiplicity
+++ of its elements.
+MultisetAggregate(S:SetCategory):
+ Category == Join(MultiDictionary S, SetAggregate S)
+
+@
+\section{category OMSAGG OrderedMultisetAggregate}
+<<category OMSAGG OrderedMultisetAggregate>>=
+)abbrev category OMSAGG OrderedMultisetAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An ordered-multiset aggregate is a multiset built over an ordered set S
+++ so that the relative sizes of its entries can be assessed.
+++ These aggregates serve as models for priority queues.
+OrderedMultisetAggregate(S:OrderedSet): Category ==
+ Join(MultisetAggregate S,PriorityQueueAggregate S) with
+ -- max: % -> S ++ smallest entry in the set
+ -- duplicates: % -> List Record(entry:S,count:NonNegativeInteger)
+ ++ to become an in order iterator
+ -- parts: % -> List S ++ in order iterator
+ min: % -> S
+ ++ min(u) returns the smallest entry in the multiset aggregate u.
+
+@
+\section{category KDAGG KeyedDictionary}
+<<category KDAGG KeyedDictionary>>=
+)abbrev category KDAGG KeyedDictionary
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A keyed dictionary is a dictionary of key-entry pairs for which there is
+++ a unique entry for each key.
+KeyedDictionary(Key:SetCategory, Entry:SetCategory): Category ==
+ Dictionary Record(key:Key,entry:Entry) with
+ key?: (Key, %) -> Boolean
+ ++ key?(k,t) tests if k is a key in table t.
+ keys: % -> List Key
+ ++ keys(t) returns the list the keys in table t.
+ -- to become keys: % -> Key* and keys: % -> Iterator(Entry,Entry)
+ remove_!: (Key, %) -> Union(Entry,"failed")
+ ++ remove!(k,t) searches the table t for the key k removing
+ ++ (and return) the entry if there.
+ ++ If t has no such key, \axiom{remove!(k,t)} returns "failed".
+ search: (Key, %) -> Union(Entry,"failed")
+ ++ search(k,t) searches the table t for the key k,
+ ++ returning the entry stored in t for key k.
+ ++ If t has no such key, \axiom{search(k,t)} returns "failed".
+ add
+ key?(k, t) == search(k, t) case Entry
+
+ member?(p, t) ==
+ r := search(p.key, t)
+ r case Entry and r::Entry = p.entry
+
+ if % has finiteAggregate then
+ keys t == [x.key for x in parts t]
+
+@
+\section{category ELTAB Eltable}
+<<category ELTAB Eltable>>=
+)abbrev category ELTAB Eltable
+++ Author: Michael Monagan; revised by Manuel Bronstein and Manuel Bronstein
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An eltable over domains D and I is a structure which can be viewed
+++ as a function from D to I.
+++ Examples of eltable structures range from data structures, e.g. those
+++ of type \spadtype{List}, to algebraic structures, e.g. \spadtype{Polynomial}.
+Eltable(S:SetCategory, Index:Type): Category == with
+ elt : (%, S) -> Index
+ ++ elt(u,i) (also written: u . i) returns the element of u indexed by i.
+ ++ Error: if i is not an index of u.
+
+@
+\section{category ELTAGG EltableAggregate}
+<<category ELTAGG EltableAggregate>>=
+)abbrev category ELTAGG EltableAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An eltable aggregate is one which can be viewed as a function.
+++ For example, the list \axiom{[1,7,4]} can applied to 0,1, and 2 respectively
+++ will return the integers 1,7, and 4; thus this list may be viewed
+++ as mapping 0 to 1, 1 to 7 and 2 to 4. In general, an aggregate
+++ can map members of a domain {\em Dom} to an image domain {\em Im}.
+EltableAggregate(Dom:SetCategory, Im:Type): Category ==
+-- This is separated from Eltable
+-- and series won't have to support qelt's and setelt's.
+ Eltable(Dom, Im) with
+ elt : (%, Dom, Im) -> Im
+ ++ elt(u, x, y) applies u to x if x is in the domain of u,
+ ++ and returns y otherwise.
+ ++ For example, if u is a polynomial in \axiom{x} over the rationals,
+ ++ \axiom{elt(u,n,0)} may define the coefficient of \axiom{x}
+ ++ to the power n, returning 0 when n is out of range.
+ qelt: (%, Dom) -> Im
+ ++ qelt(u, x) applies \axiom{u} to \axiom{x} without checking whether
+ ++ \axiom{x} is in the domain of \axiom{u}. If \axiom{x} is not in the
+ ++ domain of \axiom{u} a memory-access violation may occur. If a check
+ ++ on whether \axiom{x} is in the domain of \axiom{u} is required, use
+ ++ the function \axiom{elt}.
+ if % has shallowlyMutable then
+ setelt : (%, Dom, Im) -> Im
+ ++ setelt(u,x,y) sets the image of x to be y under u,
+ ++ assuming x is in the domain of u.
+ ++ Error: if x is not in the domain of u.
+ -- this function will soon be renamed as setelt!.
+ qsetelt_!: (%, Dom, Im) -> Im
+ ++ qsetelt!(u,x,y) sets the image of \axiom{x} to be \axiom{y} under
+ ++ \axiom{u}, without checking that \axiom{x} is in the domain of
+ ++ \axiom{u}.
+ ++ If such a check is required use the function \axiom{setelt}.
+ add
+ qelt(a, x) == elt(a, x)
+ if % has shallowlyMutable then
+ qsetelt_!(a, x, y) == (a.x := y)
+
+@
+\section{category IXAGG IndexedAggregate}
+<<category IXAGG IndexedAggregate>>=
+)abbrev category IXAGG IndexedAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An indexed aggregate is a many-to-one mapping of indices to entries.
+++ For example, a one-dimensional-array is an indexed aggregate where
+++ the index is an integer. Also, a table is an indexed aggregate
+++ where the indices and entries may have any type.
+IndexedAggregate(Index: SetCategory, Entry: Type): Category ==
+ Join(HomogeneousAggregate(Entry), EltableAggregate(Index, Entry)) with
+ entries: % -> List Entry
+ ++ entries(u) returns a list of all the entries of aggregate u
+ ++ in no assumed order.
+ -- to become entries: % -> Entry* and entries: % -> Iterator(Entry,Entry)
+ index?: (Index,%) -> Boolean
+ ++ index?(i,u) tests if i is an index of aggregate u.
+ indices: % -> List Index
+ ++ indices(u) returns a list of indices of aggregate u in no
+ ++ particular order.
+ -- to become indices: % -> Index* and indices: % -> Iterator(Index,Index).
+-- map: ((Entry,Entry)->Entry,%,%,Entry) -> %
+-- ++ exists c = map(f,a,b,x), i:Index where
+-- ++ c.i = f(a(i,x),b(i,x)) | index?(i,a) or index?(i,b)
+ if Entry has SetCategory and % has finiteAggregate then
+ entry?: (Entry,%) -> Boolean
+ ++ entry?(x,u) tests if x equals \axiom{u . i} for some index i.
+ if Index has OrderedSet then
+ maxIndex: % -> Index
+ ++ maxIndex(u) returns the maximum index i of aggregate u.
+ ++ Note: in general,
+ ++ \axiom{maxIndex(u) = reduce(max,[i for i in indices u])};
+ ++ if u is a list, \axiom{maxIndex(u) = #u}.
+ minIndex: % -> Index
+ ++ minIndex(u) returns the minimum index i of aggregate u.
+ ++ Note: in general,
+ ++ \axiom{minIndex(a) = reduce(min,[i for i in indices a])};
+ ++ for lists, \axiom{minIndex(a) = 1}.
+ first : % -> Entry
+ ++ first(u) returns the first element x of u.
+ ++ Note: for collections, \axiom{first([x,y,...,z]) = x}.
+ ++ Error: if u is empty.
+
+ if % has shallowlyMutable then
+ fill_!: (%,Entry) -> %
+ ++ fill!(u,x) replaces each entry in aggregate u by x.
+ ++ The modified u is returned as value.
+ swap_!: (%,Index,Index) -> Void
+ ++ swap!(u,i,j) interchanges elements i and j of aggregate u.
+ ++ No meaningful value is returned.
+ add
+ elt(a, i, x) == (index?(i, a) => qelt(a, i); x)
+
+ if % has finiteAggregate then
+ entries x == parts x
+ if Entry has SetCategory then
+ entry?(x, a) == member?(x, a)
+
+ if Index has OrderedSet then
+ maxIndex a == "max"/indices(a)
+ minIndex a == "min"/indices(a)
+ first a == a minIndex a
+
+ if % has shallowlyMutable then
+ map(f, a) == map_!(f, copy a)
+
+ map_!(f, a) ==
+ for i in indices a repeat qsetelt_!(a, i, f qelt(a, i))
+ a
+
+ fill_!(a, x) ==
+ for i in indices a repeat qsetelt_!(a, i, x)
+ a
+
+ swap_!(a, i, j) ==
+ t := a.i
+ qsetelt_!(a, i, a.j)
+ qsetelt_!(a, j, t)
+ void
+
+@
+\section{category TBAGG TableAggregate}
+<<category TBAGG TableAggregate>>=
+)abbrev category TBAGG TableAggregate
+++ Author: Michael Monagan, Stephen Watt; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A table aggregate is a model of a table, i.e. a discrete many-to-one
+++ mapping from keys to entries.
+TableAggregate(Key:SetCategory, Entry:SetCategory): Category ==
+ Join(KeyedDictionary(Key,Entry),IndexedAggregate(Key,Entry)) with
+ setelt: (%,Key,Entry) -> Entry -- setelt_! later
+ ++ setelt(t,k,e) (also written \axiom{t.k := e}) is equivalent
+ ++ to \axiom{(insert([k,e],t); e)}.
+ table: () -> %
+ ++ table()$T creates an empty table of type T.
+ table: List Record(key:Key,entry:Entry) -> %
+ ++ table([x,y,...,z]) creates a table consisting of entries
+ ++ \axiom{x,y,...,z}.
+ -- to become table: Record(key:Key,entry:Entry)* -> %
+ map: ((Entry, Entry) -> Entry, %, %) -> %
+ ++ map(fn,t1,t2) creates a new table t from given tables t1 and t2 with
+ ++ elements fn(x,y) where x and y are corresponding elements from t1
+ ++ and t2 respectively.
+ add
+ table() == empty()
+ table l == dictionary l
+-- empty() == dictionary()
+
+ insert_!(p, t) == (t(p.key) := p.entry; t)
+ indices t == keys t
+
+ coerce(t:%):OutputForm ==
+ prefix("table"::OutputForm,
+ [k::OutputForm = (t.k)::OutputForm for k in keys t])
+
+ elt(t, k) ==
+ (r := search(k, t)) case Entry => r::Entry
+ error "key not in table"
+
+ elt(t, k, e) ==
+ (r := search(k, t)) case Entry => r::Entry
+ e
+
+ map_!(f, t) ==
+ for k in keys t repeat t.k := f t.k
+ t
+
+ map(f:(Entry, Entry) -> Entry, s:%, t:%) ==
+ z := table()
+ for k in keys s | key?(k, t) repeat z.k := f(s.k, t.k)
+ z
+
+-- map(f, s, t, x) ==
+-- z := table()
+-- for k in keys s repeat z.k := f(s.k, t(k, x))
+-- for k in keys t | not key?(k, s) repeat z.k := f(t.k, x)
+-- z
+
+ if % has finiteAggregate then
+ parts(t:%):List Record(key:Key,entry:Entry) == [[k, t.k] for k in keys t]
+ parts(t:%):List Entry == [t.k for k in keys t]
+ entries(t:%):List Entry == parts(t)
+
+ s:% = t:% ==
+ eq?(s,t) => true
+ #s ^= #t => false
+ for k in keys s repeat
+ (e := search(k, t)) case "failed" or (e::Entry) ^= s.k => false
+ true
+
+ map(f: Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry), t: %): % ==
+ z := table()
+ for k in keys t repeat
+ ke: Record(key:Key,entry:Entry) := f [k, t.k]
+ z ke.key := ke.entry
+ z
+ map_!(f: Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry), t: %): % ==
+ lke: List Record(key:Key,entry:Entry) := nil()
+ for k in keys t repeat
+ lke := cons(f [k, remove_!(k,t)::Entry], lke)
+ for ke in lke repeat
+ t ke.key := ke.entry
+ t
+
+ inspect(t: %): Record(key:Key,entry:Entry) ==
+ ks := keys t
+ empty? ks => error "Cannot extract from an empty aggregate"
+ [first ks, t first ks]
+
+ find(f: Record(key:Key,entry:Entry)->Boolean, t:%): Union(Record(key:Key,entry:Entry), "failed") ==
+ for ke in parts(t)@List(Record(key:Key,entry:Entry)) repeat if f ke then return ke
+ "failed"
+
+ index?(k: Key, t: %): Boolean ==
+ search(k,t) case Entry
+
+ remove_!(x:Record(key:Key,entry:Entry), t:%) ==
+ if member?(x, t) then remove_!(x.key, t)
+ t
+ extract_!(t: %): Record(key:Key,entry:Entry) ==
+ k: Record(key:Key,entry:Entry) := inspect t
+ remove_!(k.key, t)
+ k
+
+ any?(f: Entry->Boolean, t: %): Boolean ==
+ for k in keys t | f t k repeat return true
+ false
+ every?(f: Entry->Boolean, t: %): Boolean ==
+ for k in keys t | not f t k repeat return false
+ true
+ count(f: Entry->Boolean, t: %): NonNegativeInteger ==
+ tally: NonNegativeInteger := 0
+ for k in keys t | f t k repeat tally := tally + 1
+ tally
+
+@
+\section{category RCAGG RecursiveAggregate}
+<<category RCAGG RecursiveAggregate>>=
+)abbrev category RCAGG RecursiveAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A recursive aggregate over a type S is a model for a
+++ a directed graph containing values of type S.
+++ Recursively, a recursive aggregate is a {\em node}
+++ consisting of a \spadfun{value} from S and 0 or more \spadfun{children}
+++ which are recursive aggregates.
+++ A node with no children is called a \spadfun{leaf} node.
+++ A recursive aggregate may be cyclic for which some operations as noted
+++ may go into an infinite loop.
+RecursiveAggregate(S:Type): Category == HomogeneousAggregate(S) with
+ children: % -> List %
+ ++ children(u) returns a list of the children of aggregate u.
+ -- should be % -> %* and also needs children: % -> Iterator(S,S)
+ nodes: % -> List %
+ ++ nodes(u) returns a list of all of the nodes of aggregate u.
+ -- to become % -> %* and also nodes: % -> Iterator(S,S)
+ leaf?: % -> Boolean
+ ++ leaf?(u) tests if u is a terminal node.
+ value: % -> S
+ ++ value(u) returns the value of the node u.
+ elt: (%,"value") -> S
+ ++ elt(u,"value") (also written: \axiom{a. value}) is
+ ++ equivalent to \axiom{value(a)}.
+ cyclic?: % -> Boolean
+ ++ cyclic?(u) tests if u has a cycle.
+ leaves: % -> List S
+ ++ leaves(t) returns the list of values in obtained by visiting the
+ ++ nodes of tree \axiom{t} in left-to-right order.
+ distance: (%,%) -> Integer
+ ++ distance(u,v) returns the path length (an integer) from node u to v.
+ if S has SetCategory then
+ child?: (%,%) -> Boolean
+ ++ child?(u,v) tests if node u is a child of node v.
+ node?: (%,%) -> Boolean
+ ++ node?(u,v) tests if node u is contained in node v
+ ++ (either as a child, a child of a child, etc.).
+ if % has shallowlyMutable then
+ setchildren_!: (%,List %)->%
+ ++ setchildren!(u,v) replaces the current children of node u
+ ++ with the members of v in left-to-right order.
+ setelt: (%,"value",S) -> S
+ ++ setelt(a,"value",x) (also written \axiom{a . value := x})
+ ++ is equivalent to \axiom{setvalue!(a,x)}
+ setvalue_!: (%,S) -> S
+ ++ setvalue!(u,x) sets the value of node u to x.
+ add
+ elt(x,"value") == value x
+ if % has shallowlyMutable then
+ setelt(x,"value",y) == setvalue_!(x,y)
+ if S has SetCategory then
+ child?(x,l) == member?(x,children(l))
+
+@
+\section{RCAGG.lsp BOOTSTRAP}
+{\bf RCAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf RCAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf RCAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RCAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |RecursiveAggregate;CAT| (QUOTE NIL))
+
+(SETQ |RecursiveAggregate;AL| (QUOTE NIL))
+
+(DEFUN |RecursiveAggregate| (#1=#:G84501) (LET (#2=#:G84502) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |RecursiveAggregate;AL|)) (CDR #2#)) (T (SETQ |RecursiveAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|RecursiveAggregate;| #1#))) |RecursiveAggregate;AL|)) #2#))))
+
+(DEFUN |RecursiveAggregate;| (|t#1|) (PROG (#1=#:G84500) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|RecursiveAggregate;CAT|) ((QUOTE T) (LETT |RecursiveAggregate;CAT| (|Join| (|HomogeneousAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|children| ((|List| |$|) |$|)) T) ((|nodes| ((|List| |$|) |$|)) T) ((|leaf?| ((|Boolean|) |$|)) T) ((|value| (|t#1| |$|)) T) ((|elt| (|t#1| |$| "value")) T) ((|cyclic?| ((|Boolean|) |$|)) T) ((|leaves| ((|List| |t#1|) |$|)) T) ((|distance| ((|Integer|) |$| |$|)) T) ((|child?| ((|Boolean|) |$| |$|)) (|has| |t#1| (|SetCategory|))) ((|node?| ((|Boolean|) |$| |$|)) (|has| |t#1| (|SetCategory|))) ((|setchildren!| (|$| |$| (|List| |$|))) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setelt| (|t#1| |$| "value" |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setvalue!| (|t#1| |$| |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))))) NIL (QUOTE ((|List| |$|) (|Boolean|) (|Integer|) (|List| |t#1|))) NIL)) . #2=(|RecursiveAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |RecursiveAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{RCAGG-.lsp BOOTSTRAP}
+{\bf RCAGG-} depends on {\bf RCAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf RCAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf RCAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RCAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |RCAGG-;elt;AvalueS;1| (|x| G84515 |$|) (SPADCALL |x| (QREFELT |$| 8)))
+
+(DEFUN |RCAGG-;setelt;Avalue2S;2| (|x| G84517 |y| |$|) (SPADCALL |x| |y| (QREFELT |$| 11)))
+
+(DEFUN |RCAGG-;child?;2AB;3| (|x| |l| |$|) (SPADCALL |x| (SPADCALL |l| (QREFELT |$| 14)) (QREFELT |$| 17)))
+
+(DEFUN |RecursiveAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|RecursiveAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |RecursiveAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 19) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasAttribute| |#1| (QUOTE |shallowlyMutable|)) (|HasCategory| |#2| (QUOTE (|SetCategory|))))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|testBitVector| |pv$| 1) (QSETREFV |$| 12 (CONS (|dispatchFunction| |RCAGG-;setelt;Avalue2S;2|) |$|)))) (COND ((|testBitVector| |pv$| 2) (QSETREFV |$| 18 (CONS (|dispatchFunction| |RCAGG-;child?;2AB;3|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |RecursiveAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (0 . |value|) (QUOTE "value") |RCAGG-;elt;AvalueS;1| (5 . |setvalue!|) (11 . |setelt|) (|List| |$|) (18 . |children|) (|Boolean|) (|List| 6) (23 . |member?|) (29 . |child?|))) (QUOTE #(|setelt| 35 |elt| 42 |child?| 48)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 18 (QUOTE (1 6 7 0 8 2 6 7 0 7 11 3 0 7 0 9 7 12 1 6 13 0 14 2 16 15 6 0 17 2 0 15 0 0 18 3 0 7 0 9 7 12 2 0 7 0 9 10 2 0 15 0 0 18)))))) (QUOTE |lookupComplete|)))
+@
+\section{category BRAGG BinaryRecursiveAggregate}
+<<category BRAGG BinaryRecursiveAggregate>>=
+)abbrev category BRAGG BinaryRecursiveAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A binary-recursive aggregate has 0, 1 or 2 children and
+++ serves as a model for a binary tree or a doubly-linked aggregate structure
+BinaryRecursiveAggregate(S:Type):Category == RecursiveAggregate S with
+ -- needs preorder, inorder and postorder iterators
+ left: % -> %
+ ++ left(u) returns the left child.
+ elt: (%,"left") -> %
+ ++ elt(u,"left") (also written: \axiom{a . left}) is
+ ++ equivalent to \axiom{left(a)}.
+ right: % -> %
+ ++ right(a) returns the right child.
+ elt: (%,"right") -> %
+ ++ elt(a,"right") (also written: \axiom{a . right})
+ ++ is equivalent to \axiom{right(a)}.
+ if % has shallowlyMutable then
+ setelt: (%,"left",%) -> %
+ ++ setelt(a,"left",b) (also written \axiom{a . left := b}) is equivalent
+ ++ to \axiom{setleft!(a,b)}.
+ setleft_!: (%,%) -> %
+ ++ setleft!(a,b) sets the left child of \axiom{a} to be b.
+ setelt: (%,"right",%) -> %
+ ++ setelt(a,"right",b) (also written \axiom{b . right := b})
+ ++ is equivalent to \axiom{setright!(a,b)}.
+ setright_!: (%,%) -> %
+ ++ setright!(a,x) sets the right child of t to be x.
+ add
+ cycleMax ==> 1000
+
+ elt(x,"left") == left x
+ elt(x,"right") == right x
+ leaf? x == empty? x or empty? left x and empty? right x
+ leaves t ==
+ empty? t => empty()$List(S)
+ leaf? t => [value t]
+ concat(leaves left t,leaves right t)
+ nodes x ==
+ l := empty()$List(%)
+ empty? x => l
+ concat(nodes left x,concat([x],nodes right x))
+ children x ==
+ l := empty()$List(%)
+ empty? x => l
+ empty? left x => [right x]
+ empty? right x => [left x]
+ [left x, right x]
+ if % has SetAggregate(S) and S has SetCategory then
+ node?(u,v) ==
+ empty? v => false
+ u = v => true
+ for y in children v repeat node?(u,y) => return true
+ false
+ x = y ==
+ empty?(x) => empty?(y)
+ empty?(y) => false
+ value x = value y and left x = left y and right x = right y
+ if % has finiteAggregate then
+ member?(x,u) ==
+ empty? u => false
+ x = value u => true
+ member?(x,left u) or member?(x,right u)
+
+ if S has SetCategory then
+ coerce(t:%): OutputForm ==
+ empty? t => "[]"::OutputForm
+ v := value(t):: OutputForm
+ empty? left t =>
+ empty? right t => v
+ r := coerce(right t)@OutputForm
+ bracket ["."::OutputForm, v, r]
+ l := coerce(left t)@OutputForm
+ r :=
+ empty? right t => "."::OutputForm
+ coerce(right t)@OutputForm
+ bracket [l, v, r]
+
+ if % has finiteAggregate then
+ aggCount: (%,NonNegativeInteger) -> NonNegativeInteger
+ #x == aggCount(x,0)
+ aggCount(x,k) ==
+ empty? x => 0
+ k := k + 1
+ k = cycleMax and cyclic? x => error "cyclic tree"
+ for y in children x repeat k := aggCount(y,k)
+ k
+
+ isCycle?: (%, List %) -> Boolean
+ eqMember?: (%, List %) -> Boolean
+ cyclic? x == not empty? x and isCycle?(x,empty()$(List %))
+ isCycle?(x,acc) ==
+ empty? x => false
+ eqMember?(x,acc) => true
+ for y in children x | not empty? y repeat
+ isCycle?(y,acc) => return true
+ false
+ eqMember?(y,l) ==
+ for x in l repeat eq?(x,y) => return true
+ false
+ if % has shallowlyMutable then
+ setelt(x,"left",b) == setleft_!(x,b)
+ setelt(x,"right",b) == setright_!(x,b)
+
+@
+\section{category DLAGG DoublyLinkedAggregate}
+<<category DLAGG DoublyLinkedAggregate>>=
+)abbrev category DLAGG DoublyLinkedAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A doubly-linked aggregate serves as a model for a doubly-linked
+++ list, that is, a list which can has links to both next and previous
+++ nodes and thus can be efficiently traversed in both directions.
+DoublyLinkedAggregate(S:Type): Category == RecursiveAggregate S with
+ last: % -> S
+ ++ last(l) returns the last element of a doubly-linked aggregate l.
+ ++ Error: if l is empty.
+ head: % -> %
+ ++ head(l) returns the first element of a doubly-linked aggregate l.
+ ++ Error: if l is empty.
+ tail: % -> %
+ ++ tail(l) returns the doubly-linked aggregate l starting at
+ ++ its second element.
+ ++ Error: if l is empty.
+ previous: % -> %
+ ++ previous(l) returns the doubly-link list beginning with its previous
+ ++ element.
+ ++ Error: if l has no previous element.
+ ++ Note: \axiom{next(previous(l)) = l}.
+ next: % -> %
+ ++ next(l) returns the doubly-linked aggregate beginning with its next
+ ++ element.
+ ++ Error: if l has no next element.
+ ++ Note: \axiom{next(l) = rest(l)} and \axiom{previous(next(l)) = l}.
+ if % has shallowlyMutable then
+ concat_!: (%,%) -> %
+ ++ concat!(u,v) destructively concatenates doubly-linked aggregate v to the end of doubly-linked aggregate u.
+ setprevious_!: (%,%) -> %
+ ++ setprevious!(u,v) destructively sets the previous node of doubly-linked aggregate u to v, returning v.
+ setnext_!: (%,%) -> %
+ ++ setnext!(u,v) destructively sets the next node of doubly-linked aggregate u to v, returning v.
+
+@
+\section{category URAGG UnaryRecursiveAggregate}
+<<category URAGG UnaryRecursiveAggregate>>=
+)abbrev category URAGG UnaryRecursiveAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A unary-recursive aggregate is a one where nodes may have either
+++ 0 or 1 children.
+++ This aggregate models, though not precisely, a linked
+++ list possibly with a single cycle.
+++ A node with one children models a non-empty list, with the
+++ \spadfun{value} of the list designating the head, or \spadfun{first}, of the
+++ list, and the child designating the tail, or \spadfun{rest}, of the list.
+++ A node with no child then designates the empty list.
+++ Since these aggregates are recursive aggregates, they may be cyclic.
+UnaryRecursiveAggregate(S:Type): Category == RecursiveAggregate S with
+ concat: (%,%) -> %
+ ++ concat(u,v) returns an aggregate w consisting of the elements of u
+ ++ followed by the elements of v.
+ ++ Note: \axiom{v = rest(w,#a)}.
+ concat: (S,%) -> %
+ ++ concat(x,u) returns aggregate consisting of x followed by
+ ++ the elements of u.
+ ++ Note: if \axiom{v = concat(x,u)} then \axiom{x = first v}
+ ++ and \axiom{u = rest v}.
+ first: % -> S
+ ++ first(u) returns the first element of u
+ ++ (equivalently, the value at the current node).
+ elt: (%,"first") -> S
+ ++ elt(u,"first") (also written: \axiom{u . first}) is equivalent to first u.
+ first: (%,NonNegativeInteger) -> %
+ ++ first(u,n) returns a copy of the first n (\axiom{n >= 0}) elements of u.
+ rest: % -> %
+ ++ rest(u) returns an aggregate consisting of all but the first
+ ++ element of u
+ ++ (equivalently, the next node of u).
+ elt: (%,"rest") -> %
+ ++ elt(%,"rest") (also written: \axiom{u.rest}) is
+ ++ equivalent to \axiom{rest u}.
+ rest: (%,NonNegativeInteger) -> %
+ ++ rest(u,n) returns the \axiom{n}th (n >= 0) node of u.
+ ++ Note: \axiom{rest(u,0) = u}.
+ last: % -> S
+ ++ last(u) resturn the last element of u.
+ ++ Note: for lists, \axiom{last(u) = u . (maxIndex u) = u . (# u - 1)}.
+ elt: (%,"last") -> S
+ ++ elt(u,"last") (also written: \axiom{u . last}) is equivalent to last u.
+ last: (%,NonNegativeInteger) -> %
+ ++ last(u,n) returns a copy of the last n (\axiom{n >= 0}) nodes of u.
+ ++ Note: \axiom{last(u,n)} is a list of n elements.
+ tail: % -> %
+ ++ tail(u) returns the last node of u.
+ ++ Note: if u is \axiom{shallowlyMutable},
+ ++ \axiom{setrest(tail(u),v) = concat(u,v)}.
+ second: % -> S
+ ++ second(u) returns the second element of u.
+ ++ Note: \axiom{second(u) = first(rest(u))}.
+ third: % -> S
+ ++ third(u) returns the third element of u.
+ ++ Note: \axiom{third(u) = first(rest(rest(u)))}.
+ cycleEntry: % -> %
+ ++ cycleEntry(u) returns the head of a top-level cycle contained in
+ ++ aggregate u, or \axiom{empty()} if none exists.
+ cycleLength: % -> NonNegativeInteger
+ ++ cycleLength(u) returns the length of a top-level cycle
+ ++ contained in aggregate u, or 0 is u has no such cycle.
+ cycleTail: % -> %
+ ++ cycleTail(u) returns the last node in the cycle, or
+ ++ empty if none exists.
+ if % has shallowlyMutable then
+ concat_!: (%,%) -> %
+ ++ concat!(u,v) destructively concatenates v to the end of u.
+ ++ Note: \axiom{concat!(u,v) = setlast_!(u,v)}.
+ concat_!: (%,S) -> %
+ ++ concat!(u,x) destructively adds element x to the end of u.
+ ++ Note: \axiom{concat!(a,x) = setlast!(a,[x])}.
+ cycleSplit_!: % -> %
+ ++ cycleSplit!(u) splits the aggregate by dropping off the cycle.
+ ++ The value returned is the cycle entry, or nil if none exists.
+ ++ For example, if \axiom{w = concat(u,v)} is the cyclic list where v is
+ ++ the head of the cycle, \axiom{cycleSplit!(w)} will drop v off w thus
+ ++ destructively changing w to u, and returning v.
+ setfirst_!: (%,S) -> S
+ ++ setfirst!(u,x) destructively changes the first element of a to x.
+ setelt: (%,"first",S) -> S
+ ++ setelt(u,"first",x) (also written: \axiom{u.first := x}) is
+ ++ equivalent to \axiom{setfirst!(u,x)}.
+ setrest_!: (%,%) -> %
+ ++ setrest!(u,v) destructively changes the rest of u to v.
+ setelt: (%,"rest",%) -> %
+ ++ setelt(u,"rest",v) (also written: \axiom{u.rest := v}) is equivalent to
+ ++ \axiom{setrest!(u,v)}.
+ setlast_!: (%,S) -> S
+ ++ setlast!(u,x) destructively changes the last element of u to x.
+ setelt: (%,"last",S) -> S
+ ++ setelt(u,"last",x) (also written: \axiom{u.last := b})
+ ++ is equivalent to \axiom{setlast!(u,v)}.
+ split_!: (%,Integer) -> %
+ ++ split!(u,n) splits u into two aggregates: \axiom{v = rest(u,n)}
+ ++ and \axiom{w = first(u,n)}, returning \axiom{v}.
+ ++ Note: afterwards \axiom{rest(u,n)} returns \axiom{empty()}.
+ add
+ cycleMax ==> 1000
+
+ findCycle: % -> %
+
+ elt(x, "first") == first x
+ elt(x, "last") == last x
+ elt(x, "rest") == rest x
+ second x == first rest x
+ third x == first rest rest x
+ cyclic? x == not empty? x and not empty? findCycle x
+ last x == first tail x
+
+ nodes x ==
+ l := empty()$List(%)
+ while not empty? x repeat
+ l := concat(x, l)
+ x := rest x
+ reverse_! l
+
+ children x ==
+ l := empty()$List(%)
+ empty? x => l
+ concat(rest x,l)
+
+ leaf? x == empty? x
+
+ value x ==
+ empty? x => error "value of empty object"
+ first x
+
+ less?(l, n) ==
+ i := n::Integer
+ while i > 0 and not empty? l repeat (l := rest l; i := i - 1)
+ i > 0
+
+ more?(l, n) ==
+ i := n::Integer
+ while i > 0 and not empty? l repeat (l := rest l; i := i - 1)
+ zero?(i) and not empty? l
+
+ size?(l, n) ==
+ i := n::Integer
+ while not empty? l and i > 0 repeat (l := rest l; i := i - 1)
+ empty? l and zero? i
+
+ #x ==
+ for k in 0.. while not empty? x repeat
+ k = cycleMax and cyclic? x => error "cyclic list"
+ x := rest x
+ k
+
+ tail x ==
+ empty? x => error "empty list"
+ y := rest x
+ for k in 0.. while not empty? y repeat
+ k = cycleMax and cyclic? x => error "cyclic list"
+ y := rest(x := y)
+ x
+
+ findCycle x ==
+ y := rest x
+ while not empty? y repeat
+ if eq?(x, y) then return x
+ x := rest x
+ y := rest y
+ if empty? y then return y
+ if eq?(x, y) then return y
+ y := rest y
+ y
+
+ cycleTail x ==
+ empty?(y := x := cycleEntry x) => x
+ z := rest x
+ while not eq?(x,z) repeat (y := z; z := rest z)
+ y
+
+ cycleEntry x ==
+ empty? x => x
+ empty?(y := findCycle x) => y
+ z := rest y
+ for l in 1.. while not eq?(y,z) repeat z := rest z
+ y := x
+ for k in 1..l repeat y := rest y
+ while not eq?(x,y) repeat (x := rest x; y := rest y)
+ x
+
+ cycleLength x ==
+ empty? x => 0
+ empty?(x := findCycle x) => 0
+ y := rest x
+ for k in 1.. while not eq?(x,y) repeat y := rest y
+ k
+
+ rest(x, n) ==
+ for i in 1..n repeat
+ empty? x => error "Index out of range"
+ x := rest x
+ x
+
+ if % has finiteAggregate then
+ last(x, n) ==
+ n > (m := #x) => error "index out of range"
+ copy rest(x, (m - n)::NonNegativeInteger)
+
+ if S has SetCategory then
+ x = y ==
+ eq?(x, y) => true
+ for k in 0.. while not empty? x and not empty? y repeat
+ k = cycleMax and cyclic? x => error "cyclic list"
+ first x ^= first y => return false
+ x := rest x
+ y := rest y
+ empty? x and empty? y
+
+ node?(u, v) ==
+ for k in 0.. while not empty? v repeat
+ u = v => return true
+ k = cycleMax and cyclic? v => error "cyclic list"
+ v := rest v
+ u=v
+
+ if % has shallowlyMutable then
+ setelt(x, "first", a) == setfirst_!(x, a)
+ setelt(x, "last", a) == setlast_!(x, a)
+ setelt(x, "rest", a) == setrest_!(x, a)
+ concat(x:%, y:%) == concat_!(copy x, y)
+
+ setlast_!(x, s) ==
+ empty? x => error "setlast: empty list"
+ setfirst_!(tail x, s)
+ s
+
+ setchildren_!(u,lv) ==
+ #lv=1 => setrest_!(u, first lv)
+ error "wrong number of children specified"
+
+ setvalue_!(u,s) == setfirst_!(u,s)
+
+ split_!(p, n) ==
+ n < 1 => error "index out of range"
+ p := rest(p, (n - 1)::NonNegativeInteger)
+ q := rest p
+ setrest_!(p, empty())
+ q
+
+ cycleSplit_! x ==
+ empty?(y := cycleEntry x) or eq?(x, y) => y
+ z := rest x
+ while not eq?(z, y) repeat (x := z; z := rest z)
+ setrest_!(x, empty())
+ y
+
+@
+\section{URAGG.lsp BOOTSTRAP}
+{\bf URAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf URAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf URAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<URAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |UnaryRecursiveAggregate;CAT| (QUOTE NIL))
+
+(SETQ |UnaryRecursiveAggregate;AL| (QUOTE NIL))
+
+(DEFUN |UnaryRecursiveAggregate| (#1=#:G84596) (LET (#2=#:G84597) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |UnaryRecursiveAggregate;AL|)) (CDR #2#)) (T (SETQ |UnaryRecursiveAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|UnaryRecursiveAggregate;| #1#))) |UnaryRecursiveAggregate;AL|)) #2#))))
+
+(DEFUN |UnaryRecursiveAggregate;| (|t#1|) (PROG (#1=#:G84595) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|UnaryRecursiveAggregate;CAT|) ((QUOTE T) (LETT |UnaryRecursiveAggregate;CAT| (|Join| (|RecursiveAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|concat| (|$| |$| |$|)) T) ((|concat| (|$| |t#1| |$|)) T) ((|first| (|t#1| |$|)) T) ((|elt| (|t#1| |$| "first")) T) ((|first| (|$| |$| (|NonNegativeInteger|))) T) ((|rest| (|$| |$|)) T) ((|elt| (|$| |$| "rest")) T) ((|rest| (|$| |$| (|NonNegativeInteger|))) T) ((|last| (|t#1| |$|)) T) ((|elt| (|t#1| |$| "last")) T) ((|last| (|$| |$| (|NonNegativeInteger|))) T) ((|tail| (|$| |$|)) T) ((|second| (|t#1| |$|)) T) ((|third| (|t#1| |$|)) T) ((|cycleEntry| (|$| |$|)) T) ((|cycleLength| ((|NonNegativeInteger|) |$|)) T) ((|cycleTail| (|$| |$|)) T) ((|concat!| (|$| |$| |$|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|concat!| (|$| |$| |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|cycleSplit!| (|$| |$|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setfirst!| (|t#1| |$| |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setelt| (|t#1| |$| "first" |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setrest!| (|$| |$| |$|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setelt| (|$| |$| "rest" |$|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setlast!| (|t#1| |$| |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setelt| (|t#1| |$| "last" |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|split!| (|$| |$| (|Integer|))) (|has| |$| (ATTRIBUTE |shallowlyMutable|))))) NIL (QUOTE ((|Integer|) (|NonNegativeInteger|))) NIL)) . #2=(|UnaryRecursiveAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |UnaryRecursiveAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{URAGG-.lsp BOOTSTRAP}
+{\bf URAGG-} depends on {\bf URAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf URAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf URAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<URAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |URAGG-;elt;AfirstS;1| (|x| G84610 |$|) (SPADCALL |x| (QREFELT |$| 8)))
+
+(DEFUN |URAGG-;elt;AlastS;2| (|x| G84612 |$|) (SPADCALL |x| (QREFELT |$| 11)))
+
+(DEFUN |URAGG-;elt;ArestA;3| (|x| G84614 |$|) (SPADCALL |x| (QREFELT |$| 14)))
+
+(DEFUN |URAGG-;second;AS;4| (|x| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 14)) (QREFELT |$| 8)))
+
+(DEFUN |URAGG-;third;AS;5| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 14)) (QREFELT |$| 14)) (QREFELT |$| 8)))
+
+(DEFUN |URAGG-;cyclic?;AB;6| (|x| |$|) (COND ((OR (SPADCALL |x| (QREFELT |$| 20)) (SPADCALL (|URAGG-;findCycle| |x| |$|) (QREFELT |$| 20))) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+
+(DEFUN |URAGG-;last;AS;7| (|x| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 22)) (QREFELT |$| 8)))
+
+(DEFUN |URAGG-;nodes;AL;8| (|x| |$|) (PROG (|l|) (RETURN (SEQ (LETT |l| NIL |URAGG-;nodes;AL;8|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |l| (CONS |x| |l|) |URAGG-;nodes;AL;8|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;nodes;AL;8|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (NREVERSE |l|))))))
+
+(DEFUN |URAGG-;children;AL;9| (|x| |$|) (PROG (|l|) (RETURN (SEQ (LETT |l| NIL |URAGG-;children;AL;9|) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 20)) |l|) ((QUOTE T) (CONS (SPADCALL |x| (QREFELT |$| 14)) |l|))))))))
+
+(DEFUN |URAGG-;leaf?;AB;10| (|x| |$|) (SPADCALL |x| (QREFELT |$| 20)))
+
+(DEFUN |URAGG-;value;AS;11| (|x| |$|) (COND ((SPADCALL |x| (QREFELT |$| 20)) (|error| "value of empty object")) ((QUOTE T) (SPADCALL |x| (QREFELT |$| 8)))))
+
+(DEFUN |URAGG-;less?;ANniB;12| (|l| |n| |$|) (PROG (|i|) (RETURN (SEQ (LETT |i| |n| |URAGG-;less?;ANniB;12|) (SEQ G190 (COND ((NULL (COND ((|<| 0 |i|) (COND ((SPADCALL |l| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) ((QUOTE T) (QUOTE NIL)))) (GO G191))) (SEQ (LETT |l| (SPADCALL |l| (QREFELT |$| 14)) |URAGG-;less?;ANniB;12|) (EXIT (LETT |i| (|-| |i| 1) |URAGG-;less?;ANniB;12|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (|<| 0 |i|))))))
+
+(DEFUN |URAGG-;more?;ANniB;13| (|l| |n| |$|) (PROG (|i|) (RETURN (SEQ (LETT |i| |n| |URAGG-;more?;ANniB;13|) (SEQ G190 (COND ((NULL (COND ((|<| 0 |i|) (COND ((SPADCALL |l| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) ((QUOTE T) (QUOTE NIL)))) (GO G191))) (SEQ (LETT |l| (SPADCALL |l| (QREFELT |$| 14)) |URAGG-;more?;ANniB;13|) (EXIT (LETT |i| (|-| |i| 1) |URAGG-;more?;ANniB;13|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((ZEROP |i|) (COND ((SPADCALL |l| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |URAGG-;size?;ANniB;14| (|l| |n| |$|) (PROG (|i|) (RETURN (SEQ (LETT |i| |n| |URAGG-;size?;ANniB;14|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |l| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (|<| 0 |i|)))) (GO G191))) (SEQ (LETT |l| (SPADCALL |l| (QREFELT |$| 14)) |URAGG-;size?;ANniB;14|) (EXIT (LETT |i| (|-| |i| 1) |URAGG-;size?;ANniB;14|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |l| (QREFELT |$| 20)) (ZEROP |i|)) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |URAGG-;#;ANni;15| (|x| |$|) (PROG (|k|) (RETURN (SEQ (SEQ (LETT |k| 0 |URAGG-;#;ANni;15|) G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |x| (QREFELT |$| 33)) (EXIT (|error| "cyclic list")))))) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;#;ANni;15|))) (LETT |k| (QSADD1 |k|) |URAGG-;#;ANni;15|) (GO G190) G191 (EXIT NIL)) (EXIT |k|)))))
+
+(DEFUN |URAGG-;tail;2A;16| (|x| |$|) (PROG (|k| |y|) (RETURN (SEQ (COND ((SPADCALL |x| (QREFELT |$| 20)) (|error| "empty list")) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;tail;2A;16|) (SEQ (LETT |k| 0 |URAGG-;tail;2A;16|) G190 (COND ((NULL (COND ((SPADCALL |y| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |x| (QREFELT |$| 33)) (EXIT (|error| "cyclic list")))))) (EXIT (LETT |y| (SPADCALL (LETT |x| |y| |URAGG-;tail;2A;16|) (QREFELT |$| 14)) |URAGG-;tail;2A;16|))) (LETT |k| (QSADD1 |k|) |URAGG-;tail;2A;16|) (GO G190) G191 (EXIT NIL)) (EXIT |x|))))))))
+
+(DEFUN |URAGG-;findCycle| (|x| |$|) (PROG (#1=#:G84667 |y|) (RETURN (SEQ (EXIT (SEQ (LETT |y| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;findCycle|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |y| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (PROGN (LETT #1# |x| |URAGG-;findCycle|) (GO #1#)))) (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;findCycle|) (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;findCycle|) (COND ((SPADCALL |y| (QREFELT |$| 20)) (PROGN (LETT #1# |y| |URAGG-;findCycle|) (GO #1#)))) (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (PROGN (LETT #1# |y| |URAGG-;findCycle|) (GO #1#)))) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;findCycle|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |y|))) #1# (EXIT #1#)))))
+
+(DEFUN |URAGG-;cycleTail;2A;18| (|x| |$|) (PROG (|y| |z|) (RETURN (SEQ (COND ((SPADCALL (LETT |y| (LETT |x| (SPADCALL |x| (QREFELT |$| 37)) |URAGG-;cycleTail;2A;18|) |URAGG-;cycleTail;2A;18|) (QREFELT |$| 20)) |x|) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;cycleTail;2A;18|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| |z| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |y| |z| |URAGG-;cycleTail;2A;18|) (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 14)) |URAGG-;cycleTail;2A;18|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |y|))))))))
+
+(DEFUN |URAGG-;cycleEntry;2A;19| (|x| |$|) (PROG (|l| |z| |k| |y|) (RETURN (SEQ (COND ((SPADCALL |x| (QREFELT |$| 20)) |x|) ((SPADCALL (LETT |y| (|URAGG-;findCycle| |x| |$|) |URAGG-;cycleEntry;2A;19|) (QREFELT |$| 20)) |y|) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|) (SEQ (LETT |l| 1 |URAGG-;cycleEntry;2A;19|) G190 (COND ((NULL (COND ((SPADCALL |y| |z| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|))) (LETT |l| (QSADD1 |l|) |URAGG-;cycleEntry;2A;19|) (GO G190) G191 (EXIT NIL)) (LETT |y| |x| |URAGG-;cycleEntry;2A;19|) (SEQ (LETT |k| 1 |URAGG-;cycleEntry;2A;19|) G190 (COND ((QSGREATERP |k| |l|) (GO G191))) (SEQ (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|))) (LETT |k| (QSADD1 |k|) |URAGG-;cycleEntry;2A;19|) (GO G190) G191 (EXIT NIL)) (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|))))))))
+
+(DEFUN |URAGG-;cycleLength;ANni;20| (|x| |$|) (PROG (|k| |y|) (RETURN (SEQ (COND ((OR (SPADCALL |x| (QREFELT |$| 20)) (SPADCALL (LETT |x| (|URAGG-;findCycle| |x| |$|) |URAGG-;cycleLength;ANni;20|) (QREFELT |$| 20))) 0) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;cycleLength;ANni;20|) (SEQ (LETT |k| 1 |URAGG-;cycleLength;ANni;20|) G190 (COND ((NULL (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;cycleLength;ANni;20|))) (LETT |k| (QSADD1 |k|) |URAGG-;cycleLength;ANni;20|) (GO G190) G191 (EXIT NIL)) (EXIT |k|))))))))
+
+(DEFUN |URAGG-;rest;ANniA;21| (|x| |n| |$|) (PROG (|i|) (RETURN (SEQ (SEQ (LETT |i| 1 |URAGG-;rest;ANniA;21|) G190 (COND ((QSGREATERP |i| |n|) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |x| (QREFELT |$| 20)) (|error| "Index out of range")) ((QUOTE T) (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;rest;ANniA;21|))))) (LETT |i| (QSADD1 |i|) |URAGG-;rest;ANniA;21|) (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))
+
+(DEFUN |URAGG-;last;ANniA;22| (|x| |n| |$|) (PROG (|m| #1=#:G84694) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 42)) |URAGG-;last;ANniA;22|) (EXIT (COND ((|<| |m| |n|) (|error| "index out of range")) ((QUOTE T) (SPADCALL (SPADCALL |x| (PROG1 (LETT #1# (|-| |m| |n|) |URAGG-;last;ANniA;22|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 43)) (QREFELT |$| 44)))))))))
+
+(DEFUN |URAGG-;=;2AB;23| (|x| |y| |$|) (PROG (|k| #1=#:G84705) (RETURN (SEQ (EXIT (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (QUOTE T)) ((QUOTE T) (SEQ (SEQ (LETT |k| 0 |URAGG-;=;2AB;23|) G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 20)) (SPADCALL |y| (QREFELT |$| 20))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |x| (QREFELT |$| 33)) (EXIT (|error| "cyclic list")))))) (COND ((NULL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (SPADCALL |y| (QREFELT |$| 8)) (QREFELT |$| 46))) (EXIT (PROGN (LETT #1# (QUOTE NIL) |URAGG-;=;2AB;23|) (GO #1#))))) (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;=;2AB;23|) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;=;2AB;23|))) (LETT |k| (QSADD1 |k|) |URAGG-;=;2AB;23|) (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 20)) (SPADCALL |y| (QREFELT |$| 20))) ((QUOTE T) (QUOTE NIL)))))))) #1# (EXIT #1#)))))
+
+(DEFUN |URAGG-;node?;2AB;24| (|u| |v| |$|) (PROG (|k| #1=#:G84711) (RETURN (SEQ (EXIT (SEQ (SEQ (LETT |k| 0 |URAGG-;node?;2AB;24|) G190 (COND ((NULL (COND ((SPADCALL |v| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |u| |v| (QREFELT |$| 48)) (PROGN (LETT #1# (QUOTE T) |URAGG-;node?;2AB;24|) (GO #1#))) ((QUOTE T) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |v| (QREFELT |$| 33)) (EXIT (|error| "cyclic list")))))) (EXIT (LETT |v| (SPADCALL |v| (QREFELT |$| 14)) |URAGG-;node?;2AB;24|))))))) (LETT |k| (QSADD1 |k|) |URAGG-;node?;2AB;24|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |u| |v| (QREFELT |$| 48))))) #1# (EXIT #1#)))))
+
+(DEFUN |URAGG-;setelt;Afirst2S;25| (|x| G84713 |a| |$|) (SPADCALL |x| |a| (QREFELT |$| 50)))
+
+(DEFUN |URAGG-;setelt;Alast2S;26| (|x| G84715 |a| |$|) (SPADCALL |x| |a| (QREFELT |$| 52)))
+
+(DEFUN |URAGG-;setelt;Arest2A;27| (|x| G84717 |a| |$|) (SPADCALL |x| |a| (QREFELT |$| 54)))
+
+(DEFUN |URAGG-;concat;3A;28| (|x| |y| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 44)) |y| (QREFELT |$| 56)))
+
+(DEFUN |URAGG-;setlast!;A2S;29| (|x| |s| |$|) (SEQ (COND ((SPADCALL |x| (QREFELT |$| 20)) (|error| "setlast: empty list")) ((QUOTE T) (SEQ (SPADCALL (SPADCALL |x| (QREFELT |$| 22)) |s| (QREFELT |$| 50)) (EXIT |s|))))))
+
+(DEFUN |URAGG-;setchildren!;ALA;30| (|u| |lv| |$|) (COND ((EQL (LENGTH |lv|) 1) (SPADCALL |u| (|SPADfirst| |lv|) (QREFELT |$| 54))) ((QUOTE T) (|error| "wrong number of children specified"))))
+
+(DEFUN |URAGG-;setvalue!;A2S;31| (|u| |s| |$|) (SPADCALL |u| |s| (QREFELT |$| 50)))
+
+(DEFUN |URAGG-;split!;AIA;32| (|p| |n| |$|) (PROG (#1=#:G84725 |q|) (RETURN (SEQ (COND ((|<| |n| 1) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |p| (SPADCALL |p| (PROG1 (LETT #1# (|-| |n| 1) |URAGG-;split!;AIA;32|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 43)) |URAGG-;split!;AIA;32|) (LETT |q| (SPADCALL |p| (QREFELT |$| 14)) |URAGG-;split!;AIA;32|) (SPADCALL |p| (SPADCALL (QREFELT |$| 61)) (QREFELT |$| 54)) (EXIT |q|))))))))
+
+(DEFUN |URAGG-;cycleSplit!;2A;33| (|x| |$|) (PROG (|y| |z|) (RETURN (SEQ (COND ((OR (SPADCALL (LETT |y| (SPADCALL |x| (QREFELT |$| 37)) |URAGG-;cycleSplit!;2A;33|) (QREFELT |$| 20)) (SPADCALL |x| |y| (QREFELT |$| 36))) |y|) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;cycleSplit!;2A;33|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |z| |y| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |x| |z| |URAGG-;cycleSplit!;2A;33|) (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 14)) |URAGG-;cycleSplit!;2A;33|))) NIL (GO G190) G191 (EXIT NIL)) (SPADCALL |x| (SPADCALL (QREFELT |$| 61)) (QREFELT |$| 54)) (EXIT |y|))))))))
+
+(DEFUN |UnaryRecursiveAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|UnaryRecursiveAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |UnaryRecursiveAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 66) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasAttribute| |#1| (QUOTE |shallowlyMutable|)))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|HasAttribute| |#1| (QUOTE |finiteAggregate|)) (QSETREFV |$| 45 (CONS (|dispatchFunction| |URAGG-;last;ANniA;22|) |$|)))) (COND ((|HasCategory| |#2| (QUOTE (|SetCategory|))) (PROGN (QSETREFV |$| 47 (CONS (|dispatchFunction| |URAGG-;=;2AB;23|) |$|)) (QSETREFV |$| 49 (CONS (|dispatchFunction| |URAGG-;node?;2AB;24|) |$|))))) (COND ((|testBitVector| |pv$| 1) (PROGN (QSETREFV |$| 51 (CONS (|dispatchFunction| |URAGG-;setelt;Afirst2S;25|) |$|)) (QSETREFV |$| 53 (CONS (|dispatchFunction| |URAGG-;setelt;Alast2S;26|) |$|)) (QSETREFV |$| 55 (CONS (|dispatchFunction| |URAGG-;setelt;Arest2A;27|) |$|)) (QSETREFV |$| 57 (CONS (|dispatchFunction| |URAGG-;concat;3A;28|) |$|)) (QSETREFV |$| 58 (CONS (|dispatchFunction| |URAGG-;setlast!;A2S;29|) |$|)) (QSETREFV |$| 59 (CONS (|dispatchFunction| |URAGG-;setchildren!;ALA;30|) |$|)) (QSETREFV |$| 60 (CONS (|dispatchFunction| |URAGG-;setvalue!;A2S;31|) |$|)) (QSETREFV |$| 63 (CONS (|dispatchFunction| |URAGG-;split!;AIA;32|) |$|)) (QSETREFV |$| 64 (CONS (|dispatchFunction| |URAGG-;cycleSplit!;2A;33|) |$|))))) |$|))))
+
+(MAKEPROP (QUOTE |UnaryRecursiveAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (0 . |first|) (QUOTE "first") |URAGG-;elt;AfirstS;1| (5 . |last|) (QUOTE "last") |URAGG-;elt;AlastS;2| (10 . |rest|) (QUOTE "rest") |URAGG-;elt;ArestA;3| |URAGG-;second;AS;4| |URAGG-;third;AS;5| (|Boolean|) (15 . |empty?|) |URAGG-;cyclic?;AB;6| (20 . |tail|) |URAGG-;last;AS;7| (|List| |$|) |URAGG-;nodes;AL;8| |URAGG-;children;AL;9| |URAGG-;leaf?;AB;10| |URAGG-;value;AS;11| (|NonNegativeInteger|) |URAGG-;less?;ANniB;12| |URAGG-;more?;ANniB;13| |URAGG-;size?;ANniB;14| (25 . |cyclic?|) |URAGG-;#;ANni;15| |URAGG-;tail;2A;16| (30 . |eq?|) (36 . |cycleEntry|) |URAGG-;cycleTail;2A;18| |URAGG-;cycleEntry;2A;19| |URAGG-;cycleLength;ANni;20| |URAGG-;rest;ANniA;21| (41 . |#|) (46 . |rest|) (52 . |copy|) (57 . |last|) (63 . |=|) (69 . |=|) (75 . |=|) (81 . |node?|) (87 . |setfirst!|) (93 . |setelt|) (100 . |setlast!|) (106 . |setelt|) (113 . |setrest!|) (119 . |setelt|) (126 . |concat!|) (132 . |concat|) (138 . |setlast!|) (144 . |setchildren!|) (150 . |setvalue!|) (156 . |empty|) (|Integer|) (160 . |split!|) (166 . |cycleSplit!|) (QUOTE "value"))) (QUOTE #(|value| 171 |third| 176 |tail| 181 |split!| 186 |size?| 192 |setvalue!| 198 |setlast!| 204 |setelt| 210 |setchildren!| 231 |second| 237 |rest| 242 |nodes| 248 |node?| 253 |more?| 259 |less?| 265 |leaf?| 271 |last| 276 |elt| 287 |cyclic?| 305 |cycleTail| 310 |cycleSplit!| 315 |cycleLength| 320 |cycleEntry| 325 |concat| 330 |children| 336 |=| 341 |#| 347)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 64 (QUOTE (1 6 7 0 8 1 6 7 0 11 1 6 0 0 14 1 6 19 0 20 1 6 0 0 22 1 6 19 0 33 2 6 19 0 0 36 1 6 0 0 37 1 6 29 0 42 2 6 0 0 29 43 1 6 0 0 44 2 0 0 0 29 45 2 7 19 0 0 46 2 0 19 0 0 47 2 6 19 0 0 48 2 0 19 0 0 49 2 6 7 0 7 50 3 0 7 0 9 7 51 2 6 7 0 7 52 3 0 7 0 12 7 53 2 6 0 0 0 54 3 0 0 0 15 0 55 2 6 0 0 0 56 2 0 0 0 0 57 2 0 7 0 7 58 2 0 0 0 24 59 2 0 7 0 7 60 0 6 0 61 2 0 0 0 62 63 1 0 0 0 64 1 0 7 0 28 1 0 7 0 18 1 0 0 0 35 2 0 0 0 62 63 2 0 19 0 29 32 2 0 7 0 7 60 2 0 7 0 7 58 3 0 7 0 12 7 53 3 0 0 0 15 0 55 3 0 7 0 9 7 51 2 0 0 0 24 59 1 0 7 0 17 2 0 0 0 29 41 1 0 24 0 25 2 0 19 0 0 49 2 0 19 0 29 31 2 0 19 0 29 30 1 0 19 0 27 2 0 0 0 29 45 1 0 7 0 23 2 0 7 0 12 13 2 0 0 0 15 16 2 0 7 0 9 10 1 0 19 0 21 1 0 0 0 38 1 0 0 0 64 1 0 29 0 40 1 0 0 0 39 2 0 0 0 0 57 1 0 24 0 26 2 0 19 0 0 47 1 0 29 0 34)))))) (QUOTE |lookupComplete|)))
+@
+\section{category STAGG StreamAggregate}
+<<category STAGG StreamAggregate>>=
+)abbrev category STAGG StreamAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A stream aggregate is a linear aggregate which possibly has an infinite
+++ number of elements. A basic domain constructor which builds stream
+++ aggregates is \spadtype{Stream}. From streams, a number of infinite
+++ structures such power series can be built. A stream aggregate may
+++ also be infinite since it may be cyclic.
+++ For example, see \spadtype{DecimalExpansion}.
+StreamAggregate(S:Type): Category ==
+ Join(UnaryRecursiveAggregate S, LinearAggregate S) with
+ explicitlyFinite?: % -> Boolean
+ ++ explicitlyFinite?(s) tests if the stream has a finite
+ ++ number of elements, and false otherwise.
+ ++ Note: for many datatypes, \axiom{explicitlyFinite?(s) = not possiblyInfinite?(s)}.
+ possiblyInfinite?: % -> Boolean
+ ++ possiblyInfinite?(s) tests if the stream s could possibly
+ ++ have an infinite number of elements.
+ ++ Note: for many datatypes, \axiom{possiblyInfinite?(s) = not explictlyFinite?(s)}.
+ add
+ c2: (%, %) -> S
+
+ explicitlyFinite? x == not cyclic? x
+ possiblyInfinite? x == cyclic? x
+ first(x, n) == construct [c2(x, x := rest x) for i in 1..n]
+
+ c2(x, r) ==
+ empty? x => error "Index out of range"
+ first x
+
+ elt(x:%, i:Integer) ==
+ i := i - minIndex x
+ (i < 0) or empty?(x := rest(x, i::NonNegativeInteger)) => error "index out of range"
+ first x
+
+ elt(x:%, i:UniversalSegment(Integer)) ==
+ l := lo(i) - minIndex x
+ l < 0 => error "index out of range"
+ not hasHi i => copy(rest(x, l::NonNegativeInteger))
+ (h := hi(i) - minIndex x) < l => empty()
+ first(rest(x, l::NonNegativeInteger), (h - l + 1)::NonNegativeInteger)
+
+ if % has shallowlyMutable then
+ concat(x:%, y:%) == concat_!(copy x, y)
+
+ concat l ==
+ empty? l => empty()
+ concat_!(copy first l, concat rest l)
+
+ map_!(f, l) ==
+ y := l
+ while not empty? l repeat
+ setfirst_!(l, f first l)
+ l := rest l
+ y
+
+ fill_!(x, s) ==
+ y := x
+ while not empty? y repeat (setfirst_!(y, s); y := rest y)
+ x
+
+ setelt(x:%, i:Integer, s:S) ==
+ i := i - minIndex x
+ (i < 0) or empty?(x := rest(x,i::NonNegativeInteger)) => error "index out of range"
+ setfirst_!(x, s)
+
+ setelt(x:%, i:UniversalSegment(Integer), s:S) ==
+ (l := lo(i) - minIndex x) < 0 => error "index out of range"
+ h := if hasHi i then hi(i) - minIndex x else maxIndex x
+ h < l => s
+ y := rest(x, l::NonNegativeInteger)
+ z := rest(y, (h - l + 1)::NonNegativeInteger)
+ while not eq?(y, z) repeat (setfirst_!(y, s); y := rest y)
+ s
+
+ concat_!(x:%, y:%) ==
+ empty? x => y
+ setrest_!(tail x, y)
+ x
+
+@
+\section{STAGG.lsp BOOTSTRAP}
+{\bf STAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf STAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf STAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<STAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |StreamAggregate;CAT| (QUOTE NIL))
+
+(SETQ |StreamAggregate;AL| (QUOTE NIL))
+
+(DEFUN |StreamAggregate| (#1=#:G87035) (LET (#2=#:G87036) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |StreamAggregate;AL|)) (CDR #2#)) (T (SETQ |StreamAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|StreamAggregate;| #1#))) |StreamAggregate;AL|)) #2#))))
+
+(DEFUN |StreamAggregate;| (|t#1|) (PROG (#1=#:G87034) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|StreamAggregate;CAT|) ((QUOTE T) (LETT |StreamAggregate;CAT| (|Join| (|UnaryRecursiveAggregate| (QUOTE |t#1|)) (|LinearAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|explicitlyFinite?| ((|Boolean|) |$|)) T) ((|possiblyInfinite?| ((|Boolean|) |$|)) T))) NIL (QUOTE ((|Boolean|))) NIL)) . #2=(|StreamAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |StreamAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{STAGG-.lsp BOOTSTRAP}
+{\bf STAGG-} depends on {\bf STAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf STAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf STAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<STAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |STAGG-;explicitlyFinite?;AB;1| (|x| |$|) (COND ((SPADCALL |x| (QREFELT |$| 9)) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+
+(DEFUN |STAGG-;possiblyInfinite?;AB;2| (|x| |$|) (SPADCALL |x| (QREFELT |$| 9)))
+
+(DEFUN |STAGG-;first;ANniA;3| (|x| |n| |$|) (PROG (#1=#:G87053 |i|) (RETURN (SEQ (SPADCALL (PROGN (LETT #1# NIL |STAGG-;first;ANniA;3|) (SEQ (LETT |i| 1 |STAGG-;first;ANniA;3|) G190 (COND ((QSGREATERP |i| |n|) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (|STAGG-;c2| |x| (LETT |x| (SPADCALL |x| (QREFELT |$| 12)) |STAGG-;first;ANniA;3|) |$|) #1#) |STAGG-;first;ANniA;3|))) (LETT |i| (QSADD1 |i|) |STAGG-;first;ANniA;3|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 14))))))
+
+(DEFUN |STAGG-;c2| (|x| |r| |$|) (COND ((SPADCALL |x| (QREFELT |$| 17)) (|error| "Index out of range")) ((QUOTE T) (SPADCALL |x| (QREFELT |$| 18)))))
+
+(DEFUN |STAGG-;elt;AIS;5| (|x| |i| |$|) (PROG (#1=#:G87056) (RETURN (SEQ (LETT |i| (|-| |i| (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;elt;AIS;5|) (COND ((OR (|<| |i| 0) (SPADCALL (LETT |x| (SPADCALL |x| (PROG1 (LETT #1# |i| |STAGG-;elt;AIS;5|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 21)) |STAGG-;elt;AIS;5|) (QREFELT |$| 17))) (EXIT (|error| "index out of range")))) (EXIT (SPADCALL |x| (QREFELT |$| 18)))))))
+
+(DEFUN |STAGG-;elt;AUsA;6| (|x| |i| |$|) (PROG (|l| #1=#:G87060 |h| #2=#:G87062 #3=#:G87063) (RETURN (SEQ (LETT |l| (|-| (SPADCALL |i| (QREFELT |$| 24)) (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;elt;AUsA;6|) (EXIT (COND ((|<| |l| 0) (|error| "index out of range")) ((NULL (SPADCALL |i| (QREFELT |$| 25))) (SPADCALL (SPADCALL |x| (PROG1 (LETT #1# |l| |STAGG-;elt;AUsA;6|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 21)) (QREFELT |$| 26))) ((QUOTE T) (SEQ (LETT |h| (|-| (SPADCALL |i| (QREFELT |$| 27)) (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;elt;AUsA;6|) (EXIT (COND ((|<| |h| |l|) (SPADCALL (QREFELT |$| 28))) ((QUOTE T) (SPADCALL (SPADCALL |x| (PROG1 (LETT #2# |l| |STAGG-;elt;AUsA;6|) (|check-subtype| (|>=| #2# 0) (QUOTE (|NonNegativeInteger|)) #2#)) (QREFELT |$| 21)) (PROG1 (LETT #3# (|+| (|-| |h| |l|) 1) |STAGG-;elt;AUsA;6|) (|check-subtype| (|>=| #3# 0) (QUOTE (|NonNegativeInteger|)) #3#)) (QREFELT |$| 29)))))))))))))
+
+(DEFUN |STAGG-;concat;3A;7| (|x| |y| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 26)) |y| (QREFELT |$| 31)))
+
+(DEFUN |STAGG-;concat;LA;8| (|l| |$|) (COND ((NULL |l|) (SPADCALL (QREFELT |$| 28))) ((QUOTE T) (SPADCALL (SPADCALL (|SPADfirst| |l|) (QREFELT |$| 26)) (SPADCALL (CDR |l|) (QREFELT |$| 34)) (QREFELT |$| 31)))))
+
+(DEFUN |STAGG-;map!;M2A;9| (|f| |l| |$|) (PROG (|y|) (RETURN (SEQ (LETT |y| |l| |STAGG-;map!;M2A;9|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |l| (QREFELT |$| 17)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |l| (SPADCALL (SPADCALL |l| (QREFELT |$| 18)) |f|) (QREFELT |$| 36)) (EXIT (LETT |l| (SPADCALL |l| (QREFELT |$| 12)) |STAGG-;map!;M2A;9|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |y|)))))
+
+(DEFUN |STAGG-;fill!;ASA;10| (|x| |s| |$|) (PROG (|y|) (RETURN (SEQ (LETT |y| |x| |STAGG-;fill!;ASA;10|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |y| (QREFELT |$| 17)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |y| |s| (QREFELT |$| 36)) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 12)) |STAGG-;fill!;ASA;10|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))
+
+(DEFUN |STAGG-;setelt;AI2S;11| (|x| |i| |s| |$|) (PROG (#1=#:G87081) (RETURN (SEQ (LETT |i| (|-| |i| (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;setelt;AI2S;11|) (COND ((OR (|<| |i| 0) (SPADCALL (LETT |x| (SPADCALL |x| (PROG1 (LETT #1# |i| |STAGG-;setelt;AI2S;11|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 21)) |STAGG-;setelt;AI2S;11|) (QREFELT |$| 17))) (EXIT (|error| "index out of range")))) (EXIT (SPADCALL |x| |s| (QREFELT |$| 36)))))))
+
+(DEFUN |STAGG-;setelt;AUs2S;12| (|x| |i| |s| |$|) (PROG (|l| |h| #1=#:G87086 #2=#:G87087 |z| |y|) (RETURN (SEQ (LETT |l| (|-| (SPADCALL |i| (QREFELT |$| 24)) (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;setelt;AUs2S;12|) (EXIT (COND ((|<| |l| 0) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |h| (COND ((SPADCALL |i| (QREFELT |$| 25)) (|-| (SPADCALL |i| (QREFELT |$| 27)) (SPADCALL |x| (QREFELT |$| 20)))) ((QUOTE T) (SPADCALL |x| (QREFELT |$| 41)))) |STAGG-;setelt;AUs2S;12|) (EXIT (COND ((|<| |h| |l|) |s|) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (PROG1 (LETT #1# |l| |STAGG-;setelt;AUs2S;12|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 21)) |STAGG-;setelt;AUs2S;12|) (LETT |z| (SPADCALL |y| (PROG1 (LETT #2# (|+| (|-| |h| |l|) 1) |STAGG-;setelt;AUs2S;12|) (|check-subtype| (|>=| #2# 0) (QUOTE (|NonNegativeInteger|)) #2#)) (QREFELT |$| 21)) |STAGG-;setelt;AUs2S;12|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |y| |z| (QREFELT |$| 42)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |y| |s| (QREFELT |$| 36)) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 12)) |STAGG-;setelt;AUs2S;12|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |s|)))))))))))))
+
+(DEFUN |STAGG-;concat!;3A;13| (|x| |y| |$|) (SEQ (COND ((SPADCALL |x| (QREFELT |$| 17)) |y|) ((QUOTE T) (SEQ (SPADCALL (SPADCALL |x| (QREFELT |$| 44)) |y| (QREFELT |$| 45)) (EXIT |x|))))))
+
+(DEFUN |StreamAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|StreamAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |StreamAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 51) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|HasAttribute| |#1| (QUOTE |shallowlyMutable|)) (PROGN (QSETREFV |$| 32 (CONS (|dispatchFunction| |STAGG-;concat;3A;7|) |$|)) (QSETREFV |$| 35 (CONS (|dispatchFunction| |STAGG-;concat;LA;8|) |$|)) (QSETREFV |$| 38 (CONS (|dispatchFunction| |STAGG-;map!;M2A;9|) |$|)) (QSETREFV |$| 39 (CONS (|dispatchFunction| |STAGG-;fill!;ASA;10|) |$|)) (QSETREFV |$| 40 (CONS (|dispatchFunction| |STAGG-;setelt;AI2S;11|) |$|)) (QSETREFV |$| 43 (CONS (|dispatchFunction| |STAGG-;setelt;AUs2S;12|) |$|)) (QSETREFV |$| 46 (CONS (|dispatchFunction| |STAGG-;concat!;3A;13|) |$|))))) |$|))))
+
+(MAKEPROP (QUOTE |StreamAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|Boolean|) (0 . |cyclic?|) |STAGG-;explicitlyFinite?;AB;1| |STAGG-;possiblyInfinite?;AB;2| (5 . |rest|) (|List| 7) (10 . |construct|) (|NonNegativeInteger|) |STAGG-;first;ANniA;3| (15 . |empty?|) (20 . |first|) (|Integer|) (25 . |minIndex|) (30 . |rest|) |STAGG-;elt;AIS;5| (|UniversalSegment| 19) (36 . |lo|) (41 . |hasHi|) (46 . |copy|) (51 . |hi|) (56 . |empty|) (60 . |first|) |STAGG-;elt;AUsA;6| (66 . |concat!|) (72 . |concat|) (|List| |$|) (78 . |concat|) (83 . |concat|) (88 . |setfirst!|) (|Mapping| 7 7) (94 . |map!|) (100 . |fill!|) (106 . |setelt|) (113 . |maxIndex|) (118 . |eq?|) (124 . |setelt|) (131 . |tail|) (136 . |setrest!|) (142 . |concat!|) (QUOTE "rest") (QUOTE "last") (QUOTE "first") (QUOTE "value"))) (QUOTE #(|setelt| 148 |possiblyInfinite?| 162 |map!| 167 |first| 173 |fill!| 179 |explicitlyFinite?| 185 |elt| 190 |concat!| 202 |concat| 208)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 46 (QUOTE (1 6 8 0 9 1 6 0 0 12 1 6 0 13 14 1 6 8 0 17 1 6 7 0 18 1 6 19 0 20 2 6 0 0 15 21 1 23 19 0 24 1 23 8 0 25 1 6 0 0 26 1 23 19 0 27 0 6 0 28 2 6 0 0 15 29 2 6 0 0 0 31 2 0 0 0 0 32 1 6 0 33 34 1 0 0 33 35 2 6 7 0 7 36 2 0 0 37 0 38 2 0 0 0 7 39 3 0 7 0 19 7 40 1 6 19 0 41 2 6 8 0 0 42 3 0 7 0 23 7 43 1 6 0 0 44 2 6 0 0 0 45 2 0 0 0 0 46 3 0 7 0 19 7 40 3 0 7 0 23 7 43 1 0 8 0 11 2 0 0 37 0 38 2 0 0 0 15 16 2 0 0 0 7 39 1 0 8 0 10 2 0 7 0 19 22 2 0 0 0 23 30 2 0 0 0 0 46 1 0 0 33 35 2 0 0 0 0 32)))))) (QUOTE |lookupComplete|)))
+@
+\section{category LNAGG LinearAggregate}
+<<category LNAGG LinearAggregate>>=
+)abbrev category LNAGG LinearAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A linear aggregate is an aggregate whose elements are indexed by integers.
+++ Examples of linear aggregates are strings, lists, and
+++ arrays.
+++ Most of the exported operations for linear aggregates are non-destructive
+++ but are not always efficient for a particular aggregate.
+++ For example, \spadfun{concat} of two lists needs only to copy its first
+++ argument, whereas \spadfun{concat} of two arrays needs to copy both arguments.
+++ Most of the operations exported here apply to infinite objects (e.g. streams)
+++ as well to finite ones.
+++ For finite linear aggregates, see \spadtype{FiniteLinearAggregate}.
+LinearAggregate(S:Type): Category ==
+ Join(IndexedAggregate(Integer, S), Collection(S)) with
+ new : (NonNegativeInteger,S) -> %
+ ++ new(n,x) returns \axiom{fill!(new n,x)}.
+ concat: (%,S) -> %
+ ++ concat(u,x) returns aggregate u with additional element x at the end.
+ ++ Note: for lists, \axiom{concat(u,x) == concat(u,[x])}
+ concat: (S,%) -> %
+ ++ concat(x,u) returns aggregate u with additional element at the front.
+ ++ Note: for lists: \axiom{concat(x,u) == concat([x],u)}.
+ concat: (%,%) -> %
+ ++ concat(u,v) returns an aggregate consisting of the elements of u
+ ++ followed by the elements of v.
+ ++ Note: if \axiom{w = concat(u,v)} then \axiom{w.i = u.i for i in indices u}
+ ++ and \axiom{w.(j + maxIndex u) = v.j for j in indices v}.
+ concat: List % -> %
+ ++ concat(u), where u is a lists of aggregates \axiom{[a,b,...,c]}, returns
+ ++ a single aggregate consisting of the elements of \axiom{a}
+ ++ followed by those
+ ++ of b followed ... by the elements of c.
+ ++ Note: \axiom{concat(a,b,...,c) = concat(a,concat(b,...,c))}.
+ map: ((S,S)->S,%,%) -> %
+ ++ map(f,u,v) returns a new collection w with elements \axiom{z = f(x,y)}
+ ++ for corresponding elements x and y from u and v.
+ ++ Note: for linear aggregates, \axiom{w.i = f(u.i,v.i)}.
+ elt: (%,UniversalSegment(Integer)) -> %
+ ++ elt(u,i..j) (also written: \axiom{a(i..j)}) returns the aggregate of
+ ++ elements \axiom{u} for k from i to j in that order.
+ ++ Note: in general, \axiom{a.s = [a.k for i in s]}.
+ delete: (%,Integer) -> %
+ ++ delete(u,i) returns a copy of u with the \axiom{i}th element deleted.
+ ++ Note: for lists, \axiom{delete(a,i) == concat(a(0..i - 1),a(i + 1,..))}.
+ delete: (%,UniversalSegment(Integer)) -> %
+ ++ delete(u,i..j) returns a copy of u with the \axiom{i}th through
+ ++ \axiom{j}th element deleted.
+ ++ Note: \axiom{delete(a,i..j) = concat(a(0..i-1),a(j+1..))}.
+ insert: (S,%,Integer) -> %
+ ++ insert(x,u,i) returns a copy of u having x as its \axiom{i}th element.
+ ++ Note: \axiom{insert(x,a,k) = concat(concat(a(0..k-1),x),a(k..))}.
+ insert: (%,%,Integer) -> %
+ ++ insert(v,u,k) returns a copy of u having v inserted beginning at the
+ ++ \axiom{i}th element.
+ ++ Note: \axiom{insert(v,u,k) = concat( u(0..k-1), v, u(k..) )}.
+ if % has shallowlyMutable then setelt: (%,UniversalSegment(Integer),S) -> S
+ ++ setelt(u,i..j,x) (also written: \axiom{u(i..j) := x}) destructively
+ ++ replaces each element in the segment \axiom{u(i..j)} by x.
+ ++ The value x is returned.
+ ++ Note: u is destructively change so
+ ++ that \axiom{u.k := x for k in i..j};
+ ++ its length remains unchanged.
+ add
+ indices a == [i for i in minIndex a .. maxIndex a]
+ index?(i, a) == i >= minIndex a and i <= maxIndex a
+ concat(a:%, x:S) == concat(a, new(1, x))
+ concat(x:S, y:%) == concat(new(1, x), y)
+ insert(x:S, a:%, i:Integer) == insert(new(1, x), a, i)
+ if % has finiteAggregate then
+ maxIndex l == #l - 1 + minIndex l
+
+--if % has shallowlyMutable then new(n, s) == fill_!(new n, s)
+
+@
+\section{LNAGG.lsp BOOTSTRAP}
+{\bf LNAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf LNAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf LNAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LNAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |LinearAggregate;CAT| (QUOTE NIL))
+
+(SETQ |LinearAggregate;AL| (QUOTE NIL))
+
+(DEFUN |LinearAggregate| (#1=#:G85818) (LET (#2=#:G85819) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |LinearAggregate;AL|)) (CDR #2#)) (T (SETQ |LinearAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|LinearAggregate;| #1#))) |LinearAggregate;AL|)) #2#))))
+
+(DEFUN |LinearAggregate;| (|t#1|) (PROG (#1=#:G85817) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (|sublisV| (PAIR (QUOTE (#2=#:G85816)) (LIST (QUOTE (|Integer|)))) (COND (|LinearAggregate;CAT|) ((QUOTE T) (LETT |LinearAggregate;CAT| (|Join| (|IndexedAggregate| (QUOTE #2#) (QUOTE |t#1|)) (|Collection| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|new| (|$| (|NonNegativeInteger|) |t#1|)) T) ((|concat| (|$| |$| |t#1|)) T) ((|concat| (|$| |t#1| |$|)) T) ((|concat| (|$| |$| |$|)) T) ((|concat| (|$| (|List| |$|))) T) ((|map| (|$| (|Mapping| |t#1| |t#1| |t#1|) |$| |$|)) T) ((|elt| (|$| |$| (|UniversalSegment| (|Integer|)))) T) ((|delete| (|$| |$| (|Integer|))) T) ((|delete| (|$| |$| (|UniversalSegment| (|Integer|)))) T) ((|insert| (|$| |t#1| |$| (|Integer|))) T) ((|insert| (|$| |$| |$| (|Integer|))) T) ((|setelt| (|t#1| |$| (|UniversalSegment| (|Integer|)) |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))))) NIL (QUOTE ((|UniversalSegment| (|Integer|)) (|Integer|) (|List| |$|) (|NonNegativeInteger|))) NIL)) . #3=(|LinearAggregate|)))))) . #3#) (SETELT #1# 0 (LIST (QUOTE |LinearAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{LNAGG-.lsp BOOTSTRAP}
+{\bf LNAGG-} depends on {\bf LNAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf LNAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf LNAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LNAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |LNAGG-;indices;AL;1| (|a| |$|) (PROG (#1=#:G85833 |i| #2=#:G85834) (RETURN (SEQ (PROGN (LETT #1# NIL |LNAGG-;indices;AL;1|) (SEQ (LETT |i| (SPADCALL |a| (QREFELT |$| 9)) |LNAGG-;indices;AL;1|) (LETT #2# (SPADCALL |a| (QREFELT |$| 10)) |LNAGG-;indices;AL;1|) G190 (COND ((|>| |i| #2#) (GO G191))) (SEQ (EXIT (LETT #1# (CONS |i| #1#) |LNAGG-;indices;AL;1|))) (LETT |i| (|+| |i| 1) |LNAGG-;indices;AL;1|) (GO G190) G191 (EXIT (NREVERSE0 #1#))))))))
+
+(DEFUN |LNAGG-;index?;IAB;2| (|i| |a| |$|) (COND ((OR (|<| |i| (SPADCALL |a| (QREFELT |$| 9))) (|<| (SPADCALL |a| (QREFELT |$| 10)) |i|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+
+(DEFUN |LNAGG-;concat;ASA;3| (|a| |x| |$|) (SPADCALL |a| (SPADCALL 1 |x| (QREFELT |$| 16)) (QREFELT |$| 17)))
+
+(DEFUN |LNAGG-;concat;S2A;4| (|x| |y| |$|) (SPADCALL (SPADCALL 1 |x| (QREFELT |$| 16)) |y| (QREFELT |$| 17)))
+
+(DEFUN |LNAGG-;insert;SAIA;5| (|x| |a| |i| |$|) (SPADCALL (SPADCALL 1 |x| (QREFELT |$| 16)) |a| |i| (QREFELT |$| 20)))
+
+(DEFUN |LNAGG-;maxIndex;AI;6| (|l| |$|) (|+| (|-| (SPADCALL |l| (QREFELT |$| 22)) 1) (SPADCALL |l| (QREFELT |$| 9))))
+
+(DEFUN |LinearAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|LinearAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |LinearAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 25) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasAttribute| |#1| (QUOTE |shallowlyMutable|)))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|HasAttribute| |#1| (QUOTE |finiteAggregate|)) (QSETREFV |$| 23 (CONS (|dispatchFunction| |LNAGG-;maxIndex;AI;6|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |LinearAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|Integer|) (0 . |minIndex|) (5 . |maxIndex|) (|List| 8) |LNAGG-;indices;AL;1| (|Boolean|) |LNAGG-;index?;IAB;2| (|NonNegativeInteger|) (10 . |new|) (16 . |concat|) |LNAGG-;concat;ASA;3| |LNAGG-;concat;S2A;4| (22 . |insert|) |LNAGG-;insert;SAIA;5| (29 . |#|) (34 . |maxIndex|) (|List| |$|))) (QUOTE #(|maxIndex| 39 |insert| 44 |indices| 51 |index?| 56 |concat| 62)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 23 (QUOTE (1 6 8 0 9 1 6 8 0 10 2 6 0 15 7 16 2 6 0 0 0 17 3 6 0 0 0 8 20 1 6 15 0 22 1 0 8 0 23 1 0 8 0 23 3 0 0 7 0 8 21 1 0 11 0 12 2 0 13 8 0 14 2 0 0 0 7 18 2 0 0 7 0 19)))))) (QUOTE |lookupComplete|)))
+@
+\section{category FLAGG FiniteLinearAggregate}
+<<category FLAGG FiniteLinearAggregate>>=
+)abbrev category FLAGG FiniteLinearAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A finite linear aggregate is a linear aggregate of finite length.
+++ The finite property of the aggregate adds several exports to the
+++ list of exports from \spadtype{LinearAggregate} such as
+++ \spadfun{reverse}, \spadfun{sort}, and so on.
+FiniteLinearAggregate(S:Type): Category == LinearAggregate S with
+ finiteAggregate
+ merge: ((S,S)->Boolean,%,%) -> %
+ ++ merge(p,a,b) returns an aggregate c which merges \axiom{a} and b.
+ ++ The result is produced by examining each element x of \axiom{a} and y
+ ++ of b successively. If \axiom{p(x,y)} is true, then x is inserted into
+ ++ the result; otherwise y is inserted. If x is chosen, the next element
+ ++ of \axiom{a} is examined, and so on. When all the elements of one
+ ++ aggregate are examined, the remaining elements of the other
+ ++ are appended.
+ ++ For example, \axiom{merge(<,[1,3],[2,7,5])} returns \axiom{[1,2,3,7,5]}.
+ reverse: % -> %
+ ++ reverse(a) returns a copy of \axiom{a} with elements in reverse order.
+ sort: ((S,S)->Boolean,%) -> %
+ ++ sort(p,a) returns a copy of \axiom{a} sorted using total ordering predicate p.
+ sorted?: ((S,S)->Boolean,%) -> Boolean
+ ++ sorted?(p,a) tests if \axiom{a} is sorted according to predicate p.
+ position: (S->Boolean, %) -> Integer
+ ++ position(p,a) returns the index i of the first x in \axiom{a} such that
+ ++ \axiom{p(x)} is true, and \axiom{minIndex(a) - 1} if there is no such x.
+ if S has SetCategory then
+ position: (S, %) -> Integer
+ ++ position(x,a) returns the index i of the first occurrence of x in a,
+ ++ and \axiom{minIndex(a) - 1} if there is no such x.
+ position: (S,%,Integer) -> Integer
+ ++ position(x,a,n) returns the index i of the first occurrence of x in
+ ++ \axiom{a} where \axiom{i >= n}, and \axiom{minIndex(a) - 1} if no such x is found.
+ if S has OrderedSet then
+ OrderedSet
+ merge: (%,%) -> %
+ ++ merge(u,v) merges u and v in ascending order.
+ ++ Note: \axiom{merge(u,v) = merge(<=,u,v)}.
+ sort: % -> %
+ ++ sort(u) returns an u with elements in ascending order.
+ ++ Note: \axiom{sort(u) = sort(<=,u)}.
+ sorted?: % -> Boolean
+ ++ sorted?(u) tests if the elements of u are in ascending order.
+ if % has shallowlyMutable then
+ copyInto_!: (%,%,Integer) -> %
+ ++ copyInto!(u,v,i) returns aggregate u containing a copy of
+ ++ v inserted at element i.
+ reverse_!: % -> %
+ ++ reverse!(u) returns u with its elements in reverse order.
+ sort_!: ((S,S)->Boolean,%) -> %
+ ++ sort!(p,u) returns u with its elements ordered by p.
+ if S has OrderedSet then sort_!: % -> %
+ ++ sort!(u) returns u with its elements in ascending order.
+ add
+ if S has SetCategory then
+ position(x:S, t:%) == position(x, t, minIndex t)
+
+ if S has OrderedSet then
+-- sorted? l == sorted?(_<$S, l)
+ sorted? l == sorted?(#1 < #2 or #1 = #2, l)
+ merge(x, y) == merge(_<$S, x, y)
+ sort l == sort(_<$S, l)
+
+ if % has shallowlyMutable then
+ reverse x == reverse_! copy x
+ sort(f, l) == sort_!(f, copy l)
+ reverse x == reverse_! copy x
+
+ if S has OrderedSet then
+ sort_! l == sort_!(_<$S, l)
+
+@
+\section{category A1AGG OneDimensionalArrayAggregate}
+<<category A1AGG OneDimensionalArrayAggregate>>=
+)abbrev category A1AGG OneDimensionalArrayAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ One-dimensional-array aggregates serves as models for one-dimensional arrays.
+++ Categorically, these aggregates are finite linear aggregates
+++ with the \spadatt{shallowlyMutable} property, that is, any component of
+++ the array may be changed without affecting the
+++ identity of the overall array.
+++ Array data structures are typically represented by a fixed area in storage and
+++ therefore cannot efficiently grow or shrink on demand as can list structures
+++ (see however \spadtype{FlexibleArray} for a data structure which
+++ is a cross between a list and an array).
+++ Iteration over, and access to, elements of arrays is extremely fast
+++ (and often can be optimized to open-code).
+++ Insertion and deletion however is generally slow since an entirely new
+++ data structure must be created for the result.
+OneDimensionalArrayAggregate(S:Type): Category ==
+ FiniteLinearAggregate S with shallowlyMutable
+ add
+ parts x == [qelt(x, i) for i in minIndex x .. maxIndex x]
+ sort_!(f, a) == quickSort(f, a)$FiniteLinearAggregateSort(S, %)
+
+ any?(f, a) ==
+ for i in minIndex a .. maxIndex a repeat
+ f qelt(a, i) => return true
+ false
+
+ every?(f, a) ==
+ for i in minIndex a .. maxIndex a repeat
+ not(f qelt(a, i)) => return false
+ true
+
+ position(f:S -> Boolean, a:%) ==
+ for i in minIndex a .. maxIndex a repeat
+ f qelt(a, i) => return i
+ minIndex(a) - 1
+
+ find(f, a) ==
+ for i in minIndex a .. maxIndex a repeat
+ f qelt(a, i) => return qelt(a, i)
+ "failed"
+
+ count(f:S->Boolean, a:%) ==
+ n:NonNegativeInteger := 0
+ for i in minIndex a .. maxIndex a repeat
+ if f(qelt(a, i)) then n := n+1
+ n
+
+ map_!(f, a) ==
+ for i in minIndex a .. maxIndex a repeat
+ qsetelt_!(a, i, f qelt(a, i))
+ a
+
+ setelt(a:%, s:UniversalSegment(Integer), x:S) ==
+ l := lo s; h := if hasHi s then hi s else maxIndex a
+ l < minIndex a or h > maxIndex a => error "index out of range"
+ for k in l..h repeat qsetelt_!(a, k, x)
+ x
+
+ reduce(f, a) ==
+ empty? a => error "cannot reduce an empty aggregate"
+ r := qelt(a, m := minIndex a)
+ for k in m+1 .. maxIndex a repeat r := f(r, qelt(a, k))
+ r
+
+ reduce(f, a, identity) ==
+ for k in minIndex a .. maxIndex a repeat
+ identity := f(identity, qelt(a, k))
+ identity
+
+ if S has SetCategory then
+ reduce(f, a, identity,absorber) ==
+ for k in minIndex a .. maxIndex a while identity ^= absorber
+ repeat identity := f(identity, qelt(a, k))
+ identity
+
+-- this is necessary since new has disappeared.
+ stupidnew: (NonNegativeInteger, %, %) -> %
+ stupidget: List % -> S
+-- a and b are not both empty if n > 0
+ stupidnew(n, a, b) ==
+ zero? n => empty()
+ new(n, (empty? a => qelt(b, minIndex b); qelt(a, minIndex a)))
+-- at least one element of l must be non-empty
+ stupidget l ==
+ for a in l repeat
+ not empty? a => return first a
+ error "Should not happen"
+
+ map(f, a, b) ==
+ m := max(minIndex a, minIndex b)
+ n := min(maxIndex a, maxIndex b)
+ l := max(0, n - m + 1)::NonNegativeInteger
+ c := stupidnew(l, a, b)
+ for i in minIndex(c).. for j in m..n repeat
+ qsetelt_!(c, i, f(qelt(a, j), qelt(b, j)))
+ c
+
+-- map(f, a, b, x) ==
+-- m := min(minIndex a, minIndex b)
+-- n := max(maxIndex a, maxIndex b)
+-- l := (n - m + 1)::NonNegativeInteger
+-- c := new l
+-- for i in minIndex(c).. for j in m..n repeat
+-- qsetelt_!(c, i, f(a(j, x), b(j, x)))
+-- c
+
+ merge(f, a, b) ==
+ r := stupidnew(#a + #b, a, b)
+ i := minIndex a
+ m := maxIndex a
+ j := minIndex b
+ n := maxIndex b
+ for k in minIndex(r).. while i <= m and j <= n repeat
+ if f(qelt(a, i), qelt(b, j)) then
+ qsetelt_!(r, k, qelt(a, i))
+ i := i+1
+ else
+ qsetelt_!(r, k, qelt(b, j))
+ j := j+1
+ for k in k.. for i in i..m repeat qsetelt_!(r, k, elt(a, i))
+ for k in k.. for j in j..n repeat qsetelt_!(r, k, elt(b, j))
+ r
+
+ elt(a:%, s:UniversalSegment(Integer)) ==
+ l := lo s
+ h := if hasHi s then hi s else maxIndex a
+ l < minIndex a or h > maxIndex a => error "index out of range"
+ r := stupidnew(max(0, h - l + 1)::NonNegativeInteger, a, a)
+ for k in minIndex r.. for i in l..h repeat
+ qsetelt_!(r, k, qelt(a, i))
+ r
+
+ insert(a:%, b:%, i:Integer) ==
+ m := minIndex b
+ n := maxIndex b
+ i < m or i > n => error "index out of range"
+ y := stupidnew(#a + #b, a, b)
+ for k in minIndex y.. for j in m..i-1 repeat
+ qsetelt_!(y, k, qelt(b, j))
+ for k in k.. for j in minIndex a .. maxIndex a repeat
+ qsetelt_!(y, k, qelt(a, j))
+ for k in k.. for j in i..n repeat qsetelt_!(y, k, qelt(b, j))
+ y
+
+ copy x ==
+ y := stupidnew(#x, x, x)
+ for i in minIndex x .. maxIndex x for j in minIndex y .. repeat
+ qsetelt_!(y, j, qelt(x, i))
+ y
+
+ copyInto_!(y, x, s) ==
+ s < minIndex y or s + #x > maxIndex y + 1 =>
+ error "index out of range"
+ for i in minIndex x .. maxIndex x for j in s.. repeat
+ qsetelt_!(y, j, qelt(x, i))
+ y
+
+ construct l ==
+-- a := new(#l)
+ empty? l => empty()
+ a := new(#l, first l)
+ for i in minIndex(a).. for x in l repeat qsetelt_!(a, i, x)
+ a
+
+ delete(a:%, s:UniversalSegment(Integer)) ==
+ l := lo s; h := if hasHi s then hi s else maxIndex a
+ l < minIndex a or h > maxIndex a => error "index out of range"
+ h < l => copy a
+ r := stupidnew((#a - h + l - 1)::NonNegativeInteger, a, a)
+ for k in minIndex(r).. for i in minIndex a..l-1 repeat
+ qsetelt_!(r, k, qelt(a, i))
+ for k in k.. for i in h+1 .. maxIndex a repeat
+ qsetelt_!(r, k, qelt(a, i))
+ r
+
+ delete(x:%, i:Integer) ==
+ i < minIndex x or i > maxIndex x => error "index out of range"
+ y := stupidnew((#x - 1)::NonNegativeInteger, x, x)
+ for i in minIndex(y).. for j in minIndex x..i-1 repeat
+ qsetelt_!(y, i, qelt(x, j))
+ for i in i .. for j in i+1 .. maxIndex x repeat
+ qsetelt_!(y, i, qelt(x, j))
+ y
+
+ reverse_! x ==
+ m := minIndex x
+ n := maxIndex x
+ for i in 0..((n-m) quo 2) repeat swap_!(x, m+i, n-i)
+ x
+
+ concat l ==
+ empty? l => empty()
+ n := _+/[#a for a in l]
+ i := minIndex(r := new(n, stupidget l))
+ for a in l repeat
+ copyInto_!(r, a, i)
+ i := i + #a
+ r
+
+ sorted?(f, a) ==
+ for i in minIndex(a)..maxIndex(a)-1 repeat
+ not f(qelt(a, i), qelt(a, i + 1)) => return false
+ true
+
+ concat(x:%, y:%) ==
+ z := stupidnew(#x + #y, x, y)
+ copyInto_!(z, x, i := minIndex z)
+ copyInto_!(z, y, i + #x)
+ z
+
+ if S has SetCategory then
+ x = y ==
+ #x ^= #y => false
+ for i in minIndex x .. maxIndex x repeat
+ not(qelt(x, i) = qelt(y, i)) => return false
+ true
+
+ coerce(r:%):OutputForm ==
+ bracket commaSeparate
+ [qelt(r, k)::OutputForm for k in minIndex r .. maxIndex r]
+
+ position(x:S, t:%, s:Integer) ==
+ n := maxIndex t
+ s < minIndex t or s > n => error "index out of range"
+ for k in s..n repeat
+ qelt(t, k) = x => return k
+ minIndex(t) - 1
+
+ if S has OrderedSet then
+ a < b ==
+ for i in minIndex a .. maxIndex a
+ for j in minIndex b .. maxIndex b repeat
+ qelt(a, i) ^= qelt(b, j) => return a.i < b.j
+ #a < #b
+
+
+@
+\section{category ELAGG ExtensibleLinearAggregate}
+<<category ELAGG ExtensibleLinearAggregate>>=
+)abbrev category ELAGG ExtensibleLinearAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An extensible aggregate is one which allows insertion and deletion of entries.
+++ These aggregates are models of lists and streams which are represented
+++ by linked structures so as to make insertion, deletion, and
+++ concatenation efficient. However, access to elements of these
+++ extensible aggregates is generally slow since access is made from the end.
+++ See \spadtype{FlexibleArray} for an exception.
+ExtensibleLinearAggregate(S:Type):Category == LinearAggregate S with
+ shallowlyMutable
+ concat_!: (%,S) -> %
+ ++ concat!(u,x) destructively adds element x to the end of u.
+ concat_!: (%,%) -> %
+ ++ concat!(u,v) destructively appends v to the end of u.
+ ++ v is unchanged
+ delete_!: (%,Integer) -> %
+ ++ delete!(u,i) destructively deletes the \axiom{i}th element of u.
+ delete_!: (%,UniversalSegment(Integer)) -> %
+ ++ delete!(u,i..j) destructively deletes elements u.i through u.j.
+ remove_!: (S->Boolean,%) -> %
+ ++ remove!(p,u) destructively removes all elements x of
+ ++ u such that \axiom{p(x)} is true.
+ insert_!: (S,%,Integer) -> %
+ ++ insert!(x,u,i) destructively inserts x into u at position i.
+ insert_!: (%,%,Integer) -> %
+ ++ insert!(v,u,i) destructively inserts aggregate v into u at position i.
+ merge_!: ((S,S)->Boolean,%,%) -> %
+ ++ merge!(p,u,v) destructively merges u and v using predicate p.
+ select_!: (S->Boolean,%) -> %
+ ++ select!(p,u) destructively changes u by keeping only values x such that
+ ++ \axiom{p(x)}.
+ if S has SetCategory then
+ remove_!: (S,%) -> %
+ ++ remove!(x,u) destructively removes all values x from u.
+ removeDuplicates_!: % -> %
+ ++ removeDuplicates!(u) destructively removes duplicates from u.
+ if S has OrderedSet then merge_!: (%,%) -> %
+ ++ merge!(u,v) destructively merges u and v in ascending order.
+ add
+ delete(x:%, i:Integer) == delete_!(copy x, i)
+ delete(x:%, i:UniversalSegment(Integer)) == delete_!(copy x, i)
+ remove(f:S -> Boolean, x:%) == remove_!(f, copy x)
+ insert(s:S, x:%, i:Integer) == insert_!(s, copy x, i)
+ insert(w:%, x:%, i:Integer) == insert_!(copy w, copy x, i)
+ select(f, x) == select_!(f, copy x)
+ concat(x:%, y:%) == concat_!(copy x, y)
+ concat(x:%, y:S) == concat_!(copy x, new(1, y))
+ concat_!(x:%, y:S) == concat_!(x, new(1, y))
+ if S has SetCategory then
+ remove(s:S, x:%) == remove_!(s, copy x)
+ remove_!(s:S, x:%) == remove_!(#1 = s, x)
+ removeDuplicates(x:%) == removeDuplicates_!(copy x)
+
+ if S has OrderedSet then
+ merge_!(x, y) == merge_!(_<$S, x, y)
+
+@
+\section{category LSAGG ListAggregate}
+<<category LSAGG ListAggregate>>=
+)abbrev category LSAGG ListAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A list aggregate is a model for a linked list data structure.
+++ A linked list is a versatile
+++ data structure. Insertion and deletion are efficient and
+++ searching is a linear operation.
+ListAggregate(S:Type): Category == Join(StreamAggregate S,
+ FiniteLinearAggregate S, ExtensibleLinearAggregate S) with
+ list: S -> %
+ ++ list(x) returns the list of one element x.
+ add
+ cycleMax ==> 1000
+
+ mergeSort: ((S, S) -> Boolean, %, Integer) -> %
+
+ sort_!(f, l) == mergeSort(f, l, #l)
+ list x == concat(x, empty())
+ reduce(f, x) ==
+ empty? x => error "reducing over an empty list needs the 3 argument form"
+ reduce(f, rest x, first x)
+ merge(f, p, q) == merge_!(f, copy p, copy q)
+
+ select_!(f, x) ==
+ while not empty? x and not f first x repeat x := rest x
+ empty? x => x
+ y := x
+ z := rest y
+ while not empty? z repeat
+ if f first z then (y := z; z := rest z)
+ else (z := rest z; setrest_!(y, z))
+ x
+
+ merge_!(f, p, q) ==
+ empty? p => q
+ empty? q => p
+ eq?(p, q) => error "cannot merge a list into itself"
+ if f(first p, first q)
+ then (r := t := p; p := rest p)
+ else (r := t := q; q := rest q)
+ while not empty? p and not empty? q repeat
+ if f(first p, first q)
+ then (setrest_!(t, p); t := p; p := rest p)
+ else (setrest_!(t, q); t := q; q := rest q)
+ setrest_!(t, if empty? p then q else p)
+ r
+
+ insert_!(s:S, x:%, i:Integer) ==
+ i < (m := minIndex x) => error "index out of range"
+ i = m => concat(s, x)
+ y := rest(x, (i - 1 - m)::NonNegativeInteger)
+ z := rest y
+ setrest_!(y, concat(s, z))
+ x
+
+ insert_!(w:%, x:%, i:Integer) ==
+ i < (m := minIndex x) => error "index out of range"
+ i = m => concat_!(w, x)
+ y := rest(x, (i - 1 - m)::NonNegativeInteger)
+ z := rest y
+ setrest_!(y, w)
+ concat_!(y, z)
+ x
+
+ remove_!(f:S -> Boolean, x:%) ==
+ while not empty? x and f first x repeat x := rest x
+ empty? x => x
+ p := x
+ q := rest x
+ while not empty? q repeat
+ if f first q then q := setrest_!(p, rest q)
+ else (p := q; q := rest q)
+ x
+
+ delete_!(x:%, i:Integer) ==
+ i < (m := minIndex x) => error "index out of range"
+ i = m => rest x
+ y := rest(x, (i - 1 - m)::NonNegativeInteger)
+ setrest_!(y, rest(y, 2))
+ x
+
+ delete_!(x:%, i:UniversalSegment(Integer)) ==
+ (l := lo i) < (m := minIndex x) => error "index out of range"
+ h := if hasHi i then hi i else maxIndex x
+ h < l => x
+ l = m => rest(x, (h + 1 - m)::NonNegativeInteger)
+ t := rest(x, (l - 1 - m)::NonNegativeInteger)
+ setrest_!(t, rest(t, (h - l + 2)::NonNegativeInteger))
+ x
+
+ find(f, x) ==
+ while not empty? x and not f first x repeat x := rest x
+ empty? x => "failed"
+ first x
+
+ position(f:S -> Boolean, x:%) ==
+ for k in minIndex(x).. while not empty? x and not f first x repeat
+ x := rest x
+ empty? x => minIndex(x) - 1
+ k
+
+ mergeSort(f, p, n) ==
+ if n = 2 and f(first rest p, first p) then p := reverse_! p
+ n < 3 => p
+ l := (n quo 2)::NonNegativeInteger
+ q := split_!(p, l)
+ p := mergeSort(f, p, l)
+ q := mergeSort(f, q, n - l)
+ merge_!(f, p, q)
+
+ sorted?(f, l) ==
+ empty? l => true
+ p := rest l
+ while not empty? p repeat
+ not f(first l, first p) => return false
+ p := rest(l := p)
+ true
+
+ reduce(f, x, i) ==
+ r := i
+ while not empty? x repeat (r := f(r, first x); x := rest x)
+ r
+
+ if S has SetCategory then
+ reduce(f, x, i,a) ==
+ r := i
+ while not empty? x and r ^= a repeat
+ r := f(r, first x)
+ x := rest x
+ r
+
+ new(n, s) ==
+ l := empty()
+ for k in 1..n repeat l := concat(s, l)
+ l
+
+ map(f, x, y) ==
+ z := empty()
+ while not empty? x and not empty? y repeat
+ z := concat(f(first x, first y), z)
+ x := rest x
+ y := rest y
+ reverse_! z
+
+-- map(f, x, y, d) ==
+-- z := empty()
+-- while not empty? x and not empty? y repeat
+-- z := concat(f(first x, first y), z)
+-- x := rest x
+-- y := rest y
+-- z := reverseInPlace z
+-- if not empty? x then
+-- z := concat_!(z, map(f(#1, d), x))
+-- if not empty? y then
+-- z := concat_!(z, map(f(d, #1), y))
+-- z
+
+ reverse_! x ==
+ empty? x => x
+ empty?(y := rest x) => x
+ setrest_!(x, empty())
+ while not empty? y repeat
+ z := rest y
+ setrest_!(y, x)
+ x := y
+ y := z
+ x
+
+ copy x ==
+ y := empty()
+ for k in 0.. while not empty? x repeat
+ k = cycleMax and cyclic? x => error "cyclic list"
+ y := concat(first x, y)
+ x := rest x
+ reverse_! y
+
+ copyInto_!(y, x, s) ==
+ s < (m := minIndex y) => error "index out of range"
+ z := rest(y, (s - m)::NonNegativeInteger)
+ while not empty? z and not empty? x repeat
+ setfirst_!(z, first x)
+ x := rest x
+ z := rest z
+ y
+
+ if S has SetCategory then
+ position(w, x, s) ==
+ s < (m := minIndex x) => error "index out of range"
+ x := rest(x, (s - m)::NonNegativeInteger)
+ for k in s.. while not empty? x and w ^= first x repeat
+ x := rest x
+ empty? x => minIndex x - 1
+ k
+
+ removeDuplicates_! l ==
+ p := l
+ while not empty? p repeat
+ p := setrest_!(p, remove_!(#1 = first p, rest p))
+ l
+
+ if S has OrderedSet then
+ x < y ==
+ while not empty? x and not empty? y repeat
+ first x ^= first y => return(first x < first y)
+ x := rest x
+ y := rest y
+ empty? x => not empty? y
+ false
+
+@
+\section{LSAGG.lsp BOOTSTRAP}
+{\bf LSAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf LSAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf LSAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LSAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |ListAggregate;CAT| (QUOTE NIL))
+
+(SETQ |ListAggregate;AL| (QUOTE NIL))
+
+(DEFUN |ListAggregate| (#1=#:G87500) (LET (#2=#:G87501) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |ListAggregate;AL|)) (CDR #2#)) (T (SETQ |ListAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|ListAggregate;| #1#))) |ListAggregate;AL|)) #2#))))
+
+(DEFUN |ListAggregate;| (|t#1|) (PROG (#1=#:G87499) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|ListAggregate;CAT|) ((QUOTE T) (LETT |ListAggregate;CAT| (|Join| (|StreamAggregate| (QUOTE |t#1|)) (|FiniteLinearAggregate| (QUOTE |t#1|)) (|ExtensibleLinearAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|list| (|$| |t#1|)) T))) NIL (QUOTE NIL) NIL)) . #2=(|ListAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |ListAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{LSAGG-.lsp BOOTSTRAP}
+{\bf LSAGG-} depends on {\bf LSAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf LSAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf LSAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LSAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |LSAGG-;sort!;M2A;1| (|f| |l| |$|) (|LSAGG-;mergeSort| |f| |l| (SPADCALL |l| (QREFELT |$| 9)) |$|))
+
+(DEFUN |LSAGG-;list;SA;2| (|x| |$|) (SPADCALL |x| (SPADCALL (QREFELT |$| 12)) (QREFELT |$| 13)))
+
+(DEFUN |LSAGG-;reduce;MAS;3| (|f| |x| |$|) (COND ((SPADCALL |x| (QREFELT |$| 16)) (|error| "reducing over an empty list needs the 3 argument form")) ((QUOTE T) (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 17)) (SPADCALL |x| (QREFELT |$| 18)) (QREFELT |$| 20)))))
+
+(DEFUN |LSAGG-;merge;M3A;4| (|f| |p| |q| |$|) (SPADCALL |f| (SPADCALL |p| (QREFELT |$| 22)) (SPADCALL |q| (QREFELT |$| 22)) (QREFELT |$| 23)))
+
+(DEFUN |LSAGG-;select!;M2A;5| (|f| |x| |$|) (PROG (|y| |z|) (RETURN (SEQ (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |f|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;select!;M2A;5|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) |x|) ((QUOTE T) (SEQ (LETT |y| |x| |LSAGG-;select!;M2A;5|) (LETT |z| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;select!;M2A;5|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |z| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (SPADCALL |z| (QREFELT |$| 18)) |f|) (SEQ (LETT |y| |z| |LSAGG-;select!;M2A;5|) (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 17)) |LSAGG-;select!;M2A;5|)))) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |z| (QREFELT |$| 17)) |LSAGG-;select!;M2A;5|) (EXIT (SPADCALL |y| |z| (QREFELT |$| 25)))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;merge!;M3A;6| (|f| |p| |q| |$|) (PROG (|r| |t|) (RETURN (SEQ (COND ((SPADCALL |p| (QREFELT |$| 16)) |q|) ((SPADCALL |q| (QREFELT |$| 16)) |p|) ((SPADCALL |p| |q| (QREFELT |$| 28)) (|error| "cannot merge a list into itself")) ((QUOTE T) (SEQ (COND ((SPADCALL (SPADCALL |p| (QREFELT |$| 18)) (SPADCALL |q| (QREFELT |$| 18)) |f|) (SEQ (LETT |r| (LETT |t| |p| |LSAGG-;merge!;M3A;6|) |LSAGG-;merge!;M3A;6|) (EXIT (LETT |p| (SPADCALL |p| (QREFELT |$| 17)) |LSAGG-;merge!;M3A;6|)))) ((QUOTE T) (SEQ (LETT |r| (LETT |t| |q| |LSAGG-;merge!;M3A;6|) |LSAGG-;merge!;M3A;6|) (EXIT (LETT |q| (SPADCALL |q| (QREFELT |$| 17)) |LSAGG-;merge!;M3A;6|))))) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |p| (QREFELT |$| 16)) (SPADCALL |q| (QREFELT |$| 16))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (SPADCALL |p| (QREFELT |$| 18)) (SPADCALL |q| (QREFELT |$| 18)) |f|) (SEQ (SPADCALL |t| |p| (QREFELT |$| 25)) (LETT |t| |p| |LSAGG-;merge!;M3A;6|) (EXIT (LETT |p| (SPADCALL |p| (QREFELT |$| 17)) |LSAGG-;merge!;M3A;6|)))) ((QUOTE T) (SEQ (SPADCALL |t| |q| (QREFELT |$| 25)) (LETT |t| |q| |LSAGG-;merge!;M3A;6|) (EXIT (LETT |q| (SPADCALL |q| (QREFELT |$| 17)) |LSAGG-;merge!;M3A;6|))))))) NIL (GO G190) G191 (EXIT NIL)) (SPADCALL |t| (COND ((SPADCALL |p| (QREFELT |$| 16)) |q|) ((QUOTE T) |p|)) (QREFELT |$| 25)) (EXIT |r|))))))))
+
+(DEFUN |LSAGG-;insert!;SAIA;7| (|s| |x| |i| |$|) (PROG (|m| #1=#:G87547 |y| |z|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;insert!;SAIA;7|) (EXIT (COND ((|<| |i| |m|) (|error| "index out of range")) ((EQL |i| |m|) (SPADCALL |s| |x| (QREFELT |$| 13))) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (PROG1 (LETT #1# (|-| (|-| |i| 1) |m|) |LSAGG-;insert!;SAIA;7|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;insert!;SAIA;7|) (LETT |z| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;insert!;SAIA;7|) (SPADCALL |y| (SPADCALL |s| |z| (QREFELT |$| 13)) (QREFELT |$| 25)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;insert!;2AIA;8| (|w| |x| |i| |$|) (PROG (|m| #1=#:G87551 |y| |z|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;insert!;2AIA;8|) (EXIT (COND ((|<| |i| |m|) (|error| "index out of range")) ((EQL |i| |m|) (SPADCALL |w| |x| (QREFELT |$| 34))) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (PROG1 (LETT #1# (|-| (|-| |i| 1) |m|) |LSAGG-;insert!;2AIA;8|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;insert!;2AIA;8|) (LETT |z| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;insert!;2AIA;8|) (SPADCALL |y| |w| (QREFELT |$| 25)) (SPADCALL |y| |z| (QREFELT |$| 34)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;remove!;M2A;9| (|f| |x| |$|) (PROG (|p| |q|) (RETURN (SEQ (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |f|)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;remove!;M2A;9|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) |x|) ((QUOTE T) (SEQ (LETT |p| |x| |LSAGG-;remove!;M2A;9|) (LETT |q| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;remove!;M2A;9|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |q| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (SPADCALL |q| (QREFELT |$| 18)) |f|) (LETT |q| (SPADCALL |p| (SPADCALL |q| (QREFELT |$| 17)) (QREFELT |$| 25)) |LSAGG-;remove!;M2A;9|)) ((QUOTE T) (SEQ (LETT |p| |q| |LSAGG-;remove!;M2A;9|) (EXIT (LETT |q| (SPADCALL |q| (QREFELT |$| 17)) |LSAGG-;remove!;M2A;9|))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;delete!;AIA;10| (|x| |i| |$|) (PROG (|m| #1=#:G87564 |y|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;delete!;AIA;10|) (EXIT (COND ((|<| |i| |m|) (|error| "index out of range")) ((EQL |i| |m|) (SPADCALL |x| (QREFELT |$| 17))) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (PROG1 (LETT #1# (|-| (|-| |i| 1) |m|) |LSAGG-;delete!;AIA;10|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;delete!;AIA;10|) (SPADCALL |y| (SPADCALL |y| 2 (QREFELT |$| 32)) (QREFELT |$| 25)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;delete!;AUsA;11| (|x| |i| |$|) (PROG (|l| |m| |h| #1=#:G87569 #2=#:G87570 |t| #3=#:G87571) (RETURN (SEQ (LETT |l| (SPADCALL |i| (QREFELT |$| 39)) |LSAGG-;delete!;AUsA;11|) (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;delete!;AUsA;11|) (EXIT (COND ((|<| |l| |m|) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |h| (COND ((SPADCALL |i| (QREFELT |$| 40)) (SPADCALL |i| (QREFELT |$| 41))) ((QUOTE T) (SPADCALL |x| (QREFELT |$| 42)))) |LSAGG-;delete!;AUsA;11|) (EXIT (COND ((|<| |h| |l|) |x|) ((EQL |l| |m|) (SPADCALL |x| (PROG1 (LETT #1# (|-| (|+| |h| 1) |m|) |LSAGG-;delete!;AUsA;11|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32))) ((QUOTE T) (SEQ (LETT |t| (SPADCALL |x| (PROG1 (LETT #2# (|-| (|-| |l| 1) |m|) |LSAGG-;delete!;AUsA;11|) (|check-subtype| (|>=| #2# 0) (QUOTE (|NonNegativeInteger|)) #2#)) (QREFELT |$| 32)) |LSAGG-;delete!;AUsA;11|) (SPADCALL |t| (SPADCALL |t| (PROG1 (LETT #3# (|+| (|-| |h| |l|) 2) |LSAGG-;delete!;AUsA;11|) (|check-subtype| (|>=| #3# 0) (QUOTE (|NonNegativeInteger|)) #3#)) (QREFELT |$| 32)) (QREFELT |$| 25)) (EXIT |x|)))))))))))))
+
+(DEFUN |LSAGG-;find;MAU;12| (|f| |x| |$|) (SEQ (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |f|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;find;MAU;12|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) (CONS 1 "failed")) ((QUOTE T) (CONS 0 (SPADCALL |x| (QREFELT |$| 18))))))))
+
+(DEFUN |LSAGG-;position;MAI;13| (|f| |x| |$|) (PROG (|k|) (RETURN (SEQ (SEQ (LETT |k| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;position;MAI;13|) G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |f|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;position;MAI;13|))) (LETT |k| (|+| |k| 1) |LSAGG-;position;MAI;13|) (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) (|-| (SPADCALL |x| (QREFELT |$| 31)) 1)) ((QUOTE T) |k|)))))))
+
+(DEFUN |LSAGG-;mergeSort| (|f| |p| |n| |$|) (PROG (#1=#:G87593 |l| |q|) (RETURN (SEQ (COND ((EQL |n| 2) (COND ((SPADCALL (SPADCALL (SPADCALL |p| (QREFELT |$| 17)) (QREFELT |$| 18)) (SPADCALL |p| (QREFELT |$| 18)) |f|) (LETT |p| (SPADCALL |p| (QREFELT |$| 47)) |LSAGG-;mergeSort|))))) (EXIT (COND ((|<| |n| 3) |p|) ((QUOTE T) (SEQ (LETT |l| (PROG1 (LETT #1# (QUOTIENT2 |n| 2) |LSAGG-;mergeSort|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) |LSAGG-;mergeSort|) (LETT |q| (SPADCALL |p| |l| (QREFELT |$| 48)) |LSAGG-;mergeSort|) (LETT |p| (|LSAGG-;mergeSort| |f| |p| |l| |$|) |LSAGG-;mergeSort|) (LETT |q| (|LSAGG-;mergeSort| |f| |q| (|-| |n| |l|) |$|) |LSAGG-;mergeSort|) (EXIT (SPADCALL |f| |p| |q| (QREFELT |$| 23)))))))))))
+
+(DEFUN |LSAGG-;sorted?;MAB;15| (|f| |l| |$|) (PROG (#1=#:G87603 |p|) (RETURN (SEQ (EXIT (COND ((SPADCALL |l| (QREFELT |$| 16)) (QUOTE T)) ((QUOTE T) (SEQ (LETT |p| (SPADCALL |l| (QREFELT |$| 17)) |LSAGG-;sorted?;MAB;15|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |p| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((NULL (SPADCALL (SPADCALL |l| (QREFELT |$| 18)) (SPADCALL |p| (QREFELT |$| 18)) |f|)) (PROGN (LETT #1# (QUOTE NIL) |LSAGG-;sorted?;MAB;15|) (GO #1#))) ((QUOTE T) (LETT |p| (SPADCALL (LETT |l| |p| |LSAGG-;sorted?;MAB;15|) (QREFELT |$| 17)) |LSAGG-;sorted?;MAB;15|))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (QUOTE T)))))) #1# (EXIT #1#)))))
+
+(DEFUN |LSAGG-;reduce;MA2S;16| (|f| |x| |i| |$|) (PROG (|r|) (RETURN (SEQ (LETT |r| |i| |LSAGG-;reduce;MA2S;16|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |r| (SPADCALL |r| (SPADCALL |x| (QREFELT |$| 18)) |f|) |LSAGG-;reduce;MA2S;16|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;reduce;MA2S;16|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |r|)))))
+
+(DEFUN |LSAGG-;reduce;MA3S;17| (|f| |x| |i| |a| |$|) (PROG (|r|) (RETURN (SEQ (LETT |r| |i| |LSAGG-;reduce;MA3S;17|) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL |r| |a| (QREFELT |$| 51))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |r| (SPADCALL |r| (SPADCALL |x| (QREFELT |$| 18)) |f|) |LSAGG-;reduce;MA3S;17|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;reduce;MA3S;17|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |r|)))))
+
+(DEFUN |LSAGG-;new;NniSA;18| (|n| |s| |$|) (PROG (|k| |l|) (RETURN (SEQ (LETT |l| (SPADCALL (QREFELT |$| 12)) |LSAGG-;new;NniSA;18|) (SEQ (LETT |k| 1 |LSAGG-;new;NniSA;18|) G190 (COND ((QSGREATERP |k| |n|) (GO G191))) (SEQ (EXIT (LETT |l| (SPADCALL |s| |l| (QREFELT |$| 13)) |LSAGG-;new;NniSA;18|))) (LETT |k| (QSADD1 |k|) |LSAGG-;new;NniSA;18|) (GO G190) G191 (EXIT NIL)) (EXIT |l|)))))
+
+(DEFUN |LSAGG-;map;M3A;19| (|f| |x| |y| |$|) (PROG (|z|) (RETURN (SEQ (LETT |z| (SPADCALL (QREFELT |$| 12)) |LSAGG-;map;M3A;19|) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL |y| (QREFELT |$| 16))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |z| (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) (SPADCALL |y| (QREFELT |$| 18)) |f|) |z| (QREFELT |$| 13)) |LSAGG-;map;M3A;19|) (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;map;M3A;19|) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;map;M3A;19|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |z| (QREFELT |$| 47)))))))
+
+(DEFUN |LSAGG-;reverse!;2A;20| (|x| |$|) (PROG (|z| |y|) (RETURN (SEQ (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL (LETT |y| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;reverse!;2A;20|) (QREFELT |$| 16))) |x|) ((QUOTE T) (SEQ (SPADCALL |x| (SPADCALL (QREFELT |$| 12)) (QREFELT |$| 25)) (SEQ G190 (COND ((NULL (COND ((SPADCALL |y| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |z| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;reverse!;2A;20|) (SPADCALL |y| |x| (QREFELT |$| 25)) (LETT |x| |y| |LSAGG-;reverse!;2A;20|) (EXIT (LETT |y| |z| |LSAGG-;reverse!;2A;20|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|))))))))
+
+(DEFUN |LSAGG-;copy;2A;21| (|x| |$|) (PROG (|k| |y|) (RETURN (SEQ (LETT |y| (SPADCALL (QREFELT |$| 12)) |LSAGG-;copy;2A;21|) (SEQ (LETT |k| 0 |LSAGG-;copy;2A;21|) G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |x| (QREFELT |$| 56)) (EXIT (|error| "cyclic list")))))) (LETT |y| (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |y| (QREFELT |$| 13)) |LSAGG-;copy;2A;21|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;copy;2A;21|))) (LETT |k| (QSADD1 |k|) |LSAGG-;copy;2A;21|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |y| (QREFELT |$| 47)))))))
+
+(DEFUN |LSAGG-;copyInto!;2AIA;22| (|y| |x| |s| |$|) (PROG (|m| #1=#:G87636 |z|) (RETURN (SEQ (LETT |m| (SPADCALL |y| (QREFELT |$| 31)) |LSAGG-;copyInto!;2AIA;22|) (EXIT (COND ((|<| |s| |m|) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |y| (PROG1 (LETT #1# (|-| |s| |m|) |LSAGG-;copyInto!;2AIA;22|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;copyInto!;2AIA;22|) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |z| (QREFELT |$| 16)) (SPADCALL |x| (QREFELT |$| 16))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |z| (SPADCALL |x| (QREFELT |$| 18)) (QREFELT |$| 58)) (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;copyInto!;2AIA;22|) (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 17)) |LSAGG-;copyInto!;2AIA;22|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |y|)))))))))
+
+(DEFUN |LSAGG-;position;SA2I;23| (|w| |x| |s| |$|) (PROG (|m| #1=#:G87644 |k|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;position;SA2I;23|) (EXIT (COND ((|<| |s| |m|) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |x| (SPADCALL |x| (PROG1 (LETT #1# (|-| |s| |m|) |LSAGG-;position;SA2I;23|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;position;SA2I;23|) (SEQ (LETT |k| |s| |LSAGG-;position;SA2I;23|) G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL |w| (SPADCALL |x| (QREFELT |$| 18)) (QREFELT |$| 51))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;position;SA2I;23|))) (LETT |k| (|+| |k| 1) |LSAGG-;position;SA2I;23|) (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) (|-| (SPADCALL |x| (QREFELT |$| 31)) 1)) ((QUOTE T) |k|)))))))))))
+
+(DEFUN |LSAGG-;removeDuplicates!;2A;24| (|l| |$|) (PROG (|p|) (RETURN (SEQ (LETT |p| |l| |LSAGG-;removeDuplicates!;2A;24|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |p| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |p| (SPADCALL |p| (SPADCALL (CONS (FUNCTION |LSAGG-;removeDuplicates!;2A;24!0|) (VECTOR |$| |p|)) (SPADCALL |p| (QREFELT |$| 17)) (QREFELT |$| 61)) (QREFELT |$| 25)) |LSAGG-;removeDuplicates!;2A;24|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |l|)))))
+
+(DEFUN |LSAGG-;removeDuplicates!;2A;24!0| (|#1| |$$|) (PROG (|$|) (LETT |$| (QREFELT |$$| 0) |LSAGG-;removeDuplicates!;2A;24|) (RETURN (PROGN (SPADCALL |#1| (SPADCALL (QREFELT |$$| 1) (QREFELT |$| 18)) (QREFELT |$| 51))))))
+
+(DEFUN |LSAGG-;<;2AB;25| (|x| |y| |$|) (PROG (#1=#:G87662) (RETURN (SEQ (EXIT (SEQ (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL |y| (QREFELT |$| 16))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((NULL (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) (SPADCALL |y| (QREFELT |$| 18)) (QREFELT |$| 51))) (PROGN (LETT #1# (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) (SPADCALL |y| (QREFELT |$| 18)) (QREFELT |$| 63)) |LSAGG-;<;2AB;25|) (GO #1#))) ((QUOTE T) (SEQ (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;<;2AB;25|) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;<;2AB;25|))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) (COND ((SPADCALL |y| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) ((QUOTE T) (QUOTE NIL)))))) #1# (EXIT #1#)))))
+
+(DEFUN |ListAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|ListAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |ListAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 66) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|HasCategory| |#2| (QUOTE (|SetCategory|))) (QSETREFV |$| 52 (CONS (|dispatchFunction| |LSAGG-;reduce;MA3S;17|) |$|)))) (COND ((|HasCategory| |#2| (QUOTE (|SetCategory|))) (PROGN (QSETREFV |$| 60 (CONS (|dispatchFunction| |LSAGG-;position;SA2I;23|) |$|)) (QSETREFV |$| 62 (CONS (|dispatchFunction| |LSAGG-;removeDuplicates!;2A;24|) |$|))))) (COND ((|HasCategory| |#2| (QUOTE (|OrderedSet|))) (QSETREFV |$| 64 (CONS (|dispatchFunction| |LSAGG-;<;2AB;25|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |ListAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|NonNegativeInteger|) (0 . |#|) (|Mapping| 15 7 7) |LSAGG-;sort!;M2A;1| (5 . |empty|) (9 . |concat|) |LSAGG-;list;SA;2| (|Boolean|) (15 . |empty?|) (20 . |rest|) (25 . |first|) (|Mapping| 7 7 7) (30 . |reduce|) |LSAGG-;reduce;MAS;3| (37 . |copy|) (42 . |merge!|) |LSAGG-;merge;M3A;4| (49 . |setrest!|) (|Mapping| 15 7) |LSAGG-;select!;M2A;5| (55 . |eq?|) |LSAGG-;merge!;M3A;6| (|Integer|) (61 . |minIndex|) (66 . |rest|) |LSAGG-;insert!;SAIA;7| (72 . |concat!|) |LSAGG-;insert!;2AIA;8| |LSAGG-;remove!;M2A;9| |LSAGG-;delete!;AIA;10| (|UniversalSegment| 30) (78 . |lo|) (83 . |hasHi|) (88 . |hi|) (93 . |maxIndex|) |LSAGG-;delete!;AUsA;11| (|Union| 7 (QUOTE "failed")) |LSAGG-;find;MAU;12| |LSAGG-;position;MAI;13| (98 . |reverse!|) (103 . |split!|) |LSAGG-;sorted?;MAB;15| |LSAGG-;reduce;MA2S;16| (109 . |=|) (115 . |reduce|) |LSAGG-;new;NniSA;18| |LSAGG-;map;M3A;19| |LSAGG-;reverse!;2A;20| (123 . |cyclic?|) |LSAGG-;copy;2A;21| (128 . |setfirst!|) |LSAGG-;copyInto!;2AIA;22| (134 . |position|) (141 . |remove!|) (147 . |removeDuplicates!|) (152 . |<|) (158 . |<|) (|Mapping| 7 7))) (QUOTE #(|sorted?| 164 |sort!| 170 |select!| 176 |reverse!| 182 |removeDuplicates!| 187 |remove!| 192 |reduce| 198 |position| 219 |new| 232 |merge!| 238 |merge| 245 |map| 252 |list| 259 |insert!| 264 |find| 278 |delete!| 284 |copyInto!| 296 |copy| 303 |<| 308)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 64 (QUOTE (1 6 8 0 9 0 6 0 12 2 6 0 7 0 13 1 6 15 0 16 1 6 0 0 17 1 6 7 0 18 3 6 7 19 0 7 20 1 6 0 0 22 3 6 0 10 0 0 23 2 6 0 0 0 25 2 6 15 0 0 28 1 6 30 0 31 2 6 0 0 8 32 2 6 0 0 0 34 1 38 30 0 39 1 38 15 0 40 1 38 30 0 41 1 6 30 0 42 1 6 0 0 47 2 6 0 0 30 48 2 7 15 0 0 51 4 0 7 19 0 7 7 52 1 6 15 0 56 2 6 7 0 7 58 3 0 30 7 0 30 60 2 6 0 26 0 61 1 0 0 0 62 2 7 15 0 0 63 2 0 15 0 0 64 2 0 15 10 0 49 2 0 0 10 0 11 2 0 0 26 0 27 1 0 0 0 55 1 0 0 0 62 2 0 0 26 0 36 3 0 7 19 0 7 50 4 0 7 19 0 7 7 52 2 0 7 19 0 21 2 0 30 26 0 46 3 0 30 7 0 30 60 2 0 0 8 7 53 3 0 0 10 0 0 29 3 0 0 10 0 0 24 3 0 0 19 0 0 54 1 0 0 7 14 3 0 0 7 0 30 33 3 0 0 0 0 30 35 2 0 44 26 0 45 2 0 0 0 38 43 2 0 0 0 30 37 3 0 0 0 0 30 59 1 0 0 0 57 2 0 15 0 0 64)))))) (QUOTE |lookupComplete|)))
+@
+\section{category ALAGG AssociationListAggregate}
+<<category ALAGG AssociationListAggregate>>=
+)abbrev category ALAGG AssociationListAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An association list is a list of key entry pairs which may be viewed
+++ as a table. It is a poor mans version of a table:
+++ searching for a key is a linear operation.
+AssociationListAggregate(Key:SetCategory,Entry:SetCategory): Category ==
+ Join(TableAggregate(Key, Entry), ListAggregate Record(key:Key,entry:Entry)) with
+ assoc: (Key, %) -> Union(Record(key:Key,entry:Entry), "failed")
+ ++ assoc(k,u) returns the element x in association list u stored
+ ++ with key k, or "failed" if u has no key k.
+
+@
+\section{ALAGG.lsp BOOTSTRAP}
+{\bf ALAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ALAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ALAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ALAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |AssociationListAggregate;CAT| (QUOTE NIL))
+
+(SETQ |AssociationListAggregate;AL| (QUOTE NIL))
+
+(DEFUN |AssociationListAggregate| (|&REST| #1=#:G88404 |&AUX| #2=#:G88402) (DSETQ #2# #1#) (LET (#3=#:G88403) (COND ((SETQ #3# (|assoc| (|devaluateList| #2#) |AssociationListAggregate;AL|)) (CDR #3#)) (T (SETQ |AssociationListAggregate;AL| (|cons5| (CONS (|devaluateList| #2#) (SETQ #3# (APPLY (FUNCTION |AssociationListAggregate;|) #2#))) |AssociationListAggregate;AL|)) #3#))))
+
+(DEFUN |AssociationListAggregate;| (|t#1| |t#2|) (PROG (#1=#:G88401) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1| |t#2|)) (LIST (|devaluate| |t#1|) (|devaluate| |t#2|))) (|sublisV| (PAIR (QUOTE (#2=#:G88400)) (LIST (QUOTE (|Record| (|:| |key| |t#1|) (|:| |entry| |t#2|))))) (COND (|AssociationListAggregate;CAT|) ((QUOTE T) (LETT |AssociationListAggregate;CAT| (|Join| (|TableAggregate| (QUOTE |t#1|) (QUOTE |t#2|)) (|ListAggregate| (QUOTE #2#)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|assoc| ((|Union| (|Record| (|:| |key| |t#1|) (|:| |entry| |t#2|)) "failed") |t#1| |$|)) T))) NIL (QUOTE NIL) NIL)) . #3=(|AssociationListAggregate|)))))) . #3#) (SETELT #1# 0 (LIST (QUOTE |AssociationListAggregate|) (|devaluate| |t#1|) (|devaluate| |t#2|)))))))
+@
+\section{category SRAGG StringAggregate}
+<<category SRAGG StringAggregate>>=
+)abbrev category SRAGG StringAggregate
+++ Author: Stephen Watt and Michael Monagan. revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A string aggregate is a category for strings, that is,
+++ one dimensional arrays of characters.
+StringAggregate: Category == OneDimensionalArrayAggregate Character with
+ lowerCase : % -> %
+ ++ lowerCase(s) returns the string with all characters in lower case.
+ lowerCase_!: % -> %
+ ++ lowerCase!(s) destructively replaces the alphabetic characters
+ ++ in s by lower case.
+ upperCase : % -> %
+ ++ upperCase(s) returns the string with all characters in upper case.
+ upperCase_!: % -> %
+ ++ upperCase!(s) destructively replaces the alphabetic characters
+ ++ in s by upper case characters.
+ prefix? : (%, %) -> Boolean
+ ++ prefix?(s,t) tests if the string s is the initial substring of t.
+ ++ Note: \axiom{prefix?(s,t) == reduce(and,[s.i = t.i for i in 0..maxIndex s])}.
+ suffix? : (%, %) -> Boolean
+ ++ suffix?(s,t) tests if the string s is the final substring of t.
+ ++ Note: \axiom{suffix?(s,t) == reduce(and,[s.i = t.(n - m + i) for i in 0..maxIndex s])}
+ ++ where m and n denote the maxIndex of s and t respectively.
+ substring?: (%, %, Integer) -> Boolean
+ ++ substring?(s,t,i) tests if s is a substring of t beginning at
+ ++ index i.
+ ++ Note: \axiom{substring?(s,t,0) = prefix?(s,t)}.
+ match: (%, %, Character) -> NonNegativeInteger
+ ++ match(p,s,wc) tests if pattern \axiom{p} matches subject \axiom{s}
+ ++ where \axiom{wc} is a wild card character. If no match occurs,
+ ++ the index \axiom{0} is returned; otheriwse, the value returned
+ ++ is the first index of the first character in the subject matching
+ ++ the subject (excluding that matched by an initial wild-card).
+ ++ For example, \axiom{match("*to*","yorktown","*")} returns \axiom{5}
+ ++ indicating a successful match starting at index \axiom{5} of
+ ++ \axiom{"yorktown"}.
+ match?: (%, %, Character) -> Boolean
+ ++ match?(s,t,c) tests if s matches t except perhaps for
+ ++ multiple and consecutive occurrences of character c.
+ ++ Typically c is the blank character.
+ replace : (%, UniversalSegment(Integer), %) -> %
+ ++ replace(s,i..j,t) replaces the substring \axiom{s(i..j)} of s by string t.
+ position : (%, %, Integer) -> Integer
+ ++ position(s,t,i) returns the position j of the substring s in string t,
+ ++ where \axiom{j >= i} is required.
+ position : (CharacterClass, %, Integer) -> Integer
+ ++ position(cc,t,i) returns the position \axiom{j >= i} in t of
+ ++ the first character belonging to cc.
+ coerce : Character -> %
+ ++ coerce(c) returns c as a string s with the character c.
+
+ split: (%, Character) -> List %
+ ++ split(s,c) returns a list of substrings delimited by character c.
+ split: (%, CharacterClass) -> List %
+ ++ split(s,cc) returns a list of substrings delimited by characters in cc.
+
+ trim: (%, Character) -> %
+ ++ trim(s,c) returns s with all characters c deleted from right
+ ++ and left ends.
+ ++ For example, \axiom{trim(" abc ", char " ")} returns \axiom{"abc"}.
+ trim: (%, CharacterClass) -> %
+ ++ trim(s,cc) returns s with all characters in cc deleted from right
+ ++ and left ends.
+ ++ For example, \axiom{trim("(abc)", charClass "()")} returns \axiom{"abc"}.
+ leftTrim: (%, Character) -> %
+ ++ leftTrim(s,c) returns s with all leading characters c deleted.
+ ++ For example, \axiom{leftTrim(" abc ", char " ")} returns \axiom{"abc "}.
+ leftTrim: (%, CharacterClass) -> %
+ ++ leftTrim(s,cc) returns s with all leading characters in cc deleted.
+ ++ For example, \axiom{leftTrim("(abc)", charClass "()")} returns \axiom{"abc)"}.
+ rightTrim: (%, Character) -> %
+ ++ rightTrim(s,c) returns s with all trailing occurrences of c deleted.
+ ++ For example, \axiom{rightTrim(" abc ", char " ")} returns \axiom{" abc"}.
+ rightTrim: (%, CharacterClass) -> %
+ ++ rightTrim(s,cc) returns s with all trailing occurences of
+ ++ characters in cc deleted.
+ ++ For example, \axiom{rightTrim("(abc)", charClass "()")} returns \axiom{"(abc"}.
+ elt: (%, %) -> %
+ ++ elt(s,t) returns the concatenation of s and t. It is provided to
+ ++ allow juxtaposition of strings to work as concatenation.
+ ++ For example, \axiom{"smoo" "shed"} returns \axiom{"smooshed"}.
+ add
+ trim(s: %, c: Character) == leftTrim(rightTrim(s, c), c)
+ trim(s: %, cc: CharacterClass) == leftTrim(rightTrim(s, cc), cc)
+
+ lowerCase s == lowerCase_! copy s
+ upperCase s == upperCase_! copy s
+ prefix?(s, t) == substring?(s, t, minIndex t)
+ coerce(c:Character):% == new(1, c)
+ elt(s:%, t:%): % == concat(s,t)$%
+
+@
+\section{category BTAGG BitAggregate}
+<<category BTAGG BitAggregate>>=
+)abbrev category BTAGG BitAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The bit aggregate category models aggregates representing large
+++ quantities of Boolean data.
+BitAggregate(): Category ==
+ Join(OrderedSet, Logic, OneDimensionalArrayAggregate Boolean) with
+ "not": % -> %
+ ++ not(b) returns the logical {\em not} of bit aggregate
+ ++ \axiom{b}.
+ "^" : % -> %
+ ++ ^ b returns the logical {\em not} of bit aggregate
+ ++ \axiom{b}.
+ nand : (%, %) -> %
+ ++ nand(a,b) returns the logical {\em nand} of bit aggregates \axiom{a}
+ ++ and \axiom{b}.
+ nor : (%, %) -> %
+ ++ nor(a,b) returns the logical {\em nor} of bit aggregates \axiom{a} and
+ ++ \axiom{b}.
+ _and : (%, %) -> %
+ ++ a and b returns the logical {\em and} of bit aggregates \axiom{a} and
+ ++ \axiom{b}.
+ _or : (%, %) -> %
+ ++ a or b returns the logical {\em or} of bit aggregates \axiom{a} and
+ ++ \axiom{b}.
+ xor : (%, %) -> %
+ ++ xor(a,b) returns the logical {\em exclusive-or} of bit aggregates
+ ++ \axiom{a} and \axiom{b}.
+
+ add
+ not v == map(_not, v)
+ _^ v == map(_not, v)
+ _~(v) == map(_~, v)
+ _/_\(v, u) == map(_/_\, v, u)
+ _\_/(v, u) == map(_\_/, v, u)
+ nand(v, u) == map(nand, v, u)
+ nor(v, u) == map(nor, v, u)
+
+@
+\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 AGG Aggregate>>
+<<category HOAGG HomogeneousAggregate>>
+<<category CLAGG Collection>>
+<<category BGAGG BagAggregate>>
+<<category SKAGG StackAggregate>>
+<<category QUAGG QueueAggregate>>
+<<category DQAGG DequeueAggregate>>
+<<category PRQAGG PriorityQueueAggregate>>
+<<category DIOPS DictionaryOperations>>
+<<category DIAGG Dictionary>>
+<<category MDAGG MultiDictionary>>
+<<category SETAGG SetAggregate>>
+<<category FSAGG FiniteSetAggregate>>
+<<category MSETAGG MultisetAggregate>>
+<<category OMSAGG OrderedMultisetAggregate>>
+<<category KDAGG KeyedDictionary>>
+<<category ELTAB Eltable>>
+<<category ELTAGG EltableAggregate>>
+<<category IXAGG IndexedAggregate>>
+<<category TBAGG TableAggregate>>
+<<category RCAGG RecursiveAggregate>>
+<<category BRAGG BinaryRecursiveAggregate>>
+<<category DLAGG DoublyLinkedAggregate>>
+<<category URAGG UnaryRecursiveAggregate>>
+<<category STAGG StreamAggregate>>
+<<category LNAGG LinearAggregate>>
+<<category FLAGG FiniteLinearAggregate>>
+<<category A1AGG OneDimensionalArrayAggregate>>
+<<category ELAGG ExtensibleLinearAggregate>>
+<<category LSAGG ListAggregate>>
+<<category ALAGG AssociationListAggregate>>
+<<category SRAGG StringAggregate>>
+<<category BTAGG BitAggregate>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}