示例#1
0
def single_loop_induct_step_checks(p,
                                   restrs,
                                   hyps,
                                   tag,
                                   split,
                                   n,
                                   eqs,
                                   eqs_assume=None):
    if eqs_assume == None:
        eqs_assume = []
    details = (split, (0, 1), eqs_assume + eqs)
    cont = split_visit_one_visit(tag, details, restrs, vc_offs(n))
    hyps = ([pc_true_hyp(cont)] + hyps + [
        h for i in range(n)
        for (h, _) in loop_eq_hyps_at_visit(tag, split, eqs_assume +
                                            eqs, restrs, vc_offs(i))
    ])

    return [
        (hyps, hyp,
         'Induct check (%s) at inductive step for %d' % (desc, split))
        for (
            hyp,
            desc) in loop_eq_hyps_at_visit(tag, split, eqs, restrs, vc_offs(n))
    ]
示例#2
0
def get_uniform_loop_vc(p, n):
    l_id = p.loop_id(n)
    assert l_id != None, n
    if n == l_id:
        restrs = tuple([(l_id, rep_graph.vc_offs(0))])
    else:
        restrs = tuple([(l_id, rep_graph.vc_offs(1))])
    restrs = search.restr_others_both(p, restrs, 2, 2)
    return restrs
示例#3
0
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))]
示例#4
0
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))]
示例#5
0
def linear_eq_induct_step_checks(p, restrs, hyps, tag, split, eqs_assume, eqs):
    details = (split, (0, 1), eqs_assume + eqs)
    cont = split_visit_one_visit(tag, details, restrs, vc_offs(1))
    hyps = (
        [pc_true_hyp(cont)]
        + hyps
        + [h for (h, _) in linear_eq_hyps_at_visit(tag, split, eqs_assume + eqs, restrs, vc_offs(0))]
    )

    return [
        (hyps, hyp, "Induct check (%s) at inductive step for %d" % (desc, split))
        for (hyp, desc) in linear_eq_hyps_at_visit(tag, split, eqs, restrs, vc_offs(1))
    ]
示例#6
0
def linear_eq_induct_step_checks (p, restrs, hyps, tag, split, eqs):
    details = (split, (0, 1), eqs)
    cont = split_visit_one_visit (tag, details, restrs, vc_offs (1))
    # the 'trivial' hyp here ensures the representation includes a loop
    # of the rhs when proving const equations on the lhs
    hyps = ([pc_true_hyp (cont)] + hyps
            + [h for (h, _) in linear_eq_hyps_at_visit (tag, split,
            eqs, restrs, vc_offs (0))])

    return [(hyps, hyp, 'Induct check (%s) at inductive step for %d'
            % (desc, split))
        for (hyp, desc) in linear_eq_hyps_at_visit (tag, split, eqs,
            restrs, vc_offs (1))]
示例#7
0
def split_loop_hyps (tags, split, restrs, exit):
	((r_split, _, _), _, _, n, _) = split
	(l_visit, _) = split_visit_visits (tags, split, restrs, vc_offs (n - 1))
	(l_cont, _) = split_visit_visits (tags, split, restrs, vc_offs (n))
	(l_tag, r_tag) = tags

	l_enter = pc_true_hyp (l_visit)
	l_exit = pc_false_hyp (l_cont)
	if exit:
		hyps = [l_enter, l_exit]
	else:
		hyps = [l_enter]
	return hyps + [hyp for offs in map (vc_offs, range (n))
		for (hyp, _) in split_hyps_at_visit (tags, split, restrs, offs)]
示例#8
0
def get_n_offset_successes (rep, sp, step, restrs):
	loop = rep.p.loop_body (sp)
	ns = [n for n in loop if rep.p.nodes[n].kind == 'Call']
	succs = []
	for i in range (step):
		for n in ns:
			vc = vc_offs (i + 1)
			if n == sp:
				vc = vc_offs (i)
			n_vc = (n, restrs + tuple ([(sp, vc)]))
			(_, _, succ) = rep.get_func (n_vc)
			pc = rep.get_pc (n_vc)
			succs.append (syntax.mk_implies (pc, succ))
	return succs
示例#9
0
def get_induct_eq_hyp(p, split, restrs, n):
    details = (split, (0, 1), [])
    (tag, _) = p.node_tags[split]
    visit = split_visit_one_visit(tag, details, restrs, vc_offs(0))
    from syntax import mk_var, word32T, mk_word32

    return eq_hyp((mk_var("%n", word32T), visit), (mk_word32(n), visit), (split, 0))
示例#10
0
 def test (n):
     assert n > 10
     hyp = get_induct_eq_hyp (p, split, restrs, n - 2)
     visit = ((split, vc_offs (2)), ) + restrs
     continue_to_split_guess = rep.get_pc ((split, visit))
     return rep.test_hyp_whyps (syntax.mk_not (continue_to_split_guess),
       [hyp] + l_hyps + hyps)
示例#11
0
def split_loop_hyps(tags, split, restrs, exit):
    ((r_split, _, _), _, _, n, _) = split
    (l_visit, _) = split_visit_visits(tags, split, restrs, vc_offs(n - 1))
    (l_cont, _) = split_visit_visits(tags, split, restrs, vc_offs(n))
    (l_tag, r_tag) = tags

    l_enter = pc_true_hyp(l_visit)
    l_exit = pc_false_hyp(l_cont)
    if exit:
        hyps = [l_enter, l_exit]
    else:
        hyps = [l_enter]
    return hyps + [
        hyp for offs in map(vc_offs, range(n))
        for (hyp, _) in split_hyps_at_visit(tags, split, restrs, offs)
    ]
示例#12
0
 def test(n):
     assert n > 10
     hyp = check.mk_loop_counter_eq_hyp(p, split, restrs, n - 2)
     visit = ((split, vc_offs(2)), ) + restrs
     continue_to_split_guess = rep.get_pc((split, visit))
     return rep.test_hyp_whyps(syntax.mk_not(continue_to_split_guess),
                               [hyp] + l_hyps + hyps)
示例#13
0
def single_loop_rev_induct_base_checks(p, restrs, hyps, tag, split, n_bound,
                                       eqs_assume, pred):
    details = (split, (0, 1), eqs_assume)
    cont = split_visit_one_visit(tag, details, restrs, vc_offs(1))
    n_hyp = mk_loop_counter_eq_hyp(p, split, restrs, n_bound)

    split_details = (None, details, None, 1, 1)
    non_err = split_r_err_pc_hyp(p, split_details, restrs)

    hyps = (hyps + [n_hyp, pc_true_hyp(cont), non_err] + [
        h for (h, _) in loop_eq_hyps_at_visit(tag, split, eqs_assume, restrs,
                                              vc_offs(0))
    ])
    goal = rep_graph.true_if_at_hyp(pred, cont)

    return [(hyps, goal, 'Pred true at %d check.' % n_bound)]
示例#14
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))]
示例#15
0
def single_loop_rev_induct_checks(p, restrs, hyps, tag, split, eqs_assume,
                                  pred):
    details = (split, (0, 1), eqs_assume)
    curr = split_visit_one_visit(tag, details, restrs, vc_offs(1))
    cont = split_visit_one_visit(tag, details, restrs, vc_offs(2))

    split_details = (None, details, None, 1, 1)
    non_err = split_r_err_pc_hyp(p, split_details, restrs)
    true_next = rep_graph.true_if_at_hyp(pred, cont)

    hyps = (hyps + [pc_true_hyp(curr), true_next, non_err] + [
        h for (h, _) in loop_eq_hyps_at_visit(
            tag, split, eqs_assume, restrs, vc_offs(1), use_if_at=True)
    ])
    goal = rep_graph.true_if_at_hyp(pred, curr)

    return [(hyps, goal, 'Pred reverse step.')]
示例#16
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))]
示例#17
0
def get_linear_series_hyps(p, split, restrs, hyps):
    eqs = get_linear_series_eqs(p, split, restrs, hyps)
    (tag, _) = p.node_tags[split]
    hyps = [
        h
        for (h,
             _) in linear_eq_hyps_at_visit(tag, split, eqs, restrs, vc_offs(0))
    ]
    return hyps
