Functions defined in python and using them in rules which are loaded

95 views
Skip to first unread message

Vesa Luukkala

unread,
Aug 18, 2014, 7:47:01 AM8/18/14
to pyda...@googlegroups.com
Hello, 

I can create a rule so that it uses a function defined in Python:

from pyDatalog import pyDatalog
from pyDatalog.pyDatalog import load,ask,create_terms
from datetime import datetime

def todate(s):
    return(datetime.strptime(s, '"%Y-%m-%dT%H:%M:%S.%fZ"'))

create_terms('todate,a,X,Y')
a(Y) <= (X == '"2014-08-11T07:39:59.788Z"') & (Y == todate(X))
print(ask('a(Z)'))

set([(datetime.datetime(2014, 8, 11, 7, 39, 59, 788000),)])

However creating the rule via load seems not be able to 
access the python function:

from pyDatalog import pyDatalog
from pyDatalog.pyDatalog import load, ask,create_terms
from datetime import datetime

def todate(s):
    return(datetime.strptime(s, '"%Y-%m-%dT%H:%M:%S.%fZ"'))

create_terms('todate,a,X,Y')
load('''a(Y) <= (X == '"2014-08-11T07:39:59.788Z"') & (Y == todate(X))''')

Traceback (most recent call last):

[ ... cut ... ]

  File "/Users/foobar/src/myenv/lib/python2.7/site-packages/pyDatalog/pyParser.py", line 601, in __eq__
    raise util.DatalogError("Syntax error near equality: consider using brackets. %s" % util.unicode_type(self), None, None)
pyDatalog.util.DatalogError: Syntax error near equality: consider using brackets. todate(X)

What am I missing, what do I need to do in order to have the loaded rules use functions
defined in Python?

BR, Vesa Luukkala

Pierre Carbonnelle

unread,
Aug 18, 2014, 3:44:33 PM8/18/14
to pyda...@googlegroups.com
Hello Vesa,

Indeed, terms created by create_terms are for in-line clauses and queries, and are not recognized in dynamic queries ("ask").

A way around that is to use a predicate resolver written in python.  See the 4th section in advanced topics.

You could then write  :

@pyDatalog.predicate()
def todate2(S,D):
   
yield (S.id, datetime.strptime(S.id, "%Y-%m-%dT%H:%M:%S.%fZ"))
   
print(pyDatalog.ask('todate("2014-08-11T07:39:59.788Z", Y)'))
#>> {(datetime.datetime(2014, 8, 11, 7, 39, 59, 788000),)}

Best regards,
Pierre C.

Vesa Luukkala

unread,
Aug 19, 2014, 10:16:31 AM8/19/14
to pyda...@googlegroups.com
Hello,

This did the trick.

Thanks, 
Vesa 
Reply all
Reply to author
Forward
0 new messages