Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    def get_invs(self, deg=2):
        """
        Default method to obtain invariants
        By default, DIG finds flat/nested relations over arr vars
        and finds eqts/ieqs(deduction) over num vars.
        """

        rs = []
        if not is_empty(self.ss_arr):
            logger.debug('*** Generate Array Invs over {} ***'.format(
                self.ss_arr))
            rs = rs + self.get_flat_array()
            rs = rs + self.get_nested_array()

        if not is_empty(self.ss_num):
            logger.debug('*** Generate Polynomial Invs over {} ***'.format(
                self.ss_num))

            if __debug__:
                assert deg >= 1, deg

            terms = dig_miscs.gen_terms(deg, self.ss_num)
            logger.debug('deg={}, |ss_num|={}, |terms|={}'.format(
                deg, len(self.ss_num), len(terms)))

            rs = rs + self.get_eqts(terms)

        return rs
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    def get_invs(self, deg=2):
        """
        Default method to obtain invariants
        By default, DIG finds flat/nested relations over arr vars
        and finds eqts/ieqs(deduction) over num vars.
        """

        rs = []
        if not is_empty(self.ss_arr):
            logger.debug('*** Generate Array Invs over {} ***\n'
                         .format(self.ss_arr))
            rs = rs + self.get_flat_array()
            rs = rs + self.get_nested_array()

        if not is_empty(self.ss_num):
            logger.debug('*** Generate Polynomial Invs over {} ***\n'
                         .format(self.ss_num))

            if __debug__:
                assert deg >= 1, deg

            terms = dig_miscs.gen_terms(deg, self.ss_num)
            logger.debug('deg={}, |ss_num|={}, |terms|={}'
                         .format(deg,len(self.ss_num),len(terms)))
            rs = rs + self.get_eqts(terms)
                
        return rs
Ejemplo n.º 7
0
    def rfilter(self, tcs, do_parallel=True):

        if is_empty(self.ps) or is_empty(tcs):
            logger.debug('rfilter skips (|ps|={}, |tcs|={})'.format(
                len(self.ps), len(tcs)))
            return None

        logger.debug('rfilter(|ps|={}, |tcs|={})'.format(
            len(self.ps), len(tcs)))

        if not isinstance(self.ps[0], InvExp):
            from dig_miscs import Miscs
            tcs = Miscs.keys_to_str(tcs)

        def wprocess(tasks, Q):
            rs = [p for p in tasks if all(p.seval(tc) for tc in tcs)]
            if Q is None:  #no multiprocessing
                return rs
            else:
                Q.put(rs)

        tasks = self.ps

        if do_parallel:
            from vu_common import get_workloads
            from multiprocessing import (Process, Queue, current_process,
                                         cpu_count)
            Q = Queue()
            workloads = get_workloads(tasks,
                                      max_nprocesses=cpu_count(),
                                      chunksiz=2)

            logger.debug("workloads 'refine' {}: {}".format(
                len(workloads), map(len, workloads)))

            workers = [
                Process(target=wprocess, args=(wl, Q)) for wl in workloads
            ]

            for w in workers:
                w.start()
            wrs = []
            for _ in workers:
                wrs.extend(Q.get())
        else:
            wrs = wprocess(tasks, Q=None)

        self.ps = wrs
        Refine.print_diff('rfilter', len(tasks), len(self.ps))
Ejemplo n.º 8
0
    def rem_dup_arrs(ps, ainfo):
        """
        Remove relations that involve elements from same arrays

        Examples:

        sage: var('x_0 x_1 y_0 y_1')
        (x_0, x_1, y_0, y_1)
        sage: ainfo = {x_0:{'name':'x','idxs':[0]},x_1:{'name':'x','idxs':[1]}, y_0:{'name':'y','idxs':[0]},y_1:{'name':'y','idxs':[1]}}
        sage: FlatArray.rem_dup_arrs([x_0 + x_1 == 0, x_1 + y_1 == 0, x_0 + y_1 + y_0==0, x_0 + x_1-2==0], ainfo)
        dig_arrays:Warn:Removed 3 array eqts
        x_0 + x_1 == 0
        x_0 + y_0 + y_1 == 0
        x_0 + x_1 - 2 == 0
        [x_1 + y_1 == 0]

        
        """
        get_anames = lambda p: [ainfo[v]['name'] for v in get_vars(p)]
        ps_rem, ps = vpartition(ps, lambda p: vall_uniq(get_anames(p)))
        
        if not is_empty(ps_rem):
            logger.warn('Removed {} array eqts\n{}'
                        .format(len(ps_rem), list_str(ps_rem,'\n')))

            
        return ps
