mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 11:25:51 +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
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));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue