''' BC1.py -- first of several incremental implementation of backward chaining to illustrate incremental development in CS4100, Artificial Intelligence.This first version works only with a KB of "facts", meaning positive ground literals (with no variables). BC2 will introduce variables and the possibility of having more than one return value. We use a dictionary to store the KB and its keys are predicates symbols: i.e., the goals we are trying to prove. The incremental approach lets you create a basic structure for: input/processing/output without getting bogged down by the details of the multi-level recursion in the BC algorithm. ''' from unify import * Fdict = {} #Here we will store the "facts" found in the knowledge base def acquireKB(KBname): kbfile = open(KBname) for aline in kbfile.readlines(): addClauseToFDict(FOLexp(aline)) # now add the FOLexp to the dictionary with its key def FOLBCtest(QFname): queryfile = open(QFname) for aline in queryfile.readlines(): print 'Query: ' , aline[:-1] nextQ = FOLexp(aline) #now find everything the query matches in the KB if Fdict.has_key(nextQ.op): thetalist = runBC(nextQ, Fdict[nextQ.op], []) showResults(thetalist) else: print "RESULT>>>>>: False" def addClauseToFDict(clause): #Adds a FOL sentence represented as a FOLexp to the KB dictionary if Fdict.has_key(clause.op): Fdict[clause.op] += [clause] #append it to entry else: Fdict[clause.op] = [clause] # make a new entry def runBC(query, clauses, thetalist): # get all theta's that satisfy the query and display # them in a readable way for c in clauses: theta = unify(query, c) if theta != False: thetalist.append(theta) return thetalist def showResults(thetalist): if len(thetalist) > 1: # Display the number of answers and each one print ">>> " , len(thetalist) , " answers found." i = 1 for theta in thetalist: print ">>> ANSWER " , i printTheta(theta) i += 1 else: print ">>> ANSWER: " printTheta(thetalist[0])