Пример #1
0
    def Uop(bvop, bop, in_, out):
        # INVAR: (<op> in) = out)
        vars_ = [in_, out]
        comment = ""  #(bvop.__name__ + " (in, out) = (%s, %s)")%(tuple([x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

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

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

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

        ts = TS(comment)
        ts.vars, ts.invar = get_free_variables(invar), invar
        return ts
Пример #2
0
    def Mux(in0, in1, sel, out):
        # if Modules.functional
        # INVAR: out' = Ite(sel = 0, in0, in1)
        # else
        # INVAR: ((sel = 0) -> (out = in0)) & ((sel = 1) -> (out = in1))
        vars_ = [in0, in1, sel, out]
        comment = "Mux (in0, in1, sel, out) = (%s, %s, %s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

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

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

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Пример #3
0
    def Clock(clk):
        # INIT: clk = 0
        # TRANS: clk' = !clk
        comment = "Clock (clk) = (" + clk.symbol_name() + ")"

        if clk.symbol_type() == BOOL:
            clk0 = Not(clk)
            clk1 = clk
        else:
            clk0 = EqualsOrIff(clk, BV(0, 1))
            clk1 = EqualsOrIff(clk, BV(1, 1))

        init = clk0

        invar = TRUE()

        if False:
            trans = EqualsOrIff(clk0, TS.to_next(clk1))
        else:
            # Implementation that leverages on the boolean propagation
            trans1 = Implies(clk0, TS.to_next(clk1))
            trans2 = Implies(clk1, TS.to_next(clk0))
            trans = And(trans1, trans2)

        if Modules.abstract_clock:
            invar = clk0
            init = TRUE()
            trans = TRUE()

        ts = TS(comment)
        ts.vars, ts.state_vars = set([clk]), set([clk])
        ts.set_behavior(init, trans, invar)
        return ts
Пример #4
0
    def solve_safety_inc_zz(self, hts, prop, k):
        self._reset_assertions(self.solver)

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

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

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

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

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

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

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

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

            self._pop(self.solver)

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

            self._add_assertion(self.solver, trans_t)

            t += 1

        return (t - 1, None)
Пример #5
0
    def Orr(in_, out):
        # INVAR: (in = 0) -> (out = 0) & (in != 0) -> (out = 1)
        vars_ = [in_, out]
        comment = "Orr (in, out) = (%s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

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

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

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

            invar = And(true_res, false_res)

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Пример #6
0
    def dag_shape(self, model):
        partial_model = []
        
        for (label, value) in model:
            if value.is_false():
                continue
            else:
                s = label.symbol_name()
#                print(s)
                #Type x, l or r
                if(s[0] == 'x'):
#                    print('VALUE+++++++',s)
                    partial_model.append(EqualsOrIff(label, value))
                    
                if(s[0] == 'l'):
#                    print('LEFT+++++++',s)
                    partial_model.append(EqualsOrIff(label, value))                    
#                    partial_model.append(EqualsOrIff(label, value))
                if(s[0] == 'r'):
#                    print('RIGHT+++++++',s)
                    partial_model.append(EqualsOrIff(label, value))                    
#                    partial_model.append(EqualsOrIff(label, value))                    
#                    print(s,'vertex', s[2], s[4:])
                    
#                else:
#                    print(s,s[0], 'edge', s[2], s[4])
    
        return partial_model
Пример #7
0
 def Negedge(self, x):
     if get_type(x).is_bool_type():
         if (self.encoder_config is not None) and (self.encoder_config.abstract_clock):
             return Not(x)
         return And(x, Not(TS.to_next(x)))
     if (self.encoder_config is not None) and (self.encoder_config.abstract_clock):
         return EqualsOrIff(x, BV(0,1))
     return And(BV2B(x), EqualsOrIff(TS.to_next(x), BV(0,1)))
Пример #8
0
 def Posedge(self, x):
     if get_type(x).is_bool_type():
         if (self.encoder_config is not None) and (self.encoder_config.abstract_clock):
             return x
         return And(Not(x), TS.to_next(x))
     if (self.encoder_config is not None) and (self.encoder_config.abstract_clock):
         return EqualsOrIff(x, BV(1,1))
     return And(EqualsOrIff(x, BV(0,1)), BV2B(TS.to_next(x)))
