Example #1
0
    def _assert_knowledge(self, knowledge: Knowledge):
        """
        Assert knowledge into Prolog engine
        """
        facts = knowledge.get_atoms()
        for f_ind in range(len(facts)):
            self._solver.assertz(facts[f_ind])

        clauses = knowledge.get_clauses()
        for cl_ind in range(len(clauses)):
            self._solver.assertz(clauses[cl_ind])
Example #2
0
def learn_with_constants():
    """
    Consider a row of blocks [ block1 block2 block3 block4 block5 block6 ]
    The order of this row is expressed using follows(X,Y)
    The color of a block is expressed using color(X,Color)
    
    Goal: learn a function f that says: a block is positive when it is followed by a red block
    pos(X) :- next(X,Y), color(Y,red)
    """
    block = c_type("block")
    col = c_type("col")

    block1 = c_const("block1", domain=block)  # blue -> positive
    block2 = c_const("block2", domain=block)  # red
    block3 = c_const("block3", domain=block)  # green -> positive
    block4 = c_const("block4", domain=block)  # red -> positive
    block5 = c_const("block5", domain=block)  # red
    block6 = c_const("block6", domain=block)  # green
    block7 = c_const("block7", domain=block)  # blue
    block8 = c_const("block8", domain=block)  # blue

    red = c_const("red", domain="col")
    green = c_const("green", domain="col")
    blue = c_const("blue", domain="col")

    follows = c_pred("follows", 2, domains=[block, block])
    color = c_pred("color", 2, domains=[block, col])

    # Predicate to learn:
    f = c_pred("f", 1, domains=[block])

    bk = Knowledge(follows(block1, block2), follows(block2, block3),
                   follows(block3, block4), follows(block4, block5),
                   follows(block5, block6), follows(block6, block7),
                   follows(block7, block8), color(block1, blue),
                   color(block2, red), color(block3,
                                             green), color(block4, red),
                   color(block5, red), color(block6, green),
                   color(block7, blue), color(block8, blue))

    pos = {f(x) for x in [block1, block3, block4]}
    neg = {f(x) for x in [block2, block5, block6, block7, block8]}

    task = Task(positive_examples=pos, negative_examples=neg)
    solver = SWIProlog()

    # EvalFn must return an upper bound on quality to prune search space.
    eval_fn1 = Coverage(return_upperbound=True)
    eval_fn2 = Compression(return_upperbound=True)
    eval_fn3 = Accuracy(return_upperbound=True)

    learners = [
        Aleph(solver, eval_fn, max_body_literals=4, do_print=False)
        for eval_fn in [eval_fn1, eval_fn3]
    ]

    for learner in learners:
        res = learner.learn(task, bk, None, minimum_freq=1)
        print(res)
Example #3
0
def learn_simpsons():
    # define the predicates
    father = c_pred("father", 2)
    mother = c_pred("mother", 2)
    grandparent = c_pred("grandparent", 2)

    # specify the background knowledge
    background = Knowledge(father("homer", "bart"), father("homer", "lisa"),
                           father("homer", "maggie"), mother("marge", "bart"),
                           mother("marge", "lisa"), mother("marge", "maggie"),
                           mother("mona", "homer"), father("abe", "homer"),
                           mother("jacqueline", "marge"),
                           father("clancy", "marge"))

    # positive examples
    pos = {
        grandparent("abe", "bart"),
        grandparent("abe", "lisa"),
        grandparent("abe", "maggie"),
        grandparent("mona", "bart"),
        grandparent("abe", "lisa"),
        grandparent("abe", "maggie"),
        grandparent("jacqueline", "bart"),
        grandparent("jacqueline", "lisa"),
        grandparent("jacqueline", "maggie"),
        grandparent("clancy", "bart"),
        grandparent("clancy", "lisa"),
        grandparent("clancy", "maggie"),
    }

    # negative examples
    neg = {
        grandparent("abe", "marge"),
        grandparent("abe", "homer"),
        grandparent("abe", "clancy"),
        grandparent("abe", "jacqueline"),
        grandparent("homer", "marge"),
        grandparent("homer", "jacqueline"),
        grandparent("jacqueline", "marge"),
        grandparent("clancy", "homer"),
        grandparent("clancy", "abe")
    }

    task = Task(positive_examples=pos, negative_examples=neg)
    solver = SWIProlog()

    # EvalFn must return an upper bound on quality to prune search space.
    eval_fn = Coverage(return_upperbound=True)
    eval_fn2 = Compression(return_upperbound=True)
    eval_fn3 = Compression(return_upperbound=True)

    learner = Aleph(solver, eval_fn, max_body_literals=4, do_print=False)
    learner2 = Aleph(solver, eval_fn2, max_body_literals=4, do_print=False)
    learner3 = Aleph(solver, eval_fn3, max_body_literals=4, do_print=False)

    result = learner.learn(task, background, None)
    print(result)
