Beispiel #1
0
    def eval_lambda(f, d, is_formula=True):
        """
        Evaluates lambda function f

        Examples:

        sage: assert InvMPP.eval_lambda('lambda x,y: max(x - 13,-3) >= y', {'x':11,'y':100}) == False

        sage: assert InvMPP.eval_lambda('lambda x,y: x+y == 5', {'x':2,'y':3,'d':7})

        sage: assert InvMPP.eval_lambda('lambda x,y: x+y == 6', {'x':2,'y':3,'d':7}) == False


        sage: assert InvMPP.eval_lambda('lambda x,y: x+y', {'x':2,'y':3,'d':7}, is_formula=False) == 5
        


        sage: assert InvMPP.eval_lambda('lambda x,y: x+y == 10 or x + y == 5', {'x':2,'y':3,'d':7})

        sage: assert InvMPP.eval_lambda('lambda x,y: x+y == 1 or x + y == 2', {'x':2,'y':3,'d':7}) == False

        """
        if __debug__:
            assert is_str(f) and 'lambda' in f, f
            assert is_dict(d), d
            assert all(is_str(k) for k in d), d.keys()

        f = sage_eval(f)
        vs = f.func_code.co_varnames
        assert set(vs) <= set(d.keys()), (vs,d.keys())

        #if d has more keys than variables in f then remove those extra keys
        d=dict([(k,d[k]) for k in vs])
        rs = f(**d)
        return bool(rs) if is_formula else rs
Beispiel #2
0
    def eval_lambda(f, d, is_formula=True):
        """
        Evaluates lambda function f

        Examples:

        sage: assert InvMPP.eval_lambda('lambda x,y: max(x - 13,-3) >= y', {'x':11,'y':100}) == False

        sage: assert InvMPP.eval_lambda('lambda x,y: x+y == 5', {'x':2,'y':3,'d':7})

        sage: assert InvMPP.eval_lambda('lambda x,y: x+y == 6', {'x':2,'y':3,'d':7}) == False


        sage: assert InvMPP.eval_lambda('lambda x,y: x+y', {'x':2,'y':3,'d':7}, is_formula=False) == 5
        


        sage: assert InvMPP.eval_lambda('lambda x,y: x+y == 10 or x + y == 5', {'x':2,'y':3,'d':7})

        sage: assert InvMPP.eval_lambda('lambda x,y: x+y == 1 or x + y == 2', {'x':2,'y':3,'d':7}) == False

        """
        if __debug__:
            assert is_str(f) and 'lambda' in f, f
            assert is_dict(d), d
            assert all(is_str(k) for k in d), d.keys()

        f = sage_eval(f)
        vs = f.func_code.co_varnames
        assert set(vs) <= set(d.keys()), (vs, d.keys())

        #if d has more keys than variables in f then remove those extra keys
        d = dict([(k, d[k]) for k in vs])
        rs = f(**d)
        return bool(rs) if is_formula else rs
Beispiel #3
0
    def __init__(self, filename, verbose=VLog.DEBUG):

        if __debug__:
            assert filename is None or is_str(filename), filename

        logger.level = verbose

        import dig_inv, dig_refine, dig_arrays, dig_polynomials
        for f in [dig_miscs, dig_inv, dig_refine, dig_arrays, dig_polynomials]:
            f.logger.set_level(logger.level)

        from platform import node, system, release, machine
        margs = [
            get_cur_time(time_only=False),
            version(), ' '.join([node(),
                                 system(),
                                 release(),
                                 machine()])
        ]
        logger.info("DIG (Dynamic Invariant Generator)\n"
                    "{}, {}, {}".format(*margs))

        if filename is not None:
            self._setup(filename)
        else:
            logger.warn('No filename given, manual setup')
Beispiel #4
0
    def __init__(self, p):
        """
        Ex:
        sage: m = InvMPP(('lambda p,r: 422 >= min(p,r + 29)', 'If(p <= r + 29, 422 >= p, 422 >= r + 29)'))
        
        sage: print m
        422 >= min(p,r + 29), If(p <= r + 29, 422 >= p, 422 >= r + 29)

        sage: m.get_score()
        62

        """
        if __debug__:
            assert (is_tuple(p) and len(p) == 2 and is_str(p[0])
                    and 'lambda' in p[0] and is_str(p[1])), p

        super(InvMPP, self).__init__(p[0].strip(), p_str=p[1])
