Exemple #1
0
def assertAll(pname, facts):
  """
  Assert all tuples in facts into the LogKB, using predicate name pname.
  Expects a list of tuples in facts.
  """
  for f in facts: 
    pyDatalog.assert_fact(pname, *f)
Exemple #2
0
    def setUp(self):
        from reloop.languages.rlp.logkb import PyDatalogLogKb
        from pyDatalog import pyDatalog
        import random
        from reloop.languages.rlp import numeric_predicate

        self.logkb = PyDatalogLogKb()
        self.predicate = numeric_predicate("test_predicate", 1)
        self.float_test_data = random.random()
        self.integer_test_data = random.randint(1, 100)
        pyDatalog.assert_fact("test_predicate", 'b', self.integer_test_data)
        pyDatalog.assert_fact("test_predicate", 'a', self.float_test_data)
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([()])
Exemple #4
0
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 main():
    r = RedisManager(host=RedisConfig['host'], port=RedisConfig['port'], db=RedisConfig['db'],
                     password=RedisConfig['password'], decodedResponses=RedisConfig['decodedResponses'])
    sub = r.getRedisPubSub()
    sub.subscribe(RedisConfig['VocalChannel'])
    learn()
    while True:
        newMsg = sub.get_message()
        if newMsg:
            if newMsg['type'] == 'message':
                now = getTimestamp()
                msgContent = newMsg['data'].decode()
                print("Vocal Result: " + str(newMsg))  # Test
                facialRes = getAverageEmotionsFromRedisQueue(r, queue=RedisConfig['FacialQueue'],
                                                           emotions=DMAConfig['emotions'])
                if msgContent == str(RedisConfig['voidMsg']):
                    facialVocal = facialRes
                else:
                    vocalRes = ast.literal_eval(msgContent)
                    facialVocal = facialVocalCompare(facialRes, vocalRes, emotions=DMAConfig['emotions'],
                                                 facialW=DMAConfig['facialWeight'], vocalW=DMAConfig['vocalWeight'])
                print("FACIAL VOCAL:" + str(facialVocal))  # Test
                if facialVocal:
                    sortedEmotions = {k: v for k, v in sorted(facialVocal.items(), key=lambda item: item[1])}
                    print(sortedEmotions)  # Test
                    sortedEmoList = list(sortedEmotions.items())
                    firstEmotion = sortedEmoList[-1]
                    secondEmotion = sortedEmoList[-2]
                    topEmotions = dict([firstEmotion, secondEmotion])
                    decisionWithPer = firstEmotion
                    diff = 0
                    for k in topEmotions:
                        diff -= topEmotions[k]
                    diff = abs(diff)
                    attitude = getAverageAttitudeFromRedisQueue(r, queue=RedisConfig['PoseQueue'])
                    print("DATA: " + str(firstEmotion) + ", " + str(secondEmotion) + ", " + str(attitude))
                    if diff <= DMAConfig['poseTestThreshold']:
                        if attitude:
                            pyDatalog.assert_fact('firstEmoPercept', firstEmotion[0])
                            pyDatalog.assert_fact('secondEmoPercept', secondEmotion[0])
                            pyDatalog.assert_fact('poseAttitudePercept', attitude)
                            decision = str(pyDatalog.ask("takeDecision(D)")).replace("{('", "").replace("'", "").split(",")[0]
                            decisionWithPer = (decision, str(topEmotions[decision]))
                            pyDatalog.retract_fact('firstEmoPercept', firstEmotion[0])
                            pyDatalog.retract_fact('secondEmoPercept', secondEmotion[0])
                            pyDatalog.retract_fact('poseAttitudePercept', attitude)
                    r.setOnRedis(key=RedisConfig['DecisionSet'], value=str(decisionWithPer))
                    r.publishOnRedis(channel=RedisConfig['newDecisionPubSubChannel'], msg=str(decisionWithPer))
                    print("Decision: " + str(decisionWithPer))  # Test
                r.deleteRedisElemsByKeyPatternAndTimestamp(RedisConfig['imageHsetRoot'] + '*', now,
                                                           DMAConfig['timeThreshold'])
                r.deleteRedisElemsByKeyPatternAndTimestamp(RedisConfig['audioHsetRoot'] + '*', now,
                                                           DMAConfig['timeThreshold'])
def init_datalog():
    database = connectToDatabase()
    mydb = database[0]
    mycursor = database[1]

    # create all Datalog terms
    pyDatalog.create_terms(
        'hasCaloriesPer100g, containsGluten, containsLactose, containsMeat, containsAnimalProduct, hasID'
    )
    pyDatalog.create_terms('recipeInstructions')
    pyDatalog.create_terms(
        'containsIngredient, weightPerServing, containsBaseIngredient')
    pyDatalog.create_terms('A, B, C, D, X, Y, Z, I')
    pyDatalog.create_terms('baseIngredientWithCalories')

    # create facts for ingredient
    mycursor.execute("SELECT * FROM `Lebensmittel`")
    myresult = mycursor.fetchall()
    for x in myresult:
        pyDatalog.assert_fact('hasID', x[1], "ingredient",
                              "ingredient" + str(x[0]))
        pyDatalog.assert_fact('hasCaloriesPer100g', x[1], x[2])
        if x[5] == 1:
            pyDatalog.assert_fact('containsGluten', x[1])
        if x[11] == 1:
            pyDatalog.assert_fact('containsLactose', x[1])
        if x[3] == 1:
            pyDatalog.assert_fact('containsMeat', x[1])
        if (x[4] == 1) | (x[3] == 1):
            pyDatalog.assert_fact('containsAnimalProduct', x[1])
        pyDatalog.assert_fact('weightPerServing', x[1], 1)

    mycursor.execute(
        "SELECT `Rezepte`.`Name` AS `Rezept`, `KomponentenRezept`.`Name` AS `KomponentenRezept`, `enthaeltRezept`.`Menge` AS `Menge` FROM `enthaeltRezept` INNER JOIN `Rezepte` ON `enthaeltRezept`.`RezeptId` = `Rezepte`.`RezeptId` INNER JOIN `Rezepte` `KomponentenRezept` ON `enthaeltRezept`.`KomponentenRezeptId` = `KomponentenRezept`.`RezeptId`"
    )
    myresult = mycursor.fetchall()
    for x in myresult:
        pyDatalog.assert_fact('containsIngredient', x[0], x[1], x[2])

    # create facts for containsIngredient
    mycursor.execute(
        "SELECT `Rezepte`.`Name` AS `Rezept`, `Lebensmittel`.`Name` AS `Lebensmittel`, `enthaeltLebensmittel`.`Menge` AS `Menge` FROM `enthaeltLebensmittel` INNER JOIN `Rezepte` ON `enthaeltLebensmittel`.`RezeptId` = `Rezepte`.`RezeptId` INNER JOIN `Lebensmittel` ON `enthaeltLebensmittel`.`LebensmittelId` = `Lebensmittel`.`LebensmittelId`"
    )
    myresult = mycursor.fetchall()
    for x in myresult:
        pyDatalog.assert_fact('containsIngredient', x[0], x[1], x[2])

    # create facts for recipes
    mycursor.execute("SELECT * FROM `Rezepte`")
    myresult = mycursor.fetchall()
    for x in myresult:
        pyDatalog.assert_fact('hasID', x[1], "recipe", "recipe" + str(x[0]))
        pyDatalog.assert_fact('recipeInstructions', x[1], x[2])
        ingredients = pyDatalog.ask("containsIngredient('" + x[1] + "', Y, Z)")
        weight = 0
        if not ingredients == None:
            for i in ingredients.answers:
                weight += i[1]
        pyDatalog.assert_fact('weightPerServing', x[1], weight)

    # resolve all ingredients from a recipe
    containsBaseIngredient(X, Y, Z) <= containsIngredient(
        X, Y, Z) & recipeInstructions(X, A) & hasCaloriesPer100g(Y, B)
    containsBaseIngredient(
        X, Y, Z) <= containsIngredient(X, A, B) & containsIngredient(
            A, Y, C) & weightPerServing(A, D) & (Z == C * B / D)

    # get calories per 100g for all recipes
    baseIngredientWithCalories(X, Y, Z) <= containsBaseIngredient(
        X, Y, B) & hasCaloriesPer100g(Y, C) & (Z == C / 100 * B)
    # hasCaloriesPer100g2(X, Y) <= baseIngredientWithCalories(X, A, B) & Y == sum(B, for_each=X))
    recipes = pyDatalog.ask('recipeInstructions(X, Y)')
    for r in recipes.answers:
        pyDatalog.assert_fact('hasCaloriesPer100g', r[0],
                              getCaloriesPer100g(r[0]))

    # resolve allergens for recipes
    containsGluten(X) <= containsIngredient(X, A, B) & containsGluten(A)
    containsLactose(X) <= containsIngredient(X, A, B) & containsLactose(A)
    containsMeat(X) <= containsIngredient(X, A, B) & containsMeat(A)
    containsAnimalProduct(X) <= containsIngredient(
        X, A, B) & containsAnimalProduct(A)

    if mydb.is_connected():
        mycursor.close()
        mydb.close()
Exemple #7
0
from pyDatalog import pyDatalog


pyDatalog.create_terms('croakes, eatflies, frog, chrips, sings, canary, green, yellow, P, X')

