def merge_some_signals(cube, C, aig, argv): # TODO: there must be a more pythonic way of doing all of this log.LOG_MSG(str(len(C)) + " sub-games originally") cube_deps = aig.get_bdd_deps(cube) dep_map = dict() for c in C: deps = frozenset(cube_deps | aig.get_lit_deps(c)) log.DBG_MSG("Current deps: " + str(deps)) found = False for key in dep_map: if key >= deps: log.DBG_MSG("Some key subsumes deps") dep_map[key] &= aig.lit2bdd(c) found = True break elif key <= deps: log.DBG_MSG("New deps subsumes some key") if deps in dep_map: log.DBG_MSG("AND... the deps existed already") dep_map[deps] &= dep_map[key] & aig.lit2bdd(c) else: dep_map[deps] = dep_map[key] & aig.lit2bdd(c) del dep_map[key] found = True break if not found: log.DBG_MSG("Adding a new dict element") dep_map[deps] = aig.lit2bdd(c) log.LOG_MSG(str(len(dep_map.keys())) + " sub-games after incl. red.") for key in dep_map: yield ~dep_map[key] & cube
def declare_winner(controllable, conc_lose): log.LOG_MSG("Nr. of predicates: " + str(len(preds.abs_blocks))) log.LOG_ACCUM() if controllable: log.LOG_MSG("The spec is realizable.") return (~conc_lose, []) else: log.LOG_MSG("The spec is unrealizable.") return (None, [])
def declare_winner(controllable, conc_lose): log.LOG_MSG("Nr. of predicates: " + str(len(preds.abs_blocks))) log.LOG_ACCUM() if controllable: log.LOG_MSG("The spec is realizable.") if compute_win_region: # make sure we reached the fixpoint log.DBG_MSG("Get winning region") return (~fp(bdd.BDD(error_fake_latch.lit) | conc_lose, fun=lambda x: x | pre_env_bdd(x)), []) else: return (~conc_lose, []) log.LOG_MSG("The spec is unrealizable.") return (None, [])
def synthesize(): if use_trans: log.register_sum("trans_time", "Time spent building transition relation: ") log.start_clock() compose_transition_bdd() log.stop_clock("trans_time") init_state_bdd = compose_init_state_bdd() error_bdd = bdd.BDD(error_fake_latch.lit) reach_over = [] # use abstraction to minimize state space exploration if ini_reach: initial_abstraction() for j in range(ini_reach): preds.drop_latches() # add some latches make_vis = (aig.num_latches() + 1) // ini_reach_latches log.DBG_MSG("Making visible " + str(make_vis) + " latches") for i in range(make_vis): preds.loc_red() log.DBG_MSG("Computing reachable states over-app") abs_reach_region = fp(compose_abs_init_state_bdd(), fun=lambda x: x | post_bdd_abs(x)) reach_over.append(gamma(abs_reach_region)) # get the winning region for controller def min_pre(s): for r in reach_over: s = s.restrict(r) result = pre_env_bdd(s) for r in reach_over: result = result.restrict(r) return s | result log.DBG_MSG("Computing fixpoint of UPRE") win_region = ~fp(error_bdd, fun=min_pre, early_exit=lambda x: x & init_state_bdd != bdd.false()) if win_region & init_state_bdd == bdd.false(): log.LOG_MSG("The spec is unrealizable.") log.LOG_ACCUM() return (None, None) else: log.LOG_MSG("The spec is realizable.") log.LOG_ACCUM() return (win_region, reach_over)
def main(): parser = argparse.ArgumentParser(description="AIG Format Based Synth") parser.add_argument("spec", metavar="spec", type=str, help="input specification in extended AIGER format") parser.add_argument("-t", "--use_trans", action="store_true", dest="use_trans", default=False, help="Compute a transition relation") parser.add_argument("-s", "--use_symb", action="store_true", dest="use_symb", default=False, help="Use the symblicit forward approach") parser.add_argument("-d", "--decomp", dest="decomp", default=None, type=str, help="Decomposition type", choices="12") parser.add_argument("-ca", "--comp_algo", dest="comp_algo", type=str, default="1", choices="1234", help="Choice of compositional algorithm") parser.add_argument("-v", "--verbose_level", dest="verbose_level", default="", required=False, help="Verbose level = (D)ebug, (W)arnings, " + "(L)og messages, (B)DD dot dumps") parser.add_argument("-o", "--out_file", dest="out_file", type=str, required=False, default=None, help=("Output file path. If file extension = .aig, " + "binary output format will be used, if " + "file extension = .aag, ASCII output will be " + "used. The argument is ignored if the spec is " + "not realizable.")) parser.add_argument("-ot", "--only_transducer", action="store_true", dest="only_transducer", default=False, help=("Output only the synth'd transducer (i.e. " + "remove the error monitor logic).")) args = parser.parse_args() args.decomp = int(args.decomp) if args.decomp is not None else None args.comp_algo = int(args.comp_algo) # initialize the log verbose level log.parse_verbose_level(args.verbose_level) # realizability / synthesis is_realizable = synth(args) log.LOG_MSG("Realizable? " + str(bool(is_realizable))) exit([EXIT_STATUS_UNREALIZABLE, EXIT_STATUS_REALIZABLE][is_realizable])
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