Example #4
0
def find_allowed_reflexivity(knowledge: Knowledge):
    """
    Returns the set of predicates in `knowledge` that allow all of its
    arguments to be equal. That is, if `knowledge` contains a fact pred(x,x,x),
    pred will be in the return value.
    """
    facts = herbrand_model(list(knowledge.as_clauses()))
    allow_reflexivity = set()
    for atom in facts:
        args = atom.get_head().get_arguments()
        pred = atom.get_head().get_predicate()
        if len(args) > 0:
            # If all arguments are equal
            if all(args[i] == args[0] for i in range(len(args))):
                allow_reflexivity.add(pred)

    return allow_reflexivity
Example #5
0
def find_allowed_positions(knowledge: Knowledge):
    """
    Returns a dict x such that x[constant][predicate] contains
    all positions such i such that `predicate` can have `constant` as
    argument at position i in the background knowledge. 
    This is used to restrict the number of clauses generated through variable 
    instantiation.
    If an atom is not implied by the background theory (i.e. is not in 
    the Herbrand Model), there is no point in considering it, because
    it will never be true.
    """
    facts = herbrand_model(list(knowledge.as_clauses()))
    predicates = set()

    # Build dict that will restrict where constants are allowed to appear
    # e.g. allowed_positions[homer][father] = [0,1]
    allowed_positions = dict()
    for atom in facts:
        args = atom.get_head().get_arguments()
        pred = atom.get_head().get_predicate()
        predicates = predicates.union({pred})
        for i in range(len(args)):
            arg = args[i]
            if isinstance(arg, Constant):
                # New constant, initialize allowed_positions[constant]
                if not arg in allowed_positions.keys():
                    allowed_positions[arg] = dict()
                # Known constant, but not for this predicate
                if not pred in allowed_positions[arg]:
                    allowed_positions[arg][pred] = [i]
                    # Known constant, and predicate already seen for this constant
                else:
                    if i not in allowed_positions[arg][pred]:
                        allowed_positions[arg][
                            pred] = allowed_positions[arg][pred] + [i]

    # Complete dict with empty lists for constant/predicate combinations
    # that were not observed in the background data
    for const in allowed_positions.keys():
        for pred in list(predicates):
            if pred not in allowed_positions[const].keys():
                allowed_positions[const][pred] = []

    return allowed_positions
Example #6
0
def find_frequent_constants(knowledge: Knowledge, min_frequency=0):
    """
    Returns a list of all constants that occur at least `min_frequency` times in 
    `knowledge`
    """
    facts = herbrand_model(list(knowledge.as_clauses()))
    d = {}

    # Count occurrences of constants
    for atom in facts:
        args = atom.get_head().get_arguments()
        for arg in args:
            if isinstance(arg, Constant):
                if arg not in d.keys():
                    d[arg] = 0
                else:
                    d[arg] = d[arg] + 1

    return [const for const in d.keys() if d[const] >= min_frequency]
            else:
                # remove from hypothesis space if it does not
                hypothesis_space.remove(exps[ind][0])

        return new_exps


if __name__ == '__main__':
    # define the predicates
    father = c_pred("father", 2)
    mother = c_pred("mother", 2)
    grandparent = c_pred("grandparent", 2)

    # specify the background knowledge
    background = Knowledge(father("a", "b"), mother("a",
                                                    "b"), mother("b", "c"),
                           father("e", "f"), father("f", "g"),
                           mother("h", "i"), mother("i", "j"))

    # positive examples
    pos = {grandparent("a", "c"), grandparent("e", "g"), grandparent("h", "j")}

    # negative examples
    neg = {grandparent("a", "b"), grandparent("a", "g"), grandparent("i", "j")}

    task = Task(positive_examples=pos, negative_examples=neg)

    # create Prolog instance
    prolog = SWIProlog()

    learner = SimpleBreadthFirstLearner(prolog, max_body_literals=3)
