mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
working on smt2 and api
This commit is contained in:
parent
2b93537366
commit
78848f3ddd
30 changed files with 1307 additions and 94 deletions
75
src/interp/foci2.h
Executable file
75
src/interp/foci2.h
Executable file
|
@ -0,0 +1,75 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
foci2.h
|
||||
|
||||
Abstract:
|
||||
|
||||
An interface class for foci2.
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef FOCI2_H
|
||||
#define FOCI2_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#define FOCI2_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define FOCI2_EXPORT __attribute__ ((visibility ("default")))
|
||||
#endif
|
||||
|
||||
class foci2 {
|
||||
public:
|
||||
virtual ~foci2(){}
|
||||
|
||||
typedef int ast;
|
||||
typedef int symb;
|
||||
|
||||
/** Built-in operators */
|
||||
enum ops {
|
||||
And = 0, Or, Not, Iff, Ite, Equal, Plus, Times, Floor, Leq, Div, Bool, Int, Array, Tsym, Fsym, Forall, Exists, Distinct, LastOp
|
||||
};
|
||||
|
||||
virtual symb mk_func(const std::string &s) = 0;
|
||||
virtual symb mk_pred(const std::string &s) = 0;
|
||||
virtual ast mk_op(ops op, const std::vector<ast> args) = 0;
|
||||
virtual ast mk_op(ops op, ast) = 0;
|
||||
virtual ast mk_op(ops op, ast, ast) = 0;
|
||||
virtual ast mk_op(ops op, ast, ast, ast) = 0;
|
||||
virtual ast mk_int(const std::string &) = 0;
|
||||
virtual ast mk_rat(const std::string &) = 0;
|
||||
virtual ast mk_true() = 0;
|
||||
virtual ast mk_false() = 0;
|
||||
virtual ast mk_app(symb,const std::vector<ast> args) = 0;
|
||||
|
||||
virtual bool get_func(ast, symb &) = 0;
|
||||
virtual bool get_pred(ast, symb &) = 0;
|
||||
virtual bool get_op(ast, ops &) = 0;
|
||||
virtual bool get_true(ast id) = 0;
|
||||
virtual bool get_false(ast id) = 0;
|
||||
virtual bool get_int(ast id, std::string &res) = 0;
|
||||
virtual bool get_rat(ast id, std::string &res) = 0;
|
||||
virtual const std::string &get_symb(symb) = 0;
|
||||
|
||||
virtual int get_num_args(ast) = 0;
|
||||
virtual ast get_arg(ast, int) = 0;
|
||||
|
||||
virtual void show_ast(ast) = 0;
|
||||
|
||||
virtual bool interpolate(const std::vector<ast> &frames, std::vector<ast> &itps, std::vector<int> parents) = 0;
|
||||
|
||||
FOCI2_EXPORT static foci2 *create(const std::string &);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -84,10 +84,9 @@ iz3base::range &iz3base::ast_scope(ast t){
|
|||
|
||||
void iz3base::print(const std::string &filename){
|
||||
ast t = make(And,cnsts);
|
||||
assert(0 && "not implemented");
|
||||
// Z3_string smt = Z3_benchmark_to_smtlib_string(ctx,"iZ3","QFLIA","unsat","",0,0,t);
|
||||
// std::ofstream f(filename.c_str());
|
||||
// f << smt;
|
||||
std::ofstream f(filename.c_str());
|
||||
print_sat_problem(f,t);
|
||||
f.close();
|
||||
}
|
||||
|
||||
|
||||
|
@ -246,3 +245,76 @@ bool iz3base::is_sat(ast f){
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
void iz3base::find_children(const hash_set<ast> &cnsts_set,
|
||||
const ast &tree,
|
||||
std::vector<ast> &cnsts,
|
||||
std::vector<int> &parents,
|
||||
std::vector<ast> &conjuncts,
|
||||
std::vector<int> &children,
|
||||
std::vector<int> &pos_map,
|
||||
bool merge
|
||||
){
|
||||
std::vector<int> my_children;
|
||||
std::vector<ast> my_conjuncts;
|
||||
if(op(tree) == Interp){ // if we've hit an interpolation position...
|
||||
find_children(cnsts_set,arg(tree,0),cnsts,parents,my_conjuncts,my_children,pos_map,merge);
|
||||
if(my_conjuncts.empty())
|
||||
my_conjuncts.push_back(mk_true()); // need at least one conjunct
|
||||
int root = cnsts.size() + my_conjuncts.size() - 1;
|
||||
for(unsigned i = 0; i < my_conjuncts.size(); i++){
|
||||
parents.push_back(root);
|
||||
cnsts.push_back(my_conjuncts[i]);
|
||||
}
|
||||
for(unsigned i = 0; i < my_children.size(); i++)
|
||||
parents[my_children[i]] = root;
|
||||
children.push_back(root);
|
||||
pos_map.push_back(root);
|
||||
}
|
||||
else {
|
||||
if(op(tree) == And){
|
||||
int nargs = num_args(tree);
|
||||
for(int i = 0; i < nargs; i++)
|
||||
find_children(cnsts_set,arg(tree,i),cnsts,parents,my_conjuncts,my_children,pos_map,merge);
|
||||
}
|
||||
if(cnsts_set.find(tree) != cnsts_set.end()){
|
||||
if(merge && !my_conjuncts.empty())
|
||||
my_conjuncts.back() = mk_and(my_conjuncts.back(),tree);
|
||||
else
|
||||
my_conjuncts.push_back(tree);
|
||||
}
|
||||
for(unsigned i = 0; i < my_children.size(); i++)
|
||||
children.push_back(my_children[i]);
|
||||
for(unsigned i = 0; i < my_conjuncts.size(); i++)
|
||||
conjuncts.push_back(my_conjuncts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void iz3base::to_parents_vec_representation(const std::vector<ast> &_cnsts,
|
||||
const ast &tree,
|
||||
std::vector<ast> &cnsts,
|
||||
std::vector<int> &parents,
|
||||
std::vector<ast> &theory,
|
||||
std::vector<int> &pos_map,
|
||||
bool merge
|
||||
){
|
||||
std::vector<int> my_children;
|
||||
std::vector<ast> my_conjuncts;
|
||||
hash_set<ast> cnsts_set;
|
||||
for(unsigned i = 0; i < _cnsts.size(); i++)
|
||||
cnsts_set.insert(_cnsts[i]);
|
||||
ast _tree = (op(tree) != Interp) ? make(Interp,tree) : tree;
|
||||
find_children(cnsts_set,_tree,cnsts,parents,my_conjuncts,my_children,pos_map,merge);
|
||||
if(op(tree) != Interp) pos_map.pop_back();
|
||||
parents[parents.size()-1] = SHRT_MAX;
|
||||
|
||||
// rest of the constraints are the background theory
|
||||
|
||||
hash_set<ast> used_set;
|
||||
for(unsigned i = 0; i < cnsts.size(); i++)
|
||||
used_set.insert(cnsts[i]);
|
||||
for(unsigned i = 0; i < _cnsts.size(); i++)
|
||||
if(used_set.find(_cnsts[i]) == used_set.end())
|
||||
theory.push_back(_cnsts[i]);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ class iz3base : public iz3mgr, public scopes {
|
|||
weak = false;
|
||||
}
|
||||
|
||||
iz3base(const iz3mgr& other,
|
||||
iz3base(const iz3mgr& other,
|
||||
const std::vector<ast> &_cnsts,
|
||||
const std::vector<int> &_parents,
|
||||
const std::vector<ast> &_theory)
|
||||
|
@ -74,6 +74,11 @@ class iz3base : public iz3mgr, public scopes {
|
|||
weak = false;
|
||||
}
|
||||
|
||||
iz3base(const iz3mgr& other)
|
||||
: iz3mgr(other), scopes() {
|
||||
weak = false;
|
||||
}
|
||||
|
||||
/* Set our options */
|
||||
void set_option(const std::string &name, const std::string &value){
|
||||
if(name == "weak" && value == "1") weak = true;
|
||||
|
@ -102,6 +107,19 @@ class iz3base : public iz3mgr, public scopes {
|
|||
return make(And,cs);
|
||||
}
|
||||
|
||||
void to_parents_vec_representation(const std::vector<ast> &_cnsts,
|
||||
const ast &tree,
|
||||
std::vector<ast> &cnsts,
|
||||
std::vector<int> &parents,
|
||||
std::vector<ast> &theory,
|
||||
std::vector<int> &pos_map,
|
||||
bool merge = false
|
||||
);
|
||||
|
||||
protected:
|
||||
std::vector<ast> cnsts;
|
||||
std::vector<ast> theory;
|
||||
|
||||
private:
|
||||
|
||||
struct ranges {
|
||||
|
@ -120,8 +138,6 @@ class iz3base : public iz3mgr, public scopes {
|
|||
|
||||
void initialize(const std::vector<ast> &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
|
||||
|
||||
std::vector<ast> cnsts;
|
||||
std::vector<ast> theory;
|
||||
|
||||
bool is_literal(ast n);
|
||||
void gather_conjuncts_rec(ast n, std::vector<ast> &conjuncts, stl_ext::hash_set<ast> &memo);
|
||||
|
@ -129,7 +145,15 @@ class iz3base : public iz3mgr, public scopes {
|
|||
ast simplify_and(std::vector<ast> &conjuncts);
|
||||
ast simplify_with_lit_rec(ast n, ast lit, stl_ext::hash_map<ast,ast> &memo, int depth);
|
||||
ast simplify_with_lit(ast n, ast lit);
|
||||
|
||||
void find_children(const stl_ext::hash_set<ast> &cnsts_set,
|
||||
const ast &tree,
|
||||
std::vector<ast> &cnsts,
|
||||
std::vector<int> &parents,
|
||||
std::vector<ast> &conjuncts,
|
||||
std::vector<int> &children,
|
||||
std::vector<int> &pos_map,
|
||||
bool merge
|
||||
);
|
||||
bool weak;
|
||||
|
||||
};
|
||||
|
|
192
src/interp/iz3checker.cpp
Executable file
192
src/interp/iz3checker.cpp
Executable file
|
@ -0,0 +1,192 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3checker.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
check correctness of interpolant
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "iz3base.h"
|
||||
#include "iz3checker.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
struct iz3checker : iz3base {
|
||||
|
||||
/* HACK: for tree interpolants, we assume that uninterpreted functions
|
||||
are global. This is because in the current state of the tree interpolation
|
||||
code, symbols that appear in sibling sub-trees have to be global, and
|
||||
we have no way to eliminate such function symbols. When tree interpoaltion is
|
||||
fixed, we can tree function symbols the same as constant symbols. */
|
||||
|
||||
bool is_tree;
|
||||
|
||||
void support(const ast &t, std::set<std::string> &res, hash_set<ast> &memo){
|
||||
if(memo.find(t) != memo.end()) return;
|
||||
memo.insert(t);
|
||||
|
||||
int nargs = num_args(t);
|
||||
for(int i = 0; i < nargs; i++)
|
||||
support(arg(t,i),res,memo);
|
||||
|
||||
switch(op(t)){
|
||||
case Uninterpreted:
|
||||
if(nargs == 0 || !is_tree) {
|
||||
std::string name = string_of_symbol(sym(t));
|
||||
res.insert(name);
|
||||
}
|
||||
break;
|
||||
case Forall:
|
||||
case Exists:
|
||||
support(get_quantifier_body(t),res,memo);
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
bool check(solver *s, std::ostream &err,
|
||||
const std::vector<ast> &cnsts,
|
||||
const std::vector<int> &parents,
|
||||
const std::vector<ast> &itp,
|
||||
const std::vector<ast> &theory){
|
||||
|
||||
is_tree = !parents.empty();
|
||||
int num = cnsts.size();
|
||||
std::vector<std::vector<int> > children(num);
|
||||
|
||||
for(int i = 0; i < num-1; i++){
|
||||
if(parents.size())
|
||||
children[parents[i]].push_back(i);
|
||||
else
|
||||
children[i+1].push_back(i);
|
||||
}
|
||||
|
||||
for(int i = 0; i < num; i++){
|
||||
s->push();
|
||||
for(unsigned j = 0; j < theory.size(); j++)
|
||||
s->assert_expr(to_expr(theory[j].raw()));
|
||||
s->assert_expr(to_expr(cnsts[i].raw()));
|
||||
std::vector<int> &cs = children[i];
|
||||
for(unsigned j = 0; j < cs.size(); j++)
|
||||
s->assert_expr(to_expr(itp[cs[j]].raw()));
|
||||
if(i != num-1)
|
||||
s->assert_expr(to_expr(mk_not(itp[i]).raw()));
|
||||
lbool result = s->check_sat(0,0);
|
||||
if(result != l_false){
|
||||
err << "interpolant " << i << " is incorrect";
|
||||
return false;
|
||||
}
|
||||
s->pop(1);
|
||||
}
|
||||
|
||||
std::vector<std::set<std::string> > supports(num);
|
||||
for(int i = 0; i < num; i++){
|
||||
hash_set<ast> memo;
|
||||
support(cnsts[i],supports[i],memo);
|
||||
}
|
||||
for(int i = 0; i < num-1; i++){
|
||||
std::vector<bool> Bside(num);
|
||||
for(int j = num-1; j >= 0; j--)
|
||||
Bside[j] = j != i;
|
||||
for(int j = num-1; j >= 0; j--)
|
||||
if(!Bside[j]){
|
||||
std::vector<int> &cs = children[i];
|
||||
for(unsigned k = 0; k < cs.size(); k++)
|
||||
Bside[cs[k]] = false;
|
||||
}
|
||||
std::set<std::string> Asup, Bsup,common,Isup,bad;
|
||||
for(int j = num-1; j >= 0; j--){
|
||||
std::set<std::string> &side = Bside[j] ? Bsup : Asup;
|
||||
side.insert(supports[j].begin(),supports[j].end());
|
||||
}
|
||||
std::set_intersection(Asup.begin(),Asup.end(),Bsup.begin(),Bsup.end(),std::inserter(common,common.begin()));
|
||||
{
|
||||
hash_set<ast> tmemo;
|
||||
for(unsigned j = 0; j < theory.size(); j++)
|
||||
support(theory[j],common,tmemo); // all theory symbols allowed in interps
|
||||
}
|
||||
hash_set<ast> memo;
|
||||
support(itp[i],Isup,memo);
|
||||
std::set_difference(Isup.begin(),Isup.end(),common.begin(),common.end(),std::inserter(bad,bad.begin()));
|
||||
if(!bad.empty()){
|
||||
err << "bad symbols in interpolant " << i << ":";
|
||||
std::copy(bad.begin(),bad.end(),std::ostream_iterator<std::string>(err,","));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool check(solver *s, std::ostream &err,
|
||||
const std::vector<ast> &_cnsts,
|
||||
const ast &tree,
|
||||
const std::vector<ast> &itp){
|
||||
|
||||
std::vector<int> pos_map;
|
||||
|
||||
// convert to the parents vector representation
|
||||
|
||||
to_parents_vec_representation(_cnsts, tree, cnsts, parents, theory, pos_map);
|
||||
|
||||
//use the parents vector representation to compute interpolant
|
||||
return check(s,err,cnsts,parents,itp,theory);
|
||||
}
|
||||
|
||||
iz3checker(ast_manager &_m)
|
||||
: iz3base(_m) {
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
std::vector<T> to_std_vector(const ::vector<T> &v){
|
||||
std::vector<T> _v(v.size());
|
||||
for(unsigned i = 0; i < v.size(); i++)
|
||||
_v[i] = v[i];
|
||||
return _v;
|
||||
}
|
||||
|
||||
|
||||
bool iz3check(ast_manager &_m_manager,
|
||||
solver *s,
|
||||
std::ostream &err,
|
||||
const ptr_vector<ast> &cnsts,
|
||||
const ::vector<int> &parents,
|
||||
const ptr_vector<ast> &interps,
|
||||
const ptr_vector<ast> &theory)
|
||||
{
|
||||
iz3checker chk(_m_manager);
|
||||
return chk.check(s,err,chk.cook(cnsts),to_std_vector(parents),chk.cook(interps),chk.cook(theory));
|
||||
}
|
||||
|
||||
bool iz3check(ast_manager &_m_manager,
|
||||
solver *s,
|
||||
std::ostream &err,
|
||||
const ptr_vector<ast> &_cnsts,
|
||||
ast *tree,
|
||||
const ptr_vector<ast> &interps)
|
||||
{
|
||||
iz3checker chk(_m_manager);
|
||||
return chk.check(s,err,chk.cook(_cnsts),chk.cook(tree),chk.cook(interps));
|
||||
}
|
41
src/interp/iz3checker.h
Normal file
41
src/interp/iz3checker.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3checker.h
|
||||
|
||||
Abstract:
|
||||
|
||||
check correctness of an interpolant
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef IZ3_CHECKER_H
|
||||
#define IZ3_CHECKER_H
|
||||
|
||||
#include "iz3mgr.h"
|
||||
#include "solver.h"
|
||||
|
||||
bool iz3check(ast_manager &_m_manager,
|
||||
solver *s,
|
||||
std::ostream &err,
|
||||
const ptr_vector<ast> &cnsts,
|
||||
const ::vector<int> &parents,
|
||||
const ptr_vector<ast> &interps,
|
||||
const ptr_vector<ast> &theory);
|
||||
|
||||
bool iz3check(ast_manager &_m_manager,
|
||||
solver *s,
|
||||
std::ostream &err,
|
||||
const ptr_vector<ast> &cnsts,
|
||||
ast *tree,
|
||||
const ptr_vector<ast> &interps);
|
||||
|
||||
#endif
|
|
@ -158,6 +158,7 @@ public:
|
|||
case Numeral: {
|
||||
std::string s = string_of_numeral(t);
|
||||
res = foci->mk_int(s);
|
||||
break;
|
||||
}
|
||||
case Forall:
|
||||
case Exists: {
|
||||
|
@ -177,12 +178,14 @@ public:
|
|||
foci_bvs.push_back(body);
|
||||
res = foci->mk_op(qop,foci_bvs);
|
||||
node_to_ast[res] = t; // desperate
|
||||
break;
|
||||
}
|
||||
case Variable: { // a deBruijn index
|
||||
int index = get_variable_index_value(t);
|
||||
type ty = get_type(t);
|
||||
foci2::symb symbol = make_deBruijn_symbol(index,ty);
|
||||
res = foci->mk_app(symbol,std::vector<foci2::ast>());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
@ -240,7 +243,7 @@ public:
|
|||
case foci2::Times:
|
||||
res = make(Times,args); break;
|
||||
case foci2::Div:
|
||||
res = make(Div,args[0],args[1]); break;
|
||||
res = make(Idiv,args[0],args[1]); break;
|
||||
case foci2::Leq:
|
||||
res = make(Leq,args[0],args[1]); break;
|
||||
case foci2::Distinct:
|
||||
|
|
|
@ -34,6 +34,7 @@ Revision History:
|
|||
#include "iz3interp.h"
|
||||
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
@ -164,9 +165,32 @@ static lbool test_secondary(context ctx,
|
|||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
struct killme {
|
||||
T *p;
|
||||
killme(){p = 0;}
|
||||
void set(T *_p) {p = _p;}
|
||||
~killme(){
|
||||
if(p)
|
||||
delete p;
|
||||
}
|
||||
};
|
||||
|
||||
class iz3interp : public iz3mgr {
|
||||
|
||||
class iz3interp : public iz3base {
|
||||
public:
|
||||
|
||||
killme<iz3secondary> sp_killer;
|
||||
killme<iz3translation> tr_killer;
|
||||
|
||||
bool is_linear(std::vector<int> &parents){
|
||||
for(int i = 0; i < ((int)parents.size())-1; i++)
|
||||
if(parents[i] != i+1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void proof_to_interpolant(z3pf proof,
|
||||
const std::vector<ast> &cnsts,
|
||||
const std::vector<int> &parents,
|
||||
|
@ -187,11 +211,17 @@ public:
|
|||
int num = cnsts_vec.size();
|
||||
std::vector<ast> interps_vec(num-1);
|
||||
|
||||
// if this is really a sequence problem, we can make it easier
|
||||
if(is_linear(parents_vec))
|
||||
parents_vec.clear();
|
||||
|
||||
// create a secondary prover
|
||||
iz3secondary *sp = iz3foci::create(this,num,parents_vec.empty()?0:&parents_vec[0]);
|
||||
sp_killer.set(sp); // kill this on exit
|
||||
|
||||
// create a translator
|
||||
iz3translation *tr = iz3translation::create(*this,sp,cnsts_vec,parents_vec,theory);
|
||||
tr_killer.set(tr);
|
||||
|
||||
// set the translation options, if needed
|
||||
if(options)
|
||||
|
@ -220,12 +250,37 @@ public:
|
|||
fr.fix_interpolants(interps_vec);
|
||||
|
||||
interps = interps_vec;
|
||||
delete tr;
|
||||
delete sp;
|
||||
}
|
||||
|
||||
|
||||
// same as above, but represents the tree using an ast
|
||||
|
||||
void proof_to_interpolant(const z3pf &proof,
|
||||
const std::vector<ast> &_cnsts,
|
||||
const ast &tree,
|
||||
std::vector<ast> &interps,
|
||||
interpolation_options_struct *options = 0
|
||||
){
|
||||
std::vector<int> pos_map;
|
||||
|
||||
// convert to the parents vector representation
|
||||
|
||||
to_parents_vec_representation(_cnsts, tree, cnsts, parents, theory, pos_map);
|
||||
|
||||
|
||||
//use the parents vector representation to compute interpolant
|
||||
proof_to_interpolant(proof,cnsts,parents,interps,theory,options);
|
||||
|
||||
// get the interps for the tree positions
|
||||
std::vector<ast> _interps = interps;
|
||||
interps.resize(pos_map.size());
|
||||
for(unsigned i = 0; i < pos_map.size(); i++)
|
||||
interps[i] = i < _interps.size() ? _interps[i] : mk_false();
|
||||
}
|
||||
|
||||
|
||||
iz3interp(ast_manager &_m_manager)
|
||||
: iz3mgr(_m_manager) {}
|
||||
: iz3base(_m_manager) {}
|
||||
};
|
||||
|
||||
void iz3interpolate(ast_manager &_m_manager,
|
||||
|
@ -254,3 +309,26 @@ void iz3interpolate(ast_manager &_m_manager,
|
|||
interps[i] = itp.uncook(_interps[i]);
|
||||
}
|
||||
|
||||
void iz3interpolate(ast_manager &_m_manager,
|
||||
ast *proof,
|
||||
const ptr_vector<ast> &cnsts,
|
||||
ast *tree,
|
||||
ptr_vector<ast> &interps,
|
||||
interpolation_options_struct * options)
|
||||
{
|
||||
iz3interp itp(_m_manager);
|
||||
std::vector<iz3mgr::ast> _cnsts(cnsts.size());
|
||||
std::vector<iz3mgr::ast> _interps;
|
||||
for(unsigned i = 0; i < cnsts.size(); i++)
|
||||
_cnsts[i] = itp.cook(cnsts[i]);
|
||||
iz3mgr::ast _proof = itp.cook(proof);
|
||||
iz3mgr::ast _tree = itp.cook(tree);
|
||||
itp.proof_to_interpolant(_proof,_cnsts,_tree,_interps,options);
|
||||
interps.resize(_interps.size());
|
||||
for(unsigned i = 0; i < interps.size(); i++)
|
||||
interps[i] = itp.uncook(_interps[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,14 @@ struct interpolation_options_struct {
|
|||
stl_ext::hash_map<std::string,std::string> map;
|
||||
};
|
||||
|
||||
/** This object is thrown if a tree interpolation problem is mal-formed */
|
||||
struct iz3_bad_tree {
|
||||
};
|
||||
|
||||
/** This object is thrown when iz3 fails due to an incompleteness in
|
||||
the secondary solver. */
|
||||
struct iz3_incompleteness {
|
||||
};
|
||||
|
||||
typedef interpolation_options_struct *interpolation_options;
|
||||
|
||||
|
@ -37,4 +45,11 @@ void iz3interpolate(ast_manager &_m_manager,
|
|||
const ptr_vector<ast> &theory,
|
||||
interpolation_options_struct * options = 0);
|
||||
|
||||
void iz3interpolate(ast_manager &_m_manager,
|
||||
ast *proof,
|
||||
const ptr_vector<ast> &cnsts,
|
||||
ast *tree,
|
||||
ptr_vector<ast> &interps,
|
||||
interpolation_options_struct * options);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,7 @@ iz3mgr::ast iz3mgr::make(opr op, int n, raw_ast **args){
|
|||
case Not: return mki(m_basic_fid,OP_NOT,n,args);
|
||||
case Implies: return mki(m_basic_fid,OP_IMPLIES,n,args);
|
||||
case Oeq: return mki(m_basic_fid,OP_OEQ,n,args);
|
||||
case Interp: return mki(m_basic_fid,OP_INTERP,n,args);
|
||||
case Leq: return mki(m_arith_fid,OP_LE,n,args);
|
||||
case Geq: return mki(m_arith_fid,OP_GE,n,args);
|
||||
case Lt: return mki(m_arith_fid,OP_LT,n,args);
|
||||
|
@ -107,7 +108,7 @@ iz3mgr::ast iz3mgr::make(opr op){
|
|||
return make(op,0,0);
|
||||
}
|
||||
|
||||
iz3mgr::ast iz3mgr::make(opr op, ast &arg0){
|
||||
iz3mgr::ast iz3mgr::make(opr op, const ast &arg0){
|
||||
raw_ast *a = arg0.raw();
|
||||
return make(op,1,&a);
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ iz3mgr::ast iz3mgr::make(opr op, const ast &arg0, const ast &arg1){
|
|||
return make(op,2,args);
|
||||
}
|
||||
|
||||
iz3mgr::ast iz3mgr::make(opr op, ast &arg0, ast &arg1, ast &arg2){
|
||||
iz3mgr::ast iz3mgr::make(opr op, const ast &arg0, const ast &arg1, const ast &arg2){
|
||||
raw_ast *args[3];
|
||||
args[0] = arg0.raw();
|
||||
args[1] = arg1.raw();
|
||||
|
@ -335,13 +336,11 @@ void iz3mgr::pretty_print(std::ostream &f, const std::string &s){
|
|||
}
|
||||
|
||||
|
||||
iz3mgr::opr iz3mgr::op(ast &t){
|
||||
iz3mgr::opr iz3mgr::op(const ast &t){
|
||||
ast_kind dk = t.raw()->get_kind();
|
||||
switch(dk){
|
||||
case AST_APP: {
|
||||
expr * e = to_expr(t.raw());
|
||||
if (m().is_unique_value(e))
|
||||
return Numeral;
|
||||
func_decl *d = to_app(t.raw())->get_decl();
|
||||
if (null_family_id == d->get_family_id())
|
||||
return Uninterpreted;
|
||||
|
@ -360,6 +359,7 @@ iz3mgr::opr iz3mgr::op(ast &t){
|
|||
case OP_NOT: return Not;
|
||||
case OP_IMPLIES: return Implies;
|
||||
case OP_OEQ: return Oeq;
|
||||
case OP_INTERP: return Interp;
|
||||
default:
|
||||
return Other;
|
||||
}
|
||||
|
@ -383,6 +383,8 @@ iz3mgr::opr iz3mgr::op(ast &t){
|
|||
case OP_TO_INT: return ToInt;
|
||||
case OP_IS_INT: return IsInt;
|
||||
default:
|
||||
if (m().is_unique_value(e))
|
||||
return Numeral;
|
||||
return Other;
|
||||
}
|
||||
}
|
||||
|
@ -423,3 +425,9 @@ iz3mgr::pfrule iz3mgr::pr(const ast &t){
|
|||
assert(m_basic_fid == d->get_family_id());
|
||||
return d->get_decl_kind();
|
||||
}
|
||||
|
||||
void iz3mgr::print_sat_problem(std::ostream &out, const ast &t){
|
||||
ast_smt_pp pp(m());
|
||||
pp.set_simplify_implies(false);
|
||||
pp.display_smt2(out, to_expr(t.raw()));
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ namespace std {
|
|||
class less<ast_r> {
|
||||
public:
|
||||
size_t operator()(const ast_r &s, const ast_r &t) const {
|
||||
return s.raw()->get_id() < t.raw()->get_id();
|
||||
return s.raw() < t.raw(); // s.raw()->get_id() < t.raw()->get_id();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ class iz3mgr {
|
|||
Distinct,
|
||||
Xor,
|
||||
Oeq,
|
||||
Interp,
|
||||
Leq,
|
||||
Geq,
|
||||
Lt,
|
||||
|
@ -196,7 +197,7 @@ class iz3mgr {
|
|||
Other
|
||||
};
|
||||
|
||||
opr op(ast &t);
|
||||
opr op(const ast &t);
|
||||
|
||||
unsigned ast_id(const ast &x)
|
||||
{
|
||||
|
@ -208,9 +209,9 @@ class iz3mgr {
|
|||
ast make_var(const std::string &name, type ty);
|
||||
ast make(opr op, const std::vector<ast> &args);
|
||||
ast make(opr op);
|
||||
ast make(opr op, ast &arg0);
|
||||
ast make(opr op, const ast &arg0);
|
||||
ast make(opr op, const ast &arg0, const ast &arg1);
|
||||
ast make(opr op, ast &arg0, ast &arg1, ast &arg2);
|
||||
ast make(opr op, const ast &arg0, const ast &arg1, const ast &arg2);
|
||||
ast make(symb sym, const std::vector<ast> &args);
|
||||
ast make(symb sym);
|
||||
ast make(symb sym, ast &arg0);
|
||||
|
@ -223,6 +224,13 @@ class iz3mgr {
|
|||
|
||||
ast cook(raw_ast *a) {return ast(&m_manager,a);}
|
||||
|
||||
std::vector<ast> cook(ptr_vector<raw_ast> v) {
|
||||
std::vector<ast> _v(v.size());
|
||||
for(unsigned i = 0; i < v.size(); i++)
|
||||
_v[i] = cook(v[i]);
|
||||
return _v;
|
||||
}
|
||||
|
||||
raw_ast *uncook(const ast &a) {
|
||||
m_manager.inc_ref(a.raw());
|
||||
return a.raw();
|
||||
|
@ -245,7 +253,7 @@ class iz3mgr {
|
|||
assert(0);
|
||||
}
|
||||
|
||||
ast arg(ast t, int i){
|
||||
ast arg(const ast &t, int i){
|
||||
ast_kind dk = t.raw()->get_kind();
|
||||
switch(dk){
|
||||
case AST_APP:
|
||||
|
@ -427,6 +435,8 @@ class iz3mgr {
|
|||
|
||||
void print_clause(std::ostream &s, std::vector<ast> &cls);
|
||||
|
||||
void print_sat_problem(std::ostream &out, const ast &t);
|
||||
|
||||
void show_clause(std::vector<ast> &cls);
|
||||
|
||||
static void pretty_print(std::ostream &f, const std::string &s);
|
||||
|
|
175
src/interp/iz3pp.cpp
Normal file
175
src/interp/iz3pp.cpp
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3pp.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Pretty-print interpolation problems
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
/* Copyright 2011 Microsoft Research. */
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
#include "iz3mgr.h"
|
||||
#include "iz3pp.h"
|
||||
#include "func_decl_dependencies.h"
|
||||
#include"for_each_expr.h"
|
||||
#include"ast_smt_pp.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"expr_functors.h"
|
||||
#include"expr_abstract.h"
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
// TBD: algebraic data-types declarations will not be printed.
|
||||
class free_func_visitor {
|
||||
ast_manager& m;
|
||||
func_decl_set m_funcs;
|
||||
obj_hashtable<sort> m_sorts;
|
||||
public:
|
||||
free_func_visitor(ast_manager& m): m(m) {}
|
||||
void operator()(var * n) { }
|
||||
void operator()(app * n) {
|
||||
m_funcs.insert(n->get_decl());
|
||||
sort* s = m.get_sort(n);
|
||||
if (s->get_family_id() == null_family_id) {
|
||||
m_sorts.insert(s);
|
||||
}
|
||||
}
|
||||
void operator()(quantifier * n) { }
|
||||
func_decl_set& funcs() { return m_funcs; }
|
||||
obj_hashtable<sort>& sorts() { return m_sorts; }
|
||||
};
|
||||
|
||||
class iz3pp_helper : public iz3mgr {
|
||||
public:
|
||||
|
||||
void print_tree(const ast &tree, hash_map<expr*,symbol> &cnames, std::ostream &out){
|
||||
hash_map<expr*,symbol>::iterator foo = cnames.find(to_expr(tree.raw()));
|
||||
if(foo != cnames.end()){
|
||||
symbol nm = foo->second;
|
||||
if (is_smt2_quoted_symbol(nm)) {
|
||||
out << mk_smt2_quoted_symbol(nm);
|
||||
}
|
||||
else {
|
||||
out << nm;
|
||||
}
|
||||
}
|
||||
else if(op(tree) == And){
|
||||
out << "(and";
|
||||
int nargs = num_args(tree);
|
||||
for(int i = 0; i < nargs; i++){
|
||||
out << " ";
|
||||
print_tree(arg(tree,i), cnames, out);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
else if(op(tree) == Interp){
|
||||
out << "(interp ";
|
||||
print_tree(arg(tree,0), cnames, out);
|
||||
out << ")";
|
||||
}
|
||||
else throw iz3pp_bad_tree();
|
||||
}
|
||||
|
||||
|
||||
iz3pp_helper(ast_manager &_m_manager)
|
||||
: iz3mgr(_m_manager) {}
|
||||
};
|
||||
|
||||
void iz3pp(ast_manager &m,
|
||||
const ptr_vector<expr> &cnsts_vec,
|
||||
expr *tree,
|
||||
std::ostream& out) {
|
||||
|
||||
unsigned sz = cnsts_vec.size();
|
||||
expr* const* cnsts = &cnsts_vec[0];
|
||||
|
||||
out << "(set-option :produce-interpolants true)\n";
|
||||
|
||||
free_func_visitor visitor(m);
|
||||
expr_mark visited;
|
||||
bool print_low_level = true; // m_params.print_low_level_smt2();
|
||||
|
||||
#define PP(_e_) if (print_low_level) out << mk_smt_pp(_e_, m); else ast_smt2_pp(out, _e_, env);
|
||||
|
||||
smt2_pp_environment_dbg env(m);
|
||||
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
expr* e = cnsts[i];
|
||||
for_each_expr(visitor, visited, e);
|
||||
}
|
||||
|
||||
// name all the constraints
|
||||
hash_map<expr *, symbol> cnames;
|
||||
int ctr = 1;
|
||||
for(unsigned i = 0; i < sz; i++){
|
||||
symbol nm;
|
||||
std::ostringstream s;
|
||||
s << "f!" << (ctr++);
|
||||
cnames[cnsts[i]] = symbol(s.str().c_str());
|
||||
}
|
||||
|
||||
func_decl_set &funcs = visitor.funcs();
|
||||
func_decl_set::iterator it = funcs.begin(), end = funcs.end();
|
||||
|
||||
obj_hashtable<sort>& sorts = visitor.sorts();
|
||||
obj_hashtable<sort>::iterator sit = sorts.begin(), send = sorts.end();
|
||||
|
||||
|
||||
|
||||
for (; sit != send; ++sit) {
|
||||
PP(*sit);
|
||||
}
|
||||
|
||||
for (; it != end; ++it) {
|
||||
func_decl* f = *it;
|
||||
if(f->get_family_id() == null_family_id){
|
||||
PP(f);
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
out << "(assert ";
|
||||
expr* r = cnsts[i];
|
||||
symbol nm = cnames[r];
|
||||
out << "(! ";
|
||||
PP(r);
|
||||
out << " :named ";
|
||||
if (is_smt2_quoted_symbol(nm)) {
|
||||
out << mk_smt2_quoted_symbol(nm);
|
||||
}
|
||||
else {
|
||||
out << nm;
|
||||
}
|
||||
out << ")";
|
||||
out << ")\n";
|
||||
}
|
||||
out << "(check-sat)\n";
|
||||
out << "(get-interpolant ";
|
||||
iz3pp_helper pp(m);
|
||||
pp.print_tree(pp.cook(tree),cnames,out);
|
||||
out << ")\n";
|
||||
}
|
||||
|
||||
|
35
src/interp/iz3pp.h
Normal file
35
src/interp/iz3pp.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3pp.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Pretty-print interpolation problems
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef IZ3_PP_H
|
||||
#define IZ3_PP_H
|
||||
|
||||
#include "iz3mgr.h"
|
||||
|
||||
/** Exception thrown in case of mal-formed tree interpoloation
|
||||
specification */
|
||||
|
||||
struct iz3pp_bad_tree {
|
||||
};
|
||||
|
||||
void iz3pp(ast_manager &m,
|
||||
const ptr_vector<expr> &cnsts_vec,
|
||||
expr *tree,
|
||||
std::ostream& out);
|
||||
#endif
|
|
@ -32,6 +32,13 @@ class scopes {
|
|||
parents = _parents;
|
||||
}
|
||||
|
||||
scopes(){
|
||||
}
|
||||
|
||||
void initialize(const std::vector<int> &_parents){
|
||||
parents = _parents;
|
||||
}
|
||||
|
||||
/** The parents vector defining the tree structure */
|
||||
std::vector<int> parents;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ Revision History:
|
|||
#include "iz3translate.h"
|
||||
#include "iz3proof.h"
|
||||
#include "iz3profiling.h"
|
||||
#include "iz3interp.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
@ -336,6 +337,16 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
AstSet::iterator it = res.begin(), en = res.end();
|
||||
if(it != en){
|
||||
AstSet::iterator old = it;
|
||||
++it;
|
||||
for(; it != en; ++it, ++old)
|
||||
if(!(*old < *it))
|
||||
std::cout << "foo!";
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -439,25 +450,28 @@ public:
|
|||
if(it != localization_map.end())
|
||||
return it->second;
|
||||
|
||||
// if is is non-local, we must first localise the arguments to
|
||||
// if is is non-local, we must first localize the arguments to
|
||||
// the range of its function symbol
|
||||
if(op(e) == Uninterpreted){
|
||||
symb f = sym(e);
|
||||
range frng = sym_range(f);
|
||||
int nargs = num_args(e);
|
||||
if(nargs > 0 /* && (!is_local(e) || flo <= hi || fhi >= lo) */){
|
||||
if(ranges_intersect(frng,rng)) // localize to desired range if possible
|
||||
{frng = range_glb(frng,rng);}
|
||||
std::vector<ast> largs(nargs);
|
||||
for(int i = 0; i < nargs; i++){
|
||||
largs[i] = localize_term(arg(e,i),frng);
|
||||
frng = range_glb(frng,ast_scope(largs[i]));
|
||||
}
|
||||
e = make(f,largs);
|
||||
assert(is_local(e));
|
||||
|
||||
int nargs = num_args(e);
|
||||
if(nargs > 0 /* && (!is_local(e) || flo <= hi || fhi >= lo) */){
|
||||
range frng = rng;
|
||||
if(op(e) == Uninterpreted){
|
||||
symb f = sym(e);
|
||||
range srng = sym_range(f);
|
||||
if(ranges_intersect(srng,rng)) // localize to desired range if possible
|
||||
frng = range_glb(srng,rng);
|
||||
}
|
||||
std::vector<ast> largs(nargs);
|
||||
for(int i = 0; i < nargs; i++){
|
||||
largs[i] = localize_term(arg(e,i),frng);
|
||||
frng = range_glb(frng,ast_scope(largs[i]));
|
||||
}
|
||||
e = clone(e,largs);
|
||||
assert(is_local(e));
|
||||
}
|
||||
|
||||
|
||||
if(ranges_intersect(ast_scope(e),rng))
|
||||
return e; // this term occurs in range, so it's O.K.
|
||||
|
||||
|
@ -774,10 +788,12 @@ public:
|
|||
|
||||
// if sat, lemma isn't valid, something is wrong
|
||||
if(sat){
|
||||
#if 1
|
||||
std::cerr << "invalid lemma written to file invalid_lemma.smt:\n";
|
||||
iz3base foo(*this,preds,std::vector<int>(),std::vector<ast>());
|
||||
foo.print("invalid_lemma.smt");
|
||||
throw invalid_lemma();
|
||||
#endif
|
||||
throw iz3_incompleteness();
|
||||
}
|
||||
assert(sat == 0); // if sat, lemma doesn't hold!
|
||||
|
||||
|
@ -961,12 +977,14 @@ public:
|
|||
AstSet &this_hyps = get_hyps(proof);
|
||||
if(std::includes(hyps.begin(),hyps.end(),this_hyps.begin(),this_hyps.end())){
|
||||
// if(hyps.find(con) == hyps.end())
|
||||
#if 0
|
||||
if(/* lemma_count == SHOW_LEMMA_COUNT - 1 && */ !is_literal_or_lit_iff(conc(proof))){
|
||||
std::cout << "\nnon-lit local ante\n";
|
||||
show_step(proof);
|
||||
show(conc(proof));
|
||||
throw non_lit_local_ante();
|
||||
}
|
||||
#endif
|
||||
local_antes.push_back(proof);
|
||||
return true;
|
||||
}
|
||||
|
@ -1019,7 +1037,7 @@ public:
|
|||
std::vector<ast> lit_trace;
|
||||
hash_set<ast> marked_proofs;
|
||||
|
||||
bool proof_has_lit(ast proof, ast lit){
|
||||
bool proof_has_lit(const ast &proof, const ast &lit){
|
||||
AstSet &hyps = get_hyps(proof);
|
||||
if(hyps.find(mk_not(lit)) != hyps.end())
|
||||
return true;
|
||||
|
@ -1033,7 +1051,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void trace_lit_rec(ast lit, ast proof, AstHashSet &memo){
|
||||
void trace_lit_rec(const ast &lit, const ast &proof, AstHashSet &memo){
|
||||
if(memo.find(proof) == memo.end()){
|
||||
memo.insert(proof);
|
||||
AstSet &hyps = get_hyps(proof);
|
||||
|
@ -1064,7 +1082,7 @@ public:
|
|||
|
||||
ast traced_lit;
|
||||
|
||||
int trace_lit(ast lit, ast proof){
|
||||
int trace_lit(const ast &lit, const ast &proof){
|
||||
marked_proofs.clear();
|
||||
lit_trace.clear();
|
||||
traced_lit = lit;
|
||||
|
@ -1073,7 +1091,7 @@ public:
|
|||
return lit_trace.size();
|
||||
}
|
||||
|
||||
bool is_literal_or_lit_iff(ast lit){
|
||||
bool is_literal_or_lit_iff(const ast &lit){
|
||||
if(my_is_literal(lit)) return true;
|
||||
if(op(lit) == Iff){
|
||||
return my_is_literal(arg(lit,0)) && my_is_literal(arg(lit,1));
|
||||
|
@ -1081,13 +1099,13 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool my_is_literal(ast lit){
|
||||
bool my_is_literal(const ast &lit){
|
||||
ast abslit = is_not(lit) ? arg(lit,0) : lit;
|
||||
int f = op(abslit);
|
||||
return !(f == And || f == Or || f == Iff);
|
||||
}
|
||||
|
||||
void print_lit(ast lit){
|
||||
void print_lit(const ast &lit){
|
||||
ast abslit = is_not(lit) ? arg(lit,0) : lit;
|
||||
if(!is_literal_or_lit_iff(lit)){
|
||||
if(is_not(lit)) std::cout << "~";
|
||||
|
@ -1099,22 +1117,22 @@ public:
|
|||
print_expr(std::cout,lit);
|
||||
}
|
||||
|
||||
void show_lit(ast lit){
|
||||
void show_lit(const ast &lit){
|
||||
print_lit(lit);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print_z3_lit(ast a){
|
||||
void print_z3_lit(const ast &a){
|
||||
print_lit(from_ast(a));
|
||||
}
|
||||
|
||||
void show_z3_lit(ast a){
|
||||
void show_z3_lit(const ast &a){
|
||||
print_z3_lit(a);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
|
||||
void show_con(ast proof, bool brief){
|
||||
void show_con(const ast &proof, bool brief){
|
||||
if(!traced_lit.null() && proof_has_lit(proof,traced_lit))
|
||||
std::cout << "(*) ";
|
||||
ast con = conc(proof);
|
||||
|
@ -1138,7 +1156,7 @@ public:
|
|||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void show_step( ast proof){
|
||||
void show_step(const ast &proof){
|
||||
std::cout << "\n";
|
||||
unsigned nprems = num_prems(proof);
|
||||
for(unsigned i = 0; i < nprems; i++){
|
||||
|
@ -1151,7 +1169,7 @@ public:
|
|||
show_con(proof,false);
|
||||
}
|
||||
|
||||
void show_marked( ast proof){
|
||||
void show_marked( const ast &proof){
|
||||
std::cout << "\n";
|
||||
unsigned nprems = num_prems(proof);
|
||||
for(unsigned i = 0; i < nprems; i++){
|
||||
|
@ -1166,7 +1184,7 @@ public:
|
|||
std::vector<ast> pfhist;
|
||||
int pfhist_pos;
|
||||
|
||||
void pfgoto(ast proof){
|
||||
void pfgoto(const ast &proof){
|
||||
if(pfhist.size() == 0)
|
||||
pfhist_pos = 0;
|
||||
else pfhist_pos++;
|
||||
|
@ -1245,7 +1263,7 @@ public:
|
|||
return res;
|
||||
}
|
||||
|
||||
Iproof::node extract_simple_proof(ast proof, hash_set<ast> &leaves){
|
||||
Iproof::node extract_simple_proof(const ast &proof, hash_set<ast> &leaves){
|
||||
if(leaves.find(proof) != leaves.end())
|
||||
return iproof->make_hypothesis(conc(proof));
|
||||
ast con = from_ast(conc(proof));
|
||||
|
@ -1271,7 +1289,7 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int extract_th_lemma_simple(ast proof, std::vector<ast> &lits){
|
||||
int extract_th_lemma_simple(const ast &proof, std::vector<ast> &lits){
|
||||
std::vector<ast> la = local_antes;
|
||||
local_antes.clear(); // clear antecedents for next lemma
|
||||
antes_added.clear();
|
||||
|
@ -1321,7 +1339,7 @@ public:
|
|||
|
||||
// #define NEW_EXTRACT_TH_LEMMA
|
||||
|
||||
void get_local_hyps(ast proof, std::set<ast> &res){
|
||||
void get_local_hyps(const ast &proof, std::set<ast> &res){
|
||||
std::set<ast> hyps = get_hyps(proof);
|
||||
for(std::set<ast>::iterator it = hyps.begin(), en = hyps.end(); it != en; ++it){
|
||||
ast hyp = *it;
|
||||
|
@ -1376,6 +1394,7 @@ public:
|
|||
try {
|
||||
res = extract_th_lemma_common(lits,nll,lemma_nll);
|
||||
}
|
||||
#if 0
|
||||
catch (const invalid_lemma &) {
|
||||
std::cout << "\n\nlemma: " << my_count;
|
||||
std::cout << "\n\nproof node: \n";
|
||||
|
@ -1397,6 +1416,7 @@ public:
|
|||
show_lit(lits[i]);
|
||||
throw invalid_lemma();
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
#else
|
||||
|
@ -1648,7 +1668,7 @@ public:
|
|||
if(!(res = extract_th_lemma(proof,lits,nll))){
|
||||
if(!(res = push_into_resolvent(proof,lits,nll,expect_clause))){
|
||||
#endif
|
||||
std::cout << "extract theory lemma failed\n";
|
||||
// std::cout << "extract theory lemma failed\n";
|
||||
add_antes(proof);
|
||||
res = fix_lemma(lits,get_hyps(proof),nll);
|
||||
}
|
||||
|
@ -1724,6 +1744,22 @@ public:
|
|||
frames = cnsts.size();
|
||||
traced_lit = ast();
|
||||
}
|
||||
|
||||
~iz3translation_direct(){
|
||||
for(hash_map<non_local_lits, non_local_lits *>::iterator
|
||||
it = non_local_lits_unique.begin(),
|
||||
en = non_local_lits_unique.end();
|
||||
it != en;
|
||||
++it)
|
||||
delete it->second;
|
||||
|
||||
for(hash_map<Z3_resolvent, Z3_resolvent *>::iterator
|
||||
it = Z3_resolvent_unique.begin(),
|
||||
en = Z3_resolvent_unique.end();
|
||||
it != en;
|
||||
++it)
|
||||
delete it->second;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1740,29 +1776,29 @@ iz3translation *iz3translation::create(iz3mgr &mgr,
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
|
||||
void iz3translation_direct_trace_lit(iz3translation_direct *p, ast lit, ast proof){
|
||||
void iz3translation_direct_trace_lit(iz3translation_direct *p, iz3mgr::ast lit, iz3mgr::ast proof){
|
||||
p->trace_lit(lit, proof);
|
||||
}
|
||||
|
||||
void iz3translation_direct_show_step(iz3translation_direct *p, ast proof){
|
||||
void iz3translation_direct_show_step(iz3translation_direct *p, iz3mgr::ast proof){
|
||||
p->show_step(proof);
|
||||
}
|
||||
|
||||
void iz3translation_direct_show_marked(iz3translation_direct *p, ast proof){
|
||||
void iz3translation_direct_show_marked(iz3translation_direct *p, iz3mgr::ast proof){
|
||||
p->show_marked(proof);
|
||||
}
|
||||
|
||||
void iz3translation_direct_show_lit(iz3translation_direct *p, ast lit){
|
||||
void iz3translation_direct_show_lit(iz3translation_direct *p, iz3mgr::ast lit){
|
||||
p->show_lit(lit);
|
||||
}
|
||||
|
||||
void iz3translation_direct_show_z3_lit(iz3translation_direct *p, ast a){
|
||||
void iz3translation_direct_show_z3_lit(iz3translation_direct *p, iz3mgr::ast a){
|
||||
p->show_z3_lit(a);
|
||||
}
|
||||
|
||||
void iz3translation_direct_pfgoto(iz3translation_direct *p, ast proof){
|
||||
void iz3translation_direct_pfgoto(iz3translation_direct *p, iz3mgr::ast proof){
|
||||
p->pfgoto(proof);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue