Commits

Leonardo de Moura committed 6c4e163 Merge

Merge branch 'unstable' of https://git01.codeplex.com/z3 into unstable

Comments (0)

Files changed (89)

scripts/config-vs-debug.mk

 CXX=cl
-CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- 
+CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- /arch:SSE2
 CXX_OUT_FLAG=/Fo
 OBJ_EXT=.obj
 LIB_EXT=.lib

scripts/mk_make.py

 add_lib('cmd_context', ['tactic', 'rewriter', 'model', 'old_params', 'simplifier'])
 add_lib('substitution', ['ast'], 'ast/substitution')
 add_lib('normal_forms', ['rewriter', 'old_params'], 'ast/normal_forms')
-add_lib('parser_util', ['ast'])
-add_lib('smt2parser', ['cmd_context', 'parser_util'])
+add_lib('parser_util', ['ast'], 'parsers/util')
+add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2')
 add_lib('pattern', ['normal_forms', 'smt2parser'], 'ast/pattern')
 add_lib('macros', ['simplifier', 'old_params'], 'ast/macros')
 add_lib('grobner', ['ast'], 'math/grobner')
 add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv')
 add_lib('portfolio', ['smtlogic_tactics', 'ufbv_tactic', 'fpa', 'aig', 'muz_qe', 'sls_tactic', 'subpaving_tactic'], 'tactic/portfolio')
 # TODO: delete SMT 1.0 frontend
-add_lib('api', ['portfolio', 'user_plugin'])
+add_lib('smtparser', ['portfolio'], 'parsers/smt')
+add_lib('api', ['portfolio', 'user_plugin', 'smtparser'])
 add_exe('shell', ['api', 'sat', 'extra_cmds'], exe_name='z3')
 add_exe('test', ['api', 'fuzzing'], exe_name='test-z3')
 API_files = ['z3_api.h']

src/api/api_parsers.cpp

 #include"cmd_context.h"
 #include"smt2parser.h"
 #include"smtparser.h"
-#include"z3_solver.h"
 
 extern "C" {
 
         return mk_c(c)->m_smtlib_error_buffer.c_str();
         Z3_CATCH_RETURN("");
     }
-    
-    Z3_ast parse_z3_stream(Z3_context c, std::istream& is) {
-        z3_solver parser(c, is, verbose_stream(), mk_c(c)->fparams(), false);
-        if (!parser.parse()) {
-            SET_ERROR_CODE(Z3_PARSER_ERROR);
-            return of_ast(mk_c(c)->m().mk_true());
-        }
-        expr_ref_vector assumptions(mk_c(c)->m());
-        parser.get_assumptions(assumptions);
-        return of_ast(mk_c(c)->mk_and(assumptions.size(), assumptions.c_ptr()));
-    }
-
-    Z3_ast Z3_API Z3_parse_z3_string(Z3_context c, Z3_string str) { 
-        Z3_TRY;
-        LOG_Z3_parse_z3_string(c, str);
-        std::string s(str);
-        std::istringstream is(s);
-        Z3_ast r = parse_z3_stream(c, is);
-        RETURN_Z3(r);
-        Z3_CATCH_RETURN(0);
-    }
-
-    Z3_ast Z3_API Z3_parse_z3_file(Z3_context c, Z3_string file_name) {
-        Z3_TRY;
-        LOG_Z3_parse_z3_file(c, file_name);
-        std::ifstream is(file_name);
-        if (!is) {
-            SET_ERROR_CODE(Z3_PARSER_ERROR);
-            return 0;
-        }
-        Z3_ast r = parse_z3_stream(c, is);
-        RETURN_Z3(r);
-        Z3_CATCH_RETURN(0);
-    }
 
     // ---------------
     // Support for SMTLIB2

src/api/smtlib.cpp

-
-#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
-}

src/api/smtlib.h

