Exemplo n.º 1
0
    def __compute_models(self,
                         model,
                         solver,
                         num,
                         blocking_manager,
                         constraints=None,
                         shared_objects=None):
        if constraints:
            model += "\n" + constraints

        assertions = blocking_manager.compute_from_sharedobjs(shared_objects)
        model += "\n" + assertions

        num_sols = 0
        while True:
            if (num != -1) and (num_sols >= num):
                break
            ret = self.solve_one(model, solver)
            self.__clean_files()
            if ret is None:
                return (shared_objects, 0)
            num_sols += 1
            (bclauses, shared_obj) = blocking_manager.compute_from_smt(ret)
            Logger.msg(".", 0, True, 0)

            if shared_obj not in shared_objects:
                shared_objects.append(shared_obj)
            else:
                if constraints is not None:
                    return (shared_objects, 2)

            model += bclauses

        return (shared_objects, 1)
Exemplo n.º 2
0
    def solutions_separators(self):
        if not self.program:
            return []

        ao_set = [(x.name, y.name) for x in self.program.get_events()
                  for y in self.program.get_events() if x != y]
        ao_cons = [
            self.encoder.assert_formula("(AO [%s, %s])" % (x)) for x in ao_set
        ]

        Logger.msg("(%s)" % len(ao_cons), 0)

        if self.shuffle_constraints:
            random.shuffle(ao_cons)

        return ao_cons
Exemplo n.º 3
0
def unmatched_analysis(config):
    analyzer = ConstraintsAnalyzer()
    analyzer.set_models_file(config.models)
    analyzer.set_outputs_file(config.outputs)

    Logger.log("\n** Unmatched Outputs Analysis **", 0)

    config.unmatched = True

    if not config.defines:
        config.defines = ""
    config.defines += CONS_LABELLING

    program = parse_program(config)

    Logger.msg("Generating model... ", 0)

    if config.use_alloy:
        strmodel = generate_alloy_model(config, program)
    else:
        strmodel = generate_cvc_model(config, program)

    Logger.log("DONE", 0)

    if config.only_model:
        return 0

    if (config.force_solving):
        del_file(config.outputs)

    if config.use_alloy:
        analyzer.analyze_constraints_alloy(program, \
                                           strmodel, \
                                           config.jsengine, \
                                           config.runs, \
                                           config.threads, \
                                           config.outprogram+".js")
    else:
        analyzer.analyze_constraints_cvc4(program, \
                                          strmodel, \
                                          config.jsengine, \
                                          config.runs, \
                                          config.threads, \
                                          config.outprogram+".js")
    return 0
Exemplo n.º 4
0
    def solve_allsmt(self, model, blocking_manager, num_sols=-1, num_t=1):
        num_t = 1
        self.__init_solvers(num_t)
        pre_objs = blocking_manager.load_models()
        Logger.msg("." * len(pre_objs), 0, True, 0)
        ret = None
        if num_t > 1:
            rb_cons = blocking_manager.solutions_separators()
            num_t = min(len(rb_cons), num_t)
            if num_t < 3:
                # Multithread is not necessary
                ret = self.__solve_nsat(model, num_sols, blocking_manager,
                                        pre_objs)
            else:
                with Manager() as manager:
                    shared_objs = manager.list([])
                    for el in pre_objs:
                        shared_objs.append(el)
                    rb_cons = manager.list(rb_cons)

                    threads = []
                    for i in range(num_t - 1):
                        process = Process(target=self.__solve_nsat,
                                          args=(model, -1, blocking_manager,
                                                shared_objs, i, num_t - 1,
                                                rb_cons))
                        threads.append(process)
                        process.start()

                    shared_objs = self.__solve_nsat(model, num_sols,
                                                    blocking_manager,
                                                    shared_objs, 0)

                    for thread in threads:
                        thread.terminate()

                    ret = list(shared_objs)
        else:
            ret = self.__solve_nsat(model, num_sols, blocking_manager,
                                    pre_objs)

        self.__quit_solvers()
        return ret
