Package edu.cmu.cs.fusion.relationship

Source Code of edu.cmu.cs.fusion.relationship.RelationshipContext

package edu.cmu.cs.fusion.relationship;


import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

import edu.cmu.cs.fusion.Relationship;
import edu.cmu.cs.fusion.ThreeValue;

/**
* The relationship context. This is effectively the tuple lattice which maps
* relationships to true, false, or unknown. Bottom is not used.
*
* Notice that since it does not use bottom, it treats the bottom
* of the lattice as the same as the top of the lattice. This issue
* is handled by a seperate bottom flag. Notice that as soon as ANY
* modification is made, it goes from bottom directly to top.
*
* This is an immutable lattice! The only way to make changes is by joining (and getting a new lattice)
* or by applying delta changes (and getting a new lattice).
*
* @author ciera
*
*/
public class RelationshipContext implements Iterable<Relationship> {

  private Set<Relationship> trueRels;
  private Set<Relationship> falseRels;
  private boolean isBottom;
 
  public RelationshipContext(boolean isBottom) {
    this.isBottom = isBottom;
    trueRels = new HashSet<Relationship>();
    falseRels = new HashSet<Relationship>();   
  }
 
  private RelationshipContext(RelationshipContext copy) {
    this.isBottom = copy.isBottom;
    trueRels = new HashSet<Relationship>(copy.trueRels);
    falseRels = new HashSet<Relationship>(copy.falseRels);
  }
 
  public boolean isBottom() {return isBottom;}

  public int getSize() {
    return trueRels.size() + falseRels.size();
  }
 
  public Iterator<Relationship> iterator() {
    HashSet<Relationship> tAndf = new HashSet<Relationship>();
    tAndf.addAll(trueRels);
    tAndf.addAll(falseRels);
    return tAndf.iterator();
  }

 
  public ThreeValue getRelationship(Relationship rel) {
    if (trueRels.contains(rel))
      return ThreeValue.TRUE;
    else if (falseRels.contains(rel))
      return ThreeValue.FALSE;
    else
      return ThreeValue.UNKNOWN;
  }
 
  private void setRelationship(Relationship rel, ThreeValue tv) {
    isBottom = false;
    if (tv == ThreeValue.TRUE) {
      falseRels.remove(rel);
      trueRels.add(rel);
    }
    else if (tv == ThreeValue.FALSE) {
      trueRels.remove(rel);
      falseRels.add(rel);
    }
    else {
      trueRels.remove(rel);
      falseRels.remove(rel);
    }
  }
 
  /**
   * @return true if this is more precise than reference for every relationship, and false otherwise.
   * That is, for every relationship
   * U more precise or equal to U
   * T more precise or equal to U
   * T more precise or equal to T
   * F more precise or equal to U
   * F more precise or equal to F
   */
  public boolean isMorePreciseOrEqualTo(RelationshipContext reference) {
    if (isBottom)
      return true;
    else if (reference.isBottom)
      return false;
    else if (!trueRels.containsAll(reference.trueRels))
      return false;
    else if (!falseRels.containsAll(reference.falseRels))
      return false;
    return true;
  }
 
  /**
   * @return true if this is strictly more precise than reference for every relationship, and false otherwise.
   * That is, for every relationship
   * U more precise or equal to U
   * T more precise or equal to U
   * T more precise or equal to T
   * F more precise or equal to U
   * F more precise or equal to F
   *
   * AND this is not exactly the same as reference.
   */
  public boolean isStrictlyMorePrecise(RelationshipContext reference) {
    if (isBottom)
      return !reference.isBottom;
    else if (reference.isBottom)
      return false;
    else
      return isMorePreciseOrEqualTo(reference) &&
      (trueRels.size() != reference.trueRels.size() ||
         falseRels.size() != reference.falseRels.size());
  }

  /**
   * Join the this with other and return a new lattice such that for every relationship in this or other
   * U join U = U
   * T join U = U
   * F join U = U
   * T join T = T
   * F join F = F
   * F join T = U
   */
  public RelationshipContext join(RelationshipContext other) {
    if (isBottom)
      return new RelationshipContext(other);
    else if (other.isBottom)
      return new RelationshipContext(this);
    else {
      RelationshipContext join = new RelationshipContext(false);
     
      for (Relationship rel : falseRels) {
        if (other.falseRels.contains(rel))
          join.setRelationship(rel, ThreeValue.FALSE);
      }
      for (Relationship rel : trueRels) {
        if (other.trueRels.contains(rel))
          join.setRelationship(rel, ThreeValue.TRUE);
      }
      return join;
    }
  }
 
  /**
   * Apply the changes from a delta lattice.
   * @param delta
   * @return A new context which is this context with the changes described in delta
   */
  public RelationshipContext applyChangesFromDelta(RelationshipDelta delta) {
    RelationshipContext changed = new RelationshipContext(this);
    changed.isBottom = isBottom && delta.numberOfChanges() == 0;
   
    for (Entry<Relationship, SevenPointLattice> entry : delta) {
      Relationship rel = entry.getKey();
      changed.setRelationship(rel, entry.getValue().override(getRelationship(rel)));
    }
   
    return changed;
  }
 
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
        + ((falseRels == null) ? 0 : falseRels.hashCode());
    result = prime * result + (isBottom ? 1231 : 1237);
    result = prime * result
        + ((trueRels == null) ? 0 : trueRels.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    RelationshipContext other = (RelationshipContext) obj;
    if (falseRels == null) {
      if (other.falseRels != null)
        return false;
    } else if (!falseRels.equals(other.falseRels))
      return false;
    if (isBottom != other.isBottom)
      return false;
    if (trueRels == null) {
      if (other.trueRels != null)
        return false;
    } else if (!trueRels.equals(other.trueRels))
      return false;
    return true;
  }

  public String toString() {
    String str = "{";
   
    for (Relationship rel : trueRels)
      str += rel.toString() + ", ";

    for (Relationship rel : falseRels)
      str += "!" + rel.toString() + ", ";
    str += "}";
   
    return str;
  }
}
TOP

Related Classes of edu.cmu.cs.fusion.relationship.RelationshipContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.