3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 19:35:50 +00:00

moved smt 1.0 parser to its own module

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2012-10-26 18:21:17 -07:00
parent 566ed44033
commit 1492b81290
7 changed files with 2 additions and 2 deletions

View file

@ -1,252 +0,0 @@
#include"smtlib.h"
#include"ast_pp.h"
#include"ast_smt2_pp.h"
#ifdef _WINDOWS
#ifdef ARRAYSIZE
#undef ARRAYSIZE
#endif
#include <windows.h>
#include <strsafe.h>
#endif
#include <iostream>
using namespace smtlib;
// --------------------------------------------------------------------------
// symtable
symtable::~symtable() {
reset();
}
void symtable::reset() {
svector<ptr_vector<func_decl>*> range;
m_ids.get_range(range);
for (unsigned i = 0; i < range.size(); ++i) {
ptr_vector<func_decl> const & v = *range[i];
for (unsigned j = 0; j < v.size(); ++j) {
m_manager.dec_ref(v[j]);
}
dealloc(range[i]);
}
m_ids.reset();
ptr_vector<sort> sorts;
m_sorts1.get_range(sorts);
for (unsigned i = 0; i < sorts.size(); ++i) {
m_manager.dec_ref(sorts[i]);
}
m_sorts1.reset();
ptr_vector<sort_builder> sort_builders;
m_sorts.get_range(sort_builders);
for (unsigned i = 0; i < sort_builders.size(); ++i) {
dealloc(sort_builders[i]);
}
m_sorts.reset();
}
void symtable::insert(symbol s, func_decl * d) {
ptr_vector<func_decl>* decls = 0;
m_manager.inc_ref(d);
if (!m_ids.find(s, decls)) {
SASSERT(!decls);
decls = alloc(ptr_vector<func_decl>);
decls->push_back(d);
m_ids.insert(s, decls);
}
else {
SASSERT(decls);
if ((*decls)[0] != d) {
decls->push_back(d);
}
else {
m_manager.dec_ref(d);
}
}
}
bool symtable::find1(symbol s, func_decl*& d) {
ptr_vector<func_decl>* decls = 0;
if (!m_ids.find(s, decls)) {
SASSERT(!decls);
return false;
}
SASSERT(decls && !decls->empty());
d = (*decls)[0];
return true;
}
bool symtable::find_overload(symbol s, ptr_vector<sort> const & dom, func_decl * & d) {
ptr_vector<func_decl>* decls = 0;
d = 0;
if (!m_ids.find(s, decls)) {
SASSERT(!decls);
return false;
}
SASSERT(decls);
for (unsigned i = 0; i < decls->size(); ++i) {
func_decl* decl = (*decls)[i];
if (decl->is_associative() && decl->get_arity() > 0) {
for (unsigned j = 0; j < dom.size(); ++j) {
if (dom[j] != decl->get_domain(0)) {
goto try_next;
}
}
d = decl;
return true;
}
if (decl->get_arity() != dom.size()) {
goto try_next;
}
for (unsigned j = 0; j < decl->get_arity(); ++j) {
if (decl->get_domain(j) != dom[j]) {
goto try_next;
}
}
d = decl;
return true;
try_next:
if (decl->get_family_id() == m_manager.get_basic_family_id() && decl->get_decl_kind() == OP_DISTINCT) {
// we skip type checking for 'distinct'
d = decl;
return true;
}
}
return false;
}
// Store in result the func_decl that are not attached to any family id.
// That is, the uninterpreted constants and function declarations.
void symtable::get_func_decls(ptr_vector<func_decl> & result) const {
svector<ptr_vector<func_decl>*> tmp;
m_ids.get_range(tmp);
svector<ptr_vector<func_decl>*>::const_iterator it = tmp.begin();
svector<ptr_vector<func_decl>*>::const_iterator end = tmp.end();
for (; it != end; ++it) {
ptr_vector<func_decl> * curr = *it;
if (curr) {
ptr_vector<func_decl>::const_iterator it2 = curr->begin();
ptr_vector<func_decl>::const_iterator end2 = curr->end();
for (; it2 != end2; ++it2) {
func_decl * d = *it2;
if (d && d->get_family_id() == null_family_id) {
result.push_back(d);
}
}
}
}
}
void symtable::insert(symbol s, sort_builder* sb) {
m_sorts.insert(s, sb);
}
bool symtable::lookup(symbol s, sort_builder*& sb) {
return m_sorts.find(s, sb);
}
void symtable::push_sort(symbol name, sort* srt) {
m_sorts.begin_scope();
sort_builder* sb = alloc(basic_sort_builder,srt);
m_sorts.insert(name, sb);
m_sorts_trail.push_back(sb);
}
void symtable::pop_sorts(unsigned num_sorts) {
while (num_sorts > 0) {
dealloc(m_sorts_trail.back());
m_sorts_trail.pop_back();
m_sorts.end_scope();
}
}
void symtable::get_sorts(ptr_vector<sort>& result) const {
vector<sort*,false> tmp;
m_sorts1.get_range(tmp);
for (unsigned i = 0; i < tmp.size(); ++i) {
if (tmp[i]->get_family_id() == null_family_id) {
result.push_back(tmp[i]);
}
}
}
// --------------------------------------------------------------------------
// theory
func_decl * theory::declare_func(symbol const & id, sort_ref_buffer & domain, sort * range,
bool is_assoc, bool is_comm, bool is_inj) {
func_decl * decl = m_ast_manager.mk_func_decl(id, domain.size(), domain.c_ptr(), range,
is_assoc, is_comm, is_inj);
m_symtable.insert(id, decl);
m_asts.push_back(decl);
return decl;
}
sort * theory::declare_sort(symbol const & id) {
sort * decl = m_ast_manager.mk_sort(id);
m_symtable.insert(id, decl);
m_asts.push_back(decl);
return decl;
}
bool theory::get_func_decl(symbol id, func_decl * & decl) {
return m_symtable.find1(id, decl);
}
bool theory::get_sort(symbol id, sort* & s) {
return m_symtable.find(id, s);
}
bool theory::get_const(symbol id, expr * & term) {
func_decl* decl = 0;
if (!get_func_decl(id,decl)) {
return false;
}
if (decl->get_arity() != 0) {
return false;
}
term = m_ast_manager.mk_const(decl);
m_asts.push_back(term);
return true;
}
void benchmark::display_as_smt2(std::ostream & out) const {
if (m_logic != symbol::null)
out << "(set-logic " << m_logic << ")\n";
out << "(set-info :smt-lib-version 2.0)\n";
out << "(set-info :status ";
switch (m_status) {
case SAT: out << "sat"; break;
case UNSAT: out << "unsat"; break;
default: out << "unknown"; break;
}
out << ")\n";
#if 0
ast_manager & m = m_ast_manager;
ptr_vector<func_decl> decls;
m_symtable.get_func_decls(decls);
ptr_vector<func_decl>::const_iterator it = decls.begin();
ptr_vector<func_decl>::const_iterator end = decls.end();
for (; it != end; ++it) {
func_decl * f = *it;
out << "(declare-fun " << f->get_name() << " (";
for (unsigned i = 0; i < f->get_arity(); i++) {
if (i > 0) out << " ";
out << mk_ismt2_pp(f->get_domain(i), m);
}
out << ") " << mk_ismt2_pp(f->get_range(), m);
out << ")\n";
}
#endif
}

