root/trunk/Library/FortressLibrary.fsi @ 2726

Revision 2726, 75.9 KB (checked in by sukyoungryu, 15 months ago)

[library] Replaced Unicode characters in FortressLibrary.fsi with ASCII characters to be LaTeX compatible.

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