001package components.tree; 002 003import java.util.Iterator; 004import java.util.NoSuchElementException; 005 006import components.sequence.Sequence; 007import components.sequence.Sequence3; 008 009/** 010 * {@code Tree} represented as a recursive data structure, done "bare-handed", 011 * with implementations of primary methods. 012 * 013 * @param <T> 014 * type of {@code Tree} labels 015 * @mathsubtypes <pre> 016 * TREE_REP is ( 017 * size: integer, 018 * height: integer, 019 * rootLabel: T, 020 * subtrees: string of TREE_REP 021 * ) 022 * </pre> 023 * @mathdefinitions {@code 024 * IS_LEGAL_REP ( 025 * tr: TREE_REP 026 * ): boolean is 027 * 0 <= tr.height <= tr.size and 028 * (if tr.size > 0 then 029 * [tr.size = 1 + sum of the sizes of the TREE_REP in tr.subtrees] and 030 * [tr.height = 1 + max of the heights of the TREE_REP in tr.subtrees] and 031 * [tr.rootLabel is not null] and 032 * [tr.subtrees is not null] and 033 * STRING_IS_LEGAL_REP(tr.subtrees) 034 * else 035 * [tr.rootLabel is null] and 036 * [tr.subtrees is null]) 037 * 038 * STRING_IS_LEGAL_REP ( 039 * s: string of TREE_REP 040 * ): string of tree of T satisfies 041 * if s = <> then 042 * STRING_IS_LEGAL_REP(s) = true 043 * else 044 * there exists t: TREE_REP, rest: string of TREE_REP 045 * (s = <t> * rest and 046 * [t is not null] and 047 * [t is not aliased to any of the TREE_REP in rest] and 048 * STRING_IS_LEGAL_REP(s) = IS_LEGAL_REP(t) and STRING_IS_LEGAL_REP(rest)) 049 * 050 * ABSTRACT_TREE ( 051 * tr: TREE_REP 052 * ): tree of T satisfies 053 * if IS_LEGAL_REP(tr) then 054 * (if tr.size = 0 then 055 * ABSTRACT_TREE(tr) = empty_tree 056 * else 057 * ABSTRACT_TREE(tr) = 058 * compose(tr.rootLabel, STRING_ABSTRACT_TREE(tr.subtrees))) 059 * 060 * STRING_ABSTRACT_TREE ( 061 * s: string of TREE_REP 062 * ): string of tree of T satisfies 063 * if STRING_IS_LEGAL_REP(s) then 064 * (if s = <> then 065 * STRING_ABSTRACT_TREE(s) = <> 066 * else 067 * there exists t: TREE_REP, rest: string of TREE_REP 068 * (s = <t> * rest and 069 * STRING_ABSTRACT_TREE(s) = 070 * ABSTRACT_TREE(t) * STRING_ABSTRACT_TREE(rest))) 071 * } 072 * @convention IS_LEGAL_REP($this) 073 * @correspondence this = ABSTRACT_TREE($this) 074 */ 075public class Tree1<T> extends TreeSecondary<T> { 076 077 /* 078 * Private members -------------------------------------------------------- 079 */ 080 081 /** 082 * Size of tree. 083 */ 084 private int size; 085 086 /** 087 * Height of tree. 088 */ 089 private int height; 090 091 /** 092 * Root label. 093 */ 094 095 private T rootLabel; 096 097 /** 098 * Subtrees. 099 */ 100 private Sequence<Tree<T>> subtrees; 101 102 /** 103 * Creator of initial representation. 104 */ 105 private void createNewRep() { 106 this.size = 0; 107 this.height = 0; 108 this.rootLabel = null; 109 this.subtrees = null; 110 } 111 112 /* 113 * Constructors ----------------------------------------------------------- 114 */ 115 116 /** 117 * No-argument constructor. 118 */ 119 public Tree1() { 120 this.createNewRep(); 121 } 122 123 /* 124 * Standard methods ------------------------------------------------------- 125 */ 126 127 @SuppressWarnings("unchecked") 128 @Override 129 public final Tree<T> newInstance() { 130 try { 131 return this.getClass().getConstructor().newInstance(); 132 } catch (ReflectiveOperationException e) { 133 throw new AssertionError( 134 "Cannot construct object of type " + this.getClass()); 135 } 136 } 137 138 @Override 139 public final void clear() { 140 this.createNewRep(); 141 } 142 143 @Override 144 public final void transferFrom(Tree<T> source) { 145 assert source != null : "Violation of: source is not null"; 146 assert source != this : "Violation of: source is not this"; 147 assert source instanceof Tree1<?> 148 : "Violation of: source is of dynamic type Tree1<?>"; 149 /* 150 * This cast cannot fail since the assert above would have stopped 151 * execution in that case: source must be of dynamic type Tree1<?>, and 152 * the ? must be T or the call would not have compiled. 153 */ 154 Tree1<T> localSource = (Tree1<T>) source; 155 this.size = localSource.size; 156 this.height = localSource.height; 157 this.rootLabel = localSource.rootLabel; 158 this.subtrees = localSource.subtrees; 159 localSource.createNewRep(); 160 } 161 162 /* 163 * Kernel methods --------------------------------------------------------- 164 */ 165 166 @Override 167 public final Sequence<Tree<T>> newSequenceOfTree() { 168 return new Sequence3<Tree<T>>(); 169 } 170 171 @Override 172 public final void assemble(T root, Sequence<Tree<T>> children) { 173 assert root != null : "Violation of: root is not null"; 174 assert children != null : "Violation of: children is not null"; 175 assert children instanceof Sequence3<?> 176 : "Violation of: the dynamic type of children must be " 177 + "the same as that returned by newSequenceOfTree"; 178 for (Tree<T> t : children) { 179 assert t != null : "Violation of: all children are not null"; 180 assert t != this : "Violation of: all children are not this"; 181 assert t instanceof Tree1<?> 182 : "Violation of: the dynamic type of each entry of " 183 + "children must be the same as the dynamic type of this"; 184 } 185 186 this.rootLabel = root; 187 this.subtrees = this.newSequenceOfTree(); 188 this.size = 1; 189 int maxHeight = 0; 190 for (Tree<T> t : children) { 191 /* 192 * These casts cannot fail since the asserts above would have 193 * stopped execution in that case: all children must be of dynamic 194 * type Tree1<?>, and the ? must be T or the call would not have 195 * compiled. 196 */ 197 Tree1<T> localT = (Tree1<T>) t; 198 this.size += localT.size; 199 if (localT.height > maxHeight) { 200 maxHeight = localT.height; 201 } 202 } 203 this.height = 1 + maxHeight; 204 this.subtrees.transferFrom(children); 205 } 206 207 @Override 208 public final T disassemble(Sequence<Tree<T>> children) { 209 assert this.size() > 0 : "Violation of: this /= empty_tree"; 210 assert children != null : "Violation of: children is not null"; 211 assert children instanceof Sequence3<?> 212 : "Violation of: the dynamic type of children must be " 213 + "the same as that returned by newSequenceOfTree"; 214 215 T localRootLabel = this.rootLabel; 216 children.transferFrom(this.subtrees); 217 this.createNewRep(); 218 return localRootLabel; 219 } 220 221 @Override 222 public final int size() { 223 return this.size; 224 } 225 226 @Override 227 public final Iterator<T> iterator() { 228 return new Tree1Iterator(); 229 } 230 231 /** 232 * Regions for iterator. 233 */ 234 private enum IteratorRegion { 235 /** 236 * There is no next label. 237 */ 238 NONE, 239 /** 240 * Next label is from the root. 241 */ 242 ROOT, 243 /** 244 * Next label is from current subtree. 245 */ 246 CHILD 247 }; 248 249 /** 250 * Implementation of {@code Iterator} interface for {@code Tree1}. 251 */ 252 private final class Tree1Iterator implements Iterator<T> { 253 254 /** 255 * Region of tree from which next label will come. 256 */ 257 private IteratorRegion region; 258 259 /** 260 * Iterator from which next label will come, if region is CHILD; 261 * otherwise null. 262 */ 263 private Iterator<T> operative; 264 265 /** 266 * Iterator from which next subtree will come, if region is CHILD; 267 * otherwise null. 268 */ 269 private Iterator<Tree<T>> subtree; 270 271 /** 272 * No-argument constructor. 273 */ 274 Tree1Iterator() { 275 /* 276 * Iterator starts at root. 277 */ 278 if (Tree1.this.size == 0) { 279 this.region = IteratorRegion.NONE; 280 } else { 281 this.region = IteratorRegion.ROOT; 282 } 283 this.operative = null; 284 this.subtree = null; 285 } 286 287 @Override 288 public boolean hasNext() { 289 return this.region != IteratorRegion.NONE; 290 } 291 292 @Override 293 public T next() { 294 assert this.hasNext() : "Violation of: ~this.unseen /= <>"; 295 if (!this.hasNext()) { 296 /* 297 * Exception is supposed to be thrown in this case, but with 298 * assertion-checking enabled it cannot happen because of assert 299 * above. 300 */ 301 throw new NoSuchElementException(); 302 } 303 T result = null; 304 switch (this.region) { 305 case NONE: { 306 /* 307 * Cannot happen because of code above. 308 */ 309 throw new AssertionError("Unreachable branch."); 310 } 311 case ROOT: { 312 result = Tree1.this.rootLabel; 313 this.subtree = Tree1.this.subtrees.iterator(); 314 while (this.subtree.hasNext()) { 315 this.operative = this.subtree.next().iterator(); 316 if (this.operative.hasNext()) { 317 this.region = IteratorRegion.CHILD; 318 break; 319 } 320 } 321 if ((this.operative == null) || !this.operative.hasNext()) { 322 this.region = IteratorRegion.NONE; 323 this.operative = null; 324 this.subtree = null; 325 } 326 break; 327 } 328 case CHILD: { 329 result = this.operative.next(); 330 if (!this.operative.hasNext()) { 331 while (this.subtree.hasNext()) { 332 this.operative = this.subtree.next().iterator(); 333 if (this.operative.hasNext()) { 334 break; 335 } 336 } 337 if (!this.operative.hasNext()) { 338 this.region = IteratorRegion.NONE; 339 this.operative = null; 340 this.subtree = null; 341 } 342 } 343 break; 344 } 345 default: { 346 /* 347 * Cannot happen because of the type of the expression. 348 */ 349 throw new AssertionError("Unreachable branch."); 350 } 351 } 352 return result; 353 } 354 355 @Override 356 public void remove() { 357 throw new UnsupportedOperationException("remove operation not supported"); 358 } 359 360 } 361 362 /* 363 * Other methods (overridden for performance reasons) --------------------- 364 */ 365 366 @Override 367 public final T root() { 368 assert this.size() > 0 : "Violation of: this /= empty_tree"; 369 return this.rootLabel; 370 } 371 372 @Override 373 public final T replaceRoot(T x) { 374 assert this.size() > 0 : "Violation of: this /= empty_tree"; 375 T root = this.rootLabel; 376 this.rootLabel = x; 377 return root; 378 } 379 380 @Override 381 public final int height() { 382 return this.height; 383 } 384 385 // @Override 386 // public final void addSubtree(int pos, Tree<T> st) { 387 // assert this.size() > 0 : "Violation of: this /= empty_tree"; 388 // assert 0 <= pos : "Violation of: 0 <= pos"; 389 // assert pos <= this.numberOfSubtrees() : "" 390 // + "Violation of: pos <= [number of children of this]"; 391 // /* 392 // * Move st into new tree t and clear st 393 // */ 394 // Tree<T> t = st.newInstance(); 395 // t.transferFrom(st); 396 // /* 397 // * Update the size and height. 398 // */ 399 // this.size += t.size(); 400 // if (this.height <= t.height()) { 401 // this.height = t.height() + 1; 402 // } 403 // /* 404 // * Add the new tree t so that no alias to st is created 405 // */ 406 // this.subtrees.add(pos, t); 407 // } 408 409 // @Override 410 // public final Tree<T> removeSubtree(int pos) { 411 // assert this.size() > 0 : "Violation of: this /= empty_tree"; 412 // assert 0 <= pos : "Violation of: 0 <= pos"; 413 // assert pos < this.numberOfSubtrees() : "" 414 // + "Violation of: pos < [number of children of this]"; 415 // /* 416 // * Remove the subtree 417 // */ 418 // Tree<T> t = this.subtrees.remove(pos); 419 // /* 420 // * Update the size and height. 421 // */ 422 // this.size -= t.size(); 423 // /* 424 // * PROBLEM: there is no efficient way to update the height 425 // */ 426 // return t; 427 // } 428 429 @Override 430 public final int numberOfSubtrees() { 431 assert this.size() > 0 : "Violation of: this /= empty_tree"; 432 return this.subtrees.length(); 433 } 434 435}