View file

@ -1,232 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smtlib.h
Abstract:
SMT library utilities
Author:
Nikolaj Bjorner (nbjorner) 2006-09-29
Revision History:
--*/
#ifndef _SMTLIB_H_
#define _SMTLIB_H_
#include "ast.h"
#include "symbol_table.h"
#include "map.h"
#include "arith_decl_plugin.h"
namespace smtlib {
class sort_builder {
public:
virtual ~sort_builder() {}
virtual bool apply(unsigned num_params, parameter const* params, sort_ref& result) = 0;
virtual char const* error_message() { return ""; }
};
class basic_sort_builder : public sort_builder {
sort* m_sort;
public:
basic_sort_builder(sort* s) : m_sort(s) {}
virtual bool apply(unsigned np, parameter const*, sort_ref& result) {
result = m_sort;
return m_sort && np != 0;
}
};
class symtable {
ast_manager& m_manager;
symbol_table<sort*> m_sorts1;
symbol_table<sort_builder*> m_sorts;
ptr_vector<sort_builder> m_sorts_trail;
symbol_table<ptr_vector<func_decl>* > m_ids;
public:
symtable(ast_manager& m): m_manager(m) {}
~symtable();
void reset();
void insert(symbol s, func_decl * d);
bool find(symbol s, ptr_vector<func_decl> * & decls) {
return m_ids.find(s, decls);
}
bool find1(symbol s, func_decl * & d);
bool find_overload(symbol s, ptr_vector<sort> const & dom, func_decl * & d);
void insert(symbol s, sort * d) {
sort * d2;
if (m_sorts1.find(s, d2)) {
m_manager.dec_ref(d2);
}
m_manager.inc_ref(d);
m_sorts1.insert(s, d);
}
bool find(symbol s, sort * & d) {
return m_sorts1.find(s, d);
}
void insert(symbol s, sort_builder* sb);
bool lookup(symbol s, sort_builder*& sb);
void push_sort(symbol s, sort*);
void pop_sorts(unsigned num_sorts);
void get_func_decls(ptr_vector<func_decl> & result) const;
void get_sorts(ptr_vector<sort>& result) const;
};
class theory {
public:
typedef ptr_vector<expr>::const_iterator expr_iterator;
theory(ast_manager & ast_manager, symbol const& name):
m_name(name),
m_ast_manager(ast_manager),
m_symtable(ast_manager),
m_asts(ast_manager)
{}
virtual ~theory() {}
symtable * get_symtable() { return &m_symtable; }
void insert(sort * s) { m_symtable.insert(s->get_name(), s); }
void insert(func_decl * c) { m_symtable.insert(c->get_name(), c); }
func_decl * declare_func(symbol const & id, sort_ref_buffer & domain, sort * range,
bool is_assoc, bool is_comm, bool is_inj);
sort * declare_sort(symbol const & id);
void add_axiom(expr * axiom) {
m_asts.push_back(axiom);
m_axioms.push_back(axiom);
}
expr_iterator begin_axioms() const {
return m_axioms.begin();
}
unsigned get_num_axioms() const {
return m_axioms.size();
}
expr * const * get_axioms() const {
return m_axioms.c_ptr();
}
expr_iterator end_axioms() const {
return m_axioms.end();
}
void add_assumption(expr * axiom) {
m_asts.push_back(axiom);
m_assumptions.push_back(axiom);
}
unsigned get_num_assumptions() const {
return m_assumptions.size();
}
expr * const * get_assumptions() const {
return m_assumptions.c_ptr();
}
bool get_func_decl(symbol, func_decl*&);
bool get_sort(symbol, sort*&);
bool get_const(symbol, expr*&);
void set_name(symbol const& name) { m_name = name; }
symbol const get_name() const { return m_name; }
protected:
symbol m_name;
ast_manager& m_ast_manager;
ptr_vector<expr> m_axioms;
ptr_vector<expr> m_assumptions;
symtable m_symtable;
ast_ref_vector m_asts;
private:
theory& operator=(theory const&);
theory(theory const&);
};
class benchmark : public theory {
public:
enum status {
UNKNOWN,
SAT,
UNSAT
};
benchmark(ast_manager & ast_manager, symbol const & name) :
theory(ast_manager, name),
m_status(UNKNOWN) {}
virtual ~benchmark() {}
status get_status() const { return m_status; }
void set_status(status status) { m_status = status; }
symbol get_logic() const {
if (m_logic == symbol::null) {
return symbol("ALL");
}
return m_logic;
}
void set_logic(symbol const & s) { m_logic = s; }
unsigned get_num_formulas() const {
return m_formulas.size();
}
expr_iterator begin_formulas() const {
return m_formulas.begin();
}
expr_iterator end_formulas() const {
return m_formulas.end();
}
void add_formula(expr * formula) {
m_asts.push_back(formula);
m_formulas.push_back(formula);
}
void display_as_smt2(std::ostream & out) const;
private:
status m_status;
symbol m_logic;
ptr_vector<expr> m_formulas;
};
};
#endif

