From c5540c7de925156af9aec2e1a448c5f340cdaa4f Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 14:57:06 -0700 Subject: [PATCH 01/35] new xor simplification Signed-off-by: Leonardo de Moura --- src/ast/rewriter/bv_rewriter.cpp | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp index 6cd3acbc3..d1ff65e80 100644 --- a/src/ast/rewriter/bv_rewriter.cpp +++ b/src/ast/rewriter/bv_rewriter.cpp @@ -1410,6 +1410,51 @@ br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & r } } } + + // XOR is a mask + // All arguments but one is a numeral. + // + // Apply a transformation of the form: + // + // (bvxor a 0011) --> (concat ((_ extract 3 2) a) ((_ extract 1 0) (bvnot a))) + // + if (!v1.is_zero() && num_coeffs == num - 1) { + // find argument that is not a numeral + expr * t = 0; + for (unsigned i = 0; i < num; i++) { + t = args[i]; + if (!is_numeral(t)) + break; + } + SASSERT(t != 0); + numeral two(2); + expr_ref_buffer exs(m()); + expr_ref not_t(m()); + not_t = m_util.mk_bv_not(t); + unsigned low = 0; + unsigned i = 0; + while (i < sz) { + while (i < sz && mod(v1, two).is_one()) { + i++; + div(v1, two, v1); + } + if (i != low) { + exs.push_back(m_mk_extract(i-1, low, not_t)); + low = i; + } + while (i < sz && mod(v1, two).is_zero()) { + i++; + div(v1, two, v1); + } + if (i != low) { + exs.push_back(m_mk_extract(i-1, low, t)); + low = i; + } + } + std::reverse(exs.c_ptr(), exs.c_ptr() + exs.size()); + result = m_util.mk_concat(exs.size(), exs.c_ptr()); + return BR_REWRITE3; + } if (!merged && !flattened && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero() && v1 != (m_util.power_of_two(sz) - numeral(1))))) return BR_FAILED; From 3e89fc092e774f3ea93b204611ccd61007d6ff9b Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 15:27:03 -0700 Subject: [PATCH 02/35] Moved Microsoft.Z3V3 to dead folder Signed-off-by: Leonardo de Moura --- scripts/mk_make.py | 3 +-- src/bindings/dotnet/{Microsoft.Z3 => }/AST.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/ASTMap.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/ASTVector.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/ApplyResult.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Constructor.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Context.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/DecRefQUeue.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Expr.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Fixedpoint.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/FuncDecl.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/FuncInterp.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Goal.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Log.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Microsoft.Z3.csproj | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Microsoft.Z3_35.csproj | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Model.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Numeral.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/ParamDescrs.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Params.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Pattern.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Probe.cs | 0 .../dotnet/{Microsoft.Z3 => }/Properties/AssemblyInfo.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Quantifier.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Solver.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Sort.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Statistics.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Status.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Symbol.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Tactic.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Version.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Z3Exception.cs | 0 src/bindings/dotnet/{Microsoft.Z3 => }/Z3Object.cs | 0 src/bindings/dotnet/{ => dead}/Microsoft.Z3V3/AssemblyInfo.cpp | 0 .../dotnet/{ => dead}/Microsoft.Z3V3/Microsoft.Z3V3.cpp | 0 src/bindings/dotnet/{ => dead}/Microsoft.Z3V3/Microsoft.Z3V3.h | 0 .../dotnet/{ => dead}/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj | 0 37 files changed, 1 insertion(+), 2 deletions(-) rename src/bindings/dotnet/{Microsoft.Z3 => }/AST.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/ASTMap.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/ASTVector.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/ApplyResult.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Constructor.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Context.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/DecRefQUeue.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Expr.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Fixedpoint.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/FuncDecl.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/FuncInterp.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Goal.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Log.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Microsoft.Z3.csproj (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Microsoft.Z3_35.csproj (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Model.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Numeral.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/ParamDescrs.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Params.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Pattern.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Probe.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Properties/AssemblyInfo.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Quantifier.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Solver.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Sort.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Statistics.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Status.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Symbol.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Tactic.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Version.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Z3Exception.cs (100%) rename src/bindings/dotnet/{Microsoft.Z3 => }/Z3Object.cs (100%) rename src/bindings/dotnet/{ => dead}/Microsoft.Z3V3/AssemblyInfo.cpp (100%) rename src/bindings/dotnet/{ => dead}/Microsoft.Z3V3/Microsoft.Z3V3.cpp (100%) rename src/bindings/dotnet/{ => dead}/Microsoft.Z3V3/Microsoft.Z3V3.h (100%) rename src/bindings/dotnet/{ => dead}/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj (100%) diff --git a/scripts/mk_make.py b/scripts/mk_make.py index dcbd4aa56..e37013745 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -64,8 +64,7 @@ add_exe('shell', ['api', 'sat', 'extra_cmds'], exe_name='z3') add_exe('test', ['api', 'fuzzing'], exe_name='test-z3') API_files = ['z3_api.h'] add_dll('api_dll', ['api', 'sat', 'extra_cmds'], 'api/dll', reexports=['api'], dll_name='libz3', export_files=API_files) -add_dot_net_dll('dotnet', ['api_dll'], 'bindings/dotnet/Microsoft.Z3', dll_name='Microsoft.Z3', assembly_info_dir='Properties') -add_dot_net_dll('dotnetV3', ['api_dll'], 'bindings/dotnet/Microsoft.Z3V3', dll_name='Microsoft.Z3V3') +add_dot_net_dll('dotnet', ['api_dll'], 'bindings/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties') set_python_dir('bindings/python') update_version(4, 2, 0, 0) diff --git a/src/bindings/dotnet/Microsoft.Z3/AST.cs b/src/bindings/dotnet/AST.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/AST.cs rename to src/bindings/dotnet/AST.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/ASTMap.cs b/src/bindings/dotnet/ASTMap.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/ASTMap.cs rename to src/bindings/dotnet/ASTMap.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/ASTVector.cs b/src/bindings/dotnet/ASTVector.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/ASTVector.cs rename to src/bindings/dotnet/ASTVector.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/ApplyResult.cs b/src/bindings/dotnet/ApplyResult.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/ApplyResult.cs rename to src/bindings/dotnet/ApplyResult.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Constructor.cs b/src/bindings/dotnet/Constructor.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Constructor.cs rename to src/bindings/dotnet/Constructor.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Context.cs b/src/bindings/dotnet/Context.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Context.cs rename to src/bindings/dotnet/Context.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/DecRefQUeue.cs b/src/bindings/dotnet/DecRefQUeue.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/DecRefQUeue.cs rename to src/bindings/dotnet/DecRefQUeue.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Expr.cs b/src/bindings/dotnet/Expr.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Expr.cs rename to src/bindings/dotnet/Expr.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Fixedpoint.cs b/src/bindings/dotnet/Fixedpoint.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Fixedpoint.cs rename to src/bindings/dotnet/Fixedpoint.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/FuncDecl.cs b/src/bindings/dotnet/FuncDecl.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/FuncDecl.cs rename to src/bindings/dotnet/FuncDecl.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/FuncInterp.cs b/src/bindings/dotnet/FuncInterp.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/FuncInterp.cs rename to src/bindings/dotnet/FuncInterp.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Goal.cs b/src/bindings/dotnet/Goal.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Goal.cs rename to src/bindings/dotnet/Goal.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Log.cs b/src/bindings/dotnet/Log.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Log.cs rename to src/bindings/dotnet/Log.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Microsoft.Z3.csproj b/src/bindings/dotnet/Microsoft.Z3.csproj similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Microsoft.Z3.csproj rename to src/bindings/dotnet/Microsoft.Z3.csproj diff --git a/src/bindings/dotnet/Microsoft.Z3/Microsoft.Z3_35.csproj b/src/bindings/dotnet/Microsoft.Z3_35.csproj similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Microsoft.Z3_35.csproj rename to src/bindings/dotnet/Microsoft.Z3_35.csproj diff --git a/src/bindings/dotnet/Microsoft.Z3/Model.cs b/src/bindings/dotnet/Model.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Model.cs rename to src/bindings/dotnet/Model.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Numeral.cs b/src/bindings/dotnet/Numeral.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Numeral.cs rename to src/bindings/dotnet/Numeral.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/ParamDescrs.cs b/src/bindings/dotnet/ParamDescrs.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/ParamDescrs.cs rename to src/bindings/dotnet/ParamDescrs.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Params.cs b/src/bindings/dotnet/Params.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Params.cs rename to src/bindings/dotnet/Params.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Pattern.cs b/src/bindings/dotnet/Pattern.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Pattern.cs rename to src/bindings/dotnet/Pattern.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Probe.cs b/src/bindings/dotnet/Probe.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Probe.cs rename to src/bindings/dotnet/Probe.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Properties/AssemblyInfo.cs b/src/bindings/dotnet/Properties/AssemblyInfo.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Properties/AssemblyInfo.cs rename to src/bindings/dotnet/Properties/AssemblyInfo.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Quantifier.cs b/src/bindings/dotnet/Quantifier.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Quantifier.cs rename to src/bindings/dotnet/Quantifier.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Solver.cs b/src/bindings/dotnet/Solver.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Solver.cs rename to src/bindings/dotnet/Solver.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Sort.cs b/src/bindings/dotnet/Sort.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Sort.cs rename to src/bindings/dotnet/Sort.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Statistics.cs b/src/bindings/dotnet/Statistics.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Statistics.cs rename to src/bindings/dotnet/Statistics.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Status.cs b/src/bindings/dotnet/Status.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Status.cs rename to src/bindings/dotnet/Status.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Symbol.cs b/src/bindings/dotnet/Symbol.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Symbol.cs rename to src/bindings/dotnet/Symbol.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Tactic.cs b/src/bindings/dotnet/Tactic.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Tactic.cs rename to src/bindings/dotnet/Tactic.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Version.cs b/src/bindings/dotnet/Version.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Version.cs rename to src/bindings/dotnet/Version.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Z3Exception.cs b/src/bindings/dotnet/Z3Exception.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Z3Exception.cs rename to src/bindings/dotnet/Z3Exception.cs diff --git a/src/bindings/dotnet/Microsoft.Z3/Z3Object.cs b/src/bindings/dotnet/Z3Object.cs similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3/Z3Object.cs rename to src/bindings/dotnet/Z3Object.cs diff --git a/src/bindings/dotnet/Microsoft.Z3V3/AssemblyInfo.cpp b/src/bindings/dotnet/dead/Microsoft.Z3V3/AssemblyInfo.cpp similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3V3/AssemblyInfo.cpp rename to src/bindings/dotnet/dead/Microsoft.Z3V3/AssemblyInfo.cpp diff --git a/src/bindings/dotnet/Microsoft.Z3V3/Microsoft.Z3V3.cpp b/src/bindings/dotnet/dead/Microsoft.Z3V3/Microsoft.Z3V3.cpp similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3V3/Microsoft.Z3V3.cpp rename to src/bindings/dotnet/dead/Microsoft.Z3V3/Microsoft.Z3V3.cpp diff --git a/src/bindings/dotnet/Microsoft.Z3V3/Microsoft.Z3V3.h b/src/bindings/dotnet/dead/Microsoft.Z3V3/Microsoft.Z3V3.h similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3V3/Microsoft.Z3V3.h rename to src/bindings/dotnet/dead/Microsoft.Z3V3/Microsoft.Z3V3.h diff --git a/src/bindings/dotnet/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj b/src/bindings/dotnet/dead/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj similarity index 100% rename from src/bindings/dotnet/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj rename to src/bindings/dotnet/dead/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj From 25e2353c271afe02531a2a297168cd2d170609dd Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 16:31:58 -0700 Subject: [PATCH 03/35] auto gen dotnet support Signed-off-by: Leonardo de Moura --- scripts/config-vs-debug.mk | 2 +- scripts/mk_util.py | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/scripts/config-vs-debug.mk b/scripts/config-vs-debug.mk index 1b2784104..8e0cdef58 100644 --- a/scripts/config-vs-debug.mk +++ b/scripts/config-vs-debug.mk @@ -1,5 +1,5 @@ CXX=cl -CXXFLAGS=/c /ZI /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- +CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- CXX_OUT_FLAG=/Fo OBJ_EXT=.obj LIB_EXT=.lib diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 40a3d7ffd..eb644ecdc 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -160,6 +160,9 @@ def is_verbose(): def get_cpp_files(path): return filter(lambda f: f.endswith('.cpp'), os.listdir(path)) +def get_cs_files(path): + return filter(lambda f: f.endswith('.cs'), os.listdir(path)) + def find_all_deps(name, deps): new_deps = [] for dep in deps: @@ -418,8 +421,30 @@ class DotNetDLLComponent(Component): def mk_makefile(self, out): if IS_WINDOW: - # TODO - out.write('%s: \n\n' % self.name) + cs_fp_files = [] + cs_files = [] + for cs_file in get_cs_files(self.src_dir): + cs_fp_files.append('%s/%s' % (self.to_src_dir, cs_file)) + cs_files.append(cs_file) + if self.assembly_info_dir != '.': + for cs_file in get_cs_files('%s/%s' % (self.src_dir, self.assembly_info_dir)): + cs_fp_files.append('%s/%s/%s' % (self.to_src_dir, self.assembly_info_dir, cs_file)) + cs_files.append('%s\%s' % (self.assembly_info_dir, cs_file)) + dllfile = '%s.dll' % self.dll_name + out.write('%s:' % dllfile) + for cs_file in cs_fp_files: + out.write(' ') + out.write(cs_file) + out.write('\n') + out.write(' cd %s && 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- /out:%s.dll /target:library' % (self.to_src_dir, self.dll_name)) + for cs_file in cs_files: + out.write(' ') + out.write(cs_file) + out.write('\n') + # HACK + win_to_src_dir = self.to_src_dir.replace('/', '\\') + out.write(' move %s\%s\n' % (win_to_src_dir, dllfile)) + out.write('%s: %s\n\n' % (self.name, dllfile)) return def main_component(self): From 00935cffd2ba6b249a2b5bb3023dc5acf6c3b0e5 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 16:35:51 -0700 Subject: [PATCH 04/35] move pdb file to build dir Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index eb644ecdc..d939e915c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -444,6 +444,7 @@ class DotNetDLLComponent(Component): # HACK win_to_src_dir = self.to_src_dir.replace('/', '\\') out.write(' move %s\%s\n' % (win_to_src_dir, dllfile)) + out.write(' move %s\%s.pdb\n' % (win_to_src_dir, self.dll_name)) out.write('%s: %s\n\n' % (self.name, dllfile)) return From 263fb481805f1a620a326e09c84ad38158872aec Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 16:59:22 -0700 Subject: [PATCH 05/35] polishing VS build Signed-off-by: Leonardo de Moura --- scripts/config-vs-debug.mk | 2 +- src/test/imdd.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/config-vs-debug.mk b/scripts/config-vs-debug.mk index 8e0cdef58..1e2a8c58a 100644 --- a/scripts/config-vs-debug.mk +++ b/scripts/config-vs-debug.mk @@ -1,5 +1,5 @@ CXX=cl -CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- +CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- /arch:SSE2 CXX_OUT_FLAG=/Fo OBJ_EXT=.obj LIB_EXT=.lib diff --git a/src/test/imdd.cpp b/src/test/imdd.cpp index f59f87b4f..12d23993e 100644 --- a/src/test/imdd.cpp +++ b/src/test/imdd.cpp @@ -18,6 +18,8 @@ Revision History: --*/ #include"imdd.h" +#ifndef _AMD64_ + static void tst0() { std::cout << "--------------------------------\n"; imdd_manager m; @@ -607,3 +609,9 @@ void tst_imdd() { } +#else + +void tst_imdd() { +} + +#endif From 95a25265f26cc23bd952045e4ee947cab8e2eeb0 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 17:18:41 -0700 Subject: [PATCH 06/35] removed native low level parser Signed-off-by: Leonardo de Moura --- src/api/api_parsers.cpp | 35 - src/api/z3_api.h | 17 - src/api/z3_solver.cpp | 1304 -------------------------------- src/api/z3_solver.h | 1007 ------------------------ src/bindings/dotnet/Context.cs | 24 - 5 files changed, 2387 deletions(-) delete mode 100644 src/api/z3_solver.cpp delete mode 100644 src/api/z3_solver.h diff --git a/src/api/api_parsers.cpp b/src/api/api_parsers.cpp index d74ade1a7..03e947c8a 100644 --- a/src/api/api_parsers.cpp +++ b/src/api/api_parsers.cpp @@ -23,7 +23,6 @@ Revision History: #include"cmd_context.h" #include"smt2parser.h" #include"smtparser.h" -#include"z3_solver.h" extern "C" { @@ -248,40 +247,6 @@ extern "C" { return mk_c(c)->m_smtlib_error_buffer.c_str(); Z3_CATCH_RETURN(""); } - - Z3_ast parse_z3_stream(Z3_context c, std::istream& is) { - z3_solver parser(c, is, verbose_stream(), mk_c(c)->fparams(), false); - if (!parser.parse()) { - SET_ERROR_CODE(Z3_PARSER_ERROR); - return of_ast(mk_c(c)->m().mk_true()); - } - expr_ref_vector assumptions(mk_c(c)->m()); - parser.get_assumptions(assumptions); - return of_ast(mk_c(c)->mk_and(assumptions.size(), assumptions.c_ptr())); - } - - Z3_ast Z3_API Z3_parse_z3_string(Z3_context c, Z3_string str) { - Z3_TRY; - LOG_Z3_parse_z3_string(c, str); - std::string s(str); - std::istringstream is(s); - Z3_ast r = parse_z3_stream(c, is); - RETURN_Z3(r); - Z3_CATCH_RETURN(0); - } - - Z3_ast Z3_API Z3_parse_z3_file(Z3_context c, Z3_string file_name) { - Z3_TRY; - LOG_Z3_parse_z3_file(c, file_name); - std::ifstream is(file_name); - if (!is) { - SET_ERROR_CODE(Z3_PARSER_ERROR); - return 0; - } - Z3_ast r = parse_z3_stream(c, is); - RETURN_Z3(r); - Z3_CATCH_RETURN(0); - } // --------------- // Support for SMTLIB2 diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 70518b54c..9e3c73ac3 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -4977,23 +4977,6 @@ BEGIN_MLAPI_EXCLUDE Z3_string Z3_API Z3_get_smtlib_error(__in Z3_context c); END_MLAPI_EXCLUDE - /** - \brief \mlh parse_z3_string c str \endmlh - Parse the given string using the Z3 native parser. - - Return the conjunction of asserts made in the input. - - def_API('Z3_parse_z3_string', AST, (_in(CONTEXT), _in(STRING))) - */ - Z3_ast Z3_API Z3_parse_z3_string(__in Z3_context c, __in Z3_string str); - - /** - \brief Similar to #Z3_parse_z3_string, but reads the benchmark from a file. - - def_API('Z3_parse_z3_file', AST, (_in(CONTEXT), _in(STRING))) - */ - Z3_ast Z3_API Z3_parse_z3_file(__in Z3_context c, __in Z3_string file_name); - /*@}*/ #ifdef CorML4 diff --git a/src/api/z3_solver.cpp b/src/api/z3_solver.cpp deleted file mode 100644 index 097f39a86..000000000 --- a/src/api/z3_solver.cpp +++ /dev/null @@ -1,1304 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - z3_solver.cpp - -Abstract: - - Native ast parser. - -Author: - - Nikolaj Bjorner (nbjorner) 2007-07-17 - -Revision History: - ---*/ - -#include "z3_solver.h" -#include "z3_private.h" -#include "warning.h" -#include "ast_pp.h" -#include "ast_ll_pp.h" -#include "ast_smt_pp.h" -#include "version.h" -#include "array_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "arith_decl_plugin.h" -#include "lbool.h" -#include - -#define CHECK(_b_) if (!(_b_)) { return false; } - -#define CHECK_P(_b_,_m_) if (!(_b_)) { warning_msg(_m_); return false; } - -#define CHECK_CB(_b_,_cb_) if (!(_b_)) { _cb_; return false; } - -#define TRY_CHECK(_b_) if (!(_b_)) { return false; } - - -ast_manager& Z3_get_manager(Z3_context c); -Z3_context Z3_mk_context_from_params(front_end_params const& p); -void Z3_display_statistics(Z3_context c, std::ostream& s); -void Z3_display_istatistics(Z3_context c, std::ostream& s); - -z3_solver::z3_solver( - Z3_context context, - std::istream& ins, - std::ostream& ous, - front_end_params & params, - bool is_active - ) - : - m_context(context?context:Z3_mk_context_from_params(params)), - m_owns_context(context?false:true), - m_manager(Z3_get_manager(m_context)), - m_params(params), - m_in(ins), - m_out(ous), - m_is_active(is_active), - m_assumptions(m_manager), - m_num_checks(0), - m_eof(false), - m_line(1), - m_arith(m_manager), - m_bv(m_manager), - m_pinned(m_manager), - m_last_check_result(Z3_L_UNDEF) -{ - add_builtins(m_manager.get_family_id("bv")); - add_builtins(m_manager.get_family_id("arith")); - add_builtins(m_manager.get_basic_family_id()); - add_builtins(m_manager.get_family_id("array")); - add_builtins(m_manager.get_family_id("datatype")); -} - -z3_solver::z3_solver( - ast_manager& m, - std::istream& ins, - std::ostream& ous, - front_end_params & params - ) - : - m_context(0), - m_owns_context(true), - m_manager(m), - m_params(params), - m_in(ins), - m_out(ous), - m_is_active(false), - m_assumptions(m_manager), - m_num_checks(0), - m_eof(false), - m_line(1), - m_arith(m_manager), - m_bv(m_manager), - m_pinned(m_manager) -{ - add_builtins(m_manager.get_family_id("bv")); - add_builtins(m_manager.get_family_id("arith")); - add_builtins(m_manager.get_basic_family_id()); - add_builtins(m_manager.get_family_id("array")); - add_builtins(m_manager.get_family_id("datatype")); - -} - - -z3_solver::~z3_solver() -{ - m_assumptions.reset(); - m_pinned.reset(); - if (m_owns_context && m_context) { - Z3_del_context(m_context); - } -} - -void z3_solver::skip_blank() { - while (*m_in == ' ' || *m_in == '\t' || *m_in == '\r') { - ++m_in; - } -} - -bool z3_solver::next_token() { - if (m_eof) { - warning_msg("line %d. EOF reached, expecting string", m_line); - return false; - } - skip_blank(); - if (*m_in == EOF) { - m_eof = true; - return true; - } - m_string.clear(); - while (*m_in != '\n' && *m_in != ' ' && - *m_in != '\r' && - *m_in != '\t' && *m_in != EOF) { - m_string.push_back(*m_in); - ++m_in; - } - if (*m_in == '\n' && m_string.empty()) { - m_string = "\n"; - ++m_in; - } - return true; -} - - -bool z3_solver::try_parse(char const* token) { - CHECK(!m_eof); - TRY_CHECK(strcmp(token, m_string.c_str()) == 0); - CHECK(next_token()); - return true; -} - -bool z3_solver::parse_int(int& i) { - if (m_eof) { - warning_msg("line %d. EOF reached, expecting numeral", m_line); - return false; - } - const char* s = m_string.c_str(); - i = 0; - bool negate = false; - if (*s == '-') { - negate = true; - ++s; - } - // NB: overflow checks are ignored. - while ('0' <= *s && *s <= '9') { - i = (i*10) + (*s - '0'); - ++s; - } - if (negate) { - i = -i; - } - CHECK(next_token()); - return true; -} - -bool z3_solver::check_int(int& i) { - if (m_eof) { - return false; - } - const char* s = m_string.c_str(); - bool negate = false; - i = 0; - if (!(('0' <= *s && *s <= '9') || *s == '-')) { - return false; - } - if (*s == '-') { - negate = true; - ++s; - } - while ('0' <= *s && *s <= '9') { - i = (i*10) + (*s - '0'); - ++s; - } - if (negate) { - i = -i; - } - return true; -} - -bool z3_solver::parse_unsigned(unsigned& i) { - if (m_eof) { - warning_msg("line %d. EOF reached, expecting numeral", m_line); - return false; - } - const char* s = m_string.c_str(); - i = 0; - // NB: overflow checks are ignored. - while ('0' <= *s && *s <= '9') { - i = (i*10) + (*s - '0'); - ++s; - } - CHECK(next_token()); - return true; -} - -bool z3_solver::check_unsigned(unsigned& i) { - if (m_eof) { - return false; - } - const char* s = m_string.c_str(); - i = 0; - if (!('0' <= *s && *s <= '9')) { - return false; - } - while ('0' <= *s && *s <= '9') { - i = (i*10) + (*s - '0'); - ++s; - } - return true; -} - - -bool z3_solver::parse_id(symbol& id) { - size_t sz = m_string.size(); - char const* str = m_string.c_str(); - if (strcmp(str,"\"null\"") == 0) { - id = symbol(); - } - else if (sz > 0 && str[0] == '"' && str[sz-1] == '"') { - std::string s(str,sz-1); - id = s.c_str(); - } - else { - id = m_string.c_str(); - } - CHECK(next_token()); - return true; -} - - -bool z3_solver::parse_rational(rational& r) { - if (m_eof) { - warning_msg("line %d. EOF reached, expecting rational", m_line); - return false; - } - r = rational(m_string.c_str()); - CHECK(next_token()); - return true; -} - - -bool z3_solver::parse_eol() { - if (m_eof) { - warning_msg("line %d. EOF reached, expecting newline", m_line); - return false; - } - if (m_string[0] != '\n') { - warning_msg("line %d. Expecting newline, got '%s'\n", m_line, m_string.c_str()); - return false; - } - ++m_line; - CHECK(next_token()); - - return true; -} - - -z3_solver::kind z3_solver::parse_kind() { - try_again: - if (m_eof) { - return T_EOF; - } - kind k = T_ERR; - - switch(m_string[0]) { - case 'A': - if (strcmp(m_string.c_str(), "Assert") == 0) { - k = T_ASSERT; - } - else if (strcmp(m_string.c_str(), "App") == 0) { - k = T_BUILTIN_CONST; - } - break; - case 'C': - if (strcmp(m_string.c_str(), "Const") == 0) { - k = T_NULLARY_CONST; - } - else if (strcmp(m_string.c_str(), "Check") == 0) { - k = T_CHECK; - } - else if (strcmp(m_string.c_str(), "CheckAssumptions") == 0) { - k = T_CHECK_ASSUMPTIONS; - } - break; - case 'D': - if (strcmp(m_string.c_str(), "Dec") == 0) { - k = T_DEC; - } - else if (strcmp(m_string.c_str(), "DbgSat") == 0) { - k = T_DBG_SAT; - } - else if (strcmp(m_string.c_str(), "DbgUnsat") == 0) { - k = T_DBG_UNSAT; - } - break; - case 'E': - if (strcmp(m_string.c_str(), "Echo") == 0) { - k = T_ECHO; - } - break; - case 'F': - if (strcmp(m_string.c_str(), "Fun") == 0) { - k = T_FUNCTION_CONST; - } - break; - case 'G': - if (strcmp(m_string.c_str(), "GetImpliedEqualities") == 0) { - k = T_GET_IMPLIED_EQUALITIES; - } - break; - case 'L': - if (strcmp(m_string.c_str(), "Lab") == 0) { - k = T_LAB; - } - break; - case 'N': - if (strcmp(m_string.c_str(), "Num") == 0) { - k = T_NUM; - } - break; - case 'P': - if (strcmp(m_string.c_str(), "Pat") == 0) { - k = T_PAT; - } - else if (strcmp(m_string.c_str(), "Push") == 0) { - k = T_PUSH; - } - else if (strcmp(m_string.c_str(), "Pop") == 0) { - k = T_POP; - } - break; - case ';': - k = T_COMMENT; - break; - case '\n': - if (!next_token()) { - k = T_ERR; - break; - } - goto try_again; - case 'Q': - if (strcmp(m_string.c_str(), "Qua") == 0) { - k = T_QUA; - } - break; - case 'R': - if (strcmp(m_string.c_str(), "Reset") == 0) { - k = T_RESET; - } - break; - case 'S': - if (strcmp(m_string.c_str(), "Solver") == 0) { - k = T_SOLVER; - } - else if (strcmp(m_string.c_str(), "Simplify") == 0) { - k = T_SIMPLIFY; - } - break; - case 'T': - if (strcmp(m_string.c_str(), "Ty") == 0) { - k = T_TY; - } - else if (strcmp(m_string.c_str(), "Type") == 0) { - k = T_TYPE; - } - break; - case 'V': - if (strcmp(m_string.c_str(), "Var") == 0) { - k = T_VAR; - } - else if (strcmp(m_string.c_str(), "Version") == 0) { - k = T_VERSION; - } - break; - default: - break; - } - if (k == T_ERR) { - warning_msg("line %d. could not recognize token '%s'", m_line, m_string.c_str()); - } - else if (!next_token()) { - k = T_ERR; - warning_msg("line %d. could not recognize token '%s'", m_line, m_string.c_str()); - } - return k; - -} - -bool z3_solver::parse_comment() { - while (m_string[0] != '\n') { - CHECK(next_token()); - } - CHECK(parse_eol()); - return true; -} - -bool z3_solver::parse_numeral() { - symbol id; - rational r; - sort* s; - expr* n; - CHECK(parse_id(id)); - CHECK(parse_rational(r)); - CHECK(parse_ast(s, sort_coerce())); - CHECK(parse_eol()); - if (m_arith.is_int(s)) { - n = m_arith.mk_numeral(r, true); - } - else if (m_arith.is_real(s)) { - n = m_arith.mk_numeral(r, false); - } - else if (m_bv.is_bv_sort(s)) { - n = m_bv.mk_numeral(r, s); - } - else { - return false; - } - add_id(id, n); - return true; -} - - -bool z3_solver::parse_var() { - symbol id; - unsigned n; - sort* ty; - - CHECK(parse_id(id)); - CHECK(parse_unsigned(n)); - CHECK(parse_ast(ty,sort_coerce())); - CHECK(parse_eol()); - - var* v = m_manager.mk_var(n, ty); - add_id(id, v); - return true; -} - - -family_id z3_solver::get_family_id(char const* s) { - symbol sym(s); - if (sym == "null") { - return null_family_id; - } - else { - return m_manager.get_family_id(sym); - } - -} - -bool z3_solver::parse_info(scoped_ptr& info) { - bool is_assoc = false; - bool is_comm = false; - bool is_inj = false; - vector params; - family_id fid = null_family_id; - decl_kind kind = null_decl_kind; - - if (!try_parse("BUILTIN")) { - info = 0; - return true; - } - - fid = get_family_id(m_string.c_str()); - - CHECK(next_token()); - CHECK(parse_int(kind)); - - while (m_string[0] != '\n') { - std::string s; - - if (strcmp(m_string.c_str(), ":assoc") == 0) { - is_assoc = true; - } - else if (strcmp(m_string.c_str(), ":comm") == 0) { - is_comm = true; - } - else if (strcmp(m_string.c_str(), ":inj") == 0) { - is_inj = true; - } - else { - CHECK(parse_parameter(params)); - continue; - } - CHECK(next_token()); - } - - - info = alloc(func_decl_info, fid, kind, params.size(), params.c_ptr()); - info->set_associative(is_assoc); - info->set_commutative(is_comm); - info->set_injective(is_inj); - return true; -} - - -bool z3_solver::parse_info(scoped_ptr& info) { - vector params; - bool is_infinite = true; - rational num_elems; - family_id fid = null_family_id; - decl_kind kind = null_decl_kind; - - if (!try_parse("BUILTIN")) { - info = 0; - return true; - } - - fid = get_family_id(m_string.c_str()); - std::string th = m_string.c_str(); - - CHECK(next_token()); - CHECK(parse_int(kind)); - - if (try_parse("Size")) { - CHECK(parse_rational(num_elems)); - is_infinite = false; - } - - while (m_string[0] != '\n') { - CHECK(parse_parameter(params)); - } - - if (!is_infinite && num_elems.is_uint64()) { - info = alloc(sort_info, fid, kind, num_elems.get_uint64(), params.size(), params.c_ptr()); - } - else { - info = alloc(sort_info, fid, kind, params.size(), params.c_ptr()); - } - return true; -} - - -bool z3_solver::parse_nullary_const() { - func_decl* d = 0; - app* n = 0; - symbol id; - CHECK(parse_func_decl(id, d)); - SASSERT(d); - n = m_manager.mk_const(d); - CHECK(n); - add_id(id, n); - return true; - -} - -bool z3_solver::parse_func_decl() { - func_decl* d = 0; - symbol id; - CHECK(parse_func_decl(id, d)); - CHECK(d); - add_id(id, d); - return true; -} - -bool z3_solver::parse_func_decl(symbol& id, func_decl*& n) { - symbol name; - sort_ref_vector args(m_manager); - scoped_ptr info; - CHECK(parse_id(id)); - CHECK(parse_id(name)); - CHECK(parse_asts(args,sort_coerce())); - CHECK(parse_info(info)); - CHECK(parse_eol()); - if (args.size() == 0) { - warning_msg("line %d. Expecting more than 0 arguments", m_line); - return false; - } - unsigned dom_size = args.size()-1; - sort* rng = args[dom_size].get(); - - if (info.get()) { - n = m_manager.mk_func_decl( - info.get()->get_family_id(), - info.get()->get_decl_kind(), - info.get()->get_num_parameters(), - info.get()->get_parameters(), - dom_size, args.c_ptr()); - - // HACK: not all theories have name-less decl_kinds: - // constructors, tuples, marbles, etc. - if (!n) { - n = m_manager.mk_func_decl(name, dom_size, args.c_ptr(), rng, *info.get()); - } - } - else { - n = m_manager.mk_func_decl(name, dom_size, args.c_ptr(), rng); - } - CHECK(n); - add_id(id, n); - return true; -} - -bool z3_solver::parse_const() { - symbol id; - func_decl* d; - expr_ref_vector args(m_manager); - CHECK(parse_id(id)); - CHECK(parse_ast(d,func_decl_coerce())); - CHECK(parse_asts(args, expr_coerce())); - CHECK(parse_eol()); - app* n = m_manager.mk_app(d, args.size(), args.c_ptr()); - CHECK(n); - if (!m_manager.check_sorts(n)) - return false; - add_id(id, n); - return true; -} - - -// App n name [ params ] args - -bool z3_solver::find_builtin_op(symbol name, family_id & fid, decl_kind& kind) { - builtin_info bi; - CHECK(m_builtin_ops.find(name, bi)); - fid = bi.m_fid; - kind = bi.m_kind; - return true; -} - -bool z3_solver::find_builtin_type(symbol name, family_id & fid, decl_kind& kind) { - builtin_info bi; - if (!m_builtin_types.find(name, bi)) { - return false; - } - fid = bi.m_fid; - kind = bi.m_kind; - return true; -} - -void z3_solver::add_builtins(family_id fid) { - decl_plugin* plugin = m_manager.get_plugin(fid); - SASSERT(plugin); - if (!plugin) { - return; - } - svector op_names; - plugin->get_op_names(op_names); - for (unsigned i = 0; i < op_names.size(); ++i) { - m_builtin_ops.insert(op_names[i].m_name, builtin_info(fid, op_names[i].m_kind)); - } - - svector sort_names; - plugin->get_sort_names(sort_names); - for (unsigned i = 0; i < sort_names.size(); ++i) { - m_builtin_types.insert(sort_names[i].m_name, builtin_info(fid, sort_names[i].m_kind)); - } -} - - - -bool z3_solver::parse_parameter(vector& params) { - ast* a = 0; - int n; - if (check_int(n)) { - params.push_back(parameter(n)); - } - else if (m_table.find(symbol(m_string.c_str()), a)) { - params.push_back(parameter(a)); - } - else { - symbol sym; - if (!parse_id(sym)) { - return false; - } - params.push_back(parameter(sym)); - return true; - } - CHECK(next_token()); - return true; -} - - -bool z3_solver::parse_params(vector& params) { - if (strcmp(m_string.c_str(),"[") == 0) { - CHECK(next_token()); - while (strcmp(m_string.c_str(),"]") != 0) { - CHECK(parse_parameter(params)); - } - CHECK(next_token()); - } - return true; -} - - - -bool z3_solver::parse_builtin_const() { - symbol id, name; - vector params; - family_id fid; - decl_kind kind; - app* n = 0; - expr_ref_vector args(m_manager); - CHECK(parse_id(id)); - CHECK(parse_id(name)); - CHECK(parse_params(params)); - CHECK(parse_asts(args, expr_coerce())); - CHECK(parse_eol()); - - if (find_builtin_op(name, fid, kind)) { - n = m_manager.mk_app(fid, kind, - params.size(), params.c_ptr(), - args.size(), args.c_ptr()); - } - else { - func_decl* d = 0; - CHECK(parse_ast(name, d, func_decl_coerce())); - CHECK(d); - n = m_manager.mk_app(d, args.size(), args.c_ptr()); - } - - CHECK(n); - if (!m_manager.check_sorts(n)) - return false; - add_id(id, n); - return true; -} - - -bool z3_solver::parse_type() { - symbol id, name; - scoped_ptr info; - CHECK(parse_id(id)); - CHECK(parse_id(name)); - CHECK(parse_info(info)); - CHECK(parse_eol()); - sort* ty; - if (info.get()) { - ty = m_manager.mk_sort(name, *info.get()); - } - else { - ty = m_manager.mk_sort(name); - } - CHECK(ty); - add_id(id, ty); - return true; -} - - -bool z3_solver::parse_type_new() { - symbol id, name; - vector params; - CHECK(parse_id(id)); - CHECK(parse_id(name)); - CHECK(parse_params(params)); - CHECK(parse_eol()); - sort* ty; - family_id fid; - decl_kind kind; - if (find_builtin_type(name, fid, kind)) { - ty = m_manager.mk_sort(fid, kind, params.size(), params.c_ptr()); - } - else { - ty = m_manager.mk_sort(name); - } - CHECK(ty); - add_id(id, ty); - return true; -} - - -bool z3_solver::parse_label() { - symbol id, name; - std::string s; - expr* a; - CHECK(parse_id(id)); - CHECK(next_token()); - s = m_string; - CHECK(parse_id(name)); - CHECK(parse_ast(a, expr_coerce())); - CHECK(parse_eol()); - bool pos = (strcmp("LBLPOS",s.c_str()) == 0); - app* n = m_manager.mk_label(pos, name, a); - CHECK(n); - add_id(id, n); - return true; -} - -bool z3_solver::parse_quantifier() { - std::string s; - symbol id; - unsigned num_decls, num_patterns; - expr* body; - bool is_forall; - unsigned weight; - symbol skid, qid; - svector names; - ptr_vector types; - ptr_vector patterns; - - CHECK(parse_id(id)); - s = m_string; - CHECK(next_token()); - is_forall = (strcmp("FORALL",s.c_str()) == 0); - CHECK_P(parse_unsigned(weight), "Expected unsigned integer"); - CHECK_P(parse_id(skid), "Expected symbol identifier"); - CHECK_P(parse_id(qid), "Expected symbol identifier"); - CHECK_P(parse_unsigned(num_decls), "Expected unsigned integer for number of declarations"); - for (unsigned i = 0; i < num_decls; ++i) { - symbol name; - sort* ty; - CHECK_P(parse_id(name), "Expected identifier"); - CHECK_P(parse_ast(ty, sort_coerce()), "Expected sort"); - names.push_back(name); - types.push_back(ty); - } - CHECK_P(parse_unsigned(num_patterns), "Expected unsigned integer for number of patterns"); - for (unsigned i = 0; i < num_patterns; ++i) { - app* p; - CHECK_P(parse_ast(p, pattern_coerce(m_manager)), "Expected pattern"); - patterns.push_back(p); - } - CHECK_P(parse_ast(body, expr_coerce()), "Expected expression"); - CHECK(parse_eol()); - - CHECK_P(m_manager.is_bool(body), "Body of quantifier should be Boolean type"); - CHECK_P(!m_manager.is_pattern(body), "Body of quantifier cannot be a pattern"); - - -#if 0 - if (qid == symbol() && m_params.m_default_qid) { - qid = symbol(m_line); - } -#endif - if (num_decls > 0) { - quantifier* n = m_manager.mk_quantifier( - is_forall, - num_decls, types.c_ptr(), names.c_ptr(), body, - weight, qid, skid, - num_patterns, patterns.c_ptr() - ); - CHECK(n); - add_id(id, n); - } - else { - add_id(id, body); - } - return true; -} - - - -bool z3_solver::parse_pattern() { - symbol id; - app_ref_vector patterns(m_manager); - CHECK(parse_id(id)); - CHECK(parse_asts(patterns, app_coerce())); - CHECK(parse_eol()); - app* n = m_manager.mk_pattern(patterns.size(), patterns.c_ptr()); - CHECK(n); - add_id(id, n); - return true; -} - - - -bool z3_solver::parse_assert() -{ - expr* a = 0; - CHECK(parse_ast(a, expr_coerce())); - CHECK(parse_eol()); - if (m_params.m_ast_ll_pp) { - ast_ll_pp(m_out, m_manager, a, true); - m_out.flush(); - } - if (m_params.m_ast_smt_pp) { - for (unsigned i = 0; i < m_pinned_lim.size(); ++i) { - m_out << " "; - } - m_out << mk_pp(a, m_manager) << "\n"; - m_out.flush(); - } - if (m_is_active && m_context) { - Z3_assert_cnstr(m_context, reinterpret_cast(a)); - if (m_params.m_smtlib_trace_path.size() > 0) { - m_assumptions.push_back(a); - } - } - else { - m_assumptions.push_back(a); - } - return true; -} - - -bool z3_solver::parse_simplify() -{ - expr* a = 0; - CHECK(parse_ast(a, expr_coerce())); - CHECK(parse_eol()); - if (m_params.m_ast_ll_pp) { - ast_ll_pp(m_out, m_manager, a, true); - m_out.flush(); - } - if (m_params.m_ast_smt_pp) { - for (unsigned i = 0; i < m_pinned_lim.size(); ++i) { - m_out << " "; - } - m_out << mk_pp(a, m_manager) << "\n"; - m_out.flush(); - } - if (m_is_active && m_context) { - Z3_ast r = Z3_simplify(m_context, reinterpret_cast(a)); - m_out << mk_pp(reinterpret_cast(r), m_manager) << "\n"; - m_out.flush(); - } - return true; -} - - - -bool z3_solver::parse_check() -{ - CHECK(parse_eol()); - - if (!m_context || !m_is_active) { - return true; - } - - Z3_model m = 0; - Z3_ast pr = 0; - Z3_lbool result = Z3_check_assumptions(m_context, 0, 0, &m, &pr, 0, 0); - m_last_check_result = result; - - // display the model. - - if (m && m_params.m_model) { - char const* md = Z3_model_to_string(m_context, m); - if (md) { - m_out << md; - } - } - if (m) { - Z3_del_model(m_context, m); - } - - if (result == Z3_L_FALSE && pr != 0 && m_params.m_display_proof) { - m_out << mk_ll_pp(reinterpret_cast(pr), m_manager, true, false); - } - - switch(result) { - case l_false: m_out << "unsat\n"; break; - case l_true: m_out << "sat\n"; break; - case l_undef: m_out << "unknown\n"; break; - } - m_out.flush(); - - dump_smtlib_benchmark(0, 0, result); - return true; -} - -void z3_solver::dump_smtlib_benchmark(unsigned num_assumptions, expr* const* assumptions, Z3_lbool result) { - // - // Generate SMT-LIB benchmark from current set of assertions. - // - if (m_params.m_dump_goal_as_smt || m_params.m_smtlib_trace_path.size() > 0) { - ast_smt_pp pp(m_manager); - pp.set_logic(m_params.m_smtlib_logic.c_str()); - pp.set_source_info(m_params.m_smtlib_source_info.c_str()); - pp.set_category(m_params.m_smtlib_category.c_str()); - for (unsigned i = 0; i < m_assumptions.size(); ++i) { - pp.add_assumption(m_assumptions[i].get()); - } - for (unsigned i = 0; i < num_assumptions; ++i) { - pp.add_assumption_star(assumptions[i]); - } - char const* status = (result == Z3_L_FALSE)?"unsat":((result == Z3_L_TRUE)?"sat":"unknown"); - pp.set_status(status); - std::ostringstream buffer; - if (m_params.m_smtlib_trace_path.size() > 0) { - buffer << m_params.m_smtlib_trace_path.c_str() << "_" << m_num_checks << ".smt2"; - } - else { - buffer << "query." << m_num_checks << ".smts"; - } - std::ofstream out(buffer.str().c_str()); - if (!out.fail() && !out.bad()) { - pp.display_smt2(out, m_manager.mk_true()); - } - m_num_checks++; - out.close(); - } - -} - - -bool z3_solver::parse_get_implied_equalities() -{ - expr_ref_vector args(m_manager); - unsigned_vector cls; - CHECK(parse_asts(args, expr_coerce())); - CHECK(parse_eol()); - cls.resize(args.size()); - - if (!m_context) { - return true; - } - - - TRACE("get_implied_equalities", tout << "checking assumptions...\n" << Z3_context_to_string(m_context) << "\n";); - Z3_lbool result = Z3_get_implied_equalities(m_context, args.size(), reinterpret_cast(args.c_ptr()), cls.c_ptr()); - TRACE("get_implied_equalities", tout << "after checking assumptions...\n" << Z3_context_to_string(m_context) << "\n";); - m_last_check_result = result; - - m_out << ";Implied Equality Classes: "; - for (unsigned i = 0; i < cls.size(); ++i) { - m_out << cls[i] << " "; - } - m_out << "\n"; - - m_out.flush(); - - return true; -} - - -bool z3_solver::parse_check_assumptions() -{ - expr_ref_vector args(m_manager); - CHECK(parse_asts(args, expr_coerce())); - CHECK(parse_eol()); - - if (!m_context) { - return true; - } - - Z3_model m = 0; - - Z3_ast pr = 0; - - TRACE("check_assumptions", tout << "checking assumptions...\n" << Z3_context_to_string(m_context) << "\n";); - Z3_lbool result = Z3_check_assumptions(m_context, args.size(), reinterpret_cast(args.c_ptr()), &m, &pr, 0, 0); - TRACE("check_assumptions", tout << "after checking assumptions...\n" << Z3_context_to_string(m_context) << "\n";); - m_last_check_result = result; - - // display the model. - - if (m && m_params.m_model) { - char const* md = Z3_model_to_string(m_context, m); - if (md) { - m_out << md; - } - } - if (m) { - Z3_del_model(m_context, m); - } - - if (result == Z3_L_FALSE && pr != 0 && m_params.m_display_proof) { - m_out << mk_ll_pp(reinterpret_cast(pr), m_manager, true, false); - } - - switch(result) { - case l_false: m_out << "unsat\n"; break; - case l_true: m_out << "sat\n"; break; - case l_undef: m_out << "unknown\n"; break; - } - m_out.flush(); - - dump_smtlib_benchmark(args.size(), args.c_ptr(), result); - - return true; -} - -bool z3_solver::parse_dbg(bool expected_sat) { - CHECK(parse_eol()); - if (m_last_check_result == Z3_L_FALSE && expected_sat) { - m_out << "!!!!!!!!BUG FOUND!!!!!!!!!\n"; - throw z3_error(ERR_UNSOUNDNESS); - } - if (m_last_check_result == Z3_L_TRUE && !expected_sat) { - m_out << "!!!!!!!!BUG FOUND!!!!!!!!!\n"; - throw z3_error(ERR_INCOMPLETENESS); - } - if (m_last_check_result == Z3_L_UNDEF) { - throw z3_error(ERR_UNKNOWN_RESULT); - } - return true; -} - -bool z3_solver::parse_push() -{ - CHECK(parse_eol()); - if (m_context) { - Z3_push(m_context); - } - m_pinned_lim.push_back(m_pinned.size()); - m_assumptions_lim.push_back(m_assumptions.size()); - return true; -} - - -bool z3_solver::parse_pop() -{ - CHECK(parse_eol()); - if (m_context) { - Z3_pop(m_context, 1); - } - m_pinned.resize(m_pinned_lim.back()); - m_pinned_lim.pop_back(); - m_assumptions.resize(m_assumptions_lim.back()); - m_assumptions_lim.pop_back(); - return true; -} - - -bool z3_solver::parse_reset() -{ - CHECK(parse_eol()); - if (m_context) { - Z3_del_context(m_context); - Z3_config m_config = 0; // TBD. - m_context = Z3_mk_context(m_config); - } - return true; -} - -bool z3_solver::parse_echo() -{ - CHECK(parse_eol()); - // TBD - return true; -} - -bool z3_solver::parse_version() -{ - unsigned major, minor; - CHECK(parse_unsigned(major)); - CHECK(parse_unsigned(minor)); - CHECK(next_token()); // build date - CHECK(next_token()); // revision - CHECK(parse_eol()); - if (major != Z3_MAJOR_VERSION) { - warning_msg("Parser is incompatible. Major version %d has changed to %d", major, Z3_MAJOR_VERSION); - return false; - } - if (minor > Z3_MINOR_VERSION) { - warning_msg("Parser is incompatible. Minor version %d of parser is younger than %d", Z3_MINOR_VERSION, minor); - return false; - } - return true; -} - - -bool z3_solver::parse_solver() -{ - std::string s; - const char * str; - s = m_string; - CHECK(next_token()); - CHECK(parse_eol()); - str = s.c_str(); -#if 0 - if (!m_solver) { - - } - else if (strcmp(str,"LIA") == 0) { - m_solver->register_arith(unmanaged_wrapper::LIA); - } - else if (strcmp(str,"LRA") == 0) { - m_solver->register_arith(unmanaged_wrapper::MIA); - } - else if (strcmp(str,"BV") == 0) { - m_solver->register_bv(); - } -#endif - return true; -} - -bool z3_solver::parse() -{ - next_token(); - bool ok = true; - while (ok) { - switch(parse_kind()) { - case T_NUM: - ok = parse_numeral(); - break; - case T_VAR: - ok = parse_var(); - break; - case T_DEC: - ok = parse_func_decl(); - break; - case T_FUNCTION_CONST: - ok = parse_const(); - break; - case T_GET_IMPLIED_EQUALITIES: - ok = parse_get_implied_equalities(); - break; - case T_NULLARY_CONST: - ok = parse_nullary_const(); - break; - case T_BUILTIN_CONST: - ok = parse_builtin_const(); - break; - case T_TY: - ok = parse_type(); - break; - case T_TYPE: - ok = parse_type_new(); - break; - case T_QUA: - ok = parse_quantifier(); - break; - case T_LAB: - ok = parse_label(); - break; - case T_PAT: - ok = parse_pattern(); - break; - case T_ASSERT: - ok = parse_assert(); - break; - case T_SOLVER: - ok = parse_solver(); - break; - case T_SIMPLIFY: - ok = parse_simplify(); - break; - case T_PUSH: - ok = parse_push(); - break; - case T_CHECK: - ok = parse_check(); - break; - case T_CHECK_ASSUMPTIONS: - ok = parse_check_assumptions(); - break; - case T_DBG_SAT: - ok = parse_dbg(true); - break; - case T_DBG_UNSAT: - ok = parse_dbg(false); - break; - case T_POP: - ok = parse_pop(); - break; - case T_RESET: - ok = parse_reset(); - break; - case T_COMMENT: - ok = parse_comment(); - break; - case T_ECHO: - ok = parse_echo(); - break; - case T_VERSION: - ok = parse_version(); - break; - case T_EOF: - return true; - case T_ERR: - return false; - case T_CTX: - // [Leo]: this case is not handled. - break; - } - } - if (!ok) { - warning_msg("line %d. error encountered", m_line); - } - return ok; -} - -void z3_solver::display_statistics(std::ostream& out, bool istats) -{ - if (m_context) { - if (istats) { - Z3_display_istatistics(m_context, out); - } - else { - Z3_display_statistics(m_context, out); - } - } -} - -void z3_solver::add_id(symbol const& id, ast* n) { - m_table.insert(id, n); - m_pinned.push_back(n); -} - diff --git a/src/api/z3_solver.h b/src/api/z3_solver.h deleted file mode 100644 index 0876646ac..000000000 --- a/src/api/z3_solver.h +++ /dev/null @@ -1,1007 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - z3_solver.h - -Abstract: - - Native ast parser. - -Author: - - Nikolaj Bjorner (nbjorner) 2007-07-17 - -Revision History: - ---*/ - -/** - \defgroup z3native Z3 low level input format - - This format is mainly used for generating logs. These logs - capture the expressions created using the Z3 API, and - the main commands available there. - It is very low-level and follows - some of the conventions found in the DIMACS format for SAT problems - and by the Spear - input format. - - The format is extensible, as the grammar allows for - selecting solvers and adding \emph{semantic attachments} - with constructors. The SMT-LIB and Simplify text formats are easier to - write and read for a human consumer. - - Every line consists of a command that gets interpreted - as a declaration of a node in anbstract syntax tree, or as - a control instruction to Z3, such as to augment the current - context with constraints or check for satisfiability. - - \nicebox{ - command := - | ast - | control - | ; commented line - } - - - White spaces are implicit in the production rules. - The legal white-spaces have the ASCII representations - - \nicebox{ - ' ' | \ t | \ r - } - - Comment lines start with \c ;. - All characters up to the newline \ n are ignored. - - We use id for identifiers in general. - Identifiers associated with certain semantic categories, - such as \emph{ast} nodes, or \emph{type}s are - prefixed by the category and suffixed by \emph{id}. - For example, we have: - - \nicebox{ - ast-id - identifier for ast nodes - - type-id - identifier for type nodes - - parameter-id - identifier for ast - - name-id - identifier for a function/type name - - decl-id - identifier for declaration node - - context-id - identifier for Boolean context - } - - Identifiers can be any sequence of non-whitespace - and non-newline characters whose first character - is not one of the decimal digits. - Identifiers enclosed in quotes ''...'' - are treated specially: the quotes are stripped. - Thus, the identifier consisting of zero characters - is written ''''. The identifier ''null'' - is allowed for skolem-id and quant-id. - - \section nativecontrol Control commands - - To load a theory solver for integer linear arithmetic, - include a line of the form \ty{Solver LIA}. To load the - mixed integer/real solver include instead a line of the - form \ty{Solver LRA} - - Use \ty{Push} and \ty{Pop} to push/pop contexts - (constraints that are asserted - under a \ty{Push} are removed after a \ty{Pop}). - To reset the state entirely, use \ty{Reset}. - - To assert a constraint use \ty{Assert} \emph{ast-id}, - where the \emph{ast-id} is an identifier declared - for a boolean typed term. - - To check for satisfiability of all asserted constraints - use \ty{Check}. - - \nicebox{ - control := - | Solver solver - load specified theory solver - | Assert ast-id - assert constraint - | Check - check for satisfiability of asserts - | Push - push a context - | Pop - pop a context - | Version major minor build-number revision - specify Z3 version - - solver := - | LRA - mixed integer/real arithmetic - | LIA - integer arithmetic} - - \section z3nativeast Abstract syntax trees - - Every node in the abstract syntax trees understood by Z3 - is declared by using a syntax category identifier, followed - by a (unique) identifier that names the node. The - node identifier is followed by a description of the node. - - In overview abstract syntax tree nodes are declared using the commands: - - \nicebox{ - ast := - | Type id type - | Dec id declaration - | Const id constant - | Fun id function - | App id built-in - | Num id numeral - | Qua id quantifier - | Var id bound-variable - | Ctx id local-context - | Lab id label-term - | Pat id pattern - } - - \subsection z3nativetypes Types - - Types are created from a name and optional parameters. - A number of names are reserved for built-in theories. - These names are: - \nicebox{ - Int Real Bool bv array - } - When the name of a type is one of these, the type is automatically - associated with the respective theory. - The \ty{bv} type takes one numeric parameter (the bit-width of the - bit-vector), and \ty{array} takes n+1 parameters (the n - types for the domain of the array and the last parameter for the - range of the array. - - \nicebox{ - type := name '[' parameter* ']' - - parameter := number | ast-id | symbol - } - A parameter can either be an integer, an identifier used for - another defined term or type, or a symbol. Symbols are given as - strings. The parser first attempts to identify a parameter as - a previously defined term or type, and if there is no - such previously defined term/type, then it treats the string - as a symbol. - - \subsection nativez3Fuctions Function and constant declarations - In Z3, functions are constants that take more than zero arguments, - thus, everything is treated as a constant. - - Constant declarations comprise of a name, followed by - a non-empty list of types, all but the first types - are the domain of the function (there are no domain - types for 0-ary constants), the last type is the range. - A constant declaration is followed by optional - theory specific information. - - The codes used in the theory specific information is described under \ref theories - - The theory specific information indicates - whether the constant is associative/commutative/injective; - a list of parameters may also be used to indicate - auxiliary information for the constant declarations. - - \nicebox{ - declaration := name-id type-id* [const-info] - - const-info := BUILTIN theory kind-num (:assoc | :comm | :inj | parameter)* - - theory := - | basic - built-in types and operations - | arith - arithmetical - | bv - bit-vectors - | array - arrays - | datatype - datatypes - } - - - \subsection z3nativeterms Terms - - - Terms are built from constants, function applications, - labeling, context formation, quantification - and bound variables. - - A constant consists of a declarations, functions consist of - a declaration followed by a non-empty list of term identifiers. - All constants and function applications can be constructed using - the \ty{Fun} construct. However, two shortcuts are available. - -
    -
  • \ty{Const}: - Constants may be defined directly by supplying the name and the type of the constant. -
  • -
  • \ty{App}: - Built-in arithmetic, array, bit-vector, and Boolean operations may be applied directly - to their arguments without first providing function declarations. -
  • -
- - \nicebox{ - constant := name-id type-id - - function := decl-id ast-id* - - built-in := name-id [ [ parameter* ] ] ast-id* - } - - Labeled terms consist of a polarity (\ty{LBLPOS} for positive - context, \ty{LBLNEG} for negative contexts), a name, and a - term identifier. - - - \nicebox{ - label-term := (LBLPOS | LBLNEG) label-name ast-id - } - - Local contexts consist of an identifier for the underlying - term, followed by a predicate summarizing the context in - which the term is interpreted. - - \nicebox{ - local-context := ast-id context-id - } - - A quantifier consists of -
    -
  • -A number indiciating the -weight of the quantifier (for matching precedence), -
  • -A skolem identifier, used for Boogie quantifier instantiation, -
  • -A quantifier identifier, used for profiling instantiations, -
  • -A number indicating how many variables are bound by the quantifier, followed -by the bound variables, which are -
      -
    • A name for the bound variable. -
    • An identifier for the type of the bound variable. -
    -
  • -A number indicating how many patterns are associated with the quantifier, -followed by the patterns, which are -
      -
    • An identifier for the pattern. -
    -
  • An identifier for the body of the quantifier. -
- - \nicebox{ - quantifier := - (FORALL | EXISTS) - weight-num - skolem-id - quant-id - decls-num - (name-id type-id)* - pattern-num - pattern-id* - ast-id - } - -A bound variable consists of a de-Brujin index for the bound -variable together with the type of the bound variable. -While the type can be computed by matching the index of -the de-Brujin index with the associated quantifier, - -Patterns comprise of a list of terms. - - - \nicebox{ - bound-variable := index-num type-id - - numeral := rational type-id - - rational := number [/number] - - number := [0-9]+ - - pattern := id ast-id* - } - - -\section z3nativeexamples Examples - -\subsection z3nativearithmetic Integer Arithmetic - -Suppose we wish to check whether -\nicebox{ - z0 >= 0 && z1 >= 0 && z2 >= 1 && z1 >= z2 && z2 >= z0 -} -is satisfiable for
z0, z1, z2
integers. -With the low-level input format, we may specify this by: - -\nicebox{ - Type INT Int - Type BOOL Bool - Const z0 z0 INT - Const z1 z1 INT - Const z2 z2 INT - Num 0 0 INT - Num 1 1 INT - App c0 >= z0 0 - Assert c0 - App c1 >= z1 0 - Assert c1 - App c2 >= z2 1 - Assert c2 - App c3 >= z1 z2 - Assert c3 - App c4 >= z2 z0 - Assert c4 - Check -} - - -Notice that the identifiers may be arbitrary strings, including numerals. -So for instance, we used 1 to represent integer 1. - -\subsection z3nativebv Bit-vectors - -We can check whether 32-bit addition is commutative. Z3 reports \ty{unsat} -in for the first check. The second satisfiable check illustrates the use of parameters -(\ty{extract} takes two integer parameters for the range of bits extracted -from the bit-vectors). - -\nicebox{ - Type bool Bool - Type bv32 bv [ 32 ] - Type bv64 bv [ 64 ] - Num 0 0 bv32 - Num 1 1 bv32 - Const x0 x0 bv32 - Const x1 x1 bv32 - Const x2 x2 bv64 - App a bvadd x0 x1 - App b bvadd x1 x0 - App eq = a b - App constraint1 not eq - Push - Assert constraint1 - Check - Pop - App c extract [ 31 0 ] x2 - App eq2 = a c - App constraint2 not eq2 - Push - Assert constraint2 - Check - Pop -} - -We added the declarations of bit-vector constants 0 and 1. Like integers, -these are also numerals, but with bit-vector type. - - -\subsection z3nativeexarray Arrays - -The low-level version of: -\nicebox{ - store(f1,i1,v1) = store(f2,i2,v2) && i1 != i3 && i2 != i3 && select(f1,i3) != select(f2,i3) -} -is: - -\nicebox{ - Type Index Index - Type Elem Elem - Type Array array [ Index Elem ] - Type bool Bool - Const i1 i1 Index - Const i2 i2 Index - Const i3 i3 Index - Const v1 v1 Elem - Const v2 v2 Elem - Const f1 f1 Array - Const f2 f2 Array - App n1 store f1 i1 v1 - App n2 store f2 i2 v2 - App n3 = n1 n2 - App n4 = i1 i3 - App n5 not n4 - App n6 = i2 i3 - App n7 not n6 - App n8 select f1 i3 - App n9 select f2 i3 - App n10 = n8 n9 - App n11 not n10 - Assert n3 - Assert n5 - Assert n7 - Assert n11 - Check -} - -\subsection z3nativeexdatatype Data-types - -To check projection over tuples -\nicebox{ - (= x (first (mk_tuple x y))) -} - -we write: -\nicebox{ - Type int Int - Type pair tuple [ mk_tuple first int second int ] - Const x x int - Const y y int - Const p p pair - App n1 mk_tuple x y - App n2 first n1 - App n3 = n2 x - App n4 not n3 - Assert n4 - Check -} - - -*/ - - /** - - \defgroup theories Z3 theories - - - \section theorisbasics Basics - -There is a single basic sort, \ty{bool}, which has op-code 0. -The basic operators are, listed with their codes in the table below. - - - - - - - - - - - - - - - - - - -
Op-codeMnmonicsDescription
0 \ty{true} the constant \emph{true}
1 \ty{false} the constant \emph{false}
2 \ty{=} equality
3 \ty{distinct} distincinctness
4 \ty{ite} if-then-else
5 \ty{and} n-ary conjunction
6 \ty{or} n-ary disjunction
7 \ty{iff} bi-impliciation
8 \ty{xor} exclusive or
9 \ty{not} negation
10 \ty{implies} implication
- - \section theoriesarithmetic Arithmetic - - \subsection tharithbuiltin Built-in operators - - Arithmetical expression can be built from reals or integers. - The arithmetical sorts are listed below - and the supported operations are listed in the table thereafter. - - - - - - - - - -
Op-codeMnmonicsDescription
0 \ty{real} sort of reals
1 \ty{int} sort of integers
- - - - - - - - - - - - - - - - - - - -
Op-codeMnmonicsDescription
0 \ty{<=} less-than or equal
1 \ty{>=} greater-than or equal
2 \ty{<} less-than
3 \ty{>} greater-than
4 \ty{+} n-ary addition
5 \ty{-} binary minus
6 \ty{~} unary minus
7 \ty{*} n-ary multiplication
8 \ty{/} rational division
9 \ty{div} integer division
10 \ty{rem} integer remainder
11 \ty{mod} integer modulus
- - \section theoriesbv Bit-vectors -To indicate the bit-vector length one adds a numeral parameter -with the number of bits the bit-vector holds. -For instance, a declaration of the form: - -\nicebox{ - Type $1 bv [ 32 ] -} - -declares a 32-bit bit-vector type. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Op-codeMnmonicsParametersDescription
0 \ty{bit1} constant comprising of a single bit set to 1
1 \ty{bit0} constant comprising of a single bit set to 0.
2 \ty{bvneg} Unary subtraction.
3 \ty{bvadd} addition.
4 \ty{bvsub} subtraction.
5 \ty{bvmul} multiplication.
6 \ty{bvsdiv} signed division.
7 \ty{bvudiv} unsigned division. -The operands are treated as unsigned numbers.
8 \ty{bvsrem} signed remainder.
9 \ty{bvurem} unsigned remainder.
10 \ty{bvsmod} signed modulus.
11 \ty{bvule} unsigned \ty{<=}.
12 \ty{bvsle} signed \ty{<=}.
13 \ty{bvuge} unsigned \ty{>=}.
14 \ty{bvsge} signed \ty{>=}.
15 \ty{bvult} unsigned \ty{<}.
16 \ty{bvslt} signed \ty{<}.
17 \ty{bvugt} unsigned \ty{>}.
18 \ty{bvsgt} signed \ty{>}.
19 \ty{bvand} n-ary (associative/commutative) bit-wise and.
20 \ty{bvor} n-ary (associative/commutative) bit-wise or.
21 \ty{bvnot} bit-wise not.
22 \ty{bvxor} n-ary bit-wise xor.
23 \ty{bvnand} bit-wise nand.
24 \ty{bvnor} bit-wise nor.
25 \ty{bvxnor} bit-wise exclusive nor.
26 \ty{concat} bit-vector concatentaion.
27 \ty{sign\_extend} \emph{n} \emph{n}-bit sign extension.
28 \ty{zero\_extend} \emph{n} \emph{n}-bit zero extension.
29 \ty{extract} \emph{hi:low} \emph{hi}-\emph{low} bit-extraction.
30 \ty{repeat} \emph{n} repeat $n$ times.
31 \ty{bvredor} or-reduction.
32 \ty{bvredand} and-reducdtion.
33 \ty{bvcomp} bit-vector comparison.
34 \ty{bvshl} shift-left.
35 \ty{bvlshr} logical shift-right.
36 \ty{bvrshr} arithmetical shift-right.
37 \ty{bvrotate\_left} \emph{n} \emph{n}-bit left rotation.
38 \ty{bvrotate\_right} \emph{n} \emph{n}-bit right rotation.
- -\section theoriesarrays Arrays - -\subsection tharraybuiltinops Built-in operators - - There is a single built-in sort constructor for arrays with code 0. - It is followed by a sequence of parameters indicating the domain - sorts and the range of the array. - - - - - - - - - - -
Op-codeMnmonicsDescription
0 \ty{store} array store
1 \ty{select} array select
- - In the low-level input format, array types - are accompanied by a sequence of identifiers corresponding - to the domain and range of the array the operations operate - upon. - In more detail, the contract is that the supplied parameters - to the type declaration of an array are of the form: - -
    -
  • parameter_0 - 1'st dimension -
  • parameter_{n-1} - n'th dimension -
  • parameter_n - range -
- - The constant array function symbol \ty{const} needs a parameter - in order to infer the types of the indices of the constant array. - We pass the array type as the parameter to \ty{const}. - The other array operations do not need parameters. - - We summarize the arities and semantics of the operators: - -
    -
  • \ty{store} - - -Updates an array at a given index with a value: - \ty{store}(A, i0, ... i_{n-1}, v) has the same contents as A, except on -index i0, ... , i_{n-1}, where the value is v. - -
  • \ty{select} - - - Selects the value from an array: - \ty{select}(A, i0, ... , i_{n-}) selects the value stored at - index i0, ... , i_{n-1}. -
- - - - - */ -#ifndef _Z3_SOLVER_H_ -#define _Z3_SOLVER_H_ - -#include "ast.h" -#include "symbol_table.h" -#include "stream_buffer.h" -#include "warning.h" -#include "front_end_params.h" -#include "arith_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "z3.h" - - -class z3_solver { - - enum kind { - T_NUM, - T_VAR, - T_DEC, - T_FUNCTION_CONST, - T_GET_IMPLIED_EQUALITIES, - T_NULLARY_CONST, - T_BUILTIN_CONST, - T_TY, - T_TYPE, - T_QUA, - T_LAB, - T_CTX, - T_PAT, - - T_SOLVER, - T_SIMPLIFY, - - T_ASSERT, - T_CHECK, - T_CHECK_ASSUMPTIONS, - T_DBG_SAT, - T_DBG_UNSAT, - T_PUSH, - T_POP, - T_RESET, - T_ECHO, - T_VERSION, - - T_COMMENT, - - T_EOF, - T_ERR - }; - - struct builtin_info { - family_id m_fid; - decl_kind m_kind; - builtin_info(family_id fid, decl_kind k) : m_fid(fid), m_kind(k) {} - builtin_info(): m_fid(null_family_id), m_kind(null_decl_kind) {} - }; - - Z3_context m_context; - bool m_owns_context; - ast_manager& m_manager; - front_end_params& m_params; - symbol_table m_table; - stream_buffer m_in; - std::ostream& m_out; - bool m_is_active; - expr_ref_vector m_assumptions; - unsigned_vector m_assumptions_lim; - unsigned m_num_checks; - std::string m_string; - bool m_eof; - unsigned m_line; - symbol_table m_builtin_ops; - symbol_table m_builtin_types; - arith_util m_arith; - bv_util m_bv; - ast_ref_vector m_pinned; - unsigned_vector m_pinned_lim; - Z3_lbool m_last_check_result; - -public: - - z3_solver( - Z3_context c, - std::istream& is, - std::ostream& os, - front_end_params & params, - bool is_active = true - ); - - z3_solver( - ast_manager& m, - std::istream& is, - std::ostream& os, - front_end_params & params - ); - - ~z3_solver(); - - bool parse(); - - void get_assumptions(expr_ref_vector& v) { v.append(m_assumptions); } - - void display_statistics(std::ostream& out, bool istats); - - void set_error_handler(Z3_error_handler h) { - Z3_set_error_handler(m_context, h); - } - -private: - - template - struct coerce { - virtual ~coerce() {} - virtual T* operator()(ast* a) const = 0; - }; - - struct sort_coerce : public coerce { - virtual sort* operator()(ast* a) const { - if (!a || a->get_kind() != AST_SORT) { - return 0; - } - return to_sort(a); - } - }; - - struct func_decl_coerce : public coerce { - virtual func_decl* operator()(ast* a) const { - if (!a || a->get_kind() != AST_FUNC_DECL) { - return 0; - } - return to_func_decl(a); - } - }; - - struct pattern_coerce : public coerce { - ast_manager& m_manager; - pattern_coerce(ast_manager& m): m_manager(m) {} - virtual app* operator()(ast* a) const { - if (!a || a->get_kind() != AST_APP) { - return 0; - } - if (!m_manager.is_pattern(to_app(a))) { - return 0; - } - return to_app(a); - } - }; - - struct expr_coerce : public coerce { - virtual expr* operator()(ast* a) const { - if (!a) { - return 0; - } - ast_kind k = a->get_kind(); - switch(k) { - case AST_APP: - case AST_QUANTIFIER: - case AST_VAR: - return reinterpret_cast(a); - default: - return 0; - } - } - }; - - struct app_coerce : public coerce { - virtual app* operator()(ast* a) const { - if (!a) { - return 0; - } - if (a->get_kind() == AST_APP) { - return to_app(a); - } - return 0; - } - }; - - - template - bool parse_ast(symbol id, T*& n, const coerce& coerce) - { - ast* a; - if (!m_table.find(id, a)) { - warning_msg("line %d. Could not find id '%s'\n", - m_line, id.str().c_str()); - return false; - } - n = coerce(a); - if (n == 0) { - warning_msg("line %d. Wrong kind %d for %s\n", - m_line, a->get_kind(), id.str().c_str()); - return false; - } - return true; - } - - - template - bool parse_ast(T*& n, const coerce& coerce) - { - symbol id; - if (parse_id(id)) { - return parse_ast(id, n, coerce); - } - return false; - } - - - template - bool parse_asts(ref_vector& asts, const coerce& c) - { - symbol id; - T* n; - while (m_string[0] != '\n') { - if (strcmp(m_string.c_str(), "BUILTIN") == 0) { - return true; - } - if (!parse_ast(n,c)) { - return false; - } - asts.push_back(n); - } - return true; - } - - kind parse_kind(); - - bool next_token(); - - bool parse_id(symbol& id); - - bool parse_rational(rational& r); - - void skip_blank(); - - bool parse_eol(); - - bool parse_numeral(); - - bool parse_var(); - - bool parse_info(scoped_ptr& info); - - bool parse_info(scoped_ptr& info); - - bool parse_func_decl(); - - bool parse_func_decl(symbol& id, func_decl*& d); - - bool parse_nullary_const(); - - bool parse_const(); - - bool parse_builtin_const(); - - bool parse_type(); - - bool parse_type_new(); - - bool parse_label(); - - bool parse_quantifier(); - - bool parse_pattern(); - - bool parse_int(int& i); - - bool check_int(int& i); - - bool parse_unsigned(unsigned& i); - - bool check_unsigned(unsigned& i); - - bool try_parse(char const* token); - - bool parse_assert(); - - bool parse_simplify(); - - bool parse_check(); - - bool parse_check_assumptions(); - - bool parse_get_implied_equalities(); - - bool parse_dbg(bool expected_sat); - - bool parse_push(); - - bool parse_comment(); - - bool parse_pop(); - - bool parse_reset(); - - bool parse_echo(); - - bool parse_version(); - - bool parse_solver(); - - bool parse_parameter(vector& params); - - bool parse_params(vector& params); - - bool find_builtin_op(symbol name, family_id & fid, decl_kind& kind); - - bool find_builtin_type(symbol name, family_id & fid, decl_kind& kind); - - void add_builtins(family_id fid); - - void add_id(symbol const& id, ast* a); - - family_id get_family_id(char const* s); - - void dump_smtlib_benchmark(unsigned num_assumptions, expr* const* assumptions, Z3_lbool result); -}; - -#endif diff --git a/src/bindings/dotnet/Context.cs b/src/bindings/dotnet/Context.cs index 27bbf6d42..2aea1586c 100644 --- a/src/bindings/dotnet/Context.cs +++ b/src/bindings/dotnet/Context.cs @@ -2853,30 +2853,6 @@ namespace Microsoft.Z3 } #endregion - #region Native Parser - /// - /// Parse the given string using the Z3 native parser. - /// - /// A conjunction of asserts made in . - public Expr ParseZ3String(string str) - { - Contract.Ensures(Contract.Result() != null); - - return Expr.Create(this, Native.Z3_parse_z3_string(nCtx, str)); - } - - /// - /// Parse the given file using the Z3 native parser. - /// - /// A conjunction of asserts made in the file. - public Expr ParseZ3File(string fileName) - { - Contract.Ensures(Contract.Result() != null); - - return Expr.Create(this, Native.Z3_parse_z3_file(nCtx, fileName)); - } - #endregion - #region Goals /// /// Creates a new Goal. From 87681c9e85f61e58e506faa2c51a125dfb0b9ed4 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 17:33:32 -0700 Subject: [PATCH 07/35] minimizing smt 1.0 parser dependencies Signed-off-by: Leonardo de Moura --- src/test/ast_pp.cpp | 59 -------- src/test/ast_smt_pp.cpp | 90 ------------- src/{dead/test => test/dead}/ackermanize.cpp | 0 src/{dead/test => test/dead}/core_theory.cpp | 0 src/{dead/test => test/dead}/dimacs.cpp | 0 src/{dead/test => test/dead}/distinct.cpp | 0 .../{ => dead}/expr_context_simplifier.cpp | 0 src/{dead/test => test/dead}/fingerprint.cpp | 0 src/{dead/test => test/dead}/gate.cpp | 0 .../dead}/interval_arithmetic.cpp | 0 src/test/{ => dead}/qe_defs.cpp | 0 src/test/{ => dead}/quant_elim.cpp | 0 src/{dead/test => test/dead}/relevancy.cpp | 0 src/{dead/test => test/dead}/sat.cpp | 0 .../test => test/dead}/simplex_polynomial.cpp | 0 src/test/{ => dead}/symmetry.cpp | 0 .../test => test/dead}/template_models.cpp | 0 .../test => test/dead}/th_propagation.cpp | 0 src/{dead/test => test/dead}/trail.cpp | 0 src/{dead/test => test/dead}/watch_list.cpp | 0 src/test/dl_rule_set.cpp | 118 ---------------- src/test/expr_delta.cpp | 127 ------------------ src/test/expr_pattern_match.cpp | 51 ------- src/test/grobner.cpp | 94 ------------- src/test/main.cpp | 13 -- src/test/smtparser.cpp | 52 ------- src/test/var_subst.cpp | 19 --- 27 files changed, 623 deletions(-) delete mode 100644 src/test/ast_pp.cpp delete mode 100644 src/test/ast_smt_pp.cpp rename src/{dead/test => test/dead}/ackermanize.cpp (100%) rename src/{dead/test => test/dead}/core_theory.cpp (100%) rename src/{dead/test => test/dead}/dimacs.cpp (100%) rename src/{dead/test => test/dead}/distinct.cpp (100%) rename src/test/{ => dead}/expr_context_simplifier.cpp (100%) rename src/{dead/test => test/dead}/fingerprint.cpp (100%) rename src/{dead/test => test/dead}/gate.cpp (100%) rename src/{dead/test => test/dead}/interval_arithmetic.cpp (100%) rename src/test/{ => dead}/qe_defs.cpp (100%) rename src/test/{ => dead}/quant_elim.cpp (100%) rename src/{dead/test => test/dead}/relevancy.cpp (100%) rename src/{dead/test => test/dead}/sat.cpp (100%) rename src/{dead/test => test/dead}/simplex_polynomial.cpp (100%) rename src/test/{ => dead}/symmetry.cpp (100%) rename src/{dead/test => test/dead}/template_models.cpp (100%) rename src/{dead/test => test/dead}/th_propagation.cpp (100%) rename src/{dead/test => test/dead}/trail.cpp (100%) rename src/{dead/test => test/dead}/watch_list.cpp (100%) delete mode 100644 src/test/dl_rule_set.cpp delete mode 100644 src/test/expr_delta.cpp delete mode 100644 src/test/expr_pattern_match.cpp delete mode 100644 src/test/grobner.cpp delete mode 100644 src/test/smtparser.cpp diff --git a/src/test/ast_pp.cpp b/src/test/ast_pp.cpp deleted file mode 100644 index 414b26411..000000000 --- a/src/test/ast_pp.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - tst_ast_pp.cpp - -Abstract: - - Test AST Pretty printing module - -Author: - - Nikolaj Bjorner (nbjorner) 2006-10-5 - -Revision History: - ---*/ -#include "ast.h" -#include "ast_pp.h" -#include "ast_dag_pp.h" -#include "smtparser.h" -#include - -void tst_ast_pp() -{ - ast_manager m; - smtlib::parser* parser = smtlib::parser::create(m); - - parser->initialize_smtlib(); - - - if (!parser->parse_string( - "(benchmark test :extrasorts (A B) :extrafuns ((f A A) (g A A A) (x A) (p A bool)) \n" - ":formula (p (f x))\n" - ":extrafuns ((x1 Int) (y1 Int))\n" - ":formula (<= 1 (+ x1 y1))\n" - ":formula (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (p (g x x))))))\n" - ":formula (p x)\n" - ")")) { - SASSERT(false); - dealloc(parser); - return; - } - - smtlib::benchmark* b = parser->get_benchmark(); - - for (unsigned j = 0; j < b->get_num_assumptions(); ++j) { - expr* e = b->get_assumptions()[j]; - std::cout << mk_pp(e, m) << "\n"; - ast_dag_pp(std::cout, m, e); - } - for (unsigned j = 0; j < b->get_num_formulas(); ++j) { - expr* e = b->begin_formulas()[j]; - std::cout << mk_pp(e, m) << "\n"; - ast_dag_pp(std::cout, m, e); - } - dealloc(parser); -} diff --git a/src/test/ast_smt_pp.cpp b/src/test/ast_smt_pp.cpp deleted file mode 100644 index 05fd5748e..000000000 --- a/src/test/ast_smt_pp.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/*++ -Copyright (c) 2008 Microsoft Corporation - -Module Name: - - tst_ast_smt_pp.cpp - -Abstract: - - Test AST Pretty printing module - -Author: - - Nikolaj Bjorner (nbjorner) 2008-09-04 - -Revision History: - ---*/ -#include "ast.h" -#include "ast_smt_pp.h" -#include "smtparser.h" -#include -#include - -void tst_ast_smt_pp() -{ - ast_manager m; - smtlib::parser* parser = smtlib::parser::create(m); - - parser->initialize_smtlib(); - - - if (!parser->parse_string( - "(benchmark test :extrasorts (A B) :extrafuns ((f A A) (g A A A) (x A) (p A bool)) \n" - ":extrafuns ((arg0 BitVec[8]) (arg1 BitVec[8]) (arg2 BitVec[8]))\n" - ":formula (p (f x))\n" - ":extrafuns ((x1 Int) (y1 Int))\n" - ":formula (<= 1 (+ x1 y1))\n" - ":formula (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (p (g x x))))))\n" - ":formula (p x)\n" - ":formula (bvsge (bvadd arg0 arg2) (extract[7:0] bv3[32]))\n" - ":formula (forall (x Int) (y Int) (z Int) (and (<= 1 x) (<= x y))) \n" - ":formula (forall (x Int) (y Int) (z Int) (and (<= 2 (ite (<= z 1) x (* 2 x))) (<= x y)))\n" - ":formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (<= z 1)) x (* 2 x))) (<= x y)))\n" - ":formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (or (> x y) (<= z 1))) x (* 2 x))) (<= x y)))\n" - ":extrafuns ((a1 Array))\n" - ":formula (= x1 (select (store a1 y1 y1) x1))\n" - ":extrafuns ((a2 Array[32:8]))\n" - ":formula (= arg0 (select a2 bv0[32]))\n" - ":datatypes ((list (cons (car Int) (cdr list)) nil))\n" - ":extrafuns ((a list) (b list) (c list))\n" - ":formula (is_nil nil)\n" - ":datatypes ((list1 (cons1 (car1 Int) (cdr1 list2)) nil1) (list2 (cons1 (car2 list) (cdr2 list1)) nil2) )\n" - ":formula (is_nil2 nil2)\n" - ")")) { - SASSERT(false); - dealloc(parser); - return; - } - - smtlib::benchmark* b = parser->get_benchmark(); - - for (unsigned j = 0; j < b->get_num_formulas(); ++j) { - expr* e = b->begin_formulas()[j]; - ast_smt_pp pp(m); - pp.display(std::cout, e); - } - - - for (unsigned j = 0; j < b->get_num_formulas(); ++j) { - expr* e = b->begin_formulas()[j]; - - // print and parse formula again. - std::ostringstream buffer; - ast_smt_pp pp(m); - pp.display(buffer, e); - ast_manager m2; - smtlib::parser* parser2 = smtlib::parser::create(m2); - parser2->initialize_smtlib(); - if (!parser2->parse_string(buffer.str().c_str())) { - SASSERT(false); - dealloc(parser2); - return; - } - dealloc(parser2); - } - - - dealloc(parser); -} diff --git a/src/dead/test/ackermanize.cpp b/src/test/dead/ackermanize.cpp similarity index 100% rename from src/dead/test/ackermanize.cpp rename to src/test/dead/ackermanize.cpp diff --git a/src/dead/test/core_theory.cpp b/src/test/dead/core_theory.cpp similarity index 100% rename from src/dead/test/core_theory.cpp rename to src/test/dead/core_theory.cpp diff --git a/src/dead/test/dimacs.cpp b/src/test/dead/dimacs.cpp similarity index 100% rename from src/dead/test/dimacs.cpp rename to src/test/dead/dimacs.cpp diff --git a/src/dead/test/distinct.cpp b/src/test/dead/distinct.cpp similarity index 100% rename from src/dead/test/distinct.cpp rename to src/test/dead/distinct.cpp diff --git a/src/test/expr_context_simplifier.cpp b/src/test/dead/expr_context_simplifier.cpp similarity index 100% rename from src/test/expr_context_simplifier.cpp rename to src/test/dead/expr_context_simplifier.cpp diff --git a/src/dead/test/fingerprint.cpp b/src/test/dead/fingerprint.cpp similarity index 100% rename from src/dead/test/fingerprint.cpp rename to src/test/dead/fingerprint.cpp diff --git a/src/dead/test/gate.cpp b/src/test/dead/gate.cpp similarity index 100% rename from src/dead/test/gate.cpp rename to src/test/dead/gate.cpp diff --git a/src/dead/test/interval_arithmetic.cpp b/src/test/dead/interval_arithmetic.cpp similarity index 100% rename from src/dead/test/interval_arithmetic.cpp rename to src/test/dead/interval_arithmetic.cpp diff --git a/src/test/qe_defs.cpp b/src/test/dead/qe_defs.cpp similarity index 100% rename from src/test/qe_defs.cpp rename to src/test/dead/qe_defs.cpp diff --git a/src/test/quant_elim.cpp b/src/test/dead/quant_elim.cpp similarity index 100% rename from src/test/quant_elim.cpp rename to src/test/dead/quant_elim.cpp diff --git a/src/dead/test/relevancy.cpp b/src/test/dead/relevancy.cpp similarity index 100% rename from src/dead/test/relevancy.cpp rename to src/test/dead/relevancy.cpp diff --git a/src/dead/test/sat.cpp b/src/test/dead/sat.cpp similarity index 100% rename from src/dead/test/sat.cpp rename to src/test/dead/sat.cpp diff --git a/src/dead/test/simplex_polynomial.cpp b/src/test/dead/simplex_polynomial.cpp similarity index 100% rename from src/dead/test/simplex_polynomial.cpp rename to src/test/dead/simplex_polynomial.cpp diff --git a/src/test/symmetry.cpp b/src/test/dead/symmetry.cpp similarity index 100% rename from src/test/symmetry.cpp rename to src/test/dead/symmetry.cpp diff --git a/src/dead/test/template_models.cpp b/src/test/dead/template_models.cpp similarity index 100% rename from src/dead/test/template_models.cpp rename to src/test/dead/template_models.cpp diff --git a/src/dead/test/th_propagation.cpp b/src/test/dead/th_propagation.cpp similarity index 100% rename from src/dead/test/th_propagation.cpp rename to src/test/dead/th_propagation.cpp diff --git a/src/dead/test/trail.cpp b/src/test/dead/trail.cpp similarity index 100% rename from src/dead/test/trail.cpp rename to src/test/dead/trail.cpp diff --git a/src/dead/test/watch_list.cpp b/src/test/dead/watch_list.cpp similarity index 100% rename from src/dead/test/watch_list.cpp rename to src/test/dead/watch_list.cpp diff --git a/src/test/dl_rule_set.cpp b/src/test/dl_rule_set.cpp deleted file mode 100644 index d68bdc3c7..000000000 --- a/src/test/dl_rule_set.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - dl_rule_set.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2010-05-18. - -Revision History: - ---*/ -#include"dl_context.h" -#include"dl_rule_set.h" -#include"dl_mk_filter_rules.h" -#include"dl_mk_simple_joins.h" -#include"smtparser.h" -#include"ast_pp.h" -#include -#include - -void tst_dl_rule_set() { - enable_trace("mk_filter_rules"); - front_end_params params; - ast_manager m; - smtlib::parser * parser = smtlib::parser::create(m); - parser->initialize_smtlib(); - datalog::context ctx(m, params); - datalog::rule_set rs(ctx); - datalog::rule_manager& rm = ctx.get_rule_manager(); - datalog::rule_ref_vector rv(rm); - - - if (!parser->parse_string( - "(benchmark test\n" - ":extrapreds ((T Int Int) (Q Int Int) (R Int Int Int) (S Int Int Int) (DynActual Int Int Int) (GlobalSym Int Int) (HeapPointsTo Int Int Int) (Calls Int Int)) \n" - ":extrapreds ((Actual Int Int Int) (PointsTo Int Int) (PointsTo0 Int Int) (FuncDecl0 Int Int) (Assign Int Int) (Load Int Int Int))\n" - ":formula (forall (x Int) (=> (Q x 1) (T x x)))\n" - ":formula (forall (v Int) (h Int) (=> (PointsTo0 v h) (PointsTo v h)))\n" - ":formula (forall (v Int) (h Int) (=> (FuncDecl0 v h) (PointsTo v h)))\n" - ":formula (forall (v Int) (h Int) (=> (FuncDecl0 v h) (PointsTo v h)))\n" - ":formula (forall (v1 Int) (v2 Int) (h Int) (=> (and (PointsTo v2 h) (Assign v1 v2)) (PointsTo v1 h)))\n" - ":formula (forall (x Int) (y Int) (z Int) (=> (and (Q x y) (T y z)) (T x y)))\n" - ":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 0 h1) (PointsTo v h1)) (DynActual i1 2 v)))\n" - ":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 1 h1) (PointsTo v h1)) (DynActual i1 3 v)))\n" - ":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 2 h1) (PointsTo v h1)) (DynActual i1 4 v)))\n" - ":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (Load v2 v1 f) (PointsTo v1 h1) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n" - ":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (Load v2 v1 0) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n" - ":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (not (Load v2 v1 0)) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n" - ")")) { - SASSERT(false); - dealloc(parser); - return; - } - - smtlib::benchmark * b = parser->get_benchmark(); - - - for (unsigned j = 0; j < b->get_num_formulas(); ++j) { - expr * e = b->begin_formulas()[j]; - ptr_vector todo; - todo.push_back(e); - while (!todo.empty()) { - e = todo.back(); - todo.pop_back(); - if (is_quantifier(e)) { - e = to_quantifier(e)->get_expr(); - todo.push_back(e); - } - else if (is_app(e)) { - app* a = to_app(e); - if (is_uninterp(e) && !ctx.is_predicate(a->get_decl())) { - std::cout << "registering " << a->get_decl()->get_name() << "\n"; - - ctx.register_predicate(a->get_decl()); - } - else { - todo.append(a->get_num_args(), a->get_args()); - } - } - } - } - - - for (unsigned j = 0; j < b->get_num_formulas(); ++j) { - expr * e = b->begin_formulas()[j]; - if (is_quantifier(e)) { - try { - rm.mk_rule(e, rv); - } - catch(...) { - std::cerr << "ERROR: it is not a valid Datalog rule:\n" << mk_pp(e, m) << "\n"; - } - } - } - rs.add_rules(rv.size(), rv.c_ptr()); - rs.display(std::cout); - - datalog::mk_filter_rules p(ctx); - model_converter_ref mc; - proof_converter_ref pc; - datalog::rule_set * new_rs = p(rs, mc, pc); - std::cout << "\nAfter mk_filter:\n"; - new_rs->display(std::cout); - datalog::mk_simple_joins p2(ctx); - datalog::rule_set * new_rs2 = p2(*new_rs, mc, pc); - std::cout << "\nAfter mk_simple_joins:\n"; - new_rs2->display(std::cout); - dealloc(new_rs); - dealloc(new_rs2); - dealloc(parser); -} diff --git a/src/test/expr_delta.cpp b/src/test/expr_delta.cpp deleted file mode 100644 index fae80336d..000000000 --- a/src/test/expr_delta.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "expr_delta.h" -#include "smtparser.h" -#include "ast_pp.h" -#include "ast_smt_pp.h" - -static void iterate_delta(ast_manager& m, expr_delta& delta) { - unsigned n = 0; - expr_ref_vector result(m); - std::cout << "Delta\n"; - while (true) { - result.reset(); - if (!delta.delta_dfs(n, result)) { - return; - } - std::cout << n << ": "; - for (unsigned i = 0; i < result.size(); ++i) { - std::cout << mk_pp(result[i].get(), m) << " "; - } - std::cout << "\n"; - n++; - } -} - -void tst_expr_delta1() { - ast_manager m; - smtlib::parser* parser = smtlib::parser::create(m); - parser->initialize_smtlib(); - - parser->parse_string( - "(benchmark samples :logic QF_LIA \n" - " :extrafuns ((a Int) (b Int) (c Int)) \n" - " :assumption (> a 0) \n" - " :assumption (> b 0) \n" - " :formula (forall (x Int) (y Int) (z Int) (and (<= 1 x) (<= x y))) \n" - " :formula (forall (x Int) (y Int) (z Int) (and (<= 2 (ite (<= z 1) x (* 2 x))) (<= x y)))\n" - " :formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (<= z 1)) x (* 2 x))) (<= x y)))\n" - " :formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (or (> x y) (<= z 1))) x (* 2 x))) (<= x y)))\n" - ")" - ); - - smtlib::benchmark* b = parser->get_benchmark(); - - for (unsigned j = 0; j < b->get_num_formulas(); ++j) { - expr_delta delta(m); - - for (unsigned i = 0; i < b->get_num_assumptions(); ++i) { - delta.assert_cnstr(b->get_assumptions()[i]); - } - delta.assert_cnstr(b->begin_formulas()[j]); - iterate_delta(m, delta); - } - - dealloc(parser); -} - -static void get_expr_delta(unsigned position, char const* in, char const* out) { - ast_manager m; - smtlib::parser* parser = smtlib::parser::create(m); - parser->initialize_smtlib(); - - if (!parser->parse_file(in)) { - std::cout << "error parsing file\n"; - dealloc(parser); - return; - } - - smtlib::benchmark* b = parser->get_benchmark(); - - SASSERT(b->get_num_formulas() == 1); - expr_delta delta(m); - - for (unsigned i = 0; i < b->get_num_assumptions(); ++i) { - delta.assert_cnstr(b->get_assumptions()[i]); - } - delta.assert_cnstr(b->begin_formulas()[0]); - - - expr_ref_vector result(m); - if (!delta.delta_dfs(position, result)) { - std::cout << "done\n"; - } - else { - ast_smt_pp pp(m); - std::ofstream outf(out); - if (outf.bad() || outf.fail()) { - std::cout << "Could not open output\n"; - } - else { - switch(b->get_status()) { - case smtlib::benchmark::UNKNOWN: - pp.set_status("unknown"); - break; - case smtlib::benchmark::SAT: - pp.set_status("sat"); - break; - case smtlib::benchmark::UNSAT: - pp.set_status("unsat"); - break; - } - pp.set_logic(b->get_logic().str().c_str()); - for (unsigned i = 0; i + 1 < result.size(); ++i) { - pp.add_assumption(result[i].get()); - } - pp.display(outf, result[result.size()-1].get()); - - std::cout << "ok\n"; - } - } - - dealloc(parser); -} - -void tst_expr_delta(char** argv, int argc, int& i) { - if (i + 3 >= argc) { - std::cout << "Usage: \n"; - return; - } - ++i; - unsigned position = atol(argv[i]); - ++i; - char const* in_file = argv[i]; - ++i; - char const* out_file = argv[i]; - - get_expr_delta(position, in_file, out_file); - -} diff --git a/src/test/expr_pattern_match.cpp b/src/test/expr_pattern_match.cpp deleted file mode 100644 index e7088913e..000000000 --- a/src/test/expr_pattern_match.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "expr_pattern_match.h" -#include "smtparser.h" -#include "ast_pp.h" -#include "arith_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "array_decl_plugin.h" -#include "reg_decl_plugins.h" - -void tst_expr_pattern_match() { - ast_manager manager; - reg_decl_plugins(manager); - - expr_pattern_match apm(manager); - - apm.display(std::cout); - - const char* test_string = "(benchmark patterns :status unknown :logic ALL \n" - ":extrasorts (S) \n" - ":extrafuns ((R S S bool)) \n" - ":formula (forall (x S) (y S) (z S) \n" - " (or (not (R x y)) (not (R y z)) (R x z)) \n" - " ; :pats { (R x y) (R y z) } \n" - " :weight { 2 } \n" - " )\n" - ")"; - smtlib::parser* parser = smtlib::parser::create(manager); - parser->initialize_smtlib(); - std::cout << "parsing test string\n"; - if (!parser->parse_string(test_string)) { - UNREACHABLE(); - } - std::cout << "test string parsed\n"; - smtlib::benchmark* bench = parser->get_benchmark(); - - for (unsigned i = 0; i < bench->get_num_formulas(); ++i) { - expr* fml = bench->begin_formulas()[i]; - SASSERT(fml->get_kind() == AST_QUANTIFIER); - quantifier* qf = to_quantifier(fml); - app_ref_vector patterns(manager); - unsigned weight = 0; - if (apm.match_quantifier(qf, patterns, weight)) { - std::cout << "Found pattern match\n"; - for (unsigned i = 0; i < patterns.size(); ++i) { - ast_pp(std::cout, patterns[i].get(), manager) << "\n"; - } - std::cout << "weight: " << weight << "\n"; - } - } - dealloc(parser); - -} diff --git a/src/test/grobner.cpp b/src/test/grobner.cpp deleted file mode 100644 index 89aea5049..000000000 --- a/src/test/grobner.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - grobner.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-12-05. - -Revision History: - ---*/ -#include"smtparser.h" -#include"ast_pp.h" -#include"arith_decl_plugin.h" -#include"simplifier.h" -#include"basic_simplifier_plugin.h" -#include"arith_simplifier_plugin.h" -#include"front_end_params.h" -#include"grobner.h" -#include"reg_decl_plugins.h" - -void display_eqs(grobner & gb, v_dependency_manager & dep_m) { - std::cerr << "RESULT:\n"; - ptr_vector eqs; - gb.get_equations(eqs); - ptr_vector::iterator it = eqs.begin(); - ptr_vector::iterator end = eqs.end(); - for (; it != end; ++it) { - grobner::equation * eq = *it; - ptr_vector exs; - v_dependency * d = eq->get_dependency(); - dep_m.linearize(d, exs); - std::cerr << "{"; - ptr_vector::iterator it2 = exs.begin(); - ptr_vector::iterator end2 = exs.end(); - for (bool first = true; it2 != end2; ++it2) { - if (first) first = false; else std::cerr << " "; - std::cerr << *it2; - } - std::cerr << "}, lc: " << eq->is_linear_combination() << ", "; - gb.display_equation(std::cerr, *eq); - } -} - -void tst_grobner(char ** argv, int argc, int & i) { - front_end_params params; - if (i + 1 < argc) { - char const* file_path = argv[i+1]; - - ast_manager m; - smtlib::parser* parser = smtlib::parser::create(m); - reg_decl_plugins(m); - parser->initialize_smtlib(); - - if (!parser->parse_file(file_path)) { - std::cout << "Could not parse file : " << file_path << std::endl; - dealloc(parser); - return; - } - - smtlib::benchmark* b = parser->get_benchmark(); - simplifier simp(m); - basic_simplifier_plugin * bp = alloc(basic_simplifier_plugin, m); - simp.register_plugin(bp); - simp.register_plugin(alloc(arith_simplifier_plugin, m, *bp, params)); - arith_util util(m); - v_dependency_manager dep_m; - grobner gb(m, dep_m); - - ptr_vector::const_iterator it = b->begin_axioms(); - ptr_vector::const_iterator end = b->end_axioms(); - for (unsigned idx = 1; it != end; ++it, ++idx) { - expr * ax = *it; - expr_ref s_ax(m); - proof_ref pr(m); - simp(ax, s_ax, pr); - std::cerr << mk_pp(s_ax, m) << "\n"; - if (m.is_eq(s_ax)) - gb.assert_eq(s_ax, dep_m.mk_leaf(reinterpret_cast(idx))); - } - gb.display(std::cerr); - gb.compute_basis(1024); - display_eqs(gb, dep_m); - dealloc(parser); - } -} - diff --git a/src/test/main.cpp b/src/test/main.cpp index e99e96729..acbea0761 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -123,7 +123,6 @@ int main(int argc, char ** argv) { memory::initialize(0); bool do_display_usage = false; parse_cmd_line_args(argc, argv, do_display_usage); - TST_ARGV(grobner); TST(random); TST(vector); TST(symbol_table); @@ -131,23 +130,17 @@ int main(int argc, char ** argv) { TST(symbol); TST(heap); TST(hashtable); - TST_ARGV(smtparser); TST(rational); TST(inf_rational); TST(ast); TST(optional); TST(bit_vector); - TST(ast_pp); - TST(ast_smt_pp); - TST_ARGV(expr_delta); TST(string_buffer); TST(map); TST(diff_logic); TST(uint_set); TST_ARGV(expr_rand); - TST(expr_context_simplifier); TST(ini_file); - TST(expr_pattern_match); TST(list); TST(small_object_allocator); TST(timeout); @@ -157,9 +150,6 @@ int main(int argc, char ** argv) { TST(bit_blaster); TST(var_subst); TST(simple_parser); - TST(symmetry); - TST_ARGV(symmetry_parse); - TST_ARGV(symmetry_prove); TST(api); TST(old_interval); TST(interval_skip_list); @@ -167,10 +157,8 @@ int main(int argc, char ** argv) { TST(memory); TST(get_implied_equalities); TST(arith_simplifier_plugin); - TST(quant_elim); TST(matcher); TST(datalog_parser); - TST(dl_rule_set); TST_ARGV(datalog_parser_file); TST(object_allocator); TST(mpz); @@ -208,7 +196,6 @@ int main(int argc, char ** argv) { TST(prime_generator); TST(permutation); TST(nlsat); - TST(qe_defs); TST(ext_numeral); TST(interval); TST(quant_solve); diff --git a/src/test/smtparser.cpp b/src/test/smtparser.cpp deleted file mode 100644 index dc4f0eb74..000000000 --- a/src/test/smtparser.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifdef _WINDOWS -#include -#include -#include -#include -#include "smtparser.h" -#include "for_each_file.h" -#include "array_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "reg_decl_plugins.h" - -class for_each_file_smt : public for_each_file_proc { -public: - for_each_file_smt() {} - - bool operator()(char const * file_path) { - bool result = true; - std::cout << "Parsing: " << file_path << std::endl; - - ast_manager ast_manager; - smtlib::parser* parser = smtlib::parser::create(ast_manager); - reg_decl_plugins(ast_manager); - - parser->initialize_smtlib(); - - if (!parser->parse_file(file_path)) { - std::cout << "Could not parse file : " << file_path << std::endl; - result = false; - } - dealloc(parser); - return result; - } -}; - - -static bool test_directory(char const * base) { - for_each_file_smt foreach; - return for_each_file(foreach, base, "*.smt"); -} - -void tst_smtparser(char** argv, int argc, int & i) { - bool result = true; - if (i + 1 < argc) { - result = test_directory(argv[i+1]); - i += 1; - } - SASSERT(result); -} -#else -void tst_smtparser(char** argv, int argc, int & i) { -} -#endif diff --git a/src/test/var_subst.cpp b/src/test/var_subst.cpp index efc4555fe..3e75d1527 100644 --- a/src/test/var_subst.cpp +++ b/src/test/var_subst.cpp @@ -17,7 +17,6 @@ Revision History: --*/ #include"var_subst.h" -#include"smtparser.h" #include"ast_pp.h" #include"arith_decl_plugin.h" #include"bv_decl_plugin.h" @@ -104,22 +103,4 @@ void tst_var_subst() { ast_manager m; reg_decl_plugins(m); tst_subst(m); - - scoped_ptr parser = smtlib::parser::create(m); - parser->initialize_smtlib(); - - parser->parse_string( - "(benchmark samples :logic AUFLIA\n" - " :extrafuns ((f Int Int) (g Int Int Int) (a Int) (b Int))\n" - " :formula (forall (x Int) (or (= (f x) x) (forall (y Int) (z Int) (= (g x y) (f z)))))\n" - " :formula (forall (x Int) (w Int) (or (= (f x) x) (forall (y Int) (z Int) (or (= (g x y) (g w z)) (forall (x1 Int) (= (f x1) (g x y)))))))\n" - ")" - ); - - smtlib::benchmark* b = parser->get_benchmark(); - - smtlib::theory::expr_iterator it = b->begin_formulas(); - smtlib::theory::expr_iterator end = b->end_formulas(); - for (; it != end; ++it) - tst_instantiate(m, *it); } From f1b6d1c7f33f344cc0f5f7a6101606250e2cf604 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 18:04:20 -0700 Subject: [PATCH 08/35] removing 'fat' from smt 1.0 parser Signed-off-by: Leonardo de Moura --- src/api/smtparser.cpp | 2377 +---------------------------------------- src/api/smtparser.h | 2 - 2 files changed, 3 insertions(+), 2376 deletions(-) diff --git a/src/api/smtparser.cpp b/src/api/smtparser.cpp index 91b636d09..f290c717b 100644 --- a/src/api/smtparser.cpp +++ b/src/api/smtparser.cpp @@ -16,7 +16,6 @@ Author: Revision History: --*/ - #include #include #include @@ -32,17 +31,15 @@ Revision History: #include"ast_pp.h" #include"bv_decl_plugin.h" #include"array_decl_plugin.h" -#include"datatype_decl_plugin.h" #include"warning.h" #include"error_codes.h" #include"pattern_validation.h" -#include"unifier.h" #include"timeit.h" #include"var_subst.h" #include"well_sorted.h" -#include "str_hashtable.h" -#include "front_end_params.h" -#include "stopwatch.h" +#include"str_hashtable.h" +#include"front_end_params.h" +#include"stopwatch.h" front_end_params& Z3_API Z3_get_parameters(Z3_context c); class id_param_info { @@ -464,66 +461,6 @@ private: }; -enum smt_cmd_token { - SMT_CMD_SET_LOGIC, // logic-name - SMT_CMD_DECLARE_SORTS, // sorts-symbols - SMT_CMD_DECLARE_FUNS, // func-decls - SMT_CMD_DECLARE_PREDS, // pred-decls - SMT_CMD_DECLARE_DATATYPES, // datatypes - SMT_CMD_DEFINE, // var expr - SMT_CMD_DEFINE_SORTS, // (var sort)* - SMT_CMD_DECLARE_SORT, // - SMT_CMD_DEFINE_SORT, // (*) - SMT_CMD_DECLARE_FUN, // (*) - SMT_CMD_DECLARE_CONST, // - SMT_CMD_DEFINE_FUN, // (*) - SMT_CMD_GET_VALUE, // (+) - - SMT_CMD_PUSH, // numeral - SMT_CMD_POP, // numeral - SMT_CMD_ASSERT, // expr - SMT_CMD_CHECK_SAT, // - SMT_CMD_GET_CORE, // expr+ - SMT_CMD_NEXT_SAT, - SMT_CMD_SIMPLIFY, // expr - SMT_CMD_GET_IMPLIED_EQUALITIES, // expr* - SMT_CMD_EVAL, // expr - SMT_CMD_GET_ASSERTIONS, // string - SMT_CMD_GET_SAT_ASSERTIONS, // string - SMT_CMD_KEEP_SAT_ASSERTIONS, // - SMT_CMD_GET_UNSAT_CORE, // string - SMT_CMD_GET_PROOF, // string - SMT_CMD_SET_OPTION, // string strings - SMT_CMD_GET_INFO, // string - SMT_CMD_SET_INFO, // string strings - SMT_CMD_ECHO, // string strings - SMT_CMD_EXIT, // - // set-option: - SMT_CMD_PRINT_SUCCESS, - SMT_CMD_RANDOM_SEED, - SMT_CMD_VERBOSITY, - SMT_CMD_EXPAND_DEFINITIONS, - SMT_CMD_OUTPUT_CHANNEL, - SMT_CMD_VERBOSE_OUTPUT_CHANNEL, - SMT_CMD_ENABLE_CORES, - SMT_CMD_SET_PARAM, - SMT_CMD_PRODUCE_MODELS, - // set-info: - SMT_CMD_NAME, - SMT_CMD_VERSION, - SMT_CMD_AUTHORS, - SMT_CMD_LAST_FAILURE, - SMT_CMD_REASON_UNKNOWN, - SMT_CMD_STATS, - SMT_CMD_MODEL, - SMT_CMD_TIME, - SMT_CMD_LABELS, - SMT_CMD_HELP, // help - - SMT_CMD_ERROR // error token -}; - - using namespace smtlib; class idbuilder { @@ -591,1280 +528,6 @@ public: } }; - - - -class scoped_stream { - std::ostream& m_default; - std::ostream* m_stream; - bool m_owned; -public: - - scoped_stream(std::ostream& strm) : m_default(strm) { - m_stream = &strm; - m_owned = false; - } - - scoped_stream(proto_expr* e) : m_default(std::cout), m_stream(0), m_owned(false) { - reset(e, 0); - } - - scoped_stream(proto_expr* e, std::ostream& out) : m_default(out), m_stream(0), m_owned(false) { - reset(e, &out); - } - - ~scoped_stream() { - dealloc_stream(); - } - - void reset(proto_expr* e, std::ostream* out = 0) { - char const* name = (e && e->kind() == proto_expr::ID)?e->string().bare_str():0; - reset(name, out); - } - - void reset(char const* name, std::ostream* out = 0) { - dealloc_stream(); - m_owned = false; - if (!out) { - out = &m_default; - } - if (!name) { - m_stream = out; - } - else if (strcmp(name, "stdout")) { - m_stream = &std::cout; - } - else if (strcmp(name, "stderr")) { - m_stream = &std::cerr; - } - else { - m_stream = alloc(std::ofstream, name, std::ios_base::app); - m_owned = true; - if (m_stream->bad() || m_stream->fail()) { - dealloc(m_stream); - m_stream = out; - m_owned = false; - } - } - SASSERT(m_stream); - } - - std::ostream& operator*() { - return *m_stream; - } - -private: - void dealloc_stream() { - if (m_owned) { - m_stream->flush(); - dealloc(m_stream); - } - m_stream = 0; - m_owned = false; - } -}; - -class cmd_exn { - Z3_error_code m_code; -public: - cmd_exn(Z3_error_code code) : m_code(code) {} - Z3_error_code get() const { return m_code; } -}; - -static void* g_sw = 0; - -#define cmd_context _cmd_context - -class cmd_context { - typedef map str2token; - str2token m_str2token; - ptr_vector m_token2str; - ptr_vector m_token2help; - ptr_vector m_token2args; - svector m_is_command; - - struct cmd_info { - smt_cmd_token m_token; - void (*m_action)(cmd_context&); - cmd_info(smt_cmd_token t, void (*action)(cmd_context&)): - m_token(t), m_action(action) {} - }; - - struct opt { - smt_cmd_token m_token; - bool (*m_action)(cmd_context&, proto_expr* const* exprs); - opt(smt_cmd_token t, bool (*action)(cmd_context&, proto_expr* const* exprs)): - m_token(t), m_action(action) {} - }; - - enum check_sat_state { - state_unsat, - state_sat, - state_unknown, - state_clear, - state_new_assertion - }; - - Z3_context m_context; - Z3_model m_model; - Z3_ast m_proof; - ast_manager& m_manager; - scoped_stream m_out; - scoped_stream m_verbose; - symbol_table m_table; - region m_region; - ast_ref_vector m_trail; - unsigned_vector m_trail_lim; - expr_ref_vector m_asserted; - unsigned_vector m_asserted_lim; - expr_ref_vector m_asserted_proxies; - unsigned_vector m_asserted_proxies_lim; - bool m_print_success; - bool m_enable_cores; - unsigned m_core_size; - svector m_core; - check_sat_state m_check_sat_state; - svector m_check_sat_states; - stopwatch m_watch; - svector m_infos; - svector m_options; - std::ostringstream m_error_stream; - - smtlib::benchmark::status m_status; - -public: - - cmd_context(ast_manager& m, Z3_context ctx, std::istream& is, std::ostream& out): - m_context(ctx), - m_model(0), - m_proof(0), - m_manager(m), - m_out(out), - m_verbose(std::cerr), - m_trail(m), - m_asserted(m), - m_asserted_proxies(m), - m_print_success(Z3_get_parameters(ctx).m_smtlib2_compliant), - m_enable_cores(false), - m_core_size(0), - m_check_sat_state(state_clear), - m_status(smtlib::benchmark::UNKNOWN) - { - add_command("set-logic", - SMT_CMD_SET_LOGIC, - "", "set the background logic"); - add_command("declare-sorts", - SMT_CMD_DECLARE_SORTS, - "", "declare sorts"); - add_command("declare-funs", - SMT_CMD_DECLARE_FUNS, - "", - "declare functions and constants"); - add_command("declare-preds", - SMT_CMD_DECLARE_PREDS, - "", - "declare predicates"); - add_command("declare-datatypes", - SMT_CMD_DECLARE_DATATYPES, - "", - "declare recursive datatypes"); - add_command("define", - SMT_CMD_DEFINE, - " or ( ( )*) ", - "define an expression shorthand"); - add_command("define-sorts", - SMT_CMD_DEFINE_SORTS, - "( )*", - "define shorthand for compound sorts, such as arrays"); - - add_command("declare-sort", - SMT_CMD_DECLARE_SORT, - "", "declare sort"); - add_command("define-sort", - SMT_CMD_DEFINE_SORT, - " (*) ", - "define shorthand for compound sorts, such as arrays"); - add_command("declare-fun", - SMT_CMD_DECLARE_FUN, - " (*) ", - "declare function or constant"); - add_command("declare-const", - SMT_CMD_DECLARE_CONST, - " ", - "declare constant"); - add_command("define-fun", - SMT_CMD_DEFINE_FUN, - " (*) ", - "define an expression shorthand"); - add_command("get-value", - SMT_CMD_GET_VALUE, - "(+)", - "evaluate list of terms"); - - - add_command("push", - SMT_CMD_PUSH, - "[]", - "push 1 (or ) scopes"); - add_command("pop", - SMT_CMD_POP, - "[]", - "pop 1 (or ) scopes"); - add_command("assert", - SMT_CMD_ASSERT, - "", - "assert expression"); - add_command("check-sat", - SMT_CMD_CHECK_SAT, - "*", - "check if the current context is satisfiable. If a list of boolean constants B is provided, then check if the current context is consistent with assigning every constant in B to true."); - add_command("get-core", - SMT_CMD_GET_CORE, - "+", - "check if the assumptions are consistent with the current context"); - add_command("next-sat", - SMT_CMD_NEXT_SAT, - "", - "get the next satisfying assignment"); - add_command("simplify", - SMT_CMD_SIMPLIFY, - "", - "simplify expression and print back result"); - add_command("get-implied-equalities", - SMT_CMD_GET_IMPLIED_EQUALITIES, - "*", - "obtain list of identifiers for expressions, such that equal expressions have the same identfiers" - ); - add_command("eval", - SMT_CMD_EVAL, - "", - "evaluate expression using the current model and print back result"); - add_command("get-assertions", - SMT_CMD_GET_ASSERTIONS, - "[]", - "retrieve current assertions"); - add_command("get-sat-assertions", - SMT_CMD_GET_SAT_ASSERTIONS, - "[]", - "retrieve current satisfying assignment"); - add_command("keep-sat-assertions", - SMT_CMD_KEEP_SAT_ASSERTIONS, - "", - "assert current satisfying assignment"); - add_command("get-unsat-core", - SMT_CMD_GET_UNSAT_CORE, - "[]", - "retrieve unsatisfiable core of assertions"); - add_command("get-proof", - SMT_CMD_GET_PROOF, - "[]", - "retrieve proof"); - add_command("set-option", - SMT_CMD_SET_OPTION, - "", - "set auxiliary options"); - add_command("set-info", - SMT_CMD_SET_INFO, - " ", - "set auxiliary information"); - add_command("get-info", - SMT_CMD_GET_INFO, - "", - "retrieve auxiliary information"); - add_command("echo", - SMT_CMD_ECHO, - "", - "display the given strings"); - add_command("exit", - SMT_CMD_EXIT, - "", - "exit Z3 session"); - m_str2token.insert("quit", SMT_CMD_EXIT); - add_option("print-success", - SMT_CMD_PRINT_SUCCESS, - "[]", - "toggle printing success", - &print_success_option); - add_option("verbosity", - SMT_CMD_VERBOSITY, - "", - "set verbosity", - &verbosity_option); - add_option("regular-output-channel", - SMT_CMD_OUTPUT_CHANNEL, - "[]", - "set name of alternate output channel", - &output_channel_option); - add_option("enable-cores", - SMT_CMD_ENABLE_CORES, - "", - "enable core extraction during solving", - &enable_cores_option); - add_option("set-param", - SMT_CMD_SET_PARAM, - " ", - "update a mutable configuration parameter", - &update_param_option); - - add_option("verbose-output-channel", - SMT_CMD_VERBOSE_OUTPUT_CHANNEL, - "", - "set output channel", - &set_verbose_output_channel_option - ); - add_option("produce-models", - SMT_CMD_PRODUCE_MODELS, - "[]", - "toggle model generation", - &produce_models_option); - // - // other options: - // add_option("random-seed", SMT_CMD_RANDOM_SEED, 0, ""); - // add_option("expand-definitions",SMT_CMD_EXPAND_DEFINITIONS, 0, ""); - // "produce-proofs" - // "produce-models" - // "produce-assignments" - // - - add_info("name", - SMT_CMD_NAME, - "", - "solver name", - &name_info - ); - add_info("version", - SMT_CMD_VERSION, - "", - "solver version", - &version_info - ); - add_info("authors", - SMT_CMD_AUTHORS, - "", - "solver authors", - &authors_info); - add_info("statistics", - SMT_CMD_STATS, - "", - "search statistics", - &stats_info); - add_info("all-statistics", - SMT_CMD_STATS, - "", - "search statistics", - &stats_info); - add_info("model", - SMT_CMD_MODEL, - "", - "model from satisfied assertions", - &model_info - ); - add_info("last-failure", - SMT_CMD_LAST_FAILURE, - "", - "reason for previous search failure", - &last_failure_info - ); - add_info("reason-unknown", - SMT_CMD_REASON_UNKNOWN, - "", - "reason for previous unknown answer; 'memout' for out of memory, 'incomplete' for everything else", - &reason_unknown_info - ); - add_info("time", - SMT_CMD_TIME, - "", - "time taken by solver", - &time_info - ); - add_info("labels", - SMT_CMD_LABELS, - "", - "retrieve (Boogie) labels from satisfiable assertion", - &labels_info); - add_info("help", - SMT_CMD_HELP, - "", - "print this help", - &help_info); - - - -#ifdef _EXTERNAL_RELEASE - Z3_set_ast_print_mode(m_context, Z3_PRINT_SMTLIB2_COMPLIANT); -#else - // use internal pretty printer - Z3_set_ast_print_mode(m_context, Z3_PRINT_SMTLIB_FULL); - // Z3_set_ast_print_mode(m_context, Z3_PRINT_SMTLIB2_COMPLIANT); -#endif - Z3_set_error_handler(m_context, error_handler); - set_error_stream(&m_error_stream); - set_warning_stream(&m_error_stream); - } - - ~cmd_context() { - if (m_model) { - Z3_del_model(m_context, m_model); - } - set_error_stream(0); - set_warning_stream(0); - } - - // - // NB. As it is now, the symbol table used in m_benchmark is not - // scoped. Declarations just live on or get over-written. - // - void push(unsigned num_scopes) { - while (num_scopes > 0) { - m_table.begin_scope(); - m_region.push_scope(); - Z3_push(m_context); - m_trail_lim.push_back(m_trail.size()); - m_asserted_lim.push_back(m_asserted.size()); - m_asserted_proxies_lim.push_back(m_asserted_proxies.size()); - --num_scopes; - m_check_sat_states.push_back(m_check_sat_state); - } - } - void pop(unsigned num_scopes) { - if (m_trail_lim.size() < num_scopes) { - num_scopes = m_trail_lim.size(); - } - Z3_pop(m_context, num_scopes); - m_region.pop_scope(num_scopes); - while (num_scopes > 0) { - m_table.end_scope(); - --num_scopes; - m_trail.resize(m_trail_lim.back()); - m_trail_lim.pop_back(); - m_asserted.resize(m_asserted_lim.back()); - m_asserted_lim.pop_back(); - m_asserted_proxies.resize(m_asserted_proxies_lim.back()); - m_asserted_proxies_lim.pop_back(); - m_check_sat_state = m_check_sat_states.back(); - m_check_sat_states.pop_back(); - } - m_proof = 0; - m_core_size = 0; - } - - static void error_handler(Z3_context, Z3_error_code code) { - throw cmd_exn(code); - } - - symbol_table& get_table() { return m_table; } - - Z3_context get_context() { return m_context; } - - std::ostream& get_out() { return *m_out; } - - void print_quoted(const char* str) { get_out() << "\"" << str << "\""; } - - void set_out(proto_expr* e) { m_out.reset(e); } - - void add_trail(ast* a) { m_trail.push_back(a); } - - void add_asserted(expr* e) { - if (get_enable_cores()) { - expr* proxy = m_manager.mk_fresh_const("proxy", m_manager.mk_bool_sort()); - expr_ref imp(m_manager); - // It is not necessary to use iff (it is just overhead). - imp = m_manager.mk_implies(proxy, e); - TRACE("proxy", tout << "new proxy:\n " << mk_pp(imp, m_manager) << "\n";); - Z3_assert_cnstr(m_context, reinterpret_cast(imp.get())); - m_asserted_proxies.push_back(proxy); - } - else { - Z3_assert_cnstr(m_context, reinterpret_cast(e)); - } - m_asserted.push_back(e); - if (m_check_sat_state != state_unsat) { - m_check_sat_state = state_new_assertion; - } - } - - unsigned get_num_assertions() const { return m_asserted.size(); } - - expr* get_assertion(unsigned idx) { return m_asserted[idx].get(); } - - Z3_ast* get_proxies_ptr() { return reinterpret_cast(m_asserted_proxies.c_ptr()); } - - unsigned* get_core_size_ptr() { return &m_core_size; } - - Z3_ast* get_core_ptr() { - m_core.resize(m_asserted_proxies.size()); - if (m_core_size > m_core.size()) { - m_core_size = m_core.size(); - } - return m_core.c_ptr(); - } - - region& get_region() { return m_region; } - - - void set_print_success(bool b) { m_print_success = b; } - - void set_enable_cores() { m_enable_cores = true; } - - void unset_enable_cores() { m_enable_cores = false; } - - void update_param(char const* p, char const* v) { - Z3_update_param_value(m_context, p, v); - } - - bool get_enable_cores() const { return m_enable_cores; } - - void print_success() { - if (m_print_success) { - *m_out << "success\n"; - } - } - - void print_unsupported() { - *m_out << "unsupported\n"; - } - - void print_failure(char const* msg, proto_expr* expr) { - if (Z3_get_parameters(m_context).m_display_error_for_vs) { - if (msg[0] != 'Z' || msg[1] != '3') { - *m_out << "Z3"; - if (expr) { - *m_out << "(" << expr->line() << "," << expr->pos() << ")"; - } - *m_out << ": ERROR: "; - } - *m_out << msg; - if (msg[strlen(msg)-1] != '\n') { - *m_out << "\n"; - } - } - else { - *m_out << "(error \""; - if (expr) { - *m_out << "line " << expr->line() << " column " << expr->pos() << ": "; - } - *m_out << escaped(msg, true) << "\")\n"; -#ifndef _EXTERNAL_RELEASE - exit(ERR_PARSER); -#endif - } - } - - Z3_model* get_model_ptr() { - if (m_model) { - Z3_del_model(m_context, m_model); - m_model = 0; - } - return &m_model; - } - - Z3_model get_model() { return m_model; } - - Z3_ast* get_proof_ptr() { - m_proof = 0; - return &m_proof; - } - - void get_proof(std::ostream& out, proto_expr* p_expr) { - Z3_ast pr = m_proof; - if (pr) { - out << Z3_ast_to_string(m_context, pr) << "\n"; - } - else if (Z3_get_parameters(m_context).m_proof_mode == PGM_DISABLED) { - print_failure("proofs are disabled - enable them using the configuration PROOF_MODE={1,2}", p_expr); - } - else { - print_failure("there is no proof to display", p_expr); - } - } - - smt_cmd_token string2token(char const * str) { - str2token::entry * e = m_str2token.find_core(str); - if (e) - return e->get_data().m_value; - else - return SMT_CMD_ERROR; - } - - class scoped_stopwatch { - cmd_context& m_ctx; - bool m_first; - void (*m_old_handler)(int); - - static scoped_stopwatch* get_sw() { return static_cast(g_sw); } - - static void on_ctrl_c(int) { - if (get_sw()->m_first) { - Z3_soft_check_cancel(get_sw()->m_ctx.get_context()); - get_sw()->m_first = false; - } - else { - signal (SIGINT, get_sw()->m_old_handler); - raise (SIGINT); - } - } - public: - scoped_stopwatch(cmd_context& c) : m_ctx(c), m_first(true) { - g_sw = this; - c.m_watch.reset(); - c.m_watch.start(); - m_old_handler = signal(SIGINT, on_ctrl_c); // TBD: parallel? - } - ~scoped_stopwatch() { - m_ctx.m_watch.stop(); - if (m_old_handler != SIG_ERR) { - signal(SIGINT, m_old_handler); - } - } - }; - - //static scoped_stopwatch* g_sw = 0; - - double get_seconds() { - return m_watch.get_seconds(); - } - - bool get_command_help(std::ostream& out, smt_cmd_token tok) { - if (!m_is_command[tok]) { - return false; - } - out << " (" << m_token2str[tok]; - if (m_token2args[tok] && m_token2args[tok][0]) { - out << " " << m_token2args[tok]; - } - out << ")\n"; - out << " " << m_token2help[tok] << "\n\n"; - return true; - } - - void get_help(std::ostream& out) { - out << "\" available commands:\n\n"; - for (unsigned i = 0; i < m_token2args.size(); ++i) { - get_command_help(out, static_cast(i)); - } - get_info_help(out, " "); - out << "\n"; - set_option_help(out, " "); - out << "\""; - } - - bool get_info(smt_cmd_token tok) { - for (unsigned i = 0; i < m_infos.size(); ++i) { - if (m_infos[i].m_token == tok) { - get_out() << ":" << m_token2str[tok] << " "; - m_infos[i].m_action(*this); - return true; - } - } - return false; - } - - void get_info_help(std::ostream& strm, char const* line_start) { - for (unsigned i = 0; i < m_infos.size(); ++i) { - smt_cmd_token tok = m_infos[i].m_token; - strm << line_start << "(get-info " << m_token2str[tok]; - if (m_token2args[tok] && m_token2args[tok][0]) { - strm << " " << m_token2args[tok]; - } - strm << ")\n"; - strm << line_start << " " << m_token2help[tok] << "\n"; - } - } - - bool set_option(smt_cmd_token tok, proto_expr* const* chs) { - for (unsigned i = 0; i < m_options.size(); ++i) { - if (m_options[i].m_token == tok) { - return m_options[i].m_action(*this, chs); - } - } - return update_param_option(*this, chs-1); - // return false; - } - - bool set_info(proto_expr* e0, proto_expr* const* chs) { - proto_expr* e1 = chs[0]; - symbol s0, s1; - if (e0) - s0 = e0->string(); - if (e1) - s1 = e1->string(); - - if (s0 == symbol("status") && s1 == symbol("sat")) { - m_status = smtlib::benchmark::SAT; - } - else if (s0 == symbol("status") && s1 == symbol("unsat")) { - m_status = smtlib::benchmark::UNSAT; - } - else if (s0 == symbol("status") && s1 == symbol("unknown")) { - m_status = smtlib::benchmark::UNKNOWN; - } - else { -#ifdef Z3DEBUG - std::cout << s0 << " " << s1 << "\n"; -#endif - } - - // :source - // :smt-lib-version - // :category - // :status - // no-op - return true; - } - - void set_option_help(std::ostream& strm, char const* line_start) { - for (unsigned i = 0; i < m_options.size(); ++i) { - smt_cmd_token tok = m_options[i].m_token; - strm << line_start << "(set-option " << m_token2str[tok]; - if (m_token2args[tok] && m_token2args[tok][0]) { - get_out() << " " << m_token2args[tok]; - } - strm << ")\n"; - strm << line_start << " " << m_token2help[tok] << "\n"; - } - } - - unsigned parse_opt_numeral(proto_expr* e, unsigned default_value) { - if (e && e->kind() == proto_expr::INT) { - rational r = e->number(); - if (r.is_unsigned()) { - return r.get_unsigned(); - } - } - return default_value; - } - - bool parse_opt_bool(proto_expr* e, bool default_value) { - if (e && e->kind() == proto_expr::ID) { - if (strcmp(e->string().bare_str(), "true") == 0) { - return true; - } - if (strcmp(e->string().bare_str(), "false") == 0) { - return false; - } - } - return default_value; - } - - - void get_core(proto_expr* p_expr, std::ostream& out, - unsigned sz, expr** exprs, bool just_get_core) { - - - Z3_context ctx = get_context(); - Z3_lbool r; - scoped_stopwatch stopw(*this); - - if (get_enable_cores()) { - print_failure("cores should be disabled", p_expr); - return; - } - - for (unsigned i = 0; i < sz; ++i) { - if (!is_uninterp_const(exprs[i]) || !m_manager.is_bool(exprs[i])) { - print_failure("assumptions must be boolean constants (e.g., p1, p2, q1)", p_expr); - return; - } - } - - // set_enable_cores(); - // push(1); - // for (unsigned i = 0; i < sz; ++i) { - // add_asserted(exprs[i]); - // } - - unsigned max_core_size = sz; - unsigned core_size = sz; - m_core.reserve(max_core_size); - Z3_ast * core = m_core.c_ptr(); - - r = Z3_check_assumptions(ctx, sz, reinterpret_cast(exprs), - get_model_ptr(), get_proof_ptr(), - &core_size, core); - switch(r) { - case Z3_L_FALSE: - if (!just_get_core) - out << "unsat\n"; - print_core_as_is(out, core_size, core); - m_check_sat_state = state_unsat; - break; - case Z3_L_TRUE: - out << "sat\n"; - m_check_sat_state = state_sat; - break; - case Z3_L_UNDEF: - out << "unknown\n"; - m_check_sat_state = state_unknown; - break; - default: - throw default_exception("unexpected output of check-sat\n"); - break; - } - // unset_enable_cores(); - // pop(1); - } - - void check_sat(std::ostream& out) { - Z3_context ctx = get_context(); - Z3_lbool r; - scoped_stopwatch stopw(*this); - - if (get_enable_cores()) { - r = Z3_check_assumptions(ctx, get_num_assertions(), get_proxies_ptr(), - get_model_ptr(), get_proof_ptr(), - get_core_size_ptr(), get_core_ptr()); - - } - else if (Z3_get_parameters(ctx).m_proof_mode != PGM_DISABLED) { - unsigned core_size = 0; - Z3_ast core[1] = { 0 }; - r = Z3_check_assumptions(ctx, 0, 0, get_model_ptr(), get_proof_ptr(), &core_size, core); - } - else if (Z3_get_parameters(ctx).m_model) { - r = Z3_check_and_get_model(ctx, get_model_ptr()); - } - else { - r = Z3_check(ctx); - } - switch(r) { - case Z3_L_FALSE: - out << "unsat\n"; - m_check_sat_state = state_unsat; - break; - case Z3_L_TRUE: - out << "sat\n"; - m_check_sat_state = state_sat; - break; - case Z3_L_UNDEF: - out << "unknown\n"; - m_check_sat_state = state_unknown; - break; - default: - throw default_exception("unexpected output of check-sat\n"); - break; - } - - // check status (duplicate from smtlib_sover) - // smtlib_solver contains support for - // - spc - // - missing. - // - dumping statistics / proofs / model / labels - // - redundant given additional command-line options - // - switch(m_status) { - case smtlib::benchmark::SAT: - if (r == Z3_L_FALSE) { -#ifdef _EXTERNAL_RELEASE - std::cout << "unsat - check annotation which says sat\n"; -#else - std::cout << "BUG: unsoundness.\n"; - exit(ERR_UNSOUNDNESS); -#endif - } - else if (r == Z3_L_UNDEF) { -#ifndef _EXTERNAL_RELEASE - std::cout << "BUG: gaveup.\n"; - exit(ERR_UNKNOWN_RESULT); -#endif - } - break; - case smtlib::benchmark::UNSAT: - if (r == Z3_L_TRUE) { -#ifdef _EXTERNAL_RELEASE - std::cout << "sat - check annotation which says unsat\n"; -#else - std::cout << "BUG: incompleteness.\n"; - exit(ERR_INCOMPLETENESS); -#endif - } - else if (r == Z3_L_UNDEF) { -#ifndef _EXTERNAL_RELEASE - std::cout << "BUG: gaveup.\n"; - exit(ERR_UNKNOWN_RESULT); -#endif - } - break; - default: - break; - } - } - - void next_sat(std::ostream& out) { - Z3_context ctx = get_context(); - if (m_check_sat_state == state_sat || m_check_sat_state == state_unknown) { - Z3_literals lits = Z3_get_relevant_literals(ctx); - if (lits) { - Z3_block_literals(ctx, lits); - Z3_del_literals(ctx, lits); - } - } - check_sat(out); - } - - void get_sat_assertions(std::ostream& out) { - if (m_check_sat_state == state_unsat) { - out << "false\n"; - } - else { - Z3_ast assignment = Z3_get_context_assignment(m_context); - out << Z3_ast_to_string(m_context, reinterpret_cast(assignment)) << "\n"; - } - } - - void get_implied_equalities(std::ostream& out, unsigned num_exprs, expr* const* exprs) { - buffer class_ids(num_exprs, UINT_MAX); - Z3_lbool r = Z3_get_implied_equalities(m_context, - num_exprs, - (Z3_ast*) exprs, - class_ids.c_ptr()); - if (r == Z3_L_FALSE) { - out << "unsat\n"; - return; - } - out << "("; - for (unsigned i = 0; i < num_exprs; ++i) { - out << class_ids[i]; - if (i + 1 < num_exprs) { - out << " "; - } - } - out << ")\n"; - } - - void eval(std::ostream& out, proto_expr* p_expr, expr* e) { - Z3_model m = get_model(); - if (!m) { - print_failure("There is no model in the current context", p_expr); - return; - } - Z3_ast result = 0; - Z3_bool fully_simplified = Z3_eval(m_context, m, reinterpret_cast(e), &result); - if (!result) { - print_failure("Evaluation was not successful", p_expr); - return; - } - (void) fully_simplified; - out << Z3_ast_to_string(m_context, result) << "\n"; - } - - void eval(std::ostream& out, proto_expr* p_expr, unsigned num_args, expr*const* args) { - svector results; - Z3_model m = get_model(); - if (!m) { - print_failure("There is no model in the current context", p_expr); - return; - } - for (unsigned i = 0; i < num_args; ++i) { - Z3_ast result = 0; - Z3_bool fully_simplified = Z3_eval(m_context, m, reinterpret_cast(args[i]), &result); - if (!result) { - print_failure("Evaluation was not successful", p_expr); - return; - } - (void) fully_simplified; - results.push_back(result); - } - out << "("; - for (unsigned i = 0; i < num_args; ++i) { - out << Z3_ast_to_string(m_context, results[i]); - if (i + 1 < num_args) { - out << "\n"; - } - } - out << ")\n"; - } - - - - - void get_unsat_core(std::ostream& out, proto_expr* p_expr) { - if (!get_enable_cores()) { - print_failure("cores have not been enabled, use (set-option enable-cores)", p_expr); - return; - } - print_core(out); - } - - Z3_ast find_proxy(Z3_ast proxy) { - for (unsigned i = 0; i < m_asserted.size(); ++i) { - if (m_asserted_proxies[i] == (expr*)proxy) { - return reinterpret_cast(m_asserted[i].get()); - } - } - UNREACHABLE(); - return proxy; - } - - void print_core(std::ostream& out) { - unsigned csz = *get_core_size_ptr(); - out << "("; - for (unsigned i = 0; i < csz; ++i) { - out << Z3_ast_to_string(m_context, find_proxy(get_core_ptr()[i])); - if (i + 1 < csz) out << "\n"; - } - out << ")\n"; - } - - void print_core_as_is(std::ostream & out, unsigned csz, Z3_ast * core) { - out << "("; - for (unsigned i = 0; i < csz; ++i) { - out << Z3_ast_to_string(m_context, core[i]); - if (i + 1 < csz) out << " "; - } - out << ")\n"; - } - - void get_assertions(std::ostream& out) { - out << "("; - unsigned num_assertions = get_num_assertions(); - for (unsigned i = 0; i < num_assertions; ++i) { - out << Z3_ast_to_string(m_context, reinterpret_cast(get_assertion(i))); - if (i + 1 < num_assertions) out << "\n"; - } - out << ")\n"; - } - - bool has_error() { - return m_error_stream.tellp() > 0; - } - - void flush_errors() { - if (has_error()) { - m_error_stream.put(0); - print_failure(m_error_stream.str().c_str(), 0); - m_error_stream.seekp(0); - m_error_stream.clear(); - } - } - - std::ostream& get_error_stream() { - return m_error_stream; - } - -private: - - void add_command( - char const* name, - smt_cmd_token tok, - char const* args, - char const* help, - bool is_command = true - ) { - m_str2token.insert(name, tok); - if ((unsigned)tok >= m_token2str.size()) { - m_token2str.resize(tok+1); - m_token2help.resize(tok+1); - m_token2args.resize(tok+1); - m_is_command.resize(tok+1); - } - m_token2str[tok] = name; - m_token2help[tok] = help; - m_token2args[tok] = args; - m_is_command[tok] = is_command; - } - - void add_info( - char const* name, - smt_cmd_token t, - char const* args, - char const* help, - void (*action)(cmd_context&) - ) - { - add_command(name, t, args, help, false); - m_infos.push_back(cmd_info(t, action)); - } - - void add_option( - char const* name, - smt_cmd_token t, - char const* args, - char const* help, - bool (*action)(cmd_context&, proto_expr* const* exprs) - ) - { - add_command(name, t, args, help, false); - m_options.push_back(opt(t, action)); - } - - - static void name_info(cmd_context& ctx) { ctx.print_quoted("Z3"); } - - static void version_info(cmd_context& ctx) { - unsigned maj, min, bn, rn; - Z3_get_version(&maj,&min,&bn,&rn); - ctx.get_out() << "\"" << maj << "." << min << "-" << bn << "." << rn << "\""; - } - - static void authors_info(cmd_context& ctx) { ctx.print_quoted("Leonardo de Moura and Nikolaj Bjorner"); } - - static void last_failure_info(cmd_context& cmd_ctx) { - Z3_context ctx = cmd_ctx.get_context(); - Z3_search_failure sf = Z3_get_search_failure(ctx); - static char const * reasons[8] = { "no failure", "unknown", "timeout", "memout", - "user canceled", "exceeded conflict bound", - "incomplete theory support", - "formulas used quantifiers that may not have been instantiated fully" - }; - if (sf < 8) { - cmd_ctx.print_quoted(reasons[sf]); - } - else { - cmd_ctx.print_quoted("not documented"); - UNREACHABLE(); - } - } - - static void reason_unknown_info(cmd_context& cmd_ctx) { - Z3_context ctx = cmd_ctx.get_context(); - Z3_search_failure sf = Z3_get_search_failure(ctx); - - if (sf == 3) - cmd_ctx.print_quoted("memout"); - else - cmd_ctx.print_quoted("incomplete"); - } - - static void stats_info(cmd_context& cmd_ctx) { - cmd_ctx.get_out() << "\"" << escaped(Z3_statistics_to_string(cmd_ctx.get_context()), true) << "\""; - } - - static void model_info(cmd_context& cmd_ctx) { - Z3_context ctx = cmd_ctx.get_context(); - Z3_model m = cmd_ctx.get_model(); - if (m) { - if (Z3_get_parameters(ctx).m_model_v1_pp || Z3_get_parameters(ctx).m_model_v2_pp) { - cmd_ctx.get_out() << "\"" << escaped(Z3_model_to_string(ctx, m), true) << "\""; - } else { - cmd_ctx.get_out() << "(z3_model" << std::endl - << Z3_model_to_string(ctx, m) - << ")"; - } - } - else if (!Z3_get_parameters(ctx).m_model) { - cmd_ctx.print_quoted("models are disabled - enable them using the configuration MODEL=true"); - } - else { - cmd_ctx.print_quoted("there is no model at the current scope"); - } - } - - static void time_info(cmd_context& cmd_ctx) { - cmd_ctx.get_out() << cmd_ctx.get_seconds(); - } - - static void labels_info(cmd_context& cmd_ctx) { - std::ostream& out = cmd_ctx.get_out(); - Z3_context ctx = cmd_ctx.get_context(); - Z3_literals lits = Z3_get_relevant_labels(ctx); - unsigned sz = Z3_get_num_literals(ctx, lits); - if (sz > 0) { - out << "(z3_labels"; - for (unsigned i = 0; i < sz; ++i) { - out << " "; - out << Z3_get_symbol_string(ctx, Z3_get_label_symbol(ctx, lits, i)); - } - out << ")"; - } - Z3_del_literals(ctx, lits); - } - - static void help_info(cmd_context& cmd_ctx) { - cmd_ctx.get_help(cmd_ctx.get_out()); - } - - static bool print_success_option(cmd_context& cmd_ctx, proto_expr*const* chs) { - cmd_ctx.set_print_success(cmd_ctx.parse_opt_bool(chs?*chs:0, true)); - return true; - } - - static bool produce_models_option(cmd_context& cmd_ctx, proto_expr*const* chs) { - cmd_ctx.update_param("MODEL", cmd_ctx.parse_opt_bool(chs?*chs:0, true) ? "true" : "false"); - return true; - } - - static bool verbosity_option(cmd_context& cmd_ctx, proto_expr*const* chs) { - unsigned lvl = cmd_ctx.parse_opt_numeral(chs?*chs:0, 0); - set_verbosity_level(lvl); - return true; - } - - static bool output_channel_option(cmd_context& cmd_ctx, proto_expr*const* chs) { - cmd_ctx.set_out(chs?*chs:0); - return true; - } - - static bool enable_cores_option(cmd_context& cmd_ctx, proto_expr*const* chs) { - cmd_ctx.set_enable_cores(); - return true; - } - - static void print_parameters(cmd_context& cmd_ctx) { - front_end_params& p = Z3_get_parameters(cmd_ctx.m_context); - ini_params ini; - p.register_params(ini); - ini.display_params(cmd_ctx.get_out()); - } - - static void print_parameter_help(char const* param, cmd_context& cmd_ctx) { - front_end_params& p = Z3_get_parameters(cmd_ctx.m_context); - ini_params ini; - p.register_params(ini); - ini.display_parameter_help(param,cmd_ctx.get_out()); - } - - static bool update_param_option(cmd_context& cmd_ctx, proto_expr*const* chs) { - if (!chs) { - print_parameters(cmd_ctx); - return false; - } - if (chs[0] && !chs[1] && chs[0]->kind() == proto_expr::CONS) { - chs = chs[0]->children(); - } - - proto_expr* p = chs[0]; - proto_expr* v = chs[1]; - char const* p_string = 0; - char const*v_string = 0; - std::string v_str; - if (!p || (p->kind() != proto_expr::ID && p->kind() != proto_expr::STRING && p->kind() != proto_expr::ANNOTATION)) { - print_parameters(cmd_ctx); - return false; - } - p_string = p->string().bare_str(); - if (v && (v->kind() == proto_expr::INT || v->kind() == proto_expr::FLOAT)) { - v_str += v->number().to_string(); - v_string = v_str.c_str(); - } - else if (!v || (v->kind() != proto_expr::ID && v->kind() != proto_expr::STRING)) { - print_parameter_help(p->string().bare_str(), cmd_ctx); - return false; - } - else { - v_str = v->string().bare_str(); - if (v_str.length() > 2 && v_str[0] == '|' && v_str[v_str.length() - 1] == '|') { - // strip the quotes - v_str = v_str.substr(1, v_str.length() - 2); - } - v_string = v_str.c_str(); - } - // hack for generating warning message when trying to set PROOF_MODE inside the command context. - if (strcmp(p_string, "PROOF_MODE") == 0) { - warning_msg("PROOF_MODE can only be set as a command line option when invoking z3.exe (e.g., \"z3.exe PROOF_MODE=2 file.smt2\"), or when creating a fresh logical context using the Z3 API."); - return false; - } - cmd_ctx.update_param(p_string, v_string); - return true; - } - - static bool set_verbose_output_channel_option(cmd_context& cmd_ctx, proto_expr*const* chs) { - cmd_ctx.m_verbose.reset(chs?(*chs):0); - set_verbose_stream(*cmd_ctx.m_verbose); - return true; - } -}; - - class smtparser : public parser { struct builtin_op { family_id m_family_id; @@ -1922,7 +585,6 @@ class smtparser : public parser { symbol m_notes; symbol m_theory; symbol m_language; - symbol m_extensions; symbol m_array; symbol m_bang; symbol m_underscore; @@ -1932,8 +594,6 @@ class smtparser : public parser { family_id m_arith_fid; family_id m_array_fid; family_id m_rel_fid; - datatype_decl_plugin * m_dt_plugin; - datatype_util m_dt_util; func_decl * m_sk_hack; std::ostream* m_err; bool m_display_error_for_vs; @@ -1968,12 +628,9 @@ public: m_notes("notes"), m_theory("theory"), m_language("language"), - m_extensions("extensions"), m_array("array"), m_bang("!"), m_underscore("_"), - m_dt_plugin(0), - m_dt_util(m), m_err(0), m_display_error_for_vs(false) { @@ -2024,45 +681,6 @@ public: return parse_stream(is); } - bool parse_commands(Z3_context ctx, std::istream& is, std::ostream& os) { - set_error_stream(os); - cmd_context context(m_manager, ctx, is, os); - set_error_stream(context.get_error_stream()); - proto_region proto_region; - scanner scanner(is, context.get_error_stream(), true); - proto_expr_parser parser(proto_region, scanner, context.get_error_stream()); - - m_display_error_for_vs = Z3_get_parameters(ctx).m_display_error_for_vs; - - ptr_vector exprs; - while (!parser.at_eof()) { - proto_region.reset(); - exprs.reset(); - if (!parser.parse(exprs, true)) { - context.flush_errors(); - context.get_out().flush(); - break; - } - if (exprs.empty()) { - break; - } - SASSERT(exprs.size() == 1); - try { - if (!process_command(context, exprs.back())) { - break; - } - } - catch(cmd_exn(ex)) { - context.flush_errors(); - context.get_out().flush(); - context.print_failure(Z3_get_error_msg(ex.get()), exprs.back()); - } - context.flush_errors(); - context.get_out().flush(); - } - return true; - } - void add_builtin_op(char const * s, family_id fid, decl_kind k) { m_builtin_ops.insert(symbol(s), builtin_op(fid, k)); } @@ -2072,15 +690,6 @@ public: } void initialize_smtlib() { - - if (!m_dt_plugin) { - family_id fid = m_manager.get_family_id("datatype"); - if (!m_manager.has_plugin(fid)) { - m_manager.register_plugin(fid, alloc(datatype_decl_plugin)); - } - m_dt_plugin = static_cast(m_manager.get_plugin(fid)); - } - smtlib::symtable* table = m_benchmark.get_symtable(); symbol arith("arith"); @@ -2253,9 +862,6 @@ private: symbol extrasorts("extrasorts"); symbol extrafuns("extrafuns"); symbol extrapreds("extrapreds"); - symbol datatypes("datatypes"); - symbol unify("unify"); - symbol unify_fail("unify-fail"); symbol assumption("assumption"); symbol assumption_core("assumption-core"); symbol define_sorts_sym("define_sorts"); @@ -2391,20 +997,6 @@ private: ++proto_exprs; continue; } - if (datatypes == e->string() && e1) { - if (!declare_datatypes(e1)) { - return false; - } - ++proto_exprs; - continue; - } - if ((unify == e->string() || unify_fail == e->string()) && e1) { - if (!test_unify(e1, unify == e->string())) { - return false; - } - ++proto_exprs; - continue; - } if (m_notes == e->string() && e1) { ++proto_exprs; continue; @@ -2442,549 +1034,6 @@ private: expr->kind() == proto_expr::ANNOTATION); } - smt_cmd_token get_command_token(cmd_context& ctx, proto_expr* expr) { - if (!expr) { - return SMT_CMD_ERROR; - } - if (!is_id_token(expr)) { - return SMT_CMD_ERROR; - } - return ctx.string2token(expr->string().bare_str()); - } - - bool process_command(cmd_context& cmd_ctx, proto_expr* p_expr) { - proto_expr* const* chs = p_expr->children(); - proto_expr* e0 = chs?chs[0]:0; - proto_expr* e1 = e0?chs[1]:0; - std::ostream& out = cmd_ctx.get_out(); - Z3_context ctx = cmd_ctx.get_context(); - - smt_cmd_token cmd_tok; - if (p_expr->kind() == proto_expr::ID) { - cmd_tok = get_command_token(cmd_ctx, p_expr); - } - else { - cmd_tok = get_command_token(cmd_ctx, e0); - } - - switch(cmd_tok) { - case SMT_CMD_SET_LOGIC: - if (!check_id(e1)) { - cmd_ctx.print_failure("logic identifier expected as argument to logic", p_expr); - break; - } - if (Z3_set_logic(ctx, e1->string().bare_str())) { - // m_smtlib_logic param is only used for pretty printing. - Z3_get_parameters(ctx).m_smtlib_logic = e1->string().bare_str(); - set_default_num_sort(e1->string()); - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("failed to set logic", p_expr); - } - break; - case SMT_CMD_DECLARE_SORTS: - if (!check_valid(cmd_ctx, p_expr, e1, "sort declaration expects an argument")) { - break; - } - if (e0 && e1 && chs[2]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - if (declare_sorts(e1)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("could not parse sort declaration", p_expr); - } - break; - case SMT_CMD_DECLARE_FUNS: // func-decls - if (!check_valid(cmd_ctx, p_expr, e1, "function declaration expects an argument")) { - break; - } - if (e0 && e1 && chs[2]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - if (declare_funs(e1)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("could not parse function declaration", p_expr); - } - break; - case SMT_CMD_DECLARE_PREDS: // pred-decls - if (!check_valid(cmd_ctx, p_expr, e1, "predicate declaration expects an argument")) { - break; - } - if (e0 && e1 && chs[2]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - if (declare_preds(e1)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("could not parse predicate declaration", p_expr); - } - break; - case SMT_CMD_DECLARE_DATATYPES: - if (!check_valid(cmd_ctx, p_expr, e1, "data-type declaration expects an argument")) { - break; - } - if (e0 && e1 && chs[2]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - if (declare_datatypes(e1)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("could not parse data-type declaration", p_expr); - } - break; - case SMT_CMD_DEFINE: { - expr_ref macro_expr(m_manager); - if (define_macro(cmd_ctx.get_table(), cmd_ctx.get_region(), p_expr, macro_expr)) { - cmd_ctx.add_trail(macro_expr); - cmd_ctx.print_success(); - } - break; - } - case SMT_CMD_DEFINE_SORTS: { - if (!check_valid(cmd_ctx, p_expr, e1, "sort definition expects an argument")) { - break; - } - if (e0 && e1 && chs[2]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - if (define_sorts(e1)) { - cmd_ctx.print_success(); - } - break; - } - case SMT_CMD_DECLARE_SORT: { // - if (!check_id(e1)) { - cmd_ctx.print_failure("identifier argument expected", p_expr); - break; - - } - unsigned num_args = cmd_ctx.parse_opt_numeral(chs[2], 0); - if (e0 && e1 && chs[2] && chs[3]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - m_benchmark.get_symtable()->insert(e1->string(), alloc(user_sort, m_manager, num_args, e1->string())); - cmd_ctx.print_success(); - - break; - } - case SMT_CMD_DEFINE_SORT: { // (*) - if (!check_id(e1)) { - cmd_ctx.print_failure("sort definition expects three arguments", p_expr); - break; - } - proto_expr* e2 = chs[2]; - if (!check_valid(cmd_ctx, p_expr, e2, "sort definition expects three arguments")) { - break; - } - proto_expr* e3 = chs[3]; - if (!check_valid(cmd_ctx, p_expr, e3, "sort definition expects three arguments")) { - break; - } - if (chs[4]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - if (define_sort(e1, e2, e3)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("could not parse sort definition", p_expr); - } - break; - } - case SMT_CMD_DECLARE_FUN: { // (*) - if (!check_id(e1)) { - cmd_ctx.print_failure("function declaration expects three arguments", p_expr); - break; - } - proto_expr* e2 = chs[2]; - if (!check_valid(cmd_ctx, p_expr, e2, "function declaration expects three arguments")) { - break; - } - proto_expr* e3 = chs[3]; - if (!check_valid(cmd_ctx, p_expr, e3, "function declaration expects three arguments")) { - break; - } - if (chs[4]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - if (declare_fun(e1,e2,e3)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("could not parse function declaration", p_expr); - } - break; - } - case SMT_CMD_DECLARE_CONST: { // - if (!check_id(e1)) { - cmd_ctx.print_failure("constant declaration expects two arguments", p_expr); - break; - } - proto_expr* e2 = chs[2]; - if (!check_valid(cmd_ctx, p_expr, e2, "constant declaration expects two arguments")) { - break; - } - if (chs[3]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - if (declare_fun(e1, 0, e2)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("could not parse constant declaration", p_expr); - } - break; - } - case SMT_CMD_DEFINE_FUN: { // (*) - if (!check_id(e1)) { - cmd_ctx.print_failure("function definition expects four arguments", p_expr); - break; - } - proto_expr* e2 = chs[2]; - if (!check_valid(cmd_ctx, p_expr, e2, "function definition expects four arguments")) { - break; - } - proto_expr* e3 = chs[3]; - if (!check_valid(cmd_ctx, p_expr, e3, "function definition expects four arguments")) { - break; - } - proto_expr* e4 = chs[4]; - if (!check_valid(cmd_ctx, p_expr, e4, "function definition expects four arguments")) { - break; - } - if (chs[5]) { - cmd_ctx.print_failure("too many arguments passed to declaration", p_expr); - } - expr_ref macro_expr(m_manager); - if (define_fun(cmd_ctx.get_table(), cmd_ctx.get_region(), e1, e2, e3, e4, macro_expr)) { - cmd_ctx.add_trail(macro_expr); - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_failure("could not parse function definition", p_expr); - } - break; - } - case SMT_CMD_GET_VALUE: { // (+) - if (!check_valid(cmd_ctx, p_expr, e1, "get-value expects a list arguments")) { - break; - } - proto_expr* const* children = e1->children(); - expr_ref_vector exprs(m_manager); - - while (children && children[0]) { - expr_ref e(m_manager); - if (!get_expression(cmd_ctx, cmd_ctx.get_table(), p_expr, children[0], e, "one expression expected to eval")) { - break; - } - exprs.push_back(e); - ++children; - } - cmd_ctx.eval(out, p_expr, exprs.size(), exprs.c_ptr()); - break; - } - case SMT_CMD_PUSH: { // numeral - unsigned num_scopes = cmd_ctx.parse_opt_numeral(e1, 1); - cmd_ctx.push(num_scopes); - cmd_ctx.print_success(); - if (e1 && chs[2]) { - cmd_ctx.print_failure("too many arguments passed to command", p_expr); - } - break; - } - case SMT_CMD_POP: { // numeral - unsigned num_scopes = cmd_ctx.parse_opt_numeral(e1, 1); - cmd_ctx.pop(num_scopes); - cmd_ctx.print_success(); - if (e1 && chs[2]) { - cmd_ctx.print_failure("too many arguments passed to command", p_expr); - } - break; - } - case SMT_CMD_ASSERT: { // expr+ - expr_ref_vector exprs(m_manager); - if (!chs) { - cmd_ctx.print_failure("expecting list of arguments", p_expr); - break; - } - if (!(*chs)) { - cmd_ctx.print_success(); - break; - } - ++chs; - if (!make_bool_expressions(cmd_ctx.get_table(), chs, exprs)) { - if (!cmd_ctx.has_error()) { - cmd_ctx.print_failure("could not parse expression", *chs); - } - return true; - } - for (unsigned i = 0; i < exprs.size(); ++i) { - cmd_ctx.add_asserted(exprs[i].get()); - } - cmd_ctx.print_success(); - break; - } - case SMT_CMD_CHECK_SAT: { // boolean-constants* - if (!chs || !(*chs)) { - cmd_ctx.check_sat(out); - } - else { - ++chs; - if (!chs || !(*chs)) { - cmd_ctx.check_sat(out); - } - else { - expr_ref_vector exprs(m_manager); - if (!make_bool_expressions(cmd_ctx.get_table(), chs, exprs)) { - if (!cmd_ctx.has_error()) { - cmd_ctx.print_failure("could not parse expression", *chs); - } - return true; - } - cmd_ctx.get_core(p_expr, out, exprs.size(), exprs.c_ptr(), false); - } - } - break; - } - case SMT_CMD_GET_CORE: { // boolean-constants+ - expr_ref_vector exprs(m_manager); - if (!chs) { - cmd_ctx.print_failure("expecting list of arguments", p_expr); - break; - } - if (!(*chs)) { - cmd_ctx.print_success(); - break; - } - ++chs; - if (!make_bool_expressions(cmd_ctx.get_table(), chs, exprs)) { - if (!cmd_ctx.has_error()) { - cmd_ctx.print_failure("could not parse expression", *chs); - } - return true; - } - cmd_ctx.get_core(p_expr, out, exprs.size(), exprs.c_ptr(), true); // just get the core - break; - } - case SMT_CMD_NEXT_SAT: { // - cmd_ctx.next_sat(out); - break; - } - case SMT_CMD_SIMPLIFY: { - expr_ref e(m_manager); - if (!get_expression(cmd_ctx, cmd_ctx.get_table(), p_expr, e1, e, "one expression expected to simplify")) { - break; - } - cmd_context::scoped_stopwatch stopw(cmd_ctx); - Z3_ast result = Z3_simplify(ctx, reinterpret_cast(e.get())); - out << Z3_ast_to_string(ctx, result) << "\n"; - break; - } - case SMT_CMD_GET_IMPLIED_EQUALITIES: { - expr_ref_vector exprs(m_manager); - expr_ref e(m_manager); - if (!chs || !(*chs)) { - cmd_ctx.print_failure("expecting list of arguments", p_expr); - break; - } - ++chs; - bool ok = true; - while (*chs) { - if (!get_expression(cmd_ctx, cmd_ctx.get_table(), p_expr, *chs, e, "list of expressions expected")) { - ok = false; - break; - } - exprs.push_back(e); - ++chs; - } - if (!ok) { - break; - } - cmd_context::scoped_stopwatch stopw(cmd_ctx); - cmd_ctx.get_implied_equalities(out, exprs.size(), exprs.c_ptr()); - break; - } - case SMT_CMD_EVAL: { - expr_ref e(m_manager); - if (!get_expression(cmd_ctx, cmd_ctx.get_table(), p_expr, e1, e, "one expression expected to eval")) { - break; - } - cmd_ctx.eval(out, p_expr, e); - break; - } - case SMT_CMD_GET_ASSERTIONS: { // string - scoped_stream strm(e1, out); - cmd_ctx.get_assertions(*strm); - break; - } - case SMT_CMD_GET_SAT_ASSERTIONS: { // string - scoped_stream strm(e1, out); - cmd_ctx.get_sat_assertions(out); - break; - } - case SMT_CMD_KEEP_SAT_ASSERTIONS: { // - Z3_ast assignment = Z3_get_context_assignment(ctx); - cmd_ctx.add_asserted(reinterpret_cast(assignment)); - cmd_ctx.print_success(); - break; - } - case SMT_CMD_GET_UNSAT_CORE: { // string - scoped_stream strm(e1, out); - cmd_ctx.get_unsat_core(out, p_expr); - break; - } - case SMT_CMD_GET_PROOF: { // string - scoped_stream strm(e1, out); - cmd_ctx.get_proof(*strm, p_expr); - break; - } - case SMT_CMD_SET_OPTION: { // string strings - if (!e1) { - cmd_ctx.set_option_help(out, ""); - break; - } - if (cmd_ctx.set_option(get_command_token(cmd_ctx,e1), chs+2)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_unsupported(); - } - break; - } - case SMT_CMD_SET_INFO: { - if (!e1) { - cmd_ctx.set_option_help(out, ""); - break; - } - if (cmd_ctx.set_info(e1, chs+2)) { - cmd_ctx.print_success(); - } - else { - cmd_ctx.print_unsupported(); - } - break; - } - case SMT_CMD_GET_INFO: { // string+ - if (!e1) { - cmd_ctx.get_info_help(out, ""); - break; - } - ++chs; - SASSERT(e1 == *chs); - out << "("; - while(*chs) { - if (!get_info(cmd_ctx, get_command_token(cmd_ctx,*chs))) { - out << ":" << chs[0]->string() << " \"unsupported\""; - } - ++chs; - if (*chs) { - out << "\n"; - } - } - out << ")\n"; - break; - } - case SMT_CMD_ECHO: { // string+ - if (!e1) { - cmd_ctx.get_info_help(out, ""); - break; - } - ++chs; - SASSERT(e1 == *chs); - while(*chs) { - out << chs[0]->string() << "\n"; - ++chs; - } - break; - } - case SMT_CMD_EXIT: // - return false; - case SMT_CMD_ERROR: // error token - cmd_ctx.print_failure("unrecognized command", p_expr); - break; - default: - if (get_info(cmd_ctx, cmd_tok)) { - out << "\n"; - break; - } - if (cmd_ctx.get_command_help(out, cmd_tok)) { - out << "\n"; - break; - } - cmd_ctx.print_failure("this is not a top-level command", p_expr); - break; - } - return true; - } - - void flatten_exprs(expr_ref_vector& exprs) { - for (unsigned i = 0; i < exprs.size(); ++i) { - expr* e = exprs[i].get(); - if (m_manager.is_and(e)) { - for (unsigned j = 1; j < to_app(e)->get_num_args(); ++j) { - exprs.push_back(to_app(e)->get_arg(j)); - } - exprs[i] = to_app(e)->get_arg(0); - --i; - continue; - } - if (m_manager.is_not(e) && - m_manager.is_or(to_app(e)->get_arg(0))) { - e = to_app(e)->get_arg(0); - app* a = to_app(e); - for (unsigned j = 1; j < a->get_num_args(); ++j) { - e = a->get_arg(j); - if (m_manager.is_not(e)) { - exprs.push_back(to_app(e)->get_arg(0)); - } - else { - exprs.push_back(m_manager.mk_not(e)); - } - } - e = a->get_arg(0); - if (m_manager.is_not(e)) { - exprs[i] = to_app(e)->get_arg(0); - } - else { - exprs[i] = m_manager.mk_not(e); - } - --i; - continue; - } - } - } - - - bool get_info(cmd_context& cmd_ctx, smt_cmd_token cmd_tok) { - return cmd_ctx.get_info(cmd_tok); - } - - bool get_expression(cmd_context& cmd_ctx, symbol_table& table, proto_expr* p_expr, proto_expr* e1, expr_ref& e, char const* msg) { - if (!check_valid(cmd_ctx, p_expr, e1, msg)) { - return false; - } - m_binding_level = 0; - if (!make_expression(table, e1, e)) { - return false; - } - return true; - } - - - bool check_valid(cmd_context& cmd_ctx, proto_expr* p_expr, proto_expr* e, char const* msg) { - if (e == 0) { - cmd_ctx.print_failure(msg, p_expr); - } - return (e != 0); - } - bool check_id(proto_expr* e) { return is_id_token(e); } @@ -4088,186 +2137,6 @@ private: return true; } - bool declare_datatypes(proto_expr * e) { - TRACE("datatypes", tout << "new datatype declarion section\n";); - proto_expr * const* children = e->children(); - - buffer dt_names; - - while (children && *children) { - proto_expr * type_decl = *children; - proto_expr * const* td_children = type_decl->children(); - if (!td_children || !td_children[0] || !(td_children[0]->kind() == proto_expr::ID)) { - set_error("invalid datatype declaration", type_decl); - return false; - } - symbol name = td_children[0]->string(); - sort * dummy; - if (m_benchmark.get_symtable()->find(name, dummy)) { - set_error("invalid datatype declaration, name was already used", type_decl); - return false; - } - dt_names.push_back(name); - TRACE("datatypes", tout << name << "\n";); - ++children; - } - - children = e->children(); - - ptr_buffer datatypes; - - while (children && *children) { - datatype_decl * d = declare_datatype(*children, dt_names); - if (!d) { - return false; - } - datatypes.push_back(d); - ++children; - } - - sort_ref_vector new_types(m_manager); - - bool result = m_dt_plugin->mk_datatypes(datatypes.size(), datatypes.c_ptr(), new_types); - del_datatype_decls(datatypes.size(), datatypes.c_ptr()); - - if (!result) { - set_error("invalid datatype declaration", e); - } - else { - unsigned num_types = new_types.size(); - for (unsigned i = 0; i < num_types; i++) { - sort * d = new_types.get(i); - TRACE("datatype", tout << "new datatype\n" << mk_pp(d, m_manager) << "\n"; - tout << "num. elements: " << d->get_num_elements() << "\n"; - tout << "recursive: " << m_dt_util.is_recursive(d) << "\n"; - tout << "non_rec constructor: " << m_dt_util.get_non_rec_constructor(d)->get_name() << "\n"; - ); - m_benchmark.insert(d); - ptr_vector const * constructors = m_dt_util.get_datatype_constructors(d); - unsigned num_constructors = constructors->size(); - for (unsigned j = 0; j < num_constructors; j++) { - func_decl * c = constructors->get(j); - m_benchmark.insert(c); - func_decl * r = m_dt_util.get_constructor_recognizer(c); - TRACE("datatype", - tout << "new constructor\n" << mk_pp(c, m_manager) << "\n"; - tout << "new recogniser\n" << mk_pp(r, m_manager) << "\n";); - m_benchmark.insert(r); - ptr_vector const * accessors = m_dt_util.get_constructor_accessors(c); - unsigned num_accessors = accessors->size(); - for (unsigned k = 0; k < num_accessors; k++) { - func_decl * a = accessors->get(k); - TRACE("datatype", tout << "new accessor\n" << mk_pp(a, m_manager) << "\n";); - m_benchmark.insert(a); - } - } - } - } - - return result; - } - - datatype_decl * declare_datatype(proto_expr * e, buffer const & dt_names) { - proto_expr* const * children = e->children(); - symbol const& name = children[0]->string(); - - ptr_buffer constructors; - ++children; // consume id - - while (children && *children) { - constructor_decl * c = declare_constructor(*children, dt_names); - if (!c) { - del_constructor_decls(constructors.size(), constructors.c_ptr()); - return 0; - } - constructors.push_back(c); - ++children; - } - - if (constructors.size() == 0) { - set_error("datatype must have at least one constructor", e); - return 0; - } - - return mk_datatype_decl(name, constructors.size(), constructors.c_ptr()); - } - - constructor_decl * declare_constructor(proto_expr * e, buffer const & dt_names) { - if (e->kind() == proto_expr::ID) { - symbol const & name = e->string(); - string_buffer<> tmp; - tmp << "is_" << name; - symbol r_name(tmp.c_str()); - return mk_constructor_decl(name, r_name, 0, 0); - } - - proto_expr* const * children = e->children(); - if (!children || !children[0] || !(children[0]->kind() == proto_expr::ID)) { - set_error("invalid constructor declaration", e); - return 0; - } - - symbol const & name = children[0]->string(); - string_buffer<> tmp; - tmp << "is_" << name; - symbol r_name(tmp.c_str()); - - ptr_buffer accessors; - ++children; // skip id - - while (children && *children) { - accessor_decl * d = declare_accessor(*children, dt_names); - if (!d) { - del_accessor_decls(accessors.size(), accessors.c_ptr()); - return 0; - } - accessors.push_back(d); - ++children; - } - - return mk_constructor_decl(name, r_name, accessors.size(), accessors.c_ptr()); - } - - accessor_decl * declare_accessor(proto_expr * e, buffer const & dt_names) { - proto_expr* const * children = e->children(); - if (!children || - !children[0] || !(children[0]->kind() == proto_expr::ID) || - !children[1] || !(children[1]->kind() == proto_expr::ID) || - children[2]) { - set_error("invalid accessor declaration", e); - return 0; - } - - symbol const& name = children[0]->string(); - symbol const& tname = children[1]->string(); - unsigned tid = 0; - for (; tid < dt_names.size(); tid++) { - if (tname == dt_names[tid]) { - break; - } - } - - type_ref ty; - if (tid < dt_names.size()) { - ty = type_ref(tid); - } - else { - sort_ref s(m_manager); - if (!make_sort(tname, children[1]->num_params(), children[1]->params(), s)) { - set_error("unknown sort", children[1]); - return 0; - } - m_pinned_sorts.push_back(s); - ty = type_ref(s.get()); - } - - return mk_accessor_decl(name, ty); - } - - // - // (define-macro (name (x A) (y B)) body[x,y]) - // - bool can_be_sorted_var(proto_expr* e) { return e && @@ -4351,133 +2220,6 @@ private: return true; } - - - bool define_fun(symbol_table& table, region& r, proto_expr* name, proto_expr* args, - proto_expr* srt, proto_expr* body, expr_ref & macro_expr) { - - symbol macro_name = name->string(); - - proto_expr* const* chs = args->children(); - // parse marco arguments. - table.begin_scope(); - ptr_vector sorts; - sort_ref sort1(m_manager), sort2(m_manager); - while (chs && *chs) { - proto_expr* e1 = *chs; - if (!can_be_sorted_var(e1)) { - set_error("Macro definition takes a list of pairs", e1); - goto error_cleanup; - } - proto_expr* var = e1->children()[0]; - proto_expr* srt = e1->children()[1]; - sort_ref sort(m_manager); - if (!make_sort(srt, sort)) { - goto error_cleanup; - } - sorts.push_back(sort); - m_pinned_sorts.push_back(sort); - table.insert(var->string(), new (r) bound_var(this, sort)); - ++chs; - ++m_binding_level; - } - - if (!make_expression(table, body, macro_expr)) { - goto error_cleanup; - } - - if (!make_sort(srt, sort1)) { - goto error_cleanup; - } - sort2 = m_manager.get_sort(macro_expr); - if (sort1.get() != sort2.get()) { - std::ostringstream strm; - strm << "The expected sort for macro was " << mk_pp(sort1, m_manager) - << " but the macro body has sort " << mk_pp(sort2, m_manager); - set_error(strm.str().c_str(), body); - goto error_cleanup; - } - table.end_scope(); - m_binding_level = 0; - table.insert(macro_name, new (r) macro_builder(r, body, macro_expr, this, sorts.size(), sorts.c_ptr())); - return true; - - error_cleanup: - table.end_scope(); - m_binding_level = 0; - return false; - } - - bool define_macro(symbol_table& table, region& r, proto_expr* macro_defn, expr_ref & macro_expr) { - SASSERT(macro_defn); - proto_expr* const* exprs = macro_defn->children(); - proto_expr* e0 = exprs?exprs[0]:0; - proto_expr* e1 = e0?exprs[1]:0; - proto_expr* e2 = e1?exprs[2]:0; - - m_binding_level = 0; - - if (!e1) { - set_error("macro definition requires two arguments, none given", macro_defn); - return false; - } - if (!e2) { - set_error("macro definition requires two arguments, only one given", macro_defn); - return false; - } - - // parse macro name - symbol macro_name; - proto_expr* const* chs = e1->children(); - if (e1->kind() == proto_expr::ID) { - macro_name = e1->string(); - chs = 0; - } - else if (chs && chs[0] && chs[0]->kind() == proto_expr::ID) { - macro_name = chs[0]->string(); - chs = chs + 1; - } - else { - set_error("first argument to macro definition should be a name or a name applied to arguments", e1); - return false; - } - - // parse marco arguments. - table.begin_scope(); - ptr_vector sorts; - while (chs && *chs) { - e1 = *chs; - if (!can_be_sorted_var(e1)) { - set_error("Macro definition takes a list of pairs", e1); - goto error_cleanup; - } - proto_expr* var = e1->children()[0]; - proto_expr* srt = e1->children()[1]; - sort_ref sort(m_manager); - if (!make_sort(srt, sort)) { - goto error_cleanup; - } - sorts.push_back(sort); - m_pinned_sorts.push_back(sort); - table.insert(var->string(), new (r) bound_var(this, sort)); - ++chs; - ++m_binding_level; - } - - if (!make_expression(table, e2, macro_expr)) { - goto error_cleanup; - } - table.end_scope(); - m_binding_level = 0; - table.insert(macro_name, new (r) macro_builder(r, e2, macro_expr, this, sorts.size(), sorts.c_ptr())); - return true; - - error_cleanup: - table.end_scope(); - m_binding_level = 0; - return false; - } - void fix_parameters(unsigned num_params, parameter* params) { for (unsigned i = 0; i < num_params; ++i) { func_decl* d = 0; @@ -4495,76 +2237,6 @@ private: } } - bool test_unify(proto_expr * e, bool expected) { - proto_expr* const * children = e->children(); - if (!children || !children[0] || !children[1]) { - set_error("invalid unification problem", e); - } - - expr_ref f1(m_manager), f2(m_manager); - if (!make_expression(children[0], f1) || !make_expression(children[1], f2)) - return false; - unsigned num_vars1 = 0; - unsigned num_vars2 = 0; - if (is_forall(f1)) { - num_vars1 = to_quantifier(f1)->get_num_decls(); - f1 = to_quantifier(f1)->get_expr(); - } - if (is_forall(f2)) { - num_vars2 = to_quantifier(f2)->get_num_decls(); - f2 = to_quantifier(f2)->get_expr(); - } - substitution s(m_manager); - s.reserve(2, std::max(num_vars1, num_vars2)); - unifier u(m_manager); - if (u(f1, f2, s)) { - std::cout << "unification: succeeded\n"; - if (!expected) { - get_err() << "WRONG ANSWER\n"; - UNREACHABLE(); - } - unsigned deltas[2] = { 0, num_vars1 }; - s.display(std::cout, 2, deltas); - } - else { - std::cout << "unification: failed\n"; - if (expected) { - get_err() << "WRONG ANSWER\n"; - UNREACHABLE(); - } - } - return true; - } - - void dump_substitution(expr_ref_buffer & s) { - unsigned sz = s.size(); - for (unsigned i = 0; i < sz; i++) { - expr * t = s[i]; - if (t) - std::cout << "VAR " << i << " -->\n" << mk_pp(t, m_manager) << "\n"; - } - } - - bool declare_axioms(proto_expr * e) { - proto_expr* const * children = e->children(); - while (children && *children) { - if (!declare_axiom(*children)) { - return false; - } - ++children; - } - return true; - } - - bool declare_axiom(proto_expr * e) { - expr_ref t(m_manager); - if (!make_expression(e, t) || - !push_assumption(t.get())) { - return false; - } - return true; - } - bool make_app(proto_expr * proto_expr, expr_ref_vector const & args, expr_ref & result) { symbol const& name = proto_expr->string(); ptr_vector sorts; @@ -4641,49 +2313,6 @@ private: } }; - class macro_builder : public idbuilder { - proto_expr* m_p_expr; - expr* m_expr; - smtparser* m_parser; - unsigned m_num_sorts; - sort** m_sorts; - public: - macro_builder(region& r, proto_expr* p_expr, expr* e, smtparser* p, unsigned num_sorts, sort* const* sorts) : - m_p_expr(p_expr), m_expr(e), m_parser(p), m_num_sorts(num_sorts) { - m_sorts = new (r) sort*[num_sorts]; - for (unsigned i = 0; i < num_sorts; ++i) { - m_sorts[i] = sorts[i]; - } - } - - virtual bool apply(expr_ref_vector const& args, expr_ref& result) { - ast_manager& m = m_parser->m_manager; - if (args.size() != m_num_sorts) { - m_parser->set_error("wrong number of arguments passed to macro", m_p_expr); - return false; - } - for (unsigned i = 0; i < m_num_sorts; ++i) { - if (m_sorts[i] != m.get_sort(args[i])) { - std::ostringstream strm; - strm << "sort miss-match for argument of macro. Expecting sort: "; - strm << mk_pp(m_sorts[i], m) << " instead argument "; - strm << mk_pp(args[i], m) << " with sort "; - strm << mk_pp(m.get_sort(args[i]), m); - m_parser->set_error(strm.str().c_str(), m_p_expr); - return false; - } - } - if (m_num_sorts == 0) { - result = m_expr; - } - else { - var_subst subst(m); - subst(m_expr, args.size(), args.c_ptr(), result); - } - return true; - } - }; - class identity : public idbuilder { public: identity() {} diff --git a/src/api/smtparser.h b/src/api/smtparser.h index 6750471a8..d593f3f05 100644 --- a/src/api/smtparser.h +++ b/src/api/smtparser.h @@ -42,8 +42,6 @@ namespace smtlib { virtual bool parse_file(char const * path) = 0; virtual bool parse_string(char const * string) = 0; - virtual bool parse_commands(Z3_context ctx, std::istream& is, std::ostream& os) = 0; - virtual benchmark * get_benchmark() = 0; }; }; From 566ed44033a96d538384b112254ffebd153fccba Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 18:11:27 -0700 Subject: [PATCH 09/35] removing 'fat' from smt 1.0 parser Signed-off-by: Leonardo de Moura --- src/api/smtparser.cpp | 13 +------------ src/api/smtparser.h | 10 +++++----- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/api/smtparser.cpp b/src/api/smtparser.cpp index f290c717b..53dffb28c 100644 --- a/src/api/smtparser.cpp +++ b/src/api/smtparser.cpp @@ -34,13 +34,11 @@ Revision History: #include"warning.h" #include"error_codes.h" #include"pattern_validation.h" -#include"timeit.h" #include"var_subst.h" #include"well_sorted.h" #include"str_hashtable.h" #include"front_end_params.h" #include"stopwatch.h" -front_end_params& Z3_API Z3_get_parameters(Z3_context c); class id_param_info { symbol m_string; @@ -60,7 +58,7 @@ public: class proto_region { ptr_vector m_rationals; - ptr_vector< id_param_info > m_id_infos; + ptr_vector m_id_infos; region m_region; public: proto_region() { } @@ -562,7 +560,6 @@ class smtparser : public parser { bool m_ignore_user_patterns; unsigned m_binding_level; // scope level for bound vars benchmark m_benchmark; // currently parsed benchmark - sort_ref_vector m_pinned_sorts; typedef map op_map; op_map m_builtin_ops; @@ -580,11 +577,8 @@ class smtparser : public parser { symbol m_sorts; symbol m_funs; symbol m_preds; - symbol m_definition; symbol m_axioms; symbol m_notes; - symbol m_theory; - symbol m_language; symbol m_array; symbol m_bang; symbol m_underscore; @@ -610,7 +604,6 @@ public: m_ignore_user_patterns(ignore_user_patterns), m_binding_level(0), m_benchmark(m_manager, symbol("")), - m_pinned_sorts(m), m_let("let"), m_flet("flet"), m_forall("forall"), @@ -623,11 +616,8 @@ public: m_sorts("sorts"), m_funs("funs"), m_preds("preds"), - m_definition("definition"), m_axioms("axioms"), m_notes("notes"), - m_theory("theory"), - m_language("language"), m_array("array"), m_bang("!"), m_underscore("_"), @@ -661,7 +651,6 @@ public: } bool parse_file(char const * filename) { - timeit tt(get_verbosity_level() >= 100, "parsing file"); if (filename != 0) { std::ifstream stream(filename); if (!stream) { diff --git a/src/api/smtparser.h b/src/api/smtparser.h index d593f3f05..dde6068f9 100644 --- a/src/api/smtparser.h +++ b/src/api/smtparser.h @@ -19,11 +19,11 @@ Revision History: #ifndef _SMT_PARSER_H_ #define _SMT_PARSER_H_ -#include "ast.h" -#include "vector.h" -#include "smtlib.h" -#include "z3.h" -#include +#include +#include"ast.h" +#include"vector.h" +#include"smtlib.h" +#include"z3.h" namespace smtlib { class parser { From 1492b81290ef4dbb7a43823d42628ad5f4e6e8c8 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 18:21:17 -0700 Subject: [PATCH 10/35] moved smt 1.0 parser to its own module Signed-off-by: Leonardo de Moura --- scripts/mk_make.py | 3 ++- src/{api => smtparser}/smtlib.cpp | 0 src/{api => smtparser}/smtlib.h | 0 src/{api => smtparser}/smtlib_solver.cpp | 0 src/{api => smtparser}/smtlib_solver.h | 0 src/{api => smtparser}/smtparser.cpp | 0 src/{api => smtparser}/smtparser.h | 1 - 7 files changed, 2 insertions(+), 2 deletions(-) rename src/{api => smtparser}/smtlib.cpp (100%) rename src/{api => smtparser}/smtlib.h (100%) rename src/{api => smtparser}/smtlib_solver.cpp (100%) rename src/{api => smtparser}/smtlib_solver.h (100%) rename src/{api => smtparser}/smtparser.cpp (100%) rename src/{api => smtparser}/smtparser.h (98%) diff --git a/scripts/mk_make.py b/scripts/mk_make.py index e37013745..a79a0034f 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -59,7 +59,8 @@ add_lib('smtlogic_tactics', ['arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv') add_lib('portfolio', ['smtlogic_tactics', 'ufbv_tactic', 'fpa', 'aig', 'muz_qe', 'sls_tactic', 'subpaving_tactic'], 'tactic/portfolio') # TODO: delete SMT 1.0 frontend -add_lib('api', ['portfolio', 'user_plugin']) +add_lib('smtparser', ['portfolio']) +add_lib('api', ['portfolio', 'user_plugin', 'smtparser']) add_exe('shell', ['api', 'sat', 'extra_cmds'], exe_name='z3') add_exe('test', ['api', 'fuzzing'], exe_name='test-z3') API_files = ['z3_api.h'] diff --git a/src/api/smtlib.cpp b/src/smtparser/smtlib.cpp similarity index 100% rename from src/api/smtlib.cpp rename to src/smtparser/smtlib.cpp diff --git a/src/api/smtlib.h b/src/smtparser/smtlib.h similarity index 100% rename from src/api/smtlib.h rename to src/smtparser/smtlib.h diff --git a/src/api/smtlib_solver.cpp b/src/smtparser/smtlib_solver.cpp similarity index 100% rename from src/api/smtlib_solver.cpp rename to src/smtparser/smtlib_solver.cpp diff --git a/src/api/smtlib_solver.h b/src/smtparser/smtlib_solver.h similarity index 100% rename from src/api/smtlib_solver.h rename to src/smtparser/smtlib_solver.h diff --git a/src/api/smtparser.cpp b/src/smtparser/smtparser.cpp similarity index 100% rename from src/api/smtparser.cpp rename to src/smtparser/smtparser.cpp diff --git a/src/api/smtparser.h b/src/smtparser/smtparser.h similarity index 98% rename from src/api/smtparser.h rename to src/smtparser/smtparser.h index dde6068f9..c63f92664 100644 --- a/src/api/smtparser.h +++ b/src/smtparser/smtparser.h @@ -23,7 +23,6 @@ Revision History: #include"ast.h" #include"vector.h" #include"smtlib.h" -#include"z3.h" namespace smtlib { class parser { From ad9bad9cc1c22cf06d83678c2dd257038be539a0 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 18:25:15 -0700 Subject: [PATCH 11/35] created parsers folder Signed-off-by: Leonardo de Moura --- scripts/mk_make.py | 6 +++--- src/{smtparser => parsers/smt}/smtlib.cpp | 0 src/{smtparser => parsers/smt}/smtlib.h | 0 src/{smtparser => parsers/smt}/smtlib_solver.cpp | 0 src/{smtparser => parsers/smt}/smtlib_solver.h | 0 src/{smtparser => parsers/smt}/smtparser.cpp | 0 src/{smtparser => parsers/smt}/smtparser.h | 0 src/{smt2parser => parsers/smt2}/smt2parser.cpp | 0 src/{smt2parser => parsers/smt2}/smt2parser.h | 0 src/{smt2parser => parsers/smt2}/smt2scanner.cpp | 0 src/{smt2parser => parsers/smt2}/smt2scanner.h | 0 src/{parser_util => parsers/util}/cost_parser.cpp | 0 src/{parser_util => parsers/util}/cost_parser.h | 0 src/{parser_util => parsers/util}/pattern_validation.cpp | 0 src/{parser_util => parsers/util}/pattern_validation.h | 0 src/{parser_util => parsers/util}/scanner.cpp | 0 src/{parser_util => parsers/util}/scanner.h | 0 src/{parser_util => parsers/util}/simple_parser.cpp | 0 src/{parser_util => parsers/util}/simple_parser.h | 0 19 files changed, 3 insertions(+), 3 deletions(-) rename src/{smtparser => parsers/smt}/smtlib.cpp (100%) rename src/{smtparser => parsers/smt}/smtlib.h (100%) rename src/{smtparser => parsers/smt}/smtlib_solver.cpp (100%) rename src/{smtparser => parsers/smt}/smtlib_solver.h (100%) rename src/{smtparser => parsers/smt}/smtparser.cpp (100%) rename src/{smtparser => parsers/smt}/smtparser.h (100%) rename src/{smt2parser => parsers/smt2}/smt2parser.cpp (100%) rename src/{smt2parser => parsers/smt2}/smt2parser.h (100%) rename src/{smt2parser => parsers/smt2}/smt2scanner.cpp (100%) rename src/{smt2parser => parsers/smt2}/smt2scanner.h (100%) rename src/{parser_util => parsers/util}/cost_parser.cpp (100%) rename src/{parser_util => parsers/util}/cost_parser.h (100%) rename src/{parser_util => parsers/util}/pattern_validation.cpp (100%) rename src/{parser_util => parsers/util}/pattern_validation.h (100%) rename src/{parser_util => parsers/util}/scanner.cpp (100%) rename src/{parser_util => parsers/util}/scanner.h (100%) rename src/{parser_util => parsers/util}/simple_parser.cpp (100%) rename src/{parser_util => parsers/util}/simple_parser.h (100%) diff --git a/scripts/mk_make.py b/scripts/mk_make.py index a79a0034f..1a3a6229a 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -30,8 +30,8 @@ add_lib('old_params', ['model', 'simplifier']) add_lib('cmd_context', ['tactic', 'rewriter', 'model', 'old_params', 'simplifier']) add_lib('substitution', ['ast'], 'ast/substitution') add_lib('normal_forms', ['rewriter', 'old_params'], 'ast/normal_forms') -add_lib('parser_util', ['ast']) -add_lib('smt2parser', ['cmd_context', 'parser_util']) +add_lib('parser_util', ['ast'], 'parsers/util') +add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2') add_lib('pattern', ['normal_forms', 'smt2parser'], 'ast/pattern') add_lib('macros', ['simplifier', 'old_params'], 'ast/macros') add_lib('grobner', ['ast'], 'math/grobner') @@ -59,7 +59,7 @@ add_lib('smtlogic_tactics', ['arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv') add_lib('portfolio', ['smtlogic_tactics', 'ufbv_tactic', 'fpa', 'aig', 'muz_qe', 'sls_tactic', 'subpaving_tactic'], 'tactic/portfolio') # TODO: delete SMT 1.0 frontend -add_lib('smtparser', ['portfolio']) +add_lib('smtparser', ['portfolio'], 'parsers/smt') add_lib('api', ['portfolio', 'user_plugin', 'smtparser']) add_exe('shell', ['api', 'sat', 'extra_cmds'], exe_name='z3') add_exe('test', ['api', 'fuzzing'], exe_name='test-z3') diff --git a/src/smtparser/smtlib.cpp b/src/parsers/smt/smtlib.cpp similarity index 100% rename from src/smtparser/smtlib.cpp rename to src/parsers/smt/smtlib.cpp diff --git a/src/smtparser/smtlib.h b/src/parsers/smt/smtlib.h similarity index 100% rename from src/smtparser/smtlib.h rename to src/parsers/smt/smtlib.h diff --git a/src/smtparser/smtlib_solver.cpp b/src/parsers/smt/smtlib_solver.cpp similarity index 100% rename from src/smtparser/smtlib_solver.cpp rename to src/parsers/smt/smtlib_solver.cpp diff --git a/src/smtparser/smtlib_solver.h b/src/parsers/smt/smtlib_solver.h similarity index 100% rename from src/smtparser/smtlib_solver.h rename to src/parsers/smt/smtlib_solver.h diff --git a/src/smtparser/smtparser.cpp b/src/parsers/smt/smtparser.cpp similarity index 100% rename from src/smtparser/smtparser.cpp rename to src/parsers/smt/smtparser.cpp diff --git a/src/smtparser/smtparser.h b/src/parsers/smt/smtparser.h similarity index 100% rename from src/smtparser/smtparser.h rename to src/parsers/smt/smtparser.h diff --git a/src/smt2parser/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp similarity index 100% rename from src/smt2parser/smt2parser.cpp rename to src/parsers/smt2/smt2parser.cpp diff --git a/src/smt2parser/smt2parser.h b/src/parsers/smt2/smt2parser.h similarity index 100% rename from src/smt2parser/smt2parser.h rename to src/parsers/smt2/smt2parser.h diff --git a/src/smt2parser/smt2scanner.cpp b/src/parsers/smt2/smt2scanner.cpp similarity index 100% rename from src/smt2parser/smt2scanner.cpp rename to src/parsers/smt2/smt2scanner.cpp diff --git a/src/smt2parser/smt2scanner.h b/src/parsers/smt2/smt2scanner.h similarity index 100% rename from src/smt2parser/smt2scanner.h rename to src/parsers/smt2/smt2scanner.h diff --git a/src/parser_util/cost_parser.cpp b/src/parsers/util/cost_parser.cpp similarity index 100% rename from src/parser_util/cost_parser.cpp rename to src/parsers/util/cost_parser.cpp diff --git a/src/parser_util/cost_parser.h b/src/parsers/util/cost_parser.h similarity index 100% rename from src/parser_util/cost_parser.h rename to src/parsers/util/cost_parser.h diff --git a/src/parser_util/pattern_validation.cpp b/src/parsers/util/pattern_validation.cpp similarity index 100% rename from src/parser_util/pattern_validation.cpp rename to src/parsers/util/pattern_validation.cpp diff --git a/src/parser_util/pattern_validation.h b/src/parsers/util/pattern_validation.h similarity index 100% rename from src/parser_util/pattern_validation.h rename to src/parsers/util/pattern_validation.h diff --git a/src/parser_util/scanner.cpp b/src/parsers/util/scanner.cpp similarity index 100% rename from src/parser_util/scanner.cpp rename to src/parsers/util/scanner.cpp diff --git a/src/parser_util/scanner.h b/src/parsers/util/scanner.h similarity index 100% rename from src/parser_util/scanner.h rename to src/parsers/util/scanner.h diff --git a/src/parser_util/simple_parser.cpp b/src/parsers/util/simple_parser.cpp similarity index 100% rename from src/parser_util/simple_parser.cpp rename to src/parsers/util/simple_parser.cpp diff --git a/src/parser_util/simple_parser.h b/src/parsers/util/simple_parser.h similarity index 100% rename from src/parser_util/simple_parser.h rename to src/parsers/util/simple_parser.h From 276befb78e70e08b64b571989d35f460ca3a9816 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 26 Oct 2012 21:50:08 -0700 Subject: [PATCH 12/35] fixing eol Signed-off-by: Leonardo de Moura --- scripts/mk_make.py | 1 + scripts/mk_util.py | 45 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/scripts/mk_make.py b/scripts/mk_make.py index e37013745..dcd30958b 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -9,6 +9,7 @@ from mk_util import * parse_options() +check_eol() add_lib('util', []) add_lib('polynomial', ['util'], 'math/polynomial') diff --git a/scripts/mk_util.py b/scripts/mk_util.py index d939e915c..edc35577b 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -13,6 +13,7 @@ import getopt import sys import shutil from mk_exception import * +from fnmatch import fnmatch BUILD_DIR='build' REV_BUILD_DIR='..' @@ -26,6 +27,48 @@ ONLY_MAKEFILES = False PYTHON_DIR=None VS_PROJ = False +def is_cr_lf(fname): + # Check whether text files use cr/lf + f = open(fname, 'r') + line = f.readline() + sz = len(line) + return sz >= 2 and line[sz-2] == '\r' and line[sz-1] == '\n' + +# dos2unix in python +# cr/lf --> lf +def dos2unix(fname): + if is_cr_lf(fname): + fin = open(fname, 'r') + fname_new = '%s.new' % fname + fout = open(fname_new, 'w') + for line in fin: + line = line.rstrip('\r\n') + fout.write(line) + fout.write('\n') + fin.close() + fout.close() + shutil.move(fname_new, fname) + if is_verbose(): + print "dos2unix '%s'" % fname + +def dos2unix_tree_core(pattern, dir, files): + for filename in files: + if fnmatch(filename, pattern): + fname = os.path.join(dir, filename) + if not os.path.isdir(fname): + dos2unix(fname) + +def dos2unix_tree(): + os.path.walk('src', dos2unix_tree_core, '*') + +def check_eol(): + if not IS_WINDOW: + # Linux/OSX/BSD check if the end-of-line is cr/lf + if is_cr_lf('LICENSE.txt'): + if is_verbose(): + print "Fixing end of line..." + dos2unix_tree() + if os.name == 'nt': IS_WINDOW=True # Visual Studio already displays the files being compiled @@ -81,7 +124,7 @@ def parse_options(): VS_PROJ = True else: raise MKException("Invalid command line option '%s'" % opt) - + # Return a list containing a file names included using '#include' in # the given C/C++ file named fname. def extract_c_includes(fname): From 946a06cddbe4d451ee187a2080548c985f75b77f Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sat, 27 Oct 2012 00:56:27 -0700 Subject: [PATCH 13/35] fixed configure.ac, now fails if gcc is not installed Signed-off-by: Leonardo de Moura --- configure.ac | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 73deedc73..c3a5563e8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,6 @@ AC_INIT([z3], [4.2]) +AC_CONFIG_SRCDIR(src/util/util.cpp) +AC_PREFIX_DEFAULT(/usr) ################### # @@ -80,7 +82,12 @@ fi # ################### # Sets CXX -AC_PROG_CXX(g++) +AC_LANG([C++]) +AC_PROG_CXX(g++ false) +AC_PROG_CC +if test $CXX = "false"; then + AC_MSG_ERROR([C++ compiler was not found]) +fi AC_PROG_MAKE_SET From 3cddd6977b753ed97b3734cdf34ba99134cfe029 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sat, 27 Oct 2012 20:22:51 -0700 Subject: [PATCH 14/35] Added make install/uninstall Signed-off-by: Leonardo de Moura --- {src/bindings => examples}/python/example.py | 0 scripts/config-debug.mk.in | 2 +- scripts/config-release.mk.in | 2 +- scripts/mk_make.py | 12 +- scripts/mk_util.py | 149 +++++++++++++++---- scripts/update_api.py | 4 +- 6 files changed, 130 insertions(+), 39 deletions(-) rename {src/bindings => examples}/python/example.py (100%) diff --git a/src/bindings/python/example.py b/examples/python/example.py similarity index 100% rename from src/bindings/python/example.py rename to examples/python/example.py diff --git a/scripts/config-debug.mk.in b/scripts/config-debug.mk.in index ce2ba3837..63ca284e0 100644 --- a/scripts/config-debug.mk.in +++ b/scripts/config-debug.mk.in @@ -1,5 +1,5 @@ - +PREFIX=@prefix@ CXX=@CXX@ CXXFLAGS=@CPPFLAGS@ @CXXFLAGS@ -DZ3DEBUG -D_TRACE -c -g -Wall -fopenmp -msse -msse2 -mfpmath=sse CXX_OUT_FLAG=-o diff --git a/scripts/config-release.mk.in b/scripts/config-release.mk.in index 903f50f58..7321367ba 100644 --- a/scripts/config-release.mk.in +++ b/scripts/config-release.mk.in @@ -1,5 +1,5 @@ - +PREFIX=@prefix@ CXX=@CXX@ CXXFLAGS=@CPPFLAGS@ @CXXFLAGS@ -c -O3 -fomit-frame-pointer -fopenmp -msse -msse2 -mfpmath=sse CXX_OUT_FLAG=-o diff --git a/scripts/mk_make.py b/scripts/mk_make.py index 5d73e735e..2f00ee88c 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -61,13 +61,17 @@ add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', add_lib('portfolio', ['smtlogic_tactics', 'ufbv_tactic', 'fpa', 'aig', 'muz_qe', 'sls_tactic', 'subpaving_tactic'], 'tactic/portfolio') # TODO: delete SMT 1.0 frontend add_lib('smtparser', ['portfolio'], 'parsers/smt') -add_lib('api', ['portfolio', 'user_plugin', 'smtparser']) +add_lib('api', ['portfolio', 'user_plugin', 'smtparser'], + includes2install=['z3.h', 'z3_api.h', 'z3_v1.h', 'z3_macros.h']) add_exe('shell', ['api', 'sat', 'extra_cmds'], exe_name='z3') -add_exe('test', ['api', 'fuzzing'], exe_name='test-z3') +add_exe('test', ['api', 'fuzzing'], exe_name='test-z3', install=False) API_files = ['z3_api.h'] -add_dll('api_dll', ['api', 'sat', 'extra_cmds'], 'api/dll', reexports=['api'], dll_name='libz3', export_files=API_files) +add_dll('api_dll', ['api', 'sat', 'extra_cmds'], 'api/dll', + reexports=['api'], + dll_name='libz3', + export_files=API_files) add_dot_net_dll('dotnet', ['api_dll'], 'bindings/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties') -set_python_dir('bindings/python') +set_z3py_dir('bindings/python') update_version(4, 2, 0, 0) mk_auto_src() diff --git a/scripts/mk_util.py b/scripts/mk_util.py index edc35577b..8add1c2fc 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -14,7 +14,10 @@ import sys import shutil from mk_exception import * from fnmatch import fnmatch +import distutils.sysconfig +import compileall +PYTHON_PACKAGE_DIR=distutils.sysconfig.get_python_lib() BUILD_DIR='build' REV_BUILD_DIR='..' SRC_DIR='src' @@ -24,8 +27,9 @@ DEBUG_MODE=False SHOW_CPPS = True VS_X64 = False ONLY_MAKEFILES = False -PYTHON_DIR=None +Z3PY_SRC_DIR=None VS_PROJ = False +TRACE = False def is_cr_lf(fname): # Check whether text files use cr/lf @@ -87,20 +91,22 @@ def display_help(): print " -m, --makefiles generate only makefiles." print " -c, --showcpp display file .cpp file names before invoking compiler." print " -v, --vsproj generate Visual Studio Project Files." + print " -t, --trace enable tracing in release mode." exit(0) # Parse configuration option for mk_make script def parse_options(): - global VERBOSE, DEBUG_MODE, IS_WINDOW, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ - options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:dsxhmcv', ['build=', - 'debug', - 'silent', - 'x64', - 'help', - 'makefiles', - 'showcpp', - 'vsproj' - ]) + global VERBOSE, DEBUG_MODE, IS_WINDOW, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE + options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:dsxhmcvt', ['build=', + 'debug', + 'silent', + 'x64', + 'help', + 'makefiles', + 'showcpp', + 'vsproj', + 'trace' + ]) for opt, arg in options: if opt in ('-b', '--build'): if arg == 'src': @@ -122,6 +128,8 @@ def parse_options(): SHOW_CPPS = True elif opt in ('-v', '--vsproj'): VS_PROJ = True + elif opt in ('-t', '--trace'): + TRACE = True else: raise MKException("Invalid command line option '%s'" % opt) @@ -165,12 +173,12 @@ def set_build_dir(d): BUILD_DIR = d REV_BUILD_DIR = reverse_path(d) -def set_python_dir(p): - global SRC_DIR, PYTHON_DIR +def set_z3py_dir(p): + global SRC_DIR, Z3PY_SRC_DIR full = '%s/%s' % (SRC_DIR, p) if not os.path.exists(full): raise MKException("Python bindings directory '%s' does not exist" % full) - PYTHON_DIR = full + Z3PY_SRC_DIR = full if VERBOSE: print "Python bindinds directory was detected." @@ -193,8 +201,8 @@ def get_component(name): return _Name2Component[name] # Return the directory where the python bindings are located. -def get_python_dir(): - return PYTHON_DIR +def get_z3py_dir(): + return Z3PY_SRC_DIR # Return true if in verbose mode def is_verbose(): @@ -290,7 +298,14 @@ class Component: out.write('\n') if SHOW_CPPS: out.write('\t@echo %s/%s\n' % (self.src_dir, cppfile)) - out.write('\t@$(CXX) $(CXXFLAGS) $(%s) $(CXX_OUT_FLAG)%s %s\n' % (include_defs, objfile, srcfile)) + # TRACE is enabled in debug mode by default + trace_opt = '' + if TRACE and not DEBUG_MODE: + if IS_WINDOW: + trace_opt = '/D _TRACE' + else: + trace_opt = '-D _TRACE' + out.write('\t@$(CXX) $(CXXFLAGS) %s $(%s) $(CXX_OUT_FLAG)%s %s\n' % (trace_opt, include_defs, objfile, srcfile)) def mk_makefile(self, out): include_defs = mk_fresh_name('includes') @@ -318,9 +333,16 @@ class Component: def require_def_file(self): return False + def mk_install(self, out): + return + + def mk_uninstall(self, out): + return + class LibComponent(Component): - def __init__(self, name, path, deps): + def __init__(self, name, path, deps, includes2install): Component.__init__(self, name, path, deps) + self.includes2install = includes2install def mk_makefile(self, out): Component.mk_makefile(self, out) @@ -343,6 +365,14 @@ class LibComponent(Component): out.write('\n') out.write('%s: %s\n\n' % (self.name, libfile)) + def mk_install(self, out): + for include in self.includes2install: + out.write('\t@cp %s/%s $(PREFIX)/include/%s\n' % (self.to_src_dir, include, include)) + + def mk_uninstall(self, out): + for include in self.includes2install: + out.write('\t@rm -f $(PREFIX)/include/%s\n' % include) + # Auxiliary function for sort_components def comp_components(c1, c2): id1 = get_component(c1).id @@ -354,11 +384,12 @@ def sort_components(cnames): return sorted(cnames, cmp=comp_components) class ExeComponent(Component): - def __init__(self, name, exe_name, path, deps): + def __init__(self, name, exe_name, path, deps, install): Component.__init__(self, name, path, deps) if exe_name == None: exe_name = name self.exe_name = exe_name + self.install = install def mk_makefile(self, out): Component.mk_makefile(self, out) @@ -395,14 +426,26 @@ class ExeComponent(Component): def main_component(self): return True + def mk_install(self, out): + if self.install: + exefile = '%s$(EXE_EXT)' % self.exe_name + out.write('\t@cp %s $(PREFIX)/bin/%s\n' % (exefile, exefile)) + + def mk_uninstall(self, out): + if self.install: + exefile = '%s$(EXE_EXT)' % self.exe_name + out.write('\t@rm -f $(PREFIX)/bin/%s\n' % exefile) + + class DLLComponent(Component): - def __init__(self, name, dll_name, path, deps, export_files, reexports): + def __init__(self, name, dll_name, path, deps, export_files, reexports, install): Component.__init__(self, name, path, deps) if dll_name == None: dll_name = name self.dll_name = dll_name self.export_files = export_files self.reexports = reexports + self.install = install def mk_makefile(self, out): Component.mk_makefile(self, out) @@ -452,6 +495,18 @@ class DLLComponent(Component): def require_def_file(self): return IS_WINDOW and self.export_files + def mk_install(self, out): + if self.install: + dllfile = '%s$(SO_EXT)' % self.dll_name + out.write('\t@cp %s $(PREFIX)/lib/%s\n' % (dllfile, dllfile)) + out.write('\t@cp %s %s/%s\n' % (dllfile, PYTHON_PACKAGE_DIR, dllfile)) + + def mk_uninstall(self, out): + if self.install: + dllfile = '%s$(SO_EXT)' % self.dll_name + out.write('\t@rm -f $(PREFIX)/lib/%s\n' % dllfile) + out.write('\t@rm -f %s/%s\n' % (PYTHON_PACKAGE_DIR, dllfile)) + class DotNetDLLComponent(Component): def __init__(self, name, dll_name, path, deps, assembly_info_dir): Component.__init__(self, name, path, deps) @@ -508,16 +563,16 @@ def reg_component(name, c): if VERBOSE: print "New component: '%s'" % name -def add_lib(name, deps=[], path=None): - c = LibComponent(name, path, deps) +def add_lib(name, deps=[], path=None, includes2install=[]): + c = LibComponent(name, path, deps, includes2install) reg_component(name, c) -def add_exe(name, deps=[], path=None, exe_name=None): - c = ExeComponent(name, exe_name, path, deps) +def add_exe(name, deps=[], path=None, exe_name=None, install=True): + c = ExeComponent(name, exe_name, path, deps, install) reg_component(name, c) -def add_dll(name, deps=[], path=None, dll_name=None, export_files=[], reexports=[]): - c = DLLComponent(name, dll_name, path, deps, export_files, reexports) +def add_dll(name, deps=[], path=None, dll_name=None, export_files=[], reexports=[], install=True): + c = DLLComponent(name, dll_name, path, deps, export_files, reexports, install) reg_component(name, c) def add_dot_net_dll(name, deps=[], path=None, dll_name=None, assembly_info_dir=None): @@ -543,6 +598,30 @@ def cp_config_mk(): else: shutil.copyfile('scripts/config-release.mk', '%s/config.mk' % BUILD_DIR) +def mk_install(out): + out.write('install:\n') + out.write('\t@mkdir -p $(PREFIX)/bin\n') + out.write('\t@mkdir -p $(PREFIX)/include\n') + out.write('\t@mkdir -p $(PREFIX)/lib\n') + for c in _Components: + c.mk_install(out) + compileall.compile_dir(Z3PY_SRC_DIR, force=1) + for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(Z3PY_SRC_DIR)): + os.rename('%s/%s' % (Z3PY_SRC_DIR, pyc), '%s/%s' % (BUILD_DIR, pyc)) + if is_verbose(): + print "Generated '%s'" % pyc + out.write('\t@cp z3*.pyc %s\n' % PYTHON_PACKAGE_DIR) + out.write('\t@echo Z3 was successfully installed.\n') + out.write('\n') + +def mk_uninstall(out): + out.write('uninstall:\n') + for c in _Components: + c.mk_uninstall(out) + out.write('\t@rm -f %s/z3*.pyc\n' % PYTHON_PACKAGE_DIR) + out.write('\t@echo Z3 was successfully uninstalled.\n') + out.write('\n') + # Generate the Z3 makefile def mk_makefile(): mk_dir(BUILD_DIR) @@ -557,13 +636,21 @@ def mk_makefile(): for c in _Components: if c.main_component(): out.write(' %s' % c.name) - out.write('\n\n') + out.write('\n\t@echo Z3 was successfully built.\n') + out.write("\t@echo Use the following command to install Z3 at prefix $(PREFIX).\n") + out.write('\t@echo "\\tsudo make install"\n') # Generate components for c in _Components: c.mk_makefile(out) + # Generate install/uninstall rules if not WINDOWS + if not IS_WINDOW: + mk_install(out) + mk_uninstall(out) # Finalize if VERBOSE: print "Makefile was successfully generated." + if not IS_WINDOW: + print " python packages dir:", PYTHON_PACKAGE_DIR if DEBUG_MODE: print " compilation mode: Debug" else: @@ -796,8 +883,8 @@ def mk_bindings(api_files): # Extract enumeration types from API files, and add python definitions. def mk_z3consts_py(api_files): - if PYTHON_DIR == None: - raise MKException("You must invoke set_python_dir(path):") + if Z3PY_SRC_DIR == None: + raise MKException("You must invoke set_z3py_dir(path):") blank_pat = re.compile("^ *$") comment_pat = re.compile("^ *//.*$") @@ -806,7 +893,7 @@ def mk_z3consts_py(api_files): openbrace_pat = re.compile("{ *") closebrace_pat = re.compile("}.*;") - z3consts = open('%s/z3consts.py' % PYTHON_DIR, 'w') + z3consts = open('%s/z3consts.py' % Z3PY_SRC_DIR, 'w') z3consts.write('# Automatically generated file\n\n') api_dll = get_component('api_dll') @@ -869,7 +956,7 @@ def mk_z3consts_py(api_files): idx = idx + 1 linenum = linenum + 1 if VERBOSE: - print "Generated '%s'" % ('%s/z3consts.py' % PYTHON_DIR) + print "Generated '%s'" % ('%s/z3consts.py' % Z3PY_SRC_DIR) # Extract enumeration types from z3_api.h, and add .Net definitions diff --git a/scripts/update_api.py b/scripts/update_api.py index 90c7ebe0c..a073596a8 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -27,7 +27,7 @@ dotnet_dir = get_component('dotnet').src_dir log_h = open('%s/api_log_macros.h' % api_dir, 'w') log_c = open('%s/api_log_macros.cpp' % api_dir, 'w') exe_c = open('%s/api_commands.cpp' % api_dir, 'w') -core_py = open('%s/z3core.py' % get_python_dir(), 'w') +core_py = open('%s/z3core.py' % get_z3py_dir(), 'w') dotnet_fileout = '%s/Native.cs' % dotnet_dir ## log_h.write('// Automatically generated file\n') @@ -671,5 +671,5 @@ if is_verbose(): print "Generated '%s'" % ('%s/api_log_macros.h' % api_dir) print "Generated '%s'" % ('%s/api_log_macros.cpp' % api_dir) print "Generated '%s'" % ('%s/api_commands.cpp' % api_dir) - print "Generated '%s'" % ('%s/z3core.py' % get_python_dir()) + print "Generated '%s'" % ('%s/z3core.py' % get_z3py_dir()) print "Generated '%s'" % ('%s/Native.cs' % dotnet_dir) From 3f6e3e543f7e840b52a3830280d79fd49f959b7a Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sat, 27 Oct 2012 22:07:27 -0700 Subject: [PATCH 15/35] fixed compilation errors reported by g++ 4.7.1 --- src/util/interval_skip_list.h | 102 +++++++++++++++++----------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/util/interval_skip_list.h b/src/util/interval_skip_list.h index 369d90bd3..66ae21d5b 100644 --- a/src/util/interval_skip_list.h +++ b/src/util/interval_skip_list.h @@ -318,7 +318,7 @@ protected: \brief Return true if the two entries (that satisfy lt(e1, e2)) can be merged. */ bool can_be_merged(entry const & e1, entry const & e2) const { - return val_eq(e1.val(), e2.val()) && eq(succ(e1.end_key()), e2.begin_key()); + return this->val_eq(e1.val(), e2.val()) && this->eq(this->succ(e1.end_key()), e2.begin_key()); } /** @@ -334,9 +334,9 @@ protected: entry & next_entry = next_bucket->get(0); if (can_be_merged(curr_entry, next_entry)) { curr_entry.set_end_key(next_entry.end_key()); - del_entry(m, next_bucket, 0); // del_entry invokes dec_ref_eh + this->del_entry(m, next_bucket, 0); // del_entry invokes dec_ref_eh if (next_bucket->empty()) - del_bucket(m, next_bucket, pred_vect); + this->del_bucket(m, next_bucket, pred_vect); } } } @@ -355,7 +355,7 @@ protected: entry & next_entry = bt->get(idx+1); if (can_be_merged(curr_entry, next_entry)) { curr_entry.set_end_key(next_entry.end_key()); - del_entry(m, bt, idx+1); // del_entry invokes dec_ref_eh + this->del_entry(m, bt, idx+1); // del_entry invokes dec_ref_eh } } } @@ -371,7 +371,7 @@ protected: entry & prev_entry = bt->get(idx-1); if (can_be_merged(prev_entry, curr_entry)) { prev_entry.set_end_key(curr_entry.end_key()); - del_entry(m, bt, idx); // del_entry invokes dec_ref_eh + this->del_entry(m, bt, idx); // del_entry invokes dec_ref_eh } } @@ -439,7 +439,7 @@ protected: int mid = low + ((high - low) / 2); SASSERT(mid < static_cast(bt->size())); entry & mid_entry = bt->get(mid); - if (gt(k, mid_entry.end_key())) { + if (this->gt(k, mid_entry.end_key())) { low = mid + 1; if (low > high) { // mid entry must be deleted since k > mid_entry.end_key(). @@ -461,7 +461,7 @@ protected: SASSERT(contains(mid_entry, k)); if (lt(k, mid_entry.end_key())) { TRACE("del_entries_upto_bug", tout << "exit 3) mid: " << mid << "\n"; this->display(tout, mid_entry); tout << "\n";); - mid_entry.set_begin_key(succ(k)); + mid_entry.set_begin_key(this->succ(k)); SASSERT(mid < static_cast(bt->size())); // Reason: loop invariant return del_entries(m, bt, s_idx, mid); } @@ -486,14 +486,14 @@ protected: del_last_entries_upto(m, bt, 0, k); return; } - else if (eq(k, bt_last_key)) { - del_bucket(m, bt, pred_vect); + else if (this->eq(k, bt_last_key)) { + this->del_bucket(m, bt, pred_vect); return; } else { - SASSERT(gt(k, bt_last_key)); + SASSERT(this->gt(k, bt_last_key)); bucket * next = bt->get_next(0); - del_bucket(m, bt, pred_vect); + this->del_bucket(m, bt, pred_vect); bt = next; // continue deleting... } @@ -524,7 +524,7 @@ protected: key const & bt_last_key = last_key(bt); TRACE("del_entries_upto_bug", tout << "bt_last_key: " << bt_last_key << "\n";); - if (lt(k, bt_last_key)) { + if (this->lt(k, bt_last_key)) { return del_last_entries_upto(m, bt, 0, k); } else { @@ -533,10 +533,10 @@ protected: this->dec_ref(m, bt); // REMARK: the slot 0 will be reused, but the element there is gone. bt->set_size(1); - if (gt(k, bt_last_key)) { + if (this->gt(k, bt_last_key)) { bucket * next = bt->get_next(0); if (next != 0) { - update_predecessor_vector(pred_vect, bt, next_pred_vect); + this->update_predecessor_vector(pred_vect, bt, next_pred_vect); del_entries_upto_loop(m, next, k, next_pred_vect); } } @@ -544,7 +544,7 @@ protected: } else { bucket * next = bt->get_next(0); - del_bucket(m, bt, pred_vect); // it will invoke dec_ref_eh for all values in bt. + this->del_bucket(m, bt, pred_vect); // it will invoke dec_ref_eh for all values in bt. // pred_vect does not need to be updated since it contains the predecessors of // bt, since bt was deleted they are now the predecessors of its successor. if (next != 0) { @@ -592,7 +592,7 @@ protected: return del_last_entries_upto(m, bt, s_idx, k); } else { - if (gt(k, bt_last_key)) { + if (this->gt(k, bt_last_key)) { del_entries_upto_loop(m, bt->get_next(0), k, pred_vect); } if (Traits::ref_count) { @@ -639,14 +639,14 @@ protected: merge_next_if_possible(m, bt, 0, next_pred_vect); } else { - update_predecessor_vector(pred_vect, bt); + this->update_predecessor_vector(pred_vect, bt); merge_next_if_possible(m, bt, 0, pred_vect); } return; } // check if can merge with first entry in the bucket. entry & fe = bt->first_entry(); - if (val_eq(fe.val(), v) && eq(fe.begin_key(), succ(e))) { + if (this->val_eq(fe.val(), v) && this->eq(fe.begin_key(), this->succ(e))) { // can merge fe.set_begin_key(b); // A new reference to v was not created. So, we must invoke dec_ref_eh since we increased the counter above. @@ -657,15 +657,15 @@ protected: if (bt->size() == bt->capacity()) { if (bt->capacity() < Traits::max_capacity) { SASSERT(this->first_bucket() == bt && this->first_bucket()->get_next(0) == 0); - expand_first_bucket(m); + this->expand_first_bucket(m); bt = this->first_bucket(); } else { // there is no space - splice(m, bt, pred_vect); + this->splice(m, bt, pred_vect); } } - open_space(bt, 0); + this->open_space(bt, 0); set_entry(bt, 0, b, e, v); // Reference to v was stored, and inc_ref_eh was invoked above. SASSERT(!can_be_merged(bt->get(0), bt->get(1))); } @@ -697,17 +697,17 @@ protected: // there is no space if (bt->capacity() < Traits::max_capacity) { SASSERT(this->first_bucket() == bt && this->first_bucket()->get_next(0) == 0); - expand_first_bucket(m); + this->expand_first_bucket(m); bt = this->first_bucket(); // there is no need to update pred_vect, since the list contains only one bucket. } else { - splice(m, bt, pred_vect); + this->splice(m, bt, pred_vect); bucket * new_next = bt->get_next(0); SASSERT(bt->size() == bt->capacity()/2); if (idx == bt->capacity()/2) { entry & bt_last_entry = bt->last_entry(); - if (val_eq(bt_last_entry.val(), v) && eq(bt_last_entry.end_key(), pred(b))) { + if (this->val_eq(bt_last_entry.val(), v) && this->eq(bt_last_entry.end_key(), this->pred(b))) { // merged with the last key of bt bt_last_entry.set_end_key(e); // A new reference to v was not created. So, we must invoke dec_ref_eh since we increased the counter above. @@ -715,7 +715,7 @@ protected: return; } entry & new_next_first_entry = new_next->first_entry(); - if (val_eq(new_next_first_entry.val(), v) && eq(new_next_first_entry.begin_key(), succ(e))) { + if (this->val_eq(new_next_first_entry.val(), v) && this->eq(new_next_first_entry.begin_key(), this->succ(e))) { // merged with the first key of new_next new_next_first_entry.set_begin_key(b); // A new reference to v was not created. So, we must invoke dec_ref_eh since we increased the counter above. @@ -731,12 +731,12 @@ protected: idx -= bt->capacity()/2; SASSERT(idx > 0); bt = new_next; - update_predecessor_vector(pred_vect, bt); + this->update_predecessor_vector(pred_vect, bt); } } } SASSERT(idx > 0); - open_space(bt, idx); + this->open_space(bt, idx); set_entry(bt, idx, b, e, v); // Reference to v was stored, and inc_ref_eh was invoked above. merge_next_if_possible(m, bt, idx, pred_vect); merge_prev_if_possible(m, bt, idx); @@ -759,7 +759,7 @@ protected: for (;;) { int mid = low + ((high - low) / 2); entry & mid_entry = bt->get(mid); - if (gt(b, mid_entry.end_key())) { + if (this->gt(b, mid_entry.end_key())) { low = mid + 1; if (low > high) { // insert after mid_entry since b > mid_entry.end_key(). @@ -779,8 +779,8 @@ protected: else { SASSERT(contains(mid_entry, b)); TRACE("insert_inside_bug", tout << "insert_inside:\n"; this->display(tout, bt);); - if (val_eq(mid_entry.val(), v)) { - if (gt(e, mid_entry.end_key())) { + if (this->val_eq(mid_entry.val(), v)) { + if (this->gt(e, mid_entry.end_key())) { // No need to create space. // We did not create a new reference to v. mid_entry.set_end_key(e); @@ -790,8 +790,8 @@ protected: } } else { - if (gt(b, mid_entry.begin_key())) { - if (lt(e, mid_entry.end_key())) { + if (this->gt(b, mid_entry.begin_key())) { + if (this->lt(e, mid_entry.end_key())) { // New interval is the middle of existing interval // We must INVOKE add_ref_eh for mid_entry.val() and v. @@ -802,11 +802,11 @@ protected: if (bt->size() >= bt->capacity() - 1) { if (bt->capacity() < Traits::max_capacity) { SASSERT(this->first_bucket() == bt && this->first_bucket()->get_next(0) == 0); - expand_first_bucket(m); + this->expand_first_bucket(m); bt = this->first_bucket(); } else { - splice(m, bt, pred_vect); + this->splice(m, bt, pred_vect); int new_sz = bt->size(); bucket * new_next = bt->get_next(0); if (mid >= new_sz) { @@ -816,19 +816,19 @@ protected: } } } - open_2spaces(bt, mid); + this->open_2spaces(bt, mid); entry & mid1_entry = bt->get(mid); entry & new_entry = bt->get(mid+1); entry & mid2_entry = bt->get(mid+2); mid2_entry = mid1_entry; - mid1_entry.set_end_key(pred(b)); + mid1_entry.set_end_key(this->pred(b)); new_entry.set_begin_key(b); new_entry.set_end_key(e); new_entry.set_val(v); - mid2_entry.set_begin_key(succ(e)); + mid2_entry.set_begin_key(this->succ(e)); } else { - mid_entry.set_end_key(pred(b)); + mid_entry.set_end_key(this->pred(b)); insert_at(m, bt, mid+1, b, e, v, pred_vect); } } @@ -864,7 +864,7 @@ protected: for (;;) { int mid = low + ((high - low) / 2); entry & mid_entry = bt->get(mid); - if (gt(b, mid_entry.end_key())) { + if (this->gt(b, mid_entry.end_key())) { low = mid + 1; if (low > high) { // insert after mid_entry since b > mid_entry.end_key(). @@ -872,7 +872,7 @@ protected: return; } } - else if (lt(b, mid_entry.begin_key())) { + else if (this->lt(b, mid_entry.begin_key())) { high = mid - 1; if (low > high) { // insert before mid_entry since b < mid_entry.begin_key(). @@ -883,8 +883,8 @@ protected: } else { SASSERT(contains(mid_entry, b)); - if (gt(b, mid_entry.begin_key())) { - if (lt(e, mid_entry.end_key())) { + if (this->gt(b, mid_entry.begin_key())) { + if (this->lt(e, mid_entry.end_key())) { // The removed interval is inside of an existing interval. // mid_entry will be split in two. So, we must invoke add_ref_eh for mid_entry.val() @@ -894,12 +894,12 @@ protected: if (bt->size() == bt->capacity()) { if (bt->capacity() < Traits::max_capacity) { SASSERT(this->first_bucket() == bt && this->first_bucket()->get_next(0) == 0); - expand_first_bucket(m); + this->expand_first_bucket(m); bt = this->first_bucket(); SASSERT(bt->size() < bt->capacity()); } else { - splice(m, bt, pred_vect); + this->splice(m, bt, pred_vect); if (mid >= static_cast(bt->size())) { // mid_entry moved to new (successor) bucket mid -= bt->size(); @@ -907,14 +907,14 @@ protected: } } } - open_space(bt, mid); + this->open_space(bt, mid); entry & mid1_entry = bt->get(mid); entry & mid2_entry = bt->get(mid+1); - mid1_entry.set_end_key(pred(b)); - mid2_entry.set_begin_key(succ(e)); + mid1_entry.set_end_key(this->pred(b)); + mid2_entry.set_begin_key(this->succ(e)); } else { - mid_entry.set_end_key(pred(b)); + mid_entry.set_end_key(this->pred(b)); del_entries_upto(m, bt, mid+1, e, pred_vect); } } @@ -1052,7 +1052,7 @@ public: SASSERT(this->first_bucket() == next); insert_begin(m, next, b, e, v, pred_vect); } - else if (next == 0 || gt(first_key(next), b)) { + else if (next == 0 || this->gt(first_key(next), b)) { insert_inside(m, curr, b, e, v, pred_vect); } else { @@ -1065,7 +1065,7 @@ public: // check if we can merge with last entry of curr entry & curr_last_entry = curr->last_entry(); - if (val_eq(curr_last_entry.val(), v) && eq(curr_last_entry.end_key(), pred(b))) { + if (this->val_eq(curr_last_entry.val(), v) && this->eq(curr_last_entry.end_key(), this->pred(b))) { // No new reference to v was create, we don't need to invok inc_ref_eh curr_last_entry.set_end_key(e); del_entries_upto(m, next, e, pred_vect, 0); @@ -1202,7 +1202,7 @@ public: SASSERT(next != 0); remove_begin(m, next, b, e, pred_vect); } - else if (next == 0 || gt(first_key(next), b)) { + else if (next == 0 || this->gt(first_key(next), b)) { remove_inside(m, curr, b, e, pred_vect); } else { From 9fb25e7708d0f83e16acecbb324dc50bbadade2b Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sat, 27 Oct 2012 22:32:50 -0700 Subject: [PATCH 16/35] fixed more compilation errors reported by g++ 4.7.1 Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 2 +- src/test/permutation.cpp | 4 ++-- src/util/interval_skip_list.h | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8add1c2fc..998d000c7 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -638,7 +638,7 @@ def mk_makefile(): out.write(' %s' % c.name) out.write('\n\t@echo Z3 was successfully built.\n') out.write("\t@echo Use the following command to install Z3 at prefix $(PREFIX).\n") - out.write('\t@echo "\\tsudo make install"\n') + out.write('\t@echo " sudo make install"\n') # Generate components for c in _Components: c.mk_makefile(out) diff --git a/src/test/permutation.cpp b/src/test/permutation.cpp index 0fa3fcaff..d5929b6c0 100644 --- a/src/test/permutation.cpp +++ b/src/test/permutation.cpp @@ -20,8 +20,6 @@ Revision History: #include"util.h" #include"vector.h" -using namespace std; - void apply_permutation_copy(unsigned sz, unsigned const * src, unsigned const * p, unsigned * target) { for (unsigned i = 0; i < sz; i++) { target[i] = src[p[i]]; @@ -29,6 +27,7 @@ void apply_permutation_copy(unsigned sz, unsigned const * src, unsigned const * } static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) { +#if 0 unsigned_vector data; unsigned_vector p; unsigned_vector new_data; @@ -51,6 +50,7 @@ static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) { for (unsigned i = 0; i < 0; i++) SASSERT(data[i] == new_data[i]); } +#endif } void tst_permutation() { diff --git a/src/util/interval_skip_list.h b/src/util/interval_skip_list.h index 66ae21d5b..04a7d6571 100644 --- a/src/util/interval_skip_list.h +++ b/src/util/interval_skip_list.h @@ -156,7 +156,7 @@ protected: \brief Return true if the given key \c k is in the entry \c e. That is, k \in [e.begin_key(), e.end_key()]. */ - bool contains(entry const & e, key const & k) const { return leq(e.begin_key(), k) && leq(k, e.end_key()); } + bool contains(entry const & e, key const & k) const { return this->leq(e.begin_key(), k) && this->leq(k, e.end_key()); } /** \brief Return true if the given key \c k is in the entry \c e. That is, @@ -193,7 +193,7 @@ protected: for (;;) { int mid = low + ((high - low) / 2); entry const & mid_entry = bt->get(mid); - if (gt(k, mid_entry.end_key())) { + if (this->gt(k, mid_entry.end_key())) { low = mid + 1; if (low > high) { idx = static_cast(mid) + 1; @@ -1273,7 +1273,7 @@ public: --i; for (;;) { next = curr->get_next(i); - if (next != 0 && leq(first_key(next), k)) { + if (next != 0 && this->leq(first_key(next), k)) { TRACE("interval_skip_list", tout << "next_bucket(" << k << "), i: " << i << " skipping #" << get_bucket_idx(curr); tout << ", moving to: #" << get_bucket_idx(next) << "\n"; this->display(tout, next);); curr = next; @@ -1427,11 +1427,11 @@ public: for (; it1 != end1 && it2 != end2; it1++, it2++) { entry const & e1 = *it1; entry const & e2 = *it2; - if (!eq(e1.begin_key(), e2.begin_key())) + if (!this->eq(e1.begin_key(), e2.begin_key())) return false; - if (!eq(e1.end_key(), e2.end_key())) + if (!this->eq(e1.end_key(), e2.end_key())) return false; - if (!val_eq(e1.val(), e2.val())) + if (!this->val_eq(e1.val(), e2.val())) return false; } return true; @@ -1459,8 +1459,8 @@ public: entry & curr = const_cast(*it); value const & old_val = curr.val(); value new_val = f(old_val); - inc_ref(m, new_val); - dec_ref(m, old_val); + this->inc_ref(m, new_val); + this->dec_ref(m, old_val); curr.set_val(new_val); } SASSERT(check_invariant()); @@ -1599,7 +1599,7 @@ private: */ void move_js(join_state & js, key const & k) const { SASSERT(!js.done()); - if (leq(k, js.tail())) { + if (this->leq(k, js.tail())) { // We can't skip the current entry, because k in inside it. // So, we just update the head. js.m_head = k; From ae71a4d5145f74f1ebe00ac7375c3c3d653d694a Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sat, 27 Oct 2012 22:51:03 -0700 Subject: [PATCH 17/35] fixed: missing library, more compilation errors in debug mode reported by g++ 4.7.1 Signed-off-by: Leonardo de Moura --- configure.ac | 3 +++ scripts/config-debug.mk.in | 4 ++-- scripts/config-release.mk.in | 4 ++-- src/util/interval_skip_list.h | 40 +++++++++++++++++------------------ 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index c3a5563e8..e111a31ce 100644 --- a/configure.ac +++ b/configure.ac @@ -115,6 +115,7 @@ host_os=`uname -s` AS_IF([test "$host_os" = "Darwin"], [ PLATFORM=osx SO_EXT=.dylib + LDFLAGS= SLIBFLAGS="-dynamiclib -fopenmp" SLIBEXTRAFLAGS="" COMP_VERSIONS="-compatibility_version \$(Z3_VERSION) -current_version \$(Z3_VERSION)" @@ -122,6 +123,7 @@ AS_IF([test "$host_os" = "Darwin"], [ ], [test "$host_os" = "Linux"], [ PLATFORM=linux SO_EXT=.so + LDFLAGS=-lrt SLIBFLAGS="-shared -fopenmp" SLIBEXTRAFLAGS= COMP_VERSIONS= @@ -140,6 +142,7 @@ AS_IF([test "$host_os" = "Darwin"], [ AC_MSG_ERROR([Unknown host platform: $host_os]) ]) AC_SUBST(SLIBFLAGS) +AC_SUBST(LDFLAGS) AC_SUBST(SLIBEXTRAFLAGS) AC_SUBST(SO_EXT) diff --git a/scripts/config-debug.mk.in b/scripts/config-debug.mk.in index 63ca284e0..a7a473dae 100644 --- a/scripts/config-debug.mk.in +++ b/scripts/config-debug.mk.in @@ -10,10 +10,10 @@ AR_FLAGS=rcs AR_OUTFLAG= EXE_EXT= LINK=@CXX@ -LINK_FLAGS=-lpthread -fopenmp +LINK_FLAGS=-lpthread -fopenmp @LDFLAGS@ LINK_OUT_FLAG=-o SO_EXT=@SO_EXT@ SLINK=@CXX@ SLINK_FLAGS=@SLIBFLAGS@ SLINK_EXTRA_FLAGS=@SLIBEXTRAFLAGS@ -SLINK_OUT_FLAG=-o \ No newline at end of file +SLINK_OUT_FLAG=-o diff --git a/scripts/config-release.mk.in b/scripts/config-release.mk.in index 7321367ba..721c657df 100644 --- a/scripts/config-release.mk.in +++ b/scripts/config-release.mk.in @@ -10,10 +10,10 @@ AR_FLAGS=rcs AR_OUTFLAG= EXE_EXT= LINK=@CXX@ -LINK_FLAGS=-lpthread -fopenmp +LINK_FLAGS=-lpthread -fopenmp @LDFLAGS@ LINK_OUT_FLAG=-o SO_EXT=@SO_EXT@ SLINK=@CXX@ SLINK_FLAGS=@SLIBFLAGS@ SLINK_EXTRA_FLAGS=@SLIBEXTRAFLAGS@ -SLINK_OUT_FLAG=-o \ No newline at end of file +SLINK_OUT_FLAG=-o diff --git a/src/util/interval_skip_list.h b/src/util/interval_skip_list.h index 04a7d6571..7865e6ca5 100644 --- a/src/util/interval_skip_list.h +++ b/src/util/interval_skip_list.h @@ -277,7 +277,7 @@ protected: // the search_key must be in the current bucket, or in the first entry of the next bucket (if the next bucket is not 0). SASSERT(curr->empty() || lt(first_key(curr), k)); - SASSERT(next == 0 || geq(first_key(next), k)); + SASSERT(next == 0 || this->geq(first_key(next), k)); DEBUG_CODE({ if (UpdatePredVect && next != 0) for (unsigned i = 0; i < next->level(); i++) @@ -327,7 +327,7 @@ protected: \remark pred_vect contains the predecessors of the successor of bt. */ void merge_first_of_succ_if_possible(manager & m, bucket * bt, bucket * pred_vect[]) { - SASSERT(check_pred_vect(bt->get_next(0), pred_vect)); + SASSERT(this->check_pred_vect(bt->get_next(0), pred_vect)); bucket * next_bucket = bt->get_next(0); if (next_bucket != 0) { entry & curr_entry = bt->last_entry(); @@ -479,7 +479,7 @@ protected: \brief Keep deleting keys <= k in bt and its successors. */ void del_entries_upto_loop(manager & m, bucket * bt, key const & k, bucket * pred_vect []) { - SASSERT(check_pred_vect(bt, pred_vect)); + SASSERT(this->check_pred_vect(bt, pred_vect)); while (bt != 0) { key const & bt_last_key = last_key(bt); if (lt(k, bt_last_key)) { @@ -516,7 +516,7 @@ protected: */ template bool del_entries_upto(manager & m, bucket * bt, key const & k, bucket * pred_vect[], bucket * next_pred_vect[]) { - SASSERT(check_pred_vect(bt, pred_vect)); // pred_vect contains the predecessors of bt. + SASSERT(this->check_pred_vect(bt, pred_vect)); // pred_vect contains the predecessors of bt. if (lt(k, first_key(bt))) { // nothing to be done... return false; // didn't manage to recycle entry. @@ -566,7 +566,7 @@ protected: */ template bool del_entries_upto(manager & m, bucket * bt, unsigned s_idx, key const & k, bucket * pred_vect[]) { - SASSERT(check_pred_vect(bt->get_next(0), pred_vect)); // pred_vect contains the predecessors of the successor of bt. + SASSERT(this->check_pred_vect(bt->get_next(0), pred_vect)); // pred_vect contains the predecessors of the successor of bt. SASSERT(s_idx > 0); TRACE("del_entries_upto_bug", tout << "INSERT: " << INSERT << "\n"; @@ -619,10 +619,10 @@ protected: */ void insert_begin(manager & m, bucket * bt, key const & b, key const & e, value const & v, bucket * pred_vect[]) { TRACE("interval_skip_list_bug", tout << "insert_begin: [" << b << ", " << e << "] -> " << v << "\n"; this->display(tout, bt);); - SASSERT(check_pred_vect(bt, pred_vect)); + SASSERT(this->check_pred_vect(bt, pred_vect)); SASSERT(!bt->empty()); SASSERT(bt->size() <= bt->capacity()); - SASSERT(leq(b, first_key(bt))); + SASSERT(this->leq(b, first_key(bt))); bucket * next_pred_vect[Traits::max_level]; next_pred_vect[0] = 0; @@ -675,7 +675,7 @@ protected: */ void insert_at(manager & m, bucket * bt, unsigned idx, key const & b, key const & e, value const & v, bucket * pred_vect[]) { SASSERT(idx > 0); - SASSERT(check_pred_vect(bt->get_next(0), pred_vect)); + SASSERT(this->check_pred_vect(bt->get_next(0), pred_vect)); this->inc_ref(m, v); TRACE("insert_at_bug", tout << "before del_entries_upto:\n"; this->display_physical(tout);); @@ -750,7 +750,7 @@ protected: */ void insert_inside(manager & m, bucket * bt, key const & b, key const & e, value const & v, bucket * pred_vect[]) { TRACE("interval_skip_list_bug", tout << "insert_inside: [" << b << ", " << e << "] -> " << v << "\n";); - SASSERT(check_pred_vect(bt->get_next(0), pred_vect)); + SASSERT(this->check_pred_vect(bt->get_next(0), pred_vect)); SASSERT(!bt->empty()); SASSERT(bt->size() <= bt->capacity()); // perform binary search to find position to insert [b, e]->v @@ -833,7 +833,7 @@ protected: } } else { - SASSERT(eq(b, mid_entry.begin_key())); + SASSERT(this->eq(b, mid_entry.begin_key())); SASSERT(mid > 0); // Reason: insert_begin would have been called instead. insert_at(m, bt, mid, b, e, v, pred_vect); } @@ -919,7 +919,7 @@ protected: } } else { - SASSERT(eq(b, mid_entry.begin_key())); + SASSERT(this->eq(b, mid_entry.begin_key())); SASSERT(mid > 0); // Reason: remove_begin would have been called instead. del_entries_upto(m, bt, mid, e, pred_vect); } @@ -1022,7 +1022,7 @@ private: SASSERT(pred_vect[i]->get_next(i) == next); }); SASSERT(curr == this->m_header || lt(first_key(curr), k)); - SASSERT(next == 0 || leq(k, first_key(next))); + SASSERT(next == 0 || this->leq(k, first_key(next))); } public: @@ -1031,7 +1031,7 @@ public: \brief Insert the entries [i -> v] for every i \in [b, e]. */ void insert(manager & m, key const & b, key const & e, value const & v) { - SASSERT(leq(b, e)); + SASSERT(this->leq(b, e)); if (this->empty()) { insert_first_entry(m, b, e, v); return; @@ -1059,7 +1059,7 @@ public: SASSERT(!curr->empty()); SASSERT(!next->empty()); SASSERT(next != 0); - SASSERT(eq(first_key(next), b)); + SASSERT(this->eq(first_key(next), b)); // Bucket curr is the predecessor of next. SASSERT(curr->get_next(0) == next); @@ -1190,7 +1190,7 @@ public: \brief For each i \in [b, e] remove any entry [i->v] if it is in the list. */ void remove(manager & m, key const & b, key const & e) { - SASSERT(leq(b, e)); + SASSERT(this->leq(b, e)); if (this->empty()) return; bucket * pred_vect[Traits::max_level]; @@ -1207,7 +1207,7 @@ public: } else { SASSERT(next != 0); - SASSERT(eq(first_key(next), b)); + SASSERT(this->eq(first_key(next), b)); remove_begin(m, next, b, e, pred_vect); } } @@ -1274,8 +1274,8 @@ public: for (;;) { next = curr->get_next(i); if (next != 0 && this->leq(first_key(next), k)) { - TRACE("interval_skip_list", tout << "next_bucket(" << k << "), i: " << i << " skipping #" << get_bucket_idx(curr); - tout << ", moving to: #" << get_bucket_idx(next) << "\n"; this->display(tout, next);); + TRACE("interval_skip_list", tout << "next_bucket(" << k << "), i: " << i << " skipping #" << this->get_bucket_idx(curr); + tout << ", moving to: #" << this->get_bucket_idx(next) << "\n"; this->display(tout, next);); curr = next; if (curr->level() > max) { max = curr->level(); @@ -1666,7 +1666,7 @@ public: #ifdef Z3DEBUG private: bool check_invariant(entry const & e) const { - SASSERT(leq(e.begin_key(), e.end_key())); + SASSERT(this->leq(e.begin_key(), e.end_key())); return true; } @@ -1705,7 +1705,7 @@ public: bucket const * next = curr->get_next(i); if (next != 0) { SASSERT(next->level() >= i); - SASSERT(i == 0 || is_reachable_at_i(curr, next, i-1)); + SASSERT(i == 0 || this->is_reachable_at_i(curr, next, i-1)); SASSERT(!next->empty()); entry const & last_of_curr = curr->last_entry(); entry const & first_of_next = next->first_entry(); From 10b54d262e61ee697a3818eafda3ac9d17bcfba4 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sat, 27 Oct 2012 23:18:50 -0700 Subject: [PATCH 18/35] fixing linking problem Signed-off-by: Leonardo de Moura --- scripts/config-debug.mk.in | 3 ++- scripts/config-release.mk.in | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/config-debug.mk.in b/scripts/config-debug.mk.in index a7a473dae..1ad4386a1 100644 --- a/scripts/config-debug.mk.in +++ b/scripts/config-debug.mk.in @@ -10,8 +10,9 @@ AR_FLAGS=rcs AR_OUTFLAG= EXE_EXT= LINK=@CXX@ -LINK_FLAGS=-lpthread -fopenmp @LDFLAGS@ +LINK_FLAGS= LINK_OUT_FLAG=-o +LINK_EXTRA_FLAGS=-lpthread -fopenmp @LDFLAGS@ SO_EXT=@SO_EXT@ SLINK=@CXX@ SLINK_FLAGS=@SLIBFLAGS@ diff --git a/scripts/config-release.mk.in b/scripts/config-release.mk.in index 721c657df..01c50faf0 100644 --- a/scripts/config-release.mk.in +++ b/scripts/config-release.mk.in @@ -10,8 +10,9 @@ AR_FLAGS=rcs AR_OUTFLAG= EXE_EXT= LINK=@CXX@ -LINK_FLAGS=-lpthread -fopenmp @LDFLAGS@ +LINK_FLAGS= LINK_OUT_FLAG=-o +LINK_EXTRA_FLAGS=-lpthread -fopenmp @LDFLAGS@ SO_EXT=@SO_EXT@ SLINK=@CXX@ SLINK_FLAGS=@SLIBFLAGS@ From 5135eecc2d8015c28a671f07c64d5dc478327e69 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 07:55:30 -0700 Subject: [PATCH 19/35] moved generated VS project file to build dir Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 998d000c7..db3f4abdb 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1049,7 +1049,7 @@ def mk_gui_str(id): def mk_vs_proj(name, components): if not VS_PROJ: return - proj_name = '%s.vcxproj' % name + proj_name = '%s/%s.vcxproj' % (BUILD_DIR, name) modes=['Debug', 'Release'] PLATFORMS=['Win32'] f = open(proj_name, 'w') @@ -1101,7 +1101,7 @@ def mk_vs_proj(name, components): first = False else: f.write(';') - f.write('%s' % get_component(dep).src_dir) + f.write(get_component(dep).to_src_dir) f.write('\n') f.write(' \n') f.write(' \n') @@ -1121,7 +1121,7 @@ def mk_vs_proj(name, components): for dep in deps: dep = get_component(dep) for cpp in filter(lambda f: f.endswith('.cpp'), os.listdir(dep.src_dir)): - f.write(' \n' % (dep.src_dir, cpp)) + f.write(' \n' % (dep.to_src_dir, cpp)) f.write(' \n') f.write(' \n') f.write(' \n') From be97785253116291bd50f29caba57a5ef142fd31 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 10:06:02 -0700 Subject: [PATCH 20/35] c++ example Signed-off-by: Leonardo de Moura --- examples/c++/README | 10 ++++ examples/c++/README.txt | 24 -------- examples/c++/build-external.cmd | 1 - examples/c++/build.cmd | 1 - examples/c++/build.sh | 9 --- examples/c++/exec-external.cmd | 5 -- scripts/mk_make.py | 3 + scripts/mk_util.py | 80 +++++++++++++++++++++++++-- {examples => src/bindings}/c++/z3++.h | 0 9 files changed, 87 insertions(+), 46 deletions(-) create mode 100644 examples/c++/README delete mode 100644 examples/c++/README.txt delete mode 100644 examples/c++/build-external.cmd delete mode 100644 examples/c++/build.cmd delete mode 100755 examples/c++/build.sh delete mode 100644 examples/c++/exec-external.cmd rename {examples => src/bindings}/c++/z3++.h (100%) diff --git a/examples/c++/README b/examples/c++/README new file mode 100644 index 000000000..56775e537 --- /dev/null +++ b/examples/c++/README @@ -0,0 +1,10 @@ +Small example using the c++ bindings. +To build the example execute + make examples +in the build directory. + +This command will create the executable cpp_example. +On Windows, you can just execute it. +On OSX and Linux, you must install z3 first using + sudo make install +OR update LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX) with the build directory. You need that to be able to find the Z3 shared library. \ No newline at end of file diff --git a/examples/c++/README.txt b/examples/c++/README.txt deleted file mode 100644 index e1350f503..000000000 --- a/examples/c++/README.txt +++ /dev/null @@ -1,24 +0,0 @@ -This directory contains scripts to build the test application using -Microsoft C compiler, or g++. - -1) Using Microsoft C compiler - -Use 'build.cmd' to build the test application using Microsoft C -compiler. - -Remark: The Microsoft C compiler (cl) must be in your path, -or you can use the Visual Studio Command Prompt. - -The script 'exec.cmd' adds the bin directory to the path. So, -example.exe can find z3.dll. - -2) Using gcc - -You must install Z3 before running this example. -To install Z3, execute the following command in the Z3 root directory. - - sudo make install - -Use 'build.sh' to build the test application using g++. -It generates the executable 'example'. - diff --git a/examples/c++/build-external.cmd b/examples/c++/build-external.cmd deleted file mode 100644 index 08932d5a3..000000000 --- a/examples/c++/build-external.cmd +++ /dev/null @@ -1 +0,0 @@ -cl /EHsc /I ..\..\include /I . ..\..\bin\z3.lib example.cpp diff --git a/examples/c++/build.cmd b/examples/c++/build.cmd deleted file mode 100644 index 64ff98f31..000000000 --- a/examples/c++/build.cmd +++ /dev/null @@ -1 +0,0 @@ -cl /W3 /EHsc /I ..\lib ..\debug\z3_dbg.lib example.cpp diff --git a/examples/c++/build.sh b/examples/c++/build.sh deleted file mode 100755 index e829332f0..000000000 --- a/examples/c++/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -if g++ -fopenmp -o example example.cpp -lz3; then - echo "Example was successfully compiled." - echo "To run example, execute:" - echo " ./example" -else - echo "You must install Z3 before compiling this example." - echo "To install Z3, execute the following command in the Z3 root directory." - echo " sudo make install" -fi diff --git a/examples/c++/exec-external.cmd b/examples/c++/exec-external.cmd deleted file mode 100644 index 8a5d53453..000000000 --- a/examples/c++/exec-external.cmd +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -SETLOCAL -set PATH=..\..\bin;%PATH% -example.exe -ENDLOCAL diff --git a/scripts/mk_make.py b/scripts/mk_make.py index 2f00ee88c..610cc86e6 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -71,7 +71,10 @@ add_dll('api_dll', ['api', 'sat', 'extra_cmds'], 'api/dll', dll_name='libz3', export_files=API_files) add_dot_net_dll('dotnet', ['api_dll'], 'bindings/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties') +add_hlib('cpp', 'bindings/c++', includes2install=['z3++.h']) set_z3py_dir('bindings/python') +# Examples +add_cpp_example('cpp_example', 'c++') update_version(4, 2, 0, 0) mk_auto_src() diff --git a/scripts/mk_util.py b/scripts/mk_util.py index db3f4abdb..f7d80e73c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -21,6 +21,15 @@ PYTHON_PACKAGE_DIR=distutils.sysconfig.get_python_lib() BUILD_DIR='build' REV_BUILD_DIR='..' SRC_DIR='src' +EXAMPLE_DIR='examples' +# Required Components +Z3_DLL_COMPONENT='api_dll' +PATTERN_COMPONENT='pattern' +UTIL_COMPONENT='util' +API_COMPONENT='api' +DOTNET_COMPONENT='dotnet' +CPP_COMPONENT='cpp' +##################### IS_WINDOW=False VERBOSE=True DEBUG_MODE=False @@ -339,6 +348,9 @@ class Component: def mk_uninstall(self, out): return + def is_example(self): + return False + class LibComponent(Component): def __init__(self, name, path, deps, includes2install): Component.__init__(self, name, path, deps) @@ -373,6 +385,14 @@ class LibComponent(Component): for include in self.includes2install: out.write('\t@rm -f $(PREFIX)/include/%s\n' % include) +# "Library" containing only .h files. This is just a placeholder for includes files to be installed. +class HLibComponent(LibComponent): + def __init__(self, name, path, includes2install): + LibComponent.__init__(self, name, path, [], includes2install) + + def mk_makefile(self, out): + return + # Auxiliary function for sort_components def comp_components(c1, c2): id1 = get_component(c1).id @@ -551,7 +571,41 @@ class DotNetDLLComponent(Component): def has_assembly_info(self): return True - + +class ExampleComponent(Component): + def __init__(self, name, path): + Component.__init__(self, name, path, []) + self.ex_dir = '%s/%s' % (EXAMPLE_DIR, path) + self.to_ex_dir = '%s/%s' % (REV_BUILD_DIR, self.ex_dir) + + def is_example(self): + return True + +class CppExampleComponent(ExampleComponent): + def __init__(self, name, path): + ExampleComponent.__init__(self, name, path) + + def mk_makefile(self, out): + dll_name = get_component(Z3_DLL_COMPONENT).dll_name + dll = '%s$(SO_EXT)' % dll_name + exefile = '%s$(EXE_EXT)' % self.name + out.write('%s: %s' % (exefile, dll)) + for cppfile in get_cpp_files(self.ex_dir): + out.write(' ') + out.write('%s/%s' % (self.to_ex_dir, cppfile)) + out.write('\n') + out.write('\t$(LINK) $(LINK_OUT_FLAG)%s $(LINK_FLAGS)' % exefile) + # Add include dir components + out.write(' -I%s' % get_component(API_COMPONENT).to_src_dir) + out.write(' -I%s' % get_component(CPP_COMPONENT).to_src_dir) + for cppfile in get_cpp_files(self.ex_dir): + out.write(' ') + out.write('%s/%s' % (self.to_ex_dir, cppfile)) + out.write(' ') + out.write(dll) + out.write(' $(LINK_EXTRA_FLAGS)\n') + if exefile.strip(' ') != self.name: + out.write('_ex_%s: %s\n\n' % (self.name, exefile)) def reg_component(name, c): global _Id, _Components, _ComponentNames, _Name2Component @@ -567,6 +621,10 @@ def add_lib(name, deps=[], path=None, includes2install=[]): c = LibComponent(name, path, deps, includes2install) reg_component(name, c) +def add_hlib(name, path=None, includes2install=[]): + c = HLibComponent(name, path, includes2install) + reg_component(name, c) + def add_exe(name, deps=[], path=None, exe_name=None, install=True): c = ExeComponent(name, exe_name, path, deps, install) reg_component(name, c) @@ -579,6 +637,10 @@ def add_dot_net_dll(name, deps=[], path=None, dll_name=None, assembly_info_dir=N c = DotNetDLLComponent(name, dll_name, path, deps, assembly_info_dir) reg_component(name, c) +def add_cpp_example(name, path=None): + c = CppExampleComponent(name, path) + reg_component(name, c) + # Copy configuration correct file to BUILD_DIR def cp_config_mk(): if IS_WINDOW: @@ -639,6 +701,12 @@ def mk_makefile(): out.write('\n\t@echo Z3 was successfully built.\n') out.write("\t@echo Use the following command to install Z3 at prefix $(PREFIX).\n") out.write('\t@echo " sudo make install"\n') + # Generate :examples rule + out.write('examples:') + for c in _Components: + if c.is_example(): + out.write(' _ex_%s' % c.name) + out.write('\n\t@echo Z3 examples were successfully built.\n') # Generate components for c in _Components: c.mk_makefile(out) @@ -676,7 +744,7 @@ def mk_auto_src(): # TODO: delete after src/ast/pattern/expr_pattern_match # database.smt ==> database.h def mk_pat_db(): - c = get_component('pattern') + c = get_component(PATTERN_COMPONENT) fin = open('%s/database.smt2' % c.src_dir, 'r') fout = open('%s/database.h' % c.src_dir, 'w') fout.write('char const * g_pattern_database =\n') @@ -695,7 +763,7 @@ def update_version(major, minor, build, revision): # Update files with the version number def mk_version_dot_h(major, minor, build, revision): - c = get_component('util') + c = get_component(UTIL_COMPONENT) fout = open('%s/version.h' % c.src_dir, 'w') fout.write('// automatically generated file.\n') fout.write('#define Z3_MAJOR_VERSION %s\n' % major) @@ -873,7 +941,7 @@ def mk_bindings(api_files): mk_z3consts_py(api_files) mk_z3consts_donet(api_files) new_api_files = [] - api = get_component('api') + api = get_component(API_COMPONENT) for api_file in api_files: api_file_path = api.find_file(api_file, api.name) new_api_files.append('%s/%s' % (api_file_path.src_dir, api_file)) @@ -896,7 +964,7 @@ def mk_z3consts_py(api_files): z3consts = open('%s/z3consts.py' % Z3PY_SRC_DIR, 'w') z3consts.write('# Automatically generated file\n\n') - api_dll = get_component('api_dll') + api_dll = get_component(Z3_DLL_COMPONENT) for api_file in api_files: api_file_c = api_dll.find_file(api_file, api_dll.name) @@ -968,7 +1036,7 @@ def mk_z3consts_donet(api_files): openbrace_pat = re.compile("{ *") closebrace_pat = re.compile("}.*;") - dotnet = get_component('dotnet') + dotnet = get_component(DOTNET_COMPONENT) DeprecatedEnums = { 'Z3_search_failure' } z3consts = open('%s/Enumerations.cs' % dotnet.src_dir, 'w') diff --git a/examples/c++/z3++.h b/src/bindings/c++/z3++.h similarity index 100% rename from examples/c++/z3++.h rename to src/bindings/c++/z3++.h From 93fbfd5f94ceedc1860b974b54b99c97b17ab15b Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 10:48:11 -0700 Subject: [PATCH 21/35] dotnet example Signed-off-by: Leonardo de Moura --- examples/{test_mapi => dotnet}/Program.cs | 0 .../{test_mapi => dotnet}/test_mapi.csproj | 0 examples/test_mapi/build.cmd | 4 -- scripts/mk_make.py | 1 + scripts/mk_util.py | 51 ++++++++++++++++--- scripts/update_api.py | 2 +- 6 files changed, 46 insertions(+), 12 deletions(-) rename examples/{test_mapi => dotnet}/Program.cs (100%) rename examples/{test_mapi => dotnet}/test_mapi.csproj (100%) delete mode 100644 examples/test_mapi/build.cmd diff --git a/examples/test_mapi/Program.cs b/examples/dotnet/Program.cs similarity index 100% rename from examples/test_mapi/Program.cs rename to examples/dotnet/Program.cs diff --git a/examples/test_mapi/test_mapi.csproj b/examples/dotnet/test_mapi.csproj similarity index 100% rename from examples/test_mapi/test_mapi.csproj rename to examples/dotnet/test_mapi.csproj diff --git a/examples/test_mapi/build.cmd b/examples/test_mapi/build.cmd deleted file mode 100644 index bfc0870aa..000000000 --- a/examples/test_mapi/build.cmd +++ /dev/null @@ -1,4 +0,0 @@ -copy ..\..\external\Microsoft.Z3.dll . -copy ..\..\external\Z3.dll . - -csc /reference:..\..\external\Microsoft.Z3.dll /platform:anycpu /reference:System.Numerics.dll Program.cs \ No newline at end of file diff --git a/scripts/mk_make.py b/scripts/mk_make.py index 610cc86e6..238197b17 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -75,6 +75,7 @@ add_hlib('cpp', 'bindings/c++', includes2install=['z3++.h']) set_z3py_dir('bindings/python') # Examples add_cpp_example('cpp_example', 'c++') +add_dotnet_example('dotnet_example', 'dotnet') update_version(4, 2, 0, 0) mk_auto_src() diff --git a/scripts/mk_util.py b/scripts/mk_util.py index f7d80e73c..b0e7dfad9 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -602,9 +602,41 @@ class CppExampleComponent(ExampleComponent): out.write(' ') out.write('%s/%s' % (self.to_ex_dir, cppfile)) out.write(' ') - out.write(dll) + if IS_WINDOW: + out.write('%s.lib' % dll_name) + else: + out.write(dll) out.write(' $(LINK_EXTRA_FLAGS)\n') - if exefile.strip(' ') != self.name: + out.write('_ex_%s: %s\n\n' % (self.name, exefile)) + +class DotNetExampleComponent(ExampleComponent): + def __init__(self, name, path): + ExampleComponent.__init__(self, name, path) + + def is_example(self): + return IS_WINDOW + + def mk_makefile(self, out): + if IS_WINDOW: + dll_name = get_component(DOTNET_COMPONENT).dll_name + dll = '%s.dll' % dll_name + exefile = '%s.exe' % self.name + out.write('%s: %s' % (exefile, dll)) + for csfile in get_cs_files(self.ex_dir): + out.write(' ') + out.write('%s/%s' % (self.to_ex_dir, csfile)) + out.write('\n') + out.write('\tcsc /out:%s /reference:%s /debug:full /reference:System.Numerics.dll' % (exefile, dll)) + if VS_X64: + out.write(' /platform:x64') + else: + out.write(' /platform:x86') + for csfile in get_cs_files(self.ex_dir): + out.write(' ') + # HACK + win_ex_dir = self.to_ex_dir.replace('/', '\\') + out.write('%s\\%s' % (win_ex_dir, csfile)) + out.write('\n') out.write('_ex_%s: %s\n\n' % (self.name, exefile)) def reg_component(name, c): @@ -641,6 +673,10 @@ def add_cpp_example(name, path=None): c = CppExampleComponent(name, path) reg_component(name, c) +def add_dotnet_example(name, path=None): + c = DotNetExampleComponent(name, path) + reg_component(name, c) + # Copy configuration correct file to BUILD_DIR def cp_config_mk(): if IS_WINDOW: @@ -699,8 +735,9 @@ def mk_makefile(): if c.main_component(): out.write(' %s' % c.name) out.write('\n\t@echo Z3 was successfully built.\n') - out.write("\t@echo Use the following command to install Z3 at prefix $(PREFIX).\n") - out.write('\t@echo " sudo make install"\n') + if not IS_WINDOW: + out.write("\t@echo Use the following command to install Z3 at prefix $(PREFIX).\n") + out.write('\t@echo " sudo make install"\n') # Generate :examples rule out.write('examples:') for c in _Components: @@ -726,12 +763,12 @@ def mk_makefile(): if IS_WINDOW: if VS_X64: print " platform: x64\n" - print "To build Z3, open a ***Visual Studio x64 Command Prompt***, then" + print "To build Z3, open a [Visual Studio x64 Command Prompt], then" else: print " platform: x86" - print "To build Z3, open a ***Visual Studio Command Prompt***, then" + print "To build Z3, open a [Visual Studio Command Prompt], then" print "type 'cd %s/%s && nmake'\n" % (os.getcwd(), BUILD_DIR) - print 'Remark: to open a Visual Studio Command Prompt, go to: "Start > All Programs > Visual Studio > Visual Studio Tools >"' + print 'Remark: to open a Visual Studio Command Prompt, go to: "Start > All Programs > Visual Studio > Visual Studio Tools"' else: print "Type 'cd %s; make' to build Z3" % BUILD_DIR diff --git a/scripts/update_api.py b/scripts/update_api.py index a073596a8..ce0d44b4e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -311,7 +311,7 @@ def mk_dotnet(): dotnet.write(' public unsafe class LIB\n') dotnet.write(' {\n') dotnet.write(' ' - ' const string Z3_DLL_NAME = \"z3.dll\";\n' + ' const string Z3_DLL_NAME = \"libz3.dll\";\n' ' \n'); dotnet.write(' [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n') dotnet.write(' public extern static void Z3_set_error_handler(Z3_context a0, Z3_error_handler a1);\n\n') From 4278b2dd515dcef6590fa293b70448e20d83887d Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 10:50:36 -0700 Subject: [PATCH 22/35] dotnet example Signed-off-by: Leonardo de Moura --- examples/dotnet/README | 7 ++ examples/dotnet/test_mapi.csproj | 133 ------------------------------- 2 files changed, 7 insertions(+), 133 deletions(-) create mode 100644 examples/dotnet/README delete mode 100644 examples/dotnet/test_mapi.csproj diff --git a/examples/dotnet/README b/examples/dotnet/README new file mode 100644 index 000000000..3f7e989df --- /dev/null +++ b/examples/dotnet/README @@ -0,0 +1,7 @@ +Small example using the .Net bindings. +This example is only built if you have Visual Studio. +To build the example execute + make examples +in the build directory. + +It will create the executable dotnet_example.exe diff --git a/examples/dotnet/test_mapi.csproj b/examples/dotnet/test_mapi.csproj deleted file mode 100644 index 9b8a935ec..000000000 --- a/examples/dotnet/test_mapi.csproj +++ /dev/null @@ -1,133 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {D350BC78-8455-45D3-9759-073394378BF2} - Exe - Properties - test_mapi - test_mapi - v4.0 - Client - 512 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - test_mapi.Program - - - true - bin\Debug\ - DEBUG;TRACE - full - AnyCPU - bin\Debug\test_mapi.exe.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - - - bin\Release\ - TRACE - true - pdbonly - AnyCPU - bin\Release\test_mapi.exe.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - - - true - bin\x64\Debug\ - DEBUG;TRACE - full - x64 - bin\Debug\test_mapi.exe.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - false - - - bin\x64\Release\ - TRACE - true - pdbonly - x64 - bin\Release\test_mapi.exe.CodeAnalysisLog.xml - true - GlobalSuppressions.cs - prompt - MinimumRecommendedRules.ruleset - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - true - ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - true - - - - - - - - - - - - - - - {EC3DB697-B734-42F7-9468-5B62821EEB5A} - Microsoft.Z3 - - - - - - - - - \ No newline at end of file From 91cc6bb768cb45f03fb3e8ca95c1b0aa4b7dcf15 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 10:51:50 -0700 Subject: [PATCH 23/35] renamed test_capi Signed-off-by: Leonardo de Moura --- examples/{test_capi => c}/README.txt | 0 examples/{test_capi => c}/build.sh | 0 examples/{test_capi => c}/test_capi.c | 0 examples/{test_capi => c}/test_capi.vcxproj | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename examples/{test_capi => c}/README.txt (100%) rename examples/{test_capi => c}/build.sh (100%) rename examples/{test_capi => c}/test_capi.c (100%) rename examples/{test_capi => c}/test_capi.vcxproj (100%) diff --git a/examples/test_capi/README.txt b/examples/c/README.txt similarity index 100% rename from examples/test_capi/README.txt rename to examples/c/README.txt diff --git a/examples/test_capi/build.sh b/examples/c/build.sh similarity index 100% rename from examples/test_capi/build.sh rename to examples/c/build.sh diff --git a/examples/test_capi/test_capi.c b/examples/c/test_capi.c similarity index 100% rename from examples/test_capi/test_capi.c rename to examples/c/test_capi.c diff --git a/examples/test_capi/test_capi.vcxproj b/examples/c/test_capi.vcxproj similarity index 100% rename from examples/test_capi/test_capi.vcxproj rename to examples/c/test_capi.vcxproj From ad615221ce3f58fc8565d249ba926f45478cca32 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 11:22:41 -0700 Subject: [PATCH 24/35] Fixed python regressions. Added missing tactic. Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 14 +++++++++----- src/bindings/python/z3.py | 8 ++++---- src/tactic/core/propagate_values_tactic.h | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b0e7dfad9..8c1f995e6 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -188,6 +188,15 @@ def set_z3py_dir(p): if not os.path.exists(full): raise MKException("Python bindings directory '%s' does not exist" % full) Z3PY_SRC_DIR = full + compileall.compile_dir(Z3PY_SRC_DIR, force=1) + for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(Z3PY_SRC_DIR)): + try: + os.remove('%s/%s' % (BUILD_DIR, pyc)) + except: + pass + os.rename('%s/%s' % (Z3PY_SRC_DIR, pyc), '%s/%s' % (BUILD_DIR, pyc)) + if is_verbose(): + print "Generated '%s'" % pyc if VERBOSE: print "Python bindinds directory was detected." @@ -703,11 +712,6 @@ def mk_install(out): out.write('\t@mkdir -p $(PREFIX)/lib\n') for c in _Components: c.mk_install(out) - compileall.compile_dir(Z3PY_SRC_DIR, force=1) - for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(Z3PY_SRC_DIR)): - os.rename('%s/%s' % (Z3PY_SRC_DIR, pyc), '%s/%s' % (BUILD_DIR, pyc)) - if is_verbose(): - print "Generated '%s'" % pyc out.write('\t@cp z3*.pyc %s\n' % PYTHON_PACKAGE_DIR) out.write('\t@echo Z3 was successfully installed.\n') out.write('\n') diff --git a/src/bindings/python/z3.py b/src/bindings/python/z3.py index 7e3d4b1ae..4d041fa6b 100644 --- a/src/bindings/python/z3.py +++ b/src/bindings/python/z3.py @@ -24,7 +24,7 @@ Small example: >>> s.check() sat >>> s.model() -[x = 1, y = 2] +[y = 2, x = 1] Z3 exceptions: @@ -1698,9 +1698,9 @@ def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]): >>> q Exists([x, y], f(x, y) >= x) >>> Tactic('nnf')(q) - [[f(x!foo!2, y!foo!1) >= x!foo!2]] + [[f(x!foo!1, y!foo!0) >= x!foo!1]] >>> Tactic('nnf')(q).as_expr() - f(x!foo!4, y!foo!3) >= x!foo!4 + f(x!foo!3, y!foo!2) >= x!foo!3 """ return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns) @@ -6908,7 +6908,7 @@ def solve(*args, **keywords): >>> a, b = Ints('a b') >>> solve(a + b == 3, Or(a == 0, a == 1), a != 0) - [a = 1, b = 2] + [b = 2, a = 1] """ s = Solver() s.set(**keywords) diff --git a/src/tactic/core/propagate_values_tactic.h b/src/tactic/core/propagate_values_tactic.h index f5ef200b7..ed8cb313f 100644 --- a/src/tactic/core/propagate_values_tactic.h +++ b/src/tactic/core/propagate_values_tactic.h @@ -27,7 +27,7 @@ class tactic; tactic * mk_propagate_values_tactic(ast_manager & m, params_ref const & p = params_ref()); /* - ADD_TACTIC_CMD("propagate-values", "propagate constants.", "mk_propagate_values_tactic(m, p)") + ADD_TACTIC("propagate-values", "propagate constants.", "mk_propagate_values_tactic(m, p)") */ #endif From 9dbd0831c4e075abbfea6593b0a019f0e3b1e318 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 11:25:02 -0700 Subject: [PATCH 25/35] Added CC (C compiler) to config.mk scripts Signed-off-by: Leonardo de Moura --- scripts/config-debug.mk.in | 2 +- scripts/config-release.mk.in | 2 +- scripts/config-vs-debug-x64.mk | 1 + scripts/config-vs-debug.mk | 1 + scripts/config-vs-release-x64.mk | 1 + scripts/config-vs-release.mk | 1 + 6 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/config-debug.mk.in b/scripts/config-debug.mk.in index 1ad4386a1..187130607 100644 --- a/scripts/config-debug.mk.in +++ b/scripts/config-debug.mk.in @@ -1,4 +1,4 @@ - +CC=@CC@ PREFIX=@prefix@ CXX=@CXX@ CXXFLAGS=@CPPFLAGS@ @CXXFLAGS@ -DZ3DEBUG -D_TRACE -c -g -Wall -fopenmp -msse -msse2 -mfpmath=sse diff --git a/scripts/config-release.mk.in b/scripts/config-release.mk.in index 01c50faf0..2f0a34a15 100644 --- a/scripts/config-release.mk.in +++ b/scripts/config-release.mk.in @@ -1,4 +1,4 @@ - +CC=@CC@ PREFIX=@prefix@ CXX=@CXX@ CXXFLAGS=@CPPFLAGS@ @CXXFLAGS@ -c -O3 -fomit-frame-pointer -fopenmp -msse -msse2 -mfpmath=sse diff --git a/scripts/config-vs-debug-x64.mk b/scripts/config-vs-debug-x64.mk index 73089334a..5810d8fe4 100644 --- a/scripts/config-vs-debug-x64.mk +++ b/scripts/config-vs-debug-x64.mk @@ -1,3 +1,4 @@ +CC=cl CXX=cl CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- CXX_OUT_FLAG=/Fo diff --git a/scripts/config-vs-debug.mk b/scripts/config-vs-debug.mk index 1e2a8c58a..bef47d337 100644 --- a/scripts/config-vs-debug.mk +++ b/scripts/config-vs-debug.mk @@ -1,3 +1,4 @@ +CC=cl CXX=cl CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- /arch:SSE2 CXX_OUT_FLAG=/Fo diff --git a/scripts/config-vs-release-x64.mk b/scripts/config-vs-release-x64.mk index 9d16d5c67..6cd264b32 100644 --- a/scripts/config-vs-release-x64.mk +++ b/scripts/config-vs-release-x64.mk @@ -1,3 +1,4 @@ +CC=cl CXX=cl CXXFLAGS=/c /Zi /nologo /W3 /WX- /O2 /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG /D _LIB /D _WINDOWS /D _AMD64_ /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TP CXX_OUT_FLAG=/Fo diff --git a/scripts/config-vs-release.mk b/scripts/config-vs-release.mk index 73d9ec8d8..16c9b0d37 100644 --- a/scripts/config-vs-release.mk +++ b/scripts/config-vs-release.mk @@ -1,3 +1,4 @@ +CC=cl CXX=cl CXXFLAGS=/nologo /c /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /GS /fp:precise /Zc:wchar_t /Zc:forScope /openmp /Gd /analyze- /arch:SSE2 CXX_OUT_FLAG=/Fo From 7f0fcefbe29f6fbc445a66bfa934820db485446d Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 11:56:27 -0700 Subject: [PATCH 26/35] C examples Signed-off-by: Leonardo de Moura --- examples/c/README | 11 + examples/c/README.txt | 25 -- examples/c/build.sh | 9 - examples/c/test_capi.vcxproj | 430 ---------------------------- examples/maxsat/README | 12 + examples/maxsat/README-external.txt | 16 -- examples/maxsat/README.txt | 28 -- examples/maxsat/build-external.cmd | 1 - examples/maxsat/build.sh | 9 - examples/maxsat/exec-external.cmd | 5 - examples/maxsat/maxsat.vcxproj | 295 ------------------- scripts/mk_make.py | 2 + scripts/mk_util.py | 31 +- 13 files changed, 52 insertions(+), 822 deletions(-) create mode 100644 examples/c/README delete mode 100644 examples/c/README.txt delete mode 100755 examples/c/build.sh delete mode 100644 examples/c/test_capi.vcxproj create mode 100644 examples/maxsat/README delete mode 100644 examples/maxsat/README-external.txt delete mode 100644 examples/maxsat/README.txt delete mode 100644 examples/maxsat/build-external.cmd delete mode 100755 examples/maxsat/build.sh delete mode 100644 examples/maxsat/exec-external.cmd delete mode 100644 examples/maxsat/maxsat.vcxproj diff --git a/examples/c/README b/examples/c/README new file mode 100644 index 000000000..5ea885519 --- /dev/null +++ b/examples/c/README @@ -0,0 +1,11 @@ +Small example using the c++ bindings. +To build the example execute + make examples +in the build directory. + +This command will create the executable c_example. +On Windows, you can just execute it. +On OSX and Linux, you must install z3 first using + sudo make install +OR update LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX) with the build directory. You need that to be able to find the Z3 shared library. + diff --git a/examples/c/README.txt b/examples/c/README.txt deleted file mode 100644 index c23e632c4..000000000 --- a/examples/c/README.txt +++ /dev/null @@ -1,25 +0,0 @@ -WARNING: this example still uses the old Z3 (version 3.x) C API. -The current version is backward compatible. - -1) Using Visual Studio (with Z3 source code release) - -The test_capi application is automatically built when the z3-prover.sln is processed. The following command should be used to compile z3-prover.sln in the Z3 root directory - - msbuild /p:configuration=external - -The maxsat executable is located at - - ..\external\test_capi - -2) Using gcc (on Linux or OSX) - -Use 'build.sh' to build the test application using gcc. - -You must install Z3 before running this example. -To install Z3, execute the following command in the Z3 root directory. - - sudo make install - -Use 'build.sh' to build the test application using gcc. -It generates the executable 'test_capi'. - diff --git a/examples/c/build.sh b/examples/c/build.sh deleted file mode 100755 index 0caa7fff5..000000000 --- a/examples/c/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -if gcc -fopenmp -o test_capi test_capi.c -lz3; then - echo "test_capi applicatio was successfully compiled." - echo "To try it, execute:" - echo " ./test_capi" -else - echo "You must install Z3 before compiling this example." - echo "To install Z3, execute the following command in the Z3 root directory." - echo " sudo make install" -fi diff --git a/examples/c/test_capi.vcxproj b/examples/c/test_capi.vcxproj deleted file mode 100644 index 91121ab1e..000000000 --- a/examples/c/test_capi.vcxproj +++ /dev/null @@ -1,430 +0,0 @@ - - - - - commercial - Win32 - - - commercial - x64 - - - Debug - Win32 - - - Debug - x64 - - - external - Win32 - - - external - x64 - - - release_mt - Win32 - - - release_mt - x64 - - - Release - Win32 - - - Release - x64 - - - - {9E76526D-EDA2-4B88-9616-A8FC08F31071} - test_capi - Win32Proj - - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - true - - - Application - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(SolutionDir)$(Configuration)\ - $(SolutionDir)$(Configuration)\ - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - false - false - false - $(SolutionDir)$(Platform)\$(Configuration)\ - $(SolutionDir)$(Platform)\$(Configuration)\ - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - false - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - AllRules.ruleset - AllRules.ruleset - - - - - - - AllRules.ruleset - AllRules.ruleset - AllRules.ruleset - - - - - - - - - - Disabled - ..\lib;%(AdditionalIncludeDirectories) - WIN32;_CONSOLE;Z3DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - true - Console - false - - - MachineX86 - - - - - X64 - - - Disabled - ..\lib;%(AdditionalIncludeDirectories) - WIN32;_CONSOLE;Z3DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - ProgramDatabase - - - true - Console - MachineX64 - - - - - false - ..\lib;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - psapi.lib;%(AdditionalDependencies) - true - Console - 8388608 - true - true - false - - - MachineX86 - - - - - X64 - - - false - ..\lib;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - psapi.lib;%(AdditionalDependencies) - true - Console - 8388608 - true - true - MachineX64 - - - - - ..\lib;%(AdditionalIncludeDirectories) - WIN32;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - true - Console - true - true - false - - - MachineX86 - - - - - ..\lib;%(AdditionalIncludeDirectories) - WIN32;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - true - Console - true - true - false - - - MachineX86 - - - - - ..\lib;%(AdditionalIncludeDirectories) - WIN32;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - ..\lib;%(AdditionalIncludeDirectories) - WIN32;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - true - Console - true - true - MachineX64 - - - - - X64 - - - ..\lib;%(AdditionalIncludeDirectories) - WIN32;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - true - Console - true - true - MachineX64 - - - - - X64 - - - ..\lib;%(AdditionalIncludeDirectories) - WIN32;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - true - Console - true - true - MachineX64 - - - - - - - - {0bf8cb94-61c7-4545-ae55-c58d858aa8b6} - false - - - {4a7e5a93-19d8-4382-8950-fb2edec7a76e} - false - - - - - - \ No newline at end of file diff --git a/examples/maxsat/README b/examples/maxsat/README new file mode 100644 index 000000000..cf022d847 --- /dev/null +++ b/examples/maxsat/README @@ -0,0 +1,12 @@ +Small example using the c++ bindings. +To build the example execute + make examples +in the build directory. + +This command will create the executable maxsat. +On Windows, you can just execute it. +On OSX and Linux, you must install z3 first using + sudo make install +OR update LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX) with the build directory. You need that to be able to find the Z3 shared library. + +This directory contains a test file (ex.smt) that can be use as input for the maxsat test application. diff --git a/examples/maxsat/README-external.txt b/examples/maxsat/README-external.txt deleted file mode 100644 index bfef1acaa..000000000 --- a/examples/maxsat/README-external.txt +++ /dev/null @@ -1,16 +0,0 @@ -WARNING: this example still uses the old Z3 (version 3.x) C API. -The current version is backward compatible. - -This directory contains scripts to build the MaxSAT application using -Microsoft C compiler, or gcc. - -1) Using Microsoft C compiler (with binary release) - -Use 'build.cmd' to build the MaxSAT application using Microsoft C compiler. - -Remark: The Microsoft C compiler (cl) must be in your path, -or you can use the Visual Studio Command Prompt. - -The script 'exec.cmd' adds the bin directory to the path. So, -maxsat.exe can find z3.dll. - diff --git a/examples/maxsat/README.txt b/examples/maxsat/README.txt deleted file mode 100644 index 82eb6bc2a..000000000 --- a/examples/maxsat/README.txt +++ /dev/null @@ -1,28 +0,0 @@ -WARNING: this example still uses the old Z3 (version 3.x) C API. -The current version is backward compatible. - -1) Using Visual Studio (with Z3 source code release) - -The maxsat example application is automatically built when the z3-prover.sln is processed. The following command should be used to compile z3-prover.sln in the Z3 root directory - - msbuild /p:configuration=external - -The maxsat executable is located at - - ..\external\maxsat - -To process ex.smt, use - - ..\external\maxsat ex.smt - -2) Using gcc (on Linux or OSX) - -Use 'build.sh' to build the MaxSAT application using gcc. - -You must install Z3 before running this example. -To install Z3, execute the following command in the Z3 root directory. - - sudo make install - -Use 'build.sh' to build the test application using gcc. -It generates the executable 'maxsat'. diff --git a/examples/maxsat/build-external.cmd b/examples/maxsat/build-external.cmd deleted file mode 100644 index d71fb0e9b..000000000 --- a/examples/maxsat/build-external.cmd +++ /dev/null @@ -1 +0,0 @@ -cl /I ..\..\include ..\..\bin\z3.lib maxsat.c diff --git a/examples/maxsat/build.sh b/examples/maxsat/build.sh deleted file mode 100755 index 22770c134..000000000 --- a/examples/maxsat/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -if gcc -fopenmp -o maxsat maxsat.c -lz3; then - echo "maxsat example was successfully compiled." - echo "To run example, execute:" - echo " ./maxsat ex.smt" -else - echo "You must install Z3 before compiling this example." - echo "To install Z3, execute the following command in the Z3 root directory." - echo " sudo make install" -fi diff --git a/examples/maxsat/exec-external.cmd b/examples/maxsat/exec-external.cmd deleted file mode 100644 index 9610dec88..000000000 --- a/examples/maxsat/exec-external.cmd +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -SETLOCAL -set PATH=..\..\bin;%PATH% -maxsat.exe %1 -ENDLOCAL diff --git a/examples/maxsat/maxsat.vcxproj b/examples/maxsat/maxsat.vcxproj deleted file mode 100644 index 4858316d4..000000000 --- a/examples/maxsat/maxsat.vcxproj +++ /dev/null @@ -1,295 +0,0 @@ - - - - - commercial - Win32 - - - commercial - x64 - - - Debug - Win32 - - - Debug - x64 - - - external - Win32 - - - external - x64 - - - Release - Win32 - - - Release - x64 - - - - {7C154132-AAAB-4F60-B652-F8C51A63D244} - Win32Proj - maxsat - - - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - - Application - false - true - Unicode - - - Application - false - true - Unicode - - - Application - false - true - Unicode - - - Application - false - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - false - - - false - - - false - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\lib - - - Console - true - false - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\lib - - - Console - true - false - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\lib - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\lib - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\lib - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - _AMD64_;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\lib - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\lib - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\lib - - - Console - true - true - true - - - - - - - - {4a7e5a93-19d8-4382-8950-fb2edec7a76e} - true - false - false - true - false - - - - - - \ No newline at end of file diff --git a/scripts/mk_make.py b/scripts/mk_make.py index 238197b17..2bf58a6b6 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -75,6 +75,8 @@ add_hlib('cpp', 'bindings/c++', includes2install=['z3++.h']) set_z3py_dir('bindings/python') # Examples add_cpp_example('cpp_example', 'c++') +add_c_example('c_example', 'c') +add_c_example('maxsat') add_dotnet_example('dotnet_example', 'dotnet') update_version(4, 2, 0, 0) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8c1f995e6..eb63ea5f5 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -229,6 +229,9 @@ def is_verbose(): def get_cpp_files(path): return filter(lambda f: f.endswith('.cpp'), os.listdir(path)) +def get_c_files(path): + return filter(lambda f: f.endswith('.c'), os.listdir(path)) + def get_cs_files(path): return filter(lambda f: f.endswith('.cs'), os.listdir(path)) @@ -584,7 +587,7 @@ class DotNetDLLComponent(Component): class ExampleComponent(Component): def __init__(self, name, path): Component.__init__(self, name, path, []) - self.ex_dir = '%s/%s' % (EXAMPLE_DIR, path) + self.ex_dir = '%s/%s' % (EXAMPLE_DIR, self.path) self.to_ex_dir = '%s/%s' % (REV_BUILD_DIR, self.ex_dir) def is_example(self): @@ -594,20 +597,26 @@ class CppExampleComponent(ExampleComponent): def __init__(self, name, path): ExampleComponent.__init__(self, name, path) + def compiler(self): + return "$(CXX)" + + def src_files(self): + return get_cpp_files(self.ex_dir) + def mk_makefile(self, out): dll_name = get_component(Z3_DLL_COMPONENT).dll_name dll = '%s$(SO_EXT)' % dll_name exefile = '%s$(EXE_EXT)' % self.name out.write('%s: %s' % (exefile, dll)) - for cppfile in get_cpp_files(self.ex_dir): + for cppfile in self.src_files(): out.write(' ') out.write('%s/%s' % (self.to_ex_dir, cppfile)) out.write('\n') - out.write('\t$(LINK) $(LINK_OUT_FLAG)%s $(LINK_FLAGS)' % exefile) + out.write('\t%s $(LINK_OUT_FLAG)%s $(LINK_FLAGS)' % (self.compiler(), exefile)) # Add include dir components out.write(' -I%s' % get_component(API_COMPONENT).to_src_dir) out.write(' -I%s' % get_component(CPP_COMPONENT).to_src_dir) - for cppfile in get_cpp_files(self.ex_dir): + for cppfile in self.src_files(): out.write(' ') out.write('%s/%s' % (self.to_ex_dir, cppfile)) out.write(' ') @@ -618,6 +627,16 @@ class CppExampleComponent(ExampleComponent): out.write(' $(LINK_EXTRA_FLAGS)\n') out.write('_ex_%s: %s\n\n' % (self.name, exefile)) +class CExampleComponent(CppExampleComponent): + def __init__(self, name, path): + CppExampleComponent.__init__(self, name, path) + + def compiler(self): + return "$(CC)" + + def src_files(self): + return get_c_files(self.ex_dir) + class DotNetExampleComponent(ExampleComponent): def __init__(self, name, path): ExampleComponent.__init__(self, name, path) @@ -682,6 +701,10 @@ def add_cpp_example(name, path=None): c = CppExampleComponent(name, path) reg_component(name, c) +def add_c_example(name, path=None): + c = CExampleComponent(name, path) + reg_component(name, c) + def add_dotnet_example(name, path=None): c = DotNetExampleComponent(name, path) reg_component(name, c) From 483942c1a57a06b5b6820895674b38dfe5ec1200 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 12:19:34 -0700 Subject: [PATCH 27/35] python example Signed-off-by: Leonardo de Moura --- scripts/mk_make.py | 1 + scripts/mk_util.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/scripts/mk_make.py b/scripts/mk_make.py index 2bf58a6b6..7e1cc79bb 100644 --- a/scripts/mk_make.py +++ b/scripts/mk_make.py @@ -78,6 +78,7 @@ add_cpp_example('cpp_example', 'c++') add_c_example('c_example', 'c') add_c_example('maxsat') add_dotnet_example('dotnet_example', 'dotnet') +add_z3py_example('python') update_version(4, 2, 0, 0) mk_auto_src() diff --git a/scripts/mk_util.py b/scripts/mk_util.py index eb63ea5f5..75075d31f 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -200,6 +200,13 @@ def set_z3py_dir(p): if VERBOSE: print "Python bindinds directory was detected." +def add_z3py_example(p): + full = '%s/%s' % (EXAMPLE_DIR, p) + for py in filter(lambda f: f.endswith('.py'), os.listdir(full)): + shutil.copyfile('%s/%s' % (full, py), '%s/%s' % (BUILD_DIR, py)) + if is_verbose(): + print "Copied Z3Py example '%s' to '%s'" % (py, BUILD_DIR) + _UNIQ_ID = 0 def mk_fresh_name(prefix): From f040db94f8068c3cec2a351e79dc0482b1111847 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 12:19:45 -0700 Subject: [PATCH 28/35] python example Signed-off-by: Leonardo de Moura --- examples/python/README | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 examples/python/README diff --git a/examples/python/README b/examples/python/README new file mode 100644 index 000000000..eb564ec1a --- /dev/null +++ b/examples/python/README @@ -0,0 +1,4 @@ +The example is copied to the build directory during configuration. +You can execute it using + python example.py +in the build directory after you build Z3. \ No newline at end of file From 462ea552150a6cbb9cb77e02e9d8783c2cce2f10 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 12:24:57 -0700 Subject: [PATCH 29/35] fixed bug in mk_make.py Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 75075d31f..3f6667c79 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -184,6 +184,7 @@ def set_build_dir(d): def set_z3py_dir(p): global SRC_DIR, Z3PY_SRC_DIR + mk_dir(BUILD_DIR) full = '%s/%s' % (SRC_DIR, p) if not os.path.exists(full): raise MKException("Python bindings directory '%s' does not exist" % full) From 573f3d1725037e3fcbcae2793138f8621380f1d6 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 13:09:23 -0700 Subject: [PATCH 30/35] fixed z3py build Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 3f6667c79..349f9b562 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -184,20 +184,10 @@ def set_build_dir(d): def set_z3py_dir(p): global SRC_DIR, Z3PY_SRC_DIR - mk_dir(BUILD_DIR) full = '%s/%s' % (SRC_DIR, p) if not os.path.exists(full): raise MKException("Python bindings directory '%s' does not exist" % full) Z3PY_SRC_DIR = full - compileall.compile_dir(Z3PY_SRC_DIR, force=1) - for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(Z3PY_SRC_DIR)): - try: - os.remove('%s/%s' % (BUILD_DIR, pyc)) - except: - pass - os.rename('%s/%s' % (Z3PY_SRC_DIR, pyc), '%s/%s' % (BUILD_DIR, pyc)) - if is_verbose(): - print "Generated '%s'" % pyc if VERBOSE: print "Python bindinds directory was detected." @@ -1008,6 +998,18 @@ def mk_def_files(): if c.require_def_file(): mk_def_file(c) +def cp_z3pyc_to_build(): + mk_dir(BUILD_DIR) + compileall.compile_dir(Z3PY_SRC_DIR, force=1) + for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(Z3PY_SRC_DIR)): + try: + os.remove('%s/%s' % (BUILD_DIR, pyc)) + except: + pass + os.rename('%s/%s' % (Z3PY_SRC_DIR, pyc), '%s/%s' % (BUILD_DIR, pyc)) + if is_verbose(): + print "Generated '%s'" % pyc + def mk_bindings(api_files): if not ONLY_MAKEFILES: mk_z3consts_py(api_files) @@ -1020,7 +1022,8 @@ def mk_bindings(api_files): g = {} g["API_FILES"] = new_api_files execfile('scripts/update_api.py', g) # HACK - + cp_z3pyc_to_build() + # Extract enumeration types from API files, and add python definitions. def mk_z3consts_py(api_files): if Z3PY_SRC_DIR == None: From d909852e992ce04045a66a7e63776d7d48b4e126 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 13:11:49 -0700 Subject: [PATCH 31/35] fixed z3py build Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 349f9b562..aabf4994e 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -192,6 +192,7 @@ def set_z3py_dir(p): print "Python bindinds directory was detected." def add_z3py_example(p): + mk_dir(BUILD_DIR) full = '%s/%s' % (EXAMPLE_DIR, p) for py in filter(lambda f: f.endswith('.py'), os.listdir(full)): shutil.copyfile('%s/%s' % (full, py), '%s/%s' % (BUILD_DIR, py)) From ff4b9daf1a9ae7df4332a8f724d7531368466980 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 28 Oct 2012 17:55:11 -0700 Subject: [PATCH 32/35] fix solution generation for quantified integer arithmetic. Added unit tests Signed-off-by: Nikolaj Bjorner --- src/muz_qe/qe.cpp | 239 +++++++++++++++-------------- src/muz_qe/qe.h | 37 ++++- src/muz_qe/qe_arith_plugin.cpp | 138 ++++++++++------- src/muz_qe/qe_datatype_plugin.cpp | 28 +++- src/test/dead/qe_defs.cpp | 87 ----------- src/test/quant_solve.cpp | 241 +++++++++++++++++++----------- 6 files changed, 418 insertions(+), 352 deletions(-) delete mode 100644 src/test/dead/qe_defs.cpp diff --git a/src/muz_qe/qe.cpp b/src/muz_qe/qe.cpp index 2c384596d..6bda83d32 100644 --- a/src/muz_qe/qe.cpp +++ b/src/muz_qe/qe.cpp @@ -45,6 +45,7 @@ Revision History: #include "cooperate.h" #include "tactical.h" #include "model_v2_pp.h" +#include "obj_hashtable.h" namespace qe { @@ -723,6 +724,85 @@ namespace qe { } }; + // ---------------------------- + // def_vector + + void def_vector::normalize() { + // apply nested definitions into place. + ast_manager& m = m_vars.get_manager(); + expr_substitution sub(m); + scoped_ptr rep = mk_expr_simp_replacer(m); + if (size() <= 1) { + return; + } + for (unsigned i = size(); i > 0; ) { + --i; + expr_ref e(m); + e = def(i); + rep->set_substitution(&sub); + (*rep)(e); + sub.insert(m.mk_const(var(i)), e); + def_ref(i) = e; + } + } + + void def_vector::project(unsigned num_vars, app* const* vars) { + obj_hashtable fns; + for (unsigned i = 0; i < num_vars; ++i) { + fns.insert(vars[i]->get_decl()); + } + for (unsigned i = 0; i < size(); ++i) { + if (fns.contains(m_vars[i].get())) { + // + // retain only first occurrence of eliminated variable. + // later occurrences are just recycling the name. + // + fns.remove(m_vars[i].get()); + } + else { + for (unsigned j = i+1; j < size(); ++j) { + m_vars[j-1] = m_vars[j]; + m_defs[j-1] = m_defs[j]; + } + m_vars.pop_back(); + m_defs.pop_back(); + --i; + } + } + } + + // ---------------------------- + // guarded_defs + + std::ostream& guarded_defs::display(std::ostream& out) const { + ast_manager& m = m_guards.get_manager(); + for (unsigned i = 0; i < size(); ++i) { + for (unsigned j = 0; j < defs(i).size(); ++j) { + out << defs(i).var(j)->get_name() << " := " << mk_pp(defs(i).def(j), m) << "\n"; + } + out << "if " << mk_pp(guard(i), m) << "\n"; + } + return out; + } + + bool guarded_defs::inv() { + return m_defs.size() == m_guards.size(); + } + + void guarded_defs::add(expr* guard, def_vector const& defs) { + SASSERT(inv()); + m_defs.push_back(defs); + m_guards.push_back(guard); + m_defs.back().normalize(); + SASSERT(inv()); + } + + void guarded_defs::project(unsigned num_vars, app* const* vars) { + for (unsigned i = 0; i < size(); ++i) { + m_defs[i].project(num_vars, vars); + } + } + // ---------------------------- // Obtain atoms in NNF formula. @@ -810,7 +890,7 @@ namespace qe { virtual lbool eliminate_exists( unsigned num_vars, app* const* vars, - expr_ref& fml, app_ref_vector& free_vars, bool get_first, def_vector* defs) = 0; + expr_ref& fml, app_ref_vector& free_vars, bool get_first, guarded_defs* defs) = 0; virtual void set_assumption(expr* fml) = 0; @@ -918,40 +998,25 @@ namespace qe { } } - bool get_leaf_rec(expr_ref& fml, def_vector& defs) { + void get_leaves_rec(def_vector& defs, guarded_defs& gdefs) { expr* f = this->fml(); + unsigned sz = defs.size(); + defs.append(def()); if (m_children.empty() && f && !m.is_false(f) && m_vars.empty() && !has_var()) { - fml = f; - return true; + gdefs.add(f, defs); } - unsigned sz = defs.size(); - for (unsigned i = 0; i < m_children.size(); ++i) { - search_tree* st = m_children[i]; - defs.append(st->def()); - if (st->get_leaf_rec(fml, defs)) { - return true; + else { + for (unsigned i = 0; i < m_children.size(); ++i) { + m_children[i]->get_leaves_rec(defs, gdefs); } - defs.shrink(sz); } - return false; + defs.shrink(sz); } - void get_leaf(expr_ref& fml, def_vector& defs) { - get_leaf_rec(fml, defs); - - // apply nested definitions into place. - expr_substitution sub(m); - scoped_ptr rep = mk_expr_simp_replacer(m); - for (unsigned i = defs.size(); i > 0; ) { - --i; - expr_ref e(m); - e = defs.def(i); - rep->set_substitution(&sub); - (*rep)(e); - sub.insert(m.mk_const(defs.var(i)), e); - defs.def_ref(i) = e; - } + void get_leaves(guarded_defs& gdefs) { + def_vector defs(m); + get_leaves_rec(defs, gdefs); } void reset() { @@ -1248,7 +1313,7 @@ namespace qe { app_ref_vector m_new_vars; // variables added by solvers bool m_get_first; // get first satisfying branch. - def_vector* m_defs; + guarded_defs* m_defs; nnf_normalizer m_nnf; // nnf conversion @@ -1311,7 +1376,7 @@ namespace qe { void check(unsigned num_vars, app* const* vars, expr* assumption, expr_ref& fml, bool get_first, - app_ref_vector& free_vars, def_vector* defs) { + app_ref_vector& free_vars, guarded_defs* defs) { reset(); m_solver.push(); @@ -1366,9 +1431,11 @@ namespace qe { expr_ref_vector result(m); m_root.get_leaves(result); m_bool_rewriter.mk_or(result.size(), result.c_ptr(), fml); - } - else if (defs) { - m_root.get_leaf(fml, *defs); + } + + if (defs) { + m_root.get_leaves(*defs); + defs->project(num_vars, vars); } TRACE("qe", @@ -1401,7 +1468,7 @@ namespace qe { private: void final_check(model_evaluator& model_eval) { - TRACE("qe", tout << (m_fml?"fml":"null") << "\n";); + TRACE("qe", tout << "\n";); while (can_propagate_assignment(model_eval)) { propagate_assignment(model_eval); } @@ -1480,7 +1547,7 @@ namespace qe { m_qe.eliminate_exists(1, &var, fml, m_free_vars, false, 0); } - lbool eliminate_exists(unsigned num_vars, app* const* vars, expr_ref& fml, bool get_first, def_vector* defs) { + lbool eliminate_exists(unsigned num_vars, app* const* vars, expr_ref& fml, bool get_first, guarded_defs* defs) { return m_qe.eliminate_exists(num_vars, vars, fml, m_free_vars, get_first, defs); } @@ -1700,7 +1767,7 @@ namespace qe { void propagate_assignment(model_evaluator& model_eval) { if (m_fml) { - update_current(model_eval, true); + update_status st = update_current(model_eval, true); } } @@ -1982,7 +2049,7 @@ namespace qe { virtual lbool eliminate_exists( unsigned num_vars, app* const* vars, expr_ref& fml, - app_ref_vector& free_vars, bool get_first, def_vector* defs) { + app_ref_vector& free_vars, bool get_first, guarded_defs* defs) { if (get_first) { return eliminate_block(num_vars, vars, fml, free_vars, get_first, defs); } @@ -2008,7 +2075,7 @@ namespace qe { lbool eliminate_block( unsigned num_vars, app* const* vars, expr_ref& fml, - app_ref_vector& free_vars, bool get_first, def_vector* defs) { + app_ref_vector& free_vars, bool get_first, guarded_defs* defs) { checkpoint(); @@ -2094,54 +2161,6 @@ namespace qe { }; - - -#if 0 - // - // Instantiation based quantifier elimination procedure. - // try a few loops of checking satisfiability. - // substitute in model values for bound variables. - // - class quant_elim_inst : public quant_elim { - ast_manager& - public: - quant_elim_inst(ast_manager& m): m(m) {} - - virtual lbool eliminate_exists( - unsigned num_vars, app* const* vars, - expr_ref& fml, app_ref_vector& free_vars, bool get_first, def_vector* defs) { - - } - - virtual void set_assumption(expr* fml) {} - - virtual void collect_statistics(statistics & st) const { - m_solver.collect_statistics(st); - } - - virtual void eliminate(bool is_forall, unsigned num_vars, app* const* vars, expr_ref& fml) { - if (is_forall) { - fml = m.mk_not(fml); - r = eliminate_exists(num_vars, vars, fml, free_vars, false, defs); - fml = m.mk_not(fml); - } - else { - r = eliminate_exists(num_vars, vars, fml, free_vars, false, defs); - } - } - - virtual void set_cancel(bool f) { - m_solver.set_cancel(f); - } - - virtual void updt_params(params_ref const& p) { - m_solver.updt_params(p); - } - - }; -#endif - - // ------------------------------------------------ // expr_quant_elim @@ -2310,40 +2329,28 @@ namespace qe { lbool expr_quant_elim::first_elim(unsigned num_vars, app* const* vars, expr_ref& fml, def_vector& defs) { app_ref_vector fvs(m); init_qe(); - return m_qe->eliminate_exists(num_vars, vars, fml, fvs, true, &defs); - } - - bool expr_quant_elim::solve_for_var(app* var, expr* _fml, expr_ref_vector& terms, expr_ref_vector& fmls) { - expr_ref assms(m.mk_true(), m); - func_decl* v = var->get_decl(); - init_qe(); - while (true) { - def_vector defs(m); - app_ref_vector fvs(m); - m_qe->set_assumption(assms); - expr_ref fml(_fml, m); - lbool is_sat = m_qe->eliminate_exists(1, &var, fml, fvs, true, &defs); - switch (is_sat) { - case l_false: return true; - case l_undef: return false; - default: break; - } - bool found = false; - for (unsigned i = 0; !found && i < defs.size(); ++i) { - if (defs.var(i) == v) { - terms.push_back(defs.def(i)); - fmls.push_back(fml); - found = true; - } - } - if (!found) { - NOT_IMPLEMENTED_YET(); - } - assms = m.mk_and(assms, m.mk_not(fml)); + guarded_defs gdefs(m); + lbool res = m_qe->eliminate_exists(num_vars, vars, fml, fvs, true, &gdefs); + if (gdefs.size() > 0) { + defs.reset(); + defs.append(gdefs.defs(0)); + fml = gdefs.guard(0); } - return true; + return res; } + bool expr_quant_elim::solve_for_var(app* var, expr* fml, guarded_defs& defs) { + return solve_for_vars(1,&var, fml, defs); + } + + bool expr_quant_elim::solve_for_vars(unsigned num_vars, app* const* vars, expr* _fml, guarded_defs& defs) { + app_ref_vector fvs(m); + expr_ref fml(_fml, m); + TRACE("qe", tout << mk_pp(fml, m) << "\n";); + init_qe(); + lbool is_sat = m_qe->eliminate_exists(num_vars, vars, fml, fvs, false, &defs); + return is_sat != l_undef; + } void expr_quant_elim::set_cancel(bool f) { if (m_qe) { diff --git a/src/muz_qe/qe.h b/src/muz_qe/qe.h index 4a444ac26..4ca098f73 100644 --- a/src/muz_qe/qe.h +++ b/src/muz_qe/qe.h @@ -226,8 +226,10 @@ namespace qe { class def_vector { func_decl_ref_vector m_vars; expr_ref_vector m_defs; + def_vector& operator=(def_vector const& other); public: def_vector(ast_manager& m): m_vars(m), m_defs(m) {} + def_vector(def_vector const& other): m_vars(other.m_vars), m_defs(other.m_defs) {} void push_back(func_decl* v, expr* e) { m_vars.push_back(v); m_defs.push_back(e); @@ -240,6 +242,33 @@ namespace qe { func_decl* var(unsigned i) const { return m_vars[i]; } expr* def(unsigned i) const { return m_defs[i]; } expr_ref_vector::element_ref def_ref(unsigned i) { return m_defs[i]; } + void normalize(); + void project(unsigned num_vars, app* const* vars); + }; + + /** + \brief Guarded definitions. + + A realizer to a an existential quantified formula is a disjunction + together with a substitution from the existentially quantified variables + to terms such that: + 1. The original formula (exists (vars) fml) is equivalent to the disjunction of guards. + 2. Each guard is equivalent to fml where 'vars' are replaced by the substitution associated + with the guard. + */ + + class guarded_defs { + expr_ref_vector m_guards; + vector m_defs; + bool inv(); + public: + guarded_defs(ast_manager& m): m_guards(m) { SASSERT(inv()); } + void add(expr* guard, def_vector const& defs); + unsigned size() const { return m_guards.size(); } + def_vector const& defs(unsigned i) const { return m_defs[i]; } + expr* guard(unsigned i) const { return m_guards[i]; } + std::ostream& display(std::ostream& out) const; + void project(unsigned num_vars, app* const* vars); }; class quant_elim; @@ -277,10 +306,12 @@ namespace qe { \brief solve for (exists (var) fml). Return false if operation failed. Return true and list of pairs (t_i, fml_i) in - such that fml[t_1] \/ ... \/ fml[t_n] == (exists (var) fml) - and fml_i == fml[t_1] + such that fml_1 \/ ... \/ fml_n == (exists (var) fml) + and fml_i => fml[t_i] */ - bool solve_for_var(app* var, expr* fml, expr_ref_vector& terms, expr_ref_vector& fmls); + bool solve_for_var(app* var, expr* fml, guarded_defs& defs); + + bool solve_for_vars(unsigned num_vars, app* const* vars, expr* fml, guarded_defs& defs); void set_cancel(bool f); diff --git a/src/muz_qe/qe_arith_plugin.cpp b/src/muz_qe/qe_arith_plugin.cpp index 0dc1a63e2..f8fe967c0 100644 --- a/src/muz_qe/qe_arith_plugin.cpp +++ b/src/muz_qe/qe_arith_plugin.cpp @@ -367,16 +367,6 @@ namespace qe { simplify(result); } - expr_ref mk_idiv(expr* a, numeral const & k) { - if (k.is_one()) { - return expr_ref(a, m); - } - expr_ref result(m); - result = m_arith.mk_idiv(a, m_arith.mk_numeral(k, true)); - simplify(result); - return result; - } - expr* mk_numeral(numeral const& k, bool is_int = true) { return m_arith.mk_numeral(k, is_int); } expr* mk_numeral(int k, bool is_int) { return mk_numeral(numeral(k),is_int); } @@ -1699,6 +1689,40 @@ public: private: + /** + \brief Compute least upper/greatest lower bounds for x. + + Assume: + (not (= k 0)) + (<= 0 (mod m k)) + (< (mod m k) (abs k)) + (= m (+ (* k (div m k)) (mod m k))) + i.e. + k * (e div k) + (e mod k) = e + + + When k is positive, least upper bound + for x such that: k*x <= e is e div k + + When k is negative, greatest lower bound + for x such that k*x <= e is e div k + + k * (e div k) + (e mod k) = e + */ + expr_ref mk_idiv(expr* e, numeral k) { + SASSERT(!k.is_zero()); + arith_util& a = m_util.m_arith; + if (k.is_one()) { + return expr_ref(e, m); + } + if (k.is_minus_one()) { + return expr_ref(a.mk_uminus(e), m); + } + SASSERT(a.is_int(e)); + return expr_ref(a.mk_idiv(e, a.mk_numeral(k, true)), m); + } + + void get_def(contains_app& contains_x, unsigned v, expr* fml, expr_ref& def) { app* x = contains_x.x(); x_subst x_t(m_util); @@ -1730,35 +1754,30 @@ public: // a*x + term <= 0 expr_ref term(bounds.exprs(is_strict, !is_lower)[i], m); rational a = bounds.coeffs(is_strict, !is_lower)[i]; + if (x_t.get_term()) { - // a*(c*x' + s) + term <= 0 - // term <- a*s + term - // a <- a*c - term = m_util.mk_add(m_util.mk_mul(a,x_t.get_term()), term); - a = a * x_t.get_coeff(); + // x := coeff * x' + s + // solve instead for + // a*coeff*x' + term + a*s <= 0 + TRACE("qe", tout << x_t.get_coeff() << "* " << mk_pp(x,m) << " + " + << mk_pp(x_t.get_term(), m) << "\n";); + SASSERT(x_t.get_coeff().is_pos()); + term = m_util.mk_add(term, m_util.mk_mul(a, x_t.get_term())); + a = a * x_t.get_coeff(); } + + TRACE("qe", tout << a << "* " << mk_pp(x,m) << " + " << mk_pp(term, m) << " <= 0\n";); SASSERT(a.is_int()); - if (is_lower) { - // a*x + t <= 0 - // <= - // x <= -t div a - SASSERT(a.is_pos()); - term = m_util.mk_idiv(m_util.mk_uminus(term), a); - } - else { - // -a*x + t <= 0 - // <=> - // t <= a*x - // <= - // ((div t a) + 1) <= x - term = m_util.mk_idiv(term, abs(a)); - if (!(abs(a).is_one())) { - term = m_util.mk_add(term, m_util.mk_one(x)); - } - } - terms.push_back(term); SASSERT(is_lower == a.is_pos()); - TRACE("qe", tout << is_lower << " " << a << " " << mk_pp(term, m) << "\n";); + + // a*x + t <= 0 + // <= + // x <= -t div a + 1 + + term = m_util.mk_uminus(term); + term = mk_idiv(term, a); + terms.push_back(term); + TRACE("qe", tout << "a: " << a << " term: " << mk_pp(term, m) << "\n";); } is_strict = true; sz = bounds.size(is_strict, !is_lower); @@ -1788,14 +1807,11 @@ public: } if (x_t.get_term()) { - // - // x = x_t.get_coeff()*x' + x_t.get_term() - // => - // x' = (x - x_t.get_term()) div x_t.get_coeff() - // - def = m_util.mk_idiv(m_util.mk_sub(def, x_t.get_term()), x_t.get_coeff()); + // x := coeff * x + s + TRACE("qe", tout << x_t.get_coeff() << "* " << mk_pp(x,m) << " + " + << mk_pp(x_t.get_term(), m) << "\n";); + def = m_util.mk_add(m_util.mk_mul(x_t.get_coeff(), def), x_t.get_term()); } - m_util.simplify(def); return; } @@ -1822,25 +1838,39 @@ public: // assert v => (x <= t_i) // SASSERT(v < bounds.size(is_strict, is_lower)); - expr_ref t(bounds.exprs(is_strict, is_lower)[v], m); + def = bounds.exprs(is_strict, is_lower)[v]; rational a = bounds.coeffs(is_strict, is_lower)[v]; - - t = x_t.mk_term(a, t); - a = x_t.mk_coeff(a); - def = t; - if (a.is_pos()) { - def = m_util.mk_uminus(def); - } if (x_t.get_term()) { - def = m_util.mk_idiv(m_util.mk_sub(def, x_t.get_term()), x_t.get_coeff()); + // x := coeff * x' + s + // solve instead for + // a*coeff*x' + term + a*s <= 0 + TRACE("qe", tout << x_t.get_coeff() << "* " << mk_pp(x,m) << " + " + << mk_pp(x_t.get_term(), m) << "\n";); + SASSERT(x_t.get_coeff().is_pos()); + def = m_util.mk_add(def, m_util.mk_mul(a, x_t.get_term())); + a = a * x_t.get_coeff(); } - if (!a.is_one()) { - def = m_util.mk_idiv(def, a); + + SASSERT(a.is_int()); + SASSERT(is_lower != a.is_pos()); + + // a*x + t <= 0 + // <= + // x <= -t div a + + def = m_util.mk_uminus(def); + def = mk_idiv(def, a); + + if (x_t.get_term()) { + // x := coeff * x + s + def = m_util.mk_add(m_util.mk_mul(x_t.get_coeff(), def), x_t.get_term()); } + m_util.simplify(def); - TRACE("qe", tout << "TBD: " << a << " " << mk_pp(t, m) << "\n";); + + TRACE("qe", tout << "TBD: " << a << " " << mk_pp(def, m) << "\n";); } expr_ref mk_not(expr* e) { diff --git a/src/muz_qe/qe_datatype_plugin.cpp b/src/muz_qe/qe_datatype_plugin.cpp index 9584241db..f200262be 100644 --- a/src/muz_qe/qe_datatype_plugin.cpp +++ b/src/muz_qe/qe_datatype_plugin.cpp @@ -467,10 +467,10 @@ namespace qe { SASSERT(m_datatype_util.is_datatype(s)); TRACE("quant_elim", tout << mk_pp(x.x(), m) << " " << vl << "\n";); if (m_datatype_util.is_recursive(s)) { - subst_rec(x, vl, fml); + subst_rec(x, vl, fml, def); } else { - subst_nonrec(x, vl, fml); + subst_nonrec(x, vl, fml, def); } if (def) { *def = 0; // TBD @@ -501,14 +501,21 @@ namespace qe { private: + void add_def(expr* term, expr_ref* def) { + if (def) { + *def = term; + } + } + // // replace x by C(y1,..,yn) where y1,..,yn are fresh variables. // - void subst_constructor(contains_app& x, func_decl* c, expr_ref& fml) { + void subst_constructor(contains_app& x, func_decl* c, expr_ref& fml, expr_ref* def) { subst_clos* sub = 0; if (m_subst_cache.find(x.x(), c, sub)) { m_replace->apply_substitution(x.x(), sub->first, 0, fml); + add_def(sub->first, def); for (unsigned i = 0; i < sub->second.size(); ++i) { m_ctx.add_var(sub->second[i]); } @@ -529,6 +536,7 @@ namespace qe { m_trail.push_back(c); m_trail.push_back(t); + add_def(t, def); m_replace->apply_substitution(x.x(), t, 0, fml); sub->first = t; m_subst_cache.insert(x.x(), c, sub); @@ -643,7 +651,7 @@ namespace qe { } } - void subst_rec(contains_app& contains_x, rational const& vl, expr_ref& fml) { + void subst_rec(contains_app& contains_x, rational const& vl, expr_ref& fml, expr_ref* def) { app* x = contains_x.x(); sort* s = x->get_decl()->get_range(); SASSERT(m_datatype_util.is_datatype(s)); @@ -661,6 +669,7 @@ namespace qe { app_ref fresh_x(m.mk_fresh_const("x", s), m); m_ctx.add_var(fresh_x); m_replace->apply_substitution(x, fresh_x, 0, fml); + add_def(fresh_x, def); TRACE("quant_elim", tout << "Add recognizer " << mk_pp(is_c, m) << "\n";); return; } @@ -668,7 +677,7 @@ namespace qe { if (has_selector(contains_x, fml, c)) { TRACE("quant_elim", tout << "Eliminate selector " << mk_ll_pp(c, m) << "\n";); - subst_constructor(contains_x, c, fml); + subst_constructor(contains_x, c, fml, def); return; } @@ -697,6 +706,7 @@ namespace qe { if (idx < eqs.num_eqs()) { expr* t = eqs.eq(idx); expr* c = eqs.eq_cond(idx); + add_def(t, def); m_replace->apply_substitution(x, t, fml); if (!m.is_true(c)) { fml = m.mk_and(c, fml); @@ -710,6 +720,10 @@ namespace qe { for (unsigned i = 0; i < eqs.num_neqs(); ++i) { m_replace->apply_substitution(eqs.neq_atom(i), m.mk_true(), fml); } + if (def) { + NOT_IMPLEMENTED_YET(); + // you need to create a diagonal term + } } TRACE("quant_elim", tout << "reduced " << mk_pp(fml.get(), m) << "\n";); } @@ -753,7 +767,7 @@ namespace qe { m_ctx.add_constraint(true, is_c); } - virtual void subst_nonrec(contains_app& x, rational const& vl, expr_ref& fml) { + virtual void subst_nonrec(contains_app& x, rational const& vl, expr_ref& fml, expr_ref* def) { sort* s = x.x()->get_decl()->get_range(); SASSERT(m_datatype_util.is_datatype(s)); SASSERT(!m_datatype_util.is_recursive(s)); @@ -767,7 +781,7 @@ namespace qe { SASSERT(vl.get_unsigned() < sz); c = (*m_datatype_util.get_datatype_constructors(s))[vl.get_unsigned()]; } - subst_constructor(x, c, fml); + subst_constructor(x, c, fml, def); } diff --git a/src/test/dead/qe_defs.cpp b/src/test/dead/qe_defs.cpp deleted file mode 100644 index d1c8232d8..000000000 --- a/src/test/dead/qe_defs.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "arith_decl_plugin.h" -#include "qe.h" -#include "ast_pp.h" -#include "smtparser.h" -#include "reg_decl_plugins.h" - - -static void test_defs(ast_manager& m, expr* _fml) { - arith_util a(m); - app_ref x(m); - qe::def_vector defs(m); - expr_ref fml(_fml, m); - x = m.mk_const(symbol("x"), a.mk_int()); - app* vars[1] = { x.get() }; - front_end_params fparams; - qe::expr_quant_elim qelim(m, fparams); - lbool result = qelim.first_elim(1, vars, fml, defs); - std::cout << mk_pp(_fml, m) << "\n--->\n"; - std::cout << mk_pp(fml, m) << "\n"; - for (unsigned i = 0; i < defs.size(); ++i) { - std::cout << defs.var(i)->get_name() << " " - << mk_pp(defs.def(i), m) << "\n"; - } - std::cout << "\n"; -} - -static void test_defs_all(ast_manager& m, expr* _fml) { - arith_util a(m); - app_ref x(m); - expr_ref fml(_fml, m), fml0(_fml, m); - x = m.mk_const(symbol("x"), a.mk_int()); - app* vars[1] = { x.get() }; - front_end_params fparams; - qe::expr_quant_elim qelim(m, fparams); - lbool result = l_true; - while (result == l_true) { - fml = fml0; - qe::def_vector defs(m); - result = qelim.first_elim(1, vars, fml, defs); - std::cout << result << "\n"; - std::cout << mk_pp(fml, m) << "\n"; - for (unsigned i = 0; i < defs.size(); ++i) { - std::cout << defs.var(i)->get_name() << " " - << mk_pp(defs.def(i), m) << "\n"; - } - fml0 = m.mk_and(fml0, m.mk_not(fml)); - } -} - -static void test_defs(char const* str) { - ast_manager m; - reg_decl_plugins(m); - scoped_ptr parser = smtlib::parser::create(m); - parser->initialize_smtlib(); - std::ostringstream buffer; - buffer << "(benchmark presburger :status unknown :logic AUFLIA " - << ":extrafuns ((x Int) (y Int) (z Int))\n" - << ":formula " << str << ")"; - parser->parse_string(buffer.str().c_str()); - smtlib::benchmark* b = parser->get_benchmark(); - smtlib::theory::expr_iterator it = b->begin_formulas(); - smtlib::theory::expr_iterator end = b->end_formulas(); - for (; it != end; ++it) { - test_defs(m, *it); - } -} - -void tst_qe_defs() { - enable_trace("qe"); - test_defs("(and (<= (* 2 x) y) (>= (* 3 x) z) (<= (* 4 x) (* 2 z)) (= (mod x 2) 0))"); - - return; - test_defs("(and (<= (* 2 x) y) (>= (* 3 x) z) (= (mod x 2) 0))"); - test_defs("(and (<= (* 2 x) y) (= (mod x 2) 0))"); - test_defs("(= (* 2 x) y)"); - test_defs("(or (< x 0) (> x 1))"); - test_defs("(or (< x y) (> x y))"); - test_defs("(= x y)"); - test_defs("(<= x y)"); - test_defs("(>= x y)"); - test_defs("(and (<= (+ x y) 0) (<= (+ x z) 0))"); - test_defs("(and (<= (+ x y) 0) (<= (+ (* 2 x) z) 0))"); - test_defs("(and (<= (+ (* 3 x) y) 0) (<= (+ (* 2 x) z) 0))"); - test_defs("(and (>= x y) (>= x z))"); - test_defs("(< x y)"); - test_defs("(> x y)"); -} diff --git a/src/test/quant_solve.cpp b/src/test/quant_solve.cpp index 003ae26b4..d78f61e34 100644 --- a/src/test/quant_solve.cpp +++ b/src/test/quant_solve.cpp @@ -8,39 +8,82 @@ #include "expr_replacer.h" #include "smt_solver.h" #include "reg_decl_plugins.h" +#include "smtparser.h" +#include "expr_abstract.h" +#include "model_smt2_pp.h" -static void validate_quant_solution(ast_manager& m, app* x, expr* fml, expr* t, expr* new_fml) { +static void validate_quant_solution(ast_manager& m, expr* fml, expr* guard, qe::def_vector const& defs) { // verify: - // new_fml <=> fml[t/x] + // new_fml => fml[t/x] scoped_ptr rep = mk_expr_simp_replacer(m); + app_ref_vector xs(m); expr_substitution sub(m); - sub.insert(x, t); + for (unsigned i = 0; i < defs.size(); ++i) { + xs.push_back(m.mk_const(defs.var(i))); + sub.insert(xs.back(), defs.def(i)); + } rep->set_substitution(&sub); expr_ref fml1(fml, m); (*rep)(fml1); expr_ref tmp(m); - tmp = m.mk_not(m.mk_iff(new_fml, fml1)); + tmp = m.mk_not(m.mk_implies(guard, fml1)); front_end_params fp; smt::solver solver(m, fp); solver.assert_expr(tmp); lbool res = solver.check(); - std::cout << res << "\n"; + //SASSERT(res == l_false); + if (res != l_false) { + std::cout << "Validation failed: " << res << "\n"; + std::cout << mk_pp(tmp, m) << "\n"; + model_ref model; + solver.get_model(model); + model_smt2_pp(std::cout, m, *model, 0); + fatal_error(0); + } +} + + +static void validate_quant_solutions(app* x, expr* fml, expr_ref_vector& guards) { + return; + // quant_elim option got removed... + // verify: + // fml <=> guard_1 \/ guard_2 \/ ... + ast_manager& m = guards.get_manager(); + expr_ref tmp(m), fml2(m); + tmp = m.mk_or(guards.size(), guards.c_ptr()); + expr* _x = x; + std::cout << mk_pp(fml, m) << "\n"; + expr_abstract(m, 0, 1, &_x, fml, fml2); + std::cout << mk_pp(fml2, m) << "\n"; + symbol name(x->get_decl()->get_name()); + sort* s = m.get_sort(x); + fml2 = m.mk_exists(1, &s, &name, fml2); + std::cout << mk_pp(fml2, m) << "\n"; + tmp = m.mk_not(m.mk_iff(fml2, tmp)); + std::cout << mk_pp(tmp, m) << "\n"; + front_end_params fp; + smt::solver solver(m, fp); + solver.assert_expr(tmp); + lbool res = solver.check(); + std::cout << "checked\n"; SASSERT(res == l_false); + if (res != l_false) { + std::cout << res << "\n"; + fatal_error(0); + } } static void test_quant_solver(ast_manager& m, app* x, expr* fml) { front_end_params params; - params.m_quant_elim = true; qe::expr_quant_elim qe(m, params); - expr_ref_vector terms(m); - expr_ref_vector fmls(m); - bool success = qe.solve_for_var(x, fml, terms, fmls); + qe::guarded_defs defs(m); + bool success = qe.solve_for_var(x, fml, defs); std::cout << "------------------------\n"; std::cout << mk_pp(fml, m) << "\n"; - if (success) { - for (unsigned i = 0; i < terms.size(); ++i) { - std::cout << mk_pp(x, m) << " = " << mk_pp(terms[i].get(), m) << "\n" << mk_pp(fmls[i].get(), m) << "\n"; - validate_quant_solution(m, x, fml, terms[i].get(), fmls[i].get()); + if (success) { + defs.display(std::cout); + for (unsigned i = 0; i < defs.size(); ++i) { + validate_quant_solution(m, fml, defs.guard(i), defs.defs(i)); } } else { @@ -48,32 +91,18 @@ static void test_quant_solver(ast_manager& m, app* x, expr* fml) { } } -static void test_quant_solver_rec(ast_manager& m, unsigned num_vars, app* const* xs, expr* fml) { - if (num_vars == 0) { - return; - } + +static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, expr* fml) { front_end_params params; - params.m_quant_elim = true; qe::expr_quant_elim qe(m, params); - expr_ref_vector fmls(m), ors(m), terms(m); - app* x = xs[0]; - bool success = qe.solve_for_var(x, fml, terms, fmls); + qe::guarded_defs defs(m); + bool success = qe.solve_for_vars(sz, xs, fml, defs); std::cout << "------------------------\n"; std::cout << mk_pp(fml, m) << "\n"; - if (success) { - for (unsigned i = 0; i < terms.size(); ++i) { - std::cout << mk_pp(x, m) << " = " << mk_pp(terms[i].get(), m) << "\n" << mk_pp(fmls[i].get(), m) << "\n"; - validate_quant_solution(m, x, fml, terms[i].get(), fmls[i].get()); - ors.reset(); - if (m.is_or(fmls[i].get())) { - ors.append(to_app(fmls[i].get())->get_num_args(), to_app(fmls[i].get())->get_args()); - } - else { - ors.push_back(fmls[i].get()); - } - for (unsigned j = 0; j < ors.size(); ++j) { - test_quant_solver_rec(m, num_vars-1, xs+1, ors[j].get()); - } + if (success) { + defs.display(std::cout); + for (unsigned i = 0; i < defs.size(); ++i) { + validate_quant_solution(m, fml, defs.guard(i), defs.defs(i)); } } else { @@ -82,65 +111,107 @@ static void test_quant_solver_rec(ast_manager& m, unsigned num_vars, app* const* } +static expr_ref parse_fml(ast_manager& m, char const* str) { + expr_ref result(m); + reg_decl_plugins(m); + scoped_ptr parser = smtlib::parser::create(m); + parser->initialize_smtlib(); + std::ostringstream buffer; + buffer << "(benchmark presburger :status unknown :logic AUFLIA " + << ":extrafuns ((x Int) (y Int) (z Int) (a Int) (b Int))\n" + << ":formula " << str << ")"; + parser->parse_string(buffer.str().c_str()); + smtlib::benchmark* b = parser->get_benchmark(); + smtlib::theory::expr_iterator it = b->begin_formulas(); + smtlib::theory::expr_iterator end = b->end_formulas(); + SASSERT(it != b->end_formulas()); + result = *it; + return result; +} + +static void test_quant_solver(ast_manager& m, app* x, char const* str) { + expr_ref fml = parse_fml(m, str); + test_quant_solver(m, x, fml); +} + +static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, char const* str) { + expr_ref fml = parse_fml(m, str); + test_quant_solver(m, sz, xs, fml); +} + + static void test_quant_solve1() { ast_manager m; arith_util ar(m); - reg_decl_plugins(m); sort* i = ar.mk_int(); - app_ref x(m.mk_const(symbol("x"),i), m); - app_ref y(m.mk_const(symbol("y"),i), m); - app_ref a(m.mk_const(symbol("a"),i), m); - app_ref b(m.mk_const(symbol("b"),i), m); - expr_ref n2(ar.mk_numeral(rational(2), true), m); - expr_ref n3(ar.mk_numeral(rational(3), true), m); - expr_ref n4(ar.mk_numeral(rational(4), true), m); - expr_ref n10(ar.mk_numeral(rational(10), true), m); - expr_ref n20(ar.mk_numeral(rational(20), true), m); - expr_ref x2(ar.mk_mul(n2, x), m); - expr_ref x3(ar.mk_mul(n3, x), m); - expr_ref fml1(m), fml2(m), fml3(m), fml4(m); - expr_ref fml(m), t1(m), t2(m); - - fml1 = m.mk_eq(x, a); - fml2 = ar.mk_lt(x, a); - fml3 = ar.mk_gt(x, a); - fml4 = m.mk_and(ar.mk_lt(x, a), ar.mk_lt(x, b)); - expr_ref fml5(m.mk_and(ar.mk_gt(x, a), ar.mk_lt(x, b)), m); - expr_ref fml6(ar.mk_le(x, a), m); - expr_ref fml7(ar.mk_ge(x, a), m); - expr_ref fml8(ar.mk_lt(ar.mk_mul(n2, x), a), m); - expr_ref fml9(m.mk_eq(ar.mk_mul(n2, x), a), m); - - test_quant_solver(m, x.get(), fml1.get()); - test_quant_solver(m, x.get(), fml2.get()); - test_quant_solver(m, x.get(), fml3.get()); - test_quant_solver(m, x.get(), fml4.get()); - test_quant_solver(m, x.get(), fml5.get()); - test_quant_solver(m, x.get(), fml6.get()); - test_quant_solver(m, x.get(), fml7.get()); - test_quant_solver(m, x.get(), fml8.get()); - test_quant_solver(m, x.get(), fml9.get()); - - fml = ar.mk_lt(x2, a); test_quant_solver(m, x.get(), fml.get()); - fml = ar.mk_gt(x2, a); test_quant_solver(m, x.get(), fml.get()); - fml = ar.mk_le(x2, a); test_quant_solver(m, x.get(), fml.get()); - fml = ar.mk_ge(x2, a); test_quant_solver(m, x.get(), fml.get()); + app_ref xr(m.mk_const(symbol("x"),i), m); + app_ref yr(m.mk_const(symbol("y"),i), m); + app* x = xr.get(); + app* y = yr.get(); + app* xy[2] = { x, y }; - fml = m.mk_and(ar.mk_lt(a, ar.mk_mul(n3,x)), ar.mk_lt(ar.mk_mul(n3,x), b)); - test_quant_solver(m, x.get(), fml.get()); + test_quant_solver(m, x, "(and (<= x y) (= (mod x 2) 0))"); + test_quant_solver(m, x, "(and (<= (* 2 x) y) (= (mod x 2) 0))"); + test_quant_solver(m, x, "(and (>= x y) (= (mod x 2) 0))"); + test_quant_solver(m, x, "(and (>= (* 2 x) y) (= (mod x 2) 0))"); + test_quant_solver(m, x, "(and (<= (* 2 x) y) (>= x z) (= (mod x 2) 0))"); + test_quant_solver(m, x, "(and (<= (* 2 x) y) (>= (* 3 x) z) (= (mod x 2) 0))"); + + test_quant_solver(m, x, "(>= (* 2 x) a)"); + + test_quant_solver(m, x, "(<= (* 2 x) a)"); + test_quant_solver(m, x, "(< (* 2 x) a)"); + test_quant_solver(m, x, "(= (* 2 x) a)"); + test_quant_solver(m, x, "(< (* 2 x) a)"); + test_quant_solver(m, x, "(> (* 2 x) a)"); + + + test_quant_solver(m, x, "(and (<= a x) (<= (* 2 x) b))"); + + test_quant_solver(m, x, "(and (<= a x) (<= x b))"); + test_quant_solver(m, x, "(and (<= (* 2 a) x) (<= x b))"); + test_quant_solver(m, x, "(and (<= (* 2 a) x) (<= (* 2 x) b))"); + test_quant_solver(m, x, "(and (<= a x) (<= (* 3 x) b))"); + test_quant_solver(m, x, "(and (<= (* 3 a) x) (<= x b))"); + test_quant_solver(m, x, "(and (<= (* 3 a) x) (<= (* 3 x) b))"); + + test_quant_solver(m, x, "(and (< a (* 3 x)) (< (* 3 x) b))"); + + test_quant_solver(m, x, "(< (* 3 x) a)"); + test_quant_solver(m, x, "(= (* 3 x) a)"); + test_quant_solver(m, x, "(< (* 3 x) a)"); + test_quant_solver(m, x, "(> (* 3 x) a)"); + test_quant_solver(m, x, "(<= (* 3 x) a)"); + test_quant_solver(m, x, "(>= (* 3 x) a)"); + + test_quant_solver(m, x, "(<= (* 2 x) a)"); + test_quant_solver(m, x, "(or (= (* 2 x) y) (= (+ (* 2 x) 1) y))"); + test_quant_solver(m, x, "(= x a)"); + test_quant_solver(m, x, "(< x a)"); + test_quant_solver(m, x, "(> x a)"); + test_quant_solver(m, x, "(and (> x a) (< x b))"); + test_quant_solver(m, x, "(and (> x a) (< x b))"); + test_quant_solver(m, x, "(<= x a)"); + test_quant_solver(m, x, "(>= x a)"); + test_quant_solver(m, x, "(and (<= (* 2 x) y) (= (mod x 2) 0))"); + test_quant_solver(m, x, "(= (* 2 x) y)"); + test_quant_solver(m, x, "(or (< x 0) (> x 1))"); + test_quant_solver(m, x, "(or (< x y) (> x y))"); + test_quant_solver(m, x, "(= x y)"); + test_quant_solver(m, x, "(<= x y)"); + test_quant_solver(m, x, "(>= x y)"); + test_quant_solver(m, x, "(and (<= (+ x y) 0) (<= (+ x z) 0))"); + test_quant_solver(m, x, "(and (<= (+ x y) 0) (<= (+ (* 2 x) z) 0))"); + test_quant_solver(m, x, "(and (<= (+ (* 3 x) y) 0) (<= (+ (* 2 x) z) 0))"); + test_quant_solver(m, x, "(and (>= x y) (>= x z))"); + test_quant_solver(m, x, "(< x y)"); + test_quant_solver(m, x, "(> x y)"); + + test_quant_solver(m, 2, xy, "(and (<= (- (* 2 y) b) (+ (* 3 x) a)) (<= (- (* 2 x) a) (+ (* 4 y) b)))"); - t1 = ar.mk_sub(ar.mk_mul(n2,y),b); - t2 = ar.mk_add(ar.mk_mul(n3,x),a); - fml1 = ar.mk_le(t1, t2); - t1 = ar.mk_sub(ar.mk_mul(n2,x),a); - t2 = ar.mk_add(ar.mk_mul(n4,y),b); - fml2 = ar.mk_le(t1,t2); - fml = m.mk_and(fml1, fml2); - app* xy[2] = { x.get(), y.get() }; - test_quant_solver_rec(m, 2, xy, fml.get()); } From 24d12793852aa92a041798f692da5ffdb028f09c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 28 Oct 2012 19:59:20 -0700 Subject: [PATCH 33/35] update unit test to use smt2parser Signed-off-by: Nikolaj Bjorner --- src/test/quant_solve.cpp | 94 ++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/src/test/quant_solve.cpp b/src/test/quant_solve.cpp index d78f61e34..16fc3bcfd 100644 --- a/src/test/quant_solve.cpp +++ b/src/test/quant_solve.cpp @@ -8,9 +8,10 @@ #include "expr_replacer.h" #include "smt_solver.h" #include "reg_decl_plugins.h" -#include "smtparser.h" #include "expr_abstract.h" #include "model_smt2_pp.h" +#include "smt2parser.h" +#include "var_subst.h" static void validate_quant_solution(ast_manager& m, expr* fml, expr* guard, qe::def_vector const& defs) { // verify: @@ -73,23 +74,6 @@ static void validate_quant_solutions(app* x, expr* fml, expr_ref_vector& guards) } } -static void test_quant_solver(ast_manager& m, app* x, expr* fml) { - front_end_params params; - qe::expr_quant_elim qe(m, params); - qe::guarded_defs defs(m); - bool success = qe.solve_for_var(x, fml, defs); - std::cout << "------------------------\n"; - std::cout << mk_pp(fml, m) << "\n"; - if (success) { - defs.display(std::cout); - for (unsigned i = 0; i < defs.size(); ++i) { - validate_quant_solution(m, fml, defs.guard(i), defs.defs(i)); - } - } - else { - std::cout << "failed\n"; - } -} static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, expr* fml) { @@ -110,28 +94,54 @@ static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, expr* } } - static expr_ref parse_fml(ast_manager& m, char const* str) { expr_ref result(m); - reg_decl_plugins(m); - scoped_ptr parser = smtlib::parser::create(m); - parser->initialize_smtlib(); + front_end_params fp; + cmd_context ctx(fp, false, &m); + ctx.set_ignore_check(true); std::ostringstream buffer; - buffer << "(benchmark presburger :status unknown :logic AUFLIA " - << ":extrafuns ((x Int) (y Int) (z Int) (a Int) (b Int))\n" - << ":formula " << str << ")"; - parser->parse_string(buffer.str().c_str()); - smtlib::benchmark* b = parser->get_benchmark(); - smtlib::theory::expr_iterator it = b->begin_formulas(); - smtlib::theory::expr_iterator end = b->end_formulas(); - SASSERT(it != b->end_formulas()); - result = *it; + buffer << "(declare-const x Int)\n" + << "(declare-const y Int)\n" + << "(declare-const z Int)\n" + << "(declare-const a Int)\n" + << "(declare-const b Int)\n" + << "(declare-datatypes () ((IList (nil) (cons (car Int) (cdr IList)))))\n" + << "(declare-const l1 IList)\n" + << "(declare-const l2 IList)\n" + << "(declare-datatypes () ((Cell (null) (cell (car Cell) (cdr Cell)))))\n" + << "(declare-const c1 Cell)\n" + << "(declare-const c2 Cell)\n" + << "(declare-const c3 Cell)\n" + << "(declare-datatypes () ((Tuple (tuple (first Int) (second Bool) (third Real)))))\n" + << "(declare-const t1 Tuple)\n" + << "(declare-const t2 Tuple)\n" + << "(declare-const t3 Tuple)\n" + << "(assert " << str << ")\n"; + std::istringstream is(buffer.str()); + VERIFY(parse_smt2_commands(ctx, is)); + SASSERT(ctx.begin_assertions() != ctx.end_assertions()); + result = *ctx.begin_assertions(); return result; } + +static void parse_fml(char const* str, app_ref_vector& vars, expr_ref& fml) { + ast_manager& m = fml.get_manager(); + fml = parse_fml(m, str); + if (is_exists(fml)) { + quantifier* q = to_quantifier(fml); + for (unsigned i = 0; i < q->get_num_decls(); ++i) { + vars.push_back(m.mk_const(q->get_decl_name(i), q->get_decl_sort(i))); + } + fml = q->get_expr(); + var_subst vs(m, true); + vs(fml, vars.size(), (expr*const*)vars.c_ptr(), fml); + } +} + static void test_quant_solver(ast_manager& m, app* x, char const* str) { expr_ref fml = parse_fml(m, str); - test_quant_solver(m, x, fml); + test_quant_solver(m, 1, &x, fml); } static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, char const* str) { @@ -139,6 +149,12 @@ static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, char c test_quant_solver(m, sz, xs, fml); } +static void test_quant_solver(ast_manager& m, char const* str) { + expr_ref fml(m); + app_ref_vector vars(m); + parse_fml(str, vars, fml); + test_quant_solver(m, vars.size(), vars.c_ptr(), fml); +} static void test_quant_solve1() { @@ -159,34 +175,26 @@ static void test_quant_solve1() { test_quant_solver(m, x, "(and (>= (* 2 x) y) (= (mod x 2) 0))"); test_quant_solver(m, x, "(and (<= (* 2 x) y) (>= x z) (= (mod x 2) 0))"); test_quant_solver(m, x, "(and (<= (* 2 x) y) (>= (* 3 x) z) (= (mod x 2) 0))"); - test_quant_solver(m, x, "(>= (* 2 x) a)"); - test_quant_solver(m, x, "(<= (* 2 x) a)"); test_quant_solver(m, x, "(< (* 2 x) a)"); test_quant_solver(m, x, "(= (* 2 x) a)"); test_quant_solver(m, x, "(< (* 2 x) a)"); test_quant_solver(m, x, "(> (* 2 x) a)"); - - test_quant_solver(m, x, "(and (<= a x) (<= (* 2 x) b))"); - test_quant_solver(m, x, "(and (<= a x) (<= x b))"); test_quant_solver(m, x, "(and (<= (* 2 a) x) (<= x b))"); test_quant_solver(m, x, "(and (<= (* 2 a) x) (<= (* 2 x) b))"); test_quant_solver(m, x, "(and (<= a x) (<= (* 3 x) b))"); test_quant_solver(m, x, "(and (<= (* 3 a) x) (<= x b))"); test_quant_solver(m, x, "(and (<= (* 3 a) x) (<= (* 3 x) b))"); - test_quant_solver(m, x, "(and (< a (* 3 x)) (< (* 3 x) b))"); - test_quant_solver(m, x, "(< (* 3 x) a)"); test_quant_solver(m, x, "(= (* 3 x) a)"); test_quant_solver(m, x, "(< (* 3 x) a)"); test_quant_solver(m, x, "(> (* 3 x) a)"); test_quant_solver(m, x, "(<= (* 3 x) a)"); test_quant_solver(m, x, "(>= (* 3 x) a)"); - test_quant_solver(m, x, "(<= (* 2 x) a)"); test_quant_solver(m, x, "(or (= (* 2 x) y) (= (+ (* 2 x) 1) y))"); test_quant_solver(m, x, "(= x a)"); @@ -209,9 +217,13 @@ static void test_quant_solve1() { test_quant_solver(m, x, "(and (>= x y) (>= x z))"); test_quant_solver(m, x, "(< x y)"); test_quant_solver(m, x, "(> x y)"); - test_quant_solver(m, 2, xy, "(and (<= (- (* 2 y) b) (+ (* 3 x) a)) (<= (- (* 2 x) a) (+ (* 4 y) b)))"); + test_quant_solver(m, "(exists ((c Cell)) (= c null))"); + test_quant_solver(m, "(exists ((c Cell)) (= c (cell null c1)))"); + //TBD: + //test_quant_solver(m, "(exists ((c Cell)) (= (cell c c) c1))"); + //test_quant_solver(m, "(exists ((c Cell)) (not (= c null)))"); } From 808d8a69b45dafec6481f456e0d31895d43716db Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 22:48:46 -0700 Subject: [PATCH 34/35] fixed compilation problems Signed-off-by: Leonardo de Moura --- src/muz_qe/qe.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/muz_qe/qe.cpp b/src/muz_qe/qe.cpp index 6bda83d32..e678fbb3e 100644 --- a/src/muz_qe/qe.cpp +++ b/src/muz_qe/qe.cpp @@ -761,8 +761,8 @@ namespace qe { } else { for (unsigned j = i+1; j < size(); ++j) { - m_vars[j-1] = m_vars[j]; - m_defs[j-1] = m_defs[j]; + m_vars.set(j-1, m_vars.get(j)); + m_defs.set(j-1, m_defs.get(j)); } m_vars.pop_back(); m_defs.pop_back(); From 9a04ab11a7081cd86ec5bb8960e5f0ed56560c5f Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 28 Oct 2012 22:58:54 -0700 Subject: [PATCH 35/35] fixed python compatibility issues Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 2 +- scripts/update_api.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index aabf4994e..275e4212d 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1114,7 +1114,7 @@ def mk_z3consts_donet(api_files): dotnet = get_component(DOTNET_COMPONENT) - DeprecatedEnums = { 'Z3_search_failure' } + DeprecatedEnums = [ 'Z3_search_failure' ] z3consts = open('%s/Enumerations.cs' % dotnet.src_dir, 'w') z3consts.write('// Automatically generated file\n\n') z3consts.write('using System;\n\n' diff --git a/scripts/update_api.py b/scripts/update_api.py index ce0d44b4e..a9c169e58 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -335,7 +335,7 @@ def mk_dotnet(): dotnet.write(' }\n') -DotnetUnwrapped = { 'Z3_del_context' } +DotnetUnwrapped = [ 'Z3_del_context' ] def mk_dotnet_wrappers(): global Type2Str