Exemple #1
0
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
Exemple #2
0
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)
Exemple #3
0
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)
Exemple #4
0
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
Exemple #5
0
def compose_transition_bdd():
    global cached_transition

    # check cache
    if cached_transition:
        return cached_transition
    b = bdd.true()
    for x in iterate_latches_and_error():
        b &= bdd.make_eq(bdd.BDD(get_primed_variable(x.lit)),
                         get_bdd_for_aig_lit(x.next))
    cached_transition = b
    log.BDD_DMP(b, "Composed and cached the concrete transition relation")
    return b
Exemple #6
0
def compose_transition_bdd():
    global cached_transition

    # check cache
    if cached_transition:
        return cached_transition
    b = bdd.true()
    for x in iterate_latches_and_error():
        b &= bdd.make_eq(bdd.BDD(get_primed_variable(x.lit)),
                         get_bdd_for_aig_lit(x.next))
    cached_transition = b
    log.BDD_DMP(b, "Composed and cached the concrete transition relation")
    return b
Exemple #7
0
def compose_abs_eq_bdd():
    global cached_abs_eq, abs_eq_procd_blocks

    # check cache
    if cached_abs_eq is None:
        log.DBG_MSG("Rebuilding abs_eq")
        for b in preds.abs_blocks:
            abs_eq_procd_blocks[b] = False
        c = bdd.true()
    else:
        c = cached_abs_eq

    for b in preds.abs_blocks:
        if b not in procd_blocks or not procd_blocks[b]:
            c &= bdd.make_eq(bdd.BDD(b), preds.block_to_bdd[b])
    # cache c
    cached_abs_eq = c
    return c
Exemple #8
0
def compose_abs_eq_bdd():
    global cached_abs_eq, abs_eq_procd_blocks

    # check cache
    if cached_abs_eq is None:
        log.DBG_MSG("Rebuilding abs_eq")
        for b in preds.abs_blocks:
            abs_eq_procd_blocks[b] = False
        c = bdd.true()
    else:
        c = cached_abs_eq

    for b in preds.abs_blocks:
        if b not in procd_blocks or not procd_blocks[b]:
            c &= bdd.make_eq(bdd.BDD(b), preds.block_to_bdd[b])
    # cache c
    cached_abs_eq = c
    return c
Exemple #9
0
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()))
Exemple #10
0
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()))
Exemple #11
0
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)
Exemple #12
0
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)
Exemple #13
0
def main(aiger_file_name, out_file):
    aig.parse_into_spec(aiger_file_name)
    log.DBG_MSG("AIG spec file parsed")
    log.LOG_MSG("Nr. of latches: " + str(aig.num_latches()))
    log.DBG_MSG("Latches: " + str([x.lit for x in
                                   iterate_latches_and_error()]))
    log.DBG_MSG("U. Inputs: " + str([x.lit for x in
                                     aig.iterate_uncontrollable_inputs()]))
    log.DBG_MSG("C. Inputs: " + str([x.lit for x in
                                     aig.iterate_controllable_inputs()]))
    # realizability and preliminary synthesis
    if use_abs:
        (win_region, reach_over) = abs_synthesis(out_file is not None)
    else:
        (win_region, reach_over) = synthesize()

    if out_file and win_region:
        log.LOG_MSG("Win region bdd node count = " +
                    str(win_region.dag_size()))
        strategy = single_pre_sys_bdd(win_region, get_strat=True)
        log.LOG_MSG("Strategy bdd node count = " +
                    str(strategy.dag_size()))
        func_by_var = extract_output_funcs(strategy, win_region)
        # attempt to minimize the winning region
        for r in reach_over:
            for (c_bdd, func_bdd) in func_by_var.items():
                func_by_var[c_bdd] = func_bdd.safe_restrict(r)
                log.DBG_MSG("Min'd version size " +
                            str(func_by_var[c_bdd].dag_size()))
        # attempt to minimize the winning region
        if min_win:
            bdd.disable_reorder()
            strategy = bdd.true()
            for (c_bdd, func_bdd) in func_by_var.items():
                strategy &= bdd.make_eq(c_bdd, func_bdd)
            win_region = fp(compose_init_state_bdd(),
                            fun=lambda x: x | post_bdd(x, strategy))
            for (c_bdd, func_bdd) in func_by_var.items():
                func_by_var[c_bdd] = func_bdd.safe_restrict(win_region)
                log.DBG_MSG("Min'd version size " +
                            str(func_by_var[c_bdd].dag_size()))
        # model check?
        if model_check:
            strategy = bdd.true()
            for (c_bdd, func_bdd) in func_by_var.items():
                strategy &= bdd.make_eq(c_bdd, func_bdd)
            assert (fp(bdd.BDD(error_fake_latch.lit),
                       fun=lambda x: x | single_pre_bdd(x, strategy)) &
                    compose_init_state_bdd()) == bdd.false()
        # print out the strategy
        total_dag = 0
        for (c_bdd, func_bdd) in func_by_var.items():
            total_dag += func_bdd.dag_size()
            model_to_aiger(c_bdd, func_bdd)
        log.LOG_MSG("Sum of func dag sizes = " + str(total_dag))
        log.LOG_MSG("# of added gates = " + str(len(bdd_gate_cache)))
        aig.write_spec(out_file)
        return True
    elif win_region:
        return True
    else:
        return False
