def analyze_constraints(self, program, model, jsengine, runs, threads, jsprogram, use_alloy): matched = None unmatched = None config = Config() config.command = jsengine config.input_file = jsprogram config.threads = threads config.number = runs config.silent = True config.models = True if use_alloy: labelling_vars = [y[2] for y in [x.split(" ") for x in model.split("\n") if len(x.split(" "))>2] \ if y[2][:len(LABELLING_VAR_PREF)] == LABELLING_VAR_PREF] else: labelling_vars = [x.split(" ")[0] for x in model.split("\n") \ if x[:len(LABELLING_VAR_PREF)] == LABELLING_VAR_PREF] if len(labelling_vars) == 0: Logger.error("No labelling vars defined") return None if use_alloy: self.al_consamanager.labelling_vars = labelling_vars else: self.c4_consamanager.labelling_vars = labelling_vars (matched, unmatched) = self.__load_outputs(config.number, self.outfile, jsengine) if (matched is None) and (unmatched is None): timer = Logger.start_timer("Run Litmus") (matched, unmatched) = run_litmus(config) Logger.stop_timer(timer) self.__save_outputs(config.number, self.outfile, jsengine, matched, unmatched) timer = Logger.start_timer("Analyze output") parser = BeParser() mexecs = parser.executions_from_string("\n".join(matched), program) uexecs = parser.executions_from_string("\n".join(unmatched), program) Logger.log(" -> Found %s matched models" % (len(matched)), 0) Logger.log(" -> Found %s unmatched models" % (len(unmatched)), 0) if len(unmatched) == 0: Logger.error("No unmatched models") Logger.stop_timer(timer) return None rels = [x for x in RELATIONS if x != AO] matched = self.al_encoder.print_assert_exl_execs(mexecs, rels) if use_alloy else \ self.c4_encoder.print_assert_exl_execs(mexecs, rels) unmatched = self.al_encoder.print_assert_exl_execs(uexecs, rels) if use_alloy else \ self.c4_encoder.print_assert_exl_execs(uexecs, rels) objs = [] Logger.log("\nMatched models analysis", 0) Logger.msg("Solving... ", 0) if use_alloy: vmodel = "\n".join([ model, matched, self.al_encoder.print_run_condition(program, True) ]) objs = self.al_solver.compute_models(vmodel, self.al_consamanager, objs) mmodels = " | ".join([x[1] for x in objs]) else: vmodel = "%s\n%s" % (model, matched) objs = self.c4_solver.compute_models(vmodel, self.c4_consamanager, objs) mmodels = " | ".join(objs) Logger.log(" DONE", 0) mmodels = self.bsolver.simplify(mmodels, True) self.__print_models(mmodels) objs = [] Logger.log("Unmatched models analysis", 0) Logger.msg("Solving... ", 0) if use_alloy: vmodel = "\n".join([ model, unmatched, self.al_encoder.print_run_condition(program, True) ]) objs = self.al_solver.compute_models(vmodel, self.al_consamanager, objs) nmodels = " | ".join([x[1] for x in objs]) else: vmodel = "%s\n%s" % (model, unmatched) objs = self.c4_solver.compute_models(vmodel, self.c4_consamanager, objs) nmodels = " | ".join(objs) Logger.log(" DONE", 0) nmodels = self.bsolver.simplify(nmodels, True) self.__print_models(nmodels) Logger.log("Difference analysis (exist support(matched) in unmatched)", 0) diffmodels = self.bsolver.support_exist(" | ".join(mmodels), " | ".join(nmodels), True) self.__print_models(diffmodels) self.user_defined_analyses(mmodels, nmodels) Logger.stop_timer(timer) return (mmodels, nmodels, diffmodels)
def main(args): parser = argparse.ArgumentParser( description='EMME: ECMAScript Memory Model Evaluator', formatter_class=RawTextHelpFormatter) parser.add_argument('input_file', metavar='program', type=str, help='the input file describing the program') jsprinters = [ " - \"%s\": %s" % (x.get_name(), x.get_desc()) for x in PrintersFactory.get_printers_by_type(PrinterType.PROGRAMS) ] config = Config() # Files generation parser.set_defaults(jsprinter=config.jsprinter) parser.add_argument( '-p', '--jsprinter', metavar='jsprinter', type=str, nargs='?', help='select the JS printer between (Default is \"%s\"):\n%s' % (config.jsprinter, "\n".join(jsprinters))) parser.set_defaults(jsdir=None) parser.add_argument( '-d', '--jsdir', metavar='jsdir', type=str, nargs='?', help= 'directory where to store all JS programs. (Default is the same as the input file)' ) parser.set_defaults(graphviz=False) parser.add_argument( '-g', '--graphviz', dest='graphviz', action='store_true', help= "generates the png files of each execution (requires neato). (Default is \"%s\")" % False) parser.set_defaults(relations=config.printing_relations) parser.add_argument( '-r', '--relations', metavar='relations', type=str, nargs='?', help= 'a (comma separated) list of relations to consider in the graphviz file.\nKeyword \"%s\" means all.' % ALL) parser.set_defaults(prefix=None) parser.add_argument( '-x', '--prefix', metavar='prefix', type=str, nargs='?', help= 'directory where to store the results. (Default is the same as the input file)' ) # Possible analyses parser.set_defaults(synth=False) parser.add_argument( '--synth', dest='synth', action='store_true', help="enables equivalent programs synthesis. (Default is \"%s\")" % False) parser.set_defaults(unmatched=False) parser.add_argument( '--unmatched', dest='unmatched', action='store_true', help="enables unmatched outputs analysis. (Default is \"%s\")" % False) parser.set_defaults(jsengine=None) parser.add_argument( '--jsengine', metavar='jsengine', type=str, nargs='?', help= 'the command used to call the JavaScript engine, to use with \"--unmatched\".' ) parser.set_defaults(runs=10) parser.add_argument( '-n', '--runs', metavar='runs', type=str, help= 'number of runs for the unmatched outputs analysis, to use with \"--unmatched\".\n(Default is \"10\")' ) # Solvers selection parser.set_defaults(use_cvc4=False) parser.add_argument( '-c', '--use-cvc4', dest='use_cvc4', action='store_true', help="relies on CVC4 instead of Alloy Analyzer. (Default is \"%s\")" % False) parser.set_defaults(best=False) parser.add_argument( '-b', '--best', dest='best', action='store_true', help= "relies on CVC4 or Alloy Analyzer for best performance. (Default is \"%s\")" % False) # Simple configurations parser.set_defaults(verbosity=1) parser.add_argument('-v', dest='verbosity', metavar="verbosity", type=int, help="verbosity level. (Default is \"%s\")" % 1) parser.set_defaults(nexecs=-1) parser.add_argument( '-e', '--max-executions', dest='nexecs', metavar='nexecs', type=int, help='maximum number of executions. (Default is \"unlimited\")') parser.set_defaults(force_solving=False) parser.add_argument( '-f', '--force-solving', dest='force_solving', action='store_true', help= "forces the solving part by discharging the previous models. (Default is \"%s\")" % False) parser.set_defaults(skip_solving=False) parser.add_argument('-k', '--skip-solving', dest='skip_solving', action='store_true', help="skips the solving part. (Default is \"%s\")" % False) parser.set_defaults(silent=False) parser.add_argument('-l', '--silent', dest='silent', action='store_true', help="silent mode. (Default is \"%s\")" % False) parser.set_defaults(check_sat=False) parser.add_argument( '-s', '--only-sat', dest='check_sat', action='store_true', help="performs only the satisfiability checking. (Default is \"%s\")" % False) parser.set_defaults(only_model=False) parser.add_argument( '-m', '--only-model', dest='only_model', action='store_true', help="exits right after the model generation. (Default is \"%s\")" % False) # Advanced configurations parser.set_defaults(threads=1) parser.add_argument( '-j', '--threads', metavar='number', type=int, help='number of threads - EXPERIMENTAL. (Default is \"1\")') parser.set_defaults(debug=False) parser.add_argument('--debug', dest='debug', action='store_true', help="enables debugging setup. (Default is \"%s\")" % False) parser.set_defaults(time=False) parser.add_argument( '-t', '--time', dest='time', action='store_true', help="enables time debugging setup. (Default is \"%s\")" % False) parser.set_defaults(no_expand_bounded_sets=False) parser.add_argument( '--no-exbounded', dest='no_expand_bounded_sets', action='store_true', help= "disables the bounded sets quantifier expansion. (Default is \"%s\")" % False) parser.set_defaults(defines=None) parser.add_argument( '--defines', metavar='defines', type=str, nargs='?', help='the set of preprocessor\'s defines. (Default is none)') parser.set_defaults(preproc=CPP) parser.add_argument( '--preproc', metavar='preproc', type=str, nargs='?', help='the memory model preprocessor. (Default is \"%s\")' % CPP) if len(sys.argv) == 1: parser.print_help() sys.exit(1) args = parser.parse_args(args) prefix = args.prefix if not prefix: prefix = args.input_file.split("/") prefix[-1] = prefix[-1].split(".")[0] prefix = "/".join(prefix) prefix += "/" if not os.path.exists(args.input_file): print("File not found: \"%s\"" % args.input_file) return 1 config.inputfile = args.input_file config.prefix = prefix config.preproc = args.preproc config.expand_bounded_sets = not args.no_expand_bounded_sets config.verbosity = args.verbosity config.defines = args.defines config.sat = args.check_sat config.only_model = args.only_model config.skip_solving = args.skip_solving config.printing_relations = args.relations config.graphviz = args.graphviz config.jsdir = args.jsdir config.debug = args.debug config.force_solving = args.force_solving config.threads = args.threads config.jsengine = args.jsengine config.runs = args.runs config.nexecs = args.nexecs config.use_alloy = not args.use_cvc4 config.unmatched = args.unmatched config.time = args.time if args.jsprinter in [ str(x.get_name()) for x in PrintersFactory.get_printers_by_type(PrinterType.PROGRAMS) ]: config.jsprinter = args.jsprinter else: Logger.error("Printer \"%s\" not found" % (args.jsprinter)) if config.unmatched and not config.jsengine: Logger.error("JavaScript engine not specified") return 1 if not config.use_alloy: try: import CVC4 except Exception: Logger.error("Error importing CVC4 module") return 1 if args.synth and args.best: config.hybrid = True if not args.synth and not args.unmatched and args.best: config.use_alloy = True if args.silent: config.verbosity = 0 if args.relations == ALL: config.printing_relations = None Logger.verbosity = config.verbosity Logger.log("** Processing file \"%s\" **" % (config.inputfile), -1) try: Logger.time = config.time ret = -1 ret = analyze_program(config) if ret == 0 and args.synth: ret = synth_program(config) if ret == 0 and args.unmatched: ret = unmatched_analysis(config) #cleanup if not config.debug: del_file(config.block_type) del_file(config.bound_int) del_file(config.alloy_model) del_file(config.cvc_model) del_file(config.cvc_model_ex) del_file(config.id_type) del_file(config.instance) Logger.log("\nExiting...", 0) return ret except Exception as e: if config.debug: raise print("\nERROR! Run with --debug option for more information") return 1