Ejemplo n.º 9
0
        def wprocess(ae,Q):
            r = ae.peelme(data=self.tcs[0])
            if not is_empty(r):
                logger.debug('Nesting {} has {} rel(s)\n{}'
                             .format(ae,len(r),'\n'.join(r)))
 
            Q.put(r)
Ejemplo n.º 10
0
def imply(fs, gs):
    """
    Checks if the set f of formulas implies the set f of formulas

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

    sage: assert imply([x-6==0],x*x-36==0)
    sage: assert imply([x-6==0,x+6==0],x*x-36==0)
    sage: assert not imply([x*x-36==0],x-6==0)
    sage: assert not imply([x-6==0],x-36==0)
    sage: assert imply(x-7>=0,x>=6)
    sage: assert not imply(x-7>=0,x>=8)
    sage: assert not imply(x-6>=0,x-7>=0)
    sage: assert not imply([x-7>=0,y+5>=0],x+y-3>=0)
    sage: assert imply([x-7>=0,y+5>=0],x+y-2>=0)
    sage: assert imply([x-2*y>=0,y-1>=0],x-2>=0)
    sage: assert not imply([],x-2>=0)
    sage: assert imply([x-7>=0,y+5>=0],x+y-2>=0)
    sage: assert imply([x^2-9>=0,x>=0],x-3>=0)
    sage: assert not imply([1/2*x**2 - 3/28*x + 1 >= 0],1/20*x**2 - 9/20*x + 1 >= 0)
    sage: assert imply([1/20*x**2 - 9/20*x + 1 >= 0],1/2*x**2 - 3/28*x + 1 >= 0)
    sage: assert imply([x-6==0],x*x-36==0)
    sage: assert not imply([x+7>=0,y+5>=0],x*y+36>=0)
    sage: assert not imply([x+7>=0,y+5>=0],x*y+35>=0)
    sage: assert not imply([x+7>=0,y+5>=0],x*y-35>=0)
    sage: assert not imply([x+7>=0],x-8>=0)
    sage: assert imply([x+7>=0],x+8>=0)
    sage: assert imply([x+7>=0],x+8.9>=0)
    sage: assert imply([x>=7,y>=5],x*y>=35)
    sage: assert not imply([x>=-7,y>=-5],x*y>=35)
    sage: assert imply([x-7>=0,y+5>=0],[x+y-2>=0,x>=2-y])

    """
    if is_empty(fs) or is_empty(gs):
        return False #conservative approach

    if not isinstance(fs, list): fs = [fs]
    if not isinstance(gs, list): gs = [gs]

    fs = [toZ3(f, is_real=True) for f in fs]
    gs = [toZ3(g, is_real=True) for g in gs]

    claim = z3.Implies(z3.And(fs), z3.And(gs))

    is_proved, _ = vprove(claim)
    return is_proved
Ejemplo n.º 11
0
    def rfilter(self,tcs,do_parallel=True):

        if is_empty(self.ps) or is_empty(tcs):
            logger.debug('rfilter skips (|ps|={}, |tcs|={})'
                         .format(len(self.ps), len(tcs)))
            return None

        logger.debug('rfilter(|ps|={}, |tcs|={})'
                     .format(len(self.ps), len(tcs)))
        
        if not isinstance(self.ps[0],InvExp):
            from dig_miscs import Miscs
            tcs = Miscs.keys_to_str(tcs)

        def wprocess(tasks,Q):
            rs = [p for p in tasks if all(p.seval(tc) for tc in tcs)]
            if Q is None: #no multiprocessing
                return rs
            else:
                Q.put(rs)
            
        tasks = self.ps

        if do_parallel:
            from vu_common import get_workloads
            from multiprocessing import (Process, Queue, 
                                         current_process, cpu_count)
            Q=Queue()
            workloads = get_workloads(tasks, 
                                      max_nprocesses=cpu_count(),
                                      chunksiz=2)

            logger.debug("workloads 'refine' {}: {}"
                         .format(len(workloads),map(len,workloads)))
                                 
            workers = [Process(target=wprocess,args=(wl,Q))
                       for wl in workloads]

            for w in workers: w.start()
            wrs = []
            for _ in workers: wrs.extend(Q.get())
        else:
            wrs = wprocess(tasks,Q=None)
        
        self.ps = wrs
        Refine.print_diff('rfilter', len(tasks), len(self.ps))
