Ejemplo n.º 1
0
    def update_would_cause_errors(self, events):
        """Return a list of PolicyException.

        Return a list of PolicyException if we were
        to apply the events EVENTS to the current policy.
        """
        self.log(None, "update_would_cause_errors %s", utility.iterstr(events))
        errors = []
        for event in events:
            if not compile.is_datalog(event.formula):
                errors.append(
                    exception.PolicyException("Non-formula found: {}".format(
                        str(event.formula))))
            else:
                if event.formula.is_atom():
                    errors.extend(
                        compile.fact_errors(event.formula, self.theories,
                                            self.name))
                else:
                    errors.extend(
                        compile.rule_head_has_no_theory(
                            event.formula,
                            permit_head=lambda lit: lit.is_update()))
                    # Should put this back in place, but there are some
                    # exceptions that we don't handle right now.
                    # Would like to mark some tables as only being defined
                    #   for certain bound/free arguments and take that into
                    #   account when doing error checking.
                    # errors.extend(compile.rule_negation_safety(event.formula))
        return errors
Ejemplo n.º 2
0
    def update_would_cause_errors(self, events):
        """Return a list of PolicyException.

        Return a list of PolicyException if we were
        to apply the insert/deletes of policy statements dictated by
        EVENTS to the current policy.
        """
        self.log(None, "update_would_cause_errors %s", utility.iterstr(events))
        errors = []
        for event in events:
            if not compile.is_datalog(event.formula):
                errors.append(
                    exception.PolicyException("Non-formula found: {}".format(
                        str(event.formula))))
            else:
                if event.formula.is_atom():
                    errors.extend(
                        compile.fact_errors(event.formula, self.theories,
                                            self.name))
                else:
                    errors.extend(
                        compile.rule_errors(event.formula, self.theories,
                                            self.name))
        # Would also check that rules are non-recursive, but that
        #   is currently being handled by Runtime.  The current implementation
        #   disallows recursion in all theories.
        return errors
Ejemplo n.º 3
0
 def compile_atom(literal, pos=-1):
     """Compiles an atom in Z3"""
     name = literal.table.table
     svc = literal.table.service
     if svc == 'builtin':
         translators = [
             self.type_registry.get_translator(str(arg_type['type']))
             for arg_type in type_env[pos]
         ]
         fullname = 'builtin:' + name
     else:
         lit_theory = theory if svc is None else self.theories[svc]
         translators = [
             self.type_registry.get_translator(str(arg_type.type))
             for arg_type in lit_theory.schema.types(name)
         ]
         fullname = lit_theory.name + ":" + name
     try:
         z3func = (z3builtins.BUILTINS[name].z3
                   if svc == 'builtin' else self.relations[fullname])
         z3args = (compile_expr(arg, tr) for (
             arg, tr) in six.moves.zip(literal.arguments, translators))
         z3lit = z3func(*z3args)
         return (Z3OPT.Not(z3lit) if literal.negated else z3lit)
     except KeyError:
         raise exception.PolicyException(
             "Z3: Relation %s not registered" % fullname)
Ejemplo n.º 4
0
    def _update_lit_schema(self, lit, is_insert):
        if self.schema is None:
            raise exception.PolicyException(
                "Cannot update schema because theory %s doesn't have "
                "schema." % self.name)

        if self.schema.complete:
            # complete means the schema is pre-built and shouldn't be updated
            return None
        return self.schema.update(lit, is_insert)
Ejemplo n.º 5
0
 def compile_expr(expr, translator):
     """Compiles an expression to Z3"""
     if isinstance(expr, ast.Variable):
         name = expr.name
         if name in variables:
             return variables[name]
         var = Z3OPT.Const(name, translator.type())
         variables[name] = var
         z3vars.append(var)
         return var
     elif isinstance(expr, ast.ObjectConstant):
         return translator.to_z3(expr.name)
     else:
         raise exception.PolicyException(
             "Expr {} not handled by Z3".format(expr))
Ejemplo n.º 6
0
    def update_would_cause_errors(self, events):
        """Return a list of Policyxception.

        Return a list of PolicyException if we were
        to apply the events EVENTS to the current policy.
        """
        self.log(None, "update_would_cause_errors %s", utility.iterstr(events))
        errors = []
        for event in events:
            if not compile.is_atom(event.formula):
                errors.append(exception.PolicyException(
                    "Non-atomic formula is not permitted: {}".format(
                        str(event.formula))))
            else:
                errors.extend(compile.fact_errors(
                    event.formula, self.theories, self.name))
        return errors