Exemple #14
0
def main(aiger_file_name, out_file):
    aig.parse_into_spec(aiger_file_name)
    log.DBG_MSG("AIG spec file parsed")
    log.LOG_MSG("Nr. of latches: " + str(aig.num_latches()))
    log.DBG_MSG("Latches: " + str([x.lit
                                   for x in iterate_latches_and_error()]))
    log.DBG_MSG("U. Inputs: " +
                str([x.lit for x in aig.iterate_uncontrollable_inputs()]))
    log.DBG_MSG("C. Inputs: " +
                str([x.lit for x in aig.iterate_controllable_inputs()]))
    # realizability and preliminary synthesis
    if use_abs:
        (win_region, reach_over) = abs_synthesis(out_file is not None)
    else:
        (win_region, reach_over) = synthesize()

    if out_file and win_region:
        log.LOG_MSG("Win region bdd node count = " +
                    str(win_region.dag_size()))
        strategy = single_pre_sys_bdd(win_region, get_strat=True)
        log.LOG_MSG("Strategy bdd node count = " + str(strategy.dag_size()))
        func_by_var = extract_output_funcs(strategy, win_region)
        # attempt to minimize the winning region
        for r in reach_over:
            for (c_bdd, func_bdd) in func_by_var.items():
                func_by_var[c_bdd] = func_bdd.safe_restrict(r)
                log.DBG_MSG("Min'd version size " +
                            str(func_by_var[c_bdd].dag_size()))
        # attempt to minimize the winning region
        if min_win:
            bdd.disable_reorder()
            strategy = bdd.true()
            for (c_bdd, func_bdd) in func_by_var.items():
                strategy &= bdd.make_eq(c_bdd, func_bdd)
            win_region = fp(compose_init_state_bdd(),
                            fun=lambda x: x | post_bdd(x, strategy))
            for (c_bdd, func_bdd) in func_by_var.items():
                func_by_var[c_bdd] = func_bdd.safe_restrict(win_region)
                log.DBG_MSG("Min'd version size " +
                            str(func_by_var[c_bdd].dag_size()))
        # model check?
        if model_check:
            strategy = bdd.true()
            for (c_bdd, func_bdd) in func_by_var.items():
                strategy &= bdd.make_eq(c_bdd, func_bdd)
            assert (fp(bdd.BDD(error_fake_latch.lit),
                       fun=lambda x: x | single_pre_bdd(x, strategy))
                    & compose_init_state_bdd()) == bdd.false()
        # print out the strategy
        total_dag = 0
        for (c_bdd, func_bdd) in func_by_var.items():
            total_dag += func_bdd.dag_size()
            model_to_aiger(c_bdd, func_bdd)
        log.LOG_MSG("Sum of func dag sizes = " + str(total_dag))
        log.LOG_MSG("# of added gates = " + str(len(bdd_gate_cache)))
        aig.write_spec(out_file)
        return True
    elif win_region:
        return True
    else:
        return False