Exemplo n.º 1
0
def rename_vars(pcs, global_states):
    ret_pcs = []
    vars_mapping = {}

    for expr in pcs:
        list_vars = get_vars(expr)
        for var in list_vars:
            if var in vars_mapping:
                expr = substitute(expr, (var, vars_mapping[var]))
                continue
            var_name = var.decl().name()
            # check if a var is global
            if var_name.startswith("Ia_store_"):
                position = var_name.split('Ia_store_')[1]
                # if it is not modified then keep the previous name
                if position not in global_states:
                    continue
            # otherwise, change the name of the variable
            new_var_name = var_name + '_old'
            new_var = BitVec(new_var_name, 256)
            vars_mapping[var] = new_var
            expr = substitute(expr, (var, vars_mapping[var]))
        ret_pcs.append(expr)

    ret_gs = {}
    # replace variable in storage expression
    for storage_addr in global_states:
        expr = global_states[storage_addr]
        # z3 4.1 makes me add this line
        if is_expr(expr):
            list_vars = get_vars(expr)
            for var in list_vars:
                if var in vars_mapping:
                    expr = substitute(expr, (var, vars_mapping[var]))
                    continue
                var_name = var.decl().name()
                # check if a var is global
                if var_name.startswith("Ia_store_"):
                    position = int(
                        var_name.split('_')[len(var_name.split('_')) - 1])
                    # if it is not modified
                    if position not in global_states:
                        continue
                # otherwise, change the name of the variable
                new_var_name = var_name + '_old'
                new_var = BitVec(new_var_name, 256)
                vars_mapping[var] = new_var
                expr = substitute(expr, (var, vars_mapping[var]))
        ret_gs[storage_addr] = expr

    return ret_pcs, ret_gs
Exemplo n.º 2
0
    def slice_defs(prop, defs, assumes_state, assumes_trans):
        """
        Return a new (potentially empty) def dictionary from the old one
        consisting of only necessary variable definitions to prove property
        """
        if __debug__:
            assert is_dict(defs), defs
            assert is_list(assumes_state), assumes_state
            assert is_list(assumes_trans), assumes_trans

        fs = [prop] + assumes_state + assumes_trans
        fs = [f for f in fs if is_expr(f)]

        vs = [get_vars(f) for f in fs]
        vs = [cur(v_) if is_pre(v_) else v_ for v_ in vflatten(vs)]
        vs = vset(vs, fhash)

        vs_ = [Prog.get_influence_vs(v, defs, []) for v in vs]
        vs = vset(vflatten(vs + vs_), fhash)

        a_defs = OrderedDict()
        for v in vs:
            k = fhash(v)
            if k in defs:
                a_defs[k] = defs[k]

        return a_defs
Exemplo n.º 3
0
def cur_f(f):
    """
    Convert a formula f with pre vars to a formula with cur vars

    >>> from z3 import *
    >>> x,y,z = Ints('x y z')

    >>> cur_f(pre(z) == 9)
    z == 9

    >>> cur_f(And(pre(y) == 4, pre(z) == 9) )
    And(y == 4, z == 9)

    >>> cur_f(pre(y) == z)
    Traceback (most recent call last):
    ...
    AssertionError: y_pre == z
    """
    if __debug__:
        assert f is None or is_pre_f(f), f

    if f is None:
        return None
    if is_expr_var(f):
        return cur(f)
    else:
        vss = [(v, cur(v)) for v in get_vars(f)]
        return substitute(f, *vss)
Exemplo n.º 4
0
def substitute_f(f, i, s=None):
    """
    Replaces all variables v in f with v_(i*_)

    s = a symbol string, e.g. n (so we will have the variable
    x_n_1 instead of x_1

    Examples:

    >>> from z3 import *
    >>> x,x_pre,y,y_pre = Ints('x x_pre y y_pre')

    >>> substitute_f(Implies(x==10,y==5),i=0)
    Or(Not(x_0 == 10), y_0 == 5)

    >>> substitute_f(Implies(x==10,y==5),i=1)
    Or(Not(x_1 == 10), y_1 == 5)

    >>> substitute_f(Implies(x==10,pre(y)==5),i=1)
    Or(Not(x_1 == 10), y_0 == 5)

    >>> substitute_f(Implies(x==10,pre(y)==5),1,s='m')
    Or(Not(x_m_1 == 10), y_m_0 == 5)


    >>> substitute_f(Implies(x==10,pre(y)==5),10,s='m')
    Or(Not(x_m_10 == 10), y_m_9 == 5)

    >>> substitute_f(BoolVal(False),i=10)
    False

    >>> substitute_f(IntVal(100),i=10)
    100

    """

    if __debug__:
        assert is_expr(f)
        assert i >= 0
        assert i != 0 or is_state(f)  # v_pre => i!=0
        assert not s or isinstance(s, str) and len(s) >= 1

    vs = get_vars(f)

    if not vs:  #e.g. True, 5, etc  has no variables so return as is
        return f
    else:
        vss = gen_vars(vs, i, s)
        f_ = f
        for vs in vss:
            f_ = substitute(f_, vs)
        return f_
