def __init__(self, key_domain: Type[KeyWrapper], precursory: FularaState, scalar_vars: Set[VariableIdentifier] = None, map_vars: Set[VariableIdentifier] = None, k_pre_k_conv: Callable[[KeyWrapper], KeyWrapper] = lambda x: x): """Map each program variable/dictionary segment to its liveness status. :param key_domain: domain for abstraction of dictionary keys, ranges over the scalar variables and the special key variable v_k, should support backward assignments with _substitute :param precursory: Forward analysis (Fulara analysis) result above the current statement :param scalar_vars: list of scalar variables, whose liveness should be abstracted :param map_vars: list of map variables, whose usage should be abstracted :param k_pre_k_conv: Conversion function to convert from key domain elements of the precursory analysis to key domain elements of this analysis (if the domains differ) """ super().__init__(precursory) self._s_vars = scalar_vars or set() self._m_vars = map_vars or set() self._k_domain = key_domain self._scalar_liveness = StrongLivenessState(scalar_vars) arguments = {} for dv in map_vars: typ = dv.typ if isinstance(typ, DictLyraType): k_var = VariableIdentifier(typ.key_typ, k_name) elif isinstance(typ, ListLyraType): k_var = VariableIdentifier(IntegerLyraType(), k_name) else: raise TypeError("Map variables should be of type DictLyraType or ListLyraType") if typ not in arguments: arguments[typ] = {'key_domain': key_domain, 'value_domain': LivenessLattice, 'key_d_args': {'scalar_variables': scalar_vars, 'k_var': k_var}} lattices = defaultdict(lambda: FularaLattice) self._dict_liveness = Store(map_vars, lattices, arguments) # start with 'dead' for var in map_vars: self._dict_liveness.store[var].empty() # self._length_usage self._k_pre_k_conv = k_pre_k_conv
def state(self): return StrongLivenessState(self.variables)