Exemplo n.º 5
0
    def find_all_intersect(self, model, program, threads):
        self.c4vexecsmanager.program = program
        executions = Executions()
        executions.executions = self.c4vexecsmanager.load_models()
        self.c4vexecsmanager.preload = False

        vmodel = model + "\n" + self.c4_encoder.print_general_AO(program)
        qupre = QuantPreprocessor()
        qupre.set_expand_sets(True)
        vmodel = qupre.preprocess_from_string(vmodel)
        self.c4vexecsmanager.blocking_relations = [AO]
        ao_execs = []
        for models_blocking in [[RBF]]:
            assertions = self.c4_encoder.print_assert_exl_execs(
                executions, models_blocking)
            vmodel += "\n%s\n" % assertions
            execs = self.c4_solver.solve_allsmt(
                vmodel, self.c4vexecsmanager, -1,
                threads if ao_execs == [] else 1)
            ao_execs += [x for x in execs if x not in ao_execs]
            self.c4vexecsmanager.prevmodels = ao_execs
            Logger.msg(" ", 0)
        self.c4vexecsmanager.prevmodels = None

        Logger.log(" -> Found %s possible candidates" % (len(ao_execs)), 1)
        Logger.msg("Checking correctness... ", 1)

        if Logger.level(1):
            Logger.msg("\n", -1)
            for el in ao_execs:
                Logger.log("INTERSECTING: %s" % el.get_AO(), 1)

        return (ao_execs, executions)
Exemplo n.º 6
0
    def find_all_intersect(self, model, program, threads):
        run_condition = self.alloy_encoder.print_run_condition(program)
        self.allvexecsmanager.program = program
        executions = Executions()
        executions.executions = self.allvexecsmanager.load_models()
        self.allvexecsmanager.preload = False

        vmodel = "\n".join(
            [model, self.alloy_encoder.print_general_AO(program)])
        self.allvexecsmanager.blocking_relations = [AO]
        ao_execs = []
        for models_blocking in [[RBF]]:
            assertions = self.alloy_encoder.print_assert_exl_execs(
                executions, models_blocking)
            vmodel += "\n%s\n" % assertions
            execs = self.alloy_solver.solve_allsmt(
                vmodel + run_condition, self.allvexecsmanager, -1,
                threads if ao_execs == [] else 1)
            ao_execs += [x for x in execs if x not in ao_execs]
            self.allvexecsmanager.prevmodels = ao_execs
            Logger.msg(" ", 0)
        self.allvexecsmanager.prevmodels = None

        Logger.log(" -> Found %s possible candidates" % (len(ao_execs)), 1)
        Logger.msg("Checking correctness... ", 1)

        if Logger.level(1):
            Logger.msg("\n", -1)
            for el in ao_execs:
                Logger.log("INTERSECTING: %s" % el.get_AO(), 1)

        return (ao_execs, executions)
Exemplo n.º 7
0
    def solutions_separators(self):
        if not self.program:
            return []

        rf = True

        cr = self.encoder.get_compatible_reads(self.program)
        rb_cons = [
            self.encoder.assert_formula("(RBF %s)" % (x)) for x in cr[1]
        ]

        if rf:
            rb_cons += [
                self.encoder.assert_formula("(RF %s)" % (x)) for x in cr[0]
            ]

        Logger.msg("(%s)" % len(rb_cons), 0)

        if self.shuffle_constraints:
            random.shuffle(rb_cons)

        return rb_cons
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
def analyze_program(config):
    config.generate_filenames()

    Logger.log("\n** Program Analysis **", 0)

    Logger.msg("Generating bounded execution... ", 0)
    program = parse_program(config)
    Logger.log("DONE", 0)

    Logger.msg("Generating model... ", 0)
    if config.use_alloy:
        strmodel = generate_alloy_model(config, program)
    else:
        strmodel = generate_cvc_model(config, program)
    Logger.log("DONE", 0)

    if config.only_model:
        return 0

    if (not config.skip_solving):
        Logger.msg("Solving... ", 0)

    totmodels = solve(config, program, strmodel)

    if (not config.skip_solving):
        Logger.log(" DONE", 0)

    if totmodels > 0:
        Logger.log(
            " -> Found %s possible model%s" %
            (totmodels, "" if totmodels == 1 else "s"), 0)
    else:
        Logger.log(" -> No viable executions found", 0)

    # Generation of the JS litmus test #
    pprinter = PrintersFactory.printer_by_name(config.jsprinter)
    dprinter = PrintersFactory.printer_by_name(DotPrinter().get_name())
    dprinter.set_printing_relations(config.printing_relations)

    prefix = config.prefix
    params = program.get_params()
    models = config.models
    for idparam in range(program.param_size()):

        if program.params:
            config.prefix = "%sparam%03d/" % (prefix, idparam + 1)
            config.generate_filenames()
            program.apply_param(dict(params[idparam]))

            if config.verbosity > 0:
                conf = params[idparam]
                pconf = ["%s=\"%s\"" % (x[0], x[1]) for x in conf]
                Logger.log(
                    "\nParameter configuration (%03d): %s" %
                    (idparam + 1, (", ".join(pconf))), 0)

        executions = None
        if (totmodels > 0):
            Logger.msg("Computing expected outputs... ", 0)

            parser = BeParser()
            parser.DEBUG = config.debug

            with open(models, "r") as modelfile:
                executions = parser.executions_from_string(
                    modelfile.read(), program)

            Logger.log("DONE", 0)

        Logger.msg("Generating program... ", 0)

        outfiles = [config.outprogram]
        if config.jsdir:
            filename = config.outprogram.replace("../",
                                                 "").replace("/", "-").replace(
                                                     "..", "")
            outprogram = "%s/%s" % (config.jsdir, filename)
            outfiles = [outprogram]

        extension = pprinter.get_extension()

        for outfile in outfiles:
            with open(outfile + extension, "w") as f:
                f.write(pprinter.print_program(program, executions))

        Logger.log("DONE", 0)

        if (totmodels > 0):
            Logger.msg("Generating expected outputs... ", 0)

            # Generation of all possible outputs for the JS litmus test #

            execs = pprinter.compute_possible_executions(program, executions)

            if config.debug:
                if execs is not None:
                    with open(config.execs, "w") as exefile:
                        exefile.write("\n".join(execs))

            # Generation of all possible MM interpretations #
            mms = dprinter.print_executions(program, executions)
            for i in range(len(mms)):
                with open(config.dots % (str(i + 1)), "w") as dot:
                    dot.write(mms[i])
                if config.graphviz:
                    with open(config.grap % (str(i + 1)), "w") as dot:
                        graphviz_gen(config, config.dots % (str(i + 1)),
                                     config.grap % (str(i + 1)))

            Logger.log("DONE", 0)

            Logger.log(
                " -> Found %s possible output%s" %
                (len(execs), "" if len(execs) == 1 else "s"), 0)

    return 0
