def slice_defs(prop, defs, assumes_state, assumes_trans): """ Return a new (potentially empty) def dictionary from the old one consisting of only necessary variable definitions to prove property """ if __debug__: assert is_dict(defs), defs assert is_list(assumes_state), assumes_state assert is_list(assumes_trans), assumes_trans fs = [prop] + assumes_state + assumes_trans fs = [f for f in fs if is_expr(f)] vs = [get_vars(f) for f in fs] vs = [cur(v_) if is_pre(v_) else v_ for v_ in vflatten(vs)] vs = vset(vs, fhash) vs_ = [Prog.get_influence_vs(v, defs, []) for v in vs] vs = vset(vflatten(vs + vs_), fhash) a_defs = OrderedDict() for v in vs: k = fhash(v) if k in defs: a_defs[k] = defs[k] return a_defs
def expr_set(fs): """ Return a set of formulas (i.e. all items are distinct) using hashing """ assert all(f is None or is_expr(f) for f in fs), fs return vset(fs, lambda f: None if f is None else fhash(f))
def build_vts_poly(ts, tcs, mpp_opt): vts = [[t.subs(tc) for t in ts] for tc in tcs] vts = vset(vts, idfun=repr) #add 0 to the end of each vertex and identity elem to terms vts = [vt + [SR(0)] for vt in vts] ts = ts + [SR(0)] #the identity element is 0 in MPP if mpp_opt == IeqMPP.opt_max_then_min: def worker_(Q, ts, is_max_plus): Q.put(IeqMPPGen.build_poly(vts, ts, is_max_plus)) Q = mp.Queue() workers = [ mp.Process(target=worker_, args=(Q, ts, is_max_plus)) for is_max_plus in [True, False] ] for w in workers: w.start() rs = [] for _ in workers: rs.extend(Q.get()) else: is_max_plus = mpp_opt == IeqMPP.opt_max_plus rs = IeqMPPGen.build_poly(vts, ts, is_max_plus=is_max_plus) return rs
def build_vts_poly(ts,tcs,mpp_opt): vts = [[t.subs(tc) for t in ts] for tc in tcs] vts = vset(vts,idfun=repr) #add 0 to the end of each vertex and identity elem to terms vts = [vt + [SR(0)] for vt in vts] ts = ts + [SR(0)] #the identity element is 0 in MPP if mpp_opt == IeqMPP.opt_max_then_min: def worker_(Q,ts,is_max_plus): Q.put(IeqMPPGen.build_poly(vts,ts,is_max_plus)) Q = mp.Queue() workers = [mp.Process(target=worker_,args=(Q,ts,is_max_plus)) for is_max_plus in [True,False]] for w in workers: w.start() rs = [] for _ in workers: rs.extend(Q.get()) else: is_max_plus = mpp_opt == IeqMPP.opt_max_plus rs = IeqMPPGen.build_poly(vts,ts,is_max_plus=is_max_plus) return rs
def getTermsFixedCoefs(ss, subsetSiz): """ sage: var('x y z t s u') (x, y, z, t, s, u) sage: getTermsFixedCoefs([x,y^2], 2) [-y^2 - x, -x, y^2 - x, -y^2, y^2, -y^2 + x, x, y^2 + x] """ if len(ss) < subsetSiz: subsetSiz = len(ss) rs = [] for ssSubset in itertools.combinations(ss, subsetSiz): css = itertools.product(*([[0, -1, 1]] * len(ssSubset))) r = (sum(c * t for c, t in zip(ssSubset, cs)) for cs in css if not all(c == 0 for c in cs)) rs.extend(r) return CM.vset(rs)
def f_eq(d): if isinstance(d, list): f_ = template for d_ in d: f_ = f_.subs(d_) rhsVals = CM.vset([d_.rhs() for d_ in d]) uk_vars = sageutil.get_vars(rhsVals) else: f_ = template(d) uk_vars = sageutil.get_vars(d.values()) #e.g., r15,r16 ... if not uk_vars: return f_ iM = sage.all.identity_matrix(len(uk_vars)) #standard basis rs = [dict(zip(uk_vars, l)) for l in iM.rows()] rs = [f_(r) for r in rs] return rs
def __init__(self, ps): if __debug__: assert is_list(ps) and all(isinstance(p,Inv) for p in ps), ps self.ps = vset(ps) Refine.print_diff('vset', len(ps), len(self.ps))
def get_influence_vs(v, defs, rs): """ Return a list of variables that influences v (i.e. the definition of v depends on these variables) >>> from z3 import Bools, BoolVal >>> from scr_miscs import mk_OIA >>> s,t = Bools('s t') >>> x,y,z = Bools('x y z') >>> vs = [x,y,z] >>> o = mk_OIA(vs) >>> vv = [o,o,And(o,s)] >>> vs2 = [t] >>> vv2 = [BoolVal(True)] >>> vs_k = map(fhash,vs + vs2) >>> vs_v =vv + vv2 >>> defs = OrderedDict(zip(vs_k,vs_v)) >>> print Prog.get_influence_vs(x,defs,rs=[]) [s, y, z] #>>> print Prog.get_influence_vs(x,defs,assumes=[x==s],rs=[]) #[s, y, z] #>>> print Prog.get_influence_vs(x,defs,assumes=[y==t],rs=[]) #[s, y, z, t] """ if __debug__: assert is_expr_var(v), v assert is_dict(defs), defs assert is_list(rs), rs if is_pre(v): v = cur(v) #return if already in the result set if expr_member(v, rs): return rs try: vs = get_vars(defs[fhash(v)]) #print vs except KeyError: return rs rs = rs + [v] #convert v_pre to v vs = [cur(v_) if is_pre(v_) else v_ for v_ in vs] vs = vset(vs, fhash) for v_ in vs: rs_ = Prog.get_influence_vs(v_, defs, rs) rs = rs + rs_ rs = rs + vs rs = vset(rs, fhash) #remove myself v_idx = map(fhash, rs).index(fhash(v)) rs = rs[:v_idx] + rs[v_idx + 1:] return sorted(rs, key=str)
def benchmark_file(filename,runs,use_specific_deg,read_only,do_parallel): def get_deg_auto(nss, nts=200, max_deg=7): if __debug__: assert nss >= 1, nss assert nts >= nss, (nts, nss) assert max_deg >= 1, max_deg for d in range(1,max_deg+1): deg = d if binomial(nss+deg, deg) - 1 > nts: deg = d - 1 break return deg def get_deg_specific(filename): deg3=['dijkstra', 'cohencu','prod4br','knuth', 'geo3','ps3'] deg4=['ps4'] deg5=['ps5'] deg6=['ps6'] deg7=['ps7'] if any(x in filename for x in deg7): return 7 elif any(x in filename for x in deg6): return 6 elif any(x in filename for x in deg5): return 5 elif any(x in filename for x in deg4): return 4 elif any(x in filename for x in deg3): return 3 else: return 2 def get_invs(ig, seed, deg): start_time = time.time() ig.set_seed(seed) #For MPP #rs = ig.get_ieqs_max_min_fixed() # if len(ig.ss_num) <= 3: # print 'also getting general form, {} vars'.format(len(ig.ss_num)) # rs_ = ig.get_ieqs_max_min_gen() # rs = rs_ + rs # rs = vset(rs) # print len(rs) #DO NOT USE fixed_3, will generate #lots of formulas that screw up Z3 #stick with fixed_2 #For NLA #rs = ig.get_eqts_ieqs_max_min_fixed_2(deg=deg) #eqts rs = ig.get_invs(deg=deg) return rs, (time.time() - start_time) sols_filename = [] start_time = time.time() ig = DIG(filename) print "Read time {}".format(time.time() - start_time) if read_only: return '', [], [] if len(ig.ss_num) <= 1: deg = 1 else: if any(x in filename for x in ['AesKeySetupEnc_w_LRA', 'AesKeySetupDec_w_LRA']): deg = 1 elif use_specific_deg: deg = get_deg_specific(filename) print 'Use *specific* max degree {}'.format(deg) else: if 'l_init' in filename: deg = 2 print 'Use default max deg {} for l_init'.format(deg) else: deg = get_deg_auto(len(ig.ss_num)) print 'Use *auto* max deg {}'.format(deg) sols_run = [] for nr in range(runs): print '\n--- Run {}/{} ({}) ---\n'.format(nr+1,runs,filename) rs,etime = get_invs(ig, seed=nr, deg=deg) print etime sols_filename = sols_filename + [(nr,rs,deg,etime)] sols_run = sols_run + rs sols_run = vset(sols_run) expect = ig.xinfo['Expect'] print_summary(filename,expect,sols_filename,sols_run) return expect, sols_filename, sols_run
def benchmark_file(filename, runs, use_specific_deg, read_only, do_parallel): def get_deg_auto(nss, nts=200, max_deg=7): if __debug__: assert nss >= 1, nss assert nts >= nss, (nts, nss) assert max_deg >= 1, max_deg for d in range(1, max_deg + 1): deg = d if binomial(nss + deg, deg) - 1 > nts: deg = d - 1 break return deg def get_deg_specific(filename): deg3 = ['dijkstra', 'cohencu', 'prod4br', 'knuth', 'geo3', 'ps3'] deg4 = ['ps4'] deg5 = ['ps5'] deg6 = ['ps6'] deg7 = ['ps7'] if any(x in filename for x in deg7): return 7 elif any(x in filename for x in deg6): return 6 elif any(x in filename for x in deg5): return 5 elif any(x in filename for x in deg4): return 4 elif any(x in filename for x in deg3): return 3 else: return 2 def get_invs(ig, seed, deg): start_time = time.time() ig.set_seed(seed) #For MPP #rs = ig.get_ieqs_max_min_fixed() # if len(ig.ss_num) <= 3: # print 'also getting general form, {} vars'.format(len(ig.ss_num)) # rs_ = ig.get_ieqs_max_min_gen() # rs = rs_ + rs # rs = vset(rs) # print len(rs) #DO NOT USE fixed_3, will generate #lots of formulas that screw up Z3 #stick with fixed_2 #For NLA #rs = ig.get_eqts_ieqs_max_min_fixed_2(deg=deg) #eqts rs = ig.get_invs(deg=deg) return rs, (time.time() - start_time) sols_filename = [] start_time = time.time() ig = DIG(filename) print "Read time {}".format(time.time() - start_time) if read_only: return '', [], [] if len(ig.ss_num) <= 1: deg = 1 else: if any(x in filename for x in ['AesKeySetupEnc_w_LRA', 'AesKeySetupDec_w_LRA']): deg = 1 elif use_specific_deg: deg = get_deg_specific(filename) print 'Use *specific* max degree {}'.format(deg) else: if 'l_init' in filename: deg = 2 print 'Use default max deg {} for l_init'.format(deg) else: deg = get_deg_auto(len(ig.ss_num)) print 'Use *auto* max deg {}'.format(deg) sols_run = [] for nr in range(runs): print '\n--- Run {}/{} ({}) ---\n'.format(nr + 1, runs, filename) rs, etime = get_invs(ig, seed=nr, deg=deg) print etime sols_filename = sols_filename + [(nr, rs, deg, etime)] sols_run = sols_run + rs sols_run = vset(sols_run) expect = ig.xinfo['Expect'] print_summary(filename, expect, sols_filename, sols_run) return expect, sols_filename, sols_run
def gen_nodes_parts(nodes, k, is_commute=False): """ Divides n nodes into k parts sage: gen_nodes_parts([],5) [([], [], [], [], [])] sage: gen_nodes_parts([1,2,3],0) [] sage: gen_nodes_parts([1,2],1) [([1, 2],)] sage: gen_nodes_parts([1,2],2) [([], [1, 2]), ([1], [2]), ([2], [1]), ([1, 2], [])] sage: gen_nodes_parts([1,2],3) [([], [], [1, 2]), ([], [1], [2]), ([], [2], [1]), ([], [1, 2], []), ([1], [], [2]), ([1], [2], []), ([2], [], [1]), ([2], [1], []), ([1, 2], [], [])] sage: gen_nodes_parts([1,2,4],3) [([], [], [1, 2, 4]), ([], [1], [2, 4]), ([], [2], [1, 4]), ([], [4], [1, 2]), ([], [1, 2], [4]), ([], [1, 4], [2]), ([], [2, 4], [1]), ([], [1, 2, 4], []), ([1], [], [2, 4]), ([1], [2], [4]), ([1], [4], [2]), ([1], [2, 4], []), ([2], [], [1, 4]), ([2], [1], [4]), ([2], [4], [1]), ([2], [1, 4], []), ([4], [], [1, 2]), ([4], [1], [2]), ([4], [2], [1]), ([4], [1, 2], []), ([1, 2], [], [4]), ([1, 2], [4], []), ([1, 4], [], [2]), ([1, 4], [2], []), ([2, 4], [], [1]), ([2, 4], [1], []), ([1, 2, 4], [], [])] sage: [len(gen_nodes_parts(range(i),2)) for i in range(6)] [1, 2, 4, 8, 16, 32] sage: [len(gen_nodes_parts(range(i),3)) for i in range(6)] [1, 3, 9, 27, 81, 243] sage: [len(gen_nodes_parts(range(i),3,is_commute=True)) for i in range(6)] [1, 1, 2, 5, 14, 41] """ assert k >= 0 if len(nodes) == 0: return [((), ) * k] if k == 0: return [] rs = [] l = len(nodes) + 1 for i in range(l): gs = itertools.combinations(nodes, i) for g in gs: rest = [node for node in nodes if node not in g] p_rest = gen_nodes_parts(rest, k - 1, is_commute) rs_ = [tuple([g] + list(p)) for p in p_rest] rs.extend(rs_) if is_commute: rs = CM.vset(rs, idfun=frozenset) return rs