diff --git a/src/cmd_context/interpolant_cmds.cpp b/src/cmd_context/interpolant_cmds.cpp index 3add76030..c482b4d09 100644 --- a/src/cmd_context/interpolant_cmds.cpp +++ b/src/cmd_context/interpolant_cmds.cpp @@ -206,17 +206,13 @@ static expr *make_tree(cmd_context & ctx, const ptr_vector &exprs){ } static void get_interpolant(cmd_context & ctx, const ptr_vector &exprs, params_ref &m_params) { - expr *foo = make_tree(ctx,exprs); - ctx.m().inc_ref(foo); - get_interpolant(ctx,foo,m_params); - ctx.m().dec_ref(foo); + expr_ref foo(make_tree(ctx, exprs),ctx.m()); + get_interpolant(ctx,foo.get(),m_params); } static void compute_interpolant(cmd_context & ctx, const ptr_vector &exprs, params_ref &m_params) { - expr *foo = make_tree(ctx, exprs); - ctx.m().inc_ref(foo); - compute_interpolant_and_maybe_check(ctx,foo,m_params,false); - ctx.m().dec_ref(foo); + expr_ref foo(make_tree(ctx, exprs),ctx.m()); + compute_interpolant_and_maybe_check(ctx,foo.get(),m_params,false); } diff --git a/src/duality/duality_wrapper.cpp b/src/duality/duality_wrapper.cpp index dc509d809..3b29adc41 100755 --- a/src/duality/duality_wrapper.cpp +++ b/src/duality/duality_wrapper.cpp @@ -562,7 +562,14 @@ namespace Duality { opts.set("weak","1"); ::ast *proof = m_solver->get_proof(); - iz3interpolate(m(),proof,_assumptions,_parents,_interpolants,_theory,&opts); + try { + iz3interpolate(m(),proof,_assumptions,_parents,_interpolants,_theory,&opts); + } + // If there's an interpolation bug, throw a char * + // exception so duality can catch it and restart. + catch (const interpolation_failure &f) { + throw f.msg(); + } std::vector linearized_interpolants(_interpolants.size()); for(unsigned i = 0; i < _interpolants.size(); i++) diff --git a/src/interp/iz3interp.cpp b/src/interp/iz3interp.cpp index 810afb103..00bc5111a 100755 --- a/src/interp/iz3interp.cpp +++ b/src/interp/iz3interp.cpp @@ -271,7 +271,18 @@ public: // translate into an interpolatable proof profiling::timer_start("Proof translation"); - tr->translate(proof,pf); + try { + tr->translate(proof,pf); + } + catch (const char *msg) { + throw interpolation_failure(msg); + } + catch (const iz3translation::unsupported &) { + throw interpolation_error(); + } + catch (const iz3proof::proof_error &) { + throw interpolation_error(); + } profiling::timer_stop("Proof translation"); // translate the proof into interpolants @@ -309,7 +320,18 @@ public: // translate into an interpolatable proof profiling::timer_start("Proof translation"); - tr->translate(proof,pf); + try { + tr->translate(proof,pf); + } + catch (const char *msg) { + throw interpolation_failure(msg); + } + catch (const iz3translation::unsupported &) { + throw interpolation_error(); + } + catch (const iz3proof::proof_error &) { + throw interpolation_error(); + } profiling::timer_stop("Proof translation"); // translate the proof into interpolants diff --git a/src/interp/iz3interp.h b/src/interp/iz3interp.h index c2668eb56..368c2c25e 100644 --- a/src/interp/iz3interp.h +++ b/src/interp/iz3interp.h @@ -43,6 +43,27 @@ struct iz3_bad_tree { struct iz3_incompleteness { }; +// This is thrown if there is some bug in the +// interpolation procedure +class interpolation_failure : public default_exception { + public: + interpolation_failure(const char *msg) + : default_exception(msg) + { + } +}; + +// This is thrown if we cannot derive an interpolant from a proof +// because it contains unsupported theories or if the proof contains +// errors +class interpolation_error : public default_exception { + public: + interpolation_error() + : default_exception("theory not supported by interpolation or bad proof" ) + { + } +}; + typedef interpolation_options_struct *interpolation_options; /* Compute an interpolant from a proof. This version uses the parents vector diff --git a/src/interp/iz3translate.cpp b/src/interp/iz3translate.cpp index 3620f0ad1..ffc17d43e 100755 --- a/src/interp/iz3translate.cpp +++ b/src/interp/iz3translate.cpp @@ -2041,11 +2041,23 @@ public: locality.clear(); #endif iproof = iz3proof_itp::create(this,range_downward(i),weak_mode()); - Iproof::node ipf = translate_main(proof); - ast itp = iproof->interpolate(ipf); - itps.push_back(itp); - delete iproof; - clear_translation(); + try { + Iproof::node ipf = translate_main(proof); + ast itp = iproof->interpolate(ipf); + itps.push_back(itp); + delete iproof; + clear_translation(); + } + catch (const iz3proof_itp::proof_error &) { + delete iproof; + clear_translation(); + throw iz3proof::proof_error(); + } + catch (const unsupported &exc) { + delete iproof; + clear_translation(); + throw exc; + } } // Very simple proof -- lemma of the empty clause with computed interpolation iz3proof::node Ipf = dst.make_lemma(std::vector(),itps); // builds result in dst