diff --git a/changelog b/changelog index 965fce8..e7bbee8 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,4 @@ +20080823 tpd src/algebra/aggcat.spad UnaryRecursiveAggregate API examples 20080822 tpd src/input/Makefile add linalg, overload regression tests 20080822 tpd src/input/linalg.input recovered 20080822 tpd src/input/overload.input recovered diff --git a/src/algebra/aggcat.spad.pamphlet b/src/algebra/aggcat.spad.pamphlet index 0719be4..69b8371 100644 --- a/src/algebra/aggcat.spad.pamphlet +++ b/src/algebra/aggcat.spad.pamphlet @@ -1,3 +1,4 @@ + \documentclass{article} \usepackage{axiom} \begin{document} @@ -1618,90 +1619,196 @@ DoublyLinkedAggregate(S:Type): Category == RecursiveAggregate S with ++ 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(u,v) returns an aggregate w consisting of the elements of u + ++ followed by the elements of v. + ++ Note: \axiom{v = rest(w,#a)}. + ++ + ++E m:=[1,2,3] + ++E concat(5,m) + 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}. + ++ 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}. + ++ + ++E m:=[1,2,3] + ++E concat(m,m) + first: % -> S - ++ first(u) returns the first element of u - ++ (equivalently, the value at the current node). + ++ first(u) returns the first element of u + ++ (equivalently, the value at the current node). + ++ + ++E m:=[1,2,3] + ++E first(m) + elt: (%,"first") -> S - ++ elt(u,"first") (also written: \axiom{u . first}) is equivalent to first u. + ++ 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. + ++ first(u,n) returns a copy of the first n + ++ (\axiom{n >= 0}) elements of u. + ++ + ++E m:=[1,2,3] + ++E first(m,2) + rest: % -> % - ++ rest(u) returns an aggregate consisting of all but the first - ++ element of u - ++ (equivalently, the next node of u). + ++ rest(u) returns an aggregate consisting of all but the first + ++ element of u + ++ (equivalently, the next node of u). + ++ + ++E m:=[1,2,3] + ++E rest m + elt: (%,"rest") -> % - ++ elt(%,"rest") (also written: \axiom{u.rest}) is - ++ equivalent to \axiom{rest u}. + ++ 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}. + ++ rest(u,n) returns the \axiom{n}th (n >= 0) node of u. + ++ Note: \axiom{rest(u,0) = u}. + ++ + ++E m:=[1,2,3] + ++E rest(m,2) + last: % -> S - ++ last(u) resturn the last element of u. - ++ Note: for lists, \axiom{last(u) = u . (maxIndex u) = u . (# u - 1)}. + ++ last(u) resturn the last element of u. + ++ Note: for lists, \axiom{last(u) = u . (maxIndex u) = u . (# u - 1)}. + ++ + ++E m:=[1,2,3] + ++E last m + elt: (%,"last") -> S - ++ elt(u,"last") (also written: \axiom{u . last}) is equivalent to last u. + ++ 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. + ++ 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. + ++ + ++E m:=[1,2,3] + ++E last(m,2) + tail: % -> % - ++ tail(u) returns the last node of u. - ++ Note: if u is \axiom{shallowlyMutable}, - ++ \axiom{setrest(tail(u),v) = concat(u,v)}. + ++ tail(u) returns the last node of u. + ++ Note: if u is \axiom{shallowlyMutable}, + ++ \axiom{setrest(tail(u),v) = concat(u,v)}. + ++ + ++E m:=[1,2,3] + ++E last(m,2) + second: % -> S - ++ second(u) returns the second element of u. - ++ Note: \axiom{second(u) = first(rest(u))}. + ++ second(u) returns the second element of u. + ++ Note: \axiom{second(u) = first(rest(u))}. + ++ + ++E m:=[1,2,3] + ++E second m + third: % -> S - ++ third(u) returns the third element of u. - ++ Note: \axiom{third(u) = first(rest(rest(u)))}. + ++ third(u) returns the third element of u. + ++ Note: \axiom{third(u) = first(rest(rest(u)))}. + ++ + ++E m:=[1,2,3] + ++E third m + cycleEntry: % -> % - ++ cycleEntry(u) returns the head of a top-level cycle contained in - ++ aggregate u, or \axiom{empty()} if none exists. + ++ cycleEntry(u) returns the head of a top-level cycle contained in + ++ aggregate u, or \axiom{empty()} if none exists. + ++ + ++E m:=[1,2,3] + ++E concat!(m,tail(m)) + ++E cycleEntry m + cycleLength: % -> NonNegativeInteger - ++ cycleLength(u) returns the length of a top-level cycle - ++ contained in aggregate u, or 0 is u has no such cycle. + ++ cycleLength(u) returns the length of a top-level cycle + ++ contained in aggregate u, or 0 is u has no such cycle. + ++ + ++E m:=[1,2,3] + ++E concat!(m,tail(m)) + ++E cycleLength m + cycleTail: % -> % - ++ cycleTail(u) returns the last node in the cycle, or - ++ empty if none exists. + ++ cycleTail(u) returns the last node in the cycle, or + ++ empty if none exists. + ++ + ++E m:=[1,2,3] + ++E concat!(m,tail(m)) + ++E cycleTail m + if % has shallowlyMutable then concat_!: (%,%) -> % ++ concat!(u,v) destructively concatenates v to the end of u. ++ Note: \axiom{concat!(u,v) = setlast_!(u,v)}. + ++ + ++E m:=[1,2,3] + ++E n:=[4,5,6] + ++E concat!(m,n) + concat_!: (%,S) -> % ++ concat!(u,x) destructively adds element x to the end of u. ++ Note: \axiom{concat!(a,x) = setlast!(a,[x])}. + ++ + ++E m:=[1,2,3] + ++E concat!(m,5) + 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 + ++ 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. + ++ + ++E m:=[1,2,3] + ++E concat!(m,m) + ++E n:=[4,5,6] + ++E p:=concat(n,m) + ++E q:=cycleSplit! p + ++E p + ++E q + setfirst_!: (%,S) -> S ++ setfirst!(u,x) destructively changes the first element of a to x. + ++ + ++E m:=[1,2,3] + ++E setfirst!(m,4) + ++E m + 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. + ++ + ++E m:=[1,2,3] + ++E setrest!(m,[4,5,6]) + ++E m + setelt: (%,"rest",%) -> % - ++ setelt(u,"rest",v) (also written: \axiom{u.rest := v}) is equivalent to - ++ \axiom{setrest!(u,v)}. + ++ 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. + ++ + ++E m:=[1,2,3] + ++E setlast!(m,4) + ++E m + 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()}. + ++ 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()}. + ++ + ++E m:=[1,2,3,4] + ++E n:=split!(m,2) + ++E m + ++E n + add cycleMax ==> 1000