Ejemplo n.º 1
0
    def Mux(in0, in1, sel, out):
        # if Modules.functional
        # INVAR: out' = Ite(sel = 0, in0, in1)
        # else
        # INVAR: ((sel = 0) -> (out = in0)) & ((sel = 1) -> (out = in1))
        vars_ = [in0, in1, sel, out]
        comment = "Mux (in0, in1, sel, out) = (%s, %s, %s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        if sel.symbol_type() == BOOL:
            sel0 = Not(sel)
            sel1 = sel
        else:
            sel0 = EqualsOrIff(sel, BV(0, 1))
            sel1 = EqualsOrIff(sel, BV(1, 1))

        if Modules.functional:
            invar = And(EqualsOrIff(out, Ite(sel0, in0, in1)))
        else:
            invar = And(Implies(sel0, EqualsOrIff(in0, out)),
                        Implies(sel1, EqualsOrIff(in1, out)))

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Ejemplo n.º 2
0
    def _get_param_assignments(self, model, time, parameters, monotonic=True):
        p_ass = []

        fwd = False

        for p in parameters:
            # search the trace for any enabled faults
            ever_true = False
            for t in range(time + 1):
                p_time = model[TS.get_ptimed(p, 0)]
                if p.symbol_type() == BOOL:
                    if p_time == TRUE():
                        ever_true = True
                        break

            if ever_true:
                p_ass.append(p)
            elif not monotonic:
                p_ass.append(EqualsOrIff(p, FALSE()))

        p_ass = And(p_ass)
        self.region = simplify(Or(self.region, p_ass))

        if self.models is None:
            self.models = []
        self.models.append((model, time))

        Logger.msg("+", 0, not (Logger.level(1)))
        self.cs_count += 1
        Logger.log(
            "Found assignment \"%s\"" % (p_ass.serialize(threshold=100)), 1)

        return (p_ass, False)
Ejemplo n.º 3
0
    def Uop(bvop, bop, in_, out):
        # INVAR: (<op> in) = out)
        vars_ = [in_, out]
        comment = ""  #(bvop.__name__ + " (in, out) = (%s, %s)")%(tuple([x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        in_B = get_type(in_).is_bool_type()
        outB = get_type(out).is_bool_type()

        bools = (1 if in_B else 0) + (1 if outB else 0)

        if bop == None:
            if in_B:
                in_ = B2BV(in_)
            if outB:
                out = B2BV(out)
            invar = EqualsOrIff(bvop(in_), out)
        else:
            if bools == 2:
                invar = EqualsOrIff(bop(in_), out)
            elif bools == 0:
                invar = EqualsOrIff(bvop(in_), out)
            else:
                if not in_B:
                    invar = EqualsOrIff(bop(BV2B(in_)), out)
                if not outB:
                    invar = EqualsOrIff(bop(in_), BV2B(out))

        ts = TS(comment)
        ts.vars, ts.invar = get_free_variables(invar), invar
        return ts
