def _reinit_pdl(self, f): pdl.clear() self._reinit_pdl_facts() self._reinit_pdl_predicates() self._reinit_pdl_functions() if f: self._read_facts_from_file(f)
def test2(): """ Deep recursion """ pyDatalog.clear() @pyDatalog.program() def _(): # the function name is ignored + even(0) even(N) <= (N > 0) & odd(N-1) assert ask(even(0)) == set([()]) odd(N) <= (N > 0) & even(N-1) assert ask(odd(9999)) == set([()])
def test1(): """ Large database + deep recursion """ pyDatalog.clear() for i in range(10000): pyDatalog.assert_fact('successor', i + 1, i + 0) @pyDatalog.program() def _(): # the function name is ignored assert ask(successor(1801, 1800)) == set([(1801, 1800)]) +even(0) even(N) <= (N > 0) & successor(N, N1) & odd(N1) odd(N) <= (N > 0) & successor(N, N2) & even(N2) assert ask(odd(299)) == set([(299, )]) assert ask(odd(9999)) == set([(9999, )])
def test1(): """ Large database + deep recursion """ pyDatalog.clear() for i in range(10000): pyDatalog.assert_fact('successor', i+1, i+0) @pyDatalog.program() def _(): # the function name is ignored assert ask(successor(1801,1800)) == set([()]) + even(0) even(N) <= (N > 0) & successor(N,N1) & odd(N1) odd(N) <= (N > 0) & successor(N,N2) & even(N2) assert ask(odd(299)) == set([()]) assert ask(odd(9999)) == set([()])
def build_datalog_model(union): pyDatalog.clear() for d in union.values: # Extensional Database assert_fact('rdf_star_triple', d[0], d[1], d[2]) # Intentional Database inferred_rdf_star_triple(A, B, T) <= rdf_star_triple(A, B, T) # & (T._in(ddiTypeToxicity)) inferred_rdf_star_triple(A, C, T2) <= inferred_rdf_star_triple(A, B, T) & rdf_star_triple(B, C, T2) & ( T._in(ddiTypeToxicity)) & (T2._in(ddiTypeToxicity)) & (A != C) inferred_rdf_star_triple(A, B, T) <= rdf_star_triple(A, B, T) # & (T._in(ddiTypeEffectiveness)) inferred_rdf_star_triple(A, C, T2) <= inferred_rdf_star_triple(A, B, T) & rdf_star_triple(B, C, T2) & ( T._in(ddiTypeEffectiveness)) & (T2._in(ddiTypeEffectiveness)) & (A != C) wedge(A, B, C, T, T2) <= inferred_rdf_star_triple(A, B, T) & inferred_rdf_star_triple(B, C, T2) & (A != C) wedge_pharmacokinetic(A, B, C, T, T2) <= inferred_rdf_star_triple(A, B, T) & inferred_rdf_star_triple(B, C, T2) & ( T._in(pharmacokinetic_ddi)) & (T2._in(pharmacokinetic_ddi)) & (A != C)
def eval_datalog(data, rule): """ Evaluation using pyDatalog. :param data: a list of tuple string :param rule: a rule node :return: a list of resulting tuple string """ assert isinstance(data, list) assert isinstance(rule, RuleNode) def extract_query_predicate(rule): # print(rule) return QUERY_PRED.match(rule).group(1) # def db2str(tuples): # return "\n".join(["+%s(%s,%s)" % (p, s, o) for (s, p, o) in tuples]) def result2tuplestring(result): # print(rule) # query_pred = extract_query_predicate(rule.left) for (s, o) in result: yield (s, rule.left, o) pyDatalog.clear() # loguru.logger.debug('Size of loaded data: %d' % len(data)) for (s, p, o) in data: pyDatalog.assert_fact(p, s, o) pyDatalog.load(str(rule)) result = pyDatalog.ask(rule.left + '(X, Y)') if not result: loguru.logger.debug("Empty evaluation") return [] # if rule.left == config.query_relation_name: # pyDatalog.ask(config.query_relation_name + "(" + config.subject + ", Y)") return list(result2tuplestring(result.answers))
def db_input(input, window, possible_relations): global Relations busy(window) inverted = [0, 1, 2, 5] Relations = [] pyDatalog.clear() try: # If file exists with open(input.get(), 'r', encoding="utf8") as csvfile: spamreader = csv.reader(csvfile, delimiter='\t', lineterminator='\n') for row in spamreader: first_index = row[0].index(":") # Search first word second_index = row[2].index(":") # Search second word relation = row[1] # If relation is generator -> generated if possible_relations.index(relation) in inverted: child_lang = row[2][0:second_index] child = row[2][second_index + 2:] parent_lang = row[0][0:first_index] parent = row[0][first_index + 2:] # If relation is generated -> generator else: child_lang = row[0][0:first_index] child = row[0][first_index + 2:] parent_lang = row[2][0:second_index] parent = row[2][second_index + 2:] # Relations[possible_relations.index(relation)].append( # [child_lang, child, relation, parent_lang, parent]) # Add to knowledge database Relations.append( Relation(child_lang, child, relation, parent_lang, parent)) messagebox.showinfo("Let's Continue!", "The upload is done!") except: messagebox.showwarning("Error!", "The file can't be upload.") notbusy(window)
def runDatalog(facts, rules, predicates): """виконує логічне виведення в pyDatalog. Повертає список тріплетів. facts - список Datalog-фактів, rules - список Datalog-правил, predicates - список предикатів, для яких будуть шукатись факти""" #if not predicates: # predicates={p for s,p,o in facts}|{r.split('(')[0] for r in rules} from pyDatalog.pyDatalog import assert_fact, load, ask, clear code = '\n'.join(facts) + '\n' + '\n'.join(rules) # факти і правила load(code) allFacts = set() for pred in predicates: # try: res = ask('%s(X,Y)' % pred).answers # except AttributeError: #Predicate without definition # continue for subj, obj in res: allFacts.add((subj.encode('utf-8'), pred.encode('utf-8'), obj.encode('utf-8'))) print subj, pred, obj clear() return allFacts
from pyDatalog.pyDatalog import create_terms, ask, load, assert_fact, clear if __name__ == "__main__": clear() create_terms('X, frog, canary, green, yellow, chirps, sings, croakes, eatFlies') load(""" frog(X) <= croakes(X) & eatFlies(X) canary(X) <= chirps(X) & sings(X) green(X) <= frog(X) yellow(X) <= canary(X) """) assert_fact('croakes', 'fritz') assert_fact('eatFlies', 'fritz') print("frog: ", ask('frog(X)')) print("green: ", ask('green(X)')) print("green: ", ask("green('cuitcuit')"))
# --------------------------------------------------------------------------- # Social graph analysis: # work through this code from top to bottom (in the way you would use a R or Jupyter notebook as well...) and write datalog clauses # and python code in order to solve the respective tasks. Overall, there are 7 tasks. # --------------------------------------------------------------------------- calls = pa.read_csv('calls.csv', sep='\t', encoding='utf-8') texts = pa.read_csv('texts.csv', sep='\t', encoding='utf-8') suspect = 'Quandt Katarina' company_Board = ['Soltau Kristine', 'Eder Eva', 'Michael Jill'] pyDatalog.create_terms('knows', 'has_link', 'board_member', 'has_path', 'short_path', 'short_path', 'COUNTER', 'COUNTER2', 'many_more_needed', 'X', 'Y', 'Z', 'P', 'P2', 'DATE', 'DATE2', 'TP', 'TP2', 'paths') pyDatalog.clear() # clears all facts and clauses # First, treat calls as simple social links (denoted as knows), that have no date for i in range(0, 150): +knows(calls.iloc[i, 1], calls.iloc[i, 2]) # Create predicate to check if a person is a member of the board for i in range(len(company_Board)): +board_member(company_Board[i]) # Task 1: Knowing someone is a bi-directional relationship -> define the predicate accordingly knows(X, Y) <= knows(Y, X) print("\nWho knows the suspect?\n") print(knows(suspect, Y))
def test(): # test of expressions pyDatalog.load(""" + p(a) # p is a proposition """) assert pyDatalog.ask('p(a)') == set([('a',)]) pyDatalog.assert_fact('p', 'a', 'b') assert pyDatalog.ask('p(a, "b")') == set([('a', 'b')]) pyDatalog.retract_fact('p', 'a', 'b') assert pyDatalog.ask('p(a, "b")') == None """unary facts """ @pyDatalog.program() def unary(): +z() assert ask(z()) == set([()]) + p(a) # check that unary queries work assert ask(p(a)) == set([('a',)]) assert ask(p(X)) == set([('a',)]) assert ask(p(Y)) == set([('a',)]) assert ask(p(_X)) == set([('a',)]) assert ask(p(b)) == None assert ask(p(a) & p(b)) == None + p(b) assert ask(p(X), _fast=True) == set([('a',), ('b',)]) + p(b) # facts are unique assert ask(p(X)) == set([('a',), ('b',)]) - p(b) # retract a unary fact assert ask(p(X)) == set([('a',)]) - p(a) assert ask(p(X)) == None + p(a) # strings and integers + p('c') assert ask(p(c)) == set([('c',)]) + p(1) assert ask(p(1)) == set([(1,)]) + n(None) assert ask(n(X)) == set([(None,)]) assert ask(n(None)) == set([(None,)]) # spaces and uppercase in strings + farmer('Moshe dayan') + farmer('omar') assert ask(farmer(X)) == set([('Moshe dayan',), ('omar',)]) # execute queries in a python program moshe_is_a_farmer = pyDatalog.ask("farmer('Moshe dayan')") assert moshe_is_a_farmer == set([('Moshe dayan',)]) """ binary facts """ @pyDatalog.program() def binary(): + q(a, b) assert ask(q(a, b)) == set([('a', 'b')]) assert ask(q(X, b)) == set([('a', 'b')]) assert ask(q(a, Y)) == set([('a', 'b')]) assert ask(q(a, c)) == None assert ask(q(X, Y)) == set([('a', 'b')]) + q(a,c) assert ask(q(a, Y)) == set([('a', 'b'), ('a', 'c')]) - q(a,c) assert ask(q(a, Y)) == set([('a', 'b')]) assert ask(q(X, X)) == None +q(a, a) assert ask(q(X, X)) == set([('a', 'a')]) -q(a, a) """ (in)equality """ @pyDatalog.program() def equality(): assert ask(X==1) == set([(1,)]) assert ask(X==Y) == None assert ask(X==Y+1) == None assert ask((X==1) & (Y==1) & (X==Y)) == set([(1,1)]) assert ask((X==1) & (Y==2) & (X==Y-1)) == set([(1,2)]) #assert ask((X==1) & (Y==2) & (X+2==Y+1)) == set([(1,2)]) assert ask((X==2) & (Y==X/2)) == set([(2,1)]) assert ask((X==2) & (Y==X//2)) == set([(2,1)]) assert ask((X==1) & (Y==1+X)) == set([(1,2)]) assert ask((X==1) & (Y==1-X)) == set([(1,0)]) assert ask((X==1) & (Y==2*X)) == set([(1,2)]) assert ask((X==2) & (Y==2/X)) == set([(2,1)]) assert ask((X==2) & (Y==2//X)) == set([(2,1)]) """ Conjunctive queries """ @pyDatalog.program() def conjuctive(): assert ask(q(X, Y) & p(X)) == set([('a', 'b')]) assert ask(p(X) & p(a)) == set([('a',),('c',),(1,)]) assert ask(p(X) & p(Y) & (X==Y)) == set([('a', 'a'), ('c', 'c'), (1, 1)]) assert ask(p(X) & p(Y) & (X==Y) & (Y==a)) == set([('a', 'a')]) assert ask(q(X, Y)) == set([('a', 'b')]) assert ask(q(X, Y) & p(X)) == set([('a', 'b')]) @pyDatalog.program() def equality2(): assert ask((X==1) & (X<X+1)) == set([(1,)]) assert ask((X==1) & (Y==X)) == set([(1,1)]) assert ask((X==1) & (Y==X+1)) == set([(1,2)]) assert ask((X==1) & (Y==X+1) & (X<Y)) == set([(1,2)]) assert ask((X==1) & (X<1)) == None assert ask((X==1) & (X<=1)) == set([(1,)]) assert ask((X==1) & (X>1)) == None assert ask((X==1) & (X>=1)) == set([(1,)]) # assert ask(X==(1,2)) == set([((1,2), (1,2))]) assert ask(X in (1,)) == set([(1,)]) assert ask((X==1) & (X not in (2,))) == set([(1,)]) assert ask((X==1) & ~(X in (2,))) == set([(1,)]) assert ask((X==1) & (X not in (1,))) == None assert ask((X==1) & ~(X in (1,))) == None @pyDatalog.program() def equality3(): # equality (must be between parenthesis): s(X) <= (X == a) assert ask(s(X)) == set([('a',)]) s(X) <= (X == 1) assert ask(s(X)) == set([(1,), ('a',)]) s(X, Y) <= p(X) & (X == Y) assert ask(s(a, a)) == set([('a', 'a')]) assert ask(s(a, b)) == None assert ask(s(X,a)) == set([('a', 'a')]) assert ask(s(X, Y)) == set([('a', 'a'),('c', 'c'),(1, 1)]) assert pyDatalog.ask('p(a)') == set([('a',)]) """ clauses """ @pyDatalog.program() def clauses(): p2(X) <= p(X) assert ask(p2(a)) == set([('a',)]) p2(X) <= p(X) r(X, Y) <= p(X) & p(Y) assert ask(r(a, a)) == set([('a', 'a')]) assert ask(r(a, c)) == set([('a', 'c')]) r(X, b) <= p(X) assert ask(r(a, b)) == set([('a', 'b')]) - (r(X, b) <= p(X)) assert ask(r(a, b)) == None # TODO more tests # integer variable for i in range(10): + successor(i+1, i) assert ask(successor(2, 1)) == set([(2, 1)]) # built-in assert abs(-3)==3 assert math.sin(3)==math.sin(3) """ in """ pyDatalog.assert_fact('is_list', (1,2)) @pyDatalog.program() def _in(): assert ((X==1) & (X in (1,2))) == [(1,)] _in(X) <= (X in [1,2]) assert ask(_in(1)) == set([(1,)]) assert ask(_in(9)) == None assert ask(_in(X)) == set([(1,), (2,)]) _in2(X) <= is_list(Y) & (X in Y) assert ask(_in2(X)) == set([(1,), (2,)]) assert ask((Y==(1,2)) & (X==1) & (X in Y)) == set([((1, 2), 1)]) assert ask((Y==(1,2)) & (X==1) & (X in Y+(3,))) == set([((1, 2), 1)]) """ recursion """ @pyDatalog.program() def recursion(): + even(0) even(N) <= successor(N, N1) & odd(N1) odd(N) <= ~ even(N) assert ask(even(0)) == set([(0,)]) assert ask(even(X)) == set([(4,), (10,), (6,), (0,), (2,), (8,)]) assert ask(even(10)) == set([(10,)]) assert ask(odd(1)) == set([(1,)]) assert ask(odd(5)) == set([(5,)]) assert ask(even(5)) == None """ recursion with expressions """ # reset the engine pyDatalog.clear() @pyDatalog.program() def recursive_expression(): predecessor(X,Y) <= (X==Y-1) assert ask(predecessor(X,11)) == set([(10, 11)]) p(X,Z) <= (Y==Z-1) & (X==Y-1) assert ask(p(X,11)) == set([(9, 11)]) # odd and even + even(0) even(N) <= (N > 0) & odd(N-1) assert ask(even(0)) == set([(0,)]) odd(N) <= (N > 0) & ~ even(N) assert ask(even(0)) == set([(0,)]) assert ask(odd(1)) == set([(1,)]) assert ask(odd(5)) == set([(5,)]) assert ask(even(5)) == None assert ask((X==3) & odd(X+2)) == set([(3,)]) # Factorial pyDatalog.clear() @pyDatalog.program() def factorial(): # (factorial[N] == F) <= (N < 1) & (F == -factorial[-N]) # + (factorial[1]==1) # (factorial[N] == F) <= (N > 1) & (F == N*factorial[N-1]) # assert ask(factorial[1] == F) == set([(1, 1)]) # assert ask(factorial[4] == F) == set([(4, 24)]) # assert ask(factorial[-4] == F) == set([(-4, -24)]) pass # Fibonacci pyDatalog.clear() @pyDatalog.program() def fibonacci(): (fibonacci[N] == F) <= (N == 0) & (F==0) (fibonacci[N] == F) <= (N == 1) & (F==1) (fibonacci[N] == F) <= (N > 1) & (F == fibonacci[N-1]+fibonacci[N-2]) assert ask(fibonacci[1] == F) == set([(1, 1)]) assert ask(fibonacci[4] == F) == set([(4, 3)]) assert ask(fibonacci[18] == F) == set([(18, 2584)]) # string manipulation @pyDatalog.program() def _lambda(): split(X, Y,Z) <= (X == Y+'-'+Z) assert ask(split(X, 'a', 'b')) == set([('a-b', 'a', 'b')]) split(X, Y,Z) <= (Y == (lambda X: X.split('-')[0])) & (Z == (lambda X: X.split('-')[1])) assert ask(split('a-b', Y, Z)) == set([('a-b', 'a', 'b')]) assert ask(split(X, 'a', 'b')) == set([('a-b', 'a', 'b')]) (two[X]==Z) <= (Z==X+(lambda X: X)) assert ask(two['A']==Y) == set([('A','AA')]) """ negation """ @pyDatalog.program() def _negation(): +p(a, b) assert ask(~p(X, b)) == None assert ask(~p(X, c)) == set([('X', 'c')]) pyDatalog.load(""" + even(0) even(N) <= (N > 0) & (N1==N-1) & odd(N1) odd(N) <= (N2==N+2) & ~ even(N) & (N2>0) """) assert pyDatalog.ask('~ odd(7)', _fast=True) == None assert pyDatalog.ask('~ odd(2)', _fast=True) == set([(2,)]) assert pyDatalog.ask('odd(3)', _fast=True) == set([(3,)]) assert pyDatalog.ask('odd(3)' ) == set([(3,)]) assert pyDatalog.ask('odd(5)', _fast=True) == set([(5,)]) assert pyDatalog.ask('odd(5)' ) == set([(5,)]) assert pyDatalog.ask('even(5)', _fast=True) == None assert pyDatalog.ask('even(5)' ) == None """ functions """ pyDatalog.clear() @pyDatalog.program() def function(): + (f[a]==b) assert ask(f[X]==Y) == set([('a', 'b')]) assert ask(f[X]==b) == set([('a', 'b')]) #TODO remove 'b' from result assert ask(f[a]==X) == set([('a', 'b')]) assert ask(f[a]==b) == set([('a', 'b')]) + (f[a]==c) assert ask(f[a]==X) == set([('a', 'c')]) + (f[a]==a) assert ask(f[f[a]]==X) == set([('a',)]) assert ask(f[X]==f[a]) == set([('a',)]) assert ask(f[X]==f[a]+'') == set([('a',)]) - (f[a]==a) assert ask(f[f[a]]==X) == None + (f[a]==None) assert (ask(f[a]==X)) == set([('a',None)]) + (f[a]==(1,2)) assert (ask(f[a]==X)) == set([('a',(1,2))]) assert (ask(f[X]==(1,2))) == set([('a',(1,2))]) + (f[a]==c) + (f2[a,x]==b) assert ask(f2[a,x]==b) == set([('a', 'x', 'b')]) + (f2[a,x]==c) assert ask(f2[a,x]==X) == set([('a', 'x', 'c')]) g[X] = f[X]+f[X] assert(ask(g[a]==X)) == set([('a', 'cc')]) h(X,Y) <= (f[X]==Y) assert (ask(h(X,'c'))) == set([('a', 'c')]) assert (ask(h(X,Y))) == set([('a', 'c')]) @pyDatalog.program() def function_comparison(): assert ask(f[X]==Y) == set([('a', 'c')]) assert ask(f[a]<'d') == set([('c',)]) assert ask(f[a]>'a') == set([('c',)]) assert ask(f[a]>='c') == set([('c',)]) assert ask(f[a]>'c') == None assert ask(f[a]<='c') == set([('c',)]) assert ask(f[a]>'c') == None assert ask(f[a] in ['c',]) == set([('c',)]) assert ask((f[X]=='c') & (f[Y]==f[X])) == set([('a', 'a')]) assert ask((f[X]=='c') & (f[Y]==f[X]+'')) == set([('a', 'a')]) assert ask((f[X]=='c') & (f[Y]==(lambda X : 'c'))) == set([('a', 'a')]) assert ask(f[X]==Y+'') == None assert ask((Y=='c') &(f[X]==Y+'')) == set([('c', 'a')]) assert ask((Y=='c') &(f[X]<=Y+'')) == set([('c', 'a')]) assert ask((Y=='c') &(f[X]<Y+'')) == None assert ask((Y=='c') &(f[X]<'d'+Y+'')) == set([('c', 'a')]) assert ask((Y==('a','c')) & (f[X] in Y)) == set([(('a', 'c'), 'a')]) assert ask((Y==('a','c')) & (f[X] in (Y+('z',)))) == set([(('a', 'c'), 'a')]) assert ask(f[X]==f[X]+'') == set([('a',)]) @pyDatalog.program() def function_negation(): assert not(ask(~(f[a]<'d'))) assert not(ask(~(f[X]<'d'))) assert ask(~(f[a] in('d',))) """ aggregates """ pyDatalog.clear() @pyDatalog.program() def sum(): + p(a, c, 1) + p(b, b, 4) + p(a, b, 1) assert(sum(1,2)) == 3 (a_sum[X] == sum(Y, key=Z)) <= p(X, Z, Y) assert ask(a_sum[X]==Y) == set([('a', 2), ('b', 4)]) assert ask(a_sum[a]==X) == set([('a', 2)]) assert ask(a_sum[a]==2) == set([('a', 2)]) assert ask(a_sum[X]==4) == set([('b', 4)]) assert ask(a_sum[c]==X) == None assert ask((a_sum[X]==2) & (p(X, Z, Y))) == set([('a', 'c', 1), ('a', 'b', 1)]) (a_sum2[X] == sum(Y, for_each=X)) <= p(X, Z, Y) assert ask(a_sum2[a]==X) == set([('a', 1)]) (a_sum3[X] == sum(Y, key=(X,Z))) <= p(X, Z, Y) assert ask(a_sum3[X]==Y) == set([('a', 2), ('b', 4)]) assert ask(a_sum3[a]==X) == set([('a', 2)]) @pyDatalog.program() def len(): assert(len((1,2))) == 2 (a_len[X] == len(Z)) <= p(X, Z, Y) assert ask(a_len[X]==Y) == set([('a', 2), ('b', 1)]) assert ask(a_len[a]==X) == set([('a', 2)]) assert ask(a_len[X]==1) == set([('b', 1)]) assert ask(a_len[X]==5) == None (a_lenY[X] == len(Y)) <= p(X, Z, Y) assert ask(a_lenY[a]==X) == set([('a', 1)]) assert ask(a_lenY[c]==X) == None (a_len2[X,Y] == len(Z)) <= p(X, Y, Z) assert ask(a_len2[a,b]==X) == set([('a', 'b', 1)]) assert ask(a_len2[a,X]==Y) == set([('a', 'b', 1), ('a', 'c', 1)]) + q(a, c, 1) + q(a, b, 2) + q(b, b, 4) @pyDatalog.program() def concat(): (a_concat[X] == concat(Y, key=Z, sep='+')) <= q(X, Y, Z) assert ask(a_concat[X]==Y) == set([('b', 'b'), ('a', 'c+b')]) assert ask(a_concat[a]=='c+b') == set([('a', 'c+b')]) assert ask(a_concat[a]==X) == set([('a', 'c+b')]) assert ask(a_concat[X]==b) == set([('b', 'b')]) (a_concat2[X] == concat(Y, order_by=(Z,), sep='+')) <= q(X, Y, Z) assert ask(a_concat2[a]==X) == set([('a', 'c+b')]) (a_concat3[X] == concat(Y, key=(-Z,), sep='-')) <= q(X, Y, Z) assert ask(a_concat3[a]==X) == set([('a', 'b-c')]) @pyDatalog.program() def min(): assert min(1,2) == 1 (a_min[X] == min(Y, key=Z)) <= q(X, Y, Z) assert ask(a_min[X]==Y) == set([('b', 'b'), ('a', 'c')]) assert ask(a_min[a]=='c') == set([('a', 'c')]) assert ask(a_min[a]==X) == set([('a', 'c')]) assert ask(a_min[X]=='b') == set([('b', 'b')]) (a_minD[X] == min(Y, order_by=-Z)) <= q(X, Y, Z) assert ask(a_minD[a]==X) == set([('a', 'b')]) (a_min2[X, Y] == min(Z, key=(X,Y))) <= q(X, Y, Z) assert ask(a_min2[Y, b]==X) == set([('a', 'b', 2),('b', 'b', 4)]) assert ask(a_min2[Y, Y]==X) == set([('b', 'b', 4)]), "a_min2" (a_min3[Y] == min(Z, key=(-X,Z))) <= q(X, Y, Z) assert ask(a_min3[b]==Y) == set([('b', 4)]), "a_min3" @pyDatalog.program() def max(): assert max(1,2) == 2 (a_max[X] == max(Y, key=-Z)) <= q(X, Y, Z) assert ask(a_max[a]==X) == set([('a', 'c')]) (a_maxD[X] == max(Y, order_by=Z)) <= q(X, Y, Z) assert ask(a_maxD[a]==X) == set([('a', 'b')]) @pyDatalog.program() def rank(): (a_rank1[Z] == rank(for_each=Z, order_by=Z)) <= q(X, Y, Z) assert ask(a_rank1[X]==Y) == set([(1, 0), (2, 0), (4, 0)]) assert ask(a_rank1[X]==0) == set([(1, 0), (2, 0), (4, 0)]) assert ask(a_rank1[1]==X) == set([(1, 0)]) assert ask(a_rank1[1]==0) == set([(1, 0)]) assert ask(a_rank1[1]==1) == None # rank (a_rank[X,Y] == rank(for_each=(X,Y2), order_by=Z2)) <= q(X, Y, Z) & q(X,Y2,Z2) assert ask(a_rank[X,Y]==Z) == set([('a', 'b', 1), ('a', 'c', 0), ('b', 'b', 0)]) assert ask(a_rank[a,b]==1) == set([('a', 'b', 1)]) assert ask(a_rank[a,b]==Y) == set([('a', 'b', 1)]) assert ask(a_rank[a,X]==0) == set([('a', 'c', 0)]) assert ask(a_rank[a,X]==Y) == set([('a', 'b', 1), ('a', 'c', 0)]) assert ask(a_rank[X,Y]==1) == set([('a', 'b', 1)]) assert ask(a_rank[a,y]==Y) == None # reversed (b_rank[X,Y] == rank(for_each=(X,Y2), order_by=-Z2)) <= q(X, Y, Z) & q(X,Y2,Z2) assert ask(b_rank[X,Y]==Z) == set([('a', 'b', 0), ('a', 'c', 1), ('b', 'b', 0)]) assert ask(b_rank[a,b]==0) == set([('a', 'b', 0)]) assert ask(b_rank[a,b]==Y) == set([('a', 'b', 0)]) assert ask(b_rank[a,X]==1) == set([('a', 'c', 1)]) assert ask(b_rank[a,X]==Y) == set([('a', 'b', 0), ('a', 'c', 1)]) assert ask(b_rank[X,Y]==0) == set([('a', 'b', 0), ('b', 'b', 0)]) assert ask(b_rank[a,y]==Y) == None @pyDatalog.program() def running_sum(): # running_sum (a_run_sum[X,Y] == running_sum(Z2, for_each=(X,Y2), order_by=Z2)) <= q(X, Y, Z) & q(X,Y2,Z2) assert ask(a_run_sum[X,Y]==Z) == set([('a', 'b', 3), ('a', 'c', 1), ('b', 'b', 4)]) assert ask(a_run_sum[a,b]==3) == set([('a', 'b', 3)]) assert ask(a_run_sum[a,b]==Y) == set([('a', 'b', 3)]) assert ask(a_run_sum[a,X]==1) == set([('a', 'c', 1)]) assert ask(a_run_sum[a,X]==Y) == set([('a', 'b', 3), ('a', 'c', 1)]) assert ask(a_run_sum[X,Y]==4) == set([('b', 'b', 4)]) assert ask(a_run_sum[a,y]==Y) == None (b_run_sum[X,Y] == running_sum(Z2, for_each=(X,Y2), order_by=-Z2)) <= q(X, Y, Z) & q(X,Y2,Z2) assert ask(b_run_sum[X,Y]==Z) == set([('a', 'b', 2), ('a', 'c', 3), ('b', 'b', 4)]) assert ask(b_run_sum[a,b]==2) == set([('a', 'b', 2)]) assert ask(b_run_sum[a,b]==Y) == set([('a', 'b', 2)]) assert ask(b_run_sum[a,X]==3) == set([('a', 'c', 3)]) assert ask(b_run_sum[a,X]==Y) == set([('a', 'b', 2), ('a', 'c', 3)]) assert ask(b_run_sum[X,Y]==4) == set([('b', 'b', 4)]) assert ask(b_run_sum[a,y]==Y) == None """ simple in-line queries """ X = pyDatalog.Variable() assert ((X==1) >= X) == 1 assert ((X==1) & (X!=2) >= X) == 1 assert set(X._in((1,2))) == set([(1,),(2,)]) assert ((X==1) & (X._in ((1,2)))) == [(1,)] """ interface with python classes """ class A(pyDatalog.Mixin): def __init__(self, b): super(A, self).__init__() self.b = b def __repr__(self): return self.b @pyDatalog.program() # indicates that the following method contains pyDatalog clauses def _(): (A.c[X]==N) <= (A.b[X]==N) (A.len[X]==len(N)) <= (A.b[X]==N) @classmethod def _pyD_x1(cls, X): if X.is_const() and X.id.b == 'za': yield (X.id,) else: for X in pyDatalog.metaMixin.__refs__[cls]: if X.b == 'za': yield (X,) a = A('a') b = A('b') assert a.c == 'a' X, Y = pyDatalog.variables(2) assert (A.c[X]=='a') == [(a,)] assert (A.c[X]=='a')[0] == (a,) assert list(X.data) == [a] assert X.v() == a assert ((A.c[a]==X) >= X) == 'a' assert ((A.c[a]==X) & (A.c[a]==X) >= X) == 'a' assert ((A.c[a]==X) & (A.c[b]==X) >= X) == None (A.c[X]=='b') & (A.b[X]=='a') assert list(X.data) == [] (A.c[X]=='a') & (A.b[X]=='a') assert list(X.data) == [a] result = (A.c[X]=='a') & (A.b[X]=='a') assert result == [(a,)] assert (A.c[a] == 'a') == [()] assert (A.b[a] == 'a') == [()] assert (A.c[a]=='a') & (A.b[a]=='a') == [()] assert (A.b[a]=='f') == [] assert ((A.c[a]=='a') & (A.b[a]=='f')) == [] """ filters on python classes """ assert (A.b[X]!=Y) == [(a, None), (b, None)] assert (A.b[X]!='a') == [(b,)] assert (A.b[X]!='z') == [(a,), (b,)] assert (A.b[a]!='a') == [] assert list(A.b[b]!='a') == [()] assert ((A.b[b]!='a') & (A.b[b]!='z')) == [()] assert (A.b[X]<Y) == [(a, None), (b, None)] assert (A.b[X]<'a') == [] assert (A.b[X]<'z') == [(a,), (b,)] assert (A.b[a]<'b') == [()] assert (A.b[b]<'a') == [] assert ((A.b[b]<'z') & (A.b[b]!='z')) == [()] assert (A.b[X]<='a') == [(a,)] assert (A.b[X]<='z') == [(a,), (b,)] assert (A.b[a]<='b') == [()] assert (A.b[b]<='a') == [] assert ((A.b[b]<='z') & (A.b[b]!='z')) == [()] assert (A.b[X]>'a') == [(b,)] assert (A.b[X]>='a') == [(a,), (b,)] assert (A.c[X]<='a') == [(a,)] assert (A.c[X]<='a'+'') == [(a,)] assert (A.c[X]._in(('a',))) == [(a,)] assert (A.c[X]._in(('a',)+('z',))) == [(a,)] assert ((Y==('a',)) & (A.c[X]._in(Y))) == [(('a',), a)] # TODO make ' in ' work assert ((Y==('a',)) & (A.c[X]._in(Y+('z',)))) == [(('a',), a)] # TODO make ' in ' work assert (A.c[X]._in(('z',))) == [] # more complex queries assert ((Y=='a') & (A.b[X]!=Y)) == [('a', b)] # order of appearance of the variables ! assert (A.len[X]==Y) == [(b, 1), (a, 1)] assert (A.len[a]==Y) == [(1,)] """ subclass """ class Z(A): def __init__(self, z): super(Z, self).__init__(z+'a') self.z = z def __repr__(self): return self.z @pyDatalog.program() # indicates that the following method contains pyDatalog clauses def _(): (Z.w[X]==N) <= (Z.z[X]!=N) @classmethod def _pyD_query(cls, pred_name, args): if pred_name == 'Z.pred': if args[0].is_const() and args[0].id.b != 'za': yield (args[0].id,) else: for X in pyDatalog.metaMixin.__refs__[cls]: if X.b != 'za': yield (X,) else: raise AttributeError z = Z('z') assert z.z == 'z' assert (Z.z[X]=='z') == [(z,)] assert ((Z.z[X]=='z') & (Z.z[X]>'a')) == [(z,)] assert list(X.data) == [z] try: a.z == 'z' except Exception as e: e_message = e.message if hasattr(e, 'message') else e.args[0] if e_message != "Predicate without definition (or error in resolver): A.z[1]==/2": print(e_message) else: assert False try: (Z.z[a] == 'z') == None except Exception as e: e_message = e.message if hasattr(e, 'message') else e.args[0] if e_message != "Object is incompatible with the class that is queried.": print(e_message) else: assert False assert (Z.b[X]==Y) == [(z, 'za')] assert (Z.c[X]==Y) == [(z, 'za')] assert ((Z.c[X]==Y) & (Z.c[X]>'a')) == [(z, 'za')] assert (Z.c[X]>'a') == [(z,)] assert ((Z.c[X]>'a') & (A.c[X]=='za')) == [(z,)] assert (A.c[X]=='za') == [(z,)] assert (A.c[z]=='za') == [()] assert (z.b) == 'za' assert (z.c) == 'za' w = Z('w') w = Z('w') # duplicated to test __refs__[cls] assert(Z.x(X)) == [(z,)] assert not (~Z.x(z)) assert ~Z.x(w) assert ~ (Z.z[w]=='z') assert(Z.pred(X)) == [(w,)] # not duplicated ! assert(Z.pred(X) & ~ (Z.z[X]>='z')) == [(w,)] assert(Z.x(X) & ~(Z.pred(X))) == [(z,)] assert (Z.len[X]==Y) == [(w, 1), (z, 1)] assert (Z.len[z]==Y) == [(1,)] # TODO print (A.b[w]==Y) """ python resolvers """ @pyDatalog.predicate() def p(X,Y): yield (1,2) yield (2,3) assert pyDatalog.ask('p(X,Y)') == set([(1, 2), (2, 3)]) assert pyDatalog.ask('p(1,Y)') == set([(1, 2)]) assert pyDatalog.ask('p(1,2)') == set([(1, 2)]) """ error detection """ @pyDatalog.program() def _(): pass error = False try: _() except: error = True assert error def assert_error(code, message='^$'): _error = False try: pyDatalog.load(code) except Exception as e: e_message = e.message if hasattr(e, 'message') else e.args[0] # python 2 and 3 if not re.match(message, e_message): print(e_message) _error = True assert _error def assert_ask(code, message='^$'): _error = False try: pyDatalog.ask(code) except Exception as e: e_message = e.message if hasattr(e, 'message') else e.args[0] if not re.match(message, e_message): print(e_message) _error = True assert _error assert_error('ask(z(a),True)', 'Too many arguments for ask \!') assert_error('ask(z(a))', 'Predicate without definition \(or error in resolver\): z/1') assert_error("+ farmer(farmer(moshe))", "Syntax error: Literals cannot have a literal as argument : farmer\[\]") assert_error("+ manager[Mary]==John", "Left-hand side of equality must be a symbol or function, not an expression.") assert_error("manager[X]==Y <= (X==Y)", "Syntax error: please verify parenthesis around \(in\)equalities") assert_error("p(X) <= (Y==2)", "Can't create clause") assert_error("p(X) <= X==1 & X==2", "Syntax error: please verify parenthesis around \(in\)equalities") assert_error("p(X) <= (manager[X]== min(X))", "Error: argument missing in aggregate") assert_error("p(X) <= (manager[X]== max(X, order_by=X))", "Aggregation cannot appear in the body of a clause") assert_error("q(min(X, order_by=X)) <= p(X)", "Syntax error: Incorrect use of aggregation\.") assert_error("manager[X]== min(X, order_by=X) <= manager(X)", "Syntax error: please verify parenthesis around \(in\)equalities") assert_error("(manager[X]== min(X, order_by=X+2)) <= manager(X)", "order_by argument of aggregate must be variable\(s\), not expression\(s\).") assert_error("ask(X<1)", 'Error: left hand side of comparison must be bound: =X<1/1') assert_error("ask(X<Y)", 'Error: left hand side of comparison must be bound: =X<Y/2') assert_error("ask(1<Y)", 'Error: left hand side of comparison must be bound: =Y>1/1') assert_error("ask( (A.c[X]==Y) & (Z.c[X]==Y))", "TypeError: First argument of Z.c\[1\]==\('.','.'\) must be a Z, not a A ") assert_ask("A.u[X]==Y", "Predicate without definition \(or error in resolver\): A.u\[1\]==/2") assert_ask("A.u[X,Y]==Z", "Predicate without definition \(or error in resolver\): A.u\[2\]==/3") assert_error('(a_sum[X] == sum(Y, key=Y)) <= p(X, Z, Y)', "Error: Duplicate definition of aggregate function.") assert_error('(two(X)==Z) <= (Z==X+(lambda X: X))', 'Syntax error near equality: consider using brackets. two\(X\)') assert_error('p(X) <= sum(X, key=X)', 'Invalid body for clause') assert_error('ask(- manager[X]==1)', "Left-hand side of equality must be a symbol or function, not an expression.") assert_error("p(X) <= (X=={})", "unhashable type: 'dict'") """ SQL Alchemy """ from sqlalchemy import create_engine from sqlalchemy import Column, Integer, String, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship engine = create_engine('sqlite:///:memory:', echo=False) # create database in memory Session = sessionmaker(bind=engine) session = Session() Base = declarative_base(cls=pyDatalog.Mixin, metaclass=pyDatalog.sqlMetaMixin) Base.session = session class Employee(Base): # --> Employee inherits from the Base class __tablename__ = 'employee' name = Column(String, primary_key=True) manager_name = Column(String, ForeignKey('employee.name')) salary = Column(Integer) def __init__(self, name, manager_name, salary): super(Employee, self).__init__() self.name = name self.manager_name = manager_name # direct manager of the employee, or None self.salary = salary # monthly salary of the employee def __repr__(self): # specifies how to display the employee return "Employee: %s" % self.name @pyDatalog.program() # --> the following function contains pyDatalog clauses def Employee(): (Employee.manager[X]==Y) <= (Employee.manager_name[X]==Z) & (Z==Employee.name[Y]) # the salary class of employee X is computed as a function of his/her salary # this statement is a logic equality, not an assignment ! Employee.salary_class[X] = Employee.salary[X]//1000 # all the indirect managers of employee X are derived from his manager, recursively Employee.indirect_manager(X,Y) <= (Employee.manager[X]==Y) & (Y != None) Employee.indirect_manager(X,Y) <= (Employee.manager[X]==Z) & Employee.indirect_manager(Z,Y) & (Y != None) # count the number of reports of X (Employee.report_count[X] == len(Y)) <= Employee.indirect_manager(Y,X) Employee.p(X,Y) <= (Y <= Employee.salary[X] + 1) Base.metadata.create_all(engine) John = Employee('John', None, 6800) Mary = Employee('Mary', 'John', 6300) Sam = Employee('Sam', 'Mary', 5900) session.add(John) session.add(Mary) session.add(Sam) session.commit() assert (John.salary_class ==6) X = pyDatalog.Variable() result = (Employee.salary[X] == 6300) # notice the similarity to a pyDatalog query assert result == [(Mary,), ] assert (X._value() == [Mary,]) # prints [Employee: Mary] assert (X.v() == Mary) # prints Employee:Mary result = (Employee.indirect_manager(Mary, X)) assert result == [(John,), ] assert (X.v() == John) # prints [Employee: John] Mary.salary_class = ((Employee.salary_class[Mary]==X) >= X) Mary.salary = 10000 assert Mary.salary_class != ((Employee.salary_class[Mary]==X) >= X) X, Y, N = pyDatalog.variables(3) result = (Employee.salary[X]==6800) & (Employee.name[X]==N) assert result == [(John,'John'), ] assert N.v() == 'John' result = (Employee.salary[X]==Employee.salary[X]) assert result == [(John,), (Mary,), (Sam,)] result = (Employee.p(X,1)) assert result == [(John,), (Mary,), (Sam,)] result = (Employee.salary[X]<Employee.salary[X]+1) assert result == [(John,), (Mary,), (Sam,)] result = (Employee.salary[John]==N) & Employee.p(John, N) assert result == [(6800,)] result = (Employee.salary[X]==6800) & (Employee.salary[X]==N) & Employee.p(X, N) assert result == [(John, 6800)] """
def tearDown(self): from pyDatalog import pyDatalog pyDatalog.clear()
def get_scores(hicno, sex, dob, month_of_eligibility, year_of_eligibility, RAF_type=None, lob=None, orec=0, medicaid=True, codes=[]): try: global model RAF_type = RAF_type.upper() combined_df = [] combined_score = 0 for params in select_model(year_of_eligibility, RAF_type, lob): print(params) try: _, weight, model_name, coefficients_file_path, _payment_year = params model = importlib.import_module( "models.{}.hcc".format(model_name)) except: print("invalid RAF_type: {}".format(RAF_type)) print(traceback.format_exc()) return try: coefficients_df = pd.read_csv( coefficients_file_path, names=['raf_type', 'coeff', 'contribution_category'], float_precision='high') coefficients_df['raf_type'] = coefficients_df[ 'raf_type'].str.upper() # print(coefficients_df.head()) except: print('coefficients file not found : {}'.format( coefficients_file_path)) def get_coeff(x): # print(x) temp = coefficients_df[coefficients_df['raf_type'] == x].values[0] return temp[2], temp[1] formatted_dob = format_date(dob) age_upto = "-".join( [year_of_eligibility, month_of_eligibility, '01']) # print(age_upto) formatted_age_upto = format_date(age_upto) formatted_sex = sex_lookup[sex.lower()] if orec not in [0, 1, 2, 3]: print("invaild original_reason_entitlement : {}".format(orec)) return else: temp_orec = orec person = model.Beneficiary( hicno=hicno, sex=formatted_sex, dob=formatted_dob, age_upto=formatted_age_upto, original_reason_entitlement=temp_orec, medicaid=medicaid, ) for code in codes: add_diagnosis_code(person, code) pyDatalog.create_terms("Vars, ScoreVar") temp_raf_type = raf_type_lookup[RAF_type][0] hcc_reg_variables_list = model.regvars(person, temp_raf_type, model.Vars) t = raf_type_lookup[RAF_type][1] out_df = {} out_df['RAF_TYPE'] = RAF_type out_df['raf_contribution'] = { 'Demographic': [], 'Clinical': [], 'Entitlement Class': [] } score = 0 if len(hcc_reg_variables_list) > 0: condition_categories = hcc_reg_variables_list[0][0].split(',') for temp_category in condition_categories: formatted_category = "{}_{}".format( RAF_type, temp_category.upper()) category, temp_coeff = get_coeff(formatted_category) out_df['raf_contribution'][category].append( {temp_category: temp_coeff}) score += temp_coeff score = float(format(score, '0.3f')) combined_score += score * weight combined_score = float(format(combined_score, '0.3f')) combined_df.append({ 'Model': model_name.split('_')[0], 'Payment_Year': _payment_year, 'RAF_TYPE': out_df['RAF_TYPE'], 'Raf_Contribution': out_df['raf_contribution'], 'Score': score }) pyDatalog.clear() final_df = {'models': combined_df, 'final_score': combined_score} return final_df except: print(traceback.format_exc()) return None
pyDatalog.create_terms("isParent, isChild, isSibling, X, Y, Z, c" ) # Datalog-терми (змінні з великої букви) +isParent("Ivan", "Petro") # додати факт (isParent - предикат) +isParent("Ivan", "Stepan") # предикати можуть бути кирилицею: globals()['назва'] # правила логічного виведення ("<=" - "якщо, то"): isChild(X, Y) <= isParent(Y, X) # якщо Y батько X, то X дитина Y isSibling(X, Y) <= isParent(Z, X) & isParent(Z, Y) & ~(X == Y) # запити: print isChild("Petro", X).data # знайти батька Петра print isChild(X, "Ivan").data # знайти усіх дітей Івана print isSibling(X, Y).data # знайти усіх братів (c[X] == len_(Y)) <= (isParent(X, Y)) print(c[X] == Y).data # знайти кількість дітей батька X pyDatalog.clear() # очистити базу даних pyDatalog.create_terms("abs, f, g") # abs - вбудована функція print((X == [1, 2, -3]) & (Y == abs(X[2]) + 1)).data # знайти X,Y print(X.in_(range(5)) & Y.in_(range(5)) & (Z == X + Y) & (Z < 2)).data # знайти X,Y f["Ivan"] = 2 # факт (f - предикат) f["Petro"] = 0 #+(f['Petro'] == 0) # або print((f[X] == Y) & (Y > 0)).data # знайти X,Y del f["Ivan"] # видалити (g[X] == 3) <= (X == "Ivan") print((g[X] == Y)).data # знайти X,Y """ [(u'Ivan',)] [(u'Petro',), (u'Stepan',)] [(u'Petro', u'Stepan'), (u'Stepan', u'Petro')]
import sys import time import random from algorithms import Alignment from pyDatalog import pyDatalog # create some python functions as helpers, because pyDatalog allows this # string length function def strlen(x): if isinstance(x,basestring): return len(x) return 0 pyDatalog.clear() pyDatalog.create_terms('seedsa,seedsb,r,s,strlen,X,Y,Z,res,A,B,SL,N') def build(a,b,k): # creates table of (Z,X) pairs where Z is original sequence and X is seed (kmer) of length SL + r(a) seedsa(Z,X) <= r(Z) & (SL==k) & (N.in_(range_(strlen(Z)))) & (X==Z[N:N+SL]) & (strlen(X)==SL) #print(seedsa(Z,X)) + s(b) seedsb(Z,X) <= s(Z) & (SL==k) & (N.in_(range_(strlen(Z)))) & (X==Z[N:N+SL]) & (strlen(X)==SL) #print(seedsb(Z,X)) def ask(): # seeds query function res(X) <= seedsa(A,Y) & seedsb(B,Z) & (Z==Y) & (X==Z) #print(res(X)) print(len_(res(X))==Y)
def close(self): pyDatalog.clear()
def test(): # test of expressions pyDatalog.load(""" + p(a) # p is a proposition """) assert pyDatalog.ask('p(a)') == set([('a', )]) pyDatalog.assert_fact('p', 'a', 'b') assert pyDatalog.ask('p(a, "b")') == set([('a', 'b')]) pyDatalog.retract_fact('p', 'a', 'b') assert pyDatalog.ask('p(a, "b")') == None """unary facts """ @pyDatalog.program() def unary(): +z() assert ask(z()) == set([()]) +p(a) # check that unary queries work assert ask(p(a)) == set([('a', )]) assert ask(p(X)) == set([('a', )]) assert ask(p(Y)) == set([('a', )]) assert ask(p(_X)) == set([('a', )]) assert ask(p(b)) == None assert ask(p(a) & p(b)) == None +p(b) assert ask(p(X), _fast=True) == set([('a', ), ('b', )]) +p(b) # facts are unique assert ask(p(X)) == set([('a', ), ('b', )]) -p(b) # retract a unary fact assert ask(p(X)) == set([('a', )]) -p(a) assert ask(p(X)) == None +p(a) # strings and integers +p('c') assert ask(p(c)) == set([('c', )]) +p(1) assert ask(p(1)) == set([(1, )]) +n(None) assert ask(n(X)) == set([(None, )]) assert ask(n(None)) == set([(None, )]) # spaces and uppercase in strings +farmer('Moshe dayan') +farmer('omar') assert ask(farmer(X)) == set([('Moshe dayan', ), ('omar', )]) # execute queries in a python program moshe_is_a_farmer = pyDatalog.ask("farmer('Moshe dayan')") assert moshe_is_a_farmer == set([('Moshe dayan', )]) """ binary facts """ @pyDatalog.program() def binary(): +q(a, b) assert ask(q(a, b)) == set([('a', 'b')]) assert ask(q(X, b)) == set([('a', 'b')]) assert ask(q(a, Y)) == set([('a', 'b')]) assert ask(q(a, c)) == None assert ask(q(X, Y)) == set([('a', 'b')]) +q(a, c) assert ask(q(a, Y)) == set([('a', 'b'), ('a', 'c')]) -q(a, c) assert ask(q(a, Y)) == set([('a', 'b')]) assert ask(q(X, X)) == None +q(a, a) assert ask(q(X, X)) == set([('a', 'a')]) -q(a, a) """ (in)equality """ @pyDatalog.program() def equality(): assert ask(X == 1) == set([(1, )]) assert ask(X == Y) == None assert ask(X == Y + 1) == None assert ask((X == 1) & (Y == 1) & (X == Y)) == set([(1, 1)]) assert ask((X == 1) & (Y == 2) & (X == Y - 1)) == set([(1, 2)]) #assert ask((X==1) & (Y==2) & (X+2==Y+1)) == set([(1,2)]) assert ask((X == 2) & (Y == X / 2)) == set([(2, 1)]) assert ask((X == 2) & (Y == X // 2)) == set([(2, 1)]) assert ask((X == 1) & (Y == 1 + X)) == set([(1, 2)]) assert ask((X == 1) & (Y == 1 - X)) == set([(1, 0)]) assert ask((X == 1) & (Y == 2 * X)) == set([(1, 2)]) assert ask((X == 2) & (Y == 2 / X)) == set([(2, 1)]) assert ask((X == 2) & (Y == 2 // X)) == set([(2, 1)]) """ Conjunctive queries """ @pyDatalog.program() def conjuctive(): assert ask(q(X, Y) & p(X)) == set([('a', 'b')]) assert ask(p(X) & p(a)) == set([('a', ), ('c', ), (1, )]) assert ask(p(X) & p(Y) & (X == Y)) == set([('a', 'a'), ('c', 'c'), (1, 1)]) assert ask(p(X) & p(Y) & (X == Y) & (Y == a)) == set([('a', 'a')]) assert ask(q(X, Y)) == set([('a', 'b')]) assert ask(q(X, Y) & p(X)) == set([('a', 'b')]) @pyDatalog.program() def equality2(): assert ask((X == 1) & (X < X + 1)) == set([(1, )]) assert ask((X == 1) & (Y == X)) == set([(1, 1)]) assert ask((X == 1) & (Y == X + 1)) == set([(1, 2)]) assert ask((X == 1) & (Y == X + 1) & (X < Y)) == set([(1, 2)]) assert ask((X == 1) & (X < 1)) == None assert ask((X == 1) & (X <= 1)) == set([(1, )]) assert ask((X == 1) & (X > 1)) == None assert ask((X == 1) & (X >= 1)) == set([(1, )]) # assert ask(X==(1,2)) == set([((1,2), (1,2))]) assert ask(X in (1, )) == set([(1, )]) assert ask((X == 1) & (X not in (2, ))) == set([(1, )]) assert ask((X == 1) & ~(X in (2, ))) == set([(1, )]) assert ask((X == 1) & (X not in (1, ))) == None assert ask((X == 1) & ~(X in (1, ))) == None @pyDatalog.program() def equality3(): # equality (must be between parenthesis): s(X) <= (X == a) assert ask(s(X)) == set([('a', )]) s(X) <= (X == 1) assert ask(s(X)) == set([(1, ), ('a', )]) s(X, Y) <= p(X) & (X == Y) assert ask(s(a, a)) == set([('a', 'a')]) assert ask(s(a, b)) == None assert ask(s(X, a)) == set([('a', 'a')]) assert ask(s(X, Y)) == set([('a', 'a'), ('c', 'c'), (1, 1)]) assert pyDatalog.ask('p(a)') == set([('a', )]) """ clauses """ @pyDatalog.program() def clauses(): p2(X) <= p(X) assert ask(p2(a)) == set([('a', )]) p2(X) <= p(X) r(X, Y) <= p(X) & p(Y) assert ask(r(a, a)) == set([('a', 'a')]) assert ask(r(a, c)) == set([('a', 'c')]) r(X, b) <= p(X) assert ask(r(a, b)) == set([('a', 'b')]) -(r(X, b) <= p(X)) assert ask(r(a, b)) == None # TODO more tests # integer variable for i in range(10): +successor(i + 1, i) assert ask(successor(2, 1)) == set([(2, 1)]) # built-in assert abs(-3) == 3 assert math.sin(3) == math.sin(3) """ in """ pyDatalog.assert_fact('is_list', (1, 2)) @pyDatalog.program() def _in(): assert ((X == 1) & (X in (1, 2))) == [(1, )] _in(X) <= (X in [1, 2]) assert ask(_in(1)) == set([(1, )]) assert ask(_in(9)) == None assert ask(_in(X)) == set([(1, ), (2, )]) _in2(X) <= is_list(Y) & (X in Y) assert ask(_in2(X)) == set([(1, ), (2, )]) assert ask((Y == (1, 2)) & (X == 1) & (X in Y)) == set([((1, 2), 1)]) assert ask((Y == (1, 2)) & (X == 1) & (X in Y + (3, ))) == set([ ((1, 2), 1) ]) """ recursion """ @pyDatalog.program() def recursion(): +even(0) even(N) <= successor(N, N1) & odd(N1) odd(N) <= ~even(N) assert ask(even(0)) == set([(0, )]) assert ask(even(X)) == set([(4, ), (10, ), (6, ), (0, ), (2, ), (8, )]) assert ask(even(10)) == set([(10, )]) assert ask(odd(1)) == set([(1, )]) assert ask(odd(5)) == set([(5, )]) assert ask(even(5)) == None """ recursion with expressions """ # reset the engine pyDatalog.clear() @pyDatalog.program() def recursive_expression(): predecessor(X, Y) <= (X == Y - 1) assert ask(predecessor(X, 11)) == set([(10, 11)]) p(X, Z) <= (Y == Z - 1) & (X == Y - 1) assert ask(p(X, 11)) == set([(9, 11)]) # odd and even +even(0) even(N) <= (N > 0) & odd(N - 1) assert ask(even(0)) == set([(0, )]) odd(N) <= (N > 0) & ~even(N) assert ask(even(0)) == set([(0, )]) assert ask(odd(1)) == set([(1, )]) assert ask(odd(5)) == set([(5, )]) assert ask(even(5)) == None assert ask((X == 3) & odd(X + 2)) == set([(3, )]) # Factorial pyDatalog.clear() @pyDatalog.program() def factorial(): # (factorial[N] == F) <= (N < 1) & (F == -factorial[-N]) # + (factorial[1]==1) # (factorial[N] == F) <= (N > 1) & (F == N*factorial[N-1]) # assert ask(factorial[1] == F) == set([(1, 1)]) # assert ask(factorial[4] == F) == set([(4, 24)]) # assert ask(factorial[-4] == F) == set([(-4, -24)]) pass # Fibonacci pyDatalog.clear() @pyDatalog.program() def fibonacci(): (fibonacci[N] == F) <= (N == 0) & (F == 0) (fibonacci[N] == F) <= (N == 1) & (F == 1) (fibonacci[N] == F) <= (N > 1) & (F == fibonacci[N - 1] + fibonacci[N - 2]) assert ask(fibonacci[1] == F) == set([(1, 1)]) assert ask(fibonacci[4] == F) == set([(4, 3)]) assert ask(fibonacci[18] == F) == set([(18, 2584)]) # string manipulation @pyDatalog.program() def _lambda(): split(X, Y, Z) <= (X == Y + '-' + Z) assert ask(split(X, 'a', 'b')) == set([('a-b', 'a', 'b')]) split(X, Y, Z) <= (Y == (lambda X: X.split('-')[0])) & (Z == ( lambda X: X.split('-')[1])) assert ask(split('a-b', Y, Z)) == set([('a-b', 'a', 'b')]) assert ask(split(X, 'a', 'b')) == set([('a-b', 'a', 'b')]) (two[X] == Z) <= (Z == X + (lambda X: X)) assert ask(two['A'] == Y) == set([('A', 'AA')]) """ negation """ @pyDatalog.program() def _negation(): +p(a, b) assert ask(~p(X, b)) == None assert ask(~p(X, c)) == set([('X', 'c')]) pyDatalog.load(""" + even(0) even(N) <= (N > 0) & (N1==N-1) & odd(N1) odd(N) <= (N2==N+2) & ~ even(N) & (N2>0) """) assert pyDatalog.ask('~ odd(7)', _fast=True) == None assert pyDatalog.ask('~ odd(2)', _fast=True) == set([(2, )]) assert pyDatalog.ask('odd(3)', _fast=True) == set([(3, )]) assert pyDatalog.ask('odd(3)') == set([(3, )]) assert pyDatalog.ask('odd(5)', _fast=True) == set([(5, )]) assert pyDatalog.ask('odd(5)') == set([(5, )]) assert pyDatalog.ask('even(5)', _fast=True) == None assert pyDatalog.ask('even(5)') == None """ functions """ pyDatalog.clear() @pyDatalog.program() def function(): +(f[a] == b) assert ask(f[X] == Y) == set([('a', 'b')]) assert ask(f[X] == b) == set([('a', 'b') ]) #TODO remove 'b' from result assert ask(f[a] == X) == set([('a', 'b')]) assert ask(f[a] == b) == set([('a', 'b')]) +(f[a] == c) assert ask(f[a] == X) == set([('a', 'c')]) +(f[a] == a) assert ask(f[f[a]] == X) == set([('a', )]) assert ask(f[X] == f[a]) == set([('a', )]) assert ask(f[X] == f[a] + '') == set([('a', )]) -(f[a] == a) assert ask(f[f[a]] == X) == None +(f[a] == None) assert (ask(f[a] == X)) == set([('a', None)]) +(f[a] == (1, 2)) assert (ask(f[a] == X)) == set([('a', (1, 2))]) assert (ask(f[X] == (1, 2))) == set([('a', (1, 2))]) +(f[a] == c) +(f2[a, x] == b) assert ask(f2[a, x] == b) == set([('a', 'x', 'b')]) +(f2[a, x] == c) assert ask(f2[a, x] == X) == set([('a', 'x', 'c')]) g[X] = f[X] + f[X] assert (ask(g[a] == X)) == set([('a', 'cc')]) h(X, Y) <= (f[X] == Y) assert (ask(h(X, 'c'))) == set([('a', 'c')]) assert (ask(h(X, Y))) == set([('a', 'c')]) @pyDatalog.program() def function_comparison(): assert ask(f[X] == Y) == set([('a', 'c')]) assert ask(f[a] < 'd') == set([('c', )]) assert ask(f[a] > 'a') == set([('c', )]) assert ask(f[a] >= 'c') == set([('c', )]) assert ask(f[a] > 'c') == None assert ask(f[a] <= 'c') == set([('c', )]) assert ask(f[a] > 'c') == None assert ask(f[a] in [ 'c', ]) == set([('c', )]) assert ask((f[X] == 'c') & (f[Y] == f[X])) == set([('a', 'a')]) assert ask((f[X] == 'c') & (f[Y] == f[X] + '')) == set([('a', 'a')]) assert ask((f[X] == 'c') & (f[Y] == (lambda X: 'c'))) == set([('a', 'a')]) assert ask(f[X] == Y + '') == None assert ask((Y == 'c') & (f[X] == Y + '')) == set([('c', 'a')]) assert ask((Y == 'c') & (f[X] <= Y + '')) == set([('c', 'a')]) assert ask((Y == 'c') & (f[X] < Y + '')) == None assert ask((Y == 'c') & (f[X] < 'd' + Y + '')) == set([('c', 'a')]) assert ask((Y == ('a', 'c')) & (f[X] in Y)) == set([(('a', 'c'), 'a')]) assert ask((Y == ('a', 'c')) & (f[X] in (Y + ('z', )))) == set([ (('a', 'c'), 'a') ]) assert ask(f[X] == f[X] + '') == set([('a', )]) @pyDatalog.program() def function_negation(): assert not (ask(~(f[a] < 'd'))) assert not (ask(~(f[X] < 'd'))) assert ask(~(f[a] in ('d', ))) """ aggregates """ pyDatalog.clear() @pyDatalog.program() def sum(): +p(a, c, 1) +p(b, b, 4) +p(a, b, 1) assert (sum(1, 2)) == 3 (a_sum[X] == sum(Y, key=Z)) <= p(X, Z, Y) assert ask(a_sum[X] == Y) == set([('a', 2), ('b', 4)]) assert ask(a_sum[a] == X) == set([('a', 2)]) assert ask(a_sum[a] == 2) == set([('a', 2)]) assert ask(a_sum[X] == 4) == set([('b', 4)]) assert ask(a_sum[c] == X) == None assert ask((a_sum[X] == 2) & (p(X, Z, Y))) == set([('a', 'c', 1), ('a', 'b', 1)]) (a_sum2[X] == sum(Y, for_each=X)) <= p(X, Z, Y) assert ask(a_sum2[a] == X) == set([('a', 1)]) (a_sum3[X] == sum(Y, key=(X, Z))) <= p(X, Z, Y) assert ask(a_sum3[X] == Y) == set([('a', 2), ('b', 4)]) assert ask(a_sum3[a] == X) == set([('a', 2)]) @pyDatalog.program() def len(): assert (len((1, 2))) == 2 (a_len[X] == len(Z)) <= p(X, Z, Y) assert ask(a_len[X] == Y) == set([('a', 2), ('b', 1)]) assert ask(a_len[a] == X) == set([('a', 2)]) assert ask(a_len[X] == 1) == set([('b', 1)]) assert ask(a_len[X] == 5) == None (a_lenY[X] == len(Y)) <= p(X, Z, Y) assert ask(a_lenY[a] == X) == set([('a', 1)]) assert ask(a_lenY[c] == X) == None (a_len2[X, Y] == len(Z)) <= p(X, Y, Z) assert ask(a_len2[a, b] == X) == set([('a', 'b', 1)]) assert ask(a_len2[a, X] == Y) == set([('a', 'b', 1), ('a', 'c', 1)]) +q(a, c, 1) +q(a, b, 2) +q(b, b, 4) @pyDatalog.program() def concat(): (a_concat[X] == concat(Y, key=Z, sep='+')) <= q(X, Y, Z) assert ask(a_concat[X] == Y) == set([('b', 'b'), ('a', 'c+b')]) assert ask(a_concat[a] == 'c+b') == set([('a', 'c+b')]) assert ask(a_concat[a] == X) == set([('a', 'c+b')]) assert ask(a_concat[X] == b) == set([('b', 'b')]) (a_concat2[X] == concat(Y, order_by=(Z, ), sep='+')) <= q(X, Y, Z) assert ask(a_concat2[a] == X) == set([('a', 'c+b')]) (a_concat3[X] == concat(Y, key=(-Z, ), sep='-')) <= q(X, Y, Z) assert ask(a_concat3[a] == X) == set([('a', 'b-c')]) @pyDatalog.program() def min(): assert min(1, 2) == 1 (a_min[X] == min(Y, key=Z)) <= q(X, Y, Z) assert ask(a_min[X] == Y) == set([('b', 'b'), ('a', 'c')]) assert ask(a_min[a] == 'c') == set([('a', 'c')]) assert ask(a_min[a] == X) == set([('a', 'c')]) assert ask(a_min[X] == 'b') == set([('b', 'b')]) (a_minD[X] == min(Y, order_by=-Z)) <= q(X, Y, Z) assert ask(a_minD[a] == X) == set([('a', 'b')]) (a_min2[X, Y] == min(Z, key=(X, Y))) <= q(X, Y, Z) assert ask(a_min2[Y, b] == X) == set([('a', 'b', 2), ('b', 'b', 4)]) assert ask(a_min2[Y, Y] == X) == set([('b', 'b', 4)]), "a_min2" (a_min3[Y] == min(Z, key=(-X, Z))) <= q(X, Y, Z) assert ask(a_min3[b] == Y) == set([('b', 4)]), "a_min3" @pyDatalog.program() def max(): assert max(1, 2) == 2 (a_max[X] == max(Y, key=-Z)) <= q(X, Y, Z) assert ask(a_max[a] == X) == set([('a', 'c')]) (a_maxD[X] == max(Y, order_by=Z)) <= q(X, Y, Z) assert ask(a_maxD[a] == X) == set([('a', 'b')]) @pyDatalog.program() def rank(): (a_rank1[Z] == rank(for_each=Z, order_by=Z)) <= q(X, Y, Z) assert ask(a_rank1[X] == Y) == set([(1, 0), (2, 0), (4, 0)]) assert ask(a_rank1[X] == 0) == set([(1, 0), (2, 0), (4, 0)]) assert ask(a_rank1[1] == X) == set([(1, 0)]) assert ask(a_rank1[1] == 0) == set([(1, 0)]) assert ask(a_rank1[1] == 1) == None # rank (a_rank[X, Y] == rank(for_each=(X, Y2), order_by=Z2)) <= q(X, Y, Z) & q(X, Y2, Z2) assert ask(a_rank[X, Y] == Z) == set([('a', 'b', 1), ('a', 'c', 0), ('b', 'b', 0)]) assert ask(a_rank[a, b] == 1) == set([('a', 'b', 1)]) assert ask(a_rank[a, b] == Y) == set([('a', 'b', 1)]) assert ask(a_rank[a, X] == 0) == set([('a', 'c', 0)]) assert ask(a_rank[a, X] == Y) == set([('a', 'b', 1), ('a', 'c', 0)]) assert ask(a_rank[X, Y] == 1) == set([('a', 'b', 1)]) assert ask(a_rank[a, y] == Y) == None # reversed (b_rank[X, Y] == rank(for_each=(X, Y2), order_by=-Z2)) <= q(X, Y, Z) & q(X, Y2, Z2) assert ask(b_rank[X, Y] == Z) == set([('a', 'b', 0), ('a', 'c', 1), ('b', 'b', 0)]) assert ask(b_rank[a, b] == 0) == set([('a', 'b', 0)]) assert ask(b_rank[a, b] == Y) == set([('a', 'b', 0)]) assert ask(b_rank[a, X] == 1) == set([('a', 'c', 1)]) assert ask(b_rank[a, X] == Y) == set([('a', 'b', 0), ('a', 'c', 1)]) assert ask(b_rank[X, Y] == 0) == set([('a', 'b', 0), ('b', 'b', 0)]) assert ask(b_rank[a, y] == Y) == None @pyDatalog.program() def running_sum(): # running_sum (a_run_sum[X, Y] == running_sum( Z2, for_each=(X, Y2), order_by=Z2)) <= q(X, Y, Z) & q(X, Y2, Z2) assert ask(a_run_sum[X, Y] == Z) == set([('a', 'b', 3), ('a', 'c', 1), ('b', 'b', 4)]) assert ask(a_run_sum[a, b] == 3) == set([('a', 'b', 3)]) assert ask(a_run_sum[a, b] == Y) == set([('a', 'b', 3)]) assert ask(a_run_sum[a, X] == 1) == set([('a', 'c', 1)]) assert ask(a_run_sum[a, X] == Y) == set([('a', 'b', 3), ('a', 'c', 1)]) assert ask(a_run_sum[X, Y] == 4) == set([('b', 'b', 4)]) assert ask(a_run_sum[a, y] == Y) == None (b_run_sum[X, Y] == running_sum( Z2, for_each=(X, Y2), order_by=-Z2)) <= q(X, Y, Z) & q(X, Y2, Z2) assert ask(b_run_sum[X, Y] == Z) == set([('a', 'b', 2), ('a', 'c', 3), ('b', 'b', 4)]) assert ask(b_run_sum[a, b] == 2) == set([('a', 'b', 2)]) assert ask(b_run_sum[a, b] == Y) == set([('a', 'b', 2)]) assert ask(b_run_sum[a, X] == 3) == set([('a', 'c', 3)]) assert ask(b_run_sum[a, X] == Y) == set([('a', 'b', 2), ('a', 'c', 3)]) assert ask(b_run_sum[X, Y] == 4) == set([('b', 'b', 4)]) assert ask(b_run_sum[a, y] == Y) == None """ simple in-line queries """ X = pyDatalog.Variable() assert ((X == 1) >= X) == 1 assert ((X == 1) & (X != 2) >= X) == 1 assert set(X._in((1, 2))) == set([(1, ), (2, )]) assert ((X == 1) & (X._in((1, 2)))) == [(1, )] """ interface with python classes """ class A(pyDatalog.Mixin): def __init__(self, b): super(A, self).__init__() self.b = b def __repr__(self): return self.b @pyDatalog.program( ) # indicates that the following method contains pyDatalog clauses def _(): (A.c[X] == N) <= (A.b[X] == N) (A.len[X] == len(N)) <= (A.b[X] == N) @classmethod def _pyD_x1(cls, X): if X.is_const() and X.id.b == 'za': yield (X.id, ) else: for X in pyDatalog.metaMixin.__refs__[cls]: if X.b == 'za': yield (X, ) a = A('a') b = A('b') assert a.c == 'a' X, Y = pyDatalog.variables(2) assert (A.c[X] == 'a') == [(a, )] assert (A.c[X] == 'a')[0] == (a, ) assert list(X.data) == [a] assert X.v() == a assert ((A.c[a] == X) >= X) == 'a' assert ((A.c[a] == X) & (A.c[a] == X) >= X) == 'a' assert ((A.c[a] == X) & (A.c[b] == X) >= X) == None (A.c[X] == 'b') & (A.b[X] == 'a') assert list(X.data) == [] (A.c[X] == 'a') & (A.b[X] == 'a') assert list(X.data) == [a] result = (A.c[X] == 'a') & (A.b[X] == 'a') assert result == [(a, )] assert (A.c[a] == 'a') == [()] assert (A.b[a] == 'a') == [()] assert (A.c[a] == 'a') & (A.b[a] == 'a') == [()] assert (A.b[a] == 'f') == [] assert ((A.c[a] == 'a') & (A.b[a] == 'f')) == [] """ filters on python classes """ assert (A.b[X] != Y) == [(a, None), (b, None)] assert (A.b[X] != 'a') == [(b, )] assert (A.b[X] != 'z') == [(a, ), (b, )] assert (A.b[a] != 'a') == [] assert list(A.b[b] != 'a') == [()] assert ((A.b[b] != 'a') & (A.b[b] != 'z')) == [()] assert (A.b[X] < Y) == [(a, None), (b, None)] assert (A.b[X] < 'a') == [] assert (A.b[X] < 'z') == [(a, ), (b, )] assert (A.b[a] < 'b') == [()] assert (A.b[b] < 'a') == [] assert ((A.b[b] < 'z') & (A.b[b] != 'z')) == [()] assert (A.b[X] <= 'a') == [(a, )] assert (A.b[X] <= 'z') == [(a, ), (b, )] assert (A.b[a] <= 'b') == [()] assert (A.b[b] <= 'a') == [] assert ((A.b[b] <= 'z') & (A.b[b] != 'z')) == [()] assert (A.b[X] > 'a') == [(b, )] assert (A.b[X] >= 'a') == [(a, ), (b, )] assert (A.c[X] <= 'a') == [(a, )] assert (A.c[X] <= 'a' + '') == [(a, )] assert (A.c[X]._in(('a', ))) == [(a, )] assert (A.c[X]._in(('a', ) + ('z', ))) == [(a, )] assert ((Y == ('a', )) & (A.c[X]._in(Y))) == [(('a', ), a) ] # TODO make ' in ' work assert ((Y == ('a', )) & (A.c[X]._in(Y + ('z', )))) == [ (('a', ), a) ] # TODO make ' in ' work assert (A.c[X]._in(('z', ))) == [] # more complex queries assert ((Y == 'a') & (A.b[X] != Y)) == [ ('a', b) ] # order of appearance of the variables ! assert (A.len[X] == Y) == [(b, 1), (a, 1)] assert (A.len[a] == Y) == [(1, )] """ subclass """ class Z(A): def __init__(self, z): super(Z, self).__init__(z + 'a') self.z = z def __repr__(self): return self.z @pyDatalog.program( ) # indicates that the following method contains pyDatalog clauses def _(): (Z.w[X] == N) <= (Z.z[X] != N) @classmethod def _pyD_query(cls, pred_name, args): if pred_name == 'Z.pred': if args[0].is_const() and args[0].id.b != 'za': yield (args[0].id, ) else: for X in pyDatalog.metaMixin.__refs__[cls]: if X.b != 'za': yield (X, ) else: raise AttributeError z = Z('z') assert z.z == 'z' assert (Z.z[X] == 'z') == [(z, )] assert ((Z.z[X] == 'z') & (Z.z[X] > 'a')) == [(z, )] assert list(X.data) == [z] try: a.z == 'z' except Exception as e: e_message = e.message if hasattr(e, 'message') else e.args[0] if e_message != "Predicate without definition (or error in resolver): A.z[1]==/2": print(e_message) else: assert False try: (Z.z[a] == 'z') == None except Exception as e: e_message = e.message if hasattr(e, 'message') else e.args[0] if e_message != "Object is incompatible with the class that is queried.": print(e_message) else: assert False assert (Z.b[X] == Y) == [(z, 'za')] assert (Z.c[X] == Y) == [(z, 'za')] assert ((Z.c[X] == Y) & (Z.c[X] > 'a')) == [(z, 'za')] assert (Z.c[X] > 'a') == [(z, )] assert ((Z.c[X] > 'a') & (A.c[X] == 'za')) == [(z, )] assert (A.c[X] == 'za') == [(z, )] assert (A.c[z] == 'za') == [()] assert (z.b) == 'za' assert (z.c) == 'za' w = Z('w') w = Z('w') # duplicated to test __refs__[cls] assert (Z.x(X)) == [(z, )] assert not (~Z.x(z)) assert ~Z.x(w) assert ~(Z.z[w] == 'z') assert (Z.pred(X)) == [(w, )] # not duplicated ! assert (Z.pred(X) & ~(Z.z[X] >= 'z')) == [(w, )] assert (Z.x(X) & ~(Z.pred(X))) == [(z, )] assert (Z.len[X] == Y) == [(w, 1), (z, 1)] assert (Z.len[z] == Y) == [(1, )] # TODO print (A.b[w]==Y) """ python resolvers """ @pyDatalog.predicate() def p(X, Y): yield (1, 2) yield (2, 3) assert pyDatalog.ask('p(X,Y)') == set([(1, 2), (2, 3)]) assert pyDatalog.ask('p(1,Y)') == set([(1, 2)]) assert pyDatalog.ask('p(1,2)') == set([(1, 2)]) """ error detection """ @pyDatalog.program() def _(): pass error = False try: _() except: error = True assert error def assert_error(code, message='^$'): _error = False try: pyDatalog.load(code) except Exception as e: e_message = e.message if hasattr( e, 'message') else e.args[0] # python 2 and 3 if not re.match(message, e_message): print(e_message) _error = True assert _error def assert_ask(code, message='^$'): _error = False try: pyDatalog.ask(code) except Exception as e: e_message = e.message if hasattr(e, 'message') else e.args[0] if not re.match(message, e_message): print(e_message) _error = True assert _error assert_error('ask(z(a),True)', 'Too many arguments for ask \!') assert_error('ask(z(a))', 'Predicate without definition \(or error in resolver\): z/1') assert_error( "+ farmer(farmer(moshe))", "Syntax error: Literals cannot have a literal as argument : farmer\[\]" ) assert_error( "+ manager[Mary]==John", "Left-hand side of equality must be a symbol or function, not an expression." ) assert_error( "manager[X]==Y <= (X==Y)", "Syntax error: please verify parenthesis around \(in\)equalities") assert_error("p(X) <= (Y==2)", "Can't create clause") assert_error( "p(X) <= X==1 & X==2", "Syntax error: please verify parenthesis around \(in\)equalities") assert_error("p(X) <= (manager[X]== min(X))", "Error: argument missing in aggregate") assert_error("p(X) <= (manager[X]== max(X, order_by=X))", "Aggregation cannot appear in the body of a clause") assert_error("q(min(X, order_by=X)) <= p(X)", "Syntax error: Incorrect use of aggregation\.") assert_error( "manager[X]== min(X, order_by=X) <= manager(X)", "Syntax error: please verify parenthesis around \(in\)equalities") assert_error( "(manager[X]== min(X, order_by=X+2)) <= manager(X)", "order_by argument of aggregate must be variable\(s\), not expression\(s\)." ) assert_error("ask(X<1)", 'Error: left hand side of comparison must be bound: =X<1/1') assert_error("ask(X<Y)", 'Error: left hand side of comparison must be bound: =X<Y/2') assert_error("ask(1<Y)", 'Error: left hand side of comparison must be bound: =Y>1/1') assert_error( "ask( (A.c[X]==Y) & (Z.c[X]==Y))", "TypeError: First argument of Z.c\[1\]==\('.','.'\) must be a Z, not a A " ) assert_ask( "A.u[X]==Y", "Predicate without definition \(or error in resolver\): A.u\[1\]==/2") assert_ask( "A.u[X,Y]==Z", "Predicate without definition \(or error in resolver\): A.u\[2\]==/3") assert_error('(a_sum[X] == sum(Y, key=Y)) <= p(X, Z, Y)', "Error: Duplicate definition of aggregate function.") assert_error( '(two(X)==Z) <= (Z==X+(lambda X: X))', 'Syntax error near equality: consider using brackets. two\(X\)') assert_error('p(X) <= sum(X, key=X)', 'Invalid body for clause') assert_error( 'ask(- manager[X]==1)', "Left-hand side of equality must be a symbol or function, not an expression." ) assert_error("p(X) <= (X=={})", "unhashable type: 'dict'") """ SQL Alchemy """ from sqlalchemy import create_engine from sqlalchemy import Column, Integer, String, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship engine = create_engine('sqlite:///:memory:', echo=False) # create database in memory Session = sessionmaker(bind=engine) session = Session() Base = declarative_base(cls=pyDatalog.Mixin, metaclass=pyDatalog.sqlMetaMixin) Base.session = session class Employee(Base): # --> Employee inherits from the Base class __tablename__ = 'employee' name = Column(String, primary_key=True) manager_name = Column(String, ForeignKey('employee.name')) salary = Column(Integer) def __init__(self, name, manager_name, salary): super(Employee, self).__init__() self.name = name self.manager_name = manager_name # direct manager of the employee, or None self.salary = salary # monthly salary of the employee def __repr__(self): # specifies how to display the employee return "Employee: %s" % self.name @pyDatalog.program( ) # --> the following function contains pyDatalog clauses def Employee(): (Employee.manager[X] == Y) <= (Employee.manager_name[X] == Z) & (Z == Employee.name[Y]) # the salary class of employee X is computed as a function of his/her salary # this statement is a logic equality, not an assignment ! Employee.salary_class[X] = Employee.salary[X] // 1000 # all the indirect managers of employee X are derived from his manager, recursively Employee.indirect_manager( X, Y) <= (Employee.manager[X] == Y) & (Y != None) Employee.indirect_manager( X, Y) <= (Employee.manager[X] == Z) & Employee.indirect_manager(Z, Y) & (Y != None) # count the number of reports of X (Employee.report_count[X] == len(Y)) <= Employee.indirect_manager( Y, X) Employee.p(X, Y) <= (Y <= Employee.salary[X] + 1) Base.metadata.create_all(engine) John = Employee('John', None, 6800) Mary = Employee('Mary', 'John', 6300) Sam = Employee('Sam', 'Mary', 5900) session.add(John) session.add(Mary) session.add(Sam) session.commit() assert (John.salary_class == 6) X = pyDatalog.Variable() result = (Employee.salary[X] == 6300 ) # notice the similarity to a pyDatalog query assert result == [ (Mary, ), ] assert (X._value() == [ Mary, ]) # prints [Employee: Mary] assert (X.v() == Mary) # prints Employee:Mary result = (Employee.indirect_manager(Mary, X)) assert result == [ (John, ), ] assert (X.v() == John) # prints [Employee: John] Mary.salary_class = ((Employee.salary_class[Mary] == X) >= X) Mary.salary = 10000 assert Mary.salary_class != ((Employee.salary_class[Mary] == X) >= X) X, Y, N = pyDatalog.variables(3) result = (Employee.salary[X] == 6800) & (Employee.name[X] == N) assert result == [ (John, 'John'), ] assert N.v() == 'John' result = (Employee.salary[X] == Employee.salary[X]) assert result == [(John, ), (Mary, ), (Sam, )] result = (Employee.p(X, 1)) assert result == [(John, ), (Mary, ), (Sam, )] result = (Employee.salary[X] < Employee.salary[X] + 1) assert result == [(John, ), (Mary, ), (Sam, )] result = (Employee.salary[John] == N) & Employee.p(John, N) assert result == [(6800, )] result = (Employee.salary[X] == 6800) & (Employee.salary[X] == N) & Employee.p(X, N) assert result == [(John, 6800)] """
from pyDatalog import pyDatalog pyDatalog.clear() pyDatalog.create_terms('rectangle, isocele, equi, isoRect, P, TroiscotesPareil, angles60, DeuxcotesPareil, angleDroit, deuxAngles45, X') equi(P) <= TroiscotesPareil(P) & angles60(P) isocele(P) <= DeuxcotesPareil(P) rectangle(P) <= angleDroit(P) isoRect(P) <= angleDroit(P) & deuxAngles45(P) pyDatalog.assert_fact('angleDroit', 'Triangle rectangle') pyDatalog.assert_fact('angleDroit', 'Triangle rectangle isocèle') pyDatalog.assert_fact('deuxAngles45', 'Triangle rectangle isocèle') print(pyDatalog.ask('angleDroit(X)')) print(pyDatalog.ask('deuxAngles45(X)'))
def _(): calls = pa.read_csv('calls.csv', sep='\t', encoding='utf-8') texts = pa.read_csv('texts.csv', sep='\t', encoding='utf-8') suspect = 'Quandt Katarina' company_Board = ['Soltau Kristine', 'Eder Eva', 'Michael Jill'] pyDatalog.create_terms('knows, ' 'has_link, ' 'all_connections, ' 'max_five_people, ' 'helper') # First, treat calls as simple social links (denoted as knows), that have no date # the caller knows callee for i in range(len(calls)): +knows(calls.iloc[i, 1], calls.iloc[i, 2]) # Task 1: Knowing someone is a bi-directional relationship -> define the predicate accordingly knows(X, Y) <= knows(Y, X) & (X != Y) print(knows(suspect, Y)) # Task 2: Define the predicate has_link in a way that it is true if a connection exists # (path of people knowing the next link) # Hints: # check if your predicate works: at least 1 of the following asserts should be true # (2 if you read in all 150 communication records) # (be aware of the unusual behaviour that if an assert evaluates as true, an exception is thrown) has_link(X, Y) <= has_link(Z, Y) & knows(X, Z) & (X != Y) has_link(X, Y) <= knows(X, Y) assert (has_link('Quandt Katarina', company_Board[0]) == ()) # assert (has_link('Quandt Katarina', company_Board[1]) == ()) # assert (has_link('Quandt Katarina', company_Board[2]) == ()) # 'Quandt Katarina' knows 'Eder Eva' and 'Michael Jill' # Task 3: You already know that a connection exists; now find the concrete paths between the board members # and the suspect helper(X, Y, P2) <= (X != Y) & (X._not_in(P2)) & (Y._not_in(P2)) all_connections(X, Y, P) <= all_connections(X, Z, P2) & knows( Z, Y) & helper(X, Y, P2) & (P == P2 + [Z]) all_connections(X, Y, P) <= knows(X, Y) & (P == []) # Task 4: There are too many paths. We are only interested in short paths. # Find all the paths between the suspect and the company board that contain five people or less (max_five_people(X, Y, P, C)) <= (max_five_people(X, Z, P2, C2)) & knows(Z, Y) \ & helper(X, Y, P2) & (P == P2+[Z]) & (C == C2 + 1) & (C <= 2) (max_five_people(X, Y, P, C)) <= knows(X, Y) & (P == []) & (C == 0) for member in company_Board: print("Who ", suspect, "/", member) print(max_five_people(suspect, member, P, C)) print("Who ", member, "/", suspect) print(max_five_people(member, suspect, P, C)) # --------------------------------------------------------------------------- # Call-Data analysis: # Now we use the text and the calls data together with their corresponding dates # --------------------------------------------------------------------------- date_board_decision = '12.2.2017' date_shares_bought = '23.2.2017' pyDatalog.create_terms( 'called, texted, descending_communication, data_valid') pyDatalog.clear() for i in range(len(calls)): # calls +called(calls.iloc[i, 1], calls.iloc[i, 2], calls.iloc[i, 3]) for i in range(len(texts)): # texts +texted(texts.iloc[i, 1], texts.iloc[i, 2], texts.iloc[i, 3]) # calls are bi-directional called(X, Y, Z) <= called(Y, X, Z) # Task 5: Again we are interested in links, but this time a connection is only valid # if the links are descending in date; # find out who could have actually sent the information by adding this new restriction data_valid(D) <= (D >= date_board_decision) & (D <= date_shares_bought) helper(X, Y, P, P2, D, D2) <= (X != Y) & (X._not_in(P2)) & ( Y._not_in(P2)) & (P == P2 + [D2] + [Y] + [D]) print("descending_communication") (descending_communication(X, Y, D, P)) <= \ (descending_communication(X, Z, D2, P2)) & (called(Z, Y, D) or texted(Z, Y, D)) & helper(X, Y, P, P2, D, D2)\ & data_valid(D) & data_valid(D2) & (D < D2) (descending_communication(X, Y, D, P)) <= called(X, Y, D) & (P == [Y]) # (descending_communication(X, Y, D, P)) <= \ # (descending_communication(X, Z, D2, P2)) & texted(Z, Y, D) & (X != Y) & \ # (X._not_in(P2)) & (Y._not_in(P2)) & (P == P2+[D2]+[Y]+[D]) & \ # (D >= date_board_decision) & (D <= date_shares_bought) & (D < D2) & (D2 >= date_board_decision) & (D2 <= date_shares_bought) # (descending_communication(X, Y, D, P)) <= texted(X, Y, D) & (P == [Y]) # D2 ist das Datum des vorhergehenden Anrufs / Kommunikation # Task 6: Find all the communication paths that lead to the suspect # (with the restriction that the dates have to be ordered correctly) for member in company_Board: print("From ", suspect, 'to ', member) print(descending_communication(suspect, member, D, P)) print("From ", member, "to ", suspect) print(descending_communication(member, suspect, D, P))