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)
from lalcheck.ai import domains from lalcheck.ai.domain_ops import (boolean_ops, interval_ops, finite_lattice_ops, product_ops) from itertools import product first_elem = domains.Intervals(-2, 2) second_elem = boolean_ops.Boolean test_dom = domains.Product(first_elem, second_elem) elem_eqs = [interval_ops.eq(first_elem), finite_lattice_ops.eq(second_elem)] elem_inv_eqs = [ interval_ops.inv_eq(first_elem), finite_lattice_ops.inv_eq(second_elem) ] elem_inv_neqs = [ interval_ops.inv_neq(first_elem), finite_lattice_ops.inv_neq(second_elem) ] class InverseOperationTest(object): """ Abstract test class. Can be inherited to test the inverse of a binary operation on a sparse array domain. """ def __init__(self, doms, debug): self.domains = doms self.debug = debug
def __init__(self, debug=False): super(EqualsToInverseTest, self).__init__(test_dom, debug) self.inv = finite_lattice_ops.inv_eq(self.domain)