def pre_env_bdd(dst_states_bdd, env_strat=None, get_strat=False): """ UPRE = EXu.AXc.EL' : T(L,Xu,Xc,L') ^ dst(L') [^St(L,Xu)] optional arguments fix possible actions for the environment and possible actions for the controller """ # can we use the transition relation? if not use_trans: return single_pre_env_bdd(dst_states_bdd, env_strat, get_strat) # do as promised transition_bdd = compose_transition_bdd() trans = transition_bdd if env_strat is not None: trans &= env_strat if restrict_like_crazy: trans = trans.restrict(~dst_states_bdd) primed_states = prime_latches_in_bdd(dst_states_bdd) primed_latches = prime_latches_in_bdd(bdd.get_cube( get_all_latches_as_bdds())) p_bdd = trans.and_abstract(primed_states, primed_latches) temp_bdd = p_bdd.univ_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = temp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) if get_strat: return temp_bdd else: return p_bdd
def pre_env_bdd_abs(dst_states_bdd, get_strat=False): """ UPRE_abs = EXu.AXc.EP' : T_abs(P,Xu,Xc,P') ^ dst(P') """ # if there is no transition bdd then return the version that can be # computed without one if not use_trans: return single_pre_env_bdd_abs(dst_states_bdd, get_strat) # if we are using the de Alfaro version of the operators, i.e. # the most precise ones if most_precise: return alpha_over( pre_env_bdd(gamma(dst_states_bdd), get_strat=get_strat)) # else, compute as the initial comment reads transition_bdd = compose_abs_transition_bdd() primed_states = prime_blocks_in_bdd(dst_states_bdd) primed_blocks = bdd.get_cube( [bdd.BDD(get_primed_variable(x)) for x in preds.abs_blocks]) tmp_bdd = transition_bdd.and_abstract(primed_states, primed_blocks) tmp_bdd = tmp_bdd.univ_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = tmp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) # return the "good actions" if they are needed if get_strat: return tmp_bdd else: return p_bdd
def single_pre_env_bdd_uabs(dst_states_bdd, env_strat=None): # if we want the most precise version of the operator if most_precise: if env_strat is not None: strat = gamma(env_strat) else: strat = None return alpha_under( single_pre_env_bdd(gamma(dst_states_bdd), env_strat=strat)) # make sure the block_funs are current update_block_funs() # take one step backwards and over-app tmp_bdd = ~dst_states_bdd tmp_bdd = tmp_bdd.compose(block_funs.keys(), block_funs.values()) tmp_bdd = alpha_over(tmp_bdd) if env_strat is not None: tmp_bdd &= env_strat # we are using the complement of the original formula so # we want that for all uncontrollable, there is a contro... tmp_bdd = tmp_bdd.exist_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = tmp_bdd.univ_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) return ~p_bdd
def pre_env_bdd(dst_states_bdd, env_strat=None, get_strat=False): """ UPRE = EXu.AXc.EL' : T(L,Xu,Xc,L') ^ dst(L') [^St(L,Xu)] optional arguments fix possible actions for the environment and possible actions for the controller """ # can we use the transition relation? if not use_trans: return single_pre_env_bdd(dst_states_bdd, env_strat, get_strat) # do as promised transition_bdd = compose_transition_bdd() trans = transition_bdd if env_strat is not None: trans &= env_strat if restrict_like_crazy: trans = trans.restrict(~dst_states_bdd) primed_states = prime_latches_in_bdd(dst_states_bdd) primed_latches = prime_latches_in_bdd( bdd.get_cube(get_all_latches_as_bdds())) p_bdd = trans.and_abstract(primed_states, primed_latches) temp_bdd = p_bdd.univ_abstract(bdd.get_cube( get_controllable_inputs_bdds())) p_bdd = temp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) if get_strat: return temp_bdd else: return p_bdd
def single_pre_env_bdd(dst_states_bdd, env_strat=None, get_strat=False): if env_strat is not None: strat = env_strat else: strat = bdd.true() latches = [x.lit for x in iterate_latches_and_error()] latch_funs = [ get_bdd_for_aig_lit(x.next) for x in iterate_latches_and_error() ] if restrict_like_crazy: latch_funs = [x.restrict(~dst_states_bdd) for x in latch_funs] # take a transition step backwards p_bdd = dst_states_bdd.compose(latches, latch_funs) # use the given strategy p_bdd &= strat # there is an uncontrollable action such that for all contro... temp_bdd = p_bdd.univ_abstract(bdd.get_cube( get_controllable_inputs_bdds())) p_bdd = temp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) if get_strat: return temp_bdd else: return p_bdd
def single_pre_env_bdd_uabs(dst_states_bdd, env_strat=None): # if we want the most precise version of the operator if most_precise: if env_strat is not None: strat = gamma(env_strat) else: strat = None return alpha_under(single_pre_env_bdd(gamma(dst_states_bdd), env_strat=strat)) # make sure the block_funs are current update_block_funs() # take one step backwards and over-app tmp_bdd = ~dst_states_bdd tmp_bdd = tmp_bdd.compose(block_funs.keys(), block_funs.values()) tmp_bdd = alpha_over(tmp_bdd) if env_strat is not None: tmp_bdd &= env_strat # we are using the complement of the original formula so # we want that for all uncontrollable, there is a contro... tmp_bdd = tmp_bdd.exist_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = tmp_bdd.univ_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) return ~p_bdd
def pre_env_bdd_abs(dst_states_bdd, get_strat=False): """ UPRE_abs = EXu.AXc.EP' : T_abs(P,Xu,Xc,P') ^ dst(P') """ # if there is no transition bdd then return the version that can be # computed without one if not use_trans: return single_pre_env_bdd_abs(dst_states_bdd, get_strat) # if we are using the de Alfaro version of the operators, i.e. # the most precise ones if most_precise: return alpha_over(pre_env_bdd(gamma(dst_states_bdd), get_strat=get_strat)) # else, compute as the initial comment reads transition_bdd = compose_abs_transition_bdd() primed_states = prime_blocks_in_bdd(dst_states_bdd) primed_blocks = bdd.get_cube([bdd.BDD(get_primed_variable(x)) for x in preds.abs_blocks]) tmp_bdd = transition_bdd.and_abstract(primed_states, primed_blocks) tmp_bdd = tmp_bdd.univ_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = tmp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) # return the "good actions" if they are needed if get_strat: return tmp_bdd else: return p_bdd
def pre_env_bdd_uabs(dst_states_bdd, env_strat=None): """ UPRE_uabs = EXu.AXc.AP' : T_abs(P,Xu,Xc,P') [^St(L,Xu)] => dst(P') """ # if there is no transition relation, use the single version if not use_trans: return single_pre_env_bdd_uabs(dst_states_bdd, env_strat) # if we want the most precise version of the operator if most_precise: if env_strat is not None: strat = gamma(env_strat) else: strat = None return alpha_under(pre_env_bdd(gamma(dst_states_bdd), env_strat=strat)) # else, do as we promised in the first comment transition_bdd = compose_abs_transition_bdd() trans = transition_bdd if env_strat is not None: trans &= env_strat primed_states = prime_blocks_in_bdd(dst_states_bdd) primed_blocks = bdd.get_cube([bdd.BDD(get_primed_variable(x)) for x in preds.abs_blocks]) tmp_bdd = bdd.make_impl(transition_bdd, primed_states) tmp_bdd = tmp_bdd.univ_abstract(primed_blocks) tmp_bdd = tmp_bdd.univ_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = tmp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) return p_bdd
def pre_env_bdd_uabs(dst_states_bdd, env_strat=None): """ UPRE_uabs = EXu.AXc.AP' : T_abs(P,Xu,Xc,P') [^St(L,Xu)] => dst(P') """ # if there is no transition relation, use the single version if not use_trans: return single_pre_env_bdd_uabs(dst_states_bdd, env_strat) # if we want the most precise version of the operator if most_precise: if env_strat is not None: strat = gamma(env_strat) else: strat = None return alpha_under(pre_env_bdd(gamma(dst_states_bdd), env_strat=strat)) # else, do as we promised in the first comment transition_bdd = compose_abs_transition_bdd() trans = transition_bdd if env_strat is not None: trans &= env_strat primed_states = prime_blocks_in_bdd(dst_states_bdd) primed_blocks = bdd.get_cube( [bdd.BDD(get_primed_variable(x)) for x in preds.abs_blocks]) tmp_bdd = bdd.make_impl(transition_bdd, primed_states) tmp_bdd = tmp_bdd.univ_abstract(primed_blocks) tmp_bdd = tmp_bdd.univ_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = tmp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) return p_bdd
def single_pre_sys_bdd(dst_states_bdd, get_strat=False): latches = [x.lit for x in iterate_latches_and_error()] latch_funs = [get_bdd_for_aig_lit(x.next) for x in iterate_latches_and_error()] # take a transition step backwards p_bdd = dst_states_bdd.compose(latches, latch_funs) # for all uncontrollable action there is a contro... # note: if argument as_strat == True then we leave the "good" # controllable actions in the bdd if not get_strat: p_bdd = p_bdd.exist_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = p_bdd.univ_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) return p_bdd
def pre_sys_bdd(dst_states_bdd): """ CPRE = AXu.EXc.EL' : T(L,Xu,Xc,L') ^ dst(L') """ # can se use the transition relation? if not use_trans: return single_pre_sys_bdd(dst_states_bdd) # get the transition relation and do as usual transition_bdd = compose_transition_bdd() primed_states = prime_latches_in_bdd(dst_states_bdd) abstract_bdd = prime_latches_in_bdd( bdd.get_cube(get_all_latches_as_bdds() + get_controllable_inputs_bdds())) p_bdd = transition_bdd.and_abstract(primed_states, abstract_bdd) p_bdd = p_bdd.univ_abstract(bdd.get_cube(get_uncontrollable_inputs_bdds())) return p_bdd
def single_pre_sys_bdd(dst_states_bdd, get_strat=False): latches = [x.lit for x in iterate_latches_and_error()] latch_funs = [ get_bdd_for_aig_lit(x.next) for x in iterate_latches_and_error() ] # take a transition step backwards p_bdd = dst_states_bdd.compose(latches, latch_funs) # for all uncontrollable action there is a contro... # note: if argument as_strat == True then we leave the "good" # controllable actions in the bdd if not get_strat: p_bdd = p_bdd.exist_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = p_bdd.univ_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) return p_bdd
def compose_abs_transition_bdd(): global cached_abs_transition, procd_blocks # check cache if cached_abs_transition is None: log.DBG_MSG("Rebuilding abstract transition relation") for b in preds.abs_blocks: procd_blocks[b] = False c = bdd.true() else: c = cached_abs_transition latches = [x.lit for x in iterate_latches_and_error()] latches_bdd = bdd.get_cube(get_all_latches_as_bdds()) latch_funs = [get_bdd_for_aig_lit(x.next) for x in iterate_latches_and_error()] for b in preds.abs_blocks: if b not in procd_blocks or not procd_blocks[b]: procd_blocks[b] = True temp = bdd.make_eq(bdd.BDD(get_primed_variable(b)), preds.block_to_bdd[b]) c &= temp.compose(latches, latch_funs) # cache c cached_abs_transition = c return c.and_abstract(compose_abs_eq_bdd(), latches_bdd)
def extract_output_funcs(strategy, care_set=None): """ Calculate BDDs for output functions given non-deterministic winning strategy. """ if care_set is None: care_set = bdd.true() output_models = dict() all_outputs = get_controllable_inputs_bdds() for c in get_controllable_inputs_bdds(): others = set(set(all_outputs) - set([c])) if others: others_cube = bdd.get_cube(others) c_arena = strategy.exist_abstract(others_cube) else: c_arena = strategy # pairs (x,u) in which c can be true can_be_true = c_arena.cofactor(c) # pairs (x,u) in which c can be false can_be_false = c_arena.cofactor(~c) must_be_true = (~can_be_false) & can_be_true must_be_false = (~can_be_true) & can_be_false local_care_set = care_set & (must_be_true | must_be_false) # Restrict operation: # on care_set: must_be_true.restrict(care_set) <-> must_be_true c_model = min([must_be_true.safe_restrict(local_care_set), (~must_be_false).safe_restrict(local_care_set)], key=bdd.dag_size) output_models[c] = c_model log.DBG_MSG("Size of function for " + str(c.get_index()) + " = " + str(c_model.dag_size())) strategy &= bdd.make_eq(c, c_model) return output_models
def compose_abs_transition_bdd(): global cached_abs_transition, procd_blocks # check cache if cached_abs_transition is None: log.DBG_MSG("Rebuilding abstract transition relation") for b in preds.abs_blocks: procd_blocks[b] = False c = bdd.true() else: c = cached_abs_transition latches = [x.lit for x in iterate_latches_and_error()] latches_bdd = bdd.get_cube(get_all_latches_as_bdds()) latch_funs = [ get_bdd_for_aig_lit(x.next) for x in iterate_latches_and_error() ] for b in preds.abs_blocks: if b not in procd_blocks or not procd_blocks[b]: procd_blocks[b] = True temp = bdd.make_eq(bdd.BDD(get_primed_variable(b)), preds.block_to_bdd[b]) c &= temp.compose(latches, latch_funs) # cache c cached_abs_transition = c return c.and_abstract(compose_abs_eq_bdd(), latches_bdd)
def extract_output_funcs(strategy, care_set=None): """ Calculate BDDs for output functions given non-deterministic winning strategy. """ if care_set is None: care_set = bdd.true() output_models = dict() all_outputs = get_controllable_inputs_bdds() for c in get_controllable_inputs_bdds(): others = set(set(all_outputs) - set([c])) if others: others_cube = bdd.get_cube(others) c_arena = strategy.exist_abstract(others_cube) else: c_arena = strategy # pairs (x,u) in which c can be true can_be_true = c_arena.cofactor(c) # pairs (x,u) in which c can be false can_be_false = c_arena.cofactor(~c) must_be_true = (~can_be_false) & can_be_true must_be_false = (~can_be_true) & can_be_false local_care_set = care_set & (must_be_true | must_be_false) # Restrict operation: # on care_set: must_be_true.restrict(care_set) <-> must_be_true c_model = min([ must_be_true.safe_restrict(local_care_set), (~must_be_false).safe_restrict(local_care_set) ], key=bdd.dag_size) output_models[c] = c_model log.DBG_MSG("Size of function for " + str(c.get_index()) + " = " + str(c_model.dag_size())) strategy &= bdd.make_eq(c, c_model) return output_models
def pre_sys_bdd(dst_states_bdd): """ CPRE = AXu.EXc.EL' : T(L,Xu,Xc,L') ^ dst(L') """ # can se use the transition relation? if not use_trans: return single_pre_sys_bdd(dst_states_bdd) # get the transition relation and do as usual transition_bdd = compose_transition_bdd() primed_states = prime_latches_in_bdd(dst_states_bdd) abstract_bdd = prime_latches_in_bdd(bdd.get_cube( get_all_latches_as_bdds() + get_controllable_inputs_bdds())) p_bdd = transition_bdd.and_abstract(primed_states, abstract_bdd) p_bdd = p_bdd.univ_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) return p_bdd
def over_post_bdd_abs(src_states_bdd, env_strat=None): # make sure the block_funs are current update_block_funs() # take the step forward and get rid of latches conc_src = gamma(src_states_bdd) if env_strat is not None: conc_strat = gamma(env_strat) else: conc_strat = bdd.true() # to do this, we use an over-simplified transition relation, EXu,Xc simple_trans = bdd.true() for b in preds.abs_blocks: trans_b = bdd.make_eq(bdd.BDD(b), block_funs[b]) simple_trans &= trans_b.exist_abstract( bdd.get_cube(get_controllable_inputs_bdds())) simple_trans &= conc_strat & conc_src return simple_trans.exist_abstract( bdd.get_cube(get_all_latches_as_bdds() + get_uncontrollable_inputs_bdds()))
def single_post_bdd(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 iterate_latches_and_error(): temp = bdd.make_eq(bdd.BDD(get_primed_variable(x.lit)), get_bdd_for_aig_lit(x.next)) b &= temp.and_abstract(strat, bdd.get_cube(get_controllable_inputs_bdds())) if restrict_like_crazy: b = b.restrict(src_states_bdd) b &= src_states_bdd b = b.exist_abstract( bdd.get_cube(get_all_latches_as_bdds() + get_uncontrollable_inputs_bdds())) return unprime_latches_in_bdd(b)
def single_pre_env_bdd_abs(dst_states_bdd, get_strat=False): # if we want the most precise version of the operator if most_precise: return alpha_over( single_pre_env_bdd(gamma(dst_states_bdd), get_strat=get_strat)) # make sure the block_funs are current update_block_funs() # take one step backwards and over-app tmp_bdd = dst_states_bdd.compose(block_funs.keys(), block_funs.values()) tmp_bdd = alpha_over(tmp_bdd) # there is an uncontrollable action, such that for all contro... tmp_bdd = tmp_bdd.univ_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = tmp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) # was a strategy asked for? if get_strat: return tmp_bdd else: return p_bdd
def single_pre_env_bdd_abs(dst_states_bdd, get_strat=False): # if we want the most precise version of the operator if most_precise: return alpha_over(single_pre_env_bdd(gamma(dst_states_bdd), get_strat=get_strat)) # make sure the block_funs are current update_block_funs() # take one step backwards and over-app tmp_bdd = dst_states_bdd.compose(block_funs.keys(), block_funs.values()) tmp_bdd = alpha_over(tmp_bdd) # there is an uncontrollable action, such that for all contro... tmp_bdd = tmp_bdd.univ_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = tmp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) # was a strategy asked for? if get_strat: return tmp_bdd else: return p_bdd
def single_pre_env_bdd(dst_states_bdd, env_strat=None, get_strat=False): if env_strat is not None: strat = env_strat else: strat = bdd.true() latches = [x.lit for x in iterate_latches_and_error()] latch_funs = [get_bdd_for_aig_lit(x.next) for x in iterate_latches_and_error()] if restrict_like_crazy: latch_funs = [x.restrict(~dst_states_bdd) for x in latch_funs] # take a transition step backwards p_bdd = dst_states_bdd.compose(latches, latch_funs) # use the given strategy p_bdd &= strat # there is an uncontrollable action such that for all contro... temp_bdd = p_bdd.univ_abstract( bdd.get_cube(get_controllable_inputs_bdds())) p_bdd = temp_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds())) if get_strat: return temp_bdd else: return p_bdd
def single_pre_bdd(dst_states_bdd, strat=None): if strat is None: strat = bdd.true() latches = [x.lit for x in iterate_latches_and_error()] latch_funs = [get_bdd_for_aig_lit(x.next) for x in iterate_latches_and_error()] if restrict_like_crazy: latch_funs = [x.restrict(~dst_states_bdd) for x in latch_funs] # take a transition step backwards p_bdd = dst_states_bdd.compose(latches, latch_funs) # use the given strategy p_bdd &= strat p_bdd = p_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds() + get_controllable_inputs_bdds())) return p_bdd
def single_pre_bdd(dst_states_bdd, strat=None): if strat is None: strat = bdd.true() latches = [x.lit for x in iterate_latches_and_error()] latch_funs = [ get_bdd_for_aig_lit(x.next) for x in iterate_latches_and_error() ] if restrict_like_crazy: latch_funs = [x.restrict(~dst_states_bdd) for x in latch_funs] # take a transition step backwards p_bdd = dst_states_bdd.compose(latches, latch_funs) # use the given strategy p_bdd &= strat p_bdd = p_bdd.exist_abstract( bdd.get_cube(get_uncontrollable_inputs_bdds() + get_controllable_inputs_bdds())) return p_bdd
def post_bdd(src_states_bdd, sys_strat=None): """ 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: return single_post_bdd(src_states_bdd, sys_strat) transition_bdd = compose_transition_bdd() trans = transition_bdd if sys_strat is not None: trans &= sys_strat if restrict_like_crazy: trans = trans.restrict(src_states_bdd) suc_bdd = trans.and_abstract( src_states_bdd, bdd.get_cube(get_controllable_inputs_bdds() + get_uncontrollable_inputs_bdds() + get_all_latches_as_bdds())) return unprime_latches_in_bdd(suc_bdd)
def post_bdd_abs(src_states_bdd, env_strat=None): """ POST_abs = EP.EXu.EXc : src(P) ^ T(P,Xu,Xc,P') [^St(P,Xu)] optional argument fixes possible actions for the environment """ # if there is no transition_bdd we do what we can if not use_trans: return over_post_bdd_abs(src_states_bdd, env_strat) # otherwise, we compute as the first comment reads transition_bdd = compose_abs_transition_bdd() trans = transition_bdd if env_strat is not None: trans &= env_strat preds_as_bdds = [bdd.BDD(x) for x in preds.abs_blocks] suc_bdd = trans.and_abstract( src_states_bdd, bdd.get_cube(get_controllable_inputs_bdds() + get_uncontrollable_inputs_bdds() + preds_as_bdds)) return unprime_blocks_in_bdd(suc_bdd)
def post_bdd(src_states_bdd, sys_strat=None): """ 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: return single_post_bdd(src_states_bdd, sys_strat) transition_bdd = compose_transition_bdd() trans = transition_bdd if sys_strat is not None: trans &= sys_strat if restrict_like_crazy: trans = trans.restrict(src_states_bdd) suc_bdd = trans.and_abstract( src_states_bdd, bdd.get_cube( get_controllable_inputs_bdds() + get_uncontrollable_inputs_bdds() + get_all_latches_as_bdds())) return unprime_latches_in_bdd(suc_bdd)
def post_bdd_abs(src_states_bdd, env_strat=None): """ POST_abs = EP.EXu.EXc : src(P) ^ T(P,Xu,Xc,P') [^St(P,Xu)] optional argument fixes possible actions for the environment """ # if there is no transition_bdd we do what we can if not use_trans: return over_post_bdd_abs(src_states_bdd, env_strat) # otherwise, we compute as the first comment reads transition_bdd = compose_abs_transition_bdd() trans = transition_bdd if env_strat is not None: trans &= env_strat preds_as_bdds = [bdd.BDD(x) for x in preds.abs_blocks] suc_bdd = trans.and_abstract( src_states_bdd, bdd.get_cube( get_controllable_inputs_bdds() + get_uncontrollable_inputs_bdds() + preds_as_bdds)) return unprime_blocks_in_bdd(suc_bdd)
def alpha_over(conc_bdd): c = compose_abs_eq_bdd() latches_bdd = bdd.get_cube(get_all_latches_as_bdds()) c = c.and_abstract(conc_bdd, latches_bdd) return c