3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

Reorganizing the code

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2012-10-20 22:44:27 -07:00
parent aa949693d4
commit 6bc591c67e
15 changed files with 4 additions and 2 deletions

94
src/ast/has_free_vars.cpp Normal file
View file

@ -0,0 +1,94 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
has_free_vars.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-06-23.
Revision History:
--*/
#include"ast.h"
#include"expr_delta_pair.h"
#include"hashtable.h"
class contains_vars {
typedef hashtable<expr_delta_pair, obj_hash<expr_delta_pair>, default_eq<expr_delta_pair> > cache;
cache m_cache;
svector<expr_delta_pair> m_todo;
bool m_contains;
unsigned m_window;
void visit(expr * n, unsigned delta, bool & visited) {
expr_delta_pair e(n, delta);
if (!m_cache.contains(e)) {
m_todo.push_back(e);
visited = false;
}
}
bool visit_children(expr * n, unsigned delta) {
bool visited = true;
unsigned dw;
unsigned j;
switch (n->get_kind()) {
case AST_VAR:
dw = m_window <= UINT_MAX - delta ? m_window + delta : UINT_MAX;
if (to_var(n)->get_idx() >= delta && to_var(n)->get_idx() <= dw)
m_contains = true;
break;
case AST_APP:
j = to_app(n)->get_num_args();
while (j > 0) {
--j;
visit(to_app(n)->get_arg(j), delta, visited);
}
break;
case AST_QUANTIFIER:
if (delta <= UINT_MAX - to_quantifier(n)->get_num_decls()) {
visit(to_quantifier(n)->get_expr(), delta + to_quantifier(n)->get_num_decls(), visited);
}
break;
default:
break;
}
return visited;
}
public:
// return true if n contains a variable in the range [begin, end]
bool operator()(expr * n, unsigned begin = 0, unsigned end = UINT_MAX) {
m_contains = false;
m_window = end - begin;
m_todo.reset();
m_cache.reset();
m_todo.push_back(expr_delta_pair(n, begin));
while (!m_todo.empty()) {
expr_delta_pair e = m_todo.back();
if (visit_children(e.m_node, e.m_delta)) {
m_cache.insert(e);
m_todo.pop_back();
}
if (m_contains) {
return true;
}
}
SASSERT(!m_contains);
return false;
}
};
bool has_free_vars(expr * n) {
contains_vars p;
return p(n);
}

27
src/ast/has_free_vars.h Normal file
View file

@ -0,0 +1,27 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
has_free_vars.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-06-23.
Revision History:
--*/
#ifndef _HAS_FREE_VARS_H_
#define _HAS_FREE_VARS_H_
class expr;
bool has_free_vars(expr * n);
#endif /* _HAS_FREE_VARS_H_ */

View file

