def default_n_vc (p, n): head = p.loop_id (n) general = [(n2, rep_graph.vc_options ([0], [1])) for n2 in p.loop_heads () if n2 != head] specific = [(head, rep_graph.vc_offs (1)) for _ in [1] if head] return (n, tuple (general + specific))
def default_n_vc_cases(p, n): head = p.loop_id(n) general = [(n2, rep_graph.vc_options([0], [1])) for n2 in p.loop_heads() if n2 != head] if head: return [(n, tuple(general + [(head, rep_graph.vc_num(1))])), (n, tuple(general + [(head, rep_graph.vc_offs(1))]))] specific = [(head, rep_graph.vc_offs(1)) for _ in [1] if head] return [(n, tuple(general + specific))]
def build_proof_rec_with_restrs (split_points, kind, searcher, p, restrs, hyps, must_find = True, name = "problem"): if not split_points: return build_proof_rec (searcher, p, restrs, hyps, name = name) sp = split_points[0] use_hyps = list (hyps) if p.node_tags[sp][0] != p.pairing.tags[1]: nrerr_hyp = check.non_r_err_pc_hyp (p.pairing.tags, restr_others (p, restrs, 2)) use_hyps = use_hyps + [nrerr_hyp] if p.loop_id (sp): lim_pair = get_proof_split_limit (p, sp, restrs, use_hyps, kind, must_find = must_find) else: lim_pair = get_proof_visit_restr (p, sp, restrs, use_hyps, kind, must_find = must_find) if not lim_pair: assert not must_find return build_proof_rec_with_restrs (split_points[1:], kind, searcher, p, restrs, hyps, must_find = must_find, name = name) (min_v, max_v) = lim_pair if kind == 'Number': vc_opts = rep_graph.vc_options (range (min_v, max_v), []) else: vc_opts = rep_graph.vc_options ([], range (min_v, max_v)) restrs = restrs + ((sp, vc_opts), ) subproof = build_proof_rec_with_restrs (split_points[1:], kind, searcher, p, restrs, hyps, must_find = must_find, name = name) return ProofNode ('Restr', (sp, (kind, (min_v, max_v))), [subproof])
def add_loop_bound_restrs_hyps(p, restrs, hyps, split, bound, ctxt): # time this for diagnostic reasons start = time.time() # vc_options([concrete numbers], [offsets]) hyps = hyps + get_linear_series_hyps(p, split, restrs, hyps) hyps = list(set(hyps)) if bound == None or bound >= 10: restrs = restrs + ((split, rep_graph.vc_options([0], [1])),) else: restrs = restrs + ((split, rep_graph.vc_upto(bound + 1)),) end = time.time() save_extra_timing("LoopBoundRestrHyps", ctxt, end - start) return (restrs, hyps)
def add_loop_bound_restrs_hyps(p, restrs, hyps, split, bound, ctxt): # time this for diagnostic reasons start = time.time() #vc_options([concrete numbers], [offsets]) hyps = hyps + get_linear_series_hyps(p, split, restrs, hyps) hyps = list(set(hyps)) if bound == None or bound >= 10: restrs = restrs + ((split, rep_graph.vc_options([0], [1])), ) else: restrs = restrs + ((split, rep_graph.vc_upto(bound + 1)), ) end = time.time() save_extra_timing('LoopBoundRestrHyps', ctxt, end - start) return (restrs, hyps)
def build_compound_problem (fnames): """mirrors build_problem from check for multiple functions""" printout ('Building compound problem for %s' % fnames) last_compound_problem_req[0] = list (fnames) p = problem.Problem (None, name = ', '.join(fnames)) fun_tag_pairs = [] all_tags = {} for (i, fn) in enumerate (fnames): i = len (fnames) - i [pair] = pairings[fn] next_tags = {} scripts = get_problem_inline_scripts (pair) for (pair_tag, fname) in pair.funs.items (): tag = '%s_%d_%s' % (fname, i, pair_tag) tag = syntax.fresh_name (tag, all_tags) next_tags[pair_tag] = tag p.add_entry_function (functions[fname], tag) p.hook_tag_hints[tag] = pair_tag p.replay_inline_script (tag, scripts[pair_tag]) fun_tag_pairs.append ((next_tags, pair)) p.pad_merge_points () p.do_analysis () free_hyps = [] for (tags, pair) in fun_tag_pairs: (inp_eqs, _) = pair.eqs free_hyps += check.inst_eqs (p, (), inp_eqs, tags) err_vis_opts = rep_graph.vc_options ([0, 1, 2], [1]) err_vis_vc = tuple ([(n, err_vis_opts) for n in p.loop_heads () if p.node_tags[n][0] == tags['C']]) err_vis = (('Err', err_vis_vc), tags['C']) free_hyps.append (rep_graph.pc_false_hyp (err_vis)) addr_map = {} for n in p.nodes: if not p.node_tags[n][0].endswith ('_ASM'): continue if type (p.node_tags[n][1]) == tuple: (fname, data) = p.node_tags[n][1] if (logic.is_int (data) and is_addr (data) and not fname.startswith ("instruction'")): assert data not in addr_map, data addr_map[data] = n return (p, free_hyps, addr_map, fun_tag_pairs)
def build_compound_problem(fnames): """mirrors build_problem from check for multiple functions""" printout('Building compound problem for %s' % fnames) last_compound_problem_req[0] = list(fnames) p = problem.Problem(None, name=', '.join(fnames)) fun_tag_pairs = [] all_tags = {} for (i, fn) in enumerate(fnames): i = len(fnames) - i [pair] = pairings[fn] next_tags = {} scripts = get_problem_inline_scripts(pair) for (pair_tag, fname) in pair.funs.items(): tag = '%s_%d_%s' % (fname, i, pair_tag) tag = syntax.fresh_name(tag, all_tags) next_tags[pair_tag] = tag p.add_entry_function(functions[fname], tag) p.hook_tag_hints[tag] = pair_tag p.replay_inline_script(tag, scripts[pair_tag]) fun_tag_pairs.append((next_tags, pair)) p.pad_merge_points() p.do_analysis() free_hyps = [] for (tags, pair) in fun_tag_pairs: (inp_eqs, _) = pair.eqs free_hyps += check.inst_eqs(p, (), inp_eqs, tags) err_vis_opts = rep_graph.vc_options([0, 1, 2], [1]) err_vis_vc = tuple([(n, err_vis_opts) for n in p.loop_heads() if p.node_tags[n][0] == tags['C']]) err_vis = (('Err', err_vis_vc), tags['C']) free_hyps.append(rep_graph.pc_false_hyp(err_vis)) addr_map = {} for n in p.nodes: if not p.node_tags[n][0].endswith('_ASM'): continue if type(p.node_tags[n][1]) == tuple: (fname, data) = p.node_tags[n][1] if (logic.is_int(data) and is_addr(data) and not fname.startswith("instruction'")): assert data not in addr_map, data addr_map[data] = n return (p, free_hyps, addr_map, fun_tag_pairs)
def findLoopBoundBS(p_n, p, restrs=None, hyps=None, try_seq=None): if hyps == None: hyps = [] # print 'restrs: %s' % str(restrs) if try_seq == None: # bound_try_seq = [1,2,3,4,5,10,50,130,200,260] # bound_try_seq = [0,1,2,3,4,5,10,50,260] calls = [n for n in p.loop_body(p_n) if p.nodes[n].kind == "Call"] if calls: bound_try_seq = [0, 1, 20] else: bound_try_seq = [0, 1, 20, 34] else: bound_try_seq = try_seq rep = mk_graph_slice(p, fast=True) # get the head # print 'Binary addr: %s' % toHexs(self.toPhyAddrs(p_loop_heads)) loop_bound = None p_loop_heads = [n for n in p.loop_data if p.loop_data[n][0] == "Head"] print "p_loop_heads: %s" % p_loop_heads if restrs == None: others = [x for x in p_loop_heads if not x == p_n] # vc_options([concrete numbers], [offsets]) restrs = tuple([(n2, rep_graph.vc_options([0], [1])) for n2 in others]) print "getting the initial bound" # try: index = tryLoopBound(p_n, p, bound_try_seq, rep, restrs=restrs, hyps=hyps) if index == -1: return None print "got the initial bound %d" % bound_try_seq[index] # do a downward binary search to find the concrete loop bound if index == 0: loop_bound = bound_try_seq[0] print "bound = %d" % loop_bound return loop_bound loop_bound = downBinSearch( bound_try_seq[index - 1], bound_try_seq[index], lambda x: tryLoopBound(p_n, p, [x], rep, restrs=restrs, hyps=hyps, bin_return=True), ) print "bound = %d" % loop_bound return loop_bound
def findLoopBoundBS(p_n, p, restrs=None, hyps=None, try_seq=None): if hyps == None: hyps = [] #print 'restrs: %s' % str(restrs) if try_seq == None: #bound_try_seq = [1,2,3,4,5,10,50,130,200,260] #bound_try_seq = [0,1,2,3,4,5,10,50,260] calls = [n for n in p.loop_body(p_n) if p.nodes[n].kind == 'Call'] if calls: bound_try_seq = [0, 1, 20] else: bound_try_seq = [0, 1, 20, 34] else: bound_try_seq = try_seq rep = mk_graph_slice(p, fast=True) #get the head #print 'Binary addr: %s' % toHexs(self.toPhyAddrs(p_loop_heads)) loop_bound = None p_loop_heads = [n for n in p.loop_data if p.loop_data[n][0] == 'Head'] print 'p_loop_heads: %s' % p_loop_heads if restrs == None: others = [x for x in p_loop_heads if not x == p_n] #vc_options([concrete numbers], [offsets]) restrs = tuple([(n2, rep_graph.vc_options([0], [1])) for n2 in others]) print 'getting the initial bound' #try: index = tryLoopBound(p_n, p, bound_try_seq, rep, restrs=restrs, hyps=hyps) if index == -1: return None print 'got the initial bound %d' % bound_try_seq[index] #do a downward binary search to find the concrete loop bound if index == 0: loop_bound = bound_try_seq[0] print 'bound = %d' % loop_bound return loop_bound loop_bound = downBinSearch( bound_try_seq[index - 1], bound_try_seq[index], lambda x: tryLoopBound( p_n, p, [x], rep, restrs=restrs, hyps=hyps, bin_return=True)) print 'bound = %d' % loop_bound return loop_bound