def test_rule_sub2():

    rules_text = """

        father_child(massimo, ridge).
        father_child(eric, thorne).
        father_child(thorne, alexandria).

        mother_child(stephanie, chloe).
        mother_child(stephanie, kristen).
        mother_child(stephanie, felicia).

        parent_child(X, Y) :- father_child(X, Y).
        parent_child(X, Y) :- mother_child(X, Y).

        sibling(X, Y) :- parent_child(Z, X), parent_child(Z, Y).

    """

    query_text = """

        sibling(X, felicia)

    """

    solver = Solver(rules_text)
    solutions = solver.find_solutions(query_text)

    assert len(solutions.get("X")) == 3

    assert ("chloe" in str(solution) for solution in solutions.get("X"))
    assert ("kristen" in str(solution) for solution in solutions.get("X"))
    assert ("alexandria" in str(solution) for solution in solutions.get("X"))
def test_find_bad_dog():

    rules_text = """
        
        bad_dog(Dog) :-
           bites(Dog, Person),
           is_person(Person),
           is_dog(Dog).
        
        bites(fido, postman).
        is_person(postman).
        is_dog(fido).

    """

    query_text = """

        bad_dog( X )

    """

    solver = Solver(rules_text)
    solutions = solver.find_solutions(query_text)

    assert len(solutions.get("X")) == 1

    assert ("fido" in str(solution) for solution in solutions.get("X"))
def test_rule_sub():

    rules_text = """

        descendant(X, Y) :- offspring(X, Y).
        descendant(X, Z) :- offspring(X, Y), descendant(Y, Z).
        
        offspring(abraham, ishmael).
        offspring(abraham, isaac).
        offspring(isaac, esau).
        offspring(isaac, jacob).

    """

    query_text = """

        descendant(abraham, X).

    """

    solver = Solver(rules_text)
    solutions = solver.find_solutions(query_text)

    assert len(solutions.get("X")) == 4

    assert ("ishmael" in str(solution) for solution in solutions.get("X"))
    assert ("isaac" in str(solution) for solution in solutions.get("X"))
    assert ("esau" in str(solution) for solution in solutions.get("X"))
    assert ("jacob" in str(solution) for solution in solutions.get("X"))
Exemple #4
0
def run_query(rules_text, query_text):
    """Interpret the entered rules and query and display the results in the
    solutions text box """

    try:
        solver = Solver(rules_text)
    except Exception as e:
        error = "Error processing prolog rules." + str(e)
        return

    # Attempt to find the solutions and handle any exceptions gracefully
    try:
        solutions = solver.find_solutions(query_text)
    except Exception as e:
        error = "Error processing prolog query." + str(e)
        return

    # If our query returns a boolean, we simply display a 'Yes' or a 'No'
    # depending on its value
    if isinstance(solutions, bool):
        solutions_display = "Yes." if solutions else "No."

    # Our solver returned a map, so we display the variable name to value mappings
    elif isinstance(solutions, dict):
        solutions_display = "\n".join(
            "{} = {}".format(variable, value[0] if len(value) == 1 else value)
            for variable, value in solutions.items())
    else:
        # We know we have no matching solutions in this instance so we provide
        # relevant feedback
        solutions_display = "No solutions found."
    return solutions_display
    def run_query(self):
        """Interpret the entered rules and query and display the results in the
        solutions text box """

        # Delete all of the text in our solutions display text box
        self.solutions_display.delete("1.0", END)

        self.set_busy()

        # Fetch the raw rule / query text entered by the user
        rules_text = self.rule_editor.get(1.0, "end-1c")
        query_text = self.query_editor.get(1.0, "end-1c")

        # Create a new solver so we can try to query for solutions.
        try:
            solver = Solver(rules_text)
        except Exception as e:
            self.handle_exception("Error processing prolog rules.", str(e))
            return

        # Attempt to find the solutions and handle any exceptions gracefully
        try:
            solutions = solver.find_solutions(query_text)
        except Exception as e:
            self.handle_exception("Error processing prolog query.", str(e))
            return

        # If our query returns a boolean, we simply display a 'Yes' or a 'No'
        # depending on its value
        if isinstance(solutions, bool):
            self.solutions_display.insert(END, "Yes." if solutions else "No.")

        # Our solver returned a map, so we display the variable name to value mappings
        elif isinstance(solutions, dict):
            self.solutions_display.insert(
                END,
                "\n".join(
                    "{} = {}"
                    # If our solution is a list contining one item, we show that
                    # item, otherwise we display the entire list
                    .format(variable, value[0] if len(value) == 1 else value)
                    for variable, value in solutions.items()
                ),
            )
        else:

            # We know we have no matching solutions in this instance so we provide
            # relevant feedback
            self.solutions_display.insert(END, "No solutions found.")

        self.set_not_busy()
def test_multiple_var_query():

    rules_text = """

        father(jack, susan).                            
        father(jack, ray).                             
        father(david, liza).                       
        father(david, john).                           
        father(john, peter).                
        father(john, mary).                     
        mother(karen, susan).                        
        mother(karen, ray).                              
        mother(amy, liza).                        
        mother(amy, john).                        
        mother(susan, peter).                            
        mother(susan, mary).                             
        
        parent(X, Y) :- father(X, Y).                    
        parent(X, Y) :- mother(X, Y).                    
        grandfather(X, Y) :- father(X, Z), parent(Z, Y).
        grandmother(X, Y) :- mother(X, Z), parent(Z, Y). 
        grandparent(X, Y) :- parent(X, Z), parent(Z, Y). 

    """

    query_text = """

        grandparent(X, Y)

    """

    solver = Solver(rules_text)
    solution_map = solver.find_solutions(query_text)
    solutions = list(zip(solution_map.get("X"), solution_map.get("Y")))

    assert len(solutions) == 8

    assert ("(jack, peter)" in str(solution) for solution in solutions)
    assert ("(jack, mary)" in str(solution) for solution in solutions)
    assert ("(david, peter)" in str(solution) for solution in solutions)
    assert ("(david, mary)" in str(solution) for solution in solutions)
    assert ("(karen, peter)" in str(solution) for solution in solutions)
    assert ("(karen, mary)" in str(solution) for solution in solutions)
    assert ("(amy, peter)" in str(solution) for solution in solutions)
    assert ("(amy, peter)" in str(solution) for solution in solutions)
def test_simple_goal_query2():
    rules_text = """

        brother_sister(joe, monica).
        brother_sister(eric, erica).
        brother_sister(jim, rebecca).

    """

    goal_text = """

        brother_sister(joe, rebecca).

    """

    solver = Solver(rules_text)
    solution = solver.find_solutions(goal_text)

    assert not solution
def test_simple_variable_query():

    rules_text = """

        father_child(mike, john).
        father_child(eric, sarah).
        father_child(bob, jim).

    """

    query_text = """

        father_child(X, sarah).

    """

    solver = Solver(rules_text)
    solutions = solver.find_solutions(query_text)

    assert len(solutions.get("X")) == 1

    assert str(solutions.get("X").pop()) == "eric"
def test_multi_variable_solutions():

    rules_text = """

        is_tall(jack, yes).
        is_tall(eric, no).
        is_tall(johnny, yes).
        is_tall(mark, no).

    """

    query_text = """

        is_tall(Y, yes)

    """

    solver = Solver(rules_text)
    solutions = solver.find_solutions(query_text)

    assert len(solutions.get("Y")) == 2

    assert ("jack" in str(solution) for solution in solutions.get("Y"))
    assert ("johnny" in str(solution) for solution in solutions.get("Y"))