@ -0,0 +1,121 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
extension_model_converter.cpp
Abstract:
Model converter that introduces eliminated variables in a model.
Author:
Leonardo (leonardo) 2011-10-21
Notes:
--*/
#include"extension_model_converter.h"
#include"model_evaluator.h"
#include"ast_smt2_pp.h"
#include"model_v2_pp.h"
#include"ast_pp.h"
extension_model_converter::~extension_model_converter() {
}
struct extension_model_converter::set_eval {
extension_model_converter * m_owner;
model_evaluator * m_old;
set_eval(extension_model_converter * owner, model_evaluator * ev) {
m_owner = owner;
m_old = owner->m_eval;
#pragma omp critical (extension_model_converter)
{
owner->m_eval = ev;
}
}
~set_eval() {
#pragma omp critical (extension_model_converter)
{
m_owner->m_eval = m_old;
}
}
};
static void display_decls_info(std::ostream & out, model_ref & md) {
ast_manager & m = md->get_manager();
unsigned sz = md->get_num_decls();
for (unsigned i = 0; i < sz; i++) {
func_decl * d = md->get_decl(i);
out << d->get_name();
out << " (";
for (unsigned j = 0; j < d->get_arity(); j++)
out << mk_pp(d->get_domain(j), m);
out << mk_pp(d->get_range(), m);
out << ") ";
if (d->get_info())
out << *(d->get_info());
out << " :id " << d->get_id() << "\n";
}
}
void extension_model_converter::operator()(model_ref & md, unsigned goal_idx) {
SASSERT(goal_idx == 0);
TRACE("extension_mc", model_v2_pp(tout, *md); display_decls_info(tout, md););
model_evaluator ev(*(md.get()));
ev.set_model_completion(true);
expr_ref val(m());
{
set_eval setter(this, &ev);
unsigned i = m_vars.size();
while (i > 0) {
--i;
expr * def = m_defs.get(i);
ev(def, val);
TRACE("extension_mc", tout << m_vars.get(i)->get_name() << " ->\n" << mk_ismt2_pp(def, m()) << "\n==>\n" << mk_ismt2_pp(val, m()) << "\n";);
func_decl * f = m_vars.get(i);
unsigned arity = f->get_arity();
if (arity == 0) {
md->register_decl(f, val);
}
else {
func_interp * new_fi = alloc(func_interp, m(), arity);
new_fi->set_else(val);
md->register_decl(f, new_fi);
}
}
}
TRACE("extension_mc", model_v2_pp(tout, *md); display_decls_info(tout, md););
}
void extension_model_converter::cancel() {
#pragma omp critical (extension_model_converter)
{
if (m_eval)
m_eval->cancel();
}
}
void extension_model_converter::display(std::ostream & out) {
ast_manager & m = m_vars.get_manager();
out << "(extension-model-converter";
for (unsigned i = 0; i < m_vars.size(); i++) {
out << "\n (" << m_vars.get(i)->get_name() << " ";
unsigned indent = m_vars.get(i)->get_name().size() + 4;
out << mk_ismt2_pp(m_defs.get(i), m, indent) << ")";
}
out << ")" << std::endl;
}
model_converter * extension_model_converter::translate(ast_translation & translator) {
extension_model_converter * res = alloc(extension_model_converter, translator.to());
for (unsigned i = 0; i < m_vars.size(); i++)
res->m_vars.push_back(translator(m_vars[i].get()));
for (unsigned i = 0; i < m_defs.size(); i++)
res->m_defs.push_back(translator(m_defs[i].get()));
// m_eval is a transient object. So, it doesn't need to be translated.
return res;
}

View file

@ -0,0 +1,57 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
extension_model_converter.h
Abstract:
Model converter that introduces new interpretations into a model.
It used to be called elim_var_model_converter
Author:
Leonardo (leonardo) 2011-10-21
Notes:
--*/
#ifndef _EXTENSION_MODEL_CONVERTER_H_
#define _EXTENSION_MODEL_CONVERTER_H_
#include"ast.h"
#include"model_converter.h"
class model_evaluator;
class extension_model_converter : public model_converter {
func_decl_ref_vector m_vars;
expr_ref_vector m_defs;
model_evaluator * m_eval;
struct set_eval;
public:
extension_model_converter(ast_manager & m):m_vars(m), m_defs(m), m_eval(0) {
}
virtual ~extension_model_converter();
ast_manager & m() const { return m_vars.get_manager(); }
virtual void operator()(model_ref & md, unsigned goal_idx);
virtual void cancel();
virtual void display(std::ostream & out);
// register a variable that was eliminated
void insert(func_decl * v, expr * def) {
m_vars.push_back(v);
m_defs.push_back(def);
}
virtual model_converter * translate(ast_translation & translator);
};
#endif

View file

@ -0,0 +1,66 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
filter_model_converter.cpp
Abstract:
Filter decls from a model
Author:
Leonardo (leonardo) 2011-05-06
Notes:
--*/
#include"filter_model_converter.h"
#include"model_v2_pp.h"
filter_model_converter::~filter_model_converter() {
}
void filter_model_converter::operator()(model_ref & old_model, unsigned goal_idx) {
TRACE("filter_mc", tout << "before filter_model_converter\n"; model_v2_pp(tout, *old_model); display(tout););
ast_fast_mark1 fs;
unsigned num = m_decls.size();
for (unsigned i = 0; i < num; i++)
fs.mark(m_decls.get(i));
model * new_model = alloc(model, m());
num = old_model->get_num_constants();
for (unsigned i = 0; i < num; i++) {
func_decl * f = old_model->get_constant(i);
if (fs.is_marked(f))
continue;
expr * fi = old_model->get_const_interp(f);
new_model->register_decl(f, fi);
}
num = old_model->get_num_functions();
for (unsigned i = 0; i < num; i++) {
func_decl * f = old_model->get_function(i);
if (fs.is_marked(f))
continue;
func_interp * fi = old_model->get_func_interp(f);
new_model->register_decl(f, fi->copy());
}
new_model->copy_usort_interps(*old_model);
old_model = new_model;
TRACE("filter_mc", tout << "after filter_model_converter\n"; model_v2_pp(tout, *old_model););
}
void filter_model_converter::display(std::ostream & out) {
out << "(filter-model-converter";
for (unsigned i = 0; i < m_decls.size(); i++) {
out << " " << m_decls.get(i)->get_name();
}
out << ")" << std::endl;
}
model_converter * filter_model_converter::translate(ast_translation & translator) {
filter_model_converter * res = alloc(filter_model_converter, translator.to());
for (unsigned i = 0; i < m_decls.size(); i++)
res->m_decls.push_back(translator(m_decls[i].get()));
return res;
}

