def check_split_induct (p, restrs, hyps, split, tags = None): """perform both the induction check and a function-call based check on successes which can avoid some problematic inductions.""" ((l_split, (_, l_step), _), (r_split, (_, r_step), _), _, n, _) = split if tags == None: tags = p.pairing.tags err_hyp = check.split_r_err_pc_hyp (p, split, restrs, tags = tags) hyps = [err_hyp] + hyps + check.split_loop_hyps (tags, split, restrs, exit = False) rep = mk_graph_slice (p) if not check.check_split_induct_step_group (rep, restrs, hyps, split, tags = tags): return False l_succs = get_n_offset_successes (rep, l_split, l_step, restrs) r_succs = get_n_offset_successes (rep, r_split, r_step, restrs) if not l_succs: return True hyp = syntax.foldr1 (syntax.mk_and, l_succs) if r_succs: hyp = syntax.mk_implies (foldr1 (syntax.mk_and, r_succs), hyp) return rep.test_hyp_whyps (hyp, hyps)
def v_eqs_to_split (p, pair, v_eqs, restrs, hyps, tags = None): trace ('v_eqs_to_split: (%s, %s)' % pair) ((l_n, l_init, l_step), (r_n, r_init, r_step)) = pair l_details = (l_n, (l_init, l_step), mk_seq_eqs (p, l_n, l_step, True) + [v_i[0] for (v_i, v_j) in v_eqs if v_j == 'Const']) r_details = (r_n, (r_init, r_step), mk_seq_eqs (p, r_n, r_step, False) + c_memory_loop_invariant (p, r_n, l_n)) eqs = [(v_i[0], mk_cast (v_j[0], v_i[0].typ)) for (v_i, v_j) in v_eqs if v_j != 'Const'] n = 2 split = (l_details, r_details, eqs, n, (n * r_step) - 1) trace ('Split: %s' % (split, )) if tags == None: tags = p.pairing.tags hyps = hyps + check.split_loop_hyps (tags, split, restrs, exit = True) r_max = find_split_limit (p, r_n, restrs, hyps, 'Offset', bound = (n + 2) * r_step, must_find = False, hints = [n * r_step, n * r_step + 1]) if r_max == None: trace ('v_eqs_to_split: no RHS limit') return None if r_max > n * r_step: trace ('v_eqs_to_split: RHS limit not %d' % (n * r_step)) return None trace ('v_eqs_to_split: split %s' % (split,)) return split