Ejemplo n.º 12
0
    def solve(self): #FlatArray
        
        #Create new variables and traces
        logger.info('Compute new traces (treating array elems as new vars)')
        ainfo  = {}  #{A_0_0=[0,0],B_1_2_3=[1,2,3]}
        tsinfo = {} #{A: [A_0,A_1, ..], B:[B_0_0,B_0_1,..]}
        print self.tcs
        
        tcs = [FlatArray.compute_new_trace(tc, ainfo, tsinfo) 
               for tc in self.tcs]

        ps = self.get_rels_elems1(tcs)
        #ps = self.get_rels_elems2(tcs,tsinfo)
        
        #Group arrays and in each group, find rels among array idxs 
        gs = FlatArray.group_arr_eqts(ps, ainfo)
        logger.info('Partition {} eqts into {} groups'
                    .format(len(ps), len(gs)))
        
        sols = []
        for i,(gns,gps) in enumerate(gs.iteritems()):
            if __debug__:
                assert not is_empty(gps)
                
            # Modify/reformat if necessary        
            gps = FlatArray.modify_arr_eqts(gps, ainfo)
           
            #Find rels over array indices
            logger.debug("{}. Find rels over idx from {} eqts (group {})"
                         .format(i,len(gps),gns))
            gps = [FlatArray.parse_arr_eqt(p,ainfo) for p in gps]
            gsols = FlatArray.find_rels(gps)
            
            sols.extend(gsols)

        
        if is_empty(sols):
            logger.warn('No rels found over arr idxs, use orig results')
            sols = flatten(ps)
            self.sols = map(InvEqt, sols)
            self.do_refine = False
        else:
            self.sols = map(InvFlatArray, sols)

        self.print_sols()
Ejemplo n.º 13
0
    def get_eqts(self, terms=None):
        if terms is None:
            terms = self.ss_num

        from dig_polynomials import Eqt
        solver = Eqt(terms, self.tcs_num, self.xinfo)
        solver.go()
        sols = solver.sols

        if not (is_empty(sols) or is_empty(self.xinfo['Assume'])):
            #deduce new info if external knowledge (assumes) is avail
            from dig_polynomials import IeqDeduce
            solver = IeqDeduce(xinfo=self.xinfo, eqts=[s.p for s in sols])
            solver.solve()
            solver.print_sols()

            sols = sols + solver.sols

        return sols
Ejemplo n.º 14
0
    def get_eqts(self,terms=None):
        if terms is None:
            terms = self.ss_num

        from dig_polynomials import Eqt
        solver = Eqt(terms, self.tcs_num, self.xinfo)
        solver.go()
        sols = solver.sols

        if not (is_empty(sols) or is_empty(self.xinfo['Assume'])):
            #deduce new info if external knowledge (assumes) is avail
            from dig_polynomials import IeqDeduce
            solver = IeqDeduce(xinfo = self.xinfo,
                               eqts  = [s.p for s in sols])
            solver.solve()
            solver.print_sols()

            sols = sols + solver.sols

        return sols
