Beispiel #1
0
    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
Beispiel #2
0
    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)
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
    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)
Beispiel #7
0
    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
Beispiel #8
0
    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}