def pointer_interpreter(elem_interpretation): """ :param TypeInterpretation elem_interpretation: The interpretation of the pointer element. :return: A type interpreter for pointers of such elements. :rtype: TypeInterpreter """ ptr_dom = domains.FiniteLattice.of_subsets({lits.NULL, lits.NOT_NULL}) elem_dom = elem_interpretation.domain bool_dom = boolean_ops.Boolean bin_rel_sig = _signer((ptr_dom, ptr_dom), bool_dom) deref_sig = _signer((ptr_dom, ), elem_dom) address_sig = _signer((elem_dom, ), ptr_dom) builder = finite_lattice_ops.lit(ptr_dom) null = builder(lits.NULL) notnull = builder(lits.NOT_NULL) def deref(ptr): return elem_dom.bottom if ptr == null else elem_dom.top def inv_deref(elem, e_constr): if ptr_dom.is_empty(e_constr) or elem_dom.is_empty(elem): return None if ptr_dom.le(notnull, e_constr): return notnull return None def address(elem): return notnull def inv_address(ptr, e_constr): if ptr_dom.is_empty(ptr) or elem_dom.is_empty(e_constr): return None return e_constr defs = { bin_rel_sig(ops.EQ): (finite_lattice_ops.eq(ptr_dom), finite_lattice_ops.inv_eq(ptr_dom)), bin_rel_sig(ops.NEQ): (finite_lattice_ops.neq(ptr_dom), finite_lattice_ops.inv_neq(ptr_dom)), deref_sig(ops.DEREF): (deref, inv_deref), address_sig(ops.ADDRESS): (address, inv_address) } return TypeInterpretation(ptr_dom, dict_to_provider(defs), builder)
def default_boolean_interpreter(tpe): if tpe.is_a(types.Boolean): bool_dom = boolean_ops.Boolean un_fun_sig = _signer((bool_dom, ), bool_dom) bin_fun_sig = _signer((bool_dom, bool_dom), bool_dom) defs = { un_fun_sig(ops.NOT): (boolean_ops.not_, boolean_ops.inv_not), bin_fun_sig(ops.AND): (boolean_ops.and_, boolean_ops.inv_and), bin_fun_sig(ops.OR): (boolean_ops.or_, boolean_ops.inv_or), bin_fun_sig(ops.EQ): (finite_lattice_ops.eq(bool_dom), finite_lattice_ops.inv_eq(bool_dom)), bin_fun_sig(ops.NEQ): (finite_lattice_ops.neq(bool_dom), finite_lattice_ops.inv_neq(bool_dom)) } builder = boolean_ops.lit return TypeInterpretation(bool_dom, dict_to_provider(defs), builder)
def default_enum_interpreter(tpe): if tpe.is_a(types.Enum): elems = set(tpe.lits) if len(tpe.lits) < 5: enum_dom = domains.FiniteLattice.of_subsets(elems) else: enum_dom = domains.FiniteSubsetLattice(elems) bool_dom = boolean_ops.Boolean bin_rel_sig = _signer((enum_dom, enum_dom), bool_dom) defs = { bin_rel_sig(ops.EQ): (finite_lattice_ops.eq(enum_dom), finite_lattice_ops.inv_eq(enum_dom)), bin_rel_sig(ops.NEQ): (finite_lattice_ops.neq(enum_dom), finite_lattice_ops.inv_neq(enum_dom)) } builder = finite_lattice_ops.lit(enum_dom) return TypeInterpretation(enum_dom, dict_to_provider(defs), builder)