def get_proof_term(self, goal, *, args=None, prevs=None): assert isinstance(prevs, list) and len(prevs) == 1, "rewrite_goal_with_prev" pt = prevs[0] C = goal.prop # In general, we assume pt.th has forall quantification. # First, obtain the patterns new_names = logic.get_forall_names(pt.prop) new_vars, prev_As, prev_C = logic.strip_all_implies(pt.prop, new_names) # Fact used must be an equality assert len( prev_As) == 0 and prev_C.is_equals(), "rewrite_goal_with_prev" for new_var in new_vars: pt = pt.forall_elim(new_var) # Check whether rewriting using the theorem has an effect assert has_rewrite(pt.th, C), "rewrite_goal_with_prev" cv = then_conv(top_sweep_conv(rewr_conv(pt)), beta_norm_conv()) eq_th = cv.eval(C) new_goal = eq_th.prop.rhs prevs = list(prevs) if not new_goal.is_reflexive(): prevs.append(ProofTerm.sorry(Thm(goal.hyps, new_goal))) return ProofTerm('rewrite_goal_with_prev', args=C, prevs=prevs)
def get_proof_term(self, goal): th = theory.get_theorem(self.th_name) assum = th.assums[0] cond = self.cond if cond is None: # Find cond by matching with goal.hyps one by one for hyp in goal.hyps: try: inst = matcher.first_order_match(th.assums[0], hyp, self.inst) cond = hyp break except matcher.MatchException: pass if cond is None: raise TacticException('elim: cannot match assumption') try: inst = matcher.first_order_match(th.concl, goal.prop, inst) except matcher.MatchException: raise TacticException('elim: matching failed') if any(v.name not in inst for v in th.prop.get_svars()): raise TacticException('elim: not all variables are matched') pt = ProofTerm.theorem(self.th_name).substitution(inst).on_prop( beta_norm_conv()) pt = pt.implies_elim(ProofTerm.assume(cond)) for assum in pt.assums: pt = pt.implies_elim(ProofTerm.sorry(Thm(goal.hyps, assum))) return pt
def get_proof_term(self, args, pts): assert isinstance(args, Term), "rewrite_goal_macro: signature" goal = args eq_pt = pts[0] new_names = get_forall_names(eq_pt.prop) new_vars, _, _ = strip_all_implies(eq_pt.prop, new_names) for new_var in new_vars: eq_pt = eq_pt.forall_elim(new_var) pts = pts[1:] cv = then_conv(top_sweep_conv(rewr_conv(eq_pt, sym=self.sym)), beta_norm_conv()) pt = cv.get_proof_term(goal) # goal = th.prop pt = pt.symmetric() # th.prop = goal if pt.prop.lhs.is_reflexive(): pt = pt.equal_elim(refl(pt.prop.lhs.rhs)) else: pt = pt.equal_elim(pts[0]) pts = pts[1:] for A in pts: pt = pt.implies_intr(A.prop).implies_elim(A) return pt
def get_proof_term(self, goal, *, args=None, prevs=None): th_name = args C = goal.prop # Check whether rewriting using the theorem has an effect assert has_rewrite(th_name, C, sym=self.sym, conds=prevs), \ "rewrite: unable to apply theorem." cv = then_conv( top_sweep_conv(rewr_conv(th_name, sym=self.sym, conds=prevs)), beta_norm_conv()) eq_th = cv.eval(C) new_goal = eq_th.prop.rhs if self.sym: macro_name = 'rewrite_goal_sym' else: macro_name = 'rewrite_goal' if new_goal.is_equals() and new_goal.lhs == new_goal.rhs: return ProofTerm(macro_name, args=(th_name, C), prevs=prevs) else: new_goal = ProofTerm.sorry(Thm(goal.hyps, new_goal)) assert new_goal.prop != goal.prop, "rewrite: unable to apply theorem" return ProofTerm(macro_name, args=(th_name, C), prevs=[new_goal] + prevs)
def get_proof_term(self, args, pts): if self.with_inst: name, inst = args else: name = args inst = Inst() th = theory.get_theorem(name) As, C = th.prop.strip_implies() assert len(pts) <= len(As), "apply_theorem: too many prevs." # First attempt to match type variables svars = th.prop.get_svars() for v in svars: if v.name in inst: v.T.match_incr(inst[v.name].get_type(), inst.tyinst) pats = As[:len(pts)] ts = [pt.prop for pt in pts] inst = matcher.first_order_match_list(pats, ts, inst) pt = ProofTerm.theorem(name) pt = pt.subst_type(inst.tyinst).substitution(inst) if pt.prop.beta_norm() != pt.prop: pt = pt.on_prop(beta_norm_conv()) pt = pt.implies_elim(*pts) assert len(pt.prop.get_stvars()) == 0, "apply_theorem: unmatched type variables." vars = pt.prop.get_svars() for v in reversed(vars): pt = pt.forall_intr(v) return pt
def get_proof_term(self, args, pts): assert len(pts) == 1, "forall_elim_gen" assert isinstance(args, Term), "forall_elim_gen" s = args # term to instantiate pt = pts[0].forall_elim(s) if pt.prop.beta_norm() != pt.prop: pt = pt.on_prop(beta_norm_conv()) return pt
def get_proof_term(self, args, pts): if not self.with_inst: assert len(pts) >= 2, "apply fact: too few prevs" pt, pt_prevs = pts[0], pts[1:] # First, obtain the patterns new_names = get_forall_names(pt.prop) new_vars, As, C = strip_all_implies(pt.prop, new_names) assert len(pt_prevs) <= len(As), "apply_fact: too many prevs" if self.with_inst: assert len(args) == len(new_names), "apply_fact_macro: wrong number of args." inst = Inst({nm: v for nm, v in zip(new_names, args)}) else: inst = Inst() for idx, pt_prev in enumerate(pt_prevs): inst = matcher.first_order_match(As[idx], pt_prev.prop, inst) pt = pt.subst_type(inst.tyinst) for new_var in new_vars: if new_var.name in inst: pt = pt.forall_elim(inst[new_var.name]) else: pt = pt.forall_elim(new_var) if pt.prop.beta_norm() != pt.prop: pt = pt.on_prop(beta_norm_conv()) for prev_pt in pt_prevs: if prev_pt.prop != pt.assums[0]: prev_pt = prev_pt.on_prop(beta_norm_conv()) pt = pt.implies_elim(prev_pt) for new_var in new_vars: if new_var.name not in inst: pt = pt.forall_intr(new_var) return pt
def get_proof_term(self, goal): th = theory.get_theorem(self.th_name) try: inst = matcher.first_order_match(th.concl, goal.prop, self.inst) except matcher.MatchException: raise TacticException('rule: matching failed') if any(v.name not in inst for v in th.prop.get_svars()): raise TacticException('rule: not all variables are matched') pt = ProofTerm.theorem(self.th_name).substitution(inst).on_prop( beta_norm_conv()) for assum in pt.assums: pt = pt.implies_elim(ProofTerm.sorry(Thm(goal.hyps, assum))) return pt
def vcg_norm(T, goal): """Compute vcg, then normalize the result into the form A_1 --> A_2 --> ... --> A_n --> Valid P c Q, where A_i are the normalized verification conditions. """ pt = vcg(T, goal) for A in reversed(pt.hyps): pt = pt.implies_intr(A) # Normalize each of the assumptions return pt.on_prop(assums_conv(rewr_conv("Entail_def")), assums_conv(beta_norm_conv()), assums_conv(top_conv(function.fun_upd_eval_conv())))
def get_proof_term(self, args, pts): assert isinstance(args, str), "rewrite_fact_macro: signature" th_name = args eq_pt = ProofTerm.theorem(th_name) assert len(pts) == len(eq_pt.assums) + 1, "rewrite_fact_macro: signature" # Check rewriting using the theorem has an effect if not has_rewrite(th_name, pts[0].prop, sym=self.sym, conds=pts[1:]): raise InvalidDerivationException("rewrite_fact using %s" % th_name) cv = then_conv(top_sweep_conv(rewr_conv(eq_pt, sym=self.sym, conds=pts[1:])), beta_norm_conv()) res = pts[0].on_prop(cv) if res == pts[0]: raise InvalidDerivationException("rewrite_fact using %s" % th_name) return res
def get_proof_term(self, goal, *, args=None, prevs=None): assert isinstance(prevs, list) and len(prevs) >= 1, "apply_prev" pt, prev_pts = prevs[0], prevs[1:] # First, obtain the patterns new_names = logic.get_forall_names(pt.prop) new_vars, As, C = logic.strip_all_implies(pt.prop, new_names) assert len(prev_pts) <= len(As), "apply_prev: too many prev_pts" if args is None: inst = Inst() else: inst = args inst = matcher.first_order_match(C, goal.prop, inst) for idx, prev_pt in enumerate(prev_pts): inst = matcher.first_order_match(As[idx], prev_pt.prop, inst) unmatched_vars = [v for v in new_names if v not in inst] if unmatched_vars: raise theory.ParameterQueryException( list("param_" + name for name in unmatched_vars)) pt = pt.subst_type(inst.tyinst) for new_name in new_names: pt = pt.forall_elim(inst[new_name]) if pt.prop.beta_norm() != pt.prop: pt = pt.on_prop(beta_norm_conv()) inst_As, inst_C = pt.prop.strip_implies() inst_arg = [inst[new_name] for new_name in new_names] new_goals = [ ProofTerm.sorry(Thm(goal.hyps, A)) for A in inst_As[len(prev_pts):] ] if set(new_names).issubset({v.name for v in term.get_vars(As)}) and \ matcher.is_pattern_list(As, []): return ProofTerm('apply_fact', args=None, prevs=prevs + new_goals) else: return ProofTerm('apply_fact_for', args=inst_arg, prevs=prevs + new_goals)
def get_proof_term(self, args, pts): assert len(pts) == 2, "rewrite_fact_with_prev" eq_pt, pt = pts # In general, we assume eq_pt has forall quantification # First, obtain the patterns new_names = get_forall_names(eq_pt.prop) new_vars, eq_As, eq_C = strip_all_implies(eq_pt.prop, new_names) # First fact must be an equality assert len(eq_As) == 0 and eq_C.is_equals(), "rewrite_fact_with_prev" for new_var in new_vars: eq_pt = eq_pt.forall_elim(new_var) # Check rewriting using eq_pt has an effect cv1 = top_sweep_conv(rewr_conv(eq_pt)) assert not cv1.eval(pt.prop).is_reflexive(), "rewrite_fact_with_prev" cv = then_conv(cv1, beta_norm_conv()) return pt.on_prop(cv)
def get_proof_term(self, args, pts): assert isinstance(args, tuple) and len(args) == 2 and \ isinstance(args[0], str) and isinstance(args[1], Term), "rewrite_goal: signature" name, goal = args eq_pt = ProofTerm.theorem(name) if len(pts) == len(eq_pt.assums): rewr_cv = rewr_conv(eq_pt, sym=self.sym, conds=pts) else: assert len(pts) == len(eq_pt.assums) + 1, "rewrite_goal: wrong number of prevs" rewr_cv = rewr_conv(eq_pt, sym=self.sym, conds=pts[1:]) cv = then_conv(top_sweep_conv(rewr_cv), beta_norm_conv()) pt = cv.get_proof_term(goal) # goal = th.prop pt = pt.symmetric() # th.prop = goal if pt.prop.lhs.is_equals() and pt.prop.lhs.lhs == pt.prop.lhs.rhs: pt = pt.equal_elim(refl(pt.prop.lhs.lhs)) else: pt = pt.equal_elim(pts[0]) # goal return pt
def get_proof_term(self, args, pts): assert args is None, "beta_norm_macro" return pts[0].on_prop(beta_norm_conv())
def eval(self, args, ths): assert args is None, "beta_norm_macro" eq_th = beta_norm_conv().eval(ths[0].prop) return Thm(ths[0].hyps, eq_th.prop.arg)