diff --git a/src/api/api_interp.cpp b/src/api/api_interp.cpp index 00503566e..622c7cf94 100644 --- a/src/api/api_interp.cpp +++ b/src/api/api_interp.cpp @@ -42,6 +42,20 @@ Revision History: using namespace stl_ext; #endif +#ifndef WIN32 +// WARNING: don't make a hash_map with this if the range type +// has a destructor: you'll get an address dependency!!! +namespace stl_ext { + template <> + class hash { + public: + size_t operator()(const Z3_ast p) const { + return (size_t) p; + } + }; +} +#endif + typedef interpolation_options_struct *Z3_interpolation_options; extern "C" { diff --git a/src/duality/duality.h b/src/duality/duality.h index ebf6c8632..7729d2175 100644 --- a/src/duality/duality.h +++ b/src/duality/duality.h @@ -1008,6 +1008,29 @@ private: }; } + +// Allow to hash on nodes and edges in deterministic way + +namespace stl_ext { + template <> + class hash { + public: + size_t operator()(const Duality::RPFP::Node *p) const { + return p->number; + } + }; +} + +namespace stl_ext { + template <> + class hash { + public: + size_t operator()(const Duality::RPFP::Edge *p) const { + return p->number; + } + }; +} + // allow to walk sets of nodes without address dependency namespace std { diff --git a/src/duality/duality_wrapper.h b/src/duality/duality_wrapper.h index 256560d02..a36f93b40 100755 --- a/src/duality/duality_wrapper.h +++ b/src/duality/duality_wrapper.h @@ -1419,7 +1419,8 @@ namespace std { class less { public: bool operator()(const Duality::func_decl &s, const Duality::func_decl &t) const { - return s.raw() < t.raw(); // s.raw()->get_id() < t.raw()->get_id(); + // return s.raw() < t.raw(); + return s.raw()->get_id() < t.raw()->get_id(); } }; } diff --git a/src/interp/iz3base.h b/src/interp/iz3base.h index 30ac57bae..e19ae894d 100755 --- a/src/interp/iz3base.h +++ b/src/interp/iz3base.h @@ -146,7 +146,14 @@ class iz3base : public iz3mgr, public scopes { ranges(){scope_computed = false;} }; - stl_ext::hash_map sym_range_hash; + // We only use this for sym_range_hash, which has no range destructor + struct symb_hash { + size_t operator()(const symb &s) const { + return (size_t) s; + } + }; + + stl_ext::hash_map sym_range_hash; stl_ext::hash_map ast_ranges_hash; stl_ext::hash_map simplify_memo; stl_ext::hash_map frame_map; // map assertions to frames diff --git a/src/interp/iz3foci.cpp b/src/interp/iz3foci.cpp index 85e090c5b..fe20f1372 100755 --- a/src/interp/iz3foci.cpp +++ b/src/interp/iz3foci.cpp @@ -51,7 +51,14 @@ public: typedef hash_map NodeToAst; NodeToAst node_to_ast; // maps Z3 ast's to foci expressions - typedef hash_map FuncDeclToSymbol; + // We only use this for FuncDeclToSymbol, which has no range destructor + struct symb_hash { + size_t operator()(const symb &s) const { + return (size_t) s; + } + }; + + typedef hash_map FuncDeclToSymbol; FuncDeclToSymbol func_decl_to_symbol; // maps Z3 func decls to symbols typedef hash_map SymbolToFuncDecl; diff --git a/src/interp/iz3hash.h b/src/interp/iz3hash.h index f6767c037..75d9aa604 100755 --- a/src/interp/iz3hash.h +++ b/src/interp/iz3hash.h @@ -141,6 +141,7 @@ namespace std { #ifndef WIN32 +#if 0 namespace stl_ext { template class hash { @@ -150,6 +151,7 @@ namespace stl_ext { } }; } +#endif #endif diff --git a/src/interp/iz3mgr.h b/src/interp/iz3mgr.h index 39c14c724..645c72ccb 100644 --- a/src/interp/iz3mgr.h +++ b/src/interp/iz3mgr.h @@ -65,7 +65,7 @@ class ast_i { return _ast == other._ast; } bool lt(const ast_i &other) const { - return _ast < other._ast; + return _ast->get_id() < other._ast->get_id(); } friend bool operator==(const ast_i &x, const ast_i&y){ return x.eq(y); @@ -76,7 +76,7 @@ class ast_i { friend bool operator<(const ast_i &x, const ast_i&y){ return x.lt(y); } - size_t hash() const {return (size_t)_ast;} + size_t hash() const {return _ast->get_id();} bool null() const {return !_ast;} }; diff --git a/src/interp/iz3pp.cpp b/src/interp/iz3pp.cpp index 1f9351453..df6fcaf53 100644 --- a/src/interp/iz3pp.cpp +++ b/src/interp/iz3pp.cpp @@ -40,6 +40,20 @@ Revision History: using namespace stl_ext; #endif +#ifndef WIN32 +// We promise not to use this for hash_map with range destructor +namespace stl_ext { + template <> + class hash { + public: + size_t operator()(const expr *p) const { + return (size_t) p; + } + }; +} +#endif + + // TBD: algebraic data-types declarations will not be printed. class free_func_visitor { ast_manager& m; diff --git a/src/interp/iz3translate.cpp b/src/interp/iz3translate.cpp index fae914292..88e4f1174 100755 --- a/src/interp/iz3translate.cpp +++ b/src/interp/iz3translate.cpp @@ -619,7 +619,14 @@ public: return 1; } - void symbols_out_of_scope_rec(hash_set &memo, hash_set &symb_memo, int frame, const ast &t){ + // We only use this for debugging purposes + struct symb_hash { + size_t operator()(const symb &s) const { + return (size_t) s; + } + }; + + void symbols_out_of_scope_rec(hash_set &memo, hash_set &symb_memo, int frame, const ast &t){ if(memo.find(t) != memo.end()) return; memo.insert(t); @@ -638,7 +645,7 @@ public: void symbols_out_of_scope(int frame, const ast &t){ hash_set memo; - hash_set symb_memo; + hash_set symb_memo; symbols_out_of_scope_rec(memo,symb_memo,frame,t); } diff --git a/src/interp/iz3translate_direct.cpp b/src/interp/iz3translate_direct.cpp index 44c907d1d..eaef956b7 100755 --- a/src/interp/iz3translate_direct.cpp +++ b/src/interp/iz3translate_direct.cpp @@ -37,6 +37,24 @@ Revision History: using namespace stl_ext; #endif +#ifndef WIN32 + +/* This can introduce an address dependency if the range type of hash_map has + a destructor. Since the code in this file is not used and only here for + historical comparisons, we allow this non-determinism. + */ +namespace stl_ext { + template + class hash { + public: + size_t operator()(const T *p) const { + return (size_t) p; + } + }; +} + +#endif + static int lemma_count = 0; static int nll_lemma_count = 0;