mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-29 18:52:29 +00:00 
			
		
		
		
	merge unstable into opt
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
						commit
						e6725b2344
					
				
					 78 changed files with 695 additions and 350 deletions
				
			
		|  | @ -455,7 +455,7 @@ def display_help(exit_code): | ||||||
|         print("  -v, --vsproj                  generate Visual Studio Project Files.") |         print("  -v, --vsproj                  generate Visual Studio Project Files.") | ||||||
|     if IS_WINDOWS: |     if IS_WINDOWS: | ||||||
|         print("  -n, --nodotnet                do not generate Microsoft.Z3.dll make rules.") |         print("  -n, --nodotnet                do not generate Microsoft.Z3.dll make rules.") | ||||||
|     print("  -j, --java                    generate Java bindinds.") |     print("  -j, --java                    generate Java bindings.") | ||||||
|     print("  --staticlib                   build Z3 static library.") |     print("  --staticlib                   build Z3 static library.") | ||||||
|     if not IS_WINDOWS: |     if not IS_WINDOWS: | ||||||
|         print("  -g, --gmp                     use GMP.") |         print("  -g, --gmp                     use GMP.") | ||||||
|  | @ -587,7 +587,7 @@ def set_z3py_dir(p): | ||||||
|         raise MKException("Python bindings directory '%s' does not exist" % full) |         raise MKException("Python bindings directory '%s' does not exist" % full) | ||||||
|     Z3PY_SRC_DIR = full |     Z3PY_SRC_DIR = full | ||||||
|     if VERBOSE: |     if VERBOSE: | ||||||
|         print("Python bindinds directory was detected.") |         print("Python bindings directory was detected.") | ||||||
| 
 | 
 | ||||||
| _UNIQ_ID = 0 | _UNIQ_ID = 0 | ||||||
| 
 | 
 | ||||||
