Example #1
0
def split_induct_step_checks (p, restrs, hyps, split, tags = None):
	((l_split, _, _), _, _, n, _) = split
	if tags == None:
		tags = p.pairing.tags

	err_hyp = split_r_err_pc_hyp (p, split, restrs, tags = tags)
	(cont, r_cont) = split_visit_visits (tags, split, restrs, vc_offs (n))
	# the 'trivial' hyp here ensures the representation includes a loop
	# of the rhs when proving const equations on the lhs
	hyps = ([err_hyp, pc_true_hyp (cont),
			rep_graph.pc_triv_hyp (r_cont)] + hyps
		+ split_loop_hyps (tags, split, restrs, exit = False))

	return [(hyps, hyp, 'Induct check (%s) at inductive step for %d'
			% (desc, l_split))
		for (hyp, desc) in split_hyps_at_visit (tags, split,
			restrs, vc_offs (n))]
Example #2
0
def split_induct_step_checks(p, restrs, hyps, split, tags=None):
    ((l_split, _, _), _, _, n, _) = split
    if tags == None:
        tags = p.pairing.tags

    err_hyp = split_r_err_pc_hyp(p, split, restrs, tags=tags)
    (cont, r_cont) = split_visit_visits(tags, split, restrs, vc_offs(n))
    # the 'trivial' hyp here ensures the representation includes a loop
    # of the rhs when proving const equations on the lhs
    hyps = (
        [err_hyp, pc_true_hyp(cont),
         rep_graph.pc_triv_hyp(r_cont)] + hyps +
        split_loop_hyps(tags, split, restrs, exit=False))

    return [(hyps, hyp,
             'Induct check (%s) at inductive step for %d' % (desc, l_split))
            for (hyp,
                 desc) in split_hyps_at_visit(tags, split, restrs, vc_offs(n))]
Example #3
0
def split_init_step_checks(p, restrs, hyps, split, tags=None):
    (_, _, _, n, _) = split
    if tags == None:
        tags = p.pairing.tags

    err_hyp = split_r_err_pc_hyp(p, split, restrs, tags=tags)
    hyps = [err_hyp] + hyps
    checks = []
    for i in range(n):
        (l_visit, r_visit) = split_visit_visits(tags, split, restrs, vc_num(i))
        lpc_hyp = pc_true_hyp(l_visit)
        # this trivial 'hyp' ensures the rep is built to include
        # the matching rhs visits when checking lhs consts
        rpc_triv_hyp = rep_graph.pc_triv_hyp(r_visit)
        vis_hyps = split_hyps_at_visit(tags, split, restrs, vc_num(i))

        for (hyp, desc) in vis_hyps:
            checks.append((hyps + [lpc_hyp, rpc_triv_hyp], hyp,
                           'Induct check at visit %d: %s' % (i, desc)))
    return checks
Example #4
0
def split_init_step_checks (p, restrs, hyps, split, tags = None):
	(_, _, _, n, _) = split
	if tags == None:
		tags = p.pairing.tags

	err_hyp = split_r_err_pc_hyp (p, split, restrs, tags = tags)
	hyps = [err_hyp] + hyps
	checks = []
	for i in range (n):
		(l_visit, r_visit) = split_visit_visits (tags, split,
			restrs, vc_num (i))
		lpc_hyp = pc_true_hyp (l_visit)
		# this trivial 'hyp' ensures the rep is built to include
		# the matching rhs visits when checking lhs consts
		rpc_triv_hyp = rep_graph.pc_triv_hyp (r_visit)
		vis_hyps = split_hyps_at_visit (tags, split, restrs, vc_num (i))

		for (hyp, desc) in vis_hyps:
			checks.append ((hyps + [lpc_hyp, rpc_triv_hyp], hyp,
				'Induct check at visit %d: %s' % (i, desc)))
	return checks
Example #5
0
    return non_r_err_pc_hyp(tags, restrs)


restr_bump = 0


def get_proof_restr(n, (kind, (x, y))):
    return (n,
            mk_vc_opts([VisitCount(kind, i)
                        for i in range(x, y + restr_bump)]))


def restr_trivial_hyp(p, n, (kind, (x, y)), restrs):
    restr = (n, VisitCount(kind, y - 1))
    return rep_graph.pc_triv_hyp(((n, (restr, ) + restrs), p.node_tags[n][0]))


def proof_restr_checks(n, (kind, (x, y)), p, restrs, hyps):
    restr = get_proof_restr(n, (kind, (x, y)))
    ncerr_hyp = non_r_err_pc_hyp(p.pairing.tags,
                                 restr_others(p, (restr, ) + restrs, 2))
    hyps = [ncerr_hyp] + hyps

    def visit(vc):
        return ((n, ((n, vc), ) + restrs), p.node_tags[n][0])

    # this cannot be more uniform because the representation of visit
    # at offset 0 is all a bit odd, with n being the only node so visited:
    if kind == 'Offset':
        min_vc = vc_offs(max(0, x - 1))
Example #6
0
	restrs = restr_others (p, ((r_split, vc), ) + restrs, 2)

	if tags == None:
		tags = p.pairing.tags

	return non_r_err_pc_hyp (tags, restrs)

restr_bump = 0

def get_proof_restr (n, (kind, (x, y))):
	return (n, mk_vc_opts ([VisitCount (kind, i)
		for i in range (x, y + restr_bump)]))

def restr_trivial_hyp (p, n, (kind, (x, y)), restrs):
	restr = (n, VisitCount (kind, y - 1))
	return rep_graph.pc_triv_hyp (((n, (restr, ) + restrs),
		p.node_tags[n][0]))

def proof_restr_checks (n, (kind, (x, y)), p, restrs, hyps):
	restr = get_proof_restr (n, (kind, (x, y)))
	ncerr_hyp = non_r_err_pc_hyp (p.pairing.tags,
		restr_others (p, (restr, ) + restrs, 2))
	hyps = [ncerr_hyp] + hyps
	def visit (vc):
		return ((n, ((n, vc), ) + restrs), p.node_tags[n][0])

	# this cannot be more uniform because the representation of visit
	# at offset 0 is all a bit odd, with n being the only node so visited:
	if kind == 'Offset':
		min_vc = vc_offs (max (0, x - 1))
	elif x > 1:
		min_vc = vc_num (x - 1)
Example #7
0
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