def problem2mc_config(self, problem, config): mc_config = MCConfig() config_selection = lambda problem, config: config if problem is None else problem mc_config.smt2file = config_selection(problem.smt2_tracing, config.smt2file) mc_config.full_trace = problem.full_trace or config.full_trace mc_config.trace_vars_change = problem.trace_vars_change or config.trace_vars_change mc_config.trace_all_vars = problem.trace_all_vars or config.trace_all_vars mc_config.prefix = problem.name mc_config.strategy = config_selection(problem.strategy, config.strategy) mc_config.incremental = config_selection(problem.incremental, config.incremental) mc_config.skip_solving = config_selection(problem.skip_solving, config.skip_solving) mc_config.map_function = self.parser.remap_an2or mc_config.solver_name = config_selection(problem.solver_name, config.solver_name) mc_config.vcd_trace = problem.vcd or config.vcd mc_config.prove = config_selection(problem.prove, config.prove) mc_config.properties = problem.formula mc_config.assumptions = problem.assumptions mc_config.lemmas = problem.lemmas return mc_config
def run_verification(config): reset_env() Logger.verbosity = config.verbosity coreir_parser = None ets_parser = None sts_parser = None if config.ltl: ltl_reset_env() hts = HTS("Top level") if config.strfiles[0][-4:] != ".pkl": ps = ProblemSolver() (hts, invar_props, ltl_props) = ps.parse_model("./", config.strfiles, config.abstract_clock, config.symbolic_init, deterministic=config.deterministic, boolean=config.boolean, no_clock=config.no_clock) config.parser = ps.parser if config.pickle_file: Logger.msg("Pickling model to %s\n" % (config.pickle_file), 1) sys.setrecursionlimit(50000) with open(config.pickle_file, "wb") as f: pickle.dump(hts, f) else: if config.pickle_file: raise RuntimeError("Don't need to re-pickle the input file %s" % (config.strfile)) Logger.msg("Loading pickle file %s\n" % (config.strfile), 0) with open(config.pickle_file, "rb") as f: hts = pickle.load(f) Logger.log("DONE", 0) printsmv = True mc_config = MCConfig() sparser = StringParser() sparser.remap_or2an = config.parser.remap_or2an ltlparser = LTLParser() # if equivalence checking wait to add assumptions to combined system if config.assumptions is not None and config.equivalence is None: Logger.log("Adding %d assumptions... " % len(config.assumptions), 1) assumps = [t[1] for t in sparser.parse_formulae(config.assumptions)] hts.assumptions = assumps lemmas = None if config.lemmas is not None: Logger.log("Adding %d lemmas... " % len(config.lemmas), 1) parsed_formulae = sparser.parse_formulae(config.lemmas) if list(set([t[2] for t in parsed_formulae]))[0][0] != False: Logger.error("Lemmas do not support \"next\" operators") lemmas = [t[1] for t in parsed_formulae] hts.lemmas = lemmas mc_config.smt2file = config.smt2file mc_config.full_trace = config.full_trace mc_config.trace_vars_change = config.trace_vars_change mc_config.trace_all_vars = config.trace_all_vars mc_config.prefix = config.prefix mc_config.strategy = config.strategy mc_config.skip_solving = config.skip_solving mc_config.map_function = config.parser.remap_an2or mc_config.solver_name = config.solver_name mc_config.vcd_trace = config.vcd mc_config.prove = config.prove mc_config.incremental = config.incremental if config.ltl: bmc_ltl = BMCLTL(hts, mc_config) else: bmc_safety = BMCSafety(hts, mc_config) if config.translate: Logger.log("Writing system to \"%s\"" % (config.translate), 0) printer = PrintersFactory.printer_by_name(config.printer) props = [] if config.ltl: props += ltlparser.parse_formulae(config.properties) props += [(str(p), p, None) for p in ltl_props] else: props += sparser.parse_formulae(config.properties) props += [(str(p), p, None) for p in invar_props] with open(config.translate, "w") as f: f.write(printer.print_hts(hts, props)) if config.simulate: count = 0 if config.properties is None: props = [("True", TRUE(), None)] else: props = sparser.parse_formulae(config.properties) for (strprop, prop, _) in props: Logger.log("Simulation for property \"%s\":" % (strprop), 0) res, trace = bmc_safety.simulate(prop, config.bmc_length) if res == VerificationStatus.TRUE: count += 1 print_trace("Execution", trace, count, config.prefix) else: Logger.log("No execution found", 0) if config.safety: count = 0 props = sparser.parse_formulae(config.properties) props += [(str(p), p, None) for p in invar_props] if len(props) == 0: Logger.warning("Safety verification requires at least a property") for (strprop, prop, _) in props: Logger.log("Safety verification for property \"%s\":" % (strprop), 0) res, trace, t = bmc_safety.safety(prop, config.bmc_length, config.bmc_length_min) Logger.log("\nProperty is %s" % res, 0) if res == VerificationStatus.FALSE: count += 1 print_trace("Counterexample", trace, count, config.prefix) return 0 if config.equivalence or config.fsm_check: if config.equivalence: parser2 = CoreIRParser(config.abstract_clock, config.symbolic_init, config.run_passes) Logger.msg("Parsing file \"%s\"... " % (config.equivalence), 0) hts2 = parser2.parse_file(config.equivalence) Logger.log("DONE", 0) symb = " (symbolic init)" if config.symbolic_init else "" Logger.log( "Equivalence checking%s with k=%s:" % (symb, config.bmc_length), 0) if Logger.level(1): print(hts2.print_statistics("System 2", Logger.level(2))) else: hts2 = hts # TODO: Make incremental solving optional htseq, miter_out = Miter.combine_systems(hts, hts2, config.bmc_length, config.symbolic_init, config.properties, True) if config.assumptions is not None: Logger.log( "Adding %d assumptions to combined system... " % len(config.assumptions), 1) assumps = [ t[1] for t in sparser.parse_formulae(config.assumptions) ] htseq.assumptions = assumps # create bmc object for combined system bmcseq = BMC(htseq, mc_config) res, trace, t = bmcseq.safety(miter_out, config.bmc_length, config.bmc_length_min) msg = "Systems are %s equivalent" if config.equivalence else "System is%s deterministic" if res == VerificationStatus.FALSE: Logger.log(msg % (" not"), 0) print_trace("Counterexample", trace, 1, config.prefix) elif res == VerificationStatus.UNK: if config.symbolic_init: # strong equivalence with symbolic initial state Logger.log(msg % (""), 0) else: Logger.log(msg % ("") + " up to k=%i" % t, 0) else: Logger.log(msg % ("") + " up to k=%i" % t, 0) if config.ltl: count = 0 props = ltlparser.parse_formulae(config.properties) props += [(str(p), p, None) for p in ltl_props] if len(props) == 0: Logger.warning("LTL verification requires at least a property") for (strprop, prop, _) in props: Logger.log("LTL verification for property \"%s\":" % (strprop), 0) res, trace, t = bmc_ltl.ltl(prop, config.bmc_length, config.bmc_length_min) Logger.log("\nProperty is %s" % res, 0) if res == VerificationStatus.FALSE: count += 1 print_trace("Counterexample", trace, count, config.prefix) return 0