| 1 | (******************************************************************************* |
|---|
| 2 | Copyright 2009 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 | component PureList |
|---|
| 19 | import CovariantCollection.{...} |
|---|
| 20 | export PureList |
|---|
| 21 | |
|---|
| 22 | (** Finger trees, based on Ralf Hinze and Ross Paterson's article, JFP |
|---|
| 23 | 16:2 2006. |
|---|
| 24 | |
|---|
| 25 | Why finger trees? They're balanced and support nearly any |
|---|
| 26 | operation we care to think of in optimal asymptotic time and |
|---|
| 27 | space. The code is niggly due to lots of cases, but fast in |
|---|
| 28 | practice. |
|---|
| 29 | |
|---|
| 30 | It's also a trial for encoding type-based invariants in Fortress. |
|---|
| 31 | Can we represent "array of size at most n"? Not yet, but we ought |
|---|
| 32 | to be able to do so. This involves questions about the encoding |
|---|
| 33 | of existentials, especially constrained existentials. |
|---|
| 34 | |
|---|
| 35 | **) |
|---|
| 36 | |
|---|
| 37 | (* Tests can be found in |
|---|
| 38 | tests/PureListQuick.fss |
|---|
| 39 | demos/PureListLong.fss |
|---|
| 40 | *) |
|---|
| 41 | |
|---|
| 42 | (** Generic list trait. |
|---|
| 43 | We return a Generator for non-List-specific operations for which |
|---|
| 44 | reuse of the Generator won't increase asymptotic complexity, but |
|---|
| 45 | return a List in cases (such as map and filter) where it will. |
|---|
| 46 | *) |
|---|
| 47 | trait List[\E\] extends { LexicographicOrder[\List[\E\],E\] } |
|---|
| 48 | excludes { Number, HasRank, String } |
|---|
| 49 | (** %left% and %extractLeft% return the leftmost element in the list |
|---|
| 50 | (and in the latter case, the remainder of the list without its |
|---|
| 51 | leftmost element). They return %Nothing% if the list is empty. |
|---|
| 52 | %right% and %extractRight% do the same with the rightmost |
|---|
| 53 | element. *) |
|---|
| 54 | getter left():Maybe[\E\] = self.extractLeft.map[\E\](fn (v:E,_):E => v) |
|---|
| 55 | getter right():Maybe[\E\] = self.extractRight.map[\E\](fn (_,v:E):E => v) |
|---|
| 56 | getter extractLeft(): Maybe[\(E,List[\E\])\] |
|---|
| 57 | getter extractRight(): Maybe[\(List[\E\],E)\] |
|---|
| 58 | getter asString(): String = "<|" || ", ".join[\E\](self) || "|>" |
|---|
| 59 | getter reverse(): List[\E\] = |
|---|
| 60 | generate[\List[\E\]\](RevConcat[\E\],singleton[\E\]) |
|---|
| 61 | opr ||(self, other:List[\E\]): List[\E\] |
|---|
| 62 | (** %addLeft% and %addRight% add an element to the left or right of |
|---|
| 63 | the list, respectively *) |
|---|
| 64 | addLeft(e:E):List[\E\] |
|---|
| 65 | addRight(e:E):List[\E\] |
|---|
| 66 | (** %take% returns the leftmost %n% elements of the list; if the |
|---|
| 67 | list is shorter than this, the entire list is returned. *) |
|---|
| 68 | take(n:ZZ32): List[\E\] |
|---|
| 69 | (** %drop% drops the leftmost %n% elements of the list; if the list |
|---|
| 70 | is shorter than this, an empty list is returned. *) |
|---|
| 71 | drop(n:ZZ32): List[\E\] |
|---|
| 72 | opr [n:ZZ32]: E |
|---|
| 73 | opr [n:Range[\ZZ32\]]: List[\E\] = do |
|---|
| 74 | r = (0 # |self|).narrowToRange(n) |
|---|
| 75 | if r.stride = 1 then |
|---|
| 76 | drop(r.left.get).take(|r|) |
|---|
| 77 | else |
|---|
| 78 | <| self[i] | i <- r |> |
|---|
| 79 | end |
|---|
| 80 | end |
|---|
| 81 | (** %l.split(n)% is equivalent to %(l.take(n),l.drop(n))%. Note in |
|---|
| 82 | particular that appending its results yields the original |
|---|
| 83 | list. *) |
|---|
| 84 | split(n:ZZ32): (List[\E\], List[\E\]) |
|---|
| 85 | (** %split% splits the list into two smaller lists. If %|l| > 1% |
|---|
| 86 | both lists will be non-empty. *) |
|---|
| 87 | split(): (List[\E\], List[\E\]) |
|---|
| 88 | filter(p: E -> Boolean): List[\E\] = |
|---|
| 89 | concatMap[\E\](fn (x:E):List[\E\] => if p(x) then singleton[\E\](x) |
|---|
| 90 | else emptyList[\E\]() end) |
|---|
| 91 | (** %concatMap% is an in-place version of the %nest% method from |
|---|
| 92 | %Generator%; it flattens the result into an actual list, rather than |
|---|
| 93 | returning an abstract %Generator%. *) |
|---|
| 94 | concatMap[\G\](f: E->List[\G\]): List[\G\] = |
|---|
| 95 | generate[\List[\G\]\](Concat[\G\],f) |
|---|
| 96 | map[\G\](f: E->G): List[\G\] = |
|---|
| 97 | concatMap[\G\](fn (e:E):List[\G\] => singleton[\G\](f(e))) |
|---|
| 98 | ivmap[\G\](f: (ZZ32,E)->G): List[\G\] = |
|---|
| 99 | self.indexValuePairs.generate[\List[\G\]\](Concat[\G\], |
|---|
| 100 | fn (t:(ZZ32,E)):List[\G\] => singleton[\G\](f(t))) |
|---|
| 101 | end |
|---|
| 102 | |
|---|
| 103 | (** Vararg factory for lists; provides aggregate list constants **) |
|---|
| 104 | opr <|[\E\] xs: E... |>: List[\E\] = list(xs) |
|---|
| 105 | opr BIG <|[\T\]|>: Comprehension[\T,List[\T\],AnyCovColl,AnyCovColl\] = |
|---|
| 106 | covariantCompr[\T,List[\T\]\](fn cc => list(cc.toImmutableArray())) |
|---|
| 107 | opr BIG <|[\T\] g:Generator[\T\]|>:List[\T\] = |
|---|
| 108 | __bigOperatorSugar[\T,List[\T\],AnyCovColl,AnyCovColl\](BIG <|[\T\]|>(), g) |
|---|
| 109 | |
|---|
| 110 | (** Convert generator into list; can be used to desugar list |
|---|
| 111 | comprehensions *) |
|---|
| 112 | list[\E\](g:Generator[\E\]):List[\E\] = |
|---|
| 113 | g.generate[\List[\E\]\](Concat[\E\], singleton[\E\]) |
|---|
| 114 | list[\E\](g:ReadableArray[\E,ZZ32\]): List[\E\] = |
|---|
| 115 | PureList[\E\](arrayToFingerTree[\E\](g)) |
|---|
| 116 | |
|---|
| 117 | arrayToFingerTree[\E\](g:ReadableArray[\E,ZZ32\]): FingerTree[\E\] = do |
|---|
| 118 | l = g.bounds.lower |
|---|
| 119 | case |g| of |
|---|
| 120 | 0 => D0[\E\] |
|---|
| 121 | 1 => D1[\E\](g[l]) |
|---|
| 122 | 2 => Deep[\E\](D1[\E\](g[l]),D0[\D23[\E\]\],D1[\E\](g[l+1])) |
|---|
| 123 | 3 => Deep[\E\](D1[\E\](g[l]),D0[\D23[\E\]\],D2[\E\](g[l+1],g[l+2])) |
|---|
| 124 | else => |
|---|
| 125 | u = g.bounds.upper |
|---|
| 126 | n = (|g| + 2) DIV 3 - 2 |
|---|
| 127 | (start, left, right) = |
|---|
| 128 | case |g| MOD 3 of |
|---|
| 129 | 0 => (3, D3[\E\](g[l],g[l+1],g[l+2]), D3[\E\](g[u-2],g[u-1],g[u])) |
|---|
| 130 | 1 => (2, D2[\E\](g[l],g[l+1]), D2[\E\]( g[u-1],g[u])) |
|---|
| 131 | 2 => (3, D3[\E\](g[l],g[l+1],g[l+2]), D2[\E\]( g[u-1],g[u])) |
|---|
| 132 | end |
|---|
| 133 | arr = immutableArray[\D23[\E\]\](n) |
|---|
| 134 | for i <- arr.indices do |
|---|
| 135 | offset = start + 3 i |
|---|
| 136 | arr.init(i, D3[\E\](g[offset],g[offset+1],g[offset+2])) |
|---|
| 137 | end |
|---|
| 138 | Deep[\E\](left,arrayToFingerTree[\D23[\E\]\](arr),right) |
|---|
| 139 | end |
|---|
| 140 | end |
|---|
| 141 | |
|---|
| 142 | (** Flatten a list of lists *) |
|---|
| 143 | concat[\E\](x:List[\List[\E\]\]):List[\E\] = x.concatMap[\E\](identity[\E\]) |
|---|
| 144 | |
|---|
| 145 | (** A reduction object for concatenating lists. *) |
|---|
| 146 | private object Concat[\E\] extends MonoidReduction[\ List[\E\] \] |
|---|
| 147 | getter asString(): String = "List concatenation reduction" |
|---|
| 148 | empty(): List[\E\] = emptyList[\E\]() |
|---|
| 149 | join(a:List[\E\], b:List[\E\]): List[\E\] = a || b |
|---|
| 150 | end |
|---|
| 151 | |
|---|
| 152 | (** The same for reverse concatenation *) |
|---|
| 153 | private object RevConcat[\E\] extends MonoidReduction[\ List[\E\] \] |
|---|
| 154 | getter asString(): String = "List reversal reduction" |
|---|
| 155 | empty(): List[\E\] = emptyList[\E\]() |
|---|
| 156 | join(a:List[\E\], b:List[\E\]): List[\E\] = b || a |
|---|
| 157 | end |
|---|
| 158 | |
|---|
| 159 | (** A reduction object for concatenating specifically PureLists. *) |
|---|
| 160 | private object PLConcat[\E\] extends MonoidReduction[\ PureList[\E\] \] |
|---|
| 161 | getter asString(): String = "PureList concatenation reduction" |
|---|
| 162 | empty(): PureList[\E\] = D0[\E\] |
|---|
| 163 | join(a:PureList[\E\], b:PureList[\E\]): PureList[\E\] = a || b |
|---|
| 164 | end |
|---|
| 165 | |
|---|
| 166 | (* We must wrap the FingerTree, since we need to also wrap the elements |
|---|
| 167 | in order to compute the nested monoidal computation (here the size of |
|---|
| 168 | each sublist) systematically. *) |
|---|
| 169 | value object PureList[\E\]( it: FingerTree[\E\] ) |
|---|
| 170 | extends { List[\E\] } |
|---|
| 171 | getter size(): ZZ32 = |self| |
|---|
| 172 | getter isEmpty(): Boolean = it.isEmpty |
|---|
| 173 | getter left():Maybe[\E\] = left1(it) |
|---|
| 174 | getter right():Maybe[\E\] = right1(it) |
|---|
| 175 | getter extractLeft(): Maybe[\(E,PureList[\E\])\] = extractLeft1(it) |
|---|
| 176 | getter extractRight(): Maybe[\(PureList[\E\],E)\] = extractRight1(it) |
|---|
| 177 | getter indexValuePairs(): Generator[\(ZZ32,E)\] = |
|---|
| 178 | IndexValuePairs[\E\](it) |
|---|
| 179 | getter reverse(): PureList[\E\] = PureList[\E\](it.revMap(identity[\E\])) |
|---|
| 180 | opr |self| : ZZ32 = leafSize(it) |
|---|
| 181 | generate[\R\](r: Reduction[\R\], body: E->R): R = |
|---|
| 182 | it.generate[\R\](r,body) |
|---|
| 183 | seq(self): SequentialGenerator[\E\] = SeqListGenerator[\E\](it) |
|---|
| 184 | opr ||(self, f:List[\E\]): List[\E\] = |
|---|
| 185 | self || f.generate[\PureList[\E\]\](PLConcat[\E\],singleton[\E\]) |
|---|
| 186 | opr ||(self, f:PureList[\E\]): PureList[\E\] = |
|---|
| 187 | PureList[\E\](it.append(f.contents())) |
|---|
| 188 | addLeft(e:E):PureList[\E\] = |
|---|
| 189 | PureList[\E\](it.addLeft(e)) |
|---|
| 190 | addRight(e:E):PureList[\E\] = |
|---|
| 191 | PureList[\E\](it.addRight(e)) |
|---|
| 192 | take(n:ZZ32): PureList[\E\] = |
|---|
| 193 | if n <= 0 then |
|---|
| 194 | emptyList[\E\]() |
|---|
| 195 | else |
|---|
| 196 | PureList[\E\](it.take(n)) |
|---|
| 197 | end |
|---|
| 198 | drop(n:ZZ32): PureList[\E\] = |
|---|
| 199 | if n >= |self| then |
|---|
| 200 | emptyList[\E\]() |
|---|
| 201 | else |
|---|
| 202 | PureList[\E\](it.drop(n)) |
|---|
| 203 | end |
|---|
| 204 | opr [n:ZZ32]: E = |
|---|
| 205 | if n < 0 then |
|---|
| 206 | fail("PureList[" n "] index negative") |
|---|
| 207 | elif n >= |self| then |
|---|
| 208 | fail("PureList[" n "] of size " |self| " index too large") |
|---|
| 209 | else |
|---|
| 210 | (_,res) = it.index(n) |
|---|
| 211 | res |
|---|
| 212 | end |
|---|
| 213 | split(n:ZZ32): (PureList[\E\], PureList[\E\]) = |
|---|
| 214 | if n <= 0 then |
|---|
| 215 | (emptyList[\E\](),self) |
|---|
| 216 | elif n >= |self| then |
|---|
| 217 | (self,emptyList[\E\]()) |
|---|
| 218 | else |
|---|
| 219 | (l,r) = it.split(n) |
|---|
| 220 | (PureList[\E\](l),PureList[\E\](r)) |
|---|
| 221 | end |
|---|
| 222 | split(): (PureList[\E\], PureList[\E\]) = do |
|---|
| 223 | (l,r) = it.split() |
|---|
| 224 | (PureList[\E\](l),PureList[\E\](r)) |
|---|
| 225 | end |
|---|
| 226 | private contents():FingerTree[\E\] = it |
|---|
| 227 | private left1(itt: D0[\E\]): Nothing[\E\] = Nothing[\E\] |
|---|
| 228 | private left1(itt: NonEmptyFingerTree[\E\]): Just[\E\] = |
|---|
| 229 | Just[\E\](itt.left) |
|---|
| 230 | private right1(itt: D0[\E\]): Nothing[\E\] = Nothing[\E\] |
|---|
| 231 | private right1(itt: NonEmptyFingerTree[\E\]): Just[\E\] = |
|---|
| 232 | Just[\E\](itt.right) |
|---|
| 233 | private extractLeft1(itt: D0[\E\]): Nothing[\(E,PureList[\E\])\] = |
|---|
| 234 | Nothing[\(E,PureList[\E\])\] |
|---|
| 235 | private extractLeft1(itt: NonEmptyFingerTree[\E\]): |
|---|
| 236 | Just[\(E,PureList[\E\])\] = do |
|---|
| 237 | (h,t) = it.extractLeft |
|---|
| 238 | Just[\(E,PureList[\E\])\](h,PureList[\E\](t)) |
|---|
| 239 | end |
|---|
| 240 | private extractRight1(itt: D0[\E\]): Nothing[\(E,PureList[\E\])\] = |
|---|
| 241 | Nothing[\(E,PureList[\E\])\] |
|---|
| 242 | private extractRight1(itt: NonEmptyFingerTree[\E\]): |
|---|
| 243 | Just[\(E,PureList[\E\])\] = do |
|---|
| 244 | (i,l) = it.extractRight |
|---|
| 245 | Just[\(PureList[\E\],E)\](PureList[\E\](i),l) |
|---|
| 246 | end |
|---|
| 247 | end |
|---|
| 248 | |
|---|
| 249 | private value object SeqListGenerator[\E\]( it: FingerTree[\E\] ) |
|---|
| 250 | extends { SequentialGenerator[\E\] } |
|---|
| 251 | getter size(): ZZ32 = |self| |
|---|
| 252 | opr |self| : ZZ32 = leafSize(it) |
|---|
| 253 | generate[\R\](r: Reduction[\R\], body: E->R): R = |
|---|
| 254 | it.seqgen[\R\](r,fn (x: E): R => body(x)) |
|---|
| 255 | end |
|---|
| 256 | |
|---|
| 257 | emptyList[\E\](): List[\E\] = PureList[\E\](D0[\E\]) |
|---|
| 258 | singleton[\E\](e:E): List[\E\] = |
|---|
| 259 | PureList[\E\](D1[\E\](e)) |
|---|
| 260 | |
|---|
| 261 | (* Everything except tree innards must be a datum, and thus has size |
|---|
| 262 | 1. This works because the tree innards can never be part of a |
|---|
| 263 | nested tree unless there is an intervening PureList. Data |
|---|
| 264 | abstraction has its advantages! *) |
|---|
| 265 | private leafSize(a:Any):ZZ32 = 1 |
|---|
| 266 | |
|---|
| 267 | private trait Sized |
|---|
| 268 | leafSize(self):ZZ32 |
|---|
| 269 | end |
|---|
| 270 | |
|---|
| 271 | private trait FTStructure[\E\] extends Sized |
|---|
| 272 | comprises { FingerTree[\E\], D04[\E\] } |
|---|
| 273 | generate[\R\](r: Reduction[\R\], body: E->R): R |
|---|
| 274 | seqgen[\R\](r: Reduction[\R\], body: E->R): R |
|---|
| 275 | ivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R |
|---|
| 276 | sivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R |
|---|
| 277 | split():(FTStructure[\E\],FTStructure[\E\]) |
|---|
| 278 | revMap(f:E -> E):FTStructure[\E\] |
|---|
| 279 | end |
|---|
| 280 | |
|---|
| 281 | private object IndexValuePairs[\E\](it: FingerTree[\E\]) extends Generator[\(ZZ32,E)\] |
|---|
| 282 | getter size(): ZZ32 = |it| |
|---|
| 283 | opr |self| : ZZ32 = |it| |
|---|
| 284 | generate[\R\](r: Reduction[\R\], body: (ZZ32,E)->R): R = |
|---|
| 285 | it.ivgen[\R\](0,r,body) |
|---|
| 286 | seq(self): SequentialGenerator[\E\] = SequentialIndexValuePairs[\E\](it) |
|---|
| 287 | end |
|---|
| 288 | |
|---|
| 289 | private object SequentialIndexValuePairs[\E\](it: FingerTree[\E\]) |
|---|
| 290 | extends SequentialGenerator[\(ZZ32,E)\] |
|---|
| 291 | getter size(): ZZ32 = |it| |
|---|
| 292 | opr |self| : ZZ32 = |it| |
|---|
| 293 | generate[\R\](r: Reduction[\R\], body: E->R): R = it.sivgen[\R\](0,r,body) |
|---|
| 294 | end |
|---|
| 295 | |
|---|
| 296 | private trait FingerTree[\E\] extends FTStructure[\E\] |
|---|
| 297 | comprises { D01[\E\], NonEmptyFingerTree[\E\] } |
|---|
| 298 | append(f:D01[\E\]) : FingerTree[\E\] = addRightD(f) |
|---|
| 299 | append(f:Deep[\E\]) : FingerTree[\E\] |
|---|
| 300 | addLeftD(e:D0[\E\]) : FingerTree[\E\] = self |
|---|
| 301 | addLeftD(e:D14[\E\]) : FingerTree[\E\] |
|---|
| 302 | addLeft(e:E):FingerTree[\E\] |
|---|
| 303 | addRightD(e:D0[\E\]) : FingerTree[\E\] = self |
|---|
| 304 | addRightD(e:D14[\E\]) : FingerTree[\E\] |
|---|
| 305 | addRight(e:E):FingerTree[\E\] |
|---|
| 306 | append3(e:D04[\E\], f:D01[\E\]):FingerTree[\E\] = addRightD(e).addRightD(f) |
|---|
| 307 | append3(e:D04[\E\], f:Deep[\E\]):FingerTree[\E\] |
|---|
| 308 | take(n:ZZ32): FingerTree[\E\] |
|---|
| 309 | drop(n:ZZ32): FingerTree[\E\] |
|---|
| 310 | index(n:ZZ32): (ZZ32, E) |
|---|
| 311 | split(n:ZZ32): (FingerTree[\E\], FingerTree[\E\]) |
|---|
| 312 | split(): (FingerTree[\E\], FingerTree[\E\]) |
|---|
| 313 | end |
|---|
| 314 | |
|---|
| 315 | private trait NonEmptyFingerTree[\E\] extends FingerTree[\E\] |
|---|
| 316 | comprises { D1[\E\], Deep[\E\] } |
|---|
| 317 | getter isEmpty(): Boolean = false |
|---|
| 318 | getter left():E |
|---|
| 319 | getter right():E |
|---|
| 320 | getter extractLeft():(E,FingerTree[\E\]) |
|---|
| 321 | getter extractRight():(FingerTree[\E\],E) |
|---|
| 322 | split(): (NonEmptyFingerTree[\E\], FingerTree[\E\]) |
|---|
| 323 | split3(n:ZZ32): (FingerTree[\E\], E, FingerTree[\E\]) |
|---|
| 324 | end |
|---|
| 325 | |
|---|
| 326 | (* The type of all digits, from 0 to 4. |
|---|
| 327 | We populate the sets of digits of particular sizes. The ones which |
|---|
| 328 | matter most are D14 (fringes of a Deep), D01 (shallow FingerTree), and |
|---|
| 329 | D23 (nodes of the middle of a Deep). *) |
|---|
| 330 | private trait D04[\E\] extends FTStructure[\E\] |
|---|
| 331 | comprises { D03[\E\], D14[\E\] } |
|---|
| 332 | toFinger():FingerTree[\E\] |
|---|
| 333 | split(): (D02[\E\], D02[\E\]) |
|---|
| 334 | index(n:ZZ32): (ZZ32, E) |
|---|
| 335 | end |
|---|
| 336 | |
|---|
| 337 | private trait D03[\E\] extends D04[\E\] |
|---|
| 338 | comprises { D02[\E\], D13[\E\] } |
|---|
| 339 | cons(e:E) : D14[\E\] |
|---|
| 340 | snoc(e:E) : D14[\E\] |
|---|
| 341 | end |
|---|
| 342 | |
|---|
| 343 | private trait D14[\E\] extends D04[\E\] |
|---|
| 344 | comprises { D13[\E\], D24[\E\] } |
|---|
| 345 | getter isEmpty(): Boolean = false |
|---|
| 346 | getter uncons() : (E,D03[\E\]) |
|---|
| 347 | getter unsnoc() : (D03[\E\],E) |
|---|
| 348 | getter car() : E |
|---|
| 349 | getter rac() : E |
|---|
| 350 | nodes3(x:D04[\E\],y:D14[\E\]):D14[\D23[\E\]\] |
|---|
| 351 | nodes2(x:D14[\E\]):D13[\D23[\E\]\] |
|---|
| 352 | take(n:ZZ32): D14[\E\] |
|---|
| 353 | drop(n:ZZ32): D14[\E\] |
|---|
| 354 | split3(n:ZZ32): (D03[\E\], E, D03[\E\]) |
|---|
| 355 | end |
|---|
| 356 | |
|---|
| 357 | private trait D02[\E\] extends D03[\E\] |
|---|
| 358 | comprises { D01[\E\],D12[\E\] } |
|---|
| 359 | cons(e:E) : D13[\E\] |
|---|
| 360 | snoc(e:E) : D13[\E\] |
|---|
| 361 | end |
|---|
| 362 | |
|---|
| 363 | private trait D13[\E\] extends { D03[\E\], D14[\E\] } |
|---|
| 364 | comprises { D12[\E\], D23[\E\] } |
|---|
| 365 | getter uncons() : (E,D02[\E\]) |
|---|
| 366 | getter unsnoc() : (D02[\E\],E) |
|---|
| 367 | cons(e:E) : D24[\E\] |
|---|
| 368 | snoc(e:E) : D24[\E\] |
|---|
| 369 | nodes3(x:D04[\E\],y:D14[\E\]):D14[\D23[\E\]\] |
|---|
| 370 | nodes2(x:D14[\E\]):D13[\D23[\E\]\] |
|---|
| 371 | end |
|---|
| 372 | |
|---|
| 373 | private trait D24[\E\] extends D14[\E\] |
|---|
| 374 | getter uncons() : (E,D13[\E\]) |
|---|
| 375 | getter unsnoc() : (D13[\E\],E) |
|---|
| 376 | nodes3(x:D04[\E\],y:D14[\E\]):D14[\D23[\E\]\] |
|---|
| 377 | nodes2(x:D14[\E\]):D13[\D23[\E\]\] |
|---|
| 378 | nodes1():D12[\D23[\E\]\] |
|---|
| 379 | end |
|---|
| 380 | |
|---|
| 381 | private trait D01[\E\] |
|---|
| 382 | extends { D02[\E\], FingerTree[\E\] } |
|---|
| 383 | comprises { D0[\E\], D1[\E\] } |
|---|
| 384 | cons(e:E) : D12[\E\] |
|---|
| 385 | snoc(e:E) : D12[\E\] |
|---|
| 386 | append(f:Deep[\E\]) : FingerTree[\E\] = f.addLeftD(self) |
|---|
| 387 | toFinger():FingerTree[\E\] = self |
|---|
| 388 | end |
|---|
| 389 | |
|---|
| 390 | private trait D12[\E\] extends { D02[\E\], D13[\E\] } |
|---|
| 391 | comprises { D1[\E\], D2[\E\] } |
|---|
| 392 | getter uncons() : (E,D01[\E\]) |
|---|
| 393 | getter unsnoc() : (D01[\E\],E) |
|---|
| 394 | cons(e:E) : D34[\E\] |
|---|
| 395 | snoc(e:E) : D34[\E\] |
|---|
| 396 | nodes3(x:D04[\E\],y:D14[\E\]):D14[\D23[\E\]\] |
|---|
| 397 | nodes2(x:D14[\E\]):D12[\D23[\E\]\] |
|---|
| 398 | end |
|---|
| 399 | |
|---|
| 400 | private trait D23[\E\] extends { D13[\E\], D24[\E\] } |
|---|
| 401 | comprises { D2[\E\], D3[\E\] } |
|---|
| 402 | getter uncons() : (E,D12[\E\]) |
|---|
| 403 | getter unsnoc() : (D12[\E\],E) |
|---|
| 404 | cons(e:E) : D34[\E\] |
|---|
| 405 | snoc(e:E) : D34[\E\] |
|---|
| 406 | nodes3(x:D04[\E\],y:D14[\E\]):D14[\D23[\E\]\] |
|---|
| 407 | nodes2(x:D14[\E\]):D13[\D23[\E\]\] |
|---|
| 408 | end |
|---|
| 409 | |
|---|
| 410 | private trait D34[\E\] extends D24[\E\] |
|---|
| 411 | comprises { D3[\E\], D4[\E\] } |
|---|
| 412 | getter uncons() : (E,D23[\E\]) |
|---|
| 413 | getter unsnoc() : (D23[\E\],E) |
|---|
| 414 | nodes3(x:D04[\E\],y:D14[\E\]):D24[\D23[\E\]\] |
|---|
| 415 | nodes2(x:D14[\E\]):D23[\D23[\E\]\] |
|---|
| 416 | end |
|---|
| 417 | |
|---|
| 418 | private object D0[\E\] extends { D01[\E\] } |
|---|
| 419 | getter isEmpty():Boolean = true |
|---|
| 420 | getter asString() = "#" |
|---|
| 421 | generate[\R\](r: Reduction[\R\], body: E->R): R = r.empty() |
|---|
| 422 | seqgen[\R\](r: Reduction[\R\], body: E->R): R = r.empty() |
|---|
| 423 | ivgen[\R\](_: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = r.empty() |
|---|
| 424 | sivgen[\R\](_: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = r.empty() |
|---|
| 425 | cons(e:E):D1[\E\] = D1[\E\](e) |
|---|
| 426 | snoc(e:E):D1[\E\] = D1[\E\](e) |
|---|
| 427 | append(f:Deep[\E\]):Deep[\E\] = f |
|---|
| 428 | addLeft(e:E):FingerTree[\E\] = cons(e) |
|---|
| 429 | addLeftD(e:D14[\E\]) : FingerTree[\E\] = e.toFinger() |
|---|
| 430 | addRight(e:E):FingerTree[\E\] = snoc(e) |
|---|
| 431 | addRightD(e:D14[\E\]): FingerTree[\E\] = e.toFinger() |
|---|
| 432 | append3(e:D04[\E\], f:Deep[\E\]):FingerTree[\E\] = f.addLeftD(e) |
|---|
| 433 | leafSize(self):ZZ32 = 0 |
|---|
| 434 | take(_:ZZ32): D0[\E\] = self |
|---|
| 435 | drop(_:ZZ32): D0[\E\] = self |
|---|
| 436 | index(_:ZZ32): (ZZ32, E) = fail("D0[] should never be called.") |
|---|
| 437 | split(_:ZZ32): (D0[\E\],D0[\E\]) = split() |
|---|
| 438 | split(): (D0[\E\],D0[\E\]) = (self,self) |
|---|
| 439 | revMap(f:E->E): D0[\E\] = self |
|---|
| 440 | end |
|---|
| 441 | |
|---|
| 442 | private object D1[\E\](a:E) |
|---|
| 443 | extends { D01[\E\], D12[\E\], NonEmptyFingerTree[\E\] } |
|---|
| 444 | getter left():Just[\E\] = a |
|---|
| 445 | getter right():Just[\E\] = a |
|---|
| 446 | getter extractLeft():(E,FingerTree[\E\]) = self.uncons |
|---|
| 447 | getter extractRight():Just[\(E,FingerTree[\E\])\] = self.unsnoc |
|---|
| 448 | getter uncons():(E,D0[\E\]) = (a,D0[\E\]) |
|---|
| 449 | getter unsnoc():(D0[\E\],E) = (D0[\E\],a) |
|---|
| 450 | getter car() = a |
|---|
| 451 | getter rac() = a |
|---|
| 452 | getter asString()= "{" || a || "}" |
|---|
| 453 | leafSize(self):ZZ32 = leafSize(a) |
|---|
| 454 | generate[\R\](r: Reduction[\R\], body: E->R): R = body(a) |
|---|
| 455 | seqgen[\R\](r: Reduction[\R\], body: E->R): R = body(a) |
|---|
| 456 | ivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = |
|---|
| 457 | body(leftIndex, a) |
|---|
| 458 | sivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = |
|---|
| 459 | body(leftIndex, a) |
|---|
| 460 | cons(e:E):D2[\E\] = D2[\E\](e,a) |
|---|
| 461 | snoc(e:E):D2[\E\] = D2[\E\](a,e) |
|---|
| 462 | append(f:FingerTree[\E\]) = f.addLeftD(self) |
|---|
| 463 | addLeft(e:E):FingerTree[\E\] = addLeftD(D1[\E\](e)) |
|---|
| 464 | addLeftD(e:D14[\E\]) = Deep[\E\](e,D0[\D23[\E\]\],self) |
|---|
| 465 | addRight(e:E):FingerTree[\E\] = addRightD(D1[\E\](e)) |
|---|
| 466 | addRightD(e:D14[\E\]) = Deep[\E\](self,D0[\D23[\E\]\],e) |
|---|
| 467 | append3(e:D04[\E\],f:Deep[\E\]):FingerTree[\E\] = f.addLeftD(e).addLeftD(self) |
|---|
| 468 | nodes3(x:D04[\E\],y:D14[\E\]):D14[\D23[\E\]\] = |
|---|
| 469 | fail("Should never be called, shortcoming of comprises handling.") |
|---|
| 470 | nodes3(x:D4[\E\],y:D14[\E\]):D23[\D23[\E\]\] = |
|---|
| 471 | D2[\E\](x.c,x.d).nodes2(y).cons(D3[\E\](a,x.a,x.b)) |
|---|
| 472 | nodes3(x:D03[\E\],y:D14[\E\]):D12[\D23[\E\]\] = |
|---|
| 473 | x.cons(a).nodes2(y) |
|---|
| 474 | nodes2(x:D14[\E\]):D12[\D23[\E\]\] = |
|---|
| 475 | fail("Should never be called, shortcoming of comprises handling.") |
|---|
| 476 | nodes2(x:D4[\E\]):D2[\D23[\E\]\] = |
|---|
| 477 | D2[\D23[\E\]\](D3[\E\](a,x.a,x.b),D2[\E\](x.c,x.d)) |
|---|
| 478 | nodes2(x:D13[\E\]):D12[\D23[\E\]\] = x.cons(a).nodes1() |
|---|
| 479 | take(n:ZZ32): D1[\E\] = if n<=0 then fail("D1.take <= 0") else self end |
|---|
| 480 | drop(n:ZZ32): D1[\E\] = |
|---|
| 481 | if n < leafSize(a) then |
|---|
| 482 | self |
|---|
| 483 | else |
|---|
| 484 | fail("D1.drop(" n ") >= leafSize()") |
|---|
| 485 | end |
|---|
| 486 | split(): (D1[\E\],D0[\E\]) = (self,D0[\E\]) |
|---|
| 487 | split(n:ZZ32): (D1[\E\],D0[\E\]) = if n<=0 then fail("D1.split <= 0") |
|---|
| 488 | else split() end |
|---|
| 489 | index(n:ZZ32): (ZZ32, E) = (n,a) |
|---|
| 490 | split3(n:ZZ32): (D0[\E\], E, D0[\E\]) = split3() |
|---|
| 491 | split3(): (D0[\E\], E, D0[\E\]) = do |
|---|
| 492 | e = D0[\E\] |
|---|
| 493 | (e,a,e) |
|---|
| 494 | end |
|---|
| 495 | revMap(f:E->E): D1[\E\] = D1[\E\](f(a)) |
|---|
| 496 | end |
|---|
| 497 | |
|---|
| 498 | private object D2[\E\](a:E, b:E) extends { D12[\E\], D23[\E\] } |
|---|
| 499 | ls = leafSize(a) + leafSize(b) |
|---|
| 500 | getter car() = a |
|---|
| 501 | getter rac() = b |
|---|
| 502 | getter uncons():(E,D1[\E\]) = (a,D1[\E\](b)) |
|---|
| 503 | getter unsnoc():(D1[\E\],E) = (D1[\E\](a),b) |
|---|
| 504 | getter asString()= "(" || a || ", " || b || ")" |
|---|
| 505 | leafSize(self):ZZ32 = ls |
|---|
| 506 | generate[\R\](r: Reduction[\R\], body: E->R): R = r.join(body(a),body(b)) |
|---|
| 507 | seqgen[\R\](r: Reduction[\R\], body: E->R): R = do |
|---|
| 508 | ab = body(a) |
|---|
| 509 | bb = body(b) |
|---|
| 510 | r.join(ab,bb) |
|---|
| 511 | end |
|---|
| 512 | ivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = |
|---|
| 513 | r.join(body(leftIndex, a), body(leftIndex+leafSize(a), b)) |
|---|
| 514 | sivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = do |
|---|
| 515 | ab = body(leftIndex,a) |
|---|
| 516 | bb = body(leftIndex + leafSize(a), b) |
|---|
| 517 | r.join(ab,bb) |
|---|
| 518 | end |
|---|
| 519 | cons(e:E):D3[\E\] = D3[\E\](e,a,b) |
|---|
| 520 | snoc(e:E):D3[\E\] = D3[\E\](a,b,e) |
|---|
| 521 | nodes3(x:D04[\E\],y:D14[\E\]):D14[\D23[\E\]\] = |
|---|
| 522 | fail("Should never be called, shortcoming of comprises handling.") |
|---|
| 523 | nodes3(x:D0[\E\],y:D14[\E\]):D14[\D23[\E\]\] = |
|---|
| 524 | nodes2(y) |
|---|
| 525 | nodes3(x:D1[\E\],y:D14[\E\]):D14[\D23[\E\]\] = |
|---|
| 526 | snoc(x.car).nodes2(y) |
|---|
| 527 | nodes3(x:D24[\E\],y:D14[\E\]):D14[\D23[\E\]\] = do |
|---|
| 528 | (xh, xt) = x.uncons |
|---|
| 529 | xt.nodes2(y).cons(D3[\E\](a,b,xh)) |
|---|
| 530 | end |
|---|
| 531 | nodes2(x:D14[\E\]):D12[\D23[\E\]\] = |
|---|
| 532 | fail("Should never be called, shortcoming of comprises handling.") |
|---|
| 533 | nodes2(x:D1[\E\]):D1[\D23[\E\]\] = |
|---|
| 534 | D1[\D23[\E\]\](self.snoc(x.car)) |
|---|
| 535 | nodes2(x:D2[\E\]):D2[\D23[\E\]\] = |
|---|
| 536 | D2[\D23[\E\]\](self,x) |
|---|
| 537 | nodes2(x:D34[\E\]):D12[\D23[\E\]\] = do |
|---|
| 538 | (xh, xt) = x.uncons |
|---|
| 539 | xt.nodes1().cons(D3[\E\](a,b,xh)) |
|---|
| 540 | end |
|---|
| 541 | nodes1():D1[\D23[\E\]\] = D1[\D23[\E\]\](self) |
|---|
| 542 | toFinger()=Deep[\E\](D1[\E\](a),D0[\D23[\E\]\],D1[\E\](b)) |
|---|
| 543 | take(n:ZZ32): D12[\E\] = |
|---|
| 544 | if n <= 0 then |
|---|
| 545 | fail("D2.take <= 0") |
|---|
| 546 | elif n <= leafSize(a) then |
|---|
| 547 | D1[\E\](a) |
|---|
| 548 | else |
|---|
| 549 | self |
|---|
| 550 | end |
|---|
| 551 | drop(n:ZZ32): D12[\E\] = |
|---|
| 552 | if n < leafSize(a) then |
|---|
| 553 | self |
|---|
| 554 | else |
|---|
| 555 | na = n - leafSize(a) |
|---|
| 556 | if na < leafSize(b) then |
|---|
| 557 | D1[\E\](b) |
|---|
| 558 | else |
|---|
| 559 | fail("D2.drop(" n ") >= leafSize()") |
|---|
| 560 | end |
|---|
| 561 | end |
|---|
| 562 | index(n:ZZ32): (ZZ32,E) = |
|---|
| 563 | if n < 0 then |
|---|
| 564 | fail("D2[" n "] subscript < 0") |
|---|
| 565 | elif n < leafSize(a) then |
|---|
| 566 | (n,a) |
|---|
| 567 | else |
|---|
| 568 | (n-leafSize(a),b) |
|---|
| 569 | end |
|---|
| 570 | split3(n:ZZ32): (D01[\E\], E, D01[\E\]) = |
|---|
| 571 | if n <= 0 then |
|---|
| 572 | fail("D2.split3 <= 0") |
|---|
| 573 | elif n <= leafSize(a) then |
|---|
| 574 | (D0[\E\], a, D1[\E\](b)) |
|---|
| 575 | else |
|---|
| 576 | (D1[\E\](a), b, D0[\E\]) |
|---|
| 577 | end |
|---|
| 578 | split():(D1[\E\],D1[\E\]) = (D1[\E\](a),D1[\E\](b)) |
|---|
| 579 | revMap(f:E->E): D2[\E\] = D2[\E\](f(b),f(a)) |
|---|
| 580 | end |
|---|
| 581 | |
|---|
| 582 | private object D3[\E\](a:E, b:E, c:E) extends { D23[\E\], D34[\E\] } |
|---|
| 583 | ls = leafSize(a) + leafSize(b) + leafSize(c) |
|---|
| 584 | getter car() = a |
|---|
| 585 | getter rac() = c |
|---|
| 586 | getter uncons():(E,D2[\E\]) = (a,D2[\E\](b,c)) |
|---|
| 587 | getter unsnoc():(D2[\E\],E) = (D2[\E\](a,b),c) |
|---|
| 588 | getter asString() = "(" || a || ", " || b || ", " || c || ")" |
|---|
| 589 | leafSize(self):ZZ32 = ls |
|---|
| 590 | generate[\R\](r: Reduction[\R\], body: E->R): R = |
|---|
| 591 | r.join(body(a),r.join(body(b),body(c))) |
|---|
| 592 | seqgen[\R\](r: Reduction[\R\], body: E->R): R = do |
|---|
| 593 | ab = body(a) |
|---|
| 594 | bb = body(b) |
|---|
| 595 | abb = r.join(ab,bb) |
|---|
| 596 | cb = body(c) |
|---|
| 597 | r.join(abb,cb) |
|---|
| 598 | end |
|---|
| 599 | ivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = do |
|---|
| 600 | lib = leftIndex + leafSize(a) |
|---|
| 601 | lic = lib + leafSize(b) |
|---|
| 602 | r.join(r.join(body(leftIndex,a),body(lib,b)),body(lic,c)) |
|---|
| 603 | end |
|---|
| 604 | sivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = do |
|---|
| 605 | ab = body(leftIndex,a) |
|---|
| 606 | lib = leftIndex + leafSize(a) |
|---|
| 607 | bb = body(lib,b) |
|---|
| 608 | abb = r.join(ab,bb) |
|---|
| 609 | lic = lib + leafSize(b) |
|---|
| 610 | cb = body(lic,c) |
|---|
| 611 | r.join(abb,cb) |
|---|
| 612 | end |
|---|
| 613 | cons(e:E):D4[\E\] = D4[\E\](e,a,b,c) |
|---|
| 614 | snoc(e:E):D4[\E\] = D4[\E\](a,b,c,e) |
|---|
| 615 | nodes3(x:D04[\E\],y:D14[\E\]):D24[\D23[\E\]\] = |
|---|
| 616 | x.nodes2(y).cons(self) |
|---|
| 617 | nodes2(x:D14[\E\]):D13[\D23[\E\]\] = |
|---|
| 618 | fail("Should never be called, shortcoming of comprises handling.") |
|---|
| 619 | nodes2(x:D1[\E\]):D23[\D23[\E\]\] = |
|---|
| 620 | D2[\D23[\E\]\](D2[\E\](a,b),D2[\E\](c,x.car)) |
|---|
| 621 | nodes2(x:D24[\E\]):D23[\D23[\E\]\] = |
|---|
| 622 | x.nodes1().cons(self) |
|---|
| 623 | nodes1():D1[\D23[\E\]\] = D1[\D23[\E\]\](self) |
|---|
| 624 | toFinger()=Deep[\E\](D2[\E\](a,b),D0[\D23[\E\]\],D1[\E\](c)) |
|---|
| 625 | take(n:ZZ32): D13[\E\] = |
|---|
| 626 | if n <= 0 then |
|---|
| 627 | fail("D3.take <= 0") |
|---|
| 628 | elif n <= leafSize(a) then |
|---|
| 629 | D1[\E\](a) |
|---|
| 630 | else |
|---|
| 631 | na = n - leafSize(a) |
|---|
| 632 | if na <= leafSize(b) then |
|---|
| 633 | D2[\E\](a,b) |
|---|
| 634 | else |
|---|
| 635 | self |
|---|
| 636 | end |
|---|
| 637 | end |
|---|
| 638 | drop(n:ZZ32): D13[\E\] = |
|---|
| 639 | if n < leafSize(a) then |
|---|
| 640 | self |
|---|
| 641 | else |
|---|
| 642 | na = n - leafSize(a) |
|---|
| 643 | if na < leafSize(b) then |
|---|
| 644 | D2[\E\](b,c) |
|---|
| 645 | else |
|---|
| 646 | nb = na - leafSize(b) |
|---|
| 647 | if nb < leafSize(c) then |
|---|
| 648 | D1[\E\](c) |
|---|
| 649 | else |
|---|
| 650 | fail("D2.drop(" n ") >= leafSize()") |
|---|
| 651 | end |
|---|
| 652 | end |
|---|
| 653 | end |
|---|
| 654 | index(n:ZZ32): (ZZ32,E) = |
|---|
| 655 | if n < 0 then |
|---|
| 656 | fail("D3[" n "] subscript < 0") |
|---|
| 657 | elif n < leafSize(a) then |
|---|
| 658 | (n,a) |
|---|
| 659 | else |
|---|
| 660 | na = n - leafSize(a) |
|---|
| 661 | if na < leafSize(b) then |
|---|
| 662 | (na,b) |
|---|
| 663 | else |
|---|
| 664 | (na-leafSize(b), c) |
|---|
| 665 | end |
|---|
| 666 | end |
|---|
| 667 | split3(n:ZZ32): (D02[\E\], E, D02[\E\]) = |
|---|
| 668 | if n <= 0 then |
|---|
| 669 | fail("D3.split3 <= 0") |
|---|
| 670 | elif n <= leafSize(a) then |
|---|
| 671 | (D0[\E\], a, D2[\E\](b,c)) |
|---|
| 672 | else |
|---|
| 673 | na = n - leafSize(a) |
|---|
| 674 | if na <= leafSize(b) then |
|---|
| 675 | (D1[\E\](a), b, D1[\E\](c)) |
|---|
| 676 | else |
|---|
| 677 | (D2[\E\](a,b), c, D0[\E\]) |
|---|
| 678 | end |
|---|
| 679 | end |
|---|
| 680 | split():(D2[\E\],D1[\E\]) = (D2[\E\](a,b),D1[\E\](c)) |
|---|
| 681 | revMap(f:E->E): D3[\E\] = D3[\E\](f(c),f(b),f(a)) |
|---|
| 682 | end |
|---|
| 683 | |
|---|
| 684 | private object D4[\E\](a:E, b:E, c:E, d:E) extends { D34[\E\] } |
|---|
| 685 | ls = leafSize(a) + leafSize(b) + leafSize(c) + leafSize(d) |
|---|
| 686 | getter car() = a |
|---|
| 687 | getter rac() = d |
|---|
| 688 | getter uncons():(E,D3[\E\]) = (a,D3[\E\](b,c,d)) |
|---|
| 689 | getter unsnoc():(D3[\E\],E) = (D3[\E\](a,b,c),d) |
|---|
| 690 | getter asString() = "{" || a || ", " || b || ", " || c || ", " || d || "}" |
|---|
| 691 | leafSize(self):ZZ32 = ls |
|---|
| 692 | generate[\R\](r: Reduction[\R\], body: E->R): R = |
|---|
| 693 | r.join(r.join(body(a),body(b)),r.join(body(c),body(d))) |
|---|
| 694 | seqgen[\R\](r: Reduction[\R\], body: E->R): R = do |
|---|
| 695 | ab = body(a) |
|---|
| 696 | bb = body(b) |
|---|
| 697 | abb = r.join(ab,bb) |
|---|
| 698 | cb = body(c) |
|---|
| 699 | abc = r.join(abb,cb) |
|---|
| 700 | db = body(d) |
|---|
| 701 | r.join(abc,db) |
|---|
| 702 | end |
|---|
| 703 | ivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = do |
|---|
| 704 | lib = leftIndex + leafSize(a) |
|---|
| 705 | lic = lib + leafSize(b) |
|---|
| 706 | lid = lic + leafSize(c) |
|---|
| 707 | r.join(r.join(body(leftIndex,a),body(lib,b)), |
|---|
| 708 | r.join(body(lic,c),body(lid,d))) |
|---|
| 709 | end |
|---|
| 710 | sivgen[\R\](leftIndex: ZZ32, r: Reduction[\R\], body: (ZZ32,E)->R): R = do |
|---|
| 711 | ab = body(leftIndex,a) |
|---|
| 712 | lib = leftIndex + leafSize(a) |
|---|
| 713 | bb = body(lib,b) |
|---|
| 714 | abb = r.join(ab,bb) |
|---|
| 715 | lic = lib + leafSize(b) |
|---|
| 716 | cb = body(lic,c) |
|---|
| 717 | abc = r.join(abb,cb) |
|---|
| 718 | lid = lic + leafSize(c) |
|---|
| 719 | db = body(lid,d) |
|---|
| 720 | r.join(abc,db) |
|---|
| 721 | end |
|---|
| 722 | nodes3(x:D04[\E\],y:D14[\E\]):D24[\D23[\E\]\] = |
|---|
| 723 | D1[\E\](d).nodes3(x,y).cons(D3[\E\](a,b,c)) |
|---|
| 724 | nodes2(x:D14[\E\]):D23[\D23[\E\]\] = |
|---|
| 725 | D1[\E\](d).nodes2(x).cons(D3[\E\](a,b,c)) |
|---|
| 726 | nodes1():D2[\D23[\E\]\] = D2[\D23[\E\]\](D2[\E\](a,b),D2[\E\](c,d)) |
|---|
| 727 | toFinger()=Deep[\E\](D2[\E\](a,b),D0[\D23[\E\]\],D2[\E\](c,d)) |
|---|
| 728 | take(n:ZZ32): D14[\E\] = |
|---|
| 729 | if n <= 0 then |
|---|
| 730 | fail("D4.take <= 0") |
|---|
| 731 | elif n <= leafSize(a) then |
|---|
| 732 | D1[\E\](a) |
|---|
| 733 | else |
|---|
| 734 | na = n - leafSize(a) |
|---|
| 735 | if na <= leafSize(b) then |
|---|
| 736 | D2[\E\](a,b) |
|---|
| 737 | else |
|---|
| 738 | nb = na - leafSize(b) |
|---|
| 739 | if nb <= leafSize(c) then |
|---|
| 740 | D3[\E\](a,b,c) |
|---|
| 741 | else |
|---|
| 742 | self |
|---|
| 743 | end |
|---|
| 744 | end |
|---|
| 745 | end |
|---|
| 746 | drop(n:ZZ32): D14[\E\] = |
|---|
| 747 | if n < leafSize(a) then |
|---|
| 748 | self |
|---|
| 749 | else |
|---|
| 750 | na = n - leafSize(a) |
|---|
| 751 | if na < leafSize(b) then |
|---|
| 752 | D3[\E\](b,c,d) |
|---|
| 753 | else |
|---|
| 754 | nb = na - leafSize(b) |
|---|
| 755 | if nb < leafSize(c) then |
|---|
| 756 | D2[\E\](c,d) |
|---|
| 757 | else |
|---|
| 758 | nc = nb - leafSize(c) |
|---|
| 759 | if nc < leafSize(d) then |
|---|
| 760 | D1[\E\](d) |
|---|
| 761 | else |
|---|
| 762 | fail("D2.drop(" n ") >= leafSize()") |
|---|
| 763 | end |
|---|
| 764 | end |
|---|
| 765 | end |
|---|
| 766 | end |
|---|
| 767 | index(n:ZZ32): (ZZ32,E) = |
|---|
| 768 | if n < 0 then |
|---|
| 769 | fail("D3[" n "] subscript < 0") |
|---|
| 770 | elif n < leafSize(a) then |
|---|
| 771 | (n,a) |
|---|
| 772 | else |
|---|
| 773 | na = n - leafSize(a) |
|---|
| 774 | if na < leafSize(b) then |
|---|
| 775 | (na,b) |
|---|
| 776 | else |
|---|
| 777 | nb = na - leafSize(b) |
|---|
| 778 | if nb < leafSize(c) then |
|---|
| 779 | (nb,c) |
|---|
| 780 | else |
|---|
| 781 | (nb-leafSize(c), d) |
|---|
| 782 | end |
|---|
| 783 | end |
|---|
| 784 | end |
|---|
| 785 | split3(n:ZZ32): (D03[\E\], E, D03[\E\]) = |
|---|
| 786 | if n <= 0 then |
|---|
| 787 | fail("D4.split3 <= 0") |
|---|
| 788 | elif n <= leafSize(a) then |
|---|
| 789 | (D0[\E\], a, D3[\E\](b,c,d)) |
|---|
| 790 | else |
|---|
| 791 | na = n - leafSize(a) |
|---|
| 792 | if na <= leafSize(b) then |
|---|
| 793 | (D1[\E\](a), b, D2[\E\](c,d)) |
|---|
| 794 | else |
|---|
| 795 | nb = na - leafSize(b) |
|---|
| 796 | if nb <= leafSize(c) then |
|---|
| 797 | (D2[\E\](a,b), c, D1[\E\](d)) |
|---|
| 798 | else |
|---|
| 799 | (D3[\E\](a,b,c), d, D0[\E\]) |
|---|
| 800 | end |
|---|
| 801 | end |
|---|
| 802 | end |
|---|
| 803 | split():(D2[\E\],D2[\E\]) = (D2[\E\](a,b),D2[\E\](c,d)) |
|---|
| 804 | revMap(f:E->E): D4[\E\] = D4[\E\](f(d),f(c),f(b),f(a)) |
|---|
| 805 | end |
|---|
| 806 | |
|---|
| 807 | private object Deep[\E\] |
|---|
| 808 | (l:D14[\E\], m:FingerTree[\ D23[\E\] \], r:D14[\E\]) |
|---|
| 809 | extends { NonEmptyFingerTree[\E\] } |
|---|
| 810 | ls = leafSize(l)+leafSize(m)+leafSize(r) |
|---|
| 811 | getter left():Just[\E\] = l.car |
|---|
| 812 | getter right():Just[\E\] = r.rac |
|---|
| 813 | getter extractLeft():(E,FingerTree[\E\]) = extractLeft1(l,m) |
|---|
| 814 | getter extractRight():(FingerTree[\E\],E) = extractRight1(r,m) |
|---|
| 815 | getter asString() = "[" l.asString ";" m.asString ";" r.asString "]" |
|---|
| 816 | |
|---|
| 817 | leafSize(self):ZZ32 = ls |
|---|
| 818 | generate[\R\](j: Reduction[\R\], body: E->R): R = do |
|---|
| 819 | j.join( |
|---|
| 820 | j.join(l.generate[\R\](j,body), |
|---|
| 821 | m.generate[\R\](j,fn (n23:D23[\E\]):R => |
|---|
| 822 | n23.generate[\R\](j,body))), |
|---|
| 823 | r.generate[\R\](j,body)) |
|---|
| 824 | end |
|---|
| 825 | seqgen[\R\](j: Reduction[\R\], body: E->R): R = do |
|---|
| 826 | gl = l.seqgen[\R\](j,body) |
|---|
| 827 | ml = m.seqgen[\R\](j,fn (n23:D23[\E\]):R => |
|---|
| 828 | n23.seqgen[\R\](j,body)) |
|---|
| 829 | ll = j.join(gl,ml) |
|---|
| 830 | rl = r.seqgen[\R\](j,body) |
|---|
| 831 | j.join(ll,rl) |
|---|
| 832 | end |
|---|
| 833 | ivgen[\R\](li: ZZ32, j: Reduction[\R\], body: (ZZ32,E)->R): R = do |
|---|
| 834 | mi = li + leafSize(l) |
|---|
| 835 | ri = mi + leafSize(m) |
|---|
| 836 | j.join( |
|---|
| 837 | j.join(l.ivgen[\R\](li,j,body), |
|---|
| 838 | m.ivgen[\R\](mi,j,fn (li':ZZ32, n23:D23[\E\]):R => |
|---|
| 839 | n23.ivgen[\R\](li',j,body))), |
|---|
| 840 | r.ivgen[\R\](ri,j,body)) |
|---|
| 841 | end |
|---|
| 842 | sivgen[\R\](li: ZZ32, j: Reduction[\R\], body: (ZZ32,E)->R): R = do |
|---|
| 843 | gl = l.sivgen[\R\](li,j,body) |
|---|
| 844 | mi = li + leafSize(l) |
|---|
| 845 | ml = m.sivgen[\R\](mi,j,fn (li':ZZ32, n23:D23[\E\]):R => |
|---|
| 846 | n23.sivgen[\R\](li',j,body)) |
|---|
| 847 | ll = j.join(gl,ml) |
|---|
| 848 | ri = mi + leafSize(m) |
|---|
| 849 | rl = r.sivgen[\R\](ri,j,body) |
|---|
| 850 | j.join(ll,rl) |
|---|
| 851 | end |
|---|
| 852 | |
|---|
| 853 | addLeft(e:E):FingerTree[\E\] = addLeft1(e,l) |
|---|
| 854 | addLeft1(e:E,l0:D4[\E\]) = |
|---|
| 855 | Deep[\E\](D2[\E\](e,l0.a),m.addLeft(D3[\E\](l0.b,l0.c,l0.d)),r) |
|---|
| 856 | addLeft1(e:E,l0:D03[\E\]) = Deep[\E\](l0.cons(e),m,r) |
|---|
| 857 | addLeftD(e:D14[\E\]) : FingerTree[\E\] = do |
|---|
| 858 | (ef,er) = e.unsnoc |
|---|
| 859 | addLeft(er).addLeftD(ef) |
|---|
| 860 | end |
|---|
| 861 | addRight(e:E):FingerTree[\E\] = addRight1(e,r) |
|---|
| 862 | addRight1(e:E,r0:D4[\E\]) = |
|---|
| 863 | Deep[\E\](l,m.addRight(D3[\E\](r0.a,r0.b,r0.c)),D2[\E\](r0.d,e)) |
|---|
| 864 | addRight1(e:E,r0:D03[\E\]) = Deep[\E\](l,m,r.snoc(e)) |
|---|
| 865 | addRightD(e:D14[\E\]) : FingerTree[\E\] = do |
|---|
| 866 | (ef,er) = e.uncons |
|---|
| 867 | addRight(ef).addRightD(er) |
|---|
| 868 | end |
|---|
| 869 | |
|---|
| 870 | (* Helper methods for extractLeft and extractRight *) |
|---|
| 871 | extractLeft1(l0:D1[\E\], m0:D0[\D23[\E\]\]) = (l0.car,r.toFinger()) |
|---|
| 872 | extractLeft1(l0:D1[\E\], m0:NonEmptyFingerTree[\D23[\E\]\]) = do |
|---|
| 873 | (l1,m1) = m0.extractLeft |
|---|
| 874 | (l0.car,Deep[\E\](l1,m1,r)) |
|---|
| 875 | end |
|---|
| 876 | extractLeft1(l0:D24[\E\], m0:FingerTree[\D23[\E\]\]) = do |
|---|
| 877 | (f,l1) = l0.uncons |
|---|
| 878 | (f,Deep[\E\](l1,m0,r)) |
|---|
| 879 | end |
|---|
| 880 | extractRight1(r0:D1[\E\], m0:D0[\D23[\E\]\]) = (l.toFinger(),r0.rac) |
|---|
| 881 | extractRight1(r0:D1[\E\], m0:NonEmptyFingerTree[\D23[\E\]\]) = do |
|---|
| 882 | (m1,r1) = m0.extractRight |
|---|
| 883 | (Deep[\E\](l,m1,r1),r0.rac) |
|---|
| 884 | end |
|---|
| 885 | extractRight1(r0:D24[\E\], m0:FingerTree[\D23[\E\]\]) = do |
|---|
| 886 | (r1,b) = r0.unsnoc |
|---|
| 887 | (Deep[\E\](l,m0,r1),b) |
|---|
| 888 | end |
|---|
| 889 | |
|---|
| 890 | append(f:Deep[\E\]) : FingerTree[\E\] = |
|---|
| 891 | Deep[\E\](l,m.append3(r.nodes2(f.l),f.m),f.r) |
|---|
| 892 | append3(e:D04[\E\], f:Deep[\E\]):FingerTree[\E\] = |
|---|
| 893 | Deep[\E\](l,m.append3(r.nodes3(e,f.l),f.m),f.r) |
|---|
| 894 | |
|---|
| 895 | take(n:ZZ32): FingerTree[\E\] = |
|---|
| 896 | if n <= 0 then |
|---|
| 897 | fail("Deep.take " n " <= 0") |
|---|
| 898 | elif n <= leafSize(l) then |
|---|
| 899 | l.take(n).toFinger() |
|---|
| 900 | else |
|---|
| 901 | takeM(n - leafSize(l), m) |
|---|
| 902 | end |
|---|
| 903 | takeM(n:ZZ32, m0:D0[\D23[\E\]\]): FingerTree[\E\] = takeR(n) |
|---|
| 904 | takeM(n:ZZ32, m0:NonEmptyFingerTree[\D23[\E\]\]): FingerTree[\E\] = |
|---|
| 905 | if n <= leafSize(m0) then |
|---|
| 906 | (mm,mr) = m0.take(n).extractRight |
|---|
| 907 | deepR[\E\](l,mm,mr.take(n - leafSize(mm))) |
|---|
| 908 | else |
|---|
| 909 | takeR(n - leafSize(m0)) |
|---|
| 910 | end |
|---|
| 911 | takeR(n:ZZ32): FingerTree[\E\] = Deep[\E\](l,m,r.take(n)) |
|---|
| 912 | drop(n:ZZ32): NonEmptyFingerTree[\E\] = |
|---|
| 913 | if n <= 0 then |
|---|
| 914 | self |
|---|
| 915 | elif n < leafSize(l) then |
|---|
| 916 | Deep[\E\](l.drop(n),m,r) |
|---|
| 917 | else |
|---|
| 918 | dropM(n - leafSize(l), m) |
|---|
| 919 | end |
|---|
| 920 | dropM(n:ZZ32,_:D0[\D23[\E\]\]): NonEmptyFingerTree[\E\] = dropR(n) |
|---|
| 921 | dropM(n:ZZ32,m0:NonEmptyFingerTree[\D23[\E\]\]): NonEmptyFingerTree[\E\] = |
|---|
| 922 | if n < leafSize(m0) then |
|---|
| 923 | md = m0.drop(n) |
|---|
| 924 | (ml,mm) = md.extractLeft |
|---|
| 925 | deepL[\E\](ml.drop(n-(leafSize(m0)-leafSize(md))),mm,r) |
|---|
| 926 | else |
|---|
| 927 | dropR(n - leafSize(m0)) |
|---|
| 928 | end |
|---|
| 929 | dropR(n:ZZ32) = |
|---|
| 930 | if n < leafSize(r) then |
|---|
| 931 | r.drop(n).toFinger() |
|---|
| 932 | else |
|---|
| 933 | fail("Deep.drop(" n ") too large") |
|---|
| 934 | end |
|---|
| 935 | split(n:ZZ32): (FingerTree[\E\], FingerTree[\E\]) = do |
|---|
| 936 | (ll,mm,rr) = split3(n) |
|---|
| 937 | (ll.addRight(mm),rr) |
|---|
| 938 | end |
|---|
| 939 | split(): (FingerTree[\E\], FingerTree[\E\]) = do |
|---|
| 940 | (ll, rr) = m.split() |
|---|
| 941 | (deepR[\E\](l,ll,D0[\E\]), deepL[\E\](D0[\E\],rr,r)) |
|---|
| 942 | end |
|---|
| 943 | index(n:ZZ32): (ZZ32,E) = |
|---|
| 944 | if n < 0 then |
|---|
| 945 | fail("Deep[" n "]: negative index") |
|---|
| 946 | elif n < leafSize(l) then |
|---|
| 947 | l.index(n) |
|---|
| 948 | else |
|---|
| 949 | nm = n - leafSize(l) |
|---|
| 950 | if nm < leafSize(m) then |
|---|
| 951 | (nm0,mm) = m.index(nm) |
|---|
| 952 | mm.index(nm0) |
|---|
| 953 | else |
|---|
| 954 | nr = nm - leafSize(m) |
|---|
| 955 | r.index(nr) |
|---|
| 956 | end |
|---|
| 957 | end |
|---|
| 958 | split3(n:ZZ32): (FingerTree[\E\], E, FingerTree[\E\]) = |
|---|
| 959 | if n <= 0 then |
|---|
| 960 | fail("Deep.split3 n<=0 should not happen.") |
|---|
| 961 | elif n <= leafSize(l) then |
|---|
| 962 | (ll,lm,lr) = l.split3(n) |
|---|
| 963 | (ll.toFinger(), lm, deepL[\E\](lr,m,r)) |
|---|
| 964 | else |
|---|
| 965 | nm = n - leafSize(l) |
|---|
| 966 | if nm <= leafSize(m) then |
|---|
| 967 | (ml,mm,mr) = m.split3(nm) |
|---|
| 968 | ne = nm - leafSize(ml) |
|---|
| 969 | (ll,e,rr) = mm.split3(ne) |
|---|
| 970 | (deepR[\E\](l,ml,ll), e, deepL[\E\](rr,mr,r)) |
|---|
| 971 | else |
|---|
| 972 | nr = nm - leafSize(m) |
|---|
| 973 | (rl,rm,rr) = r.split3(nr) |
|---|
| 974 | (deepR[\E\](l,m,rl), rm, rr.toFinger()) |
|---|
| 975 | end |
|---|
| 976 | end |
|---|
| 977 | revMap(f: E->E): Deep[\E\] = |
|---|
| 978 | Deep[\E\](r.revMap(f), |
|---|
| 979 | m.revMap(fn (x:D23[\E\]):D23[\E\] => x.revMap(f)), |
|---|
| 980 | l.revMap(f)) |
|---|
| 981 | end |
|---|
| 982 | |
|---|
| 983 | deepL[\E\](l:D14[\E\],m:FingerTree[\D23[\E\]\],r:D14[\E\]):NonEmptyFingerTree[\E\] = |
|---|
| 984 | Deep[\E\](l,m,r) |
|---|
| 985 | deepL[\E\](_:D0[\E\],_:D0[\D23[\E\]\],r:D14[\E\]):FingerTree[\E\] = r.toFinger() |
|---|
| 986 | deepL[\E\](_:D0[\E\],m:NonEmptyFingerTree[\D23[\E\]\],r:D14[\E\]):NonEmptyFingerTree[\E\] = do |
|---|
| 987 | (ll,mm) = m.extractLeft |
|---|
| 988 | Deep[\E\](ll,mm,r) |
|---|
| 989 | end |
|---|
| 990 | |
|---|
| 991 | deepR[\E\](l:D14[\E\],m:FingerTree[\D23[\E\]\],r:D14[\E\]):NonEmptyFingerTree[\E\] = |
|---|
| 992 | Deep[\E\](l,m,r) |
|---|
| 993 | deepR[\E\](l:D14[\E\],_:D0[\D23[\E\]\],_:D0[\E\]):FingerTree[\E\] = l.toFinger() |
|---|
| 994 | deepR[\E\](l:D14[\E\],m:NonEmptyFingerTree[\D23[\E\]\],_:D0[\E\]):NonEmptyFingerTree[\E\] = do |
|---|
| 995 | (mm,rr) = m.extractRight |
|---|
| 996 | Deep[\E\](l,mm,rr) |
|---|
| 997 | end |
|---|
| 998 | |
|---|
| 999 | end |
|---|