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 vcg_solve(goal): """Compute the verification conditions for a hoare triple, then solves the verification conditions using SMT. """ assert goal.is_comb("Valid", 3), "vcg_solve" P, c, Q = goal.args T = Q.get_type().domain_type() pt = vcg_norm(T, goal) vc_pt = [ProofTerm("z3", vc, []) for vc in pt.assums] return ProofTerm("vcg", goal, vc_pt)
def get_proof_term(self, tm): if not tm.is_equals() or not int_eval(tm.lhs) != 0 or not int_eval( tm.rhs) == 0: raise ConvException(str(tm)) lhs_value = int_eval(tm.lhs) if lhs_value > 0: premise_pt = ProofTerm("int_const_ineq", greater(IntType)(Int(lhs_value), Int(0))) return apply_theorem("int_pos_neq_zero", premise_pt) else: premise_pt = ProofTerm("int_const_ineq", less(IntType)(Int(lhs_value), Int(0))) return apply_theorem("int_neg_neq_zero", premise_pt)
def get_proof_term(self, t): if t.get_type() != RealType: return refl(t) simp_t = Real(real_eval(t)) if simp_t == t: return refl(t) return ProofTerm('real_eval', Eq(t, simp_t))
def handle_leq_stage2(self, pt_upper_bound, pts, delta): # get ⊢ x_i ≤ -δ, for i = 1...n leq_pt = [] pt_b = pt_upper_bound for i in range(len(pts)): if i != len(pts) - 1: pt = logic.apply_theorem("both_leq_max", pt_b) pt_1, pt_2 = logic.apply_theorem("conjD1", pt), logic.apply_theorem( "conjD2", pt) else: pt_2 = pt_b ineq = pt_2.prop if ineq.arg1.is_minus() and ineq.arg1.arg.is_number(): num = ineq.arg1.arg expr = less_eq(ineq.arg1.arg1, num - delta) else: expr = less_eq(ineq.arg1, Real(0) - delta) pt_eq_comp = ProofTerm("real_eq_comparison", Eq(ineq, expr)) leq_pt.insert(0, pt_2.on_prop(replace_conv(pt_eq_comp))) if i != len(pts) - 1: pt_b = pt_1 return leq_pt
def handle_geq_stage2(self, pt_lower_bound, pts, delta): # get ⊢ x_i ≥ δ, i = 1...n geq_pt = [] pt_a = pt_lower_bound d = set() for i in range(len(pts)): if i != len(pts) - 1: pt = logic.apply_theorem("both_geq_min", pt_a) pt_1, pt_2 = logic.apply_theorem("conjD1", pt), logic.apply_theorem( "conjD2", pt) else: pt_2 = pt_a ineq = pt_2.prop if ineq.arg1.is_minus() and ineq.arg1.arg.is_number(): # move all constant term from left to right in pt_2's prop num = ineq.arg1.arg expr = greater_eq(ineq.arg1.arg1, num + delta) else: expr = greater_eq(ineq.arg1, Real(0) + delta) pt_eq_comp = ProofTerm("real_eq_comparison", Eq(ineq, expr)) geq_pt.insert(0, pt_2.on_prop(replace_conv(pt_eq_comp))) if i != len(pts) - 1: pt_a = pt_1 return geq_pt
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, prevs=None): elems = goal.strip_disj() disjs = [tm.arg for tm in elems[:-1]] disj_pts = [ProofTerm.assume(disj) for disj in disjs] pt0 = disj_pts[0] for pt1 in disj_pts[1:]: if pt1.lhs == pt0.rhs: pt0 = pt0.transitive(pt1) elif pt1.lhs == pt0.lhs: pt0 = pt0.symmetric().transitive(pt1) elif pt1.rhs == pt0.lhs: pt0 = pt0.symmetric().transitive(pt1.symmetric()) elif pt1.rhs == pt0.rhs: pt0 = pt0.transitive(pt1.symmetric()) else: print(pt0.prop) print(pt1.prop) raise NotImplementedError if pt0.symmetric().prop == elems[-1]: pt0 = pt0.symmetric() assert pt0.prop == elems[-1], "%s \n %s" % (str( pt0.prop), str(goal.strip_disj()[-1])) return ProofTerm("imp_to_or", elems[:-1] + [goal], prevs=[pt0])
def get_proof_term(self, t): if t.get_type() != IntType: return refl(t) simp_t = Int(int_eval(t)) if simp_t == t: return refl(t) else: return ProofTerm('int_eval', Eq(t, int_eval(t)))
def get_proof_term(self, prevs): p1, p2 = prevs lhs_triple = collect_int_polynomial_coeff(p1.arg1) rhs_triple = collect_int_polynomial_coeff(p2.arg1) lhs_singleton = [(p[1], p[2]) for p in lhs_triple] rhs_singleton = [(p[1], p[2]) for p in rhs_triple] if lhs_singleton != rhs_singleton or len(lhs_singleton) != len( rhs_singleton): raise NotImplementedError lhs_coeff = [p[0] for p in lhs_triple] rhs_coeff = [p[0] for p in rhs_triple] ratios = [p1 / p2 for p1, p2 in zip(lhs_coeff, rhs_coeff)] if len(set(ratios)) != 1: raise NotImplementedError lhs_mul = int(rhs_coeff[0] / gcd(lhs_coeff[0], rhs_coeff[0])) rhs_mul = int(lhs_coeff[0] / gcd(lhs_coeff[0], rhs_coeff[0])) if lhs_mul > 0: pt_lhs_mul = ProofTerm('int_const_ineq', greater(IntType)(Int(lhs_mul), Int(0))) if lhs_mul < 0: pt_lhs_mul = ProofTerm('int_const_ineq', less(IntType)(Int(lhs_mul), Int(0))) if rhs_mul > 0: pt_rhs_mul = ProofTerm('int_const_ineq', greater(IntType)(Int(rhs_mul), Int(0))) if rhs_mul < 0: pt_rhs_mul = ProofTerm('int_const_ineq', less(IntType)(Int(rhs_mul), Int(0))) pt_lhs_mul = int_ineq_mul_const_macro().get_proof_term(pt_lhs_mul, p1) pt_rhs_mul = int_ineq_mul_const_macro().get_proof_term(pt_rhs_mul, p2) # normalize both sides pt_lhs_mul_norm = pt_lhs_mul.transitive(norm_eq().get_proof_term( pt_lhs_mul.prop.rhs)) pt_rhs_mul_norm = pt_rhs_mul.transitive(norm_eq().get_proof_term( pt_rhs_mul.prop.rhs)) return pt_lhs_mul_norm.transitive(pt_rhs_mul_norm.symmetric())
def get_proof_term(self, t): eq_t = norm(t, self.conds) if t == eq_t.rhs: return refl(t) else: return ProofTerm('auto', args=eq_t.prop, prevs=self.conds, th=eq_t.th)
def get_proof_term(self, tm): if not ((tm.is_compares() or tm.is_equals()) and \ tm.arg1.is_constant() and tm.arg.is_constant()): return refl(tm) pt = ProofTerm("int_const_ineq", tm) if pt.prop.is_not(): return pt.on_prop(rewr_conv("eq_false")) else: return pt.on_prop(rewr_conv("eq_true"))
def get_proof_term(self, goal, args, prevs): assert isinstance(args, str) and len(prevs) == 1, "resolve: type" th_name = args th = theory.get_theorem(th_name) assert th.prop.is_not(), "resolve: prop is not a negation" # Checking that the theorem matches the fact is done here. return ProofTerm('resolve_theorem', (args, goal.prop), prevs)
def sympy_solve(goal, pts): if pts is None: pts = [] macro = SymPyMacro() if macro.can_eval(goal, pts): th = Thm(sum([th.hyps for th in pts], ()), goal) return ProofTerm('sympy', args=goal, prevs=pts, th=th) else: raise TacticException
def get_proof_term(self, goal, prevs=None): """{(not (= x_1 y_1)) ... (not (= x_n y_n)) (not (p x_1 ... x_n)) (p y_1 ... y_n)} Special case: (not (= x y)) (not (p x y)) (p y x) """ elems = goal.strip_disj() preds, pred_fun, concl = elems[:-2], elems[-2], elems[-1] if pred_fun.is_not(): args_pair = [(i, j) for i, j in zip(pred_fun.arg.strip_comb()[1], concl.strip_comb()[1])] else: args_pair = [(i, j) for i, j in zip(pred_fun.strip_comb()[1], concl.arg.strip_comb()[1])] if len(preds) > 1: preds_pair = [(i.arg.lhs, i.arg.rhs) for i in preds] else: preds_pair = [(preds[0].arg.lhs, preds[0].arg.rhs), (preds[0].arg.lhs, preds[0].arg.rhs)] if pred_fun.is_not(): fun = concl.head else: fun = pred_fun.head pt0 = ProofTerm.reflexive(fun) pt_args_assms = [] for arg, pred in zip(args_pair, preds_pair): if arg == pred: pt_args_assms.append(ProofTerm.assume(Eq(pred[0], pred[1]))) elif arg[0] == pred[1] and pred[0] == arg[1]: pt_args_assms.append( ProofTerm.assume(Eq(pred[0], pred[1])).symmetric()) else: raise NotImplementedError pt1 = functools.reduce(lambda x, y: x.combination(y), pt_args_assms, pt0) if pred_fun.is_not(): pt2 = logic.apply_theorem("eq_implies1", pt1).implies_elim( ProofTerm.assume(pred_fun.arg)) return ProofTerm("imp_to_or", elems[:-1] + [goal], prevs=[pt2]) else: pt2 = pt1.on_prop(conv.rewr_conv("neg_iff_both_sides")) pt3 = logic.apply_theorem("eq_implies1", pt2).implies_elim( ProofTerm.assume(Not(pred_fun))) return ProofTerm("imp_to_or", elems[:-1] + [goal], prevs=[pt3])
def get_proof_term(self, goal, *, args=None, prevs=None): assert isinstance(goal, Thm), "MacroTactic" if prevs is None: prevs = [] if args is None: args = goal.prop else: args = (goal.prop, ) + args return ProofTerm(self.macro, args, prevs)
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 apply_theorem(th_name, *pts, concl=None, inst=None): """Wrapper for apply_theorem and apply_theorem_for macros. The function takes optional arguments concl, inst. Matching always starts with inst. If conclusion is specified, it is matched next. Finally, the assumptions are matched. """ typecheck.checkinstance('apply_theorem', pts, [ProofTerm]) if concl is None and inst is None: # Normal case, can use apply_theorem return ProofTerm("apply_theorem", th_name, pts) else: pt = ProofTerm.theorem(th_name) if inst is None: inst = Inst() if concl is not None: inst = matcher.first_order_match(pt.concl, concl, inst) for i, prev in enumerate(pts): inst = matcher.first_order_match(pt.assums[i], prev.prop, inst) return ProofTerm("apply_theorem_for", (th_name, inst), pts)
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, *, 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 combine_mem_bounds(pt1, pt2): """Given two inequalities of the form x </<= a and b </<= y, where a and b are constants, attempt to form the theorem x </<= y. """ assert pt1.prop.is_less_eq() or pt1.prop.is_less(), "combine_mem_bounds" assert pt2.prop.is_less_eq() or pt2.prop.is_less(), "combine_mem_bounds" x, a = pt1.prop.args b, y = pt2.prop.args # First obtain the comparison between a and b if eval_hol_expr(a) < eval_hol_expr(b): pt_ab = ProofTerm('const_inequality', real.less(a, b)) elif eval_hol_expr(a) <= eval_hol_expr(b): pt_ab = ProofTerm('const_inequality', real.less_eq(a, b)) else: raise TacticException # Next, successively combine the inequalities pt = inequality_trans(inequality_trans(pt1, pt_ab), pt2) return pt
def get_proof_term(self, args, pts): # First, find the pair i, j such that B_j = ~A_i or A_i = ~B_j, the # variable side records the side of the positive literal. pt1, pt2 = pts disj1 = strip_num(pt1.prop, args[0]) disj2 = strip_num(pt2.prop, args[1]) side = None for i, t1 in enumerate(disj1): for j, t2 in enumerate(disj2): if t2 == Not(t1): side = 'left' break elif t1 == Not(t2): side = 'right' break if side is not None: break assert side is not None, "resolution: literal not found" # If side is wrong, just swap: if side == 'right': return self.get_proof_term([args[1], args[0]], [pt2, pt1]) # Move items i and j to the front disj1 = [disj1[i]] + disj1[:i] + disj1[i + 1:] disj2 = [disj2[j]] + disj2[:j] + disj2[j + 1:] eq_pt1 = logic.imp_disj_iff(Eq(pt1.prop, Or(*disj1))) eq_pt2 = logic.imp_disj_iff(Eq(pt2.prop, Or(*disj2))) pt1 = eq_pt1.equal_elim(pt1) pt2 = eq_pt2.equal_elim(pt2) if len(disj1) > 1 and len(disj2) > 1: pt = logic.apply_theorem('resolution', pt1, pt2) elif len(disj1) > 1 and len(disj2) == 1: pt = logic.apply_theorem('resolution_left', pt1, pt2) elif len(disj1) == 1 and len(disj2) > 1: pt = logic.apply_theorem('resolution_right', pt1, pt2) else: pt = logic.apply_theorem('negE', pt2, pt1) # return pt.on_prop(disj_norm()) disj_new = set(disj1[1:] + disj2[1:]) # eq_pt_norm = logic.imp_disj_iff(Eq(pt.prop, Or(*disj_new))) implies_pt_norm = ProofTerm("imp_disj", Implies(pt.prop, Or(*disj_new))) pt_final = implies_pt_norm.implies_elim(pt) self.arity = len(disj_new) return pt_final.on_prop(conv.top_conv(conv.rewr_conv("double_neg")))
def handle_geq_stage1(self, pts): if not pts: return None, None, None # ⊢ min(min(...(min(x_1, x_2), x_3)...), x_n-1), x_n) > 0 min_pos_pt = functools.reduce( lambda pt1, pt2: logic.apply_theorem("min_greater_0", pt1, pt2), pts[1:], pts[0]) # ⊢ 0 < 2 two_pos_pt = ProofTerm("real_compare", Real(0) < Real(2)) # ⊢ min(...) / 2 > 0 min_divides_two_pos = logic.apply_theorem( "real_lt_div", min_pos_pt.on_prop(rewr_conv("real_ge_to_le")), two_pos_pt).on_prop(rewr_conv("real_ge_to_le", sym=True)) # ⊢ 2 ≥ 1 two_larger_one = ProofTerm("real_compare", Real(2) >= Real(1)) # ⊢ min(...) ≥ min(...) / 2 larger_half_pt = logic.apply_theorem("real_divides_larger_1", two_larger_one, min_pos_pt) # ⊢ min(...) / 2 = δ_1 delta_1 = Var("δ_1", RealType) pt_delta1_eq = ProofTerm.assume(Eq(larger_half_pt.prop.arg, delta_1)) # ⊢ min(...) ≥ δ_1 larger_half_pt_delta = larger_half_pt.on_prop( top_conv(replace_conv(pt_delta1_eq))) # ⊢ δ_1 > 0 delta_1_pos = min_divides_two_pos.on_prop( arg1_conv(replace_conv(pt_delta1_eq))) return larger_half_pt_delta, delta_1_pos, pt_delta1_eq
def handle_leq_stage1(self, pts): if not pts: return None, None, None # ⊢ max(max(...(max(x_1, x_2), x_3)...), x_n-1), x_n) < 0 max_pos_pt = functools.reduce( lambda pt1, pt2: logic.apply_theorem("max_less_0", pt1, pt2), pts[1:], pts[0]) # ⊢ 0 < 2 two_pos_pt = ProofTerm("real_compare", Real(2) > Real(0)) # ⊢ max(...) / 2 < 0 max_divides_two_pos = logic.apply_theorem("real_neg_div_pos", max_pos_pt, two_pos_pt) # ⊢ 2 ≥ 1 two_larger_one = ProofTerm("real_compare", Real(2) >= Real(1)) # ⊢ max(...) ≤ max(...) / 2 less_half_pt = logic.apply_theorem("real_neg_divides_larger_1", two_larger_one, max_pos_pt) # ⊢ max(...) / 2 = -δ delta_2 = Var("δ_2", RealType) pt_delta_eq = ProofTerm.assume(Eq(less_half_pt.prop.arg, -delta_2)) # ⊢ δ > 0 delta_pos_pt = max_divides_two_pos.on_prop( rewr_conv("real_le_gt"), top_conv(replace_conv(pt_delta_eq)), auto.auto_conv()) # max(...) ≤ -δ less_half_pt_delta = less_half_pt.on_prop( arg_conv(replace_conv(pt_delta_eq))) return less_half_pt_delta, delta_pos_pt, pt_delta_eq
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 get_proof_term(self, t): if not t.is_compares(): raise ConvException('%s is not a comparison.' % str(t)) pt = refl(t) pt_norm_form = pt.on_rhs(norm_eq(), arg1_conv(omega_simp_full_conv())) summands = strip_plus(pt_norm_form.rhs.arg1) coeffs = [ int_eval(s.arg1) if not s.is_number() else int_eval(s) for s in summands ] g = functools.reduce(gcd, coeffs) if g <= 1: return pt vars = [s.arg for s in summands if not s.is_number()] elim_gcd_coeffs = [int(i / g) for i in coeffs] if len(vars) < len(coeffs): simp_t = sum([ coeff * v for coeff, v in zip(elim_gcd_coeffs[1:-1], vars[1:]) ], elim_gcd_coeffs[0] * vars[0]) + Int(elim_gcd_coeffs[-1]) else: simp_t = sum( [coeff * v for coeff, v in zip(elim_gcd_coeffs[1:], vars[1:])], elim_gcd_coeffs[0] * vars[0]) simp_t_times_gcd = Int(g) * simp_t pt_simp_t_times_gcd = refl(simp_t_times_gcd).on_rhs( omega_simp_full_conv()).symmetric() pt_c = ProofTerm('int_const_ineq', greater(IntType)(Int(g), Int(0))) if t.is_less(): gcd_pt = ProofTerm.theorem('int_simp_less') elif t.is_less_eq(): gcd_pt = ProofTerm.theorem('int_simp_leq') elif t.is_greater(): gcd_pt = ProofTerm.theorem('int_simp_gt') elif t.is_greater_eq(): gcd_pt = ProofTerm.theorem('int_simp_geq') inst1 = matcher.first_order_match(gcd_pt.prop.arg1, pt_c.prop) inst2 = matcher.first_order_match(gcd_pt.prop.arg.rhs.arg1, simp_t, inst=inst1) pt_simp = gcd_pt.substitution(inst2).implies_elim(pt_c).on_lhs( arg1_conv(omega_simp_full_conv())) return pt_norm_form.transitive(pt_simp).on_rhs(omega_form_conv())
def process_file(input, output): basic.load_theory('hoare') dn = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(dn, 'examples/' + input + '.json'), encoding='utf-8') as a: data = json.load(a) output = json_output.JSONTheory(output, ["hoare"], "Generated from " + input) content = data['content'] eval_count = 0 vcg_count = 0 for run in content[:5]: if run['ty'] == 'eval': com = parse_com(run['com']) st1 = mk_const_fun(NatType, nat.zero) for k, v in sorted(run['init'].items()): st1 = mk_fun_upd(st1, Nat(str_to_nat(k)), Nat(v)) st2 = mk_const_fun(NatType, nat.zero) for k, v in sorted(run['final'].items()): st2 = mk_fun_upd(st2, Nat(str_to_nat(k)), Nat(v)) Sem = imp.Sem(natFunT) goal = Sem(com, st1, st2) prf = ProofTerm("eval_Sem", goal, []).export() rpt = ProofReport() th = theory.check_proof(prf, rpt) output.add_theorem("eval" + str(eval_count), th, prf) eval_count += 1 elif run['ty'] == 'vcg': com = parse_com(run['com']) pre = Lambda(st, parse_cond(run['pre'])) post = Lambda(st, parse_cond(run['post'])) Valid = imp.Valid(natFunT) goal = Valid(pre, com, post) prf = imp.vcg_solve(goal).export() rpt = ProofReport() th = theory.check_proof(prf, rpt) output.add_theorem("vcg" + str(vcg_count), th, prf) vcg_count += 1 else: raise TypeError output.export_json()
def get_proof_term(self, goal, prevs=None): elems = goal.strip_disj() preds, concl = elems[:-1], elems[-1] args_pair = [(i, j) for i, j in zip(concl.lhs.strip_comb()[1], concl.rhs.strip_comb()[1])] preds_pair = [(i.arg.lhs, i.arg.rhs) for i in preds] fun = concl.lhs.head pt0 = ProofTerm.reflexive(fun) pt_args_assms = [] for pair in args_pair: r_pair = pair[::-1] if pair in args_pair: pt_args_assms.append(ProofTerm.assume(Eq(*pair))) elif r_pair in args_pair: pt_args_assms.append(ProofTerm.assume(Eq(*r_pair))) pt1 = functools.reduce(lambda x, y: x.combination(y), pt_args_assms, pt0) return ProofTerm("imp_to_or", elems[:-1] + [goal], prevs=[pt1])
def inequality_solve(goal, pts): if pts is None: pts = [] if len(pts) == 0: macro = ConstInequalityMacro() if macro.can_eval(goal, pts): th = macro.eval(goal, pts) return ProofTerm('const_inequality', args=goal, prevs=pts, th=th) else: raise TacticException elif len(pts) == 1: macro = IntervalInequalityMacro() try: return macro.get_proof_term(goal, pts) except ConvException: raise TacticException else: raise TacticException else: raise TacticException
def auto_solve(t, pts=None): return ProofTerm('auto', args=t, prevs=pts)