Exemplo n.º 10
0
def synth_program(config):
    analyzer = EquivalentExecutionSynthetizer()
    analyzer.set_models_file(config.models)

    Logger.log("\n** Equivalent Programs Synthesis **", 0)

    config.synth = True

    if not config.defines:
        config.defines = ""
    config.defines += RELAX_AO

    program = parse_program(config)
    if program.has_conditions():
        Logger.msg("Program synthesis does not support conditional programs",
                   0)
        return 0

    Logger.msg("Generating relaxed SMT model... ", 0)
    if config.use_alloy or config.hybrid:
        strmodel_alloy = generate_alloy_model(config, program)

    if not config.use_alloy or config.hybrid:
        strmodel_cvc4 = generate_cvc_model(config, program)
    Logger.log("DONE", 0)

    if config.only_model:
        return 0

    Logger.msg("Solving... ", 0)

    if config.use_alloy:
        programs = analyzer.solve_all_synth_alloy(strmodel_alloy, program,
                                                  config.threads)
    else:
        if config.hybrid:
            programs = analyzer.solve_all_synth_hybrid(strmodel_cvc4,
                                                       strmodel_alloy, program,
                                                       config.threads)
        else:
            programs = analyzer.solve_all_synth_cvc(strmodel_cvc4, program,
                                                    config.threads)
    totmodels = len(programs)

    Logger.log(" DONE", 0)

    if totmodels > 0:
        Logger.log(
            " -> Found %s equivalent program%s" %
            (totmodels, "" if totmodels == 1 else "s"), 0)
    else:
        Logger.log(" -> No viable equivalent programs found", 0)

    Logger.msg("Generating equivalent programs... ", 0)

    printer = PrintersFactory.printer_by_name(BePrinter.get_name())
    filename = (config.inputfile.split("/")[-1]).split(".")[0]

    for i in range(len(programs)):
        with open(config.eqprogs % (filename, str(i + 1)), "w") as eqprog:
            eqprog.write(printer.print_program(programs[i]))

    Logger.log("DONE", 0)

    Logger.log("", 1)

    Logger.log("** Original Program: **\n", 1)
    Logger.log(printer.print_program(program), 1)

    for program in programs:
        Logger.log(
            "** Equivalent Program %s: **\n" % (programs.index(program) + 1),
            1)
        Logger.log(printer.print_program(program), 1)

    return 0
