示例#1
0
def test_isinstance_str():
    s = 's'
    r = stx.isinstance_str(s)
    assert r is True, r
    s = 0
    r = stx.isinstance_str(s)
    assert r is False, r
示例#2
0
def test_isinstance_str():
    s = 's'
    r = stx.isinstance_str(s)
    assert r is True, r
    s = 0
    r = stx.isinstance_str(s)
    assert r is False, r
示例#3
0
文件: fol.py 项目: johnyf/omega
    def add_expr(self, e, with_ops=False):
        """Add first-order predicate.

        A predicate is a Boolean-valued formula.
        """
        assert stx.isinstance_str(e), e
        # optional because current implementation is slow
        if with_ops:
            defs = self.op
        else:
            defs = None
        s = bv.bitblast(e, vrs=self.vars, defs=defs)
        assert stx.isinstance_str(s), s  # was `e` a predicate ?
        return sym_bdd.add_expr(s, self.bdd)
示例#4
0
    def add_expr(self, e, with_ops=False):
        """Add first-order predicate.

        A predicate is a Boolean-valued formula.
        """
        assert stx.isinstance_str(e), e
        # optional because current implementation is slow
        if with_ops:
            defs = self.op
        else:
            defs = None
        s = bv.bitblast(e, vrs=self.vars, defs=defs)
        assert stx.isinstance_str(s), s  # was `e` a predicate ?
        return sym_bdd.add_expr(s, self.bdd)
示例#5
0
文件: bitvector.py 项目: johnyf/omega
def _flatten_var(v, *arg, **kw):
    """Return `list` of bits, for both integer and Boolean var."""
    flat = v.flatten(*arg, **kw)
    # bool ?
    if stx.isinstance_str(flat):
        flat = [flat]
    bits = _filter_trailing_zeros(flat)
    return bits
示例#6
0
def _flatten_var(v, *arg, **kw):
    """Return `list` of bits, for both integer and Boolean var."""
    flat = v.flatten(*arg, **kw)
    # bool ?
    if stx.isinstance_str(flat):
        flat = [flat]
    bits = _filter_trailing_zeros(flat)
    return bits
示例#7
0
文件: fol.py 项目: johnyf/omega
    def define(self, e):
        """Register operator definitions.

        The string `e` must contain definitions. Example:

        ```python
        e = '''
            a == x + y > 3
            b == z - x <= 0
            c == a /\ b
            '''
        ```

        In the future, this method may merge with `add_expr`.
        """
        assert stx.isinstance_str(e), e
        bv_defs = bv._parser.parse(e)
        defs = _parser.parse(e)
        for opdef, bv_opdef in zip(defs, bv_defs):
            assert opdef.operator == '==', opdef
            name_ast, expr_ast = opdef.operands
            _, bv_ast = bv_opdef.operands
            name = name_ast.value
            if name in self.vars:
                raise ValueError((
                    'Attempted to define operator "{name}", '
                    'but "{name}" already declared as variable: '
                    '{old}').format(
                        name=name, old=self.vars[name]))
            if name in self.op:
                raise ValueError((
                    'Attempted to redefine operator "{name}". '
                    'Previous definition as: "{old}"').format(
                        name=name, old=self.op[name]))
            s = bv_ast.flatten(
                t=self.vars, defs=self.op_bdd)
            assert stx.isinstance_str(s), s
            # sensitive point:
            #     operator expressions are stored before substitutions
            #     operator BDDs are stored after operator substitutions
            # operator definitions cannot change, so this should
            # not cause problems as currently arranged.
            self.op[name] = expr_ast.flatten()
            self.op_bdd[name] = sym_bdd.add_expr(s, self.bdd)
示例#8
0
    def define(self, e):
        """Register operator definitions.

        The string `e` must contain definitions. Example:

        ```python
        e = '''
            a == x + y > 3
            b == z - x <= 0
            c == a /\ b
            '''
        ```

        In the future, this method may merge with `add_expr`.
        """
        assert stx.isinstance_str(e), e
        bv_defs = bv._parser.parse(e)
        defs = _parser.parse(e)
        for opdef, bv_opdef in zip(defs, bv_defs):
            assert opdef.operator == '==', opdef
            name_ast, expr_ast = opdef.operands
            _, bv_ast = bv_opdef.operands
            name = name_ast.value
            if name in self.vars:
                raise ValueError(('Attempted to define operator "{name}", '
                                  'but "{name}" already declared as variable: '
                                  '{old}').format(name=name,
                                                  old=self.vars[name]))
            if name in self.op:
                raise ValueError(('Attempted to redefine operator "{name}". '
                                  'Previous definition as: "{old}"').format(
                                      name=name, old=self.op[name]))
            s = bv_ast.flatten(t=self.vars, defs=self.op_bdd)
            assert stx.isinstance_str(s), s
            # sensitive point:
            #     operator expressions are stored before substitutions
            #     operator BDDs are stored after operator substitutions
            # operator definitions cannot change, so this should
            # not cause problems as currently arranged.
            self.op[name] = expr_ast.flatten()
            self.op_bdd[name] = sym_bdd.add_expr(s, self.bdd)
示例#9
0
    def replace(self, u, vars_to_new):
        """Return substitution of var names by values or vars.

        @param vars_to_new: `dict` that maps each var name to
            a var (as `str`), or to a value (as `bool` or `int`).
        """
        if len(vars_to_new) == 0:  # must be mapping, not `None`
            return u
        assert vars_to_new, vars_to_new
        for k in vars_to_new:
            rename = stx.isinstance_str(vars_to_new[k])
            break
        if rename:
            d = _refine_renaming(vars_to_new, self.vars)
        else:
            d = _refine_assignment(vars_to_new, self.vars)
        return self.bdd.let(d, u)
示例#10
0
文件: fol.py 项目: johnyf/omega
    def replace(self, u, vars_to_new):
        """Return substitution of var names by values or vars.

        @param vars_to_new: `dict` that maps each var name to
            a var (as `str`), or to a value (as `bool` or `int`).
        """
        if len(vars_to_new) == 0:  # must be mapping, not `None`
            return u
        assert vars_to_new, vars_to_new
        for k in vars_to_new:
            rename = stx.isinstance_str(vars_to_new[k])
            break
        if rename:
            d = _refine_renaming(vars_to_new, self.vars)
        else:
            d = _refine_assignment(vars_to_new, self.vars)
        return self.bdd.let(d, u)
示例#11
0
文件: gr1.py 项目: johnyf/omega
def split_gr1_old(f):
    """Earlier implementation of `split_gr1`.

    Does not preserve formula structure.
    Instead, it arranges conjunction operators as a
    binary tree.
    """
    # TODO: preprocess by applying syntactic identities: [][] = [] etc
    if stx.isinstance_str(f):
        t = f
    else:
        t = parser.parse(f)
    g = tx.Tree.from_recursive_ast(t)
    # collect boundary of conjunction operators
    Q = [g.root]
    b = list()  # use lists to preserve as much given syntactic order
    while Q:
        u = Q.pop()
        # terminal ?
        if not g.succ.get(u):
            b.append(u)
            continue
        # operator
        if u.operator == '/\\':
            # use `u.operands` instead of `g.successors`
            # to preserve original order
            Q.extend(u.operands)
        else:
            b.append(u)
    d = dict(init=list(), G=list(), GF=list())
    for u in b:
        # terminal ?
        if not g.succ.get(u):
            d['init'].append(u)
            continue
        # some operator
        if u.operator != '[]':
            d['init'].append(u)
            continue
        # G
        (v,) = u.operands
        # terminal in G ?
        if not g.succ.get(v):
            d['[]'].append(v)
            continue
        # some operator in G
        if v.operator == '<>':
            (w,) = v.operands
            d['[]<>'].append(w)
        else:
            # not a GF
            d['[]'].append(v)
    # assert only admissible temporal operators
    ops = {'[]', '<>', 'U', 'V', 'R'}
    operators = dict(G=ops)
    ops = set(ops)
    ops.add('X')
    operators.update(init=ops, GF=ops)
    for part, f in d.items():
        ops = operators[part]
        for u in f:
            op = has_operator(u, g, ops)
            if op is None:
                continue
            raise AssertionError((
                'found inadmissible operator "{op}" '
                'in "{f}" formula. Parts:\n {d}').format(
                    op=op, f=part, d=d))
    # conjoin (except for progress)
    init = conj(u.flatten() for u in reversed(d['init']))
    d['init'] = [init]
    safe = conj(u.flatten() for u in reversed(d['[]']))
    d['[]'] = [safe]
    # flatten individual progress formulas
    d['[]<>'] = [u.flatten() for u in d['[]<>']]
    return d
示例#12
0
def split_gr1_old(f):
    """Earlier implementation of `split_gr1`.

    Does not preserve formula structure.
    Instead, it arranges conjunction operators as a
    binary tree.
    """
    # TODO: preprocess by applying syntactic identities: [][] = [] etc
    if stx.isinstance_str(f):
        t = f
    else:
        t = parser.parse(f)
    g = tx.Tree.from_recursive_ast(t)
    # collect boundary of conjunction operators
    Q = [g.root]
    b = list()  # use lists to preserve as much given syntactic order
    while Q:
        u = Q.pop()
        # terminal ?
        if not g.succ.get(u):
            b.append(u)
            continue
        # operator
        if u.operator == '/\\':
            # use `u.operands` instead of `g.successors`
            # to preserve original order
            Q.extend(u.operands)
        else:
            b.append(u)
    d = dict(init=list(), G=list(), GF=list())
    for u in b:
        # terminal ?
        if not g.succ.get(u):
            d['init'].append(u)
            continue
        # some operator
        if u.operator != '[]':
            d['init'].append(u)
            continue
        # G
        (v, ) = u.operands
        # terminal in G ?
        if not g.succ.get(v):
            d['[]'].append(v)
            continue
        # some operator in G
        if v.operator == '<>':
            (w, ) = v.operands
            d['[]<>'].append(w)
        else:
            # not a GF
            d['[]'].append(v)
    # assert only admissible temporal operators
    ops = {'[]', '<>', 'U', 'V', 'R'}
    operators = dict(G=ops)
    ops = set(ops)
    ops.add('X')
    operators.update(init=ops, GF=ops)
    for part, f in d.items():
        ops = operators[part]
        for u in f:
            op = has_operator(u, g, ops)
            if op is None:
                continue
            raise AssertionError(
                ('found inadmissible operator "{op}" '
                 'in "{f}" formula. Parts:\n {d}').format(op=op, f=part, d=d))
    # conjoin (except for progress)
    init = conj(u.flatten() for u in reversed(d['init']))
    d['init'] = [init]
    safe = conj(u.flatten() for u in reversed(d['[]']))
    d['[]'] = [safe]
    # flatten individual progress formulas
    d['[]<>'] = [u.flatten() for u in d['[]<>']]
    return d