Ejemplo n.º 4
0
    def Neq(in0, in1, out):
        # INVAR: (((in0 != in1) -> (out = #b1)) & ((in0 == in1) -> (out = #b0)))
        vars_ = [in0, in1, out]
        comment = "Eq (in0, in1, out) = (%s, %s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        # TODO: Create functional encoding
        if Modules.functional:
            if out.symbol_type() == BOOL:
                invar = EqualsOrIff(out, Not(EqualsOrIff(in0, in1)))
            else:
                invar = EqualsOrIff(out, BVNot(BVComp(in0, in1)))
        else:
            eq = EqualsOrIff(in0, in1)

            if out.symbol_type() == BOOL:
                out0 = Not(out)
                out1 = out
            else:
                out0 = EqualsOrIff(out, BV(0, 1))
                out1 = EqualsOrIff(out, BV(1, 1))

            invar = And(Implies(Not(eq), out1), Implies(eq, out0))

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Ejemplo n.º 5
0
    def Zext(in_, out):
        # INVAR: (<op> in) = out)
        vars_ = [in_, out]
        comment = ("ZExt (in, out) = (%s, %s)") % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        if (in_.symbol_type() == BOOL) and (out.symbol_type() == BOOL):
            invar = EqualsOrIff(in_, out)

        if (in_.symbol_type() != BOOL) and (out.symbol_type() == BOOL):
            invar = EqualsOrIff(BV2B(in_), out)

        if (in_.symbol_type() == BOOL) and (out.symbol_type() != BOOL):
            length = (out.symbol_type().width) - 1
            if length == 0:
                invar = EqualsOrIff(in_, BV2B(out))
            else:
                invar = EqualsOrIff(BVZExt(B2BV(in_), length), out)

        if (in_.symbol_type() != BOOL) and (out.symbol_type() != BOOL):
            length = (out.symbol_type().width) - (in_.symbol_type().width)
            if length == 0:
                invar = EqualsOrIff(in_, out)
            else:
                invar = EqualsOrIff(BVZExt(in_, length), out)

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Ejemplo n.º 6
0
    def simulate(self, prop, k):
        if self.config.strategy == VerificationStrategy.NU:
            self._init_at_time(self.hts.vars, 1)
            (t, model) = self.sim_no_unroll(self.hts, prop, k)
        else:
            self._init_at_time(self.hts.vars, k)
            if prop == TRUE():
                self.config.incremental = False
                (t, model) = self.solve_safety_fwd(self.hts, Not(prop), k,
                                                   False)
            else:
                (t, model) = self.solve_safety(self.hts, Not(prop), k)

        model = self._remap_model(self.hts.vars, model, t)
        if (t > -1) and (model is not None):
            Logger.log("Execution found", 1)
            trace = self.print_trace(self.hts,
                                     model,
                                     t,
                                     get_free_variables(prop),
                                     map_function=self.config.map_function)
            return (VerificationStatus.TRUE, trace)
        else:
            Logger.log("Deadlock wit k=%s" % k, 1)
            return (VerificationStatus.FALSE, None)
Ejemplo n.º 7
0
        def check_init():
            self._reset_assertions(self.solver)
            self._add_assertion(self.solver,
                                self.at_time(And(init, Not(lemma)), 0),
                                comment="Init check")
            res = self._solve(self.solver)

            prefix = None
            if self.config.prefix is not None:
                prefix = self.config.prefix + "-ind"

            if res:
                if Logger.level(2):
                    Logger.log("Lemma \"%s\" failed for I -> L" % lemma, 2)
                    (hr_trace, vcd_trace) = self.print_trace(
                        hts,
                        self._get_model(self.solver),
                        0,
                        prefix=prefix,
                        map_function=self.config.map_function)
                    Logger.log("", 2)
                    if hr_trace:
                        Logger.log("Counterexample: \n%s" % (hr_trace), 2)
                    else:
                        Logger.log("", 2)
                return False
            else:
                Logger.log("Lemma \"%s\" holds for I -> L" % lemma, 2)

            return True
Ejemplo n.º 8
0
    def solve_safety_inc_zz(self, hts, prop, k):
        self._reset_assertions(self.solver)

        if TS.has_next(prop):
            Logger.error(
                "Invariant checking with next variables only supports FWD strategy"
            )

        init = hts.single_init()
        trans = hts.single_trans()
        invar = hts.single_invar()

        initt = self.at_time(And(init, invar), 0)
        Logger.log("Add init at_0", 2)
        self._add_assertion(self.solver, initt)

        propt = self.at_ptime(And(Not(prop), invar), -1)
        Logger.log("Add property pat_%d" % 0, 2)
        self._add_assertion(self.solver, propt)

        t = 0
        while (t < k + 1):
            self._push(self.solver)
            even = (t % 2) == 0
            th = int(t / 2)

            if even:
                eq = And([
                    EqualsOrIff(self.at_time(v, th), self.at_ptime(v, th - 1))
                    for v in hts.vars
                ])
            else:
                eq = And([
                    EqualsOrIff(self.at_time(v, th + 1),
                                self.at_ptime(v, th - 1)) for v in hts.vars
                ])

            Logger.log("Add equivalence time %d" % t, 2)
            self._add_assertion(self.solver, eq)

            if self._solve(self.solver):
                Logger.log("Counterexample found with k=%s" % (t), 1)
                model = self._get_model(self.solver)
                return (t, model)
            else:
                Logger.log("No counterexample found with k=%s" % (t), 1)
                Logger.msg(".", 0, not (Logger.level(1)))

            self._pop(self.solver)

            if even:
                trans_t = self.unroll(trans, invar, th + 1, th)
            else:
                trans_t = self.unroll(trans, invar, th, th + 1)

            self._add_assertion(self.solver, trans_t)

            t += 1

        return (t - 1, None)