Exemplo n.º 11
0
    def __solve_nsat(self,
                     model,
                     n,
                     blocking_manager,
                     shared_objs=None,
                     id_thread=None,
                     total=None,
                     constraints=None):
        applying_cons = None

        if shared_objs is None:
            shared_objs = []
        is_multithread = id_thread is not None
        is_master = constraints is None

        if is_multithread:
            if is_master:
                process = self.alloy_processes[0]
            else:
                process = self.alloy_processes[id_thread + 1]
        else:
            process = self.alloy_processes[0]

        if not is_multithread or is_master:
            self.__clean_files()

        if constraints is not None:
            applying_cons = constraints[id_thread]

        if not is_multithread:
            (sol, ret) = self.__compute_models(model, process, n,
                                               blocking_manager, applying_cons,
                                               shared_objs)

            for el in sol:
                if el not in shared_objs:
                    shared_objs.append(el)

            blocking_manager.write_models(shared_objs, ret == 0)
            return sol

        sol = None
        prvsolsize = 0
        solsize = 0
        while (solsize < n) or (n == -1):
            prvsolsize = solsize
            (sol, ret) = self.__compute_models(model, process, 1,
                                               blocking_manager, applying_cons,
                                               shared_objs)

            for el in sol:
                if el not in shared_objs:
                    shared_objs.append(el)
            solsize = len(sol)

            if is_master:
                blocking_manager.write_models(shared_objs, ret == 0)

            if (self.verbosity > 0) and is_multithread and is_master:
                if ((solsize - prvsolsize) > 1):
                    gain = (solsize - prvsolsize) - 1
                    Logger.msg("+%s%s" % (gain, "." * (gain)), 0, True, 0)

            if not is_master:
                if ret == 0:  #UNSAT
                    if id_thread >= len(constraints) - 1:
                        break
                    Logger.msg("d", 0)
                    constraints[id_thread] = constraints[-1]
                    del (constraints[-1])
                    applying_cons = constraints[id_thread]
                    continue

                if ret == 2:  # Not interesting constraint
                    Logger.msg("s", 0)

                    if len(constraints) > total:
                        tmp = constraints[id_thread]
                        constraints[id_thread] = constraints[-1]
                        constraints[-1] = tmp
                        constraints[total:] = constraints[total + 1:] + [
                            constraints[total]
                        ]
                        applying_cons = constraints[id_thread]

            if ret == 0:
                break

        return shared_objs
Exemplo n.º 12
0
    def __compute_models(self,
                         model,
                         num,
                         blocking_manager,
                         constraints=None,
                         shared_objects=None):
        opts = Options()
        opts.setInputLanguage(CVC4.INPUT_LANG_CVC4)

        exit_with_unknown = False

        if shared_objects is None:
            shared_objects = []

        exprmgr = ExprManager(opts)

        smt = SmtEngine(exprmgr)
        smt.setOption("produce-models", SExpr(True))
        smt.setOption("fmf-bound", SExpr(True))
        smt.setOption("macros-quant", SExpr(True))
        smt.setOption("finite-model-find", SExpr(True))
        #        smt.setOption("repeat-simp", SExpr(True))
        #        smt.setOption("check-models", SExpr(True))
        #        smt.setOption("full-saturate-quant", SExpr(True))
        smt.setOption("incremental", SExpr(True))

        ind = 0

        assertions = blocking_manager.compute_from_sharedobjs(shared_objects)
        model = model + assertions

        if constraints:
            model += "\n%s;" % (constraints)

        parserbuilder = ParserBuilder(exprmgr, "", opts)
        parserbuilder.withStringInput(model)
        parser = parserbuilder.build()

        symboltable = parser.getSymbolTable()

        blocking_manager.exprmgr = exprmgr
        blocking_manager.symboltable = symboltable

        while True:
            cmd = parser.nextCommand()
            if not cmd: break
            cmd.invoke(smt)

        while True:
            checksat = CheckSatCommand()
            checksat.invoke(smt)

            sat = checksat.getResult().isSat() == 1
            unk = checksat.getResult().isUnknown()
            uns = (not sat) and (not unk)

            Logger.log("sat: %s, uns: %s, unk: %s" % (sat, uns, unk), 2)

            exitcond = (not sat) if exit_with_unknown else uns

            if exitcond:
                return (shared_objects, 0)

            (bclauses, shared_obj) = blocking_manager.compute_from_smt(smt)

            Logger.log("%s" % str(shared_obj), 2)

            if shared_obj not in shared_objects:
                shared_objects.append(shared_obj)
            else:
                if constraints is not None:
                    return (shared_objects, 2)

            for bclause in bclauses:
                assertion = AssertCommand(bclause)
                assertion.invoke(smt)

            Logger.msg(".", 0, constraints is None, 0)

            ind += 1
            if (num != -1) and (ind >= num):
                return (shared_objects, 1)

        return (None, -1)