def upre_bdd(self, dst_states_bdd, env_strat=None, get_strat=False, use_trans=False): """ UPRE = EXu.AXc.EL' : T(L,Xu,Xc,L') ^ dst(L') [^St(L,Xu)] """ # take a transition step backwards # TECH NOTE: the restrict_fun=~dst... works ONLY because I will use the # result and take the union with dst_states afterwards... p_bdd = self.substitute_latches_next( dst_states_bdd, restrict_fun=~dst_states_bdd, use_trans=use_trans) # use the given strategy if env_strat is not None: p_bdd &= env_strat # there is an uncontrollable action such that for all contro... temp_bdd = p_bdd.univ_abstract( BDD.make_cube(imap(funcomp(BDD, symbol_lit), self.iterate_controllable_inputs()))) p_bdd = temp_bdd.exist_abstract( BDD.make_cube(imap(funcomp(BDD, symbol_lit), self.iterate_uncontrollable_inputs()))) # prepare the output if get_strat: return temp_bdd else: return p_bdd
def upre_bdd(self, dst_states_bdd, env_strat=None, get_strat=False, use_trans=False): """ UPRE = EXu.AXc.EL' : T(L,Xu,Xc,L') ^ dst(L') [^St(L,Xu)] """ # take a transition step backwards # TECH NOTE: the restrict_fun=~dst... works ONLY because I will use the # result and take the union with dst_states afterwards... p_bdd = self.substitute_latches_next(dst_states_bdd, restrict_fun=~dst_states_bdd, use_trans=use_trans) # use the given strategy if env_strat is not None: p_bdd &= env_strat # there is an uncontrollable action such that for all contro... temp_bdd = p_bdd.univ_abstract( BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.iterate_controllable_inputs()))) p_bdd = temp_bdd.exist_abstract( BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.iterate_uncontrollable_inputs()))) # prepare the output if get_strat: return temp_bdd else: return p_bdd
def over_post_bdd(self, src_states_bdd, sys_strat=None): """ Over-approximated version of concrete post which can be done even without the transition relation """ strat = BDD.true() if sys_strat is not None: strat &= sys_strat # to do this, we use an over-simplified transition relation, EXu,Xc b = BDD.true() for x in self.iterate_latches(): temp = BDD.make_eq(BDD(self.get_primed_var(x.lit)), self.lit2bdd(x.next)) b &= temp.and_abstract( strat, BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.iterate_controllable_inputs()))) b = b.restrict(src_states_bdd) b &= src_states_bdd b = b.exist_abstract( BDD.make_cube( imap( funcomp(BDD, symbol_lit), chain(self.iterate_latches(), self.iterate_uncontrollable_inputs())))) return self.unprime_latches_in_bdd(b)
def __init__(self, aig): self.aig = aig self.uinputs = [x.lit for x in self.aig.iterate_uncontrollable_inputs()] self.latches = [x.lit for x in self.aig.iterate_latches()] self.latch_cube = BDD.make_cube(imap(funcomp(BDD, symbol_lit), self.aig.iterate_latches())) self.platch_cube = BDD.make_cube(imap(funcomp(BDD, self.aig.get_primed_var, symbol_lit), self.aig.iterate_latches())) self.cinputs_cube = BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.aig.iterate_controllable_inputs())) self.pcinputs_cube = self.aig.prime_all_inputs_in_bdd( self.cinputs_cube) self.uinputs_cube = BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.aig.iterate_uncontrollable_inputs())) self.init_state_bdd = self.aig.init_state_bdd() self.error_bdd = self.aig.lit2bdd(self.aig.error_fake_latch.lit) self.Venv = dict() self.Venv[self.init_state_bdd] = True self.succ_cache = dict()
def strat_is_inductive(self, strat, use_trans=False): strat_dom = strat.exist_abstract( BDD.make_cube(imap(funcomp(BDD, symbol_lit), chain(self.iterate_controllable_inputs(), self.iterate_uncontrollable_inputs())))) p_bdd = self.substitute_latches_next(strat_dom, use_trans=use_trans) return BDD.make_impl(strat, p_bdd) == BDD.true()
def cpre_bdd(self, dst_states_bdd, get_strat=False, use_trans=False): """ CPRE = AXu.EXc.EL' : T(L,Xu,Xc,L') ^ dst(L') """ # take a transition step backwards p_bdd = self.substitute_latches_next(dst_states_bdd, use_trans=use_trans) # for all uncontrollable action there is a contro... # note: if argument get_strat == True then we leave the "good" # controllable actions in the bdd if not get_strat: p_bdd = p_bdd.exist_abstract( BDD.make_cube(imap(funcomp(BDD, symbol_lit), self.iterate_controllable_inputs()))) p_bdd = p_bdd.univ_abstract( BDD.make_cube(imap(funcomp(BDD, symbol_lit), self.iterate_uncontrollable_inputs()))) return p_bdd
def post_bdd(self, src_states_bdd, sys_strat=None, use_trans=False, over_approx=False): """ POST = EL.EXu.EXc : src(L) ^ T(L,Xu,Xc,L') [^St(L,Xu,Xc)] optional argument fixes possible actions for the environment """ if not use_trans or over_approx: return self.over_post_bdd(src_states_bdd, sys_strat) transition_bdd = self.trans_rel_bdd() trans = transition_bdd if sys_strat is not None: trans &= sys_strat trans = trans.restrict(src_states_bdd) suc_bdd = trans.and_abstract( src_states_bdd, BDD.make_cube( imap( funcomp(BDD, symbol_lit), chain(self.iterate_controllable_inputs(), self.iterate_uncontrollable_inputs(), self.iterate_latches())))) return self.unprime_latches_in_bdd(suc_bdd)
def strat_is_inductive(self, strat, use_trans=False): strat_dom = strat.exist_abstract( BDD.make_cube( imap( funcomp(BDD, symbol_lit), chain(self.iterate_controllable_inputs(), self.iterate_uncontrollable_inputs())))) p_bdd = self.substitute_latches_next(strat_dom, use_trans=use_trans) return BDD.make_impl(strat, p_bdd) == BDD.true()
def cpre_bdd(self, dst_states_bdd, get_strat=False, use_trans=False): """ CPRE = AXu.EXc.EL' : T(L,Xu,Xc,L') ^ dst(L') """ # take a transition step backwards p_bdd = self.substitute_latches_next(dst_states_bdd, use_trans=use_trans) # for all uncontrollable action there is a contro... # note: if argument get_strat == True then we leave the "good" # controllable actions in the bdd if not get_strat: p_bdd = p_bdd.exist_abstract( BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.iterate_controllable_inputs()))) p_bdd = p_bdd.univ_abstract( BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.iterate_uncontrollable_inputs()))) return p_bdd
def over_post_bdd(self, src_states_bdd, sys_strat=None): """ Over-approximated version of concrete post which can be done even without the transition relation """ strat = BDD.true() if sys_strat is not None: strat &= sys_strat # to do this, we use an over-simplified transition relation, EXu,Xc b = BDD.true() for x in self.iterate_latches(): temp = BDD.make_eq(BDD(self.get_primed_var(x.lit)), self.lit2bdd(x.next)) b &= temp.and_abstract( strat, BDD.make_cube(imap( funcomp(BDD, symbol_lit), self.iterate_controllable_inputs() ))) b = b.restrict(src_states_bdd) b &= src_states_bdd b = b.exist_abstract( BDD.make_cube(imap(funcomp(BDD, symbol_lit), chain(self.iterate_latches(), self.iterate_uncontrollable_inputs())))) return self.unprime_latches_in_bdd(b)
def __init__(self, aig): self.aig = aig self.uinputs = [ x.lit for x in self.aig.iterate_uncontrollable_inputs() ] self.latches = [x.lit for x in self.aig.iterate_latches()] self.latch_cube = BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.aig.iterate_latches())) self.platch_cube = BDD.make_cube( imap(funcomp(BDD, self.aig.get_primed_var, symbol_lit), self.aig.iterate_latches())) self.cinputs_cube = BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.aig.iterate_controllable_inputs())) self.pcinputs_cube = self.aig.prime_all_inputs_in_bdd( self.cinputs_cube) self.uinputs_cube = BDD.make_cube( imap(funcomp(BDD, symbol_lit), self.aig.iterate_uncontrollable_inputs())) self.init_state_bdd = self.aig.init_state_bdd() self.error_bdd = self.aig.lit2bdd(self.aig.error_fake_latch.lit) self.Venv = dict() self.Venv[self.init_state_bdd] = True self.succ_cache = dict()
def substitute_latches_next(self, b, use_trans=False, restrict_fun=None): if use_trans: transition_bdd = self.trans_rel_bdd() trans = transition_bdd if restrict_fun is not None: trans = trans.restrict(restrict_fun) primed_bdd = self.prime_latches_in_bdd(b) primed_latches = BDD.make_cube( imap(funcomp(BDD, self.get_primed_var, symbol_lit), self.iterate_latches())) return trans.and_abstract(primed_bdd, primed_latches) else: latches = [x.lit for x in self.iterate_latches()] latch_funs = [self.lit2bdd(x.next) for x in self.iterate_latches()] if restrict_fun is not None: latch_funs = [x.restrict(restrict_fun) for x in latch_funs] # take a transition step backwards return b.compose(latches, latch_funs)
def post_bdd(self, src_states_bdd, sys_strat=None, use_trans=False, over_approx=False): """ POST = EL.EXu.EXc : src(L) ^ T(L,Xu,Xc,L') [^St(L,Xu,Xc)] optional argument fixes possible actions for the environment """ if not use_trans or over_approx: return self.over_post_bdd(src_states_bdd, sys_strat) transition_bdd = self.trans_rel_bdd() trans = transition_bdd if sys_strat is not None: trans &= sys_strat trans = trans.restrict(src_states_bdd) suc_bdd = trans.and_abstract( src_states_bdd, BDD.make_cube(imap(funcomp(BDD, symbol_lit), chain( self.iterate_controllable_inputs(), self.iterate_uncontrollable_inputs(), self.iterate_latches()) ))) return self.unprime_latches_in_bdd(suc_bdd)