Ejemplo n.º 9
0
    def Orr(in_, out):
        # INVAR: (in = 0) -> (out = 0) & (in != 0) -> (out = 1)
        vars_ = [in_, out]
        comment = "Orr (in, out) = (%s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        if (in_.symbol_type() == BOOL) and (out.symbol_type() == BOOL):
            invar = EqualsOrIff(in_, out)
        else:

            if out.symbol_type() == BOOL:
                out0 = Not(out)
                out1 = out
            else:
                out0 = EqualsOrIff(out, BV(0, 1))
                out1 = EqualsOrIff(out, BV(1, 1))

            true_res = Implies(
                EqualsOrIff(in_, BV(0,
                                    in_.symbol_type().width)), out0)
            false_res = Implies(
                Not(EqualsOrIff(in_, BV(0,
                                        in_.symbol_type().width))), out1)

            invar = And(true_res, false_res)

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Ejemplo n.º 10
0
    def _get_param_assignments(self, model, time, parameters, monotonic=True):
        p_ass = []

        fwd = False

        for p in parameters:
            p_time = model[TS.get_ptimed(p, 0)]
            if p.symbol_type() == BOOL:
                if monotonic:
                    if p_time == TRUE():
                        p_ass.append(p)
                else:
                    p_ass.append(p if p_time == TRUE() else Not(p))
            else:
                p_ass.append(EqualsOrIff(p, p_time))

        p_ass = And(p_ass)
        self.region = simplify(Or(self.region, p_ass))

        if self.models is None:
            self.models = []
        self.models.append((model, time))

        Logger.msg("+", 0, not (Logger.level(1)))
        self.cs_count += 1
        Logger.log(
            "Found assignment \"%s\"" % (p_ass.serialize(threshold=100)), 1)

        return (p_ass, False)
Ejemplo n.º 11
0
    def _pop(self, solver):
        Logger.log("Pop solver \"%s\"" % solver.name, 2)
        if not self.config.skip_solving:
            solver.solver.pop()

        solver.smt2vars = solver.smt2vars_inc.pop()
        self._write_smt2_log(solver, "(pop 1)")
Ejemplo n.º 12
0
    def _push(self, solver):
        Logger.log("Push solver \"%s\"" % solver.name, 2)
        if not self.config.skip_solving:
            solver.solver.push()

        solver.smt2vars_inc.append(solver.smt2vars)
        self._write_smt2_log(solver, "(push 1)")
Ejemplo n.º 13
0
def translate(hts, config, formulae=None):
    Logger.log("\nWriting system to \"%s\"" % (config.translate), 0)
    printer = HTSPrintersFactory.printer_by_name(config.printer)
    props = []
    if formulae is not None:
        props = [(f.serialize(threshold=100), f, None) for f in formulae
                 if f is not None]
    with open(config.translate, "w") as f:
        f.write(printer.print_hts(hts, props))
Ejemplo n.º 14
0
 def Wrap(in_, out):
     # INVAR: (in = out)
     vars_ = [in_,out]
     comment = ("Wrap (in, out) = (%s, %s)")%(tuple([x.symbol_name() for x in vars_]))
     Logger.log(comment, 3)
     invar = EqualsOrIff(in_, out)
     ts = TS(comment)
     ts.vars, ts.invar = set(vars_), invar
     return ts
