root/trunk/Library/FortressLibrary.fsi @ 2739

Revision 2739, 76.1 KB (checked in by black, 15 months ago)

Next iteration of CordedStrings?, with substring nodes. Comparison of Strings with substring nodes is a work in progress. This commit fixes bugs in the Range comparison code that were impeding that progress

Line 
1(*******************************************************************************
2    Copyright 2008 Sun Microsystems, Inc.,
3    4150 Network Circle, Santa Clara, California 95054, U.S.A.
4    All rights reserved.
5
6    U.S. Government Rights - Commercial software.
7    Government users are subject to the Sun Microsystems, Inc. standard
8    license agreement and applicable provisions of the FAR and its supplements.
9
10    Use is subject to license terms.
11
12    This distribution may include materials developed by third parties.
13
14    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
15    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
16 ******************************************************************************)
17
18api FortressLibrary
19
20(************************************************************
21* \subsection*{Simple Combinators}
22*************************************************************)
23
24(** Casting *)
25
26cast[\T extends Any\](x:Any):T
27
28instanceOf[\T extends Any\](x:Any):Boolean
29
30(** Useful functions *)
31
32ignore(_:Any):()
33
34identity[\T extends Any\](x:T):T
35
36(* Should we depracate tuple and use identity instead?  Decision: no. *)
37tuple[\T\](x:T):T
38
39(* Function composition *)
40opr COMPOSE[\A,B,C\](f: B->C, g: A->B): A->C
41
42fail[\T\](s:String):T
43
44(************************************************************
45* \subsection*{Control over locality and location}
46************************************************************
47
48At the moment, all Fortress objects are immediately shared by default. *)
49
50shared[\T extends Any\](x:T): T
51
52isShared(x:Any): Boolean
53
54localize[\T extends Any\](x:T): T
55
56(* copy is presently unimplemented.
57copy[\T extends Any\](x:T): T
58*)
59
60trait Region extends Equality[\Region\]
61    getter toString(): String
62    isLocalTo(r: Region): Boolean
63end
64
65object Global extends Region end
66
67region(a:Any): Region
68
69here(): Region
70
71(************************************************************
72* \subsection*{Equality and ordering}
73************************************************************)
74
75opr =(a:Any, b:Any):Boolean
76
77opr =/=(a:Any, b:Any):Boolean
78
79trait Equality[\Self extends Equality[\Self\]\]
80    abstract opr =(self, other:Self): Boolean
81end
82
83(** Total ordering *)
84object LexicographicPartialReduction
85        extends { MonoidReduction[\Comparison\],
86                  ReductionWithZeroes[\Comparison, Comparison\] }
87    empty(): Comparison
88    join(a:Comparison, b:Comparison):Comparison
89    isZero(_:Unordered): Boolean
90    isZero(_:Comparison): Boolean
91end
92
93object LexicographicReduction
94        extends { MonoidReduction[\TotalComparison\],
95                  ReductionWithZeroes[\TotalComparison, TotalComparison\] }
96    empty(): TotalComparison
97    join(a:TotalComparison, b:TotalComparison):TotalComparison
98    isLeftZero(_:EqualTo): Boolean
99    isLeftZero(_:Comparison): Boolean
100end
101
102opr BIG LEXICO(): BigReduction[\TotalComparison, TotalComparison\]
103
104trait Comparison
105        extends { StandardPartialOrder[\Comparison\] }
106        comprises { Unordered, TotalComparison }
107    abstract getter toString(): String
108    opr =(self, other:Comparison): Boolean
109    opr LEXICO(self, other:Comparison): Comparison
110    abstract opr INVERSE(self): Comparison
111end
112
113(** Unordered is the outcome of %a CMP b% when %a% and %b% are partially
114    ordered and no ordering relationship exists between them. **)
115object Unordered extends Comparison
116    getter toString(): String
117    opr =(self, other:Unordered): Boolean
118    opr <(self, other:Comparison): Boolean
119    opr INVERSE(self): Comparison
120end
121
122(** %TotalComparison% is both a partial order (including %Unordered%)
123    and a total order (%TotalComparison% alone).  Its method
124    definitions avoid ambiguities between these orderings. *)
125trait TotalComparison
126        extends { Comparison, StandardTotalOrder[\TotalComparison\] }
127        comprises { LessThan, EqualTo, GreaterThan }
128    opr =(self, other:Comparison): Boolean
129    opr CMP(self, other:Unordered): Comparison
130    opr >=(self, other:Unordered): Boolean
131    opr >=(self, other:Comparison): Boolean
132    opr LEXICO(self, other:TotalComparison): TotalComparison
133    opr LEXICO(self, other:()->TotalComparison): TotalComparison
134    abstract opr INVERSE(self): TotalComparison
135end
136
137object LessThan extends TotalComparison
138    getter toString(): String
139    opr =(self, other:LessThan): Boolean
140    opr CMP(self, other:LessThan): Comparison
141    opr CMP(self, other:TotalComparison): TotalComparison
142    opr <(self, other:LessThan): Boolean
143    opr <(self, other:TotalComparison): Boolean
144    opr INVERSE(self): TotalComparison
145end
146
147object GreaterThan extends TotalComparison
148    getter toString(): String
149    opr =(self, other:GreaterThan): Boolean
150    opr CMP(self, other:GreaterThan): Comparison
151    opr CMP(self, other:TotalComparison): TotalComparison
152    opr <(self, other:TotalComparison): Boolean
153    opr INVERSE(self): TotalComparison
154end
155
156object EqualTo extends TotalComparison
157    getter toString(): String
158    opr =(self, other:EqualTo): Boolean
159    opr CMP(self, other:TotalComparison): TotalComparison
160    opr <(self, other:LessThan): Boolean
161    opr <(self, other:TotalComparison): Boolean
162    opr LEXICO(self, other:TotalComparison): TotalComparison
163    opr LEXICO(self, other:()->TotalComparison): TotalComparison
164    opr INVERSE(self): TotalComparison
165end
166
167(** StandardPartialOrder is partial ordering using %<%,%>%,%<=%,%>=%,%=%, and %CMP%.
168    This is primarily for floating-point values.  Minimal complete
169    definition: %CMP% or %{ <, = }%. **)
170trait StandardPartialOrder[\Self extends StandardPartialOrder[\Self\]\]
171        extends { Equality[\Self\] }
172    opr CMP(self, other:Self): Comparison
173    opr <(self, other:Self): Boolean
174    opr >(self, other:Self): Boolean
175    opr =(self, other:Self): Boolean
176    opr <=(self, other:Self): Boolean
177    opr >=(self, other:Self): Boolean
178end
179
180(** %StandardMin% is the %MIN% operator; most types that implement %MIN%
181    will implement a corresponding total order.  It's a separate type
182    to account for the existence of floating point numbers, for which
183    NaN counts as a bottom that is less than anything else but doesn't
184    actually participate in the standard total ordering.  It is
185    otherwise the case that %a MIN b = a% when %a <= b% and that
186    %a MIN b = b MIN a%. **)
187trait StandardMin[\T extends StandardMin[\T\]\]
188    opr MIN(self, other:T): T
189end
190
191(** %StandardMax% is the %MAX% operator; most types that implement %MAX%
192    will implement a corresponding total order.  It's a separate type
193    to account for the existence of floating point numbers, for which
194    NaN counts as a bottom that is less than anything else but doesn't
195    actually participate in the standard total ordering.  It is
196    otherwise the case that %a MAX b = a% when %a <= b% and that
197    %a MAX b = b MAX a%. **)
198trait StandardMax[\T extends StandardMax[\T\]\]
199    opr MAX(self, other:T): T
200end
201
202(** StandardTotalOrder is the usual total order using %<%,%>%,%<=%,%>=%,%=%, and %CMP%.
203    Most values that define a comparison should do so using this.
204    Minimal complete definition: either %CMP% or %<% (it is advisable to
205    define %=% in the latter case).  As noted above, %MIN%
206    and %MAX% respect the total order and are defined in the obvious
207    way. **)
208trait StandardTotalOrder[\Self extends StandardTotalOrder[\Self\]\]
209        extends { StandardPartialOrder[\Self\], StandardMin[\Self\], StandardMax[\Self\] }
210    opr CMP(self, other:Self): TotalComparison
211end
212
213(************************************************************
214 * \subsection*{Assertions}
215 *)
216assert(flag:Boolean): ()
217
218assert(flag: Boolean, failMsg: String): ()
219
220(** This version of %assert% checks the equality of its first two arguments;
221    if unequal it includes the remaining arguments in its error indication. *)
222assert(x:Any, y:Any, failMsg: Any...): ()
223
224deny(flag:Boolean): ()
225
226deny(flag: Boolean, failMsg: String): ()
227
228(** This version of %deny% checks the inequality of its first two arguments;
229    if equal it includes the remaining arguments in its error indication. *)
230deny(x:Any, y:Any, failMsg: Any...): ()
231
232shouldRaise[\Ex extends Exception\] (expr: ()->()): ()
233
234(************************************************************
235* \subsection*{Numeric hierarchy}
236************************************************************)
237
238(** Additive group making use of %+%.  Must define %+% and
239    either unary or binary %-%. **)
240trait AdditiveGroup[\Self extends AdditiveGroup[\Self\]\]
241    getter zero(): Self
242    abstract opr +(self, other: Self): Self
243    opr -(self, other: Self): Self
244    opr -(self) : Self
245end
246
247(** Place holder for exclusions of MultiplicativeRing **)
248trait AnyMultiplicativeRing end
249
250(** Multiplicative ring using TIMES and juxtaposition.
251    Define opr TIMES; juxtaposition is defined in terms of TIMES. **)
252trait MultiplicativeRing[\Self extends MultiplicativeRing[\Self\]\]
253        extends { AdditiveGroup[\Self\], AnyMultiplicativeRing }
254    abstract getter one(): Self
255    abstract opr TIMES(self, other:Self): Self
256    opr juxtaposition(self, other:Self): Self
257    (** Exponentiation need only deal with natural exponents. **)
258    opr ^(self, other:ZZ64): Self
259end
260
261trait Number
262      extends { StandardPartialOrder[\Number\], StandardMin[\Number\], StandardMax[\Number\] }
263      comprises { RR64 }
264    opr =(self, b:Number):Boolean
265    opr =/=(self, b:Number):Boolean
266    opr <(self, b:Number):Boolean
267    opr <=(self, b:Number):Boolean
268    opr >(self, b:Number):Boolean
269    opr >=(self, b:Number):Boolean
270    opr CMP(self, b:Number):Comparison
271    (** In case of NaN, %MIN% and %MAX% return a NaN, otherwise it respects the
272        total order. **)
273    opr MIN(self, b:Number):Number
274    opr MAX(self, b:Number):Number
275
276    opr -(self):RR64
277    opr +(self,b:Number):RR64
278    opr -(self,b:Number):RR64
279    opr DOT(self,b:Number):RR64
280    opr TIMES(self,b:Number):RR64
281    opr juxtaposition
282         (self,b:Number):RR64
283    opr /(self,b:Number):RR64
284    opr SQRT(self):RR64
285    opr PLUS_UP(self,b:Number):RR64
286    opr MINUS_UP(self,b:Number):RR64
287    opr DOT_UP(self,b:Number):RR64
288    opr SLASH_UP(self,b:Number):RR64
289    opr SQRT_UP(self):RR64
290    opr PLUS_DOWN(self,b:Number):RR64
291    opr MINUS_DOWN(self,b:Number):RR64
292    opr DOT_DOWN(self,b:Number):RR64
293    opr SLASH_DOWN(self,b:Number):RR64
294    opr SQRT_DOWN(self):RR64
295    opr IEEE_PLUS_UP(self,b:Number):RR64
296    opr IEEE_MINUS_UP(self,b:Number):RR64
297    opr IEEE_DOT_UP(self,b:Number):RR64
298    opr IEEE_PLUS_DOWN(self,b:Number):RR64
299    opr IEEE_MINUS_DOWN(self,b:Number):RR64
300    opr IEEE_DOT_DOWN(self,b:Number):RR64
301    opr IEEE_SLASH_DOWN(self,b:Number):RR64
302    opr IEEE_SLASH_UP(self,b:Number):RR64
303    opr |a:RR64| : RR64
304    opr ^(self, b:RR64):RR64
305    sin(self):RR64
306    cos(self):RR64
307    tan(self):RR64
308    asin(self):RR64
309    acos(self):RR64
310    atan(self):RR64
311    atan2(self,x:Number):RR64
312    log(self):RR64
313    exp(self):RR64
314    floor(self):RR64
315    opr |\self/| : ZZ64
316    ceiling(self):RR64
317    opr |/self\| : ZZ64
318    truncate(self):ZZ64
319end
320
321trait RR64 extends Number comprises { RR32, Float, AnyIntegral, FloatLiteral }
322    (** returns true if the value is an IEEE NaN **)
323    getter isNaN(): Boolean
324    (** returns true if the value is an IEEE infinity **)
325    getter isInfinite(): Boolean
326    (** returns true if the value is a valid number (not NaN) **)
327    getter isNumber(): Boolean
328    (** returns true if the value is finite **)
329    getter isFinite(): Boolean
330    (** %check% returns %Just(its argument)% if it is finite, otherwise %Nothing%. **)
331    getter check(): Maybe[\RR64\]
332    (** %check_star% returns %Just(its argument)% if it is non-NaN, otherwise %Nothing%. **)
333    getter check_star(): Maybe[\RR64\]
334    (** obtain the raw bits of the IEEE floating-point representation of this value. **)
335    getter rawBits():ZZ64
336    (** obtain the sign bit of the IEEE floating-point representation of this value. **)
337    getter signBit():ZZ32
338    (** next higher IEEE float **)
339    getter nextUp():RR64
340    (** next lower IEEE float **)
341    getter nextDown():RR64
342    (** %MINNUM% and %MAXNUM% return a numeric result where possible (avoiding NaN).
343        Note that %MINNUM% and %MAX% form a lattice with NaN at the top, and
344        that %MAXNUM% and %MIN% form a lattice with NaN at the bottom.  **)
345    opr MINNUM(self, b:RR64):RR64
346    opr MAXNUM(self, b:RR64):RR64
347    (** returns a value of type RR32 **)
348    narrow(self): RR32
349end
350
351
352trait QQ extends { RR64, StandardPartialOrder[\QQ\] }
353    getter isNaN(): Boolean
354    getter isInfinite(): Boolean
355    getter isNumber(): Boolean
356    getter isFinite(): Boolean
357    numerator(self): ZZ
358    denominator(self): ZZ  (* Ideally would be NN *)
359    opr |self| : QQ
360    opr =(self, other:QQ):Boolean
361    opr =/=(self, other:QQ):Boolean
362    opr <(self, other:QQ):Boolean
363    opr <=(self, other:QQ):Boolean
364    opr >(self, other:QQ):Boolean
365    opr >=(self, other:QQ):Boolean
366    (** In case of 0/0, %MIN% and %MAX% return 0/0, otherwise it respects the total order. **)
367    opr MIN(self, other:QQ):QQ
368    opr MAX(self, other:QQ):QQ
369    opr -(self):QQ
370    opr +(self,other:QQ):QQ
371    opr -(self,other:QQ):QQ
372    opr DOT(self,other:QQ):QQ
373    opr TIMES(self,other:QQ):QQ
374    opr juxtaposition (self,other:QQ):QQ
375    opr /(self,other:QQ):QQ
376    opr ^(self, other:ZZ64):QQ
377    floor(self):ZZ
378    opr |\self/| : ZZ
379    ceiling(self):ZZ
380    opr |/self\| : ZZ
381    truncate(self): ZZ
382    round(self): ZZ
383    opr MINNUM(self, other:QQ):QQ
384    opr MAXNUM(self, other:QQ):QQ
385end
386
387trait AnyIntegral extends { QQ } end
388
389trait Integral[\I extends Integral[\I\]\] extends { StandardTotalOrder[\I\], AnyIntegral }
390        comprises { ZZ, IntLiteral }
391    getter zero(): I
392    getter one(): I
393    opr -(self):I
394    opr +(self,b:I):I
395    opr -(self,b:I):I
396    opr DOT(self,b:I):I
397    opr TIMES(self,b:I):I
398    opr juxtaposition(self,b:I):I
399    opr DIV(self,b:I):I
400    opr REM(self,b:I):I
401    opr MOD(self,b:I):I
402    opr GCD(self,b:I):I
403    opr LCM(self,b:I):I
404    opr DIVIDES(self,b:I):Boolean
405    opr CHOOSE(self,b:I):I
406    opr BITAND(self,b:I):I
407    opr BITOR(self,b:I):I
408    opr BITXOR(self,b:I):I
409    opr LSHIFT(self,b:AnyIntegral):I
410    opr RSHIFT(self,b:AnyIntegral):I
411    opr BITNOT(self):I
412    opr ^(self, b:AnyIntegral):RR64
413    unsigned(self):NN64
414end
415
416trait NN64 extends { ZZ, Integral[\NN64\] } comprises { UnsignedLong, NN32 }
417    opr |self| : NN64
418    opr =(self, b:NN64):Boolean
419    opr <(self, b:NN64):Boolean
420    opr -(self):NN64
421    opr +(self,b:NN64):NN64
422    opr -(self,b:NN64):NN64
423    opr DOT(self,b:NN64):NN64
424    opr TIMES(self,b:NN64):NN64
425    opr juxtaposition(self,b:NN64):NN64
426    opr DIV(self,b:NN64):NN64
427    opr REM(self,b:NN64):NN64
428    opr MOD(self,b:NN64):NN64
429    opr GCD(self,b:NN64):NN64
430    opr LCM(self,b:NN64):NN64
431    opr CHOOSE(self,b:NN64):NN64
432    opr BITAND(self,b:NN64):NN64
433    opr BITOR(self,b:NN64):NN64
434    opr BITXOR(self,b:NN64):NN64
435    opr LSHIFT(self,b:AnyIntegral):NN64
436    opr RSHIFT(self,b:AnyIntegral):NN64
437    opr BITNOT(self):NN64
438    opr ^(self, b:AnyIntegral):RR64
439    narrow(self):NN32
440    signed(self):NN64
441end
442
443trait ZZ32 extends { ZZ64, Integral[\ZZ32\] } comprises { Int, IntLiteral }
444    getter zero(): ZZ32
445    getter one(): ZZ32
446    getter minimum(): ZZ32
447    getter maximum(): ZZ32
448
449
450
451    opr |self| : ZZ32
452    opr =(self, b:ZZ32):Boolean
453    opr <(self, b:ZZ32):Boolean
454
455    opr -(self):ZZ32
456    opr +(self,b:ZZ32):ZZ32
457    opr -(self,b:ZZ32):ZZ32
458    opr DOT(self,b:ZZ32):ZZ32
459    opr juxtaposition(self,b:ZZ32):ZZ32
460    opr DIV(self,b:ZZ32):ZZ32
461    opr REM(self,b:ZZ32):ZZ32
462    opr MOD(self,b:ZZ32):ZZ32
463    opr GCD(self,b:ZZ32):ZZ32
464    opr LCM(self,b:ZZ32):ZZ32
465    opr CHOOSE(self,b:ZZ32):ZZ32
466    opr BITAND(self,b:ZZ32):ZZ32
467    opr BITOR(self,b:ZZ32):ZZ32
468    opr BITXOR(self,b:ZZ32):ZZ32
469    opr LSHIFT(self,b:ZZ64):ZZ32
470    opr RSHIFT(self,b:ZZ64):ZZ32
471    opr BITNOT(self):ZZ32
472    widen(self):ZZ64
473    partitionL(self):ZZ32
474    unsigned(self):NN32
475end
476
477trait ZZ64 extends { ZZ, Integral[\ZZ64\] } comprises { Long, ZZ32 }
478    getter zero(): ZZ64
479    getter one(): ZZ64
480    getter minimum(): ZZ64
481    getter maximum(): ZZ64
482
483
484    opr |x:ZZ64| : ZZ64
485
486    opr =(self, b:ZZ64):Boolean
487    opr <(self, b:ZZ64):Boolean
488    opr >(self, b:ZZ64):Boolean
489    opr >=(self, b:ZZ64):Boolean
490    opr <=(self, b:ZZ64):Boolean
491    opr CMP(self, b:ZZ64): TotalComparison
492
493    opr -(self):ZZ64
494    opr +(self,b:ZZ64):ZZ64
495    opr -(self,b:ZZ64):ZZ64
496    opr DOT(self,b:ZZ64):ZZ64
497    opr TIMES(self,b:ZZ64):ZZ64
498    opr juxtaposition(self,b:ZZ64):ZZ64
499    opr DIV(self,b:ZZ64):ZZ64
500    opr REM(self,b:ZZ64):ZZ64
501    opr MOD(self,b:ZZ64):ZZ64
502    opr GCD(self,b:ZZ64):ZZ64
503    opr LCM(self,b:ZZ64):ZZ64
504    opr CHOOSE(self,b:ZZ64):ZZ64
505    opr BITAND(self,b:ZZ64):ZZ64
506    opr BITOR(self,b:ZZ64):ZZ64
507    opr BITXOR(self,b:ZZ64):ZZ64
508    opr LSHIFT(self,b:ZZ64):ZZ64
509    opr RSHIFT(self,b:ZZ64):ZZ64
510    opr BITNOT(self):ZZ64
511    narrow(self):ZZ32
512    big(self):ZZ
513end
514
515trait ZZ extends { Integral[\ZZ\] } comprises { BigNum, ZZ64}
516    opr /(self,other:ZZ):QQ
517    numerator(self): ZZ
518end
519
520(************************************************************
521* \subsection*{Generator support}
522************************************************************
523
524**
525 * We say an object which extends %Generator[\T\]% ``generates objects of
526 * type %T%.''
527 *
528 * Generators are used to express iteration in Fortress.  Every generated
529 * expression in Fortress (eg. for loop and comprehension) is desugared into
530 * calls to methods of Generator, chiefly the %generate% method.
531 *
532 * Every generator has a notion of a ``natural order'' (which by default is
533 * unspecified), which describes the ordering of reduction operations,
534 * and also describes the order in which elements are produced by the
535 * sequential version of the same generator (given by the
536 * %seq(self)% method).  The default implementation of
537 * %seq(self)% guarantees that these orders will match.
538 *
539 * Note in particular that the natural order of a Generator must be
540 * consistent; that is, if %a SEQV b% then %a% and %b%
541 * must yield %SEQV% elements in the same natural order.  However,
542 * note that unless a type specifically documents otherwise, no
543 * particular element ordering is guaranteed, nor is it necessary to
544 * guarantee that %a=b% have the same natural order when equality is
545 * defined.
546 *
547 * Note that more complex derived generators are specified further down
548 * in the definition of Generator.  These have the same notions of
549 * natural order and by default are defined in terms of the
550 * %generate% method.
551 *
552 * Minimal complete definition of a %Generator% is the %generate%
553 * method.  *)
554trait Generator[\E\]
555    excludes { Number }
556    (** %generate% is the core of %Generator%.  It generates elements of
557        type %E% and passes them to the %body% function.  This generation
558        can occur using any mixture of serial and parallel execution
559        desired by the author of the generator; by default uses of a
560        generator must assume every call to %body% occurs in
561        parallel.
562
563        The results of generation are combined using the reduction
564        object %R%, which specifies a monoidal operation (associative
565        and with an identity).  Body results must be combined together
566        following the natural order of the generator.  The author of
567        the generator is free to use the identity element anywhere
568        desired in this computation, and to group reductions in any
569        way desired; if no elements are generated, the identity must be
570        returned. *)
571    abstract generate[\R\](r: Reduction[\R\], body: E->R): R
572
573    (** \textbf{Transforming generators into new generators} *)
574
575    (** %map% applies a function %f% to each element generated and yields
576        the result.  The resulting generator must have the same
577        ordering and cross product properties as the generator from
578        which it is derived. *)
579    map[\G\](f: E->G): Generator[\G\]
580    (** %seq% produces a sequential version of the same generator, in
581        which elements are produced in the generator's natural order. *)
582    seq(self): SequentialGenerator[\E\]
583
584    (** Nesting of two generators; the innermost is data-dependent
585        upon the outer one.  This is specifically designed to be
586        overloaded so that the combined generators have properties
587        appropriate to the pairing.  Because of the data dependency,
588        the natural order of the nesting is the natural order of the
589        inner generators, in the natural order the outer nesting
590        produces them.  So, for example, if we write:
591          %(0#3).nest[\ZZ32\](fn (n:ZZ32):Generator[\ZZ32\] => ((n 100)#4))
592        then the natural order is 0,1,2,3,100,101,102,103,200,201,202,203.
593     **)
594    nest[\G\](f: E -> Generator[\G\]): Generator[\G\]
595
596    (** Filtering data from a generator.  Only elements that satisfy
597        the predicate p are retained.  Natural order and cross product
598        properties are otherwise preserved. **)
599    filter(f: E -> Condition[\()\]): Generator[\E\]
600
601    (** Cross product of two generators.  This is specifically
602        designed to be overloaded, such that pairs of independent
603        generators can be combined to produce a generator which
604        possibly interleaves the iteration spaces of the two
605        generators.  For example, we might combine
606        % (0#16).cross(0#32)
607        such that it first splits the second range in half, then the
608        first range in half, then the second, and so forth.
609
610        Consider a grid for which the rows are labeled from top to
611        bottom with the elements of %a% in natural order, and the
612        columns are labeled from left to right with the elements of %g%
613        in natural order.  Each point in the grid corresponds to a
614        pair %(a,b)% that must be generated by
615        %self.cross(g)%.  In the natural
616        order of the cross product, an element must occur after those
617        that lie above and to the left of it in the grid.  By default
618        the natural order of the cross product is left-to-right, top
619        to bottom.  Programmers must not rely on the default order,
620        except that cross products involving one or more sequential
621        generators are always performed in the default order.  Note
622        that this means that the following have the same natural
623        order:
624          %seq(a).cross(b)
625          %a.cross(seq(b))
626          %seq(a).cross(seq(b))
627        But %seq(a.cross(b))% may have a different natural order. *)
628    cross[\G\](g: Generator[\G\]): Generator[\(E,G)\]
629
630    (** \textbf{Derived generation operations} *)
631
632    (** %mapReduce% is equivalent to %generate%, but takes an explicit %join%
633        and %zero% which can have any type.  It still assumes %join% is
634        associative and that %zero% is the identity of %join%. **)
635    mapReduce[\R\](body: E->R, join:(R,R)->R, zero:R): R
636    (** %reduce% works much like %generate% or %mapReduce%,
637        but has no body expression. **)
638    reduce(j:(E,E)->E, z:E):E
639    reduce(r: Reduction[\E\]):E
640    (** %loop% is a version of %generate% which discards the %()% results
641        of the body computation.  It can be used to translate
642        reduction-variable-free %for% loops. **)
643    loop(f:E->()): ()
644
645    (** %x IN self% holds if $x$ is generated by this generator.  By
646        default this is implemented using the naive $O(n)$ algorithm. **)
647    opr IN(x:E, self): Boolean
648    (** The %MATCH% operator is used (as a temporary hack) by CASE when the
649        match clause is a %Generator[\E\]%.  We must choose either %=%, %SEQV%, or
650        %IN% as appropriate, depending on the type of the LHS. **)
651    opr MATCH(x:Any, self): Boolean
652end
653
654(** The following stubs exist as a temporary workaround to shortcomings
655   in interpreter type inference, and are intended for use by
656   reduction desugaring. *)
657__generate[\E,R\](g:Generator[\E\], r: Reduction[\R\], b:E->R): R
658
659__filter[\E\](g:Generator[\E\], p:E->Condition[\()\]): Generator[\E\]
660
661__bigOperator[\I,O,R,L\](o:BigOperator[\I,O,R,L\],desugaredClauses:(Reduction[\L\],I->L)->L): O
662
663(** Application of two nested BIG operators, possibly with fusion.  This only covers
664    a comprehension of the form:
665        %BIG outer [ xs <- expro ] (BIG inner [x <- xs] expri)
666    The desugarer extracts comprehensions of this form from more complex nests of
667    comprehensions, using a combination of splitting:
668        %BIG OP [ gs1, gs2 ] expr = BIG OP [ gs1 ] (BIG OP [ gs2 ] expr)
669    and filter squeezing:
670        %BIG OP [ xs <- g, p(xs) ] expr = BIG OP [ xs <- g.filter(p) ] expr
671    There are some big caveats to this explanation in practice.  Most important is that
672    we don't unlift and lift or do input/output conversion except where neccessary, so
673    splitting skips these operations in between the inner and outer comprehension.
674    **)
675__bigOperator2[\I,M,O,R1,L1,R2,L2,E\](outer:BigOperator[\M,O,R1,L1\],
676                                    inner:BigOperator[\I,M,R2,L2\],
677                                    gg: Generator[\Generator[\E\]\],
678                                    innerBody:E->L2): L1
679
680(* Not currently used for desugaring, but will be used in future.
681__nest[\E1,E2\](g:Generator[\E1\], f:E1->Generator[\E2\]):Generator[\E2\]
682
683__map[\E,R\](g:Generator[\E\], f:E->R): Generator[\R\]
684*)
685
686(** Used in desugaring binding %if% **)
687__cond[\E,R\](c:Condition[\E\], t:E->R, e:()->R): R
688__cond[\E\](c:Condition[\E\], t:E->()): ()
689
690(** Used in desugaring binding %while% **)
691__whileCond[\E\](c:Condition[\E\], b:E->()): ()
692
693trait SequentialGenerator[\E\] extends { Generator[\E\] }
694    seq(self)
695    map[\G\](f: E->G): SequentialGenerator[\G\]
696    nest[\G\](f: E -> Generator[\G\]): Generator[\G\]
697    cross[\F\](g:Generator[\F\]): Generator[\(E,F)\]
698end
699
700(** A Condition is a Generator that generates 0 or 1 element.
701    Conditions can be used as nullary comprehension generators or
702    as predicates in an if expression. **)
703trait Condition[\E\] extends SequentialGenerator[\E\]
704    getter isEmpty(): Boolean
705    getter nonEmpty(): Boolean
706    getter holds(): Boolean
707    getter size(): ZZ32
708    getter get(): E throws NotFound
709    getter bounds(): FullRange[\ZZ32,true\]
710    getter indices(): FullRange[\ZZ32,true\]
711    getter indexValuePairs(): Generator[\(ZZ32,E)\]
712    opr |self|: ZZ32
713    opr [i:ZZ32]:E throws NotFound
714
715    (** %cond% is the core of a %Condition%, in terms of which all other
716        methods are written.  When %holds()%, %t% is invoked with the
717        value of %get()%; otherwise %e% is called. **)
718    abstract cond[\G\](t: E -> G, e: () -> G): G
719
720    (** For a %Condition%, these methods run eagerly. **)
721    generate[\G\](r:Reduction[\G\], body: E -> G): G
722    map[\G\](f: E->G): Generator[\G\]
723    ivmap[\G\](f: (ZZ32,E)->G): Generator[\G\]
724    nest[\G\](f: E -> Generator[\G\]): Generator[\G\]
725    cross[\G\](g: Generator[\G\]): Generator[\(E,G)\]
726    mapReduce[\R\](body: E->R, _:(R,R)->R, zero:R): R
727    reduce(_:(E,E)->E, z:E):E
728    reduce(r: Reduction[\E\]):E
729    loop(f:E->()): ()
730    opr IN(x:E, self):Boolean
731end
732
733(** Conjunction and disjunction of condition functions **)
734opr ANDCOND[\I\](p1:I->Condition[\()\], p2:I->Condition[\()\]): I->Condition[\()\]
735
736(** Conjunction and disjunction of condition functions **)
737opr ORCOND[\I\](p1:I->Condition[\()\], p2:I->Condition[\()\]): I->Condition[\()\]
738
739
740(** %opr IN% returns true if any element generated by its second argument is
741    %=% to its first argument.  %x NOTIN g% is simply %NOT (x IN g)%. **)
742opr NOTIN[\E\](x: E, this: Generator[\E\]): Boolean
743
744sequential[\T\](g:Generator[\T\]):SequentialGenerator[\T\]
745
746
747(************************************************************
748* \subsection{The Maybe type}
749* \seclabel{maybe-type}
750************************************************************
751
752** This trait makes excludes work without where clauses, and allows opr =
753   to remain non-parametric. *)
754value trait AnyMaybe extends Equality[\AnyMaybe\] excludes Number
755        (** not yet: ``%comprises Maybe[\T\] where [\T\]%'' *)
756    abstract getter holds() : Boolean
757    opr =(self, other:AnyMaybe): Boolean
758end
759
760just(t:Any):AnyMaybe
761
762(** %Maybe% represents either %Nothing% or a single element of type
763    %T% (%Just[\T\]%), which may be retrieved by calling %get%.  An
764    object of type %Maybe[\T\]% can be used as a generator; it is either
765    empty (%Nothing%) or generates the single element yielded by
766    %get%, so there is no issue of canonical order or parallelism.
767
768    Thus, %Just[\T\]% can be used as a single-element generator, and
769    %Nothing% can be used as an empty generator. *)
770value trait Maybe[\T\]
771        extends { AnyMaybe, Condition[\T\], ZeroIndexed[\T\] }
772        comprises { Nothing[\T\], Just[\T\] }
773end
774
775value object Just[\T\](x:T) extends Maybe[\T\]
776    getter size(): ZZ32
777    getter toString():String
778    getter holds(): Boolean
779    getter get(): T
780    opr |self| : ZZ32
781    getDefault(_:T): T
782    cond[\R\](t:T->R, _:()->R): R
783    generate[\R\](_:Reduction[\R\],m:T->R): R
784    opr[i:ZZ32]:T
785    opr[r:Range[\ZZ32\]]:Maybe[\T\]
786    map[\G\](f: T->G): Just[\G\]
787    cross[\G\](g: Generator[\G\]): Generator[\(T,G)\]
788    mapReduce[\R\](m: T->R, _:(R,R)->R, _:R): R
789    reduce(_:(T,T)->T, _:T):T
790    reduce(_: Reduction[\T\]):T
791    loop(f:T->()): ()
792    opr =(self,o:Just[\T\]): Boolean
793end
794
795(** %Nothing% will become a non-parametric singleton when we get where
796    clauses working. *)
797value object Nothing[\T\] extends Maybe[\T\]
798    getter size(): ZZ32
799    getter holds(): Boolean
800    getter get(): T
801    getter toString():String
802    opr |self| : ZZ32
803    getDefault(t:T):T
804    cond[\R\](t:T->R, _:()->R): R
805    generate[\R\](r:Reduction[\R\],_:T->R): R
806    opr[_:ZZ32]: T
807    opr[r:Range[\ZZ32\]]: Nothing[\T\]
808    map[\G\](f: T->G): Nothing[\G\]
809    cross[\G\](g: Generator[\G\]): Generator[\(T,G)\]
810
811    mapReduce[\R\](_: T->R, _:(R,R)->R, z:R): R
812    reduce(_:(T,T)->T, z:T):T
813    reduce(r: Reduction[\T\]):T
814    loop(f:T->()): ()
815    opr =(self,_:Nothing[\T\]): Boolean
816end
817
818(************************************************************
819* \subsection*{Exception hierarchy}
820************************************************************)
821
822trait Exception comprises { UncheckedException, CheckedException }
823end
824
825(* Exceptions which are not checked *)
826
827trait UncheckedException extends Exception excludes CheckedException
828end
829
830object FailCalled(s:String) extends UncheckedException
831  toString(): String
832end
833
834object DivisionByZero extends UncheckedException
835end
836
837object UnpastingError extends UncheckedException
838end
839
840object CallerViolation extends UncheckedException
841end
842
843object CalleeViolation extends UncheckedException
844end
845
846object TestFailure extends UncheckedException
847end
848
849object ContractHierarchyViolation extends UncheckedException
850end
851
852object NoEqualityOnFunctions extends UncheckedException
853end
854
855object InvalidRange extends UncheckedException
856end
857
858object ForbiddenException(chain : Exception) extends UncheckedException
859end
860
861(* Should this be called ``IndexNotFound'' instead? *)
862object NotFound extends UncheckedException
863end
864
865object IndexOutOfBounds(min:ZZ32,max:ZZ32,index:ZZ32) extends UncheckedException
866end
867
868object NegativeLength extends UncheckedException
869end
870
871object IntegerOverflow extends UncheckedException
872end
873
874object RationalComparisonError extends UncheckedException
875end
876
877object FloatingComparisonError extends UncheckedException
878end
879
880(* Checked Exceptions *)
881
882trait CheckedException extends Exception excludes UncheckedException
883end
884
885object CastError extends CheckedException
886end
887
888object IOFailure extends CheckedException
889end
890
891object MatchFailure extends CheckedException
892end
893
894(* SetsNotDisjoint? *)
895object DisjointUnionError extends CheckedException
896end
897
898object APIMissing extends CheckedException
899end
900
901object APINameCollision extends CheckedException
902end
903
904object ExportedAPIMissing extends CheckedException
905end
906
907object HiddenAPIMissing extends CheckedException
908end
909
910object TryAtomicFailure extends CheckedException
911end
912
913(* Should take a spawned thread as an argument *)
914object AtomicSpawnSynchronization extends {UncheckedException}
915end
916
917(************************************************************
918* \subsection*{Array support}
919************************************************************)
920
921trait HasRank extends Equality[\HasRank\] excludes { Number, AnyMaybe }
922  (** not yet: ``% comprises Array[\T,E,I\] where [\T,E,I\]{ T extends Array[\T,E,I\] }%'' *)
923  abstract rank():ZZ32
924  opr =(self, other:HasRank): Boolean
925end
926
927(* Declared Rank-n-ness *)
928trait Rank[\ nat n \] extends HasRank
929  rank():ZZ32
930end
931
932(** Potemkin exclusion traits.  Really we just want to say that
933    ``%Rank[\n\] excludes Rank[\m\] where { m =/= n }%'', but we cannot yet. *)
934
935trait Rank1 extends { Rank[\1\]} excludes { Rank2, Rank3, Number, String }
936end
937
938trait Rank2 extends { Rank[\2\]} excludes { Rank3, Number, String }
939end
940
941trait Rank3 extends { Rank[\3\]} excludes { Number, String }
942end
943
944(** The trait %Indexed_i[\n\]%
945   indicates that something has an $i^{th}$ dimension of size $n$.  In
946   general, anything which extends %Indexed_i% must also
947   extend %Indexed_j% for $j < i$. *)
948
949trait Indexed1[\ nat n \] end
950
951trait Indexed2[\ nat n \] end
952
953trait Indexed3[\ nat n \] end
954
955(** The indexed trait indicates that an object of type %T% can be
956indexed using type %I% to obtain elements with type %E%.
957
958An object %i% that is an instance of %Indexed% defines three basic things:
959
960  The indexing operator %opr []%, which must be defined for every instance of
961    the type.
962
963  A suite of generators: %i.indices% generates the index space of the
964    array.  %i% itself generates the values contained at those indices.
965    %i.indexValuePairs% yields pairs of %(index,val)%.  All of these
966    share the same natural order.  It is necessary to define one of
967    %indices()% and %indexValuePairs()%, in addition to %generate()% (but
968    the latter requirement can be dispensed by instead extending
969    %DelegatedIndexed%).
970
971  A set of utility functions, %assign%, %fill%, and %copy%.  Only %fill% and
972    %copy% need to be defined.
973**)
974trait Indexed[\E, I\] extends Generator[\E\]
975    (** %isEmpty()% indicates whether there are any valid indices.  It is
976        defined as %|self| = 0%. *)
977    getter isEmpty(): Boolean
978    getter nonEmpty(): Boolean
979    (** %size()% is depracted; use %|self|% instead. *)
980    abstract getter size(): ZZ32
981    (** %bounds()% yields a range of indices that are valid for the
982        indexed generator. *)
983    abstract getter bounds(): FullRange[\I,true\]
984    (** %indexValuePairs()% generates the elements of the indexed object
985        (exactly those elements that are generated by the object itself),
986        but each element is paired with its index.  When we obtain
987        %(i,v)% from %indexValuePairs()% we know that:
988        \begin{itemize}
989           \item %self[i] = v%
990           \item the %i% are distinct and %i IN bounds()%
991           \item stripping away the %i% yields exactly the results of %v <- self%
992        \end{itemize}
993        This generator attempts to follow the structure of the
994        underlying object as closely as possible.  *)
995    getter indexValuePairs(): Indexed[\(I,E),I\]
996    (** %indices()% yields the indices corresponding to the elements of
997        the indexed object---it corresponds to the index component of
998        %indexValuePairs()%.  This may in general be a subset of all the
999        valid indices represented by %bounds()%.  This generator
1000        attempts to follow the structure of the underlying object as
1001        closely as possible. *)
1002    getter indices(): Indexed[\I,I\]
1003    (** %|self|% indicates the number of distinct valid indices that may
1004        be passed to indexing operations. *)
1005    abstract opr |self| : ZZ32
1006    (** Indexing.  %i IN bounds()% must hold. *)
1007    abstract opr[i:I] : E
1008
1009    (** Indexing by ranges.  The results are 0-based when the
1010        underlying index type has a notion of 0.  This ensures
1011        consistency of behavior between types such as vectors that
1012        ``only'' support 0-indexing and types such as arrays that permit
1013        other choices of lower bounds.  The easiest way to write the
1014        index by ranges operation for an instance of %Indexed% is to
1015        take advantage of indexing on the ranges themselves by writing
1016        %(bounds())[r]% in order to narrow and bounds check the range %r%
1017        and obtain a closed range of indices on the underlying
1018        data. **)
1019    abstract opr[r:Range[\I\]] : Indexed[\E,I\]
1020    opr[_:OpenRange[\Any\]] : Indexed[\E,I\]
1021
1022    (** Roughly speaking, %ivmap(f)% is equivalent to
1023        %indexValuePairs.map(f)%.  However %ivmap% is not
1024        merely a convenient shortcut.  It is actually intended to
1025        create a copy of the underlying indexed structure when that is
1026        appropriate.
1027
1028        The usual %map% function in %Generator% should do the same (and
1029        does for the instances in this library).  Copying can be bad
1030        for space, but is complexity-preserving if the mapped
1031        generator is used more than once. **)
1032    ivmap[\R\](f:(I,E)->R): Indexed[\R, I\]
1033    map[\R\](f:E->R): Indexed[\R, I\]
1034
1035
1036    (** indexOf(e) returns an index at which e can be found,
1037        or Nothing if no such index exists. **)
1038    indexOf(e:E): Maybe[\I\]
1039end
1040
1041trait ZeroIndexed[\E\] extends Indexed[\E,ZZ32\]
1042    bounds(): FullRange[\ZZ32,true\]
1043    zip[\F\](g:ZeroIndexed[\F\]):ZeroIndexed[\(E,F)\]
1044end
1045
1046object DefaultZip[\E,F\](e:ZeroIndexed[\E\],f:ZeroIndexed[\F\])
1047        extends { ZeroIndexed[\(E,F)\], DelegatedIndexed[\(E,F),ZZ32\] }
1048    getter size(): ZZ32
1049    getter indices(): Generator[\ZZ32\]
1050    opr |self| : ZZ32
1051    opr[i:ZZ32]:(E,F)
1052    opr[r:Range[\ZZ32\]] : ZeroIndexed[\(E,F)\]
1053end
1054
1055trait LexicographicOrder[\T extends LexicographicOrder[\T,E\],E\]
1056        extends { StandardTotalOrder[\T\], ZeroIndexed[\E\] }
1057    opr CMP(self, other:T): TotalComparison
1058    (** We give a specialized version of %=% because it can fail faster
1059        than %CMP% by checking sizes early. **)
1060    opr =(self,other:T): Boolean
1061end
1062
1063toArray[\E\](g:Indexed[\E,ZZ32\]): Array[\E,ZZ32\]
1064
1065(** %DelegatedIndexed% is an indexed generator that has recourse to
1066    another indexed generator internally.  By default, this in turn
1067    is defined in terms of %indexValuePairs()%.  Thus, it is only
1068    necessary to define either %indexValuePairs()% or %indices()%.
1069
1070    This class is designed for convenience; it should not be used as a
1071    type in running code, but only as a supertype in lieu of %Indexed%.
1072**)
1073trait DelegatedIndexed[\E,I\] extends Indexed[\E,I\]
1074    getter generator(): Generator[\E\]
1075    getter size(): ZZ32
1076    opr |self| : ZZ32
1077    generate[\R\](r: Reduction[\R\], body: E->R): R
1078    seq(self): SequentialGenerator[\E\]
1079    cross[\G\](g: Generator[\G\]): Generator[\(E,G)\]
1080    mapReduce[\R\](body: E->R, join:(R,R)->R, zero:R): R
1081    reduce(j:(E,E)->E, z:E):E
1082    reduce(r: Reduction[\E\]):E
1083    loop(f:E->()): ()
1084end
1085
1086(** The %MutableIndexed% trait is an indexed trait whose elements can be
1087    mutated using indexed assignment.  Right now, we are using this type
1088    in a somewhat dangerous way, since, for example,
1089    %Array1[\E,b0,s0\]% extends both
1090    %Indexed[\Array1[\E,b0,s0\],E,ZZ32\]%
1091    and
1092    %Indexed[\Array[\E,ZZ32\],E,ZZ32\]%.
1093    We will need to find a solution to this at some point.  **)
1094trait MutableIndexed[\E, I\]
1095        extends { Indexed[\E,I\] }
1096    abstract opr[i:I]:=(v:E) : ()
1097
1098    (** For %Ranged% assignment, the extents of %r% and %v.bounds()% must
1099        match, but the lower bounds need not. **)
1100    abstract opr[r:Range[\I\]]:=(v:Indexed[\E,I\]) : ()
1101    opr[_:OpenRange[\Any\]]:=(v:Indexed[\E,I\]) : ()
1102end
1103
1104(** Array whose bounds are implicit rather than static, and which may
1105    be either mutable or immutable. *)
1106trait ReadableArray[\E,I\]
1107        extends { HasRank, Indexed[\E,I\], DelegatedIndexed[\E,I\] }
1108        comprises { Array[\E,I\], ImmutableArray[\E,I\] }
1109    (** CONCRETE GETTERS
1110        Default implementations of getters based on abstract methods
1111        below. **)
1112    getter indices(): Indexed[\I,I\]
1113    getter indexValuePairs(): Indexed[\(I,E),I\]
1114    getter generator(): Indexed[\E,I\]
1115
1116    (** CONCRETE METHODS
1117        Default implementations of most array stuff based on the above.
1118        The things we can't provide are anything involving replica. **)
1119
1120    opr[i:I]:E
1121
1122    (** Initialize element at index i with value v.  This should occur
1123        once, before any other access or assignment occurs to element
1124        i.  An error will be signaled if an uninitialized element is
1125        read or an initialized element is re-initialized. **)
1126    init(i:I, v:E)
1127
1128    generate[\R\](r: Reduction[\R\], body: E->R): R
1129    seq(self): SequentialGenerator[\E\]
1130
1131    (** 0-based non-bounds-checked indexing. **)
1132    abstract get(i:I): E
1133    abstract init0(i:I, e:E): ()
1134    abstract zeroIndices(): FullRange[\I,true\]
1135    (** Convert from %base%-based indexing to 0-based indexing,
1136        performing bounds checking. **)
1137    abstract offset(i:I): I
1138    (** Convert from 0-based indexing to %base%-based indexing. **)
1139    abstract toIndex(i:I): I
1140    (** Indexed functionality with more specific type information. **)
1141    abstract opr[r:Range[\I\]] : ReadableArray[\E,I\]
1142    abstract opr[_:OpenRange[\Any\]] : ReadableArray[\E,I\]
1143    abstract ivmap[\R\](f:(I,E)->R): ReadableArray[\R, I\]
1144    abstract map[\R\](f:E->R): ReadableArray[\R, I\]
1145
1146    (** Shift the origin of an array.  This should yield a new view of
1147        the same array; that is, initialization and/or update to either will
1148        be reflected in the other. **)
1149    abstract shift(newOrigin:I):ReadableArray[\E,I\]
1150
1151    (** Bulk initialization of an array using a given function or
1152        value.  These are defined with more specific self types in
1153        StandardImmutableArrayType. **)
1154    abstract fill(f:I->E):ReadableArray[\E,I\]
1155    abstract fill(v:E):ReadableArray[\E,I\]
1156
1157    abstract copy():ReadableArray[\E,I\]
1158
1159    (** Create a fresh array structurally identical to the present
1160        one, but holding elements of type %U%. **)
1161    abstract replica[\U\]():ReadableArray[\U,I\]
1162
1163    opr =(self, other:HasRank): Boolean
1164end
1165
1166trait ImmutableArray[\E,I\] extends { ReadableArray[\E,I\] }
1167        excludes { Array[\E,I\] }
1168    abstract opr[r:Range[\I\]] : ImmutableArray[\E,I\]
1169    abstract opr[_:OpenRange[\Any\]] : ImmutableArray[\E,I\]
1170    abstract ivmap[\R\](f:(I,E)->R): ImmutableArray[\R, I\]
1171    abstract map[\R\](f:E->R): ImmutableArray[\R, I\]
1172    abstract shift(newOrigin:I):ImmutableArray[\E,I\]
1173    abstract fill(f:I->E):ImmutableArray[\E,I\]
1174    abstract fill(v:E):ImmutableArray[\E,I\]
1175    abstract copy():ImmutableArray[\E,I\]
1176    abstract replica[\U\]():ImmutableArray[\U,I\]
1177
1178    (** Thaw array (return mutable copy). **)
1179    abstract thaw():Array[\E,I\]
1180end
1181
1182trait Array[\E,I\] extends { ReadableArray[\E,I\], MutableIndexed[\E,I\] }
1183    abstract put(i:I, e:E): ()
1184    opr[i:I]:=(v:E):()
1185
1186    opr[r:Range[\I\]]:=(a:Indexed[\E,I\]):()
1187
1188    abstract opr[r:Range[\I\]] : Array[\E,I\]
1189    abstract opr[_:OpenRange[\Any\]] : Array[\E,I\]
1190    abstract ivmap[\R\](f:(I,E)->R): Array[\R, I\]
1191    abstract map[\R\](f:E->R): Array[\R, I\]
1192    abstract shift(newOrigin:I):Array[\E,I\]
1193    abstract fill(f:I->E):Array[\E,I\]
1194    abstract fill(v:E):Array[\E,I\]
1195    abstract assign(f:I->E):Array[\E,I\]
1196    abstract copy():Array[\E,I\]
1197    abstract replica[\U\]():Array[\U,I\]
1198
1199    (** Freeze array (return mutable copy). **)
1200    abstract freeze(): ImmutableArray[\E,I\]
1201end
1202
1203(** Factory for arrays that returns an empty 0-indexed array of a given
1204    run-time-determined size. **)
1205array[\E\](x:ZZ32):Array[\E,ZZ32\]
1206array[\E\](x:ZZ32,y:ZZ32):Array[\E,(ZZ32,ZZ32)\]
1207array[\E\](x:ZZ32,y:ZZ32,z:ZZ32):Array[\E,(ZZ32,ZZ32,ZZ32)\]
1208
1209(** Factory for immutable arrays that returns an empty 0-indexed array
1210    of a given run-time-determined size. **)
1211immutableArray[\E\](x:ZZ32):ImmutableArray[\E,ZZ32\]
1212immutableArray[\E\](x:ZZ32,y:ZZ32):ImmutableArray[\E,(ZZ32,ZZ32)\]
1213immutableArray[\E\](x:ZZ32,y:ZZ32,z:ZZ32):ImmutableArray[\E,(ZZ32,ZZ32,ZZ32)\]
1214
1215primitiveArray[\E\](x:ZZ32):Array[\E,ZZ32\]
1216
1217primitiveImmutableArray[\E\](x:ZZ32):ImmutableArray[\E,ZZ32\]
1218
1219(** NOTE: %StandardImmutableArrayType% is a parent of
1220    %StandardMutableArrayType%.  It therefore does not extend
1221    %ImmutableArray% as you might expect.  Other types that extend
1222    it should also extend %ImmutableArray% explicitly. **)
1223trait StandardImmutableArrayType[\T extends StandardImmutableArrayType[\T,E,I\],E,I\]
1224        extends { ReadableArray[\E,I\] }
1225    fill(f:I->E):T
1226    fill(v:E):T
1227    abstract copy():T
1228end
1229
1230
1231trait StandardMutableArrayType[\T extends StandardMutableArrayType[\T,E,I\],E,I\]
1232        extends { StandardImmutableArrayType[\T,E,I\], Array[\E,I\] }
1233    assign(v:T):T
1234    assign(f:I->E):T
1235end
1236
1237(** Canonical partitioning of a positive number %x% into two pieces.  If
1238   %(a,b) = partition(n)%
1239   and $n > 0$ then $0 < a <= b$, $n = a + b$.
1240   As it turns out we choose $a$ to be the largest power of $2 < n$.
1241*)
1242partition(x:ZZ32):(ZZ32,ZZ32)
1243
1244(** A %ReadableArray1[\T,b0,s0\]% is
1245    an arbitrary 1-dimensional array whose %s0% elements are of
1246    type %T%, and whose lowest index is %b0%.
1247
1248    The natural order of all generators is from %b0% to
1249    %b0+s0-1%. **)
1250trait ReadableArray1[\T, nat b0, nat s0\]
1251        extends { Indexed1[\s0\], Rank1, ReadableArray[\T,ZZ32\] }
1252        comprises { ImmutableArray1[\T,b0,s0\], Array1[\T,b0,s0\] }
1253    getter size():ZZ32
1254    getter bounds():FullRange[\ZZ32,true\]
1255    abstract getter mutability():String
1256    getter toString()
1257    opr |self| : ZZ32
1258
1259    subarray[\nat b, nat s, nat o\]():ReadableArray1[\T, b, s\]
1260
1261    (** Offset converts from %b0%-indexing to 0-indexing,
1262        bounds checking en route. *)
1263    offset(i:ZZ32):ZZ32
1264    toIndex(i:ZZ32):ZZ32
1265
1266    zeroIndices(): FullRange[\ZZ32,true\]
1267end
1268
1269trait ImmutableArray1[\T, nat b0, nat s0\]
1270    extends { StandardImmutableArrayType[\ImmutableArray1[\T,b0,s0\],T,ZZ32\],
1271              ImmutableArray[\T,ZZ32\], ReadableArray1[\T,b0,s0\] }
1272    getter mutability():String
1273    shift(o:ZZ32): ImmutableArray[\T,ZZ32\]
1274    opr[r: Range[\ZZ32\]] : ImmutableArray[\T,ZZ32\]
1275    opr[_:OpenRange[\ZZ32\]] : ImmutableArray1[\T,0,s0\]
1276    opr[_:OpenRange[\Any\]] : ImmutableArray1[\T,0,s0\]
1277
1278    (** %subarray% selects a subarray of this array based on static parameters.
1279        %b#s% are the new bounds of the array; %o% is
1280        the index of the subarray within the current array. **)
1281    subarray[\nat b, nat s, nat o\]():ImmutableArray1[\T, b, s\]
1282
1283    (** The %replica% method returns a replica of the array (similar layout
1284        etc.) but with a different element type. *)
1285    replica[\U\]():ImmutableArray1[\U,b0,s0\]
1286
1287    copy():ImmutableArray1[\T,b0,s0\]
1288
1289    thaw():Array1[\T,b0,s0\]
1290    map[\R\](f:T->R): ImmutableArray1[\R,b0,s0\]
1291    ivmap[\R\](f:(ZZ32,T)->R): ImmutableArray1[\R,b0,s0\]
1292end
1293
1294(** %Array1[\T,b0,s0\]% is a 1-dimension array whose %s0% elements are of
1295    type %T%, and whose lowest index is %b0%. **)
1296trait Array1[\T, nat b0, nat s0\]
1297    extends { ReadableArray1[\T,b0,s0\],
1298              StandardMutableArrayType[\Array1[\T,b0,s0\],T,ZZ32\] }
1299    excludes {Number, String}
1300
1301    getter mutability():String
1302
1303    shift(o:ZZ32): Array[\T,ZZ32\]
1304
1305    opr[r: Range[\ZZ32\]] : Array[\T,ZZ32\]
1306    opr[_:OpenRange[\ZZ32\]] : Array1[\T,0,s0\]
1307    opr[_:OpenRange[\Any\]] : Array1[\T,0,s0\]
1308
1309    subarray[\nat b, nat s, nat o\]():Array1[\T, b, s\]
1310
1311    replica[\U\]():Array1[\U,b0,s0\]
1312
1313    copy():Array1[\T,b0,s0\]
1314    freeze():ImmutableArray1[\T,b0,s0\]
1315    map[\R\](f:T->R): Array1[\R,b0,s0\]
1316    ivmap[\R\](f:(ZZ32,T)->R): Array1[\R,b0,s0\]
1317end
1318
1319trait AnyVector end
1320
1321trait Vector[\T extends Number, nat s0\]
1322        extends { AnyVector, Array1[\T,0,s0\], AdditiveGroup[\Vector[\T,s0\]\] }
1323        excludes { AnyMultiplicativeRing }
1324    opr +(self, v:Vector[\T,s0\]): Vector[\T,s0\]
1325    opr -(self, v:Vector[\T,s0\]): Vector[\T,s0\]
1326    opr -(self): Vector[\T,s0\]
1327    scale(t: T): Vector[\T,s0\]
1328    pmul(v: Vector[\T,s0\]): Vector[\T,s0\]
1329    dot(v: Vector[\T,s0\]): T
1330end
1331
1332(** %__builtinFactory1% must be a non-overloaded 0-parameter factory for
1333   1-D arrays.  The type parameters are enshrined in \texttt{LHSEvaluator.java}
1334   and \texttt{NonPrimitive.java}; the factory name is enshrined in
1335   \texttt{WellKnownNames.java}.  There must be some factory, named in this
1336   file, with this type signature.  A similar thing is true for
1337   $k$-dimensional array types. *)
1338__builtinFactory1[\T, nat b0, nat s0\]():Array1[\T,b0,s0\]
1339
1340(** %__immutableFactory1% is a non-overloaded 0-parameter factory for
1341   0-indexed 1-D write-once arrays.  It is also mentioned in \texttt{WellKnownNames} as it
1342   is used to allocate storage for varargs. *)
1343__immutableFactory1[\T, nat b0, nat s0\]():Array1[\T,b0,s0\]
1344
1345array1[\T, nat s0\]():Array1[\T,0,s0\]
1346array1[\T, nat s0\](v:T):Array1[\T,0,s0\]
1347array1[\T, nat s0\](f:ZZ32->T):Array1[\T,0,s0\]
1348
1349immutableArray1[\T, nat s0\](): ImmutableArray1[\T,0,s0\]
1350
1351(** %vector% is the same as %array1%, but specialized to numeric type arguments. *)
1352vector[\T extends Number, nat s0\]():Vector[\T,s0\]
1353vector[\T extends Number, nat s0\](v:T):Vector[\T,s0\]
1354vector[\T extends Number, nat s0\](f:ZZ32->T):Vector[\T,s0\]
1355
1356
1357opr +[\ T extends Number, nat n, nat m \]
1358     (me : Vector[\T,n\], other : Vector[\T,n\]):Vector[\T,n\]
1359
1360opr -[\ T extends Number, nat n, nat m \]
1361     (me : Vector[\T,n\], other : Vector[\T,n\]):Vector[\T,n\]
1362
1363opr -[\ T extends Number, nat n, nat m \]
1364     (me : Vector[\T,n\]):Vector[\T,n\]
1365
1366pmul[\ T extends Number, nat k \]
1367    (a : Vector[\T,k\], b : Vector[\T,k\]):Vector[\T,k\]
1368
1369opr DOT[\ T extends Number, nat n, nat m, nat p \]
1370       (me : Vector[\T,n\], other : Vector[\T,n\]):T
1371
1372opr juxtaposition[\ T extends Number, nat n, nat m, nat p \]
1373     (me : Vector[\T,n\], other : Vector[\T,n\]):T
1374
1375opr DOT[\ T extends Number, nat n, nat m, nat p \]
1376       (me : Vector[\T,n\], other : T) : Vector[\T,n\]
1377
1378opr juxtaposition[\ T extends Number, nat n, nat m, nat p \]
1379     (me : Vector[\T,n\], other : T) : Vector[\T,n\]
1380
1381opr DOT[\ T extends Number, nat n, nat m, nat p \]
1382        (other : T, me : Vector[\T,n\]) : Vector[\T,n\]
1383
1384opr juxtaposition[\ T extends Number, nat n, nat m, nat p \]
1385     (other : T, me : Vector[\T,n\]) : Vector[\T,n\]
1386
1387squaredNorm[\T extends Number, nat s0\](a:Vector[\T,s0\]):T
1388
1389opr ||[\ T extends Number, nat k \]me : Vector[\T,k\]|| : RR64
1390
1391(** %Array2[\T,b0,s0,b1,s1\]%
1392    is the type of 2-dimensional arrays of element type %T%, with
1393    size %s0% in the first dimension and %s1% in the second
1394    dimension and lowest index %(b0,b1)%.  Natural order for
1395    all generators in each dimension is from $b$ to $b+s-1$; the
1396    overall order of elements need only be consistent with the cross
1397    product of these orderings (see %Generator.cross()%). **)
1398trait Array2[\T, nat b0, nat s0, nat b1, nat s1\]
1399    extends { Indexed1[\s0\], Indexed2[\s1\], Rank2,
1400              StandardMutableArrayType[\Array2[\T,b0,s0,b1,s1\],T,(ZZ32,ZZ32)\] }
1401    excludes { Number, String }
1402  getter size():ZZ32
1403  getter bounds():FullRange[\(ZZ32,ZZ32),true\]
1404  getter toString()
1405  opr |self| : ZZ32
1406  (** Translate from %b0%, %b1%-indexing to 0-indexing, checking bounds. **)
1407  offset(t1:(ZZ32,ZZ32)):(ZZ32,ZZ32)
1408  toIndex(t1:(ZZ32,ZZ32)):(ZZ32,ZZ32)
1409  opr[x:ZZ32,y:ZZ32]:=(v:T):()
1410  opr[r:Range[\(ZZ32,ZZ32)\]]: Array[\T,(ZZ32,ZZ32)\]
1411  opr[_:OpenRange[\ZZ32\]] : Array2[\T,0,s0,0,s1\]
1412  opr[_:OpenRange[\Any\]] : Array2[\T,0,s0,0,s1\]
1413  shift(t1:(ZZ32,ZZ32)): Array[\T,(ZZ32,ZZ32)\]
1414
1415  (** 2-D subarray given static subarray parameters.
1416      %(bo1,bo2)#(so1,so2)% are output bounds.
1417      The result is the subarray starting at %(o0,o1)% in the original array.
1418   **)
1419  subarray[\nat bo0, nat so0, nat bo1, nat so1, nat o0, nat o1\]
1420          (): Array2[\T,bo0,so0,bo1,so1\]
1421
1422  zeroIndices():FullRange[\(ZZ32,ZZ32),true\]
1423
1424  replica[\U\]():Array2[\U,b0,s0,b1,s1\]
1425  copy():Array2[\T,b0,s0,b1,s1\]
1426  put(t1:(ZZ32, ZZ32), v:T) : ()
1427  get(t1:(ZZ32, ZZ32)):T
1428  t():Array2[\T,b1,s1,b0,s0\]
1429  (* Copied here for better return type information. *)
1430  map[\R\](f:T->R): Array2[\R,b0,s0,b1,s1\]
1431  ivmap[\R\](f:((ZZ32,ZZ32),T)->R): Array2[\R,b0,s0,b1,s1\]
1432
1433  freeze():ImmutableArray[\T,(ZZ32,ZZ32)\]
1434end
1435
1436trait AnyMatrix end
1437
1438trait Matrix[\T extends Number, nat s0, nat s1\]
1439        extends { AnyMatrix, Array2[\T, 0, s0, 0, s1\], AdditiveGroup[\Matrix[\T,s0,s1\]\] }
1440        excludes { AnyMultiplicativeRing }
1441    opr +(self, v:Matrix[\T,s0,s1\]): Matrix[\T,s0,s1\]
1442    opr -(self, v:Matrix[\T,s0,s1\]): Matrix[\T,s0,s1\]
1443    opr -(self): Matrix[\T,s0,s1\]
1444    scale(t1: T): Matrix[\T,s0,s1\]
1445    mul[\ nat s2 \](other: Matrix[\T,s1,s2\]): Matrix[\T,s0,s2\]
1446    rmul(v: Vector[\T,s1\]): Vector[\T,s0\]
1447    lmul(v: Vector[\T,s0\]): Vector[\T,s1\]
1448    t(): Matrix[\T,s1,s0\]
1449end
1450
1451__builtinFactory2[\T,nat b0,nat s0,nat b1,nat s1\]():Array2[\T,b0,s0,b1,s1\]
1452
1453(** %array2% is a factory for 0-based 2-D arrays. **)
1454array2[\T, nat s0, nat s1\]():Array2[\T,0,s0,0,s1\]
1455array2[\T, nat s0, nat s1\](v:T):Array2[\T,0,s0,0,s1\]
1456array2[\T, nat s0, nat s1\](f:(ZZ32,ZZ32)->T):Array2[\T,0,s0,0,s1\]
1457
1458(** %matrix% is the same as %array2%, but specialized to numeric type
1459   arguments, except that the default value (if given) is used to
1460   construct a multiple of the identity matrix. **)
1461matrix[\T extends Number, nat s0, nat s1\]():Matrix[\T,s0,s1\]
1462matrix[\T extends Number, nat s0, nat s1\](v:T):Matrix[\T,s0,s1\]
1463
1464opr +[\ T extends Number, nat n, nat m \]
1465     (me:Matrix[\T,n,m\], other:Matrix[\T,n,m\]): Matrix[\T,n,m\]
1466
1467opr -[\ T extends Number, nat n, nat m \]
1468     (me:Matrix[\T,n,m\], other:Matrix[\T,n,m\]) : Matrix[\T,n,m\]
1469
1470opr -[\ T extends Number, nat n, nat m \]
1471     (me:Matrix[\T,n,m\]): Matrix[\T,n,m\]
1472
1473(** Matrix multiplication. *)
1474opr DOT[\ T extends Number, nat n, nat m, nat p\]
1475       (me:Matrix[\T,n,m\], other:Matrix[\T,m,p\]): Matrix[\T,n,p\]
1476
1477opr juxtaposition[\ T extends Number, nat n, nat m, nat p\]
1478     (me:Matrix[\T,n,m\], other:Matrix[\T,m,p\]): Matrix[\T,n,p\]
1479
1480(** Matrix-vector multiplication. *)
1481opr DOT[\ T extends Number, nat n, nat m, nat p \]
1482       (me:Matrix[\T,n,m\], v:Vector[\T,m\]):Vector[\T,n\]
1483
1484opr juxtaposition[\ T extends Number, nat n, nat m, nat p \]
1485     (me:Matrix[\T,n,m\], v:Vector[\T,m\]):Vector[\T,n\]
1486
1487(** Vector-matrix multiplication. *)
1488opr DOT[\ T extends Number, nat n, nat m, nat p \]
1489       (v:Vector[\T,n\], me:Matrix[\T,n,m\]):Vector[\T,m\]
1490
1491opr juxtaposition[\ T extends Number, nat n, nat m, nat p \]
1492     (v:Vector[\T,n\], me:Matrix[\T,n,m\]):Vector[\T,m\]
1493
1494opr DOT[\ T extends Number, nat n, nat m, nat p \]
1495       (me : Matrix[\T,n,m\], other : T) : Matrix[\T,n,m\]
1496
1497opr juxtaposition[\ T extends Number, nat n, nat m, nat p \]
1498     (me : Matrix[\T,n,m\], other : T) : Matrix[\T,n,m\]
1499
1500opr DOT[\ T extends Number, nat n, nat m, nat p \]
1501       (other : T, me : Matrix[\T,n,m\]) : Matrix[\T,n,m\]
1502
1503opr juxtaposition[\ T extends Number, nat n, nat m, nat p \]
1504     (other : T, me : Matrix[\T,n,m\]) : Matrix[\T,n,m\]
1505
1506(** %Array3[\T,b0,s0,b1,s1,b2,s2\]% is the type of 3-dimensional arrays
1507    of element type %T%, with size %s_i% in the $i^{th}$ dimension and lowest
1508    index %(b0,b1,b2)%.  Natural order for all generators in each
1509    dimension is from %b% to %b+s-1%; the overall order of elements need
1510    only be consistent with the cross product of these orderings (see
1511    %Generator.cross()%). **)
1512trait Array3[\T, nat b0, nat s0, nat b1, nat s1, nat b2, nat s2\]
1513    extends { Indexed1[\s0\], Indexed2[\s1\], Indexed3[\s2\], Rank3,
1514              StandardMutableArrayType[\Array3[\T,b0,s0,b1,s1,b2,s2\],T,
1515                                        (ZZ32,ZZ32,ZZ32)\] }
1516    excludes { Number, String }
1517
1518    getter size():ZZ32
1519    getter bounds():FullRange[\(ZZ32,ZZ32,ZZ32),true\]
1520
1521    getter toString():String
1522
1523    opr |self| : ZZ32
1524
1525    (** Again, %offset% performs bounds checking and shifts to 0-indexing. *)
1526    offset(t:(ZZ32,ZZ32,ZZ32)):(ZZ32,ZZ32,ZZ32)
1527    toIndex(t:(ZZ32,ZZ32,ZZ32)):(ZZ32,ZZ32,ZZ32)
1528
1529    (** And %get% and %put% are 0-indexed without bounds checks. *)
1530    abstract put(t:(ZZ32,ZZ32,ZZ32), v:T) : ()
1531    abstract get(t:(ZZ32,ZZ32,ZZ32)):T
1532
1533    opr[i:ZZ32, j:ZZ32, k:ZZ32] := (v:T)
1534    opr[r:Range[\(ZZ32,ZZ32,ZZ32)\]]: Array[\T,(ZZ32,ZZ32,ZZ32)\]
1535    opr[_:OpenRange[\ZZ32\]] : Array3[\T,0,s0,0,s1,0,s2\]
1536    opr[_:OpenRange[\Any\]] : Array3[\T,0,s0,0,s1,0,s2\]
1537    shift(t:(ZZ32,ZZ32,ZZ32)): Array[\T,(ZZ32,ZZ32)\]
1538
1539    (** 2-D subarray given static subarray parameters.
1540        %(bo1,bo2)#(so1,so2)% are output bounds.
1541        The result is the subarray starting at %(o0,o1)% in the original array.
1542     **)
1543    subarray[\nat bo0, nat so0, nat bo1, nat so1, nat bo2, nat so2,
1544              nat o0, nat o1, nat o2\]
1545            (): Array3[\T,bo0,so0,bo1,so1,bo2,so2\]
1546
1547    zeroIndices():FullRange[\(ZZ32,ZZ32,ZZ32),true\]
1548
1549    replica[\U\]():Array3[\U,b0,s0,b1,s1,b2,s2\]
1550    copy():Array3[\T,b0,s0,b1,s1,b2,s2\]
1551    map[\R\](f:T->R): Array3[\R,b0,s0,b1,s1,b2,s2\]
1552    ivmap[\R\](f:((ZZ32,ZZ32,ZZ32),T)->R): Array3[\R,b0,s0,b1,s1,b2,s2\]
1553
1554    freeze():ImmutableArray[\T,(ZZ32,ZZ32,ZZ32)\]
1555end
1556
1557__builtinFactory3[\T, nat b0, nat s0, nat b1, nat s1, nat b2, nat s2\]():
1558        Array3[\T,b0,s0,b1,s1,b2,s2\]
1559
1560array3[\T,nat s0, nat s1, nat s2\]():Array3[\T,0,s0,0,s1,0,s2\]
1561
1562(************************************************************
1563* \subsection*{Reductions}
1564************************************************************)
1565
1566trait Reduction[\R\] end
1567
1568(** Invariants:
1569    join must be associative with identity empty
1570    unlift(lift(x)) = x
1571 **)
1572trait ActualReduction[\R,L\] extends Reduction[\R\]
1573    abstract getter toString()
1574    abstract empty(): L
1575    abstract join(a: L, b: L): L
1576    abstract lift(r:R): L
1577    abstract unlift(l:L): R
1578    (** If this reduction left-distributes over r, return a pair of
1579        reductions with the same lift and unlift **)
1580    leftDistribute(r: Reduction[\R\]): Maybe[\(Reduction[\R\],Reduction[\R\])\]
1581    (** If this reduction right-distributes over r, return a pair of
1582        reductions with the same lift and unlift **)
1583    rightDistribute(r: Reduction[\R\]): Maybe[\(Reduction[\R\],Reduction[\R\])\]
1584    (** If this reduction distributes over r, return a pair of
1585        reductions with the same lift and unlift **)
1586    distribute(r: Reduction[\R\]): Maybe[\(Reduction[\R\],Reduction[\R\])\]
1587end
1588
1589trait PossibleReductionPair[\R\] extends Condition[\SomeReductionPair[\R\]\]
1590    comprises { NoReductionPair[\R\], SomeReductionPair[\R\] }
1591end
1592
1593object NoReductionPair[\R\] extends PossibleReductionPair[\R\]
1594    getter holds(): Boolean
1595    getter cond[\G\](t:PossibleReductionPair[\R\]->G, e:()->G): G
1596end
1597
1598trait SomeReductionPair[\R\] extends PossibleReductionPair[\R\]
1599    getter holds(): Boolean
1600    getter cond[\G\](t:PossibleReductionPair[\R\]->G, e:()->G): G
1601    abstract getter outer(): Reduction[\R\]
1602    abstract getter inner(): Reduction[\R\]
1603end
1604
1605trait ReductionPair[\R,L\] extends SomeReductionPair[\R\]
1606    abstract getter outer(): ActualReduction[\R,L\]
1607    abstract getter inner(): ActualReduction[\R,L\]
1608end
1609
1610(** The usual lifting to Maybe for identity-less operators **)
1611trait AssociativeReduction[\R\] extends ActualReduction[\R,AnyMaybe\]
1612    empty(): Nothing[\R\]
1613    join(a: AnyMaybe, b: AnyMaybe): AnyMaybe
1614    abstract simpleJoin(a:Any, b:Any): Any
1615    lift(r:Any): AnyMaybe
1616    unlift(r:AnyMaybe): R
1617end
1618
1619trait CommutativeReduction[\R\] extends AssociativeReduction[\R\] end
1620
1621(** Monoids don't require a special lift and unlift operation. **)
1622trait MonoidReduction[\R\] extends ActualReduction[\R,R\]
1623    lift(r:R): R
1624    unlift(r:R): R
1625end
1626
1627trait CommutativeMonoidReduction[\R\] extends MonoidReduction[\R\] end
1628
1629trait ReductionWithZeroes[\R,L\] extends ActualReduction[\R,L\]
1630    isLeftZero(l:L): Boolean
1631    isRightZero(l:L): Boolean
1632    isZero(l:L): Boolean
1633end
1634
1635trait BigOperator[\I,O,R,L\]
1636    abstract getter reduction(): ActualReduction[\R,L\]
1637    abstract getter body(): I->R
1638    abstract getter unwrap(): R->O
1639end
1640
1641object BigReduction[\R,L\](r:ActualReduction[\R,L\]) extends BigOperator[\R,R,R,L\]
1642    getter reduction(): ActualReduction[\R,L\]
1643    getter body(): R->R
1644    getter unwrap(): R->R
1645end
1646
1647object Comprehension[\I,O,R,L\](u: R->O, r: ActualReduction[\R,L\], singleton:I->R)
1648        extends BigOperator[\I,O,R,L\]
1649    getter reduction(): ActualReduction[\R,L\]
1650    getter body(): I->R
1651    getter unwrap(): R->O
1652end
1653
1654(** VoidReduction is usually done for effect, so we pretend that
1655    the completion performs the effects.  This rules out things
1656    distributing over void (that would change the number of effects in
1657    our program) but not void distributing over other things. **)
1658object VoidReduction extends { CommutativeMonoidReduction[\()\] }
1659    getter toString()
1660    empty(): ()
1661    join(a: (), b: ()): ()
1662end
1663
1664(* Hack to permit any Number to work non-parametrically. *)
1665object SumReduction extends CommutativeMonoidReduction[\Number\]
1666    getter toString()
1667    empty(): Number
1668    join(a: Number, b: Number): Number
1669end
1670
1671opr SUM[\T extends Number\](): Comprehension[\T,Number,Number,Number\]
1672
1673object ProdReduction extends CommutativeMonoidReduction[\Number\]
1674    getter toString()
1675    empty(): Number
1676    join(a:Number, b:Number): Number
1677end
1678
1679opr PROD[\T extends Number\](): Comprehension[\T,Number,Number,Number\]
1680
1681object MinReduction[\T extends StandardMin[\T\]\] extends CommutativeReduction[\T\]
1682    getter toString()
1683    simpleJoin(a:T, b:T): T
1684end
1685
1686opr BIG MIN[\T extends StandardMin[\T\]\](): BigReduction[\T,AnyMaybe\]
1687
1688object MaxReduction[\T extends StandardMax[\T\]\] extends CommutativeReduction[\T\]
1689    getter toString()
1690    simpleJoin(a:T, b:T): T
1691end
1692
1693opr BIG MAX[\T extends StandardMax[\T\]\](): BigReduction[\T,AnyMaybe\]
1694
1695opr BIG MINNUM(): BigReduction[\RR64,RR64\]
1696
1697opr BIG MAXNUM(): BigReduction[\RR64,RR64\]
1698
1699(** AndReduction and OrReduction take advantage of natural zeroes for early exit. **)
1700object AndReduction
1701        extends { CommutativeMonoidReduction[\Boolean\],
1702                  ReductionWithZeroes[\Boolean,Boolean\] }
1703    getter toString()
1704    empty(): Boolean
1705    join(a: Boolean, b: Boolean): Boolean
1706    isZero(a:Boolean): Boolean
1707end
1708
1709opr BIG AND[\T\](): BigReduction[\Boolean,Boolean\]
1710
1711object OrReduction
1712        extends { CommutativeMonoidReduction[\Boolean\],
1713                  ReductionWithZeroes[\Boolean,Boolean\] }
1714    getter toString()
1715    empty(): Boolean
1716    join(a: Boolean, b: Boolean): Boolean
1717    isZero(a:Boolean): Boolean
1718end
1719
1720opr BIG OR[\T\]():BigReduction[\Boolean, Boolean\]
1721
1722(** A reduction performing String concatenation **)
1723object StringReduction extends MonoidReduction[\String\]
1724    getter toString()
1725    empty(): String
1726    join(a:String, b:String): String
1727end
1728
1729(** A reduction performing String concatenation with a space **)
1730object SpaceReduction extends MonoidReduction[\String\]
1731    getter toString()
1732    empty(): String
1733    join(a:String, b:String): String
1734end
1735
1736(** A reduction performing String concatenation with newline separation **)
1737object NewlineReduction extends AssociativeReduction[\String\]
1738    getter toString()
1739    simpleJoin(a:String, b:String): String
1740end
1741
1742(** This operator performs string concatenation, first converting
1743    its inputs (of type Any) to String if necessary. **)
1744opr BIG ||(): Comprehension[\Any,String,String,String\]
1745
1746(** This operator performs string concatenation, first converting
1747    its inputs (of type Any) to String if necessary, and separating
1748    non-empty components by a space. **)
1749opr BIG |||(): Comprehension[\Any,String,String,String\]
1750
1751(** This operator performs string concatenation with newline
1752    separation, first converting its inputs (of type Any) to String if
1753    necessary. **)
1754opr BIG //(): Comprehension[\Any,String,AnyMaybe,AnyMaybe\]
1755
1756(** A %MapReduceReduction% takes an associative binary function %j% on
1757    arguments of type %R%, and the identity of that function %z%, and
1758    returns the corresponding reduction. **)
1759object MapReduceReduction[\R\](j:(R,R)->R, z:R) extends MonoidReduction[\R\]
1760    getter toString()
1761    empty(): R
1762    join(a:R, b:R): R
1763end
1764
1765(** A %MIMapReduceReduction% takes an associative binary function %j% on
1766    arguments of type %R%, and the identity of that function %z%, and
1767    returns the corresponding reduction. **)
1768object MIMapReduceReduction[\R\](j:(Any,Any)->R, z:Any) extends MonoidReduction[\Any\]
1769    getter toString()
1770    empty(): R
1771    join(a:Any, b:Any): R
1772end
1773
1774(** %embiggen% takes a type %T% and an operation (either an operator
1775    %OP% or binary function %f% on type %T%), along with the identity
1776    %z% of the operation, and returns a function suitable as the right-hand
1777    side of the definition of the corresponding BIG operator. **)
1778(*
1779embiggen[\T,opr OP\](z:T): ((Reduction[\T\],T->T) -> T) -> T
1780*)
1781embiggen[\T\](j:(Any,Any)->T, z:T) : Comprehension[\T,T,Any,Any\]
1782
1783trait FilterGenerator[\E\] extends Generator[\E\]
1784    getter g(): Generator[\E\]
1785    getter p(): E -> Condition[\()\]
1786    getter toString(): String
1787    generate[\R\](r:Reduction[\R\], m: E->R): R
1788    reduce(r: Reduction[\E\]): E
1789    filter(p': E -> Condition[\()\]): FilterGenerator[\E\]
1790    seq(self)
1791end
1792
1793(************************************************************
1794* \subsection*{Ranges}
1795************************************************************
1796
1797** Ranges in general represent uses of the %#% and %:% operators.
1798    It is mostly subtypes of %Range% that are interesting.
1799
1800    The partial order on ranges describes containment:
1801      %a < b% if and only if all points in %a% are strictly contained in %b%.
1802 **)
1803trait Range[\T\]
1804    extends StandardPartialOrder[\Range[\T\]\]
1805    comprises { RangeWithLower[\T\], RangeWithUpper[\T\],
1806                RangeWithExtent[\T\], PartialRange[\T\] }
1807    excludes { Number }
1808   
1809    opr =(self,_:Range[\T\]): Boolean
1810end
1811
1812trait PartialRange[\T\] extends Range[\T\]
1813    comprises { OpenRange[\T\],
1814                LowerRange[\T\], UpperRange[\T\], ExtentRange[\T\] }
1815    excludes { CompleteRange[\T\] }
1816end
1817
1818object OpenRange[\T\] extends { Range[\T\], PartialRange[\T\] }
1819    toString():String
1820    opr =(self,_:OpenRange[\T\]): Boolean
1821    opr CMP(self,other:Range[\T\]): Comparison
1822end
1823
1824opr PARTIAL_LEXICO(a:Comparison, b:Comparison)
1825opr PARTIAL_LEXICO(a:Comparison, b:()->Comparison)
1826
1827trait RangeWithLower[\T\] extends Range[\T\]
1828        comprises { LowerRange[\T\], CompleteRange[\T\] }
1829    abstract getter lower():T
1830end
1831
1832object LowerRange[\T\](lo:T) extends { RangeWithLower[\T\], PartialRange[\T\] }
1833    getter lower():T
1834    toString():String
1835    opr =(self, x:LowerRange[\T\]): Boolean
1836    opr CMP(self, other:Range[\T\]): Comparison
1837end
1838
1839trait RangeWithUpper[\T\] extends Range[\T\]
1840        comprises { UpperRange[\T\], CompleteRange[\T\] }
1841    abstract getter upper():T
1842end
1843
1844object UpperRange[\T\](up:T) extends { RangeWithUpper[\T\], PartialRange[\T\] }
1845    getter upper():T
1846    toString():String
1847    opr =(self,x:UpperRange[\T\]): Boolean
1848    opr CMP(self, other:Range[\T\]): Comparison
1849end
1850
1851trait RangeWithExtent[\T\] extends Range[\T\]
1852        comprises { ExtentRange[\T\], CompleteRange[\T\] }
1853    abstract getter extent():T
1854    toString():String
1855end
1856
1857object ExtentRange[\T\](ex:T) extends { RangeWithExtent[\T\], PartialRange[\T\] }
1858    getter extent():T
1859    opr =(self,x:ExtentRange[\T\]): Boolean
1860    opr CMP(self, other:Range[\T\]): Comparison
1861end
1862
1863(** The type %CompleteRange[\T\]% is really just %FullRange[\T,flag\]% for
1864    either setting of %flag%.  We need it for stuff like %typecase%
1865    and %extends% clauses since we can't bind universally quantified
1866    variables in those settings.  Since essentially all the methods are
1867    independent of the setting of flag we include them here. **)
1868trait CompleteRange[\T\]
1869        extends { RangeWithLower[\T\], RangeWithUpper[\T\],
1870                  RangeWithExtent[\T\], Indexed[\T,T\] }
1871        comprises { FullRange[\T,true\], FullRange[\T,false\] }
1872    getter indices(): FullRange[\T,true\]
1873    abstract getter isBounded(): Boolean
1874    abstract getter isSized(): Boolean
1875    abstract getter increment(): T
1876
1877    (** The following two methods are used in bounds checking code to
1878        permit ranges that are just outside the edge of the given
1879        range.   Because they're intended for internal use we ignore
1880        the setting of flag and return a CompleteRange. **)
1881    abstract widenUpper(): CompleteRange[\T\]
1882    abstract widenLower(): CompleteRange[\T\]
1883
1884    opr[r:Range[\T\]]: FullRange[\T,true\]
1885    opr[_:OpenRange[\T\]]: FullRange[\T,true\]
1886    (** Square-bracket indexing on a FullRange restricts that range to
1887         the range provided.  Restriction should behave as follows:
1888            - Restriction to an OpenRange is the identity.
1889            - An UpperRange or ExtentRange restrict the upper bound and
1890              extent of the range.
1891            - A LowerRange restricts the lower bound and extent of the range.
1892        Note that this makes it compatible with the square-bracket
1893        indexing of the Indexed trait. **)
1894    opr[r:LowerRange[\T\]]: FullRange[\T,true\]
1895    opr[r:UpperRange[\T\]]: FullRange[\T,true\]
1896    opr[r:ExtentRange[\T\]]: FullRange[\T,true\]
1897    opr[r:CompleteRange[\T\]]: FullRange[\T,true\]
1898    toString():String
1899    opr =(self, other:CompleteRange[\T\]): Boolean
1900    opr CMP(self, other:Range[\T\]): Comparison
1901end
1902
1903(** A %FullRange% is either bounded (generated from a lower and upper
1904    bound, as in %l:u%) or sized (generated from a lower bound and a
1905    size, as in %l#s%).  These two kinds of range behave identically
1906    in most settings; the only time they behave differently is when we
1907    construct a strided range: both %l:u:i% and %l#s:i% generate
1908    elements %l, l+i, l+2i, ...%, but the former is bounded and
1909    generates no element larger than %i% and the latter is sized and
1910    generates exactly %s% elements.
1911
1912    Data structure bounds are always bounded. **)
1913trait FullRange[\T, bool bounded\] extends CompleteRange[\T\]
1914        comprises { ... }
1915    getter isBounded(): Boolean
1916    getter isSized(): Boolean
1917end
1918
1919(** The %#% and %:% operators serve as factories for parallel ranges. **)
1920opr #[\I extends AnyIntegral\](lo:I, ex:I): FullRange[\I,false\]
1921(*
1922opr #(lo:IntLiteral, ex:IntLiteral): FullRange[\ZZ32\]
1923*)
1924opr #[\I extends AnyIntegral, J extends AnyIntegral\]
1925     (lo:(I,J), ex:(I,J)): FullRange[\(I,J),false\]
1926opr #[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
1927     (lo:(I,J,K), ex:(I,J,K)): FullRange[\(I,J,K),false\]
1928
1929opr :[\I extends AnyIntegral\](lo:I, hi:I): FullRange[\I,true\]
1930(*
1931opr :(lo:IntLiteral, ex:IntLiteral): FullRange[\ZZ32\]
1932*)
1933opr :[\I extends AnyIntegral, J extends AnyIntegral\]
1934     (lo:(I,J), hi:(I,J)): FullRange[\(I,J),true\]
1935opr :[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
1936     (lo:(I,J,K), hi:(I,J,K)): FullRange[\(I,J,K),true\]
1937
1938(** Factories for incomplete ranges. **)
1939opr (x:I)#[\I extends AnyIntegral\] : LowerRange[\I\]
1940opr (x:I,y:J)#[\I extends AnyIntegral, J extends AnyIntegral\] : LowerRange[\(I,J)\]
1941opr (x:I,y:J,z:K)#[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\] :
1942         LowerRange[\(I,J,K)\]
1943opr (x:I):[\I\] : LowerRange[\I\]
1944opr #[\I extends AnyIntegral\](x:I) : ExtentRange[\I\]
1945opr #[\I extends AnyIntegral, J extends AnyIntegral\](xy:(I,J)) : ExtentRange[\(I,J)\]
1946opr #[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\](xyz:(I,J,K)) :
1947         ExtentRange[\(I,J,K)\]
1948opr :[\I extends AnyIntegral\](x:I) : UpperRange[\I\]
1949opr :[\I extends AnyIntegral, J extends AnyIntegral\](xy:(I,J)) : UpperRange[\(I,J)\]
1950opr :[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\](xyz:(I,J,K)) :
1951         UpperRange[\(I,J,K)\]
1952(*
1953opr (x:T)#[\T\] : LowerRange[\T\]
1954opr (x:T):[\T\] : LowerRange[\T\]
1955opr #[\T\](x:T) : ExtentRange[\T\]
1956opr :[\T\](x:T) : UpperRange[\T\]
1957*)
1958
1959opr #(): OpenRange[\Any\]
1960opr :(): OpenRange[\Any\]
1961
1962trait String extends { StandardTotalOrder[\String\],
1963                  ZeroIndexed[\Char\], DelegatedIndexed[\Char,ZZ32\] }
1964    getter size() : ZZ32
1965    getter toString() : String
1966    getter indices() : FullRange[\ZZ32,true\]
1967    getter generator() : Generator[\Char\]
1968    getter depth() : ZZ32
1969    verify() : ()       (* Verify the data structure invaraints of self *)
1970    showStructure() : ()        (* a debugging printout *)
1971    showStructure(indent: ZZ32) : ()         (* a debugging printout *)
1972    opr |self| : ZZ32
1973    opr CASE_INSENSITIVE_CMP(self, other:String): TotalComparison
1974   
1975    opr [i:ZZ32]: Char
1976    (** As a convenience, we permit LowerRange indexing to go 1 past the bounds
1977        of the string, returning the empty string, in order to permit some convenient
1978        string-trimming idioms. **)
1979    opr[r0:Range[\ZZ32\]] : String
1980
1981    (** This version is like [ ] above, but does not do the bounds checking.  Really, this
1982         should be in a "friends" interface *)
1983    uncheckedSubstring(r0: Range[\ZZ32\]) : String
1984   
1985    subdivide(): Maybe[\Generator[\(ZZ32, String)\]\]
1986
1987    (** The operator %||% with at least one String argument converts to string and
1988        appends **)
1989    opr ||(self, b:String):String
1990    opr ||(self, b:Number):String
1991    opr ||(self, c:Char):String
1992    opr ||(self, b:()):String
1993    opr ||(self, b:(Any,Any)):String
1994    opr ||(self, b:(Any,Any,Any)):String
1995    opr ||(a:Any, self):String
1996    opr ||(self, b:Any):String
1997
1998    (** The operator %|||% with at least one String argument converts to string,
1999        then appends with a whitespace separator unless one of the two arguments is
2000        empty.  If there is an empty argument, the other argument is returned. **)
2001    opr |||(self, b:String): String
2002    opr |||(self, b:Any): String
2003    opr |||(a:Any, self): String
2004
2005    (** Right now for backward compatibility juxtaposition works like %||% **)
2006    opr juxtaposition(a:Any, self):String
2007    opr juxtaposition(self, b:String):String
2008    opr juxtaposition(self, b:Any):String
2009
2010    (** opr // appends with a single newline separator. **)
2011    opr //(self) : String
2012    opr //(self, a:String): String
2013    opr //(self, a:Any): String
2014    opr //(a:Any, self): String
2015
2016    (** opr /// appends with a double newline separator **)
2017    opr ///(self) : String
2018    opr ///(self, a:String): String
2019    opr ///(self, a:Any): String
2020    opr ///(a:Any, self): String
2021
2022    print(self): ()
2023    println(self): ()
2024
2025end
2026
2027(***********************************************************
2028* \subsection{Top-level primitives}
2029************************************************************)
2030
2031(** %nanoTime% returns the current time in nanoseconds.  Currently,
2032    this only supports taking differences of results of %nanoTime%
2033    to produce an elapsed time interval. **)
2034nanoTime():ZZ64
2035
2036(** %printTaskTrace% dumps some internal error state. *)
2037printTaskTrace():()
2038
2039recordTime(dummy: Any): ()
2040printTime(dummy: Any): ()
2041
2042fromRawBits(a:ZZ64):RR64
2043
2044random(a:Number):RR64
2045
2046match(regex:String,some:String):Boolean
2047
2048(** %char% converts an integer unicode code point into the
2049    corresponding 16-bit %Char%.  Note that we don't presently deal
2050    gracefully with %Char%s outside the 16-bit plane. **)
2051char(a:ZZ32):Char
2052
2053print(a:Number):()
2054println(a:Number):()
2055print(a:Boolean):()
2056println(a:Boolean):()
2057println(a:Char):()
2058print(a:Any):()
2059println(a:Any):()
2060(** 0-argument versions handle passing of () to single-argument versions. **)
2061print():()
2062println():()
2063
2064forDigit(x:ZZ32, radix:ZZ32): Maybe[\Char\]
2065forDigit(x:ZZ32, radixString:String): Maybe[\Char\]
2066
2067(** Convert string to arbitrary integral type.  String may contain
2068    leading - or +.  Valid radixes are 2,8,10,12, and 16.  No spaces
2069    may occur in the string, and it must have at least one digit.
2070
2071    Right now we're oblivious to overflow!  This ought to be fixed.
2072
2073    This ought to support arbitrary integer types, but right now
2074    there's no clean way to convert all the arithmetic to use a
2075    provided type without having an instance of that type in hand.
2076    Unsigned types in particular are a bit sticky.
2077 **)
2078strToInt(s: String, radix: ZZ32): ZZ32
2079
2080(** Radix-10 digit conversion.  All caveats of the flexible-radix conversion above apply. *)
2081strToInt(s: String): ZZ32
2082
2083(** opr // appends a single newline separator. **)
2084opr (x:Any)// : String
2085
2086(** opr /// appends a double newline separator **)
2087opr (x:Any)/// : String
2088
2089(* A way to get environment information from inside of fortress *)
2090getEnvironment(name:String, defaultValue:String):String
2091
2092(** The following three functions are useful temporary hacks for
2093    debugging multi-threaded programs. **)
2094printThreadInfo(a:String):()
2095printThreadInfo(a:Number):()
2096throwError(a:String):()
2097
2098opr SEQV(a:Any, b:Any):Boolean
2099
2100opr XOR(a:Boolean, b:Boolean):Boolean
2101opr  OR(a:Boolean, b:Boolean):Boolean
2102opr AND(a:Boolean, b:Boolean):Boolean
2103opr  OR(a:Boolean, b:()->Boolean):Boolean
2104opr AND(a:Boolean, b:()->Boolean):Boolean
2105opr NOT(a:Boolean):Boolean
2106opr ->(a: Boolean, b:Boolean):Boolean
2107opr ->(a: Boolean, b:()->Boolean):Boolean
2108opr <->(a: Boolean, b:Boolean):Boolean
2109
2110true : Boolean
2111false : Boolean
2112
2113opr +[\T extends Number\](x:T):T
2114
2115opr =[\A,B\](t1:(A,B), t2:(A,B)): Boolean
2116opr <[\A,B\](t1:(A,B), t2:(A,B)): Boolean
2117opr <=[\A,B\](t1:(A,B), t2:(A,B)): Boolean
2118opr >[\A,B\](t1:(A,B), t2:(A,B)): Boolean
2119opr >=[\A,B\](t1:(A,B), t2:(A,B)): Boolean
2120opr CMP[\A,B\](t1:(A,B), t2:(A,B)): Comparison
2121opr =[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean
2122opr <[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean
2123opr <=[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean
2124opr >[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean
2125opr >=[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean
2126opr CMP[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Comparison
2127
2128
2129
2130end
Note: See TracBrowser for help on using the browser.