root/trunk/Library/FortressLibrary.fss @ 2739

Revision 2739, 157.6 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
18component FortressLibrary
19import NativeArray.{...}
20import NatReflect.{...}
21import JavaString.{...}
22import List.{AnyList}
23
24export FortressLibrary
25
26(************************************************************
27* Simple Combinators
28************************************************************)
29
30(** Casting *)
31
32cast[\T extends Any\](x:Any):T =
33  typecase x of
34    T => x
35    else => throw CastError
36  end
37
38instanceOf[\T extends Any\](x:Any):Boolean =
39  typecase x of
40    T => true
41    else => false
42  end
43
44(** Useful functions *)
45
46ignore(_:Any):() = ()
47
48identity[\T extends Any\](x:T):T = x
49
50(* Should we depracate tuple and use identity instead?  Decision: no. *)
51tuple[\T\](x:T):T = x
52
53(* Function composition *)
54opr COMPOSE[\A,B,C\](f: B->C, g: A->B): A->C = fn (a:A): C => f(g(a))
55
56(** Reflection of static type parameters for overloading purposes.
57    Works around shortcomings in the story on parametric overloading
58    (all overloadings must have the same parameters with the same
59    bounds).  Allows us to overload a function based on the parametric
60    type of an output. *)
61
62object __Proxy[\T extends (* U *) Any\]
63    (* extends { __Proxy[\U\], Object } where { U extends Any } *)
64  getter toString() = "__Proxy object, should not be user-visible."
65end
66
67fail[\T\](s:String):T = do
68   println("FAIL: " s)
69   (* throwError(s) *)
70   throw FailCalled(s)
71end
72
73(************************************************************
74* Control over locality and location
75************************************************************)
76
77(* At the moment all Fortress objects are immediately shared by default. *)
78
79shared[\T extends Any\](x:T): T = x
80
81isShared(x:Any): Boolean = true
82
83localize[\T extends Any\](x:T): T = x
84
85(* copy is presently unimplemented.
86copy[\T extends Any\](x:T): T =
87*)
88
89trait Region extends Equality[\Region\]
90    getter toString(): String
91    isLocalTo(r: Region): Boolean = false
92    opr =(self, other:Region): Boolean = self SEQV other
93end
94
95object Global extends Region
96    getter toString(): String = "Global"
97    isLocalTo(_: Region): Boolean = true
98end
99
100region(a:Any): Region = Global
101
102here(): Region = Global
103
104(************************************************************
105* Equality and ordering
106************************************************************)
107
108opr =(a:Any, b:Any):Boolean = a SEQV b
109
110opr =/=(a:Any, b:Any):Boolean = NOT (a=b)
111
112trait Equality[\Self extends Equality[\Self\]\]
113    opr =(self, other:Self): Boolean
114end
115
116(** Total ordering *)
117
118object LexicographicPartialReduction
119        extends { MonoidReduction[\Comparison\],
120                  ReductionWithZeroes[\Comparison, Comparison\] }
121    getter toString():String = "Lexicographic reduction on partial order"
122    empty(): Comparison = EqualTo
123    join(a:Comparison, b:Comparison):Comparison = a LEXICO b
124    isZero(_:Unordered): Boolean = true
125    isZero(_:Comparison): Boolean = false
126end
127
128object LexicographicReduction
129        extends { MonoidReduction[\TotalComparison\],
130                  ReductionWithZeroes[\TotalComparison, TotalComparison\] }
131    getter toString():String = "Lexicographic reduction on total order"
132    empty(): TotalComparison = EqualTo
133    join(a:TotalComparison, b:TotalComparison):TotalComparison = a LEXICO b
134    isLeftZero(_:EqualTo): Boolean = false
135    isLeftZero(_:Comparison): Boolean = true
136end
137
138opr BIG LEXICO(): BigReduction[\TotalComparison, TotalComparison\] =
139  BigReduction[\TotalComparison,TotalComparison\](LexicographicReduction)
140 
141
142trait Comparison
143        extends { StandardPartialOrder[\Comparison\] }
144        comprises { Unordered, TotalComparison }
145    getter toString(): String
146    opr =(self, other:Comparison): Boolean = false
147    opr LEXICO(self, other:Comparison): Comparison = Unordered
148    opr INVERSE(self): Comparison
149end
150
151(** Unordered is the outcome of a CMP b when a and b are partially
152    ordered and no ordering relationship exists between them. **)
153object Unordered extends Comparison
154    getter toString(): String = "Unordered"
155    opr =(self, other:Unordered): Boolean = true
156    opr <(self, other:Comparison): Boolean = false
157    opr INVERSE(self): Comparison = Unordered
158end
159
160trait TotalComparison
161        extends { Comparison, StandardTotalOrder[\TotalComparison\] }
162        comprises { LessThan, EqualTo, GreaterThan }
163    (* We're both a partial order (including Unordered) and a total
164       order (TotalComparison alone).  Avoid ambiguity between the
165       default definitions of CMP and >=. *)
166    opr =(self, other:TotalComparison): Boolean = false
167    opr =(self, other:Unordered): Boolean = false
168    opr CMP(self, other:Unordered): Comparison = Unordered
169    opr <(self, other:Unordered): Boolean = false
170    opr >=(self, other:Unordered): Boolean = false
171    opr >=(self, other:Comparison): Boolean = NOT (other < self)
172    opr LEXICO(self, other:TotalComparison): TotalComparison = self
173    opr LEXICO(self, other:()->TotalComparison): TotalComparison = self
174    opr INVERSE(self): TotalComparison
175end
176
177object LessThan extends TotalComparison
178    getter toString(): String = "LessThan"
179    opr =(self, other:LessThan): Boolean = true
180    opr CMP(self, other:LessThan): TotalComparison = EqualTo
181    opr CMP(self, other:TotalComparison): TotalComparison = GreaterThan
182    opr <(self, other:LessThan): Boolean = false
183    opr <(self, other:TotalComparison): Boolean = true
184    opr INVERSE(self): TotalComparison = GreaterThan
185end
186
187object GreaterThan extends TotalComparison
188    getter toString(): String = "GreaterThan"
189    opr =(self, other:GreaterThan): Boolean = true
190    opr CMP(self, other:GreaterThan): TotalComparison = EqualTo
191    opr CMP(self, other:TotalComparison): TotalComparison = LessThan
192    opr <(self, other:TotalComparison): Boolean = false
193    opr INVERSE(self): TotalComparison = LessThan
194end
195
196object EqualTo extends TotalComparison
197    getter toString(): String = "EqualTo"
198    opr =(self, other:EqualTo): Boolean = true
199    opr CMP(self, other:TotalComparison): TotalComparison = INVERSE other
200    opr <(self, other:GreaterThan): Boolean = true
201    opr <(self, other:TotalComparison): Boolean = false
202    opr LEXICO(self, other:TotalComparison): TotalComparison = other
203    opr LEXICO(self, other:()->TotalComparison): TotalComparison = other()
204    opr INVERSE(self): TotalComparison = EqualTo
205end
206
207(** StandardPartialOrder is partial ordering using <,>,<=,>=,=, and CMP.
208    This is primarily for floating-point values.  Minimal complete
209    definition: CMP or { <, = }. **)
210trait StandardPartialOrder[\Self extends StandardPartialOrder[\Self\]\]
211        extends { Equality[\Self\] }
212    opr CMP(self, other:Self): Comparison =
213        if self < other then LessThan
214        elif other > self then GreaterThan
215        elif self = other then EqualTo
216        else Unordered
217        end
218    opr <(self, other:Self): Boolean = LessThan = (self CMP other)
219    opr >(self, other:Self): Boolean = other < self
220    opr =(self, other:Self): Boolean = EqualTo = (self CMP other)
221    opr <=(self, other:Self): Boolean = other >= self
222    opr >=(self, other:Self): Boolean = (self = other OR: self > other)
223end
224
225(** %StandardMin% is a MIN operator; most types that implement %MIN%
226    will implement a corresponding total order.  It's a separate type
227    to account for the existence of floating point numbers, for which
228    NaN counts as a bottom that is less than anything else but doesn't
229    actually participate in the standard total ordering.  It is
230    otherwise the case that %a MIN b = a% when %a <= b% and that
231    %a MIN b = b MIN a%. **)
232trait StandardMin[\T extends StandardMin[\T\]\]
233    opr MIN(self, other:T): T
234end
235
236(** %StandardMax% is a MAX operator; most types that implement %MAX%
237    will implement a corresponding total order.  It's a separate type
238    to account for the existence of floating point numbers, for which
239    NaN counts as a bottom that is less than anything else but doesn't
240    actually participate in the standard total ordering.  It is
241    otherwise the case that %a MAX b = a% when %a <= b% and that
242    %a MAX b = b MAX a%. **)
243trait StandardMax[\T extends StandardMax[\T\]\]
244    opr MAX(self, other:T): T
245end
246
247(** StandardTotalOrder is the usual total order using <,>,<=,>=,=, and
248    CMP.  Most values that define a comparison should do so using
249    this.  Minimal complete definition: either CMP or < (it's
250    advisable to define = in the latter case).  As noted above, %MIN%
251    and %MAX% respect the total order and are defined in the obvious
252    way. **)
253trait StandardTotalOrder[\Self extends StandardTotalOrder[\Self\]\]
254        extends { StandardPartialOrder[\Self\], StandardMin[\Self\], StandardMax[\Self\] }
255    opr CMP(self, other:Self): TotalComparison =
256        if self < other then LessThan
257        elif other < self then GreaterThan
258        else EqualTo
259        end
260    opr >=(self, other:Self): Boolean = NOT (self < other)
261    opr <=(self, other:Self): Boolean = NOT (other < self)
262    opr MIN(self, other:Self): Self = if other < self then other else self end
263    opr MAX(self, other:Self): Self = if self < other then other else self end
264end
265
266(** Assertion *)
267assert(flag:Boolean): () =
268    if NOT flag then
269        fail("Assertion failed!")
270    end
271
272assert(flag: Boolean, failMsg: String): () =
273    if NOT flag then
274        fail(failMsg)
275    end
276
277assert(x:Any, y:Any, failMsg: Any...): () =
278    if x =/= y then
279        msg = x " =/= " y "; " (BIG || failMsg)
280        fail(msg)
281    end
282   
283deny(flag:Boolean): () = assert(NOT flag)
284
285deny(flag: Boolean, failMsg: String): () = assert(NOT flag, failMsg)
286
287deny(x:Any, y:Any, failMsg: Any...): () =
288    if x = y then
289        msg = x " = " y "; " (BIG || failMsg)
290        fail(msg)
291    end
292   
293shouldRaise⟦Ex extends Exception⟧ (expr: ()→()): () = do
294    try
295        expr()
296        throw ForbiddenException
297    catch x
298        Ex => assert(true) (* This is what we hope for *)
299    forbid Exception
300    end
301end
302       
303
304(************************************************************
305* Numeric hierarchy
306************************************************************)
307
308(** Additive group making use of +.  Must define + and either unary or binary -. **)
309trait AdditiveGroup[\Self extends AdditiveGroup[\Self\]\]
310    getter zero(): Self = self - self
311    opr +(self, other: Self): Self
312    opr -(self, other: Self): Self = self + (-other)
313    opr -(self) : Self = self.zero - self
314end
315
316(** Place holder for exclusions of MultiplicativeRing **)
317trait AnyMultiplicativeRing end
318
319(** Multiplicative ring using TIMES and juxtaposition.
320    Define opr TIMES; juxtaposition is defined in terms of TIMES. **)
321trait MultiplicativeRing[\Self extends MultiplicativeRing[\Self\]\]
322        extends { AdditiveGroup[\Self\], AnyMultiplicativeRing }
323    getter one(): Self
324    opr TIMES(self, other:Self): Self
325    opr juxtaposition(self, other:Self): Self = self TIMES other
326    (** Exponentiation need only deal with natural exponents. **)
327    opr ^(self, other:AnyIntegral): Self
328end
329
330(** The use of StandardTotalOrder here is a lie; it will have to suffice
331    until we can deal gracefully with NaNs disobeying the ordering rules
332    (and even the equivalence rules for = and =/=). **)
333trait Number
334        extends { StandardPartialOrder[\Number\], StandardMin[\Number\], StandardMax[\Number\],
335                  AdditiveGroup[\Number\], MultiplicativeRing[\Number\] }
336        comprises { RR64 }
337    getter zero(): Number = 0.0
338    getter one(): Number = 1.0
339    getter toString(): String
340    opr |self| : Number =
341        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Abs")
342    opr =(self, b:Number):Boolean =
343        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Eq")
344    opr =/=(self, b:Number):Boolean =
345        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$NEq")
346    opr <(self, b:Number):Boolean =
347        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Less")
348    opr <=(self, b:Number):Boolean =
349        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$LessEq")
350    opr >(self, b:Number):Boolean =
351        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Greater")
352    opr >=(self, b:Number):Boolean =
353        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$GreaterEq")
354    opr CMP(self, b:Number):Comparison =
355        if self<b then LessThan
356        elif self>b then GreaterThan
357        elif self=b then EqualTo
358        else Unordered
359        end
360    (** In case of NaN, %MIN% and %MAX% return a NaN, otherwise it respects the
361        total order. **)
362    opr MIN(self, b:Number):Number =
363        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Min")
364    opr MAX(self, b:Number):Number =
365        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Max")
366
367    opr -(self):RR64 =
368        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Negate")
369    opr +(self,b:Number):RR64 =
370        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Add")
371    opr -(self,b:Number):RR64 =
372        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Sub")
373    opr DOT(self,b:Number):RR64 =
374        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Mul")
375    opr TIMES(self,b:Number):RR64 =
376        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Mul")
377    opr juxtaposition
378         (self,b:Number):RR64 =
379        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Mul")
380    opr /(self,b:Number):RR64 =
381        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Div")
382    opr SQRT(self):RR64 =
383        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Sqrt")
384    opr PLUS_UP(self,b:Number):RR64 =
385        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$AddUpNoNaN")
386    opr MINUS_UP(self,b:Number):RR64 =
387        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$SubUpNoNaN")
388    opr DOT_UP(self,b:Number):RR64 =
389        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$MulUpNoNaN")
390    opr SLASH_UP(self,b:Number):RR64 =
391        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$DivUpNoNaN")
392    opr SQRT_UP(self):RR64 =
393        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$SqrtUp")
394    opr PLUS_DOWN(self,b:Number):RR64 =
395        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$AddDownNoNaN")
396    opr MINUS_DOWN(self,b:Number):RR64 =
397        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$SubDownNoNaN")
398    opr DOT_DOWN(self,b:Number):RR64 =
399        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$MulDownNoNaN")
400    opr SLASH_DOWN(self,b:Number):RR64 =
401        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$DivDownNoNaN")
402    opr SQRT_DOWN(self):RR64 =
403        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$SqrtDown")
404    opr IEEE_PLUS_UP(self,b:Number):RR64 =
405        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$AddUp")
406    opr IEEE_MINUS_UP(self,b:Number):RR64 =
407        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$SubUp")
408    opr IEEE_DOT_UP(self,b:Number):RR64 =
409        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$MulUp")
410    opr IEEE_SLASH_UP(self,b:Number):RR64 =
411        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$DivUp")
412    opr IEEE_PLUS_DOWN(self,b:Number):RR64 =
413        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$AddDown")
414    opr IEEE_MINUS_DOWN(self,b:Number):RR64 =
415        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$SubDown")
416    opr IEEE_DOT_DOWN(self,b:Number):RR64 =
417        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$MulDown")
418    opr IEEE_SLASH_DOWN(self,b:Number):RR64 =
419        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$DivDown")
420    opr ^(self, b:Number):RR64 =
421        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Pow")
422    (** Shouldn't need this extra declaration. **)
423    opr ^(self, b:AnyIntegral):RR64 =
424        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Pow")
425    sin(self):RR64 =
426        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Sin")
427    cos(self):RR64 =
428        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Cos")
429    tan(self):RR64 =
430        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Tan")
431    asin(self):RR64 =
432        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$ASin")
433    acos(self):RR64 =
434        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$ACos")
435    atan(self):RR64 =
436        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$ATan")
437    atan2(self,x:Number):RR64 =
438        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$ATan2")
439    log(self):RR64 =
440        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Log")
441    exp(self):RR64 =
442        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Exp")
443    floor(self):RR64 =
444        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Floor")
445    opr |\self/| : ZZ64 =
446        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$IFloor")
447    ceiling(self):RR64 =
448        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Ceiling")
449    opr |/self\| : ZZ64 =
450        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$ICeiling")
451    truncate(self):ZZ64 =
452        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Truncate")
453end
454
455trait RR64 extends Number comprises { Float, AnyIntegral, FloatLiteral }
456    (** returns true if the value is an IEEE NaN **)
457    getter isNaN(): Boolean =
458        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$isNaN")
459    (** returns true if the value is an IEEE infinity **)
460    getter isInfinite(): Boolean =
461        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$isInfinite")
462    (** returns true if the value is a valid number (not NaN) **)
463    getter isNumber(): Boolean = NOT self.isNaN
464    (** returns true if the value is finite **)
465    getter isFinite(): Boolean = NOT (self.isInfinite OR self.isNaN)
466    (** check returns Just(its argument) if it is finite, otherwise Nothing. **)
467    getter check(): Maybe[\RR64\] =
468        if self.isFinite then Just[\RR64\](self) else Nothing[\RR64\] end
469    (** check_star returns Just(its argument) if it is non-NaN, otherwise Nothing. **)
470    getter check_star(): Maybe[\RR64\] =
471        if self.isNaN then Nothing[\RR64\] else Just[\RR64\](self) end
472    (** obtain the raw bits of the IEEE floating-point representation of this value. **)
473    getter rawBits():ZZ64 =
474        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$RawBits")
475    getter signBit():ZZ32 = if rawBits() < 0 then 1 else 0 end
476    (** next higher IEEE float **)
477    getter nextUp():RR64 =
478        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$NextUp")
479    (** next lower IEEE float **)
480    getter nextDown():RR64 =
481        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$NextDown")
482    (** %MINNUM% and %MAXNUM% return a numeric result where possible (avoiding NaN).
483        Note that %MINNUM% and %MAX% form a lattice with NaN at the top, and
484        that %MAXNUM% and %MIN% form a lattice with NaN at the bottom.  **)
485    opr MINNUM(self, b:RR64):RR64 = do
486        r = self MIN b
487        if r.isNaN then
488            if self.isNumber then self
489            elif b.isNumber then b
490            else r end
491        else
492            r
493        end
494      end
495    opr MAXNUM(self, b:RR64):RR64 = do
496        r = self MAX b
497        if r.isNaN then
498            if self.isNumber then self
499            elif b.isNumber then b
500            else r end
501        else
502            r
503        end
504      end
505    (** returns a value of type RR32 **)
506    narrow(self): RR32 =
507        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Narrow")
508end
509
510trait QQ extends { RR64, StandardPartialOrder[\QQ\] }
511    getter zero(): QQ = 0
512    getter one(): QQ = 1
513    getter isNaN(): Boolean
514    getter isInfinite(): Boolean
515    getter isNumber(): Boolean = NOT self.isNaN
516    getter isFinite(): Boolean = (denominator(self) =/= 0)
517    numerator(self): ZZ
518    denominator(self): ZZ  (* Ideally would be NN *)
519    opr |self| : QQ = |numerator(self)| / denominator(self)
520    (* Note that 0/0 = 0/0 is supposed to be true (//unlike// the behavior of floating-point NaN) *)
521    opr =(self, other:QQ):Boolean =
522        numerator(self) = numerator(other) AND: denominator(self) = denominator(other)
523    opr =/=(self, other:QQ):Boolean = NOT (self = other)
524    opr <(self, other:QQ):Boolean = do
525        (a, b) = (numerator(self), denominator(self))
526        (c, d) = (numerator(other), denominator(other))
527        (b=0 AND d=0 AND a=-1 AND c=1) OR (a d < b c)
528    end
529    opr <=(self, other:QQ):Boolean = (self < other) OR (self = other)
530    opr >(self, other:QQ):Boolean = (other < self)
531    opr >=(self, other:QQ):Boolean = (other <= self)
532    (** In case of 0/0, %MIN% and %MAX% return 0/0, otherwise it respects the
533        total order. **)
534    opr MIN(self, other:QQ):QQ =
535        if self < other then self elif other < self then other elif self = 0/0 then self else other end
536    opr MAX(self, other:QQ):QQ =
537        if self > other then self elif other > self then other elif self = 0/0 then self else other end
538
539    opr -(self):QQ = (-numerator(self)) / denominator(self)
540    opr +(self,other:QQ):QQ =
541        if self = other AND denominator(self) = 0 then self else
542            (a, b) = (numerator(self), denominator(self))
543            (c, d) = (numerator(other), denominator(other))
544            (a d + b c) / b d
545        end
546    opr -(self,other:QQ):QQ = self + (-other)
547    opr DOT(self,other:QQ):QQ = do
548        (a, b) = (numerator(self), denominator(self))
549        (c, d) = (numerator(other), denominator(other))
550        a c / b d
551    end
552    opr TIMES(self,other:QQ):QQ = self DOT other
553    opr juxtaposition (self,other:QQ):QQ = self DOT other
554    opr /(self,other:QQ):QQ = do
555        (a, b) = (numerator(self), denominator(self))
556        (c, d) = (numerator(other), denominator(other))
557        a d / b c
558    end
559    opr ^(self, other:AnyIntegral):QQ =
560        if -other > 0 then   (* Way too clever by half (to avoid infinite recursion on 2^(-63)) *)
561            (denominator(self)/numerator(self))^(-other)
562        else
563            (numerator(self))^other / (denominator(self))^other
564        end
565    floor(self):ZZ = if self < 0 then -ceiling(-self) else truncate(self) end
566    opr |\self/| : ZZ = floor(self)
567    ceiling(self):ZZ = if denominator(self) = 0 then self else
568        (a, b) = (numerator(self), denominator(self))
569        if a < 0 then -floor(-self) else (a + b - 1) DIV b end
570    end
571    opr |/self\| : ZZ = ceiling(self)
572    truncate(self):ZZ = if denominator(self) = 0 then self else numerator(self) DIV denominator(self) end
573    round(self): ZZ = do x = self + 1/2; z = floor(x); if z = x AND odd z then z-1 else z end end
574    opr MINNUM(self, other:QQ):QQ =
575        if self < other then self elif other < self then other elif self = 0/0 then other else self end
576    opr MAXNUM(self, other:QQ):QQ =
577        if self > other then self elif other > self then other elif self = 0/0 then other else self end
578end
579
580object Ratio(num: ZZ, den: ZZ) extends { QQ }
581    getter toString(): String = num.toString || "/" || den.toString
582    getter isNaN(): Boolean = (numerator(self) = 0 AND denominator(self) = 0)
583    getter isInfinite(): Boolean = (numerator(self) =/= 0 AND denominator(self) = 0)
584    numerator(self):ZZ = num
585    denominator(self):ZZ = den
586end
587
588trait AnyIntegral extends { QQ } end
589
590trait Integral[\I extends Integral[\I\]\] extends { StandardTotalOrder[\I\], AnyIntegral }
591    getter zero(): I
592    getter one(): I
593    getter isNaN(): Boolean = false
594    getter isInfinite(): Boolean = false  (* For now, no infinite integers. *)
595    denominator(self):ZZ = 1
596    opr -(self):I
597    opr +(self,b:I):I
598    opr -(self,b:I):I
599    opr DOT(self,b:I):I
600    opr TIMES(self,b:I):I
601    opr juxtaposition(self,b:I):I
602    opr DIV(self,b:I):I
603    opr REM(self,b:I):I
604    opr MOD(self,b:I):I
605    opr GCD(self,b:I):I
606    opr LCM(self,b:I):I
607    opr DIVIDES(self,b:I):Boolean = b =/= zero() AND: (b MOD self) = zero()
608    opr CHOOSE(self,b:I):I
609    opr BITAND(self,b:I):I
610    opr BITOR(self,b:I):I
611    opr BITXOR(self,b:I):I
612    opr LSHIFT(self,b:AnyIntegral):I
613    opr RSHIFT(self,b:AnyIntegral):I
614    opr BITNOT(self):I
615    opr ^(self, b:AnyIntegral):RR64
616end
617
618trait ZZ32 extends { ZZ64, Integral[\ZZ32\] } comprises { Int, IntLiteral }
619    getter zero(): ZZ32 = 0
620    getter one(): ZZ32 = 1
621    getter minimum(): ZZ32 = -2147483647 - 1
622    getter maximum(): ZZ32 = 2147483647
623       
624    opr |self| : ZZ32 = if self>=0 then self else -self end
625    opr =(self, b:ZZ32):Boolean =
626        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Eq")
627    opr <(self, b:ZZ32):Boolean =
628        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Less")
629
630    opr -(self):ZZ32 =
631        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Negate")
632    opr +(self,b:ZZ32):ZZ32 =
633        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Add")
634    opr -(self,b:ZZ32):ZZ32 =
635        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Sub")
636    opr DOT(self,b:ZZ32):ZZ32 =
637        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Mul")
638    opr TIMES(self,b:ZZ32):ZZ32 =
639        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Mul")
640    opr juxtaposition(self,b:ZZ32):ZZ32 =
641        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Mul")
642    opr DIV(self,b:ZZ32):ZZ32 =
643        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Div")
644    opr REM(self,b:ZZ32):ZZ32 =
645        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Rem")
646    opr MOD(self,b:ZZ32):ZZ32 =
647        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Mod")
648    opr GCD(self,b:ZZ32):ZZ32 =
649        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Gcd")
650    opr LCM(self,b:ZZ32):ZZ32 =
651        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Lcm")
652    opr CHOOSE(self,b:ZZ32):ZZ32 =
653        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Choose")
654    opr BITAND(self,b:ZZ32):ZZ32 =
655        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$BitAnd")
656    opr BITOR(self,b:ZZ32):ZZ32 =
657        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$BitOr")
658    opr BITXOR(self,b:ZZ32):ZZ32 =
659        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$BitXor")
660    opr LSHIFT(self,b:ZZ64):ZZ32 =
661        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$LShift")
662    opr RSHIFT(self,b:ZZ64):ZZ32 =
663        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$RShift")
664    opr BITNOT(self):ZZ32 =
665        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$BitNot")
666    opr ^(self, b:AnyIntegral):RR64 =
667        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Pow")
668    widen(self):ZZ64 =
669        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$ToLong")
670    partitionL(self):ZZ32 =
671        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Int$Partition")
672    unsigned(self):NN32 =
673        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.ZZ32$ToNN32")
674end
675
676trait ZZ64 extends { ZZ, Integral[\ZZ64\] } comprises { Long, ZZ32 }
677    getter zero(): ZZ64 = widen(0)
678    getter one(): ZZ64 = widen(1)
679    getter minimum(): ZZ64 = -9223372036854775807 - 1
680    getter maximum(): ZZ64 = 9223372036854775807
681
682    opr |x:ZZ64| : ZZ64 = if x>=0 then x else -x end
683
684    opr =(self, b:ZZ64):Boolean =
685        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Eq")
686    opr <(self, b:ZZ64):Boolean =
687        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Less")
688    (* Argh!  Due to method ambiguities with ZZ, these definitions must be given
689       explicitly here. *)
690    opr >(self, b:ZZ64):Boolean = b < self
691    opr >=(self, b:ZZ64):Boolean = NOT (self < b)
692    opr <=(self, b:ZZ64):Boolean = NOT (b < self)
693    opr CMP(self, b:ZZ64): TotalComparison =
694        if self < b then LessThan
695        elif b < self then GreaterThan
696        else EqualTo end
697
698    opr -(self):ZZ64 =
699        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Negate")
700    opr +(self,b:ZZ64):ZZ64 =
701        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Add")
702    opr -(self,b:ZZ64):ZZ64 =
703        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Sub")
704    opr DOT(self,b:ZZ64):ZZ64 =
705        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Mul")
706    opr TIMES(self,b:ZZ64):ZZ64 =
707        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Mul")
708    opr juxtaposition(self,b:ZZ64):ZZ64 =
709        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Mul")
710    opr DIV(self,b:ZZ64):ZZ64 =
711        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Div")
712    opr REM(self,b:ZZ64):ZZ64 =
713        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Rem")
714    opr MOD(self,b:ZZ64):ZZ64 =
715        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Mod")
716    opr GCD(self,b:ZZ64):ZZ64 =
717        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Gcd")
718    opr LCM(self,b:ZZ64):ZZ64 =
719        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Lcm")
720    opr CHOOSE(self,b:ZZ64):ZZ64 =
721        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Choose")
722    opr BITAND(self,b:ZZ64):ZZ64 =
723        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$BitAnd")
724    opr BITOR(self,b:ZZ64):ZZ64 =
725        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$BitOr")
726    opr BITXOR(self,b:ZZ64):ZZ64 =
727        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$BitXor")
728    opr LSHIFT(self,b:AnyIntegral):ZZ64 =
729        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$LShift")
730    opr RSHIFT(self,b:AnyIntegral):ZZ64 =
731        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$RShift")
732    opr BITNOT(self):ZZ64 =
733        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$BitNot")
734    opr ^(self, b:AnyIntegral):RR64 =
735        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Pow")
736    partitionL(self):ZZ64 =
737        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$Partition")
738    narrow(self):ZZ32 =
739        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$FromLong")
740    unsigned(self):NN64 =
741        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$ToUnsignedLong")
742    big(self):ZZ =
743        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$ToBigNum")
744end
745
746trait NN64 extends { ZZ, Integral[\NN64\] } comprises { UnsignedLong, NN32 }
747    opr |self| : NN64 = self
748    opr =(self, b:NN64):Boolean =
749        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Eq")
750    opr <(self, b:NN64):Boolean =
751        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Less")
752    opr -(self):NN64 =
753        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Negate")
754    opr +(self,b:NN64):NN64 =
755        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Add")
756    opr -(self,b:NN64):NN64 =
757        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Sub")
758    opr DOT(self,b:NN64):NN64 =
759        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Mul")
760    opr TIMES(self,b:NN64):NN64 =
761        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Mul")
762    opr juxtaposition(self,b:NN64):NN64 =
763        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Mul")
764    opr DIV(self,b:NN64):NN64 =
765        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Div")
766    opr REM(self,b:NN64):NN64 =
767        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Rem")
768    opr MOD(self,b:NN64):NN64 =
769        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Mod")
770    opr GCD(self,b:NN64):NN64 =
771        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Gcd")
772    opr LCM(self,b:NN64):NN64 =
773        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Lcm")
774    opr CHOOSE(self,b:NN64):NN64 =
775        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Choose")
776    opr BITAND(self,b:NN64):NN64 =
777        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$BitAnd")
778    opr BITOR(self,b:NN64):NN64 =
779        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$BitOr")
780    opr BITXOR(self,b:NN64):NN64 =
781        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$BitXor")
782    opr LSHIFT(self,b:AnyIntegral):NN64 =
783        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$LShift")
784    opr RSHIFT(self,b:AnyIntegral):NN64 =
785        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$RShift")
786    opr BITNOT(self):NN64 =
787        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$BitNot")
788    opr ^(self, b:AnyIntegral):RR64 =
789        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Pow")
790    partitionL(self):NN64 =
791        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$Partition")
792    narrow(self):NN32 =
793        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$FromLong")
794    signed(self):NN64 =
795        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.UnsignedLong$ToLong")
796end
797
798trait ZZ extends Integral[\ZZ\]
799        comprises { BigNum, ZZ64 }
800    getter zero(): ZZ =
801        1934791870947204798109283471902037419 - 1934791870947204798109283471902037419
802    getter one(): ZZ = zero() + 1
803    numerator(self):ZZ = self
804    opr |self| : ZZ32 = if self>=0 then self else -self end
805    opr =(self, b: ZZ):Boolean =
806        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Eq")
807    opr <(self, other:ZZ): Boolean = self.cmp(other) < 0
808    opr <=(self, other:ZZ): Boolean = self.cmp(other) <= 0
809    opr >(self, other:ZZ): Boolean = self.cmp(other) > 0
810    opr >=(self, other:ZZ): Boolean = self.cmp(other) >= 0
811    opr CMP(self, other:ZZ): TotalComparison = self.cmp(other) CMP 0
812    cmp(b:ZZ): ZZ32 =
813        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Cmp")
814
815    opr -(self): ZZ =
816        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Negate")
817    opr +(self, b: ZZ): ZZ =
818        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Add")
819    opr -(self, b: ZZ): ZZ =
820        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Sub")
821    opr DOT(self, b: ZZ): ZZ =
822        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Mul")
823    opr juxtaposition(self, b: ZZ): ZZ =
824        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Mul")
825    opr TIMES(self, b: ZZ): ZZ =
826        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Mul")
827    opr /(self,other:ZZ):QQ = if other < 0 then (-self)/(-other) else
828        g = self GCD other
829        if g=0 then Ratio(0,0) else
830            a = self DIV g
831            b = other DIV g
832            if b = 1 then a else Ratio(a,b) end
833        end
834    end
835    opr DIV(self, b: ZZ): ZZ =
836        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Div")
837    opr REM(self, b: ZZ): ZZ =
838        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Rem")
839    opr MOD(self, b: ZZ): ZZ =
840        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Mod")
841    opr GCD(self, b: ZZ): ZZ =
842        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Gcd")
843    opr LCM(self, b: ZZ): ZZ =
844        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Lcm")
845    opr CHOOSE(self, b: ZZ): ZZ =
846        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Choose")
847    opr BITAND(self, b: ZZ): ZZ =
848        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$BitAnd")
849    opr BITOR(self, b: ZZ): ZZ =
850        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$BitOr")
851    opr BITXOR(self, b: ZZ): ZZ =
852        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$BitXor")
853    opr LSHIFT(self, b:AnyIntegral): ZZ =
854        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$LShift")
855    opr RSHIFT(self, b:AnyIntegral): ZZ =
856        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$RShift")
857    opr BITNOT(self): ZZ =
858        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$BitNot")
859    opr ^(self, b:AnyIntegral):RR64 =
860        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.BigNum$Pow")
861    odd(self): Boolean = NOT (even self)
862    even(self): Boolean = (self MOD 2) = 0
863end
864
865(************************************************************
866* Generator support
867************************************************************)
868
869(** Generator
870 *
871 * We say an object which extends Generator[\T\] "generates objects of
872 * type T."
873 *
874 * Generators are used to express iteration in Fortress.  Every
875 * generated expression in Fortress (eg for loop, comprehension) is
876 * desugared into calls to methods of Generator, chiefly the generate
877 * method.
878 *
879 * Every generator has a notion of a "natural order" (which by default is
880 * unspecified), which describes the ordering of reduction operations,
881 * and also describes the order in which elements are produced by the
882 * sequential version of the same generator (given by the seq(self)
883 * method).  The default implementation of seq(self) guarantees that these
884 * orders will match.
885 *
886 * Note in particular that the natural order of a Generator must be
887 * consistent; that is, if a SEQV b then a and b must yield SEQV
888 * elements in the same natural order.  However, note that unless a type
889 * specifically documents otherwise, no particular element ordering is
890 * guaranteed, nor is it necessary to guarantee that a=b have the same
891 * natural order when equality is defined.
892 *
893 * Note that more complex derived generators are specified further
894 * down in the definition of Generator.  These have the same notions
895 * of natural order and by default are defined in terms of the
896 * generate() method.
897 *
898 * Minimal complete definition of a Generator is the generate(...) method.
899 *)
900trait Generator[\E\]
901    excludes { Number }
902    (** generate is the core of Generator.  It generates elements of
903        type E and passes them to the body function.  This generation
904        can occur using any mixture of serial and parallel execution
905        desired by the author of the generator; by default uses of a
906        generator must assume every call to the body occurs in
907        parallel.
908
909        The results of generation are combined using the reduction
910        object R, which specifies a monoidal operation (associative
911        and with an identity).  Body results must be combined together
912        following the natural order of the generator.  The author of
913        the generator is free to use the identity element anywhere
914        desired in this computation, and to group reductions in any
915        way desired; if no elements are generated the identity must be
916        returned. *)
917    generate[\R\](r: Reduction[\R\], body: E->R): R
918
919    (** Transforming generators into new generators *)
920    (** map applies a function f to each element generated and yields
921        the result.  The resulting generator must have the same
922        ordering and cross product properties as the generator from
923        which it is derived. *)
924    map[\G\](f: E->G): Generator[\G\] = SimpleMappedGenerator[\E,G\](self,f)
925    (** seq produces a sequential version of the same generator, in
926        which elements are produced in the generator's natural order. *)
927    seq(self): SequentialGenerator[\E\] = NaiveSeqGenerator[\E\](self)
928
929    (** Nesting of two generators; the innermost is data-dependent
930        upon the outer one.  This is specifically designed to be
931        overloaded so that the combined generators have properties
932        appropriate to the pairing.  Because of the data dependency
933        the natural order of the nesting is the natural order of the
934        inner generators, in the natural order the outer nesting
935        produces them.  So for example, if we write:
936          (0#3).nest[\ZZ32\](\(n:ZZ32):Generator[\ZZ32\] => (n*100#4))
937        then the natural order is 0,1,2,3,100,101,102,103,200,201,202,203
938     **)
939    nest[\G\](f: E -> Generator[\G\]): Generator[\G\] =
940        SimpleNestedGenerator[\E,G\](self,f)
941
942    (** Filtering data from a generator.  Only elements that satisfy
943        the predicate p are retained.  Natural order and cross product
944        properties are otherwise preserved. **)
945    filter(f: E -> Condition[\()\]): Generator[\E\] =
946        SimpleFilterGenerator[\E\](self,f)
947
948    (** Cross product of two generators.  This is specifically
949        designed to be overloaded, such that pairs of independent
950        generators can be combined to produce a generator which
951        possibly interleaves the iteration spaces of the two
952        generators.  For example, we might combine (0#16).cross(0#32)
953        such that it first splits the second range in half, then the
954        first range in half, then the second, and so forth.
955
956        Consider a grid for which the rows are labeled from top to
957        bottom with the elements of a in natural order, and the
958        columns are labeled from left to right with the elements of g
959        in natural order.  Each point in the grid corresponds to a
960        pair (a,b) that must be generated by self.cross(g).  In the
961        natural order of the cross product, an element must occur
962        after those that lie above and to the left of it in the grid.
963        By default the natural order of the cross product is
964        left-to-right, top to bottom.  Programmers must not rely on
965        the default order, except that cross products involving one or
966        more sequential generators are always performed in the default
967        order.  Note that this means that the following have the same
968        natural order:
969           seq(a).cross(b)
970           a.cross(seq(b))
971           seq(a).cross(seq(b))
972        But seq(a.cross(b)) may have a different natural order. *)
973    cross[\G\](g: Generator[\G\]): Generator[\(E,G)\] =
974        SimplePairGenerator[\E,G\](self, g)
975
976    (** Derived generation operations *)
977    (** mapReduce is equivalent to generate, but takes an explicit join
978        and zero which can have any type.  It still assumes join is
979        associative and that zero is the identity of join. **)
980    mapReduce[\R\](body: E->R, join:(R,R)->R, id:R): R =
981        generate[\R\](MapReduceReduction[\R\](join,id), body)
982    (** reduce works much like generate or mapReduce,
983        but has no body expression **)
984    reduce(j:(E,E)->E, z:E):E = mapReduce[\E\](fn (e:E)=>e, j, z)
985    reduce(r: Reduction[\E\]):E = generate[\E\](r, fn(e:E)=>e)
986    (** loop is a version of generate which discards the void results
987        of the body computation.  It is used to translated
988        reduction-variable-free for loops. **)
989    loop(f:E->()): () = generate[\()\](VoidReduction, f)
990    (** Is x generated by this generator? **)
991    opr IN(x:E, self): Boolean = BIG OR [y <- self] x=y
992    (** The MATCH operator is used (as a temporary hack) by CASE when the
993        match clause is a Generator[\E\].  We must choose either =, SEQV, or
994        IN as appropriate, depending on the type of the LHS. **)
995    opr MATCH(x:Any, self): Boolean =
996        typecase x of
997            E => (x IN self)
998            Generator[\E\] => (x = self)
999            else => fail("Type error in MATCH of Generator")
1000        end
1001end
1002
1003(** The following top-level functions are used as glue in the
1004    desugaring of generated expressions (comprehensions, BIG
1005    operators, and loops).  They exist at the top level in part to
1006    work around shortcomings in the ablity of the Fortress interpreter
1007    to check types dynamically for anything except top-level
1008    non-overloaded function calls. **)
1009__generate[\E,R\](g:Generator[\E\], r: Reduction[\R\], b:E->R): R =
1010    g.generate[\R\](r,b)
1011
1012__nest[\E1,E2\](g:Generator[\E1\], f:E1->Generator[\E2\]):Generator[\E2\] =
1013    g.nest[\E2\](f)
1014
1015__singleton[\E\](body:E): Generator[\E\] = Just[\E\](body)
1016
1017__loop[\E,R\](g:Generator[\E\], body:E->R): () = g.loop(body)
1018
1019__cond[\E,R\](c:Condition[\E\], t:E->R, e:()->R): R = c.cond[\R\](t,e)
1020__cond[\E\](c:Condition[\E\], t:E->()): () = c.cond[\()\](t, fn () => ())
1021
1022(** Used in desugaring binding %while% **)
1023__whileCond[\E\](c:Condition[\E\], b:E->()): () =
1024    c.cond[\Boolean\](fn (e): Boolean => do b(e); true end, fn ():Boolean => false)
1025
1026(** Unlike the user-visible dotted map method, this method is used for
1027    the internals of comprehension desugaring [except that at present
1028    it is not actually in use, but we're planning to use it].  As a
1029    result we know that its result will immediately be consumed, and
1030    we should *not* create an intermediate collection if we're passed
1031    a collection. **)
1032__map[\E,R\](g:Generator[\E\], f:E->R): Generator[\R\] =
1033    typecase g of
1034        SomeMappedGenerator[\E\] => g.map[\R\](f)
1035        SequentialGenerator[\E\] => SimpleMappedSeqGenerator[\E,R\](g,f)
1036        else => SimpleMappedGenerator[\E,R\](g,f)
1037    end
1038
1039(** Unlike the user-visible dotted filter method, but like the __map
1040    method, this method is intended for use in the internals of
1041    comprehension desugaring.  Again its result will immediately be
1042    consumed, and we do not create an intermediate collection but
1043    perform the filtering lazily on demand. **)
1044__filter[\E\](g:Generator[\E\], p:E->Condition[\()\]): Generator[\E\] =
1045    typecase g of
1046        FilterGenerator[\E\] => g.filter(p)
1047        SequentialGenerator[\E\] => SimpleSeqFilterGenerator[\E\](g,p)
1048        else => SimpleFilterGenerator[\E\](g,p)
1049    end
1050
1051(** Application of a BIG operator, the topmost level of comprehension desugaring. **)
1052__bigOperator[\I,O,R,L\](o:BigOperator[\I,O,R,L\],desugaredClauses:(Reduction[\L\],I->L)->L): O = do
1053    r = o.reduction()
1054    body(i): L = r.lift((o.body())(i))
1055    (o.unwrap())(r.unlift(desugaredClauses(r,body)))
1056  end
1057
1058(** Application of two nested BIG operators, possibly with fusion.  This only covers
1059    a comprehension of the form:
1060       BIG outer [ xs <- expr_o ] (BIG inner [x <- xs] expr_i)
1061    The desugarer extracts comprehensions of this form from more complex nests of
1062    comprehensions, using a combination of splitting:
1063        BIG OP [ gs_1, gs_2 ] expr = BIG OP [ gs_1 ] (BIG OP [ gs_2 ] expr)
1064    and filter squeezing:
1065        BIG OP [ xs <- g, p(xs) ] expr = BIG OP [ xs <- g.filter(p) ] expr
1066    There are some big caveats to this explanation in practice.  Most important is that
1067    we don't unlift and lift or do input/output conversion except where neccessary, so
1068    splitting skips these operations in between the inner and outer comprehension.
1069    **)
1070__bigOperator2[\I,M,O,R1,L1,R2,L2,E\](outer:BigOperator[\M,O,R1,L1\],
1071                                    inner:BigOperator[\I,M,R2,L2\],
1072                                    gg: Generator[\Generator[\E\]\],
1073                                    innerBody:E->L2): L1 = do
1074    o = outer.reduction()
1075    i = inner.reduction()
1076    gg.generate(o,fn (xs) =>
1077                   o.lift((outer.wrap())((inner.unwrap())(i.unlift(
1078                                                xs.generate(i,innerBody))))))
1079  end
1080
1081trait SequentialGenerator[\E\] extends { Generator[\E\] }
1082    seq(self) = self
1083    map[\G\](f: E->G): SequentialGenerator[\G\] =
1084        SimpleMappedSeqGenerator[\E,G\](self,f)
1085    (* TODO: make overloaded *)
1086    nest[\G\](f: E -> Generator[\G\]): Generator[\G\] =
1087        typecase f of
1088            E -> SequentialGenerator[\G\] =>
1089                SimpleNestedSeqGenerator[\E,G\](self,f)
1090            else => SimpleNestedGenerator[\E,G\](self,f)
1091        end
1092    (* TODO: make overloaded *)
1093    cross[\F\](g:Generator[\F\]): Generator[\(E,F)\] =
1094        typecase g of
1095            SequentialGenerator[\F\] =>
1096                    SimplePairSeqGenerator[\E,F\](self,g)
1097            else => SimplePairGenerator[\E,F\](self,g)
1098        end
1099end
1100
1101(** A Condition is a Generator that generates 0 or 1 element.
1102    Conditions can be used as nullary comprehension generators or
1103    as predicates in an if expression. **)
1104trait Condition[\E\] extends { ZeroIndexed[\E\], SequentialGenerator[\E\] }
1105    getter isEmpty(): Boolean = NOT holds()
1106    getter nonEmpty(): Boolean = NOT isEmpty()
1107    getter holds(): Boolean = cond[\Boolean\](fn (_:E):Boolean => true, fn () => false)
1108    getter size(): ZZ32 = if holds() then 1 else 0 end
1109    getter get(): E throws NotFound = cond[\E\](identity[\E\], fn () => throw NotFound)
1110    getter bounds(): FullRange[\ZZ32,true\] = 0 # |self|
1111    getter indices(): FullRange[\ZZ32,true\] = bounds()
1112    getter indexValuePairs(): Condition[\(ZZ32,E)\] =
1113        cond[\E\](fn (e:E) => Just[\(ZZ32,E)\](0,e), fn () => Nothing[\(ZZ32,E)\])
1114    opr |self|: ZZ32 = if holds() then 1 else 0 end
1115    opr [i:ZZ32]:E throws NotFound = if i=0 then get() else throw NotFound end
1116    opr [r:Range[\ZZ32\]]: Condition[\E\] =
1117        cond[\E\](fn (e:E): Condition[\E\] => do
1118                    r1 = (0#1)[r]
1119                    if r1.isEmpty then Nothing[\E\] else self end
1120                  end,
1121                fn (): Condition[\E\] => do r1 = (0#0)[r]; self end)
1122    getDefault(e:E): E = cond[\E\](identity[\E\], fn () => e)
1123    cond[\G\](t: E -> G, e: () -> G): G
1124    generate[\G\](r:Reduction[\G\], body: E -> G): G = cond[\G\](body,fn () => r.empty())
1125
1126    (** For a Condition, these methods run eagerly. **)
1127    map[\G\](f: E->G): Condition[\G\] =
1128        cond[\G\](fn (e:E) => Just[\G\](f(e)), fn () => Nothing[\G\])
1129    ivmap[\G\](f: (ZZ32,E)->G): Condition[\G\] =
1130        cond[\G\](fn (e:E) => Just[\G\](f(0,e)), fn () => Nothing[\G\])
1131    nest[\G\](f: E -> Generator[\G\]): Generator[\G\] =
1132        cond[\G\](f, fn () => Nothing[\G\])
1133    cross[\G\](g: Generator[\G\]): Generator[\(E,G)\] =
1134        cond[\G\](fn (e:E):Generator[\(E,G)\] => g.map[\(E,G)\](fn (g':G):(E,G) => (e,g')),
1135               fn () => Nothing[\(E,G)\])
1136    mapReduce[\R\](body: E->R, _:(R,R)->R, id:R): R =
1137        cond[\R\](body, fn () => id)
1138    reduce(_:(E,E)->E, z:E):E = cond[\E\](identity[\E\], fn ():E => z)
1139    reduce(r: Reduction[\E\]):E = cond[\E\](identity[\E\], fn ():E => r.empty())
1140    loop(f:E->()): () = cond[\()\](f,fn ():() => ())
1141    opr IN(x:E, self):Boolean = cond[\Boolean\](fn (e:E):Boolean => x=e, fn () => false)
1142end
1143
1144(** Conjunction and disjunction of condition functions **)
1145opr ANDCOND[\I\](p1:I->Condition[\()\], p2:I->Condition[\()\]): I->Condition[\()\] =
1146    fn (i:I):Boolean => p1(i).holds AND: p2(i).holds
1147
1148(** Conjunction and disjunction of condition functions **)
1149opr ORCOND[\I\](p1:I->Condition[\()\], p2:I->Condition[\()\]): I->Condition[\()\] =
1150    fn (i:I):Boolean => p1(i).holds OR: p2(i).holds
1151
1152(** Operations which use generation internally.  Should be functional
1153    methods of Generator, but that didn't work when last tested. **)
1154
1155(** IN returns true if any element generated by its second argument is
1156    = to its first argument.  x NOTIN g is simply NOT (x IN g).
1157    Unless documented otherwise, this is O(n) for an n-element
1158    Generator (it simply performs naive matching).  **)
1159opr NOTIN[\E\](x: E, this: Generator[\E\]): Boolean = NOT (x IN this)
1160
1161(* seq[\T\](g:Generator[\T\]):SequentialGenerator[\T\] = g.seq() *)
1162sequential[\T\](g:Generator[\T\]):SequentialGenerator[\T\] = seq(g)
1163
1164(************************************************************
1165* Meta-generators: BIG GENERATOR
1166************************************************************)
1167
1168(** The problem: Your code is sprinkled with the same generator code,
1169    over and over again.  Maybe it looks something like this:
1170    % for (i,v) <- a.indexValuePairs, v =/= 0, j <- 0:i do (code using i and j) %
1171    You goal: abstract this into a single generator.  You can do this as follows:
1172    % usefulGen = BIG GENERATOR[(i,v) <- a.indexValuePairs, v =/= 0, j <- 0:i] (i,j) %
1173    Not much savings there, but the important part is that you can just
1174    cut and paste the generators from the original code.  And all occurrences
1175    can be cleaned up:
1176    % for (i,j) <- usefulGen do (code using i and j) %
1177    This is possible using %map%, %filter%, and %nest%, but you end up
1178    effectively desugaring the code by hand.  Using BIG GENERATOR is much easier.
1179 **)
1180
1181(** TODO
1182
1183The big problem here is that the new desugaring story actually gets in
1184the way.  We can't simply package up a function passed in, because
1185that's being done by the __bigOperator functionality directly.
1186
1187How do we deal with reduction properties?  It's all very sticky.  And
1188we're already running into difficulties with co- and contra-variance
1189of the type parameters floating around that force us to use Any in
1190awkward places.
1191
1192In particular, we don't want to generate the data when creating the
1193generator, as that misses the whole point.  We want to defer the
1194object traversals until the moment the resulting generator is used.
1195**)
1196
1197(************************************************************
1198* The Maybe type, used instead of null
1199************************************************************)
1200
1201(* This makes excludes work without where clauses, and allows opr =()
1202   to remain non-parametric. *)
1203value trait AnyMaybe extends Equality[\AnyMaybe\] excludes Number
1204        (** \vspace{-4ex} NOT YET: %comprises Maybe[\T\] where [\T\]% *)
1205    getter holds() : Boolean
1206    opr =(self, other:AnyMaybe): Boolean = false
1207end
1208
1209just(t:Any):AnyMaybe = Just(t)
1210
1211(** %Maybe% represents either %Nothing% or a single element of type
1212    %T% (%Just[\T\]%), which may be retrieved by calling %get%.  An
1213    object of type %Maybe[\T\]% can be used as a generator; it is either
1214    empty (%Nothing%) or generates the single element yielded by
1215    %get%, so there is no issue of canonical order or parallelism.
1216
1217    Thus, %Just[\T\]% can be used as a single-element generator, and
1218    %Nothing% can be used as an empty generator. *)
1219value trait Maybe[\T\]
1220        extends { AnyMaybe, Condition[\T\] }
1221        comprises { Nothing[\T\], Just[\T\] }
1222end
1223
1224value object Just[\T\](x:T) extends Maybe[\T\]
1225    getter size()=1
1226    getter toString():String = "Just(" x ")"
1227    getter holds() = true
1228    getter get() = x
1229    opr |self| : ZZ32 = 1
1230    getDefault(_:T): T = x
1231    cond[\R\](t:T->R, _:()->R): R = t(x)
1232    generate[\R\](_:Reduction[\R\],m:T->R): R = m(x)
1233    opr[i:ZZ32]:T = if i=0 then x else fail("Maybe[" i "] nonzero index") end
1234
1235    map[\G\](f: T->G): Just[\G\] = Just[\G\](f(x))
1236    cross[\G\](g: Generator[\G\]): Generator[\(T,G)\] =
1237        g.map[\(T,G)\](fn (e:G):(T,G) => (x,e))
1238
1239    mapReduce[\R\](m: T->R, _:(R,R)->R, _:R): R = m(x)
1240    reduce(_:(T,T)->T, _:T):T = x
1241    reduce(_: Reduction[\T\]):T = x
1242    loop(f:T->()): () = f(x)
1243    opr IN(y:T, self): Boolean = x=y
1244    opr =(self,o:Just[\T\]): Boolean = x=o.get
1245end
1246
1247(* Obviously ought to be a non-parametric singleton when we get where
1248   clauses working. *)
1249value object Nothing[\T\] extends Maybe[\T\]
1250    getter size()=0
1251    getter holds() = false
1252    getter get() = throw NotFound
1253    getter toString():String = "Nothing"
1254    opr |self| : ZZ32 = 0
1255    getDefault(t:T):T = t
1256    cond[\R\](_:T->R, e:()->R): R = e()
1257    generate[\R\](r:Reduction[\R\],_:T->R): R = r.empty()
1258    opr[_:ZZ32]: T = fail("Cannot index Nothing")
1259
1260    map[\G\](f: T->G): Nothing[\G\] = Nothing[\G\]
1261    cross[\G\](g: Generator[\G\]): Generator[\(T,G)\] = Nothing[\(T,G)\]
1262
1263    mapReduce[\R\](_: T->R, _:(R,R)->R, z:R): R = z
1264    reduce(_:(T,T)->T, z:T):T = z
1265    reduce(r: Reduction[\T\]):T = r.empty()
1266    loop(f:T->()): () = ()
1267    opr IN(x:T, self): Boolean = false
1268    opr =(self,_:Nothing[\T\]) = true
1269end
1270
1271(************************************************************
1272* Exception hierarchy
1273************************************************************)
1274
1275trait Exception comprises { UncheckedException, CheckedException }
1276end
1277
1278(* Exceptions which are not checked *)
1279
1280trait UncheckedException extends Exception excludes CheckedException
1281end
1282
1283object FailCalled(s:String) extends UncheckedException
1284  toString(): String = "FAIL: " s
1285end
1286
1287object DivisionByZero extends UncheckedException
1288    toString(): String = "Division by zero"
1289end
1290
1291object UnpastingError extends UncheckedException
1292    toString(): String = "Unpasting error"
1293end
1294
1295object CallerViolation extends UncheckedException
1296    toString(): String = "Caller violation"
1297end
1298
1299object CalleeViolation extends UncheckedException
1300    toString(): String = "Callee violation"
1301end
1302
1303object TestFailure extends UncheckedException
1304    toString(): String = "Test failure"
1305end
1306
1307object ContractHierarchyViolation extends UncheckedException
1308    toString(): String = "Contract hierarchy violation"
1309end
1310
1311object NoEqualityOnFunctions extends UncheckedException
1312    toString(): String = "No equality on functions"
1313end
1314
1315object InvalidRange extends UncheckedException
1316    toString(): String = "Invalid range"
1317end
1318
1319object ForbiddenException(chain : Exception) extends UncheckedException
1320    toString(): String = "Forbidden exception"
1321end
1322
1323(* Should this be called "IndexNotFound" instead? *)
1324object NotFound extends UncheckedException
1325    toString(): String = "Not found"
1326end
1327
1328object IndexOutOfBounds(min:ZZ32,max:ZZ32,index:ZZ32) extends UncheckedException
1329    toString(): String = index " is outside the range " min " to " max
1330end
1331
1332object NegativeLength extends UncheckedException
1333    toString(): String = "Negative length"
1334end
1335
1336object IntegerOverflow extends UncheckedException
1337    toString(): String = "Integer Overflow"
1338end
1339
1340object RationalComparisonError extends UncheckedException
1341    toString(): String = "Rational comparison error"
1342end
1343
1344object FloatingComparisonError extends UncheckedException
1345    toString(): String = "Floating comparison error"
1346end
1347
1348(* Checked Exceptions *)
1349
1350trait CheckedException extends Exception excludes UncheckedException
1351end
1352
1353object CastError extends CheckedException
1354    toString(): String = "Cast error"
1355end
1356
1357object IOFailure extends CheckedException
1358    toString(): String = "I/O error"
1359end
1360
1361object MatchFailure extends CheckedException
1362    toString(): String = "Match failure"
1363end
1364
1365(* SetsNotDisjoint? *)
1366object DisjointUnionError extends CheckedException
1367    toString(): String = "Disjoint union error"
1368end
1369
1370object APIMissing extends CheckedException
1371    toString(): String = "Api is missing"
1372end
1373
1374object APINameCollision extends CheckedException
1375    toString(): String = "Api name collides with another"
1376end
1377
1378object ExportedAPIMissing extends CheckedException
1379    toString(): String = "Exported api is missing"
1380end
1381
1382object HiddenAPIMissing extends CheckedException
1383    toString(): String = "Hidden api is missing"
1384end
1385
1386object TryAtomicFailure extends CheckedException
1387    toString(): String = "Try/atomic failure"
1388end
1389
1390(* Should take a spawned thread as an argument *)
1391object AtomicSpawnSynchronization extends {UncheckedException}
1392    toString(): String = "Atomic spawn synchronization"
1393end
1394
1395(************************************************************
1396* Array support
1397************************************************************)
1398
1399oops(s:ZZ32, l:ZZ32, sz:ZZ32, got:ZZ32):() = do
1400   fail("Index of dimension " s " out of bounds; got " got
1401        " which is not in " l "#" sz);
1402end
1403
1404trait HasRank extends Equality[\HasRank\] excludes { Number, AnyMaybe }
1405  (** \vspace{-4ex} NOT YET: %comprises Array[\T,E,I\]
1406                              where [\T,E,I\]{ T extends Array[\T,E,I\] }% *)
1407  rank():ZZ32
1408  opr =(self, other:HasRank): Boolean = false
1409end
1410
1411(* Declared Rank-n-ness *)
1412trait Rank[\ nat n \] extends HasRank
1413  rank():ZZ32 = n
1414end
1415
1416(* Potemkin exclusion traits.  Really we just want to say that
1417 * Rank[\n\] excludes Rank[\m\] where { m =/= n }, but we can't yet. *)
1418
1419trait Rank1 extends { Rank[\1\]} excludes { Rank2, Rank3, Number, String }
1420end
1421
1422trait Rank2 extends { Rank[\2\]} excludes { Rank3, Number, String }
1423end
1424
1425trait Rank3 extends { Rank[\3\]} excludes { Number, String }
1426end
1427
1428(* The trait Indexed_i[\n\] indicates that something has an i^th
1429 * dimension of size n.  In general anything which extends Indexed_i
1430 * must also extend Indexed_j for j < i. *)
1431
1432trait Indexed1[\ nat n \] extends HasRank end
1433
1434trait Indexed2[\ nat n \] extends HasRank end
1435
1436trait Indexed3[\ nat n \] extends HasRank end
1437
1438(** The indexed trait indicates that an object of type T can be
1439indexed using type I to obtain elements with type E.
1440
1441An object i that's an instance of Indexed defines three basic things:
1442  The indexing operator opr [], which must be defined for every instance of
1443    the type.
1444
1445  A suite of generators: i.indices generates the index space of the
1446    array.  i itself generates the values contained at those indices.
1447    i.indexValuePairs yields pairs of (index,value).  All of these
1448    share the same natural order.  It is necessary to define one of
1449    indices() and indexValuePairs(), in addition to generate() (but
1450    the latter requirement can be dispensed by instead extending
1451    DelegatedIndexed).
1452
1453  A set of utility functions, assign, fill, and copy.  Only fill and
1454    copy need to be defined.
1455**)
1456trait Indexed[\E, I\] extends Generator[\E\]
1457    (** isEmpty indicates whether there are any valid indices.  It is
1458        defined as size=0 *)
1459    getter isEmpty(): Boolean = |self| = 0
1460    getter nonEmpty(): Boolean = NOT self.isEmpty
1461    (** %self.size% is equivalent to %|self|%. *)
1462    getter size(): ZZ32
1463    (** bounds() yields a range of indices that are valid for the
1464        indexed generator. *)
1465    getter bounds(): FullRange[\I,true\]
1466    (** indexValuePairs() generates the elements of the indexed object
1467        (exactly those elements that are generated by the object itself),
1468        but each element is paired with its index.  When we obtain
1469        (i,v) from indexValuePairs we know that:
1470           self[i] = v
1471           the i are distinct and i IN bounds()
1472           stripping away the i yields exactly the results of v <- self
1473        This generator attempts to follow the structure of the
1474        underlying object as closely as possible.  *)
1475    getter indexValuePairs(): Indexed[\(I,E),I\] =
1476        indices().map[\(I,E)\](fn (i:I): (I,E) => (i,self[i]))
1477    (** indices() yields the indices corresponding to the elements of
1478        the indexed object---it corresponds to the index component of
1479        indexValuePairs().  This may in general be a subset of all the
1480        valid indices represented by bounds().  This generator
1481        attempts to follow the structure of the underlying object as
1482        closely as possible. *)
1483    getter indices(): Indexed[\I,I\] =
1484        indexValuePairs().map[\I\](fn (i:I, e:E): I => i)
1485
1486    (** %|self|% indicates the number of distinct valid indices that may
1487        be passed to indexing operations. *)
1488    opr |self| : ZZ32
1489
1490    (** Indexing.  i IN bounds() must hold. *)
1491    opr[i:I] : E
1492
1493    (** Locality of a particular index (NOT of its contents!). *)
1494    region(i:I): Region = Global
1495
1496    (** Indexing by ranges.  The results are 0-based when the
1497        underlying index type has a notion of 0.  This ensures
1498        consistency of behavior between types such as vectors that
1499        *only* support 0 indexing and types such as arrays that permit
1500        other choices of lower bounds.  The easiest way to write the
1501        index by ranges operation for an instance of Indexed is to
1502        take advantage of indexing on the ranges themselves by writing
1503        (bounds())[r] in order to narrow and bounds check the range r
1504        and obtain a closed range of indices on the underlying
1505        data. **)
1506    opr[r:Range[\I\]] : Indexed[\E,I\]
1507    opr[_:OpenRange[\Any\]] : Indexed[\E,I\] = self[OpenRange[\I\]]
1508
1509    (** Roughly speaking, ivmap(f) is equivalent to
1510        indexValuePairs.map(f).  However ivmap function isn't merely a
1511        convenient shortcut.  It's actually intended to create a copy
1512        of the underlying indexed structure when that is appropriate.
1513
1514        The usual map function in Generator should do the same (and
1515        does for the instances in this library).  Copying can be bad
1516        for space, but is complexity-preserving if the mapped
1517        generator is used more than once. **)
1518    ivmap[\R\](f:(I,E)->R): Indexed[\R, I\] = indexValuePairs().map[\R\](f)
1519    map[\R\](f:E->R): Indexed[\R, I\] = SimpleMappedIndexed[\E,R,I\](self,f)
1520
1521    (** indexOf(e) returns an index at which e can be found,
1522        or Nothing if no such index exists. **)
1523    indexOf(e:E): Maybe[\I\] =
1524        label found
1525            for (i,v) <- indexValuePairs(), v=e do
1526                exit found with Just[\I\](i)
1527            end
1528            Nothing[\I\]
1529        end found
1530end
1531
1532trait ZeroIndexed[\E\] extends Indexed[\E,ZZ32\]
1533    bounds(): FullRange[\ZZ32,true\] = 0 # |self|
1534    zip[\F\](g:ZeroIndexed[\F\]):ZeroIndexed[\(E,F)\] =
1535        DefaultZip[\E,F\](self,g)
1536end
1537
1538object DefaultZip[\E,F\](e:ZeroIndexed[\E\],f:ZeroIndexed[\F\])
1539        extends { ZeroIndexed[\(E,F)\], DelegatedIndexed[\(E,F),ZZ32\] }
1540    getter size(): ZZ32 = |self|
1541    getter indices(): Generator[\ZZ32\] =
1542        if |e| <= |f| then e.indices else f.indices end
1543    opr |self| : ZZ32 = |e| MIN |f|
1544    opr[i:ZZ32]:(E,F) = (e[i],f[i])
1545    opr[r:Range[\ZZ32\]] : ZeroIndexed[\(E,F)\] =
1546        DefaultZip[\E,F\](e[r],f[r])
1547end
1548
1549trait LexicographicOrder[\T extends LexicographicOrder[\T,E\],E\]
1550        extends { StandardTotalOrder[\T\], ZeroIndexed[\E\] }
1551    opr CMP(self, other:T): TotalComparison =
1552        self.zip[\E\](other).generate[\TotalComparison\](
1553            LexicographicReduction,
1554            fn(a:E,b:E): TotalComparison => a CMP b) LEXICO
1555        (|self| CMP |other|)
1556    (** We give a specialized version of = because it can fail faster
1557        than CMP by checking sizes early. **)
1558    opr =(self,other:T): Boolean =
1559        (|self| = |other|) AND:
1560          (BIG AND [(a,b)<-self.zip[\E\](other)] a=b)
1561end
1562
1563toArray[\E\](g:Indexed[\E,ZZ32\]): Array[\E,ZZ32\] = do
1564    bnds = g.bounds
1565    r = array[\E\](|bnds|).shift(bnds.lower())
1566    for (i,v) <- g.indexValuePairs do
1567        r.init(i,v)
1568    end
1569    r
1570  end
1571
1572(** DelegatedIndexed is an Indexed generator that has recourse to
1573    another Indexed generator() internally.  By default this in turn
1574    is defined in terms of indexValuePairs().  Thus it's only
1575    necessary to define either indexValuePairs() or indices().
1576
1577    This class is designed for convenience; it shouldn't be used as a
1578    type in runing code, but only as a supertype in lieu of Indexed.
1579**)
1580trait DelegatedIndexed[\E,I\] extends Indexed[\E,I\]
1581    getter generator(): Generator[\E\] =
1582        indexValuePairs().map[\E\](fn (i:I, e:E): E => e)
1583    getter size(): ZZ32 = |generator()|
1584    opr |self| : ZZ32 = |generator()|
1585    generate[\R\](r: Reduction[\R\], body: E->R): R =
1586        generator().generate[\R\](r,body)
1587    seq(self): SequentialGenerator[\E\] = seq(generator())
1588    cross[\G\](g: Generator[\G\]): Generator[\(E,G)\] =
1589        generator().cross[\G\](g)
1590    mapReduce[\R\](body: E->R, join:(R,R)->R, id:R): R =
1591        generator().mapReduce[\R\](body,join,id)
1592    reduce(j:(E,E)->E, z:E):E = generator().reduce(j,z)
1593    reduce(r: Reduction[\E\]):E = generator().reduce(r)
1594    loop(f:E->()): () = generator().loop(f)
1595end
1596
1597(** The MutableIndexed trait is an indexed trait whose elements can be
1598    mutated using indexed assignment.  Right now we're using this type
1599    in a somewhat dangerous way, since eg Array1[\E,b0,s0\] extends
1600    both Indexed[\Array1[\E,b0,s0\],E,ZZ32\] and
1601    Indexed[\Array[\E,ZZ32\],E,ZZ32\].  We will need to find a
1602    solution to this at some point.
1603**)
1604trait MutableIndexed[\E, I\]
1605        extends { Indexed[\E,I\] }
1606    opr[i:I]:=(v:E) : ()
1607
1608    (** For Ranged assignment, the extents of r and v.bounds must
1609        match, but the lower bounds need not. **)
1610    opr[r:Range[\I\]]:=(v:Indexed[\E,I\]) : ()
1611    opr[_:OpenRange[\Any\]]:=(v:Indexed[\E,I\]) : () =
1612        do self[bounds()] := v end
1613end
1614
1615(* Array whose bounds are implicit rather than static, and which may
1616   be either mutable or immutable. *)
1617trait ReadableArray[\E,I\]
1618        extends { HasRank, Indexed[\E,I\], DelegatedIndexed[\E,I\] }
1619        comprises { Array[\E,I\], ImmutableArray[\E,I\] }
1620    (** CONCRETE GETTERS
1621        Default implementations of getters based on abstract methods
1622        below. **)
1623    getter indices(): Indexed[\I,I\] = bounds()
1624    getter indexValuePairs(): Indexed[\(I,E),I\] =
1625        zeroIndices().map[\(I,E)\](fn (i:I):(I,E) => (toIndex(i),get(i)))
1626    getter generator(): Indexed[\E,I\] =
1627        zeroIndices().map[\E\](fn (i:I):E => get(i))
1628
1629    (** CONCRETE METHODS
1630        Default implementations of most array stuff based on the above.
1631        The things we can't provide are anything involving replica. **)
1632
1633    opr[i:I]:E = get(offset(i))
1634
1635    (** Initialize element at index i with value v.  This should occur
1636        once, before any other access or assignment occurs to element
1637        i.  An error will be signaled if an uninitialized element is
1638        read or an initialized element is re-initialized. **)
1639    init(i:I, v:E) = init0(offset(i),v)
1640
1641    generate[\R\](r: Reduction[\R\], body: E->R): R =
1642        generator().generate[\R\](r,body)
1643    seq(self): SequentialGenerator[\E\] = seq(generator())
1644
1645    (** 0-based non-bounds-checked indexing **)
1646    get(i:I): E
1647    init0(i:I, e:E): ()
1648    zeroIndices(): FullRange[\I,true\]
1649    (** Convert from base()-based indexing to 0-based indexing,
1650        performing bounds checking. **)
1651    offset(i:I): I
1652    (** Convert from 0-based indexing to base()-based indexing **)
1653    toIndex(i:I): I
1654
1655    (** Indexed functionality with more specific type information **)
1656    opr[r:Range[\I\]] : ReadableArray[\E,I\]
1657    opr[_:OpenRange[\Any\]] : ReadableArray[\E,I\]
1658    ivmap[\R\](f:(I,E)->R): ReadableArray[\R, I\]
1659    map[\R\](f:E->R): ReadableArray[\R, I\]
1660
1661    (** Shift the origin of an array.  This should yield a new view of
1662        the same array; ie initialization and/or update to either will
1663        be reflected in the other. **)
1664    shift(newOrigin:I):ReadableArray[\E,I\]
1665
1666    (** Bulk initialization of an array using a given function or
1667        value.  These are defined with more specific self types in
1668        StandardImmutableArrayType. **)
1669    fill(f:I->E):ReadableArray[\E,I\]
1670    fill(v:E):ReadableArray[\E,I\]
1671
1672    copy():ReadableArray[\E,I\]
1673
1674    (** Create a fresh array structurally identical to the present
1675        one, but holding elements of type U. **)
1676    replica[\U\]():ReadableArray[\U,I\]
1677
1678    opr =(self, other:HasRank): Boolean =
1679        typecase other of
1680            ReadableArray[\E,I\] => indices().generate[\Boolean\](AndReduction,
1681                                           fn (i:I):Boolean => (self[i]=other[i]))
1682            else => false
1683        end
1684
1685end
1686
1687trait ImmutableArray[\E,I\] extends { ReadableArray[\E,I\] }
1688        excludes { Array[\E,I\] }
1689    opr[r:Range[\I\]] : ImmutableArray[\E,I\]
1690    opr[_:OpenRange[\Any\]] : ImmutableArray[\E,I\]
1691    ivmap[\R\](f:(I,E)->R): ImmutableArray[\R, I\]
1692    map[\R\](f:E->R): ImmutableArray[\R, I\]
1693    shift(newOrigin:I):ImmutableArray[\E,I\]
1694    fill(f:I->E):ImmutableArray[\E,I\]
1695    fill(v:E):ImmutableArray[\E,I\]
1696    copy():ImmutableArray[\E,I\]
1697    replica[\U\]():ImmutableArray[\U,I\]
1698
1699    (** Thaw array (return mutable copy) **)
1700    thaw():Array[\E,I\]
1701end
1702
1703trait Array[\E,I\] extends { ReadableArray[\E,I\], MutableIndexed[\E,I\] }
1704    (** 0-based non-bounds-checked indexing **)
1705    put(i:I, e:E): ()
1706    opr[i:I]:=(v:E):() = put(offset(i),v)
1707
1708    opr[r:Range[\I\]]:=(a:Indexed[\E,I\]):() = do
1709        a0 = a[a.bounds]        (* Make a have 0 origin *)
1710        s0 = self[r]            (* Make self have 0 origin *)
1711        if a0.bounds = s0.bounds then
1712            for (i,v) <- a0.indexValuePairs do
1713                s0.put(i,v)
1714            end
1715        else
1716            fail("Can't assign indexed with bounds " a.bounds //
1717                 " to differently-sized subarray " self.bounds)
1718        end
1719      end
1720
1721    (** The following are repetition with better return type info. **)
1722    opr[r:Range[\I\]] : Array[\E,I\]
1723    opr[_:OpenRange[\Any\]] : Array[\E,I\]
1724    ivmap[\R\](f:(I,E)->R): Array[\R, I\]
1725    map[\R\](f:E->R): Array[\R, I\]
1726    shift(newOrigin:I):Array[\E,I\]
1727    fill(f:I->E):Array[\E,I\]
1728    fill(v:E):Array[\E,I\]
1729    assign(f:I->E):Array[\E,I\]
1730    copy():Array[\E,I\]
1731    replica[\U\]():Array[\U,I\]
1732
1733    (** Freeze array (return mutable copy) **)
1734    freeze(): ImmutableArray[\E,I\]
1735end
1736
1737(** Factory for arrays that returns an empty 0-indexed array of a given
1738    run-time-determined size. **)
1739array[\E\](x:ZZ32):Array[\E,ZZ32\] = __arr1(__Proxy[\E\],reflect(x))
1740array[\E\](x:ZZ32,y:ZZ32):Array[\E,(ZZ32,ZZ32)\] =
1741    __arr2(__Proxy[\E\],reflect(x), reflect(y))
1742array[\E\](x:ZZ32,y:ZZ32,z:ZZ32):Array[\E,(ZZ32,ZZ32,ZZ32)\] =
1743    __arr3(__Proxy[\E\],reflect(x), reflect(y), reflect(z))
1744
1745(* This should be local to array, but we don't support local
1746   parametric methods in the language spec at all at the moment. *)
1747__arr1[\E, nat n\](w:__Proxy[\E\],x:N[\n\]):Array1[\E,0,n\] =
1748    array1[\E,n\]()
1749__arr2[\E, nat n, nat m\](w:__Proxy[\E\],x:N[\n\],y:N[\m\]):
1750    Array2[\E,0,n,0,m\] = array2[\E,n,m\]()
1751__arr3[\E, nat n, nat m, nat p\](w:__Proxy[\E\],x:N[\n\],y:N[\m\],z:N[\p\]):
1752    Array3[\E,0,n,0,m,0,p\] = array3[\E,n,m,p\]()
1753
1754(** Factory for immutable arrays that returns an empty 0-indexed array
1755    of a given run-time-determined size. **)
1756immutableArray[\E\](x:ZZ32):ImmutableArray[\E,ZZ32\] =
1757    __imm1(__Proxy[\E\],reflect(x))
1758(*
1759immutableArray[\E\](x:ZZ32,y:ZZ32):ImmutableArray[\E,(ZZ32,ZZ32)\] =
1760    __imm2(__Proxy[\E\],reflect(x), reflect(y))
1761immutableArray[\E\](x:ZZ32,y:ZZ32,z:ZZ32):ImmutableArray[\E,(ZZ32,ZZ32,ZZ32)\] =
1762    __imm3(__Proxy[\E\],reflect(x), reflect(y), reflect(z))
1763*)
1764
1765(* This should be local to immutableArray, but we don't support local
1766   parametric methods in the language spec at all at the moment. *)
1767__imm1[\E, nat n\](w:__Proxy[\E\],x:N[\n\]):ImmutableArray1[\E,0,n\] =
1768   immutableArray1[\E,n\]()
1769(*
1770__imm2[\E, nat n, nat m\](w:__Proxy[\E\],x:N[\n\],y:N[\m\]):
1771    ImmutableArray2[\E,0,n,0,m\] = immutableArray2[\E,n,m\]()
1772__imm3[\E, nat n, nat m, nat p\](w:__Proxy[\E\],x:N[\n\],y:N[\m\],z:N[\p\]):
1773    ImmutableArray3[\E,0,n,0,m,0,p\] = immutableArray3[\E,n,m,p\]()
1774*)
1775
1776primitiveArray[\E\](x:ZZ32):Array[\E,ZZ32\] = __parr(__Proxy[\E\],reflect(x))
1777__parr[\E, nat n\](w:__Proxy[\E\],x:N[\n\]):PrimitiveArray[\E,n\] =
1778    PrimitiveArray[\E,n\]()
1779
1780primitiveImmutableArray[\E\](x:ZZ32):ImmutableArray[\E,ZZ32\] =
1781    __piarr(__Proxy[\E\],reflect(x))
1782__piarr[\E, nat n\](w:__Proxy[\E\],x:N[\n\]):PrimImmutableArray[\E,n\] =
1783    PrimImmutableArray[\E,n\]()
1784
1785(** NOTE: StandardImmutableArrayType is a parent of
1786    StandardMutableArrayType.  It therefore doesn't extend
1787    ImmutableArray as you might expect.  Other types that extend
1788    it should also extend ImmutableArray explicitly. **)
1789trait StandardImmutableArrayType[\T extends StandardImmutableArrayType[\T,E,I\],E,I\]
1790        extends { ReadableArray[\E,I\] }
1791    fill(f:I->E):T = do
1792        for i <- zeroIndices() do init0(i,f(toIndex(i))) end
1793        self
1794      end
1795    fill(v:E):T = do
1796        for i <- zeroIndices() do init0(i,v) end
1797        self
1798      end
1799
1800    copy():T
1801end
1802
1803
1804trait StandardMutableArrayType[\T extends StandardMutableArrayType[\T,E,I\],E,I\]
1805        extends { StandardImmutableArrayType[\T,E,I\], Array[\E,I\] }
1806    assign(v:T):T = do
1807        for i <- zeroIndices() do put(i,v.get(i)) end
1808        self
1809      end
1810    assign(f:I->E):T = do
1811        for i <- zeroIndices() do put(i,f(toIndex(i))) end
1812        self
1813      end
1814end
1815
1816(* Canonical partitioning of a positive number x into two pieces.  If
1817     (a,b) = partition(n)
1818   and n > 0 then 0 < a <= b,  n = a + b.
1819   As it turns out we choose a to be the largest power of 2 < n.
1820*)
1821partition(x:ZZ32):(ZZ32,ZZ32) = do
1822    m = partitionL(x)
1823    (m,x-m)
1824  end
1825
1826(** A ReadableArray1[\T,b0,s0\] is an arbitrary 1-dimensional array
1827    whose s0 elements are of type T, and whose lowest index is b0.
1828
1829    The natural order of all generators is from b0 to b0+s0-1. **)
1830trait ReadableArray1[\T, nat b0, nat s0\]
1831        extends { Indexed1[\s0\], Rank1, ReadableArray[\T,ZZ32\] }
1832        comprises { ImmutableArray1[\T,b0,s0\], Array1[\T,b0,s0\] }
1833    getter size():ZZ32 = s0
1834    getter bounds():ScalarRange[\ZZ32,true\] = ParRange[\ZZ32,true\](b0,s0)
1835    getter mutability():String
1836    getter toString() = do
1837        r = "[" b0 "#" s0 "]" mutability() " = ["
1838        if s0=0 then
1839            r "]"
1840        else
1841            f(i:ZZ32,t:T):String = " " t
1842            j(a:String,b:String):String = a b
1843            r indexValuePairs().mapReduce[\String\](f,j,"") " ]"
1844        end
1845      end
1846
1847    opr |self| : ZZ32 = s0
1848
1849    subarray[\nat b, nat s, nat o\]():ReadableArray1[\T, b, s\]
1850
1851    (* Offset converts from b0 indexing to 0 indexing,
1852       bounds checking en route *)
1853    offset(i:ZZ32):ZZ32 = do
1854        r = i - b0
1855        if NOT (0 <= r < s0) then oops(1, b0, s0, i) end
1856        r
1857    end
1858    toIndex(i:ZZ32):ZZ32 = i + b0
1859
1860    zeroIndices(): ScalarRange[\ZZ32,true\] = ParRange[\ZZ32,true\](0,s0)
1861end
1862
1863trait ImmutableArray1[\T, nat b0, nat s0\]
1864    extends { StandardImmutableArrayType[\ImmutableArray1[\T,b0,s0\],T,ZZ32\],
1865              ImmutableArray[\T,ZZ32\], ReadableArray1[\T,b0,s0\] }
1866    getter mutability():String = "(immutable)"
1867    shift(o:ZZ32): ImmutableArray[\T,ZZ32\] =
1868        if o=0 then
1869            self
1870        else
1871            __subarrayI(self,reflect(o),N[\s0\],N[\b0\])
1872        end
1873
1874    opr[r: Range[\ZZ32\]] : ImmutableArray[\T,ZZ32\] = do
1875        r' = (bounds())[r]
1876        z = N[\0\]
1877        s = reflect( |r'| )
1878        l = reflect(r'.lower())
1879        __subarrayI(self,z,s,l)
1880      end
1881    opr[_:OpenRange[\ZZ32\]] : ImmutableArray1[\T,0,s0\] =
1882        subarray[\0,s0,0\]()
1883    opr[_:OpenRange[\Any\]] : ImmutableArray1[\T,0,s0\] =
1884        subarray[\0,s0,0\]()
1885
1886    (** subarray selects a subarray of this array based on static parameters.
1887        b#s are the new bounds of the array; o is
1888        the index of the subarray within the current array. **)
1889    subarray[\nat b, nat s, nat o\]():ImmutableArray1[\T, b, s\] = do
1890        boundsCheck = (bounds())[o#s]
1891        __ImmutableSubArray1[\T,b,s,b0,s0\](self,o-b0,1)
1892    end
1893
1894    (* the replica method returns a replica of the array (similar layout
1895       etc.) but with a different element type. *)
1896    replica[\U\]():ImmutableArray1[\U,b0,s0\] = __immutableFactory1[\U,b0,s0\]()
1897
1898    copy():ImmutableArray1[\T,b0,s0\] =
1899        replica[\T\]().fill(fn (i:ZZ32):T => get(i-b0))
1900
1901    thaw():Array1[\T,b0,s0\] =
1902        __builtinFactory1[\T,b0,s0\]().fill(fn (i:ZZ32):T => get(i-b0))
1903
1904    map[\R\](f:T->R): ImmutableArray1[\R,b0,s0\] =
1905        replica[\R\]().fill(fn (i:ZZ32):R => f(get(i-b0)))
1906    ivmap[\R\](f:(ZZ32,T)->R): ImmutableArray1[\R,b0,s0\] =
1907        replica[\R\]().fill(fn (i:ZZ32):R => f(i,get(i-b0)))
1908end
1909
1910(** Array1[\T,b0,s0\] is a 1-dimension array whose s0 elements are of
1911    type T, and whose lowest index is b0. **)
1912trait Array1[\T, nat b0, nat s0\]
1913    extends { ReadableArray1[\T,b0,s0\],
1914              StandardMutableArrayType[\Array1[\T,b0,s0\],T,ZZ32\] }
1915    excludes {Number, String}
1916
1917    getter mutability():String = ""
1918
1919    shift(o:ZZ32): Array[\T,ZZ32\] =
1920        if o=0 then
1921            self
1922        else
1923            __subarray(self,reflect(o),N[\s0\],N[\b0\])
1924        end
1925
1926    opr[r: Range[\ZZ32\]] : Array[\T,ZZ32\] = do
1927        r' = (bounds())[r]
1928        z = N[\0\]
1929        s = reflect( |r'| )
1930        l = reflect(r'.lower())
1931        __subarray(self,z,s,l)
1932      end
1933    opr[_:OpenRange[\ZZ32\]] : Array1[\T,0,s0\] =
1934        subarray[\0,s0,0\]()
1935    opr[_:OpenRange[\Any\]] : Array1[\T,0,s0\] =
1936        subarray[\0,s0,0\]()
1937
1938    (** subarray selects a subarray of this array based on static parameters.
1939        b#s are the new bounds of the array; o is
1940        the index of the subarray within the current array. **)
1941    subarray[\nat b, nat s, nat o\]():Array1[\T, b, s\] = do
1942      boundsCheck = (bounds())[o#s]
1943      __SimpleSubArray1[\T,b,s,b0,s0\](self,o-b0,1)
1944    end
1945
1946    (* the replica method returns a replica of the array (similar layout
1947       etc.) but with a different element type. *)
1948    replica[\U\]():Array1[\U,b0,s0\] = __builtinFactory1[\U,b0,s0\]()
1949
1950    copy():Array1[\T,b0,s0\] =
1951        replica[\T\]().fill(fn (i:ZZ32):T => get(i-b0))
1952
1953    freeze():ImmutableArray1[\T,b0,s0\] =
1954        __immutableFactory1[\T,b0,s0\]().fill(fn (i:ZZ32):T => get(i-b0))
1955
1956    map[\R\](f:T->R): Array1[\R,b0,s0\] =
1957        replica[\R\]().fill(fn (i:ZZ32):R => f(get(i-b0)))
1958    ivmap[\R\](f:(ZZ32,T)->R): Array1[\R,b0,s0\] =
1959        replica[\R\]().fill(fn (i:ZZ32):R => f(i,get(i-b0)))
1960end
1961
1962(* WORK AROUND absence of type inference in method calls. *)
1963__subarray[\T, nat b0, nat s0, nat b, nat s, nat o\]
1964          (it:Array1[\T,b0,s0\],
1965           _:N[\b\],_:N[\s\],_:N[\o\]):Array1[\T,b,s\] =
1966    it.subarray[\b,s,o\]()
1967
1968__subarrayI[\T, nat b0, nat s0, nat b, nat s, nat o\]
1969          (it:ImmutableArray1[\T,b0,s0\],
1970           _:N[\b\],_:N[\s\],_:N[\o\]):ImmutableArray1[\T,b,s\] =
1971    it.subarray[\b,s,o\]()
1972
1973
1974(** A 1-D subarray of an Array1.
1975    b_a#s_a is the underlying array's bounds; b0#s0 is the
1976    result bounds.  o0 is the starting offset in the underlying array,
1977    defined in 0-indexed space.  m0 the stride within that array.
1978    Invariant: (s0-1) m0 + o0 - b_a) < s_a *)
1979object __SimpleSubArray1[\T, nat b0, nat s0, nat b_a, nat s_a\]
1980       (arr:Array1[\T,b_a,s_a\], o0:ZZ32, m0:ZZ32)
1981       extends Array1[\T, b0, s0\]
1982    index(i:ZZ32):T = i m0 + o0
1983    get(i:ZZ32):T = arr.get(index(i))
1984    put(i:ZZ32,v:T): () = arr.put(index(i),v)
1985    init0(i:ZZ32,v:T): () = arr.init0(index(i),v)
1986    subarray[\nat b, nat s, nat o\]():Array1[\T, b, s\] = do
1987        boundsCheck = (bounds())[o#s]
1988        o_n : ZZ32 = o - b0
1989        __SimpleSubArray1[\T, b, s, b_a, s_a\](arr, index(o_n), m0)
1990      end
1991end
1992
1993(** The same as above, but immutable. **)
1994object __ImmutableSubArray1[\T, nat b0, nat s0, nat b_a, nat s_a\]
1995       (arr:ImmutableArray1[\T,b_a,s_a\], o0:ZZ32, m0:ZZ32)
1996       extends ImmutableArray1[\T, b0, s0\]
1997    index(i:ZZ32):T = i m0 + o0
1998    get(i:ZZ32):T = arr.get(index(i))
1999    put(i:ZZ32,v:T): () = arr.put(index(i),v)
2000    init0(i:ZZ32,v:T): () = arr.init0(index(i),v)
2001    subarray[\nat b, nat s, nat o\]():ImmutableArray1[\T, b, s\] = do
2002        boundsCheck = (bounds())[o#s]
2003        o_n : ZZ32 = o - b0
2004        __ImmutableSubArray1[\T, b, s, b_a, s_a\](arr, index(o_n), m0)
2005      end
2006end
2007
2008trait AnyVector end
2009
2010trait Vector[\T extends Number, nat s0\]
2011        extends { AnyVector, Array1[\T,0,s0\], AdditiveGroup[\Vector[\T,s0\]\] }
2012        excludes { AnyMultiplicativeRing }
2013    opr +(self, v:Vector[\T,s0\]): Vector[\T,s0\] =
2014        ivmap[\T\](fn (i:ZZ32, e: T):T => e + v.get(i))
2015    opr -(self, v:Vector[\T,s0\]): Vector[\T,s0\] =
2016        ivmap[\T\](fn (i:ZZ32, e: T):T => e - v.get(i))
2017    opr -(self): Vector[\T,s0\] = map[\T\](fn (e: T):T => - e)
2018    scale(t: T): Vector[\T,s0\] = map[\T\](fn (v) => t v)
2019    pmul(v: Vector[\T,s0\]): Vector[\T,s0\] =
2020        ivmap[\T\](fn (i:ZZ32, e: T):T => e v.get(i))
2021    dot(v: Vector[\T,s0\]): T =
2022        SUM [(i,me_i)<-indexValuePairs()] me_i v.get(i)
2023end
2024
2025object __DefaultVector[\T, nat s0\]() extends Vector[\T,s0\]
2026  mem: PrimitiveArray[\T,s0\] = PrimitiveArray[\T,s0\]()
2027  get(i:ZZ32):T = mem.get(i)
2028  put(i:ZZ32, v:T) = mem.put(i,v)
2029  init0(i:ZZ32, v:T) = mem.init0(i,v)
2030  replica[\U\]() = array1[\U,s0\]()
2031end
2032
2033(* builtinFactory1 must be a non-overloaded 0-parameter factory for
2034   1-D arrays.  The type parameters are enshrined in LHSEvaluator.java
2035   and NonPrimitive.java; the factory name is enshrined in
2036   WellKnownNames.java.  There must be some factory, named in this
2037   file, with this type signature.  A similar thing is true for
2038   K-dimensional array types. *)
2039__builtinFactory1[\T, nat b0, nat s0\]():Array1[\T,b0,s0\] = do
2040    r = array1[\T,s0\]()
2041    typecase _ = N[\b0\] of
2042        N[\0\] => r
2043        else => r.subarray[\b0,s0,0\]()
2044    end
2045  end
2046
2047(* immutableFactory1 is a non-overloaded 0-parameter factory for
2048   0-indexed 1-D arrays.  It is also mentioned in WellKnownNames as it
2049   is used to allocate storage for varargs. *)
2050__immutableFactory1[\T, nat b0, nat s0\]():ReadableArray1[\T,b0,s0\] = do
2051    r = immutableArray1[\T,s0\]()
2052    typecase _ = N[\b0\] of
2053        N[\0\] => r
2054        else => r.subarray[\b0,s0,0\]()
2055    end
2056  end
2057
2058(* TODO: fix when Number is covariant. *)
2059array1[\T, nat s0\]():Array1[\T,0,s0\] =
2060    typecase _ = __Proxy[\T\] of
2061        __Proxy[\ZZ32\] => vector[\T,s0\]()
2062        __Proxy[\ZZ64\] => vector[\T,s0\]()
2063        __Proxy[\RR64\] => vector[\T,s0\]()
2064        __Proxy[\Number\] => vector[\T,s0\]()
2065        else => PrimitiveArray[\T,s0\]()
2066    end
2067array1[\T, nat s0\](v:T):Array1[\T,0,s0\] = array1[\T,s0\]().fill(v)
2068array1[\T, nat s0\](f:ZZ32->T):Array1[\T,0,s0\] = array1[\T,s0\]().fill(f)
2069
2070immutableArray1[\T, nat s0\](): ImmutableArray1[\T,0,s0\] =
2071    PrimImmutableArray[\T,s0\]()
2072
2073(* vector is the same as array1, but specialized to numeric type arguments *)
2074vector[\T extends Number, nat s0\]():Vector[\T,s0\] = __DefaultVector[\T,s0\]()
2075vector[\T extends Number, nat s0\](v:T):Vector[\T,s0\] =
2076    vector[\T,s0\]().fill(v)
2077vector[\T extends Number, nat s0\](f:ZZ32->T):Vector[\T,s0\] =
2078    vector[\T,s0\]().fill(f)
2079
2080pmul[\ T extends Number, nat k \]
2081    (a : Vector[\T,k\], b : Vector[\T,k\]):Vector[\T,k\] = a.pmul(b)
2082
2083opr DOT[\ T extends Number, nat n \]
2084       (me : Vector[\T,n\], other : Vector[\T,n\]):T = me.dot(other)
2085
2086opr juxtaposition[\ T extends Number, nat n \]
2087     (me : Vector[\T,n\], other : Vector[\T,n\]):T = me.dot(other)
2088
2089opr DOT[\ T extends Number, nat n \]
2090       (me : Vector[\T,n\], other : T) : Vector[\T,n\] = me.scale(other)
2091
2092opr juxtaposition[\ T extends Number, nat n \]
2093     (me : Vector[\T,n\], other : T) : Vector[\T,n\] = me.scale(other)
2094
2095opr DOT[\ T extends Number, nat n \]
2096        (other : T, me : Vector[\T,n\]) : Vector[\T,n\] = me.scale(other)
2097
2098opr juxtaposition[\ T extends Number, nat n \]
2099     (other : T, me : Vector[\T,n\]) : Vector[\T,n\] = me.scale(other)
2100
2101squaredNorm[\T extends Number, nat s0\](a:Vector[\T,s0\]):T = a.dot(a)
2102
2103opr ||[\ T extends Number, nat k \]me : Vector[\T,k\]|| : RR64 = SQRT squaredNorm(me)
2104
2105(** Array2[\T,b0,s0,b1,s1\] is the type of 2-dimensional arrays of
2106    element type T, with size s0 in the first dimension and s1 in the
2107    second dimension and lowest index (b0,b1).  Natural order for all
2108    generators in each dimension is from b to b+s-1; the overall order
2109    of elements need only be consistent with the cross product of
2110    these orderings (see Generator.cross()). **)
2111trait Array2[\T, nat b0, nat s0, nat b1, nat s1\]
2112    extends { Indexed1[\s0\], Indexed2[\s1\], Rank2,
2113              StandardMutableArrayType[\Array2[\T,b0,s0,b1,s1\],T,(ZZ32,ZZ32)\] }
2114    excludes { Number, String }
2115  getter size():ZZ32 = s0 s1
2116  getter bounds():Tuple2Range[\ZZ32,ZZ32,true\] = Tuple2Range[\ZZ32,ZZ32,true\](b0,b1,s0,s1)
2117  getter toString() = do
2118    r : String := "[" b0 "#" s0 "," b1 "#" s1 "] ="
2119    row(i) =
2120      for j <- seq(0#s1) do
2121         r := r " " get(i,j)
2122      end
2123    if s0 = 0 then
2124      r " []"
2125    else
2126      r := r "\n["
2127      row(0)
2128      for i <- seq(1#(s0-1)) do
2129        r := r "\n "
2130        row(i)
2131      end
2132      r " ]"
2133    end
2134  end
2135  opr |self| : ZZ32 = s0 s1
2136  (* Translate from b0,b1-indexing to 0-indexing, checking bounds. *)
2137  offset(t_1:(ZZ32,ZZ32)):(ZZ32,ZZ32) = do
2138    (a0,a1) = t_1
2139    c0 = a0 - b0
2140    c1 = a1 - b1
2141    if NOT (0 <= c0 < s0) then
2142        oops(1,b0,s0,a0)
2143    elif NOT (0 <= c1 < s1) then
2144        oops(2,b1,s1,a1)
2145    else
2146        (c0,c1)
2147    end
2148  end
2149  toIndex(t_1:(ZZ32,ZZ32)):(ZZ32,ZZ32) = do (a0,a1)=t_1; (a0+b0,a1+b1) end
2150  opr[x:ZZ32,y:ZZ32]:=(v:T):() = do self[ (x,y) ] := v end
2151  opr[r:Range[\(ZZ32,ZZ32)\]]: Array[\T,(ZZ32,ZZ32)\] = do
2152      r' = (bounds())[r]
2153      (z0,z1) = r'.extent()
2154      (l0,l1) = r'.lower()
2155      __subarray(self, N[\0\],reflect(z0), N[\0\], reflect(z1),
2156                 reflect(l0),reflect(l1))
2157    end
2158  opr[_:OpenRange[\ZZ32\]] : Array2[\T,0,s0,0,s1\] =
2159      subarray[\0,s0,0,s1,0,0\]()
2160  opr[_:OpenRange[\Any\]] : Array2[\T,0,s0,0,s1\] =
2161      subarray[\0,s0,0,s1,0,0\]()
2162  shift(t_1:(ZZ32,ZZ32)): Array[\T,(ZZ32,ZZ32)\] = do
2163      (o0,o1)=t_1
2164      if o0=0 AND o1=0 then
2165          self
2166      else
2167          __subarray(self,reflect(o0),N[\s0\], reflect(o1),N[\s1\], N[\b0\],N[\b1\])
2168      end
2169    end
2170
2171  (** 2-D subarray given static subarray parameters.
2172      (bo1,bo2)#(so1,so2) are output bounds.
2173      The result is the subarray starting at (o0,o1) in the original array.
2174   **)
2175  subarray[\nat bo0, nat so0, nat bo1, nat so1, nat o0, nat o1\]
2176          (): Array2[\T,bo0,so0,bo1,so1\] = do
2177      boundsCheck = (bounds())[ (o0,o1)#(so0,so1) ]
2178      SubArray2[\T,bo0,so0,bo1,so1,b0,s0,b1,s1\](self,1,o0,1,o1)
2179    end
2180
2181  zeroIndices():Tuple2Range[\ZZ32,ZZ32,true\] = Tuple2Range[\ZZ32,ZZ32,true\](0,0,s0,s1)
2182
2183  replica[\U\]():Array2[\U,b0,s0,b1,s1\] =
2184      __builtinFactory2[\U,b0,s0,b1,s1\]()
2185  copy():Array2[\T,b0,s0,b1,s1\] =
2186      self.replica[\T\]().fill(fn (i:ZZ32,j:ZZ32):T => get(i-b0,j-b1))
2187  put(t1:(ZZ32, ZZ32), v:T) : ()
2188  get(t1:(ZZ32, ZZ32)):T
2189  t():Array2[\T,b1,s1,b0,s0\] = TransposedArray2[\T,b1,s1,b0,s0\](self)
2190  (* Copied here for better return type information. *)
2191  map[\R\](f:T->R): Array2[\R,b0,s0,b1,s1\] =
2192      replica[\R\]().fill(fn (i:ZZ32,j:ZZ32):R => f(get(i-b0,j-b1)))
2193  ivmap[\R\](f:((ZZ32,ZZ32),T)->R): Array2[\R,b0,s0,b1,s1\] =
2194      replica[\R\]().fill(fn (i:ZZ32,j:ZZ32):R => f((i,j),get(i-b0,j-b1)))
2195
2196  freeze():ImmutableArray[\T,(ZZ32,ZZ32)\] = fail("Freeze not defined yet!")
2197end
2198
2199(** Hoisted out here to work around the lack of method type inference. **)
2200__subarray[\T, nat b0, nat s0, nat b1, nat s1,
2201           nat bo0, nat so0, nat bo1, nat so1, nat o0, nat o1\]
2202        (this:Array2[\T,b0,s0,b1,s1\],
2203         _:N[\bo0\],_:N[\so0\],_:N[\bo1\],_:N[\so1\],
2204         _:N[\o0\],_:N[\o1\]): Array2[\T,bo0,so0,bo1,so1\] = do
2205(*
2206    println("__subarray[\\" b0 "," s0 "," b1 "," s1 ", "
2207            bo0 "," so0 "," bo1 "," so1 ", " o0 "," o1 "\\]()")
2208*)
2209    this.subarray[\bo0,so0,bo1,so1,o0,o1\]()
2210  end
2211
2212(** Default array is column-major, but we could switch it. **)
2213object __DefaultArray2[\T, nat b0, nat s0, nat b1, nat s1\]()
2214        extends Array2[\T, b0, s0, b1, s1\]
2215    mem:PrimitiveArray[\T, (s0 s1) \] = PrimitiveArray[\T, (s0 s1) \]()
2216    init0(t_1:(ZZ32,ZZ32), v:T) : () = do (i,j)=t_1; mem.init0(i s1 + j, v) end
2217    put(t_1:(ZZ32,ZZ32), v:T) : () = do (i,j)=t_1; mem.put(i s1 + j, v) end
2218    get(t_1:(ZZ32,ZZ32)):T = do (i,j)=t_1; mem.get(i s1 + j) end
2219end
2220
2221(** Transposes the index of the underlying array mem, and transposes
2222    its natural order as well. **)
2223object TransposedArray2[\T, nat b0, nat s0, nat b1, nat s1\]
2224                       (mem:Array2[\T,b1,s1,b0,s0\])
2225    extends Array2[\T, b0, s0, b1, s1\]
2226  replica[\U\]():Array2[\U,b0,s0,b1,s1\] = mem.replica[\U\]().t()
2227
2228  init0(t_1:(ZZ32,ZZ32), v:T) : () = do (i,j)=t_1; mem.init0((j,i),v) end
2229  put(t_1:(ZZ32,ZZ32), v:T) : () = do (i,j)=t_1; mem.put((j,i),v) end
2230  get(t_1:(ZZ32,ZZ32)):T = do (i,j)=t_1; mem.get(j,i) end
2231  t() = mem
2232end
2233
2234(** Simple 2-D subarray, used when we have no other knowledge of the
2235    underlying structure.  If we're on top of a PrimitiveArray we can
2236    really do much better than this.
2237    (b0,b1)#(s0,s1) are the bounds of the subarray.
2238    (bu0,bu1)#(su0,su1) are the bounds of the underlying array.
2239    m_i, o_i are multiplier and offset (0-based) of dimension i.
2240**)
2241object SubArray2[\T, nat b0, nat s0, nat b1, nat s1,
2242                     nat bu0, nat su0, nat bu1, nat su1\]
2243                (mem: Array2[\T,bu0,su0,bu1,su1\],
2244                 m0:ZZ32, o0:ZZ32, m1:ZZ32, o1:ZZ32)
2245        extends Array2[\T,b0,s0,b1,s1\]
2246    index(a0:ZZ32, a1:ZZ32): (ZZ32,ZZ32) = (m0 a0 + o0, m1 a1 + o1)
2247    init0(t_1:(ZZ32,ZZ32), v:T): () = mem.init0(index(t_1),v)
2248    put(t_1:(ZZ32,ZZ32), v:T): () = mem.put(index(t_1),v)
2249    get(t_1:(ZZ32,ZZ32)): T = mem.get(index(t_1))
2250end
2251
2252trait AnyMatrix end
2253
2254trait Matrix[\T extends Number, nat s0, nat s1\]
2255        extends { AnyMatrix, Array2[\T, 0, s0, 0, s1\], AdditiveGroup[\Matrix[\T,s0,s1\]\] }
2256        excludes { AnyMultiplicativeRing }
2257    opr +(self, v:Matrix[\T,s0,s1\]): Matrix[\T,s0,s1\] =
2258        ivmap[\T\](fn (i:(ZZ32,ZZ32),e:T):T => e + v.get(i))
2259    opr -(self, v:Matrix[\T,s0,s1\]): Matrix[\T,s0,s1\] =
2260        ivmap[\T\](fn (i:(ZZ32,ZZ32),e:T):T => e - v.get(i))
2261    opr -(self): Matrix[\T,s0,s1\] = map[\T\](fn (e:T):T => - e)
2262    scale(t_1: T): Matrix[\T,s0,s1\] = map[\T\](fn (e:T):T => t_1 e)
2263    mul[\ nat s2 \](other: Matrix[\T,s1,s2\]): Matrix[\T,s0,s2\] = do
2264        res = matrix[\T,s0,s2\]()
2265        mma(a:ZZ32,i:ZZ32,b:ZZ32,j:ZZ32,c:ZZ32,k:ZZ32):() =
2266            if k>=i AND k>=j then
2267              if k=1 then
2268                pr : T = get(a,b) other.get(b,c)
2269                (* If this were atomic, we could parallelize j-partition. *)
2270                res.put((a,c), res.get(a,c) + pr)
2271              else
2272                (k0,k1) = partition(k)
2273                (mma(a,i,b,j,c,k0),mma(a,i,b,j,c+k0,k1))
2274              end
2275            elif j>=i then
2276                (j0,j1) = partition(j)
2277                mma(a,i,b,j0,c,k)
2278                mma(a,i,b+j0,j1,c,k)
2279            else
2280                (i0,i1) = partition(i)
2281                (mma(a,i0,b,j,c,k),mma(a+i0,i1,b,j,c,k))
2282            end
2283        mm(a:ZZ32,i:ZZ32,b:ZZ32,j:ZZ32,c:ZZ32,k:ZZ32):() =
2284            if k>=i AND k>=j then
2285              if k=1 then
2286                res.put((a,c), get(a,b) other.get(b,c))
2287              else
2288                (k0,k1) = partition(k)
2289                (mm(a,i,b,j,c,k0),mm(a,i,b,j,c+k0,k1))
2290              end
2291            elif j>=i then
2292                (j0,j1) = partition(j)
2293                mm(a,i,b,j0,c,k)
2294                mma(a,i,b+j0,j1,c,k)
2295            else
2296                (i0,i1) = partition(i)
2297                (mm(a,i0,b,j,c,k),mm(a+i0,i1,b,j,c,k))
2298            end
2299        if s0=0 OR s1=0 OR s2=0 then
2300          res
2301        else
2302          mm(0,s0,0,s1,0,s2)
2303          res
2304        end
2305      end
2306    rmul(v: Vector[\T,s1\]): Vector[\T,s0\] = do
2307        row(i:ZZ32):T =
2308            SUM[(j,v_j)<-v.indexValuePairs] get(i,j) v_j
2309        vector[\T,s0\]().fill(row)
2310      end
2311    lmul(v: Vector[\T,s0\]): Vector[\T,s1\] = do
2312        col(i:ZZ32):T =
2313            SUM[(j,v_j)<-v.indexValuePairs] v_j get(j,i)
2314        vector[\T,s1\]().fill(col)
2315      end
2316    t(): Matrix[\T,s1,s0\] = TransposedMatrix[\T,s1,s0\](self)
2317end
2318
2319(* Default matrix should match default array in column vs row-major. *)
2320object __DefaultMatrix[\T, nat s0, nat s1\]()
2321    extends Matrix[\T, s0, s1\]
2322  mem:PrimitiveArray[\T, (s0 s1) \] = PrimitiveArray[\T, (s0 s1) \]()
2323  init0(t_1:(ZZ32,ZZ32), v:T) : () = do (i,j)=t_1; mem.init0(i s1 + j, v) end
2324  put(t_1:(ZZ32,ZZ32), v:T) : () = do (i,j)=t_1; mem.put(i s1 + j, v) end
2325  get(t_1:(ZZ32,ZZ32)):T = do (i,j)=t_1; mem.get(i s1 + j) end
2326end
2327
2328object TransposedMatrix[\T, nat s0, nat s1\](mem:Matrix[\T,s1,s0\])
2329        extends Matrix[\T, s0, s1\]
2330    replica[\U\]():Array2[\U,0,s0,0,s1\] = mem.replica[\U\]().t()
2331
2332    init0(t_1:(ZZ32,ZZ32), v:T) : () = do (i,j)=t_1; mem.init0((j,i),v) end
2333    put(t_1:(ZZ32,ZZ32), v:T) : () = do (i,j)=t_1; mem.put((j,i),v) end
2334    get(t_1:(ZZ32,ZZ32)):T = do (i,j)=t_1; mem.get(j,i) end
2335    t(): Matrix[\T,s1,s0\] = mem
2336    add(v:TransposedMatrix[\T,s0,s1\]): Matrix[\T,s0,s1\] = mem.add(v.t()).t()
2337    subtract(v:Matrix[\T,s0,s1\]): Matrix[\T,s0,s1\] = mem.subtract(v.t()).t()
2338    negate(): Matrix[\T,s0,s1\] = mem.negate().t()
2339    scale(f: T): Matrix[\T,s0,s1\] = mem.scale(f).t()
2340    rmul(v: Vector[\T,s1\]): Vector[\T,s0\] = mem.lmul(v)
2341    lmul(v: Vector[\T,s0\]): Vector[\T,s1\] = mem.rmul(v)
2342(*  Can't overload generic methods yet, but this is preferable.
2343    mul[\nat s2\](v:TransposedMatrix[\T,s1,s2\]): Matrix[\T,s0,s2\] =
2344        v.t().mul(mem).t()
2345*)
2346end
2347
2348__builtinFactory2[\T,nat b0,nat s0,nat b1,nat s1\]():Array2[\T,b0,s0,b1,s1\] =
2349    if b0=0 AND b1=0 then
2350        array2[\T,s0,s1\]()
2351    else
2352        __DefaultArray2[\T,b0,s0,b1,s1\]()
2353    end
2354
2355(* array2 is a factory for 0-based 2-D arrays. *)
2356(* TODO: fix when Number is covariant. *)
2357array2[\T, nat s0, nat s1\]():Array2[\T,0,s0,0,s1\] =
2358    typecase _ = __Proxy[\T\] of
2359        __Proxy[\ZZ32\] => matrix[\T,s0,s1\]()
2360        __Proxy[\ZZ64\] => matrix[\T,s0,s1\]()
2361        __Proxy[\RR64\] => matrix[\T,s0,s1\]()
2362        __Proxy[\Number\] => matrix[\T,s0,s1\]()
2363        else => __DefaultArray2[\T,0,s0,0,s1\]()
2364    end
2365array2[\T, nat s0, nat s1\](v:T):Array2[\T,0,s0,0,s1\] =
2366  array2[\T,s0,s1\]().fill(v)
2367array2[\T, nat s0, nat s1\](f:(ZZ32,ZZ32)->T):Array2[\T,0,s0,0,s1\] =
2368  array2[\T,s0,s1\]().fill(f)
2369
2370(* matrix is the same as array1, but specialized to numeric type
2371   arguments, except that the default value (if given) is used to
2372   construct a multiple of the identity matrix. *)
2373matrix[\T extends Number, nat s0, nat s1\]():Matrix[\T,s0,s1\] =
2374  __DefaultMatrix[\T,s0,s1\]()
2375matrix[\T extends Number, nat s0, nat s1\](v:T):Matrix[\T,s0,s1\] =
2376  array2[\T,s0,s1\]().fill(fn (x:ZZ32,y:ZZ32):T => if x=y then v else 0 end)
2377
2378(* Matrix multiplication; used to use a cache-oblivious algorithm, but
2379   we ran into trouble due to lack of support for atomic increment of
2380   matrix elements. *)
2381opr DOT[\ T extends Number, nat n, nat m, nat p\]
2382       (me:Matrix[\T,n,m\], other:Matrix[\T,m,p\]): Matrix[\T,n,p\] =
2383        me.mul[\p\](other)
2384
2385opr juxtaposition[\ T extends Number, nat n, nat m, nat p\]
2386     (me:Matrix[\T,n,m\], other:Matrix[\T,m,p\]): Matrix[\T,n,p\] =
2387        me.mul[\p\](other)
2388
2389
2390(* matrix-vector multiplication *)
2391opr DOT[\ T extends Number, nat n, nat m \]
2392       (me:Matrix[\T,n,m\], v:Vector[\T,m\]):Vector[\T,n\] = me.rmul(v)
2393
2394opr juxtaposition[\ T extends Number, nat n, nat m \]
2395     (me:Matrix[\T,n,m\], v:Vector[\T,m\]):Vector[\T,n\] = me.rmul(v)
2396
2397(* vector-matrix multiplication *)
2398opr DOT[\ T extends Number, nat n, nat m \]
2399       (v:Vector[\T,n\], me:Matrix[\T,n,m\]):Vector[\T,m\] = me.lmul(v)
2400
2401opr juxtaposition[\ T extends Number, nat n, nat m \]
2402     (v:Vector[\T,n\], me:Matrix[\T,n,m\]):Vector[\T,m\] = me.lmul(v)
2403
2404opr DOT[\ T extends Number, nat n, nat m \]
2405       (me : Matrix[\T,n,m\], other : T) : Matrix[\T,n,m\] = me.scale(other)
2406
2407opr juxtaposition[\ T extends Number, nat n, nat m \]
2408     (me : Matrix[\T,n,m\], other : T) : Matrix[\T,n,m\] = me.scale(other)
2409
2410opr DOT[\ T extends Number, nat n, nat m \]
2411       (other : T, me : Matrix[\T,n,m\]) : Matrix[\T,n,m\] = me.scale(other)
2412
2413opr juxtaposition[\ T extends Number, nat n, nat m \]
2414     (other : T, me : Matrix[\T,n,m\]) : Matrix[\T,n,m\] = me.scale(other)
2415
2416(** Array3[\T,b0,s0,b1,s1,b2,s2\] is the type of 3-dimensional arrays
2417    of element type T, with size s_i in the i^th dimension and lowest
2418    index (b0,b1,b2).  Natural order for all generators in each
2419    dimension is from b to b+s-1; the overall order of elements need
2420    only be consistent with the cross product of these orderings (see
2421    Generator.cross()). **)
2422trait Array3[\T, nat b0, nat s0, nat b1, nat s1, nat b2, nat s2\]
2423    extends { Indexed1[\s0\], Indexed2[\s1\], Indexed3[\s2\], Rank3,
2424              StandardMutableArrayType[\Array3[\T,b0,s0,b1,s1,b2,s2\],T,
2425                                        (ZZ32,ZZ32,ZZ32)\] }
2426    excludes { Number, String }
2427
2428    getter size():ZZ32 = s0 s1 s2
2429    getter bounds():Tuple3Range[\ZZ32,ZZ32,ZZ32,true\] =
2430        Tuple3Range[\ZZ32,ZZ32,ZZ32,true\](b0,b1,b2,s0,s1,s2)
2431
2432    getter toString():String = do
2433      r : String := "[" b0 "#" s0 "," b1 "#" s1 "," b2 "#" s2 "] ="
2434      row(i,k) =
2435          for j <- seq(0#s1) do
2436            r := r " " self[b0+i,b1+j,b2+k]
2437          end
2438      plane(k) =
2439        if s1 > 0 then
2440          row(0,k)
2441          for i <- seq(1#(s0-1)) do
2442            r := r "\n "
2443            row(i,k)
2444          end
2445        end
2446      if s0=0 then
2447        r " []"
2448      else
2449        r := r "\n["
2450        plane(0)
2451        for k <- seq(1#(s2-1)) do
2452          r := r " ;;\n "
2453          plane(k)
2454        end
2455        r " ]"
2456      end
2457    end
2458
2459    opr |self| : ZZ32 = s0 s1 s2
2460
2461    (* Again, offset performs bounds checking and shifts to 0 indexing. *)
2462    offset(t:(ZZ32,ZZ32,ZZ32)):(ZZ32,ZZ32,ZZ32) = do
2463      (a0,a1,a2)=t
2464      c0 = a0 - b0; c1 = a1 - b1; c2 = a2 - b2
2465      if NOT (0 <= c0 < s0) then oops(1, b0, s0, a0); end
2466      if NOT (0 <= c1 < s1) then oops(2, b1, s1, a1); end
2467      if NOT (0 <= c2 < s2) then oops(3, b2, s2, a2); end
2468      (c0,c1,c2)
2469    end
2470    toIndex(t:(ZZ32,ZZ32,ZZ32)):(ZZ32,ZZ32,ZZ32) =
2471        do (a0,a1,a2) = t; (a0+b0,a1+b1,a2+b2) end
2472
2473    (* And get and put are 0-indexed without bounds checks. *)
2474    put(t:(ZZ32,ZZ32,ZZ32), v:T) : ()
2475    get(t:(ZZ32,ZZ32,ZZ32)):T
2476
2477    opr[i:ZZ32, j:ZZ32, k:ZZ32] := (v:T) = do self[ (i,j,k) ] := v end
2478    opr[r:Range[\(ZZ32,ZZ32,ZZ32)\]]: Array[\T,(ZZ32,ZZ32,ZZ32)\] = do
2479        r' = (bounds())[r]
2480        (z0,z1,z2) = r'.extent()
2481        (l0,l1,l2) = r'.lower()
2482        __subarray(self, N[\0\],reflect(z0), N[\0\],reflect(z1),
2483                   N[\0\],reflect(z2), reflect(l0),reflect(l1), reflect(l2))
2484      end
2485    opr[_:OpenRange[\ZZ32\]] : Array3[\T,0,s0,0,s1,0,s2\] =
2486        subarray[\0,s0,0,s1,0,s2,0,0,0\]()
2487    opr[_:OpenRange[\Any\]] : Array3[\T,0,s0,0,s1,0,s2\] =
2488        subarray[\0,s0,0,s1,0,s2,0,0,0\]()
2489    shift(t:(ZZ32,ZZ32,ZZ32)): Array[\T,(ZZ32,ZZ32)\] = do
2490        (o0,o1,o2)=t
2491        if o0=0 AND o1=0 AND o2=0 then
2492            self
2493        else
2494            __subarray(self,
2495                       reflect(o0),N[\s0\], reflect(o1),N[\s1\],
2496                       reflect(o2),N[\s2\], N[\b0\],N[\b1\],N[\b2\])
2497        end
2498      end
2499
2500    (** 3-D subarray given static subarray parameters.
2501        (bo1,bo2)#(so1,so2) are output bounds.
2502        The result is the subarray starting at (o0,o1) in the original array.
2503     **)
2504    subarray[\nat bo0, nat so0, nat bo1, nat so1, nat bo2, nat so2,
2505              nat o0, nat o1, nat o2\]
2506            (): Array3[\T,bo0,so0,bo1,so1,bo2,so2\] = do
2507        boundsCheck = (bounds())[ (o0,o1,o2)#(so0,so1,so2) ]
2508        SubArray3[\T,bo0,so0,bo1,so1,bo2,so2,b0,s0,b1,s1,b2,s2\](self,1,o0,1,o1,1,o2)
2509      end
2510
2511    zeroIndices():Tuple3Range[\ZZ32,ZZ32,ZZ32,true\] =
2512        Tuple3Range[\ZZ32,ZZ32,ZZ32,true\](0,0,0,s0,s1,s2)
2513
2514    replica[\U\]():Array3[\U,b0,s0,b1,s1,b2,s2\] =
2515        __DefaultArray3[\U,b0,s0,b1,s1,b2,s2\]()
2516    copy():Array3[\T,b0,s0,b1,s1,b2,s2\] =
2517        self.replica[\T\]().fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):T =>
2518                                     get(i-b0,j-b1,k-b2))
2519    map[\R\](f:T->R): Array3[\R,b0,s0,b1,s1,b2,s2\] =
2520        replica[\R\]().fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):R =>
2521                                f(get(i-b0,j-b1,k-b2)))
2522    ivmap[\R\](f:((ZZ32,ZZ32,ZZ32),T)->R): Array3[\R,b0,s0,b1,s1,b2,s2\] =
2523        replica[\R\]().fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):R =>
2524                                f((i,j,k),get(i-b0,j-b1,k-b2)))
2525
2526    freeze():ImmutableArray[\T,(ZZ32,ZZ32,ZZ32)\] =
2527        fail("Freeze not defined yet!")
2528end
2529
2530(** hoisted out here to work around absence of type inference for methods. **)
2531__subarray[\T, nat b0, nat s0, nat b1, nat s1, nat b2, nat s2,
2532            nat bo0, nat so0, nat bo1, nat so1, nat bo2, nat so2,
2533            nat o0, nat o1, nat o2\]
2534      (this:Array3[\T,b0,s0,b1,s1,b2,s2\],
2535       _:N[\bo0\],_:N[\so0\],_:N[\bo1\],_:N[\so1\],_:N[\bo2\],_:N[\so2\],
2536       _:N[\o0\],_:N[\o1\],_:N[\o2\]): Array3[\T,bo0,so0,bo1,so1,bo2,so2\] =
2537    this.subarray[\bo0,so0,bo1,so1,bo2,so2,o0,o1,o2\]()
2538
2539object __DefaultArray3[\T, nat b0, nat s0, nat b1, nat s1, nat b2, nat s2\]() extends
2540                                        Array3[\T, b0, s0, b1, s1, b2, s2\]
2541  mem:PrimitiveArray[\T,(s0 (s1 s2))\] = PrimitiveArray[\T,(s0 (s1 s2))\]()
2542
2543  ofs(i:ZZ32,j:ZZ32,k:ZZ32):ZZ32 = (i s1 + j) s2 + k
2544
2545  init0(t:(ZZ32,ZZ32,ZZ32), v:T) : () = mem.init0(ofs(t),v)
2546  put(t:(ZZ32,ZZ32,ZZ32), v:T) : () = mem.put(ofs(t),v)
2547  get(t:(ZZ32,ZZ32,ZZ32)) : T = mem.get(ofs(t))
2548end
2549
2550(** Simple 3-D subarray, used when we have no other knowledge of the
2551    underlying structure.  If we're on top of a PrimitiveArray we can
2552    really do much better than this.
2553    (b0,b1,b2)#(s0,s1,s2) are the bounds of the subarray.
2554    (bu0,bu1,bu2)#(su0,su1,su2) are the bounds of the underlying array.
2555    m_i, o_i are multiplier and offset (0-based) of dimension i.
2556**)
2557object SubArray3[\T, nat b0, nat s0, nat b1, nat s1, nat b2, nat s2,
2558                     nat bu0, nat su0, nat bu1, nat su1, nat bu2, nat su2\]
2559                (mem: Array3[\T,bu0,su0,bu1,su1,bu2,su2\],
2560                 m0:ZZ32,o0:ZZ32, m1:ZZ32,o1:ZZ32, m2:ZZ32, o2:ZZ32)
2561        extends Array3[\T,b0,s0,b1,s1,b2,s2\]
2562    index(a0:ZZ32, a1:ZZ32, a2:ZZ32): (ZZ32,ZZ32,ZZ32) =
2563        (m0 a0 + o0, m1 a1 + o1, m2 a2 + o2)
2564    init0(t:(ZZ32,ZZ32,ZZ32), v:T): () = mem.init0(index(t),v)
2565    put(t:(ZZ32,ZZ32,ZZ32), v:T): () = mem.put(index(t),v)
2566    get(t:(ZZ32,ZZ32,ZZ32)): T = mem.get(index(t))
2567end
2568
2569__builtinFactory3[\T, nat b0, nat s0, nat b1, nat s1, nat b2, nat s2\]():
2570        Array3[\T,b0,s0,b1,s1,b2,s2\] =
2571  __DefaultArray3[\T,b0,s0,b1,s1,b2,s2\]()
2572
2573array3[\T,nat s0, nat s1, nat s2\]():Array3[\T,0,s0,0,s1,0,s2\] =
2574  __DefaultArray3[\T,0,s0,0,s1,0,s2\]()
2575
2576(*************
2577
2578trait Monoid[\ T, opr OPLUS \]
2579  where { T extends Monoid[\ T, OPLUS \] }
2580    zero() : T
2581    opr OPLUS(self, other:T):T
2582end
2583
2584*************)
2585
2586(************************************************************
2587* Reductions
2588************************************************************)
2589
2590trait Reduction[\L\]
2591    empty(): L
2592    join(a: L, b: L): L
2593end
2594
2595(** Invariants:
2596    join must be associative with identity empty
2597    unlift(lift(x)) = x
2598 **)
2599trait ActualReduction[\R,L\] extends Reduction[\L\]
2600    getter toString():String
2601    lift(r: Any): L
2602    unlift(l:L): R
2603    (** If this reduction left-distributes over r, return a pair of
2604        reductions with the same lift and unlift **)
2605    leftDistribute(r: Reduction[\R\]): SomeReductionPair[\R\] =
2606        distribute(r)
2607    (** If this reduction right-distributes over r, return a pair of
2608        reductions with the same lift and unlift **)
2609    rightDistribute(r: Reduction[\R\]): SomeReductionPair[\R\] =
2610        distribute(r)
2611    (** If this reduction distributes over r, return a pair of
2612        reductions with the same lift and unlift **)
2613    distribute[\K\](r: ActualReduction[\R,K\]): SomeReductionPair[\R\] =
2614        NoReductionPair[\R\]
2615end
2616
2617trait PossibleReductionPair[\R\] extends Condition[\SomeReductionPair[\R\]\]
2618    comprises { NoReductionPair[\R\], SomeReductionPair[\R\] }
2619end
2620
2621object NoReductionPair[\R\] extends PossibleReductionPair[\R\]
2622    getter holds(): Boolean = false
2623    getter cond[\G\](t:PossibleReductionPair[\R\]->G, e:()->G): G = e()
2624end
2625
2626trait SomeReductionPair[\R\] extends PossibleReductionPair[\R\]
2627    getter holds(): Boolean = true
2628    getter cond[\G\](t:PossibleReductionPair[\R\]->G, e:()->G): G = t(self)
2629    getter outer(): Reduction[\R\]
2630    getter inner(): Reduction[\R\]
2631end
2632
2633trait ReductionPair[\R,L\] extends SomeReductionPair[\R\]
2634    getter outer(): ActualReduction[\R,L\]
2635    getter inner(): ActualReduction[\R,L\]
2636end
2637
2638(** The usual lifting to Maybe for identity-less operators **)
2639trait AssociativeReduction[\R\] extends ActualReduction[\R,AnyMaybe\]
2640    empty(): Nothing[\R\] = Nothing[\R\]
2641    join(a: AnyMaybe, b: AnyMaybe): AnyMaybe =
2642        if av <- a then
2643            if bv <- b then
2644                Just(simpleJoin(av,bv))
2645            else
2646                a
2647            end
2648        else
2649            b
2650        end
2651    simpleJoin(a:Any, b:Any): Any
2652    lift(r:Any): AnyMaybe = Just(r)
2653    unlift(r:AnyMaybe): R = r.get
2654end
2655
2656trait CommutativeReduction[\R\] extends AssociativeReduction[\R\] end
2657
2658(** Monoids don't require a special lift and unlift operation. **)
2659trait MonoidReduction[\R\] extends ActualReduction[\R,R\]
2660    lift(r:Any): R = r
2661    unlift(r:R): R = r
2662end
2663
2664trait CommutativeMonoidReduction[\R\] extends MonoidReduction[\R\] end
2665
2666trait ReductionWithZeroes[\R,L\] extends ActualReduction[\R,L\]
2667    isLeftZero(l:L): Boolean = isZero(l)
2668    isRightZero(l:L): Boolean = isZero(l)
2669    isZero(l:L): Boolean = false
2670end
2671
2672trait BigOperator[\I,O,R,L\]
2673    getter reduction(): ActualReduction[\R,L\]
2674    getter body(): I->R
2675    getter unwrap(): R->O
2676end
2677
2678object BigReduction[\R,L\](r:ActualReduction[\R,L\]) extends BigOperator[\R,R,R,L\]
2679    getter reduction(): ActualReduction[\R,L\] = r
2680    getter body(): R->R = fn x => x
2681    getter unwrap(): R->R = fn x => x
2682end
2683
2684object Comprehension[\I,O,R,L\](u: R->O, r: ActualReduction[\R,L\], singleton:I->R)
2685        extends BigOperator[\I,O,R,L\]
2686    getter reduction(): ActualReduction[\R,L\] = r
2687    getter body(): I->R = singleton
2688    getter unwrap(): R->O = u
2689end
2690
2691(** VoidReduction is usually done for effect, so we pretend that
2692    the completion performs the effects.  This rules out things
2693    distributing over void (that would change the number of effects in
2694    our program) but not void distributing over other things. **)
2695object VoidReduction extends { CommutativeMonoidReduction[\()\] }
2696    getter toString() = "VoidReduction"
2697    empty(): () = ()
2698    join(a: (), b: ()): () = ()
2699end
2700
2701(* Hack to permit any Number to work non-parametrically. *)
2702object SumReduction extends CommutativeMonoidReduction[\Number\]
2703    getter toString() = "SumReduction"
2704    empty(): Number = 0
2705    join(a: Number, b: Number): Number = a+b
2706end
2707
2708opr SUM[\T extends Number\](): Comprehension[\T,Number,Number,Number\] =
2709    Comprehension[\T,Number,Number,Number\](fn x => x, SumReduction, cast[\Number\])
2710
2711object ProdReduction extends CommutativeMonoidReduction[\Number\]
2712    getter toString() = "ProdReduction"
2713    empty(): Number = 1
2714    join(a:Number, b:Number): Number = a b
2715end
2716
2717opr PROD[\T extends Number\](): Comprehension[\T,Number,Number,Number\] =
2718    Comprehension[\T,Number,Number,Number\](fn x => x, ProdReduction, cast[\Number\])
2719
2720object MinReduction[\T extends StandardMin[\T\]\] extends CommutativeReduction[\T\]
2721    getter toString() = "MinReduction"
2722    simpleJoin(a, b) = a MIN b
2723end
2724
2725opr BIG MIN[\T extends StandardMin[\T\]\](): BigReduction[\T,AnyMaybe\] =
2726    BigReduction[\T,AnyMaybe\](MinReduction[\T\])
2727
2728object MaxReduction[\T extends StandardMax[\T\]\] extends CommutativeReduction[\T\]
2729    getter toString() = "MaxReduction"
2730    simpleJoin(a, b) = a MAX b
2731end
2732
2733opr BIG MAX[\T extends StandardMax[\T\]\](): BigReduction[\T,AnyMaybe\] =
2734    BigReduction[\T,AnyMaybe\](MaxReduction[\T\])
2735
2736opr BIG MINNUM(): BigReduction[\RR64,RR64\] =
2737    BigReduction[\RR64,RR64\](
2738        MapReduceReduction[\RR64\](fn (a:RR64,b:RR64):RR64 => a MINNUM b, 0.0/0.0))
2739
2740opr BIG MAXNUM(): BigReduction[\RR64,RR64\] =
2741    BigReduction[\RR64,RR64\](
2742        MapReduceReduction[\RR64\](fn (a:RR64,b:RR64):RR64 => a MAXNUM b, 0.0/0.0))
2743
2744(** AndReduction and OrReduction take advantage of natural zeroes for early exit. **)
2745object AndReduction
2746        extends { CommutativeMonoidReduction[\Boolean\],
2747                  ReductionWithZeroes[\Boolean,Boolean\] }
2748    getter toString() = "AndReduction"
2749    empty(): Boolean = true
2750    join(a: Boolean, b: Boolean): Boolean = a AND b
2751    isZero(a:Boolean): Boolean = NOT a
2752end
2753
2754opr BIG AND[\T\](): BigReduction[\Boolean,Boolean\] =
2755    BigReduction[\Boolean,Boolean\](AndReduction)
2756
2757object OrReduction
2758        extends { CommutativeMonoidReduction[\Boolean\],
2759                  ReductionWithZeroes[\Boolean,Boolean\] }
2760    getter toString() = "OrReduction"
2761    empty(): Boolean = false
2762    join(a: Boolean, b: Boolean): Boolean = a OR b
2763    isZero(a:Boolean): Boolean = a
2764end
2765
2766opr BIG OR[\T\]():BigReduction[\Boolean, Boolean\] =
2767    BigReduction[\Boolean,Boolean\](OrReduction)
2768
2769(** A reduction performing String concatenation **)
2770object StringReduction extends MonoidReduction[\String\]
2771    getter toString() = "StringReduction"
2772    empty(): String = ""
2773    join(a:String, b:String): String = a || b
2774end
2775
2776(** A reduction performing String concatenation with a space **)
2777object SpaceReduction extends MonoidReduction[\String\]
2778    getter toString() = "StringReduction"
2779    empty(): String = ""
2780    join(a:String, b:String): String = a ||| b
2781end
2782
2783(** A reduction performing String concatenation with newline separation **)
2784object NewlineReduction extends AssociativeReduction[\String\]
2785    getter toString() = "NewlineReduction"
2786    simpleJoin(a, b) = a // b
2787end
2788
2789(** This operator performs string concatenation, first converting
2790    its inputs (of type Any) to String if necessary. **)
2791opr BIG ||(): Comprehension[\Any,String,String,String\] =
2792    Comprehension[\Any,String,String,String\](
2793        identity[\String\],StringReduction,fn (x:Any)=> "" x)
2794
2795(** This operator performs string concatenation, first converting
2796    its inputs (of type Any) to String if necessary, and separating
2797    non-empty components by a space. **)
2798opr BIG |||(): Comprehension[\Any,String,String,String\] =
2799    Comprehension[\Any,String,String,String\](
2800        identity[\String\],SpaceReduction,fn (x:Any)=> "" x)
2801
2802(** This operator performs string concatenation with newline
2803    separation, first converting its inputs (of type Any) to String if
2804    necessary. **)
2805opr BIG //(): Comprehension[\Any,String,String,AnyMaybe\] =
2806    Comprehension[\Any,String,String,AnyMaybe\](
2807        fn x => x,NewlineReduction,fn (x:Any)=> "" x)
2808
2809(** A %MapReduceReduction% takes an associative binary function %j% on
2810    arguments of type %R%, and the identity of that function %z%, and
2811    returns the corresponding reduction. **)
2812object MapReduceReduction[\R\](j:(R,R)->R, z:R) extends MonoidReduction[\R\]
2813    getter toString()="mapReduceReduction"
2814    empty(): R = z
2815    join(a:R, b:R): R = (j)(a,b)
2816end
2817
2818(** A %MIMapReduceReduction% takes an associative binary function %j% on
2819    arguments of type %R%, and the identity of that function %z%, and
2820    returns the corresponding reduction. **)
2821object MIMapReduceReduction[\R\](j:(Any,Any)->R, z:Any) extends MonoidReduction[\Any\]
2822    getter toString():String="MIMapReduceReduction from embiggen"
2823    empty(): R = z
2824    join(a:Any, b:Any): R = (j)(a,b)
2825end
2826
2827(** %embiggen% takes a type %T% and an operation (either an operator
2828    %OP% or binary function %f% on type %T%), along with the identity
2829    %z% of the operation, and returns a function suitable as the right-hand
2830    side of the definition of the corresponding BIG operator. **)
2831(*
2832embiggen[\T,opr OP\](z:Any, g:(Reduction[\Any\],T->Any) -> Any) : T =
2833    g(MIOprReduction[\T,OP\](z), fn (x) => x)
2834*)
2835embiggen[\T\](j:(Any,Any)->T, z:T) : Comprehension[\T,T,Any,Any\] =
2836    Comprehension[\T,T,Any,Any\](fn (x) => x, MIMapReduceReduction[\T\](j,z), fn (x) => x)
2837
2838(** Helpers for maps and cross products of generators.  These can be
2839    quite a bit more sophisticated (for example, we can hoist maps
2840    outwards if we think that'd be useful), but let's get this much
2841    working first. *)
2842trait SomeMappedGenerator[\F\] extends Generator[\F\] end
2843
2844trait MappedGenerator[\E,F\] extends SomeMappedGenerator[\F\]
2845    getter g(): Generator[\E\]
2846    getter f(): E -> F
2847    getter toString(): String = g() ".map(f)"
2848    generate[\R\](r: Reduction[\R\], m: F->R): R =
2849        g().generate[\R\](r, m COMPOSE f())
2850    reduce(r: Reduction[\F\]): F =
2851        g().generate[\F\](r, f())
2852    map[\G\](f': F->G): SimpleMappedGenerator[\E,G\] =
2853        SimpleMappedGenerator[\E,G\](g(), f' COMPOSE f())
2854    seq(self) = SimpleMappedSeqGenerator[\E,F\](seq(g()),f())
2855end
2856
2857object SimpleMappedGenerator[\E,F\](g0: Generator[\E\], f0: E->F)
2858        extends MappedGenerator[\E,F\]
2859    getter g() = g0
2860    getter f() = f0
2861end
2862
2863object SimpleMappedIndexed[\E,F,I\](g0: Indexed[\E,I\], f0: E->F)
2864        extends { MappedGenerator[\E,F\], Indexed[\F,I\] }
2865    getter size(): ZZ32 = |g()|
2866    getter g() = g0
2867    getter f() = f0
2868    getter bounds(): Range[\I\] = g().bounds
2869    getter indexValuePairs(): Indexed[\(I,F),I\] =
2870        g().indexValuePairs.map[\(I,F)\](fn (i:I, e:E): F => (i,(f())(e)))
2871    getter indices(): Indexed[\I,I\] = g().indices
2872    opr |self| : ZZ32 = |g()|
2873    opr[i:I] : F = (f())(g()[i])
2874    opr[r:Range[\I\]] : Indexed[\F,I\] =
2875        SimpleMappedIndexed[\E,F,I\](g()[r],f())
2876
2877    ivmap[\R\](ff:(I,F)->R): Indexed[\R,I\] =
2878        g0().ivmap[\R\](fn (i:I, e:E) => ff(i, (f())(e)))
2879    map[\G\](f': F->G): SimpleMappedIndexed[\E,G,I\] =
2880        SimpleMappedIndexed[\E,G,I\](g(), f' COMPOSE f())
2881end
2882
2883object SimpleMappedSeqGenerator[\E,F\](g0: SequentialGenerator[\E\], f0: E->F)
2884        extends { MappedGenerator[\E,F\], SequentialGenerator[\F\] }
2885    getter g() = g0
2886    getter f() = f0
2887    getter toString() = "seq(" g0 ".map(f))"
2888    seq(self): SimpleMappedSeqGenerator[\E,F\] = self
2889end
2890
2891trait FilterGenerator[\E\] extends Generator[\E\]
2892    getter g(): Generator[\E\]
2893    getter p(): E -> Condition[\()\]
2894    getter toString(): String = g() ".filter(p)"
2895    generate[\R\](r:Reduction[\R\], m: E->R): R =
2896        g().generate[\R\](r, fn(e:E):R => if (p())(e).holds then m(e) else r.empty() end)
2897    reduce(r: Reduction[\E\]): E =
2898        g().generate[\E\](r, fn(e:E):E => if (p())(e).holds then e else r.empty() end)
2899    filter(p': E -> Condition[\()\]): SimpleFilterGenerator[\E\] =
2900        SimpleFilterGenerator[\E\](g(), p() ANDCOND p')
2901    seq(self) = SimpleSeqFilterGenerator[\E\](seq(g()),p())
2902end
2903
2904object SimpleFilterGenerator[\E\](g0:Generator[\E\], p0: E->Condition[\()\])
2905        extends FilterGenerator[\E\]
2906    getter g(): Generator[\E\]       = g0
2907    getter p(): E -> Condition[\()\]  = p0
2908end
2909
2910object SimpleSeqFilterGenerator[\E\](g0: SequentialGenerator[\E\], p0: E->Condition[\()\])
2911        extends { FilterGenerator[\E\], SequentialGenerator[\E\] }
2912    getter g(): Generator[\E\]       = g0
2913    getter p(): E -> Condition[\()\]  = p0
2914    getter toString() = "seq(" g0 ".filter(p))"
2915    seq(self): SimpleSeqFilterGenerator[\E\] = self
2916end
2917
2918trait NestedGenerator[\E,F\] extends Generator[\F\]
2919    getter g(): Generator[\E\]
2920    getter f(): E -> Generator[\F\]
2921    getter toString(): String
2922    generate[\R\](r: Reduction[\R\], m: F->R): R =
2923        g().generate[\R\](r,fn (e:E):R => (f())(e).generate[\R\](r,m))
2924    mapReduce[\R\](body: F->R, join:(R,R)->R, id:R): R =
2925        g().mapReduce[\R\](
2926            fn (e:E): R => (f())(e).mapReduce[\R\](body,join,id),
2927            join, id)
2928    reduce(r: Reduction[\F\]): F =
2929        g().generate[\F\](r,fn (e:E):F => (f())(e).reduce(r))
2930    reduce(j:(F,F)->F, z:F):F =
2931        g().mapReduce[\F\](fn (e:E): F => (f())(e).reduce(j,z), j, z)
2932    loop(body:F->()): () =
2933        g().loop(fn (e:E) => (f())(e).loop(body))
2934    map[\G\](h:F->G): Generator[\G\] =
2935        g().nest[\G\](fn (e:E): Generator[\G\] => (f())(e).map[\G\](h))
2936    nest[\G\](h:F->Generator[\G\]): Generator[\G\] =
2937        g().nest[\G\](fn (e:E):Generator[\G\] => (f())(e).nest[\G\](h))
2938end
2939
2940object SimpleNestedGenerator[\E,F\](g0: Generator[\E\], f0: E->Generator[\F\])
2941        extends { NestedGenerator[\E,F\] }
2942    getter g() = g0
2943    getter f() = f0
2944    getter toString() = g() ".nest(f)"
2945    seq(self) =
2946        typecase ff = f() of
2947            (E -> SequentialGenerator[\F\]) =>
2948                SimpleNestedSeqGenerator[\E,F\](seq(g()),ff)
2949            else =>
2950                SimpleNestedSeqGenerator[\E,F\](seq(g()),
2951                     fn (e:E): SequentialGenerator[\F\] => seq(self.f()(e)))
2952        end
2953end
2954
2955object SimpleNestedSeqGenerator[\E,F\]
2956        (g0: SequentialGenerator[\E\], f0: E->SequentialGenerator[\F\])
2957        extends { NestedGenerator[\E,F\], SequentialGenerator[\F\] }
2958    getter g() = g0
2959    getter f() = f0
2960    getter toString() = "seq(" g() ".nest(f))"
2961end
2962
2963trait PairGenerator[\E,F\] extends Generator[\(E,F)\]
2964  comprises { SimplePairGenerator[\E,F\], SimplePairSeqGenerator[\E,F\] }
2965    getter e(): Generator[\E\]
2966    getter f(): Generator[\F\]
2967    getter toString(): String
2968    getter size():ZZ32 = |self|
2969    opr |self| : ZZ32 = |e()| |f()|
2970    generate[\R\](r: Reduction[\R\], m:(E,F)->R): R =
2971        e().generate[\R\](r, fn (a: E): R =>
2972                              f().generate[\R\](r, fn (b: F): R => m(a,b)))
2973end
2974
2975object SimplePairGenerator[\E,F\](e0: Generator[\E\], f0: Generator[\F\])
2976        extends PairGenerator[\E,F\]
2977    getter e() = e0
2978    getter f() = f0
2979    getter toString()=(e0 ".cross(" f0 ")" )
2980    seq(self) = SimplePairSeqGenerator[\E,F\](seq(e0),seq(f0))
2981end
2982
2983object SimplePairSeqGenerator[\E,F\](e0: Generator[\E\], f0: Generator[\F\])
2984        extends { PairGenerator[\E,F\], SequentialGenerator[\(E,F)\] }
2985    getter e() = e0
2986    getter f() = f0
2987    getter toString()=("seq(" e ".cross(" f "))" )
2988end
2989
2990(** Helper for serializing generators naively.  This code should make
2991 *  obvious that naive seq is *VERY INEFFICIENT*.  It
2992 *  constructs a function closure whose size is proportional to
2993 *  %|g|%, and then executes that closure.  This trick is old hat
2994 *  to lambda-calculus wonks, but pretty unfamiliar to the common man.
2995 *
2996 *  Basically each element takes in the accumulated value a from the element
2997 *  to its left.  This is joined with the result of mapping on the
2998 *  current element value, and that result is returned.  Join simply
2999 *  reverse-composes the functions for its subtrees, so the output of the left
3000 *  subtree is fed to the right subtree.
3001 *
3002 *  Note that a similar trick can be used to reverse and sequentialize
3003 *  a generator (use forward function composition rather than reverse
3004 *  composition, and flipping around the join at the leaves). *)
3005object NaiveSeqGenerator[\E\](g: Generator[\E\])
3006        extends SequentialGenerator[\E\]
3007    getter size() = |g|
3008    getter toString():String = "naive seq(" g.toString ")"
3009    opr |self| : ZZ32 = |g|
3010    generate[\R\](r: Reduction[\R\], m:E->R): R = do
3011      rcompose(f:R->R, f':R->R): R->R = fn (x:R):R => f'(f(x))
3012      id(x:R):R = x
3013      mp(x:E):R->R = fn (a:R):R => r.join(a,m(x))
3014      f : R -> R = g.mapReduce[\R->R\](mp,rcompose,id)
3015      mt : R = r.empty()
3016      f mt
3017    end
3018end
3019
3020(************************************************************
3021* Ranges
3022************************************************************)
3023
3024(** Ranges in general represent uses of the # and : operators.
3025    It's mostly subtypes of Range that are interesting.
3026
3027    The partial order on ranges describes containment:
3028      a < b iff all points in a are strictly contained in b.
3029 **)
3030trait Range[\T\]
3031    extends StandardPartialOrder[\Range[\T\]\]
3032    comprises { RangeWithLower[\T\], RangeWithUpper[\T\],
3033                RangeWithExtent[\T\], PartialRange[\T\] }
3034    excludes { Number }
3035   
3036    opr[r:Range[\T\]]: Range[\T\] = fail("Unrecognized Range " r)
3037    opr[_:OpenRange[\Any\]] : Range[\T\] = self
3038    opr[other:LowerRange[\T\]] : Range[\T\]
3039    opr[other:UpperRange[\T\]] : Range[\T\]
3040    opr[other:ExtentRange[\T\]] : Range[\T\]
3041    opr[other:CompleteRange[\T\]] : CompleteRange[\T\]
3042    opr =(self,_:Range[\T\]): Boolean = false
3043end
3044
3045trait PartialRange[\T\] extends Range[\T\]
3046    comprises { OpenRange[\T\],
3047                LowerRange[\T\], UpperRange[\T\], ExtentRange[\T\] }
3048    excludes { CompleteRange[\T\] }
3049end
3050
3051object OpenRange[\T\] extends { Range[\T\], PartialRange[\T\] }
3052    toString():String = "#"
3053    opr[_:OpenRange[\T\]] : OpenRange[\T\] = self
3054
3055    opr[other:LowerRange[\T\]] : LowerRange[\T\] = other
3056    opr[other:UpperRange[\T\]] : UpperRange[\T\] = other
3057    opr[other:ExtentRange[\T\]] : ExtentRange[\T\] = other
3058    opr[other:CompleteRange[\T\]] : CompleteRange[\T\] = other
3059    opr =(self,_:OpenRange[\T\]): Boolean = true
3060    opr CMP(self,other:Range[\T\]): TotalComparison =
3061        typecase other of
3062            OpenRange[\T\] => EqualTo
3063            else => GreaterThan
3064        end
3065end
3066
3067opr PARTIAL_LEXICO(a:Comparison, b:Comparison) =
3068    typecase a of
3069        Unordered => Unordered
3070        EqualTo => b
3071        else =>
3072            typecase b of
3073                Unordered => Unordered
3074                else => a
3075            end
3076    end
3077
3078opr PARTIAL_LEXICO(a:Comparison, b:()->Comparison) =
3079    typecase a of
3080        Unordered => Unordered
3081        EqualTo => b()
3082        else =>
3083            typecase _ = b() of
3084                Unordered => Unordered
3085                else => a
3086            end
3087    end
3088
3089(** Non-traditional partial ordering on tuples, CMP ordering elsewhere. **)
3090opr PCMP[\A,B\](t1:(A,B), t2:(A,B)): Comparison = do
3091    (a1,b1)=t1
3092    (a2,b2)=t2
3093    (a1 CMP a2) PARTIAL_LEXICO: (b1 CMP b2)
3094  end
3095
3096opr PCMP[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Comparison = do
3097    (a1,b1,c1)=t1
3098    (a2,b2,c2)=t2
3099    (a1 CMP a2) PARTIAL_LEXICO: (b1 CMP b2) PARTIAL_LEXICO (c1 CMP c2)
3100  end
3101
3102opr PCMP(a:Number, b:Number): TotalComparison = a CMP b
3103
3104(** Non-traditional subtraction of bounds, elementwise on tuples **)
3105opr SUBTR[\A,B\](t1:(A,B), t2:(A,B)): (A,B) = do
3106    (a1,b1) = t1
3107    (a2,b2) = t2
3108    (a1 SUBTR a2, b1 SUBTR b2)
3109  end
3110
3111opr SUBTR[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): (A,B,C) = do
3112    (a1,b1,c1) = t1
3113    (a2,b2,c2) = t2
3114    (a1 SUBTR a2, b1 SUBTR b2, c1 SUBTR c2)
3115  end
3116
3117opr SUBTR[\T extends MultiplicativeRing[\T\]\](a:T, b:T):T = a.one + a - b
3118
3119(** join upper and lower bounds comparisons (total or partial) to
3120    yield partial containment. **)
3121
3122trait RangeWithLower[\T\] extends Range[\T\]
3123        comprises { LowerRange[\T\], CompleteRange[\T\] }
3124    getter lower():T
3125end
3126
3127rangeBoundError[\T\](r1:Range[\T\], r2: Range[\T\]): Range[\T\] =
3128    fail(r1 "[" r2 "] does not contain bound of indexing range")
3129
3130object LowerRange[\T\](lo:T) extends { RangeWithLower[\T\], PartialRange[\T\] }
3131    getter lower():T = lo
3132    toString():String = lower() "#"
3133    opr[_:OpenRange[\T\]] : LowerRange[\T\] = self
3134    opr[other:LowerRange[\T\]] : LowerRange[\T\] =
3135        if other.lower >= self.lower then
3136            other
3137        else
3138            rangeBoundError[\T\](self,other)
3139        end
3140    opr[other:ExtentRange[\T\]] : FullRange[\T,true\] = self.lower # other.extent()
3141    opr[other:UpperRange[\T\]] : FullRange[\T,true\] =
3142        if other.upper >= self.lower then
3143            self.lower : other.upper
3144        else
3145            rangeBoundError[\T\](self,other)
3146        end
3147    opr[other:CompleteRange[\T\]] : CompleteRange[\T\] =
3148        if other.lower >= self.lower then
3149            other
3150        else
3151            rangeBoundError[\T\](self,other)
3152        end
3153    opr =(self, x:LowerRange[\T\]): Boolean = self.lower = x.lower
3154    opr CMP(self, other:Range[\T\]): Comparison =
3155        typecase other of
3156            OpenRange[\T\] => LessThan
3157            LowerRange[\T\] => other.lower PCMP self.lower
3158            CompleteRange[\T\] =>
3159                typecase c = other.lower PCMP self.lower of
3160                    EqualTo => GreaterThan
3161                    LessThan => Unordered
3162                    else => c
3163                end
3164            else => Unordered
3165        end
3166end
3167
3168trait RangeWithUpper[\T\] extends Range[\T\]
3169        comprises { UpperRange[\T\], CompleteRange[\T\] }
3170    getter upper():T
3171end
3172
3173object UpperRange[\T\](up:T) extends { RangeWithUpper[\T\], PartialRange[\T\] }
3174    getter upper():T = up
3175    toString():String = ":" upper()
3176    opr[_:OpenRange[\T\]] : UpperRange[\T\] = self
3177    opr[other:LowerRange[\T\]] : FullRange[\T,true\] = other.lower:self:upper
3178    opr[other:UpperRange[\T\]] : UpperRange[\T\] =
3179        if other.upper <= self.upper then
3180            other
3181        else
3182            rangeBoundError[\T\](self,other)
3183        end
3184    opr[other:ExtentRange[\T\]] : FullRange[\T,true\] =
3185        (self.upper SUBTR other.extent) # other.extent
3186    opr[other:CompleteRange[\T\]] : CompleteRange[\T\] =
3187        if other.upper <= self.upper then
3188            other
3189        else
3190            rangeBoundError[\T\](self,other)
3191        end
3192    opr =(self,x:UpperRange[\T\]): Boolean = upper() = x.upper()
3193    opr CMP(self, other:Range[\T\]): Comparison =
3194        typecase other of
3195            OpenRange[\T\]  => LessThan
3196            UpperRange[\T\] => self.upper PCMP other.upper
3197            CompleteRange[\T\]  =>
3198                typecase c = self.upper PCMP other.upper of
3199                    EqualTo => GreaterThan
3200                    LessThan => Unordered
3201                    else => c
3202                end
3203            else => Unordered
3204        end
3205end
3206
3207trait RangeWithExtent[\T\] extends Range[\T\]
3208        comprises { ExtentRange[\T\], CompleteRange[\T\] }
3209    getter extent():T
3210    toString():String = "#" self.extent
3211end
3212
3213object ExtentRange[\T\](ex:T) extends { RangeWithExtent[\T\], PartialRange[\T\] }
3214    getter extent():T = ex
3215    opr[_:OpenRange[\T\]] : ExtentRange[\T\] = self
3216    opr[other:LowerRange[\T\]] : FullRange[\T,true\] = other.lower # self.extent
3217    opr[other:UpperRange[\T\]] : FullRange[\T,true\] =
3218        (other.upper SUBTR self.extent) # self.extent
3219    opr[other:ExtentRange[\T\]] : ExtentRange[\T\] =
3220        if other.extent <= self.extent then
3221            other
3222        else
3223            rangeBoundError[\T\](self,other)
3224        end
3225    opr[other:CompleteRange[\T\]] : CompleteRange[\T\] =
3226        if other.extent <= self.extent then
3227            other
3228        else
3229            rangeBoundError[\T\](self,other)
3230        end
3231    opr =(self,x:ExtentRange[\T\]): Boolean = self.extent = x.extent
3232    opr CMP(self, other:Range[\T\]): Comparison =
3233        typecase other of
3234            OpenRange[\T\]   => LessThan
3235            ExtentRange[\T\] => self.extent PCMP other.extent
3236            else => Unordered
3237        end
3238end
3239
3240(** The type %CompleteRange[\T\]% is really just %FullRange[\T,flag\]% for
3241    either setting of %flag%.  We need it for stuff like %typecase%
3242    and %extends% clauses since we can't bind universally quantified
3243    variables in those settings.  Since essentially all the methods are
3244    independent of the setting of flag we include them here. **)
3245trait CompleteRange[\T\]
3246        extends { RangeWithLower[\T\], RangeWithUpper[\T\],
3247                  RangeWithExtent[\T\], Indexed[\T,T\] }
3248        comprises { FullRange[\T,true\], FullRange[\T,false\] }
3249    getter indices(): FullRange[\T,true\] = bounds()
3250    getter isBounded(): Boolean
3251    getter isSized(): Boolean
3252
3253    (** The following two methods are used in bounds checking code to
3254        permit ranges that are just outside the edge of the given
3255        range.   Because they're intended for internal use we ignore
3256        the setting of flag and return a CompleteRange. **)
3257    widenUpper(): CompleteRange[\T\]
3258    widenLower(): CompleteRange[\T\]
3259
3260    opr[r:Range[\T\]]: CompleteRange[\T\] = fail("Unrecognized Range " r)
3261    opr[_:OpenRange[\T\]]: CompleteRange[\T\] = self
3262    (** Square-bracket indexing on a FullRange restricts that range to
3263         the range provided.  Restriction should behave as follows:
3264            - Restriction to an OpenRange is the identity.
3265            - An UpperRange or ExtentRange restrict the upper bound and
3266              extent of the range.
3267            - A LowerRange restricts the lower bound and extent of the range.
3268        Note that this makes it compatible with the square-bracket
3269        indexing of the Indexed trait. **)
3270    opr[r:LowerRange[\T\]]: CompleteRange[\T\] =
3271        if r.lower = self.lower then
3272            (* Important, also handles empty range case. *)
3273            self
3274        elif r.lower IN widenUpper() then
3275            r.lower:self.upper
3276        else
3277            rangeBoundError[\T\](self,r)
3278        end
3279    opr[r:UpperRange[\T\]]: CompleteRange[\T\] =
3280        if r.upper = self.upper then
3281            (* Important, also handles empty range case. *)
3282            self
3283        elif r.upper IN widenLower() then
3284            self.lower:r.upper
3285        else
3286            rangeBoundError[\T\](self,r)
3287        end
3288    opr[r:ExtentRange[\T\]]: CompleteRange[\T\] =
3289        if r.extent <= self.extent then
3290            self.lower#r.extent
3291        else
3292            fail(self "[" r "] is too small in some dimension")
3293        end
3294    opr[r:CompleteRange[\T\]]: CompleteRange[\T\] =
3295        if r.lower < self.lower then
3296            rangeBoundError[\T\](self,r)
3297        elif r.upper > self.upper then
3298            rangeBoundError[\T\](self,r)
3299        else
3300            r
3301        end
3302
3303    toString():String =
3304        if self.isBounded then
3305            self.lower ":" self.upper
3306        else
3307            self.lower "#" self.extent
3308        end
3309
3310    opr =(self, other:CompleteRange[\T\]): Boolean =
3311    (*    isBounded()=other.isBounded() AND
3312         APB 2008.08.20: this seems bogus: isBounded tells us only whether we were created
3313         using an extent or an upper bound, and should not effect the comparison *)
3314         lower()=other.lower() AND extent() = other.extent()   
3315         
3316    opr CMP(self, other:Range[\T\]): Comparison =
3317        typecase other of
3318            CompleteRange[\T\] =>
3319                a = self.lower PCMP other.lower
3320                b = self.upper PCMP other.upper
3321                typecase _ = (a,b) of
3322                    (Unordered,Comparison) => Unordered
3323                    (Comparison,Unordered) => Unordered
3324                    (LessThan,LessThan) => Unordered
3325                    (GreaterThan,GreaterThan) => Unordered
3326    (*  This case seems unncessary; the (EqualTo,Comparison) case will cover us    --- APB  2008.08.20
3327                    (EqualTo,EqualTo) => EqualTo
3328                        if self.isBounded = other.isBounded then
3329                            EqualTo
3330                        else
3331                            Unordered
3332                        end
3333   *)
3334                    (EqualTo,Comparison) => b
3335                    (GreaterThan,Comparison) => LessThan
3336                    else (* LessThan,Comparison *) => GreaterThan
3337                end
3338            else => INVERSE (other CMP self)
3339        end
3340end
3341
3342(** A %FullRange% is either bounded (generated from a lower and upper
3343    bound, as in %l:u%) or sized (generated from a lower bound and a
3344    size, as in %l#s%).  These two kinds of range behave identically
3345    in most settings; the only time they behave differently is when we
3346    construct a strided range: both %l:u:i% and %l#s:i% generate
3347    elements %l, l+i, l+2i, ...%, but the former is bounded and
3348    generates no element larger than %i% and the latter is sized and
3349    generates exactly %s% elements.
3350
3351    Data structure bounds are always bounded. **)
3352trait FullRange[\T, bool bounded\] extends CompleteRange[\T\]
3353        comprises { ScalarRange[\T,bounded\], TupleRange[\T,bounded\] }
3354    getter isBounded(): Boolean = bounded
3355    getter isSized(): Boolean = NOT bounded
3356end
3357
3358rangeIndexFailure[\T\](r:CompleteRange[\T\],i:T): () =
3359    fail(r "[" i "] out of range.")
3360
3361(** ParRanges and SeqRanges, the simplest and most basic of all
3362    generators.  They generate |self| numbers, incrementing by 1,
3363    starting with lower() (that's the canonical ordering). *)
3364trait ScalarRange[\N extends Integral[\N\], bool bounded\]
3365        extends { FullRange[\N, bounded\] }
3366        comprises { ParRange[\N, bounded\], SeqRange[\N, bounded\] }
3367    getter bounds():FullRange[\N,true\] = ParRange[\N,true\](0,extent())
3368    getter upper():N = lower() + extent() - 1
3369    getter size():ZZ32 = |self|
3370    widenUpper(): ScalarRange[\N,false\] = lower()#(extent()+1)
3371    widenLower(): ScalarRange[\N,false\] = (lower()-1)#(extent()+1)
3372    opr |self| : ZZ32 = narrow(0 MAX extent())
3373    opr[i:N]: N =
3374        if 0 <= i < extent() then
3375            i + lower()
3376        else
3377            rangeIndexFailure[\N\](self,i)
3378        end
3379    opr IN(a:N, self): Boolean = do
3380        t = a - lower()
3381        0 <= t < extent()
3382      end
3383end
3384
3385value object ParRange[\N extends Integral[\N\], bool bounded\](lo:N, ex:N)
3386        extends ScalarRange[\N,bounded\]
3387    getter extent() = ex
3388    getter lower() = lo
3389    getter indexValuePairs() =
3390        ParRange[\N,bounded\](0,ex).map[\(N,N)\](fn (n:N):(N,N) => (n,n+lo))
3391
3392    seq(self) = SeqRange[\N,bounded\](lo,ex)
3393    generate[\R\](r: Reduction[\R\], m: N->R): R =
3394        if ex < 1 then
3395            r.empty()
3396        else
3397            gen(l,s) = if s>=2 then
3398                           (s1,s2) = partition(s)
3399                           r.join(gen(l,s1),gen(l+s1,s2))
3400                       else
3401                           m(l)
3402                       end
3403            gen(lo,ex)
3404        end
3405    mapReduce[\R\](m: N->R, j:(R,R)->R, z:R): R =
3406        if ex < 1 then
3407            z
3408        else
3409            gen(l,s) = if s>=2 then
3410                           (s1,s2) = partition(s)
3411                           j(gen(l,s1),gen(l+s1,s2))
3412                       else
3413                           m(l)
3414                       end
3415            gen(lo,ex)
3416        end
3417    reduce(j:(N,N)->N, z:N):N =
3418        if ex < 1 then
3419            z
3420        else
3421            gen(l,s) = if s>=2 then
3422                           (s1,s2) = partition(s)
3423                           j(gen(l,s1),gen(l+s1,s2))
3424                       else
3425                           l
3426                       end
3427            gen(lo,ex)
3428        end
3429    reduce(r: Reduction[\N\]):N =
3430        if ex < 1 then
3431            r.empty()
3432        else
3433            gen(l,s) = if s>=2 then
3434                           (s1,s2) = partition(s)
3435                           r.join(gen(l,s1),gen(l+s1,s2))
3436                       else
3437                           l
3438                       end
3439            gen(lo,ex)
3440        end
3441    loop(f:N->()): () =
3442        if ex < 1 then
3443            ()
3444        else
3445            gen(l,s) = if s>=2 then
3446                           (s1,s2) = partition(s)
3447                           (gen(l,s1),gen(l+s1,s2))
3448                           ()
3449                       else
3450                           f(l)
3451                       end
3452            gen(lo,ex)
3453        end
3454end
3455value object SeqRange[\N extends Integral[\N\], bool bounded\](lo:N, ex:N)
3456        extends { ScalarRange[\N,bounded\], SequentialGenerator[\N\] }
3457    getter extent() = ex
3458    getter lower() = lo
3459    getter toString() =
3460        ("seq(" lo (if bounded then ":" upper() else "#" ex ")"))
3461    getter indexValuePairs() =
3462        SeqRange[\N,bounded\](0,ex).map[\(N,N)\](fn (n:N):(N,N) => (n,n+lo))
3463    generate[\R\](r: Reduction[\R\], m: N->R): R = do
3464        h = lo + ex
3465        l : N := lo
3466        acc : R = r.empty()
3467        (* DON'T DEFINE THIS USING RECURSION!!! *)
3468        while l < h do
3469            b = m(l)
3470            acc := r.join(acc, b)
3471            l += 1
3472        end
3473        acc
3474      end
3475    loop(f: N->()): () = do
3476        h = lo + ex
3477        l : N := lo
3478        (* DON'T DEFINE THIS USING RECURSION!!! *)
3479        while l < h do
3480            f(l)
3481            l += 1
3482        end
3483      end
3484end
3485
3486trait TupleRange[\T, bool bounded\] extends FullRange[\T,bounded\]
3487end
3488
3489object Tuple2Range[\N extends Integral[\N\], M extends Integral[\M\], bool bounded\]
3490                  (l1:N,l2:M,x1:N,x2:M)
3491        extends { TupleRange[\(N,M),bounded\], DelegatedIndexed[\(N,M),(N,M)\] }
3492    getter bounds():Tuple2Range[\N,M,true\] = Tuple2Range[\N,M,true\](0,0,x1,x2)
3493    getter extent():(N,M) = (x1,x2)
3494    getter lower():(N,M) = (l1,l2)
3495    getter upper():(N,M) = (l1+x1-1, l2+x2-1)
3496    getter size():(N,M) = |self|
3497    getter generator():Generator[\(N,M)\] =
3498        ParRange[\N,bounded\](l1,x1).cross[\M\](ParRange[\M,bounded\](l2,x2))
3499    getter toString(): String =
3500        ("(" l1 "," l2
3501         (if bounded then
3502             (u1,u2) = upper()
3503             "):(" u1 "," u2 ")"
3504         else
3505             ")#(" x1 "," x2 ")"
3506         end))
3507    getter indexValuePairs() =
3508        bounds().map[\((N,M),(N,M))\](
3509            fn (n:N,m:M):((N,M),(N,M)) => ((n,m),(n+l1,m+l2)))
3510    widenUpper(): Tuple2Range[\N,M,true\] = Tuple2Range[\N,M,true\](l1,l2,x1+1,x2+1)
3511    widenLower(): Tuple2Range[\N,M,true\] = Tuple2Range[\N,M,true\](l1-1,l2-1,x1+1,x2+1)
3512    opr |self| : ZZ32 = narrow((0 MAX x1) (0 MAX x2))
3513    opr[i:(N,M)]: (N,M) = do
3514        (i1,i2) = i
3515        if 0 <= i1 < x1 AND 0 <= i2 < x2 then
3516            (i1+l1,i2+l2)
3517        else
3518            rangeIndexFailure[\(N,M)\](self,i)
3519        end
3520      end
3521    opr IN(t:(N,M), self): Boolean = do
3522        (v1,v2) = t
3523        0 <= v1-l1 < x1 AND 0 <= v2-l2 < x2
3524      end
3525    opr =(self,r:Tuple2Range[\N,M,bounded\]): Boolean =
3526        l1=r.l1 AND l2=r.l2 AND x1=r.x1 AND x2=r.x2
3527end
3528
3529object Tuple3Range[\N1 extends Integral[\N1\], N2 extends Integral[\N2\], N3 extends Integral[\N3\],
3530                   bool bounded\]
3531                  (l1:N1,l2:N2,l3:N3,x1:N1,x2:N2,x3:N3)
3532        extends { TupleRange[\(N1,N2,N3),bounded\],
3533                  DelegatedIndexed[\(N1,N2,N3),(N1,N2,N3)\] }
3534    getter bounds():Tuple3Range[\N1,N2,N3,true\] =
3535        Tuple3Range[\N1,N2,N3,true\]((0,0,0),(x1,x2,x3))
3536    getter extent():(N1,N2,N3) = (x1,x2,x3)
3537    getter lower():(N1,N2,N3) = (l1,l2,l3)
3538    getter upper():(N1,N2,N3) = (l1+x1-1,l2+x2-1,l3+x3-1)
3539    getter size():(N1,N2,N3) = |self|
3540    getter generator():Generator[\(N1,N2,N3)\] =
3541        ParRange[\N1,bounded\](l1,x1).cross[\N2\](ParRange[\N2,bounded\](l2,x2)).cross[\N3\](
3542            ParRange[\N3,bounded\](l3,x3)).map[\(N1,N2,N3)\](
3543                fn (t:(N1,N2),n3:N3):(N1,N2,N3) => do (n1,n2)=t; (n1,n2,n3) end)
3544    getter toString(): String =
3545        ("(" l1 "," l2 "," l3
3546         (if bounded then
3547             (u1,u2,u3) = upper()
3548             "):(" u1 "," u2 "," u3 ")"
3549         else
3550             ")#(" x1 "," x2 "," x3 ")"
3551         end))
3552    getter indexValuePairs() =
3553        (0#x1).cross(0#x2).cross(0#x3).map[\((N1,N2,N3),(N1,N2,N3))\](
3554            fn (t:(N1,N2),n3:N3):((N1,N2,N3),(N1,N2,N3)) =>
3555                do (n1,n2)=t; ((n1,n2,n3),(n1+l1,n2+l2,n3+l3)) end)
3556    widenUpper(): Tuple3Range[\N1,N2,N3,true\] =
3557        Tuple3Range[\N1,N2,N3,true\](l1,l2,l3,x1+1,x2+1,x3+1)
3558    widenLower(): Tuple3Range[\N1,N2,N3,true\] =
3559        Tuple3Range[\N1,N2,N3,true\](l1-1,l2-1,l3-1,x1+1,x2+1,x3+1)
3560    opr |self| : (N1,N2,N3) = narrow((0 MAX x1) (0 MAX x2) (0 MAX x3))
3561    opr[i:(N1,N2,N3)]: (N1,N2,N3) = do
3562        (i1,i2,i3) = i
3563        if 0 <= i1 < x1 AND 0 <= i2 < x2 AND 0 <= i3 < x3 then
3564            (i1+l1,i2+l2,i3+l3)
3565        else
3566            rangeIndexFailure[\(N1,N2,N3)\](self,i)
3567        end
3568      end
3569    opr IN(t:(N1,N2,N3), self): Boolean = do
3570        (v1,v2,v3) = t
3571        0 <= v1-l1 < x1 AND 0 <= v2-l2 < x2 AND 0 <= v3-l3 < x3
3572      end
3573    opr =(self,r:Tuple3Range[\N1,N2,N3,bounded\]): Boolean =
3574        l1=r.l1 AND l2=r.l2 AND x1=r.x1 AND x2=r.x2 AND l3=r.l3 AND x3=r.x3
3575end
3576
3577(** Helpers for # to get the type instantiation "right".  We pass in bogus ZZ32's to
3578    ensure that the result type is at least ZZ32. **)
3579sizedRange[\I extends AnyIntegral\](_:I,lo:I,ex:I): ParRange[\I,false\] = ParRange[\I,false\](lo,ex)
3580sized2Range[\I extends AnyIntegral, J extends AnyIntegral\]
3581           (_:I,_:J,l1:I,l2:J,ex1:I,ex2:J): Tuple2Range[\I,J,false\] =
3582    Tuple2Range[\I,J,false\](l1,l2,ex1,ex2)
3583sized3Range[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
3584     (_:I,_:J,_:K,l1:I,l2:J,l3:K,ex1:I,ex2:J,ex3:K): Tuple3Range[\I,J,K,false\] =
3585    Tuple3Range[\I,J,K,false\](l1,l2,l3,ex1,ex2,ex3)
3586
3587(** The # and : operators serve as factories for parallel ranges. **)
3588opr #[\I extends AnyIntegral\](lo:I, ex:I): ParRange[\I,false\] = sizedRange(0 asif ZZ32,lo,ex)
3589(*
3590opr #(lo:IntLiteral, ex:IntLiteral): ParRange[\ZZ32\] = ParRange[\ZZ32,false\](lo,ex)
3591*)
3592opr #[\I extends AnyIntegral, J extends AnyIntegral\]
3593     (lo:(I,J), ex:(I,J)): Tuple2Range[\I,J,false\] =
3594    do (l1,l2)=lo; (x1,x2)=ex; sized2Range(0 asif ZZ32,0 asif ZZ32,l1,l2,x1,x2) end
3595opr #[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
3596     (lo:(I,J,K), ex:(I,J,K)): Tuple3Range[\I,J,K,false\] =
3597    do (l1,l2,l3)=lo; (x1,x2,x3)=ex
3598       sized3Range(0 asif ZZ32,0 asif ZZ32,0 asif ZZ32,l1,l2,l3,x1,x2,x3)
3599    end
3600
3601(** Helpers for : to get the type instantiation "right".  We pass in bogus ZZ32's to
3602    ensure that the result type is at least ZZ32.  **)
3603boundedRange[\I extends AnyIntegral\](_:I,lo:I,ex:I): ParRange[\I,true\] = ParRange[\I,true\](lo,ex)
3604bounded2Range[\I extends AnyIntegral, J extends AnyIntegral\]
3605           (_:I,_:J,l1:I,l2:J,ex1:I,ex2:J): Tuple2Range[\I,J,true\] =
3606    Tuple2Range[\I,J,true\](l1,l2,ex1,ex2)
3607bounded3Range[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
3608     (_:I,_:J,_:K,l1:I,l2:J,l3:K,ex1:I,ex2:J,ex3:K): Tuple3Range[\I,J,K,true\] =
3609    Tuple3Range[\I,J,K,true\](l1,l2,l3,ex1,ex2,ex3)
3610
3611opr :[\I extends AnyIntegral\](lo:I, hi:I): ParRange[\I,true\] =
3612        boundedRange(0 asif ZZ32,lo,hi-lo+1)
3613(*
3614opr :(lo:IntLiteral, hi:IntLiteral): ParRange[\ZZ32,true\] =
3615        ParRange[\ZZ32,true\](lo,hi-lo+1)
3616*)
3617opr :[\I extends AnyIntegral, J extends AnyIntegral\]
3618     (lo:(I,J), hi:(I,J)): Tuple2Range[\I,J,true\] =
3619    do (l1,l2)=lo; (h1,h2)=hi; bounded2Range(0 asif ZZ32,0 asif ZZ32,l1,l2,h1-l1+1,h2-l2+1) end
3620opr :[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
3621     (lo:(I,J,K), hi:(I,J,K)): Tuple3Range[\I,J,K,true\] = do
3622    (l1,l2,l3)=lo; (h1,h2,h3)=hi
3623    bounded3Range(0 asif ZZ32,0 asif ZZ32,0 asif ZZ32,l1,l2,l3,h1-l1+1,h2-l2+1,h3-l3+1)
3624  end
3625
3626lowerRange[\I extends AnyIntegral\](_:I,x:I):LowerRange[\I\] = LowerRange[\I\](x)
3627lower2Range[\I extends AnyIntegral, J extends AnyIntegral\](_:I,_:J,x:I,y:J):
3628    LowerRange[\(I,J)\] = LowerRange[\(I,J)\](x,y)
3629lower3Range[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
3630           (_:I,_:J,_:K,x:I,y:J,z:K): LowerRange[\(I,J,K)\] =
3631    LowerRange[\(I,J,K)\](x,y,z)
3632
3633extentRange[\I extends AnyIntegral\](_:I,x:I):ExtentRange[\I\] = ExtentRange[\I\](x)
3634extent2Range[\I extends AnyIntegral, J extends AnyIntegral\](_:I,_:J,x:I,y:J):
3635    ExtentRange[\(I,J)\] = ExtentRange[\(I,J)\](x,y)
3636extent3Range[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
3637            (_:I,_:J,_:K,x:I,y:J,z:K): ExtentRange[\(I,J,K)\] =
3638    ExtentRange[\(I,J,K)\](x,y,z)
3639
3640upperRange[\I extends AnyIntegral\](_:I,x:I):UpperRange[\I\] = UpperRange[\I\](x)
3641upper2Range[\I extends AnyIntegral, J extends AnyIntegral\](_:I,_:J,x:I,y:J):
3642    UpperRange[\(I,J)\] = UpperRange[\(I,J)\](x,y)
3643upper3Range[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\]
3644           (_:I,_:J,_:K,x:I,y:J,z:K): UpperRange[\(I,J,K)\] =
3645    UpperRange[\(I,J,K)\](x,y,z)
3646
3647(** Factories for incomplete ranges **)
3648opr (x:I)#[\I extends AnyIntegral\] : LowerRange[\I\] = lowerRange(0 asif ZZ32, x)
3649opr (x:I,y:J)#[\I extends AnyIntegral, J extends AnyIntegral\] : LowerRange[\(I,J)\] =
3650    lower2Range(0 asif ZZ32,0 asif ZZ32, x,y)
3651opr (x:I,y:J,z:K)#[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\] :
3652         LowerRange[\(I,J,K)\] = lower3Range(0 asif ZZ32,0 asif ZZ32,0 asif ZZ32, x,y,z)
3653opr (x:I):[\I\] : LowerRange[\I\] = x#
3654opr #[\I extends AnyIntegral\](x:I) : ExtentRange[\I\] = extentRange(0 asif ZZ32, x)
3655opr #[\I extends AnyIntegral, J extends AnyIntegral\](xy:(I,J)) : ExtentRange[\(I,J)\] =
3656    do (x,y) = xy; extent2Range(0 asif ZZ32,0 asif ZZ32, x,y) end
3657opr #[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\](xyz:(I,J,K)) :
3658         ExtentRange[\(I,J,K)\] =
3659    do (x,y,z) = xyz; extent3Range(0 asif ZZ32,0 asif ZZ32,0 asif ZZ32, x,y,z) end
3660opr :[\I extends AnyIntegral\](x:I) : UpperRange[\I\] = upperRange(0 asif ZZ32, x)
3661opr :[\I extends AnyIntegral, J extends AnyIntegral\](xy:(I,J)) : UpperRange[\(I,J)\] =
3662    do (x,y) = xy; upper2Range(0 asif ZZ32,0 asif ZZ32, x,y) end
3663opr :[\I extends AnyIntegral, J extends AnyIntegral, K extends AnyIntegral\](xyz:(I,J,K)) :
3664         UpperRange[\(I,J,K)\] =
3665    do (x,y,z) = xyz; upper3Range(0 asif ZZ32,0 asif ZZ32,0 asif ZZ32, x,y,z) end
3666(*
3667opr (x:I)#[\I\] : LowerRange[\I\] = LowerRange[\I\](x)
3668opr (x:I):[\I\] : LowerRange[\I\] = LowerRange[\I\](x)
3669opr #[\I\](x:I) : ExtentRange[\I\] = ExtentRange[\I\](x)
3670opr :[\I\](x:I) : UpperRange[\I\] = UpperRange[\I\](x)
3671*)
3672opr #() : OpenRange[\Any\] = OpenRange[\Any\]
3673opr :() : OpenRange[\Any\] = OpenRange[\Any\]
3674
3675trait String extends { StandardTotalOrder[\String\], ZeroIndexed[\Char\], DelegatedIndexed[\Char,ZZ32\] }
3676             excludes {Number, Char, AnyMultiplicativeRing, AnyList}
3677    getter size() : ZZ32
3678    getter toString() : String = self
3679    getter indices() : FullRange[\ZZ32,true\] = self.bounds
3680    (* This is the "dumb" generator.  It always works, but can be "Big O" inefficient, e.g., for
3681       CatString trees.  Sub-traits should override it with equivalent but more efficeint code. *)
3682    getter generator() : Generator[\Char\] =
3683        indices().map[\Char\](fn (i:ZZ32):Char => self[i])       
3684    getter depth() = 0
3685   
3686    showStructure() = showStructure(0)
3687     
3688    opr |self| : ZZ32 = self.size
3689       
3690    opr CASE_INSENSITIVE_CMP(self, other:String): TotalComparison =
3691      ((BIG LEXICO[i <- 0#(|self| MIN |other|) ] self.get(i) CASE_INSENSITIVE_CMP other.get(i)) LEXICO (|self| CMP |other|))
3692   
3693    opr CMP(self, other:String): TotalComparison =
3694      ((BIG LEXICO[i <- 0#(|self| MIN |other|) ] self.get(i) CMP other.get(i)) LEXICO (|self| CMP |other|))
3695     
3696    opr [i:ZZ32]: Char =
3697        (** As a convenience, we permit LowerRange indexing to go 1 past the bounds
3698        of the String, returning the empty String, in order to permit some convenient
3699        String-trimming idioms. **)
3700        if 0 <= i < |self|
3701        then self.get(i)
3702        else
3703            (* println "Index " i " not in bounds " self.bounds *)
3704            throw IndexOutOfBounds(0,(|self|)-1,i)
3705        end
3706
3707    opr[r0:Range[\ZZ32\]] : String =  do
3708        r1 = self.bounds[r0]     (* This will complete r0 if it is incomplete, and throw a bounds exception when necessary *)
3709        self.uncheckedSubstring(r1)
3710      end
3711
3712    (** The operator %||% with at least one String argument converts to String and
3713        appends **)
3714    opr ||(self, b:String):String
3715    opr ||(self, b:Number):String = self || b.toString
3716    opr ||(self, c:Char):String
3717    opr ||(self, b:()):String = self || "()"
3718    opr ||(self, b:(Any,Any)):String = do (i,j) = b; self || "(" || i || "," j || ")" end
3719    opr ||(self, b:(Any,Any,Any)):String =
3720        do (i,j,k) = b; self || "(" || i || "," j || "," k || ")" end
3721    opr ||(self, b:(Any,Any,Any,Any)):String =
3722        do (i,j,k,l) = b; self || "(" || i || "," j || "," k || "," l || ")" end
3723    opr ||(self, b:(Any,Any,Any,Any,Any)):String =
3724        do (i,j,k,l,m) = b; self || "(" || i || "," j || "," k || "," l || "," m || ")" end
3725    opr ||(self, b:(Any,Any,Any,Any,Any,Any)):String =
3726        do (i,j,k,l,m,n) = b; self || "(" || i || "," j || "," k || "," l || "," m || "," n || ")" end
3727    opr ||(a:Any, self):String = a.toString || self
3728    opr ||(self, b:Any):String = self || b.toString
3729
3730    (** The operator %|||% with at least one String argument converts to string,
3731        then appends with a whitespace separator unless one of the two arguments is
3732        empty.  If there is an empty argument, the other argument is returned. **)
3733    opr |||(self, b:String): String =
3734        if |self| = 0 then b
3735        elif |b| = 0 then self
3736        else self || " " || b
3737        end
3738    opr |||(self, b:Any): String = self ||| (""||b)
3739    opr |||(a:Any, self): String = (""||a) ||| self
3740
3741    (** Right now for backward compatibility juxtaposition works like %||% **)
3742    opr juxtaposition(a:Any, self):String = (""||a) || self
3743    opr juxtaposition(self, b:String):String = self || b
3744    opr juxtaposition(self, b:Any):String = self || b
3745
3746    (** opr %//% appends with a single newline separator.  Note that as
3747        with %||% and %|||% at least one argument must be a String.
3748        There is a postfix version in FortressLibrary that performs
3749        string conversion, but the prefix version must occur before a
3750        String. **)
3751    opr //(self) : String = "\n"||self
3752    opr //(self, a:String): String = self||"\n"||a
3753    opr //(self, a:Any): String    = self||"\n"||a
3754    opr //(a:Any, self): String    = a||"\n"||self
3755
3756    (** opr %///% appends with a double newline separator.  Note that, as
3757        with %||% and %|||%, at least one argument must be a String.
3758        There is a postfix version in FortressLibrary that performs
3759        string conversion, but the prefix version must occur before a
3760        String. **)
3761    opr ///(self) : String = "\n\n"||self
3762    opr ///(self, a:String): String = self||"\n\n"||a
3763    opr ///(self, a:Any): String    = self||"\n\n"||a
3764    opr ///(a:Any, self): String    = a||"\n\n"||self
3765
3766  end
3767
3768(***********************************************************
3769* Numeric primitives
3770************************************************************)
3771
3772nanoTime():ZZ64 = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Long$NanoTime")
3773printTaskTrace():() = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$PrintTaskTrace")
3774
3775__globalTimeInformation: ZZ64 := 0
3776recordTime(dummy: Any): () = do __globalTimeInformation := nanoTime() end
3777printTime(dummy: Any): () = do
3778    r = nanoTime()
3779    e = r - __globalTimeInformation
3780    __globalTimeInformation := r
3781    secs: ZZ64 = (e+500000) DIV 1000000
3782    println("Operation took " secs "ms")
3783  end
3784
3785fromRawBits(a:ZZ64):RR64 = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$FromRawBits")
3786
3787random(a:Number):RR64 = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Float$Random")
3788
3789char(a:ZZ32):Char = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.Char$Chr")
3790
3791
3792print(a:Any):() = print(a.toString)
3793println(a:Any):() = println(a.toString)
3794(* 0-argument versions handle passing of () to single-argument versions. *)
3795print():() = print("")
3796println():() = println("")
3797print(a: JavaString): () =
3798        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$Print")
3799println(a: JavaString): () =
3800        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$Println")
3801
3802forDigit(x:ZZ32, radix:ZZ32): Maybe[\Char\] =
3803    if (radix<2 OR radix>16 OR x<0 OR x>=radix) then
3804        Nothing[\Char\]
3805    elif (radix <= 12) then
3806        forDigit(x, "0123456789xe")
3807    else
3808        forDigit(x, "0123456789abcdef")
3809    end
3810
3811forDigit(x:ZZ32, radixString:String): Maybe[\Char\] =
3812    if( 0 <= x < |radixString| ) then
3813        Just[\Char\](radixString[x])
3814    else
3815        Nothing[\Char\]
3816    end
3817
3818
3819(** Convert string to arbitrary integral type.  String may contain
3820    leading - or +.  Valid radixes are 2,8,10,12, and 16.  No spaces
3821    may occur in the string, and it must have at least one digit.
3822
3823    Right now we're oblivious to overflow!  This ought to be fixed.
3824
3825    This ought to support arbitrary integer types, but right now
3826    there's no clean way to convert all the arithmetic to use a
3827    provided type without having an instance of that type in hand.
3828    Unsigned types in particular are a bit sticky.
3829 **)
3830strToInt(s: String, radix: ZZ32): ZZ32 = do
3831    (i0, neg) =
3832        if s[0] = '-' then (1, true)
3833        elif s[0] = '+' then (1, false)
3834        else (0,false) end
3835    n = |s| - 1
3836    r = SUM[ i <- i0:n] if d <- digit(s[i], radix) then
3837                          d radix^(n-i)
3838                      else
3839                          fail("strToInt(" s.toString "," radix "): non-digit " s[i].toString)
3840                      end
3841    if neg then -r else r end
3842  end
3843
3844(** Radix-10 digit conversion.  All caveats of the flexible-radix conversion above apply. *)
3845strToInt(s: String): ZZ32 = strToInt(s,10)
3846
3847match(regex:String,some:String):Boolean = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$Match")
3848
3849(** postfix %//% appends a single newline separator.  The postfix version
3850    performs implicit conversion to String, which is why it's a
3851    standalone top-level function.  Infix and prefix versions are defined by String. **)
3852opr (x:Any)// : String = x||"\n"
3853
3854(** postfix %///% appends a double newline separator.  The postfix version
3855    performs implicit conversion to String, which is why it's a
3856    standalone top-level function.  Infix and prefix versions are defined by String. **)
3857opr (x:Any)/// : String = x||"\n\n"
3858
3859(* A way to get environment information from inside of fortress *)
3860getEnvironment(name:String, defaultValue:String):String = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$GetEnvironment")
3861
3862(* These are useful temporary hacks for debugging multi-threaded programs *)
3863printThreadInfo(a:String):() = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$PrintThreadInfo")
3864printThreadInfo(a:Number):() = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$PrintThreadInfo")
3865throwError(a:String):() = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$ThrowError")
3866
3867opr SEQV(a:Any, b:Any):Boolean =
3868    builtinPrimitive("com.sun.fortress.interpreter.glue.prim.AnyPrim$SEquiv")
3869
3870opr  XOR(a:Boolean, b:Boolean):Boolean = if a then NOT b else b end
3871opr  OR(a:Boolean, b:Boolean):Boolean = if a then true else b end
3872opr AND(a:Boolean, b:Boolean):Boolean = if a then b else false end
3873opr  OR(a:Boolean, b:()->Boolean):Boolean = if a then true else b() end
3874opr AND(a:Boolean, b:()->Boolean):Boolean = if a then b() else false end
3875opr NOT(a:Boolean):Boolean = if a then false else true end
3876opr ->(a: Boolean, b:Boolean):Boolean = if a then b else true end
3877opr ->(a: Boolean, b:()->Boolean):Boolean = if a then b() else true end
3878opr <->(a: Boolean, b:Boolean):Boolean = a=b
3879
3880true : Boolean = () SEQV ()
3881false : Boolean = true SEQV ()
3882
3883opr +[\T extends Number\](x:T):T = x
3884
3885(* Shouldn't these operators have to extend something? A,B,C? *)
3886
3887opr =[\A,B\](t1:(A,B), t2:(A,B)): Boolean = do
3888    (a1,b1) = t1
3889    (a2,b2) = t2
3890    (a1=a2) AND: (b1=b2)
3891  end
3892
3893opr <[\A,B\](t1:(A,B), t2:(A,B)): Boolean = do
3894    (a1,b1) = t1
3895    (a2,b2) = t2
3896    typecase _ = a1 CMP a2 of
3897        LessThan => true
3898        EqualTo => b1 < b2
3899        GreaterThan => false
3900    end
3901  end
3902
3903opr <=[\A,B\](t1:(A,B), t2:(A,B)): Boolean = do
3904    (a1,b1) = t1
3905    (a2,b2) = t2
3906    typecase _ = a1 CMP a2 of
3907        LessThan => true
3908        EqualTo => b1 <= b2
3909        GreaterThan => false
3910    end
3911  end
3912
3913opr >[\A,B\](t1:(A,B), t2:(A,B)): Boolean = do
3914    (a1,b1) = t1
3915    (a2,b2) = t2
3916    typecase _ = a1 CMP a2 of
3917        LessThan => false
3918        EqualTo => b1 > b2
3919        GreaterThan => true
3920    end
3921  end
3922
3923opr >=[\A,B\](t1:(A,B), t2:(A,B)): Boolean = do
3924    (a1,b1) = t1
3925    (a2,b2) = t2
3926    typecase _ = a1 CMP a2 of
3927        LessThan => false
3928        EqualTo => b1 >= b2
3929        GreaterThan => true
3930    end
3931  end
3932
3933opr CMP[\A,B\](t1:(A,B), t2:(A,B)): Comparison = do
3934    (a1,b1) = t1
3935    (a2,b2) = t2
3936    (a1 CMP a2) LEXICO: (b1 CMP b2)
3937  end
3938
3939opr =[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean = do
3940    (a1,b1,c1) = t1
3941    (a2,b2,c2) = t2
3942    (a1=a2) AND: (b1=b2) AND: (c1=c2)
3943  end
3944
3945opr <[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean = do
3946    (a1,b1,c1) = t1
3947    (a2,b2,c2) = t2
3948    typecase _ = (a1 CMP a2) LEXICO: (b1 CMP b2) of
3949        LessThan => true
3950        EqualTo => c1 < c2
3951        GreaterThan => false
3952    end
3953  end
3954
3955opr <=[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean = do
3956    (a1,b1,c1) = t1
3957    (a2,b2,c2) = t2
3958    typecase _ = (a1 CMP a2) LEXICO: (b1 CMP b2) of
3959        LessThan => true
3960        EqualTo => c1 <= c2
3961        GreaterThan => false
3962    end
3963  end
3964
3965opr >[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean = do
3966    (a1,b1,c1) = t1
3967    (a2,b2,c2) = t2
3968    typecase _ = (a1 CMP a2) LEXICO: (b1 CMP b2) of
3969        LessThan => false
3970        EqualTo => c1 > c2
3971        GreaterThan => true
3972    end
3973  end
3974
3975opr >=[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Boolean = do
3976    (a1,b1,c1) = t1
3977    (a2,b2,c2) = t2
3978    typecase _ = (a1 CMP a2) LEXICO: (b1 CMP b2) of
3979        LessThan => false
3980        EqualTo => c1 >= c2
3981        GreaterThan => true
3982    end
3983  end
3984
3985opr CMP[\A,B,C\](t1:(A,B,C), t2:(A,B,C)): Comparison = do
3986    (a1,b1,c1) = t1
3987    (a2,b2,c2) = t2
3988    (a1 CMP a2) LEXICO: (b1 CMP b2) LEXICO: (c1 CMP c2)
3989  end
3990
3991object Box[\T\](var val : T)
3992end
3993
3994end
Note: See TracBrowser for help on using the browser.