示例#1
0
def contains_variables(literal):
    for ele in literal:
        if is_variable(ele):
            return True
        elif isinstance(ele, tuple) and contains_variables(ele):
            return True
    return False
示例#2
0
    def successors(self, node):
        h = node.state
        args, pos, pos_mapping, gensym = node.extra

        print("H", h)

        # remove literals
        for literal in h:
            removable = True
            for ele in literal[1:]:
                if not is_variable(ele):
                    removable = False
                    break
                if (ele in args or count_occurances(ele, h) > 1):
                    removable = False
                    break

            if removable:
                new_h = frozenset(x for x in h if x != literal)
                # yield Node(new_h, node, ('remove', literal), node.cost()+1,
                #            node.extra)

        # replace constants with variables.
        for literal in h:
            for new_l in get_variablizations(literal, gensym):
                new_h = frozenset([x if x != literal else new_l for x in h])
                yield Node(new_h, node, ('variablize', literal, new_l),
                           node.cost() + 1, node.extra)
示例#3
0
def remove_vars(literal):
    """
    This removes all variables by putting XXX at the front of the string, so it
    cannot be unified anymore.
    """
    return tuple('XXX' + ele if is_variable(ele) else remove_vars(ele) if
                 isinstance(ele, tuple) else ele for ele in literal)
示例#4
0
def generalize_literal(literal, gensym):
    """
    This takes a literal and returns the most general version of it possible.
    i.e., a version that has all the values replaced with new veriables.
    """
    return (literal[0],) + tuple(ele if is_variable(ele) else
                                 # '?gen%s' % hash(ele)
                                 gensym()
                                 for ele in literal[1:])
示例#5
0
def get_variablizations(literal, gensym):
    for i, ele in enumerate(literal[1:]):
        if isinstance(ele, tuple):
            for inner in get_variablizations(ele, gensym):
                yield tuple([literal[0]] + [
                    inner if j == i else iele
                    for j, iele in enumerate(literal[1:])
                ])
        elif not is_variable(ele):
            yield tuple([literal[0]] + [
                gensym() if j == i else iele
                for j, iele in enumerate(literal[1:])
            ])
示例#6
0
def count_elements(x, var_counts):
    """
    Counts the number of constants and keeps track of variable occurnaces.
    """
    if x is None:
        return 0

    c = 0
    if isinstance(x, tuple):
        c = sum([count_elements(ele, var_counts) for ele in x])
    elif is_variable(x):
        if x not in var_counts:
            var_counts[x] = 0
        var_counts[x] += 1
    else:
        c = 1
    return c
示例#7
0
def get_variablizations(literal):
    """
    Takes a literal and returns all possible variablizations of it. Currently,
    this replaces constants only. Also, it replaces them with a variable that
    is generated based on the hash of the constant, so that similar constants
    map to the same variable.
    """
    if isinstance(literal, tuple):
        head = literal[0]
        possible_bodies = [[e] + list(get_variablizations(e)) for e in
                           literal[1:]]
        for body in product(*possible_bodies):
            new = (head,) + tuple(body)
            if new != literal:
                yield new

    elif not is_variable(literal):
        yield '?gen%s' % repr(literal)
示例#8
0
    def successors(self, node):
        h = node.state
        # print("EXPANDING H", h)
        args, constraints, pset, neg, neg_mapping, gensym = node.extra

        all_args = set(s for x in h.union(constraints)
                       for s in extract_strings(x) if is_variable(s))

        if len(pset) == 0:
            return

        p, pm = choice(pset)
        p_index = build_index(p)

        operator = Operator(tuple(('Rule', ) + tuple(all_args)),
                            h.union(constraints), [])

        # operator = Operator(tuple(('Rule',) + args), h, [])

        found = False
        for m in operator.match(p_index, initial_mapping=pm):
            reverse_m = {m[a]: a for a in m}
            pos_partial = set([rename(reverse_m, x) for x in p])
            found = True
            break

        if not found:
            return

        n_index = build_index(neg)
        found = False
        for nm in operator.match(n_index, initial_mapping=neg_mapping):
            # print(nm)
            reverse_nm = {nm[a]: a for a in nm}
            neg_partial = set([rename(reverse_nm, x) for x in neg])
            found = True
            break

        if not found:
            return

        unique_pos = pos_partial - neg_partial
        unique_neg = neg_partial - pos_partial

        # print("UNIQUE POS", unique_pos)
        # print("UNIQUE NEG", unique_neg)

        # Yield all minimum specializations of current vars
        for a in m:
            # TODO make sure m[a] is a minimum specialization
            sub_m = {a: m[a]}
            new_h = frozenset([subst(sub_m, ele) for ele in h])
            # print("SPECIALIZATION", new_h, sub_m)
            # print()
            yield Node(new_h, node, ('specializing', (a, m[a])),
                       node.cost() + 1, node.extra)

        # Add Negations for all neg specializations
        # for a in nm:
        #     sub_nm = {a: nm[a]}
        #     new_nh = set()
        #     for ele in h:
        #         new = subst(sub_nm, ele)
        #         if new != ele and new not in h:
        #             new_nh.add(('not', new))
        #     new_h = h.union(new_nh)
        #     print("NEGATION SPECIALIZATION", new_nh)
        #     yield Node(new_h, node, ('negation specialization', (a, nm[a])),
        #                node.cost()+1, node.extra)

        # if current vars then add all relations that include current vars
        if len(all_args) > 0:
            added = set()
            for literal in unique_pos:
                if literal in h or literal in constraints:
                    continue
                args = set(s for s in extract_strings(literal)
                           if is_variable(s))
                if len(args.intersection(all_args)) > 0:
                    key = (literal[0], ) + tuple(
                        ele if is_variable(ele) else '?'
                        for ele in literal[1:])
                    if key in added:
                        continue
                    added.add(key)

                    literal = generalize_literal(literal, gensym)
                    new_h = h.union(frozenset([literal]))
                    # print("ADD CURRENT", new_h)
                    # print()
                    yield Node(new_h, node, ('adding current', literal),
                               node.cost() + 1, node.extra)

        else:
            added = set()
            for literal in unique_pos:
                if literal in h or literal in constraints:
                    continue
                if literal[0] in added:
                    continue
                added.add(literal[0])
                literal = generalize_literal(literal, gensym)
                new_h = h.union(frozenset([literal]))
                # print("ADD NEW", new_h)
                # print()
                yield Node(new_h, node, ('adding', literal),
                           node.cost() + 1, node.extra)
示例#9
0
def generalize_literal(literal, gensym):
    return (literal[0], ) + tuple(ele if is_variable(ele) else
                                  # '?gen%s' % hash(ele)
                                  gensym() for ele in literal[1:])
示例#10
0
def remove_vars(literal):
    return tuple('XXX' + ele if is_variable(ele) else
                 remove_vars(ele) if isinstance(ele, tuple) else ele
                 for ele in literal)