Ejemplo n.º 15
0
    def rinfer(self):
        """
        Return a (preferably minimal) subset of ps that
        infers all properties in ps.

        sage: logger.set_level(VLog.DEBUG)
            
        sage: var('a s t y')
        (a, s, t, y)

        sage: rf = Refine(map(InvEqt,[a*a - s + t == 0, t*t - 4*s + 2*t + 1 == 0, \
        a*s - 1/2*s*t + 1/2*s == 0,  a*x - 1/2*x*t + 1/2*x == 0, \
        a - 1/2*t + 1/2 == 0, a*t - 2*s + 3/2*t + 1/2 == 0]))
        sage: rf.rinfer()
        refine:Debug:rinfer(|ps|=6)
        refine:Debug:rinfer (before 6, after 2, diff 4)
        sage: assert \
        set([p.p for p in rf.ps]) == set([a - 1/2*t + 1/2 == 0, t^2 - 4*s + 2*t + 1 == 0]) or \
        set([p.p for p in rf.ps]) == set([a - 1/2*t + 1/2 == 0, a^2 - s + t == 0])


        sage: rf = Refine(map(InvIeq,[x-7>=0, x + y -2>=0, y+5 >= 0, -7 + x >= 0])); rf.rinfer(); sorted(rf.ps,key=str)
        refine:Debug:vset (before 4, after 3, diff 1)
        refine:Debug:rinfer(|ps|=3)
        refine:Debug:rinfer (before 3, after 2, diff 1)
        [x - 7 >= 0, y + 5 >= 0]


        sage: rf = Refine(map(InvEqt,[x+y==0])); rf.rinfer(); sorted(rf.ps,key=str)
        refine:Debug:rinfer skips (|ps|=1)
        [x + y == 0]
        
        """

        if len(self.ps) <= 1:
            logger.debug('rinfer skips (|ps|={})'.format(len(self.ps)))
            return None

        logger.debug('rinfer(|ps|={})'.format(len(self.ps)))

        ps = [p.p for p in self.ps if isinstance(p, InvExp)]

        if is_empty(ps):
            logger.warn('cannot do inferrence on non polynomial rels')
            return None

        self.ps = [
            InvEqt(p) if p.operator() == operator.eq else InvIeq(p)
            for p in Refine.rinfer_helper(ps)
        ]

        Refine.print_diff('rinfer', len(ps), len(self.ps))
Ejemplo n.º 16
0
    def rinfer(self):
        """
        Return a (preferably minimal) subset of ps that
        infers all properties in ps.

        sage: logger.set_level(VLog.DEBUG)
            
        sage: var('a s t y')
        (a, s, t, y)

        sage: rf = Refine(map(InvEqt,[a*a - s + t == 0, t*t - 4*s + 2*t + 1 == 0, \
        a*s - 1/2*s*t + 1/2*s == 0,  a*x - 1/2*x*t + 1/2*x == 0, \
        a - 1/2*t + 1/2 == 0, a*t - 2*s + 3/2*t + 1/2 == 0]))
        sage: rf.rinfer()
        refine:Debug:rinfer(|ps|=6)
        refine:Debug:rinfer (before 6, after 2, diff 4)
        sage: assert \
        set([p.p for p in rf.ps]) == set([a - 1/2*t + 1/2 == 0, t^2 - 4*s + 2*t + 1 == 0]) or \
        set([p.p for p in rf.ps]) == set([a - 1/2*t + 1/2 == 0, a^2 - s + t == 0])


        sage: rf = Refine(map(InvIeq,[x-7>=0, x + y -2>=0, y+5 >= 0, -7 + x >= 0])); rf.rinfer(); sorted(rf.ps,key=str)
        refine:Debug:vset (before 4, after 3, diff 1)
        refine:Debug:rinfer(|ps|=3)
        refine:Debug:rinfer (before 3, after 2, diff 1)
        [x - 7 >= 0, y + 5 >= 0]


        sage: rf = Refine(map(InvEqt,[x+y==0])); rf.rinfer(); sorted(rf.ps,key=str)
        refine:Debug:rinfer skips (|ps|=1)
        [x + y == 0]
        
        """

        if len(self.ps) <= 1:
            logger.debug('rinfer skips (|ps|={})'.format(len(self.ps)))
            return None

        logger.debug('rinfer(|ps|={})'.format(len(self.ps)))

        ps = [p.p for p in self.ps if isinstance(p,InvExp)]

        if is_empty(ps):
            logger.warn('cannot do inferrence on non polynomial rels')
            return None

        
        self.ps = [InvEqt(p) if p.operator() == operator.eq else InvIeq(p)
                   for p in Refine.rinfer_helper(ps)]

        Refine.print_diff('rinfer', len(ps), len(self.ps))
Ejemplo n.º 17
0
    def _get_clp(self, typ, terms=None, subset_siz=None):
        if terms is None:
            terms = self.ss_num
        if is_empty(terms):
            return []

        import dig_polynomials as dp

        if 'gen' in typ:
            solver = dp.IeqCLPGen(terms, self.tcs_num, self.xinfo)
        else:
            solver = dp.IeqCLPFixed(terms, self.tcs_num, self.xinfo)

        solver.subset_siz = subset_siz

        solver.go()
        return solver.sols
