Exemple #1
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 #2
0
    def prove(self,
              prop,
              k,
              do_trans=False,
              do_base_case=True,
              do_induction=True,
              do_pcompress=True,
              do_term_check=True,
              do_abstraction=True):
        """
        Prove a property using KIP.
        """

        if __debug__:
            assert is_expr(prop), prop
            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
            assert is_bool(do_abstraction), do_abstraction

        #import time
        #stime = time.time()
        logger.debug('Original program:\n{}'.format(self))

        if do_abstraction:
            prog = self.gen_abstraction(self, prop)
            logger.info('Abstract program:\n{}'.format(prog))
        else:
            prog = self

        kip = KIP(prop,
                  prog,
                  k=k,
                  do_base_case=do_base_case,
                  do_induction=do_induction,
                  do_pcompress=do_pcompress,
                  do_term_check=do_term_check)

        if do_trans:
            raise AssertionError('trans: not implemented')

        r, m, k_ = kip.k_ind()

        #time_elapsed = time.time() - stime
        #logger.warn('Time elapsed: %.4f s'%time_elapsed)
        return r, m, k_
    def r_mp2df(t, rs, is_max_plus, idx, is_eq):
        """
        Convert max/min-plus format to disjunctive formula
        Inputs:
        t = single term
        rs = list of terms
        idx = operate over rs[idx:]
        """
        if __debug__:
            assert not is_empty(rs)
            assert idx >= 0, idx
            assert is_bool(is_max_plus), is_max_plus

        rs_ = rs[idx:]

        if __debug__:
            assert not is_empty(rs_)

        first_elem = rs_[0]
        first_elem_f = ("{} {} {}".format(t, '==' if is_eq else '>=',
                                          first_elem))

        if len(rs_) == 1:  # t <= x ==> t <= x
            return first_elem_f

        else:  # t <= max(x,y,z) ==> If(x>=y and x >= z, t <= x, ...)
            op = ">=" if is_max_plus else "<="
            rest_f = IeqMPP.r_mp2df(t, rs, is_max_plus, idx + 1, is_eq)

            others = rs[:idx] + rs[idx + 1:]
            csts = ','.join('{} {} {}'.format(first_elem, op, t)
                            for t in others)
            cond = ('And({})' if len(others) >= 2 else '{}').format(csts)
            return "If({}, {}, {})".format(cond, first_elem_f, rest_f)
    def l_mp2df(ls, rs, is_max_plus, idx, is_eq):
        if __debug__:
            assert not is_empty(ls), ls
            assert not is_empty(rs), rs
            assert idx >= 0, idx
            assert is_bool(is_max_plus), is_max_plus

        ls_ = ls[idx:]

        if __debug__:
            assert ls_, ls_

        first_elem = ls_[0]
        first_elem_f = IeqMPP.r_mp2df(first_elem, rs, is_max_plus, 0, is_eq)

        if len(ls_) == 1:  #t <= max(x,y,z)
            return first_elem_f
        else:
            op = ">=" if is_max_plus else "<="
            rest_f = IeqMPP.l_mp2df(ls, rs, is_max_plus, idx + 1, is_eq)

            others = ls[:idx] + ls[idx + 1:]
            csts = ','.join('{} {} {}'.format(first_elem, op, t)
                            for t in others)
            cond = ("And({})" if len(others) >= 2 else "{}").format(csts)
            return "If({},{},{})".format(cond, first_elem_f, rest_f)
Exemple #5
0
    def sparse(ls, is_max_plus):
        """
        Parse the result from
        'compute_ext_rays_polar' in TPLib into proper lambda format

        Examples:

        sage: var('x,y,z,d')
        (x, y, z, d)

        #TODO: (may be bug) any diff btw is_max_plus=True vs False ???

        sage: IeqMPP.sparse([x-oo,y+0,z-oo,SR(0)-oo,x-6,y-oo,z-oo,SR(0)-oo], is_max_plus=True)
        ('lambda x,y: -x + y + 6 >= 0', 'y >= x - 6')

        sage: IeqMPP.sparse([x-oo,y-oo,z-oo,d+9,x-6,y-oo,z-oo,d+20], is_max_plus=True)
        ('lambda d,x: d + 9 - max(x - 6,d + 20) >= 0', 'If(x - 6 >= d + 20, d + 9 >= x - 6, d + 9 >= d + 20)')

        sage: IeqMPP.sparse([x-1,SR(0)-oo,x-oo,SR(0)+0], is_max_plus=True)
        ('lambda x: x - 1 >= 0', 'x - 1 >= 0')

        sage: IeqMPP.sparse([x+0,SR(0)-oo,x-oo,SR(0)+1], is_max_plus=True)
        ('lambda x: x - 1 >= 0', 'x >= 1')

        sage: IeqMPP.sparse([x-oo,y+0,z-oo,SR(0)-oo,x-6,y-oo,z-oo,SR(0)-oo], is_max_plus=False)
        ('lambda x,y: -x + y + 6 >= 0', 'y >= x - 6')

        sage: IeqMPP.sparse([x-oo,y-oo,z-oo,d+9,x-6,y-oo,z-oo,d+20], is_max_plus=False)
        ('lambda d,x: d + 9 - min(x - 6,d + 20) >= 0', 'If(x - 6 <= d + 20, d + 9 >= x - 6, d + 9 >= d + 20)')

        sage: IeqMPP.sparse([x-1,SR(0)-oo,x-oo,SR(0)+0], is_max_plus=False)
        ('lambda x: x - 1 >= 0', 'x - 1 >= 0')

        sage: IeqMPP.sparse([x+0,SR(0)-oo,x-oo,SR(0)+1], is_max_plus=False)
        ('lambda x: x - 1 >= 0', 'x >= 1')

        """

        if __debug__:
            assert is_list(ls) and is_even(len(ls)), ls
            assert is_bool(is_max_plus), is_max_plus

        mp = len(ls) / 2

        lhs = [l for l in ls[:mp] if not is_sage_inf(l)]
        rhs = [l for l in ls[mp:] if not is_sage_inf(l)]

        # if lhs contains the same exact elems as rhs then remove
        # b/c it's a tautology, e.g. max(x,y) >= max(y,x)
        if set(lhs) == set(rhs):
            return None

        # if one of these is empty, i.e. contain only +/-Inf originally
        if not lhs or not rhs:
            return None

        return IeqMPP.gen_lambda_disj(lhs, rhs, is_max_plus, is_eq=False)
