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