View file

@ -0,0 +1,48 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
filter_model_converter.h
Abstract:
Filter decls from a model
Author:
Leonardo (leonardo) 2011-05-06
Notes:
--*/
#ifndef _FILTER_MODEL_CONVERTER_H_
#define _FILTER_MODEL_CONVERTER_H_
#include"model_converter.h"
class filter_model_converter : public model_converter {
func_decl_ref_vector m_decls;
public:
filter_model_converter(ast_manager & m):m_decls(m) {}
virtual ~filter_model_converter();
ast_manager & m() const { return m_decls.get_manager(); }
virtual void operator()(model_ref & md, unsigned goal_idx);
virtual void operator()(model_ref & md) { operator()(md, 0); } // TODO: delete
virtual void cancel() {}
virtual void display(std::ostream & out);
void insert(func_decl * d) {
m_decls.push_back(d);
}
virtual model_converter * translate(ast_translation & translator);
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
smt2parser.h
Abstract:
SMT 2.0 parser
Author:
Leonardo de Moura (leonardo) 2011-03-01
Revision History:
--*/
#ifndef _SMT2_PARSER_H_
#define _SMT2_PARSER_H_
#include"cmd_context.h"
bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive = false);
#endif

View file

@ -0,0 +1,355 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smt2scanner.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2011-03-09.
Revision History:
--*/
#include"smt2scanner.h"
namespace smt2 {
void scanner::next() {
if (m_cache_input)
m_cache.push_back(m_curr);
SASSERT(m_curr != EOF);
if (m_interactive) {
m_curr = m_stream.get();
}
else if (m_bpos < m_bend) {
m_curr = m_buffer[m_bpos];
m_bpos++;
}
else {
m_stream.read(m_buffer, SCANNER_BUFFER_SIZE);
m_bend = static_cast<unsigned>(m_stream.gcount());
m_bpos = 0;
if (m_bpos == m_bend) {
m_curr = EOF;
}
else {
m_curr = m_buffer[m_bpos];
m_bpos++;
}
}
m_spos++;
}
void scanner::read_comment() {
SASSERT(curr() == ';');
next();
while (true) {
char c = curr();
if (c == EOF)
return;
if (c == '\n') {
new_line();
next();
return;
}
next();
}
}
scanner::token scanner::read_quoted_symbol() {
SASSERT(curr() == '|');
bool escape = false;
m_string.reset();
next();
while (true) {
char c = curr();
if (c == EOF) {
throw scanner_exception("unexpected end of quoted symbol", m_line, m_spos);
}
else if (c == '\n') {
new_line();
}
else if (c == '|' && !escape) {
next();
m_string.push_back(0);
m_id = m_string.begin();
TRACE("scanner", tout << "new quoted symbol: " << m_id << "\n";);
return SYMBOL_TOKEN;
}
escape = (c == '\\');
m_string.push_back(c);
next();
}
}
scanner::token scanner::read_symbol_core() {
while (true) {
char c = curr();
char n = m_normalized[static_cast<unsigned char>(c)];
if (n == 'a' || n == '0' || n == '-') {
m_string.push_back(c);
next();
}
else {
m_string.push_back(0);
m_id = m_string.begin();
TRACE("scanner", tout << "new symbol: " << m_id << "\n";);
return SYMBOL_TOKEN;
}
}
}
scanner::token scanner::read_symbol() {
SASSERT(m_normalized[static_cast<unsigned>(curr())] == 'a' || curr() == ':' || curr() == '-');
m_string.reset();
m_string.push_back(curr());
next();
return read_symbol_core();
}
scanner::token scanner::read_number() {
SASSERT('0' <= curr() && curr() <= '9');
rational q(1);
m_number = rational(curr() - '0');
next();
bool is_float = false;
while (true) {
char c = curr();
if ('0' <= c && c <= '9') {
m_number = rational(10)*m_number + rational(c - '0');
if (is_float)
q *= rational(10);
next();
}
else if (c == '.') {
if (is_float)
break;
is_float = true;
next();
}
else {
break;
}
}
if (is_float)
m_number /= q;
TRACE("scanner", tout << "new number: " << m_number << "\n";);
return is_float ? FLOAT_TOKEN : INT_TOKEN;
}
scanner::token scanner::read_signed_number() {
SASSERT(curr() == '-');
next();
if ('0' <= curr() && curr() <= '9') {
scanner::token r = read_number();
m_number.neg();
return r;
}
else {
// it is a symbol.
m_string.reset();
m_string.push_back('-');
return read_symbol_core();
}
}
scanner::token scanner::read_string() {
SASSERT(curr() == '\"');
next();
m_string.reset();
while (true) {
char c = curr();
if (c == EOF)
throw scanner_exception("unexpected end of string", m_line, m_spos);
if (c == '\"') {
next();
m_string.push_back(0);
return STRING_TOKEN;
}
if (c == '\n')
new_line();
else if (c == '\\') {
next();
c = curr();
if (c == EOF)
throw scanner_exception("unexpected end of string", m_line, m_spos);
if (c != '\\' && c != '\"')
throw scanner_exception("invalid escape sequence", m_line, m_spos);
}
m_string.push_back(c);
next();
}
}
scanner::token scanner::read_bv_literal() {
SASSERT(curr() == '#');
next();
char c = curr();
if (c == 'x') {
next();
c = curr();
m_number = rational(0);
m_bv_size = 0;
while (true) {
if ('0' <= c && c <= '9') {
m_number *= rational(16);
m_number += rational(c - '0');
}
else if ('a' <= c && c <= 'f') {
m_number *= rational(16);
m_number += rational(10 + (c - 'a'));
}
else if ('A' <= c && c <= 'F') {
m_number *= rational(16);
m_number += rational(10 + (c - 'A'));
}
else {
if (m_bv_size == 0)
throw scanner_exception("invalid empty bit-vector literal", m_line, m_spos);
return BV_TOKEN;
}
m_bv_size += 4;
next();
c = curr();
}
}
else if (c == 'b') {
next();
c = curr();
m_number = rational(0);
m_bv_size = 0;
while (c == '0' || c == '1') {
m_number *= rational(2);
m_number += rational(c - '0');
m_bv_size++;
next();
c = curr();
}
if (m_bv_size == 0)
throw scanner_exception("invalid empty bit-vector literal", m_line, m_spos);
return BV_TOKEN;
}
else {
throw scanner_exception("invalid bit-vector literal, expecting 'x' or 'b'", m_line, m_spos);
}
}
scanner::scanner(cmd_context & ctx, std::istream& stream, bool interactive):
m_ctx(ctx),
m_interactive(interactive),
m_spos(0),
m_curr(0), // avoid Valgrind warning
m_line(1),
m_pos(0),
m_bv_size(UINT_MAX),
m_bpos(0),
m_bend(0),
m_stream(stream),
m_cache_input(false) {
for (int i = 0; i < 256; ++i) {
m_normalized[i] = (char) i;
}
m_normalized[static_cast<int>('\t')] = ' ';
m_normalized[static_cast<int>('\r')] = ' ';
// assert ('a' < 'z');
for (char ch = 'b'; ch <= 'z'; ++ch) {
m_normalized[static_cast<int>(ch)] = 'a';
}
for (char ch = 'A'; ch <= 'Z'; ++ch) {
m_normalized[static_cast<int>(ch)] = 'a';
}
// assert ('0' < '9', '9' - '0' == 9);
for (char ch = '1'; ch <= '9'; ++ch) {
m_normalized[static_cast<int>(ch)] = '0';
}
// SMT2 "Symbols": ~ ! @ $ % ^ & * _ - + = < > . ? /
m_normalized[static_cast<int>('~')] = 'a';
m_normalized[static_cast<int>('!')] = 'a';
m_normalized[static_cast<int>('@')] = 'a';
m_normalized[static_cast<int>('$')] = 'a';
m_normalized[static_cast<int>('%')] = 'a';
m_normalized[static_cast<int>('^')] = 'a';
m_normalized[static_cast<int>('&')] = 'a';
m_normalized[static_cast<int>('*')] = 'a';
m_normalized[static_cast<int>('_')] = 'a';
m_normalized[static_cast<int>('-')] = '-';
m_normalized[static_cast<int>('+')] = 'a';
m_normalized[static_cast<int>('=')] = 'a';
m_normalized[static_cast<int>('<')] = 'a';
m_normalized[static_cast<int>('>')] = 'a';
m_normalized[static_cast<int>('.')] = 'a';
m_normalized[static_cast<int>('?')] = 'a';
m_normalized[static_cast<int>('/')] = 'a';
next();
}
scanner::token scanner::scan() {
while (true) {
char c = curr();
m_pos = m_spos;
switch (m_normalized[(unsigned char) c]) {
case ' ':
next();
break;
case '\n':
next();
new_line();
break;
case ';':
read_comment();
break;
case ':':
read_symbol();
return KEYWORD_TOKEN;
case '(':
next();
return LEFT_PAREN;
case ')':
next();
return RIGHT_PAREN;
case '|':
return read_quoted_symbol();
case 'a':
return read_symbol();
case '"':
return read_string();
case '0':
return read_number();
case '#':
return read_bv_literal();
case '-':
if (m_ctx.is_smtlib2_compliant())
return read_symbol();
else
return read_signed_number();
case -1:
return EOF_TOKEN;
default: {
scanner_exception ex("unexpected character", m_line, m_spos);
next();
throw ex;
}}
}
}
char const * scanner::cached_str(unsigned begin, unsigned end) {
m_cache_result.reset();
while (isspace(m_cache[begin]) && begin < end)
begin++;
while (begin < end && isspace(m_cache[end-1]))
end--;
for (unsigned i = begin; i < end; i++)
m_cache_result.push_back(m_cache[i]);
m_cache_result.push_back(0);
return m_cache_result.begin();
}
};