Ejemplo n.º 18
0
def toZ3(p, is_real):
    """
    Convert a Sage expression to a Z3 expression

    Initially implements with a dictionary containing variables
    e.g. {x:Real('x')} but the code is longer and more complicated.
    This implemention does not require a dictionary pass in.

    Todo: cache this function

    sage: toZ3(x*x*x, False)
    x*x*x
    """
    assert is_sage_expr(p), p

    def retval(p):
        if p.is_symbol():
            _f = z3.Real if is_real else z3.Int
        else:
            _f = z3.RealVal if is_real else z3.IntVal

        return _f(str(p))

    try:
        oprs = p.operands()
    except Exception:
        return retval(p)

    if is_empty(oprs):
        return retval(p)
    else:
        op = p.operator()

        #z3 has problem w/ t^c , so use t*t*t..
        if op == operator.pow:
            assert len(oprs) == 2, oprs
            t, c = oprs
            t = toZ3(t, is_real)
            vs = [t] * c
            z3exp = reduce(operator.mul, vs)
        else:
            oprs = [toZ3(o, is_real) for o in oprs]
            z3exp = reduce(op, oprs)

        assert z3.is_expr(z3exp), z3exp
        return z3exp
Ejemplo n.º 19
0
def print_summary(filename,expect,sols_filename,sols_run):
    if is_empty(sols_filename):
        return

    print("\nSUMMARY ({})".format(filename))
    print("Expect ({}): {}".format(len(expect), ', '.join(map(str,expect))))
    time_total = 0.0
    for (nr,rs,deg,etime) in sols_filename:
        print '* Run {}, time {}, deg {}'.format(nr, etime, deg)
        Inv.print_invs(rs)
        time_total =  time_total + etime

    print('\nObtain {} unique results over {} run'
          .format(len(sols_run), len(sols_filename)))
    Inv.print_invs(sols_run,nice_format=False)

    time_str = '{0:.1f}'.format(time_total/len(sols_filename))
    print('TIME AVG {}, #invs {}, ({})\n'
          .format(time_str,len(sols_run), filename))
Ejemplo n.º 20
0
def print_summary(filename, expect, sols_filename, sols_run):
    if is_empty(sols_filename):
        return

    print("\nSUMMARY ({})".format(filename))
    print("Expect ({}): {}".format(len(expect), ', '.join(map(str, expect))))
    time_total = 0.0
    for (nr, rs, deg, etime) in sols_filename:
        print '* Run {}, time {}, deg {}'.format(nr, etime, deg)
        Inv.print_invs(rs)
        time_total = time_total + etime

    print('\nObtain {} unique results over {} run'.format(
        len(sols_run), len(sols_filename)))
    Inv.print_invs(sols_run, nice_format=False)

    time_str = '{0:.1f}'.format(time_total / len(sols_filename))
    print('TIME AVG {}, #invs {}, ({})\n'.format(time_str, len(sols_run),
                                                 filename))
Ejemplo n.º 21
0
    def preprocess(self, xinfo):
        """
        Preprocess input data
        1) transforms external functions to special arrays
        1) change arr repr to value->index repr to speed up arr idx lookup
        2) generate nodes
        """
        if __debug__:
            assert is_dict(xinfo), xinfo
        
        evs = ExtFun.gen_extvars(xinfo=xinfo)
        #arrays only
        evs = [OrderedDict([(k,v) for k,v in ev.iteritems() if is_list(v)])
               for ev in evs]
        evs = Miscs.keys_to_str(evs)
        
        if not is_empty(evs): #add to traces
            self.tcs = [merge_dict(evs + [tc]) for tc in self.tcs]
            self.tcs_extra = [merge_dict(evs + [tc]) for tc in self.tcs_extra]

        
        mytcs = []
        for tc in self.tcs:
            #arrs reprent ext funs (already in new format)
            efs = ExtFun.gen_extfuns(tc=tc,xinfo=xinfo)
            
            #convert normal arr format to new format
            arrs = [(k, Miscs.getListIdxs(v)) for k,v in tc.items()] 
            arrs = OrderedDict(arrs)
            
            d = merge_dict(efs + [arrs])
            mytcs.append(d)
         
 
        self.tcs = mytcs

        self.trees = [Tree({'root':k,
                            'children': [None] * len(c.values()[0][0]),
                            'commute': ExtFun(k).is_commute()})
                      for k,c in self.tcs[0].items()]
        
        self.xinfo = xinfo