Пример #9
0
    def get_ordered_zero(self):
        self.zero = None
        self.firste = None
        self.le = None
        res = []
        for g in self.curr._globals:
            gstr = pretty_print_str(g)
            if gstr == "zero":
                gt = g.symbol_type()
                assert (gt in self._enumsorts)
                domain = self._enumsorts[gt]
                eq = EqualsOrIff(g, domain[0])
                res.append(eq)
                self.zero = (domain[0], g)
            elif gstr == "firste":
                gt = g.symbol_type()
                assert (gt in self._enumsorts)
                domain = self._enumsorts[gt]
                eq = EqualsOrIff(g, domain[1])
                res.append(eq)
                self.firste = (domain[1], g)

        for pre in self.curr._le:
            pret = pre.symbol_type()
            orderedt = pret.param_types[0]
            if orderedt in self._enumsorts:
                self._ordered_sorts[orderedt] = pre
                self.le = pre
                domain = self._enumsorts[orderedt]
                #                 end = 2
                end = len(domain)
                for i in range(end):
                    for j in range(i, end):
                        arg1 = domain[i]
                        arg2 = domain[j]
                        rel1 = Function(pre, [arg1, arg2])
                        rel2 = Function(pre, [arg2, arg1])
                        if (i == j):
                            res.append(rel1)
                        elif (i < j):
                            res.append(rel1)
                            res.append(Not(rel2))
                        elif (i > j):
                            res.append(Not(rel1))
                            res.append(rel2)
                        else:
                            assert (0)

        if len(res) == 0:
            return TRUE()
        else:
            print("\nZero axiom: ")
            for v in res:
                print("\t", end="")
                pretty_print(v)
            return And(res)
Пример #10
0
 def Andr(in_, out):
     # INVAR: (in = 2**width - 1) -> (out = 1) & (in != 2**width - 1) -> (out = 0)
     vars_ = [in_, out]
     comment = "Andr (in, out) = (%s, %s)"%(tuple([x.symbol_name() for x in vars_]))
     Logger.log(comment, 3)
     width = in_.symbol_type().width
     eq_all_ones = EqualsOrIff(in_, BV(2**width - 1,width))
     true_res = Implies(eq_all_ones, EqualsOrIff(out, BV(1,1)))
     false_res = Implies(Not(eq_all_ones), EqualsOrIff(out, BV(0,1)))
     invar = And(true_res, false_res)
     ts = TS(comment)
     ts.vars, ts.invar = set(vars_), invar
     return ts
Пример #11
0
def mem_access(addr, locations, width_idx, idx=0):
    first_loc = min(2**width_idx, len(locations)) - 1
    ite_chain = locations[first_loc]
    for i in reversed(range(0, first_loc)):
        location = BV(i, width_idx)
        ite_chain = Ite(EqualsOrIff(addr, location), locations[i], ite_chain)
    return ite_chain
Пример #12
0
    def flatten(self, path=[]):

        vardic = dict([(v.symbol_name(), v) for v in self.vars])
        for sub in self.subs:
            instance, actual, module = sub
            formal = module.params

            ts = TS("FLATTEN")
            (ts.init, ts.trans, ts.invar) = module.flatten(path + [instance])
            self.add_ts(ts)

            links = TRUE()
            for i in range(len(actual)):
                local_var = ".".join(path + [actual[i]])
                module_var = sub[2].newname(formal[i].symbol_name(),
                                            path + [sub[0]])
                links = And(links,
                            EqualsOrIff(vardic[local_var], vardic[module_var]))

            ts = TS("LINKS")
            ts.invar = links
            self.add_ts(ts)

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

        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])

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

        return (s_init, s_trans, s_invar)
Пример #13
0
 def _op_raw_eq(self, *args):
     # We emulate the integer through a bitvector but
     # since a constraint with the form (assert (= (str.len Symb_str) bit_vect))
     # is not valid we need to tranform the concrete vqalue of the bitvector in an integer
     #
     # TODO: implement logic for integer
     return EqualsOrIff(*_normalize_arguments(*args))
Пример #14
0
    def all_loopbacks(self, vars, k, heqvar=None):
        lvars = list(vars)
        vars_k = [TS.get_timed(v, k) for v in lvars]
        loopback = FALSE()
        eqvar = None
        heqvars = None

        if heqvar is not None:
            eqvar = Symbol(EQVAR, BOOL)
            heqvars = []

        peqvars = FALSE()

        for i in range(k):
            vars_i = [TS.get_timed(v, i) for v in lvars]
            eq_k_i = And(
                [EqualsOrIff(vars_k[j], vars_i[j]) for j in range(len(lvars))])
            if heqvar is not None:
                eqvar_i = TS.get_timed(eqvar, i)
                peqvars = Or(peqvars, eqvar_i)
                eq_k_i = And(eqvar_i, Iff(eqvar_i, eq_k_i))

                heqvars.append(Iff(TS.get_timed(heqvar, i), peqvars))

            loopback = Or(loopback, eq_k_i)

        if heqvar is not None:
            loopback = And(loopback, And(heqvars))

        return loopback
Пример #15
0
def is_long_clause(system, cl):
    sort2sz = {}
    cube = Not(cl)
    if cube.is_exists():
        qvars = cube.quantifier_vars()
        for qv in qvars:
            qvt = qv.symbol_type()
            if qvt not in sort2sz:
                sort2sz[qvt] = 0
            sort2sz[qvt] += 1
    fullsorts = set()
    for s_fin in system._enumsorts.keys():
        sz = len(s_fin.domain)
        if sz < 3:
            continue
        if s_fin in sort2sz:
            if sort2sz[s_fin] >= sz:
                fullsorts.add(s_fin)
    if len(fullsorts) == 0:
        return False
    atoms = cube.get_atoms()
    for enumsort in fullsorts:
        isLong = True
        enumqvars = system._enum2qvar[enumsort]
        for i in range(len(enumqvars)-1):
            for j in range(i+1, len(enumqvars)):
                eq = EqualsOrIff(enumqvars[i], enumqvars[j])
                if eq not in atoms:
                    isLong = False
                    break
            if not isLong:
                break
        if isLong:
            return True
    return False
Пример #16
0
    def _get_param_assignments(self, model, time, parameters, monotonic=True):
        p_ass = []

        fwd = False

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

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

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

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

        return (p_ass, False)
Пример #17
0
    def _get_param_assignments(self, model, time, parameters, monotonic=True):
        p_ass = []

        fwd = False

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

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

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

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

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

        return (p_ass, False)
Пример #18
0
 def solve(self, formula):
     """Provides a satisfiable assignment to the state variables that are consistent with the input formula"""
     if self.solver.solve([formula]):
         return And([
             EqualsOrIff(v, self.solver.get_value(v))
             for v in self.system.variables
         ])
     return None
Пример #19
0
    def get_sts(self, params):
        if len(params) != len(self.interface.split()):
            Logger.error("Invalid parameters for clock behavior \"%s\"" %
                         (self.name))
        clk = params[0]
        valuepar = params[1]

        if (not type(clk) == FNode) or (not clk.is_symbol()):
            Logger.error("Clock symbol \"%s\" not found" % (str(clk)))

        if (type(valuepar) == FNode) and (valuepar.is_bv_constant()):
            value = valuepar.constant_value()
        else:
            try:
                value = int(valuepar)
            except:
                Logger.error(
                    "Clock value should be an integer number instead of \"%s\""
                    % valuepar)

        init = []
        invar = []
        trans = []
        vars = set([])

        if clk.symbol_type().is_bv_type():
            pos_clk = EqualsOrIff(clk, BV(1, 1))
            neg_clk = EqualsOrIff(clk, BV(0, 1))
        else:
            pos_clk = clk
            neg_clk = Not(clk)

        if value == 1:
            invar.append(pos_clk)
        else:
            invar.append(neg_clk)

        ts = TS("Clock Behavior")
        ts.vars, ts.init, ts.invar, ts.trans = vars, And(init), And(
            invar), And(trans)

        Logger.log(
            "Adding clock behavior \"%s(%s)\"" %
            (self.name, ", ".join([str(p) for p in params])), 1)

        return ts
Пример #20
0
    def check_equal_and_valid(self, formula, expected):
        simplified = formula.simplify()

        self.assertEqual(simplified, expected)

        # Check the formula equality by a solver.
        if self.env.factory.all_solvers(QF_BV):
            self.assertValid(EqualsOrIff(simplified, formula), logic=QF_BV)
Пример #21
0
    def compile_ftrans(self):
        if self.ftrans is None:
            return None

        ret_trans = TRUE()
        ret_invar = TRUE()

        use_ites = False

        if use_ites:
            for var, cond_assign_list in self.ftrans.items():
                if TS.has_next(var):
                    ite_list = TS.to_prev(var)
                else:
                    ite_list = var
                for (condition, value) in reversed(cond_assign_list):
                    if condition == TRUE():
                        ite_list = value
                    else:
                        ite_list = Ite(condition, value, ite_list)

                if TS.has_next(ite_list):
                    ret_trans = And(ret_trans, EqualsOrIff(var, ite_list))
                else:
                    ret_invar = And(ret_invar, EqualsOrIff(var, ite_list))
        else:
            for var, cond_assign_list in self.ftrans.items():
                effects = []
                all_neg_cond = []
                for (condition, value) in cond_assign_list:
                    effects.append(
                        simplify(Implies(condition, EqualsOrIff(var, value))))
                    all_neg_cond.append(Not(condition))

                if not TS.has_next(var) and not TS.has_next(condition):
                    ret_invar = And(ret_invar, And(effects))
                else:
                    ret_trans = And(ret_trans, And(effects))

                if TS.has_next(var):
                    no_change = EqualsOrIff(var, TS.to_prev(var))
                    ret_trans = And(
                        ret_trans,
                        simplify(Implies(And(all_neg_cond), no_change)))

        return (ret_invar, ret_trans)
Пример #22
0
def all_smt(formula, keys):
    target_logic = get_logic(formula)
    print("Target Logic: %s" % target_logic)
    with Solver(logic=target_logic) as solver:
        solver.add_assertion(formula)
        while solver.solve():
            partial_model = [EqualsOrIff(k, solver.get_value(k)) for k in keys]
            print(partial_model)
            solver.add_assertion(Not(And(partial_model)))
Пример #23
0
 def Wrap(in_, out):
     # INVAR: (in = out)
     vars_ = [in_,out]
     comment = ("Wrap (in, out) = (%s, %s)")%(tuple([x.symbol_name() for x in vars_]))
     Logger.log(comment, 3)
     invar = EqualsOrIff(in_, out)
     ts = TS(comment)
     ts.vars, ts.invar = set(vars_), invar
     return ts
Пример #24
0
 def Slice(in_, out, low, high):
     # INVAR: (extract low high in) = out
     high -= 1
     vars_ = [in_,out, low, high]
     comment = "Mux (in, out, low, high) = (%s, %s, %s, %s)"%(tuple([str(x) for x in vars_]))
     Logger.log(comment, 3)
     invar = EqualsOrIff(BVExtract(in_, low, high), out)
     ts = TS(comment)
     ts.vars, ts.invar = set([in_, out]), invar
     return ts
Пример #25
0
    def Bop(bvop, bop, in0, in1, out):
        # INVAR: (in0 <op> in1) = out
        vars_ = [in0, in1, out]
        comment = (bvop.__name__ + " (in0, in1, out) = (%s, %s, %s)") % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

        in0B = in0.symbol_type() == BOOL
        in1B = in1.symbol_type() == BOOL
        outB = out.symbol_type() == BOOL

        bools = (1 if in0B else 0) + (1 if in1B else 0) + (1 if outB else 0)

        if bop == None:
            if in0B:
                in0 = Ite(in0, BV(1, 1), BV(0, 1))
            if in1B:
                in1 = Ite(in1, BV(1, 1), BV(0, 1))
            if outB:
                out = Ite(out, BV(1, 1), BV(0, 1))

            invar = EqualsOrIff(bvop(in0, in1), out)

        else:
            if bools == 3:
                invar = EqualsOrIff(bop(in0, in1), out)
            elif bools == 0:
                invar = EqualsOrIff(bvop(in0, in1), out)
            elif bools == 1:
                if in0B:
                    invar = EqualsOrIff(bvop(B2BV(in0), in1), out)
                if in1B:
                    invar = EqualsOrIff(bvop(in0, B2BV(in1)), out)
                if outB:
                    invar = EqualsOrIff(BV2B(bvop(in0, in1)), out)
            else:
                if not in0B:
                    invar = EqualsOrIff(bop(BV2B(in0), in1), out)
                if not in1B:
                    invar = EqualsOrIff(bop(in0, BV2B(in1)), out)
                if not outB:
                    invar = EqualsOrIff(B2BV(bop(in0, in1)), out)

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Пример #26
0
def solve(formula, n, max_models=None, solver="msat"):
    s = Solver(name=solver)
    st = s.is_sat(formula)
    if st:
        vs = [x for xs in variables(n) for x in xs]
        k = 0
        s.add_assertion(formula)
        while s.solve() and ((not max_models) or k < max_models):
            k = k + 1
            model = s.get_model()
            s.add_assertion(Not(And([EqualsOrIff(v, model[v]) for v in vs])))
            yield to_bn(model, n)