Beispiel #5
0
    def __init__(self, p): 
        """
        Ex:
        sage: m = InvMPP(('lambda p,r: 422 >= min(p,r + 29)', 'If(p <= r + 29, 422 >= p, 422 >= r + 29)'))
        
        sage: print m
        422 >= min(p,r + 29), If(p <= r + 29, 422 >= p, 422 >= r + 29)

        sage: m.get_score()
        62

        """
        if __debug__:
            assert (is_tuple(p) and len(p)==2 and 
                    is_str(p[0]) and 'lambda' in p[0] and
                    is_str(p[1])), p

        super(InvMPP,self).__init__(p[0].strip(), p_str=p[1])
Beispiel #6
0
    def __init__(self, p, p_str=None): 
        if __debug__:
            assert p_str is None or is_str(p_str), p_str

        self.p = p
        if p_str is None:
            p_str = str(p)

        self.p_str = Inv.rm_lambda(p_str)
Beispiel #7
0
    def __init__(self, p, p_str=None):
        if __debug__:
            assert p_str is None or is_str(p_str), p_str

        self.p = p
        if p_str is None:
            p_str = str(p)

        self.p_str = Inv.rm_lambda(p_str)
Beispiel #8
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')
Beispiel #9
0
    def __init__(self, p):
        """
        Ex:
        'lambda a,b,c,i,j: a[i][j]==2*b[i]+c[j]'
        """
        if __debug__:
            assert (is_str(p) and all(s in p for s in ['lambda', '[', ']'])), p

        super(InvNestedArray, self).__init__(p.strip())
        self.idx_info = None  #no info about idx (only for FlatArr)
Beispiel #10
0
    def __init__(self, p):
        """
        Ex:
        flat arr: 'lambda A, B, A0: (A[A0]) + (-7*B[2*A0]) + (-3*A0) == 0 
        nested arr: 'lambda A,B,i1: A[i1] == B[-2*i1 + 5]'
        """
        if __debug__:
            assert (is_str(p) and all(s in p for s in ['lambda', '[', ']'])), p

        super(InvArray, self).__init__(p)
Beispiel #11
0
    def _setup(self,filename):
        if __debug__:
            assert is_str(filename), filename

        rf = dig_miscs.ReadFile(filename)
        
        self.filename = rf.filename
        self.xinfo    = rf.xinfo
        
        self.ss_arr, self.tcs_arr = rf.ss_arr, rf.tcs_arr
        self.ss_num, self.tcs_num = rf.ss_num, rf.tcs_num
Beispiel #12
0
    def __init__(self, p):
        """
        Ex:
        flat arr: 'lambda A, B, A0: (A[A0]) + (-7*B[2*A0]) + (-3*A0) == 0 
        nested arr: 'lambda A,B,i1: A[i1] == B[-2*i1 + 5]'
        """
        if __debug__:
            assert (is_str(p) and 
                    all(s in p for s in ['lambda','[' ,']'])), p

        super(InvArray,self).__init__(p)
Beispiel #13
0
    def __init__(self, p):
        """
        Ex:
        'lambda a,b,c,i,j: a[i][j]==2*b[i]+c[j]'
        """
        if __debug__:
            assert (is_str(p) and 
                    all(s in p for s in ['lambda','[' ,']'])), p

        super(InvNestedArray,self).__init__(p.strip())
        self.idx_info = None #no info about idx (only for FlatArr)
Beispiel #14
0
    def _setup(self, filename):
        if __debug__:
            assert is_str(filename), filename

        rf = dig_miscs.ReadFile(filename)

        self.filename = rf.filename
        self.xinfo = rf.xinfo

        self.ss_arr, self.tcs_arr = rf.ss_arr, rf.tcs_arr
        self.ss_num, self.tcs_num = rf.ss_num, rf.tcs_num
Beispiel #15
0
    def __init__(self, p):
        """
        Ex:
        ('lambda A, B, A0: (A[A0]) + (-7*B[2*A0]) + (-3*A0) == 0', 
        [{'A0': 2}, {'A0': 0}, {'A0': 1}])
        """

        if __debug__:
            assert (is_tuple(p) and len(p) == 2 and is_str(p[0])
                    and all(s in p[0] for s in ['lambda', '[', ']'])
                    and is_list(p[1]) and all(is_dict(v) for v in p[1])), p

        super(InvFlatArray, self).__init__(p[0].strip())
        self.idx_info = p[1]
