/** * Author: Ashutosh Gupta <agupta@ist.ac.at> */ package at.iaik.suraq.resProof; import java.lang.ref.WeakReference; import java.util.Map; import java.util.WeakHashMap; /** * * Represents a literal in a resolution proof. A literal has an integer * identifier and a polarity. To save memory, both are stored in one * <code>int</code>. The last bit is used to store the polarity. * * <code>Literal</code> objects are immutable. * */ public class Literal implements Comparable<Literal> { /** * Stores the unique literal objects. */ private static final Map<Literal, WeakReference<Literal>> uniqueLiterals = new WeakHashMap<Literal, WeakReference<Literal>>(); /** * the internal storage for identifier and polarity */ private final int lit; /** * * Constructs a new <code>Literal</code>, based on the given * <code>lit</code>. * * @param lit * the internal <code>lit</code> of another <code>Literal</code>. */ private Literal(int lit) { this.lit = lit; } /** * * Constructs a new <code>Literal</code>, based on the given identifier and * polarity. * * @param id * @param polarity */ private Literal(int id, boolean polarity) { lit = (id << 1) | (polarity ? 1 : 0); } /** * * Constructs a new <code>Literal</code>, based on the given * <code>lit</code>. If the same literal object already exists, the existing * reference is returned. * * @param lit * the internal <code>lit</code> of another <code>Literal</code>. */ public static Literal create(int lit) { Literal newLiteral = new Literal(lit); WeakReference<Literal> oldLiteralRef = Literal.uniqueLiterals .get(newLiteral); if (oldLiteralRef != null) { Literal oldLiteral = oldLiteralRef.get(); if (oldLiteral != null) { return oldLiteral; } } Literal.uniqueLiterals.put(newLiteral, new WeakReference<Literal>( newLiteral)); return newLiteral; } /** * * Constructs a new <code>Literal</code>, based on the given identifier and * polarity. If the same literal object already exists, the existing * reference is returned. * * @param id * @param polarity */ public static Literal create(int id, boolean polarity) { Literal newLiteral = new Literal(id, polarity); WeakReference<Literal> oldLiteralRef = Literal.uniqueLiterals .get(newLiteral); if (oldLiteralRef != null) { Literal oldLiteral = oldLiteralRef.get(); if (oldLiteral != null) { return oldLiteral; } } Literal.uniqueLiterals.put(newLiteral, new WeakReference<Literal>( newLiteral)); return newLiteral; } /** * * @return the variable identifier of this literal (disregarding polarity, * i.e., always positive). */ public int id() { return lit >> 1; } /** * * @return <code>true</code> iff this literal is positive. */ public boolean isPos() { return (lit & 0x1) == 1; } /** * * @return the negated version of this literal. */ public Literal negate() { return Literal.create(lit ^ 0x1); } /** * * @return the internal <code>lit</code>. */ public int getLit() { return lit; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (this.getClass() != obj.getClass()) return false; return this.lit == ((Literal) obj).lit; } @Override public int hashCode() { return lit; } @Override public String toString() { if ((lit & 1) == 0) return "~" + (lit >> 1); else return Integer.toString(lit >> 1); } /** * @return the identifying <code>int</code> of this literal, with a sign * signifying the polarity. */ public int signed_var() { return (lit >> 1) * ((lit & 0x1) == 1 ? 1 : -1); } /** * @see java.lang.Comparable#compareTo(java.lang.Object) */ @Override public int compareTo(Literal other) { if (other == null) throw new NullPointerException(); return this.lit - other.lit; } }