コード例 #1
0
ファイル: search.py プロジェクト: SEL4PROJ/graph-refine
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
コード例 #2
0
ファイル: loop_bounds.py プロジェクト: SEL4PROJ/graph-refine
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)
コード例 #3
0
ファイル: loop_bounds.py プロジェクト: yyshen/graph-refine
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)
コード例 #4
0
ファイル: search.py プロジェクト: bacam/graph-refine
def build_proof_rec_with_restrs (split_points, kind, searcher, p, restrs, hyps):
	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]
	limit = find_split_limit (p, sp, restrs, use_hyps, kind)
	# double-check this limit with a rep constructed without the 'fast' flag
	limit = find_split_limit (p, sp, restrs, use_hyps, kind,
		hints = [limit, limit + 1], use_rep = mk_graph_slice (p))
	if kind == 'Number':
		vc_opts = vc_upto (limit + 1)
	else:
		vc_opts = vc_offset_upto (limit + 1)
	restrs = restrs + ((sp, vc_opts), )
	if len (split_points) == 1:
		subproof = build_proof_rec (searcher, p, restrs, hyps)
	else:
		subproof = build_proof_rec_with_restrs (split_points[1:],
			kind, searcher, p, restrs, hyps)

	return ProofNode ('Restr', (sp, (kind, (0, limit + 1))), [subproof])
コード例 #5
0
ファイル: check.py プロジェクト: yyshen/graph-refine
def restr_others(p, restrs, n):
    extras = [(sp, vc_upto(n)) for sp in loops_to_split(p, restrs)]
    return restrs + tuple(extras)
コード例 #6
0
ファイル: search.py プロジェクト: bacam/graph-refine
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
コード例 #7
0
ファイル: check.py プロジェクト: SEL4PROJ/graph-refine
def restr_others (p, restrs, n):
	extras = [(sp, vc_upto (n)) for sp in loops_to_split (p, restrs)]
	return restrs + tuple (extras)
コード例 #8
0
ファイル: search.py プロジェクト: SEL4PROJ/graph-refine
def get_necessary_split_opts (p, head, restrs, hyps, tags = None, iters = None):
	if not tags:
		tags = p.pairing.tags

	[l_tag, r_tag] = tags
	assert p.node_tags[head][0] == l_tag
	l_seq_vs = get_interesting_linear_series_exprs (p, head)
	if not l_seq_vs:
		return None
	r_seq_vs = {}
	for n in init_loops_to_split (p, restrs):
		if p.node_tags[n][0] == r_tag:
			vs = get_interesting_linear_series_exprs (p, n)
			r_seq_vs.update (vs)
	if not r_seq_vs:
		return None

	rep = rep_graph.mk_graph_slice (p, fast = True)
	def vis (n, i):
		if n != p.loop_id (n):
			i = i + 1
		return (n, tuple ([(p.loop_id (n), vc_num (i))]) + restrs)
	smt = lambda expr, n, i: rep.to_smt_expr (expr, vis (n, i))
	smt_pc = lambda n, i: rep.get_pc (vis (n, i))

	# remove duplicates by concretising
	l_seq_vs = dict ([(smt (expr, n, 2), (kind, n, expr))
		for n in l_seq_vs for (kind, expr) in l_seq_vs[n]]).values ()
	r_seq_vs = dict ([(smt (expr, n, 2), (kind, n, expr))
                for n in r_seq_vs for (kind, expr) in r_seq_vs[n]]).values ()

	if iters == None:
		if [n for n in p.loop_body (head) if p.nodes[n].kind == 'Call']:
			iters = 5
		else:
			iters = 8

	r_seq_end = 1 + 2 * iters
	l_seq_end = 1 + iters
	l_seq_ineq = 1 + max ([1 << n for n in range (iters)
		if 1 << n <= iters])

	hyps = hyps + [rep_graph.pc_triv_hyp ((vis (n, r_seq_end), r_tag))
		for n in set ([n for (_, n, _) in r_seq_vs])]
	hyps = hyps + [rep_graph.pc_triv_hyp ((vis (n, l_seq_end), l_tag))
		for n in set ([n for (_, n, _) in l_seq_vs])]
	ex_restrs = [(n, rep_graph.vc_upto (r_seq_end + 1))
		for n in set ([p.loop_id (n) for (_, n, _) in r_seq_vs])]
	hyps = hyps + [check.non_r_err_pc_hyp (tags,
			restr_others (p, restrs + tuple (ex_restrs), 2))]

	necessary_split_opts_trace[:] = []
	necessary_split_opts_long_trace[:] = []
	for (kind, n, expr) in sorted (l_seq_vs):
		rel_r_seq_vs = [v for v in r_seq_vs if v[0] == kind]
		if not rel_r_seq_vs:
			necessary_split_opts_trace.append ((n, 'NoneRelevant'))
			continue
		m = {}
		eq = mk_eq (smt (expr, n, 1), smt (expr, n, l_seq_ineq))
		ex_hyps = [rep_graph.pc_true_hyp ((vis (n, i), l_tag))
			for i in range (1, l_seq_end + 1)]
		res = rep.test_hyp_whyps (eq, hyps + ex_hyps, model = m)
		necessary_split_opts_long_trace.append ((n, eq, hyps + ex_hyps,
			res, m, smt, smt_pc, (kind, n, expr), r_seq_vs, iters))
		if not m:
			necessary_split_opts_trace.append ((n, None))
			continue
		seq_eq = get_linear_seq_eq (rep, m, smt, smt_pc,
			(kind, n, expr), r_seq_vs, iters)
		necessary_split_opts_trace.append ((n, ('Seq', seq_eq)))
		if not seq_eq:
			continue
		((n2, expr2), (l_start, l_step), (r_start, r_step)) = seq_eq
		eqs = [rep_graph.eq_hyp ((expr,
			(vis (n, l_start + (i * l_step)), l_tag)),
			(expr2, (vis (n2, r_start + (i * r_step)), r_tag)))
			for i in range (10)
			if l_start + (i * l_step) <= l_seq_end
			if r_start + (i * r_step) <= r_seq_end]
		eq = foldr1 (mk_and, map (rep.interpret_hyp, eqs))
		if rep.test_hyp_whyps (eq, hyps):
			mk_i = lambda i: (l_start + (i * l_step), l_step)
			mk_j = lambda j: (r_start + (j * r_step), r_step)
			return [([mk_i (0)], [mk_j (0)]),
				([mk_i (0), mk_i (1)], [mk_j (0), mk_j (1)])]
		n_vcs = entry_path_no_loops (rep, l_tag, m, head)
		path_hyps = [rep_graph.pc_true_hyp ((n_vc, l_tag)) for n_vc in n_vcs]
		if rep.test_hyp_whyps (eq, hyps + path_hyps):
			# immediate case split on difference between entry paths
			checks = [(hyps, eq_hyp, 'eq') for eq_hyp in eqs]
			return derive_case_split (rep, n_vcs, checks)
		necessary_split_opts_trace.append ((n, 'Seq check failed'))
	return None