pyDatalog.load("""
frog(X) <= croakes(X) & eatflies(X)
canary(X) <= sings(X) & chrips(X)
green(X) <= frog(X)
yellow(X) <= canary(X)
                """)

pyDatalog.assert_fact('croakes', 'Fritz')
pyDatalog.assert_fact('eatflies', 'Fritz')

pyDatalog.assert_fact('sings', 'Paul')
pyDatalog.assert_fact('chrips', 'Paul')

query = 'yellow(X)'
answers = pyDatalog.ask(query).answers

print(answers)

print(pyDatalog.ask('green(X)'))
Exemple #8
0

Y = pyDatalog.Variable()
Ingredient.Fleisch[Y] == 0
print(Y)

X = pyDatalog.Variable()
Recipe.Name[X] == "Pizzateig"
print(X)

result = pyDatalog.ask('hasIngredient(X, Y, Z)')
print(result)






pyDatalog.create_terms('ingredient, contains')
pyDatalog.create_terms('allergenList, freeFrom')

pyDatalog.assert_fact('ingredient', 'Mehl')
pyDatalog.assert_fact('ingredient', 'Nudeln')
pyDatalog.assert_fact('contains', 'Mehl', 'Gluten')
pyDatalog.assert_fact('contains', 'Nudeln', 'Mehl')

contains(I, A) <= contains(I, X) & contains(X, A)

print(pyDatalog.ask('contains(I, A)'))

#freeFrom(allergenList[N]) <= not(contains(I, allergenList[N])) & freeFrom(allergenList[N-1])
Exemple #9
0
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')"))

Exemple #10
0
def almacenar_respuesta_base_dinamica(organo,nombre_sintoma):
  assert_fact( 'respuesta', organo, nombre_sintoma )
Exemple #11
0
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)]

    """
Exemple #12
0
 def setData(self, estereotipo, nombre):
     pyDatalog.assert_fact(estereotipo, nombre)
Exemple #13
0
    def calcular_respuesta(self):
        pyDatalog.assert_fact('pregunta', 'Arte_y_creatividad',
                              'Ilustrar, dibujar y animar digitalmente',
                              lista_respuestas[3])
        pyDatalog.assert_fact('pregunta', 'Arte_y_creatividad',
                              'Fotografiar Paisajes', lista_respuestas[8])
        pyDatalog.assert_fact('pregunta', 'Arte_y_creatividad',
                              'Disenar logotipos y portadas de una revista',
                              lista_respuestas[10])
        pyDatalog.assert_fact(
            'pregunta', 'Arte_y_creatividad',
            'Pintar, hacer esculturas, ilustrar libros de arte, etcetera',
            lista_respuestas[19])
        pyDatalog.assert_fact('pregunta', 'Arte_y_creatividad',
                              'Prepararse para ser modelo profesional', 'X')
        pyDatalog.assert_fact(
            'pregunta', 'Arte_y_creatividad',
            'Disenar juegos interactivos electronicos para computadora', 'X')
        pyDatalog.assert_fact(
            'pregunta', 'Arte_y_creatividad',
            'Redactar guiones y libretos para un programa de television', 'X')
        pyDatalog.assert_fact('pregunta', 'Arte_y_creatividad',
                              'Crear campanas publicitarias', 'X')

        #Area II CIENCIAS SOCIALES
        pyDatalog.assert_fact(
            'pregunta', 'sociales',
            'Realizar cavaciones para descubrir restos del pasado',
            lista_respuestas[5])
        pyDatalog.assert_fact('pregunta', 'sociales',
                              'Organizar eventos y atender a sus asistentes',
                              lista_respuestas[12])
        pyDatalog.assert_fact(
            'pregunta', 'sociales',
            'Investigar el pasado y saber acerca de Historia',
            lista_respuestas[7])
        pyDatalog.assert_fact(
            'pregunta', 'sociales',
            'Ayudar a la sociedad con los problemas que tienen',
            lista_respuestas[15])
        pyDatalog.assert_fact(
            'pregunta', 'sociales',
            'Escribir articulos periodisticos, cuentos, novelas y otros', 'X')
        pyDatalog.assert_fact(
            'pregunta', 'sociales',
            'Estudiar la diversidad cultural en el ambito rural y urbano', 'X')
        pyDatalog.assert_fact(
            'pregunta', 'sociales',
            'Gestionar y evaluar convenios internacionales de cooperacion para el desarrollo social',
            'X')

        # AREA III: ECONOMICA, ADMINISTRATIVA Y FINANCIERA.
        pyDatalog.assert_fact(
            'pregunta', 'administrativa',
            'Seleccionar, capacitar y motivar al personal de una organizacion/empresa',
            lista_respuestas[4])
        pyDatalog.assert_fact(
            'pregunta', 'administrativa',
            'Planificar cuales son las metas de una organizacion publica o privada a mediano y largo plazo',
            lista_respuestas[9])
        pyDatalog.assert_fact(
            'pregunta', 'administrativa',
            'Controlar ingresos y egresos de fondos y presentar el balance final de una institucion',
            lista_respuestas[14])
        pyDatalog.assert_fact(
            'pregunta', 'administrativa',
            'Hacer propuestas y formular estrategias para aprovechar las relaciones economicas entre dos paises',
            lista_respuestas[18])
        pyDatalog.assert_fact(
            'pregunta', 'administrativa',
            'Elaborar campanas para introducir un nuevo producto al mercado',
            'X')
        pyDatalog.assert_fact('pregunta', 'administrativa',
                              'Supervisar las ventas de un centro comercial',
                              'X')
        pyDatalog.assert_fact(
            'pregunta', 'administrativa',
            'Aconsejar a las personas sobre planes de ahorro e inversiones',
            'X')
        pyDatalog.assert_fact('pregunta', 'administrativa',
                              'Tener un negocio propio de tipo comercial', 'X')
        pyDatalog.assert_fact(
            'pregunta', 'administrativa',
            'Organizar un plan de distribucion y venta de un gran almacen',
            'X')

        # AREA IV: CIENCIA Y TECONOLOGIA.
        pyDatalog.assert_fact(
            'pregunta', 'ciencia_y_tecnologia',
            'Disenar programas de computacion y plorar nuevas aplicaciones tecnologicas para uso del internet',
            lista_respuestas[0])
        pyDatalog.assert_fact('pregunta', 'ciencia_y_tecnologia',
                              'Resolver Problemas de Calculo Matematico',
                              lista_respuestas[6])
        pyDatalog.assert_fact(
            'pregunta', 'ciencia_y_tecnologia',
            'Te gusta la programacion o cosas que tenga que ver con computadoras',
            lista_respuestas[11])
        pyDatalog.assert_fact(
            'pregunta', 'ciencia_y_tecnologia',
            'Te gusta la Fisica, Matematica, y todo lo que tenga que ver con numeros',
            lista_respuestas[16])
        pyDatalog.assert_fact(
            'pregunta', 'ciencia_y_tecnologia',
            'Investigar y probar nuevos productos farmaceuticos', 'X')
        pyDatalog.assert_fact(
            'pregunta', 'ciencia_y_tecnologia',
            'Disenar maquinas que puedan simular actividades humanas', 'X')
        pyDatalog.assert_fact(
            'pregunta', 'ciencia_y_tecnologia',
            'Elaborar mapas, planos e imagenes para el estudio y analisis de datos geograficos',
            'X')

        # AREA V: CIENCIAS ECOLOGICAS, BIOLOGICAS Y DE SALUD.
        pyDatalog.assert_fact(
            'pregunta', 'biologia_y_salud',
            'Criar, cuidar y tratar animales domesticos y de campo',
            lista_respuestas[1])
        pyDatalog.assert_fact(
            'pregunta', 'biologia_y_salud',
            'Investigar sobre areas verdes, medio ambiente y cambios climaticos',
            lista_respuestas[2])
        pyDatalog.assert_fact(
            'pregunta', 'biologia_y_salud',
            'Disenar cursos para ensenar a la gente sobre temas de salud e higiene',
            'X')
        pyDatalog.assert_fact('pregunta', 'biologia_y_salud',
                              'Atender la salud de personas enfermas',
                              lista_respuestas[13])
        pyDatalog.assert_fact(
            'pregunta', 'biologia_y_salud',
            'Hacer experimentos con plantas (frutas, arboles, flores)', 'X')
        pyDatalog.assert_fact('pregunta', 'biologia_y_salud',
                              'Examinar y tratar los problemas visuales', 'X')
        pyDatalog.assert_fact(
            'pregunta', 'biologia_y_salud',
            'Realizar el control de calidad de los alimentos',
            lista_respuestas[17])
        pyDatalog.assert_fact(
            'pregunta', 'biologia_y_salud',
            'Atender y realizar ejercicios a personas que tienen limitaciones fisicas, problemas de lenguaje, etcetera',
            'X')

        s = str(pyDatalog.ask('pregunta(X,_,si)'))

        SaveMax = max([
            s.count("biologia_y_salud"),
            s.count("ciencia_y_tecnologia"),
            s.count("administrativa"),
            s.count("sociales"),
            s.count("Arte_y_creatividad")
        ])

        respuesta = ""

        if s.count("biologia_y_salud") == SaveMax:
            respuesta = respuesta + "estudia una carrera del area de biologia y salud:  Biología, Farmacia, Zootecnia, Veterinaria, Medicina, Enfermería. <br/>"
        if s.count("ciencia_y_tecnologia") == SaveMax:
            respuesta = respuesta + "estudia una carrera del area de las ciencia y tecnologia: Ingenieria en sistemas, Ingenieria Civil, Electrónica, Física, Matemáticas, Ingeniería Mecatrónica. <br/>"
        if s.count("administrativa") == SaveMax:
            respuesta = respuesta + "estudia una carrera del area de las ciencias administrativas: Administración, Ingeniería comercial, Marketing, Gestión y Negocios internacionales, Finanzas.  <br/>"
        if s.count("sociales") == SaveMax:
            respuesta = respuesta + "estudia una carrera del area de las ciencias sociales: Trabajo Social, Historia y Geografía, Periodismo, Antropología, Arqueología.<br/>"
        if s.count("Arte_y_creatividad") == SaveMax:
            respuesta = respuesta + "estudia una carrera del area de la facultad de belleas artes: Diseño Gráfico, Artes plasticas, Publicidad, Fotografía, actuación. <br/>"

        self.lblRespuesta.setText(
            "<html><head/><body><p><span style=\" font-size:14pt; color:#000000;\">"
            + respuesta + "</span></p></body></html>")
Exemple #14
0
    def __assert_user(self, user, prediction):
        assert_fact('user_id', user.id)
        assert_fact('name', user.id, user.name)
        assert_fact('age', user.id, user.age)
        assert_fact('bio', user.id, user.bio)
        assert_fact('distance', user.id, user.distance)
        assert_fact('distance_unit', user.id, user.distance_unit)
        assert_fact('ping_time', user.id, user.ping_time)
        assert_fact('birth_date', user.id, user.birth_date)

        for friend in user.common_friends:
            assert_fact('common_friend', user.id, friend)

        for like in user.common_likes:
            assert_fact('common_likes', user.id, like)

        assert_fact('prediction', user.id, prediction)
Exemple #15
0
    def test_pydatalog(self):
        from pyDatalog import pyDatalog
        from reloop.languages.rlp.logkb import PyDatalogLogKb

        pyDatalog.assert_fact('node', 'a')
        pyDatalog.assert_fact('node', 'b')
        pyDatalog.assert_fact('node', 'c')
        pyDatalog.assert_fact('node', 'd')
        pyDatalog.assert_fact('node', 'e')
        pyDatalog.assert_fact('node', 'f')
        pyDatalog.assert_fact('node', 'g')

        pyDatalog.assert_fact('edge', 'a', 'b')
        pyDatalog.assert_fact('edge', 'a', 'c')
        pyDatalog.assert_fact('edge', 'b', 'd')
        pyDatalog.assert_fact('edge', 'b', 'e')
        pyDatalog.assert_fact('edge', 'c', 'd')
        pyDatalog.assert_fact('edge', 'c', 'f')
        pyDatalog.assert_fact('edge', 'd', 'e')
        pyDatalog.assert_fact('edge', 'd', 'f')
        pyDatalog.assert_fact('edge', 'e', 'g')
        pyDatalog.assert_fact('edge', 'f', 'g')

        pyDatalog.assert_fact('source','a')
        pyDatalog.assert_fact('target', 'g')

        pyDatalog.assert_fact('cost', 'a', 'b', 50 )
        pyDatalog.assert_fact('cost', 'a', 'c', 100)
        pyDatalog.assert_fact('cost', 'b', 'd', 40 )
        pyDatalog.assert_fact('cost', 'b', 'e', 20 )
        pyDatalog.assert_fact('cost', 'c', 'd', 60 )
        pyDatalog.assert_fact('cost', 'c', 'f', 20 )
        pyDatalog.assert_fact('cost', 'd', 'e', 50 )
        pyDatalog.assert_fact('cost', 'd', 'f', 60 )
        pyDatalog.assert_fact('cost', 'e', 'g', 70 )
        pyDatalog.assert_fact('cost', 'f', 'g', 70 )

        logkb = PyDatalogLogKb()
        grounder = RecursiveGrounder(logkb)

        solver = CvxoptSolver()
        model = maxflow_example.maxflow(grounder, solver)
        self.assertEqual(model, 0, "PyDataLog Recursive Failed")
Exemple #16
0
 def __assert_user(self, user, prediction):
     assert_fact('user_id', user.id)
     assert_fact('name', user.id, user.name)
     assert_fact('age', user.id, user.age)
     assert_fact('bio', user.id, user.bio)
     assert_fact('distance', user.id, user.distance)
     assert_fact('distance_unit', user.id, user.distance_unit)
     assert_fact('ping_time', user.id, user.ping_time)
     assert_fact('birth_date', user.id, user.birth_date)
     
     for friend in user.common_friends:
         assert_fact('common_friend', user.id, friend)
         
     for like in user.common_likes:
         assert_fact('common_likes', user.id, like)
         
     assert_fact('prediction', user.id, prediction)
Exemple #17
0
    def test_sudoku(self):
        from pyDatalog import pyDatalog
        from examples.RLP import sudoku_example
        from reloop.languages.rlp.logkb import PyDatalogLogKb

        for u in range(1, 10):
            pyDatalog.assert_fact('num', u)

        for u in range(1, 4):
            pyDatalog.assert_fact('boxind', u)

        pyDatalog.assert_fact('initial', 1, 1, 5)
        pyDatalog.assert_fact('initial', 2, 1, 6)
        pyDatalog.assert_fact('initial', 4, 1, 8)
        pyDatalog.assert_fact('initial', 5, 1, 4)
        pyDatalog.assert_fact('initial', 6, 1, 7)
        pyDatalog.assert_fact('initial', 1, 2, 3)
        pyDatalog.assert_fact('initial', 3, 2, 9)
        pyDatalog.assert_fact('initial', 7, 2, 6)
        pyDatalog.assert_fact('initial', 3, 3, 8)
        pyDatalog.assert_fact('initial', 2, 4, 1)
        pyDatalog.assert_fact('initial', 5, 4, 8)
        pyDatalog.assert_fact('initial', 8, 4, 4)
        pyDatalog.assert_fact('initial', 1, 5, 7)
        pyDatalog.assert_fact('initial', 2, 5, 9)
        pyDatalog.assert_fact('initial', 4, 5, 6)
        pyDatalog.assert_fact('initial', 6, 5, 2)
        pyDatalog.assert_fact('initial', 8, 5, 1)
        pyDatalog.assert_fact('initial', 9, 5, 8)
        pyDatalog.assert_fact('initial', 2, 6, 5)
        pyDatalog.assert_fact('initial', 5, 6, 3)
        pyDatalog.assert_fact('initial', 8, 6, 9)
        pyDatalog.assert_fact('initial', 7, 7, 2)
        pyDatalog.assert_fact('initial', 3, 8, 6)
        pyDatalog.assert_fact('initial', 7, 8, 8)
        pyDatalog.assert_fact('initial', 9, 8, 7)
        pyDatalog.assert_fact('initial', 4, 9, 3)
        pyDatalog.assert_fact('initial', 5, 9, 1)
        pyDatalog.assert_fact('initial', 6, 9, 6)
        pyDatalog.assert_fact('initial', 8, 9, 5)

        pyDatalog.load("""
            box(I, J, U, V) <= boxind(U) & boxind(V) & num(I) & num(J) & (I > (U-1)*3) & (I <= U*3) & (J > (V-1)*3) & (J <= V*3)
        """)

        logkb = PyDatalogLogKb()
        grounder = BlockGrounder(logkb)
        # Note: CVXOPT needs to be compiled with glpk support. See the CVXOPT documentation.
        solver = CvxoptSolver(solver_solver='glpk')

        model = sudoku_example.sudoku(grounder, solver)

        self.assertEqual(model, 0, "ERROR : Sudoku couldn't be solved")
def learn():
    pyDatalog.create_terms('attitudeLThreshold, attitudeRThreshold, firstEmoPercept, secondEmoPercept, '
                           'poseAttitudePercept, takeDecision, D, negativeEmotion, positiveEmotion, neutralEmotion')
    print("Learning started...")
    pyDatalog.assert_fact('attitudeLThreshold', DMAConfig['attitudeLThreshold'])
    pyDatalog.assert_fact('attitudeRThreshold', DMAConfig['attitudeRThreshold'])
    pyDatalog.assert_fact('positiveEmotion', 'happiness')
    pyDatalog.assert_fact('neutralEmotion', 'neutral')
    for negEmo in ['sadness', 'fear', 'angry']:
        pyDatalog.assert_fact('negativeEmotion', negEmo)

    pyDatalog.load("""    
    positive(P) <= positiveEmotion(P)
    positive(P) <= attitude(P) & attitudeRThreshold(R) & (P >= R)
    neutral(O) <= neutralEmotion(O)
    neutral(O) <= attitude(O) & attitudeRThreshold(R) & (R > O) & attitudeLThreshold(L) & (O > L)
    negative(N) <= negativeEmotion(N)
    negative(N) <= attitude(N) & attitudeLThreshold(L) & (N <= L)
    
    firstEmo(X) <= firstEmoPercept(X)
    secondEmo(Y) <= secondEmoPercept(Y)
    attitude(A) <= poseAttitudePercept(A)
    estimations(X, Y, A) <= firstEmo(X) & secondEmo(Y) & attitude(A)

    takeDecision(X) <= estimations(X, Y, A) & neutral(Y) & neutral(A)
    takeDecision(Y) <= estimations(X, Y, A) & neutral(X) & neutral(A)

    # 0, +, -
    takeDecision(X) <= estimations(X, Y, A) & neutral(X) & positive(Y) & negative(A)
    # 0, -, +
    takeDecision(X) <= estimations(X, Y, A) & neutral(X) & negative(Y) & positive(A)
    # +, 0, +
    takeDecision(X) <= estimations(X, Y, A) & positive(X) & neutral(Y) & positive(A)
    # -, 0, -
    takeDecision(X) <= estimations(X, Y, A) & negative(X) & neutral(Y) & negative(A)

    # -, -, _ 
    takeDecision(X) <= estimations(X, Y, A) & negative(X) & negative(Y)
    # +, +, _ 
    takeDecision(X) <= estimations(X, Y, A) & positive(X) & positive(Y)

    # 0, +, +
    takeDecision(Y) <= estimations(X, Y, A) & neutral(X) & positive(Y) & positive(A)
    # 0, -, -
    takeDecision(Y) <= estimations(X, Y, A) & neutral(X) & negative(Y) & negative(A)
    # +, 0, -
    takeDecision(Y) <= estimations(X, Y, A) & positive(X) & neutral(Y) & negative(A)
    # -, 0, +
    takeDecision(Y) <= estimations(X, Y, A) & negative(X) & neutral(Y) & positive(A)
    
    # _, _, 0
    takeDecision(X) <= estimations(X, Y, A) & neutral(A)
    # -, +, +
    takeDecision(Y) <= estimations(X, Y, A) & negative(X) & positive(Y) & positive(A)
    # -, +, -
    takeDecision(X) <= estimations(X, Y, A) & negative(X) & positive(Y) & negative(A)
    # +, -, -
    takeDecision(Y) <= estimations(X, Y, A) & positive(X) & negative(Y) & negative(A)
    # +, -, +
    takeDecision(X) <= estimations(X, Y, A) & positive(X) & negative(Y) & positive(A)
    """)

    print("Learning finished")
        pyDatalog.retract_fact('is_sport_person', nombre)
        pyDatalog.retract_fact('is_person', nombre)
        pyDatalog.retract_fact('is_exited', nombre, '3', '600')
        pyDatalog.retract_fact('has_interest_in_sports', nombre, '4', '800')


# CREACIÓN DE LAS REGLAS
pyDatalog.load("""
    is_person(X) <= is_sport_person(X)
    like_suspense(X,0,100) <= is_person(X)
    is_exited(X,3,600) <= is_sport_person(X)
    has_interest_in_sports(X,4,800) <= is_sport_person(X)
