def type_atom(atom, pos): # type: (ast.Literal, int) -> None """Type iteration for a single atom""" table = atom.table svc = theory.name if table.service is None else table.service tablename = table.table if svc == 'builtin': if pos == -1: raise exception.PolicyRuntimeException( 'builtin not authorized in rule head') strict = False tbl_schema = builtin_types.get(pos, []) # type: List[CELLTYPE] else: strict = svc not in self.theorynames tbl_schema = self.world[svc].schema.map[tablename] for (arg, typ_col) in six.moves.zip(atom.arguments, tbl_schema): if isinstance(arg, ast.Variable): typ_var = var_types[arg.name] err = self.type_cells(typ_var, typ_col, strict) if err is not None: raise exception.PolicyRuntimeException( ("Type error while typing variable '{}' " "in {} in rule {}: {}").format( arg.name, atom, rule.id, err)) elif isinstance(arg, ast.ObjectConstant) and self.once: self.type_constant(arg.name, typ_col)
def z3_to_array(expr): # type: (z3.BoolRef) -> Union[bool, List[List[Any]]] """Compiles back a Z3 result to a matrix of values""" def extract(item): """Extract a row""" kind = item.decl().kind() if kind == z3.Z3_OP_AND: return [x.children()[1] for x in item.children()] elif kind == z3.Z3_OP_EQ: return [item.children()[1]] else: raise exception.PolicyRuntimeException( "Bad Z3 result not translatable {}: {}".format(expr, kind)) kind = expr.decl().kind() if kind == z3.Z3_OP_OR: return [extract(item) for item in expr.children()] elif kind == z3.Z3_OP_AND: return [[item.children()[1] for item in expr.children()]] elif kind == z3.Z3_OP_EQ: return [[expr.children()[1]]] elif kind == z3.Z3_OP_FALSE: return False elif kind == z3.Z3_OP_TRUE: return True else: raise exception.PolicyRuntimeException( "Bad Z3 result not translatable {}: {}".format(expr, kind))
def builtin_type_env(atom): """Generates the type of a builtin. The builtin can be polymorphic For a fixed type, we must tell if the type is nullable. Nullable types must begin with character @. """ tablename = atom.table.table builtin = z3builtins.BUILTINS.get(tablename) if builtin is None: raise exception.PolicyRuntimeException( 'Unknown builtin {}'.format(tablename)) typ_vars = [{ 'type': None, 'nullable': False } for _ in range(builtin.ty_vars)] def cell(t): return ({ 'type': arg[1:], 'nullable': True } if arg[0] == '@' else { 'type': arg, 'nullable': False }) return [ typ_vars[arg] if isinstance(arg, int) else cell(arg) for arg in builtin.args ]
def get_translator(self, name): # type: (str) -> Z3Type """Return the translator for a given type name""" trans = self.type_dict.get(name, None) if trans is None: try: congress_type = data_types.TypesRegistry.type_class(name) except KeyError: raise exception.PolicyRuntimeException( "Z3 typechecker: Unknown congress type {}".format(name)) if issubclass(congress_type, data_types.CongressTypeFiniteDomain): trans = FiniteType(name, congress_type.DOMAIN) self.register(trans) else: raise exception.PolicyRuntimeException( "Z3 typechecker: cannot handle type {}".format(name)) return trans
def extract(item): """Extract a row""" kind = item.decl().kind() if kind == z3.Z3_OP_AND: return [x.children()[1] for x in item.children()] elif kind == z3.Z3_OP_EQ: return [item.children()[1]] else: raise exception.PolicyRuntimeException( "Bad Z3 result not translatable {}: {}".format(expr, kind))
def type_atom(atom): # type: (ast.Literal) -> None """Type iteration for a single atom""" table = atom.table svc = theory.name if table.service is None else table.service tablename = table.table if svc == 'builtin': raise exception.PolicyRuntimeException( 'typing Z3 theories with builtin not supported yet') strict = svc not in self.theorynames tbl_schema = self.world[svc].schema.map[tablename] for (arg, typ_col) in six.moves.zip(atom.arguments, tbl_schema): if isinstance(arg, ast.Variable): typ_var = var_types[arg.name] err = self.type_cells(typ_var, typ_col, strict) if err is not None: raise exception.PolicyRuntimeException( ("Type error while typing variable '{}' " "in {} in rule {}: {}").format( arg.name, atom, rule.id, err)) elif isinstance(arg, ast.ObjectConstant) and self.once: self.type_constant(arg.name, typ_col)
def to_z3(self, val, strict=False): if val in self.map: return self.map[val] if val not in self.domain and val is not None: if strict: raise exception.PolicyRuntimeException( "Z3 Finite type: {} is not a value of {}".format( val, self.name)) else: val = '__OTHER__' code = len(self.map) bvect = z3.BitVecVal(code, self.type_instance) self.map[val] = bvect self.back[code] = val return bvect