Ejemplo n.º 15
0
    def run_passes(self):
        Logger.log("Running CoreIR passes...", 1)
        print_level = 3
        if not Logger.level(print_level):
            saved_stdout = suppress_output()

        self.context.run_passes(PASSES)

        if not Logger.level(print_level):
            restore_output(saved_stdout)
Ejemplo n.º 16
0
        def check_overappr(Ri, R):
            self._reset_assertions(solver_proof)
            self._add_assertion(solver_proof, And(Ri, Not(R)))

            if not self._solve(solver_proof):
                Logger.log("Proof found with k=%s"%(t), 1)
                return TRUE()

            Logger.log("Extending initial states (%s)"%int_c, 1)
            return Or(R, Ri)
Ejemplo n.º 17
0
 def Slice(in_, out, low, high):
     # INVAR: (extract low high in) = out
     high -= 1
     vars_ = [in_,out, low, high]
     comment = "Mux (in, out, low, high) = (%s, %s, %s, %s)"%(tuple([str(x) for x in vars_]))
     Logger.log(comment, 3)
     invar = EqualsOrIff(BVExtract(in_, low, high), out)
     ts = TS(comment)
     ts.vars, ts.invar = set([in_, out]), invar
     return ts
Ejemplo n.º 18
0
def run_problems(problems_config: ProblemsManager):

    if sys.version_info[0] < 3:
        if config.devel:
            Logger.warning(
                "This software is not tested for Python 2, we recommend to use Python 3 instead"
            )
        else:
            Logger.error(
                "This software is not tested for Python 2, please use Python 3 instead. To avoid this error run in developer mode"
            )

    reset_env()

    # Named tuple representing all the general configuration options
    # (things that don't change between problems)
    general_config = problems_config.general_config
    Logger.verbosity = general_config.verbosity
    Logger.time = general_config.time

    psol = ProblemSolver()
    psol.solve_problems(problems_config)

    global_status = 0
    traces = []

    if len(problems_config.problems) > 0:
        Logger.log("\n*** SUMMARY ***", 0)
    else:
        if not general_config.translate:
            Logger.log("No problems to solve", 0)
            return 0

    formulae = []
    for pbm in problems_config.problems:
        (status, trace) = print_problem_result(pbm, problems_config)

        if status != 0:
            global_status = status
        traces += trace
        formulae.append(pbm.properties)

    if len(traces) > 0:
        Logger.log("\n*** TRACES ***\n", 0)
        for trace in traces:
            Logger.log("[%d]:\t%s" % (traces.index(trace) + 1, trace), 0)

    if general_config.translate:
        translate(problems_config.hts, general_config, formulae)

    if global_status != 0:
        Logger.log("", 0)
        Logger.warning("Verifications with unexpected result")

    return global_status
Ejemplo n.º 19
0
        def check_step():
            self._reset_assertions(self.solver)
            self._add_assertion(self.solver, self.at_time(And(trans, lemma), 0))
            self._add_assertion(self.solver, self.at_time(Not(lemma), 1))

            if self._solve(self.solver):
                Logger.log("Lemma \"%s\" failed for L & T -> L'"%lemma, 2)
                return False

            Logger.log("Lemma \"%s\" holds for L & T -> L'"%lemma, 2)
            return True
Ejemplo n.º 20
0
        def check_init():
            self._reset_assertions(self.solver)
            self._add_assertion(self.solver, self.at_time(And(init, Not(lemma)), 0), comment="Init check")
            res = self._solve(self.solver)

            if res:
                Logger.log("Lemma \"%s\" failed for I -> L"%lemma, 2)
                return False

            Logger.log("Lemma \"%s\" holds for I -> L"%lemma, 2)
            return True
Ejemplo n.º 21
0
    def solve(self, hts, prop, k, lemmas=None):
        if lemmas is not None:
            (hts, res) = self.add_lemmas(hts, prop, lemmas)
            if res:
                Logger.log("Lemmas imply the property", 1)
                Logger.log("", 0, not (Logger.level(1)))
                return (0, True)

        hts.reset_formulae()

        return self.solve_inc(hts, prop, k)
