mirror of
https://github.com/Z3Prover/z3
synced 2025-07-17 18:06:40 +00:00
137 lines
4.1 KiB
C++
137 lines
4.1 KiB
C++
/*++
|
|
Copyright (c) 2011 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
proof_converter.cpp
|
|
|
|
Abstract:
|
|
|
|
Abstract interface for converting proofs, and basic combinators
|
|
|
|
Author:
|
|
|
|
Leonardo (leonardo) 2011-11-14
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
#include "tactic/proof_converter.h"
|
|
#include "tactic/goal.h"
|
|
#include "ast/ast_smt2_pp.h"
|
|
|
|
class concat_proof_converter : public concat_converter<proof_converter> {
|
|
public:
|
|
concat_proof_converter(proof_converter * pc1, proof_converter * pc2):concat_converter<proof_converter>(pc1, pc2) {}
|
|
|
|
char const * get_name() const override { return "concat-proof-converter"; }
|
|
|
|
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
|
|
proof_ref tmp(m);
|
|
tmp = this->m_c2->operator()(m, num_source, source);
|
|
proof * new_source = tmp.get();
|
|
return this->m_c1->operator()(m, 1, &new_source);
|
|
}
|
|
|
|
proof_converter * translate(ast_translation & translator) override {
|
|
return this->translate_core<concat_proof_converter>(translator);
|
|
}
|
|
};
|
|
|
|
proof_converter * concat(proof_converter * pc1, proof_converter * pc2) {
|
|
if (pc1 == nullptr)
|
|
return pc2;
|
|
if (pc2 == nullptr)
|
|
return pc1;
|
|
return alloc(concat_proof_converter, pc1, pc2);
|
|
}
|
|
|
|
class subgoal_proof_converter : public proof_converter {
|
|
proof_converter_ref m_pc;
|
|
goal_ref_buffer m_goals;
|
|
public:
|
|
subgoal_proof_converter(proof_converter* pc, unsigned n, goal * const* goals):
|
|
m_pc(pc)
|
|
{
|
|
for (unsigned i = 0; i < n; ++i) m_goals.push_back(goals[i]);
|
|
}
|
|
|
|
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
|
|
// ignore the proofs from the arguments, instead obtain the proofs fromt he subgoals.
|
|
SASSERT(num_source == 0);
|
|
proof_converter_ref_buffer pc_buffer;
|
|
for (goal_ref g : m_goals) {
|
|
pc_buffer.push_back(g->pc());
|
|
|
|
}
|
|
return apply(m, m_pc, pc_buffer);
|
|
}
|
|
|
|
proof_converter* translate(ast_translation& tr) override {
|
|
proof_converter_ref pc1 = m_pc->translate(tr);
|
|
goal_ref_buffer goals;
|
|
for (goal_ref g : m_goals) goals.push_back(g->translate(tr));
|
|
return alloc(subgoal_proof_converter, pc1.get(), goals.size(), goals.data());
|
|
}
|
|
|
|
void display(std::ostream& out) override {}
|
|
|
|
};
|
|
|
|
proof_converter * concat(proof_converter *pc, unsigned n, goal* const* goals) {
|
|
return alloc(subgoal_proof_converter, pc, n, goals);
|
|
}
|
|
|
|
class proof2pc : public proof_converter {
|
|
proof_ref m_pr;
|
|
public:
|
|
proof2pc(ast_manager & m, proof * pr):m_pr(pr, m) {}
|
|
~proof2pc() override {}
|
|
|
|
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
|
|
SASSERT(num_source == 0);
|
|
return m_pr;
|
|
}
|
|
|
|
proof_converter * translate(ast_translation & translator) override {
|
|
return alloc(proof2pc, translator.to(), translator(m_pr.get()));
|
|
}
|
|
|
|
void display(std::ostream & out) override {
|
|
out << "(proof->proof-converter-wrapper\n" << mk_ismt2_pp(m_pr.get(), m_pr.get_manager()) << ")\n";
|
|
}
|
|
};
|
|
|
|
proof_converter * proof2proof_converter(ast_manager & m, proof * pr) {
|
|
if (pr == nullptr)
|
|
return nullptr;
|
|
return alloc(proof2pc, m, pr);
|
|
}
|
|
|
|
void apply(ast_manager & m, proof_converter * pc, proof_ref & pr) {
|
|
if (pc) {
|
|
proof * _pr = pr.get();
|
|
pr = (*pc)(m, 1, &_pr);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Let pc2s be a buffer of proof converters that are wrappers for proofs.
|
|
That is, they are functors of the form: unit -> Proof
|
|
Then, this function applies pc1 to the proofs produced by pc2s's and store
|
|
the resultant proof in result.
|
|
|
|
pc1 and pc2s must be different from 0.
|
|
*/
|
|
proof_ref apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s) {
|
|
SASSERT(pc1);
|
|
proof_ref_buffer prs(m);
|
|
unsigned sz = pc2s.size();
|
|
for (unsigned i = 0; i < sz; i++) {
|
|
proof_ref pr(m);
|
|
SASSERT(pc2s[i]); // proof production is enabled
|
|
pr = pc2s[i]->operator()(m, 0, nullptr);
|
|
prs.push_back(pr);
|
|
}
|
|
return (*pc1)(m, sz, prs.data());
|
|
}
|