Ejemplo n.º 22
0
    def _get_mpp(self, typ, terms=None, subset_siz=None):
        if terms is None:
            terms = self.ss_num
        if is_empty(terms):
            return []

        import dig_polynomials as dp

        solver = dp.IeqMPPGen if 'gen' in typ else dp.IeqMPPFixed
        solver = solver(terms, self.tcs_num, self.xinfo)

        if 'max_then_min' in typ:
            mpp_opt = dp.IeqMPP.opt_max_then_min
        elif 'min' in typ:
            mpp_opt = dp.IeqMPP.opt_min_plus
        else:
            mpp_opt = dp.IeqMPP.opt_max_plus

        solver.mpp_opt = mpp_opt
        solver.subset_siz = subset_siz

        solver.go()
        return solver.sols
Ejemplo n.º 23
0
    def to_z3exp(p, is_real):
        """
        Convert a Sage expression to a Z3 expression

        Initially implements with a dictionary containing variables
        e.g. {x:Real('x')} but the code is longer and more complicated.
        This implemention does not require a dictionary pass in.

        Todo: cache this function
        """

        assert is_sage_expr(p), p

        def retval(p):
            if p.is_symbol():
                z3exp = (z3.Real if is_real else z3.Int)(str(p))
            else:
                z3exp = (z3.RealVal if is_real else z3.IntVal)(str(p))

            if __debug__:
                assert z3.is_expr(z3exp), z3exp

            return z3exp

        try:
            oprs = p.operands()
        except Exception:
            return retval(p)
        
        if is_empty(oprs):
            return retval(p)
        else:
            oprs = [SMT_Z3.to_z3exp(o, is_real) for o in oprs]
            z3exp = SMT_Z3._reduce(p.operator(),oprs)

        assert z3.is_expr(z3exp), z3exp
        return z3exp
Ejemplo n.º 24
0
 def get_gid(ls):
     k = [i for i, l in enumerate(ls) if not is_sage_inf(l) and l != 0]
     return None if is_empty(k) else tuple(k)
Ejemplo n.º 25
0
    def rfilter_old(self, tcs):
        """
        Returns the subset of ps that satisfies all testcases tcs

        Examples:

        sage: logger.set_level(VLog.DEBUG)

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

        sage: rf = Refine(map(InvIeq,[x^2 >= 0 , x-y >= 7]));rf.rfilter([{x:1,y:0}]);  sorted(rf.ps,key=str)
        refine:Debug:rfilter(|ps|=2, |tcs|=1)
        refine:Debug:rfilter (before 2, after 1, diff 1)
        [x^2 >= 0]

        sage: rf = Refine(map(InvIeq,[2*x -y >= 0])); rf.rfilter([{y: 14, x: 7}, {y: 13, x: 7}, {y: 6, x: 4}, {y: 1, x: 1}, {y: 2, x: 1}, {y: 5, x: 100}]); sorted(rf.ps,key=str)
        refine:Debug:rfilter(|ps|=1, |tcs|=6)
        [2*x - y >= 0]

        sage: rf = Refine(map(InvIeq,[2*x -y >= 0])); rf.rfilter([{y: 14, x: 7}, {y: 13, x: 7}, {y: 6, x: 4}, {y: 1, x: 1}, {y: 2, x: 1}, {y: 25, x: 9}, {y:25 , x*y: 15, x: 9}]); sorted(rf.ps,key=str)
        refine:Debug:rfilter(|ps|=1, |tcs|=7)
        refine:Debug:rfilter (before 1, after 0, diff 1)
        []

        ** This is by design
        sage: rf = Refine(map(InvIeq,[x^3 >= 0 , x-y >= 7])); rf.rfilter([{z:1}])
        refine:Debug:rfilter(|ps|=2, |tcs|=1)
        refine:Debug:rfilter (before 2, after 0, diff 2)
        sage: assert(rf.ps == [])

        sage: rf = Refine(map(InvMPP,[('lambda x: x>=10',''), ('lambda x,y: max(x,y)>12',''), ('lambda x: x>=10','')])); rf.rfilter([{x:20,y:0},{x:9,y:13}]); sorted(rf.ps,key=str)
        refine:Debug:vset (before 3, after 2, diff 1)
        refine:Debug:rfilter(|ps|=2, |tcs|=2)
        refine:Debug:rfilter (before 2, after 1, diff 1)
        ['lambda x,y: max(x,y)>12']


        sage: rf = Refine(map(InvMPP,[('lambda x: x>=10', ''), ('lambda x,y: max(x,y)>12','')])); rf.rfilter([{x:20,y:0}]); sorted(rf.ps,key=str)
        refine:Debug:rfilter(|ps|=2, |tcs|=1)
        ['lambda x: x>=10', 'lambda x,y: max(x,y)>12']


        sage: rf = Refine(map(InvMPP,[('lambda x: x>=10',''), ('lambda x,y: max(x,y)>12','')])); rf.rfilter([]); sorted(rf.ps,key=str)
        refine:Debug:rfilter skips (|ps|=2, |tcs|=0)
        ['lambda x: x>=10', 'lambda x,y: max(x,y)>12']


        """

        if is_empty(self.ps) or is_empty(tcs):
            logger.debug('rfilter skips (|ps|={}, |tcs|={})'
                         .format(len(self.ps), len(tcs)))
            return None

        logger.debug('rfilter(|ps|={}, |tcs|={})'
                     .format(len(self.ps), len(tcs)))
        
        if not isinstance(self.ps[0],InvExp):
            from dig_miscs import Miscs
            tcs = Miscs.keys_to_str(tcs)

        old_len = len(self.ps)
        self.ps = [p for p in self.ps if all(p.seval(tc) for tc in tcs)]

        Refine.print_diff('rfilter', old_len, len(self.ps))