Exemplo n.º 5
0
def atT(c, when_c=None):
    """
    Return And(!pre(c),c,when_c)

    When seeing the SCR syntax such as `@T(x) when c1`, the parser calls
    atT(x,c1') where c1' is c1 with all variables v => pre(v).
    In other words, the when_c only contains 'pre' variables.

    IMPORTANT: SCR syntax allows syntax such as `@T(x) when c1 OR @T(x) when c2`
    But I require explicit parentheses around these
    `(@T(x) when c1) OR (@T(x) when c2)`.
    The reason is to avoid ambiguity:
    'c1 OR @T(x) when c2' could be treated as an expression c3, i.e.
    @T(x) when c3.

    EXAMPLES:

    >>> from z3 import *
    >>> x,y = Ints('x y')
    >>> atT(x==10)
    And(Not(x_pre == 10), x == 10)


    >>> atT(x==10, pre(x)!= pre(y))
    And(Not(x_pre == 10), x == 10, x_pre != y_pre)

    >>> atT(Or(x==10,y==3),pre(x)!= pre(y))
    And(Not(Or(x_pre == 10, y_pre == 3)),
        Or(x == 10, y == 3),
        x_pre != y_pre)

    """

    if __debug__:
        assert is_state(c), c
        assert not when_c or is_pre_f(when_c),\
             "'{}' does not have the right WHEN format. "\
                    "Perhaps missing parenthesis, e.g."\
                    "(@T(x) when c1) OR (@T(y) when c2). "\
                    "See document in function for details.".format(when_c)

    vss_c_cur = get_vars(c)

    vss_c_pre = map(pre, vss_c_cur)
    vss_c = zip(vss_c_cur, vss_c_pre)

    not_c = Not(substitute(c, *vss_c))
    return myAnd(not_c, c, when_c)
Exemplo n.º 6
0
def is_pre_f(f):
    """
    Check if all variables in f are pre variables

    Examples:

    >>> from z3 import *
    >>> x,y = Ints('x y')
    >>> is_pre_f(x)
    False
    >>> is_pre_f(pre(x))
    True
    >>> is_pre_f(Or(pre(x)==10, y==3))
    False
    >>> is_pre_f(Or(pre(x)==10, pre(y)==3))
    True
    """
    if __debug__:
        assert is_expr(f), f

    return all(is_pre(v) for v in get_vars(f))
Exemplo n.º 7
0
def pre_f(f):
    """
    Convert a formula f with cur vars to a formula with pre vars

    >>> from z3 import *
    >>> x,y,z = Ints('x y z')

    >>> pre_f(z == 9)
    z_pre == 9

    >>> pre_f(And(y == 4, z == 9) )
    And(y_pre == 4, z_pre == 9)

    """
    if __debug__:
        assert f is None or is_cur_f(f), f

    if f is None:
        return None
    elif is_expr_var(f):
        return pre(f)
    else:
        vss = [(v, pre(v)) for v in get_vars(f)]
        return substitute(f, *vss)
