/** * Author: Georg Hofferek <georg.hofferek@iaik.tugraz.at> */ package at.iaik.suraq.util; import java.util.ArrayList; import java.util.List; import at.iaik.suraq.smtlib.formula.DomainEq; import at.iaik.suraq.util.chain.TransitivityCongruenceChain; /** * A container for a justification of an equality between to terms in an * equality graph. Either contains an equality formula, or a set of * transitivity-congruence chains. * * @author Georg Hofferek <georg.hofferek@iaik.tugraz.at> * */ public class Justification implements Copyable<Justification> { /** * The equality justification, or <code>null</code> */ private final DomainEq equality; /** * The congruence justification, or <code>null</code> */ private final ImmutableArrayList<TransitivityCongruenceChain> chains; /** * * Constructs a new <code>Justification</code> based on * <code>equality</code>. * * @param equality */ public Justification(DomainEq equality) { assert (equality.isEqual()); this.equality = equality; this.chains = null; } /** * * Constructs a new <code>Justification</code> based on <code>chains</code>. * * @param chains */ public Justification(List<TransitivityCongruenceChain> chains) { this.equality = null; this.chains = new ImmutableArrayList<TransitivityCongruenceChain>( chains); } /** * * @return <code>true</code> if this is an equality justification. */ public boolean isEqualityJustification() { if (equality == null) { assert (chains != null); return false; } else { assert (chains == null); return true; } } /** * * @return <code>true</code> if this is a congruence justification. */ public boolean isCongruenceJustification() { if (chains == null) { assert (equality != null); return false; } else { assert (equality == null); return true; } } /** * * @return the equality justification or <code>null</code> if this is a * congruence justification. */ public DomainEq getEqualityJustification() { return equality; } /** * * @return the congruence justification or <code>null</code> if this is an * equality justification. */ public ImmutableArrayList<TransitivityCongruenceChain> getCongruenceJustification() { return chains; } /** * If this is an equality justification, <code>this</code> is returned. * Otherwise a new object with reversed chains is returned. * * @return <code>this</code> or a reversed congruence justification. */ public Justification reverse() { if (equality != null) { assert (chains == null); return this; } else { assert (chains != null); List<TransitivityCongruenceChain> reverseChains = new ArrayList<TransitivityCongruenceChain>( chains.size()); for (TransitivityCongruenceChain chain : chains) { reverseChains.add(chain.reverse()); } return new Justification(reverseChains); } } /** * Returns a clone of this object. Equality justifications are copied * shallowly (as they are immutable anyway), congruence justifications are * copied deeply. * * @see java.lang.Object#clone() */ @Override public Justification clone() { if (equality != null) { assert (chains == null); return new Justification(equality); } if (chains != null) { assert (equality == null); List<TransitivityCongruenceChain> clonedChains = new ArrayList<TransitivityCongruenceChain>( chains.size()); for (TransitivityCongruenceChain chain : chains) { clonedChains.add(chain.clone()); } return new Justification(clonedChains); } assert (false); return null; } @Override public String toString() { if (chains != null) { assert (equality == null); return "(congr)"; } if (equality != null) { assert (chains == null); return "(equal)"; } assert (false); return null; } }