/** * Author: Ashutosh Gupta <agupta@ist.ac.at> */ package at.iaik.suraq.resProof; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.TreeSet; /** * Represents a clause in a node of a resolution proof. Clauses are immutable. * */ public class Clause implements Iterable<Literal> { /** * The literals in this clause. This is supposed to be sorted according to * the natural order of Literals. */ private final Literal[] literals; /** * The hashCode. */ private final int hashCode; /** * * Constructs a new <code>Clause</code> that is empty. */ public Clause() { literals = new Literal[0]; hashCode = 0; } /** * * Constructs a new <code>Clause</code> with the given literals. * * @param lits */ public Clause(Collection<Literal> lits) { assert (lits != null); TreeSet<Literal> literalSet = new TreeSet<Literal>(); literalSet.addAll(lits); Literal[] litArray = new Literal[literalSet.size()]; literals = literalSet.toArray(litArray); assert (literalsSorted()); hashCode = literalSet.hashCode(); } /** * * Constructs a new <code>Clause</code>. (Copy constructor) * * @param clause */ public Clause(Clause clause) { this(Arrays.asList(clause.literals)); } /** * * Constructs a new <code>Clause</code> that is the result of resolving the * two given collections of literals over the given pivot. * * @param clLeft * @param clRight * @param pivot */ public Clause(Clause clLeft, Clause clRight, int pivot) { TreeSet<Literal> literalSet = new TreeSet<Literal>(); Collections.addAll(literalSet, clLeft.literals); literalSet.remove(Literal.create(pivot, true)); if (literalSet.contains(Literal.create(pivot, false))) { Collections.addAll(literalSet, clRight.literals); } else { Collections.addAll(literalSet, clRight.literals); literalSet.remove(Literal.create(pivot, false)); } Literal[] litArray = new Literal[literalSet.size()]; literals = literalSet.toArray(litArray); assert (literalsSorted()); hashCode = literalSet.hashCode(); } /** * Checks if the array of literals is sorted. * * @return */ private boolean literalsSorted() { for (int count = 1; count < literals.length; count++) { if (literals[count - 1].compareTo(literals[count]) >= 0) return false; } return true; } /** * Checks whether the clause contains the literal with the given id and * polarity. * * @param id * @param polarity * @return */ public boolean contains(int id, boolean polarity) { return contains(Literal.create(id, polarity)); } /** * Checks whether the given literal is contained in this clause. * * @param literal * @return <code>true</code> iff <code>literal</code> is contained in this * clause. */ public boolean contains(Literal literal) { return Arrays.binarySearch(literals, literal) >= 0; } /** * * @return <code>true</code> if this clause is empty. */ public boolean isEmpty() { return literals.length == 0; } /** * * @return an iterator over the literals of this clause */ @Override public Iterator<Literal> iterator() { return Arrays.asList(literals).iterator(); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return hashCode; } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Clause)) return false; if (this.hashCode() != obj.hashCode()) return false; if (!Arrays.equals(literals, ((Clause) obj).literals)) return false; return true; } /** * * @see java.lang.Object#toString() */ @Override public String toString() { return Arrays.toString(literals); } }