Ejemplo n.º 26
0
    def rfilter_old(self, tcs):
        """
        Returns the subset of ps that satisfies all testcases tcs

        Examples:

        sage: logger.set_level(VLog.DEBUG)

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

        sage: rf = Refine(map(InvIeq,[x^2 >= 0 , x-y >= 7]));rf.rfilter([{x:1,y:0}]);  sorted(rf.ps,key=str)
        refine:Debug:rfilter(|ps|=2, |tcs|=1)
        refine:Debug:rfilter (before 2, after 1, diff 1)
        [x^2 >= 0]

        sage: rf = Refine(map(InvIeq,[2*x -y >= 0])); rf.rfilter([{y: 14, x: 7}, {y: 13, x: 7}, {y: 6, x: 4}, {y: 1, x: 1}, {y: 2, x: 1}, {y: 5, x: 100}]); sorted(rf.ps,key=str)
        refine:Debug:rfilter(|ps|=1, |tcs|=6)
        [2*x - y >= 0]

        sage: rf = Refine(map(InvIeq,[2*x -y >= 0])); rf.rfilter([{y: 14, x: 7}, {y: 13, x: 7}, {y: 6, x: 4}, {y: 1, x: 1}, {y: 2, x: 1}, {y: 25, x: 9}, {y:25 , x*y: 15, x: 9}]); sorted(rf.ps,key=str)
        refine:Debug:rfilter(|ps|=1, |tcs|=7)
        refine:Debug:rfilter (before 1, after 0, diff 1)
        []

        ** This is by design
        sage: rf = Refine(map(InvIeq,[x^3 >= 0 , x-y >= 7])); rf.rfilter([{z:1}])
        refine:Debug:rfilter(|ps|=2, |tcs|=1)
        refine:Debug:rfilter (before 2, after 0, diff 2)
        sage: assert(rf.ps == [])

        sage: rf = Refine(map(InvMPP,[('lambda x: x>=10',''), ('lambda x,y: max(x,y)>12',''), ('lambda x: x>=10','')])); rf.rfilter([{x:20,y:0},{x:9,y:13}]); sorted(rf.ps,key=str)
        refine:Debug:vset (before 3, after 2, diff 1)
        refine:Debug:rfilter(|ps|=2, |tcs|=2)
        refine:Debug:rfilter (before 2, after 1, diff 1)
        ['lambda x,y: max(x,y)>12']


        sage: rf = Refine(map(InvMPP,[('lambda x: x>=10', ''), ('lambda x,y: max(x,y)>12','')])); rf.rfilter([{x:20,y:0}]); sorted(rf.ps,key=str)
        refine:Debug:rfilter(|ps|=2, |tcs|=1)
        ['lambda x: x>=10', 'lambda x,y: max(x,y)>12']


        sage: rf = Refine(map(InvMPP,[('lambda x: x>=10',''), ('lambda x,y: max(x,y)>12','')])); rf.rfilter([]); sorted(rf.ps,key=str)
        refine:Debug:rfilter skips (|ps|=2, |tcs|=0)
        ['lambda x: x>=10', 'lambda x,y: max(x,y)>12']


        """

        if is_empty(self.ps) or is_empty(tcs):
            logger.debug('rfilter skips (|ps|={}, |tcs|={})'
                         .format(len(self.ps), len(tcs)))
            return

        logger.debug('rfilter(|ps|={}, |tcs|={})'
                     .format(len(self.ps), len(tcs)))
        
        if not isinstance(self.ps[0],InvExp):
            from dig_miscs import Miscs
            tcs = Miscs.keys_to_str(tcs)

        old_len = len(self.ps)
        self.ps = [p for p in self.ps if all(p.seval(tc) for tc in tcs)]

        Refine.print_diff('rfilter', old_len, len(self.ps))