Пример #27
0
    def Neq(in0, in1, out):
        # INVAR: (((in0 != in1) -> (out = #b1)) & ((in0 == in1) -> (out = #b0)))
        vars_ = [in0, in1, out]
        comment = "Eq (in0, in1, out) = (%s, %s, %s)" % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

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

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

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

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Пример #28
0
    def Zext(in_, out):
        # INVAR: (<op> in) = out)
        vars_ = [in_, out]
        comment = ("ZExt (in, out) = (%s, %s)") % (tuple(
            [x.symbol_name() for x in vars_]))
        Logger.log(comment, 3)

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

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

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

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

        ts = TS(comment)
        ts.vars, ts.invar = set(vars_), invar
        return ts
Пример #29
0
    def MultiOp(op, end_op, out, *inparams):
        cum = inparams[0]
        for el in inparams[1:]:
            cum = op(cum, el)

        if end_op is not None:
            cum = end_op(cum)

        formula = EqualsOrIff(cum, out)

        ts = TS()
        ts.vars, ts.invar = get_free_variables(formula), formula
        return ts
Пример #30
0
    def test_simple_sorts(self):
        # (define-sort I () Int)
        # (define-sort Set (T) (Array T Bool))
        I = INT
        SET = PartialType("Set", lambda t1: ArrayType(t1, BOOL))
        self.assertEqual(ArrayType(INT, BOOL), SET(I))

        # (declare-const s1 (Set I))
        # (declare-const a I)
        # (declare-const b Int)
        s1 = FreshSymbol(SET(I))
        a = FreshSymbol(I)
        b = FreshSymbol(INT)

        # (= (select s1 a) true)
        # (= (select s1 b) false)
        f1 = EqualsOrIff(Select(s1, a), TRUE())
        f2 = EqualsOrIff(Select(s1, b), FALSE())
        self.assertIsNotNone(f1)
        self.assertIsNotNone(f2)

        # Cannot instantiate a PartialType directly:
        with self.assertRaises(PysmtValueError):
            FreshSymbol(SET)

        # (declare-sort A 0)
        # Uninterpreted sort
        A = Type("A", 0)
        B = Type("B")

        c1 = FreshSymbol(A)
        c2 = FreshSymbol(A)
        c3 = FreshSymbol(Type("A"))
        c4 = FreshSymbol(B)
        EqualsOrIff(c1, c2)
        EqualsOrIff(c2, c3)
        with self.assertRaises(PysmtTypeError):
            EqualsOrIff(c1, c4)

        with self.assertRaises(PysmtValueError):
            Type("A", 1)

        C = Type("C", 1)
        CA = self.env.type_manager.get_type_instance(C, A)
        CB = self.env.type_manager.get_type_instance(C, B)
        c5 = FreshSymbol(CA)
        c6 = FreshSymbol(CB)
        self.assertIsNotNone(c5)
        with self.assertRaises(PysmtTypeError):
            EqualsOrIff(c5, c6)

        # Nesting
        self.env.enable_infix_notation = True
        ty = C(C(C(C(C(A)))))
        self.assertIsNotNone(FreshSymbol(ty))

        pty = PartialType("pty", lambda S, T: S(S(S(S(S(T))))))
        self.assertEqual(pty(C, A), ty)