/******************************************************************************* * Copyright (C) 2008-2012 Dominik Jain. * * This file is part of ProbCog. * * ProbCog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ProbCog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ProbCog. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package probcog.logic.sat; import probcog.logic.ComplexFormula; import probcog.logic.Disjunction; import probcog.logic.Formula; import probcog.logic.GroundAtom; import probcog.logic.GroundLiteral; import probcog.logic.IPossibleWorld; import probcog.srl.GenericDatabase; import edu.tum.cs.util.StringTool; /** * Represents a logical clause. * @author Dominik Jain */ public class Clause extends ComplexFormula { public GroundLiteral[] lits; public Clause(Formula f) throws Exception { //System.out.println("generating clause from " + f.toString()); if(f instanceof GroundLiteral) { lits = new GroundLiteral[1]; lits[0] = (GroundLiteral)f; } else if(f instanceof Disjunction) { Disjunction d = (Disjunction)f; lits = new GroundLiteral[d.children.length]; // add each child of the disjunction for(int i = 0; i < lits.length; i++) { // the child must be a ground literal if(d.children[i] instanceof GroundLiteral) lits[i] = (GroundLiteral)d.children[i]; else throw new Exception("Disjunction contains child of unacceptable type " + d.children[i].getClass().getSimpleName() + "; only GroundLiterals allowed."); // check if we previously added the negative literal or the same literal for(int j = 0; j < i; j++) if(lits[i].gndAtom == lits[j].gndAtom) { if(lits[i].isPositive != lits[j].isPositive) throw new TautologyException(d); throw new Exception("Tried to create SAT clause from disjunction with duplicate ground atoms: " + d); } } } else if(f instanceof GroundAtom) { lits = new GroundLiteral[1]; lits[0] = new GroundLiteral(true, (GroundAtom)f); } else throw new Exception("Instance of type " + f.getClass().getSimpleName() + " cannot be treated as a clause"); } public static class TautologyException extends Exception { private static final long serialVersionUID = 1L; public TautologyException(Disjunction d) { super("Tried to create SAT clause from tautology: " + d); } } @Override public boolean isTrue(IPossibleWorld w) { for(GroundLiteral lit : lits) if(lit.isTrue(w)) return true; return false; } @Override public Formula toCNF() { return this; } public String toString() { return StringTool.join(" v ", this.lits); } @Override public Formula simplify(GenericDatabase<?, ?> evidence) { throw new UnsupportedOperationException("Not supported yet."); } @Override public Formula toNNF() { return this; } }