View file

@ -0,0 +1,108 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smt2scanner.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2011-03-09.
Revision History:
--*/
#ifndef _SMT2SCANNER_H_
#define _SMT2SCANNER_H_
#include<iostream>
#include"symbol.h"
#include"vector.h"
#include"rational.h"
#include"cmd_context.h"
namespace smt2 {
typedef cmd_exception scanner_exception;
class scanner {
private:
cmd_context & m_ctx;
bool m_interactive;
int m_spos; // position in the current line of the stream
char m_curr; // current char;
int m_line; // line
int m_pos; // start position of the token
// data
symbol m_id;
rational m_number;
unsigned m_bv_size;
// end of data
char m_normalized[256];
#define SCANNER_BUFFER_SIZE 1024
char m_buffer[SCANNER_BUFFER_SIZE];
unsigned m_bpos;
unsigned m_bend;
svector<char> m_string;
std::istream& m_stream;
bool m_cache_input;
svector<char> m_cache;
svector<char> m_cache_result;
char curr() const { return m_curr; }
void new_line() { m_line++; m_spos = 0; }
void next();
public:
enum token {
NULL_TOKEN = 0,
LEFT_PAREN = 1,
RIGHT_PAREN,
KEYWORD_TOKEN,
SYMBOL_TOKEN,
STRING_TOKEN,
INT_TOKEN,
BV_TOKEN,
FLOAT_TOKEN,
EOF_TOKEN
};
scanner(cmd_context & ctx, std::istream& stream, bool interactive = false);
~scanner() {}
int get_line() const { return m_line; }
int get_pos() const { return m_pos; }
symbol const & get_id() const { return m_id; }
rational get_number() const { return m_number; }
unsigned get_bv_size() const { return m_bv_size; }
char const * get_string() const { return m_string.begin(); }
token scan();
token read_symbol_core();
token read_symbol();
token read_quoted_symbol();
void read_comment();
token read_number();
token read_signed_number();
token read_string();
token read_bv_literal();
void start_caching() { m_cache_input = true; m_cache.reset(); }
void stop_caching() { m_cache_input = false; }
unsigned cache_size() const { return m_cache.size(); }
void reset_cache() { m_cache.reset(); }
char const * cached_str(unsigned begin, unsigned end);
};
};
#endif /* _SCANNER_H_ */