def get_proof_term(self, goal, *, args=None, prevs=None): assert isinstance(args, Term), "cases" As = goal.hyps C = goal.prop goal1 = ProofTerm.sorry(Thm(goal.hyps, Implies(args, C))) goal2 = ProofTerm.sorry(Thm(goal.hyps, Implies(Not(args), C))) return apply_theorem('classical_cases', goal1, goal2)
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, *, 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, goal): if not goal.prop.is_forall(): raise TacticException('intro_forall: goal is not forall') v, body = goal.prop.arg.dest_abs(self.var_name) new_goal = ProofTerm.sorry(Thm(goal.hyps, body)) return new_goal.forall_intr(v)
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, goal): if not goal.prop.is_implies(): raise TacticException('intro_imp: goal is not implies.') A, C = goal.prop.args new_goal = ProofTerm.sorry(Thm(list(goal.hyps) + [A], C)) return new_goal.implies_intr(A)
def get_proof_term(self, goal): pt = ProofTerm.sorry(goal) while True: try: pt = pt.tac(self.tac) except TacticException: break return pt
def eval(self, args, prevs): """Obtain the result of applying the macro. Input is the current theory, argument of the proof method, and the list of previous theorems. """ pts = [ProofTerm.sorry(prev) for prev in prevs] return self.get_proof_term(args, pts).th
def get_proof_term(self, goal, *, args=None, prevs=None): if isinstance(args, tuple): th_name, inst = args else: th_name, inst = args, None assert isinstance(th_name, str), "rule: theorem name must be a string" if prevs is None: prevs = [] th = theory.get_theorem(th_name) As, C = th.assums, th.concl # Length of prevs is at most length of As assert len(prevs) <= len(As), "rule: too many previous facts" if inst is None: inst = Inst() # Match the conclusion and assumptions. Either the conclusion # or the list of assumptions must be a first-order pattern. if matcher.is_pattern(C, []): inst = matcher.first_order_match(C, goal.prop, inst) for pat, prev in zip(As, prevs): inst = matcher.first_order_match(pat, prev.prop, inst) else: for pat, prev in zip(As, prevs): inst = matcher.first_order_match(pat, prev.prop, inst) inst = matcher.first_order_match(C, goal.prop, inst) # Check that every variable in the theorem has an instantiation. unmatched_vars = [ v.name for v in term.get_svars(As + [C]) if v.name not in inst ] if unmatched_vars: raise theory.ParameterQueryException( list("param_" + name for name in unmatched_vars)) # Substitute and normalize As, _ = th.prop.subst_norm(inst).strip_implies() goal_Alen = len(goal.assums) if goal_Alen > 0: As = As[:-goal_Alen] pts = prevs + [ ProofTerm.sorry(Thm(goal.hyps, A)) for A in As[len(prevs):] ] # Determine whether it is necessary to provide instantiation # to apply_theorem. if set(term.get_svars(th.assums)) != set(th.prop.get_svars()) or \ set(term.get_stvars(th.assums)) != set(th.prop.get_stvars()) or \ not matcher.is_pattern_list(th.assums, []): return apply_theorem(th_name, *pts, inst=inst) else: return apply_theorem(th_name, *pts)
def get_proof_term(self, goal, args, prevs): assert len(goal.hyps) == 0, "vcg_tactic" assert goal.prop.is_comb("Valid", 3), "vcg_tactic" P, c, Q = goal.prop.args # Obtain the theorem [...] |- Valid P c Q T = Q.get_type().domain_type() pt = vcg_norm(T, goal.prop) ptAs = [ProofTerm.sorry(Thm(goal.hyps, A)) for A in pt.assums] return ProofTerm("vcg", goal.prop, ptAs)
def get_proof_term(self, goal, *, args=None, prevs=None): if args is None: var_names = [] else: var_names = args vars, As, C = logic.strip_all_implies(goal.prop, var_names, svar=False) pt = ProofTerm.sorry(Thm(list(goal.hyps) + As, C)) ptAs = [ProofTerm.assume(A) for A in As] ptVars = [ProofTerm.variable(var.name, var.T) for var in vars] return ProofTerm('intros', None, ptVars + ptAs + [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 testIntro(self): basic.load_theory('logic_base') macro = logic.intros_macro() Ta = TVar('a') x = Var('x', Ta) P = Var('P', TFun(Ta, BoolType)) C = Var('C', BoolType) ex_P = Exists(x, P(x)) pt1 = ProofTerm.assume(ex_P) pt2 = ProofTerm.variable('x', Ta) pt3 = ProofTerm.assume(P(x)) pt4 = ProofTerm.sorry(Thm([P(x)], C)) pt4 = ProofTerm('intros', args=[ex_P], prevs=[pt1, pt2, pt3, pt4]) prf = pt4.export() self.assertEqual(theory.check_proof(prf), Thm([ex_P], C))
def run_test(self, thy_name, tactic, *, vars=None, prevs=None, goal, args=None, new_goals=None, failed=None): """Test a single invocation of a tactic.""" context.set_context(thy_name, vars=vars) assms = [parser.parse_term(prev) for prev in prevs] if prevs is not None else [] prf = Proof(*assms) prevs = [ ProofTerm.atom(i, Thm.assume(assm)) for i, assm in enumerate(assms) ] goal = parser.parse_term(goal) goal_pt = ProofTerm.sorry(Thm(assms, goal)) # Invoke the tactic to get the proof term if failed is not None: self.assertRaises(failed, tactic.get_proof_term, goal_pt, prevs=prevs, args=args) return pt = tactic.get_proof_term(goal_pt, prevs=prevs, args=args) # Export and check proof prefix = ItemID(len(prevs) - 1) if len(prevs) > 0 else ItemID(len(prevs)) prf = pt.export(prefix=prefix, prf=prf, subproof=False) self.assertEqual(theory.check_proof(prf), Thm(assms, goal)) # Test agreement of new goals new_goals = [parser.parse_term(new_goal) for new_goal in new_goals ] if new_goals is not None else [] concls = [goal.prop for goal in prf.get_sorrys()] self.assertEqual(new_goals, concls)
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_proofterm(u, v): """Get proof term corresponding to u = v.""" path = explain[(u, v)] cur_pos = u pt = ProofTerm.reflexive(self.index[u]) for eq in path: # Form the proof term for eq, depending on the two cases. if eq[0] == EQ_CONST: _, a, b = eq if (a, b) in self.pts: eq_pt = self.pts[(a, b)] else: eq_pt = ProofTerm.sorry( Thm([], Eq(self.index[a], self.index[b]))) else: _, ((a1, a2), a), ((b1, b2), b) = eq # We already should have: # - a corresponds to Comb(a1, a2) # - b corresponds to Comb(b1, b2) eq_pt1 = get_proofterm( a1, b1) if a1 != b1 else ProofTerm.reflexive( self.index[a1]) eq_pt2 = get_proofterm( a2, b2) if a2 != b2 else ProofTerm.reflexive( self.index[a2]) eq_pt = eq_pt1.combination(eq_pt2) # Append the equality to the current chain. if a == cur_pos: pt = pt.transitive(eq_pt) cur_pos = b else: assert b == cur_pos pt = pt.transitive(pt, eq_pt.symmetric()) cur_pos = a return pt
def get_proof_term(self, goal): return ProofTerm.sorry(goal).tacs(elim_tac('conjE'), intro_imp_tac(), intro_imp_tac())
def get_proof_term(self, goal): return ProofTerm.sorry(goal).tacs(self.tac1, self.tac2)