###main.py ###pychinko invocation script ### ###usage: ### ###python main.py --facts=filename --rules=filename --output= ### ###If --rules= is not provided, Pychinko defaults to 'rules.n3' in the cwd. import sys import nodes as n from terms import URI, Rule, Variable, Fact, Pattern from rete import RuleCompiler, Rete from interpreter import Interpreter #from pychinko.pychinkafon import PychinkoN3Sink, N3Parser, serializeTripleElt from N3Loader import N3Loader from helpers import handleURL from urllib import pathname2url from sets import Set from copy import copy import getopt import exception import urllib import time import os #OUTPUTDIR = os.path.expanduser('~') + '/svn.mindswap.org/pychinko/' class Pychinko: """I create a selection network for the rules that are passed.""" def __init__(self): self.filePrefix = 'file://' def run(self, initialFacts, outputFile=None): t = time.time() self.interp.addFacts(Set(initialFacts), initialSet=True) print "add facts time:", time.time() - t t = time.time() self.interp.run() print "interp.run() time:", time.time() - t t = time.time() #self.dumpFacts(outputFile) print "dump facts time:", time.time() - t def knownFacts(self): """I return a list of the currently known facts""" return self.interp.totalFacts def knownRules(self): """I return a list of the currently known rules""" return self.interp.rules def dumpFacts(self, outputFile): if not outputFile: outputFile = 'pychinko.output' outputFile = handleURL(outputFile) outputfp = open(outputFile, 'w') for fact in self.interp.totalFacts: subj = serializeTripleElt(fact.s) obj = serializeTripleElt(fact.o) pred = serializeTripleElt(fact.p) factTriple = subj + ' ' + pred + ' ' + obj + '.\n' outputfp.write(factTriple) outputfp.close() return outputFile def dumpRules(self, rules, outputFile=None): if not outputFile: outputFile = 'pychinko.output1' outputFile = handleURL(outputFile) outputfp = open(outputFile, 'w') for rule in rules: outputfp.write("------Rule---------\n") for x in rule.lhs: outputfp.write(str(x) + "\n") outputfp.write("-----=>----------\n") for x in rule.rhs: outputfp.write(str(x) + "\n") outputfp.write("\n") outputfp.close() return outputFile def handleFilename(self, filename): """Determine whether the file is local or not and return its URI.""" if not filename.startswith('http://'): fname = self.filePrefix + os.path.abspath(filename) return fname else: # slurp URL content and write to file content = urllib.urlopen(filename) fname = filename.split('/')[-1] fname += '.temp' fp = open(fname, 'w') fp.write(content.read()) fp.close() return self.filePrefix + os.path.abspath(fname) def setupAndRun(self, factsFile=None, rulesFile=None, outputFile=None, convert2URL=True): #parse rules #sink = PychinkoN3Sink() t = time.time() if convert2URL and (not rulesFile.startswith('http://')): #fix here: convert to url #rulesFile = self.filePrefix + os.path.abspath(rulesFile) rulesFile = pathname2url(rulesFile) #p = N3Parser(sink, rulesFile) rulesLoader = N3Loader() rulesLoader.parse(rulesFile, format='n3') rules = list(rulesLoader.rules()) #there may be facts in the rules file facts = list(rulesLoader.facts()) print "rules" print rules #print "rules:", rules self.dumpRules(rules) self.interp = Interpreter(rules) if factsFile: factsLoader = N3Loader() if factsFile.endswith('.n3'): factsLoader.parse(factsFile, format='n3') elif factsFile.endswith('.rdf'): factsLoader.parse(factsFile, format='xml') else: raise exception.UnknownFactsFile(factsFile) facts.extend(factsLoader.facts()) print "Ground fact(s): ", len(facts) #print facts print "parsing time:", time.time() - t t = time.time() self.run(facts, outputFile) print "pychinko time:", time.time() - t print len(self.interp.inferredFacts), ' inferred fact(s)' for f in self.interp.inferredFacts: print f #self.interp.totalFacts = self.interp.totalFacts.union(self.interp.inferredFacts) # test code for whether addRule() works """ incRulesFile = pathname2url('rules\incRules1.n3') rulesLoader = N3Loader() rulesLoader.parse(incRulesFile, format='n3') rules = list(rulesLoader.rules()) print "new rule:", rules[0] self.interp.addRule(rules[0]) self.interp.run() print len(self.interp.inferredFacts), ' inferred fact(s)' print self.interp.inferredFacts""" # test code for addFacts() """newFactsLoader = N3Loader() incFactsFile = pathname2url('groundtests\pit-small.rdf') newFactsLoader.parse(incFactsFile, format='xml') facts = list(newFactsLoader.facts()) print "new facts:", len(facts) t = time.time() self.interp.addFacts(Set(facts), initialSet=False) self.interp.joinedBetaNodes = Set() self.interp.inferredFacts = Set() self.interp.fta = Set() print "total facts:", len(self.interp.totalFacts) # print facts print "add facts time:", time.time() - t t = time.time() self.interp.run() print "interp.run() time:", time.time() - t print len(self.interp.inferredFacts), ' inferred fact(s)' for f in self.interp.inferredFacts: print f """ # print self.interp.inferredFacts # print "rules: ", rules # print self.interp.totalFacts def runFromCWM(filename): rulesFile = filename test = Pychinko() test.setupAndRun(None, rulesFile, None, convert2URL=False) if __name__ == '__main__': rulesFile = None opts, args = getopt.getopt(sys.argv[1:], 'ho:v', ['facts=', 'rules=', 'output=', 'profile=']) factsFile = None outputFile = None withProfile = False for option in opts: if option[0] == '--facts': factsFile = pathname2url(option[1]) elif option[0] == '--rules': rulesFile = pathname2url(option[1]) elif option[0] == '--profile': withProfile = True elif option[0] == '--output': outputFile = option[1] #if not factsFile: # print "Give me a --facts=filename please." # sys.exit(0) if withProfile: import hotshot, hotshot.stats prof = hotshot.Profile("pychinko.prof") benchtime = prof.runcall(test.run, outputFile, facts) stats = hotshot.stats.load("pychinko.prof") stats.strip_dirs() stats.sort_stats('time', 'calls') stats.print_stats(23) prof.close() else: test = Pychinko() test.setupAndRun(factsFile, rulesFile, outputFile) #print "Known facts:", test.knownFacts() #print "Known rules:", test.knownRules()