Ejemplo n.º 1
0
    def solve_safety_inc_bwd(self, hts, prop, k, assert_property=False):
        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()

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

        t = 0
        while (t < k + 1):
            self._push(self.solver)

            pinit = self.at_ptime(init, t - 1)
            Logger.log("Add init at time %d" % t, 2)
            self._add_assertion(self.solver, pinit)

            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)

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

            if assert_property and t > 0:
                prop_t = self.unroll(TRUE(), prop, t - 1, t)
                self._add_assertion(self.solver, prop_t)
                Logger.log("Add property at time %d" % t, 2)

            t += 1

        return (t - 1, None)
Ejemplo n.º 2
0
    def test_iss171(self):
        auto_env = AutoEnv(get_env(), False)

        auto = Automaton(auto_env)

        s0 = auto._add_new_state(True, True)
        s1 = auto._add_new_state(False, False)
        s2 = auto._add_new_state(False, True)

        l1 = auto_env.new_label(Symbol('l1'))
        true_label = auto_env.new_label(TRUE())

        auto._add_trans(s0, s1, l1)
        auto._add_trans(s0, s2, l1)
        auto._add_trans(s1, s2, true_label)
        auto._add_trans(s1, s2, true_label)

        auto.klenee_star()
Ejemplo n.º 3
0
    def test_3(self):
        # need 2 bits
        var_name = "counter_3"
        self.enc.add_var(var_name, 3)

        b0 = self.enc._get_bitvar(var_name,0)
        b1 = self.enc._get_bitvar(var_name,1)

        e = self.enc.eq_val(var_name, 0)
        self._is_eq(e, And(Not(b0), Not(b1)))
        e = self.enc.eq_val(var_name, 1)
        self._is_eq(e, And(b0, Not(b1)))
        e = self.enc.eq_val(var_name, 2)
        self._is_eq(e, And(Not(b0), b1))
        e = self.enc.eq_val(var_name, 3)
        self._is_eq(e, And(b0, b1))

        mask = self.enc.get_mask(var_name)
        self._is_eq(mask, TRUE())
Ejemplo n.º 4
0
    def normalize(self, new_support, conjoin_old_support=True, paths=True):
        # type: (FNode, bool, bool) -> Optional[FNode]

        if not os.path.exists(XaddEngine.path()):
            raise RuntimeError(
                "The XADD engine requires the XADD library JAR file which is currently not installed."
            )

        if conjoin_old_support:
            new_support = self.support & new_support

        with self.temp_file() as f:
            with TemporaryFile() as f2:
                Density(self.domain, new_support, Real(1.0)).to_file(f2)
                with TemporaryFile() as f3:
                    Density(self.domain, TRUE(), Real(1.0)).to_file(f3)

                    try:
                        cmd_args = [
                            "java",
                            "-jar",
                            XaddEngine.path(),
                            "normalize",
                            f,
                            f2,
                            "-p" if paths else "-t",
                            f3,
                        ]
                        logger.info("> {}".format(" ".join(cmd_args)))
                        output = subprocess.check_output(
                            cmd_args,
                            timeout=self.timeout).decode(sys.stdout.encoding)
                        # print(output.replace("Academic license - for non-commercial use only\n", ""))
                        return XaddEngine.import_normalized(f3)
                    except subprocess.CalledProcessError as e:
                        logger.warning(e.output)
                        raise
                    except subprocess.TimeoutExpired:
                        logger.warning("Timeout")
                    except ValueError:
                        logger.warning(output)
                        raise
        return None
Ejemplo n.º 5
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():
                (t, model) = self.solve_safety_fwd(self.hts, Not(prop), k, k)
            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.generate_trace(model, t, get_free_variables(prop))
            return (VerificationStatus.TRUE, trace)
        else:
            Logger.log("Deadlock with k=%s"%k, 1)
            return (VerificationStatus.FALSE, None)
Ejemplo n.º 6
0
    def __print_single_hts(self, hts, printed_vars):

        has_comment = len(hts.comment) > 0

        if has_comment:
            lenstr = len(hts.comment) + 3

            self.write("\n%s\n" % ("-" * lenstr))
            self.write("-- %s\n" % hts.comment)
            self.write("%s\n" % ("-" * lenstr))

        locvars = [v for v in hts.vars if v not in printed_vars]

        for v in hts.vars:
            printed_vars.add(v)

        if locvars: self.write("\nVAR\n")
        for var in locvars:
            sname = self.names(var.symbol_name())
            if var.symbol_type() == BOOL:
                self.write("%s : boolean;\n" % (sname))
            else:
                self.write("%s : word[%s];\n" %
                           (sname, var.symbol_type().width))

        sections = [((hts.init), "INIT"), ((hts.invar), "INVAR"),
                    ((hts.trans), "TRANS")]

        for (formula, keyword) in sections:
            if formula not in [TRUE(), FALSE()]:
                self.write("\n%s\n" % keyword)
                cp = list(conjunctive_partition(formula))
                for i in range(len(cp)):
                    f = simplify(cp[i])
                    self.printer(f)
                    if i < len(cp) - 1:
                        self.write(" &\n")
                self.write(";\n")

        if has_comment:
            self.write("\n%s\n" % ("-" * lenstr))

        return printed_vars
Ejemplo n.º 7
0
 def test_incrementality(self):
     with Portfolio(["cvc4", "msat", "yices"],
                    logic=QF_UFLIRA,
                    environment=self.env,
                    incremental=True,
                    generate_models=True) as s:
         x, y = Symbol("x"), Symbol("y")
         s.add_assertion(Implies(x, y))
         s.push()
         s.add_assertion(x)
         res = s.solve()
         self.assertTrue(res)
         v = s.get_value(y)
         self.assertTrue(v, TRUE())
         s.pop()
         s.add_assertion(x)
         res = s.solve()
         self.assertTrue(res)
         v = s.get_value(x)
         self.assertTrue(v, FALSE())
Ejemplo n.º 8
0
    def check_property(self, prop):
        """Property Directed Reachability approach without optimizations."""
        print("Checking property %s..." % prop)

        while True:
            cube = self.get_bad_state(prop)
            if cube is not None:
                # Blocking phase of a bad state
                if self.recursive_block(cube):
                    print("--> Bug found at step %d" % (len(self.frames)))
                    break
                else:
                    print("   [PDR] Cube blocked '%s'" % str(cube))
            else:
                # Checking if the last two frames are equivalent i.e., are inductive
                if self.inductive():
                    print("--> The system is safe!")
                    break
                else:
                    print("   [PDR] Adding frame %d..." % (len(self.frames)))
                    self.frames.append(TRUE())
Ejemplo n.º 9
0
    def loop_free(self, vars_, k_end, k_start=0):
        Logger.log("Simple path from %s to %s"%(k_start, k_end), 2)

        if k_end == k_start:
            return TRUE()

        def not_eq_states(vars1, vars2):
            assert len(vars1) == len(vars2)
            eqvars = []
            for i in range(len(vars1)):
                eqvars.append(EqualsOrIff(vars1[i], vars2[i]))
            return Not(And(eqvars))

        lvars = list(vars_)
        end_vars = [TS.get_timed(v, k_end) for v in lvars]

        formula = []
        for t in range(k_start, k_end, 1):
            formula.append(not_eq_states(end_vars, [TS.get_timed(v, t) for v in lvars]))

        return And(formula)
Ejemplo n.º 10
0
    def add_negatives(domain,
                      data,
                      labels,
                      thresholds,
                      sample_count,
                      background_knowledge=None,
                      distance_measure=None):
        # type: (Domain, np.ndarray, np.ndarray, Dict, int, FNode, Any) -> Tuple[np.ndarray, np.ndarray]

        new_data = uniform(domain, sample_count)
        background_knowledge = background_knowledge or TRUE()
        supported_indices = evaluate(domain, background_knowledge, new_data)
        boolean_indices = [
            i for i, v in enumerate(domain.variables) if domain.is_bool(v)
        ]
        real_indices = [
            i for i, v in enumerate(domain.variables) if domain.is_real(v)
        ]
        for j in range(new_data.shape[0]):
            valid_negative = True
            for i in range(data.shape[0]):
                # noinspection PyTypeChecker
                if labels[i] and all(
                        data[i, boolean_indices] == new_data[j,
                                                             boolean_indices]):
                    in_range = True
                    for ri, v in zip(real_indices, domain.real_vars):
                        t = thresholds[v] if isinstance(
                            thresholds, dict) else thresholds[i, ri]
                        if abs(data[i, ri] - new_data[j, ri]) > t:
                            in_range = False
                            break
                    valid_negative = valid_negative and (not in_range)
                    if not valid_negative:
                        break
            supported_indices[j] = supported_indices[j] and valid_negative
        new_data = new_data[supported_indices == 1, :]
        return np.concatenate([data, new_data], axis=0), np.concatenate(
            [labels, np.zeros(new_data.shape[0])])
Ejemplo n.º 11
0
    def __print_single_ts(self, ts, printed_vars):

        has_comment = len(ts.comment) > 0

        if has_comment:
            lenstr = len(ts.comment) + 3

            self.write("\n%s\n" % ("-" * lenstr))
            self.write("-- %s\n" % ts.comment)
            self.write("%s\n" % ("-" * lenstr))

        locvars = [v for v in ts.vars if v not in printed_vars]

        for v in ts.vars:
            printed_vars.add(v)

        if locvars: self.write("\nVAR\n")
        for var in locvars:
            self.write("{} : {};\n".format(var.symbol_name(),
                                           to_smv_type(var.get_type())))

        sections = [((ts.init), "INIT"), ((ts.invar), "INVAR"),
                    ((ts.trans), "TRANS")]

        for (formula, keyword) in sections:
            if formula not in [TRUE(), FALSE()]:
                self.write("\n%s\n" % keyword)
                cp = list(conjunctive_partition(formula))
                for i in range(len(cp)):
                    f = simplify(cp[i])
                    self.printer(f)
                    if i < len(cp) - 1:
                        self.write(" &\n")
                self.write(";\n")

        if has_comment:
            self.write("\n%s\n" % ("-" * lenstr))

        return printed_vars
Ejemplo n.º 12
0
def set_axiom_formula(self, unbounded):
    axiomS = []
    
    for cl in self._faxioms:
        if unbounded:
            cl = self.system.replaceDefinitions(cl, 1)
        axiomS.append(cl)
    for cl in self.system.curr._axiom:
        if unbounded:
            cl = self.system.replaceDefinitions(cl, 1)
        axiomS.append(cl)
    
    if True or (not unbounded):
        for k, v in self.system.curr._definitions.items():
            axiomS.append(v)
    
    if len(self.system._sort2fin) == len(self.system._sorts):
        if self.ordered == "zero":
            cl = self.system.get_ordered_zero()
            axiomS.append(cl)
        
        if self.ordered == "partial":
            cl = self.system.get_ordered_le()
            axiomS.append(cl)
#             assert(0)
        
    if self.quorums != "none":
        cl = self.system.get_quorum_axiom()
        axiomS.append(cl)
#         assert(0)
        
    if not axiomS:
        res = TRUE()
    else:
        res = And(axiomS)
    res = self.get_formula_qf(res)
    self._axiom_formula = res
    return res
Ejemplo n.º 13
0
    def test_enum_trans(self):
        env = AutoEnv.get_global_auto_env()
        solver = env.sat_solver

        symbols = [Symbol(chr(i), BOOL) for i in range(ord('a'), ord('z') + 1)]
        false_label = env.new_label(FALSE())
        true_label = env.new_label(TRUE())
        a = env.new_label(symbols[0])
        b = env.new_label(symbols[1])
        c = env.new_label(symbols[2])
        a_and_b = a.intersect(b)

        results = Automaton.enum_trans([false_label], env.sat_solver)
        self.assertTrue(len(results) == 1)

        results = Automaton.enum_trans([true_label], env.sat_solver)
        self.assertTrue(len(results) == 1)

        results = Automaton.enum_trans([a, b, c], env.sat_solver)
        self.assertTrue(len(results) == 8)

        results = Automaton.enum_trans([a, b, a_and_b], env.sat_solver)
        self.assertTrue(len(results) == 4)
Ejemplo n.º 14
0
    def _build_trace(self, model, steps):
        """Extract the trace from the satisfying assignment."""

        vars_to_use = [self.ts.state_vars, self.ts.input_vars]
        cex = []

        for i in range(steps + 1):
            if (i not in self.helper.time_memo):
                self.helper.get_formula_at_i(self.all_vars, TRUE(), i)

            cex_i = {}

            # skip the input variables in the last step
            if (i >= steps):
                vars_to_use = [self.ts.state_vars]

            for vs in vars_to_use:
                for var in vs:
                    assert var is not None
                    var_i = self.helper.get_var_at_time(var, i)
                    assert var_i is not None
                    cex_i[var] = model.get_py_value(var_i, True)
            cex.append(cex_i)
        return cex