Example #8
0
 background = Knowledge(
     clause1, clause2, clause3, clause4, clause5, clause6, clause7, clause8,
     clause9, clause10, clause11, clause12,
     Atom(not_empty, [Structure(s, [Pair(H, Z), O])]),
     Atom(is_empty, [Structure(s, [List([]), Z])]),
     Atom(is_space, [Structure(s, [Pair(space, Z), O])]),
     Atom(skip1, [Structure(s, [Pair(Z, Ta), B]),
                  Structure(s, [Ta, B])]),
     Atom(copy1, [
         Structure(s, [Pair(H, Ta), Pair(H, Tb)]),
         Structure(s, [Pair(H, Ta), Tb])
     ]),
     Atom(write1,
          [Structure(s, [A, Pair(H, Tb)]),
           Structure(s, [A, Tb]), H]),
     Atom(
         copyskip1,
         [Structure(s, [Pair(H, Ta), Pair(H, Tb)]),
          Structure(s, [Ta, Tb])]), is_uppercase_aux(Az),
     is_uppercase_aux(Bz), is_uppercase_aux(Cz), is_uppercase_aux(Dz),
     is_uppercase_aux(Ez), is_uppercase_aux(Fz), is_uppercase_aux(Gz),
     is_uppercase_aux(Hz), is_uppercase_aux(Iz), is_uppercase_aux(Jz),
     is_uppercase_aux(Kz), is_uppercase_aux(Lz), is_uppercase_aux(Mz),
     is_uppercase_aux(Nz), is_uppercase_aux(Oz), is_uppercase_aux(Pz),
     is_uppercase_aux(Qz), is_uppercase_aux(Rz), is_uppercase_aux(Sz),
     is_uppercase_aux(Tz), is_uppercase_aux(Uz), is_uppercase_aux(Vz),
     is_uppercase_aux(Wz), is_uppercase_aux(Xz), is_uppercase_aux(Yz),
     is_uppercase_aux(Zz), is_lowercase_aux('a'), is_lowercase_aux('b'),
     is_lowercase_aux('c'), is_lowercase_aux('d'), is_lowercase_aux('e'),
     is_lowercase_aux('f'), is_lowercase_aux('g'), is_lowercase_aux('h'),
     is_lowercase_aux('i'), is_lowercase_aux('j'), is_lowercase_aux('k'),
     is_lowercase_aux('l'), is_lowercase_aux('m'), is_lowercase_aux('n'),
     is_lowercase_aux('o'), is_lowercase_aux('p'), is_lowercase_aux('q'),
     is_lowercase_aux('r'), is_lowercase_aux('s'), is_lowercase_aux('t'),
     is_lowercase_aux('u'), is_lowercase_aux('v'), is_lowercase_aux('w'),
     is_lowercase_aux('x'), is_lowercase_aux('y'), is_lowercase_aux('z'),
     convert_case(Az, 'a'), convert_case(Bz, 'b'), convert_case(Cz, 'c'),
     convert_case(Dz, 'd'), convert_case(Ez, 'e'), convert_case(Fz, 'f'),
     convert_case(Gz, 'g'), convert_case(Hz, 'h'), convert_case(Iz, 'i'),
     convert_case(Jz, 'j'), convert_case(Kz, 'k'), convert_case(Lz, 'l'),
     convert_case(Mz, 'm'), convert_case(Nz, 'n'), convert_case(Oz, 'o'),
     convert_case(Pz, 'p'), convert_case(Qz, 'q'), convert_case(Rz, 'r'),
     convert_case(Sz, 's'), convert_case(Tz, 't'), convert_case(Uz, 'u'),
     convert_case(Vz, 'v'), convert_case(Wz, 'w'), convert_case(Xz, 'x'),
     convert_case(Yz, 'y'), convert_case(Zz, 'z'), is_number_aux(nul),
     is_number_aux(een), is_number_aux(twee), is_number_aux(drie),
     is_number_aux(vier), is_number_aux(vijf), is_number_aux(zes))
