Exemplo n.º 1
0
def saturate(q: structures.ConjunctiveQuery, bad_fd: FrozenSet[structures.FunctionalDependency]) \
        -> Tuple[structures.ConjunctiveQuery, List[structures.DatalogQuery]]:
    """
    Saturates a non saturated query.
    :param q:           A non saturated ConjunctiveQuery.
    :param bad_fd:      Set of internal FD that makes q non saturated
    :return:            The saturated query and a set of Datalog rules.
    """
    n_index = 0
    atoms = q.get_atoms()
    output = []
    new_q = q
    for fd in bad_fd:
        content = list(fd.left) + [fd.right]
        n_atom = structures.Atom("N_" + str(n_index), content)
        fd_set = structures.FunctionalDependencySet()
        fd_set.add(fd)
        new_q = q.add_atom(n_atom, fd_set, [True] * len(fd.left) + [False], True)
        valuation = algorithms.generate_renaming(1, list(new_q.get_all_variables()))[0]
        n_rule = structures.DatalogQuery(n_atom)
        for atom in atoms:
            n_rule.add_atom(atom)
        bad_atom = structures.Atom("BadFact_" + str(n_index), content)
        n_rule.add_atom(bad_atom, True)
        bad_rule = structures.DatalogQuery(bad_atom)
        for atom in atoms:
            bad_rule.add_atom(atom)
            bad_rule.add_atom(algorithms.apply_renaming_to_atom(atom, valuation))
        for var in fd.left:
            bad_rule.add_atom(structures.EqualityAtom(var, valuation[var]))
        bad_rule.add_atom(structures.EqualityAtom(fd.right, valuation[fd.right], True))
        output += [n_rule, bad_rule]
    return new_q, output
Exemplo n.º 2
0
def atom_attacks_variables(atom: Atom, var: AtomValue,
                           q: ConjunctiveQuery) -> bool:
    """
    Returns True if the given atom attacks the given Variable
    :param atom:        An Atom
    :param var:         A Variable
    :param q:           A ConjunctiveQuery
    :return:            True if atom attacks var, else returns False
    """
    n = Atom("N", [var])
    q_new = q.add_atom(n, FunctionalDependencySet(), [True], False)
    g = gen_attack_graph(q_new)
    return g.has_edge(atom, n)
Exemplo n.º 3
0
def parse_query(string):
    pattern = re.compile("\[[A-Za-z_,0-9]*\]:[A-Za-z_,\(\)\[\]\*0-9]*$")
    if pattern.match(string):
        try:
            free_var_body, query_body = string.split(":")
            free_var_body = free_var_body[1:-1]
            free_vars = parse_atoms_values(free_var_body)
            q = ConjunctiveQuery()
            for atom, fd_set, is_key, is_consistent in parse_atoms(query_body):
                q = q.add_atom(atom, fd_set, is_key, is_consistent)
            for value in free_vars:
                if value.var:
                    q = q.release_variable(value)
            return q
        except MalformedQuery:
            raise

    else:
        raise MalformedQuery(string, "ConjunctiveQuery")
Exemplo n.º 4
0
def reduce_cycle(cycle: List[structures.Atom], q: structures.ConjunctiveQuery,
                 rewriting_index: int) -> Tuple[structures.ConjunctiveQuery, List[structures.DatalogQuery]]:
    """
    Reduces a cycle in the M-graph corresponding to an initial strong component in the attack graph of q.
    :param cycle:				Cycle to be reduced
    :param q: 					A ConjunctiveQuery
    :param rewriting_index: 	Index used to enumerate the Datalog rules
    :return: 					A list of Datalog rules and a ConjunctiveQuery that corresponds to
                                q\{atom} U {T} U {Nc} (Just as described in the report)
    """
    rules = []
    k = len(cycle)
    renamings = algorithms.generate_renaming(2 * k + 2, list(q.get_all_variables()))
    rules += [templates.EqQuery(atom, q) for atom in cycle]
    rules += [templates.NeqQuery(atom, q, renamings[0]) for atom in cycle]
    rules += garbage_set_rules(cycle, q, rewriting_index, renamings)
    rules += new_atoms_rules(cycle, q, rewriting_index, renamings)
    t, n_atoms = new_atoms(cycle, q, rewriting_index, renamings[0])
    new_q = q.add_atom(*t)
    for n_atom in n_atoms:
        new_q = new_q.add_atom(*n_atom)
    for atom in cycle:
        new_q = new_q.remove_atom(atom)
    return new_q, rules
Exemplo n.º 5
0
atom_s = Atom("S", [y, z])

# Initialize functional dependencies
#       First parameter :   Left side of the FD (List of variables)
#       Second parameter :  Right side of the FD (must be a single variable)
fd1 = FunctionalDependencySet()
fd1.add(FunctionalDependency([x], y))
fd2 = FunctionalDependencySet()
fd2.add(FunctionalDependency([y], z))

# Initialize the conjunctive query
q = ConjunctiveQuery()

# Add atoms to q
#       First parameter :   The atom to be added
#       Second parameter :  The set of FD (must be a frozenset as in the example)
#       Third parameter :   A List of booleans describing the "key positions" of the atom
#       Fourth Parameter :  A boolean that must be True if the atom is consistent, False if not
q = q.add_atom(atom_r, fd1, [True, True, False], False)
q = q.add_atom(atom_s, fd2, [True, False], False)

# Choose free variables (creates a new instance)
q = q.release_variable(x)
q = q.release_variable(y)

# Launch rewriting
program = rewrite(q)

# You can print the Datalog program
print(program)