|  | @ -1151,7 +1151,11 @@ class DotNetDLLComponent(Component): | ||||||
|                 out.write(' ') |                 out.write(' ') | ||||||
|                 out.write(cs_file) |                 out.write(cs_file) | ||||||
|             out.write('\n') |             out.write('\n') | ||||||
|             out.write('  csc /noconfig /unsafe+ /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:mscorlib.dll /reference:System.Core.dll /reference:System.dll /reference:System.Numerics.dll /debug+ /debug:full /filealign:512 /optimize- /linkresource:%s.dll /out:%s.dll /target:library' % (get_component(Z3_DLL_COMPONENT).dll_name, self.dll_name)) |             out.write('  csc /noconfig /unsafe+ /nowarn:1701,1702 /nostdlib+ /errorreport:prompt /warn:4 /reference:mscorlib.dll /reference:System.Core.dll /reference:System.dll /reference:System.Numerics.dll /filealign:512 /linkresource:%s.dll /out:%s.dll /target:library /doc:%s.xml' % (get_component(Z3_DLL_COMPONENT).dll_name, self.dll_name, self.dll_name)) | ||||||
|  |             if DEBUG_MODE: | ||||||
|  |                 out.write(' /define:DEBUG;TRACE /debug+ /debug:full /optimize-') | ||||||
|  |             else: | ||||||
|  |                 out.write(' /optimize+') | ||||||
|             if VS_X64: |             if VS_X64: | ||||||
|                 out.write(' /platform:x64') |                 out.write(' /platform:x64') | ||||||
|             else: |             else: | ||||||
|  | @ -1174,6 +1178,13 @@ class DotNetDLLComponent(Component): | ||||||
|             mk_dir(os.path.join(dist_path, 'bin')) |             mk_dir(os.path.join(dist_path, 'bin')) | ||||||
|             shutil.copy('%s.dll' % os.path.join(build_path, self.dll_name), |             shutil.copy('%s.dll' % os.path.join(build_path, self.dll_name), | ||||||
|                         '%s.dll' % os.path.join(dist_path, 'bin', self.dll_name)) |                         '%s.dll' % os.path.join(dist_path, 'bin', self.dll_name)) | ||||||
|  |             shutil.copy('%s.xml' % os.path.join(build_path, self.dll_name), | ||||||
|  |                         '%s.xml' % os.path.join(dist_path, 'bin', self.dll_name)) | ||||||
|  |             if DEBUG_MODE: | ||||||
|  |                 shutil.copy('%s.pdb' % os.path.join(build_path, self.dll_name), | ||||||
|  |                             '%s.pdb' % os.path.join(dist_path, 'bin', self.dll_name)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     def mk_unix_dist(self, build_path, dist_path): |     def mk_unix_dist(self, build_path, dist_path): | ||||||
|         # Do nothing |         # Do nothing | ||||||
|  | @ -2511,7 +2522,11 @@ def mk_vs_proj(name, components): | ||||||
|     f.write('    <ClCompile>\n') |     f.write('    <ClCompile>\n') | ||||||
|     f.write('      <Optimization>Disabled</Optimization>\n') |     f.write('      <Optimization>Disabled</Optimization>\n') | ||||||
|     f.write('      <PreprocessorDefinitions>WIN32;_DEBUG;Z3DEBUG;_TRACE;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n') |     f.write('      <PreprocessorDefinitions>WIN32;_DEBUG;Z3DEBUG;_TRACE;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n') | ||||||
|     f.write('      <MinimalRebuild>true</MinimalRebuild>\n') |     if VS_PAR: | ||||||
|  |         f.write('      <MinimalRebuild>false</MinimalRebuild>\n') | ||||||
|  |         f.write('      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n') | ||||||
|  |     else: | ||||||
|  |         f.write('      <MinimalRebuild>true</MinimalRebuild>\n') | ||||||
|     f.write('      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n') |     f.write('      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n') | ||||||
|     f.write('      <WarningLevel>Level3</WarningLevel>\n') |     f.write('      <WarningLevel>Level3</WarningLevel>\n') | ||||||
|     f.write('      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n') |     f.write('      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n') | ||||||
|  | @ -2545,7 +2560,11 @@ def mk_vs_proj(name, components): | ||||||
|     f.write('    <ClCompile>\n') |     f.write('    <ClCompile>\n') | ||||||
|     f.write('      <Optimization>Disabled</Optimization>\n') |     f.write('      <Optimization>Disabled</Optimization>\n') | ||||||
|     f.write('      <PreprocessorDefinitions>WIN32;_NDEBUG;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n') |     f.write('      <PreprocessorDefinitions>WIN32;_NDEBUG;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n') | ||||||
|     f.write('      <MinimalRebuild>true</MinimalRebuild>\n') |     if VS_PAR: | ||||||
|  |         f.write('      <MinimalRebuild>false</MinimalRebuild>\n') | ||||||
|  |         f.write('      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n') | ||||||
|  |     else: | ||||||
|  |         f.write('      <MinimalRebuild>true</MinimalRebuild>\n') | ||||||
|     f.write('      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n') |     f.write('      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n') | ||||||
|     f.write('      <WarningLevel>Level3</WarningLevel>\n') |     f.write('      <WarningLevel>Level3</WarningLevel>\n') | ||||||
|     f.write('      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n') |     f.write('      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n') | ||||||
|  |  | ||||||
|  | @ -420,7 +420,7 @@ def mk_dotnet(): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| NULLWrapped = [ 'Z3_mk_context', 'Z3_mk_context_rc' ] | NULLWrapped = [ 'Z3_mk_context', 'Z3_mk_context_rc' ] | ||||||
| Unwrapped = [ 'Z3_del_context' ] | Unwrapped = [ 'Z3_del_context', 'Z3_get_error_code' ] | ||||||
| 
 | 
 | ||||||
| def mk_dotnet_wrappers(): | def mk_dotnet_wrappers(): | ||||||
|     global Type2Str |     global Type2Str | ||||||
|  |  | ||||||
|  | @ -129,6 +129,7 @@ namespace api { | ||||||
|             for (unsigned i = 0; i < m_replay_stack.size(); ++i) { |             for (unsigned i = 0; i < m_replay_stack.size(); ++i) { | ||||||
|                 dealloc(m_replay_stack[i]); |                 dealloc(m_replay_stack[i]); | ||||||
|             } |             } | ||||||
|  |             m_ast_trail.reset(); | ||||||
|         } |         } | ||||||
|         reset_parser(); |         reset_parser(); | ||||||
|         dealloc(m_solver); |         dealloc(m_solver); | ||||||
|  | @ -343,24 +344,21 @@ namespace api { | ||||||
|      |      | ||||||
|     void context::push() { |     void context::push() { | ||||||
|         get_smt_kernel().push(); |         get_smt_kernel().push(); | ||||||
|         if (!m_user_ref_count) { |         m_ast_lim.push_back(m_ast_trail.size()); | ||||||
|             m_ast_lim.push_back(m_ast_trail.size()); |         m_replay_stack.push_back(0);         | ||||||
|             m_replay_stack.push_back(0); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     void context::pop(unsigned num_scopes) { |     void context::pop(unsigned num_scopes) { | ||||||
|         for (unsigned i = 0; i < num_scopes; ++i) { |         for (unsigned i = 0; i < num_scopes; ++i) { | ||||||
|             if (!m_user_ref_count) { |             unsigned sz = m_ast_lim.back(); | ||||||
|                 unsigned sz = m_ast_lim.back(); |             m_ast_lim.pop_back(); | ||||||
|                 m_ast_lim.pop_back(); |             dealloc(m_replay_stack.back()); | ||||||
|                 dealloc(m_replay_stack.back()); |             m_replay_stack.pop_back(); | ||||||
|                 m_replay_stack.pop_back(); |             while (m_ast_trail.size() > sz) { | ||||||
|                 while (m_ast_trail.size() > sz) { |                 m_ast_trail.pop_back(); | ||||||
|                     m_ast_trail.pop_back(); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         SASSERT(num_scopes <= get_smt_kernel().get_scope_level()); | ||||||
|         get_smt_kernel().pop(num_scopes); |         get_smt_kernel().pop(num_scopes); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,6 +38,7 @@ Revision History: | ||||||
| #include"iz3hash.h" | #include"iz3hash.h" | ||||||
| #include"iz3pp.h" | #include"iz3pp.h" | ||||||
| #include"iz3checker.h" | #include"iz3checker.h" | ||||||
|  | #include"scoped_proof.h" | ||||||
| 
 | 
 | ||||||
| using namespace stl_ext; | using namespace stl_ext; | ||||||
| 
 | 
 | ||||||
|  | @ -290,6 +291,99 @@ extern "C" { | ||||||
|     opts->map[name] = value; |     opts->map[name] = value; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   Z3_ast_vector Z3_API Z3_get_interpolant(__in Z3_context c, __in Z3_ast pf, __in Z3_ast pat, __in Z3_params p){ | ||||||
|  |     Z3_TRY; | ||||||
|  |     LOG_Z3_get_interpolant(c, pf, pat, p); | ||||||
|  |     RESET_ERROR_CODE(); | ||||||
|  | 
 | ||||||
|  |     Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m()); | ||||||
|  |     mk_c(c)->save_object(v); | ||||||
|  | 
 | ||||||
|  |     ast *_pf = to_ast(pf); | ||||||
|  |     ast *_pat = to_ast(pat); | ||||||
|  |      | ||||||
|  |     ptr_vector<ast> interp; | ||||||
|  |     ptr_vector<ast> cnsts; // to throw away
 | ||||||
|  |      | ||||||
|  |     ast_manager &_m = mk_c(c)->m(); | ||||||
|  | 
 | ||||||
|  |     iz3interpolate(_m, | ||||||
|  | 		   _pf, | ||||||
|  | 		   cnsts, | ||||||
|  | 		   _pat, | ||||||
|  | 		   interp, | ||||||
|  | 		   (interpolation_options_struct *) 0 // ignore params for now
 | ||||||
|  | 		   ); | ||||||
|  |      | ||||||
|  |     // copy result back
 | ||||||
|  |     for(unsigned i = 0; i < interp.size(); i++){ | ||||||
|  |       v->m_ast_vector.push_back(interp[i]); | ||||||
|  |       _m.dec_ref(interp[i]); | ||||||
|  |     } | ||||||
|  |     RETURN_Z3(of_ast_vector(v)); | ||||||
|  |     Z3_CATCH_RETURN(0); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Z3_lbool Z3_API Z3_compute_interpolant(__in Z3_context c, __in Z3_ast pat, __in Z3_params p, __out Z3_ast_vector *out_interp, __out Z3_model *model){ | ||||||
|  |     Z3_TRY; | ||||||
|  |     LOG_Z3_compute_interpolant(c, pat, p, out_interp, model); | ||||||
|  |     RESET_ERROR_CODE(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     // params_ref &_p = to_params(p)->m_params;
 | ||||||
|  |     params_ref _p; | ||||||
|  |     _p.set_bool("proof", true); // this is currently useless
 | ||||||
|  | 
 | ||||||
|  |     scoped_proof_mode spm(mk_c(c)->m(),PGM_FINE); | ||||||
|  |     scoped_ptr<solver_factory> sf = mk_smt_solver_factory(); | ||||||
|  |     scoped_ptr<solver> m_solver((*sf)(mk_c(c)->m(), _p, true, true, true, ::symbol::null)); | ||||||
|  |     m_solver.get()->updt_params(_p); // why do we have to do this?
 | ||||||
|  | 
 | ||||||
|  |     ast *_pat = to_ast(pat); | ||||||
|  |      | ||||||
|  |     ptr_vector<ast> interp; | ||||||
|  |     ptr_vector<ast> cnsts; // to throw away
 | ||||||
|  |      | ||||||
|  |     ast_manager &_m = mk_c(c)->m(); | ||||||
|  | 
 | ||||||
|  |     model_ref m; | ||||||
|  |     lbool _status = iz3interpolate(_m, | ||||||
|  | 				   *(m_solver.get()), | ||||||
|  | 				   _pat, | ||||||
|  | 				   cnsts, | ||||||
|  | 				   interp, | ||||||
|  | 				   m, | ||||||
|  | 				   0 // ignore params for now
 | ||||||
|  | 				   ); | ||||||
|  |      | ||||||
|  |     Z3_lbool status = of_lbool(_status); | ||||||
|  |      | ||||||
|  |     Z3_ast_vector_ref *v = 0; | ||||||
|  |     *model = 0; | ||||||
|  | 
 | ||||||
|  |     if(_status == l_false){ | ||||||
|  |       // copy result back
 | ||||||
|  |       v = alloc(Z3_ast_vector_ref, mk_c(c)->m()); | ||||||
|  |       mk_c(c)->save_object(v); | ||||||
|  |       for(unsigned i = 0; i < interp.size(); i++){ | ||||||
|  | 	v->m_ast_vector.push_back(interp[i]); | ||||||
|  | 	_m.dec_ref(interp[i]); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       model_ref _m; | ||||||
|  |       m_solver.get()->get_model(_m); | ||||||
|  |       Z3_model_ref *crap = alloc(Z3_model_ref); | ||||||
|  |       crap->m_model = _m.get(); | ||||||
|  |       mk_c(c)->save_object(crap); | ||||||
|  |       *model = of_model(crap); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *out_interp = of_ast_vector(v); | ||||||
|  |      | ||||||
|  |     return status; | ||||||
|  |     Z3_CATCH_RETURN(Z3_L_UNDEF); | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
|  | @ -317,7 +411,7 @@ static void get_file_params(const char *filename, hash_map<std::string,std::stri | ||||||
|       for(unsigned i = 0; i < tokens.size(); i++){ |       for(unsigned i = 0; i < tokens.size(); i++){ | ||||||
| 	std::string &tok = tokens[i]; | 	std::string &tok = tokens[i]; | ||||||
| 	size_t eqpos = tok.find('='); | 	size_t eqpos = tok.find('='); | ||||||
| 	if(eqpos < tok.size()){ | 	if(eqpos != std::string::npos){ | ||||||
| 	  std::string left = tok.substr(0,eqpos); | 	  std::string left = tok.substr(0,eqpos); | ||||||
| 	  std::string right = tok.substr(eqpos+1,tok.size()-eqpos-1); | 	  std::string right = tok.substr(eqpos+1,tok.size()-eqpos-1); | ||||||
| 	  params[left] = right; | 	  params[left] = right; | ||||||
|  |  | ||||||
|  | @ -40,6 +40,7 @@ extern "C" { | ||||||
|         params_ref p = s->m_params; |         params_ref p = s->m_params; | ||||||
|         mk_c(c)->params().get_solver_params(mk_c(c)->m(), p, proofs_enabled, models_enabled, unsat_core_enabled); |         mk_c(c)->params().get_solver_params(mk_c(c)->m(), p, proofs_enabled, models_enabled, unsat_core_enabled); | ||||||
|         s->m_solver = (*(s->m_solver_factory))(mk_c(c)->m(), p, proofs_enabled, models_enabled, unsat_core_enabled, s->m_logic); |         s->m_solver = (*(s->m_solver_factory))(mk_c(c)->m(), p, proofs_enabled, models_enabled, unsat_core_enabled, s->m_logic); | ||||||
|  |         s->m_solver->updt_params(p); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static void init_solver(Z3_context c, Z3_solver s) { |     static void init_solver(Z3_context c, Z3_solver s) { | ||||||
|  |  | ||||||
|  | @ -40,7 +40,7 @@ extern "C" { | ||||||
|         LOG_Z3_pop(c, num_scopes); |         LOG_Z3_pop(c, num_scopes); | ||||||
|         RESET_ERROR_CODE(); |         RESET_ERROR_CODE(); | ||||||
|         CHECK_SEARCHING(c); |         CHECK_SEARCHING(c); | ||||||
|         if (num_scopes > mk_c(c)->get_smt_kernel().get_scope_level()) { |         if (num_scopes > mk_c(c)->get_num_scopes()) { | ||||||
|             SET_ERROR_CODE(Z3_IOB); |             SET_ERROR_CODE(Z3_IOB); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -3565,7 +3565,7 @@ namespace Microsoft.Z3 | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <remarks> |         /// <remarks> | ||||||
|         /// The list of all configuration parameters can be obtained using the Z3 executable: |         /// The list of all configuration parameters can be obtained using the Z3 executable: | ||||||
|         /// <c>z3.exe -ini?</c> |         /// <c>z3.exe -p</c> | ||||||
|         /// Only a few configuration parameters are mutable once the context is created. |         /// Only a few configuration parameters are mutable once the context is created. | ||||||
|         /// An exception is thrown when trying to modify an immutable parameter. |         /// An exception is thrown when trying to modify an immutable parameter. | ||||||
|         /// </remarks> |         /// </remarks> | ||||||
|  | @ -3691,7 +3691,7 @@ namespace Microsoft.Z3 | ||||||
|         internal Optimize.DecRefQueue Optimize_DRQ { get { Contract.Ensures(Contract.Result<Optimize.DecRefQueue>() != null); return m_Optimize_DRQ; } } |         internal Optimize.DecRefQueue Optimize_DRQ { get { Contract.Ensures(Contract.Result<Optimize.DecRefQueue>() != null); return m_Optimize_DRQ; } } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         internal uint refCount = 0; |         internal long refCount = 0; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Finalizer. |         /// Finalizer. | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ Notes: | ||||||
| 
 | 
 | ||||||
| using System; | using System; | ||||||
| using System.Diagnostics.Contracts; | using System.Diagnostics.Contracts; | ||||||
|  | using System.Threading; | ||||||
| 
 | 
 | ||||||
| namespace Microsoft.Z3 | namespace Microsoft.Z3 | ||||||
| { | { | ||||||
|  | @ -50,8 +51,7 @@ namespace Microsoft.Z3 | ||||||
| 
 | 
 | ||||||
|             if (m_ctx != null) |             if (m_ctx != null) | ||||||
|             { |             { | ||||||
|                 m_ctx.refCount--; |                 if (Interlocked.Decrement(ref m_ctx.refCount) == 0) | ||||||
|                 if (m_ctx.refCount == 0) |  | ||||||
|                     GC.ReRegisterForFinalize(m_ctx); |                     GC.ReRegisterForFinalize(m_ctx); | ||||||
|                 m_ctx = null; |                 m_ctx = null; | ||||||
|             } |             } | ||||||
|  | @ -77,7 +77,7 @@ namespace Microsoft.Z3 | ||||||
|         { |         { | ||||||
|             Contract.Requires(ctx != null); |             Contract.Requires(ctx != null); | ||||||
| 
 | 
 | ||||||
|             ctx.refCount++; |             Interlocked.Increment(ref ctx.refCount); | ||||||
|             m_ctx = ctx; |             m_ctx = ctx; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -85,7 +85,7 @@ namespace Microsoft.Z3 | ||||||
|         { |         { | ||||||
|             Contract.Requires(ctx != null); |             Contract.Requires(ctx != null); | ||||||
| 
 | 
 | ||||||
|             ctx.refCount++; |             Interlocked.Increment(ref ctx.refCount); | ||||||
|             m_ctx = ctx; |             m_ctx = ctx; | ||||||
|             IncRef(obj); |             IncRef(obj); | ||||||
|             m_n_obj = obj; |             m_n_obj = obj; | ||||||
|  |  | ||||||
|  | @ -7117,7 +7117,7 @@ def substitute(t, *m): | ||||||
|     if isinstance(m, tuple): |     if isinstance(m, tuple): | ||||||
|         m1 = _get_args(m) |         m1 = _get_args(m) | ||||||
|         if isinstance(m1, list): |         if isinstance(m1, list): | ||||||
|             m = _get_args(m1) |             m = m1 | ||||||
|     if __debug__: |     if __debug__: | ||||||
|         _z3_assert(is_expr(t), "Z3 expression expected") |         _z3_assert(is_expr(t), "Z3 expression expected") | ||||||
|         _z3_assert(all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) and p[0].sort().eq(p[1].sort()) for p in m]), "Z3 invalid substitution, expression pairs expected.") |         _z3_assert(all([isinstance(p, tuple) and is_expr(p[0]) and is_expr(p[1]) and p[0].sort().eq(p[1].sort()) for p in m]), "Z3 invalid substitution, expression pairs expected.") | ||||||
|  | @ -7410,3 +7410,128 @@ def parse_smt2_file(f, sorts={}, decls={}, ctx=None): | ||||||
|     dsz, dnames, ddecls = _dict2darray(decls, ctx) |     dsz, dnames, ddecls = _dict2darray(decls, ctx) | ||||||
|     return _to_expr_ref(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx) |     return _to_expr_ref(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx) | ||||||
|     |     | ||||||
|  | def Interp(a,ctx=None): | ||||||
|  |     """Create an interpolation operator. | ||||||
|  |      | ||||||
|  |     The argument is an interpolation pattern (see tree_interpolant).  | ||||||
|  | 
 | ||||||
|  |     >>> x = Int('x') | ||||||
|  |     >>> print Interp(x>0) | ||||||
|  |     interp(x > 0) | ||||||
|  |     """ | ||||||
|  |     ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx)) | ||||||
|  |     s = BoolSort(ctx) | ||||||
|  |     a = s.cast(a) | ||||||
|  |     return BoolRef(Z3_mk_interp(ctx.ref(), a.as_ast()), ctx) | ||||||
|  | 
 | ||||||
|  | def tree_interpolant(pat,p=None,ctx=None): | ||||||
|  |     """Compute interpolant for a tree of formulas. | ||||||
|  | 
 | ||||||
|  |     The input is an interpolation pattern over a set of formulas C. | ||||||
|  |     The pattern pat is a formula combining the formulas in C using | ||||||
|  |     logical conjunction and the "interp" operator (see Interp). This | ||||||
|  |     interp operator is logically the identity operator. It marks the | ||||||
|  |     sub-formulas of the pattern for which interpolants should be | ||||||
|  |     computed. The interpolant is a map sigma from marked subformulas | ||||||
|  |     to formulas, such that, for each marked subformula phi of pat | ||||||
|  |     (where phi sigma is phi with sigma(psi) substituted for each | ||||||
|  |     subformula psi of phi such that psi in dom(sigma)): | ||||||
|  | 
 | ||||||
|  |       1) phi sigma implies sigma(phi), and | ||||||
|  | 
 | ||||||
|  |       2) sigma(phi) is in the common uninterpreted vocabulary between | ||||||
|  |       the formulas of C occurring in phi and those not occurring in | ||||||
|  |       phi | ||||||
|  | 
 | ||||||
|  |       and moreover pat sigma implies false. In the simplest case | ||||||
|  |       an interpolant for the pattern "(and (interp A) B)" maps A | ||||||
|  |       to an interpolant for A /\ B.  | ||||||
|  | 
 | ||||||
|  |       The return value is a vector of formulas representing sigma. This | ||||||
|  |       vector contains sigma(phi) for each marked subformula of pat, in | ||||||
|  |       pre-order traversal. This means that subformulas of phi occur before phi | ||||||
|  |       in the vector. Also, subformulas that occur multiply in pat will | ||||||
|  |       occur multiply in the result vector. | ||||||
|  | 
 | ||||||
|  |     If pat is satisfiable, raises an object of class ModelRef | ||||||
|  |     that represents a model of pat. | ||||||
|  | 
 | ||||||
|  |     If parameters p are supplied, these are used in creating the | ||||||
|  |     solver that determines satisfiability. | ||||||
|  | 
 | ||||||
|  |     >>> x = Int('x') | ||||||
|  |     >>> y = Int('y') | ||||||
|  |     >>> print tree_interpolant(And(Interp(x < 0), Interp(y > 2), x == y)) | ||||||
|  |     [Not(x >= 0), Not(y <= 2)] | ||||||
|  | 
 | ||||||
|  |     >>> g = And(Interp(x<0),x<2) | ||||||
|  |     >>> try: | ||||||
|  |     ...     print tree_interpolant(g).sexpr() | ||||||
|  |     ... except ModelRef as m: | ||||||
|  |     ...     print m.sexpr() | ||||||
|  |     (define-fun x () Int | ||||||
|  |       (- 1)) | ||||||
|  |     """ | ||||||
|  |     f = pat | ||||||
|  |     ctx = _get_ctx(_ctx_from_ast_arg_list([f], ctx)) | ||||||
|  |     ptr = (AstVectorObj * 1)() | ||||||
|  |     mptr = (Model * 1)() | ||||||
|  |     if p == None: | ||||||
|  |         p = ParamsRef(ctx) | ||||||
|  |     res = Z3_compute_interpolant(ctx.ref(),f.as_ast(),p.params,ptr,mptr) | ||||||
|  |     if res == Z3_L_FALSE: | ||||||
|  |         return AstVector(ptr[0],ctx) | ||||||
|  |     raise ModelRef(mptr[0], ctx) | ||||||
|  | 
 | ||||||
|  | def binary_interpolant(a,b,p=None,ctx=None): | ||||||
|  |     """Compute an interpolant for a binary conjunction. | ||||||
|  | 
 | ||||||
|  |     If a & b is unsatisfiable, returns an interpolant for a & b. | ||||||
|  |     This is a formula phi such that | ||||||
|  | 
 | ||||||
|  |     1) a implies phi | ||||||
|  |     2) b implies not phi | ||||||
|  |     3) All the uninterpreted symbols of phi occur in both a and b. | ||||||
|  | 
 | ||||||
|  |     If a & b is satisfiable, raises an object of class ModelRef | ||||||
|  |     that represents a model of a &b. | ||||||
|  | 
 | ||||||
|  |     If parameters p are supplied, these are used in creating the | ||||||
|  |     solver that determines satisfiability. | ||||||
|  | 
 | ||||||
|  |     x = Int('x') | ||||||
|  |     print binary_interpolant(x<0,x>2) | ||||||
|  |     Not(x >= 0) | ||||||
|  |     """ | ||||||
|  |     f = And(Interp(a),b) | ||||||
|  |     return tree_interpolant(f,p,ctx)[0] | ||||||
|  | 
 | ||||||
|  | def sequence_interpolant(v,p=None,ctx=None): | ||||||
|  |     """Compute interpolant for a sequence of formulas. | ||||||
|  | 
 | ||||||
|  |     If len(v) == N, and if the conjunction of the formulas in v is | ||||||
|  |     unsatisfiable, the interpolant is a sequence of formulas w | ||||||
|  |     such that len(w) = N-1 and v[0] implies w[0] and for i in 0..N-1: | ||||||
|  | 
 | ||||||
|  |     1) w[i] & v[i+1] implies w[i+1] (or false if i+1 = N) | ||||||
|  |     2) All uninterpreted symbols in w[i] occur in both v[0]..v[i] | ||||||
|  |     and v[i+1]..v[n] | ||||||
|  |      | ||||||
|  |     Requires len(v) >= 1.  | ||||||
|  | 
 | ||||||
|  |     If a & b is satisfiable, raises an object of class ModelRef | ||||||
|  |     that represents a model of a & b. | ||||||
|  | 
 | ||||||
|  |     If parameters p are supplied, these are used in creating the | ||||||
|  |     solver that determines satisfiability. | ||||||
|  | 
 | ||||||
|  |     >>> x = Int('x') | ||||||
|  |     >>> y = Int('y') | ||||||
|  |     >>> print sequence_interpolant([x < 0, y == x , y > 2]) | ||||||
|  |     [Not(x >= 0), Not(y >= 0)] | ||||||
|  |     """ | ||||||
|  |     f = v[0] | ||||||
|  |     for i in range(1,len(v)): | ||||||
|  |         f = And(Interp(f),v[i]) | ||||||
|  |     return tree_interpolant(f,p,ctx) | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -113,3 +113,4 @@ class FuncEntryObj(ctypes.c_void_p): | ||||||
| class RCFNumObj(ctypes.c_void_p): | class RCFNumObj(ctypes.c_void_p): | ||||||
|   def __init__(self, e): self._as_parameter_ = e |   def __init__(self, e): self._as_parameter_ = e | ||||||
|   def from_param(obj): return obj |   def from_param(obj): return obj | ||||||
|  | 
 | ||||||
|  |  | ||||||
							
								
								
									
										133
									
								
								src/api/z3_api.h
									
										
									
									
									
								
							
							
						
						
									
										133
									
								
								src/api/z3_api.h
									
										
									
									
									
								
							|  | @ -1392,6 +1392,16 @@ extern "C" { | ||||||
|        although some parameters can be changed using #Z3_update_param_value. |        although some parameters can be changed using #Z3_update_param_value. | ||||||
|        All main interaction with Z3 happens in the context of a \c Z3_context. |        All main interaction with Z3 happens in the context of a \c Z3_context. | ||||||
| 
 | 
 | ||||||
|  |        In contrast to #Z3_mk_context_rc, the life time of Z3_ast objects | ||||||
|  |        are determined by the scope level of #Z3_push and #Z3_pop. | ||||||
|  |        In other words, a Z3_ast object remains valid until there is a  | ||||||
|  |        call to Z3_pop that takes the current scope below the level where  | ||||||
|  |        the object was created. | ||||||
|  | 
 | ||||||
|  |        Note that all other reference counted objects, including Z3_model, | ||||||
|  |        Z3_solver, Z3_func_interp have to be managed by the caller.  | ||||||
|  |        Their reference counts are not handled by the context.        | ||||||
|  | 
 | ||||||
|        \conly \sa Z3_del_context |        \conly \sa Z3_del_context | ||||||
| 
 | 
 | ||||||
|        \conly \deprecated Use #Z3_mk_context_rc |        \conly \deprecated Use #Z3_mk_context_rc | ||||||
|  | @ -6841,6 +6851,13 @@ END_MLAPI_EXCLUDE | ||||||
|     /**
 |     /**
 | ||||||
|        \brief Create a new (incremental) solver. |        \brief Create a new (incremental) solver. | ||||||
| 
 | 
 | ||||||
|  |        The function #Z3_solver_get_model retrieves a model if the | ||||||
|  |        assertions is satisfiable (i.e., the result is \c | ||||||
|  |        Z3_L_TRUE) and model construction is enabled. | ||||||
|  |        The function #Z3_solver_get_model can also be used even | ||||||
|  |        if the result is \c Z3_L_UNDEF, but the returned model | ||||||
|  |        is not guaranteed to satisfy quantified assertions. | ||||||
|  | 
 | ||||||
|        def_API('Z3_mk_simple_solver', SOLVER, (_in(CONTEXT),)) |        def_API('Z3_mk_simple_solver', SOLVER, (_in(CONTEXT),)) | ||||||
|     */ |     */ | ||||||
|     Z3_solver Z3_API Z3_mk_simple_solver(__in Z3_context c); |     Z3_solver Z3_API Z3_mk_simple_solver(__in Z3_context c); | ||||||
|  | @ -6978,8 +6995,11 @@ END_MLAPI_EXCLUDE | ||||||
|        \brief Check whether the assertions in a given solver are consistent or not. |        \brief Check whether the assertions in a given solver are consistent or not. | ||||||
| 
 | 
 | ||||||
|        The function #Z3_solver_get_model retrieves a model if the |        The function #Z3_solver_get_model retrieves a model if the | ||||||
|        assertions are not unsatisfiable (i.e., the result is not \c |        assertions is satisfiable (i.e., the result is \c | ||||||
|        Z3_L_FALSE) and model construction is enabled. |        Z3_L_TRUE) and model construction is enabled. | ||||||
|  |        Note that if the call returns Z3_L_UNDEF, Z3 does not | ||||||
|  |        ensure that calls to #Z3_solver_get_model succeed and any models | ||||||
|  |        produced in this case are not guaranteed to satisfy the assertions. | ||||||
| 
 | 
 | ||||||
|        The function #Z3_solver_get_proof retrieves a proof if proof |        The function #Z3_solver_get_proof retrieves a proof if proof | ||||||
|        generation was enabled when the context was created, and the  |        generation was enabled when the context was created, and the  | ||||||
|  | @ -7290,7 +7310,7 @@ END_MLAPI_EXCLUDE | ||||||
|        \mlonly then a valid model is returned.  Otherwise, it is unsafe to use the returned model.\endmlonly |        \mlonly then a valid model is returned.  Otherwise, it is unsafe to use the returned model.\endmlonly | ||||||
|        \conly The caller is responsible for deleting the model using the function #Z3_del_model. |        \conly The caller is responsible for deleting the model using the function #Z3_del_model. | ||||||
|         |         | ||||||
|        \conly \remark In constrast with the rest of the Z3 API, the reference counter of the |        \conly \remark In contrast with the rest of the Z3 API, the reference counter of the | ||||||
|        \conly model is incremented. This is to guarantee backward compatibility. In previous |        \conly model is incremented. This is to guarantee backward compatibility. In previous | ||||||
|        \conly versions, models did not support reference counting. |        \conly versions, models did not support reference counting. | ||||||
|         |         | ||||||
|  | @ -7404,6 +7424,11 @@ END_MLAPI_EXCLUDE | ||||||
|         |         | ||||||
|        \sa Z3_check_and_get_model |        \sa Z3_check_and_get_model | ||||||
| 
 | 
 | ||||||
|  |        \conly \remark The Z3_check_and_get_model automatically increments a reference count on the model. | ||||||
|  |        \conly The expected usage is that models created by that method are deleted using Z3_del_model. | ||||||
|  |        \conly This is for backwards compatibility and in contrast to the rest of the API where | ||||||
|  |        \conly callers are responsible for managing reference counts. | ||||||
|  |      | ||||||
|        \deprecated Subsumed by Z3_solver API |        \deprecated Subsumed by Z3_solver API | ||||||
|         |         | ||||||
|        def_API('Z3_del_model', VOID, (_in(CONTEXT), _in(MODEL))) |        def_API('Z3_del_model', VOID, (_in(CONTEXT), _in(MODEL))) | ||||||
|  | @ -7930,6 +7955,108 @@ END_MLAPI_EXCLUDE | ||||||
| 
 | 
 | ||||||
|   Z3_context Z3_API Z3_mk_interpolation_context(__in Z3_config cfg); |   Z3_context Z3_API Z3_mk_interpolation_context(__in Z3_config cfg); | ||||||
| 
 | 
 | ||||||
|  |   /** Compute an interpolant from a refutation. This takes a proof of
 | ||||||
|  |       "false" from a set of formulas C, and an interpolation | ||||||
|  |       pattern. The pattern pat is a formula combining the formulas in C | ||||||
|  |       using logical conjunction and the "interp" operator (see | ||||||
|  |       #Z3_mk_interp). This interp operator is logically the identity | ||||||
|  |       operator. It marks the sub-formulas of the pattern for which interpolants should | ||||||
|  |       be computed. The interpolant is a map sigma from marked subformulas to | ||||||
|  |       formulas, such that, for each marked subformula phi of pat (where phi sigma | ||||||
|  |       is phi with sigma(psi) substituted for each subformula psi of phi such that | ||||||
|  |       psi in dom(sigma)): | ||||||
|  | 
 | ||||||
|  |       1) phi sigma implies sigma(phi), and | ||||||
|  | 
 | ||||||
|  |       2) sigma(phi) is in the common uninterpreted vocabulary between | ||||||
|  |       the formulas of C occurring in phi and those not occurring in | ||||||
|  |       phi | ||||||
|  | 
 | ||||||
|  |       and moreover pat sigma implies false. In the simplest case | ||||||
|  |       an interpolant for the pattern "(and (interp A) B)" maps A | ||||||
|  |       to an interpolant for A /\ B.  | ||||||
|  | 
 | ||||||
|  |       The return value is a vector of formulas representing sigma. The | ||||||
|  |       vector contains sigma(phi) for each marked subformula of pat, in | ||||||
|  |       pre-order traversal. This means that subformulas of phi occur before phi | ||||||
|  |       in the vector. Also, subformulas that occur multiply in pat will | ||||||
|  |       occur multiply in the result vector. | ||||||
|  | 
 | ||||||
|  |       In particular, calling Z3_get_interpolant on a pattern of the | ||||||
|  |       form (interp ... (interp (and (interp A_1) A_2)) ... A_N) will | ||||||
|  |       result in a sequence interpolant for A_1, A_2,... A_N.  | ||||||
|  | 
 | ||||||
|  |       Neglecting interp markers, the pattern must be a conjunction of | ||||||
|  |       formulas in C, the set of premises of the proof. Otherwise an | ||||||
|  |       error is flagged. | ||||||
|  | 
 | ||||||
|  |       Any premises of the proof not present in the pattern are | ||||||
|  |       treated as "background theory". Predicate and function symbols | ||||||
|  |       occurring in the background theory are treated as interpreted and | ||||||
|  |       thus always allowed in the interpolant. | ||||||
|  | 
 | ||||||
|  |       Interpolant may not necessarily be computable from all | ||||||
|  |       proofs. To be sure an interpolant can be computed, the proof | ||||||
|  |       must be generated by an SMT solver for which interpoaltion is | ||||||
|  |       supported, and the premises must be expressed using only | ||||||
|  |       theories and operators for which interpolation is supported. | ||||||
|  | 
 | ||||||
|  |       Currently, the only SMT solver that is supported is the legacy | ||||||
|  |       SMT solver. Such a solver is available as the default solver in | ||||||
|  |       #Z3_context objects produced by #Z3_mk_interpolation_context. | ||||||
|  |       Currently, the theories supported are equality with | ||||||
|  |       uninterpreted functions, linear integer arithmetic, and the | ||||||
|  |       theory of arrays (in SMT-LIB terms, this is AUFLIA). | ||||||
|  |       Quantifiers are allowed. Use of any other operators (including | ||||||
|  |       "labels") may result in failure to compute an interpolant from a | ||||||
|  |       proof. | ||||||
|  | 
 | ||||||
|  |       Parameters: | ||||||
|  | 
 | ||||||
|  |       \param c logical context. | ||||||
|  |       \param pf a refutation from premises (assertions) C | ||||||
|  |       \param pat an interpolation pattern over C | ||||||
|  |       \param p parameters | ||||||
|  | 
 | ||||||
|  |        def_API('Z3_get_interpolant', AST_VECTOR, (_in(CONTEXT), _in(AST), _in(AST), _in(PARAMS))) | ||||||
|  |     */ | ||||||
|  | 
 | ||||||
|  |   Z3_ast_vector Z3_API Z3_get_interpolant(__in Z3_context c, __in Z3_ast pf, __in Z3_ast pat, __in Z3_params p); | ||||||
|  | 
 | ||||||
|  |   /* Compute an interpolant for an unsatisfiable conjunction of formulas.
 | ||||||
|  | 
 | ||||||
|  |      This takes as an argument an interpolation pattern as in | ||||||
|  |      #Z3_get_interpolant. This is a conjunction, some subformulas of | ||||||
|  |      which are marked with the "interp" operator (see #Z3_mk_interp). | ||||||
|  |       | ||||||
|  |      The conjunction is first checked for unsatisfiability. The result | ||||||
|  |      of this check is returned in the out parameter "status". If the result | ||||||
|  |      is unsat, an interpolant is computed from the refutation as in #Z3_get_interpolant | ||||||
|  |      and returned as a vector of formulas. Otherwise the return value is | ||||||
|  |      an empty formula.  | ||||||
|  | 
 | ||||||
|  |      See #Z3_get_interpolant for a discussion of supported theories. | ||||||
|  | 
 | ||||||
|  |      The advantage of this function over #Z3_get_interpolant is that | ||||||
|  |      it is not necessary to create a suitable SMT solver and generate | ||||||
|  |      a proof. The disadvantage is that it is not possible to use the | ||||||
|  |      solver incrementally. | ||||||
|  | 
 | ||||||
|  |      Parameters: | ||||||
|  |       | ||||||
|  |      \param c logical context. | ||||||
|  |      \param pat an interpolation pattern | ||||||
|  |      \param p parameters for solver creation | ||||||
|  |      \param status returns the status of the sat check | ||||||
|  |      \param model returns model if satisfiable | ||||||
|  | 
 | ||||||
|  |      Return value: status of SAT check | ||||||
|  |       | ||||||
|  |      def_API('Z3_compute_interpolant', INT, (_in(CONTEXT), _in(AST), _in(PARAMS), _out(AST_VECTOR), _out(MODEL))) | ||||||
|  |   */ | ||||||
|  |    | ||||||
|  |   Z3_lbool Z3_API Z3_compute_interpolant(__in Z3_context c, __in Z3_ast pat, __in Z3_params p, __out Z3_ast_vector *interp, __out Z3_model *model); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /** Constant reprepresenting a root of a formula tree for tree interpolation */ | /** Constant reprepresenting a root of a formula tree for tree interpolation */ | ||||||
| #define IZ3_ROOT SHRT_MAX | #define IZ3_ROOT SHRT_MAX | ||||||
|  |  | ||||||
|  | @ -547,6 +547,9 @@ public: | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | #define STRINGIZE(x) #x | ||||||
|  | #define STRINGIZE_VALUE_OF(x) STRINGIZE(x) | ||||||
|  | 
 | ||||||
| class get_info_cmd : public cmd { | class get_info_cmd : public cmd { | ||||||
|     symbol   m_error_behavior; |     symbol   m_error_behavior; | ||||||
|     symbol   m_name; |     symbol   m_name; | ||||||
|  | @ -584,7 +587,11 @@ public: | ||||||
|             ctx.regular_stream() << "(:authors \"Leonardo de Moura and Nikolaj Bjorner\")" << std::endl; |             ctx.regular_stream() << "(:authors \"Leonardo de Moura and Nikolaj Bjorner\")" << std::endl; | ||||||
|         } |         } | ||||||
|         else if (opt == m_version) { |         else if (opt == m_version) { | ||||||
|             ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER << "\")" << std::endl; |             ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER | ||||||
|  | #ifdef Z3GITHASH | ||||||
|  |                 << " - build hashcode " << STRINGIZE_VALUE_OF(Z3GITHASH) | ||||||
|  | #endif | ||||||
|  |                 << "\")" << std::endl; | ||||||
|         } |         } | ||||||
|         else if (opt == m_status) { |         else if (opt == m_status) { | ||||||
|             ctx.regular_stream() << "(:status " << ctx.get_status() << ")" << std::endl; |             ctx.regular_stream() << "(:status " << ctx.get_status() << ")" << std::endl; | ||||||
|  |  | ||||||
|  | @ -347,8 +347,14 @@ cmd_context::~cmd_context() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cmd_context::set_cancel(bool f) { | void cmd_context::set_cancel(bool f) { | ||||||
|     if (m_solver) |     if (m_solver) { | ||||||
|         m_solver->set_cancel(f); |         if (f) { | ||||||
|  |             m_solver->cancel();  | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             m_solver->reset_cancel(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|     if (has_manager()) |     if (has_manager()) | ||||||
|         m().set_cancel(f); |         m().set_cancel(f); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -33,6 +33,7 @@ Notes: | ||||||
| #include"iz3checker.h" | #include"iz3checker.h" | ||||||
| #include"iz3profiling.h" | #include"iz3profiling.h" | ||||||
| #include"interp_params.hpp" | #include"interp_params.hpp" | ||||||
|  | #include"scoped_proof.h" | ||||||
| 
 | 
 | ||||||
| static void show_interpolant_and_maybe_check(cmd_context & ctx, | static void show_interpolant_and_maybe_check(cmd_context & ctx, | ||||||
| 					     ptr_vector<ast> &cnsts, | 					     ptr_vector<ast> &cnsts, | ||||||
|  | @ -153,7 +154,7 @@ static void compute_interpolant_and_maybe_check(cmd_context & ctx, expr * t, par | ||||||
|   ast_manager &_m = ctx.m(); |   ast_manager &_m = ctx.m(); | ||||||
|   // TODO: the following is a HACK to enable proofs in the old smt solver
 |   // TODO: the following is a HACK to enable proofs in the old smt solver
 | ||||||
|   // When we stop using that solver, this hack can be removed
 |   // When we stop using that solver, this hack can be removed
 | ||||||
|   _m.toggle_proof_mode(PGM_FINE);   |   scoped_proof_mode spm(_m,PGM_FINE); | ||||||
|   ctx.params().get_solver_params(_m, p, proofs_enabled, models_enabled, unsat_core_enabled); |   ctx.params().get_solver_params(_m, p, proofs_enabled, models_enabled, unsat_core_enabled); | ||||||
|   p.set_bool("proof", true); |   p.set_bool("proof", true); | ||||||
|   scoped_ptr<solver> sp = (ctx.get_interpolating_solver_factory())(_m, p, true, models_enabled, false, ctx.get_logic()); |   scoped_ptr<solver> sp = (ctx.get_interpolating_solver_factory())(_m, p, true, models_enabled, false, ctx.get_logic()); | ||||||
|  |  | ||||||
|  | @ -1152,6 +1152,13 @@ protected: | ||||||
| 
 | 
 | ||||||
|       virtual void LearnFrom(Solver *old_solver) = 0; |       virtual void LearnFrom(Solver *old_solver) = 0; | ||||||
| 
 | 
 | ||||||
|  |       /** Return true if the solution be incorrect due to recursion bounding.
 | ||||||
|  | 	  That is, the returned "solution" might contain all derivable facts up to the | ||||||
|  | 	  given recursion bound, but not be actually a fixed point. | ||||||
|  |        */ | ||||||
|  | 
 | ||||||
|  |       virtual bool IsResultRecursionBounded() = 0; | ||||||
|  | 
 | ||||||
|       virtual ~Solver(){} |       virtual ~Solver(){} | ||||||
| 
 | 
 | ||||||
|       static Solver *Create(const std::string &solver_class, RPFP *rpfp); |       static Solver *Create(const std::string &solver_class, RPFP *rpfp); | ||||||
|  |  | ||||||
|  | @ -768,6 +768,29 @@ namespace Duality { | ||||||
|       annot.Simplify(); |       annot.Simplify(); | ||||||
|     }     |     }     | ||||||
| 
 | 
 | ||||||
|  |     bool recursionBounded; | ||||||
|  | 
 | ||||||
|  |     /** See if the solution might be bounded. */ | ||||||
|  |     void TestRecursionBounded(){ | ||||||
|  |       recursionBounded = false; | ||||||
|  |       if(RecursionBound == -1) | ||||||
|  | 	return; | ||||||
|  |       for(unsigned i = 0; i < nodes.size(); i++){ | ||||||
|  | 	Node *node = nodes[i]; | ||||||
|  | 	std::vector<Node *> &insts = insts_of_node[node]; | ||||||
|  | 	for(unsigned j = 0; j < insts.size(); j++) | ||||||
|  | 	  if(indset->Contains(insts[j])) | ||||||
|  | 	    if(NodePastRecursionBound(insts[j])){ | ||||||
|  | 	      recursionBounded = true; | ||||||
|  | 	      return; | ||||||
|  | 	    } | ||||||
|  |       } | ||||||
|  |     }     | ||||||
|  | 
 | ||||||
|  |     bool IsResultRecursionBounded(){ | ||||||
|  |       return recursionBounded; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** Generate a proposed solution of the input RPFP from
 |     /** Generate a proposed solution of the input RPFP from
 | ||||||
| 	the unwinding, by unioning the instances of each node. */ | 	the unwinding, by unioning the instances of each node. */ | ||||||
|     void GenSolutionFromIndSet(bool with_markers = false){ |     void GenSolutionFromIndSet(bool with_markers = false){ | ||||||
|  | @ -1026,6 +1049,7 @@ namespace Duality { | ||||||
| 	timer_stop("ProduceCandidatesForExtension"); | 	timer_stop("ProduceCandidatesForExtension"); | ||||||
| 	if(candidates.empty()){ | 	if(candidates.empty()){ | ||||||
| 	  GenSolutionFromIndSet(); | 	  GenSolutionFromIndSet(); | ||||||
|  | 	  TestRecursionBounded(); | ||||||
| 	  return true; | 	  return true; | ||||||
| 	} | 	} | ||||||
| 	Candidate cand = candidates.front(); | 	Candidate cand = candidates.front(); | ||||||
|  |  | ||||||
|  | @ -41,6 +41,7 @@ Revision History: | ||||||
| #include "iz3hash.h" | #include "iz3hash.h" | ||||||
| #include "iz3interp.h" | #include "iz3interp.h" | ||||||
| 
 | 
 | ||||||
|  | #include"scoped_proof.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| using namespace stl_ext; | using namespace stl_ext; | ||||||
|  | @ -347,8 +348,10 @@ public: | ||||||
|     // get the interps for the tree positions
 |     // get the interps for the tree positions
 | ||||||
|     std::vector<ast> _interps = interps; |     std::vector<ast> _interps = interps; | ||||||
|     interps.resize(pos_map.size()); |     interps.resize(pos_map.size()); | ||||||
|     for(unsigned i = 0; i < pos_map.size(); i++) |     for(unsigned i = 0; i < pos_map.size(); i++){ | ||||||
|       interps[i] = i < _interps.size() ? _interps[i] : mk_false(); |       unsigned j = pos_map[i]; | ||||||
|  |       interps[i] = j < _interps.size() ? _interps[j] : mk_false(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   bool has_interp(hash_map<ast,bool> &memo, const ast &t){ |   bool has_interp(hash_map<ast,bool> &memo, const ast &t){ | ||||||
|  | @ -501,6 +504,8 @@ lbool iz3interpolate(ast_manager &_m_manager, | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| void interpolation_options_struct::apply(iz3base &b){ | void interpolation_options_struct::apply(iz3base &b){ | ||||||
|   for(stl_ext::hash_map<std::string,std::string>::iterator it = map.begin(), en = map.end(); |   for(stl_ext::hash_map<std::string,std::string>::iterator it = map.begin(), en = map.end(); | ||||||
|       it != en; |       it != en; | ||||||
|  |  | ||||||
|  | @ -76,6 +76,7 @@ void iz3interpolate(ast_manager &_m_manager, | ||||||
| 		    ptr_vector<ast> &interps, | 		    ptr_vector<ast> &interps, | ||||||
| 		    interpolation_options_struct * options); | 		    interpolation_options_struct * options); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /* Compute an interpolant from an ast representing an interpolation
 | /* Compute an interpolant from an ast representing an interpolation
 | ||||||
|    problem, if unsat, else return a model (if enabled). Uses the |    problem, if unsat, else return a model (if enabled). Uses the | ||||||
|    given solver to produce the proof/model. Also returns a vector |    given solver to produce the proof/model. Also returns a vector | ||||||
|  | @ -90,4 +91,5 @@ lbool iz3interpolate(ast_manager &_m_manager, | ||||||
| 		     model_ref &m, | 		     model_ref &m, | ||||||
| 		     interpolation_options_struct * options); | 		     interpolation_options_struct * options); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -981,10 +981,10 @@ namespace datalog { | ||||||
|     |     | ||||||
|     void context::get_raw_rule_formulas(expr_ref_vector& rules, svector<symbol>& names){ |     void context::get_raw_rule_formulas(expr_ref_vector& rules, svector<symbol>& names){ | ||||||
|         for (unsigned i = 0; i < m_rule_fmls.size(); ++i) { |         for (unsigned i = 0; i < m_rule_fmls.size(); ++i) { | ||||||
| 	  expr_ref r = bind_vars(m_rule_fmls[i].get(), true); |             expr_ref r = bind_vars(m_rule_fmls[i].get(), true); | ||||||
| 	  rules.push_back(r.get()); |             rules.push_back(r.get()); | ||||||
| 	  //            rules.push_back(m_rule_fmls[i].get());
 |             //            rules.push_back(m_rule_fmls[i].get());
 | ||||||
| 	  names.push_back(m_rule_names[i]); |             names.push_back(m_rule_names[i]); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -54,6 +54,7 @@ namespace datalog { | ||||||
|         MEMOUT, |         MEMOUT, | ||||||
|         INPUT_ERROR, |         INPUT_ERROR, | ||||||
|         APPROX, |         APPROX, | ||||||
|  | 	BOUNDED, | ||||||
|         CANCELED |         CANCELED | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -311,6 +312,8 @@ namespace datalog { | ||||||
|            \brief Retrieve predicates |            \brief Retrieve predicates | ||||||
|         */ |         */ | ||||||
|         func_decl_set const& get_predicates() const { return m_preds; } |         func_decl_set const& get_predicates() const { return m_preds; } | ||||||
|  | 	ast_ref_vector const &get_pinned() const {return m_pinned; } | ||||||
|  | 
 | ||||||
|         bool is_predicate(func_decl* pred) const { return m_preds.contains(pred); } |         bool is_predicate(func_decl* pred) const { return m_preds.contains(pred); } | ||||||
|         bool is_predicate(expr * e) const { return is_app(e) && is_predicate(to_app(e)->get_decl()); } |         bool is_predicate(expr * e) const { return is_app(e) && is_predicate(to_app(e)->get_decl()); } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -36,6 +36,7 @@ Revision History: | ||||||
| #include "model_v2_pp.h" | #include "model_v2_pp.h" | ||||||
| #include "fixedpoint_params.hpp" | #include "fixedpoint_params.hpp" | ||||||
| #include "used_vars.h" | #include "used_vars.h" | ||||||
|  | #include "func_decl_dependencies.h" | ||||||
| 
 | 
 | ||||||
| // template class symbol_table<family_id>;
 | // template class symbol_table<family_id>;
 | ||||||
| 
 | 
 | ||||||
|  | @ -207,6 +208,46 @@ lbool dl_interface::query(::expr * query) { | ||||||
|     _d->rpfp->AssertAxiom(e); |     _d->rpfp->AssertAxiom(e); | ||||||
|   } |   } | ||||||
|    |    | ||||||
|  |   // make sure each predicate is the head of at least one clause
 | ||||||
|  |   func_decl_set heads; | ||||||
|  |   for(unsigned i = 0; i < clauses.size(); i++){ | ||||||
|  |     expr cl = clauses[i]; | ||||||
|  | 
 | ||||||
|  |     while(true){ | ||||||
|  |       if(cl.is_app()){ | ||||||
|  | 	decl_kind k = cl.decl().get_decl_kind(); | ||||||
|  | 	if(k == Implies) | ||||||
|  | 	  cl = cl.arg(1); | ||||||
|  | 	else { | ||||||
|  | 	  heads.insert(cl.decl()); | ||||||
|  | 	  break; | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |       else if(cl.is_quantifier()) | ||||||
|  | 	cl = cl.body(); | ||||||
|  |       else break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   ast_ref_vector const &pinned = m_ctx.get_pinned(); | ||||||
|  |   for(unsigned i = 0; i < pinned.size(); i++){ | ||||||
|  |     ::ast *fa = pinned[i]; | ||||||
|  |     if(is_func_decl(fa)){ | ||||||
|  |       ::func_decl *fd = to_func_decl(fa); | ||||||
|  |       if(m_ctx.is_predicate(fd)) { | ||||||
|  | 	func_decl f(_d->ctx,fd); | ||||||
|  | 	if(!heads.contains(fd)){ | ||||||
|  | 	  int arity = f.arity(); | ||||||
|  | 	  std::vector<expr> args; | ||||||
|  | 	  for(int j = 0; j < arity; j++) | ||||||
|  | 	    args.push_back(_d->ctx.fresh_func_decl("X",f.domain(j))()); | ||||||
|  | 	  expr c = implies(_d->ctx.bool_val(false),f(args)); | ||||||
|  | 	  c = _d->ctx.make_quant(Forall,args,c); | ||||||
|  | 	  clauses.push_back(c); | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   // creates 1-1 map between clauses and rpfp edges
 |   // creates 1-1 map between clauses and rpfp edges
 | ||||||
|   _d->rpfp->FromClauses(clauses); |   _d->rpfp->FromClauses(clauses); | ||||||
| 
 | 
 | ||||||
|  | @ -265,7 +306,19 @@ lbool dl_interface::query(::expr * query) { | ||||||
|   // dealloc(rs); this is now owned by data
 |   // dealloc(rs); this is now owned by data
 | ||||||
| 
 | 
 | ||||||
|   // true means the RPFP problem is SAT, so the query is UNSAT
 |   // true means the RPFP problem is SAT, so the query is UNSAT
 | ||||||
|   return ans ? l_false : l_true; |   // but we return undef if the UNSAT result is bounded
 | ||||||
|  |   if(ans){ | ||||||
|  |     if(rs->IsResultRecursionBounded()){ | ||||||
|  | #if 0 | ||||||
|  |       m_ctx.set_status(datalog::BOUNDED); | ||||||
|  |       return l_undef; | ||||||
|  | #else | ||||||
|  |       return l_false; | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     return l_false; | ||||||
|  |   } | ||||||
|  |   return l_true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| expr_ref dl_interface::get_cover_delta(int level, ::func_decl* pred_orig) { | expr_ref dl_interface::get_cover_delta(int level, ::func_decl* pred_orig) { | ||||||
|  |  | ||||||
|  | @ -253,6 +253,11 @@ public: | ||||||
|             print_certificate(ctx); |             print_certificate(ctx); | ||||||
|             break; |             break; | ||||||
|         case l_undef:  |         case l_undef:  | ||||||
|  | 	    if(dlctx.get_status() == datalog::BOUNDED){ | ||||||
|  | 	      ctx.regular_stream() << "bounded\n"; | ||||||
|  | 	      print_certificate(ctx); | ||||||
|  | 	      break; | ||||||
|  | 	    } | ||||||
|             ctx.regular_stream() << "unknown\n"; |             ctx.regular_stream() << "unknown\n"; | ||||||
|             switch(dlctx.get_status()) { |             switch(dlctx.get_status()) { | ||||||
|             case datalog::INPUT_ERROR: |             case datalog::INPUT_ERROR: | ||||||
|  |  | ||||||
|  | @ -251,7 +251,6 @@ namespace pdr { | ||||||
|         model_node*        m_root; |         model_node*        m_root; | ||||||
|         std::deque<model_node*> m_leaves; |         std::deque<model_node*> m_leaves; | ||||||
|         vector<obj_map<expr, model_nodes > > m_cache; |         vector<obj_map<expr, model_nodes > > m_cache; | ||||||
| 
 |  | ||||||
|         obj_map<expr, model_nodes>& cache(model_node const& n); |         obj_map<expr, model_nodes>& cache(model_node const& n); | ||||||
|         void erase_children(model_node& n, bool backtrack); |         void erase_children(model_node& n, bool backtrack); | ||||||
|         void erase_leaf(model_node& n); |         void erase_leaf(model_node& n); | ||||||
|  |  | ||||||
|  | @ -60,8 +60,6 @@ namespace datalog { | ||||||
|             dealloc(m_elems); |             dealloc(m_elems); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         virtual bool can_swap() const { return true; } |  | ||||||
| 
 |  | ||||||
|         virtual void swap(relation_base& other) { |         virtual void swap(relation_base& other) { | ||||||
|             vector_relation& o = dynamic_cast<vector_relation&>(other); |             vector_relation& o = dynamic_cast<vector_relation&>(other); | ||||||
|             if (&o == this) return; |             if (&o == this) return; | ||||||
|  |  | ||||||
|  | @ -124,7 +124,7 @@ public: | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|         m_goal2sat.set_cancel(f); |         m_goal2sat.set_cancel(f); | ||||||
|         m_solver.set_cancel(f); |         m_solver.set_cancel(f); | ||||||
|         m_preprocess->set_cancel(f); |         if (f) m_preprocess->cancel(); else m_preprocess->reset_cancel(); | ||||||
|     } |     } | ||||||
|     virtual void push() { |     virtual void push() { | ||||||
|         m_solver.user_push(); |         m_solver.user_push(); | ||||||
|  |  | ||||||
|  | @ -299,6 +299,7 @@ namespace opt { | ||||||
|      |      | ||||||
|     void maxsmt::set_cancel(bool f) { |     void maxsmt::set_cancel(bool f) { | ||||||
|         m_cancel = f; |         m_cancel = f; | ||||||
|  |          | ||||||
|         if (m_msolver) { |         if (m_msolver) { | ||||||
|             m_msolver->set_cancel(f); |             m_msolver->set_cancel(f); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -78,7 +78,7 @@ namespace opt { | ||||||
|         virtual rational get_lower() const { return m_lower; } |         virtual rational get_lower() const { return m_lower; } | ||||||
|         virtual rational get_upper() const { return m_upper; } |         virtual rational get_upper() const { return m_upper; } | ||||||
|         virtual bool get_assignment(unsigned index) const { return m_assignment[index]; } |         virtual bool get_assignment(unsigned index) const { return m_assignment[index]; } | ||||||
|         virtual void set_cancel(bool f) { m_cancel = f; s().set_cancel(f); } |         virtual void set_cancel(bool f) { m_cancel = f; if (f) s().cancel(); else s().reset_cancel(); } | ||||||
|         virtual void collect_statistics(statistics& st) const { } |         virtual void collect_statistics(statistics& st) const { } | ||||||
|         virtual void get_model(model_ref& mdl) { mdl = m_model.get(); } |         virtual void get_model(model_ref& mdl) { mdl = m_model.get(); } | ||||||
|         void set_model() { s().get_model(m_model); } |         void set_model() { s().get_model(m_model); } | ||||||
|  |  | ||||||
|  | @ -1011,13 +1011,13 @@ namespace opt { | ||||||
|         #pragma omp critical (opt_context) |         #pragma omp critical (opt_context) | ||||||
|         { |         { | ||||||
|             if (m_solver) { |             if (m_solver) { | ||||||
|                 m_solver->set_cancel(f); |                 if (f) m_solver->cancel(); else m_solver->reset_cancel(); | ||||||
|             } |             } | ||||||
|             if (m_pareto) { |             if (m_pareto) { | ||||||
|                 m_pareto->set_cancel(f); |                 m_pareto->set_cancel(f); | ||||||
|             } |             } | ||||||
|             if (m_simplify) { |             if (m_simplify) { | ||||||
|                 m_simplify->set_cancel(f); |                 if (f) m_simplify->cancel(); else m_solver->reset_cancel(); | ||||||
|             } |             } | ||||||
|             map_t::iterator it = m_maxsmts.begin(), end = m_maxsmts.end(); |             map_t::iterator it = m_maxsmts.begin(), end = m_maxsmts.end(); | ||||||
|             for (; it != end; ++it) { |             for (; it != end; ++it) { | ||||||
|  |  | ||||||
|  | @ -64,7 +64,10 @@ namespace opt { | ||||||
|             m_solver->collect_statistics(st); |             m_solver->collect_statistics(st); | ||||||
|         } |         } | ||||||
|         virtual void set_cancel(bool f) { |         virtual void set_cancel(bool f) { | ||||||
|             m_solver->set_cancel(f); |             if (f)  | ||||||
|  |                 m_solver->cancel(); | ||||||
|  |             else  | ||||||
|  |                 m_solver->reset_cancel(); | ||||||
|             m_cancel = f; |             m_cancel = f; | ||||||
|         } |         } | ||||||
|         virtual void display(std::ostream & out) const { |         virtual void display(std::ostream & out) const { | ||||||
|  |  | ||||||
|  | @ -136,9 +136,8 @@ namespace smt { | ||||||
|         if (cex == 0) |         if (cex == 0) | ||||||
|             return false; // no model available.
 |             return false; // no model available.
 | ||||||
|         unsigned num_decls = q->get_num_decls(); |         unsigned num_decls = q->get_num_decls(); | ||||||
|         unsigned   num_sks = sks.size(); |  | ||||||
|         // Remark: sks were created for the flat version of q.
 |         // Remark: sks were created for the flat version of q.
 | ||||||
|         SASSERT(num_sks >= num_decls);  |         SASSERT(sks.size() >= num_decls); | ||||||
|         expr_ref_buffer bindings(m_manager); |         expr_ref_buffer bindings(m_manager); | ||||||
|         bindings.resize(num_decls); |         bindings.resize(num_decls); | ||||||
|         unsigned max_generation = 0; |         unsigned max_generation = 0; | ||||||
|  |  | ||||||
|  | @ -413,6 +413,7 @@ namespace smt { | ||||||
|         atoms                   m_atoms;            // set of theory atoms
 |         atoms                   m_atoms;            // set of theory atoms
 | ||||||
|         ptr_vector<bound>       m_asserted_bounds;  // set of asserted bounds
 |         ptr_vector<bound>       m_asserted_bounds;  // set of asserted bounds
 | ||||||
|         unsigned                m_asserted_qhead;    |         unsigned                m_asserted_qhead;    | ||||||
|  |         ptr_vector<atom>        m_new_atoms;        // new bound atoms that have yet to be internalized.
 | ||||||
|         svector<theory_var>     m_nl_monomials;     // non linear monomials
 |         svector<theory_var>     m_nl_monomials;     // non linear monomials
 | ||||||
|         svector<theory_var>     m_nl_propagated;    // non linear monomials that became linear
 |         svector<theory_var>     m_nl_propagated;    // non linear monomials that became linear
 | ||||||
|         v_dependency_manager    m_dep_manager;      // for tracking bounds during non-linear reasoning
 |         v_dependency_manager    m_dep_manager;      // for tracking bounds during non-linear reasoning
 | ||||||
|  | @ -575,7 +576,6 @@ namespace smt { | ||||||
|         void mk_clause(literal l1, literal l2, literal l3, unsigned num_params, parameter * params); |         void mk_clause(literal l1, literal l2, literal l3, unsigned num_params, parameter * params); | ||||||
|         void mk_bound_axioms(atom * a); |         void mk_bound_axioms(atom * a); | ||||||
|         void mk_bound_axiom(atom* a1, atom* a2); |         void mk_bound_axiom(atom* a1, atom* a2); | ||||||
|         ptr_vector<atom> m_new_atoms; |  | ||||||
|         void flush_bound_axioms(); |         void flush_bound_axioms(); | ||||||
|         typename atoms::iterator next_sup(atom* a1, atom_kind kind,  |         typename atoms::iterator next_sup(atom* a1, atom_kind kind,  | ||||||
|                                           typename atoms::iterator it,  |                                           typename atoms::iterator it,  | ||||||
|  |  | ||||||
|  | @ -874,9 +874,6 @@ namespace smt { | ||||||
|         parameter coeffs[3] = { parameter(symbol("farkas")),  |         parameter coeffs[3] = { parameter(symbol("farkas")),  | ||||||
|                                 parameter(rational(1)), parameter(rational(1)) }; |                                 parameter(rational(1)), parameter(rational(1)) }; | ||||||
| 
 | 
 | ||||||
|         //std::cout << "v" << v << " " << ((kind1==A_LOWER)?"<= ":">= ") << k1 << "\t    ";
 |  | ||||||
|         //std::cout << "v" << v << " " << ((kind2==A_LOWER)?"<= ":">= ") << k2 << "\n";
 |  | ||||||
| 
 |  | ||||||
|         if (kind1 == A_LOWER) { |         if (kind1 == A_LOWER) { | ||||||
|             if (kind2 == A_LOWER) { |             if (kind2 == A_LOWER) { | ||||||
|                 if (k2 <= k1) { |                 if (k2 <= k1) { | ||||||
|  | @ -958,7 +955,6 @@ namespace smt { | ||||||
|             typename atoms::iterator lo_inf1 = begin1, lo_sup1 = begin1; |             typename atoms::iterator lo_inf1 = begin1, lo_sup1 = begin1; | ||||||
|             typename atoms::iterator hi_inf1 = begin2, hi_sup1 = begin2; |             typename atoms::iterator hi_inf1 = begin2, hi_sup1 = begin2; | ||||||
|             bool flo_inf, fhi_inf, flo_sup, fhi_sup; |             bool flo_inf, fhi_inf, flo_sup, fhi_sup; | ||||||
|    //         std::cout << atoms.size() << "\n";
 |  | ||||||
|             ptr_addr_hashtable<atom> visited; |             ptr_addr_hashtable<atom> visited; | ||||||
|             for (unsigned i = 0; i < atoms.size(); ++i) { |             for (unsigned i = 0; i < atoms.size(); ++i) { | ||||||
|                 atom* a1 = atoms[i]; |                 atom* a1 = atoms[i]; | ||||||
|  | @ -966,8 +962,6 @@ namespace smt { | ||||||
|                 hi_inf1 = next_inf(a1, A_UPPER, hi_inf, end, fhi_inf); |                 hi_inf1 = next_inf(a1, A_UPPER, hi_inf, end, fhi_inf); | ||||||
|                 lo_sup1 = next_sup(a1, A_LOWER, lo_sup, end, flo_sup); |                 lo_sup1 = next_sup(a1, A_LOWER, lo_sup, end, flo_sup); | ||||||
|                 hi_sup1 = next_sup(a1, A_UPPER, hi_sup, end, fhi_sup); |                 hi_sup1 = next_sup(a1, A_UPPER, hi_sup, end, fhi_sup); | ||||||
| //                std::cout << "v" << a1->get_var() << ((a1->get_atom_kind()==A_LOWER)?" <= ":" >= ") << a1->get_k() << "\n";
 |  | ||||||
|  //               std::cout << (lo_inf1 != end) << " " << (lo_sup1 != end) << " " << (hi_inf1 != end) << " " << (hi_sup1 != end) << "\n";
 |  | ||||||
|                 if (lo_inf1 != end) lo_inf = lo_inf1;  |                 if (lo_inf1 != end) lo_inf = lo_inf1;  | ||||||
|                 if (lo_sup1 != end) lo_sup = lo_sup1;  |                 if (lo_sup1 != end) lo_sup = lo_sup1;  | ||||||
|                 if (hi_inf1 != end) hi_inf = hi_inf1;  |                 if (hi_inf1 != end) hi_inf = hi_inf1;  | ||||||
|  |  | ||||||
|  | @ -655,6 +655,7 @@ namespace smt { | ||||||
|         return get_value(v, computed_epsilon) == val; |         return get_value(v, computed_epsilon) == val; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|        \brief Return true if for every monomial x_1 * ... * x_n, |        \brief Return true if for every monomial x_1 * ... * x_n, | ||||||
|        get_value(x_1) * ... * get_value(x_n) = get_value(x_1 * ... * x_n) |        get_value(x_1) * ... * get_value(x_n) = get_value(x_1 * ... * x_n) | ||||||
|  | @ -2309,8 +2310,9 @@ namespace smt { | ||||||
|         if (m_nl_monomials.empty()) |         if (m_nl_monomials.empty()) | ||||||
|             return FC_DONE; |             return FC_DONE; | ||||||
| 
 | 
 | ||||||
|         if (check_monomial_assignments()) |         if (check_monomial_assignments()) { | ||||||
|             return FC_DONE; |             return FC_DONE; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         if (!m_params.m_nl_arith) |         if (!m_params.m_nl_arith) | ||||||
|             return FC_GIVEUP; |             return FC_GIVEUP; | ||||||
|  | @ -2338,8 +2340,9 @@ namespace smt { | ||||||
|         if (!max_min_nl_vars()) |         if (!max_min_nl_vars()) | ||||||
|             return FC_CONTINUE; |             return FC_CONTINUE; | ||||||
| 
 | 
 | ||||||
|         if (check_monomial_assignments()) |         if (check_monomial_assignments()) { | ||||||
|             return m_liberal_final_check || !m_changed_assignment ? FC_DONE : FC_CONTINUE; |             return m_liberal_final_check || !m_changed_assignment ? FC_DONE : FC_CONTINUE; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         svector<theory_var> vars; |         svector<theory_var> vars; | ||||||
|         get_non_linear_cluster(vars); |         get_non_linear_cluster(vars); | ||||||
|  | @ -2391,8 +2394,9 @@ namespace smt { | ||||||
|         } |         } | ||||||
|         while (m_nl_strategy_idx != old_idx); |         while (m_nl_strategy_idx != old_idx); | ||||||
| 
 | 
 | ||||||
|         if (check_monomial_assignments()) |         if (check_monomial_assignments()) { | ||||||
|             return m_liberal_final_check || !m_changed_assignment ? FC_DONE : FC_CONTINUE; |             return m_liberal_final_check || !m_changed_assignment ? FC_DONE : FC_CONTINUE; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         TRACE("non_linear", display(tout);); |         TRACE("non_linear", display(tout);); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -218,8 +218,14 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|         m_solver1->set_cancel(f); |         if (f) { | ||||||
|         m_solver2->set_cancel(f); |             m_solver1->cancel(); | ||||||
|  |             m_solver2->cancel(); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             m_solver1->reset_cancel(); | ||||||
|  |             m_solver2->reset_cancel(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void set_progress_callback(progress_callback * callback) { |     virtual void set_progress_callback(progress_callback * callback) { | ||||||
|  |  | ||||||
|  | @ -99,7 +99,6 @@ public: | ||||||
|     */ |     */ | ||||||
|     virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) = 0; |     virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) = 0; | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) {} |  | ||||||
|     /**
 |     /**
 | ||||||
|        \brief Interrupt this solver. |        \brief Interrupt this solver. | ||||||
|     */ |     */ | ||||||
|  | @ -130,7 +129,6 @@ public: | ||||||
|        \brief Display the content of this solver. |        \brief Display the content of this solver. | ||||||
|     */ |     */ | ||||||
|     virtual void display(std::ostream & out) const; |     virtual void display(std::ostream & out) const; | ||||||
| 
 |  | ||||||
|     class scoped_push { |     class scoped_push { | ||||||
|         solver& s; |         solver& s; | ||||||
|         bool    m_nopop; |         bool    m_nopop; | ||||||
|  | @ -139,6 +137,8 @@ public: | ||||||
|         ~scoped_push() { if (!m_nopop) s.pop(1); } |         ~scoped_push() { if (!m_nopop) s.pop(1); } | ||||||
|         void disable_pop() { m_nopop = true; } |         void disable_pop() { m_nopop = true; } | ||||||
|     }; |     }; | ||||||
|  | protected: | ||||||
|  |     virtual void set_cancel(bool f) = 0; | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -82,7 +82,7 @@ void solver_na2as::pop(unsigned n) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void solver_na2as::restore_assumptions(unsigned old_sz) { | void solver_na2as::restore_assumptions(unsigned old_sz) { | ||||||
|     SASSERT(old_sz == 0); |   //    SASSERT(old_sz == 0);
 | ||||||
|     for (unsigned i = old_sz; i < m_assumptions.size(); i++) { |     for (unsigned i = old_sz; i < m_assumptions.size(); i++) { | ||||||
|         m_manager.dec_ref(m_assumptions[i]); |         m_manager.dec_ref(m_assumptions[i]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -175,8 +175,12 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void tactic2solver::set_cancel(bool f) { | void tactic2solver::set_cancel(bool f) { | ||||||
|     if (m_tactic.get()) |     if (m_tactic.get()) { | ||||||
|         m_tactic->set_cancel(f); |         if (f)  | ||||||
|  |             m_tactic->cancel(); | ||||||
|  |         else | ||||||
|  |             m_tactic->reset_cancel(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void tactic2solver::collect_statistics(statistics & st) const {     | void tactic2solver::collect_statistics(statistics & st) const {     | ||||||
|  |  | ||||||
|  | @ -73,8 +73,6 @@ public: | ||||||
|     void display(std::ostream & out, aig_ref const & r) const; |     void display(std::ostream & out, aig_ref const & r) const; | ||||||
|     void display_smt2(std::ostream & out, aig_ref const & r) const; |     void display_smt2(std::ostream & out, aig_ref const & r) const; | ||||||
|     unsigned get_num_aigs() const; |     unsigned get_num_aigs() const; | ||||||
|     void cancel() { set_cancel(true); } |  | ||||||
|     void reset_cancel() { set_cancel(false); } |  | ||||||
|     void set_cancel(bool f); |     void set_cancel(bool f); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -172,18 +172,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_imp; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -319,18 +319,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -398,20 +398,13 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         unsigned num_conflicts = m_imp->m_num_conflicts; |         imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|         ast_manager & m = m_imp->m; |         d->m_num_conflicts = m_imp->m_num_conflicts; | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_imp; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|         m_imp->m_num_conflicts = num_conflicts; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -333,18 +333,12 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -338,18 +338,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -1682,18 +1682,12 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void operator()(goal_ref const & in,  |     virtual void operator()(goal_ref const & in,  | ||||||
|  |  | ||||||
|  | @ -345,18 +345,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_imp; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -191,17 +191,12 @@ public: | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         ast_manager & m = m_imp->m; | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_imp; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -1002,17 +1002,12 @@ public: | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         ast_manager & m = m_imp->m; | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_imp; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -548,16 +548,10 @@ void propagate_ineqs_tactic::set_cancel(bool f) { | ||||||
| } | } | ||||||
|   |   | ||||||
| void propagate_ineqs_tactic::cleanup() { | void propagate_ineqs_tactic::cleanup() { | ||||||
|     ast_manager & m = m_imp->m; |     imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|     imp * d = m_imp; |  | ||||||
|     #pragma omp critical (tactic_cancel) |     #pragma omp critical (tactic_cancel) | ||||||
|     { |     { | ||||||
|         d = m_imp; |         std::swap(d, m_imp); | ||||||
|     } |     } | ||||||
|     dealloc(d); |     dealloc(d); | ||||||
|     d = alloc(imp, m, m_params); |  | ||||||
|     #pragma omp critical (tactic_cancel)  |  | ||||||
|     { |  | ||||||
|         m_imp = d; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -425,18 +425,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_imp; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -144,18 +144,12 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m(); |         imp * d = alloc(imp, m_imp->m(), m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     unsigned get_num_steps() const { |     unsigned get_num_steps() const { | ||||||
|  |  | ||||||
|  | @ -465,18 +465,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m(); |         imp * d = alloc(imp, m_imp->m(), m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_imp; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     unsigned get_num_steps() const { |     unsigned get_num_steps() const { | ||||||
|  |  | ||||||
|  | @ -392,17 +392,11 @@ void bv_size_reduction_tactic::set_cancel(bool f) { | ||||||
| } | } | ||||||
|   |   | ||||||
| void bv_size_reduction_tactic::cleanup() { | void bv_size_reduction_tactic::cleanup() { | ||||||
|     ast_manager & m = m_imp->m; |     imp * d = alloc(imp, m_imp->m); | ||||||
|     imp * d = m_imp; |  | ||||||
|     #pragma omp critical (tactic_cancel) |     #pragma omp critical (tactic_cancel) | ||||||
|     { |     { | ||||||
|         m_imp = 0; |         std::swap(d, m_imp); | ||||||
|     } |     } | ||||||
|     dealloc(d); |     dealloc(d); | ||||||
|     d = alloc(imp, m); |  | ||||||
|     #pragma omp critical (tactic_cancel) |  | ||||||
|     { |  | ||||||
|         m_imp = d; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -311,18 +311,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m(); |         imp * d = alloc(imp, m_imp->m(), m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -683,12 +683,7 @@ cofactor_elim_term_ite::cofactor_elim_term_ite(ast_manager & m, params_ref const | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| cofactor_elim_term_ite::~cofactor_elim_term_ite() { | cofactor_elim_term_ite::~cofactor_elim_term_ite() { | ||||||
|     imp * d = m_imp; |     dealloc(m_imp); | ||||||
|     #pragma omp critical (cofactor_elim_term_ite) |  | ||||||
|     { |  | ||||||
|         m_imp = 0; |  | ||||||
|     } |  | ||||||
|     dealloc(d); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cofactor_elim_term_ite::updt_params(params_ref const & p) { | void cofactor_elim_term_ite::updt_params(params_ref const & p) { | ||||||
|  | @ -704,19 +699,17 @@ void cofactor_elim_term_ite::operator()(expr * t, expr_ref & r) { | ||||||
| } | } | ||||||
|      |      | ||||||
| void cofactor_elim_term_ite::set_cancel(bool f) { | void cofactor_elim_term_ite::set_cancel(bool f) { | ||||||
|     #pragma omp critical (cofactor_elim_term_ite) |     if (m_imp) | ||||||
|     { |         m_imp->set_cancel(f); | ||||||
|         if (m_imp) |  | ||||||
|             m_imp->set_cancel(f); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cofactor_elim_term_ite::cleanup() { | void cofactor_elim_term_ite::cleanup() { | ||||||
|     ast_manager & m = m_imp->m;     |     ast_manager & m = m_imp->m;     | ||||||
|     #pragma omp critical (cofactor_elim_term_ite)  |     imp * d = alloc(imp, m, m_params); | ||||||
|  |     #pragma omp critical (tactic_cancel) | ||||||
|     { |     { | ||||||
|         dealloc(m_imp); |         std::swap(d, m_imp); | ||||||
|         m_imp = alloc(imp, m, m_params); |  | ||||||
|     } |     } | ||||||
|  |     dealloc(d); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,8 +37,9 @@ public: | ||||||
|      |      | ||||||
|     void cancel() { set_cancel(true); } |     void cancel() { set_cancel(true); } | ||||||
|     void reset_cancel() { set_cancel(false); } |     void reset_cancel() { set_cancel(false); } | ||||||
|     void set_cancel(bool f); |  | ||||||
|     void cleanup(); |     void cleanup(); | ||||||
|  |     void set_cancel(bool f); | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -548,16 +548,11 @@ void ctx_simplify_tactic::set_cancel(bool f) { | ||||||
| 
 | 
 | ||||||
| void ctx_simplify_tactic::cleanup() { | void ctx_simplify_tactic::cleanup() { | ||||||
|     ast_manager & m   = m_imp->m; |     ast_manager & m   = m_imp->m; | ||||||
|     imp * d = m_imp; |     imp * d = alloc(imp, m, m_params); | ||||||
|     #pragma omp critical (tactic_cancel) |     #pragma omp critical (tactic_cancel) | ||||||
|     { |     { | ||||||
|         m_imp = 0; |         std::swap(d, m_imp); | ||||||
|     } |     } | ||||||
|     dealloc(d); |     dealloc(d); | ||||||
|     d = alloc(imp, m, m_params); |  | ||||||
|     #pragma omp critical (tactic_cancel) |  | ||||||
|     { |  | ||||||
|         m_imp = d; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -90,17 +90,12 @@ public: | ||||||
| 
 | 
 | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m(); |         ast_manager & m = m_imp->m(); | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -174,17 +174,12 @@ public: | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         ast_manager & m = m_imp->m; | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -1037,17 +1037,12 @@ public: | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         unsigned num_elim_apps = get_num_elim_apps(); |         unsigned num_elim_apps = get_num_elim_apps(); | ||||||
|         ast_manager & m = m_imp->m_manager;         |         ast_manager & m = m_imp->m_manager;         | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|         m_imp->m_num_elim_apps = num_elim_apps; |         m_imp->m_num_elim_apps = num_elim_apps; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -225,18 +225,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -255,17 +255,12 @@ public: | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m(); |         ast_manager & m = m_imp->m(); | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -542,16 +542,11 @@ void reduce_args_tactic::set_cancel(bool f) { | ||||||
| 
 | 
 | ||||||
| void reduce_args_tactic::cleanup() { | void reduce_args_tactic::cleanup() { | ||||||
|     ast_manager & m   = m_imp->m();     |     ast_manager & m   = m_imp->m();     | ||||||
|     imp * d = m_imp; |     imp * d = alloc(imp, m); | ||||||
|     #pragma omp critical (tactic_cancel) |     #pragma omp critical (tactic_cancel) | ||||||
|     { |     { | ||||||
|         m_imp = 0; |         std::swap(d, m_imp); | ||||||
|     } |     } | ||||||
|     dealloc(d); |     dealloc(d); | ||||||
|     d = alloc(imp, m); |  | ||||||
|     #pragma omp critical (tactic_cancel) |  | ||||||
|     { |  | ||||||
|         m_imp = d; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -118,17 +118,12 @@ void simplify_tactic::set_cancel(bool f) { | ||||||
| 
 | 
 | ||||||
| void simplify_tactic::cleanup() { | void simplify_tactic::cleanup() { | ||||||
|     ast_manager & m = m_imp->m(); |     ast_manager & m = m_imp->m(); | ||||||
|     imp * d = m_imp; |     imp * d = alloc(imp, m, m_params); | ||||||
|     #pragma omp critical (tactic_cancel) |     #pragma omp critical (tactic_cancel) | ||||||
|     { |     { | ||||||
|         m_imp = 0; |         std::swap(d, m_imp); | ||||||
|     } |     } | ||||||
|     dealloc(d); |     dealloc(d); | ||||||
|     d = alloc(imp, m, m_params); |  | ||||||
|     #pragma omp critical (tactic_cancel) |  | ||||||
|     { |  | ||||||
|         m_imp = d; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unsigned simplify_tactic::get_num_steps() const { | unsigned simplify_tactic::get_num_steps() const { | ||||||
|  |  | ||||||
|  | @ -43,9 +43,11 @@ public: | ||||||
|     virtual void cleanup(); |     virtual void cleanup(); | ||||||
| 
 | 
 | ||||||
|     unsigned get_num_steps() const; |     unsigned get_num_steps() const; | ||||||
|     virtual void set_cancel(bool f); |  | ||||||
| 
 | 
 | ||||||
|     virtual tactic * translate(ast_manager & m) { return alloc(simplify_tactic, m, m_params); } |     virtual tactic * translate(ast_manager & m) { return alloc(simplify_tactic, m, m_params); } | ||||||
|  | protected: | ||||||
|  |     virtual void set_cancel(bool f); | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| tactic * mk_simplify_tactic(ast_manager & m, params_ref const & p = params_ref()); | tactic * mk_simplify_tactic(ast_manager & m, params_ref const & p = params_ref()); | ||||||
|  |  | ||||||
|  | @ -749,23 +749,19 @@ public: | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         unsigned num_elim_vars = m_imp->m_num_eliminated_vars; |         unsigned num_elim_vars = m_imp->m_num_eliminated_vars; | ||||||
|         ast_manager & m = m_imp->m(); |         ast_manager & m = m_imp->m(); | ||||||
|         imp * d = m_imp; |  | ||||||
|         expr_replacer * r = m_imp->m_r; |         expr_replacer * r = m_imp->m_r; | ||||||
|         if (r) |         if (r) | ||||||
|             r->set_substitution(0); |             r->set_substitution(0); | ||||||
|         bool owner = m_imp->m_r_owner; |         bool owner = m_imp->m_r_owner; | ||||||
|         m_imp->m_r_owner  = false; // stole replacer
 |         m_imp->m_r_owner  = false; // stole replacer
 | ||||||
|  | 
 | ||||||
|  |         imp * d = alloc(imp, m, m_params, r, owner); | ||||||
|  |         d->m_num_eliminated_vars = num_elim_vars; | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params, r, owner); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|         m_imp->m_num_eliminated_vars = num_elim_vars; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void collect_statistics(statistics & st) const { |     virtual void collect_statistics(statistics & st) const { | ||||||
|  |  | ||||||
|  | @ -898,20 +898,14 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         unsigned num_aux_vars = m_imp->m_num_aux_vars; |  | ||||||
|         ast_manager & m = m_imp->m; |         ast_manager & m = m_imp->m; | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|  |         d->m_num_aux_vars = m_imp->m_num_aux_vars; | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|         m_imp->m_num_aux_vars = num_aux_vars; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -139,18 +139,12 @@ public: | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void cleanup() {         |     virtual void cleanup() {         | ||||||
|         ast_manager & m = m_imp->m; |         imp * d = alloc(imp, m_imp->m, m_params); | ||||||
|         imp * d = m_imp; |  | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_imp; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -79,17 +79,12 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void cleanup() {         |     virtual void cleanup() {         | ||||||
|         sls_engine * d = m_engine; |         sls_engine * d = alloc(sls_engine, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             d = m_engine; |             std::swap(d, m_engine); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(sls_engine, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel)  |  | ||||||
|         { |  | ||||||
|             m_engine = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     virtual void collect_statistics(statistics & st) const { |     virtual void collect_statistics(statistics & st) const { | ||||||
|  |  | ||||||
|  | @ -47,7 +47,6 @@ public: | ||||||
| 
 | 
 | ||||||
|     void cancel(); |     void cancel(); | ||||||
|     void reset_cancel(); |     void reset_cancel(); | ||||||
|     virtual void set_cancel(bool f) {} |  | ||||||
|      |      | ||||||
|     /**
 |     /**
 | ||||||
|        \brief Apply tactic to goal \c in. |        \brief Apply tactic to goal \c in. | ||||||
|  | @ -96,6 +95,13 @@ public: | ||||||
| 
 | 
 | ||||||
|     // translate tactic to the given manager
 |     // translate tactic to the given manager
 | ||||||
|     virtual tactic * translate(ast_manager & m) = 0; |     virtual tactic * translate(ast_manager & m) = 0; | ||||||
|  | private: | ||||||
|  |     friend class nary_tactical; | ||||||
|  |     friend class binary_tactical; | ||||||
|  |     friend class unary_tactical; | ||||||
|  | 
 | ||||||
|  |     virtual void set_cancel(bool f) {} | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef ref<tactic>         tactic_ref; | typedef ref<tactic>         tactic_ref; | ||||||
|  |  | ||||||
|  | @ -102,11 +102,8 @@ protected: | ||||||
|        \brief Reset cancel flag of t if this was not canceled. |        \brief Reset cancel flag of t if this was not canceled. | ||||||
|     */ |     */ | ||||||
|     void parent_reset_cancel(tactic & t) { |     void parent_reset_cancel(tactic & t) { | ||||||
|         #pragma omp critical (tactic_cancel) |         if (!m_cancel) { | ||||||
|         { |             t.reset_cancel(); | ||||||
|             if (!m_cancel) { |  | ||||||
|                 t.set_cancel(false); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -393,11 +390,8 @@ protected: | ||||||
|        \brief Reset cancel flag of st if this was not canceled. |        \brief Reset cancel flag of st if this was not canceled. | ||||||
|     */ |     */ | ||||||
|     void parent_reset_cancel(tactic & t) { |     void parent_reset_cancel(tactic & t) { | ||||||
|         #pragma omp critical (tactic_cancel) |         if (!m_cancel) { | ||||||
|         { |             t.reset_cancel(); | ||||||
|             if (!m_cancel) { |  | ||||||
|                 t.set_cancel(false); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -144,17 +144,12 @@ public: | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m(); |         ast_manager & m = m_imp->m(); | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -151,17 +151,12 @@ public: | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m(); |         ast_manager & m = m_imp->m(); | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -119,17 +119,12 @@ public: | ||||||
|      |      | ||||||
|     virtual void cleanup() { |     virtual void cleanup() { | ||||||
|         ast_manager & m = m_imp->m(); |         ast_manager & m = m_imp->m(); | ||||||
|         imp * d = m_imp; |         imp * d = alloc(imp, m, m_params); | ||||||
|         #pragma omp critical (tactic_cancel) |         #pragma omp critical (tactic_cancel) | ||||||
|         { |         { | ||||||
|             m_imp = 0; |             std::swap(d, m_imp); | ||||||
|         } |         } | ||||||
|         dealloc(d); |         dealloc(d); | ||||||
|         d = alloc(imp, m, m_params); |  | ||||||
|         #pragma omp critical (tactic_cancel) |  | ||||||
|         { |  | ||||||
|             m_imp = d; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void set_cancel(bool f) { |     virtual void set_cancel(bool f) { | ||||||
|  |  | ||||||
|  | @ -58,8 +58,12 @@ void dl_query_test(ast_manager & m, smt_params & fparams, params_ref& params, | ||||||
|     ctx_q.updt_params(params); |     ctx_q.updt_params(params); | ||||||
|     { |     { | ||||||
|         parser* p = parser::create(ctx_q,m); |         parser* p = parser::create(ctx_q,m); | ||||||
|         TRUSTME( p->parse_file(problem_file) ); |         bool ok = p->parse_file(problem_file); | ||||||
|         dealloc(p); |         dealloc(p); | ||||||
|  |         if (!ok) { | ||||||
|  |             std::cout << "Could not parse: " << problem_file << "\n"; | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     relation_manager & rel_mgr_q = ctx_b.get_rel_context()->get_rmanager(); |     relation_manager & rel_mgr_q = ctx_b.get_rel_context()->get_rmanager(); | ||||||
| 
 | 
 | ||||||
|  | @ -143,10 +147,11 @@ void dl_query_test_wpa(smt_params & fparams, params_ref& params) { | ||||||
|     ctx.updt_params(params); |     ctx.updt_params(params); | ||||||
|     { |     { | ||||||
|         wpa_parser* p = wpa_parser::create(ctx, m); |         wpa_parser* p = wpa_parser::create(ctx, m); | ||||||
|         bool = ok = p->parse_directory(problem_dir); |         bool ok = p->parse_directory(problem_dir); | ||||||
|         dealloc(p); |         dealloc(p); | ||||||
|         if (!ok) { |         if (!ok) { | ||||||
|             std::cout << "Could not parse: " << problem_dir << "\n"; |             std::cout << "Could not parse: " << problem_dir << "\n"; | ||||||
|  |             return; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -216,8 +221,12 @@ void tst_dl_query() { | ||||||
|     ctx_base.updt_params(params); |     ctx_base.updt_params(params); | ||||||
|     { |     { | ||||||
|         parser* p = parser::create(ctx_base,m); |         parser* p = parser::create(ctx_base,m); | ||||||
|         TRUSTME( p->parse_file(problem_file) ); |         bool ok = p->parse_file(problem_file); | ||||||
|         dealloc(p); |         dealloc(p); | ||||||
|  |         if (!ok) { | ||||||
|  |             std::cout << "Could not parse: " << problem_file << "\n"; | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     ctx_base.get_rel_context()->saturate(); |     ctx_base.get_rel_context()->saturate(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -73,7 +73,7 @@ bool is_debug_enabled(const char * tag); | ||||||
|         UNREACHABLE();                                          \ |         UNREACHABLE();                                          \ | ||||||
|     }                                                            |     }                                                            | ||||||
| #else | #else | ||||||
| #define VERIFY(_x_) (_x_) | #define VERIFY(_x_) (void)(_x_) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define MAKE_NAME2(LINE) zofty_ ## LINE  | #define MAKE_NAME2(LINE) zofty_ ## LINE  | ||||||
|  |  | ||||||
|  | @ -35,6 +35,7 @@ static long long  g_memory_max_used_size     = 0; | ||||||
| static long long  g_memory_watermark         = 0; | static long long  g_memory_watermark         = 0; | ||||||
| static bool       g_exit_when_out_of_memory  = false; | static bool       g_exit_when_out_of_memory  = false; | ||||||
| static char const * g_out_of_memory_msg      = "ERROR: out of memory"; | static char const * g_out_of_memory_msg      = "ERROR: out of memory"; | ||||||
|  | static volatile bool g_memory_fully_initialized = false; | ||||||
| 
 | 
 | ||||||
| void memory::exit_when_out_of_memory(bool flag, char const * msg) { | void memory::exit_when_out_of_memory(bool flag, char const * msg) { | ||||||
|     g_exit_when_out_of_memory = flag; |     g_exit_when_out_of_memory = flag; | ||||||
|  | @ -83,10 +84,18 @@ void memory::initialize(size_t max_size) { | ||||||
|             initialize = true; |             initialize = true; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if (!initialize) |     if (initialize) { | ||||||
|         return; |         g_memory_out_of_memory = false; | ||||||
|     g_memory_out_of_memory  = false; |         mem_initialize(); | ||||||
|     mem_initialize(); |         g_memory_fully_initialized = true; | ||||||
|  |     } | ||||||
|  |     else {         | ||||||
|  |         // Delay the current thread until the DLL is fully initialized
 | ||||||
|  |         // Without this, multiple threads can start to call API functions
 | ||||||
|  |         // before memory::initialize(...) finishes.
 | ||||||
|  |         while (!g_memory_fully_initialized) | ||||||
|  |             /* wait */ ; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool memory::is_out_of_memory() { | bool memory::is_out_of_memory() { | ||||||
|  | @ -98,9 +107,9 @@ bool memory::is_out_of_memory() { | ||||||
|     return r; |     return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void memory::set_high_watermark(size_t watermak) { | void memory::set_high_watermark(size_t watermark) { | ||||||
|     // This method is only safe to invoke at initialization time, that is, before the threads are created.
 |     // This method is only safe to invoke at initialization time, that is, before the threads are created.
 | ||||||
|     g_memory_watermark = watermak; |     g_memory_watermark = watermark; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool memory::above_high_watermark() { | bool memory::above_high_watermark() { | ||||||
|  |  | ||||||
|  | @ -166,6 +166,14 @@ public: | ||||||
|         return e->get_data().m_value; |         return e->get_data().m_value; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     value const & operator[](key * k) const { | ||||||
|  |         return find(k); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     value & operator[](key * k) { | ||||||
|  |         return find(k); | ||||||
|  |     } | ||||||
|  |      | ||||||
|     iterator find_iterator(Key * k) const {  |     iterator find_iterator(Key * k) const {  | ||||||
|         return m_table.find(key_data(k)); |         return m_table.find(key_data(k)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -24,6 +24,9 @@ Revision History: | ||||||
| #include<iostream> | #include<iostream> | ||||||
| #include<climits> | #include<climits> | ||||||
| #include<limits> | #include<limits> | ||||||
|  | #ifdef _MSC_VER | ||||||
|  | #include<intrin.h> | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| #ifndef SIZE_MAX | #ifndef SIZE_MAX | ||||||
| #define SIZE_MAX std::numeric_limits<std::size_t>::max() | #define SIZE_MAX std::numeric_limits<std::size_t>::max() | ||||||
|  | @ -95,7 +98,12 @@ unsigned uint64_log2(uint64 v); | ||||||
| COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); | COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); | ||||||
| 
 | 
 | ||||||
| // Return the number of 1 bits in v.
 | // Return the number of 1 bits in v.
 | ||||||
| inline unsigned get_num_1bits(unsigned v) { | static inline unsigned get_num_1bits(unsigned v) { | ||||||
|  | #ifdef _MSC_VER | ||||||
|  |     return __popcnt(v); | ||||||
|  | #elif defined(__GNUC__) | ||||||
|  |     return __builtin_popcount(v); | ||||||
|  | #else | ||||||
| #ifdef Z3DEBUG | #ifdef Z3DEBUG | ||||||
|     unsigned c; |     unsigned c; | ||||||
|     unsigned v1 = v; |     unsigned v1 = v; | ||||||
|  | @ -108,15 +116,16 @@ inline unsigned get_num_1bits(unsigned v) { | ||||||
|     unsigned r = (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;  |     unsigned r = (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;  | ||||||
|     SASSERT(c == r); |     SASSERT(c == r); | ||||||
|     return r; |     return r; | ||||||
|  | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Remark: on gcc, the operators << and >> do not produce zero when the second argument >= 64.
 | // Remark: on gcc, the operators << and >> do not produce zero when the second argument >= 64.
 | ||||||
| // So, I'm using the following two definitions to fix the problem
 | // So, I'm using the following two definitions to fix the problem
 | ||||||
| inline uint64 shift_right(uint64 x, uint64 y) { | static inline uint64 shift_right(uint64 x, uint64 y) { | ||||||
|     return y < 64ull ? (x >> y) : 0ull; |     return y < 64ull ? (x >> y) : 0ull; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline uint64 shift_left(uint64 x, uint64 y) { | static inline uint64 shift_left(uint64 x, uint64 y) { | ||||||
|     return y < 64ull ? (x << y) : 0ull; |     return y < 64ull ? (x << y) : 0ull; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -255,10 +264,6 @@ inline std::ostream & operator<<(std::ostream & out, std::pair<T1, T2> const & p | ||||||
|     return out; |     return out; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifndef _WINDOWS |  | ||||||
| #define __forceinline inline |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| template<typename IT> | template<typename IT> | ||||||
| bool has_duplicates(const IT & begin, const IT & end) { | bool has_duplicates(const IT & begin, const IT & end) { | ||||||
|     for (IT it1 = begin; it1 != end; ++it1) { |     for (IT it1 = begin; it1 != end; ++it1) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue