import Prelude as pre import CombParse as cp, pdb def createVar(name): term = Term() term.type = "var" term.name = name return term def createPredicate(name,list): term = Term() term.type = "pred" term.name = name term.termList = list return term def printPredicate(predicate): print predicate.printP() return "" def printClause(clause): print clause.printP() return "" def printDB(db): print db.printP() return "" def createClause(head,body): clause = Clause() clause.head = head clause.body = body return clause def createDB(type,cList): db = DB() db.type = type db.db = cList return db # definition of a letter letter = lambda c: (pre.isAlpha(c) or pre.isDigit(c) or pre.elem(c,"\"_:;+=-*&%$#@?/.~!")) # merge characters for creating a variable merge = lambda (c,l): c + pre.foldr(pre.plusC,"",l) # Prolog parser ####################### # definition of a variable parser variable = lambda sin: (cp.pam(cp.pseq(cp.sat (pre.isUpper),cp.many(cp.sat(letter))), lambda name: createVar(merge(name))))(sin) # definition of a word parser. The word starts with a lower case letter. pwordl = lambda sin: (cp.pam(cp.pseq(cp.sat (pre.isLower),cp.many(cp.sat(letter))), lambda name: merge(name)))(sin) # parser to parse a predicate ppterm = lambda sin: (cp.pseq(cp.pseq(cp.sptok("("),termlist),cp.sptok(")")))(sin) pterm = lambda sin: (cp.orelse(cp.pam(ppterm ,lambda ((o,ts),c):ts),cp.okay([])))(sin) ppred = lambda sin: (cp.pam(cp.pseq(pwordl, pterm), lambda (name,terms): createPredicate(name,terms)))(sin) struct = lambda sin: (cp.orelse(ppred, cp.okay([])))(sin) # parse a list of terms termlist = lambda sin: cp.listOf(term,cp.sptok(","))(sin) # parse a term term = lambda sin: (cp.sp(cp.orelse(variable,struct)))(sin) # parse a clause # parse the body terms = lambda sin: (cp.listOf(term,cp.sptok(",")))(sin) # parse the clause clauseP = lambda sin: (cp.pam(cp.pseq( cp.pseq(cp.sp(term),cp.orelse(cp.pam( cp.pseq(cp.sptok(":-"),terms), lambda (b,c):c),cp.okay([]))), cp.sptok(".")),lambda ((h,g),d):createClause(h,g))) (sin) def clause(sin): cl = clauseP(sin) if len(cl) > 0: return pre.fst(clauseP(sin)[0]) # End of Prolog parser ###################### # read a database from a file # type is "db" or "query" def readClauses(filename,type): inFile = open(filename,"r") clauses = [] for line in inFile: cl = clause(line) if cl <> None: clauses += [cl] return createDB(type,clauses) class Term: # this class defines a prolog term; this is either a variable # or a predicate of the form p(a,...). # the type = var or pred type = "" # the variable or predicate name name = "" # the list of predicate terms termList = [] # print the contents def printP(self): s = self.name l = len(self.termList) if l > 0: s = s + "(" c = 0 for t in self.termList: if c < l-1: s = s + t.printP() s = s + "," else: s = s + t.printP() c = c + 1 s = s + ")" return s class Clause: # this class defines a clause # head of the clause. This is a term. head = None # the body of the clause. This is a list of terms body = [] # print the clause def printP(self): s = self.head.printP() if len(self.body) == 0: return s + "." s = s + " :- " l = len(self.body) c = 1 for term in self.body: s = s + term.printP() if c < l: s = s + "," c =c + 1 return s + "." class DB: # db type = query or db type = "" # contents is a list of clauses db = [] # print the db def printP(self): s = "" for cl in self.db: s = s + cl.printP() + "\n" return s #print createVar("Test") #tuple = variable("Test ddd") #var = pre.fst(tuple[0]) #print var.type, var.name #print "termtest",term("B") #print "termlist",termlist(" ab,cb") print "pwordl ",pwordl("word test") #print "pterm",pterm("") prpred = ppred("cd(c(d(b,a,f),b))") print prpred res = pre.fst(prpred[0]) print printPredicate(res) #print ppterm("(a,b)") #print terms("v(a,b(c)),f(g)") print clauseP("v(a,b).") print printClause(clause("v(a,b).")) print printClause(clause("v(a,b(cd,ef)) :- f(g(a,b),f(h)). some comment after.")) print clause("This is comment") # comment returns a None print printDB( readClauses("authen.axiom.pro","db"))