Ejemplo n.º 22
0
def run_problems(problems_file, config, problems=None):

    if sys.version_info[0] < 3:
        if config.devel:
            Logger.warning(
                "This software is not tested for Python 2, we recommend to use Python 3 instead"
            )
        else:
            Logger.error(
                "This software is not tested for Python 2, please use Python 3 instead. To avoid this error run in developer mode"
            )

    reset_env()
    Logger.verbosity = config.verbosity
    Logger.time = config.time

    psol = ProblemSolver()
    if problems is None:
        problems = Problems()
        problems.load_problems(problems_file)

    psol.solve_problems(problems, config)

    global_status = 0
    traces = []

    if len(problems.problems) > 0:
        Logger.log("\n*** SUMMARY ***", 0)
    else:
        if not config.translate:
            Logger.log("No problems to solve", 0)
            return 0

    formulae = []
    for pbm in problems.problems:
        (status, trace) = print_problem_result(pbm, config, len(traces) + 1)
        if status != 0:
            global_status = status
        traces += trace
        formulae.append(pbm.formula)

    if len(traces) > 0:
        Logger.log("\n*** TRACES ***\n", 0)
        for trace in traces:
            Logger.log("[%d]:\t%s" % (traces.index(trace) + 1, trace), 0)

    if config.translate:
        translate(problems.get_hts(), config, formulae)

    if global_status != 0:
        Logger.log("", 0)
        Logger.warning("Verifications with unexpected result")

    return global_status
Ejemplo n.º 23
0
 def Andr(in_, out):
     # INVAR: (in = 2**width - 1) -> (out = 1) & (in != 2**width - 1) -> (out = 0)
     vars_ = [in_, out]
     comment = "Andr (in, out) = (%s, %s)"%(tuple([x.symbol_name() for x in vars_]))
     Logger.log(comment, 3)
     width = in_.symbol_type().width
     eq_all_ones = EqualsOrIff(in_, BV(2**width - 1,width))
     true_res = Implies(eq_all_ones, EqualsOrIff(out, BV(1,1)))
     false_res = Implies(Not(eq_all_ones), EqualsOrIff(out, BV(0,1)))
     invar = And(true_res, false_res)
     ts = TS(comment)
     ts.vars, ts.invar = set(vars_), invar
     return ts
Ejemplo n.º 24
0
    def parse_file(self, strfile, config, flags=None):
        if flags is None:
            Logger.error("Top module not provided")

        topmodule = flags[0]
        absstrfile = os.path.abspath(strfile)
        directory = "/".join(absstrfile.split("/")[:-1])
        filename = absstrfile.split("/")[-1]

        if self.single_file:
            files = [absstrfile]
        else:
            if self.files_from_dir:
                files = [
                    "%s/%s" % (directory, f) for f in os.listdir(directory)
                    if self._get_extension(f) in self.extensions
                ]
            else:
                files = [
                    "%s/%s" % (directory, f) for f in list(
                        set(self._collect_dependencies(directory, filename)))
                ]
                files.append(absstrfile)

        command = "%s -p \"%s\"" % (CMD, "; ".join(COMMANDS))
        command = command.format(FILES=" ".join(files), \
                                 TARGET=topmodule, \
                                 PASSES="; ".join(PASSES), \
                                 BTORFILE=TMPFILE)

        Logger.log("Command: %s" % command, 2)

        print_level = 3
        if not Logger.level(print_level):
            saved_stdout = suppress_output()

        retval = os.system(command)

        if not Logger.level(print_level):
            restore_output(saved_stdout)

        if retval != 0:
            Logger.error("Error in Verilog conversion")

        parser = BTOR2Parser()
        ret = parser.parse_file(TMPFILE, config)

        if not Logger.level(1):
            os.remove(TMPFILE)

        return ret
