Exemple #1
0
    def D(self, i, s):
        """
        Return a formula expressing state s_i is different
        than states [0, s_0, s_1, ..., s_(i-1)].

        If s is None then the returned formula expresses
        state i different than states [0 ... i-1]
        """
        if __debug__:
            assert i >= 2, 'i ({}) must start from 2!'.format(i)

        if len(self.state_vars) == 0:
            return None

        def S(i, s):
            """
            Return a set (list) consisting of the variables at state i.
            I.e. x_1i, x_2i, ...
            """
            return [self._at_state(v, i, s) for v in self.state_vars]

        cur_state = S(i, s)
        #states s_0 ... s_(j-1)
        pre_states = [S(i_, s) for i_ in range(i)]

        if s:
            #D(s,s+i) = s_i #  [0,s_0,s_1,..,s_(i-1)]
            pre_states = [S(0, None)] + pre_states

        f = [
            Not(self.state_eq(cur_state, pre_state))
            for pre_state in pre_states
        ]

        return myAnd(f)
Exemple #2
0
    def state_eq(vs1, vs2):
        """
        Generate a formula expressing the variables in vs1,vs2 are the same
        """
        if __debug__:
            assert is_list(vs1) and all(is_expr_var(v) for v in vs1), vs1
            assert is_list(vs2) and all(is_expr_var(v) for v in vs2), vs2
            assert len(vs1) == len(vs2)

        eqts = [v1 == v2 for v1, v2 in zip(vs1, vs2)]
        return myAnd(eqts)
Exemple #3
0
    def I_S(self, i, s):
        """
        Return the formula for (state) invariant at state i.
        """
        if __debug__:
            assert is_list(self.invs_state) and\
                all(is_state(a) for a in self.invs_state), self.invs_state
            assert i >= 0, i

        inv_state = myAnd([self._at_state(a, i, s) for a in self.invs_state])
        return inv_state
Exemple #4
0
    def I_T(self, i, s):
        """
        Return the formula for (trans) invariant at state i
        """
        if __debug__:
            assert is_list(self.invs_trans) and\
                all(is_trans(a) for a in self.invs_trans), self.invs_trans
            assert i >= 1, i

        inv_trans = myAnd([self._at_state(a, i, s) for a in self.invs_trans])
        return inv_trans
Exemple #5
0
    def I(self, i, s):
        """
        Return the formula for init condition at state i
        """
        if __debug__:
            assert is_list(self.init_conds) and\
                all(is_state(a) for a in self.init_conds), self.init_conds
            assert i >= 0, i

        init_cond = myAnd([self._at_state(a, i, s) for a in self.init_conds])
        return init_cond
Exemple #6
0
    def __init__(self,
                 prop,
                 prog,
                 k=100,
                 do_base_case=True,
                 do_induction=True,
                 do_pcompress=True,
                 do_term_check=True):

        if __debug__:
            assert is_expr(prop), prop
            assert isinstance(prog, Prog), prog
            assert k >= 0, k
            assert is_bool(do_base_case), do_base_case
            assert is_bool(do_induction), do_induction
            assert is_bool(do_pcompress), do_pcompress
            assert is_bool(do_term_check), do_term_check

        self.k = k

        self.prop = prop
        self.is_prop_state = is_state(self.prop)

        self.init_conds = prog.init_conds
        self.assumes_state = prog.assumes_state
        self.assumes_trans = prog.assumes_trans
        self.invs_state = prog.invs_state
        self.invs_trans = prog.invs_trans
        self.input_vars = prog.input_vars
        self.defs_vals = prog.defs.values()

        f = myAnd(self.defs_vals + self.assumes_state + self.assumes_trans)
        self.state_vars = self.get_state_vars(f, self.input_vars)

        logger.debug("KIP (k={})".format(k))
        logger.debug("prop: '{}'".format(self.prop))
        logger.debug("|state_vars|: {}".format(len(self.state_vars)))
        logger.debug(self.state_vars)

        if len(self.state_vars) == 0:
            logger.warn("No state vars")
            if do_pcompress:
                logger.warn("Disable path compression")
                do_pcompress = False
            if do_term_check:
                logger.warn("Disable termination check")
                do_term_check = False

        self.do_base_case = do_base_case
        self.do_induction = do_induction
        self.do_pcompress = do_pcompress
        self.do_term_check = do_term_check
