def instr(cls, filename, filePostfix, locs_d, mkStmts): stmts = cls.mkProgStmts(filename, locs_d, mkStmts) fname = filename + filePostfix CM.vwrite(fname, '\n'.join(stmts)) CM.vcmd("astyle -Y {}".format(fname)) return fname
def start(self, seed, maxdeg, maxterm): #set seed import random random.seed(seed) sage.all.set_random_seed(seed) logger.debug('set seed to: {} (test {})'.format( seed, sage.all.randint(0, 100))) maxvars = max(self.invdecls.itervalues(), key=lambda d: len(d)) #set terms if maxdeg and maxterm: deg = maxdeg elif maxdeg: deg = maxdeg elif maxterm: deg = Miscs.getDeg(len(maxvars), maxterm) else: deg = Miscs.getDeg(len(maxvars), 200) self.deg = deg #other miscs setups self.tcsFile = "{}.tcs".format(self.src.filename) self.printfSrc = self.src.instrPrintfs(self.invdecls) self.exeFile = "{}.exe".format(self.printfSrc) ## -lm for math.h to work cmd = "gcc -lm {} -o {}".format(self.printfSrc, self.exeFile) CM.vcmd(cmd) gTraces = dict() #global set of traces gInps = set() #global set of inps for loc in self.invdecls: invs = self.infer(loc, self.deg, gTraces, gInps)
def mexec(self, exe, inps): assert isinstance(exe, str) and exe.endswith(".exe"), exe assert isinstance(inps, set) and inps, inps if os.path.isfile(self.tcsFile): os.remove(self.tcsFile) for inp in inps: inp = ' '.join(map(str, inp)) cmd = "{} {} >> {}".format(exe, inp, self.tcsFile) logger.detail(cmd) CM.vcmd(cmd) return Trace.parse(self.tcsFile)
def instrAssertsRT(self, invs, inps, inps_d, invdecls, lineno, startFun="mainQ"): assert isinstance(invs, set) and invs, dinvs assert isinstance(inps, set), inps assert (inps_d is None or (isinstance(inps_d, OrderedDict) and inps_d)), inps_d #mk_f(invs, invdecls, lineno) _mk = lambda myinvs, _, loc: RT.mkAssertInvs(myinvs, loc) stmts = self.mkProgStmts(self.filename, invs, invdecls, lineno, _mk) #comment startFun(..argv[]) and add symbolic input stmts_ = [] for stmt in stmts: if startFun in stmt and "argv" in stmt: for varname, (vartyp, (minV, maxV)) in inps_d.iteritems(): stmt = RT.mkSymbolic(varname, vartyp) stmts_.append(stmt) if minV is not None and maxV is not None: stmts__ = RT.mkAssumeRanges(varname, minV, maxV) stmts_.extend(stmts__) #klee_assume(x!=0 || y!=1); klee_assume(x!=2 || y!=3); if inps: stmts__ = RT.mkAssumeInps(inps) stmts_.extend(stmts__) #call mainQ(inp0, ..); stmt = "{}({});".format(startFun, ",".join(map(str, inps_d.iterkeys()))) stmts_.append(stmt) elif (all(x in stmt for x in ['assert', '(', ')', ';']) and '//' not in stmt): stmt = RT.mkAssert(stmt) stmts_.append(stmt) else: stmts_.append(stmt) stmts = stmts_ #add header, e.g., #include ... stmts = RT.mkHeaders() + stmts fname = self.filename + ".assert.c" CM.vwrite(fname, '\n'.join(stmts)) CM.vcmd("astyle -Y {}".format(fname)) return fname
def getTraces(self, inps): assert isinstance(inps, Inps) and inps, inps if os.path.isfile(self.tcsFile): os.remove(self.tcsFile) for inp in inps: inp_ = ' '.join(map(str, [v for _, v in inp.iteritems()])) cmd = "{} {} >> {}".format(self.exeFile, inp_, self.tcsFile) logger.detail(cmd) CM.vcmd(cmd) new_dtraces = Trace.parse(self.tcsFile, self.invdecls) return new_dtraces
def instrAsserts(self, invs, inps, inpsd, invdecls, startFun="mainQ"): assert isinstance(invs, dict), invs assert (inpsd is None or (isinstance(inpsd, OrderedDict) and inpsd)), inpsd assert isinstance(invdecls, OrderedDict) and invdecls, invdecls assert inps is None or (isinstance(inps, set) and inps), inps inpParts = self.mkPrintfArgs(inpsd) if inpsd else (None, None) _mk = lambda invs, loc: KLEE.mkAssertInvs( invs, loc, inpParts, self.mkPrintfArgs(invdecls[loc])) stmts = self.mkProgStmts(self.filename, invs, _mk) #comment startFun(..argv[]) and add symbolic input stmts_ = [] for stmt in stmts: if startFun in stmt and "argv" in stmt: # stmt = "//" + stmt # stmts_.append(stmt) for varname, (vartyp, (minV, maxV)) in inpsd.iteritems(): stmt = KLEE.mkSymbolic(varname, vartyp) stmts_.append(stmt) if minV is not None and maxV is not None: stmts__ = KLEE.mkAssumeRanges(varname, minV, maxV) stmts_.extend(stmts__) #klee_assume(x!=0 || y!=1); klee_assume(x!=2 || y!=3); if inps: ss = inpsd.keys() #so that assertions are in order #(KLEE will give diff outputs based on order) inps = sorted(inps) stmts__ = KLEE.mkAssumeInps(ss, inps) stmts_.extend(stmts__) #call mainQ(inp0, ..); stmt = "{}({});".format(startFun, ",".join(map(str, inpsd.iterkeys()))) stmts_.append(stmt) else: stmts_.append(stmt) stmts = stmts_ #add header stmts = ["#include <klee/klee.h>"] + stmts uid = str(hash(str(invs))).replace("-", "_") fname = "{}_{}.{}".format(self.filename, uid, "klee_assert.c") CM.vwrite(fname, '\n'.join(stmts)) CM.vcmd("astyle -Y {}".format(fname)) return fname
def texec(self, inps): """ Run the program on inpts and get traces, e.g., {1: {(t1), (t2)}} """ assert inps, inps if os.path.isfile(self.tcsFile): os.remove(self.tcsFile) for inp in inps: inp_ = ' '.join(map(str, inp)) cmd = "{} {} >> {}".format(self.exeFile, inp_, self.tcsFile) logger.detail(cmd) CM.vcmd(cmd) traces = Traces.parse(self.tcsFile) return traces
def check(self, invs, einps, minV, maxV, dorandom=True): assert isinstance(invs, Invs) and invs, invs assert isinstance(einps, set) #existing inps src = self.src.instrDisproves(invs, self.invdecls, self.lineno) exe = "{}.exe".format(src) cmd = "gcc -lm {} -o {}".format(src, exe) rs, rs_err = CM.vcmd(cmd) assert not rs, rs assert not rs_err, rs_err traces = None if dorandom: inps = miscs.genInps(len(self.inpdecls), maxV) for inp in inps: einps.add(inp) dtraces = self.mexec(exe, inps) traces = self.pp(invs, dtraces, maxV) #use RT if not traces: disproved = self.checkRT(invs, einps, minV, maxV, quickbreak=True) if disproved: inps = set() for dinv in disproved: for inp in disproved[dinv]: inp = tuple([inp[str(k)] for k in self.inpdecls]) einps.add(inp) inps.add(inp) dtraces = self.mexec(exe, inps) traces = self.pp(invs, dtraces, maxV) return traces
def initialize(self, seed, deg, maxtime): import random random.seed(seed) sage.all.set_random_seed(seed) logger.info('set seed to: {} (test {})'.format( seed, sage.all.randint(0, 100))) fname = os.path.basename(self.filename) src = os.path.join(self.tmpdir, fname) _, rs_err = CM.vcmd("astyle -Y < {} > {}".format(self.filename, src)) assert not rs_err, rs_err logger.debug("src: {}".format(src)) self.src = Src(src) self.inpdecls, self.invdecls, self.lineno = self.src.parse() self.ss = [sage.all.var(k) for k in self.invdecls] if callable(deg): self.deg = deg(len(self.ss)) logger.info("autodeg {}".format(self.deg)) else: self.deg = deg self.maxtime = maxtime #tracefile self.tcsFile = "{}.tcs".format(self.src.filename) from solver import IeqSolver self.minV, self.maxV = IeqSolver.minV, IeqSolver.maxV self.unboundMinV, self.unboundMaxV = self.minV * 10, self.maxV * 10
def instrKleeAsserts(self, dinvs, inps, inps_d, startFun="mainQ"): assert isinstance(dinvs, DInvs), dinvs assert (inps_d is None or (isinstance(inps_d, OrderedDict) and inps_d)), inps_d assert isinstance(inps, Inps), inps if inps_d: parts = self.mkPrintfArgs(inps_d) else: parts = (None, None) _mk = lambda invs, loc: KLEE.mkAssertInvs(invs, loc, parts) stmts = self.mkProgStmts(self.filename, dinvs, _mk) #comment startFun(..argv[]) and add symbolic input stmts_ = [] for stmt in stmts: if startFun in stmt and "argv" in stmt: # stmt = "//" + stmt # stmts_.append(stmt) for varname, (vartyp, (minV, maxV)) in inps_d.iteritems(): stmt = KLEE.mkSymbolic(varname, vartyp) stmts_.append(stmt) if minV is not None and maxV is not None: stmts__ = KLEE.mkAssumeRanges(varname, minV, maxV) stmts_.extend(stmts__) #klee_assume(x!=0 || y!=1); klee_assume(x!=2 || y!=3); if inps: stmts__ = KLEE.mkAssumeInps(inps) stmts_.extend(stmts__) #call mainQ(inp0, ..); stmt = "{}({});".format(startFun, ",".join(map(str, inps_d.iterkeys()))) stmts_.append(stmt) else: stmts_.append(stmt) stmts = stmts_ #add header stmts = ["#include <klee/klee.h>"] + stmts fname = self.filename + ".klee_assert.c" CM.vwrite(fname, '\n'.join(stmts)) CM.vcmd("astyle -Y {}".format(fname)) return fname
def getTraces(self, inps): """ Run program on inps and get traces """ assert isinstance(inps, Inps) and inps, inps tcsFile = "{}_{}".format(self.tcsFile, hash(str(inps))).replace("-","_") if os.path.isfile(tcsFile): traces = DTraces.parse(tcsFile, self.invdecls) else: for inp in inps: inp_ = ' '.join(map(str, inp)) cmd = "{} {} >> {}".format(self.exeFile, inp_, tcsFile) logger.detail(cmd) CM.vcmd(cmd) traces = DTraces.parse(tcsFile, self.invdecls) assert all(loc in self.invdecls for loc in traces), traces.keys() return traces
def myrun(cls, code): filename = "Test" filename_ext = filename + cls.file_ext CM.vwrite(filename_ext, code) if cls.cmd_compile: cmd = cls.cmd_compile.format(filename_ext) logger.debug("cmd {}".format(cmd)) logger.detail(cmd) rs, rs_err = CM.vcmd(cmd) assert not rs_err, rs_err.decode('ascii') assert not rs, rs.decode('ascii') cmd = cls.cmd_run.format(filename) logger.debug("cmd: {}".format(cmd)) rs, rs_err = CM.vcmd(cmd) assert not rs_err, rs_err.decode('ascii') rs = rs.decode('ascii').strip() stats = [cls.get_stat(stat.strip()) for stat in rs.split()] return stats
def __init__(self, filename): import tempfile self.tmpdir = tempfile.mkdtemp(dir="/var/tmp", prefix="DIG2_") self.filename = filename basename = os.path.basename(self.filename) src = os.path.join(self.tmpdir, basename) _, rs_err = CM.vcmd("astyle -Y < {} > {}".format(self.filename, src)) assert not rs_err, rs_err logger.debug("src: {}".format(src)) self.src = Src(src) self.inpdecls, self.invdecls = self.src.parse()
def initialize(self, seed): #set seed import random random.seed(seed) sage.all.set_random_seed(seed) logger.info('set seed to: {} (test {})'.format( seed, sage.all.randint(0, 100))) fname = os.path.basename(self.filename) src = os.path.join(self.tmpdir, fname) _, rs_err = CM.vcmd("astyle -Y < {} > {}".format(self.filename, src)) assert not rs_err, rs_err self.src = Src(src) self.inpdecls, self.invdecls = self.src.parse() self.printfSrc = self.src.instrPrintfs(self.invdecls) self.exeFile = "{}.exe".format(self.printfSrc) #-lm for math.h to work cmd = "gcc -lm {} -o {}".format(self.printfSrc, self.exeFile) CM.vcmd(cmd) #tracefile self.tcsFile = "{}.tcs".format(self.printfSrc)
def __init__(self, filename): assert os.path.isfile(filename), filename import tempfile tmpdir = tempfile.mkdtemp(dir=settings.tmpdir, prefix="DIG2_") basename = os.path.basename(filename) src = os.path.join(tmpdir, basename) _, rs_err = CM.vcmd("astyle -Y < {} > {}".format(filename, src)) assert not rs_err, rs_err logger.debug("src: {}".format(src)) src = Src(src) self.inpdecls, self.invdecls = src.parse() printfSrc = src.instrPrintfs(self.invdecls) exeFile = "{}.exe".format(printfSrc) cmd = "gcc -lm {} -o {}".format(printfSrc, exeFile) #-lm for math.h CM.vcmd(cmd) tcsFile = "{}.tcs".format(printfSrc) #tracefile self.prover = Prover(src, self.inpdecls, self.invdecls, tmpdir) self.tmpdir = tmpdir self.filename = filename self.tcsFile = tcsFile self.exeFile = exeFile logger.info("analyze {}".format(filename))
def build_poly(vts, ts, is_max_plus): """ Build a MPP convex polyhedron over vts and return a set of constraints Examples: sage: var('y') y sage: rs = IeqMPPGen.build_poly([[0,0,0],[3,3,0]], [x,y,SR(0)], is_max_plus=True) dig_polynomials:Debug:Build (gen max-plus) poly from 2 vts in 3 dims: [x, y, 0] sage: print '\n'.join(map(str,sorted(rs))) ('lambda x,y: -x + y >= 0', 'y >= x') ('lambda x,y: x - y >= 0', 'x >= y') ('lambda x: -x + 3 >= 0', '0 >= x - 3') ('lambda x: x >= 0', 'x >= 0') ('lambda y: -y + 3 >= 0', '0 >= y - 3') ('lambda y: y >= 0', 'y >= 0') """ opt_arg = '' if is_max_plus: mpp_str = 'max-plus' else: mpp_str = 'min-plus' opt_arg = "{} {}".format(opt_arg, '-{}'.format(mpp_str)) # if any vertex is float if any(any(not SR(v).is_integer() for v in vt) for vt in vts): vts = [[RR(v).n() for v in vt] for vt in vts] opt_arg = "{} -numerical-data ocaml_float".format(opt_arg) # exec external program # important, has to end with newline \n !!! vts_s = '\n'.join(str(vt).replace(' ', '') for vt in vts) + '\n' logger.debug('Build (gen {}) poly from {} vts in {} dims: {}'.format( mpp_str, len(vts), len(vts[0]), ts)) cmd = 'compute_ext_rays_polar {} {}'.format(opt_arg, len(vts[0])) rs, _ = vcmd(cmd, vts_s) rs = [sage_eval(s.replace('oo', 'Infinity')) for s in rs.split()] rs = IeqMPPGen.group_rs(rs) rs = map(lambda ls: [x + y for x, y in zip(ls, ts + ts)], rs) rs = map(lambda ls: IeqMPP.sparse(ls, is_max_plus), rs) rs = filter(None, rs) return rs
def compile(self): #compile file with llvm includePath = "~/Src/Devel/KLEE/klee/include" clangOpts = "-emit-llvm -c" obj = os.path.basename(self.filename) + os.extsep + 'o' obj = os.path.join(self.tmpdir, obj) cmd = ("clang -I {} {} {} -o {}".format(includePath, clangOpts, self.filename, obj)) logger.detail("$ {}".format(cmd)) rs, rsErr = CM.vcmd(cmd) assert not rs, rs assert "clang" not in rsErr and "error" not in rsErr, rsErr if rsErr: logger.detail(rsErr) return obj
def build_poly(vts, ts, is_max_plus): """ Build a MPP convex polyhedron over vts and return a set of constraints Examples: sage: logger.set_level(VLog.DEBUG) sage: IeqMPP.build_poly([[0,0,0],[3,3,0]], is_max_plus=True) dig_polynomials:Debug:Ieq: Build (MPP max-plus) polyhedra from 2 vertices in 3 dim ['[-oo,0,-oo,-oo,-oo,0]', '[0,-oo,-oo,-oo,-oo,0]', '[0,-oo,-oo,-oo,-oo,-oo]', '[-oo,0,-oo,-oo,-oo,-oo]', '[-oo,-oo,0,-oo,-oo,-oo]', '[-oo,-oo,0,-oo,-oo,0]', '[-oo,-oo,0,-oo,-3,-oo]', '[-oo,-oo,0,-3,-oo,-oo]', '[-oo,0,-oo,-oo,0,-oo]', '[-oo,0,-oo,0,-oo,-oo]', '[0,-oo,-oo,-oo,0,-oo]', '[0,-oo,-oo,0,-oo,-oo]'] """ opt_arg = '' if is_max_plus: mpp_str = 'max-plus' else: mpp_str = 'min-plus' opt_arg = "{} {}".format(opt_arg, '-{}'.format(mpp_str)) #if any vertex is float if any(any(not SR(v).is_integer() for v in vt) for vt in vts): vts = [[RR(v).n() for v in vt] for vt in vts] opt_arg = "{} -numerical-data ocaml_float".format(opt_arg) #exec external program #important, has to end with newline \n !!! vts_s = '\n'.join(str(vt).replace(' ','') for vt in vts) + '\n' logger.debug('Build (gen {}) poly from {} vts in {} dims: {}' .format(mpp_str,len(vts),len(vts[0]),ts)) cmd = 'compute_ext_rays_polar {} {}'.format(opt_arg, len(vts[0])) rs,_ = vcmd(cmd, vts_s) rs = [sage_eval(s.replace('oo','Infinity')) for s in rs.split()] rs = IeqMPPGen.group_rs(rs) rs = map(lambda ls:[x+y for x,y in zip(ls,ts+ts)], rs) rs = map(lambda ls: IeqMPP.sparse(ls,is_max_plus), rs) rs = filter(None, rs) return rs
def build_poly(vts, ts, is_max_plus): """ Build a MPP convex polyhedron over vts and return a set of constraints Examples: sage: logger.set_level(VLog.DEBUG) sage: IeqMPP.build_poly([[0,0,0],[3,3,0]], is_max_plus=True) dig_polynomials:Debug:Ieq: Build (MPP max-plus) polyhedra from 2 vertices in 3 dim ['[-oo,0,-oo,-oo,-oo,0]', '[0,-oo,-oo,-oo,-oo,0]', '[0,-oo,-oo,-oo,-oo,-oo]', '[-oo,0,-oo,-oo,-oo,-oo]', '[-oo,-oo,0,-oo,-oo,-oo]', '[-oo,-oo,0,-oo,-oo,0]', '[-oo,-oo,0,-oo,-3,-oo]', '[-oo,-oo,0,-3,-oo,-oo]', '[-oo,0,-oo,-oo,0,-oo]', '[-oo,0,-oo,0,-oo,-oo]', '[0,-oo,-oo,-oo,0,-oo]', '[0,-oo,-oo,0,-oo,-oo]'] """ opt_arg = '' if is_max_plus: mpp_str = 'max-plus' else: mpp_str = 'min-plus' opt_arg = "{} {}".format(opt_arg, '-{}'.format(mpp_str)) #if any vertex is float if any(any(not SR(v).is_integer() for v in vt) for vt in vts): vts = [[RR(v).n() for v in vt] for vt in vts] opt_arg = "{} -numerical-data ocaml_float".format(opt_arg) #exec external program #important, has to end with newline \n !!! vts_s = '\n'.join(str(vt).replace(' ', '') for vt in vts) + '\n' logger.debug('Build (gen {}) poly from {} vts in {} dims: {}'.format( mpp_str, len(vts), len(vts[0]), ts)) cmd = 'compute_ext_rays_polar {} {}'.format(opt_arg, len(vts[0])) rs, _ = vcmd(cmd, vts_s) rs = [sage_eval(s.replace('oo', 'Infinity')) for s in rs.split()] rs = IeqMPPGen.group_rs(rs) rs = map(lambda ls: [x + y for x, y in zip(ls, ts + ts)], rs) rs = map(lambda ls: IeqMPP.sparse(ls, is_max_plus), rs) rs = filter(None, rs) return rs