View file

@ -1,115 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smtlib_solver.cpp
Abstract:
SMT based solver.
Author:
Nikolaj Bjorner (nbjorner) 2006-11-3.
Revision History:
--*/
#include"smtparser.h"
#include"smtlib_solver.h"
#include"warning.h"
#include"ast_pp.h"
#include"ast_ll_pp.h"
#include"well_sorted.h"
#include"model.h"
#include"model_v2_pp.h"
#include"solver.h"
#include"smt_strategic_solver.h"
#include"cmd_context.h"
namespace smtlib {
solver::solver(front_end_params & params):
m_ast_manager(params.m_proof_mode, params.m_trace_stream),
m_params(params),
m_ctx(0),
m_parser(parser::create(m_ast_manager, params.m_ignore_user_patterns)),
m_error_code(0) {
m_parser->initialize_smtlib();
}
solver::~solver() {
if (m_ctx)
dealloc(m_ctx);
}
bool solver::solve_smt(char const * benchmark_file) {
IF_VERBOSE(100, verbose_stream() << "parsing...\n";);
if (!m_parser->parse_file(benchmark_file)) {
if (benchmark_file) {
warning_msg("could not parse file '%s'.", benchmark_file);
}
else {
warning_msg("could not parse input stream.");
}
m_error_code = ERR_PARSER;
return false;
}
benchmark * benchmark = m_parser->get_benchmark();
solve_benchmark(*benchmark);
return true;
}
bool solver::solve_smt_string(char const * benchmark_string) {
if (!m_parser->parse_string(benchmark_string)) {
warning_msg("could not parse string '%s'.", benchmark_string);
return false;
}
benchmark * benchmark = m_parser->get_benchmark();
solve_benchmark(*benchmark);
return true;
}
void solver::display_statistics() {
if (m_ctx)
m_ctx->display_statistics();
}
void solver::solve_benchmark(benchmark & benchmark) {
if (benchmark.get_num_formulas() == 0) {
// Hack: it seems SMT-LIB allow benchmarks without any :formula
benchmark.add_formula(m_ast_manager.mk_true());
}
m_ctx = alloc(cmd_context, m_params, true, &m_ast_manager, benchmark.get_logic());
m_ctx->set_solver(mk_smt_strategic_solver(*m_ctx));
theory::expr_iterator fit = benchmark.begin_formulas();
theory::expr_iterator fend = benchmark.end_formulas();
for (; fit != fend; ++fit)
solve_formula(benchmark, *fit);
}
void solver::solve_formula(benchmark const & benchmark, expr * f) {
IF_VERBOSE(100, verbose_stream() << "starting...\n";);
m_ctx->reset();
for (unsigned i = 0; i < benchmark.get_num_axioms(); i++)
m_ctx->assert_expr(benchmark.get_axioms()[i]);
m_ctx->assert_expr(f);
m_ctx->check_sat(benchmark.get_num_assumptions(), benchmark.get_assumptions());
check_sat_result * r = m_ctx->get_check_sat_result();
if (r != 0) {
proof * pr = r->get_proof();
if (pr != 0 && m_params.m_display_proof)
std::cout << mk_ll_pp(pr, m_ast_manager, false, false);
model_ref md;
if (r->status() != l_false) r->get_model(md);
if (md.get() != 0 && m_params.m_model) {
model_v2_pp(std::cout, *(md.get()), m_params.m_model_partial);
}
}
else {
m_error_code = ERR_UNKNOWN_RESULT;
}
}
};

