def generalize(f, ss, maxV, minV): assert z3.is_expr(f), f assert isinstance(ss, set) and all(z3.is_expr(x) for x in ss), ss ofs = Miscs.getTermsFixedCoefs(ss, 2) ofs = [OctForm.convert(of) for of in ofs] #octagonal forms #fExprs = [f.expr for f in fs] ofs = [(of, of.mkUbExpr(maxV)) for of in ofs] rs = [(of, SMT.check(f, ubExpr)) for (of, ubExpr) in ofs] rs = [(of, cexs) for (of, (cexs, isSucc)) in rs if SMT.getStat(cexs, isSucc) != SMT.DISPROVED] def _f(octForm): statsd = {maxV: SMT.PROVED} boundV = gc(f, octForm, minV, maxV, statsd) if boundV not in statsd or statsd[boundV] != SMT.DISPROVED: return boundV else: return None print "compute upperbounds for {} oct terms".format(len(rs)) ubVs = [(of, _f(of)) for (of, _) in rs] ubVs = [(of, v) for (of, v) in ubVs if v is not None] return ubVs
def gen(self, deg, traces, inps): assert deg >= 1, deg assert isinstance(traces, DTraces), traces assert isinstance(inps, Inps), inps assert isinstance(traces, DTraces) and traces, traces assert isinstance(inps, Inps), inps mymaxv = 10 maxV = mymaxv minV = -1 * maxV #without these restrictions, klee takes a long time to run ubmaxV = maxV * 2 ubminV = -1 * ubmaxV locs = traces.keys() vss = [[sage.all.var(k) for k in self.invdecls[loc]] for loc in locs] mydeg = 2 if mydeg > 2: logger.warn("not Oct invs (deg {}). Might be slow".format(deg)) termss = [Miscs.getTermsFixedCoefs(vs, mydeg) for vs in vss] logger.info( "{} locs: check upperbounds for {} terms (range {})".format( len(locs), sum(map(len, termss)), mymaxv)) refs = { loc: {Inv(t <= maxV): t for t in terms} for loc, terms in zip(locs, termss) } ieqs = DInvs((loc, Invs.mk(refs[loc].keys())) for loc in refs) myinps = None cInps, cTraces, ieqs = self.prover.check(ieqs, myinps, ubminV, ubmaxV) if cInps: newInps = Gen.updateInps(cInps, inps) _ = self.getTracesAndUpdate(newInps, traces) ieqs = ieqs.removeDisproved() tasks = [(loc, refs[loc][ieq]) for loc in ieqs for ieq in ieqs[loc]] logger.debug("{} locs: compute upperbounds for {} terms".format( len(locs), len(tasks))) def _f(loc, term): vs = traces[loc].myeval(term) try: mminV = int(max(minV, max(v for v in vs if v < maxV))) except ValueError: mminV = minV logger.debug( "{}: compute ub for '{}', start w/ min {}, maxV {})".format( loc, term, mminV, maxV)) disproves = set() boundV = self.guessCheck( loc, term, #traces, inps, mminV, maxV, ubminV, ubmaxV, disproves) if boundV not in disproves and boundV not in {maxV, minV}: inv = Inv(term <= boundV) logger.detail("got {}".format(inv)) return inv else: return None def wprocess(tasks, Q): rs = [(loc, _f(loc, term)) for loc, term in tasks] if Q is None: return rs else: Q.put(rs) doMP = settings.doMP and len(tasks) >= 2 wrs = Miscs.runMP('guesscheck', tasks, wprocess, chunksiz=1, doMP=doMP) rs = [(loc, inv) for loc, inv in wrs if inv] dinvs = DInvs() for loc, inv in rs: if loc not in dinvs: dinvs[loc] = Invs() dinvs[loc].add(inv) return dinvs