Exemplo n.º 1
0
    def generate_HTS(self, module, modulesdic):
        hts = HTS(module.name)
        ts = TS("TS %s" % module.name)

        init = []
        trans = []
        invar = []
        params = []

        sparser = StringParser()

        (vars, states, inputs,
         outputs) = self._collect_sub_variables(module,
                                                modulesdic,
                                                path=[],
                                                varlist=[],
                                                statelist=[],
                                                inputlist=[],
                                                outputlist=[])

        for var in vars:
            ts.add_var(self._define_var(var, module.name))

        for var in states:
            ts.add_state_var(self._define_var(var, module.name))

        for var in inputs:
            ts.add_input_var(self._define_var(var, module.name))

        for var in outputs:
            ts.add_output_var(self._define_var(var, module.name))

        self._check_parameters(module, modulesdic, ts.vars)

        for par in module.pars:
            assert len(par) == 2, "Expecting a variable"
            hts.add_param(self._define_var((par[0], par[1]), module.name))

        for init_s in module.init:
            formula = sparser.parse_formula(quote_names(init_s, module.name),
                                            False)
            init.append(formula)

        for invar_s in module.invar:
            formula = sparser.parse_formula(quote_names(invar_s, module.name),
                                            False)
            invar.append(formula)

        for trans_s in module.trans:
            formula = sparser.parse_formula(quote_names(trans_s, module.name),
                                            False)
            trans.append(formula)

        for sub in module.subs:
            hts.add_sub(sub[0],
                        self.generate_HTS(modulesdic[sub[1]], modulesdic),
                        tuple([v[0] for v in sub[2]]))

        ts.init = And(init)
        ts.invar = And(invar)
        ts.trans = And(trans)

        hts.add_ts(ts)

        return hts
Exemplo n.º 2
0
Arquivo: btor2.py Projeto: 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)
Exemplo n.º 3
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)
Exemplo n.º 4
0
    def parse_string(self, strinput):

        hts = HTS()
        ts = TS()

        nodemap = {}
        node_covered = set([])

        translist = []
        initlist = []
        invarlist = []

        invar_props = []
        ltl_props = []

        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
                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:
                if len(nids) > 2:
                    symbol = Symbol(nids[2], getnode(nids[0]))
                else:
                    symbol = Symbol((SN%nid), getnode(nids[0]))

                nodemap[nid] = EqualsOrIff(symbol, B2BV(getnode(nids[1])))
                invarlist.append(nodemap[nid])
                node_covered.add(nid)
                ts.add_output_var(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 == 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 == UEXT:
                nodemap[nid] = BVZExt(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 == EQ:
                nodemap[nid] = BVComp(getnode(nids[1]), getnode(nids[2]))

            if ntype == NE:
                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])), BV2B(getnode(nids[2])), BV2B(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):
                    nodemap[nid] = EqualsOrIff(BV2B(TS.get_prime(getnode(nids[1]))), BV2B(getnode(nids[2])))
                else:
                    nodemap[nid] = EqualsOrIff(TS.get_prime(getnode(nids[1])), getnode(nids[2]))
                translist.append(getnode(nid))

            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])
                invar_props.append(Not(BV2B(getnode(nid))))

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

        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()
        trans = simplify(And(translist))
        invar = simplify(And(invarlist))

        ts.set_behavior(init, trans, invar)
        hts.add_ts(ts)

        return (hts, invar_props, ltl_props)