示例#18
0
def split_visit_one_visit (tag, details, restrs, visit):
	if details == None:
		return None
	(split, (seq_start, step), eqs) = details

	# the split point sequence at low numbers ('Number') is offset
	# by the point the sequence starts. At symbolic offsets we ignore
	# that, instead having the loop counter for the two sequences
	# be the same number of iterations after the sequence start.
	if visit.kind == 'Offset':
		visit = vc_offs (visit.n * step)
	else:
		visit = vc_num (seq_start + (visit.n * step))

	visit = ((split, ((split, visit), ) + restrs), tag)
	return visit
示例#19
0
def split_visit_one_visit(tag, details, restrs, visit):
    if details == None:
        return None
    (split, (seq_start, step), eqs) = details

    # the split point sequence at low numbers ('Number') is offset
    # by the point the sequence starts. At symbolic offsets we ignore
    # that, instead having the loop counter for the two sequences
    # be the same number of iterations after the sequence start.
    if visit.kind == 'Offset':
        visit = vc_offs(visit.n * step)
    else:
        visit = vc_num(seq_start + (visit.n * step))

    visit = ((split, ((split, visit), ) + restrs), tag)
    return visit
示例#20
0
def get_linear_series_hyps(p, split, restrs, hyps):

    k = ("linear_series_hyps", split, restrs, tuple(hyps))
    if k in p.cached_analysis:
        return p.cached_analysis[k]

    cands = search.mk_seq_eqs(p, split, 1, with_rodata=False)
    cands += candidate_additional_eqs(p, split)
    (tag, _) = p.node_tags[split]

    rep = rep_graph.mk_graph_slice(p, fast=True)

    def do_checks(eqs_assume, eqs):
        checks = linear_eq_induct_step_checks(
            p, restrs, hyps, tag, split, eqs_assume, eqs
        ) + linear_eq_induct_base_checks(p, restrs, hyps, tag, split, eqs)

        groups = check.proof_check_groups(checks)
        for group in groups:
            (res, _) = check.test_hyp_group(rep, group)
            if not res:
                return False
        return True

    eqs = []
    failed = []
    while cands:
        cand = cands.pop()
        if do_checks(eqs, [cand]):
            eqs.append(cand)
            failed.reverse()
            cands = failed + cands
            failed = []
        else:
            failed.append(cand)

    assert do_checks([], eqs)

    hyps = [h for (h, _) in linear_eq_hyps_at_visit(tag, split, eqs, restrs, vc_offs(0))]
    p.cached_analysis[k] = hyps
    return hyps
示例#21
0
def mk_loop_counter_eq_hyp(p, split, restrs, n):
    details = (split, (0, 1), [])
    (tag, _) = p.node_tags[split]
    visit = split_visit_one_visit(tag, details, restrs, vc_offs(0))
    return eq_hyp((mk_var('%n', word32T), visit), (mk_word32(n), visit),
                  (split, 0))
示例#22
0
	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)
	else:
		min_vc = None
	if min_vc:
		init_check = [(hyps, pc_true_hyp (visit (min_vc)),
			'Check of restr min %d %s for %d' % (x, kind, n))]
	else:
		init_check = []

	# if we can reach node n with (y - 1) visits to n, then the next
	# node will have y visits to n, which we are disallowing
	# thus we show that this visit is impossible
	top_vc = VisitCount (kind, y - 1)
	top_check = (hyps, pc_false_hyp (visit (top_vc)),
示例#23
0
    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)
    else:
        min_vc = None
    if min_vc:
        init_check = [(hyps, pc_true_hyp(visit(min_vc)),
                       'Check of restr min %d %s for %d' % (x, kind, n))]
    else:
        init_check = []

    # if we can reach node n with (y - 1) visits to n, then the next
    # node will have y visits to n, which we are disallowing
    # thus we show that this visit is impossible
    top_vc = VisitCount(kind, y - 1)
    top_check = (hyps, pc_false_hyp(visit(top_vc)),