Ejemplo n.º 15
0
def get_full_example_formulae(environment=None):
    """Return a list of Examples using the given environment."""

    if environment is None:
        environment = get_env()

    with environment:
        x = Symbol("x", BOOL)
        y = Symbol("y", BOOL)
        p = Symbol("p", INT)
        q = Symbol("q", INT)
        r = Symbol("r", REAL)
        s = Symbol("s", REAL)
        aii = Symbol("aii", ARRAY_INT_INT)
        ari = Symbol("ari", ArrayType(REAL, INT))
        arb = Symbol("arb", ArrayType(REAL, BV8))
        abb = Symbol("abb", ArrayType(BV8, BV8))
        nested_a = Symbol("a_arb_aii",
                          ArrayType(ArrayType(REAL, BV8), ARRAY_INT_INT))

        rf = Symbol("rf", FunctionType(REAL, [REAL, REAL]))
        rg = Symbol("rg", FunctionType(REAL, [REAL]))

        ih = Symbol("ih", FunctionType(INT, [REAL, INT]))
        ig = Symbol("ig", FunctionType(INT, [INT]))

        bf = Symbol("bf", FunctionType(BOOL, [BOOL]))
        bg = Symbol("bg", FunctionType(BOOL, [BOOL]))

        bv8 = Symbol("bv1", BV8)
        bv16 = Symbol("bv2", BV16)

        result = [
            # Formula, is_valid, is_sat, is_qf
            Example(hr="(x & y)",
                    expr=And(x, y),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BOOL),
            Example(hr="(x <-> y)",
                    expr=Iff(x, y),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BOOL),
            Example(hr="((x | y) & (! (x | y)))",
                    expr=And(Or(x, y), Not(Or(x, y))),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BOOL),
            Example(hr="(x & (! y))",
                    expr=And(x, Not(y)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BOOL),
            Example(hr="(False -> True)",
                    expr=Implies(FALSE(), TRUE()),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BOOL),

            #
            #  LIA
            #
            Example(hr="((q < p) & (x -> y))",
                    expr=And(GT(p, q), Implies(x, y)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_IDL),
            Example(hr="(((p + q) = 5) & (q < p))",
                    expr=And(Equals(Plus(p, q), Int(5)), GT(p, q)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LIA),
            Example(hr="((q <= p) | (p <= q))",
                    expr=Or(GE(p, q), LE(p, q)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_IDL),
            Example(hr="(! (p < (q * 2)))",
                    expr=Not(LT(p, Times(q, Int(2)))),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LIA),
            Example(hr="(p < (p - (5 - 2)))",
                    expr=GT(Minus(p, Minus(Int(5), Int(2))), p),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_IDL),
            Example(hr="((x ? 7 : ((p + -1) * 3)) = q)",
                    expr=Equals(
                        Ite(x, Int(7), Times(Plus(p, Int(-1)), Int(3))), q),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LIA),
            Example(hr="(p < (q + 1))",
                    expr=LT(p, Plus(q, Int(1))),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LIA),

            #
            # LRA
            #
            Example(hr="((s < r) & (x -> y))",
                    expr=And(GT(r, s), Implies(x, y)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_RDL),
            Example(hr="(((r + s) = 28/5) & (s < r))",
                    expr=And(Equals(Plus(r, s), Real(Fraction("5.6"))),
                             GT(r, s)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LRA),
            Example(hr="((s <= r) | (r <= s))",
                    expr=Or(GE(r, s), LE(r, s)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_RDL),
            Example(hr="(! ((r * 2.0) < (s * 2.0)))",
                    expr=Not(LT(Div(r, Real((1, 2))), Times(s, Real(2)))),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LRA),
            Example(hr="(! (r < (r - (5.0 - 2.0))))",
                    expr=Not(GT(Minus(r, Minus(Real(5), Real(2))), r)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_RDL),
            Example(hr="((x ? 7.0 : ((s + -1.0) * 3.0)) = r)",
                    expr=Equals(
                        Ite(x, Real(7), Times(Plus(s, Real(-1)), Real(3))), r),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LRA),

            #
            # EUF
            #
            Example(hr="(bf(x) <-> bg(x))",
                    expr=Iff(Function(bf, (x, )), Function(bg, (x, ))),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_UF),
            Example(hr="(rf(5.0, rg(r)) = 0.0)",
                    expr=Equals(Function(rf, (Real(5), Function(rg, (r, )))),
                                Real(0)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_UFLRA),
            Example(hr="((rg(r) = (5.0 + 2.0)) <-> (rg(r) = 7.0))",
                    expr=Iff(Equals(Function(rg, [r]), Plus(Real(5), Real(2))),
                             Equals(Function(rg, [r]), Real(7))),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_UFLRA),
            Example(
                hr="((r = (s + 1.0)) & (rg(s) = 5.0) & (rg((r - 1.0)) = 7.0))",
                expr=And([
                    Equals(r, Plus(s, Real(1))),
                    Equals(Function(rg, [s]), Real(5)),
                    Equals(Function(rg, [Minus(r, Real(1))]), Real(7))
                ]),
                is_valid=False,
                is_sat=False,
                logic=pysmt.logics.QF_UFLRA),

            #
            # BV
            #
            Example(hr="((1_32 & 0_32) = 0_32)",
                    expr=Equals(BVAnd(BVOne(32), BVZero(32)), BVZero(32)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((! 2_3) = 5_3)",
                    expr=Equals(BVNot(BV("010")), BV("101")),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((7_3 xor 0_3) = 0_3)",
                    expr=Equals(BVXor(BV("111"), BV("000")), BV("000")),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv1::bv1) u< 0_16)",
                    expr=BVULT(BVConcat(bv8, bv8), BVZero(16)),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BV),
            Example(hr="(1_32[0:7] = 1_8)",
                    expr=Equals(BVExtract(BVOne(32), end=7), BVOne(8)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="(0_8 u< (((bv1 + 1_8) * 5_8) u/ 5_8))",
                    expr=BVUGT(
                        BVUDiv(BVMul(BVAdd(bv8, BVOne(8)), BV(5, width=8)),
                               BV(5, width=8)), BVZero(8)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="(0_16 u<= bv2)",
                    expr=BVUGE(bv16, BVZero(16)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="(0_16 s<= bv2)",
                    expr=BVSGE(bv16, BVZero(16)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(
                hr="((0_32 u< (5_32 u% 2_32)) & ((5_32 u% 2_32) u<= 1_32))",
                expr=And(
                    BVUGT(BVURem(BV(5, width=32), BV(2, width=32)),
                          BVZero(32)),
                    BVULE(BVURem(BV(5, width=32), BV(2, width=32)),
                          BVOne(32))),
                is_valid=True,
                is_sat=True,
                logic=pysmt.logics.QF_BV),
            Example(hr="((((1_32 + (- 1_32)) << 1_32) >> 1_32) = 1_32)",
                    expr=Equals(
                        BVLShr(BVLShl(BVAdd(BVOne(32), BVNeg(BVOne(32))), 1),
                               1), BVOne(32)),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((1_32 - 1_32) = 0_32)",
                    expr=Equals(BVSub(BVOne(32), BVOne(32)), BVZero(32)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),

            # Rotations
            Example(hr="(((1_32 ROL 1) ROR 1) = 1_32)",
                    expr=Equals(BVRor(BVRol(BVOne(32), 1), 1), BVOne(32)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),

            # Extensions
            Example(hr="((0_5 ZEXT 11) = (0_1 SEXT 15))",
                    expr=Equals(BVZExt(BVZero(5), 11), BVSExt(BVZero(1), 15)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 - bv2) = 0_16)",
                    expr=Equals(BVSub(bv16, bv16), BVZero(16)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 - bv2)[0:7] = bv1)",
                    expr=Equals(BVExtract(BVSub(bv16, bv16), 0, 7), bv8),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2[0:7] bvcomp bv1) = 1_1)",
                    expr=Equals(BVComp(BVExtract(bv16, 0, 7), bv8), BVOne(1)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 bvcomp bv2) = 0_1)",
                    expr=Equals(BVComp(bv16, bv16), BVZero(1)),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BV),
            Example(hr="(bv2 s< bv2)",
                    expr=BVSLT(bv16, bv16),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BV),
            Example(hr="(bv2 s< 0_16)",
                    expr=BVSLT(bv16, BVZero(16)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 s< 0_16) | (0_16 s<= bv2))",
                    expr=Or(BVSGT(BVZero(16), bv16), BVSGE(bv16, BVZero(16))),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="(bv2 u< bv2)",
                    expr=BVULT(bv16, bv16),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BV),
            Example(hr="(bv2 u< 0_16)",
                    expr=BVULT(bv16, BVZero(16)),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 | 0_16) = bv2)",
                    expr=Equals(BVOr(bv16, BVZero(16)), bv16),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 & 0_16) = 0_16)",
                    expr=Equals(BVAnd(bv16, BVZero(16)), BVZero(16)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((0_16 s< bv2) & ((bv2 s/ 65535_16) s< 0_16))",
                    expr=And(BVSLT(BVZero(16), bv16),
                             BVSLT(BVSDiv(bv16, SBV(-1, 16)), BVZero(16))),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((0_16 s< bv2) & ((bv2 s% 1_16) s< 0_16))",
                    expr=And(BVSLT(BVZero(16), bv16),
                             BVSLT(BVSRem(bv16, BVOne(16)), BVZero(16))),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 u% 1_16) = 0_16)",
                    expr=Equals(BVURem(bv16, BVOne(16)), BVZero(16)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 s% 1_16) = 0_16)",
                    expr=Equals(BVSRem(bv16, BVOne(16)), BVZero(16)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 s% (- 1_16)) = 0_16)",
                    expr=Equals(BVSRem(bv16, BVNeg(BVOne(16))), BVZero(16)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((bv2 a>> 0_16) = bv2)",
                    expr=Equals(BVAShr(bv16, BVZero(16)), bv16),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            Example(hr="((0_16 s<= bv2) & ((bv2 a>> 1_16) = (bv2 >> 1_16)))",
                    expr=And(
                        BVSLE(BVZero(16), bv16),
                        Equals(BVAShr(bv16, BVOne(16)),
                               BVLShr(bv16, BVOne(16)))),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_BV),
            #
            # Quantification
            #
            Example(hr="(forall y . (x -> y))",
                    expr=ForAll([y], Implies(x, y)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.BOOL),
            Example(hr="(forall p, q . ((p + q) = 0))",
                    expr=ForAll([p, q], Equals(Plus(p, q), Int(0))),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.LIA),
            Example(
                hr="(forall r, s . (((0.0 < r) & (0.0 < s)) -> ((r - s) < r)))",
                expr=ForAll([r, s],
                            Implies(And(GT(r, Real(0)), GT(s, Real(0))),
                                    (LT(Minus(r, s), r)))),
                is_valid=True,
                is_sat=True,
                logic=pysmt.logics.LRA),
            Example(hr="(exists x, y . (x -> y))",
                    expr=Exists([x, y], Implies(x, y)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.BOOL),
            Example(hr="(exists p, q . ((p + q) = 0))",
                    expr=Exists([p, q], Equals(Plus(p, q), Int(0))),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.LIA),
            Example(hr="(exists r . (forall s . (r < (r - s))))",
                    expr=Exists([r], ForAll([s], GT(Minus(r, s), r))),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.LRA),
            Example(hr="(forall r . (exists s . (r < (r - s))))",
                    expr=ForAll([r], Exists([s], GT(Minus(r, s), r))),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.LRA),
            Example(hr="(x & (forall r . ((r + s) = 5.0)))",
                    expr=And(x, ForAll([r], Equals(Plus(r, s), Real(5)))),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.LRA),
            Example(hr="(exists x . ((x <-> (5.0 < s)) & (s < 3.0)))",
                    expr=Exists([x],
                                (And(Iff(x, GT(s, Real(5))), LT(s, Real(3))))),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.LRA),

            #
            # UFLIRA
            #
            Example(hr="((p < ih(r, q)) & (x -> y))",
                    expr=And(GT(Function(ih, (r, q)), p), Implies(x, y)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_UFLIRA),
            Example(
                hr=
                "(((p - 3) = q) -> ((p < ih(r, (q + 3))) | (ih(r, p) <= p)))",
                expr=Implies(
                    Equals(Minus(p, Int(3)), q),
                    Or(GT(Function(ih, (r, Plus(q, Int(3)))), p),
                       LE(Function(ih, (r, p)), p))),
                is_valid=True,
                is_sat=True,
                logic=pysmt.logics.QF_UFLIRA),
            Example(
                hr=
                "(((ToReal((p - 3)) = r) & (ToReal(q) = r)) -> ((p < ih(ToReal((p - 3)), (q + 3))) | (ih(r, p) <= p)))",
                expr=Implies(
                    And(Equals(ToReal(Minus(p, Int(3))), r),
                        Equals(ToReal(q), r)),
                    Or(
                        GT(
                            Function(
                                ih,
                                (ToReal(Minus(p, Int(3))), Plus(q, Int(3)))),
                            p), LE(Function(ih, (r, p)), p))),
                is_valid=True,
                is_sat=True,
                logic=pysmt.logics.QF_UFLIRA),
            Example(
                hr=
                "(! (((ToReal((p - 3)) = r) & (ToReal(q) = r)) -> ((p < ih(ToReal((p - 3)), (q + 3))) | (ih(r, p) <= p))))",
                expr=Not(
                    Implies(
                        And(Equals(ToReal(Minus(p, Int(3))), r),
                            Equals(ToReal(q), r)),
                        Or(
                            GT(
                                Function(ih, (ToReal(Minus(
                                    p, Int(3))), Plus(q, Int(3)))), p),
                            LE(Function(ih, (r, p)), p)))),
                is_valid=False,
                is_sat=False,
                logic=pysmt.logics.QF_UFLIRA),
            Example(
                hr=
                """("Did you know that any string works? #yolo" & "10" & "|#somesolverskeepthe||" & " ")""",
                expr=And(Symbol("Did you know that any string works? #yolo"),
                         Symbol("10"), Symbol("|#somesolverskeepthe||"),
                         Symbol(" ")),
                is_valid=False,
                is_sat=True,
                logic=pysmt.logics.QF_BOOL),

            #
            # Arrays
            #
            Example(hr="((q = 0) -> (aii[0 := 0] = aii[0 := q]))",
                    expr=Implies(
                        Equals(q, Int(0)),
                        Equals(Store(aii, Int(0), Int(0)),
                               Store(aii, Int(0), q))),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_ALIA),
            Example(hr="(aii[0 := 0][0] = 0)",
                    expr=Equals(Select(Store(aii, Int(0), Int(0)), Int(0)),
                                Int(0)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_ALIA),
            Example(hr="((Array{Int, Int}(0)[1 := 1] = aii) & (aii[1] = 0))",
                    expr=And(Equals(Array(INT, Int(0), {Int(1): Int(1)}), aii),
                             Equals(Select(aii, Int(1)), Int(0))),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.get_logic_by_name("QF_ALIA*")),
            Example(hr="((Array{Int, Int}(0)[1 := 3] = aii) & (aii[1] = 3))",
                    expr=And(Equals(Array(INT, Int(0), {Int(1): Int(3)}), aii),
                             Equals(Select(aii, Int(1)), Int(3))),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.get_logic_by_name("QF_ALIA*")),
            Example(hr="((Array{Real, Int}(10) = ari) & (ari[6/5] = 0))",
                    expr=And(Equals(Array(REAL, Int(10)), ari),
                             Equals(Select(ari, Real((6, 5))), Int(0))),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")),
            Example(
                hr=
                "((Array{Real, Int}(0)[1.0 := 10][2.0 := 20][3.0 := 30][4.0 := 40] = ari) & (! ((ari[0.0] = 0) & (ari[1.0] = 10) & (ari[2.0] = 20) & (ari[3.0] = 30) & (ari[4.0] = 40))))",
                expr=And(
                    Equals(
                        Array(
                            REAL, Int(0), {
                                Real(1): Int(10),
                                Real(2): Int(20),
                                Real(3): Int(30),
                                Real(4): Int(40)
                            }), ari),
                    Not(
                        And(Equals(Select(ari, Real(0)), Int(0)),
                            Equals(Select(ari, Real(1)), Int(10)),
                            Equals(Select(ari, Real(2)), Int(20)),
                            Equals(Select(ari, Real(3)), Int(30)),
                            Equals(Select(ari, Real(4)), Int(40))))),
                is_valid=False,
                is_sat=False,
                logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")),
            Example(
                hr=
                "((Array{Real, Int}(0)[1.0 := 10][2.0 := 20][3.0 := 30][4.0 := 40][5.0 := 50] = ari) & (! ((ari[0.0] = 0) & (ari[1.0] = 10) & (ari[2.0] = 20) & (ari[3.0] = 30) & (ari[4.0] = 40) & (ari[5.0] = 50))))",
                expr=And(
                    Equals(
                        Array(
                            REAL, Int(0), {
                                Real(1): Int(10),
                                Real(2): Int(20),
                                Real(3): Int(30),
                                Real(4): Int(40),
                                Real(5): Int(50)
                            }), ari),
                    Not(
                        And(Equals(Select(ari, Real(0)), Int(0)),
                            Equals(Select(ari, Real(1)), Int(10)),
                            Equals(Select(ari, Real(2)), Int(20)),
                            Equals(Select(ari, Real(3)), Int(30)),
                            Equals(Select(ari, Real(4)), Int(40)),
                            Equals(Select(ari, Real(5)), Int(50))))),
                is_valid=False,
                is_sat=False,
                logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")),
            Example(
                hr=
                "((a_arb_aii = Array{Array{Real, BV{8}}, Array{Int, Int}}(Array{Int, Int}(7))) -> (a_arb_aii[arb][42] = 7))",
                expr=Implies(
                    Equals(nested_a,
                           Array(ArrayType(REAL, BV8), Array(INT, Int(7)))),
                    Equals(Select(Select(nested_a, arb), Int(42)), Int(7))),
                is_valid=True,
                is_sat=True,
                logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")),
            Example(hr="(abb[bv1 := y_][bv1 := z_] = abb[bv1 := z_])",
                    expr=Equals(
                        Store(Store(abb, bv8, Symbol("y_", BV8)), bv8,
                              Symbol("z_", BV8)),
                        Store(abb, bv8, Symbol("z_", BV8))),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_ABV),
            Example(hr="((r / s) = (r * s))",
                    expr=Equals(Div(r, s), Times(r, s)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_NRA),
            Example(hr="(2.0 = (r * r))",
                    expr=Equals(Real(2), Times(r, r)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_NRA),
            Example(hr="((p ^ 2) = 0)",
                    expr=Equals(Pow(p, Int(2)), Int(0)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_NIA),
            Example(hr="((r ^ 2.0) = 0.0)",
                    expr=Equals(Pow(r, Real(2)), Real(0)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_NRA),
            Example(hr="((r * r * r) = 25.0)",
                    expr=Equals(Times(r, r, r), Real(25)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_NRA),
            Example(hr="((5.0 * r * 5.0) = 25.0)",
                    expr=Equals(Times(Real(5), r, Real(5)), Real(25)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LRA),
            Example(hr="((p * p * p) = 25)",
                    expr=Equals(Times(p, p, p), Int(25)),
                    is_valid=False,
                    is_sat=False,
                    logic=pysmt.logics.QF_NIA),
            Example(hr="((5 * p * 5) = 25)",
                    expr=Equals(Times(Int(5), p, Int(5)), Int(25)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_LIA),
            Example(hr="(((1 - 1) * p * 1) = 0)",
                    expr=Equals(Times(Minus(Int(1), Int(1)), p, Int(1)),
                                Int(0)),
                    is_valid=True,
                    is_sat=True,
                    logic=pysmt.logics.QF_LIA),

            # Huge Fractions:
            Example(
                hr=
                "((r * 1606938044258990275541962092341162602522202993782792835301376/7) = -20480000000000000000000000.0)",
                expr=Equals(Times(r, Real(Fraction(2**200, 7))),
                            Real(-200**11)),
                is_valid=False,
                is_sat=True,
                logic=pysmt.logics.QF_LRA),
            Example(hr="(((r + 5.0 + s) * (s + 2.0 + r)) = 0.0)",
                    expr=Equals(
                        Times(Plus(r, Real(5), s), Plus(s, Real(2), r)),
                        Real(0)),
                    is_valid=False,
                    is_sat=True,
                    logic=pysmt.logics.QF_NRA),
            Example(
                hr=
                "(((p + 5 + q) * (p - (q - 5))) = ((p * p) + (10 * p) + 25 + (-1 * q * q)))",
                expr=Equals(
                    Times(Plus(p, Int(5), q), Minus(p, Minus(q, Int(5)))),
                    Plus(Times(p, p), Times(Int(10), p), Int(25),
                         Times(Int(-1), q, q))),
                is_valid=True,
                is_sat=True,
                logic=pysmt.logics.QF_NIA),
        ]
    return result
Ejemplo n.º 16
0
 def test_nested(self):
     f = Exists([self.x], ForAll([self.y], Or(self.x, self.y)))
     g = qelim(f, solver_name="shannon")
     g = g.simplify()
     self.assertEqual(g, TRUE())
Ejemplo n.º 17
0
    def solve_liveness_inc_fwd(self, hts, prop, k, k_min, eventually=False):
        self._reset_assertions(self.solver)

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

        if self.config.simplify:
            Logger.log("Simplifying the Transition System", 1)
            if Logger.level(1):
                timer = Logger.start_timer("Simplify")

            init = simplify(init)
            trans = simplify(trans)
            invar = simplify(invar)

            if Logger.level(1):
                Logger.get_timer(timer)

        heqvar = None
        if not eventually:
            heqvar = Symbol(HEQVAR, BOOL)
            self._init_at_time(hts.vars.union(set([heqvar])), k)

        if self.config.prove:
            self.solver_klive = self.solver.copy("klive")

            self._reset_assertions(self.solver_klive)
            self._add_assertion(self.solver_klive, self.at_time(invar, 0))

            if eventually:
                self._add_assertion(self.solver_klive, self.at_time(init, 0))

        propt = FALSE()
        formula = And(init, invar)
        formula = self.at_time(formula, 0)
        Logger.log("Add init and invar", 2)
        self._add_assertion(self.solver, formula)

        next_prop = TS.has_next(prop)
        if next_prop:
            if k < 1:
                Logger.error(
                    "Liveness checking with next variables requires at least k=1"
                )
            k_min = 1

        t = 0
        while (t < k + 1):
            self._push(self.solver)

            loopback = FALSE()
            if t > 0:
                loopback = self.all_loopbacks(self.hts.vars, t, heqvar)

            Logger.log("Add loopbacks at time %d" % t, 2)
            self._add_assertion(self.solver, loopback)

            if t >= k_min:
                self._write_smt2_comment(self.solver, "Solving for k=%s" % (t))
                Logger.log("\nSolving for k=%s" % (t), 1)

                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)))
            else:
                Logger.log("Skipping solving for k=%s (k_min=%s)" % (t, k_min),
                           1)
                Logger.msg(".", 0, not (Logger.level(1)))

            self._pop(self.solver)

            n_prop = Not(prop)
            if not eventually:
                n_prop = Or(n_prop, Not(heqvar))

            if next_prop:
                if t > 0:
                    propt = self.at_time(n_prop, t - 1)
            else:
                propt = self.at_time(n_prop, t)

            self._add_assertion(self.solver, propt)

            if self.config.prove:

                if t > 0:
                    self._add_assertion(self.solver_klive, trans_t)
                    self._write_smt2_comment(self.solver_klive,
                                             "Solving for k=%s" % (t))

                    if next_prop:
                        if t > 0:
                            propt = self.at_time(Not(prop), t - 1)
                    else:
                        propt = self.at_time(Not(prop), t)

                    self._add_assertion(self.solver_klive, propt)

                    if t >= k_min:
                        if self._solve(self.solver_klive):
                            Logger.log("K-Liveness failed with k=%s" % (t), 1)
                        else:
                            Logger.log("K-Liveness holds with k=%s" % (t), 1)
                            return (t, True)

                else:
                    self._add_assertion(self.solver_klive,
                                        self.at_time(Not(prop), 0))

                    # self._push(self.solver_klive)
                    # self._add_assertion(self.solver_klive, self.at_time(prop, 0))
                    # res = self._solve(self.solver_klive)
                    # self._pop(self.solver_klive)
                    # if res:
                    #     self._add_assertion(self.solver_klive, self.at_time(prop, 0))
                    # else:
                    #     self._add_assertion(self.solver_klive, self.at_time(Not(prop), 0))

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

            if self.assert_property:
                prop_t = self.unroll(TRUE(), prop, t, t - 1)
                self._add_assertion(self.solver, prop_t)
                Logger.log("Add property at time %d" % t, 2)

            t += 1

        return (t - 1, None)
Ejemplo n.º 18
0
 def test_trivial_true_times(self):
     x, y, z = (Symbol(name, REAL) for name in "xyz")
     f = Equals(Times(x, z, y), Times(z, y, x))
     self.assertEqual(f.simplify(), TRUE())
Ejemplo n.º 19
0
 def test_trivial_true_or(self):
     x, y, z = (Symbol(name) for name in "xyz")
     f = Or(x, y, z, Not(x))
     self.assertEqual(f.simplify(), TRUE())
Ejemplo n.º 20
0
    def _flatten_rec(self, path=[]):
        self.is_flatten = True
        vardic = dict([(v.symbol_name(), v) for v in self.vars])

        def full_path(name, path):
            ret = ".".join(path + [name])
            if ret[0] == ".":
                return ret[1:]
            return ret

        for sub in self.subs:
            instance, actual, module = sub
            module.is_flatten = True
            formal = module.params

            ts = TS(FLATTEN)

            (ts.vars, \
             ts.state_vars, \
             ts.input_vars, \
             ts.output_vars, \
             ts.init, \
             ts.trans, \
             ts.ftrans, \
             ts.invar) = module._flatten_rec(path+[instance])

            self.add_ts(ts, reset=False)

            links = {}
            for i in range(len(actual)):
                # Unset parameter
                if actual[i] == None:
                    continue
                if type(actual[i]) == str:
                    local_expr = vardic[full_path(actual[i], path)]
                else:
                    local_vars = [(v.symbol_name(), v.symbol_name().replace(self.name, ".".join(path))) \
                                  for v in get_free_variables(actual[i])]
                    local_expr = substitute(actual[i], dict(local_vars))
                module_var = sub[2].newname(formal[i].symbol_name(),
                                            path + [sub[0]])
                assert sub[2].name != ""
                if module_var not in vardic:
                    modulevar = Symbol(module_var, formal[i].symbol_type())
                    self.vars.add(modulevar)
                    vardic[module_var] = modulevar
                if vardic[module_var] in self.output_vars:
                    links[local_expr] = [(TRUE(), vardic[module_var])]
                else:
                    links[vardic[module_var]] = [(TRUE(), local_expr)]

            ts = TS(LINKS)
            ts.ftrans = links
            self.add_ts(ts, reset=False)

        s_init = self.single_init()
        s_invar = self.single_invar(include_ftrans=False)
        s_trans = self.single_trans(include_ftrans=False)

        replace_dic = dict([(v.symbol_name(), self.newname(v.symbol_name(), path)) for v in self.vars] + \
                           [(TS.get_prime_name(v.symbol_name()), self.newname(TS.get_prime_name(v.symbol_name()), path)) \
                            for v in self.vars])

        substitute_dic = {}

        def substitute_mem(f, dic):
            if f in substitute_dic:
                return substitute_dic[f]
            ret = substitute(f, dic)
            substitute_dic[f] = ret
            return ret

        s_init = substitute_mem(s_init, replace_dic)
        s_invar = substitute_mem(s_invar, replace_dic)
        s_trans = substitute_mem(s_trans, replace_dic)

        s_ftrans = {}

        local_vars = []
        local_state_vars = []
        local_input_vars = []
        local_output_vars = []

        single_ftrans = self.single_ftrans()

        for var in list(self.vars):
            newsym = Symbol(replace_dic[var.symbol_name()], var.symbol_type())

            local_vars.append(newsym)
            if var in self.state_vars:
                local_state_vars.append(newsym)
            if var in self.input_vars:
                local_input_vars.append(newsym)
            if var in self.output_vars:
                local_output_vars.append(newsym)

            if var in single_ftrans:
                cond_assign_list = single_ftrans[var]
                s_ftrans[newsym] = [(substitute_mem(condition, replace_dic), \
                                     substitute_mem(value, replace_dic)) \
                                    for (condition, value) in cond_assign_list]
                del (single_ftrans[var])

        for var, cond_assign_list in single_ftrans.items():
            s_ftrans[substitute_mem(var, replace_dic)] = [(substitute_mem(condition, replace_dic), \
                                                           substitute_mem(value, replace_dic)) \
                                                          for (condition, value) in cond_assign_list]

        return (local_vars, local_state_vars, local_input_vars,
                local_output_vars, s_init, s_trans, s_ftrans, s_invar)
Ejemplo n.º 21
0
    def sim_no_unroll(self, hts, cover, k, all_vars=True, inc=False):
        init = hts.single_init()
        invar = hts.single_invar()
        trans = hts.single_trans()

        init_0 = self.at_time(init, 0)
        invar_0 = self.at_time(invar, 0)
        trans_01 = self.unroll(trans, invar, 1)
        cover_1 = self.at_time(cover, 1)

        full_model = {}

        if all_vars:
            relevant_vars = hts.vars
        else:
            relevant_vars = hts.state_vars | hts.output_vars

        relevant_vars_0 = [TS.get_timed(v, 0) for v in relevant_vars]
        relevant_vars_1 = [TS.get_timed(v, 1) for v in relevant_vars]

        relevant_vars_01 = [(TS.get_timed(v, 0), TS.get_timed(v, 1), v) for v in relevant_vars]

        self._reset_assertions(self.solver)

        # Picking Initial State
        Logger.log("\nSolving for k=0", 1)
        self._add_assertion(self.solver, And(init_0, invar_0))

        if self._solve(self.solver):
            init_model =  self._get_model(self.solver, relevant_vars_0)
            init_0 = And([EqualsOrIff(v, init_model[v]) for v in relevant_vars_0])

            for v in relevant_vars_0:
                full_model[v] = init_model[v]

            Logger.msg(".", 0, not(Logger.level(1)))
        else:
            return (0, None)

        self._reset_assertions(self.solver)

        if inc:
            self._add_assertion(self.solver, trans_01)
            self._add_assertion(self.solver, invar_0)

        init_model = None
        for t in range(1, k + 1):
            Logger.log("\nSolving for k=%s"%(t), 1)

            if not inc:
                self._reset_assertions(self.solver, True)

                formula = And(init_0, invar_0)
                self._add_assertion(self.solver, trans_01)
            else:
                formula = init_0
                self._push(self.solver)

            self._add_assertion(self.solver, formula)

            res_step = self._solve(self.solver)

            if res_step:
                Logger.msg(".", 0, not(Logger.level(1)))
                Logger.log("Able to step forward at k=%s"%(t), 2)
                if all_vars:
                    init_model = self._get_model(self.solver)
                else:
                    init_model = self._get_model(self.solver, relevant_vars_1)
                model = init_model
            else:
                Logger.log("System deadlocked at k=%s"%(t), 2)
                return (-1, full_model)

            # Use previous model as initial state for next sat call
            init_0 = []
            init_1 = []

            for v in relevant_vars_01:
                if v[1] not in init_model:
                    continue
                val = init_model[v[1]]
                full_model[TS.get_timed(v[2], t)] = val
                init_0.append(EqualsOrIff(v[0], val))
                init_1.append(EqualsOrIff(v[1], val))

            init_0 = And(init_0)

            if cover != TRUE():
                init_1 = And(init_1)

                self._add_assertion(self.solver, init_1)
                self._add_assertion(self.solver, cover_1)

                res_cont = self._solve(self.solver)

                if res_cont:
                    Logger.log('Reached cover in no unroll simulation at k=%s'%(t), 2)
                    model = init_model
                    return (t, full_model)
                else:
                    Logger.log('Cover not reached at k=%s'%t, 2)

            if inc:
                self._pop(self.solver)

        return (t, full_model)
Ejemplo n.º 22
0
def expr_to_pysmt(context: TranslationContext,
                  expr: Expr,
                  *,
                  is_expectation: bool = False,
                  allow_infinity: bool = False) -> FNode:
    """
    Translate a pGCL expression to a pySMT formula.

    Note that substitution expressions are not allowed here (they are not
    supported in pySMT).

    You can pass in the optional `is_expectation` parameter to have all integer
    values converted to real values.

    If `allow_infinity` is `True`, then infinity expressions will be mapped
    directly to the `infinity` variable of the given
    :py:class:`TranslationContext`. Take care to appropriately constrain the
    `infinity` variable! Note that arithmetic expressions may not contain
    infinity, to prevent expressions like `infinity - infinity`.

    .. doctest::

        >>> from probably.pgcl.parser import parse_expr
        >>> from pysmt.shortcuts import Symbol
        >>> from pysmt.typing import INT

        >>> expr = parse_expr("x + 4 * 13")
        >>> context = TranslationContext({"x": Symbol("x", INT)})
        >>> expr_to_pysmt(context, expr)
        (x + (4 * 13))
    """
    if isinstance(expr, BoolLitExpr):
        return TRUE() if expr.value else FALSE()
    elif isinstance(expr, NatLitExpr):
        if is_expectation:
            return ToReal(Int(expr.value))
        else:
            return Int(expr.value)
    elif isinstance(expr, FloatLitExpr):
        if expr.is_infinite():
            if not allow_infinity:
                raise Exception(
                    f"Infinity is not allowed in this expression: {expr}")
            return context.infinity
        else:
            return Real(Fraction(expr.value))
    elif isinstance(expr, VarExpr):
        var = context.variables[expr.var]
        if is_expectation and get_type(var) == INT:
            var = ToReal(var)
        return var
    elif isinstance(expr, UnopExpr):
        operand = expr_to_pysmt(context,
                                expr.expr,
                                is_expectation=False,
                                allow_infinity=allow_infinity)
        if expr.operator == Unop.NEG:
            return Not(operand)
        elif expr.operator == Unop.IVERSON:
            return Ite(operand, Real(1), Real(0))
    elif isinstance(expr, BinopExpr):
        # `is_expectation` is disabled if we enter a non-arithmetic expression
        # (we do not convert integers to reals within a boolean expression such
        # as `x == y`, for example).
        #
        # Similarly, `allow_infinity` is disabled if we enter an arithmetic
        # expression because calculations with infinity are hard to make sense of.
        is_arith_op = expr.operator in [Binop.PLUS, Binop.MINUS, Binop.TIMES]
        is_expectation = is_expectation  # TODO: and is_arith_op
        allow_infinity = allow_infinity  # TODO: and not is_arith_op?!??!
        lhs = expr_to_pysmt(context,
                            expr.lhs,
                            is_expectation=is_expectation,
                            allow_infinity=allow_infinity)
        rhs = expr_to_pysmt(context,
                            expr.rhs,
                            is_expectation=is_expectation,
                            allow_infinity=allow_infinity)
        if expr.operator == Binop.OR:
            return Or(lhs, rhs)
        elif expr.operator == Binop.AND:
            return And(lhs, rhs)
        elif expr.operator == Binop.LEQ:
            return LE(lhs, rhs)
        elif expr.operator == Binop.LE:
            return LT(lhs, rhs)
        elif expr.operator == Binop.EQ:
            return EqualsOrIff(lhs, rhs)
        elif expr.operator == Binop.PLUS:
            return Plus(lhs, rhs)
        elif expr.operator == Binop.MINUS:
            return Ite(LE(lhs, rhs),
                       (Int(0) if get_type(lhs) == INT else Real(0)),
                       Minus(lhs, rhs))
        elif expr.operator == Binop.TIMES:
            return Times(lhs, rhs)
    elif isinstance(expr, SubstExpr):
        raise Exception("Substitution expression is not allowed here.")

    raise Exception("unreachable")
Ejemplo n.º 23
0
Archivo: btor2.py Proyecto: pllab/CoSA
    def parse_string(self, strinput):

        hts = HTS()
        ts = TS()

        nodemap = {}
        node_covered = set([])

        # list of tuples of var and cond_assign_list
        # cond_assign_list is tuples of (condition, value)
        # where everything is a pysmt FNode
        # for btor, the condition is always True
        ftrans = []

        initlist = []
        invarlist = []

        invar_props = []
        ltl_props = []

        prop_count = 0

        # clean string input, remove special characters from names
        for sc, rep in special_char_replacements.items():
            strinput = strinput.replace(sc, rep)

        def getnode(nid):
            node_covered.add(nid)
            if int(nid) < 0:
                return Ite(BV2B(nodemap[str(-int(nid))]), BV(0, 1), BV(1, 1))
            return nodemap[nid]

        def binary_op(bvop, bop, left, right):
            if (get_type(left) == BOOL) and (get_type(right) == BOOL):
                return bop(left, right)
            return bvop(B2BV(left), B2BV(right))

        def unary_op(bvop, bop, left):
            if (get_type(left) == BOOL):
                return bop(left)
            return bvop(left)

        for line in strinput.split(NL):
            linetok = line.split()
            if len(linetok) == 0:
                continue
            if linetok[0] == COM:
                continue

            (nid, ntype, *nids) = linetok

            if ntype == SORT:
                (stype, *attr) = nids
                if stype == BITVEC:
                    nodemap[nid] = BVType(int(attr[0]))
                    node_covered.add(nid)
                if stype == ARRAY:
                    nodemap[nid] = ArrayType(getnode(attr[0]),
                                             getnode(attr[1]))
                    node_covered.add(nid)

            if ntype == WRITE:
                nodemap[nid] = Store(*[getnode(n) for n in nids[1:4]])

            if ntype == READ:
                nodemap[nid] = Select(getnode(nids[1]), getnode(nids[2]))

            if ntype == ZERO:
                nodemap[nid] = BV(0, getnode(nids[0]).width)

            if ntype == ONE:
                nodemap[nid] = BV(1, getnode(nids[0]).width)

            if ntype == ONES:
                width = getnode(nids[0]).width
                nodemap[nid] = BV((2**width) - 1, width)

            if ntype == REDOR:
                width = get_type(getnode(nids[1])).width
                zeros = BV(0, width)
                nodemap[nid] = BVNot(BVComp(getnode(nids[1]), zeros))

            if ntype == REDAND:
                width = get_type(getnode(nids[1])).width
                ones = BV((2**width) - 1, width)
                nodemap[nid] = BVComp(getnode(nids[1]), ones)

            if ntype == CONSTD:
                width = getnode(nids[0]).width
                nodemap[nid] = BV(int(nids[1]), width)

            if ntype == CONST:
                width = getnode(nids[0]).width
                try:
                    nodemap[nid] = BV(bin_to_dec(nids[1]), width)
                except ValueError:
                    if not all([i == 'x' or i == 'z' for i in nids[1]]):
                        raise RuntimeError(
                            "If not a valid number, only support "
                            "all don't cares or high-impedance but got {}".
                            format(nids[1]))
                    # create a fresh variable for this non-deterministic constant
                    nodemap[nid] = Symbol('const_' + nids[1], BVType(width))
                    ts.add_state_var(nodemap[nid])
                    Logger.warning(
                        "Creating a fresh symbol for unsupported X/Z constant %s"
                        % nids[1])

            if ntype == STATE:
                if len(nids) > 1:
                    nodemap[nid] = Symbol(nids[1], getnode(nids[0]))
                else:
                    nodemap[nid] = Symbol((SN % nid), getnode(nids[0]))
                ts.add_state_var(nodemap[nid])

            if ntype == INPUT:
                if len(nids) > 1:
                    nodemap[nid] = Symbol(nids[1], getnode(nids[0]))
                else:
                    nodemap[nid] = Symbol((SN % nid), getnode(nids[0]))
                ts.add_input_var(nodemap[nid])

            if ntype == OUTPUT:
                # unfortunately we need to create an extra symbol just to have the output name
                # we could be smarter about this, but then this parser can't be greedy
                original_symbol = B2BV(getnode(nids[0]))
                output_symbol = Symbol(nids[1], original_symbol.get_type())
                nodemap[nid] = EqualsOrIff(output_symbol, original_symbol)
                invarlist.append(nodemap[nid])
                node_covered.add(nid)
                ts.add_output_var(output_symbol)

            if ntype == AND:
                nodemap[nid] = binary_op(BVAnd, And, getnode(nids[1]),
                                         getnode(nids[2]))

            if ntype == CONCAT:
                nodemap[nid] = BVConcat(B2BV(getnode(nids[1])),
                                        B2BV(getnode(nids[2])))

            if ntype == XOR:
                nodemap[nid] = binary_op(BVXor, Xor, getnode(nids[1]),
                                         getnode(nids[2]))

            if ntype == XNOR:
                nodemap[nid] = BVNot(
                    binary_op(BVXor, Xor, getnode(nids[1]), getnode(nids[2])))

            if ntype == NAND:
                bvop = lambda x, y: BVNot(BVAnd(x, y))
                bop = lambda x, y: Not(And(x, y))
                nodemap[nid] = binary_op(bvop, bop, getnode(nids[1]),
                                         getnode(nids[2]))

            if ntype == IMPLIES:
                nodemap[nid] = BVOr(BVNot(getnode(nids[1])), getnode(nids[2]))

            if ntype == NOT:
                nodemap[nid] = unary_op(BVNot, Not, getnode(nids[1]))

            if ntype == NEG:
                nodemap[nid] = unary_op(BVNeg, Not, getnode(nids[1]))

            if ntype == UEXT:
                nodemap[nid] = BVZExt(B2BV(getnode(nids[1])), int(nids[2]))

            if ntype == SEXT:
                nodemap[nid] = BVSExt(B2BV(getnode(nids[1])), int(nids[2]))

            if ntype == OR:
                nodemap[nid] = binary_op(BVOr, Or, getnode(nids[1]),
                                         getnode(nids[2]))

            if ntype == ADD:
                nodemap[nid] = BVAdd(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == SUB:
                nodemap[nid] = BVSub(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == UGT:
                nodemap[nid] = BVUGT(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == UGTE:
                nodemap[nid] = BVUGE(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == ULT:
                nodemap[nid] = BVULT(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == ULTE:
                nodemap[nid] = BVULE(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == SGT:
                nodemap[nid] = BVSGT(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == SGTE:
                nodemap[nid] = BVSGE(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == SLT:
                nodemap[nid] = BVSLT(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == SLTE:
                nodemap[nid] = BVSLE(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == EQ:
                nodemap[nid] = BVComp(B2BV(getnode(nids[1])),
                                      B2BV(getnode(nids[2])))

            if ntype == NEQ:
                nodemap[nid] = BVNot(BVComp(getnode(nids[1]),
                                            getnode(nids[2])))

            if ntype == MUL:
                nodemap[nid] = BVMul(B2BV(getnode(nids[1])),
                                     B2BV(getnode(nids[2])))

            if ntype == SLICE:
                nodemap[nid] = BVExtract(B2BV(getnode(nids[1])), int(nids[3]),
                                         int(nids[2]))

            if ntype == SLL:
                nodemap[nid] = BVLShl(getnode(nids[1]), getnode(nids[2]))

            if ntype == SRA:
                nodemap[nid] = BVAShr(getnode(nids[1]), getnode(nids[2]))

            if ntype == SRL:
                nodemap[nid] = BVLShr(getnode(nids[1]), getnode(nids[2]))

            if ntype == ITE:
                if (get_type(getnode(nids[2])) == BOOL) or (get_type(
                        getnode(nids[3])) == BOOL):
                    nodemap[nid] = Ite(BV2B(getnode(nids[1])),
                                       B2BV(getnode(nids[2])),
                                       B2BV(getnode(nids[3])))
                else:
                    nodemap[nid] = Ite(BV2B(getnode(nids[1])),
                                       getnode(nids[2]), getnode(nids[3]))

            if ntype == NEXT:
                if (get_type(getnode(nids[1])) == BOOL) or (get_type(
                        getnode(nids[2])) == BOOL):
                    lval = TS.get_prime(getnode(nids[1]))
                    rval = B2BV(getnode(nids[2]))
                else:
                    lval = TS.get_prime(getnode(nids[1]))
                    rval = getnode(nids[2])

                nodemap[nid] = EqualsOrIff(lval, rval)

                ftrans.append((lval, [(TRUE(), rval)]))

            if ntype == INIT:
                if (get_type(getnode(nids[1])) == BOOL) or (get_type(
                        getnode(nids[2])) == BOOL):
                    nodemap[nid] = EqualsOrIff(BV2B(getnode(nids[1])),
                                               BV2B(getnode(nids[2])))
                elif get_type(getnode(nids[1])).is_array_type():
                    _type = get_type(getnode(nids[1]))
                    nodemap[nid] = EqualsOrIff(
                        getnode(nids[1]),
                        Array(_type.index_type, default=getnode(nids[2])))
                else:
                    nodemap[nid] = EqualsOrIff(getnode(nids[1]),
                                               getnode(nids[2]))
                initlist.append(getnode(nid))

            if ntype == CONSTRAINT:
                nodemap[nid] = BV2B(getnode(nids[0]))
                invarlist.append(getnode(nid))

            if ntype == BAD:
                nodemap[nid] = getnode(nids[0])

                if len(nids) > 1:
                    assert_name = nids[1]
                    description = "Embedded assertion: {}".format(assert_name)
                else:
                    assert_name = 'embedded_assertion_%i' % prop_count
                    description = 'Embedded assertion number %i' % prop_count
                    prop_count += 1

                # Following problem format (name, description, strformula)
                invar_props.append(
                    (assert_name, description, Not(BV2B(getnode(nid)))))

            if nid not in nodemap:
                Logger.error("Unknown node type \"%s\"" % ntype)

            # get wirename if it exists
            if ntype not in {STATE, INPUT, OUTPUT, BAD}:
                # disregard comments at the end of the line
                try:
                    symbol_idx = nids.index(';')
                    symbol_idx -= 1  # the symbol should be before the comment
                except:
                    # the symbol is just the end
                    symbol_idx = -1

                # check for wirename, if it's an integer, then it's a node ref
                try:
                    a = int(nids[symbol_idx])
                except:
                    try:
                        name = str(nids[symbol_idx])
                        # use the exact name, unless it has already been used
                        wire = Symbol(name, getnode(nids[0]))
                        if wire in ts.vars:
                            wire = FreshSymbol(getnode(nids[0]),
                                               template=name + "%d")
                        invarlist.append(EqualsOrIff(wire, B2BV(nodemap[nid])))
                        ts.add_var(wire)
                    except:
                        pass

        if Logger.level(1):
            name = lambda x: str(nodemap[x]) if nodemap[x].is_symbol() else x
            uncovered = [name(x) for x in nodemap if x not in node_covered]
            uncovered.sort()
            if len(uncovered) > 0:
                Logger.warning("Unlinked nodes \"%s\"" % ",".join(uncovered))

        if not self.symbolic_init:
            init = simplify(And(initlist))
        else:
            init = TRUE()

        invar = simplify(And(invarlist))

        # instead of trans, we're using the ftrans format -- see below
        ts.set_behavior(init, TRUE(), invar)

        # add ftrans
        for var, cond_assign_list in ftrans:
            ts.add_func_trans(var, cond_assign_list)

        hts.add_ts(ts)

        return (hts, invar_props, ltl_props)
Ejemplo n.º 24
0
    def parse_string(self, strinput):

        hts = HTS()
        ts = TS()

        nodemap = {}
        node_covered = set([])

        # list of tuples of var and cond_assign_list
        # cond_assign_list is tuples of (condition, value)
        # where everything is a pysmt FNode
        # for btor, the condition is always True
        ftrans = []

        initlist = []
        invarlist = []

        invar_props = []
        ltl_props = []

        prop_count = 0

        # clean string input, remove special characters from names
        for sc, rep in special_char_replacements.items():
            strinput = strinput.replace(sc, rep)

        def getnode(nid):
            node_covered.add(nid)
            if int(nid) < 0:
                return Ite(BV2B(nodemap[str(-int(nid))]), BV(0,1), BV(1,1))
            return nodemap[nid]

        def binary_op(bvop, bop, left, right):
            if (get_type(left) == BOOL) and (get_type(right) == BOOL):
                return bop(left, right)
            return bvop(B2BV(left), B2BV(right))

        def unary_op(bvop, bop, left):
            if (get_type(left) == BOOL):
                return bop(left)
            return bvop(left)

        for line in strinput.split(NL):
            linetok = line.split()
            if len(linetok) == 0:
                continue
            if linetok[0] == COM:
                continue

            (nid, ntype, *nids) = linetok

            if ntype == SORT:
                (stype, *attr) = nids
                if stype == BITVEC:
                    nodemap[nid] = BVType(int(attr[0]))
                    node_covered.add(nid)
                if stype == ARRAY:
                    nodemap[nid] = ArrayType(getnode(attr[0]), getnode(attr[1]))
                    node_covered.add(nid)

            if ntype == WRITE:
                nodemap[nid] = Store(*[getnode(n) for n in nids[1:4]])

            if ntype == READ:
                nodemap[nid] = Select(getnode(nids[1]), getnode(nids[2]))

            if ntype == ZERO:
                nodemap[nid] = BV(0, getnode(nids[0]).width)

            if ntype == ONE:
                nodemap[nid] = BV(1, getnode(nids[0]).width)

            if ntype == ONES:
                width = getnode(nids[0]).width
                nodemap[nid] = BV((2**width)-1, width)

            if ntype == REDOR:
                width = get_type(getnode(nids[1])).width
                zeros = BV(0, width)
                nodemap[nid] = BVNot(BVComp(getnode(nids[1]), zeros))

            if ntype == REDXOR:
                width = get_type(getnode(nids[1])).width
                nodemap[nid] = BV(0, width)
                zeros = BV(0, width)
                for yx_i in range(width):
                  tmp = BV(1 << yx_i, width)
                  tmp_2 = BVAnd(tmp, B2BV(getnode(nids[1])))
                  tmp_3 = BVZExt(B2BV(BVComp(tmp_2, zeros)), int(width - 1))
                  nodemap[nid] = BVAdd(tmp_3, nodemap[nid])
                nodemap[nid] = BVComp(BVAnd(BV(1, width), nodemap[nid]), BV(1, width))

            if ntype == REDAND:
                width = get_type(getnode(nids[1])).width
                ones = BV((2**width)-1, width)
                nodemap[nid] = BVComp(getnode(nids[1]), ones)

            if ntype == CONSTD:
                width = getnode(nids[0]).width
                nodemap[nid] = BV(int(nids[1]), width)

            if ntype == CONST:
                width = getnode(nids[0]).width
                nodemap[nid] = BV(bin_to_dec(nids[1]), width)

            if ntype == STATE:
                if len(nids) > 1:
                    nodemap[nid] = Symbol(nids[1], getnode(nids[0]))
                else:
                    nodemap[nid] = Symbol((SN%nid), getnode(nids[0]))
                ts.add_state_var(nodemap[nid])

            if ntype == INPUT:
                if len(nids) > 1:
                    nodemap[nid] = Symbol(nids[1], getnode(nids[0]))
                else:
                    nodemap[nid] = Symbol((SN%nid), getnode(nids[0]))
                ts.add_input_var(nodemap[nid])

            if ntype == OUTPUT:
                # unfortunately we need to create an extra symbol just to have the output name
                # we could be smarter about this, but then this parser can't be greedy
                original_symbol = getnode(nids[0])
                output_symbol = Symbol(nids[1], original_symbol.get_type())
                nodemap[nid] = EqualsOrIff(output_symbol, original_symbol)
                invarlist.append(nodemap[nid])
                node_covered.add(nid)
                ts.add_output_var(output_symbol)

            if ntype == AND:
                nodemap[nid] = binary_op(BVAnd, And, getnode(nids[1]), getnode(nids[2]))

            if ntype == CONCAT:
                nodemap[nid] = BVConcat(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == XOR:
                nodemap[nid] = binary_op(BVXor, Xor, getnode(nids[1]), getnode(nids[2]))

            if ntype == XNOR:
                nodemap[nid] = BVNot(binary_op(BVXor, Xor, getnode(nids[1]), getnode(nids[2])))

            if ntype == NAND:
                bvop = lambda x,y: BVNot(BVAnd(x, y))
                bop = lambda x,y: Not(And(x, y))
                nodemap[nid] = binary_op(bvop, bop, getnode(nids[1]), getnode(nids[2]))

            if ntype == IMPLIES:
                nodemap[nid] = BVOr(BVNot(getnode(nids[1])), getnode(nids[2]))

            if ntype == NOT:
                nodemap[nid] = unary_op(BVNot, Not, getnode(nids[1]))

            if ntype == NEG:
                nodemap[nid] = unary_op(BVNeg, Not, getnode(nids[1]))

            if ntype == UEXT:
                nodemap[nid] = BVZExt(B2BV(getnode(nids[1])), int(nids[2]))

            if ntype == SEXT:
                nodemap[nid] = BVSExt(B2BV(getnode(nids[1])), int(nids[2]))

            if ntype == OR:
                nodemap[nid] = binary_op(BVOr, Or, getnode(nids[1]), getnode(nids[2]))

            if ntype == ADD:
                nodemap[nid] = BVAdd(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == SUB:
                nodemap[nid] = BVSub(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == UGT:
                nodemap[nid] = BVUGT(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == UGTE:
                nodemap[nid] = BVUGE(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == ULT:
                nodemap[nid] = BVULT(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == ULTE:
                nodemap[nid] = BVULE(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == SGT:
                nodemap[nid] = BVSGT(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == SGTE:
                nodemap[nid] = BVSGE(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == SLT:
                nodemap[nid] = BVSLT(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == SLTE:
                nodemap[nid] = BVSLE(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == EQ:
                nodemap[nid] = BVComp(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == NEQ:
                nodemap[nid] = BVNot(BVComp(getnode(nids[1]), getnode(nids[2])))

            if ntype == MUL:
                nodemap[nid] = BVMul(B2BV(getnode(nids[1])), B2BV(getnode(nids[2])))

            if ntype == SLICE:
                nodemap[nid] = BVExtract(B2BV(getnode(nids[1])), int(nids[3]), int(nids[2]))

            if ntype == SLL:
                nodemap[nid] = BVLShl(getnode(nids[1]), getnode(nids[2]))

            if ntype == SRA:
                nodemap[nid] = BVAShr(getnode(nids[1]), getnode(nids[2]))

            if ntype == SRL:
                nodemap[nid] = BVLShr(getnode(nids[1]), getnode(nids[2]))

            if ntype == ITE:
                if (get_type(getnode(nids[2])) == BOOL) or (get_type(getnode(nids[3])) == BOOL):
                    nodemap[nid] = Ite(BV2B(getnode(nids[1])), B2BV(getnode(nids[2])), B2BV(getnode(nids[3])))
                else:
                    nodemap[nid] = Ite(BV2B(getnode(nids[1])), getnode(nids[2]), getnode(nids[3]))

            if ntype == NEXT:
                if (get_type(getnode(nids[1])) == BOOL) or (get_type(getnode(nids[2])) == BOOL):
                    lval = TS.get_prime(getnode(nids[1]))
                    rval = BV2B(getnode(nids[2]))
                else:
                    lval = TS.get_prime(getnode(nids[1]))
                    rval = getnode(nids[2])

                nodemap[nid] = EqualsOrIff(lval, rval)

                ftrans.append(
                     (lval,
                     [(TRUE(), rval)])
                )

            if ntype == INIT:
                if (get_type(getnode(nids[1])) == BOOL) or (get_type(getnode(nids[2])) == BOOL):
                    nodemap[nid] = EqualsOrIff(BV2B(getnode(nids[1])), BV2B(getnode(nids[2])))
                else:
                    nodemap[nid] = EqualsOrIff(getnode(nids[1]), getnode(nids[2]))
                initlist.append(getnode(nid))

            if ntype == CONSTRAINT:
                nodemap[nid] = BV2B(getnode(nids[0]))
                invarlist.append(getnode(nid))

            if ntype == BAD:
                nodemap[nid] = getnode(nids[0])

                if ASSERTINFO in line:
                    filename_lineno = os.path.basename(nids[3])
                    assert_name = 'embedded_assertion_%s'%filename_lineno
                    description = "Embedded assertion at line {1} in {0}".format(*filename_lineno.split(COLON_REP))
                else:
                    assert_name = 'embedded_assertion_%i'%prop_count
                    description = 'Embedded assertion number %i'%prop_count
                    prop_count += 1

                # Following problem format (name, description, strformula)
                invar_props.append((assert_name, description, Not(BV2B(getnode(nid)))))

            if nid not in nodemap:
                Logger.error("Unknown node type \"%s\""%ntype)

            # get wirename if it exists
            if ntype not in {STATE, INPUT, OUTPUT, BAD}:
                # check for wirename, if it's an integer, then it's a node ref
                try:
                    a = int(nids[-1])
                except:
                    try:
                        wire = Symbol(str(nids[-1]), getnode(nids[0]))
                        invarlist.append(EqualsOrIff(wire, B2BV(nodemap[nid])))
                        ts.add_var(wire)
                    except:
                        pass

        if Logger.level(1):
            name = lambda x: str(nodemap[x]) if nodemap[x].is_symbol() else x
            uncovered = [name(x) for x in nodemap if x not in node_covered]
            uncovered.sort()
            if len(uncovered) > 0:
                Logger.warning("Unlinked nodes \"%s\""%",".join(uncovered))

        if not self.symbolic_init:
            init = simplify(And(initlist))
        else:
            init = TRUE()

        invar = simplify(And(invarlist))

        # instead of trans, we're using the ftrans format -- see below
        ts.set_behavior(init, TRUE(), invar)

        # add ftrans
        for var, cond_assign_list in ftrans:
            ts.add_func_trans(var, cond_assign_list)

        hts.add_ts(ts)

        return (hts, invar_props, ltl_props)
Ejemplo n.º 25
0
def test_normalization():
    def get_normalization_file(filename):
        return path.join(path.dirname(__file__), "res", "renorm_bug", filename)

    for i in range(5):
        domain = Domain.from_file(get_normalization_file("domain.json"))
        support = read_smtlib(get_normalization_file("vanilla.support"))
        weight = read_smtlib(get_normalization_file("vanilla.weight"))
        new_support = read_smtlib(
            get_normalization_file("renorm_chi_{}.support".format(i)))

        # print(smt_to_nested(support))

        clean_support = normalize_formula(support)
        clean_new_support = normalize_formula(new_support)
        clean_weight = normalize_formula(weight)

        print(smt_to_nested(clean_weight))

        assert (RejectionEngine(domain, ~Iff(support, clean_support),
                                Real(1.0), 1000000).compute_volume() == 0)
        assert (RejectionEngine(domain, ~Iff(new_support, clean_new_support),
                                Real(1.0), 1000000).compute_volume() == 0)

        # plot_formula("new_support", domain, new_support, ["r0", "r1"])
        # plot_formula("clean_new_support", domain, clean_new_support, ["r0", "r1"])

        support = clean_support
        new_support = clean_new_support
        weight = clean_weight

        # print(RejectionEngine(domain, Iff(weight, ~clean_weight), Real(1.0), 1000000).compute_volume())

        # print(smt_to_nested(support))

        print("Problem", i)
        engine = XaddEngine(domain, support, weight, "original")
        print("Volume before starting", engine.compute_volume())
        new_weight = engine.normalize(new_support, paths=False)

        Density(domain, new_support, new_weight).to_file("normalized.json")

        illegal_volume = XaddEngine(domain, ~new_support, new_weight,
                                    "mass").compute_volume()
        assert illegal_volume == pytest.approx(0, rel=EXACT_REL_ERROR)

        computed_volume = XaddEngine(domain, TRUE(), new_weight,
                                     "mass").compute_volume()
        computed_volume_within = XaddEngine(domain, new_support, new_weight,
                                            "mass").compute_volume()
        computed_volume_within2 = XaddEngine(domain, new_support,
                                             new_weight).compute_volume()
        computed_volume_within3 = RejectionEngine(domain, new_support,
                                                  new_weight,
                                                  1000000).compute_volume()
        print(
            "pa new_support new_weight",
            computed_volume_within,
            "xadd new_support new_weight:",
            computed_volume_within2,
            "rej new_support new_weight:",
            computed_volume_within3,
        )
        assert computed_volume_within == pytest.approx(computed_volume_within2,
                                                       EXACT_REL_ERROR)
        print(
            "pa true new_weight:",
            computed_volume,
            "pa new_support new_weight",
            computed_volume_within,
            "pa outside new_support new_weight",
            illegal_volume,
        )
        assert computed_volume == pytest.approx(1, rel=EXACT_REL_ERROR)
        assert computed_volume_within == pytest.approx(1, rel=EXACT_REL_ERROR)

        illegal_volume = engine.copy_with(support=~new_support,
                                          weight=new_weight).compute_volume()
        assert illegal_volume == pytest.approx(0, rel=EXACT_REL_ERROR)
Ejemplo n.º 26
0
 def test_contains(self):
     x, y, z = [FreshSymbol() for _ in xrange(3)]
     d = {x: TRUE(), y: FALSE()}
     model = EagerModel(assignment=d)
     self.assertTrue(x in model)
     self.assertFalse(z in model)
Ejemplo n.º 27
0
    def comb_attack(self):
        # dis generator
        solver_name = 'btor'
        solver_obf = Solver(name=solver_name)
        solver_key = Solver(name=solver_name)
        solver_oracle = Solver(name=solver_name)
        attack_formulas = FormulaGenerator(self.oracle_cir, self.obf_cir)

        f = attack_formulas.dip_gen_ckt
        # f = simplify(f)
        solver_obf.add_assertion(f)

        f = attack_formulas.key_inequality_ckt
        # f = simplify(f)
        solver_obf.add_assertion(f)

        iteration = 0
        while 1:
            # query dip generator
            if solver_obf.solve():
                dip_formula = []
                dip_boolean = []
                for l in self.obf_cir.input_wires:
                    t = Symbol(l)
                    if solver_obf.get_py_value(t):
                        dip_formula.append(t)
                        dip_boolean.append(TRUE())
                    else:
                        dip_formula.append(Not(t))
                        dip_boolean.append(FALSE())
                logging.info(dip_formula)

                # query oracle
                dip_out = []
                for l in self.oracle_cir.output_wires:
                    t = self.oracle_cir.wire_objs[l].formula
                    solver_oracle.reset_assertions()
                    solver_oracle.add_assertion(t)
                    if solver_oracle.solve(dip_formula):
                        dip_out.append(TRUE())
                    else:
                        dip_out.append(FALSE())
                logging.info(dip_out)

                # add dip checker
                f = []
                for i in range(len(attack_formulas.dip_chk1)):
                    f.append(And(Iff(dip_out[i], attack_formulas.dip_chk1[i]),
                                 Iff(dip_out[i], attack_formulas.dip_chk2[i])))
                f = And(f)

                subs = {}
                for i in range(len(self.obf_cir.input_wires)):
                    subs[Symbol(self.obf_cir.input_wires[i])] = dip_boolean[i]

                # f = simplify(f)
                f = substitute(f, subs)
                solver_obf.add_assertion(f)
                solver_key.add_assertion(f)

                iteration += 1
                logging.warning('iteration: {}'.format(iteration))
            else:
                logging.warning('print keys')
                if solver_key.solve():
                    key = ''
                    for i in range(len(self.obf_cir.key_wires)):
                        k = 'keyinput{}_0'.format(i)
                        if solver_key.get_py_value(Symbol(k)):
                            key += '1'
                        else:
                            key += '0'
                    print("key=%s" % key)
                else:
                    logging.critical('key solver returned UNSAT')
                return
Ejemplo n.º 28
0
 def times_neutral(self):
     return TRUE()
Ejemplo n.º 29
0
    def parse_string(self, lines):

        [none, var, state, input, output, init, invar, trans,
         ftrans] = range(9)
        section = none

        inits = TRUE()
        invars = TRUE()
        transs = TRUE()
        ftranss = {}

        sparser = StringParser()

        count = 0
        vars = set([])
        states = set([])
        inputs = set([])
        outputs = set([])
        invar_props = []
        ltl_props = []

        for line in lines:
            count += 1

            if (line.strip() in ["", "\n"]) or line[0] == T_COM:
                continue

            if T_VAR == line[:len(T_VAR)]:
                section = var
                continue

            if T_STATE == line[:len(T_STATE)]:
                section = state
                continue

            if T_INPUT == line[:len(T_INPUT)]:
                section = input
                continue

            if T_OUTPUT == line[:len(T_OUTPUT)]:
                section = output
                continue

            if T_INIT == line[:len(T_INIT)]:
                section = init
                continue

            if T_INVAR == line[:len(T_INVAR)]:
                section = invar
                continue

            if T_TRANS == line[:len(T_TRANS)]:
                section = trans
                continue

            if T_FTRANS == line[:len(T_FTRANS)]:
                section = ftrans
                continue

            if section in [var, state, input, output]:
                varname, vartype = line[:-2].replace(" ", "").split(":")
                if varname[0] == "'":
                    varname = varname[1:-1]
                vartype = parse_typestr(vartype)
                vardef = self._define_var(varname, vartype)

                vars.add(vardef)
                if section == state:
                    states.add(vardef)
                if section == input:
                    inputs.add(vardef)
                if section == output:
                    outputs.add(vardef)

            if section in [init, invar, trans]:
                line = line.replace(T_SC, "").strip()
                qline = quote_names(line, replace_ops=False)

            if section == init:
                inits = And(inits, sparser.parse_formula(qline))

            if section == invar:
                invars = And(invars, sparser.parse_formula(qline))

            if section == trans:
                transs = And(transs, sparser.parse_formula(qline))

            if section == ftrans:
                strvar = line[:line.find(":=")]
                var = sparser.parse_formula(
                    quote_names(strvar, replace_ops=False))
                cond_ass = line[line.find(":=") + 2:].strip()
                ftranss[var] = []

                for cond_as in cond_ass.split("{"):
                    if cond_as == "":
                        continue
                    cond = cond_as[:cond_as.find(",")]
                    ass = cond_as[cond_as.find(",") + 1:cond_as.find("}")]
                    ftranss[var].append((sparser.parse_formula(
                        quote_names(cond, replace_ops=False)),
                                         sparser.parse_formula(
                                             quote_names(ass,
                                                         replace_ops=False))))

        hts = HTS("STS")
        ts = TS()

        ts.vars = vars
        ts.state_vars = states
        ts.input_vars = inputs
        ts.output_vars = outputs
        ts.init = inits
        ts.invar = invars
        ts.trans = transs
        ts.ftrans = ftranss

        hts.add_ts(ts)

        return (hts, invar_props, ltl_props)
Ejemplo n.º 30
0
    def _test_auto_aux(self, auto_env):
        def _check_auto_tautologies(auto):
            self.assertTrue(auto.is_equivalent(auto))
            self.assertTrue(auto.is_equivalent(auto.copy_reachable()))
            self.assertTrue(auto.is_equivalent(auto.complete()))
            self.assertTrue(auto.is_equivalent(auto.determinize()))
            self.assertTrue(auto.is_equivalent(auto.union(auto)))
            self.assertTrue(auto.is_equivalent((auto.reverse()).reverse()))
            self.assertTrue(auto.is_equivalent(auto.minimize()))

        symbols = [Symbol(chr(i), BOOL) for i in range(ord('a'), ord('z') + 1)]

        a = auto_env.new_label(symbols[0])
        b = auto_env.new_label(symbols[1])
        c = auto_env.new_label(symbols[2])

        # test copy
        auto_a = Automaton.get_singleton(a, auto_env)
        self.assertTrue(auto_a.is_equivalent(auto_a))

        copy_1 = auto_a.copy_reachable()
        copy_2 = copy_1.copy_reachable()
        det = auto_a.determinize()
        twice_neg = auto_a.complement().complement()
        complete = auto_a.complete()
        for auto in [auto_a, copy_1, copy_2, twice_neg, complete]:
            self.assertFalse(auto.is_empty())
            self.assertTrue(auto.accept([a]))
            self.assertFalse(auto.accept([a, a]))
            _check_auto_tautologies(auto)

        auto_a_neg = auto_a.complement()
        self.assertFalse(auto_a_neg.accept([a]))
        self.assertTrue(auto_a_neg.accept([a, a]))
        self.assertTrue(auto_a_neg.accept([b]))

        # aa
        auto_aa = auto_a.concatenate(auto_a)
        det = auto_aa.determinize()
        twice_neg = auto_aa.complement().complement()
        complete = auto_aa.complete()
        for auto in [auto_aa, det, twice_neg, complete]:
            self.assertFalse(auto.is_empty())
            self.assertFalse(auto.accept([a]))
            self.assertTrue(auto.accept([a, a]))
            self.assertFalse(auto.accept([a, a, a]))
            _check_auto_tautologies(auto)

        auto_aa_neg = auto_aa.complement()
        self.assertTrue(auto_aa_neg.accept([a]))
        self.assertTrue(auto_aa_neg.accept([b]))
        self.assertFalse(auto_aa_neg.accept([a, a]))
        self.assertTrue(auto_aa_neg.accept([a, a, a]))

        # a[*]
        auto_astar = auto_a.klenee_star()
        det = auto_astar.determinize()
        twice_neg = auto_astar.complement().complement()
        complete = auto_astar.complete()
        for auto in [auto_astar, det, twice_neg, complete]:
            self.assertFalse(auto.is_empty())
            self.assertTrue(auto.accept([]))
            self.assertTrue(auto.accept([a, a]))
            self.assertTrue(auto.accept([a, a, a]))
            _check_auto_tautologies(auto)

        # TRUE
        aut_true = Automaton.get_singleton(auto_env.new_label(TRUE()),
                                           auto_env)
        twice_neg = aut_true.complement().complement()
        det = aut_true.determinize()
        complete = aut_true.complete()
        for auto in [aut_true, det, twice_neg, complete]:
            self.assertFalse(det.is_empty())
            self.assertFalse(det.accept([]))
            self.assertTrue(det.accept([a]))
            self.assertTrue(det.accept([b]))
            self.assertTrue(det.accept([c]))
            self.assertFalse(det.accept([a, b]))
            _check_auto_tautologies(auto)

        # TRUE[*]
        aut_truestar = aut_true.klenee_star()
        twice_neg = aut_truestar.complement().complement()
        det = aut_truestar.determinize()
        complete = aut_truestar.complete()
        for auto in [aut_truestar, det, twice_neg, complete]:
            self.assertFalse(auto.is_empty())
            self.assertTrue(auto.accept([]))
            self.assertTrue(auto.accept([a]))
            self.assertTrue(auto.accept([b]))
            self.assertTrue(auto.accept([c]))
            self.assertTrue(auto.accept([a, b]))
            _check_auto_tautologies(auto)

        a = Automaton()
        self.assertTrue(a.is_empty())
        a = Automaton.get_empty(auto_env)
        self.assertTrue(a.is_empty())