proof *mk_lemma_core(proof *pf, expr *fact) { ptr_buffer<expr> args; expr_ref lemma(m); if (m.is_or(fact)) { for (unsigned i = 0, sz = to_app(fact)->get_num_args(); i < sz; ++i) { expr *a = to_app(fact)->get_arg(i); if (!is_reduced(a)) { args.push_back(a); } } } else if (!is_reduced(fact)) { args.push_back(fact); } if (args.size() == 0) { return pf; } else if (args.size() == 1) { lemma = args.get(0); } else { lemma = m.mk_or(args.size(), args.c_ptr()); } proof* res = m.mk_lemma(pf, lemma); m_pinned.push_back(res); if (m_hyps.contains(lemma)) { m_units.insert(lemma, res); } return res; }
auto step(_Red r, _Input&& i) { using brf = typename toolbox::template base_reducing_function<_Rf>; using result_t = typename brf::template result_type<_Red, _Input>; result_t reduction = brf::m_rf.step(r, std::forward<_Input>(i)); if (is_reduced(reduction)) { return reduction; } return brf::m_rf.step(reduction, m_insertion); }
// Determine if a sequent of this form: // // A1, A2, ..., An |- C // // denotes a valid proof. // // The proof is valid if any Ai proves C. The proof is invalid when // no Ai proves C. The proof is incomplete when it is invalid by // some Ai is non-atomic. // // TODO: I wonder if there's an opportunity to quickly reject a // proof with non-reduced antecedents. That would avoid multiple // (potentially) exponential invocations of derive(), but it would // also likely lead to more aggressive creation of goals. Validation check_term(Proof& p, Prop_list& ants, Cons const& c) { // If antecedent set (syntacically) contains C, then the // proof is valid. if (ants.contains(c)) return valid_proof; // FIXME: Memoization? // Actually derive a proof of C from AS. If the result // is invalid, by the thre are incomplete terms, then // the result is incomplete. Validation v = find_support(p, ants, c); if (v == invalid_proof) { if (!is_reduced(ants)) return incomplete_proof; } return v; }
auto recursive_step(Re&& reduction, In&& input, Rdr & reducer, Rest&... rest) { using first_result_type = decltype(reducer.step(reduction, input)); using rest_result_type = decltype(recursive_step(reduction, std::forward<In>(input), rest...)); using result_type = typename std::conditional< is_reduction_wrapper<first_result_type>::value || is_reduction_wrapper<rest_result_type>::value, wrapped_t<first_result_type>, first_result_type>::type; result_type _result = reduction; // do not forward input to step function because it can't // be consumed until the final reducer gets its hands on it _result = reducer.step(_result, input); if (is_reduced(_result)) { return _result; } return recursive_step(std::move(_result), std::forward<In>(input), rest...); }