def check_unreal( ltl_text, part_text, is_moore, ltl3ba: LTL3BA, solver_factory: Z3SolverFactory, min_size, max_size, ltl3ba_timeout_sec=None, opt_level=0, ) -> LTS: """ :raise: subprocess.TimeoutException :arg opt_level: Note that opt_level > 0 may introduce unsoundness (returns unrealizable while it is) """ timer = Timer() outputs, inputs, expr = parse_acacia_and_build_expr(ltl_text, part_text, ltl3ba, opt_level) timer.sec_restart() automaton = ltl3ba.convert(expr, timeout=ltl3ba_timeout_sec) # note no negation logging.info("(unreal) automaton size is: %i" % len(automaton.nodes)) logging.debug("(unreal) automaton (dot) is:\n" + automaton2dot.to_dot(automaton)) logging.debug("(unreal) automaton translation took (sec): %i" % timer.sec_restart()) encoder = create_encoder(inputs, outputs, not is_moore, automaton, solver_factory.create()) model = model_searcher.search(min_size, max_size, encoder) logging.debug("(unreal) model_searcher.search took (sec): %i" % timer.sec_restart()) return model
def main(tlsf_file_name, output_file_name, dot_file_name, smt_files_prefix, keep_temp_files) -> int: """ :return: REALIZABLE, UNREALIZABLE, UNKNOWN (see elli) """ timer = Timer() logic = UFLRA() ltl3ba, solver_factory = create_spec_converter_z3(logic, True, False, smt_files_prefix, not keep_temp_files) ltl_text, part_text = convert_tlsf_to_acacia(tlsf_file_name) is_moore = get_spec_type(tlsf_file_name) try: timer.sec_restart() env_model = elli.check_unreal( ltl_text, part_text, is_moore, ltl3ba, solver_factory, 1, 1, ltl3ba_timeout_sec=200 ) logging.info("unreal check took (sec): %i" % timer.sec_restart()) logging.info("env model is {NOT} FOUND".format(NOT="" if env_model else "NOT")) if env_model: print("UNREALIZABLE") logging.debug(lts_to_dot(env_model, ARG_MODEL_STATE, is_moore)) return UNREALIZABLE except subprocess.TimeoutExpired: logging.info("I aborted unreal check (>200sec). Proceed to real check.") model = elli.check_real(ltl_text, part_text, is_moore, ltl3ba, solver_factory, 1, 40) logging.info("real check took (sec): %i" % timer.sec_restart()) logging.info("sys model is {NOT} FOUND".format(NOT="" if model else "NOT")) if not model: logging.info("trying check_real without formula strengthening") model = elli.check_real(ltl_text, part_text, is_moore, ltl3ba, solver_factory, 1, 40, opt_level=0) logging.info("(without formula strengthening): real check took (sec): %i" % timer.sec_restart()) logging.info("(without formula strengthening): sys model is {NOT} FOUND".format(NOT="" if model else "NOT")) if not model: return UNKNOWN dot_model_str = lts_to_dot(model, ARG_MODEL_STATE, not is_moore) if dot_file_name: with open(dot_file_name, "w") as out: out.write(dot_model_str) logging.info( "{model_type} model is written to {file}".format(model_type=["Mealy", "Moore"][is_moore], file=out.name) ) else: logging.info(dot_model_str) aiger_model_str = lts_to_aiger(model) logging.info("circuit size: %i" % len(model.states)) if output_file_name: with open(output_file_name, "w") as out: out.write(aiger_model_str) else: print("REALIZABLE") print(aiger_model_str) solver_factory.down_solvers() return REALIZABLE
def check_real(ltl_text, part_text, is_moore, ltl_to_atm: LTLToAutomaton, solver: SolverInterface, max_k: int, min_size, max_size, opt_level=0) -> LTS: """ When opt_level>0, introduce incompleteness (but it is sound: if returns REAL, then REAL) When max_k>0, reduce UCW to k-UCW. """ timer = Timer() spec = parse_acacia_and_build_expr(ltl_text, part_text, ltl_to_atm, opt_level) logging.info("LTL formula size: %i", expr_size(spec.formula)) timer.sec_restart() automaton = ltl_to_atm.convert(~spec.formula) logging.info('automaton size is: %i' % len(automaton.nodes)) logging.debug('automaton (dot) is:\n' + automaton_to_dot.to_dot(automaton)) logging.debug('automaton translation took (sec): %i' % timer.sec_restart()) tau_desc = build_tau_desc(spec.inputs) desc_by_output = dict( (o, build_output_desc(o, is_moore, spec.inputs)) for o in spec.outputs) if max_k == 0: logging.info("using CoBuchiEncoder") encoder = CoBuchiEncoder(automaton, tau_desc, spec.inputs, desc_by_output, range(max_size)) model = model_searcher.search(min_size, max_size, encoder, solver) else: coreach_automaton = k_reduce(automaton, max_k) # with open('/tmp/orig.dot', 'w') as f: # f.write(automaton_to_dot.to_dot(automaton)) # with open('/tmp/red.dot', 'w') as f: # f.write(automaton_to_dot.to_dot(coreach_automaton)) # exit() logging.info("using CoReachEncoder") logging.info('co-reachability automaton size is: %i' % len(coreach_automaton.nodes)) logging.debug('co-reachability automaton (dot) is:\n' + automaton_to_dot.to_dot(coreach_automaton)) encoder = CoreachEncoder(coreach_automaton, tau_desc, spec.inputs, desc_by_output, range(max_size), max_k) model = model_k_searcher.search(min_size, max_size, max_k, encoder, solver) logging.info('searching a model took (sec): %i' % timer.sec_restart()) return model
def check_unreal(ltl_text, part_text, is_moore, ltl_to_atm: LTLToAutomaton, solver: SolverInterface, max_k: int, min_size, max_size, opt_level=0) -> LTS: """ Note that opt_level > 0 may introduce unsoundness (returns unrealizable while it is). """ timer = Timer() spec = parse_acacia_and_build_expr(ltl_text, part_text, ltl_to_atm, opt_level) logging.info("LTL formula size: %i", expr_size(spec.formula)) timer.sec_restart() automaton = ltl_to_atm.convert(spec.formula) logging.info('(unreal) automaton size is: %i' % len(automaton.nodes)) logging.debug('(unreal) automaton (dot) is:\n' + automaton_to_dot.to_dot(automaton)) logging.debug('(unreal) automaton translation took (sec): %i' % timer.sec_restart()) # note: inputs/outputs and machine type are reversed tau_desc = build_tau_desc(spec.outputs) desc_by_output = dict((i, build_output_desc(i, not is_moore, spec.outputs)) for i in spec.inputs) if max_k == 0: encoder = CoBuchiEncoder(automaton, tau_desc, spec.outputs, desc_by_output, range(max_size)) model = model_searcher.search(min_size, max_size, encoder, solver) else: coreach_automaton = k_reduce(automaton, max_k) logging.info("(unreal) using CoReachEncoder") logging.info('(unreal) co-reachability automaton size is: %i' % len(coreach_automaton.nodes)) logging.debug('(unreal) co-reachability automaton (dot) is:\n' + automaton_to_dot.to_dot(coreach_automaton)) encoder = CoreachEncoder(coreach_automaton, tau_desc, spec.outputs, desc_by_output, range(max_size), max_k) model = model_k_searcher.search(min_size, max_size, max_k, encoder, solver) logging.debug('(unreal) model_searcher.search took (sec): %i' % timer.sec_restart()) return model
def check_real( ltl_text, part_text, is_moore, ltl3ba, solver_factory: Z3SolverFactory, min_size, max_size, opt_level=2 ) -> LTS: """ :param opt_level: values > 0 introduce incompleteness (but it is sound: if returns REAL, then REAL) """ timer = Timer() inputs, outputs, expr = parse_acacia_and_build_expr(ltl_text, part_text, ltl3ba, opt_level) timer.sec_restart() automaton = ltl3ba.convert(~expr) logging.info("(real) automaton size is: %i" % len(automaton.nodes)) logging.debug("(real) automaton (dot) is:\n" + automaton2dot.to_dot(automaton)) logging.debug("(real) automaton translation took (sec): %i" % timer.sec_restart()) encoder = create_encoder(inputs, outputs, is_moore, automaton, solver_factory.create()) model = model_searcher.search(min_size, max_size, encoder) logging.debug("(real) model_searcher.search took (sec): %i" % timer.sec_restart()) return model
def run_and_report(spec_file_name, is_moore_: bool, output_file_name, dot_file_name, tasks_creator: TaskCreator): timer = Timer() ltl_text, part_text, is_moore = convert_tlsf_or_acacia_to_acacia( spec_file_name, is_moore_) tasks = tasks_creator.create(ltl_text, part_text, is_moore) is_real, lts_or_aiger = run_synth_tasks(tasks) if is_real is None: logging.warning('Either crashed or did not succeed') print_syntcomp_unknown() exit(UNKNOWN_RC) logging.info('finished in %i sec.' % timer.sec_restart()) if not lts_or_aiger: logging.info('status unknown') print_syntcomp_unknown() exit(UNKNOWN_RC) if not is_real: if isinstance(lts_or_aiger, LTS): lts_str = lts_to_dot(lts_or_aiger, ARG_MODEL_STATE, is_moore) # we invert machine type _write_dot_result(lts_str, dot_file_name) print_syntcomp_unreal() exit(UNREALIZABLE_RC) else: if isinstance(lts_or_aiger, LTS): lts_str = lts_to_dot(lts_or_aiger, ARG_MODEL_STATE, not is_moore) logging.info('state machine size: %i' % len(lts_or_aiger.states)) _write_dot_result(lts_str, dot_file_name) lts_aiger = lts_to_aiger(lts_or_aiger) else: lts_aiger = lts_or_aiger if output_file_name: with open(output_file_name, 'w') as out: out.write(lts_aiger) print_syntcomp_real(lts_aiger) exit(REALIZABLE_RC)