Exemple #6
0
    def tprove(self,
               prop,
               expected,
               msg,
               do_trans=False,
               do_term_check=True,
               do_pcompress=True,
               do_induction=True,
               do_base_case=True,
               do_abstraction=True,
               do_assert=True,
               k=10):
        """
        Shortcut to prove properties.
        Raise errors if the result of the proof is not as expected.
        """
        if __debug__:
            assert is_expr(prop), prop
            assert expected in [True, False, None], expected
            assert is_str(msg), msg
            assert k >= 0, k
            assert all(
                is_bool(c) for c in [
                    do_term_check, do_pcompress, do_induction, do_base_case,
                    do_assert, do_abstraction
                ])

        logger.info('*****')

        (r, m, k_) = self.prove(prop,
                                k=k,
                                do_trans=do_trans,
                                do_abstraction=do_abstraction,
                                do_base_case=do_base_case,
                                do_induction=do_induction,
                                do_term_check=do_term_check,
                                do_pcompress=do_pcompress)

        logger.info(msg)

        if r == True:
            logger.info('proved')
        elif r == False:
            logger.info('disproved')
            logger.debug(model_str(m))
        else:
            logger.info('unproved')

        if r != expected:
            msg = "***** UNEXPECTED RESULT: output={}, expected={} *****"
            logger.warn(msg.format(r, expected))

            if do_assert:
                raise AssertionError('unexpected result !!!')

        logger.info('*****\n')
    def sparse(ls, is_max_plus):
        """
        Parse the result from
        'compute_ext_rays_polar' in TPLib into proper lambda format

        Examples:

        sage: var('x,y,z,d')
        (x, y, z, d)

        sage: IeqMPP.sparse([-oo,0,-oo,-oo,-6,-oo,-oo,-oo],[x,y,z,SR(0)], IeqMPP.opt_max_plus)
        ('lambda x,y: -x + y + 6 >= 0', 'y >= x - 6')

        sage: IeqMPP.sparse([-oo,-oo,-oo,9,-6,-oo,-oo,20],[x,y,z,d], IeqMPP.opt_max_plus)
        ('lambda d,x: d + 9 - max(x - 6,d + 20) >= 0', 'If(x - 6 >= d + 20, d + 9 >= x - 6, d + 9 >= d + 20)')

        sage: IeqMPP.sparse([-1,-oo,-oo,0],[x,SR(0)],IeqMPP.opt_max_plus)
        ('lambda x: x - 1 >= 0', 'x - 1 >= 0')

        sage: IeqMPP.sparse([0,-oo,-oo,1],[x,SR(0)],IeqMPP.opt_max_plus)
        ('lambda x: x - 1 >= 0', 'x >= 1')


        sage: IeqMPP.sparse([-oo,0,-oo,-oo,-6,-oo,-oo,-oo],[x,y,z,SR(0)], IeqMPP.opt_min_plus)
        ('lambda x,y: -x + y + 6 >= 0', 'y >= x - 6')

        sage: IeqMPP.sparse([-oo,-oo,-oo,9,-6,-oo,-oo,20],[x,y,z,d], IeqMPP.opt_min_plus)
        ('lambda d,x: d + 9 - min(x - 6,d + 20) >= 0', 'If(x - 6 <= d + 20, d + 9 >= x - 6, d + 9 >= d + 20)')

        sage: IeqMPP.sparse([-1,-oo,-oo,0],[x,SR(0)],IeqMPP.opt_min_plus)
        ('lambda x: x - 1 >= 0', 'x - 1 >= 0')

        sage: IeqMPP.sparse([0,-oo,-oo,1],[x,SR(0)],IeqMPP.opt_min_plus)
        ('lambda x: x - 1 >= 0', 'x >= 1')

        """

        if __debug__:
            assert is_list(ls) and is_even(len(ls)), ls
            assert is_bool(is_max_plus), is_max_plus

        mp = len(ls) / 2
        lhs = [l for l in ls[:mp] if not l.is_infinity()]
        rhs = [l for l in ls[mp:] if not l.is_infinity()]

        #if lhs contains the same exact elems as rhs then remove
        #b/c it's a tautology, e.g. max(x,y) >= max(y,x)
        if set(lhs) == set(rhs):
            return None

        #if one of these is empty, i.e. contain only +/-Inf originally
        if not lhs or not rhs:
            return None

        return IeqMPP.gen_lambda_disj(lhs, rhs, is_max_plus, is_eq=False)