def gen(self, deg, traces, inps): assert deg >= 1, deg assert isinstance(traces, DTraces) and traces, traces assert isinstance(inps, Inps), inps locs = traces.keys() # first obtain enough traces tasks = [(loc, self._get_init_traces(loc, deg, traces, inps, settings.EQT_RATE)) for loc in locs] tasks = [(loc, tcs) for loc, tcs in tasks if tcs] # then solve/prove in parallel def f(tasks): return [(loc, self._infer(loc, template, uks, exprs, traces, inps)) for loc, (template, uks, exprs) in tasks] wrs = Miscs.run_mp('find eqts', tasks, f) # put results together dinvs = DInvs() for loc, (eqts, cexs) in wrs: new_inps = inps.merge(cexs, self.inp_decls.names) mlog.debug("{}: got {} eqts, {} new inps".format( loc, len(eqts), len(new_inps))) if eqts: mlog.debug('\n'.join(map(str, eqts))) dinvs[loc] = Invs(eqts) return dinvs
def simplify(self, use_reals): assert isinstance(use_reals, bool), use_reals eqts, eqts_largecoefs, octs, mps, preposts, falseinvs = \ self.classify(self) assert not falseinvs, falseinvs non_mps = eqts + preposts + octs if non_mps and len(mps) >= 2: # parallelizing simplifying mps non_mps_exprs = [e.expr(use_reals) for e in non_mps] conj = z3.And(non_mps_exprs) def f(mps): return [ mp for mp in mps if not Z3._imply(conj, mp.expr(use_reals)) ] wrs = Miscs.run_mp("simplifying {} mps".format(len(mps)), mps, f) mps = [mp for mp in wrs] rs = non_mps + mps if rs: is_conj = True rs = self._simplify(rs, is_conj, use_reals) return self.__class__(rs + eqts_largecoefs)
def simplify(self, use_reals): assert isinstance(use_reals, bool), use_reals assert (self.siz), self st = time() def f(tasks): return [(loc, self[loc].simplify(use_reals)) for loc in tasks] wrs = Miscs.run_mp('simplify', list(self), f) dinvs = self.__class__((loc, invs) for loc, invs in wrs if invs) Miscs.show_removed('simplify', self.siz, dinvs.siz, time() - st) return dinvs
def test(self, dtraces): # assert isinstance(dtraces, DTraces) assert self.siz, self st = time() tasks = [loc for loc in self if self[loc]] def f(tasks): return [(loc, self[loc].test(dtraces[loc])) for loc in tasks] wrs = Miscs.run_mp("test_dinvs", tasks, f) dinvs = DInvs([(loc, invs) for loc, invs in wrs if invs]) Miscs.show_removed("test_dinvs", self.siz, dinvs.siz, time() - st) return dinvs
def gen(self, traces, inps): assert isinstance(traces, data.traces.DTraces) and traces, traces assert isinstance(inps, data.traces.Inps), inps statss = [] locs = traces.keys() termss = [ self.get_terms(self.inv_decls[loc].sageExprs) for loc in locs ] mlog.debug("check upperbounds for {} terms at {} locs".format( sum(map(len, termss)), len(locs))) maxV = settings.OCT_MAX_V minV = -1 * maxV refs = { loc: {self.mk_le(t, maxV): t for t in terms} for loc, terms in zip(locs, termss) } ieqs = data.inv.invs.DInvs([(loc, data.inv.invs.Invs(refs[loc].keys())) for loc in refs]) cexs, ieqs, stats = self.check(ieqs, inps=None) statss.extend(stats) if cexs: cexs_inps = inps.merge(cexs, self.inp_decls.names) if cexs_inps: self.get_traces(cexs_inps, traces) ieqs = ieqs.remove_disproved() tasks = [(loc, refs[loc][mp]) for loc in ieqs for mp in ieqs[loc]] mlog.debug("{} locs: infer upperbounds for {} terms".format( len(locs), len(tasks))) def f(tasks): return [(loc, self.gc(loc, term, minV, maxV, traces)) for loc, term in tasks] wrs = Miscs.run_mp('guesscheck', tasks, f) dinvs = data.inv.invs.DInvs() for loc, (inv, stats) in wrs: statss.extend(stats) if inv: dinvs.setdefault(loc, data.inv.invs.Invs()).add(inv) return dinvs, statss
def start(self, seed, maxdeg): assert maxdeg is None or maxdeg >= 1, maxdeg super().start(seed, maxdeg) st = time.time() tasks = [] for loc in self.dtraces: symbols = self.inv_decls[loc] traces = self.dtraces[loc] if settings.DO_EQTS: def _f(): return self.infer_eqts(maxdeg, symbols, traces) tasks.append((loc, _f)) if settings.DO_IEQS: def _f(): return self.infer_ieqs(symbols, traces) tasks.append((loc, _f)) def f(tasks): rs = [(loc, _f()) for loc, _f in tasks] return rs wrs = Miscs.run_mp("(pure) dynamic inference", tasks, f) dinvs = DInvs() for loc, invs in wrs: for inv in invs: dinvs.add(loc, inv) try: new_traces = self.dtraces.merge(self.test_dtraces) mlog.debug('added {} test traces'.format(new_traces.siz)) except AttributeError: # no test traces pass dinvs = self.sanitize(dinvs, self.dtraces) print(dinvs)
def test(self, traces): # assert isinstance(traces, Traces) assert (self), self def f(tasks): return [(inv, inv.test(traces)) for inv in tasks] wrs = Miscs.run_mp("test", list(self), f) myinvs = set() for inv, passed in wrs: if passed: myinvs.add(inv) else: mlog.debug("remove {}".format(inv)) invs = self.__class__(myinvs) return invs
def _get_traces_mp(self, inps): """ run program on inps and obtain traces in parallel return {inp: traces} """ assert isinstance(inps, data.traces.Inps), inps tasks = [inp for inp in inps if inp not in self._cache] def f(tasks): return [(inp, self._get_traces(inp)) for inp in tasks] wrs = Miscs.run_mp("get traces", tasks, f) for inp, traces in wrs: assert inp not in self._cache self._cache[inp] = traces return {inp: self._cache[inp] for inp in inps}