Ejemplo n.º 25
0
    def solve_safety_fwd(self, hts, prop, k, k_min):
        init = hts.single_init()
        trans = hts.single_trans()
        invar = hts.single_invar()

        t = k_min
        while (t < k+1):
            self._reset_assertions(self.solver)
            formula = And(init, invar)
            formula = self.at_time(formula, 0)
            Logger.log("Add init and invar", 2)
            self._add_assertion(self.solver, formula)

            trans_t = self.unroll(trans, invar, t)
            self._add_assertion(self.solver, trans_t)

            propt = self.at_time(Not(prop), t)
            Logger.log("Add property time %d"%t, 2)
            self._add_assertion(self.solver, propt)

            if self._solve(self.solver):
                Logger.log("Counterexample found with k=%s"%(t), 1)
                model = self._get_model(self.solver)
                return (t, model)
            else:
                Logger.log("No counterexample found with k=%s"%(t), 1)
                Logger.msg(".", 0, not(Logger.level(1)))

            t += 1

        return (t-1, None)
Ejemplo n.º 26
0
    def Const(out, value):
        invar = TRUE()
        if value is not None:
            if out.symbol_type() == BOOL:
                const = TRUE() if value == 1 else FALSE()
            else:
                const = BV(value, out.symbol_type().width)
            invar = EqualsOrIff(out, const)

        comment = "Const (out, val) = (" + out.symbol_name() + ", " + str(value) + ")"
        Logger.log(comment, 3)
        ts = TS(comment)
        ts.vars, ts.invar = set([out]), invar
        return ts
Ejemplo n.º 27
0
        def check_step():
            self._reset_assertions(self.solver)
            self._add_assertion(self.solver,
                                self.at_time(And(trans, lemma), 0))
            self._add_assertion(self.solver, self.at_time(Not(lemma), 1))

            if self._solve(self.solver):
                if Logger.level(2):
                    Logger.log("Lemma \"%s\" failed for L & T -> L'" % lemma,
                               2)
                    if Logger.level(3):
                        (hr_trace, vcd_trace) = self.print_trace(
                            hts,
                            self._get_model(self.solver),
                            1,
                            prefix=prefix,
                            map_function=self.config.map_function)
                        if hr_trace or vcd_trace:
                            vcd_msg = ""
                            if vcd_trace:
                                vcd_msg = " and in \"%s\"" % (vcd_trace)
                            Logger.log(
                                "Counterexample stored in \"%s\"%s" %
                                (hr_trace, vcd_msg), 2)
                        else:
                            Logger.log("", 2)
                return False
            else:
                Logger.log("Lemma \"%s\" holds for L & T -> L'" % lemma, 2)

            return True
Ejemplo n.º 28
0
    def solve_safety(self, hts, prop, k, k_min=0, lemmas=None, processes=1):
        if lemmas is not None:
            (hts, res) = self.add_lemmas(hts, prop, lemmas)
            if res:
                Logger.log("Lemmas imply the property", 1)
                Logger.log("", 0, not(Logger.level(1)))
                return (0, True)

        hts.reset_formulae()

        if self.config.incremental:
            return self.solve_safety_inc(hts, prop, k, k_min, processes)

        return self.solve_safety_ninc(hts, prop, k, k_min)
Ejemplo n.º 29
0
    def BopBool(op, in0, in1, out):
        # INVAR: (in0 <op> in1) = out
        vars_ = [in0,in1,out]
        comment = (op.__name__ + " (in0, in1, out) = (%s, %s, %s)")%(tuple([x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        if out.symbol_type() == BOOL:
            bout = out
        else:
            bout = EqualsOrIff(out, BV(1, 1))

        invar = Iff(op(in0,in1), bout)
        ts = TS(comment)
        ts.vars, ts.invar = get_free_variables(invar), invar
        return ts
Ejemplo n.º 30
0
def translate(hts, config, formulae=None):
    # TODO: Fix this for the formulae which are not pysmt nodes at this point
    #       accessing the problem copy of it which is still a string
    Logger.log("\nWriting system to \"%s\""%(config.translate), 0)
    printer = HTSPrintersFactory.printer_by_name(config.printer)
    props = []
    if formulae is not None:
        for f in formulae:
            if f is None:
                continue
            assert isinstance(f, FNode), "Expecting parsed properties"
            props.append(f)

    with open(config.translate, "w") as f:
        f.write(printer.print_hts(hts, props))