View file

@ -1,48 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smtlib_solver.h
Abstract:
SMT based solver.
Author:
Nikolaj Bjorner (nbjorner) 2006-11-3.
Revision History:
--*/
#ifndef _SMTLIB_SOLVER_H_
#define _SMTLIB_SOLVER_H_
#include"smtparser.h"
#include"front_end_params.h"
#include"lbool.h"
class cmd_context;
namespace smtlib {
class solver {
ast_manager m_ast_manager;
front_end_params & m_params;
cmd_context * m_ctx;
scoped_ptr<parser> m_parser;
unsigned m_error_code;
public:
solver(front_end_params & params);
~solver();
bool solve_smt(char const * benchmark_file);
bool solve_smt_string(char const * benchmark_string);
void display_statistics();
unsigned get_error_code() const { return m_error_code; }
private:
void solve_benchmark(benchmark & benchmark);
void solve_formula(benchmark const & benchmark, expr * f);
};
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,49 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smtparser.h
Abstract:
SMT parsing utilities
Author:
Nikolaj Bjorner (nbjorner) 2006-09-25
Revision History:
--*/
#ifndef _SMT_PARSER_H_
#define _SMT_PARSER_H_
#include<iostream>
#include"ast.h"
#include"vector.h"
#include"smtlib.h"
#include"z3.h"
namespace smtlib {
class parser {
public:
static parser * create(ast_manager & ast_manager, bool ignore_user_patterns = false);
virtual ~parser() {}
virtual void add_builtin_op(char const *, family_id fid, decl_kind kind) = 0;
virtual void add_builtin_type(char const *, family_id fid, decl_kind kind) = 0;
virtual void initialize_smtlib() = 0;
virtual void set_error_stream(std::ostream& strm) = 0;
virtual bool parse_file(char const * path) = 0;
virtual bool parse_string(char const * string) = 0;
virtual benchmark * get_benchmark() = 0;
};
};
#endif