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.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.solver_name = config_selection(problem.solver_name, config.solver_name) mc_config.prove = config_selection(problem.prove, config.prove) return mc_config
def __init__(self): PrintersFactory.init_printers() self.parser = None self.strfiles = None self.verbosity = 1 self.simulate = False self.bmc_length = 10 self.bmc_length_min = 0 self.safety = None self.ltl = None self.properties = None self.lemmas = None self.assumptions = None self.equivalence = None self.symbolic_init = False self.fsm_check = False self.full_trace = False self.trace_vars_change = False self.trace_all_vars = False self.prefix = None self.run_passes = True self.printer = PrintersFactory.get_default().get_name() self.translate = None self.smt2file = None self.strategy = MCConfig.get_strategies()[0][0] self.boolean = False self.abstract_clock = False self.no_clock = False self.skip_solving = False self.pickle_file = None self.solver_name = "msat" self.vcd = False self.prove = False self.incremental = True self.deterministic = False self.time = False
def test(): parser = CosaArgParser() wrapper = TextWrapper(initial_indent=" - ") extra_info = [] devel = False if DEVEL_OPT in sys.argv: sys.argv = [a for a in sys.argv if a != DEVEL_OPT] devel = True extra_info.append(bold_text("\nADDITIONAL INFORMATION:")) clock_behaviors = [] for x in ClockBehaviorsFactory.get_clockbehaviors(): wrapper.subsequent_indent = " " * (len(" - \"\": " + x.get_name())) clock_behaviors.append("\n".join( wrapper.wrap("\"%s\": %s, parameters (%s)" % (x.get_name(), x.get_desc(), x.get_interface())))) extra_info.append('\nClock behaviors:\n%s' % ("\n".join(clock_behaviors))) sugars = [] for x in SyntacticSugarFactory.get_sugars(): wrapper.subsequent_indent = " " * (len(" - \"\": " + x.get_name())) sugars.append("\n".join( wrapper.wrap("\"%s\": %s, parameters (%s)" % (x.get_name(), x.get_desc(), x.get_interface())))) extra_info.append('\nSpecial operators:\n%s' % ("\n".join(sugars))) generators = [] for x in GeneratorsFactory.get_generators(): wrapper.subsequent_indent = " " * (len(" - \"\": " + x.get_name())) generators.append("\n".join( wrapper.wrap("\"%s\": %s, parameters (%s) values (%s)" % (x.get_name(), x.get_desc(), x.get_interface(), x.get_values())))) extra_info.append('\nModule generators:\n%s' % ("\n".join(generators))) modifiers = [] modifiers.append(" - \"None\": No extension") for x in ModelModifiersFactory.get_modifiers(): wrapper.subsequent_indent = " " * (len(" - \"\": " + x.get_name())) modifiers.append("\n".join( wrapper.wrap("\"%s\": %s" % (x.get_name(), x.get_desc())))) extra_info.append('\nModel modifiers:\n%s' % ("\n".join(modifiers))) parser = CosaArgParser(description=bold_text( 'CoSA: CoreIR Symbolic Analyzer\n..an SMT-based Symbolic Model Checker for Hardware Design' ), formatter_class=RawTextHelpFormatter, epilog="\n".join(extra_info)) # Main inputs # Options in the general group are options that must stay constant for all problems # in a problem file # in our architecture, the input files are compiled into a single transition system which # is then used to verify mutliple properties (problems) # thus any option regarding the encoding of said transition system must be a general option in_options = parser.add_general_group('input options') av_input_types = [" - \"%s\": %s"%(x.name, ", ".join(["*.%s"%e for e in x.extensions])) \ for x in ModelParsersFactory.get_parsers() if x.is_available()] ua_input_types = [" - \"%s\": %s"%(x.name, ", ".join(["*.%s"%e for e in x.extensions])) \ for x in ModelParsersFactory.get_parsers() if not x.is_available()] in_options.set_defaults(model_files=None) in_options.add_argument('-i', '--model_files', metavar='<model files>', type=str, required=False, help='comma separated list of input files.\nSupported types:\n%s%s'%\ ("\n".join(av_input_types), "\nNot enabled:\n%s"%("\n".join(ua_input_types)) \ if len(ua_input_types) > 0 else "")) in_options.set_defaults(problems=None) in_options.add_argument( '--problems', metavar='<problems file>', type=str, required=False, help='problems file describing the verifications to be performed.', is_config_file=True) general_encoding_options = parser.add_general_group('encoding') general_encoding_options.set_defaults(abstract_clock=False) general_encoding_options.add_argument( '--abstract-clock', dest='abstract_clock', action='store_true', help="abstracts the clock behavior. (Default is \"%s\")" % False) general_encoding_options.set_defaults(add_clock=False) general_encoding_options.add_argument( '--add-clock', dest='add_clock', action='store_true', help="adds clock behavior. (Default is \"%s\")" % False) general_encoding_options.set_defaults(cache_files=False) general_encoding_options.add_argument( '-c', '--cache-files', dest='cache_files', action='store_true', help="caches encoded files to speed-up parsing. (Default is \"%s\")" % False) general_encoding_options.set_defaults(clean_cache=False) general_encoding_options.add_argument( '--clean-cache', dest='clean_cache', action='store_true', help="deletes the stored cache. (Default is \"%s\")" % False) general_encoding_options.set_defaults(boolean=False) general_encoding_options.add_argument( '--boolean', dest='boolean', action='store_true', help= 'interprets single bits as Booleans instead of 1-bit Bitvector. (Default is \"%s\")' % False) general_encoding_options.set_defaults(run_coreir_passes=True) general_encoding_options.add_argument( '--no-run-coreir-passes', dest='run_coreir_passes', action='store_false', help='does not run CoreIR passes. (Default is \"%s\")' % True) general_encoding_options.set_defaults(model_extension=False) general_encoding_options.add_argument( '--model-extension', metavar='model_extension', type=str, nargs='?', help='select the model modifier. (Default is \"%s\")' % (False)) general_encoding_options.set_defaults(opt_circuit=False) general_encoding_options.add_argument( '--opt-circuit', action='store_true', help='Use Yosys to optimize the circuit -- can remove signals.') general_encoding_options.set_defaults(no_arrays=False) general_encoding_options.add_argument( '--no-arrays', action='store_true', help= 'For Yosys frontend, blast memories to registers instead of using arrays.\n' 'Note: This can fail -- particularly for dualport memories.') general_encoding_options.set_defaults(symbolic_init=False) general_encoding_options.add_argument( '--symbolic-init', dest='symbolic_init', action='store_true', help='removes constraints on the initial state. (Default is \"%s\")' % False) general_encoding_options.set_defaults(zero_init=False) general_encoding_options.add_argument( '--zero-init', dest='zero_init', action='store_true', help='sets initial state to zero. (Default is \"%s\")' % False) general_encoding_options.set_defaults(vcd=False) general_encoding_options.add_argument( '--vcd', dest='vcd', action='store_true', help="generate traces also in vcd format. (Default is \"%s\")" % False) general_encoding_options.add_argument( '--clock-behaviors', metavar='clock_behaviors', type=str, nargs='?', help='semi column separated list of clock behaviors instantiation.') # Verification Options ver_options = parser.add_problem_group('analysis') ver_options.set_defaults(safety=False) ver_options.add_argument('--safety', dest='safety', action='store_true', help='safety verification using BMC.') ver_options.set_defaults(ltl=False) ver_options.add_argument('--ltl', dest='ltl', action='store_true', help='ltl verification using BMC.') ver_options.set_defaults(simulate=False) ver_options.add_argument('--simulate', dest='simulate', action='store_true', help='simulate system using BMC.') ver_options.set_defaults(equivalence=None) ver_options.add_argument('--equivalence', metavar='<input files>', type=str, required=False, help='equivalence checking using BMC.') ver_options.set_defaults(fsm_check=False) ver_options.add_argument( '--fsm-check', dest='fsm_check', action='store_true', help='check if the state machine is deterministic.') ver_options.set_defaults(parametric=False) ver_options.add_argument('--parametric', dest='parametric', action='store_true', help='parametric analysis using BMC.') # Verification parameters ver_params = parser.add_problem_group('verification parameters') ver_params.set_defaults(properties=None) ver_params.add_argument('-p', '--properties', metavar='<invar list>', type=str, required=False, help='comma separated list of properties.') ver_params.set_defaults(bmc_length=5) ver_params.add_argument( '-k', '--bmc-length', metavar='<BMC length>', type=int, required=False, help="depth of BMC unrolling. (Default is \"%s\")" % 5) ver_params.set_defaults(bmc_length_min=0) ver_params.add_argument( '-km', '--bmc-length-min', metavar='<BMC length>', type=int, required=False, help="minimum depth of BMC unrolling. (Default is \"%s\")" % 0) ver_params.set_defaults(precondition=None) ver_params.add_argument('-r', '--precondition', metavar='<invar>', type=str, required=False, help='invariant properties precondition.') ver_params.set_defaults(lemmas=None) ver_params.add_argument('-l', '--lemmas', metavar='<invar list>', type=str, required=False, help='comma separated list of lemmas.') ver_params.set_defaults(assumptions=None) ver_params.add_argument( '-a', '--assumptions', metavar='<invar assumptions list>', type=str, required=False, help='semi column separated list of invariant assumptions.') ver_params.add_argument( '--generators', metavar='generators', type=str, nargs='?', help='semi column separated list of generators instantiation.') ver_params.set_defaults(prove=False) ver_params.add_argument( '--prove', dest='prove', action='store_true', help= "use indution to prove the satisfiability of the property. (Default is \"%s\")" % False) ver_params.set_defaults(assume_if_true=False) ver_params.add_argument( '--assume-if-true', dest='assume_if_true', action='store_true', help="add true properties as assumptions. (Default is \"%s\")" % False) ver_params.set_defaults(coi=False) ver_params.add_argument( '--coi', dest='coi', action='store_true', help="enables Cone of Influence. (Default is \"%s\")" % False) ver_params.set_defaults(cardinality=5) ver_params.add_argument( '--cardinality', dest='cardinality', type=int, required=False, help= "bounds number of active parameters. -1 is unbounded. (Default is \"%s\")" % 5) strategies = [ " - \"%s\": %s" % (x[0], x[1]) for x in MCConfig.get_strategies() ] defstrategy = MCConfig.get_strategies()[0][0] ver_params.set_defaults(strategy=defstrategy) ver_params.add_argument( '--strategy', metavar='strategy', type=str, nargs='?', help='select the BMC strategy between (Default is \"%s\"):\n%s' % (defstrategy, "\n".join(strategies))) ver_params.set_defaults(processes=int(multiprocessing.cpu_count() / 2)) ver_params.add_argument( '-j', dest='processes', metavar="<integer level>", type=int, help="number of multi-processes for MULTI strategy. (Default is \"%s\")" % int(multiprocessing.cpu_count() / 2)) ver_params.set_defaults(ninc=False) ver_params.add_argument( '--ninc', dest='ninc', action='store_true', help="disables incrementality. (Default is \"%s\")" % True) ver_params.set_defaults(solver_name='msat') ver_params.add_argument( '--solver-name', metavar='<Solver Name>', type=str, required=False, help="name of SMT solver to be use. (Default is \"%s\")" % 'msat') # Printing parameters print_params = parser.add_problem_group('trace printing') print_params.set_defaults(trace_vars_change=False) print_params.add_argument( '--trace-vars-change', dest='trace_vars_change', action='store_true', help= "show variable assignments in the counterexamples even when unchanged. (Default is \"%s\")" % False) print_params.set_defaults(trace_all_vars=False) print_params.add_argument( '--trace-all-vars', dest='trace_all_vars', action='store_true', help="show all variables in the counterexamples. (Default is \"%s\")" % False) print_params.set_defaults(full_trace=False) print_params.add_argument( '--full-trace', dest='full_trace', action='store_true', help= "sets trace-vars-unchanged and trace-all-vars to True. (Default is \"%s\")" % False) trace_values_base_default = TraceValuesBase.get_all()[0] print_params.set_defaults(trace_values_base=trace_values_base_default) print_params.add_argument( '--trace-values-base', metavar='trace_values_base', type=str, nargs='?', help="sets the style of Bit-Vector values printing. (Default is \"%s\")" % trace_values_base_default) print_params.set_defaults(prefix=None) print_params.add_argument( '--prefix', metavar='<prefix location>', type=str, required=False, help='write the counterexamples with a specified location prefix.') # Translation parameters trans_params = parser.add_problem_group('translation') trans_params.set_defaults(translate=None) trans_params.add_argument('--translate', metavar='<output file>', type=str, required=False, help='translate input file.') printers = [ " - \"%s\": %s" % (x.get_name(), x.get_desc()) for x in HTSPrintersFactory.get_printers_by_type(HTSPrinterType.TRANSSYS) ] printer_default = HTSPrintersFactory.get_default().get_name() trans_params.set_defaults(printer=printer_default) trans_params.add_argument( '--printer', metavar='printer', type=str, nargs='?', help='select the printer between (Default is \"%s\"):\n%s' % (printer_default, "\n".join(printers))) trans_params.set_defaults(skip_solving=False) trans_params.add_argument( '--skip-solving', dest='skip_solving', action='store_true', help="does not call the solver. (Default is \"%s\")" % False) # Debugging deb_params = parser.add_general_group('verbosity') deb_params.set_defaults(verbosity=1) deb_params.add_argument('-v', dest='verbosity', metavar="<integer level>", type=int, help="verbosity level. (Default is \"%s\")" % 1) deb_params.set_defaults(time=False) deb_params.add_argument( '--time', dest='time', action='store_true', help="prints time for every verification. (Default is \"%s\")" % False) deb_params.set_defaults(devel=False) deb_params.add_argument( '--devel', dest='devel', action='store_true', help="enables developer mode. (Default is \"%s\")" % False) problems = parser.parse_args() for problem in problems._problems: print(problem)
def main(): parser = argparse.ArgumentParser(description='CoreIR Symbolic Analyzer.', formatter_class=RawTextHelpFormatter) config = Config() # Main inputs in_options = parser.add_argument_group('input options') in_options.set_defaults(input_files=None) in_options.add_argument('-i', '--input_files', metavar='<input files>', type=str, required=False, help='comma separated list of input files.') in_options.set_defaults(problems=None) in_options.add_argument( '--problems', metavar='<problems file>', type=str, required=False, help='problems file describing the verifications to be performed.') # Verification Options ver_options = parser.add_argument_group('analysis') ver_options.set_defaults(safety=False) ver_options.add_argument('--safety', dest='safety', action='store_true', help='safety verification using BMC.') ver_options.set_defaults(ltl=False) ver_options.add_argument('--ltl', dest='ltl', action='store_true', help='ltl verification using BMC.') ver_options.set_defaults(simulate=False) ver_options.add_argument('--simulate', dest='simulate', action='store_true', help='simulate system using BMC.') ver_options.set_defaults(equivalence=None) ver_options.add_argument('--equivalence', metavar='<input files>', type=str, required=False, help='equivalence checking using BMC.') ver_options.set_defaults(fsm_check=False) ver_options.add_argument( '--fsm-check', dest='fsm_check', action='store_true', help='check if the state machine is deterministic.') # Verification parameters ver_params = parser.add_argument_group('verification parameters') ver_params.set_defaults(properties=None) ver_params.add_argument('-p', '--properties', metavar='<invar list>', type=str, required=False, help='comma separated list of properties.') ver_params.set_defaults(bmc_length=config.bmc_length) ver_params.add_argument( '-k', '--bmc-length', metavar='<BMC length>', type=int, required=False, help="depth of BMC unrolling. (Default is \"%s\")" % config.bmc_length) ver_params.set_defaults(bmc_length_min=config.bmc_length_min) ver_params.add_argument( '-km', '--bmc-length-min', metavar='<BMC length>', type=int, required=False, help="minimum depth of BMC unrolling. (Default is \"%s\")" % config.bmc_length_min) ver_params.set_defaults(lemmas=None) ver_params.add_argument('-l', '--lemmas', metavar='<invar list>', type=str, required=False, help='comma separated list of lemmas.') ver_params.set_defaults(assumptions=None) ver_params.add_argument( '-a', '--assumptions', metavar='<invar assumptions list>', type=str, required=False, help='comma separated list of invariant assumptions.') # monitors = [" - \"%s\": %s, with parameters (%s)"%(x.get_name(), x.get_desc(), x.get_interface()) for x in MonitorsFactory.get_monitors()] # ver_params.add_argument('--monitors', metavar='monitors', type=str, nargs='?', # help='comma separated list of monitors instantiation. Possible types:\n%s'%("\n".join(monitors))) ver_params.set_defaults(prove=False) ver_params.add_argument( '--prove', dest='prove', action='store_true', help='use indution to prove the satisfiability of the property.') strategies = [ " - \"%s\": %s" % (x[0], x[1]) for x in MCConfig.get_strategies() ] defstrategy = MCConfig.get_strategies()[0][0] ver_params.set_defaults(strategy=defstrategy) ver_params.add_argument( '--strategy', metavar='strategy', type=str, nargs='?', help='select the BMC strategy between (Default is \"%s\"):\n%s' % (defstrategy, "\n".join(strategies))) ver_params.set_defaults(ninc=False) ver_params.add_argument('--ninc', dest='ninc', action='store_true', help='disables incrementality.') ver_params.set_defaults(solver_name=config.solver_name) ver_params.add_argument( '--solver-name', metavar='<Solver Name>', type=str, required=False, help="name of SMT solver to be use. (Default is \"%s\")" % config.solver_name) # Encoding parameters enc_params = parser.add_argument_group('encoding') enc_params.set_defaults(no_clock=False) enc_params.add_argument('--no-clock', dest='no_clock', action='store_true', help='does not add the clock behavior.') enc_params.set_defaults(abstract_clock=False) enc_params.add_argument('--abstract-clock', dest='abstract_clock', action='store_true', help='abstracts the clock behavior.') enc_params.set_defaults(symbolic_init=config.symbolic_init) enc_params.add_argument( '--symbolic-init', dest='symbolic_init', action='store_true', help= 'symbolic inititial state for equivalence checking. (Default is \"%s\")' % config.symbolic_init) enc_params.set_defaults(boolean=config.boolean) enc_params.add_argument( '--boolean', dest='boolean', action='store_true', help= 'interprets single bits as Booleans instead of 1-bit Bitvector. (Default is \"%s\")' % config.boolean) enc_params.set_defaults(run_passes=config.run_passes) enc_params.add_argument( '--no-run-passes', dest='run_passes', action='store_false', help='does not run CoreIR passes. (Default is \"%s\")' % config.run_passes) # Printing parameters print_params = parser.add_argument_group('trace printing') print_params.set_defaults(trace_vars_change=config.trace_vars_change) print_params.add_argument( '--trace-vars-change', dest='trace_vars_change', action='store_true', help= "show variable assignments in the counterexamples even when unchanged. (Default is \"%s\")" % config.trace_vars_change) print_params.set_defaults(trace_all_vars=config.trace_all_vars) print_params.add_argument( '--trace-all-vars', dest='trace_all_vars', action='store_true', help="show all variables in the counterexamples. (Default is \"%s\")" % config.trace_all_vars) print_params.set_defaults(full_trace=config.full_trace) print_params.add_argument( '--full-trace', dest='full_trace', action='store_true', help= "sets trace-vars-unchanged and trace-all-vars to True. (Default is \"%s\")" % config.full_trace) print_params.set_defaults(prefix=None) print_params.add_argument( '--prefix', metavar='<prefix location>', type=str, required=False, help='write the counterexamples with a specified location prefix.') print_params.set_defaults(vcd=False) print_params.add_argument('--vcd', dest='vcd', action='store_true', help='generate traces also in vcd format.') # Translation parameters trans_params = parser.add_argument_group('translation') trans_params.set_defaults(smt2=None) trans_params.add_argument( '--smt2', metavar='<smt-lib2 file>', type=str, required=False, help='generates the smtlib2 encoding for a BMC call.') trans_params.set_defaults(translate=None) trans_params.add_argument('--translate', metavar='<output file>', type=str, required=False, help='translate input file.') printers = [ " - \"%s\": %s" % (x.get_name(), x.get_desc()) for x in PrintersFactory.get_printers_by_type(PrinterType.TRANSSYS) ] trans_params.set_defaults(printer=config.printer) trans_params.add_argument( '--printer', metavar='printer', type=str, nargs='?', help='select the printer between (Default is \"%s\"):\n%s' % (config.printer, "\n".join(printers))) trans_params.set_defaults(skip_solving=False) trans_params.add_argument( '--skip-solving', dest='skip_solving', action='store_true', help= 'does not call the solver (used with --smt2 or --translate parameters).' ) trans_params.set_defaults(pickle=None) trans_params.add_argument( '--pickle', metavar='<pickle file>', type=str, required=False, help='pickles the transition system to be loaded later.') # Debugging deb_params = parser.add_argument_group('verbosity') deb_params.set_defaults(verbosity=config.verbosity) deb_params.add_argument('-v', dest='verbosity', metavar="<integer level>", type=int, help="verbosity level. (Default is \"%s\")" % config.verbosity) deb_params.set_defaults(debug=False) deb_params.add_argument('--debug', dest='debug', action='store_true', help='enables debug mode.') deb_params.set_defaults(time=False) deb_params.add_argument('--time', dest='time', action='store_true', help='prints time for every verification.') args = parser.parse_args() config.strfiles = args.input_files config.simulate = args.simulate config.safety = args.safety config.ltl = args.ltl config.properties = args.properties config.lemmas = args.lemmas config.assumptions = args.assumptions config.equivalence = args.equivalence config.symbolic_init = args.symbolic_init config.fsm_check = args.fsm_check config.bmc_length = args.bmc_length config.bmc_length_min = args.bmc_length_min config.full_trace = args.full_trace config.trace_vars_change = args.trace_vars_change config.trace_all_vars = args.trace_all_vars config.prefix = args.prefix config.translate = args.translate config.smt2file = args.smt2 config.strategy = args.strategy config.skip_solving = args.skip_solving config.pickle_file = args.pickle config.abstract_clock = args.abstract_clock config.boolean = args.boolean config.verbosity = args.verbosity config.vcd = args.vcd config.prove = args.prove config.solver_name = args.solver_name config.incremental = not args.ninc config.time = args.time config.no_clock = args.no_clock # config.monitors = args.monitors if len(sys.argv) == 1: parser.print_help() sys.exit(1) if args.problems: if args.debug: sys.exit(run_problems(args.problems, config)) else: try: sys.exit(run_problems(args.problems, config)) except Exception as e: Logger.msg(str(e), 0) sys.exit(1) Logger.error_raise_exept = False if (args.problems is None) and (args.input_files is None): Logger.error("No input files provided") if args.printer in [ str(x.get_name()) for x in PrintersFactory.get_printers_by_type(PrinterType.TRANSSYS) ]: config.printer = args.printer else: Logger.error("Printer \"%s\" not found" % (args.printer)) if args.strategy not in [s[0] for s in MCConfig.get_strategies()]: Logger.error("Strategy \"%s\" not found" % (args.strategy)) if not(config.simulate or \ (config.safety) or \ (config.ltl) or \ (config.equivalence is not None) or\ (config.translate is not None) or\ (config.fsm_check)): Logger.error("Analysis selection is necessary") parsing_defs = [config.properties, config.lemmas, config.assumptions] for i in range(len(parsing_defs)): if parsing_defs[i] is not None: if os.path.isfile(parsing_defs[i]): with open(parsing_defs[i]) as f: parsing_defs[i] = [ p.strip() for p in f.read().strip().split("\n") ] else: parsing_defs[i] = [ p.strip() for p in parsing_defs[i].split(",") ] [config.properties, config.lemmas, config.assumptions] = parsing_defs Logger.error_raise_exept = True if args.debug: sys.exit(run_verification(config)) else: try: sys.exit(run_verification(config)) except Exception as e: Logger.msg(str(e), 0) sys.exit(1)
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
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 __init__(self): HTSPrintersFactory.init_printers() self.printer = HTSPrintersFactory.get_default().get_name() self.strategy = MCConfig.get_strategies()[0][0]
def main(): wrapper = TextWrapper(initial_indent=" - ") extra_info = [] devel = False if DEVEL_OPT in sys.argv: sys.argv = [a for a in sys.argv if a != DEVEL_OPT] devel = True extra_info.append(bold_text("\nADDITIONAL INFORMATION:")) clock_behaviors = [] for x in ClockBehaviorsFactory.get_clockbehaviors(): wrapper.subsequent_indent = " " * (len(" - \"\": " + x.get_name())) clock_behaviors.append("\n".join( wrapper.wrap("\"%s\": %s, parameters (%s)" % (x.get_name(), x.get_desc(), x.get_interface())))) extra_info.append('\nClock behaviors:\n%s' % ("\n".join(clock_behaviors))) sugars = [] for x in SyntacticSugarFactory.get_sugars(): wrapper.subsequent_indent = " " * (len(" - \"\": " + x.get_name())) sugars.append("\n".join( wrapper.wrap("\"%s\": %s, parameters (%s)" % (x.get_name(), x.get_desc(), x.get_interface())))) extra_info.append('\nSpecial operators:\n%s' % ("\n".join(sugars))) generators = [] for x in GeneratorsFactory.get_generators(): wrapper.subsequent_indent = " " * (len(" - \"\": " + x.get_name())) generators.append("\n".join( wrapper.wrap("\"%s\": %s, parameters (%s)" % (x.get_name(), x.get_desc(), x.get_interface())))) extra_info.append('\nModule generators:\n%s' % ("\n".join(generators))) modifiers = [] modifiers.append(" - \"None\": No extension") for x in ModelModifiersFactory.get_modifiers(): wrapper.subsequent_indent = " " * (len(" - \"\": " + x.get_name())) modifiers.append("\n".join( wrapper.wrap("\"%s\": %s" % (x.get_name(), x.get_desc())))) extra_info.append('\nModel modifiers:\n%s' % ("\n".join(modifiers))) parser = argparse.ArgumentParser(description=bold_text('CoSA: CoreIR Symbolic Analyzer\n..an SMT-based Symbolic Model Checker for Hardware Design'), \ #usage='%(prog)s [options]', \ formatter_class=RawTextHelpFormatter, \ epilog="\n".join(extra_info)) config = Config() # Main inputs in_options = parser.add_argument_group('input options') av_input_types = [" - \"%s\": %s"%(x.name, ", ".join(["*.%s"%e for e in x.extensions])) \ for x in ModelParsersFactory.get_parsers() if x.is_available()] ua_input_types = [" - \"%s\": %s"%(x.name, ", ".join(["*.%s"%e for e in x.extensions])) \ for x in ModelParsersFactory.get_parsers() if not x.is_available()] in_options.set_defaults(input_files=None) in_options.add_argument('-i', '--input_files', metavar='<input files>', type=str, required=False, help='comma separated list of input files.\nSupported types:\n%s%s'%\ ("\n".join(av_input_types), "\nNot enabled:\n%s"%("\n".join(ua_input_types)) \ if len(ua_input_types) > 0 else "")) in_options.set_defaults(problems=None) in_options.add_argument( '--problems', metavar='<problems file>', type=str, required=False, help='problems file describing the verifications to be performed.') # Verification Options ver_options = parser.add_argument_group('analysis') ver_options.set_defaults(safety=False) ver_options.add_argument('--safety', dest='safety', action='store_true', help='safety verification using BMC.') ver_options.set_defaults(ltl=False) ver_options.add_argument('--ltl', dest='ltl', action='store_true', help='ltl verification using BMC.') ver_options.set_defaults(simulate=False) ver_options.add_argument('--simulate', dest='simulate', action='store_true', help='simulate system using BMC.') ver_options.set_defaults(equivalence=None) ver_options.add_argument('--equivalence', metavar='<input files>', type=str, required=False, help='equivalence checking using BMC.') ver_options.set_defaults(fsm_check=False) ver_options.add_argument( '--fsm-check', dest='fsm_check', action='store_true', help='check if the state machine is deterministic.') ver_options.set_defaults(parametric=False) ver_options.add_argument('--parametric', dest='parametric', action='store_true', help='parametric analysis using BMC.') # Verification parameters ver_params = parser.add_argument_group('verification parameters') ver_params.set_defaults(properties=None) ver_params.add_argument('-p', '--properties', metavar='<invar list>', type=str, required=False, help='comma separated list of properties.') ver_params.set_defaults(bmc_length=config.bmc_length) ver_params.add_argument( '-k', '--bmc-length', metavar='<BMC length>', type=int, required=False, help="depth of BMC unrolling. (Default is \"%s\")" % config.bmc_length) ver_params.set_defaults(bmc_length_min=config.bmc_length_min) ver_params.add_argument( '-km', '--bmc-length-min', metavar='<BMC length>', type=int, required=False, help="minimum depth of BMC unrolling. (Default is \"%s\")" % config.bmc_length_min) ver_params.set_defaults(precondition=None) ver_params.add_argument('-r', '--precondition', metavar='<invar>', type=str, required=False, help='invariant properties precondition.') ver_params.set_defaults(lemmas=None) ver_params.add_argument('-l', '--lemmas', metavar='<invar list>', type=str, required=False, help='comma separated list of lemmas.') ver_params.set_defaults(assumptions=None) ver_params.add_argument( '-a', '--assumptions', metavar='<invar assumptions list>', type=str, required=False, help='semi column separated list of invariant assumptions.') ver_params.add_argument( '--generators', metavar='generators', type=str, nargs='?', help='semi column separated list of generators instantiation.') ver_params.add_argument( '--clock-behaviors', metavar='clock_behaviors', type=str, nargs='?', help='semi column separated list of clock behaviors instantiation.') ver_params.set_defaults(prove=False) ver_params.add_argument( '--prove', dest='prove', action='store_true', help= "use indution to prove the satisfiability of the property. (Default is \"%s\")" % config.prove) ver_params.set_defaults(assume_if_true=False) ver_params.add_argument( '--assume-if-true', dest='assume_if_true', action='store_true', help="add true properties as assumptions. (Default is \"%s\")" % config.assume_if_true) ver_params.set_defaults(coi=False) ver_params.add_argument( '--coi', dest='coi', action='store_true', help="enables Cone of Influence. (Default is \"%s\")" % config.coi) ver_params.set_defaults(cardinality=config.cardinality) ver_params.add_argument( '--cardinality', dest='cardinality', type=int, required=False, help= "bounds number of active parameters. -1 is unbounded. (Default is \"%s\")" % config.cardinality) strategies = [ " - \"%s\": %s" % (x[0], x[1]) for x in MCConfig.get_strategies() ] defstrategy = MCConfig.get_strategies()[0][0] ver_params.set_defaults(strategy=defstrategy) ver_params.add_argument( '--strategy', metavar='strategy', type=str, nargs='?', help='select the BMC strategy between (Default is \"%s\"):\n%s' % (defstrategy, "\n".join(strategies))) ver_params.set_defaults(processes=config.processes) ver_params.add_argument( '-j', dest='processes', metavar="<integer level>", type=int, help="number of multi-processes for MULTI strategy. (Default is \"%s\")" % config.processes) ver_params.set_defaults(ninc=False) ver_params.add_argument( '--ninc', dest='ninc', action='store_true', help="disables incrementality. (Default is \"%s\")" % (not config.incremental)) ver_params.set_defaults(solver_name=config.solver_name) ver_params.add_argument( '--solver-name', metavar='<Solver Name>', type=str, required=False, help="name of SMT solver to be use. (Default is \"%s\")" % config.solver_name) # Encoding parameters enc_params = parser.add_argument_group('encoding') enc_params.set_defaults(cache_files=False) enc_params.add_argument( '-c', '--cache-files', dest='cache_files', action='store_true', help="caches encoded files to speed-up parsing. (Default is \"%s\")" % config.cache_files) enc_params.set_defaults(add_clock=False) enc_params.add_argument('--add-clock', dest='add_clock', action='store_true', help="adds clock behavior. (Default is \"%s\")" % config.add_clock) enc_params.set_defaults(abstract_clock=False) enc_params.add_argument( '--abstract-clock', dest='abstract_clock', action='store_true', help="abstracts the clock behavior. (Default is \"%s\")" % config.abstract_clock) enc_params.set_defaults(symbolic_init=config.symbolic_init) enc_params.add_argument( '--symbolic-init', dest='symbolic_init', action='store_true', help='removes constraints on the initial state. (Default is \"%s\")' % config.symbolic_init) enc_params.set_defaults(zero_init=config.zero_init) enc_params.add_argument( '--zero-init', dest='zero_init', action='store_true', help='sets initial state to zero. (Default is \"%s\")' % config.zero_init) enc_params.set_defaults(boolean=config.boolean) enc_params.add_argument( '--boolean', dest='boolean', action='store_true', help= 'interprets single bits as Booleans instead of 1-bit Bitvector. (Default is \"%s\")' % config.boolean) enc_params.set_defaults(run_passes=config.run_passes) enc_params.add_argument( '--no-run-passes', dest='run_passes', action='store_false', help='does not run CoreIR passes. (Default is \"%s\")' % config.run_passes) enc_params.set_defaults(model_extension=config.model_extension) enc_params.add_argument( '--model-extension', metavar='model_extension', type=str, nargs='?', help='select the model modifier. (Default is \"%s\")' % (config.model_extension)) # Printing parameters print_params = parser.add_argument_group('trace printing') print_params.set_defaults(trace_vars_change=config.trace_vars_change) print_params.add_argument( '--trace-vars-change', dest='trace_vars_change', action='store_true', help= "show variable assignments in the counterexamples even when unchanged. (Default is \"%s\")" % config.trace_vars_change) print_params.set_defaults(trace_all_vars=config.trace_all_vars) print_params.add_argument( '--trace-all-vars', dest='trace_all_vars', action='store_true', help="show all variables in the counterexamples. (Default is \"%s\")" % config.trace_all_vars) print_params.set_defaults(full_trace=config.full_trace) print_params.add_argument( '--full-trace', dest='full_trace', action='store_true', help= "sets trace-vars-unchanged and trace-all-vars to True. (Default is \"%s\")" % config.full_trace) print_params.set_defaults(prefix=None) print_params.add_argument( '--prefix', metavar='<prefix location>', type=str, required=False, help='write the counterexamples with a specified location prefix.') print_params.set_defaults(vcd=False) print_params.add_argument( '--vcd', dest='vcd', action='store_true', help="generate traces also in vcd format. (Default is \"%s\")" % config.vcd) # Translation parameters trans_params = parser.add_argument_group('translation') trans_params.set_defaults(translate=None) trans_params.add_argument('--translate', metavar='<output file>', type=str, required=False, help='translate input file.') printers = [ " - \"%s\": %s" % (x.get_name(), x.get_desc()) for x in HTSPrintersFactory.get_printers_by_type(HTSPrinterType.TRANSSYS) ] trans_params.set_defaults(printer=config.printer) trans_params.add_argument( '--printer', metavar='printer', type=str, nargs='?', help='select the printer between (Default is \"%s\"):\n%s' % (config.printer, "\n".join(printers))) trans_params.set_defaults(skip_solving=False) trans_params.add_argument( '--skip-solving', dest='skip_solving', action='store_true', help="does not call the solver. (Default is \"%s\")" % config.skip_solving) # Debugging deb_params = parser.add_argument_group('verbosity') deb_params.set_defaults(verbosity=config.verbosity) deb_params.add_argument('-v', dest='verbosity', metavar="<integer level>", type=int, help="verbosity level. (Default is \"%s\")" % config.verbosity) deb_params.set_defaults(time=False) deb_params.add_argument( '--time', dest='time', action='store_true', help="prints time for every verification. (Default is \"%s\")" % config.time) deb_params.set_defaults(devel=False) deb_params.add_argument( '--devel', dest='devel', action='store_true', help="enables developer mode. (Default is \"%s\")" % config.devel) # Developers if devel: config.devel = True devel_params = parser.add_argument_group('developer') devel_params.set_defaults(smt2=None) devel_params.add_argument( '--smt2', metavar='<smt-lib2 file>', type=str, required=False, help='generates the smtlib2 tracing file for each solver call.') args = parser.parse_args() config.strfiles = args.input_files config.simulate = args.simulate config.safety = args.safety config.parametric = args.parametric config.ltl = args.ltl config.properties = args.properties config.lemmas = args.lemmas config.precondition = args.precondition config.assumptions = args.assumptions config.equivalence = args.equivalence config.symbolic_init = args.symbolic_init config.zero_init = args.zero_init config.fsm_check = args.fsm_check config.bmc_length = args.bmc_length config.bmc_length_min = args.bmc_length_min config.full_trace = args.full_trace config.trace_vars_change = args.trace_vars_change config.trace_all_vars = args.trace_all_vars config.prefix = args.prefix config.translate = args.translate config.strategy = args.strategy config.processes = args.processes config.skip_solving = args.skip_solving config.abstract_clock = args.abstract_clock config.boolean = args.boolean config.verbosity = args.verbosity config.vcd = args.vcd config.prove = args.prove config.solver_name = args.solver_name config.incremental = not args.ninc config.time = args.time config.add_clock = args.add_clock config.generators = args.generators config.clock_behaviors = args.clock_behaviors config.assume_if_true = args.assume_if_true config.coi = args.coi config.model_extension = args.model_extension config.cardinality = args.cardinality config.cache_files = args.cache_files if devel: config.smt2file = args.smt2 if len(sys.argv) == 1: parser.print_help() sys.exit(1) if args.printer in [ str(x.get_name()) for x in HTSPrintersFactory.get_printers_by_type( HTSPrinterType.TRANSSYS) ]: config.printer = args.printer else: Logger.error("Printer \"%s\" not found" % (args.printer)) if args.problems: if config.devel: sys.exit(run_problems(args.problems, config)) else: try: sys.exit(run_problems(args.problems, config)) except Exception as e: Logger.error(str(e), False) sys.exit(1) Logger.error_raise_exept = False if (args.problems is None) and (args.input_files is None): Logger.error("No input files provided") if args.strategy not in [s[0] for s in MCConfig.get_strategies()]: Logger.error("Strategy \"%s\" not found" % (args.strategy)) if not(config.simulate or \ (config.safety) or \ (config.parametric) or \ (config.ltl) or \ (config.equivalence is not None) or\ (config.translate is not None) or\ (config.fsm_check)): Logger.error("Analysis selection is necessary") Logger.error_raise_exept = True if config.devel: sys.exit(run_verification(config)) else: try: sys.exit(run_verification(config)) except Exception as e: Logger.error(str(e), False) sys.exit(1)