001package daikon.diff;
002
003import daikon.inv.Invariant;
004import java.io.PrintStream;
005import org.checkerframework.checker.nullness.qual.Nullable;
006
007/**
008 * <B>XorInvariantsVisitor</B> is a visitor that performs a standard Diff on two PptMaps, that is,
009 * finds the set of Invariants in the XOR set of two PptMaps. However, while those XOR Invariants
010 * were the end product of standard diff, this visitor is useful when the XOR set is a means to an
011 * end, since you get back a data structure containing the XOR set.
012 *
013 * <p>Currently, this visitor actually modifies the first of the two PptMaps. This might be an
014 * undesirable design call, but creating a PptMap from scratch is difficult given the constraining
015 * creational pattern in place.
016 */
017public class XorInvariantsVisitor extends PrintDifferingInvariantsVisitor {
018
019  /** Create an instance of XorInvariantsVisitor. */
020  public XorInvariantsVisitor(PrintStream ps, boolean verbose, boolean printEmptyPpts) {
021    super(ps, verbose, printEmptyPpts);
022  }
023
024  @Override
025  public void visit(PptNode node) {
026    super.visit(node);
027  }
028
029  @Override
030  public void visit(InvNode node) {
031    Invariant inv1 = node.getInv1();
032    Invariant inv2 = node.getInv2();
033    // do nothing if they are unique
034
035    if (shouldPrint(inv1, inv2)) {
036      // do nothing, keep both
037    } else {
038      if (inv1 != null) {
039        inv1.ppt.removeInvariant(inv1);
040      }
041
042      if (inv2 != null) {
043        inv2.ppt.removeInvariant(inv2);
044      }
045    }
046  }
047
048  /**
049   * Returns true if the pair of invariants should be printed, depending on their type,
050   * relationship, and printability.
051   */
052  @Override
053  protected boolean shouldPrint(@Nullable Invariant inv1, @Nullable Invariant inv2) {
054    int rel = DetailedStatisticsVisitor.determineRelationship(inv1, inv2);
055    if (rel == DetailedStatisticsVisitor.REL_SAME_JUST1_JUST2
056        || rel == DetailedStatisticsVisitor.REL_SAME_UNJUST1_UNJUST2
057        || rel == DetailedStatisticsVisitor.REL_DIFF_UNJUST1_UNJUST2
058        || rel == DetailedStatisticsVisitor.REL_MISS_UNJUST1
059        || rel == DetailedStatisticsVisitor.REL_MISS_UNJUST2) {
060      return false;
061    }
062
063    if ((inv1 == null || !inv1.isWorthPrinting()) && (inv2 == null || !inv2.isWorthPrinting())) {
064      return false;
065    }
066
067    return true;
068  }
069}