Ejemplo n.º 27
0
    def imply(fs, gs):
        """
        Checks if the set f of formulas implies the set f of formulas

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

        sage: SMT_Z3.imply([x-6==0],x*x-36==0)
        True
        sage: SMT_Z3.imply([x-6==0,x+6==0],x*x-36==0)
        True
        sage: SMT_Z3.imply([x*x-36==0],x-6==0)
        False
        sage: SMT_Z3.imply([x-6==0],x-36==0)
        False
        sage: SMT_Z3.imply(x-7>=0,x>=6)
        True
        sage: SMT_Z3.imply(x-7>=0,x>=8)
        False
        sage: SMT_Z3.imply(x-6>=0,x-7>=0)
        False
        sage: SMT_Z3.imply([x-7>=0,y+5>=0],x+y-3>=0)
        False
        sage: SMT_Z3.imply([x-7>=0,y+5>=0],x+y-2>=0)
        True
        sage: SMT_Z3.imply([x-2*y>=0,y-1>=0],x-2>=0)
        True
        sage: SMT_Z3.imply([],x-2>=0)
        False
        sage: SMT_Z3.imply([x-7>=0,y+5>=0],x+y-2>=0)
        True
        sage: SMT_Z3.imply([x^2-9>=0,x>=0],x-3>=0)
        True
        sage: SMT_Z3.imply([1/2*x**2 - 3/28*x + 1 >= 0],1/20*x**2 - 9/20*x + 1 >= 0)
        False
        sage: SMT_Z3.imply([1/20*x**2 - 9/20*x + 1 >= 0],1/2*x**2 - 3/28*x + 1 >= 0)
        True
        sage: SMT_Z3.imply([x-6==0],x*x-36==0)
        True
        sage: SMT_Z3.imply([x+7>=0,y+5>=0],x*y+36>=0)
        False
        sage: SMT_Z3.imply([x+7>=0,y+5>=0],x*y+35>=0)
        False
        sage: SMT_Z3.imply([x+7>=0,y+5>=0],x*y-35>=0)
        False
        sage: SMT_Z3.imply([x+7>=0],x-8>=0)
        False
        sage: SMT_Z3.imply([x+7>=0],x+8>=0)
        True
        sage: SMT_Z3.imply([x+7>=0],x+8.9>=0)
        True
        sage: SMT_Z3.imply([x>=7,y>=5],x*y>=35)
        True
        sage: SMT_Z3.imply([x>=-7,y>=-5],x*y>=35)
        False
        sage: SMT_Z3.imply([x-7>=0,y+5>=0],[x+y-2>=0,x>=2-y])
        True

        """
        if __debug__:
            assert fs is not None, fs
            assert gs is not None, gs

        if is_empty(fs) or is_empty(gs):
            return False #conservative approach

        if not is_list(fs): fs = [fs]
        if not is_list(gs): gs = [gs]
            
        fs = [SMT_Z3.to_z3exp(f, is_real=True) for f in fs]
        gs = [SMT_Z3.to_z3exp(g, is_real=True) for g in gs]

        claim = z3.Implies(z3.And(fs), z3.And(gs))

        is_proved, _ = vprove(claim)
        return is_proved
Ejemplo n.º 28
0
 def get_gid(ls):
     k = [i for i,l in enumerate(ls) if not SR(l).is_infinity() and l != 0]
     return None if is_empty(k) else tuple(k)
Ejemplo n.º 29
0
 def get_gid(ls):
     k = [
         i for i, l in enumerate(ls)
         if not SR(l).is_infinity() and l != 0
     ]
     return None if is_empty(k) else tuple(k)