def test_alternate_einstein_puzzle():

    rules_text = """ 

        exists(A, list(A, _, _, _, _)).
        exists(A, list(_, A, _, _, _)).
        exists(A, list(_, _, A, _, _)).
        exists(A, list(_, _, _, A, _)).
        exists(A, list(_, _, _, _, A)).

        rightOf(R, L, list(L, R, _, _, _)).
        rightOf(R, L, list(_, L, R, _, _)).
        rightOf(R, L, list(_, _, L, R, _)).
        rightOf(R, L, list(_, _, _, L, R)).

        middle(A, list(_, _, A, _, _)).

        first(A, list(A, _, _, _, _)).

        nextTo(A, B, list(B, A, _, _, _)).
        nextTo(A, B, list(_, B, A, _, _)).
        nextTo(A, B, list(_, _, B, A, _)).
        nextTo(A, B, list(_, _, _, B, A)).
        nextTo(A, B, list(A, B, _, _, _)).
        nextTo(A, B, list(_, A, B, _, _)).
        nextTo(A, B, list(_, _, A, B, _)).
        nextTo(A, B, list(_, _, _, A, B)).

        puzzle(Houses) :-
              exists(house(red, british, _, _, _), Houses),
              exists(house(_, swedish, _, _, dog), Houses),
              exists(house(green, _, coffee, _, _), Houses),
              exists(house(_, danish, tea, _, _), Houses),
              rightOf(house(white, _, _, _, _), house(green, _, _, _, _), Houses),
              exists(house(_, _, _, pall_mall, bird), Houses),
              exists(house(yellow, _, _, dunhill, _), Houses),
              middle(house(_, _, milk, _, _), Houses),
              first(house(_, norwegian, _, _, _), Houses),
              nextTo(house(_, _, _, blend, _), house(_, _, _, _, cat), Houses),
              nextTo(house(_, _, _, dunhill, _),house(_, _, _, _, horse), Houses),
              exists(house(_, _, beer, bluemaster, _), Houses),
              exists(house(_, german, _, prince, _), Houses),
              nextTo(house(_, norwegian, _, _, _), house(blue, _, _, _, _), Houses),
              nextTo(house(_, _, _, blend, _), house(_, _, water_, _, _), Houses).

        solution(FishOwner) :-
          puzzle(Houses),
          exists(house(_, FishOwner, _, _, fish), Houses).

    """

    query_text = """

        solution(FishOwner)

    """

    solver = Solver(rules_text)
    solutions = solver.find_solutions(query_text)

    assert len(solutions.get("FishOwner")) == 1

    assert "german" in [
        str(solution) for solution in solutions.get("FishOwner")
    ]
def test_einstein_puzzle():

    rules_text = """ 

        exists(A, list(A, _, _, _, _)).
        exists(A, list(_, A, _, _, _)).
        exists(A, list(_, _, A, _, _)).
        exists(A, list(_, _, _, A, _)).
        exists(A, list(_, _, _, _, A)).
        
        rightOf(R, L, list(L, R, _, _, _)).
        rightOf(R, L, list(_, L, R, _, _)).
        rightOf(R, L, list(_, _, L, R, _)).
        rightOf(R, L, list(_, _, _, L, R)).
        
        middle(A, list(_, _, A, _, _)).
        
        first(A, list(A, _, _, _, _)).
        
        nextTo(A, B, list(B, A, _, _, _)).
        nextTo(A, B, list(_, B, A, _, _)).
        nextTo(A, B, list(_, _, B, A, _)).
        nextTo(A, B, list(_, _, _, B, A)).
        nextTo(A, B, list(A, B, _, _, _)).
        nextTo(A, B, list(_, A, B, _, _)).
        nextTo(A, B, list(_, _, A, B, _)).
        nextTo(A, B, list(_, _, _, A, B)).

        puzzle(Houses) :-
              exists(house(red, english, _, _, _), Houses),
              exists(house(_, spaniard, _, _, dog), Houses),
              exists(house(green, _, coffee, _, _), Houses),
              exists(house(_, ukrainian, tea, _, _), Houses),
              rightOf(house(green, _, _, _, _), 
              house(ivory, _, _, _, _), Houses),
              exists(house(_, _, _, oldgold, snails), Houses),
              exists(house(yellow, _, _, kools, _), Houses),
              middle(house(_, _, milk, _, _), Houses),
              first(house(_, norwegian, _, _, _), Houses),
              nextTo(house(_, _, _, chesterfield, _), house(_, _, _, _, fox), Houses),
              nextTo(house(_, _, _, kools, _),house(_, _, _, _, horse), Houses),
              exists(house(_, _, orangejuice, luckystike, _), Houses),
              exists(house(_, japanese, _, parliament, _), Houses),
              nextTo(house(_, norwegian, _, _, _), house(blue, _, _, _, _), Houses),
              exists(house(_, _, water, _, _), Houses),
              exists(house(_, _, _, _, zebra), Houses).

        solution(WaterDrinker, ZebraOwner) :-
              puzzle(Houses),
              exists(house(_, WaterDrinker, water, _, _), Houses),
              exists(house(_, ZebraOwner, _, _, zebra), Houses).

    """

    query_text = """

        solution(WaterDrinker, ZebraOwner)

    """

    solver = Solver(rules_text)
    solutions = solver.find_solutions(query_text)

    assert ("norwegian" in str(solution)
            for solution in solutions.get("WaterDrinker"))
    assert ("japanese" in str(solution)
            for solution in solutions.get("ZebraOwner"))