Beispiel #16
0
    def __init__(self, p): 
        """
        Ex:
        ('lambda A, B, A0: (A[A0]) + (-7*B[2*A0]) + (-3*A0) == 0', 
        [{'A0': 2}, {'A0': 0}, {'A0': 1}])
        """

        if __debug__:
            assert (is_tuple(p) and len(p)==2 and 
                    is_str(p[0]) and 
                    all(s in p[0] for s in ['lambda','[' ,']']) and
                    is_list(p[1]) and all(is_dict(v) for v in p[1])), p
            
        super(InvFlatArray,self).__init__(p[0].strip())
        self.idx_info = p[1]
Beispiel #17
0
    def __init__(self,filename,verbose=VLog.DEBUG):
    
        if __debug__:
            assert filename is None or is_str(filename), filename

        logger.level = verbose

        import dig_inv, refine, dig_arrays, dig_polynomials
        for f in [dig_inv, refine, dig_arrays, dig_polynomials, dig_miscs]:
            f.logger.set_level(logger.level)
        
        from platform import node, system, release, machine
        margs = [get_cur_time(time_only=False),version(),
                 ' '.join([node(),system(),release(),machine()])]
        logger.info("{}, {}, {}".format(*margs))
        
        if filename is not None:
            self._setup(filename)
        else:
            logger.warn('No filename given, manual setup')
Beispiel #18
0
    def eval_lambda(f, idx_info, tc):
        """
        Evaluate array expression p, e.g. p:  A[i,j,k]=B[2i+3j+k]

        if idx_info is specified then only test p on the idxs from idx_info


        Assumes:
        the first array in lambda is the pivot
        lambda A,B,i,j,k: ...  =>  i,j,k  belong to A



        inv = 'lambda B,C,D,i,j: B[i][j]=C[D[2i+3]]'
        returns true if inv is true on tc

        Examples:

        sage: var('a,b,c,i,j')
        (a, b, c, i, j)

        sage: InvArray.eval_lambda('lambda a,b,c,i,j: a[i][j]==2*b[i]+c[j]', None, {'a':[[4,-5],[20,11]],'b':[1,9],'c':[2,-7]})
        True

        sage: InvArray.eval_lambda('lambda c,a,b,xor,i: c[i] == xor(a[i],b[i])', None, {'a': [147, 156, 184, 76], 'b': [51, 26, 247, 189], 'c': [160, 334, 79, 281]})
        False

        sage: InvArray.eval_lambda('lambda c,a,b,xor,i1: c[i1] == xor(a[i1],b[i1])', None, {'a': [147, 156, 184, 76], 'b': [51, 26, 247, 189], 'c': [160, 134, 79, 241]})
        True


        sage: InvArray.eval_lambda('lambda rvu, t, rvu1, rvu0: (rvu[rvu0][rvu1]) + (-t[4*rvu0 + rvu1]) == 0', None, {'t': [28, 131, 11, 85, 133, 46, 179, 20, 227, 148, 225, 197, 38, 221, 221, 126], 'rvu': [[28, 131, 11, 85], [133, 46, 179, 20], [227, 148, 225, 197], [38, 221, 221, 126]]})
        True

        #The following illustrate the use of idxVals,
        #i.e. p is only true under certain array rages

        sage: InvArray.eval_lambda('lambda st, rvu, st0, st1: (-st[st0][st1]) + (rvu[4*st0 + st1]) == 0', None, tc = {'rvu': [28, 131, 11, 85, 193, 124, 103, 215, 66, 26, 68, 54, 176, 102, 15, 237], 'st': [[28, 131, 11, 85, 133, 46, 179, 20, 227, 148, 225, 197, 38, 221, 221, 126], [193, 124, 103, 215, 106, 229, 162, 168, 166, 78, 144, 234, 199, 254, 152, 250], [66, 26, 68, 54, 206, 16, 155, 248, 231, 198, 240, 43, 208, 205, 213, 26], [176, 102, 15, 237, 49, 141, 213, 97, 137, 155, 50, 243, 112, 51, 124, 107]]})
        False

        sage: InvArray.eval_lambda('lambda st, rvu, st0, st1: (-st[st0][st1]) + (rvu[4*st0 + st1]) == 0', idx_info = [{'st0': 0, 'st1': 0}, {'st0': 0, 'st1': 1}, {'st0': 2, 'st1': 2}, {'st0': 2, 'st1': 3}, {'st0': 3, 'st1': 0}, {'st0': 3, 'st1': 1}, {'st0': 3, 'st1': 2}, {'st0': 3, 'st1': 3}, {'st0': 0, 'st1': 2}, {'st0': 0, 'st1': 3}, {'st0': 1, 'st1': 0}, {'st0': 1, 'st1': 1}, {'st0': 1, 'st1': 2}, {'st0': 1, 'st1': 3}, {'st0': 2, 'st1': 0}, {'st0': 2, 'st1': 1}], tc = {'rvu': [28, 131, 11, 85, 193, 124, 103, 215, 66, 26, 68, 54, 176, 102, 15, 237], 'st': [[28, 131, 11, 85, 133, 46, 179, 20, 227, 148, 225, 197, 38, 221, 221, 126], [193, 124, 103, 215, 106, 229, 162, 168, 166, 78, 144, 234, 199, 254, 152, 250], [66, 26, 68, 54, 206, 16, 155, 248, 231, 198, 240, 43, 208, 205, 213, 26], [176, 102, 15, 237, 49, 141, 213, 97, 137, 155, 50, 243, 112, 51, 124, 107]]})
        True

        """


        """
        Note: sage_eval vs eval
        sage_eval works on str of the format 'lambda x,y: 2*x+y'
        whereas eval works on str of the format 2*x+y directly (no lambda)
        Also, the result of sage_eval can apply on dicts whose keys are str
        e.g.  f(**{'x':2,'y':3})
        whereas the result of eval applies on dict whose keys are variables
        e.g.  f(**{x:2,y:3})
        """

        if __debug__:
            assert is_str(f) and 'lambda' in f, f
            assert (idx_info is None or 
                    is_list(idx_info) and all(is_dict(v) for v in idx_info)), indx_info
            assert is_dict(tc), tc
            assert all(is_str(k) for k in tc), tc.keys()

        f = sage_eval(f)
        vs = f.func_code.co_varnames

        arrs    = [v for v in vs if v in tc]        #A,B
        extfuns = [v for v in vs if v in ExtFun.efdict]
        idxStr  = [v for v in vs if v not in arrs+extfuns]  #i,j,k

        d_tc    = dict([(v,tc[v]) for v in arrs])
        d_extfun= dict([(v,ExtFun(v).get_fun()) for v in extfuns])
        d_      = merge_dict([d_tc,d_extfun])

        if idx_info is None: #obtain idxsVals from the pivot array
            pivotContents = tc[arrs[0]]
            idxVals  = [idx for idx,_ in Miscs.travel(pivotContents)]
            idx_info = [dict(zip(idxStr,idxV)) for idxV in idxVals]

        ds = [merge_dict([d_, idx_info_]) for idx_info_ in idx_info]

        try:
            return all(f(**d) for d in ds)
        except IndexError:
            return False
        except TypeError:
            return False
        except NameError as msg:
            logger.warn(msg)
            return False