Exemplo n.º 8
0
    def get_state_vars(f, exclude_vars):
        """
        f: a formula, e.g. the transition formula
        exclude_vars: variables that are not considered as state vars,
        e.g. independent variables

        From Verifying Safety Property of Lustre Programs:
        Temporal Induction

        Let L be a Lustre program, S be the tuple of L's state
        variables, non-input variables that occur within a pre.

        Then only non-input variables that occur within a pre are considered
        program states

        node test( X: bool ) returns ( P : bool );
        var A, B, C : bool;
        let
        A = X -> pre A;
        B = not (not X -> pre(C));
        C = not B;
        P = A = B;  #property to be proved, not important, not part of input

        >>> from z3 import Bools, Implies, Ints, If, Or


        #states variables = [A,C]
        >>> A,A_pre,B,B_pre,C,C_pre,X = Bools('A A_pre B B_pre C C_pre X')
        >>> af = A == A_pre
        >>> bf = B == Not(Not(Implies(X,C_pre)))
        >>> cf = C == Not(B)
        >>> trans = And(af,bf,cf)
        >>> exclude_vars = [X]
        >>> KIP.get_state_vars(trans, exclude_vars)
        [A, C]

        >>> af = A == Implies(X,A_pre)
        >>> bf = B == Not(Implies(Not(X),C_pre))
        >>> cf = C == Not(B)
        >>> trans = And(af,bf,cf)
        >>> exclude_vars = [X]
        >>> KIP.get_state_vars(trans, exclude_vars)
        [A, C]

        #state variables = c , R is not included because R_pre is not used
        >>> R,c_pre,c = Ints('R c_pre c')
        >>> trans = If(Or(R == 100, c_pre == 2), c == 0, c == c_pre + 1)
        >>> KIP.get_state_vars(trans, exclude_vars=[])
        [c]

        #this algorithm would return [], instead of [C]
        #this is by design because it doesn't make sense to have
        #C_pre without C in trans
        >>> KIP.get_state_vars(A == C_pre,[])
        []
        """

        if __debug__:
            assert f is None or is_expr(f), f
            assert is_list(exclude_vars), exclude_vars

        if f is None:
            return []

        #start with state_vars being all vars in trans
        state_vars = get_vars(f)

        #keep those that not being excluded
        state_vars = [
            v for v in state_vars if not expr_member(v, exclude_vars)
        ]

        #keep those v that are not pre but v's pre is part of the f
        state_vars = [
            v for v in state_vars
            if not is_pre(v) and expr_member(pre(v), state_vars)
        ]
        if __debug__:
            assert all(not is_pre(v) for v in state_vars)

        return state_vars
Exemplo n.º 9
0
    def get_influence_vs(v, defs, rs):
        """
        Return a list of variables that influences v
        (i.e. the definition of v depends on these variables)

        >>> from z3 import Bools, BoolVal
        >>> from scr_miscs import mk_OIA

        >>> s,t = Bools('s t')
        >>> x,y,z = Bools('x y z')
        >>> vs = [x,y,z]
        >>> o = mk_OIA(vs)
        >>> vv = [o,o,And(o,s)]
        >>> vs2 = [t]
        >>> vv2 = [BoolVal(True)]
        >>> vs_k = map(fhash,vs + vs2)
        >>> vs_v =vv + vv2
        >>> defs = OrderedDict(zip(vs_k,vs_v))
        >>> print Prog.get_influence_vs(x,defs,rs=[])
        [s, y, z]

        #>>> print Prog.get_influence_vs(x,defs,assumes=[x==s],rs=[])
        #[s, y, z]

        #>>> print Prog.get_influence_vs(x,defs,assumes=[y==t],rs=[])
        #[s, y, z, t]


        """
        if __debug__:
            assert is_expr_var(v), v
            assert is_dict(defs), defs
            assert is_list(rs), rs

        if is_pre(v):
            v = cur(v)

        #return if already in the result set
        if expr_member(v, rs):
            return rs

        try:
            vs = get_vars(defs[fhash(v)])
            #print vs

        except KeyError:
            return rs

        rs = rs + [v]

        #convert v_pre to v
        vs = [cur(v_) if is_pre(v_) else v_ for v_ in vs]
        vs = vset(vs, fhash)

        for v_ in vs:
            rs_ = Prog.get_influence_vs(v_, defs, rs)
            rs = rs + rs_

        rs = rs + vs
        rs = vset(rs, fhash)

        #remove myself
        v_idx = map(fhash, rs).index(fhash(v))
        rs = rs[:v_idx] + rs[v_idx + 1:]
        return sorted(rs, key=str)
Exemplo n.º 10
0
def get_all_vars(list_of_storage_exprs):
    ret_vars = []
    for expr in list_of_storage_exprs:
        ret_vars += get_vars(list_of_storage_exprs[expr])
    return ret_vars
Exemplo n.º 11
0
def has_storage_vars(expr, storage_vars):
    list_vars = get_vars(expr)
    for var in list_vars:
        if var in storage_vars:
            return True
    return False
Exemplo n.º 12
0
def is_in_expr(var, expr):
    list_vars = get_vars(expr)
    set_vars = set(i.decl().name() for i in list_vars)
    return var in set_vars