Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 151   Methods: 20
NCLOC: 94   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ComposedRelation.java 0% 0% 0% 0%
coverage
 1    /*BEGIN_COPYRIGHT_BLOCK*
 2   
 3    PLT Utilities BSD License
 4   
 5    Copyright (c) 2007-2010 JavaPLT group at Rice University
 6    All rights reserved.
 7   
 8    Developed by: Java Programming Languages Team
 9    Rice University
 10    http://www.cs.rice.edu/~javaplt/
 11   
 12    Redistribution and use in source and binary forms, with or without modification, are permitted
 13    provided that the following conditions are met:
 14   
 15    - Redistributions of source code must retain the above copyright notice, this list of conditions
 16    and the following disclaimer.
 17    - Redistributions in binary form must reproduce the above copyright notice, this list of
 18    conditions and the following disclaimer in the documentation and/or other materials provided
 19    with the distribution.
 20    - Neither the name of the JavaPLT group, Rice University, nor the names of the library's
 21    contributors may be used to endorse or promote products derived from this software without
 22    specific prior written permission.
 23   
 24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 25    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 26    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND
 27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 28    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 29    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 30    IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 31    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32   
 33    *END_COPYRIGHT_BLOCK*/
 34   
 35    package edu.rice.cs.plt.collect;
 36   
 37    import java.util.Iterator;
 38    import java.io.Serializable;
 39    import edu.rice.cs.plt.tuple.Pair;
 40    import edu.rice.cs.plt.tuple.Option;
 41    import edu.rice.cs.plt.iter.ReadOnlyIterator;
 42    import edu.rice.cs.plt.iter.EmptyIterator;
 43    import edu.rice.cs.plt.iter.IterUtil;
 44    import edu.rice.cs.plt.lambda.Predicate;
 45    import edu.rice.cs.plt.lambda.Lambda;
 46    import edu.rice.cs.plt.object.ObjectUtil;
 47   
 48    /**
 49    * The transitive composition of two relations, lazily constructed and dynamically-updated. An entry
 50    * {@code (x, y)} appears in the relation if and only if there is an entry {@code (x, z)} in the first
 51    * relation and {@code (z, y)} in the second.
 52    */
 53    public class ComposedRelation<T1, T2, T3> extends AbstractRelation<T1, T3> implements Serializable {
 54   
 55    private final Relation<T1, T2> _rel1;
 56    private final Relation<T2, T3> _rel2;
 57    private final PredicateSet<T1> _firstSet;
 58    private final PredicateSet<T3> _secondSet;
 59   
 60  0 public ComposedRelation(Relation<T1, T2> rel1,
 61    Relation<T2, T3> rel2) {
 62  0 _rel1 = rel1;
 63  0 _rel2 = rel2;
 64  0 _firstSet = new FilteredSet<T1>(rel1.firstSet(), new Predicate<T1>() {
 65  0 public boolean contains(T1 first) {
 66  0 for (T2 middle : _rel1.matchFirst(first)) {
 67  0 if (_rel2.containsFirst(middle)) { return true; }
 68    }
 69  0 return false;
 70    }
 71    });
 72  0 _secondSet = new FilteredSet<T3>(rel2.secondSet(), new Predicate<T3>() {
 73  0 public boolean contains(T3 second) {
 74  0 for (T2 middle : _rel2.matchSecond(second)) {
 75  0 if (_rel1.containsSecond(middle)) { return true; }
 76    }
 77  0 return false;
 78    }
 79    });
 80    }
 81   
 82  0 public int compositeHeight() { return ObjectUtil.compositeHeight(_rel1, _rel2) + 1; }
 83  0 public int compositeSize() { return ObjectUtil.compositeSize(_rel1, _rel2) + 1; }
 84   
 85  0 @Override public boolean isEmpty() { return _firstSet.isEmpty(); }
 86  0 public boolean isInfinite() { return false; }
 87  0 public boolean hasFixedSize() { return false; }
 88  0 public boolean isStatic() { return _rel1.isStatic() && _rel2.isStatic(); }
 89   
 90  0 public boolean contains(T1 first, T3 second) {
 91  0 return matchFirst(first).contains(second);
 92    }
 93   
 94  0 public boolean contains(Object o) {
 95  0 if (o instanceof Pair<?, ?>) {
 96  0 Pair<?, ?> p = (Pair<?, ?>) o;
 97  0 Option<T1> first = CollectUtil.castIfContains(_firstSet, p.first());
 98  0 return first.isSome() && matchFirst(first.unwrap()).contains(p.second());
 99    }
 100  0 else { return false; }
 101    }
 102   
 103    /** For each element of {@code rel1.firstSet()}, iterate over all transitive matches. */
 104  0 public Iterator<Pair<T1, T3>> iterator() {
 105  0 return new ReadOnlyIterator<Pair<T1, T3>>() {
 106    private final Iterator<T1> _firsts = _firstSet.iterator();
 107    private T1 _currentFirst = null;
 108    private Iterator<T2> _currentMiddles = EmptyIterator.<T2>make();
 109    private T2 _currentMiddle = null;
 110    private Iterator<? extends T3> _currentSeconds = EmptyIterator.<T3>make();
 111   
 112  0 public boolean hasNext() {
 113  0 return _currentSeconds.hasNext() || _currentMiddles.hasNext() || _firsts.hasNext();
 114    }
 115   
 116  0 public Pair<T1, T3> next() {
 117    // the use of _firstSet for _firsts guarantees that none of these match sets is empty
 118  0 if (!_currentSeconds.hasNext()) {
 119  0 if (!_currentMiddles.hasNext()) {
 120  0 _currentFirst = _firsts.next();
 121  0 _currentMiddles = _rel1.matchFirst(_currentFirst).iterator();
 122    }
 123  0 _currentMiddle = _currentMiddles.next();
 124  0 _currentSeconds = _rel2.matchFirst(_currentMiddle).iterator();
 125    }
 126  0 return new Pair<T1, T3>(_currentFirst, _currentSeconds.next());
 127    }
 128    };
 129    }
 130   
 131  0 public PredicateSet<T1> firstSet() { return _firstSet; }
 132   
 133  0 public PredicateSet<T3> matchFirst(T1 first) {
 134  0 Iterable<PredicateSet<T3>> seconds =
 135    IterUtil.map(_rel1.matchFirst(first), new Lambda<T2, PredicateSet<T3>>() {
 136  0 public PredicateSet<T3> value(T2 middle) { return _rel2.matchFirst(middle); }
 137    });
 138  0 return new IterableSet<T3>(IterUtil.collapse(seconds));
 139    }
 140   
 141  0 public PredicateSet<T3> secondSet() { return _secondSet; }
 142   
 143  0 public PredicateSet<T1> matchSecond(T3 second) {
 144  0 Iterable<PredicateSet<T1>> firsts =
 145    IterUtil.map(_rel2.matchSecond(second), new Lambda<T2, PredicateSet<T1>>() {
 146  0 public PredicateSet<T1> value(T2 middle) { return _rel1.matchSecond(middle); }
 147    });
 148  0 return new IterableSet<T1>(IterUtil.collapse(firsts));
 149    }
 150   
 151    }