Beispiel #19
0
    def eval_lambda(f, idx_info, tc):
        """
        Evaluate array expression p, e.g. p:  A[i,j,k]=B[2i+3j+k]

        if idx_info is specified then only test p on the idxs from idx_info


        Assumes:
        the first array in lambda is the pivot
        lambda A,B,i,j,k: ...  =>  i,j,k  belong to A



        inv = 'lambda B,C,D,i,j: B[i][j]=C[D[2i+3]]'
        returns true if inv is true on tc

        Examples:

        sage: var('a,b,c,i,j')
        (a, b, c, i, j)

        sage: InvArray.eval_lambda('lambda a,b,c,i,j: a[i][j]==2*b[i]+c[j]', None, {'a':[[4,-5],[20,11]],'b':[1,9],'c':[2,-7]})
        True

        sage: InvArray.eval_lambda('lambda c,a,b,xor,i: c[i] == xor(a[i],b[i])', None, {'a': [147, 156, 184, 76], 'b': [51, 26, 247, 189], 'c': [160, 334, 79, 281]})
        False

        sage: InvArray.eval_lambda('lambda c,a,b,xor,i1: c[i1] == xor(a[i1],b[i1])', None, {'a': [147, 156, 184, 76], 'b': [51, 26, 247, 189], 'c': [160, 134, 79, 241]})
        True


        sage: InvArray.eval_lambda('lambda rvu, t, rvu1, rvu0: (rvu[rvu0][rvu1]) + (-t[4*rvu0 + rvu1]) == 0', None, {'t': [28, 131, 11, 85, 133, 46, 179, 20, 227, 148, 225, 197, 38, 221, 221, 126], 'rvu': [[28, 131, 11, 85], [133, 46, 179, 20], [227, 148, 225, 197], [38, 221, 221, 126]]})
        True

        #The following illustrate the use of idxVals,
        #i.e. p is only true under certain array rages

        sage: InvArray.eval_lambda('lambda st, rvu, st0, st1: (-st[st0][st1]) + (rvu[4*st0 + st1]) == 0', None, tc = {'rvu': [28, 131, 11, 85, 193, 124, 103, 215, 66, 26, 68, 54, 176, 102, 15, 237], 'st': [[28, 131, 11, 85, 133, 46, 179, 20, 227, 148, 225, 197, 38, 221, 221, 126], [193, 124, 103, 215, 106, 229, 162, 168, 166, 78, 144, 234, 199, 254, 152, 250], [66, 26, 68, 54, 206, 16, 155, 248, 231, 198, 240, 43, 208, 205, 213, 26], [176, 102, 15, 237, 49, 141, 213, 97, 137, 155, 50, 243, 112, 51, 124, 107]]})
        False

        sage: InvArray.eval_lambda('lambda st, rvu, st0, st1: (-st[st0][st1]) + (rvu[4*st0 + st1]) == 0', idx_info = [{'st0': 0, 'st1': 0}, {'st0': 0, 'st1': 1}, {'st0': 2, 'st1': 2}, {'st0': 2, 'st1': 3}, {'st0': 3, 'st1': 0}, {'st0': 3, 'st1': 1}, {'st0': 3, 'st1': 2}, {'st0': 3, 'st1': 3}, {'st0': 0, 'st1': 2}, {'st0': 0, 'st1': 3}, {'st0': 1, 'st1': 0}, {'st0': 1, 'st1': 1}, {'st0': 1, 'st1': 2}, {'st0': 1, 'st1': 3}, {'st0': 2, 'st1': 0}, {'st0': 2, 'st1': 1}], tc = {'rvu': [28, 131, 11, 85, 193, 124, 103, 215, 66, 26, 68, 54, 176, 102, 15, 237], 'st': [[28, 131, 11, 85, 133, 46, 179, 20, 227, 148, 225, 197, 38, 221, 221, 126], [193, 124, 103, 215, 106, 229, 162, 168, 166, 78, 144, 234, 199, 254, 152, 250], [66, 26, 68, 54, 206, 16, 155, 248, 231, 198, 240, 43, 208, 205, 213, 26], [176, 102, 15, 237, 49, 141, 213, 97, 137, 155, 50, 243, 112, 51, 124, 107]]})
        True

        """
        """
        Note: sage_eval vs eval
        sage_eval works on str of the format 'lambda x,y: 2*x+y'
        whereas eval works on str of the format 2*x+y directly (no lambda)
        Also, the result of sage_eval can apply on dicts whose keys are str
        e.g.  f(**{'x':2,'y':3})
        whereas the result of eval applies on dict whose keys are variables
        e.g.  f(**{x:2,y:3})
        """

        if __debug__:
            assert is_str(f) and 'lambda' in f, f
            assert (idx_info is None
                    or is_list(idx_info) and all(is_dict(v)
                                                 for v in idx_info)), indx_info
            assert is_dict(tc), tc
            assert all(is_str(k) for k in tc), tc.keys()

        f = sage_eval(f)
        vs = f.func_code.co_varnames

        arrs = [v for v in vs if v in tc]  #A,B
        extfuns = [v for v in vs if v in ExtFun.efdict]
        idxStr = [v for v in vs if v not in arrs + extfuns]  #i,j,k

        d_tc = dict([(v, tc[v]) for v in arrs])
        d_extfun = dict([(v, ExtFun(v).get_fun()) for v in extfuns])
        d_ = merge_dict([d_tc, d_extfun])

        if idx_info is None:  #obtain idxsVals from the pivot array
            pivotContents = tc[arrs[0]]
            idxVals = [idx for idx, _ in Miscs.travel(pivotContents)]
            idx_info = [dict(zip(idxStr, idxV)) for idxV in idxVals]

        ds = [merge_dict([d_, idx_info_]) for idx_info_ in idx_info]

        try:
            return all(f(**d) for d in ds)
        except IndexError:
            return False
        except TypeError:
            return False
        except NameError as msg:
            logger.warn(msg)
            return False