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}