def investigate_funcall_pair(rep, m, l_n_vc, r_n_vc, verbose=False, verbose_imp=False, simplify=True): l_nm = "%s @ %s" % (rep.p.nodes[l_n_vc[0]].fname, rep.node_count_name(l_n_vc)) r_nm = "%s @ %s" % (rep.p.nodes[r_n_vc[0]].fname, rep.node_count_name(r_n_vc)) print "Attempt match %s -> %s" % (l_nm, r_nm) imp = rep.get_func_assert(l_n_vc, r_n_vc) if verbose_imp: imp2 = logic.weaken_assert(imp) imp2 = solver.smt_expr(imp2, {}, rep.solv) if simplify: imp2 = simplify_sexp(imp2, rep, m) print imp2 assert imp.is_op("Implies"), imp [pred, concl] = imp.vals pred = solver.smt_expr(pred, {}, rep.solv) pred = solver.parse_s_expression(pred) bits = solver.split_hyp_sexpr(pred, []) xs = [eval_model_bool(m, v) for v in bits] print " %s" % xs for (v, bit) in zip(xs, bits): if v != True or verbose: print " %s: %s" % (v, bit) if bit[0] == "word32-eq": vs = [model_sx_word(m, x) for x in bit[1:]] print " (%s = %s)" % tuple(vs)
def investigate_funcall_pair(rep, m, l_n_vc, r_n_vc, verbose=False, verbose_imp=False, simplify=True): l_nm = "%s @ %s" % (rep.p.nodes[l_n_vc[0]].fname, rep.node_count_name(l_n_vc)) r_nm = "%s @ %s" % (rep.p.nodes[r_n_vc[0]].fname, rep.node_count_name(r_n_vc)) print 'Attempt match %s -> %s' % (l_nm, r_nm) imp = rep.get_func_assert(l_n_vc, r_n_vc) imp = logic.weaken_assert(imp) if verbose_imp: imp2 = solver.smt_expr(imp, {}, rep.solv) if simplify: imp2 = simplify_sexp(imp2, rep, m) print imp2 assert imp.is_op('Implies'), imp [pred, concl] = imp.vals pred = solver.smt_expr(pred, {}, rep.solv) pred = solver.parse_s_expression(pred) bits = solver.split_hyp_sexpr(pred, []) xs = [eval_model_bool(m, v) for v in bits] print ' %s' % xs for (v, bit) in zip(xs, bits): if v != True or verbose: print ' %s: %s' % (v, bit) if bit[0] == 'word32-eq': vs = [model_sx_word(m, x) for x in bit[1:]] print ' (%s = %s)' % tuple(vs)
def setup_split_search (rep, head, restrs, hyps, i_opts, j_opts, unfold_limit = None, tags = None): p = rep.p if not tags: tags = p.pairing.tags if unfold_limit == None: unfold_limit = max ([start + (2 * step) + 1 for (start, step) in i_opts + j_opts]) trace ('Split search at %d, unfold limit %d.' % (head, unfold_limit)) l_tag, r_tag = tags loop_elts = [(n, start, step) for n in p.splittable_points (head) for (start, step) in i_opts] init_to_split = init_loops_to_split (p, restrs) r_to_split = [n for n in init_to_split if p.node_tags[n][0] == r_tag] cand_r_loop_elts = [(n2, start, step) for n in r_to_split for n2 in p.splittable_points (n) for (start, step) in j_opts] err_restrs = restr_others (p, tuple ([(sp, vc_upto (unfold_limit)) for sp in r_to_split]) + restrs, 1) nrerr_pc = mk_not (rep.get_pc (('Err', err_restrs), tag = r_tag)) def get_pc (n, k): head = p.loop_id (n) assert head in init_to_split if n != head: k += 1 restrs2 = restrs + ((head, vc_num (k)), ) return rep.get_pc ((n, restrs2)) for n in r_to_split: get_pc (n, unfold_limit) get_pc (head, unfold_limit) premise = foldr1 (mk_and, [nrerr_pc] + map (rep.interpret_hyp, hyps)) premise = logic.weaken_assert (premise) knowledge = SearchKnowledge (rep, 'search at %d (unfold limit %d)' % (head, unfold_limit), restrs, hyps, tags, (loop_elts, cand_r_loop_elts)) knowledge.premise = premise last_knowledge[0] = knowledge # make sure the representation is in sync rep.test_hyp_whyps (true_term, hyps) # make sure all mem eqs are being tracked mem_vs = [v for v in knowledge.v_ids if v[0].typ == builtinTs['Mem']] for (i, v) in enumerate (mem_vs): for v2 in mem_vs[:i]: for pred in expand_var_eqs (knowledge, (v, v2)): smt_expr (pred, {}, rep.solv) for v in knowledge.v_ids: for pred in expand_var_eqs (knowledge, (v, 'Const')): smt_expr (pred, {}, rep.solv) return knowledge
def add_func_assert (self, n_vc, n_vc2): imp = self.get_func_assert (n_vc, n_vc2) imp = logic.weaken_assert (imp) if self.local_defs_unsat: self.solv.assert_fact (imp, {}, unsat_tag = ('FunEq', ln, rn)) else: self.solv.assert_fact (imp, {})
def find_split (rep, head, restrs, hyps, i_opts, j_opts, unfold_limit, tags = None): p = rep.p if tags: l_tag, r_tag = tags else: l_tag, r_tag = p.pairing.tags loop_elts = [(n, start, step) for n in p.loop_data[head][1] if p.loop_splittables[n] for (start, step) in i_opts] init_to_split = init_loops_to_split (p, restrs) r_to_split = [n for n in init_to_split if p.node_tags[n][0] == r_tag] cand_r_loop_elts = [(n2, start, step) for n in r_to_split for n2 in p.loop_data[n][1] if p.loop_splittables[n2] for (start, step) in j_opts] err_restrs = restr_others (p, tuple ([(sp, vc_upto (unfold_limit)) for sp in r_to_split]) + restrs, 1) nrerr_pc = mk_not (rep.get_pc (('Err', err_restrs), tag = r_tag)) def get_pc (n, k): head = p.loop_id (n) assert head in init_to_split if n != head: k += 1 restrs2 = restrs + ((head, vc_num (k)), ) return rep.get_pc ((n, restrs2)) for n in r_to_split: get_pc (n, unfold_limit) get_pc (head, unfold_limit) premise = foldr1 (mk_and, [nrerr_pc] + map (rep.interpret_hyp, hyps)) premise = logic.weaken_assert (premise) knowledge = (rep, (restrs, loop_elts, cand_r_loop_elts, premise), init_knowledge_pairs (rep, loop_elts, cand_r_loop_elts), set ()) last_knowledge[0] = knowledge # make sure the representation is in sync rep.test_hyp_whyps (true_term, hyps) # make sure all mem eqs are being tracked (_, _, (pairs, vs), _) = knowledge mem_vs = [v for v in vs if v[0].typ == builtinTs['Mem']] for (i, v) in enumerate (mem_vs): for v2 in mem_vs[:i]: for pred in expand_var_eqs (knowledge, (v, v2)): smt_expr (pred, {}, rep.solv) for v in vs: for pred in expand_var_eqs (knowledge, (v, 'Const')): smt_expr (pred, {}, rep.solv) # start the process with a model add_model (knowledge, [mk_not (get_pc (head, unfold_limit))]) num_eqs = 3 while True: trace ('Search at unfold limit %d' % unfold_limit) trace ('Computing live pairings') pair_eqs = [(pair, mk_pairing_v_eqs (knowledge, pair)) for pair in sorted (pairs) if pairs[pair][0] != 'Failed'] endorsed = [(pair, eqs) for (pair, eqs) in pair_eqs if eqs != None] trace (' ... %d live pairings, %d endorsed' % (len (pair_eqs), len (endorsed))) for (pair, eqs) in endorsed: split = v_eqs_to_split (p, pair, eqs, restrs, hyps, tags = tags) if split == None: pairs[pair] = ('Failed', 'SplitWeak', eqs) continue if check_split_induct (p, restrs, hyps, split, tags = tags): trace ('Tested v_eqs!') return ('Split', split) else: pairs[pair] = ('Failed', 'InductFailed', eqs) u_eqs = unknown_eqs (knowledge, num_eqs) if not u_eqs: trace (('Exhausted split candidates for loop at %d,' + ' unfold limit %d') % (head, unfold_limit)) fails = [it for it in pairs.items () if it[1][0] == 'Failed'] fails10 = fails[:10] trace (' %d of %d failed pairings:' % (len (fails10), len (fails))) last_failed_pairings.append (fails) del last_failed_pairings[:-10] for f in fails: trace (' %s' % (f,)) ind_fails = [it for it in fails if str (it[1][1]) == 'InductFailed'] if ind_fails: trace ( 'Inductive failures!') for f in ind_fails: trace (' %s' % (f,)) return (None, ind_fails) add_model_wrapper (knowledge, u_eqs) num_eqs = 4 - num_eqs # oscillate between 3, 1