""")

# CREACION DIMAMICA DE JUANITO
pyDatalog.assert_fact('is_sport_person', 'Juanito')
pyDatalog.assert_fact('is_person', 'Juanito')
pyDatalog.assert_fact('is_exited', 'Juanito', '3', '600')
pyDatalog.assert_fact('has_interest_in_sports', 'Juanito', '4', '800')
# CREACION DIMAMICA DE PABLITO
pyDatalog.assert_fact('is_sport_person', 'Pablito')
pyDatalog.assert_fact('is_person', 'Pablito')
pyDatalog.assert_fact('is_exited', 'Pablito', '3', '600')
pyDatalog.assert_fact('has_interest_in_sports', 'Pablito', '4', '800')

print("Práctica pyDatalog dinámico\n")

print("Base de conocimiento de personas")

while True:
    print("\n\nSeleccione una opción:\n")
Exemple #20
0
    def __init__(self):
        # Declarar las reglas dinámicamente
        pyDatalog.load("""
    		persona(X) <= trabajador(X)
    		persona(X) <= estudiante(X)
    		trabajador(X) <= activo(X)
    		trabajador(X) <= jubilado(X)
    		estudiante(X) <= preescolar(X)
    		estudiante(X) <= primaria(X)
    		estudiante(X) <= secundaria(X)
    		estudiante(X) <= mediaSuperior(X)
    		estudiante(X) <= universidad(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', 0) <= persona(X)
    		tiene_interes(X, 'juegosInfantiles', -1) <= persona(X)
    		tiene_interes(X, 'series', 4) <= persona(X)
    		tiene_interes(X, 'caricaturas', -2) <= persona(X)
    		tiene_interes(X, 'musica', 2) <= persona(X)
    		tiene_interes(X, 'redesSociales', 2) <= persona(X)
    		tiene_interes(X, 'tareas', 1) <= persona(X)
    		tiene_interes(X, 'navegarIntenet', 4) <= persona(X)
    		tiene_interes(X, 'correo', 2) <= persona(X)
    		tiene_interes(X, 'trabajo', 1) <= persona(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', -5) <= trabajador(X)
    		tiene_interes(X, 'juegosInfantiles', -5) <= trabajador(X)
    		tiene_interes(X, 'series', -1) <= trabajador(X)
    		tiene_interes(X, 'caricaturas', -5) <= trabajador(X)
    		tiene_interes(X, 'musica', 2) <= trabajador(X)
    		tiene_interes(X, 'redesSociales', 1) <= trabajador(X)
    		tiene_interes(X, 'tareas', -5) <= trabajador(X)
    		tiene_interes(X, 'navegarIntenet', 4) <= trabajador(X)
    		tiene_interes(X, 'correo', 4) <= trabajador(X)
    		tiene_interes(X, 'trabajo', 4) <= trabajador(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', 2) <= estudiante(X)
    		tiene_interes(X, 'juegosInfantiles', 2) <= estudiante(X)
    		tiene_interes(X, 'series', 3) <= estudiante(X)
    		tiene_interes(X, 'caricaturas', 1) <= estudiante(X)
    		tiene_interes(X, 'musica', 3) <= estudiante(X)
    		tiene_interes(X, 'redesSociales', 3) <= estudiante(X)
    		tiene_interes(X, 'tareas', 4) <= estudiante(X)
    		tiene_interes(X, 'navegarIntenet', 4) <= estudiante(X)
    		tiene_interes(X, 'correo', 2) <= estudiante(X)
    		tiene_interes(X, 'trabajo', -5) <= estudiante(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', -5) <= activo(X)
    		tiene_interes(X, 'juegosInfantiles', -5) <= activo(X)
    		tiene_interes(X, 'series', -2) <= activo(X)
    		tiene_interes(X, 'caricaturas', -5) <= activo(X)
    		tiene_interes(X, 'musica', 3) <= activo(X)
    		tiene_interes(X, 'redesSociales', 1) <= activo(X)
    		tiene_interes(X, 'tareas', -5) <= activo(X)
    		tiene_interes(X, 'navegarIntenet', 4) <= activo(X)
    		tiene_interes(X, 'correo', 4) <= activo(X)
    		tiene_interes(X, 'trabajo', 5) <= activo(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', -5) <= jubilado(X)
    		tiene_interes(X, 'juegosInfantiles', -5) <= jubilado(X)
    		tiene_interes(X, 'series', 5) <= jubilado(X)
    		tiene_interes(X, 'caricaturas', -5) <= jubilado(X)
    		tiene_interes(X, 'musica', 4) <= jubilado(X)
    		tiene_interes(X, 'redesSociales', 3) <= jubilado(X)
    		tiene_interes(X, 'tareas', -5) <= jubilado(X)
    		tiene_interes(X, 'navegarIntenet', 4) <= jubilado(X)
    		tiene_interes(X, 'correo', 2) <= jubilado(X)
    		tiene_interes(X, 'trabajo', -5) <= jubilado(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', -5) <= preescolar(X)
    		tiene_interes(X, 'juegosInfantiles', 5) <= preescolar(X)
    		tiene_interes(X, 'series', 2) <= preescolar(X)
    		tiene_interes(X, 'caricaturas', 5) <= preescolar(X)
    		tiene_interes(X, 'musica', 1) <= preescolar(X)
    		tiene_interes(X, 'redesSociales', -5) <= preescolar(X)
    		tiene_interes(X, 'tareas', -3) <= preescolar(X)
    		tiene_interes(X, 'navegarIntenet', 1) <= preescolar(X)
    		tiene_interes(X, 'correo', -5) <= preescolar(X)
    		tiene_interes(X, 'trabajo', -5) <= preescolar(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', 1) <= primaria(X)
    		tiene_interes(X, 'juegosInfantiles', 4) <= primaria(X)
    		tiene_interes(X, 'series', 3) <= primaria(X)
    		tiene_interes(X, 'caricaturas', 5) <= primaria(X)
    		tiene_interes(X, 'musica', 2) <= primaria(X)
    		tiene_interes(X, 'redesSociales', -2) <= primaria(X)
    		tiene_interes(X, 'tareas', 0) <= primaria(X)
    		tiene_interes(X, 'navegarIntenet', 2) <= primaria(X)
    		tiene_interes(X, 'correo', -2) <= primaria(X)
    		tiene_interes(X, 'trabajo', -5) <= primaria(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', 4) <= secundaria(X)
    		tiene_interes(X, 'juegosInfantiles', -2) <= secundaria(X)
    		tiene_interes(X, 'series', 5) <= secundaria(X)
    		tiene_interes(X, 'caricaturas', 2) <= secundaria(X)
    		tiene_interes(X, 'musica', 4) <= secundaria(X)
    		tiene_interes(X, 'redesSociales', 3) <= secundaria(X)
    		tiene_interes(X, 'tareas', 3) <= secundaria(X)
    		tiene_interes(X, 'navegarIntenet', 3) <= secundaria(X)
    		tiene_interes(X, 'correo', 1) <= secundaria(X)
    		tiene_interes(X, 'trabajo', -5) <= secundaria(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', 5) <= mediaSuperior(X)
    		tiene_interes(X, 'juegosInfantiles', -5) <= mediaSuperior(X)
    		tiene_interes(X, 'series', 4) <= mediaSuperior(X)
    		tiene_interes(X, 'caricaturas', 0) <= mediaSuperior(X)
    		tiene_interes(X, 'musica', 5) <= mediaSuperior(X)
    		tiene_interes(X, 'redesSociales', 5) <= mediaSuperior(X)
    		tiene_interes(X, 'tareas', 4) <= mediaSuperior(X)
    		tiene_interes(X, 'navegarIntenet', 4) <= mediaSuperior(X)
    		tiene_interes(X, 'correo', 3) <= mediaSuperior(X)
    		tiene_interes(X, 'trabajo', 0) <= mediaSuperior(X)
    	""")
        pyDatalog.load("""
    		tiene_interes(X, 'videojuegos', 5) <= universidad(X)
    		tiene_interes(X, 'juegosInfantiles', -5) <= universidad(X)
    		tiene_interes(X, 'series', 5) <= universidad(X)
    		tiene_interes(X, 'caricaturas', -2) <= universidad(X)
    		tiene_interes(X, 'musica', 5) <= universidad(X)
    		tiene_interes(X, 'redesSociales', 5) <= universidad(X)
    		tiene_interes(X, 'tareas', 5) <= universidad(X)
    		tiene_interes(X, 'navegarIntenet', 4) <= universidad(X)
    		tiene_interes(X, 'correo', 4) <= universidad(X)
    		tiene_interes(X, 'trabajo', 2) <= universidad(X)
    	""")

        #Insertar valores vacíos por defecto
        pyDatalog.assert_fact('persona', '')
        pyDatalog.assert_fact('estudiante', '')
        pyDatalog.assert_fact('jubilado', '')
        pyDatalog.assert_fact('primaria', '')
        pyDatalog.assert_fact('mediaSuperior', '')
        pyDatalog.assert_fact('trabajador', '')
        pyDatalog.assert_fact('activo', '')
        pyDatalog.assert_fact('preescolar', '')
        pyDatalog.assert_fact('secundaria', '')
        pyDatalog.assert_fact('universidad', '')
Exemple #21
0
from reloop.languages.rlp import *
import maxflow_example
from reloop.solvers.lpsolver import CvxoptSolver
from reloop.languages.rlp.logkb import PyDatalogLogKb
from pyDatalog import pyDatalog
"""
Dependencies:
    PyDatalog>0.15.2
--------------------
Maxflow example, which uses the implemented PyDatalog knowledge base interface. The pure python way to define one's
predicates is to assert the predicates via pyDatalog as shown below.

pyDatalog.assert_fact(predicate_name, arg_1, arg_2 ...,arg_n)

Additionally one can use one of the already available solvers and grounders by creating the appropriate object.

grounder = Blockgrounder(logkb) | RecursiveGrounder(logkb)
logkb = PyDatalogKB() | PostgreSQLKb(dbname,user,password) | PrologKb(swi_prolog_object) | ProbLogKb(path_to_pl_file)
solver = CvxoptSolver() | PicosSolver()

Additional parameters for the solver can be passed onto the solver / lifted solver by simply creating the solver object
with the prefered arguments. For more information on the available parameters see lpsolvers.py.

We recommend using the Block Grounding as it is more efficient especially grounding problems with huge amounts of data.
For further information on the different logkbs please see the corresponding examples.

After instantiating the objects one only has to create a model to solve the rlp.

model = ...
"""
Exemple #22
0
# df = pd.DataFrame(regles, columns=['Liaisons'])
# print(df)

pyDatalog.load("""
    P01(X) <=G001(X) & G002(X) & G003(X) & G004(X)
    P02(X) <=G001(X) & G002(X) & G005(X) & G006(X)
    P03(X) <=G007(X) & G008(X)
    P04(X) <=G009(X) & G0010(X) & G0011(X) & G0012(X)
    P05(X) <=G0013(X) & G0014(X) & G0015(X) & G0016(X)
    P06(X) <=G0010(X) & G0015(X) & G0016(X) & G0017(X) & G0018(X) & G0019(X)
    P07(X) <=G0010(X) & G0019(X) & G0020(X) & G0021(X)
    P08(X) <=G001(X) & G0010(X) & G0019(X) & G0022(X)& G0023(X)
    
    blepharite(X) <= P01(X)
    orgelet_de_prevention(X) <= P02(X)
    
   
    G001(X) <= paupiere_rouge(X) 
    G002(X) <= paupiere_enflee(X) 
    G003(X) <= douleur_et_demangeaison_oculaire(X)
    G004(X) <= salete_oculaire_collante(X)
    
""")

pyDatalog.assert_fact('paupiere_rouge', 'fritz')
pyDatalog.assert_fact('paupiere_enflee', 'fritz')
pyDatalog.assert_fact('douleur_et_demangeaison_oculaire', 'fritz')
pyDatalog.assert_fact('salete_oculaire_collante', 'fritz')

print(pyDatalog.ask('blepharite(X)'))
from reloop.languages.rlp import *
import maxflow_example
from reloop.solvers.lpsolver import CvxoptSolver
from reloop.languages.rlp.logkb import PyDatalogLogKb
from pyDatalog import pyDatalog

"""
Dependencies:
    PyDatalog>0.15.2
--------------------
Maxflow example, which uses the implemented PyDatalog knowledge base interface. The pure python way to define one's
predicates is to assert the predicates via pyDatalog as shown below.

pyDatalog.assert_fact(predicate_name, arg_1, arg_2 ...,arg_n)

Additionally one can use one of the already available solvers and grounders by creating the appropriate object.

grounder = Blockgrounder(logkb) | RecursiveGrounder(logkb)
logkb = PyDatalogKB() | PostgreSQLKb(dbname,user,password) | PrologKb(swi_prolog_object) | ProbLogKb(path_to_pl_file)
solver = CvxoptSolver() | PicosSolver()

Additional parameters for the solver can be passed onto the solver / lifted solver by simply creating the solver object
with the prefered arguments. For more information on the available parameters see lpsolvers.py.

We recommend using the Block Grounding as it is more efficient especially grounding problems with huge amounts of data.
For further information on the different logkbs please see the corresponding examples.

After instantiating the objects one only has to create a model to solve the rlp.

model = ...
"""
Exemple #24
0
pyDatalog.clear()
pyDatalog.create_terms(
    'frogs, croakes, eatFlies, canary, chirps, sings, green, yellow, X,FROGS')

frogs(X) <= croakes(X) & eatFlies(X)
canary(X) <= chirps(X) & sings(X)
green(X) <= frogs(X)
yellow(X) <= canary(X)

# croakes[fritz]
# eatFlies[fritz]

# frogs[a]
# canary[b]
pyDatalog.assert_fact('croakes', 'fritz')
pyDatalog.assert_fact('eatFlies', 'fritz')

pyDatalog.assert_fact('frogs', 'a')

pyDatalog.assert_fact('chirps', 'b')
pyDatalog.assert_fact('sings', 'b')
pyDatalog.assert_fact('canary', 'c')

print(frogs(FROGS))

# print(pyDatalog.ask('green(X)'))

# print(eatFlies[b])
# print(len(globals()))
# -*- coding: utf-8 -*-
"""
Created on Thu Dec  5 11:10:21 2019

@author: delan
"""

from pyDatalog import pyDatalog
pyDatalog.clear()

pyDatalog.create_terms('croakes, Pet, frog, chrisp, cannary, sing, yellow, green, eat_flies, p, marg')

frog(Pet) <= croakes(Pet) & eat_flies(Pet)
cannary(Pet) <= chrisp(Pet) & sing(Pet)
green(Pet) <= frog(Pet)
yellow(Pet) <= cannary(Pet)
+croakes(marg)
+eat_flies(marg)
+frog(marg)


pyDatalog.assert_fact('croakes, marg')
pyDatalog.assert_fact('eat_flies, marg')

query = 'green(marg)'
answers = pyDatalog.ask(query).answers
print( answers )
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 29 14:34:10 2019

@author: Margot
"""

from pyDatalog import pyDatalog
pyDatalog.clear()
pyDatalog.create_terms(
    'X, P, rectangle,  angleDroit, quelconque,  equilateral, deuxcote, troiscote, isocele, rectangleIsocele, triangle'
)

pyDatalog.load("""
""")

rectangle(X) <= angleDroit(X)
isocele(X) <= deuxcote(X)
rectangleIsocele(X) <= angleDroit(X) & deuxcote(X)
equilateral(X) <= troiscote(X)

pyDatalog.assert_fact('deuxcote', 'triangle')
pyDatalog.assert_fact('angleDroit', 'triangle')

query = 'isocele(X)'
answers = pyDatalog.ask(query).answers
print(answers)
class Employee(object):
    
    def __init__(self, name, manager, salary): # method to initialize Employee instances
        super(Employee, self).__init__() # calls the initialization method of the object class
        self.name = name
        self.manager = manager           # direct manager of the employee, or None
        self.salary = salary             # monthly salary of the employee
    
    def __repr__(self): # specifies how to display an Employee
        return self.name

John = Employee('John', None, 6800)
Mary = Employee('Mary', John, 6300)

pyDatalog.assert_fact('has_car', Mary)
print(pyDatalog.ask('has_car(X)')) # prints a set with one element : the (Mary) tuple




from pyDatalog import pyDatalog 

class Employee(pyDatalog.Mixin): # --> Employee inherits the pyDatalog capability
    
    def __init__(self, name, manager, salary): 
        # call the initialization method of the Mixin class
        super(Employee, self).__init__()
        self.name = name
        self.manager = manager     # direct manager of the employee, or None
        self.salary = salary       # monthly salary of the employee
Exemple #28
0
from pyDatalog import pyDatalog

pyDatalog.create_terms('X,Y,Z,works_in,is_manager_of,is_indirect_manager_of')

# Crear hechos
+works_in('Mary', 'Production')
+works_in('Sam', 'Marketing')
+works_in('John', 'Production')
+works_in('John', 'Marketing')

+is_manager_of('Mary', 'John')
+is_manager_of('Sam', 'Mary')
+is_manager_of('Tom', 'Mary')

# REGLAS
# Jefe indirecto
is_indirect_manager_of(X, Y) <= is_manager_of(X, Y)
is_indirect_manager_of(
    X, Y) <= is_manager_of(X, Z) & is_indirect_manager_of(Z, Y)

# print(is_indirect_manager_of(X,Y))

# AGREGAR HECHOS AL VUELO
pyDatalog.assert_fact('parent', 'bill', 'John Adams')
W = pyDatalog.ask('parent(Z,X)')

print(W.answers[0][1])
Exemple #29
0
def determineResidualUtility(debug=False):
    rMax = riskDistribution.maxRisk()
    #Uncomment this after debugging
    #Time hog?
    #if debug:
    print "Calculating attack scenarios..."
    costsPlus = pyDatalog.ask("allAttackerPathsCostPlus(SourceService,TargetService,P,E,F,U,TotalC," + str(rMax) + ")")
    #if debug:
    print "Scenarios calculated."
    #if debug:
    #    print "Query: " + "allAttackerPathsCostPlus(SourceService,TargetService,P,E,F,U,TotalC," + str(rMax) + ")"
    #costsPlus = pyDatalog.ask("allAttackerPathsCostPlus(SourceService,TargetService,P,E,F,U,TotalC," + str(1) + ")")
    if costsPlus != None:
        costsPlusSorted = sorted(costsPlus.answers, key=itemgetter(5))
        if debug:
            print "No attack traces"
    else:
        costsPlusSorted = []
        if debug:
            print "Attack traces:"
            pprint.pprint(costsPlusSorted)

    #qFs = pyDatalog.ask("functionQuestionable(FuncName,Util)")
    #print("Questionable functions:")
    #print(qFs.answers)

    compromisedComponents = pyDatalog.ask("probCompromised(SourceService,Prob)")
    if compromisedComponents != None:
        #if debug:
        #    print "Compromised Components x:"
        #    print compromisedComponents.answers
        combos = getCombinations(compromisedComponents.answers,debug)
    else:
        #if debug:
        print "Nothing compromised"

    sumOverCombos = 0
    compromisedAllPossibleAnswer = pyDatalog.ask("compromised(SourceService)").answers
    compromisedAllPossible = [] #List of all possible compromised components
    if compromisedAllPossibleAnswer != None:
        for c in compromisedAllPossibleAnswer:
            compromisedAllPossible.append(c)

    #Loop over each possible combination of compromised components
    #print "Combos: " + str(combos)
    for compromiseCombo in combos:
        compromisedComponents = compromiseCombo[0]
        prob = compromiseCombo[1]
        if debug:
            print "Compromised Components:"
            print compromisedComponents
            print "Prob:"
            print prob


        #New Code to remove from database things that aren't compromised this iteration
        #There are probably better ways to do this for performance
        for cc in compromisedAllPossible:
            if cc[0] not in compromisedComponents:
                if debug:
                    print "Remove " + str(cc[0])
                pyDatalog.retract_fact("compromised",str(cc[0]))
        #Was this right to comment out?
        #costsPlus = pyDatalog.ask("allAttackerPathsCostPlus(SourceService,TargetService,P,E,F,U,TotalC," + str(rMax) + ")")
        #End New Code

        costsPlusSortedLimited = costsPlusSorted #These are just the attack traces with the currently compromised components
        #print costsPlusSorted
        #possibleConnections = itertools.ifilter(lambda connectionPair: connectionDoesNotExist(connectionPair),allPossibleConnections)
        #print CostPlusSorted[0][0]
        costsPlusSortedLimited = [trace for trace in costsPlusSorted if trace[0] in compromisedComponents]
        if debug:
            print "CostPlusSorted Length: "
            print len(costsPlusSorted)
            print len(costsPlusSortedLimited)
        #Find the worst case scenario for any given level of attacker capability
        riskUtilDict = {}
        if debug:
            fDict = {}
            #print "BROKEN CONNECTIONS:"
            #pprint.pprint(pyDatalog.ask("transitiveConnectionBroken(SourceService,TargetService)").answers)
            #print "RTU CONNECTIONS"
            #pprint.pprint(pyDatalog.ask("transitiveConnects('rtus',TargetService)").answers)
        downOrCompUtil = 0

        if False:
            downFunctions = pyDatalog.ask("functionDown(FunctionA,U)") # Required connections are down
            compromisedFunctions = pyDatalog.ask("functionCompromised(FunctionA,U)")
            if downFunctions != None:
                downUtils = downFunctions.answers
                #if debug:
                print "Down Utilities:"
                print downUtils
                #for [f,u] in downUtils:
                    #print u
                    #downUtil += u
            if compromisedFunctions != None:
                compromisedFs = compromisedFunctions.answers
                #if debug:
                print "Compromised Utilities:"
                print compromisedFs
        #Time hog?
        #if debug:
        print "Calculating Down and Compromised Functions"
        downOrCompromisedFunctions = pyDatalog.ask("functionDownOrCompromised(FunctionA,U)")
        #if debug:
        print "Down and Compromised Functions Calculated"
        if downOrCompromisedFunctions == None:
            if debug:
                print "Nothing Down or Compromised"
                fDict[0] = ""
            riskUtilDict[0] = 0
        else:
            downOrCompromisedUtils = downOrCompromisedFunctions.answers
            if debug:
                print "Down or Compromised Utilities:"
                print downOrCompromisedUtils
                #fDict[0] =
            for [f,u] in downOrCompromisedUtils:
                downOrCompUtil += u
            riskUtilDict[0] = downOrCompUtil


        for funcUtilRisk in costsPlusSortedLimited: #Limited to just ones starting from specific compromises
            #u is the questionable utility, not the residual utility
            if debug:
                f = funcUtilRisk[4]
            u = funcUtilRisk[5]
            r = funcUtilRisk[6]
            if r in riskUtilDict:
                #If this is a new worst case scenario for that level of attacker capability
                if u > riskUtilDict[r]:
                    riskUtilDict[r] = u
                    if debug:
                        fDict[r] = f
            #This is the first time seeing this level of risk
            else:
                riskUtilDict[r] = u
                if debug:
                    fDict[r] = f
        if debug:
            print "Worst case scenarios by attacker capability:"
            print riskUtilDict
            print fDict
            riskUtilDictAdjusted = {}

        sum = 0
        worstQuestionableU = downOrCompUtil #To track the worst case so far
        for r in range(0,maxRisk+1):
            if r in riskUtilDict:
                questionableU = riskUtilDict[r]
                if questionableU > worstQuestionableU:
                    worstQuestionableU = questionableU
            if debug:
                riskUtilDictAdjusted[r] = worstQuestionableU

            #Adjust the compromised components here to reflect the particular
            #combination under evaluation


            sum += (maxUtility - worstQuestionableU) * riskDistribution.probabilityOfRisk(r)
        #print("Residual utility: " + str(sum))
        if debug:
            print "Adjusted worst case scenarios:"
            print riskUtilDictAdjusted
            print "Sum: " + str(sum)
            print "Prob: " + str(prob)
        sumOverCombos += sum * prob

        #New code to put back in compromised components for next loop iteration
        for cc in compromisedAllPossible:
            if cc[0] not in compromisedComponents:
                if debug:
                    print "Add back " + str(cc[0])
                pyDatalog.assert_fact("compromised",str(cc[0]))
        #End new code
    if debug:
        print "Residual Utility:"
    #print sumOverCombos
    return sumOverCombos
def load_data():
    #Generation 1
    gen1 = ["Jose Arcadio Buendia", "Ursula Iguaran"]
    pyDatalog.assert_fact('married', gen1[0], gen1[1])
    pyDatalog.assert_fact('cousin', gen1[0], gen1[1])
    pyDatalog.assert_fact('buendia_blood', gen1[0], True)
    pyDatalog.assert_fact('buendia_blood', gen1[1], True)
    pyDatalog.assert_fact('gender', gen1[0], 'Male')
    pyDatalog.assert_fact('gender', gen1[1], 'Female')

    # Generation 2
    gen2 = [
        "Colonel Aureliano Buendia", "Jose Arcadio Buendia (II)",
        "Amaranta Buendia", "Pilar Ternera", "Remedios Moscote",
        "Rebeca Buendia"
    ]
    pyDatalog.assert_fact('parent', gen1[0], gen2[0])
    pyDatalog.assert_fact('parent', gen1[1], gen2[0])
    pyDatalog.assert_fact('parent', gen1[0], gen2[1])
    pyDatalog.assert_fact('parent', gen1[1], gen2[1])
    pyDatalog.assert_fact('parent', gen1[0], gen2[2])
    pyDatalog.assert_fact('parent', gen1[1], gen2[2])
    pyDatalog.assert_fact('gender', gen2[2], 'Female')
    pyDatalog.assert_fact('gender', gen2[0], 'Male')
    pyDatalog.assert_fact('gender', gen2[1], 'Male')
    pyDatalog.assert_fact('gender', gen2[3], 'Female')
    pyDatalog.assert_fact('gender', gen2[4], 'Female')
    pyDatalog.assert_fact('gender', gen2[5], 'Female')
    pyDatalog.assert_fact('buendia_blood', gen2[0], True)
    pyDatalog.assert_fact('buendia_blood', gen2[1], True)
    pyDatalog.assert_fact('buendia_blood', gen2[2], True)
    pyDatalog.assert_fact('buendia_blood', gen2[3], False)
    pyDatalog.assert_fact('buendia_blood', gen2[4], False)
    pyDatalog.assert_fact('buendia_blood', gen2[5], False)
    pyDatalog.assert_fact('buendia', gen2[0], True)
    pyDatalog.assert_fact('buendia', gen2[1], True)
    pyDatalog.assert_fact('buendia', gen2[2], True)
    pyDatalog.assert_fact('buendia', gen2[3], False)
    pyDatalog.assert_fact('buendia', gen2[4], True)
    pyDatalog.assert_fact('buendia', gen2[5], True)
    pyDatalog.assert_fact('married', gen2[0], gen2[4])
    pyDatalog.assert_fact('married', gen2[1], gen2[5])

    # Generation 3
    gen3 = [
        "The 17 Aurelianos", "Aureliano Jose Buendia",
        "Arcadio (Jose Arcadio III)", "Santa Sofia de la Piedad"
    ]
    pyDatalog.assert_fact('parent', gen2[0], gen3[0])
    pyDatalog.assert_fact('parent', gen2[0], gen3[1])
    pyDatalog.assert_fact('parent', gen2[3], gen3[1])
    pyDatalog.assert_fact('parent', gen2[1], gen3[2])
    pyDatalog.assert_fact('parent', gen2[3], gen3[2])
    pyDatalog.assert_fact('gender', gen3[0], 'Male')
    pyDatalog.assert_fact('gender', gen3[1], 'Male')
    pyDatalog.assert_fact('gender', gen3[2], 'Male')
    pyDatalog.assert_fact('gender', gen3[3], 'Female')
    pyDatalog.assert_fact('buendia_blood', gen3[0], True)
    pyDatalog.assert_fact('buendia_blood', gen3[1], True)
    pyDatalog.assert_fact('buendia_blood', gen3[2], True)
    pyDatalog.assert_fact('buendia_blood', gen3[3], False)
    pyDatalog.assert_fact('buendia', gen3[0], True)
    pyDatalog.assert_fact('buendia', gen3[1], True)
    pyDatalog.assert_fact('buendia', gen3[2], True)
    pyDatalog.assert_fact('buendia', gen3[3], True)
    pyDatalog.assert_fact('married', gen3[2], gen3[3])

    # Generation 4
    gen4 = [
        "Remedios the Beauty", "Fernanda del Carpio",
        "Aureliano Segundo Buendia", "Jose Arcadio Segundo Buendia"
    ]
    pyDatalog.assert_fact('parent', gen3[2], gen4[0])
    pyDatalog.assert_fact('parent', gen3[3], gen4[0])
    pyDatalog.assert_fact('parent', gen3[2], gen4[2])
    pyDatalog.assert_fact('parent', gen3[3], gen4[2])
    pyDatalog.assert_fact('parent', gen3[2], gen4[3])
    pyDatalog.assert_fact('parent', gen3[3], gen4[3])
    pyDatalog.assert_fact('gender', gen4[0], 'Female')
    pyDatalog.assert_fact('gender', gen4[1], 'Female')
    pyDatalog.assert_fact('gender', gen4[2], 'Male')
    pyDatalog.assert_fact('gender', gen4[3], 'Male')
    pyDatalog.assert_fact('buendia_blood', gen4[0], True)
    pyDatalog.assert_fact('buendia_blood', gen4[1], False)
    pyDatalog.assert_fact('buendia_blood', gen4[2], True)
    pyDatalog.assert_fact('buendia_blood', gen4[3], True)
    pyDatalog.assert_fact('buendia', gen4[0], True)
    pyDatalog.assert_fact('buendia', gen4[1], True)
    pyDatalog.assert_fact('buendia', gen4[2], True)
    pyDatalog.assert_fact('buendia', gen4[3], True)
    pyDatalog.assert_fact('married', gen4[2], gen4[1])

    gen5 = [
        'Jose Arcadio Buendia (IV)', 'Renata Remedios Buendia (Meme)',
        'Mauricio Babilonia', 'Amaranta Ursula Buendia'
    ]
    pyDatalog.assert_fact('parent', gen4[2], gen5[0])
    pyDatalog.assert_fact('parent', gen4[1], gen5[0])
    pyDatalog.assert_fact('parent', gen4[2], gen5[1])
    pyDatalog.assert_fact('parent', gen4[1], gen5[1])
    pyDatalog.assert_fact('parent', gen4[2], gen5[3])
    pyDatalog.assert_fact('parent', gen4[1], gen5[3])
    pyDatalog.assert_fact('gender', gen5[0], 'Male')
    pyDatalog.assert_fact('gender', gen5[1], 'Female')
    pyDatalog.assert_fact('gender', gen5[2], 'Male')
    pyDatalog.assert_fact('gender', gen5[3], 'Female')
    pyDatalog.assert_fact('buendia_blood', gen5[0], True)
    pyDatalog.assert_fact('buendia_blood', gen5[1], True)
    pyDatalog.assert_fact('buendia_blood', gen5[2], False)
    pyDatalog.assert_fact('buendia_blood', gen5[3], True)
    pyDatalog.assert_fact('buendia', gen5[0], True)
    pyDatalog.assert_fact('buendia', gen5[1], True)
    pyDatalog.assert_fact('buendia', gen5[2], False)
    pyDatalog.assert_fact('buendia', gen5[3], True)

    gen6 = ['Aureliano (II)', 'Gaston']
    pyDatalog.assert_fact('parent', gen5[1], gen6[0])
    pyDatalog.assert_fact('parent', gen5[2], gen6[0])
    pyDatalog.assert_fact('gender', gen6[0], 'Male')
    pyDatalog.assert_fact('gender', gen6[1], 'Male')
    pyDatalog.assert_fact('buendia_blood', gen6[0], True)
    pyDatalog.assert_fact('buendia_blood', gen6[1], False)
    pyDatalog.assert_fact('buendia', gen6[0], True)
    pyDatalog.assert_fact('buendia', gen6[1], False)
    pyDatalog.assert_fact('married', gen6[1], gen5[3])

    gen7 = ['Aureliano (III)']
    pyDatalog.assert_fact('parent', gen6[0], gen7[0])
    pyDatalog.assert_fact('parent', gen5[3], gen7[0])
    pyDatalog.assert_fact('buendia_blood', gen7[0], True)
    pyDatalog.assert_fact('buendia', gen7[0], True)
Exemple #31
0
def tryTacticOptions(maxTactics,debug=False):
    #Initialize utilities dictionary for each of the tactic options
    utilities = {}
    #if debug:
    #bestUtility = float(0)
    originalUtil = float(determineResidualUtility())
    bestUtility = originalUtil
    print("Original utility: " + str(originalUtil))
    utilities[""] = originalUtil

    #For progress tracking
    numOptions = 0
    for numTactics in range(1,maxTactics+1):
        numOptions += len(list(itertools.combinations(tacticsIter(),numTactics)))
        #TODO? Put following line back in
        #utilities[None] = float(determineResidualUtility())

    setNumber = 0

    print("Tactic options: " + str(numOptions))
    #TODO Extra double-check to ensure logic is correct here...should be all possible vulnerabilities
    #TODO Also try zero tactics! Maybe current config is the best
    for numTactics in range(1,maxTactics+1):
        #Creator iterator of tactic sets to try
        tacticOptions = itertools.combinations(tacticsIter(),numTactics)
        #if numTactics == 0:
        #    tacticOptions = iter([[]])
        for tacticSet in tacticOptions:
            #Print status
            setNumber += 1
            percentComplete = 100 * setNumber / numOptions
            print(str(percentComplete) + "%...\r"),
            sys.stdout.flush()
            #print "***************************************"
            #print "Tactic Set:"
            #print tacticSet
            #Apply the tactics in the selected tactic set
            for tactic in tacticSet:
                #print tactic
                args = tactic[1:]
                if tactic[0] == "retract":
                    pyDatalog.retract_fact(*args)
                    if bidirectional:
                        if tactic[1] == "networkConnectsTo": #retract the symmetric connection
                            #TODO Did we already do this in the code above? Is it a safe assumption that the reversed connection has the same CIA attributes?
                            #Changed
                            argsRev = [args[0],args[2],args[1],args[3],args[4],args[5]]
                            pyDatalog.retract_fact(*argsRev)
                else:
                    pyDatalog.assert_fact(*args)
            #Determine utility and put in dictionary
            #This weighted value includes cost of tactic: A cost of 1 per tactic
            tsStr = str(sorted(list(tacticSet))) #key
            residualUtil = float(determineResidualUtility() - numTactics) #value
            if debug and residualUtil>=bestUtility:
                print("New optimal: " + str(residualUtil) + str(tacticSet))
                bestUtility = residualUtil
            #TODO The check for multiple tactics may not be necessary in some versions of this code
            if tsStr in utilities:
                #print("MULTIPLE: " + tsStr + ": " + str(residualUtil))
                if residualUtil < utilities[tsStr]:
                    utilities[tsStr] = residualUtil
            else:
                utilities[tsStr] = residualUtil
            #Undo the tactic application
            for tactic in tacticSet:
                args = tactic[1:]
                if tactic[0] == "assert":
                    pyDatalog.retract_fact(*args)
                    #Changed
                    #TODO Is this a safe assumption that the reversed connection has the same CIA attributes?
                    if (tactic[1] == "networkConnectsToWithAttributes") and (bidirectional == True):
                        pyDatalog.retract_fact(args[0],args[2],args[1],args[3],args[4],args[5])
                else:
                    pyDatalog.assert_fact(*args)
    #pprint.pprint(utilities)
    #Find the best performing tactic set in the dictionary created earlier
    bestOptions(utilities)
from pyDatalog import  pyDatalog

pyDatalog.create_terms('fritz,X,croakes,eatFlies,frog,chirps,sings,canary,green,yellow')
#pyDatalog.create_atoms('croakes','eatFlies','frog','chirps','sings','canary','green','yellow')

frog(X) <= croakes(X) & eatFlies(X)
canary(X) <= sings(X) & chirps(X)

#frog(X) <= green(X)
green(X) <= frog(X)
canary(X) <= yellow(X)

# fritz is a frog
#+ (frog(fritz))

pyDatalog.assert_fact('croakes','fritz')
pyDatalog.assert_fact('eatFlies','fritz')

print("Frog :",pyDatalog.ask('frog(X)').answers)
print("Green :",pyDatalog.ask('green(X)').answers)
def addIngredient(name, calorie, glutenFree, lactoseFree, vegan, vegetarian):
    isAlreadyDefined = pyDatalog.ask("hasID('" + name + "', 'ingredient', Z)")
    if (not isAlreadyDefined == None):
        print("This ingredient is already defined")
        return isAlreadyDefined.answers[0][0]

    # insert ingredient in database
    database = connectToDatabase()
    mydb = database[0]
    mycursor = database[1]
    sqlZutat = "INSERT INTO `Lebensmittel` (`Name`, `KalorienPro100g`, `Fleisch`, `Tierprodukt`, `Gluten`, `Krebstiere`, `Eier`, `Fisch`, `Erdnuesse`, `Sojabohnen`, `Milch`, `Schalenfruechte`, `Sellerie`, `Sesamsamen`, `Schwefeldioxid`, `Lupinien`, `Weichtiere`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
    valZutat = [(name, calorie, 0 if vegetarian else 1, 0 if vegan else 1,
                 0 if glutenFree else 1, 0, 0, 0, 0, 0,
                 0 if lactoseFree else 1, 0, 0, 0, 0, 0, 0)]
    mycursor.executemany(sqlZutat, valZutat)
    mydb.commit()
    ingredientNumber = mycursor.lastrowid
    id = "ingredient" + str(ingredientNumber)

    # add ingredient to datalog
    pyDatalog.assert_fact('hasID', name, "ingredient", id)
    pyDatalog.assert_fact('hasCaloriesPer100g', name, calorie)
    if not glutenFree:
        pyDatalog.assert_fact('containsGluten', name)
    if not lactoseFree:
        pyDatalog.assert_fact('containsLactose', name)
    if not vegetarian:
        pyDatalog.assert_fact('containsMeat', name)
    if (not vegetarian) | (not vegan):
        pyDatalog.assert_fact('containsAnimalProduct', name)
    pyDatalog.assert_fact('weightPerServing', name, 1)
def add_facts(pruned_data):
    print('adding data:', pruned_data)
    evaluated_data = ast.literal_eval(pruned_data)
    for entry in evaluated_data:
        pyDatalog.assert_fact(entry[0], entry[1])
Exemple #35
0
def main(argv):
    def formatter(prog):
        return argparse.HelpFormatter(prog, max_help_position=100, width=200)

    argparser = argparse.ArgumentParser('Populate a Knowledge Base',
                                        formatter_class=formatter)

    argparser.add_argument('triples', action='store', type=str, default=None)
    argparser.add_argument('clauses', action='store', type=str, default=None)
    argparser.add_argument('--output',
                           '-o',
                           action='store',
                           type=str,
                           default=None)

    args = argparser.parse_args(argv)

    triples_path = args.triples
    clauses_path = args.clauses
    output_path = args.output

    triples, _ = read_triples(triples_path)

    # Parse the clauses using Sebastian's parser
    with open(clauses_path, 'r') as f:
        clauses_str = [line.strip() for line in f.readlines()]
    clauses = [parse_clause(clause_str) for clause_str in clauses_str]

    # Create a set containing all the entities from the triples
    entity_names = {s for (s, _, _) in triples} | {o for (_, _, o) in triples}

    # Create a set containing all predicate names from the triples and clauses
    predicate_names = {p for (_, p, _) in triples}
    for clause in clauses:
        predicate_names |= {clause.head.predicate.name}
        for atom in clause.body:
            predicate_names |= {atom.predicate.name}

    # Associate each entity and predicate to an unique index
    entity_to_idx = {entity: idx for idx, entity in enumerate(entity_names)}
    idx_to_entity = {idx: entity for entity, idx in entity_to_idx.items()}

    predicate_to_idx = {
        predicate: idx
        for idx, predicate in enumerate(predicate_names)
    }
    idx_to_predicate = {
        idx: predicate
        for predicate, idx in predicate_to_idx.items()
    }

    logger.info('Asserting facts ..')

    # Asserting the facts
    for (s, p, o) in triples:
        pyDatalog.assert_fact('p', entity_to_idx[s], predicate_to_idx[p],
                              entity_to_idx[o])

    logger.info('Querying triples ..')

    ans = pyDatalog.ask('p(S, P, O)')
    print(len(ans.answers))

    logger.info('Loading rules ..')

    def atom_to_str(atom):
        atom_predicate_idx = predicate_to_idx[atom.predicate.name]
        atom_arg_0, atom_arg_1 = atom.arguments[0], atom.arguments[1]
        return 'p({}, {}, {})'.format(atom_arg_0, atom_predicate_idx,
                                      atom_arg_1)

    def clause_to_str(clause):
        head, body = clause.head, clause.body
        return '{} <= {}'.format(atom_to_str(head),
                                 ' & '.join([atom_to_str(a) for a in body]))

    rules_str = '\n'.join([clause_to_str(clause) for clause in clauses])

    pyDatalog.load(rules_str)

    logger.info('Querying triples ..')

    ans = pyDatalog.ask('p(S, P, O)')
    answers = sorted(ans.answers)
Exemple #36
0
def moveService(ServiceA,HostA,HostB):
    pyDatalog.retract_fact(residesOn,ServiceA,HostA)
    pyDatalog.assert_fact(residesOn,HostB)
                       Les yeux brillent,Douleur oculaire,Vision diminuée,Sensation de douleur légère à sévère,Yeux sales,\
                       Douleur intense,Yeux enflés difficiles à ouvrir,')

load("""
""")

P01(X) <= G001(X) & G002(X) & G003(X) & G004(X)
P02(X) <= G001(X) & G002(X) & G005(X) & G006(X)
P03(X) <= G007(X) & G008(X)
P04(X) <= G009(X) & G010(X) & G011(X) & G012(X)
P05(X) <= G013(X) & G014(X) & G015(X) & G016(X)
P06(X) <= G010(X) & G015(X) & G016(X) & G017(X) & G018(X) & G019(X)
P07(X) <= G010(X) & G019(X) & G020(X) & G021(X)
P08(X) <= G001(X) & G010(X) & G022(X) & G023(X)

pyDatalog.assert_fact('G001', 'Paupière rouge')
pyDatalog.assert_fact('G002', 'Paupière enflée')
pyDatalog.assert_fact('G003', 'Douleur oculaire et démangeaisons')
pyDatalog.assert_fact('G004',
                      'La saleté oculaire est collante et dépend des cils')
pyDatalog.assert_fact('G005', 'Ressentir une gêne et des douleurs oculaires')
pyDatalog.assert_fact('G006', 'Douleur quand on presse')
pyDatalog.assert_fact('G007', 'Bosse sur les paupières dans quelques semaines')
pyDatalog.assert_fact('G008', 'Indolore lorsqu il est pressé')
pyDatalog.assert_fact('G009', 'Il y a un peu de poussière dans l oeil')
pyDatalog.assert_fact('G010', 'Yeux rouges')
pyDatalog.assert_fact('G011', 'Les yeux sont un peu irritants et douloureux')
pyDatalog.assert_fact('G012', 'Maux de gorge et fièvre')
pyDatalog.assert_fact('G013', 'Yeux qui piquent')
pyDatalog.assert_fact('G014', 'Yeux enflés et douloureux')
pyDatalog.assert_fact('G015', 'Yeux larmoyants')
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)'))
Exemple #39
0
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)]
    """