'''SATSolver.py - a simple Python interface to the zchaff SAT solver. Originally by Todd Neller Ported to Python by Dave Musicant Copyright (C) 2008 Dave Musicant This program 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 2 of the License, or (at your option) any later version. This program 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. Information about the GNU General Public License is available online at: http://www.gnu.org/licenses/ To receive a copy of the GNU General Public License, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ''' import subprocess def testKb(clauses): maxVar = 0 for clause in clauses: for literal in clause: maxVar = max(abs(literal),maxVar) out = open('query.cnf','w') print >> out, 'c This DIMACS format CNF file was generated by SATSolver.py' print >> out, 'c Do not edit.' print >> out, 'p cnf',maxVar,len(clauses) for clause in clauses: for literal in clause: print >> out,literal, print >> out,'0' out.close(); process = subprocess.Popen('zchaff query.cnf',stdout=subprocess.PIPE, shell=True) process.wait() stdout = process.stdout result = stdout.read().split() stdout.close() it = iter(result) try: while it.next() != 'RESULT:': pass answer = it.next() if answer == 'SAT': return True elif answer == 'UNSAT': return False else: print "Error: SAT/UNSAT not indicated in query.cnf." return False except StopIteration: print "Error: Unexpected file end in query.cnf." return False def testLiteral(literal,clauses): kb = clauses + [[literal]] if not testKb(kb): return False kb = clauses + [[-literal]] if not testKb(kb): return True return None if __name__ == '__main__': clauses = [[-1,-2],[2 ,1],[-2,-3],[3,2],[-3,-1],[-3, -2],[1,2,3]] print 'Knowledge base is satisfiable:',testKb(clauses) print 'Is Cal a truth-teller?', result = testLiteral(3,clauses) if result==True: print 'Yes.' elif result==False: print 'No.' else: print 'Unknown.'