Exemple #7
0
    def A_S(self, i, s):
        """
        Return the formula for (state) assume at state i
        """
        if __debug__:
            assert is_list(self.assumes_state) and\
                all(is_state(a) for a in self.assumes_state),\
                self.assumes_state
            assert i >= 0, i

        assume_state = myAnd(
            [self._at_state(a, i, s) for a in self.assumes_state])
        return assume_state
Exemple #8
0
    def A_T(self, i, s):
        """
        Return the formula for (trans) assume at state i
        """

        if __debug__:
            assert is_list(self.assumes_trans) and\
                all(is_trans(a) for a in self.assumes_trans),\
                self.assumes_trans
            assert i >= 1, i

        assume_trans = myAnd(
            [self._at_state(a, i, s) for a in self.assumes_trans])
        return assume_trans
Exemple #9
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)
Exemple #10
0
        def _term_check(k):
            c = [D(k_, _sbase) for k_ in range(2, k + 1)]  #2..k
            c = myAnd(c)

            #Term check
            logger.debug('* Term Check ({})'.format(k))
            if c is None:
                logger.warn('skipping term check')
                return None, None

            r_t, cex_t = KIP.entails(S_base, Not(c))
            if r_t == True:
                logger.info('** proved (cycle found) ({}): {}'.format(
                    k, self.prop))

            return r_t, cex_t
Exemple #11
0
    def T(self, i, s):
        """
        Return the formula for trans at state i.
        I.e. the transaction from state i-1 to state i

        T(i=0) is by default initial state (condition)
        T(i=1) is the trans from state 0 to state 1, and so on

        """
        if __debug__:
            assert is_list(self.defs_vals) and\
                all(is_expr(a) for a in self.defs_vals),\
                self.defs_vals
            assert i >= 1, i

        trans = myAnd([self._at_state(a, i, s) for a in self.defs_vals])
        return trans
Exemple #12
0
def atC(v, when_c=None):
    """
    Analogous to atT

    Return And(pre(v) != v, when_c)

    EXAMPLES:

    >>> from z3 import *
    >>> x,y = Bools('x y')
    >>> atC(x)
    x_pre != x

    >>> atC(x,when_c = pre(x) == pre(y))
    And(x_pre != x, x_pre == y_pre)
    """
    if __debug__:
        assert is_expr_var(v) and not is_pre(v), v
        assert not when_c or is_pre_f(when_c), when_c

    f = myAnd(pre(v) != v, when_c)
    return f
Exemple #13
0
def mk_OIA(vs):
    """
    Create an expression representing the One Input Assumption over
    the variables in vs.

    version 1 (this implementation):
    (x # pre(x) and y=pre(y) ...) OR
    (y # pre(y) and x=pre(x) ...) OR

    version 2:
    (x # pre(x) => y=pre(y) and ...) AND
    (y # pre(y) => x=pre(x) and ...) AND
    (x#pre(x) or y#pre(y) ...)

    Examples:

    >>> from z3 import *
    >>> x = Int('x')
    >>> y = Real('y')
    >>> z = Bool('z')
    >>> mk_OIA([x,y,z])
    Or(And(x != x_pre, y == y_pre, z == z_pre),
       And(y != y_pre, x == x_pre, z == z_pre),
       And(z != z_pre, x == x_pre, y == y_pre))

   >>> mk_OIA([x])
   x != x_pre

   >>> mk_OIA([])
   """
    if __debug__:
        assert is_list(vs) and all(not is_pre(v) for v in vs), vs

    oia = lambda v, vs: myAnd(v != pre(v), *[v_ == pre(v_) for v_ in vs])

    return myOr([oia(v, vs[:i] + vs[i + 1:]) for i, v in enumerate(vs)])