Example #9
0
def learn_text():
    """
    We describe piece of text spanning multiple lines:
    "node A red <newline> node B green <newline> node C blue <newline>"
    using the next\2, linestart\2, lineend\2, tokenlength\2 predicates
    """
    token = c_type("token")
    num = c_type("num")

    next = c_pred("next", 2, ("token", "token"))
    linestart = c_pred("linestart", 2, ("token", "token"))
    lineend = c_pred("lineend", 2, ("token", "token"))
    tokenlength = c_pred("tokenlength", 2, ("token", "num"))

    n1 = c_const("n1", num)
    n3 = c_const("n3", num)
    n4 = c_const("n4", num)
    n5 = c_const("n5", num)
    node1 = c_const("node1", token)
    node2 = c_const("node2", token)
    node3 = c_const("node3", token)
    red = c_const("red", token)
    green = c_const("green", token)
    blue = c_const("blue", token)
    a_c = c_const("a_c", token)
    b_c = c_const("b_c", token)
    c_c = c_const("c_c", token)
    start = c_const("c_START", token)
    end = c_const("c_END", token)

    bk = Knowledge(next(start, node1), next(node1, a_c), next(a_c, red),
                   next(red, node2), next(node2, green), next(green, b_c),
                   next(b_c, node3), next(node3, c_c), next(c_c, blue),
                   next(blue, end), tokenlength(node1, n4),
                   tokenlength(node2, n4), tokenlength(node3, n4),
                   tokenlength(a_c, n1), tokenlength(b_c, n1),
                   tokenlength(c_c, n1), tokenlength(red, n3),
                   tokenlength(green, n5), tokenlength(blue, n4),
                   linestart(node1, node1), linestart(a_c, node1),
                   linestart(red, node1), linestart(node2, node2),
                   linestart(b_c, node2), linestart(green, node2),
                   linestart(node3, node3), linestart(c_c, node3),
                   linestart(blue, node3), lineend(node1, a_c),
                   lineend(a_c, red), lineend(node2, red), lineend(b_c, green),
                   lineend(node3, blue), lineend(c_c, blue), lineend(red, red),
                   lineend(green, green), lineend(blue, blue))

    solver = SWIProlog()
    eval_fn1 = Coverage(return_upperbound=True)
    learner = Aleph(solver, eval_fn1, max_body_literals=3, do_print=False)

    # 1. Consider the hypothesis: f1(word) :- word is the second word on a line
    if True:
        f1 = c_pred("f1", 1, [token])
        neg = {f1(x) for x in [node1, node2, node3, blue, green, red]}
        pos = {f1(x) for x in [a_c, b_c, c_c]}
        task = Task(positive_examples=pos, negative_examples=neg)

        res = learner.learn(task, bk, None)
        print(res)

    # 2. Consider the hypothesis: f2(word) :- word is the first word on a line
    if True:
        f2 = c_pred("f2", 1, [token])
        neg = {f1(x) for x in [a_c, b_c, c_c, blue, green, red]}
        pos = {f1(x) for x in [node1, node2, node3]}
        task2 = Task(positive_examples=pos, negative_examples=neg)

        res = learner.learn(task2, bk, None)
        print(res)

    # 3. Assume we have learned the predicate node(X) before (A, B and C and nodes).
    # We want to learn f3(Node,X) :- X is the next token after Node
    if True:
        node = c_pred("node", 1, [token])
        color = c_pred("color", 1, [token])
        nodecolor = c_pred("nodecolor", 2, [token, token])
        a = c_var("A", token)
        b = c_var("B", token)
        bk_old = bk.get_all()
        bk = Knowledge(*bk_old, node(a_c), node(b_c), node(c_c), node(a_c),
                       node(b_c), node(c_c), color(red), color(green),
                       color(blue))
        pos = {
            nodecolor(a_c, red),
            nodecolor(b_c, green),
            nodecolor(c_c, blue)
        }
        neg = set()
        neg = {
            nodecolor(node1, red),
            nodecolor(node2, red),
            nodecolor(node3, red),
            nodecolor(node1, blue),
            nodecolor(node2, blue),
            nodecolor(node2, blue),
            nodecolor(node1, green),
            nodecolor(node2, green),
            nodecolor(node3, green),
            nodecolor(a_c, green),
            nodecolor(a_c, blue),
            nodecolor(b_c, blue),
            nodecolor(b_c, red),
            nodecolor(c_c, red),
            nodecolor(c_c, green)
        }
        task3 = Task(positive_examples=pos, negative_examples=neg)

        # prog = learner.learn(task3,bk,None,initial_clause=Body(node(a),color(b)))
        result = learner.learn(task3,
                               bk,
                               None,
                               initial_clause=Body(node(a), color(b)),
                               minimum_freq=3)
        print(result)