-/*++
-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

src/api/smtlib_solver.cpp

-/*++
-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;
-        }
-    }
-};

src/api/smtlib_solver.h

-/*++
-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

src/api/smtparser.cpp

-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
-    smtparser.cpp
-
-Abstract:
-
-    SMT parser into ast.
-
-Author:
-
-    Nikolaj Bjorner (nbjorner) 2006-10-4.
-    Leonardo de Moura (leonardo) 
-
-Revision History:
---*/
-
-#include<iostream>
-#include<istream>
-#include<fstream>
-#include<sstream>
-#include<signal.h>
-#include"region.h"
-#include"scanner.h"
-#include"symbol.h"
-#include"vector.h"
-#include"symbol_table.h"
-#include"smtlib.h"
-#include"smtparser.h"
-#include"ast_pp.h"
-#include"bv_decl_plugin.h"
-#include"array_decl_plugin.h"
-#include"datatype_decl_plugin.h"
-#include"warning.h"
-#include"error_codes.h"
-#include"pattern_validation.h"
-#include"unifier.h"
-#include"timeit.h"
-#include"var_subst.h"
-#include"well_sorted.h"
-#include "str_hashtable.h"
-#include "front_end_params.h"
-#include "stopwatch.h"
-front_end_params& Z3_API Z3_get_parameters(Z3_context c);
-
-class id_param_info {
-    symbol    m_string;
-    unsigned  m_num_params;
-    parameter m_params[0];
-public:
-    id_param_info(symbol const& s, unsigned n, parameter const* p) : m_string(s), m_num_params(n) {
-        for (unsigned i = 0; i < n; ++i) {
-            new (&(m_params[i])) parameter();
-            m_params[i] = p[i];
-        }
-    }
-    symbol string() const { return m_string; }
-    parameter * params() { return m_params; }
-    unsigned num_params() const { return m_num_params; }
-};
-
-class proto_region {
-    ptr_vector<rational>            m_rationals;
-    ptr_vector< id_param_info >     m_id_infos;
-    region                          m_region;
-public:
-    proto_region() { }
-
-    ~proto_region() { reset(); }
-
-    rational* allocate(rational const & n) { 
-        rational* r = alloc(rational, n); 
-        m_rationals.push_back(r);
-        return r;
-    }
-
-    id_param_info* allocate(vector<parameter> const& params, symbol const & s) {
-        unsigned size = sizeof(id_param_info) + sizeof(parameter)*(params.size());
-        id_param_info* r = static_cast<id_param_info*>(m_region.allocate(size));
-        new (r) id_param_info(s, params.size(), params.c_ptr());
-        m_id_infos.push_back(r);
-        return r;
-    }
-
-    void* allocate(size_t s) { return m_region.allocate(s); }
-
-    void reset() {
-        for (unsigned i = 0; i < m_rationals.size(); ++i) {
-            dealloc(m_rationals[i]);
-        }
-        for (unsigned i = 0; i < m_id_infos.size(); ++i) {
-            unsigned n = m_id_infos[i]->num_params();
-            for (unsigned j = 0; j < n; ++j) {
-                m_id_infos[i]->params()[j].~parameter();
-            }
-        }
-        m_rationals.reset();
-        m_id_infos.reset();
-        m_region.reset();
-    }
-
-private:
-
-};
-
-inline void * operator new(size_t s, proto_region& r) { return r.allocate(s); }
-inline void * operator new[](size_t s, proto_region & r) { return r.allocate(s); }
-inline void operator delete(void*, proto_region& r) {}
-inline void operator delete[](void *, proto_region& r) {}
-
-class proto_expr {
-public:
-
-    enum kind_t {
-        ID,
-        STRING,
-        COMMENT,
-        ANNOTATION,
-        INT,
-        FLOAT,
-        CONS
-    };
-private:
-
-    int      m_kind:8;
-    int      m_line:24;
-    int      m_pos;
-    union {
-        id_param_info* m_id_info;
-        rational*      m_number;
-        proto_expr**   m_children;
-    };
-
-public:
-
-    symbol string() { 
-        if (m_kind == INT || m_kind == FLOAT) {
-            std::string s = m_number->to_string();
-            return symbol(s.c_str());
-        }
-        if (m_kind == CONS) {
-            return symbol("");
-        }
-        SASSERT(m_kind == STRING || m_kind == COMMENT || m_kind == ID || m_kind == ANNOTATION);
-        return m_id_info->string(); 
-    }
-
-    rational const& number() { 
-        SASSERT(m_kind == INT || m_kind == FLOAT);
-        return *m_number; 
-    }
-
-    proto_expr* const* children() const { 
-        if (m_kind == CONS) {
-            return m_children; 
-        }
-        else {
-            return 0;
-        }
-    }
-
-    int line() { return m_line; }
-    int pos() { return m_pos; }
-    kind_t kind() { return static_cast<kind_t>(m_kind); }
-
-    unsigned num_params() const { 
-        SASSERT(m_kind == ID); 
-        return m_id_info->num_params();
-    }
-    
-    parameter *  params() { 
-        SASSERT(m_kind == ID); 
-        return m_id_info->params();
-    }
-
-    proto_expr(proto_region & region, kind_t kind, symbol const & s, vector<parameter> const & params, int line, int pos): 
-        m_kind(kind),
-        m_line(line),
-        m_pos(pos),
-        m_id_info(region.allocate(params, s)) {
-        SASSERT(kind != CONS);
-        SASSERT(kind != INT);
-        SASSERT(kind != FLOAT);
-    }
-
-    proto_expr(proto_region& region, bool is_int, rational const & n, int line, int pos): 
-        m_kind(is_int?INT:FLOAT),
-        m_line(line),
-        m_pos(pos),
-        m_number(region.allocate(n))
-    {}
-
-    proto_expr(proto_region& region, ptr_vector<proto_expr>& proto_exprs, int line, int pos): 
-        m_kind(CONS),
-        m_line(line),
-        m_pos(pos) {
-        //
-        // null terminated list of proto_expression pointers.
-        //
-        unsigned num_children = proto_exprs.size();
-        m_children = new (region) proto_expr*[num_children+1];
-        for (unsigned i = 0; i < num_children; ++i) {
-            m_children[i] = proto_exprs[i];
-        }
-        m_children[num_children] = 0;
-    }
-
-    ~proto_expr() {}
-   
-
-    static proto_expr* copy(proto_region& r, proto_expr* e) {
-        switch(e->kind()) {
-        case proto_expr::CONS: {
-            ptr_vector<proto_expr> args;
-            proto_expr* const* children = e->children();
-            while (children && *children) {
-                args.push_back(copy(r, *children));
-                ++children;
-            }
-            return new (r) proto_expr(r, args, e->line(), e->pos());
-        }
-        case proto_expr::INT: {
-            return new (r) proto_expr(r, true, e->number(), e->line(), e->pos());
-        }
-        case proto_expr::FLOAT: {
-            return new (r) proto_expr(r, false, e->number(), e->line(), e->pos());
-        }
-        case proto_expr::ID: {
-            vector<parameter> params; 
-            for (unsigned i = 0; i < e->num_params(); ++i) {
-                params.push_back(e->params()[i]);
-            }
-            return new (r) proto_expr(r, e->kind(), e->string(), params, e->line(), e->pos());
-        }
-        default: {
-            vector<parameter> params; 
-            return new (r) proto_expr(r, e->kind(), e->string(), params, e->line(), e->pos());
-        }
-        }
-    }
- 
-private:
-
-    proto_expr(proto_expr const & other); 
-    proto_expr& operator=(proto_expr const & other);    
-};
-
-
-//
-// build up proto_expr tree from token stream.
-// 
-
-class proto_expr_parser {
-    proto_region&  m_region;
-    scanner&      m_scanner;
-    std::ostream& m_err;
-    bool          m_at_eof;
-public:
-    proto_expr_parser(proto_region& region, scanner& scanner, std::ostream& err):
-        m_region(region),
-        m_scanner(scanner),
-        m_err(err), 
-        m_at_eof(false) {
-    }
-
-    ~proto_expr_parser() {}
-
-    bool parse(ptr_vector<proto_expr> & proto_exprs, bool parse_single_expr = false) {
-        scanner::token   token;
-        vector<frame>    stack;
-        proto_expr* result = 0;
-        
-        stack.push_back(frame(PROTO_EXPRS_PRE));
-
-        token = m_scanner.scan();
-
-        if (token == scanner::EOF_TOKEN) {
-            proto_exprs.reset();
-            return true;
-        }
-        
-        while (!stack.empty()) {
-
-            if (token == scanner::EOF_TOKEN) {
-                break;
-            }
-
-            if (token == scanner::ERROR_TOKEN) {
-                print_error("unexpected token");
-                goto done;
-            }
-
-            switch(stack.back().m_state) {
-
-            case PROTO_EXPR:
-                switch (token) {
-                case scanner::LEFT_PAREN:
-                    stack.back().m_state = PROTO_EXPRS_PRE;
-                    token = m_scanner.scan();
-                    break;
-                default:
-                    stack.back().m_state = ATOM;
-                    break;
-                }
-                break;
-
-            case ATOM: 
-                SASSERT(!result);
-                switch(token) {
-                case scanner::ID_TOKEN:
-                    result = new (m_region) proto_expr(m_region, proto_expr::ID, m_scanner.get_id(), m_scanner.get_params(),
-                                                       m_scanner.get_line(), m_scanner.get_pos());
-                    break;
-                case scanner::INT_TOKEN:
-                    result = new (m_region) proto_expr(m_region, true, m_scanner.get_number(), m_scanner.get_line(), 
-                                                       m_scanner.get_pos());
-                    break;
-                case scanner::FLOAT_TOKEN:
-                    result = new (m_region) proto_expr(m_region, false, m_scanner.get_number(), m_scanner.get_line(), 
-                                                       m_scanner.get_pos());
-                    break;
-                case scanner::STRING_TOKEN:
-                    result = new (m_region) proto_expr(m_region, proto_expr::STRING, m_scanner.get_id(), m_scanner.get_params(), 
-                                                       m_scanner.get_line(), m_scanner.get_pos());
-                    break;
-                case scanner::COMMENT_TOKEN:
-                    result = new (m_region) proto_expr(m_region, proto_expr::COMMENT, m_scanner.get_id(), m_scanner.get_params(),
-                                                       m_scanner.get_line(), m_scanner.get_pos());
-                    break;
-                case scanner::COLON:
-                    token = m_scanner.scan();
-                    if (token == scanner::ID_TOKEN) {
-                        result = new (m_region) proto_expr(m_region, proto_expr::ANNOTATION, m_scanner.get_id(), 
-                                                           m_scanner.get_params(), m_scanner.get_line(), m_scanner.get_pos());
-                    }
-                    else {
-                        print_error("unexpected identifier ':'");
-                        token = scanner::ERROR_TOKEN;
-                        goto done;
-                    }
-                    break;
-                default:
-                    print_error("unexpected token");
-                    token = scanner::ERROR_TOKEN;
-                    goto done;
-                }
-                stack.pop_back();
-                SASSERT(!stack.empty());
-                stack.back().m_proto_exprs.push_back(result);
-                result = 0;
-                if (parse_single_expr && stack.size() == 1) {
-                    goto done;
-                }
-                token = m_scanner.scan();               
-                break;
-
-            case PROTO_EXPRS_PRE:
-                SASSERT(!result);
-                switch(token) {
-                case scanner::RIGHT_PAREN:
-                    result = new (m_region) proto_expr(m_region, stack.back().m_proto_exprs, m_scanner.get_line(), 
-                                                       m_scanner.get_pos());
-                    stack.pop_back();
-                    
-                    if (stack.empty()) {
-                        print_error("unexpected right parenthesis");
-                        token = scanner::ERROR_TOKEN;
-                        result = 0;
-                        goto done;
-                    }
-                    stack.back().m_proto_exprs.push_back(result);
-                    if (parse_single_expr && stack.size() == 1) {
-                        goto done;
-                    }
-                    result = 0;
-                    token = m_scanner.scan();
-                    break;
-
-                case scanner::EOF_TOKEN:
-                    m_at_eof = true;
-                    break;
-
-                case scanner::ERROR_TOKEN:                    
-                    print_error("could not parse expression");
-                    goto done;
-
-                default:
-                    stack.back().m_state = PROTO_EXPRS_POST;
-                    stack.push_back(frame(PROTO_EXPR));
-                    break;
-                }
-                break;
-
-            case PROTO_EXPRS_POST:
-                stack.back().m_state = PROTO_EXPRS_PRE;
-                break;
-            }
-        }
-
-    done:
-
-        if (stack.size() == 1) {
-            for (unsigned i = 0; i < stack.back().m_proto_exprs.size(); ++i) {
-                proto_exprs.push_back(stack.back().m_proto_exprs[i]);
-            }
-            return true;
-        }
-
-        if (stack.size() == 2) {
-            proto_exprs.push_back(new (m_region) proto_expr(m_region, stack.back().m_proto_exprs, m_scanner.get_line(), 
-                                                            m_scanner.get_pos()));
-            return true;
-        }
-        
-        print_error("unexpected nesting of parenthesis: ", stack.size());
-        return false;
-    }    
-
-    int get_line() {
-        return m_scanner.get_line();
-    }
-
-    bool at_eof() const {
-        return m_at_eof;
-    }
-
-private:
-
-    template<typename T>
-    void print_error(char const* msg1, T msg2) {
-        m_err << "ERROR: line " << m_scanner.get_line() 
-              << " column " << m_scanner.get_pos() << ": " 
-              << msg1 << msg2 << "\n";
-    }
-
-    void print_error(char const* msg) {
-        print_error(msg, "");
-    }
-
-    // stack frame:
-    enum frame_state {
-        PROTO_EXPR,
-        PROTO_EXPRS_PRE,
-        PROTO_EXPRS_POST,
-        ATOM
-    };
-
-    class frame {
-    public:
-        frame_state m_state;
-        ptr_vector<proto_expr> m_proto_exprs;
-        frame(frame_state state): 
-            m_state(state){            
-        }
-        frame(frame const & other):
-            m_state(other.m_state),
-            m_proto_exprs(other.m_proto_exprs) {
-        }
-    private:
-        frame& operator=(frame const &);
-    };
-
-};
-
-enum smt_cmd_token {
-    SMT_CMD_SET_LOGIC,            // logic-name
-    SMT_CMD_DECLARE_SORTS,        // sorts-symbols
-    SMT_CMD_DECLARE_FUNS,         // func-decls
-    SMT_CMD_DECLARE_PREDS,        // pred-decls
-    SMT_CMD_DECLARE_DATATYPES,    // datatypes
-    SMT_CMD_DEFINE,               // var expr
-    SMT_CMD_DEFINE_SORTS,         // (var sort)*
-    SMT_CMD_DECLARE_SORT,         // <symbol> <numeral>
-    SMT_CMD_DEFINE_SORT,          // <symbol> (<symbol>*) <sort>
-    SMT_CMD_DECLARE_FUN,          // <symbol> (<sort>*) <sort>
-    SMT_CMD_DECLARE_CONST,        // <symbol> <sort>
-    SMT_CMD_DEFINE_FUN,           // <symbol> (<sorted_var>*) <sort> <term>
-    SMT_CMD_GET_VALUE,            // (<term>+)
-    
-    SMT_CMD_PUSH,                 // numeral
-    SMT_CMD_POP,                  // numeral
-    SMT_CMD_ASSERT,               // expr
-    SMT_CMD_CHECK_SAT,            // 
-    SMT_CMD_GET_CORE,             // expr+
-    SMT_CMD_NEXT_SAT,
-    SMT_CMD_SIMPLIFY,             // expr
-    SMT_CMD_GET_IMPLIED_EQUALITIES, // expr*
-    SMT_CMD_EVAL,                 // expr
-    SMT_CMD_GET_ASSERTIONS,       // string
-    SMT_CMD_GET_SAT_ASSERTIONS,   // string
-    SMT_CMD_KEEP_SAT_ASSERTIONS,  // 
-    SMT_CMD_GET_UNSAT_CORE,       // string
-    SMT_CMD_GET_PROOF,            // string
-    SMT_CMD_SET_OPTION,           // string strings
-    SMT_CMD_GET_INFO,             // string
-    SMT_CMD_SET_INFO,             // string strings
-    SMT_CMD_ECHO,                 // string strings
-    SMT_CMD_EXIT,                 // 
-    // set-option:
-    SMT_CMD_PRINT_SUCCESS,
-    SMT_CMD_RANDOM_SEED,
-    SMT_CMD_VERBOSITY,
-    SMT_CMD_EXPAND_DEFINITIONS,
-    SMT_CMD_OUTPUT_CHANNEL,
-    SMT_CMD_VERBOSE_OUTPUT_CHANNEL,
-    SMT_CMD_ENABLE_CORES,
-    SMT_CMD_SET_PARAM,
-    SMT_CMD_PRODUCE_MODELS,
-    // set-info:
-    SMT_CMD_NAME,
-    SMT_CMD_VERSION,
-    SMT_CMD_AUTHORS,
-    SMT_CMD_LAST_FAILURE,
-    SMT_CMD_REASON_UNKNOWN,
-    SMT_CMD_STATS,
-    SMT_CMD_MODEL,
-    SMT_CMD_TIME,  
-    SMT_CMD_LABELS,
-    SMT_CMD_HELP,                 // help
-
-    SMT_CMD_ERROR                 // error token        
-};
-
-
-using namespace smtlib;
-
-class idbuilder {
-public:
-    virtual ~idbuilder() {}
-    virtual bool apply(expr_ref_vector const & args, expr_ref & result) = 0;
-};
-
-class builtin_sort_builder : public sort_builder {
-    ast_manager& m_manager;
-    family_id    m_fid;
-    decl_kind    m_kind;
-public:
-    builtin_sort_builder(ast_manager& m, family_id fid, decl_kind k) : 
-        m_manager(m), m_fid(fid), m_kind(k) {}
-
-    virtual bool apply(unsigned num_params, parameter const* params, sort_ref & result) {
-        result = m_manager.mk_sort(m_fid, m_kind, num_params, params);
-        return result.get() != 0;
-    }   
-};
-
-class array_sort : public builtin_sort_builder {
-public:
-    array_sort(ast_manager& m) : 
-        builtin_sort_builder(m, m.get_family_id("array"), ARRAY_SORT) {}
-};
-
-class bv_sort : public builtin_sort_builder {
-public:
-    bv_sort(ast_manager& m) : 
-        builtin_sort_builder(m, m.get_family_id("bv"), BV_SORT) {}
-};
-
-class user_sort : public sort_builder {    
-    user_sort_plugin *  m_plugin;
-    decl_kind           m_kind;
-    symbol              m_name;
-    unsigned            m_num_args;
-    std::string         m_error_message;
-public:
-    user_sort(ast_manager& m, unsigned num_args, symbol name): 
-        m_name(name),
-        m_num_args(num_args) {
-        m_plugin = m.get_user_sort_plugin();
-        m_kind = m_plugin->register_name(name);
-    }
-    
-    ~user_sort() {}
-    
-    virtual bool apply(unsigned num_params, parameter const* params, sort_ref & result) {
-        if (num_params != m_num_args) {
-            std::ostringstream strm;
-            strm << "wrong number of arguments passed to " << m_name << " " 
-                 << m_num_args << " expected, but " << num_params << " given";
-            m_error_message = strm.str();
-            return false;
-        }
-        result = m_plugin->mk_sort(m_kind, num_params, params);
-        return true;
-    }
-
-    virtual char const* error_message() {
-        return m_error_message.c_str();
-    }
-};
-
-
-
-
-class scoped_stream {
-    std::ostream& m_default;
-    std::ostream* m_stream;
-    bool m_owned;
-public:
-
-    scoped_stream(std::ostream& strm) : m_default(strm) {
-        m_stream = &strm;
-        m_owned = false;
-    }
-
-    scoped_stream(proto_expr* e) : m_default(std::cout), m_stream(0), m_owned(false) {
-        reset(e, 0);
-    }
-
-    scoped_stream(proto_expr* e, std::ostream& out) : m_default(out), m_stream(0), m_owned(false) {
-        reset(e, &out);
-    }
-    
-    ~scoped_stream() {
-        dealloc_stream();
-    }
-
-    void reset(proto_expr* e, std::ostream* out = 0) {
-        char const* name = (e && e->kind() == proto_expr::ID)?e->string().bare_str():0;
-        reset(name, out);
-    }
-
-    void reset(char const* name, std::ostream* out = 0) {
-        dealloc_stream();
-        m_owned = false;
-        if (!out) {
-            out = &m_default;
-        }
-        if (!name) {
-            m_stream = out;
-        }
-        else if (strcmp(name, "stdout")) {
-            m_stream = &std::cout;
-        }
-        else if (strcmp(name, "stderr")) {
-            m_stream = &std::cerr;
-        }
-        else {
-            m_stream = alloc(std::ofstream, name, std::ios_base::app);
-            m_owned = true;
-            if (m_stream->bad() || m_stream->fail()) {
-                dealloc(m_stream);
-                m_stream = out;
-                m_owned = false;
-            }
-        }
-        SASSERT(m_stream);
-    }
-
-    std::ostream& operator*() {
-        return *m_stream;
-    }
-
-private:
-    void dealloc_stream() {
-        if (m_owned) {
-            m_stream->flush();
-            dealloc(m_stream);
-        }
-        m_stream = 0;
-        m_owned = false;
-    }
-};
-
-class cmd_exn {
-    Z3_error_code m_code;
-public:
-    cmd_exn(Z3_error_code code) : m_code(code) {}
-    Z3_error_code get() const { return m_code; }
-};
-
-static void* g_sw = 0;
-
-#define cmd_context _cmd_context
-
-class cmd_context {
-    typedef map<char const *, smt_cmd_token, str_hash_proc, str_eq_proc> str2token;
-    str2token               m_str2token;
-    ptr_vector<char const>  m_token2str;
-    ptr_vector<char const>  m_token2help;
-    ptr_vector<char const>  m_token2args;
-    svector<bool>           m_is_command;
-
-    struct cmd_info {
-        smt_cmd_token m_token;
-        void        (*m_action)(cmd_context&);
-        cmd_info(smt_cmd_token t, void (*action)(cmd_context&)): 
-            m_token(t), m_action(action) {}
-    };
-
-    struct opt {
-        smt_cmd_token m_token;
-        bool        (*m_action)(cmd_context&, proto_expr* const* exprs);
-        opt(smt_cmd_token t,  bool (*action)(cmd_context&, proto_expr* const* exprs)): 
-            m_token(t), m_action(action) {}
-    };
-
-    enum check_sat_state {
-        state_unsat,
-        state_sat,
-        state_unknown,
-        state_clear,
-        state_new_assertion
-    };
-
-    Z3_context               m_context;
-    Z3_model                 m_model;
-    Z3_ast                   m_proof;
-    ast_manager&             m_manager;
-    scoped_stream            m_out;
-    scoped_stream            m_verbose;
-    symbol_table<idbuilder*> m_table;
-    region                   m_region;
-    ast_ref_vector           m_trail;
-    unsigned_vector          m_trail_lim;
-    expr_ref_vector          m_asserted;
-    unsigned_vector          m_asserted_lim;
-    expr_ref_vector          m_asserted_proxies;
-    unsigned_vector          m_asserted_proxies_lim;
-    bool                     m_print_success;
-    bool                     m_enable_cores;
-    unsigned                 m_core_size;
-    svector<Z3_ast>          m_core;
-    check_sat_state          m_check_sat_state;
-    svector<check_sat_state> m_check_sat_states;
-    stopwatch                m_watch;
-    svector<cmd_info>        m_infos;
-    svector<opt>             m_options;
-    std::ostringstream       m_error_stream;
-    
-    smtlib::benchmark::status m_status;
-    
-public:
-
-    cmd_context(ast_manager& m, Z3_context ctx, std::istream& is, std::ostream& out):
-        m_context(ctx), 
-        m_model(0),
-        m_proof(0),
-        m_manager(m),
-        m_out(out),
-        m_verbose(std::cerr),
-        m_trail(m),
-        m_asserted(m),
-        m_asserted_proxies(m),
-        m_print_success(Z3_get_parameters(ctx).m_smtlib2_compliant),
-        m_enable_cores(false),
-        m_core_size(0),
-        m_check_sat_state(state_clear),
-        m_status(smtlib::benchmark::UNKNOWN)
-    {
-        add_command("set-logic",     
-                    SMT_CMD_SET_LOGIC,     
-                    "<string>", "set the background logic");
-        add_command("declare-sorts", 
-                    SMT_CMD_DECLARE_SORTS, 
-                    "<sort declarations>", "declare sorts");
-        add_command("declare-funs",  
-                    SMT_CMD_DECLARE_FUNS, 
-                    "<function and constant declarations>", 
-                    "declare functions and constants");
-        add_command("declare-preds", 
-                    SMT_CMD_DECLARE_PREDS, 
-                    "<predicate declarations>", 
-                    "declare predicates");
-        add_command("declare-datatypes", 
-                    SMT_CMD_DECLARE_DATATYPES, 
-                    "<data type declarations>", 
-                    "declare recursive datatypes");
-        add_command("define",        
-                    SMT_CMD_DEFINE,        
-                    "<id> <expression> or (<id> (<id> <sort>)*) <expression>", 
-                    "define an expression shorthand");
-        add_command("define-sorts",
-                    SMT_CMD_DEFINE_SORTS,
-                    "(<id> <sort>)*",
-                    "define shorthand for compound sorts, such as arrays");
-
-        add_command("declare-sort", 
-                    SMT_CMD_DECLARE_SORT, 
-                    "<sort declaration>", "declare sort");
-        add_command("define-sort",
-                    SMT_CMD_DEFINE_SORT,
-                    "<symbol> (<symbol>*) <sort>",
-                    "define shorthand for compound sorts, such as arrays");
-        add_command("declare-fun",  
-                    SMT_CMD_DECLARE_FUN, 
-                    "<symbol> (<sort>*) <sort>", 
-                    "declare function or constant");
-        add_command("declare-const",  
-                    SMT_CMD_DECLARE_CONST, 
-                    "<symbol> <sort>", 
-                    "declare constant");
-        add_command("define-fun",        
-                    SMT_CMD_DEFINE_FUN,        
-                    "<symbol> (<sorted_var>*) <sort> <term>",
-                    "define an expression shorthand");
-        add_command("get-value",
-                    SMT_CMD_GET_VALUE,
-                    "(<term>+)",
-                    "evaluate list of terms");
-
-
-        add_command("push",          
-                    SMT_CMD_PUSH,          
-                    "[<number>]", 
-                    "push 1 (or <number>) scopes");
-        add_command("pop",           
-                    SMT_CMD_POP,           
-                    "[<number>]", 
-                    "pop 1 (or <number>) scopes");
-        add_command("assert",        
-                    SMT_CMD_ASSERT,        
-                    "<expression>", 
-                    "assert expression");
-        add_command("check-sat",     
-                    SMT_CMD_CHECK_SAT,     
-                    "<boolean-constants>*", 
-                    "check if the current context is satisfiable. If a list of boolean constants B is provided, then check if the current context is consistent with assigning every constant in B to true.");
-        add_command("get-core",     
-                    SMT_CMD_GET_CORE,
-                    "<boolean-constants>+", 
-                    "check if the assumptions are consistent with the current context");
-        add_command("next-sat",     
-                    SMT_CMD_NEXT_SAT,     
-                    "", 
-                    "get the next satisfying assignment");
-        add_command("simplify",      
-                    SMT_CMD_SIMPLIFY,      
-                    "<expression>", 
-                    "simplify expression and print back result");
-        add_command("get-implied-equalities",
-                    SMT_CMD_GET_IMPLIED_EQUALITIES,
-                    "<expression>*",
-                    "obtain list of identifiers for expressions, such that equal expressions have the same identfiers"
-                    );
-        add_command("eval",
-                    SMT_CMD_EVAL,
-                    "<expression>",
-                    "evaluate expression using the current model and print back result");
-        add_command("get-assertions", 
-                    SMT_CMD_GET_ASSERTIONS, 
-                    "[<file>]", 
-                    "retrieve current assertions");
-        add_command("get-sat-assertions", 
-                    SMT_CMD_GET_SAT_ASSERTIONS, 
-                    "[<file>]", 
-                    "retrieve current satisfying assignment");
-        add_command("keep-sat-assertions", 
-                    SMT_CMD_KEEP_SAT_ASSERTIONS, 
-                    "", 
-                    "assert current satisfying assignment");
-        add_command("get-unsat-core", 
-                    SMT_CMD_GET_UNSAT_CORE, 
-                    "[<file>]", 
-                    "retrieve unsatisfiable core of assertions");
-        add_command("get-proof",      
-                    SMT_CMD_GET_PROOF,      
-                    "[<file>]", 
-                    "retrieve proof");
-        add_command("set-option",     
-                    SMT_CMD_SET_OPTION,     
-                    "<strings>", 
-                    "set auxiliary options");
-        add_command("set-info",     
-                    SMT_CMD_SET_INFO,     
-                    "<attribute> <strings>", 
-                    "set auxiliary information");
-        add_command("get-info",       
-                    SMT_CMD_GET_INFO,       
-                    "<attribute>", 
-                    "retrieve auxiliary information");
-        add_command("echo",       
-                    SMT_CMD_ECHO,
-                    "<strings>", 
-                    "display the given strings");
-        add_command("exit",           
-                    SMT_CMD_EXIT,           
-                    "",         
-                    "exit Z3 session");
-        m_str2token.insert("quit", SMT_CMD_EXIT);
-        add_option("print-success",  
-                   SMT_CMD_PRINT_SUCCESS,  
-                   "[<bool>]",
-                   "toggle printing success",
-                   &print_success_option);
-        add_option("verbosity",      
-                   SMT_CMD_VERBOSITY,
-                   "<numeral>",
-                   "set verbosity",
-                   &verbosity_option);
-        add_option("regular-output-channel", 
-                   SMT_CMD_OUTPUT_CHANNEL,  
-                   "[<file>]",
-                   "set name of alternate output channel",
-                   &output_channel_option);
-        add_option("enable-cores",   
-                   SMT_CMD_ENABLE_CORES,
-                   "",
-                   "enable core extraction during solving",
-                   &enable_cores_option);
-        add_option("set-param",
-                   SMT_CMD_SET_PARAM,
-                   "<param-id> <param-value>",
-                   "update a mutable configuration parameter",
-                   &update_param_option);
-
-        add_option("verbose-output-channel", 
-                   SMT_CMD_VERBOSE_OUTPUT_CHANNEL, 
-                   "<file>", 
-                   "set output channel",
-                   &set_verbose_output_channel_option
-                   );
-        add_option("produce-models",
-                    SMT_CMD_PRODUCE_MODELS,
-                   "[<bool>]",
-                   "toggle model generation",
-                   &produce_models_option);
-        //
-        // other options:
-        // add_option("random-seed",    SMT_CMD_RANDOM_SEED,  0, "");
-        // add_option("expand-definitions",SMT_CMD_EXPAND_DEFINITIONS, 0, "");
-        // "produce-proofs"
-        // "produce-models"
-        // "produce-assignments"
-        //
-
-        add_info("name",           
-                 SMT_CMD_NAME, 
-                 "",
-                 "solver name",
-                 &name_info
-                 );
-        add_info("version",        
-                 SMT_CMD_VERSION,
-                 "",
-                 "solver version",
-                 &version_info
-                 );
-        add_info("authors",        
-                 SMT_CMD_AUTHORS,
-                 "",
-                 "solver authors",
-                 &authors_info);
-        add_info("statistics",          
-                 SMT_CMD_STATS,           
-                 "",
-                 "search statistics",
-                 &stats_info);
-        add_info("all-statistics",          
-                 SMT_CMD_STATS,           
-                 "",
-                 "search statistics",
-                 &stats_info);
-        add_info("model",          
-                 SMT_CMD_MODEL,   
-                 "",
-                 "model from satisfied assertions",
-                 &model_info
-                 );
-        add_info("last-failure",   
-                 SMT_CMD_LAST_FAILURE, 
-                 "",
-                 "reason for previous search failure",
-                 &last_failure_info
-                 );
-        add_info("reason-unknown",   
-                 SMT_CMD_REASON_UNKNOWN,
-                 "",
-                 "reason for previous unknown answer; 'memout' for out of memory, 'incomplete' for everything else",
-                 &reason_unknown_info
-                 );
-        add_info("time",           
-                 SMT_CMD_TIME,     
-                 "",
-                 "time taken by solver",
-                 &time_info
-                 );
-        add_info("labels",         
-                 SMT_CMD_LABELS,   
-                 "",
-                 "retrieve (Boogie) labels from satisfiable assertion",
-                 &labels_info);
-        add_info("help",           
-                 SMT_CMD_HELP,           
-                 "", 
-                 "print this help",
-                 &help_info);
-
-
-
-#ifdef _EXTERNAL_RELEASE
-        Z3_set_ast_print_mode(m_context, Z3_PRINT_SMTLIB2_COMPLIANT);
-#else
-        // use internal pretty printer
-        Z3_set_ast_print_mode(m_context, Z3_PRINT_SMTLIB_FULL);
-        // Z3_set_ast_print_mode(m_context, Z3_PRINT_SMTLIB2_COMPLIANT);
-#endif
-        Z3_set_error_handler(m_context, error_handler);
-        set_error_stream(&m_error_stream);
-        set_warning_stream(&m_error_stream);
-    }
-    
-    ~cmd_context() {
-        if (m_model) {
-            Z3_del_model(m_context, m_model);
-        }
-        set_error_stream(0);
-        set_warning_stream(0);
-    }
-
-    //
-    // NB. As it is now, the symbol table used in m_benchmark is not
-    // scoped. Declarations just live on or get over-written.
-    // 
-    void push(unsigned num_scopes) {
-        while (num_scopes > 0) {
-            m_table.begin_scope();
-            m_region.push_scope();
-            Z3_push(m_context);
-            m_trail_lim.push_back(m_trail.size());
-            m_asserted_lim.push_back(m_asserted.size());
-            m_asserted_proxies_lim.push_back(m_asserted_proxies.size());
-            --num_scopes;
-            m_check_sat_states.push_back(m_check_sat_state);
-        }
-    }
-    void pop(unsigned num_scopes) {
-        if (m_trail_lim.size() < num_scopes) {
-            num_scopes = m_trail_lim.size();
-        }
-        Z3_pop(m_context, num_scopes);
-        m_region.pop_scope(num_scopes);
-        while (num_scopes > 0) {
-            m_table.end_scope();
-            --num_scopes;
-            m_trail.resize(m_trail_lim.back());
-            m_trail_lim.pop_back();
-            m_asserted.resize(m_asserted_lim.back());
-            m_asserted_lim.pop_back();
-            m_asserted_proxies.resize(m_asserted_proxies_lim.back());
-            m_asserted_proxies_lim.pop_back();
-            m_check_sat_state = m_check_sat_states.back();
-            m_check_sat_states.pop_back();
-        }
-        m_proof = 0;
-        m_core_size = 0;
-    }
-
-    static void error_handler(Z3_context, Z3_error_code code) {
-        throw cmd_exn(code);
-    }
-    
-    symbol_table<idbuilder*>& get_table() { return m_table; }
-
-    Z3_context get_context() { return m_context; }
-
-    std::ostream& get_out() { return *m_out; }
-
-    void print_quoted(const char* str) { get_out() << "\"" << str << "\""; }
-
-    void set_out(proto_expr* e) { m_out.reset(e); }
-
-    void add_trail(ast* a) { m_trail.push_back(a); }
-
-    void add_asserted(expr* e) { 
-        if (get_enable_cores()) {
-            expr* proxy = m_manager.mk_fresh_const("proxy", m_manager.mk_bool_sort());
-            expr_ref imp(m_manager);
-            // It is not necessary to use iff (it is just overhead). 
-            imp = m_manager.mk_implies(proxy, e);
-            TRACE("proxy", tout << "new proxy:\n " << mk_pp(imp, m_manager) << "\n";);
-            Z3_assert_cnstr(m_context, reinterpret_cast<Z3_ast>(imp.get()));
-            m_asserted_proxies.push_back(proxy);            
-        }
-        else {
-            Z3_assert_cnstr(m_context, reinterpret_cast<Z3_ast>(e));
-        }
-        m_asserted.push_back(e); 
-        if (m_check_sat_state != state_unsat) {
-            m_check_sat_state = state_new_assertion;
-        }
-    }
-   
-    unsigned get_num_assertions() const { return m_asserted.size(); }
-
-    expr* get_assertion(unsigned idx) { return m_asserted[idx].get(); }
-
-    Z3_ast* get_proxies_ptr() { return reinterpret_cast<Z3_ast*>(m_asserted_proxies.c_ptr()); }
-
-    unsigned* get_core_size_ptr() { return &m_core_size; }
-
-    Z3_ast* get_core_ptr() { 
-        m_core.resize(m_asserted_proxies.size());
-        if (m_core_size > m_core.size()) {
-            m_core_size = m_core.size();
-        }
-        return m_core.c_ptr();
-    }       
-
-    region& get_region() { return m_region; }
-    
-
-    void set_print_success(bool b) { m_print_success = b; }
-
-    void set_enable_cores() { m_enable_cores = true; }    
-
-    void unset_enable_cores() { m_enable_cores = false; }    
-
-    void update_param(char const* p, char const* v) {
-        Z3_update_param_value(m_context, p, v);
-    }
-
-    bool get_enable_cores() const { return m_enable_cores; }
-
-    void print_success() {
-        if (m_print_success) {
-            *m_out << "success\n";
-        }
-    }
-
-    void print_unsupported() {
-        *m_out << "unsupported\n";
-    }
-    
-    void print_failure(char const* msg, proto_expr* expr) {
-        if (Z3_get_parameters(m_context).m_display_error_for_vs) {
-            if (msg[0] != 'Z' || msg[1] != '3') {
-                *m_out << "Z3";
-                if (expr) {
-                    *m_out << "(" << expr->line() << "," << expr->pos() << ")";
-                }           
-                *m_out << ": ERROR: ";
-            }
-            *m_out << msg;
-            if (msg[strlen(msg)-1] != '\n') {
-                *m_out << "\n";
-            }
-        }
-        else {
-            *m_out << "(error \"";
-            if (expr) {
-                *m_out << "line " << expr->line() << " column " << expr->pos() << ": ";
-            }
-            *m_out << escaped(msg, true) << "\")\n";
-#ifndef _EXTERNAL_RELEASE
-            exit(ERR_PARSER);
-#endif
-        }
-    }
-
-    Z3_model* get_model_ptr() { 
-        if (m_model) {
-            Z3_del_model(m_context, m_model);
-            m_model = 0;
-        }
-        return &m_model;
-    }
-
-    Z3_model get_model() { return m_model; }
-    
-    Z3_ast* get_proof_ptr() {
-        m_proof = 0;
-        return &m_proof;
-    }
-    
-    void get_proof(std::ostream& out, proto_expr* p_expr) { 
-        Z3_ast pr = m_proof;
-        if (pr) {
-            out << Z3_ast_to_string(m_context, pr) << "\n";       
-        }
-        else if (Z3_get_parameters(m_context).m_proof_mode == PGM_DISABLED) {
-            print_failure("proofs are disabled - enable them using the configuration PROOF_MODE={1,2}", p_expr);
-        }
-        else {                
-            print_failure("there is no proof to display", p_expr);
-        }
-    }
-
-    smt_cmd_token string2token(char const * str) {
-        str2token::entry * e = m_str2token.find_core(str);
-        if (e)
-            return e->get_data().m_value;
-        else
-            return SMT_CMD_ERROR;
-    }
-
-    class scoped_stopwatch {
-        cmd_context& m_ctx;
-        bool         m_first;
-        void        (*m_old_handler)(int);
-
-        static scoped_stopwatch* get_sw() { return static_cast<scoped_stopwatch*>(g_sw); }        
-
-        static void on_ctrl_c(int) {
-            if (get_sw()->m_first) {
-                Z3_soft_check_cancel(get_sw()->m_ctx.get_context());
-                get_sw()->m_first = false;
-            }
-            else {
-                signal (SIGINT, get_sw()->m_old_handler); 
-                raise (SIGINT);
-            }
-        }
-    public:
-        scoped_stopwatch(cmd_context& c) : m_ctx(c), m_first(true) { 
-            g_sw = this;
-            c.m_watch.reset();
-            c.m_watch.start(); 
-            m_old_handler = signal(SIGINT, on_ctrl_c); // TBD: parallel?
-        }
-        ~scoped_stopwatch() { 
-            m_ctx.m_watch.stop();
-            if (m_old_handler != SIG_ERR) {
-                signal(SIGINT, m_old_handler);
-            }
-        }
-    };
-
-    //static scoped_stopwatch* g_sw = 0;
-
-    double get_seconds() { 
-        return m_watch.get_seconds(); 
-    }
-
-    bool get_command_help(std::ostream& out, smt_cmd_token tok) {
-        if (!m_is_command[tok]) {
-            return false;
-        }
-        out << " (" << m_token2str[tok];
-        if (m_token2args[tok] && m_token2args[tok][0]) {
-            out << " " << m_token2args[tok];
-        }
-        out << ")\n";
-        out << "    " << m_token2help[tok] << "\n\n";
-        return true;
-    }
-
-    void get_help(std::ostream& out) {
-        out << "\" available commands:\n\n";
-        for (unsigned i = 0; i < m_token2args.size(); ++i) {
-            get_command_help(out, static_cast<smt_cmd_token>(i));
-        }
-        get_info_help(out, " ");
-        out << "\n";
-        set_option_help(out, " ");
-        out << "\"";
-    }
-
-    bool get_info(smt_cmd_token tok) {
-        for (unsigned i = 0; i < m_infos.size(); ++i) {
-            if (m_infos[i].m_token == tok) {                
-                get_out() << ":" << m_token2str[tok] << " ";
-                m_infos[i].m_action(*this);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    void get_info_help(std::ostream& strm, char const* line_start) {
-        for (unsigned i = 0; i < m_infos.size(); ++i) {
-            smt_cmd_token tok = m_infos[i].m_token;
-            strm << line_start << "(get-info " << m_token2str[tok];
-            if (m_token2args[tok] && m_token2args[tok][0]) {
-                strm << " " << m_token2args[tok];
-            }
-            strm << ")\n";
-            strm << line_start << "   " << m_token2help[tok] << "\n";            
-        }   
-    }
-
-    bool set_option(smt_cmd_token tok, proto_expr* const* chs) {
-        for (unsigned i = 0; i < m_options.size(); ++i) {
-            if (m_options[i].m_token == tok) {
-                return m_options[i].m_action(*this, chs);
-            }
-        }
-        return update_param_option(*this, chs-1);
-        // return false;        
-    }
-
-    bool set_info(proto_expr* e0, proto_expr* const* chs) {
-        proto_expr* e1 = chs[0];
-        symbol s0, s1;
-        if (e0)
-            s0 = e0->string();
-        if (e1)
-            s1 = e1->string();
-
-        if (s0 == symbol("status") && s1 == symbol("sat")) {
-            m_status = smtlib::benchmark::SAT;
-        }
-        else if (s0 == symbol("status") && s1 == symbol("unsat")) {
-            m_status = smtlib::benchmark::UNSAT;
-        }
-        else if (s0 == symbol("status") && s1 == symbol("unknown")) {
-            m_status = smtlib::benchmark::UNKNOWN;
-        }          
-        else {
-#ifdef Z3DEBUG
-            std::cout << s0 << " " << s1 << "\n";
-#endif
-        }
-        
-        // :source
-        // :smt-lib-version
-        // :category
-        // :status
-        // no-op
-        return true;
-    }
-
-    void set_option_help(std::ostream& strm, char const* line_start) {
-        for (unsigned i = 0; i < m_options.size(); ++i) {
-            smt_cmd_token tok = m_options[i].m_token;
-            strm << line_start << "(set-option " << m_token2str[tok];
-            if (m_token2args[tok] && m_token2args[tok][0]) {
-                get_out() << " " << m_token2args[tok];
-            }