diff --git a/changelog b/changelog index e7bbee8..776b956 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,4 @@ +20080823 tpd src/algebra/stream.spad stream API examples 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 diff --git a/src/algebra/stream.spad.pamphlet b/src/algebra/stream.spad.pamphlet index 1d68e08..d69cbfb 100644 --- a/src/algebra/stream.spad.pamphlet +++ b/src/algebra/stream.spad.pamphlet @@ -29,21 +29,42 @@ LazyStreamAggregate(S:Type): Category == StreamAggregate(S) with ++ remove(f,st) returns a stream consisting of those elements of stream ++ st which do not satisfy the predicate f. ++ Note: \spad{remove(f,st) = [x for x in st | not f(x)]}. + ++ + ++E m:=[i for i in 1..] + ++E f(i:PositiveInteger):Boolean == even? i + ++E remove(f,m) + select: (S -> Boolean,%) -> % ++ select(f,st) returns a stream consisting of those elements of stream ++ st satisfying the predicate f. ++ Note: \spad{select(f,st) = [x for x in st | f(x)]}. + ++ + ++E m:=[i for i in 0..] + ++E select(x+->prime? x,m) + explicitEntries?: % -> Boolean ++ explicitEntries?(s) returns true if the stream s has ++ explicitly computed entries, and false otherwise. + ++ + ++E m:=[i for i in 0..] + ++E explicitEntries? m + explicitlyEmpty?: % -> Boolean ++ explicitlyEmpty?(s) returns true if the stream is an ++ (explicitly) empty stream. ++ Note: this is a null test which will not cause lazy evaluation. + ++ + ++E m:=[i for i in 0..] + ++E explicitlyEmpty? m + lazy?: % -> Boolean ++ lazy?(s) returns true if the first node of the stream s ++ is a lazy evaluation mechanism which could produce an ++ additional entry to s. + ++ + ++E m:=[i for i in 0..] + ++E lazy? m + lazyEvaluate: % -> % ++ lazyEvaluate(s) causes one lazy evaluation of stream s. ++ Caution: the first node must be a lazy evaluation mechanism @@ -54,23 +75,47 @@ LazyStreamAggregate(S:Type): Category == StreamAggregate(S) with ++ frst(s) returns the first element of stream s. ++ Caution: this function should only be called after a \spad{empty?} test ++ has been made since there no error check. + ++ + ++E m:=[i for i in 0..] + ++E frst m + rst: % -> % ++ rst(s) returns a pointer to the next node of stream s. ++ Caution: this function should only be called after a \spad{empty?} test ++ has been made since there no error check. + ++ + ++E m:=[i for i in 0..] + ++E rst m + numberOfComputedEntries: % -> NonNegativeInteger ++ numberOfComputedEntries(st) returns the number of explicitly ++ computed entries of stream st which exist immediately prior to the time ++ this function is called. + ++ + ++E m:=[i for i in 0..] + ++E numberOfComputedEntries m + extend: (%,Integer) -> % ++ extend(st,n) causes entries to be computed, if necessary, ++ so that 'st' will have at least 'n' explicit entries or so ++ that all entries of 'st' will be computed if 'st' is finite ++ with length <= n. + ++ + ++E m:=[i for i in 0..] + ++E numberOfComputedEntries m + ++E extend(m,20) + ++E numberOfComputedEntries m + complete: % -> % ++ complete(st) causes all entries of 'st' to be computed. ++ this function should only be called on streams which are ++ known to be finite. + ++ + ++E m:=[i for i in 1..] + ++E n:=filterUntil(i+->i>100,m) + ++E numberOfComputedEntries n + ++E complete n + ++E numberOfComputedEntries n add @@ -503,16 +548,32 @@ CyclicStreamTools(S,ST): Exports == Implementation where Exports ==> with cycleElt: ST -> Union(ST,"failed") - ++ cycleElt(s) returns a pointer to a node in the cycle if the stream s is - ++ cyclic and returns "failed" if s is not cyclic + ++ cycleElt(s) returns a pointer to a node in the cycle if the stream + ++ s is cyclic and returns "failed" if s is not cyclic + ++ + ++E p:=repeating([1,2,3]) + ++E q:=cons(4,p) + ++E cycleElt q + ++E r:=[1,2,3]::Stream(Integer) + ++E cycleElt r + computeCycleLength: ST -> NonNegativeInteger ++ computeCycleLength(s) returns the length of the cycle of a ++ cyclic stream t, where s is a pointer to a node in the ++ cyclic part of t. + ++ + ++E p:=repeating([1,2,3]) + ++E q:=cons(4,p) + ++E computeCycleLength(cycleElt(q)) + computeCycleEntry: (ST,ST) -> ST ++ computeCycleEntry(x,cycElt), where cycElt is a pointer to a ++ node in the cyclic part of the cyclic stream x, returns a ++ pointer to the first node in the cycle + ++ + ++E p:=repeating([1,2,3]) + ++E q:=cons(4,p) + ++E computeCycleEntry(q,cycleElt(q)) Implementation ==> add @@ -755,28 +816,63 @@ Stream(S): Exports == Implementation where coerce: L S -> % ++ coerce(l) converts a list l to a stream. + ++ + ++E m:=[1,2,3,4,5,6,7,8,9,10,11,12] + ++E coerce(m)@Stream(Integer) + ++E m::Stream(Integer) + repeating: L S -> % ++ repeating(l) is a repeating stream whose period is the list l. + ++ + ++E m:=repeating([-1,0,1,2,3]) + if S has SetCategory then repeating?: (L S,%) -> B ++ repeating?(l,s) returns true if a stream s is periodic ++ with period l, and false otherwise. + ++ + ++E m:=[1,2,3] + ++E n:=repeating(m) + ++E repeating?(m,n) + findCycle: (NNI,%) -> Record(cycle?: B, prefix: NNI, period: NNI) ++ findCycle(n,st) determines if st is periodic within n. + ++ + ++E m:=[1,2,3] + ++E n:=repeating(m) + ++E findCycle(3,n) + ++E findCycle(2,n) + delay: (() -> %) -> % - ++ delay(f) creates a stream with a lazy evaluation defined by function f. + ++ delay(f) creates a stream with a lazy evaluation defined by + ++ function f. ++ Caution: This function can only be called in compiled code. cons: (S,%) -> % ++ cons(a,s) returns a stream whose \spad{first} is \spad{a} ++ and whose \spad{rest} is s. ++ Note: \spad{cons(a,s) = concat(a,s)}. + ++ + ++E m:=[1,2,3] + ++E n:=repeating(m) + ++E cons(4,n) + if S has SetCategory then output: (I, %) -> Void ++ output(n,st) computes and displays the first n entries ++ of st. + ++ + ++E m:=[1,2,3] + ++E n:=repeating(m) + ++E output(5,n) + showAllElements: % -> OUT ++ showAllElements(s) creates an output form which displays all ++ computed elements. + ++ + ++E m:=[1,2,3,4,5,6,7,8,9,10,11,12] + ++E n:=m::Stream(PositiveInteger) + ++E showAllElements n + showAll?: () -> B ++ showAll?() returns true if all computed entries of streams ++ will be displayed. @@ -784,22 +880,46 @@ Stream(S): Exports == Implementation where setrest_!: (%,I,%) -> % ++ setrest!(x,n,y) sets rest(x,n) to y. The function will expand ++ cycles if necessary. + ++ + ++E p:=[i for i in 1..] + ++E q:=[i for i in 9..] + ++E setrest!(p,4,q) + ++E p + generate: (() -> S) -> % ++ generate(f) creates an infinite stream all of whose elements are ++ equal to \spad{f()}. ++ Note: \spad{generate(f) = [f(),f(),f(),...]}. + ++ + ++E f():Integer == 1 + ++E generate(f) + generate: (S -> S,S) -> % ++ generate(f,x) creates an infinite stream whose first element is ++ x and whose nth element (\spad{n > 1}) is f applied to the previous ++ element. Note: \spad{generate(f,x) = [x,f(x),f(f(x)),...]}. + ++ + ++E f(x:Integer):Integer == x+10 + ++E generate(f,10) + filterWhile: (S -> Boolean,%) -> % ++ filterWhile(p,s) returns \spad{[x0,x1,...,x(n-1)]} where ++ \spad{s = [x0,x1,x2,..]} and ++ n is the smallest index such that \spad{p(xn) = false}. + ++ + ++E m:=[i for i in 1..] + ++E f(x:PositiveInteger):Boolean == x < 5 + ++E filterWhile(f,m) + filterUntil: (S -> Boolean,%) -> % ++ filterUntil(p,s) returns \spad{[x0,x1,...,x(n)]} where ++ \spad{s = [x0,x1,x2,..]} and ++ n is the smallest index such that \spad{p(xn) = true}. + ++ + ++E m:=[i for i in 1..] + ++E f(x:PositiveInteger):Boolean == x < 5 + ++E filterUntil(f,m) + -- if S has SetCategory then -- map: ((S,S) -> S,%,%,S) -> % -- ++ map(f,x,y,a) is equivalent to map(f,x,y) @@ -1323,8 +1443,13 @@ StreamFunctions1(S:Type): Exports == Implementation where Exports ==> with concat: ST ST S -> ST S - ++ concat(u) returns the left-to-right concatentation of the streams in u. - ++ Note: \spad{concat(u) = reduce(concat,u)}. + ++ concat(u) returns the left-to-right concatentation of the + ++ streams in u. Note: \spad{concat(u) = reduce(concat,u)}. + ++ + ++E m:=[i for i in 10..] + ++E n:=[j for j in 1.. | prime? j] + ++E p:=[m,n]::Stream(Stream(PositiveInteger)) + ++E concat(p) Implementation ==> add @@ -1350,17 +1475,32 @@ StreamFunctions2(A:Type,B:Type): Exports == Implementation where ++ map(f,s) returns a stream whose elements are the function f applied ++ to the corresponding elements of s. ++ Note: \spad{map(f,[x0,x1,x2,...]) = [f(x0),f(x1),f(x2),..]}. + ++ + ++E m:=[i for i in 1..] + ++E f(i:PositiveInteger):PositiveInteger==i**2 + ++E map(f,m) + scan: (B,((A,B) -> B),ST A) -> ST B ++ scan(b,h,[x0,x1,x2,...]) returns \spad{[y0,y1,y2,...]}, where ++ \spad{y0 = h(x0,b)}, ++ \spad{y1 = h(x1,y0)},\spad{...} ++ \spad{yn = h(xn,y(n-1))}. + ++ + ++E m:=[i for i in 1..]::Stream(Integer) + ++E f(i:Integer,j:Integer):Integer==i+j + ++E scan(1,f,m) + reduce: (B,(A,B) -> B,ST A) -> B ++ reduce(b,f,u), where u is a finite stream \spad{[x0,x1,...,xn]}, ++ returns the value \spad{r(n)} computed as follows: ++ \spad{r0 = f(x0,b), ++ r1 = f(x1,r0),..., ++ r(n) = f(xn,r(n-1))}. + ++ + ++E m:=[i for i in 1..300]::Stream(Integer) + ++E f(i:Integer,j:Integer):Integer==i+j + ++E reduce(1,f,m) + -- rreduce: (B,(A,B) -> B,ST A) -> B -- ++ reduce(b,h,[x0,x1,..,xn]) = h(x1,h(x2(..,h(x(n-1),h(xn,b))..) -- reshape: (ST B,ST A) -> ST B @@ -1411,7 +1551,13 @@ StreamFunctions3(A,B,C): Exports == Implementation where map: ((A,B) -> C,ST A,ST B) -> ST C ++ map(f,st1,st2) returns the stream whose elements are the ++ function f applied to the corresponding elements of st1 and st2. - ++ Note: \spad{map(f,[x0,x1,x2,..],[y0,y1,y2,..]) = [f(x0,y0),f(x1,y1),..]}. + ++ \spad{map(f,[x0,x1,x2,..],[y0,y1,y2,..]) = [f(x0,y0),f(x1,y1),..]}. + ++ + ++S + ++E m:=[i for i in 1..]::Stream(Integer) + ++E n:=[i for i in 1..]::Stream(Integer) + ++E f(i:Integer,j:Integer):Integer == i+j + ++E map(f,m,n) Implementation ==> add