diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000..e3e3ccfa9 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,466 @@ + +SHELL=/bin/sh +SED=sed +AWK=awk +DOS2UNIX=@D2U@ + +@SET_MAKE@ + +##### Configuration ##### +CPPFLAGS_CORE=@CPPFLAGS@ -I lib -fopenmp -msse -msse2 -mfpmath=sse +CXXFLAGS_CORE=@CXXFLAGS@ +ifeq ($(MODE),) +Z3_BUILD_MODE=external +else +Z3_BUILD_MODE=$(MODE) +endif +LIBS=@LIBS@ +## -lrt is for timer_create and timer_settime +LDFLAGS=@LDFLAGS@ -lpthread -fopenmp +LDFLAGS_EXTRA= +######################### + +Z3=z3 +TEST_CAPI=test_capi +EPR=epr +GROBNER=grobner +TEST=test + +BIN_DIR=bin/$(Z3_BUILD_MODE) +OBJ_DIR=obj/$(Z3_BUILD_MODE) +SED_OBJ_DIR=obj\/$(Z3_BUILD_MODE) +OBJ_TEST_DIR=obj-test/$(Z3_BUILD_MODE) +SED_OBJ_TEST_DIR=obj-test\/$(Z3_BUILD_MODE) + +MAJ=$(shell grep 'Z3_MAJOR_VERSION' lib/version.h | cut -d ' ' -f 4) +MIN=$(shell grep 'Z3_MINOR_VERSION' lib/version.h | cut -d ' ' -f 4) +Z3_VERSION=$(MAJ).$(MIN) + +PLATFORM=@PLATFORM@ + + +ifeq ($(Z3_BUILD_MODE),release) +CPPFLAGS=$(CPPFLAGS_CORE) -DNDEBUG +CXXFLAGS=-O3 -fomit-frame-pointer $(CXXFLAGS_CORE) +else +ifeq ($(Z3_BUILD_MODE),smtcomp07) +CPPFLAGS=$(CPPFLAGS_CORE) -DNDEBUG -DSMTCOMP +CXXFLAGS=-O3 -fomit-frame-pointer $(CXXFLAGS_CORE) +# doesn't work on cygwin +LDFLAGS_EXTRA=@STATIC_FLAGS@ +else +ifeq ($(Z3_BUILD_MODE),external) +CPPFLAGS=$(CPPFLAGS_CORE) -DNDEBUG -D_EXTERNAL_RELEASE +CXXFLAGS=-O3 -fomit-frame-pointer $(CXXFLAGS_CORE) +# doesn't work on cygwin +LDFLAGS_EXTRA=@STATIC_FLAGS@ +else +ifeq ($(Z3_BUILD_MODE),debug) +CPPFLAGS=$(CPPFLAGS_CORE) -DZ3DEBUG -D_TRACE +CXXFLAGS=-g -Wall $(CXXFLAGS_CORE) +else +ifeq ($(Z3_BUILD_MODE),debugopt) +CPPFLAGS=$(CPPFLAGS_CORE) -DNDEBUG -DZ3DEBUG -D_TRACE +CXXFLAGS=-g -O1 $(CXXFLAGS_CORE) +else +ifeq ($(Z3_BUILD_MODE),trace) +CPPFLAGS=$(CPPFLAGS_CORE) -DNDEBUG -D_TRACE +CXXFLAGS=-g -O1 $(CXXFLAGS_CORE) +else +ifeq ($(Z3_BUILD_MODE),profile) +CPPFLAGS=$(CPPFLAGS_CORE) -DNDEBUG +CXXFLAGS=-g -pg -O2 $(CXXFLAGS_CORE) +LDFLAGS_EXTRA=-pg +else +ifeq ($(Z3_BUILD_MODE),gcov) +CPPFLAGS=$(CPPFLAGS_CORE) -DNDEBUG +CXXFLAGS=-g -fprofile-arcs -ftest-coverage -O2 $(CXXFLAGS_CORE) +LDFLAGS_EXTRA=-fprofile-arcs -ftest-coverage +else +ifeq ($(Z3_BUILD_MODE),external_parallel) +CPPFLAGS=$(CPPFLAGS_CORE) -DNDEBUG -D_EXTERNAL_RELEASE -D_Z3_BUILD_PARALLEL_SMT +CXXFLAGS=-O3 -fomit-frame-pointer $(CXXFLAGS_CORE) +# doesn't work on cygwin +LDFLAGS_EXTRA=@STATIC_FLAGS@ +else +ifeq ($(Z3_BUILD_MODE),debug_parallel) +CPPFLAGS=$(CPPFLAGS_CORE) -DZ3DEBUG -D_TRACE -D_Z3_BUILD_PARALLEL_SMT +CXXFLAGS=-g -Wall $(CXXFLAGS_CORE) +else +$(error INVALID BUILD MODE = $(Z3_BUILD_MODE)) +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif + +LIBFLAGS=@SLIBFLAGS@ + +################################ +# +# Extract the source files from +# the MSVC++ project files. +# +# lib.vcproj ===> lib.srcs +# shell.vcproj ===> shell.srcs +# +################################ + +main: $(BIN_DIR)/$(Z3) + +lib.srcs: lib/lib.vcxproj + @echo Making 'lib.srcs'... + @cp $< lib0.srcs + @chmod +rw lib0.srcs + @$(DOS2UNIX) lib0.srcs + @$(AWK) '/cpp\"/{ print $$0 }' lib0.srcs > lib1.srcs + @$(SED) 's|\"||g;s|||g;s|Include=|lib/|g' lib1.srcs > lib2.srcs + @$(AWK) 'BEGIN { printf ("LIB_SRCS= "); } { printf($$1 " ") } END { print ""; }' lib2.srcs > $@ + @rm -f lib0.srcs + @rm -f lib1.srcs + @rm -f lib2.srcs + +shell.srcs: shell/shell.vcxproj + @echo Making 'shell.srcs'... + @cp $< shell0.srcs + @chmod +rw shell0.srcs + @$(DOS2UNIX) shell0.srcs + @$(AWK) '/cpp\"/{ print $$0 }' shell0.srcs > shell1.srcs + @$(SED) 's|\"||g;s|||g;s|Include=|shell/|g' shell1.srcs > shell2.srcs + @$(AWK) 'BEGIN { printf ("SHELL_SRCS= "); } { printf($$1 " ") } END { print ""; }' shell2.srcs > $@ + @rm -f shell0.srcs + @rm -f shell1.srcs + @rm -f shell2.srcs + +epr.srcs: epr/epr.vcxproj + @echo Making 'epr.srcs'... + @cp $< epr0.srcs + @chmod +rw epr0.srcs + @$(DOS2UNIX) epr0.srcs + @$(AWK) '/cpp\"/{ print $$0 }' epr0.srcs > epr1.srcs + @$(SED) 's|\"||g;s|||g;s|Include=|epr/|g' epr1.srcs > epr2.srcs + @$(AWK) 'BEGIN { printf ("EPR_SRCS= "); } { printf($$1 " ") } END { print ""; }' epr2.srcs > $@ + @rm -f epr0.srcs + @rm -f epr1.srcs + @rm -f epr2.srcs + +test.srcs: test/test.vcxproj + @echo Making 'test.srcs'... + @cp $< test0.srcs + @chmod +rw test0.srcs + @$(DOS2UNIX) test0.srcs + @$(AWK) '/cpp\"/{ print $$0 }' test0.srcs > test1.srcs + @$(SED) 's|\"||g;s|||g;s|Include=|test/|g' test1.srcs > test2.srcs + @$(AWK) 'BEGIN { printf ("TEST_SRCS= "); } { printf($$1 " ") } END { print ""; }' test2.srcs > $@ + @rm -f test0.srcs + @rm -f test1.srcs + @rm -f test2.srcs + + +include lib.srcs +include shell.srcs +include epr.srcs +include test.srcs + +LIB_SRCS+=@EXTRA_LIB_SRCS@ +LIB_OBJS=$(LIB_SRCS:lib/%.cpp=$(OBJ_DIR)/%.o) +SHELL_OBJS=$(SHELL_SRCS:shell/%.cpp=$(OBJ_DIR)/%.o) + +OBJS=$(LIB_OBJS) $(SHELL_OBJS) +TEST_CAPI_OBJS=$(OBJ_DIR)/test_capi.o $(LIB_OBJS) +EPR_OBJS=$(EPR_SRCS:epr/%.cpp=$(OBJ_DIR)/%.o) $(LIB_OBJS) +GROBNER_OBJS=$(OBJ_DIR)/grobner_main.o $(LIB_OBJS) +TEST_OBJS=$(TEST_SRCS:test/%.cpp=$(OBJ_TEST_DIR)/%.o) + +$(BIN_DIR)/$(Z3): $(OBJ_DIR) $(BIN_DIR) $(OBJS) + @mkdir -p $(BIN_DIR) + $(CXX) -o $(BIN_DIR)/$(Z3) $(OBJS) $(LDFLAGS) $(LDFLAGS_EXTRA) $(LIBS) + +$(BIN_DIR)/$(TEST): $(OBJ_DIR) $(BIN_DIR) $(LIB_OBJS) $(TEST_OBJS) + @mkdir -p $(BIN_DIR) + $(CXX) -o $(BIN_DIR)/$(TEST) $(LIB_OBJS) $(TEST_OBJS) $(LDFLAGS) $(LDFLAGS_EXTRA) $(LIBS) + +$(BIN_DIR)/$(TEST_CAPI): $(OBJ_DIR) $(BIN_DIR) $(TEST_CAPI_OBJS) + @mkdir -p $(BIN_DIR) + $(CXX) -o $(BIN_DIR)/$(TEST_CAPI) $(TEST_CAPI_OBJS) $(LDFLAGS) $(LDFLAGS_EXTRA) $(LIBS) + +$(BIN_DIR)/$(EPR): $(OBJ_DIR) $(BIN_DIR) $(EPR_OBJS) + @mkdir -p $(BIN_DIR) + $(CXX) -o $(BIN_DIR)/$(EPR) $(EPR_OBJS) $(LDFLAGS) $(LDFLAGS_EXTRA) $(LIBS) + +$(BIN_DIR)/lib$(Z3).@SO_EXT@: $(OBJ_DIR) $(BIN_DIR) $(LIB_OBJS) + @mkdir -p $(BIN_DIR) + $(CXX) -o $(BIN_DIR)/lib$(Z3).@SO_EXT@ $(LIB_OBJS) $(LIBFLAGS) $(LIBS) @COMP_VERSIONS@ + +$(BIN_DIR)/lib$(Z3).a: $(OBJ_DIR) $(BIN_DIR) $(LIB_OBJS) + @mkdir -p $(BIN_DIR) + ar -cvr $(BIN_DIR)/lib$(Z3).a $(LIB_OBJS) + +$(BIN_DIR)/$(GROBNER): $(OBJ_DIR) $(BIN_DIR) $(GROBNER_OBJS) + @mkdir -p $(BIN_DIR) + $(CXX) -o $(BIN_DIR)/$(GROBNER) $(GROBNER_OBJS) $(LDFLAGS) $(LDFLAGS_EXTRA) $(LIBS) + +$(BIN_DIR): + mkdir -p $(BIN_DIR) + +$(OBJ_DIR): + mkdir -p $(OBJ_DIR) + +$(OBJ_TEST_DIR): + mkdir -p $(OBJ_TEST_DIR) + +smtcomp07: $(BIN_DIR)/$(Z3) + rm -r -f z3 + mkdir z3 + cp $(BIN_DIR)/$(Z3) z3/run + strip z3/run + cp doc/MAGIC_NUMBER z3/ + cp doc/README-SMTCOMP07 z3/README + cp doc/NOTICES-SMTCOMP07 z3/NOTICES + cp doc/z3.pdf z3/ + tar -czf z3.tar.gz z3 + +test_capi: $(BIN_DIR)/$(TEST_CAPI) + +epr: $(BIN_DIR)/$(EPR) + +@SO_EXT@: $(BIN_DIR)/lib$(Z3).@SO_EXT@ + +a: $(BIN_DIR)/lib$(Z3).a + +grobner: $(BIN_DIR)/$(GROBNER) + +test: $(BIN_DIR)/$(TEST) + +################################ +# +# Grobner +# +################################ +lib/grobner_main.cpp: test/igrobner.cpp + cp test/igrobner.cpp lib/grobner_main.cpp + chmod +rw lib/grobner_main.cpp + +$(OBJ_DIR)/grobner_main.o: lib/grobner_main.cpp + @mkdir -p $(OBJ_DIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -DGB_APP -c -o $@ $< + +################################ +# +# .cpp ===> .o +# +################################ + +$(OBJ_DIR)/%.o : lib/%.cpp + @mkdir -p $(OBJ_DIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +$(OBJ_TEST_DIR)/%.o : test/%.cpp + @mkdir -p $(OBJ_TEST_DIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +$(OBJ_DIR)/%.o : shell/%.cpp + @mkdir -p $(OBJ_DIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +$(OBJ_DIR)/%.o : test_capi/%.c + @mkdir -p $(OBJ_DIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -I ../lib -c -o $@ $< + +$(OBJ_DIR)/%.o : epr/%.cpp + @mkdir -p $(OBJ_DIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +################################ +# +# Dependency files +# +# .cpp ===> .d +# +################################ + +$(OBJ_DIR)/%.d: lib/%.cpp + @echo Making dependency file \'$@\' ... + @mkdir -p $(OBJ_DIR) + @$(SHELL) -ec '$(CXX) -MM $(CPPFLAGS) $< | $(SED) '\''s/\($*\)\.o[ :]*/$(SED_OBJ_DIR)\/\1.o $(SED_OBJ_DIR)\/\1.d : /g'\'' > $@; [ -s $@ ] || rm -f $@' + +$(OBJ_DIR)/%.d: shell/%.cpp + @echo Making dependency file \'$@\' ... + @mkdir -p $(OBJ_DIR) + @$(SHELL) -ec '$(CXX) -MM $(CPPFLAGS) $< | $(SED) '\''s/\($*\)\.o[ :]*/$(SED_OBJ_DIR)\/\1.o $(SED_OBJ_DIR)\/\1.d : /g'\'' > $@; [ -s $@ ] || rm -f $@' + +$(OBJ_TEST_DIR)/%.d: test/%.cpp + @echo Making dependency file \'$@\' ... + @mkdir -p $(OBJ_TEST_DIR) + @$(SHELL) -ec '$(CXX) -MM $(CPPFLAGS) $< | $(SED) '\''s/\($*\)\.o[ :]*/$(SED_OBJ_TEST_DIR)\/\1.o $(SED_OBJ_TEST_DIR)\/\1.d : /g'\'' > $@; [ -s $@ ] || rm -f $@' + + +include $(LIB_SRCS:lib/%.cpp=$(OBJ_DIR)/%.d) +include $(SHELL_SRCS:shell/%.cpp=$(OBJ_DIR)/%.d) +include $(TEST_SRCS:test/%.cpp=$(OBJ_TEST_DIR)/%.d) + +################################ +# +# Cleanup +# +################################ +.PHONY: clean + +clean: + rm -f $(BIN_DIR)/$(Z3) + rm -f $(OBJ_DIR)/* + rm -f lib.srcs + rm -f shell.srcs + find . -name '*.bb' -exec rm -f '{}' ';' + find . -name '*.bbg' -exec rm -f '{}' ';' + find . -name '*.da' -exec rm -f '{}' ';' + find . -name '*.gcov' -exec rm -f '{}' ';' + find . -name 'cachegrind*' -exec rm -f '{}' ';' + find . -name 'a.out' -exec rm -f '{}' ';' + find . -name 'a.exe' -exec rm -f '{}' ';' + find . -name 'core' -exec rm -f '{}' ';' + +################################ +# +# Release +# +# NOTE: In 64-bit systems it is not possible to build a dynamic library using static gmp. +# So, EXTRA_LIBS="" in 64-bit systems. +# EXTRA_LIBS="$(BIN_DIR)/lib$(Z3)-gmp.so" in 32-bit systems. +################################ +release: $(BIN_DIR)/$(Z3) $(BIN_DIR)/lib$(Z3).@SO_EXT@ @EXTRA_LIBS@ $(BIN_DIR)/lib$(Z3).a + @rm -f -r z3 + @mkdir -p z3 + @mkdir -p z3/bin + @mkdir -p z3/lib + @mkdir -p z3/include + @mkdir -p z3/examples + @mkdir -p z3/ocaml + @mkdir -p z3/python + @mkdir -p z3/examples/c + @mkdir -p z3/examples/c++ + @mkdir -p z3/examples/python + @mkdir -p z3/examples/maxsat + @mkdir -p z3/examples/theory + @mkdir -p z3/examples/ocaml + @cp lib/z3.h z3/include + @cp lib/z3_v1.h z3/include + @cp lib/z3_api.h z3/include + @cp lib/z3_macros.h z3/include + @cp ml/z3_stubs.c z3/ocaml + @cp ml/z3_theory_stubs.c z3/ocaml + @cp ml/z3.mli z3/ocaml + @cp ml/z3.ml z3/ocaml + @cp ml_release/build-lib.sh z3/ocaml + @$(DOS2UNIX) z3/ocaml/build-lib.sh + @chmod +rwx z3/ocaml/build-lib.sh + @cp ml_release/README_$(PLATFORM) z3/ocaml/README + @$(DOS2UNIX) z3/ocaml/README + @cp ml_release/build-test.sh z3/examples/ocaml + @$(DOS2UNIX) z3/examples/ocaml/build-test.sh + @chmod +rwx z3/examples/ocaml/build-test.sh + @cp ml_release/README_test_$(PLATFORM) z3/examples/ocaml/README + @$(DOS2UNIX) z3/examples/ocaml/README + @$(DOS2UNIX) z3/include/* + @cp $(BIN_DIR)/$(Z3) z3/bin + @cp $(BIN_DIR)/lib$(Z3).@SO_EXT@ z3/lib + @cp $(BIN_DIR)/lib$(Z3).a z3/lib + @cp test_capi/test_capi.c z3/examples/c + @$(DOS2UNIX) z3/examples/c/test_capi.c + @cp test_capi/README-$(PLATFORM).txt z3/examples/c/README + @$(DOS2UNIX) z3/examples/c/README + @cp test_capi/build-external-$(PLATFORM).sh z3/examples/c/build.sh + @cp test_capi/build-static-$(PLATFORM).sh z3/examples/c/build-static.sh + @$(DOS2UNIX) z3/examples/c/build.sh + @chmod +rwx z3/examples/c/build.sh + @$(DOS2UNIX) z3/examples/c/build-static.sh + @chmod +rwx z3/examples/c/build-static.sh + @cp test_capi/exec-external-$(PLATFORM).sh z3/examples/c/exec.sh + @$(DOS2UNIX) z3/examples/c/exec.sh + @chmod +rwx z3/examples/c/exec.sh + @cp maxsat/maxsat.c z3/examples/maxsat + @$(DOS2UNIX) z3/examples/maxsat/maxsat.c + @cp maxsat/README-$(PLATFORM).txt z3/examples/maxsat/README + @$(DOS2UNIX) z3/examples/maxsat/README + @cp maxsat/build-external-$(PLATFORM).sh z3/examples/maxsat/build.sh + @cp maxsat/build-static-$(PLATFORM).sh z3/examples/maxsat/build-static.sh + @$(DOS2UNIX) z3/examples/maxsat/build.sh + @chmod +rwx z3/examples/maxsat/build.sh + @$(DOS2UNIX) z3/examples/maxsat/build-static.sh + @chmod +rwx z3/examples/maxsat/build-static.sh + @cp maxsat/exec-external-$(PLATFORM).sh z3/examples/maxsat/exec.sh + @$(DOS2UNIX) z3/examples/maxsat/exec.sh + @chmod +rwx z3/examples/maxsat/exec.sh + @cp test_user_theory/test_user_theory.c z3/examples/theory + @$(DOS2UNIX) z3/examples/theory/test_user_theory.c + @cp test_user_theory/README-$(PLATFORM).txt z3/examples/theory/README + @$(DOS2UNIX) z3/examples/theory/README + @cp test_user_theory/build-external-$(PLATFORM).sh z3/examples/theory/build.sh + @cp test_user_theory/build-static-$(PLATFORM).sh z3/examples/theory/build-static.sh + @$(DOS2UNIX) z3/examples/theory/build.sh + @chmod +rwx z3/examples/theory/build.sh + @$(DOS2UNIX) z3/examples/theory/build-static.sh + @chmod +rwx z3/examples/theory/build-static.sh + @cp test_user_theory/exec-external-$(PLATFORM).sh z3/examples/theory/exec.sh + @$(DOS2UNIX) z3/examples/theory/exec.sh + @chmod +rwx z3/examples/theory/exec.sh + @cp ml_release/exec-$(PLATFORM).sh z3/examples/ocaml/exec.sh + @$(DOS2UNIX) z3/examples/ocaml/exec.sh + @chmod +rwx z3/examples/ocaml/exec.sh + @cp ml/test_mlapi.ml z3/examples/ocaml + @$(DOS2UNIX) z3/examples/ocaml/test_mlapi.ml + @cp c++/z3++.h z3/include + @cp c++/example.cpp z3/examples/c++ + @cp c++/build-external-$(PLATFORM).sh z3/examples/c++/build.sh + @$(DOS2UNIX) z3/examples/c++/build.sh + @chmod +rwx z3/examples/c++/build.sh + @cp c++/exec-external-$(PLATFORM).sh z3/examples/c++/exec.sh + @$(DOS2UNIX) z3/examples/c++/exec.sh + @chmod +rwx z3/examples/c++/exec.sh + @cp python/z3.py z3/python + @cp python/z3core.py z3/python + @cp python/z3types.py z3/python + @cp python/z3consts.py z3/python + @cp python/z3tactics.py z3/python + @cp python/z3printer.py z3/python + @cp python/README-$(PLATFORM).txt z3/examples/python/README + @cp python/exec-$(PLATFORM).sh z3/examples/python/exec.sh + @cp python/example.py z3/examples/python + @$(DOS2UNIX) z3/python/*.py + @$(DOS2UNIX) z3/examples/python/*.py + @$(DOS2UNIX) z3/examples/python/*.sh + @chmod +rwx z3/examples/python/*.sh + @$(DOS2UNIX) iZ3/pack-iz3-$(PLATFORM).sh + @chmod +rwx iZ3/pack-iz3-$(PLATFORM).sh + @iZ3/pack-iz3-$(PLATFORM).sh + @tar -cvzf z3.tar.gz z3 + +################################ +# +# Support +# +################################ + +Makefile: Makefile.in config.status + ./config.status + make + +config.status: configure + ./config.status --recheck + +################################ +# +# checkgmake +# +################################ +.PHONY: checkgmake + +checkgmake: + @ ./gmaketest --make=$(MAKE) || \ + (echo "Z3 needs GNU-Make to be built"; exit 1) + diff --git a/Microsoft.Z3/AST.cs b/Microsoft.Z3/AST.cs new file mode 100644 index 000000000..e3b8fc3ec --- /dev/null +++ b/Microsoft.Z3/AST.cs @@ -0,0 +1,260 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + AST.cs + +Abstract: + + Z3 Managed API: ASTs + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-16 + +Notes: + +--*/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// The abstract syntax tree (AST) class. + /// + [ContractVerification(true)] + public class AST : Z3Object, IComparable + { + /// + /// Comparison operator. + /// + /// An AST + /// An AST + /// True if and are from the same context + /// and represent the same sort; false otherwise. + public static bool operator ==(AST a, AST b) + { + return Object.ReferenceEquals(a, b) || + (!Object.ReferenceEquals(a, null) && + !Object.ReferenceEquals(b, null) && + a.Context.nCtx == b.Context.nCtx && + Native.Z3_is_eq_ast(a.Context.nCtx, a.NativeObject, b.NativeObject) != 0); + } + + /// + /// Comparison operator. + /// + /// An AST + /// An AST + /// True if and are not from the same context + /// or represent different sorts; false otherwise. + public static bool operator !=(AST a, AST b) + { + return !(a == b); + } + + /// + /// Object comparison. + /// + public override bool Equals(object o) + { + AST casted = o as AST; + if (casted == null) return false; + return this == casted; + } + + /// + /// Object Comparison. + /// + /// Another AST + /// Negative if the object should be sorted before , positive if after else zero. + public virtual int CompareTo(object other) + { + if (other == null) return 1; + AST oAST = other as AST; + if (oAST == null) + return 1; + else + { + if (Id < oAST.Id) + return -1; + else if (Id > oAST.Id) + return +1; + else + return 0; + } + } + + /// + /// The AST's hash code. + /// + /// A hash code + public override int GetHashCode() + { + return (int)Native.Z3_get_ast_hash(Context.nCtx, NativeObject); + } + + /// + /// A unique identifier for the AST (unique among all ASTs). + /// + public uint Id + { + get { return Native.Z3_get_ast_id(Context.nCtx, NativeObject); } + } + + /// + /// Translates (copies) the AST to the Context . + /// + /// A context + /// A copy of the AST which is associated with + public AST Translate(Context ctx) + { + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result() != null); + + if (ReferenceEquals(Context, ctx)) + return this; + else + return new AST(ctx, Native.Z3_translate(Context.nCtx, NativeObject, ctx.nCtx)); + } + + /// + /// The kind of the AST. + /// + public Z3_ast_kind ASTKind + { + get { return (Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, NativeObject); } + } + + /// + /// Indicates whether the AST is an Expr + /// + public bool IsExpr + { + get + { + switch (ASTKind) + { + case Z3_ast_kind.Z3_APP_AST: + case Z3_ast_kind.Z3_NUMERAL_AST: + case Z3_ast_kind.Z3_QUANTIFIER_AST: + case Z3_ast_kind.Z3_VAR_AST: return true; + default: return false; + } + } + } + + /// + /// Indicates whether the AST is a BoundVariable + /// + public bool IsVar + { + get { return this.ASTKind == Z3_ast_kind.Z3_VAR_AST; } + } + + /// + /// Indicates whether the AST is a Quantifier + /// + public bool IsQuantifier + { + get { return this.ASTKind == Z3_ast_kind.Z3_QUANTIFIER_AST; } + } + + /// + /// Indicates whether the AST is a Sort + /// + public bool IsSort + { + get { return this.ASTKind == Z3_ast_kind.Z3_SORT_AST; } + } + + /// + /// Indicates whether the AST is a FunctionDeclaration + /// + public bool IsFuncDecl + { + get { return this.ASTKind == Z3_ast_kind.Z3_FUNC_DECL_AST; } + } + + /// + /// A string representation of the AST. + /// + public override string ToString() + { + return Native.Z3_ast_to_string(Context.nCtx, NativeObject); + } + + /// + /// A string representation of the AST in s-expression notation. + /// + public string SExpr() + { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_ast_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal AST(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } + internal AST(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + // Console.WriteLine("AST IncRef()"); + if (Context == null) + throw new Z3Exception("inc() called on null context"); + if (o == IntPtr.Zero) + throw new Z3Exception("inc() called on null AST"); + Context.AST_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + // Console.WriteLine("AST DecRef()"); + if (Context == null) + throw new Z3Exception("dec() called on null context"); + if (o == IntPtr.Zero) + throw new Z3Exception("dec() called on null AST"); + Context.AST_DRQ.Add(o); + base.DecRef(o); + } + + internal static AST Create(Context ctx, IntPtr obj) + { + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result() != null); + + switch ((Z3_ast_kind)Native.Z3_get_ast_kind(ctx.nCtx, obj)) + { + case Z3_ast_kind.Z3_FUNC_DECL_AST: return new FuncDecl(ctx, obj); + case Z3_ast_kind.Z3_QUANTIFIER_AST: return new Quantifier(ctx, obj); + case Z3_ast_kind.Z3_SORT_AST: return Sort.Create(ctx, obj); + case Z3_ast_kind.Z3_APP_AST: + case Z3_ast_kind.Z3_NUMERAL_AST: + case Z3_ast_kind.Z3_VAR_AST: return Expr.Create(ctx, obj); + default: + throw new Z3Exception("Unknown AST kind"); + } + } + #endregion + } +} diff --git a/Microsoft.Z3/ASTMap.cs b/Microsoft.Z3/ASTMap.cs new file mode 100644 index 000000000..d945b3d44 --- /dev/null +++ b/Microsoft.Z3/ASTMap.cs @@ -0,0 +1,155 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + ASTMap.cs + +Abstract: + + Z3 Managed API: AST Maps + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Map from AST to AST + /// + [ContractVerification(true)] + internal class ASTMap : Z3Object + { + /// + /// Checks whether the map contains the key . + /// + /// An AST + /// True if is a key in the map, false otherwise. + public bool Contains(AST k) + { + Contract.Requires(k != null); + + return Native.Z3_ast_map_contains(Context.nCtx, NativeObject, k.NativeObject) != 0; + } + + /// + /// Finds the value associated with the key . + /// + /// + /// This function signs an error when is not a key in the map. + /// + /// An AST + public AST Find(AST k) + { + Contract.Requires(k != null); + Contract.Ensures(Contract.Result() != null); + + return new AST(Context, Native.Z3_ast_map_find(Context.nCtx, NativeObject, k.NativeObject)); + } + + /// + /// Stores or replaces a new key/value pair in the map. + /// + /// The key AST + /// The value AST + public void Insert(AST k, AST v) + { + Contract.Requires(k != null); + Contract.Requires(v != null); + + Native.Z3_ast_map_insert(Context.nCtx, NativeObject, k.NativeObject, v.NativeObject); + } + + /// + /// Erases the key from the map. + /// + /// An AST + public void Erase(AST k) + { + Contract.Requires(k != null); + + Native.Z3_ast_map_erase(Context.nCtx, NativeObject, k.NativeObject); + } + + /// + /// Removes all keys from the map. + /// + public void Reset() + { + Native.Z3_ast_map_reset(Context.nCtx, NativeObject); + } + + /// + /// The size of the map + /// + public uint Size + { + get { return Native.Z3_ast_map_size(Context.nCtx, NativeObject); } + } + + /// + /// The keys stored in the map. + /// + public ASTVector Keys + { + get + { + return new ASTVector(Context, Native.Z3_ast_map_keys(Context.nCtx, NativeObject)); + } + } + + /// + /// Retrieves a string representation of the map. + /// + public override string ToString() + { + return Native.Z3_ast_map_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal ASTMap(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal ASTMap(Context ctx) + : base(ctx, Native.Z3_mk_ast_map(ctx.nCtx)) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_ast_map_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_ast_map_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.ASTMap_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.ASTMap_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/ASTVector.cs b/Microsoft.Z3/ASTVector.cs new file mode 100644 index 000000000..1e66c4b21 --- /dev/null +++ b/Microsoft.Z3/ASTVector.cs @@ -0,0 +1,132 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + ASTVector.cs + +Abstract: + + Z3 Managed API: AST Vectors + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Vectors of ASTs. + /// + internal class ASTVector : Z3Object + { + /// + /// The size of the vector + /// + public uint Size + { + get { return Native.Z3_ast_vector_size(Context.nCtx, NativeObject); } + } + + /// + /// Retrieves the i-th object in the vector. + /// + /// May throw an IndexOutOfBoundsException when is out of range. + /// Index + /// An AST + public AST this[uint i] + { + get + { + Contract.Ensures(Contract.Result() != null); + + return new AST(Context, Native.Z3_ast_vector_get(Context.nCtx, NativeObject, i)); + } + set + { + Contract.Requires(value!= null); + + Native.Z3_ast_vector_set(Context.nCtx, NativeObject, i, value.NativeObject); + } + } + + /// + /// Resize the vector to . + /// + /// The new size of the vector. + public void Resize(uint newSize) + { + Native.Z3_ast_vector_resize(Context.nCtx, NativeObject, newSize); + } + + /// + /// Add the AST to the back of the vector. The size + /// is increased by 1. + /// + /// An AST + public void Push(AST a) + { + Contract.Requires(a != null); + + Native.Z3_ast_vector_push(Context.nCtx, NativeObject, a.NativeObject); + } + + /// + /// Translates all ASTs in the vector to . + /// + /// A context + /// A new ASTVector + public ASTVector Translate(Context ctx) + { + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result() != null); + + return new ASTVector(Context, Native.Z3_ast_vector_translate(Context.nCtx, NativeObject, ctx.nCtx)); + } + + /// + /// Retrieves a string representation of the vector. + /// + public override string ToString() + { + return Native.Z3_ast_vector_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal ASTVector(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + internal ASTVector(Context ctx) : base(ctx, Native.Z3_mk_ast_vector(ctx.nCtx)) { Contract.Requires(ctx != null); } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_ast_vector_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_ast_vector_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.ASTVector_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.ASTVector_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/ApplyResult.cs b/Microsoft.Z3/ApplyResult.cs new file mode 100644 index 000000000..21a515643 --- /dev/null +++ b/Microsoft.Z3/ApplyResult.cs @@ -0,0 +1,111 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + ApplyResult.cs + +Abstract: + + Z3 Managed API: Result object for tactic applications + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// ApplyResult objects represent the result of an application of a + /// tactic to a goal. It contains the subgoals that were produced. + /// + [ContractVerification(true)] + public class ApplyResult : Z3Object + { + /// + /// The number of Subgoals. + /// + public uint NumSubgoals + { + get { return Native.Z3_apply_result_get_num_subgoals(Context.nCtx, NativeObject); } + } + + /// + /// Retrieves the subgoals from the ApplyResult. + /// + public Goal[] Subgoals + { + get + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result().Length == this.NumSubgoals); + + uint n = NumSubgoals; + Goal[] res = new Goal[n]; + for (uint i = 0; i < n; i++) + res[i] = new Goal(Context, Native.Z3_apply_result_get_subgoal(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// Convert a model for the subgoal into a model for the original + /// goal g, that the ApplyResult was obtained from. + /// + /// A model for g + public Model ConvertModel(uint i, Model m) + { + Contract.Requires(m != null); + Contract.Ensures(Contract.Result() != null); + + return new Model(Context, Native.Z3_apply_result_convert_model(Context.nCtx, NativeObject, i, m.NativeObject)); + } + + /// + /// A string representation of the ApplyResult. + /// + public override string ToString() + { + return Native.Z3_apply_result_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal ApplyResult(Context ctx, IntPtr obj) : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_apply_result_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_apply_result_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.ApplyResult_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.ApplyResult_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Constructor.cs b/Microsoft.Z3/Constructor.cs new file mode 100644 index 000000000..403d18736 --- /dev/null +++ b/Microsoft.Z3/Constructor.cs @@ -0,0 +1,170 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Constructor.cs + +Abstract: + + Z3 Managed API: Constructors + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-22 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Constructors are used for datatype sorts. + /// + [ContractVerification(true)] + public class Constructor : Z3Object + { + /// + /// The number of fields of the constructor. + /// + public uint NumFields + { + get { init(); return n; } + } + + /// + /// The function declaration of the constructor. + /// + public FuncDecl ConstructorDecl + { + get { + Contract.Ensures(Contract.Result() != null); + init(); return m_constructorDecl; } + } + + /// + /// The function declaration of the tester. + /// + public FuncDecl TesterDecl + { + get { + Contract.Ensures(Contract.Result() != null); + init(); return m_testerDecl; } + } + + /// + /// The function declarations of the accessors + /// + public FuncDecl[] AccessorDecls + { + get { + Contract.Ensures(Contract.Result() != null); + init(); return m_accessorDecls; } + } + + /// + /// Destructor. + /// + ~Constructor() + { + Native.Z3_del_constructor(Context.nCtx, NativeObject); + } + + #region Object invariant + + [ContractInvariantMethod] + private void ObjectInvariant() + { + Contract.Invariant(m_testerDecl == null || m_constructorDecl != null); + Contract.Invariant(m_testerDecl == null || m_accessorDecls != null); + } + + #endregion + + #region Internal + readonly private uint n = 0; + private FuncDecl m_testerDecl = null; + private FuncDecl m_constructorDecl = null; + private FuncDecl[] m_accessorDecls = null; + + internal Constructor(Context ctx, Symbol name, Symbol recognizer, Symbol[] fieldNames, + Sort[] sorts, uint[] sortRefs) + : base(ctx) + { + Contract.Requires(ctx != null); + Contract.Requires(name != null); + Contract.Requires(recognizer != null); + + n = AST.ArrayLength(fieldNames); + + if (n != AST.ArrayLength(sorts)) + throw new Z3Exception("Number of field names does not match number of sorts"); + if (sortRefs != null && sortRefs.Length != n) + throw new Z3Exception("Number of field names does not match number of sort refs"); + + if (sortRefs == null) sortRefs = new uint[n]; + + NativeObject = Native.Z3_mk_constructor(ctx.nCtx, name.NativeObject, recognizer.NativeObject, + n, + Symbol.ArrayToNative(fieldNames), + Sort.ArrayToNative(sorts), + sortRefs); + + } + + private void init() + { + Contract.Ensures(m_constructorDecl != null); + Contract.Ensures(m_testerDecl != null); + Contract.Ensures(m_accessorDecls != null); + + if (m_testerDecl != null) return; + IntPtr constructor = IntPtr.Zero; + IntPtr tester = IntPtr.Zero; + IntPtr[] accessors = new IntPtr[n]; + Native.Z3_query_constructor(Context.nCtx, NativeObject, n, ref constructor, ref tester, accessors); + m_constructorDecl = new FuncDecl(Context, constructor); + m_testerDecl = new FuncDecl(Context, tester); + m_accessorDecls = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + m_accessorDecls[i] = new FuncDecl(Context, accessors[i]); + } + + #endregion + } + + /// + /// Lists of constructors + /// + public class ConstructorList : Z3Object + { + /// + /// Destructor. + /// + ~ConstructorList() + { + Native.Z3_del_constructor_list(Context.nCtx, NativeObject); + } + + #region Internal + internal ConstructorList(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal ConstructorList(Context ctx, Constructor[] constructors) + : base(ctx) + { + Contract.Requires(ctx != null); + Contract.Requires(constructors != null); + + NativeObject = Native.Z3_mk_constructor_list(Context.nCtx, (uint)constructors.Length, Constructor.ArrayToNative(constructors)); + } + #endregion + } +} diff --git a/Microsoft.Z3/Context.cs b/Microsoft.Z3/Context.cs new file mode 100644 index 000000000..597b9b7c6 --- /dev/null +++ b/Microsoft.Z3/Context.cs @@ -0,0 +1,3694 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Context.cs + +Abstract: + + Z3 Managed API: Context + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-15 + +Notes: + +--*/ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// The main interaction with Z3 happens via the Context. + /// + [ContractVerification(true)] + public class Context : IDisposable + { + #region Constructors + /// + /// Constructor. + /// + public Context() + : base() + { + m_ctx = Native.Z3_mk_context_rc(IntPtr.Zero); + InitContext(); + } + + /// + /// Constructor. + /// + public Context(Dictionary settings) + : base() + { + Contract.Requires(settings != null); + + IntPtr cfg = Native.Z3_mk_config(); + foreach(KeyValuePair kv in settings) + Native.Z3_set_param_value(cfg, kv.Key, kv.Value); + m_ctx = Native.Z3_mk_context_rc(cfg); + Native.Z3_del_config(cfg); + InitContext(); + } + #endregion + + #region Symbols + /// + /// Creates a new symbol using an integer. + /// + /// + /// Not all integers can be passed to this function. + /// The legal range of unsigned integers is 0 to 2^30-1. + /// + public IntSymbol MkSymbol(int i) + { + Contract.Ensures(Contract.Result() != null); + + return new IntSymbol(this, i); + } + + /// + /// Create a symbol using a string. + /// + public StringSymbol MkSymbol(string name) + { + Contract.Ensures(Contract.Result() != null); + + return new StringSymbol(this, name); + } + + /// + /// Create an array of symbols. + /// + internal Symbol[] MkSymbols(string[] names) + { + Contract.Ensures(names == null || Contract.Result() != null); + Contract.Ensures(names != null || Contract.Result() == null); + Contract.Ensures(Contract.Result() == null || Contract.Result().Length == names.Length); + Contract.Ensures(Contract.Result() == null || Contract.ForAll(Contract.Result(), s => s != null)); + + if (names == null) return null; + Symbol[] result = new Symbol[names.Length]; + for (int i = 0; i < names.Length; ++i) result[i] = MkSymbol(names[i]); + return result; + } + #endregion + + #region Sorts + private BoolSort m_boolSort = null; + private IntSort m_intSort = null; + private RealSort m_realSort = null; + + /// + /// Retrieves the Boolean sort of the context. + /// + public BoolSort BoolSort + { + get + { + Contract.Ensures(Contract.Result() != null); + + if (m_boolSort == null) m_boolSort = new BoolSort(this); return m_boolSort; + } + } + + /// + /// Retrieves the Integer sort of the context. + /// + public IntSort IntSort + { + get + { + Contract.Ensures(Contract.Result() != null); + if (m_intSort == null) m_intSort = new IntSort(this); return m_intSort; + } + } + + + /// + /// Retrieves the Real sort of the context. + /// + public RealSort RealSort { get { Contract.Ensures(Contract.Result() != null); if (m_realSort == null) m_realSort = new RealSort(this); return m_realSort; } } + + /// + /// Create a new Boolean sort. + /// + public BoolSort MkBoolSort() + { + Contract.Ensures(Contract.Result() != null); + return new BoolSort(this); + } + + /// + /// Create a new uninterpreted sort. + /// + public UninterpretedSort MkUninterpretedSort(Symbol s) + { + Contract.Requires(s != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(s); + return new UninterpretedSort(this, s); + } + + /// + /// Create a new uninterpreted sort. + /// + public UninterpretedSort MkUninterpretedSort(string str) + { + Contract.Ensures(Contract.Result() != null); + + return MkUninterpretedSort(MkSymbol(str)); + } + + /// + /// Create a new integer sort. + /// + public IntSort MkIntSort() + { + Contract.Ensures(Contract.Result() != null); + + return new IntSort(this); + } + + /// + /// Create a real sort. + /// + public RealSort MkRealSort() + { + Contract.Ensures(Contract.Result() != null); + return new RealSort(this); + } + + /// + /// Create a new bit-vector sort. + /// + public BitVecSort MkBitVecSort(uint size) + { + Contract.Ensures(Contract.Result() != null); + + return new BitVecSort(this, size); + } + + /// + /// Create a new array sort. + /// + public ArraySort MkArraySort(Sort domain, Sort range) + { + Contract.Requires(domain != null); + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(domain); + CheckContextMatch(range); + return new ArraySort(this, domain, range); + } + + /// + /// Create a new tuple sort. + /// + public TupleSort MkTupleSort(Symbol name, Symbol[] fieldNames, Sort[] fieldSorts) + { + Contract.Requires(name != null); + Contract.Requires(fieldNames != null); + Contract.Requires(Contract.ForAll(fieldNames, fn => fn != null)); + Contract.Requires(fieldSorts == null || Contract.ForAll(fieldSorts, fs => fs != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + CheckContextMatch(fieldNames); + CheckContextMatch(fieldSorts); + return new TupleSort(this, name, (uint)fieldNames.Length, fieldNames, fieldSorts); + } + + /// + /// Create a new enumeration sort. + /// + public EnumSort MkEnumSort(Symbol name, Symbol[] enumNames) + { + Contract.Requires(name != null); + Contract.Requires(enumNames != null); + Contract.Requires(Contract.ForAll(enumNames, f => f != null)); + + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + CheckContextMatch(enumNames); + return new EnumSort(this, name, enumNames); + } + + /// + /// Create a new enumeration sort. + /// + public EnumSort MkEnumSort(string name, string[] enumNames) + { + Contract.Requires(enumNames != null); + Contract.Ensures(Contract.Result() != null); + + return new EnumSort(this, MkSymbol(name), MkSymbols(enumNames)); + } + + /// + /// Create a new list sort. + /// + public ListSort MkListSort(Symbol name, Sort elemSort) + { + Contract.Requires(name != null); + Contract.Requires(elemSort != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + CheckContextMatch(elemSort); + return new ListSort(this, name, elemSort); + } + + /// + /// Create a new list sort. + /// + public ListSort MkListSort(string name, Sort elemSort) + { + Contract.Requires(elemSort != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(elemSort); + return new ListSort(this, MkSymbol(name), elemSort); + } + + /// + /// Create a new finite domain sort. + /// + public FiniteDomainSort MkFiniteDomainSort(Symbol name, ulong size) + { + Contract.Requires(name != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + return new FiniteDomainSort(this, name, size); + } + + /// + /// Create a new finite domain sort. + /// + public FiniteDomainSort MkFiniteDomainSort(string name, ulong size) + { + Contract.Ensures(Contract.Result() != null); + + return new FiniteDomainSort(this, MkSymbol(name), size); + } + + + #region Datatypes + /// + /// Create a datatype constructor. + /// + /// constructor name + /// name of recognizer function. + /// names of the constructor fields. + /// field sorts, 0 if the field sort refers to a recursive sort. + /// reference to datatype sort that is an argument to the constructor; + /// if the corresponding sort reference is 0, then the value in sort_refs should be an index + /// referring to one of the recursive datatypes that is declared. + public Constructor MkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) + { + Contract.Requires(name != null); + Contract.Requires(recognizer != null); + Contract.Ensures(Contract.Result() != null); + + return new Constructor(this, name, recognizer, fieldNames, sorts, sortRefs); + } + + /// + /// Create a datatype constructor. + /// + /// + /// + /// + /// + /// + /// + public Constructor MkConstructor(string name, string recognizer, string[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) + { + Contract.Ensures(Contract.Result() != null); + + return new Constructor(this, MkSymbol(name), MkSymbol(recognizer), MkSymbols(fieldNames), sorts, sortRefs); + } + + /// + /// Create a new datatype sort. + /// + public DatatypeSort MkDatatypeSort(Symbol name, Constructor[] constructors) + { + Contract.Requires(name != null); + Contract.Requires(constructors != null); + Contract.Requires(Contract.ForAll(constructors, c => c != null)); + + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + CheckContextMatch(constructors); + return new DatatypeSort(this, name, constructors); + } + + /// + /// Create a new datatype sort. + /// + public DatatypeSort MkDatatypeSort(string name, Constructor[] constructors) + { + Contract.Requires(constructors != null); + Contract.Requires(Contract.ForAll(constructors, c => c != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(constructors); + return new DatatypeSort(this, MkSymbol(name), constructors); + } + + /// + /// Create mutually recursive datatypes. + /// + /// names of datatype sorts + /// list of constructors, one list per sort. + public DatatypeSort[] MkDatatypeSorts(Symbol[] names, Constructor[][] c) + { + Contract.Requires(names != null); + Contract.Requires(c != null); + Contract.Requires(names.Length == c.Length); + Contract.Requires(Contract.ForAll(0, c.Length, j => c[j] != null)); + Contract.Requires(Contract.ForAll(names, name => name != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(names); + uint n = (uint)names.Length; + ConstructorList[] cla = new ConstructorList[n]; + IntPtr[] n_constr = new IntPtr[n]; + for (uint i = 0; i < n; i++) + { + var constructor = c[i]; + Contract.Assume(Contract.ForAll(constructor, arr => arr != null), "Clousot does not support yet quantified formula on multidimensional arrays"); + CheckContextMatch(constructor); + cla[i] = new ConstructorList(this, constructor); + n_constr[i] = cla[i].NativeObject; + } + IntPtr[] n_res = new IntPtr[n]; + Native.Z3_mk_datatypes(nCtx, n, Symbol.ArrayToNative(names), n_res, n_constr); + DatatypeSort[] res = new DatatypeSort[n]; + for (uint i = 0; i < n; i++) + res[i] = new DatatypeSort(this, n_res[i]); + return res; + } + + /// + /// Create mutually recursive data-types. + /// + /// + /// + /// + public DatatypeSort[] MkDatatypeSorts(string[] names, Constructor[][] c) + { + Contract.Requires(names != null); + Contract.Requires(c != null); + Contract.Requires(names.Length == c.Length); + Contract.Requires(Contract.ForAll(0, c.Length, j => c[j] != null)); + Contract.Requires(Contract.ForAll(names, name => name != null)); + Contract.Ensures(Contract.Result() != null); + + return MkDatatypeSorts(MkSymbols(names), c); + } + + #endregion + #endregion + + #region Function Declarations + /// + /// Creates a new function declaration. + /// + public FuncDecl MkFuncDecl(Symbol name, Sort[] domain, Sort range) + { + Contract.Requires(name != null); + Contract.Requires(range != null); + Contract.Requires(Contract.ForAll(domain, d => d != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + CheckContextMatch(domain); + CheckContextMatch(range); + return new FuncDecl(this, name, domain, range); + } + + /// + /// Creates a new function declaration. + /// + public FuncDecl MkFuncDecl(Symbol name, Sort domain, Sort range) + { + Contract.Requires(name != null); + Contract.Requires(domain != null); + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + CheckContextMatch(domain); + CheckContextMatch(range); + Sort[] q = new Sort[] { domain }; + return new FuncDecl(this, name, q, range); + } + + /// + /// Creates a new function declaration. + /// + public FuncDecl MkFuncDecl(string name, Sort[] domain, Sort range) + { + Contract.Requires(range != null); + Contract.Requires(Contract.ForAll(domain, d => d != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(domain); + CheckContextMatch(range); + return new FuncDecl(this, MkSymbol(name), domain, range); + } + + /// + /// Creates a new function declaration. + /// + public FuncDecl MkFuncDecl(string name, Sort domain, Sort range) + { + Contract.Requires(range != null); + Contract.Requires(domain != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(domain); + CheckContextMatch(range); + Sort[] q = new Sort[] { domain }; + return new FuncDecl(this, MkSymbol(name), q, range); + } + + /// + /// Creates a fresh function declaration with a name prefixed with . + /// + /// + /// + public FuncDecl MkFreshFuncDecl(string prefix, Sort[] domain, Sort range) + { + Contract.Requires(range != null); + Contract.Requires(Contract.ForAll(domain, d => d != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(domain); + CheckContextMatch(range); + return new FuncDecl(this, prefix, domain, range); + } + + /// + /// Creates a new constant function declaration. + /// + public FuncDecl MkConstDecl(Symbol name, Sort range) + { + Contract.Requires(name != null); + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + CheckContextMatch(range); + return new FuncDecl(this, name, null, range); + } + + /// + /// Creates a new constant function declaration. + /// + public FuncDecl MkConstDecl(string name, Sort range) + { + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(range); + return new FuncDecl(this, MkSymbol(name), null, range); + } + + /// + /// Creates a fresh constant function declaration with a name prefixed with . + /// + /// + /// + public FuncDecl MkFreshConstDecl(string prefix, Sort range) + { + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(range); + return new FuncDecl(this, prefix, null, range); + } + #endregion + + #region Bound Variables + /// + /// Creates a new bound variable. + /// + /// The de-Bruijn index of the variable + /// The sort of the variable + public Expr MkBound(uint index, Sort ty) + { + Contract.Requires(ty != null); + Contract.Ensures(Contract.Result() != null); + + return Expr.Create(this, Native.Z3_mk_bound(nCtx, index, ty.NativeObject)); + } + #endregion + + #region Quantifier Patterns + /// + /// Create a quantifier pattern. + /// + public Pattern MkPattern(params Expr[] terms) + { + Contract.Requires(terms != null); + if (terms.Length == 0) + throw new Z3Exception("Cannot create a pattern from zero terms"); + + Contract.Ensures(Contract.Result() != null); + + Contract.EndContractBlock(); + + IntPtr[] termsNative = AST.ArrayToNative(terms); + return new Pattern(this, Native.Z3_mk_pattern(nCtx, (uint)terms.Length, termsNative)); + } + #endregion + + #region Constants + /// + /// Creates a new Constant of sort and named . + /// + public Expr MkConst(Symbol name, Sort range) + { + Contract.Requires(name != null); + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(name); + CheckContextMatch(range); + + return Expr.Create(this, Native.Z3_mk_const(nCtx, name.NativeObject, range.NativeObject)); + } + + /// + /// Creates a new Constant of sort and named . + /// + public Expr MkConst(string name, Sort range) + { + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + return MkConst(MkSymbol(name), range); + } + + /// + /// Creates a fresh Constant of sort and a + /// name prefixed with . + /// + public Expr MkFreshConst(string prefix, Sort range) + { + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(range); + return Expr.Create(this, Native.Z3_mk_fresh_const(nCtx, prefix, range.NativeObject)); + } + + /// + /// Creates a fresh constant from the FuncDecl . + /// + /// A decl of a 0-arity function + public Expr MkConst(FuncDecl f) + { + Contract.Requires(f != null); + Contract.Ensures(Contract.Result() != null); + + return MkApp(f); + } + + /// + /// Create a Boolean constant. + /// + public BoolExpr MkBoolConst(Symbol name) + { + Contract.Requires(name != null); + Contract.Ensures(Contract.Result() != null); + + return (BoolExpr)MkConst(name, BoolSort); + } + + /// + /// Create a Boolean constant. + /// + public BoolExpr MkBoolConst(string name) + { + Contract.Ensures(Contract.Result() != null); + + return (BoolExpr)MkConst(MkSymbol(name), BoolSort); + } + + /// + /// Creates an integer constant. + /// + public IntExpr MkIntConst(Symbol name) + { + Contract.Requires(name != null); + Contract.Ensures(Contract.Result() != null); + + return (IntExpr)MkConst(name, IntSort); + } + + /// + /// Creates an integer constant. + /// + public IntExpr MkIntConst(string name) + { + Contract.Requires(name != null); + Contract.Ensures(Contract.Result() != null); + + return (IntExpr)MkConst(name, IntSort); + } + + /// + /// Creates a real constant. + /// + public RealExpr MkRealConst(Symbol name) + { + Contract.Requires(name != null); + Contract.Ensures(Contract.Result() != null); + + return (RealExpr)MkConst(name, RealSort); + } + + /// + /// Creates a real constant. + /// + public RealExpr MkRealConst(string name) + { + Contract.Ensures(Contract.Result() != null); + + return (RealExpr)MkConst(name, RealSort); + } + + /// + /// Creates a bit-vector constant. + /// + public BitVecExpr MkBVConst(Symbol name, uint size) + { + Contract.Requires(name != null); + Contract.Ensures(Contract.Result() != null); + + return (BitVecExpr)MkConst(name, MkBitVecSort(size)); + } + + /// + /// Creates a bit-vector constant. + /// + public BitVecExpr MkBVConst(string name, uint size) + { + Contract.Ensures(Contract.Result() != null); + + return (BitVecExpr)MkConst(name, MkBitVecSort(size)); + } + #endregion + + #region Terms + /// + /// Create a new function application. + /// + public Expr MkApp(FuncDecl f, params Expr[] args) + { + Contract.Requires(f != null); + Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(f); + CheckContextMatch(args); + return Expr.Create(this, f, args); + } + + #region Propositional + /// + /// The true Term. + /// + public BoolExpr MkTrue() + { + Contract.Ensures(Contract.Result() != null); + + return new BoolExpr(this, Native.Z3_mk_true(nCtx)); + } + + /// + /// The false Term. + /// + public BoolExpr MkFalse() + { + Contract.Ensures(Contract.Result() != null); + + return new BoolExpr(this, Native.Z3_mk_false(nCtx)); + } + + /// + /// Creates a Boolean value. + /// + public BoolExpr MkBool(bool value) + { + Contract.Ensures(Contract.Result() != null); + + return value ? MkTrue() : MkFalse(); + } + + /// + /// Creates the equality = . + /// + public BoolExpr MkEq(Expr x, Expr y) + { + Contract.Requires(x != null); + Contract.Requires(y != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(x); + CheckContextMatch(y); + return new BoolExpr(this, Native.Z3_mk_eq(nCtx, x.NativeObject, y.NativeObject)); + } + + /// + /// Creates a distinct term. + /// + public BoolExpr MkDistinct(params Expr[] args) + { + Contract.Requires(args != null); + Contract.Requires(Contract.ForAll(args, a => a != null)); + + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(args); + return new BoolExpr(this, Native.Z3_mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + + /// + /// Mk an expression representing not(a). + /// + public BoolExpr MkNot(BoolExpr a) + { + Contract.Requires(a != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(a); + return new BoolExpr(this, Native.Z3_mk_not(nCtx, a.NativeObject)); + } + + /// + /// Create an expression representing an if-then-else: ite(t1, t2, t3). + /// + /// An expression with Boolean sort + /// An expression + /// An expression with the same sort as + public Expr MkITE(BoolExpr t1, Expr t2, Expr t3) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Requires(t3 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + CheckContextMatch(t3); + return Expr.Create(this, Native.Z3_mk_ite(nCtx, t1.NativeObject, t2.NativeObject, t3.NativeObject)); + } + + /// + /// Create an expression representing t1 iff t2. + /// + public BoolExpr MkIff(BoolExpr t1, BoolExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_iff(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 -> t2. + /// + public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_implies(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 xor t2. + /// + public BoolExpr MkXor(BoolExpr t1, BoolExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_xor(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t[0] and t[1] and .... + /// + public BoolExpr MkAnd(params BoolExpr[] t) + { + Contract.Requires(t != null); + Contract.Requires(Contract.ForAll(t, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + + /// + /// Create an expression representing t[0] or t[1] or .... + /// + public BoolExpr MkOr(params BoolExpr[] t) + { + Contract.Requires(t != null); + Contract.Requires(Contract.ForAll(t, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BoolExpr(this, Native.Z3_mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + #endregion + + #region Arithmetic + /// + /// Create an expression representing t[0] + t[1] + .... + /// + public ArithExpr MkAdd(params ArithExpr[] t) + { + Contract.Requires(t != null); + Contract.Requires(Contract.ForAll(t, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Native.Z3_mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + + /// + /// Create an expression representing t[0] * t[1] * .... + /// + public ArithExpr MkMul(params ArithExpr[] t) + { + Contract.Requires(t != null); + Contract.Requires(Contract.ForAll(t, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + + /// + /// Create an expression representing t[0] - t[1] - .... + /// + public ArithExpr MkSub(params ArithExpr[] t) + { + Contract.Requires(t != null); + Contract.Requires(Contract.ForAll(t, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Native.Z3_mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + + /// + /// Create an expression representing -t. + /// + public ArithExpr MkUnaryMinus(ArithExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Native.Z3_mk_unary_minus(nCtx, t.NativeObject)); + } + + /// + /// Create an expression representing t1 / t2. + /// + public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return (ArithExpr)Expr.Create(this, Native.Z3_mk_div(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 mod t2. + /// + /// The arguments must have int type. + public IntExpr MkMod(IntExpr t1, IntExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new IntExpr(this, Native.Z3_mk_mod(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 rem t2. + /// + /// The arguments must have int type. + public IntExpr MkRem(IntExpr t1, IntExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new IntExpr(this, Native.Z3_mk_rem(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 ^ t2. + /// + public ArithExpr MkPower(ArithExpr t1, ArithExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return (ArithExpr)Expr.Create(this, Native.Z3_mk_power(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 < t2 + /// + public BoolExpr MkLt(ArithExpr t1, ArithExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_lt(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 <= t2 + /// + public BoolExpr MkLe(ArithExpr t1, ArithExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_le(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 > t2 + /// + public BoolExpr MkGt(ArithExpr t1, ArithExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_gt(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an expression representing t1 >= t2 + /// + public BoolExpr MkGe(ArithExpr t1, ArithExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_ge(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Coerce an integer to a real. + /// + /// + /// There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + /// + /// You can take the floor of a real by creating an auxiliary integer Term k and + /// and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + /// The argument must be of integer sort. + /// + public RealExpr MkInt2Real(IntExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new RealExpr(this, Native.Z3_mk_int2real(nCtx, t.NativeObject)); + } + + /// + /// Coerce a real to an integer. + /// + /// + /// The semantics of this function follows the SMT-LIB standard for the function to_int. + /// The argument must be of real sort. + /// + public IntExpr MkReal2Int(RealExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new IntExpr(this, Native.Z3_mk_real2int(nCtx, t.NativeObject)); + } + + /// + /// Creates an expression that checks whether a real number is an integer. + /// + public BoolExpr MkIsInteger(RealExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BoolExpr(this, Native.Z3_mk_is_int(nCtx, t.NativeObject)); + } + #endregion + + #region Bit-vectors + /// + /// Bitwise negation. + /// + /// The argument must have a bit-vector sort. + public BitVecExpr MkBVNot(BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_bvnot(nCtx, t.NativeObject)); + } + + /// + /// Take conjunction of bits in a vector, return vector of length 1. + /// + /// The argument must have a bit-vector sort. + public BitVecExpr MkBVRedAND(BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_bvredand(nCtx, t.NativeObject)); + } + + /// + /// Take disjunction of bits in a vector, return vector of length 1. + /// + /// The argument must have a bit-vector sort. + public BitVecExpr MkBVRedOR(BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_bvredor(nCtx, t.NativeObject)); + } + + /// + /// Bitwise conjunction. + /// + /// The arguments must have a bit-vector sort. + public BitVecExpr MkBVAND(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvand(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Bitwise disjunction. + /// + /// The arguments must have a bit-vector sort. + public BitVecExpr MkBVOR(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvor(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Bitwise XOR. + /// + /// The arguments must have a bit-vector sort. + public BitVecExpr MkBVXOR(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvxor(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Bitwise NAND. + /// + /// The arguments must have a bit-vector sort. + public BitVecExpr MkBVNAND(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvnand(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Bitwise NOR. + /// + /// The arguments must have a bit-vector sort. + public BitVecExpr MkBVNOR(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvnor(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Bitwise XNOR. + /// + /// The arguments must have a bit-vector sort. + public BitVecExpr MkBVXNOR(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvxnor(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Standard two's complement unary minus. + /// + /// The arguments must have a bit-vector sort. + public BitVecExpr MkBVNeg(BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_bvneg(nCtx, t.NativeObject)); + } + + /// + /// Two's complement addition. + /// + /// The arguments must have the same bit-vector sort. + public BitVecExpr MkBVAdd(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvadd(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Two's complement subtraction. + /// + /// The arguments must have the same bit-vector sort. + public BitVecExpr MkBVSub(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvsub(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Two's complement multiplication. + /// + /// The arguments must have the same bit-vector sort. + public BitVecExpr MkBVMul(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvmul(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Unsigned division. + /// + /// + /// It is defined as the floor of t1/t2 if \c t2 is + /// different from zero. If t2 is zero, then the result + /// is undefined. + /// The arguments must have the same bit-vector sort. + /// + public BitVecExpr MkBVUDiv(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvudiv(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Signed division. + /// + /// + /// It is defined in the following way: + /// + /// - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + /// + /// - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + /// + /// If t2 is zero, then the result is undefined. + /// The arguments must have the same bit-vector sort. + /// + public BitVecExpr MkBVSDiv(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvsdiv(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Unsigned remainder. + /// + /// + /// It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + /// If t2 is zero, then the result is undefined. + /// The arguments must have the same bit-vector sort. + /// + public BitVecExpr MkBVURem(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvurem(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Signed remainder. + /// + /// + /// It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + /// The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + /// + /// If t2 is zero, then the result is undefined. + /// The arguments must have the same bit-vector sort. + /// + public BitVecExpr MkBVSRem(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvsrem(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Two's complement signed remainder (sign follows divisor). + /// + /// + /// If t2 is zero, then the result is undefined. + /// The arguments must have the same bit-vector sort. + /// + public BitVecExpr MkBVSMod(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvsmod(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Unsigned less-than + /// + /// + /// The arguments must have the same bit-vector sort. + /// + public BoolExpr MkBVULT(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvult(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Two's complement signed less-than + /// + /// + /// The arguments must have the same bit-vector sort. + /// + public BoolExpr MkBVSLT(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvslt(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Unsigned less-than or equal to. + /// + /// + /// The arguments must have the same bit-vector sort. + /// + public BoolExpr MkBVULE(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvule(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Two's complement signed less-than or equal to. + /// + /// + /// The arguments must have the same bit-vector sort. + /// + public BoolExpr MkBVSLE(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvsle(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Unsigned greater than or equal to. + /// + /// + /// The arguments must have the same bit-vector sort. + /// + public BoolExpr MkBVUGE(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvuge(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Two's complement signed greater than or equal to. + /// + /// + /// The arguments must have the same bit-vector sort. + /// + public BoolExpr MkBVSGE(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvsge(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Unsigned greater-than. + /// + /// + /// The arguments must have the same bit-vector sort. + /// + public BoolExpr MkBVUGT(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvugt(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Two's complement signed greater-than. + /// + /// + /// The arguments must have the same bit-vector sort. + /// + public BoolExpr MkBVSGT(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvsgt(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Bit-vector concatenation. + /// + /// + /// The arguments must have a bit-vector sort. + /// + /// + /// The result is a bit-vector of size n1+n2, where n1 (n2) + /// is the size of t1 (t2). + /// + public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_concat(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Bit-vector extraction. + /// + /// + /// Extract the bits down to from a bitvector of + /// size m to yield a new bitvector of size n, where + /// n = high - low + 1. + /// The argument must have a bit-vector sort. + /// + public BitVecExpr MkExtract(uint high, uint low, BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_extract(nCtx, high, low, t.NativeObject)); + } + + /// + /// Bit-vector sign extension. + /// + /// + /// Sign-extends the given bit-vector to the (signed) equivalent bitvector of + /// size m+i, where \c m is the size of the given bit-vector. + /// The argument must have a bit-vector sort. + /// + public BitVecExpr MkSignExt(uint i, BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_sign_ext(nCtx, i, t.NativeObject)); + } + + /// + /// Bit-vector zero extension. + /// + /// + /// Extend the given bit-vector with zeros to the (unsigned) equivalent + /// bitvector of size m+i, where \c m is the size of the + /// given bit-vector. + /// The argument must have a bit-vector sort. + /// + public BitVecExpr MkZeroExt(uint i, BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_zero_ext(nCtx, i, t.NativeObject)); + } + + /// + /// Bit-vector repetition. + /// + /// + /// The argument must have a bit-vector sort. + /// + public BitVecExpr MkRepeat(uint i, BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_repeat(nCtx, i, t.NativeObject)); + } + + /// + /// Shift left. + /// + /// + /// It is equivalent to multiplication by 2^x where \c x is the value of . + /// + /// NB. The semantics of shift operations varies between environments. This + /// definition does not necessarily capture directly the semantics of the + /// programming language or assembly architecture you are modeling. + /// + /// The arguments must have a bit-vector sort. + /// + public BitVecExpr MkBVSHL(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvshl(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Logical shift right + /// + /// + /// It is equivalent to unsigned division by 2^x where \c x is the value of . + /// + /// NB. The semantics of shift operations varies between environments. This + /// definition does not necessarily capture directly the semantics of the + /// programming language or assembly architecture you are modeling. + /// + /// The arguments must have a bit-vector sort. + /// + public BitVecExpr MkBVLSHR(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvlshr(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Arithmetic shift right + /// + /// + /// It is like logical shift right except that the most significant + /// bits of the result always copy the most significant bit of the + /// second argument. + /// + /// NB. The semantics of shift operations varies between environments. This + /// definition does not necessarily capture directly the semantics of the + /// programming language or assembly architecture you are modeling. + /// + /// The arguments must have a bit-vector sort. + /// + public BitVecExpr MkBVASHR(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_bvashr(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Rotate Left. + /// + /// + /// Rotate bits of \c t to the left \c i times. + /// The argument must have a bit-vector sort. + /// + public BitVecExpr MkBVRotateLeft(uint i, BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_rotate_left(nCtx, i, t.NativeObject)); + } + + /// + /// Rotate Right. + /// + /// + /// Rotate bits of \c t to the right \c i times. + /// The argument must have a bit-vector sort. + /// + public BitVecExpr MkBVRotateRight(uint i, BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_rotate_right(nCtx, i, t.NativeObject)); + } + + /// + /// Rotate Left. + /// + /// + /// Rotate bits of to the left times. + /// The arguments must have the same bit-vector sort. + /// + public BitVecExpr MkBVRotateLeft(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_ext_rotate_left(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Rotate Right. + /// + /// + /// Rotate bits of to the right times. + /// The arguments must have the same bit-vector sort. + /// + public BitVecExpr MkBVRotateRight(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.Z3_mk_ext_rotate_right(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create an bit bit-vector from the integer argument . + /// + /// + /// NB. This function is essentially treated as uninterpreted. + /// So you cannot expect Z3 to precisely reflect the semantics of this function + /// when solving constraints with this function. + /// + /// The argument must be of integer sort. + /// + public BitVecExpr MkInt2BV(uint n, IntExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BitVecExpr(this, Native.Z3_mk_int2bv(nCtx, n, t.NativeObject)); + } + + /// + /// Create an integer from the bit-vector argument . + /// + /// + /// If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + /// So the result is non-negative and in the range [0..2^N-1], where + /// N are the number of bits in . + /// If \c is_signed is true, \c t1 is treated as a signed bit-vector. + /// + /// NB. This function is essentially treated as uninterpreted. + /// So you cannot expect Z3 to precisely reflect the semantics of this function + /// when solving constraints with this function. + /// + /// The argument must be of bit-vector sort. + /// + public IntExpr MkBV2Int(BitVecExpr t, bool signed) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new IntExpr(this, Native.Z3_mk_bv2int(nCtx, t.NativeObject, (signed) ? 1 : 0)); + } + + /// + /// Create a predicate that checks that the bit-wise addition does not overflow. + /// + /// + /// The arguments must be of bit-vector sort. + /// + public BoolExpr MkBVAddNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvadd_no_overflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0)); + } + + /// + /// Create a predicate that checks that the bit-wise addition does not underflow. + /// + /// + /// The arguments must be of bit-vector sort. + /// + public BoolExpr MkBVAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvadd_no_underflow(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create a predicate that checks that the bit-wise subtraction does not overflow. + /// + /// + /// The arguments must be of bit-vector sort. + /// + public BoolExpr MkBVSubNoOverflow(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvsub_no_overflow(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create a predicate that checks that the bit-wise subtraction does not underflow. + /// + /// + /// The arguments must be of bit-vector sort. + /// + public BoolExpr MkBVSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvsub_no_underflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0)); + } + + /// + /// Create a predicate that checks that the bit-wise signed division does not overflow. + /// + /// + /// The arguments must be of bit-vector sort. + /// + public BoolExpr MkBVSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvsdiv_no_overflow(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create a predicate that checks that the bit-wise negation does not overflow. + /// + /// + /// The arguments must be of bit-vector sort. + /// + public BoolExpr MkBVNegNoOverflow(BitVecExpr t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BoolExpr(this, Native.Z3_mk_bvneg_no_overflow(nCtx, t.NativeObject)); + } + + /// + /// Create a predicate that checks that the bit-wise multiplication does not overflow. + /// + /// + /// The arguments must be of bit-vector sort. + /// + public BoolExpr MkBVMulNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvmul_no_overflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0)); + } + + /// + /// Create a predicate that checks that the bit-wise multiplication does not underflow. + /// + /// + /// The arguments must be of bit-vector sort. + /// + public BoolExpr MkBVMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.Z3_mk_bvmul_no_underflow(nCtx, t1.NativeObject, t2.NativeObject)); + } + #endregion + + #region Arrays + /// + /// Create an array constant. + /// + public ArrayExpr MkArrayConst(Symbol name, Sort domain, Sort range) + { + Contract.Requires(name != null); + Contract.Requires(domain != null); + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + return (ArrayExpr)MkConst(name, MkArraySort(domain, range)); + } + + /// + /// Create an array constant. + /// + public ArrayExpr MkArrayConst(string name, Sort domain, Sort range) + { + Contract.Requires(domain != null); + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + return (ArrayExpr)MkConst(MkSymbol(name), MkArraySort(domain, range)); + } + + /// + /// Array read. + /// + /// + /// The argument a is the array and i is the index + /// of the array that gets read. + /// + /// The node a must have an array sort [domain -> range], + /// and i must have the sort domain. + /// The sort of the result is range. + /// + /// + /// + public Expr MkSelect(ArrayExpr a, Expr i) + { + Contract.Requires(a != null); + Contract.Requires(i != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(a); + CheckContextMatch(i); + return Expr.Create(this, Native.Z3_mk_select(nCtx, a.NativeObject, i.NativeObject)); + } + + /// + /// Array update. + /// + /// + /// The node a must have an array sort [domain -> range], + /// i must have sort domain, + /// v must have sort range. The sort of the result is [domain -> range]. + /// The semantics of this function is given by the theory of arrays described in the SMT-LIB + /// standard. See http://smtlib.org for more details. + /// The result of this function is an array that is equal to a + /// (with respect to select) + /// on all indices except for i, where it maps to v + /// (and the select of a with + /// respect to i may be a different value). + /// + /// + /// + public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) + { + Contract.Requires(a != null); + Contract.Requires(i != null); + Contract.Requires(v != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(a); + CheckContextMatch(i); + CheckContextMatch(v); + return new ArrayExpr(this, Native.Z3_mk_store(nCtx, a.NativeObject, i.NativeObject, v.NativeObject)); + } + + /// + /// Create a constant array. + /// + /// + /// The resulting term is an array, such that a selecton an arbitrary index + /// produces the value v. + /// + /// + /// + public ArrayExpr MkConstArray(Sort domain, Expr v) + { + Contract.Requires(domain != null); + Contract.Requires(v != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(domain); + CheckContextMatch(v); + return new ArrayExpr(this, Native.Z3_mk_const_array(nCtx, domain.NativeObject, v.NativeObject)); + } + + /// + /// Maps f on the argument arrays. + /// + /// + /// Eeach element of args must be of an array sort [domain_i -> range_i]. + /// The function declaration f must have type range_1 .. range_n -> range. + /// v must have sort range. The sort of the result is [domain_i -> range]. + /// + /// + /// + /// + public ArrayExpr MkMap(FuncDecl f, params ArrayExpr[] args) + { + Contract.Requires(f != null); + Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(f); + CheckContextMatch(args); + return (ArrayExpr)Expr.Create(this, Native.Z3_mk_map(nCtx, f.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args))); + } + + /// + /// Access the array default value. + /// + /// + /// Produces the default range value, for arrays that can be represented as + /// finite maps with a default range value. + /// + public Expr MkTermArray(ArrayExpr array) + { + Contract.Requires(array != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(array); + return Expr.Create(this, Native.Z3_mk_array_default(nCtx, array.NativeObject)); + } + #endregion + + #region Sets + /// + /// Create a set type. + /// + public SetSort MkSetSort(Sort ty) + { + Contract.Requires(ty != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(ty); + return new SetSort(this, ty); + } + + /// + /// Create an empty set. + /// + public Expr MkEmptySet(Sort domain) + { + Contract.Requires(domain != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(domain); + return Expr.Create(this, Native.Z3_mk_empty_set(nCtx, domain.NativeObject)); + } + + /// + /// Create the full set. + /// + public Expr MkFullSet(Sort domain) + { + Contract.Requires(domain != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(domain); + return Expr.Create(this, Native.Z3_mk_full_set(nCtx, domain.NativeObject)); + } + + /// + /// Add an element to the set. + /// + public Expr MkSetAdd(Expr set, Expr element) + { + Contract.Requires(set != null); + Contract.Requires(element != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(set); + CheckContextMatch(element); + return Expr.Create(this, Native.Z3_mk_set_add(nCtx, set.NativeObject, element.NativeObject)); + } + + + /// + /// Remove an element from a set. + /// + public Expr MkSetDel(Expr set, Expr element) + { + Contract.Requires(set != null); + Contract.Requires(element != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(set); + CheckContextMatch(element); + return Expr.Create(this, Native.Z3_mk_set_del(nCtx, set.NativeObject, element.NativeObject)); + } + + /// + /// Take the union of a list of sets. + /// + public Expr MkSetUnion(params Expr[] args) + { + Contract.Requires(args != null); + Contract.Requires(Contract.ForAll(args, a => a != null)); + + CheckContextMatch(args); + return Expr.Create(this, Native.Z3_mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + + /// + /// Take the intersection of a list of sets. + /// + public Expr MkSetIntersection(params Expr[] args) + { + Contract.Requires(args != null); + Contract.Requires(Contract.ForAll(args, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(args); + return Expr.Create(this, Native.Z3_mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + + /// + /// Take the difference between two sets. + /// + public Expr MkSetDifference(Expr arg1, Expr arg2) + { + Contract.Requires(arg1 != null); + Contract.Requires(arg2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(arg1); + CheckContextMatch(arg2); + return Expr.Create(this, Native.Z3_mk_set_difference(nCtx, arg1.NativeObject, arg2.NativeObject)); + } + + /// + /// Take the complement of a set. + /// + public Expr MkSetComplement(Expr arg) + { + Contract.Requires(arg != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(arg); + return Expr.Create(this, Native.Z3_mk_set_complement(nCtx, arg.NativeObject)); + } + + /// + /// Check for set membership. + /// + public Expr MkSetMembership(Expr elem, Expr set) + { + Contract.Requires(elem != null); + Contract.Requires(set != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(elem); + CheckContextMatch(set); + return Expr.Create(this, Native.Z3_mk_set_member(nCtx, elem.NativeObject, set.NativeObject)); + } + + /// + /// Check for subsetness of sets. + /// + public Expr MkSetSubset(Expr arg1, Expr arg2) + { + Contract.Requires(arg1 != null); + Contract.Requires(arg2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(arg1); + CheckContextMatch(arg2); + return Expr.Create(this, Native.Z3_mk_set_subset(nCtx, arg1.NativeObject, arg2.NativeObject)); + } + #endregion + + #region Numerals + + #region General Numerals + /// + /// Create a Term of a given sort. + /// + /// A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. + /// The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. + /// A Term with value and sort + public Expr MkNumeral(string v, Sort ty) + { + Contract.Requires(ty != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(ty); + return Expr.Create(this, Native.Z3_mk_numeral(nCtx, v, ty.NativeObject)); + } + + /// + /// Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + /// It is slightly faster than MakeNumeral since it is not necessary to parse a string. + /// + /// Value of the numeral + /// Sort of the numeral + /// A Term with value and type + public Expr MkNumeral(int v, Sort ty) + { + Contract.Requires(ty != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(ty); + return Expr.Create(this, Native.Z3_mk_int(nCtx, v, ty.NativeObject)); + } + + /// + /// Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + /// It is slightly faster than MakeNumeral since it is not necessary to parse a string. + /// + /// Value of the numeral + /// Sort of the numeral + /// A Term with value and type + public Expr MkNumeral(uint v, Sort ty) + { + Contract.Requires(ty != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(ty); + return Expr.Create(this, Native.Z3_mk_unsigned_int(nCtx, v, ty.NativeObject)); + } + + /// + /// Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + /// It is slightly faster than MakeNumeral since it is not necessary to parse a string. + /// + /// Value of the numeral + /// Sort of the numeral + /// A Term with value and type + public Expr MkNumeral(long v, Sort ty) + { + Contract.Requires(ty != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(ty); + return Expr.Create(this, Native.Z3_mk_int64(nCtx, v, ty.NativeObject)); + } + + /// + /// Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + /// It is slightly faster than MakeNumeral since it is not necessary to parse a string. + /// + /// Value of the numeral + /// Sort of the numeral + /// A Term with value and type + public Expr MkNumeral(ulong v, Sort ty) + { + Contract.Requires(ty != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(ty); + return Expr.Create(this, Native.Z3_mk_unsigned_int64(nCtx, v, ty.NativeObject)); + } + #endregion + + #region Reals + /// + /// Create a real from a fraction. + /// + /// numerator of rational. + /// denominator of rational. + /// A Term with value / and sort Real + /// + public RatNum MkReal(int num, int den) + { + if (den == 0) + throw new Z3Exception("Denominator is zero"); + + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + return new RatNum(this, Native.Z3_mk_real(nCtx, num, den)); + } + + /// + /// Create a real numeral. + /// + /// A string representing the Term value in decimal notation. + /// A Term with value and sort Real + public RatNum MkReal(string v) + { + Contract.Ensures(Contract.Result() != null); + + return new RatNum(this, Native.Z3_mk_numeral(nCtx, v, RealSort.NativeObject)); + } + + /// + /// Create a real numeral. + /// + /// value of the numeral. + /// A Term with value and sort Real + public RatNum MkReal(int v) + { + Contract.Ensures(Contract.Result() != null); + + return new RatNum(this, Native.Z3_mk_int(nCtx, v, RealSort.NativeObject)); + } + + /// + /// Create a real numeral. + /// + /// value of the numeral. + /// A Term with value and sort Real + public RatNum MkReal(uint v) + { + Contract.Ensures(Contract.Result() != null); + + return new RatNum(this, Native.Z3_mk_unsigned_int(nCtx, v, RealSort.NativeObject)); + } + + /// + /// Create a real numeral. + /// + /// value of the numeral. + /// A Term with value and sort Real + public RatNum MkReal(long v) + { + Contract.Ensures(Contract.Result() != null); + + return new RatNum(this, Native.Z3_mk_int64(nCtx, v, RealSort.NativeObject)); + } + + /// + /// Create a real numeral. + /// + /// value of the numeral. + /// A Term with value and sort Real + public RatNum MkReal(ulong v) + { + Contract.Ensures(Contract.Result() != null); + + return new RatNum(this, Native.Z3_mk_unsigned_int64(nCtx, v, RealSort.NativeObject)); + } + #endregion + + #region Integers + /// + /// Create an integer numeral. + /// + /// A string representing the Term value in decimal notation. + public IntNum MkInt(string v) + { + Contract.Ensures(Contract.Result() != null); + + return new IntNum(this, Native.Z3_mk_numeral(nCtx, v, IntSort.NativeObject)); + } + + /// + /// Create an integer numeral. + /// + /// value of the numeral. + /// A Term with value and sort Integer + public IntNum MkInt(int v) + { + Contract.Ensures(Contract.Result() != null); + + return new IntNum(this, Native.Z3_mk_int(nCtx, v, IntSort.NativeObject)); + } + + /// + /// Create an integer numeral. + /// + /// value of the numeral. + /// A Term with value and sort Integer + public IntNum MkInt(uint v) + { + Contract.Ensures(Contract.Result() != null); + + return new IntNum(this, Native.Z3_mk_unsigned_int(nCtx, v, IntSort.NativeObject)); + } + + /// + /// Create an integer numeral. + /// + /// value of the numeral. + /// A Term with value and sort Integer + public IntNum MkInt(long v) + { + Contract.Ensures(Contract.Result() != null); + + return new IntNum(this, Native.Z3_mk_int64(nCtx, v, IntSort.NativeObject)); + } + + /// + /// Create an integer numeral. + /// + /// value of the numeral. + /// A Term with value and sort Integer + public IntNum MkInt(ulong v) + { + Contract.Ensures(Contract.Result() != null); + + return new IntNum(this, Native.Z3_mk_unsigned_int64(nCtx, v, IntSort.NativeObject)); + } + #endregion + + #region Bit-vectors + /// + /// Create a bit-vector numeral. + /// + /// A string representing the value in decimal notation. + /// the size of the bit-vector + public BitVecNum MkBV(string v, uint size) + { + Contract.Ensures(Contract.Result() != null); + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + + /// + /// Create a bit-vector numeral. + /// + /// value of the numeral. + /// the size of the bit-vector + public BitVecNum MkBV(int v, uint size) + { + Contract.Ensures(Contract.Result() != null); + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + + /// + /// Create a bit-vector numeral. + /// + /// value of the numeral. + /// the size of the bit-vector + public BitVecNum MkBV(uint v, uint size) + { + Contract.Ensures(Contract.Result() != null); + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + + /// + /// Create a bit-vector numeral. + /// + /// value of the numeral. + /// /// the size of the bit-vector + public BitVecNum MkBV(long v, uint size) + { + Contract.Ensures(Contract.Result() != null); + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + + /// + /// Create a bit-vector numeral. + /// + /// value of the numeral. + /// the size of the bit-vector + public BitVecNum MkBV(ulong v, uint size) + { + Contract.Ensures(Contract.Result() != null); + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + #endregion + + #endregion // Numerals + + #region Quantifiers + /// + /// Create a universal Quantifier. + /// + /// + /// Creates a forall formula, where is the weight, + /// is an array of patterns, is an array + /// with the sorts of the bound variables, is an array with the + /// 'names' of the bound variables, and is the body of the + /// quantifier. Quantifiers are associated with weights indicating + /// the importance of using the quantifier during instantiation. + /// + /// the sorts of the bound variables. + /// names of the bound variables + /// the body of the quantifier. + /// quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. + /// array containing the patterns created using MkPattern. + /// array containing the anti-patterns created using MkPattern. + /// optional symbol to track quantifier. + /// optional symbol to track skolem constants. + public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + Contract.Requires(sorts != null); + Contract.Requires(names != null); + Contract.Requires(body != null); + Contract.Requires(sorts.Length == names.Length); + Contract.Requires(Contract.ForAll(sorts, s => s != null)); + Contract.Requires(Contract.ForAll(names, n => n != null)); + Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); + Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); + + Contract.Ensures(Contract.Result() != null); + + return new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + + /// + /// Create a universal Quantifier. + /// + public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + Contract.Requires(body != null); + Contract.Requires(boundConstants == null || Contract.ForAll(boundConstants, b => b != null)); + Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); + Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); + + Contract.Ensures(Contract.Result() != null); + + return new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + /// + /// Create an existential Quantifier. + /// + /// + public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + Contract.Requires(sorts != null); + Contract.Requires(names != null); + Contract.Requires(body != null); + Contract.Requires(sorts.Length == names.Length); + Contract.Requires(Contract.ForAll(sorts, s => s != null)); + Contract.Requires(Contract.ForAll(names, n => n != null)); + Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); + Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); + Contract.Ensures(Contract.Result() != null); + + return new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + /// + /// Create an existential Quantifier. + /// + public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + Contract.Requires(body != null); + Contract.Requires(boundConstants == null || Contract.ForAll(boundConstants, n => n != null)); + Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); + Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); + Contract.Ensures(Contract.Result() != null); + + return new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + + /// + /// Create a Quantifier. + /// + public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + Contract.Requires(body != null); + Contract.Requires(names != null); + Contract.Requires(sorts != null); + Contract.Requires(sorts.Length == names.Length); + Contract.Requires(Contract.ForAll(sorts, s => s != null)); + Contract.Requires(Contract.ForAll(names, n => n != null)); + Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); + Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); + + Contract.Ensures(Contract.Result() != null); + + if (universal) + return MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + return MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + + /// + /// Create a Quantifier. + /// + public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + Contract.Requires(body != null); + Contract.Requires(boundConstants == null || Contract.ForAll(boundConstants, n => n != null)); + Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); + Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); + + Contract.Ensures(Contract.Result() != null); + + if (universal) + return MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + #endregion + + #endregion // Expr + + #region Options + /// + /// Selects the format used for pretty-printing expressions. + /// + /// + /// The default mode for pretty printing expressions is to produce + /// SMT-LIB style output where common subexpressions are printed + /// at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. + /// To print shared common subexpressions only once, + /// use the Z3_PRINT_LOW_LEVEL mode. + /// To print in way that conforms to SMT-LIB standards and uses let + /// expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + /// + /// + /// + /// + /// + public Z3_ast_print_mode PrintMode + { + set { Native.Z3_set_ast_print_mode(nCtx, (uint)value); } + } + #endregion + + #region SMT Files & Strings + /// + /// Convert a benchmark into an SMT-LIB formatted string. + /// + /// Name of the benchmark. The argument is optional. + /// The benchmark logic. + /// The status string (sat, unsat, or unknown) + /// Other attributes, such as source, difficulty or category. + /// Auxiliary assumptions. + /// Formula to be checked for consistency in conjunction with assumptions. + /// A string representation of the benchmark. + public string BenchmarkToSMTString(string name, string logic, string status, string attributes, + BoolExpr[] assumptions, BoolExpr formula) + { + Contract.Requires(assumptions != null); + Contract.Requires(formula != null); + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_benchmark_to_smtlib_string(nCtx, name, logic, status, attributes, + (uint)assumptions.Length, AST.ArrayToNative(assumptions), + formula.NativeObject); + } + + /// + /// Parse the given string using the SMT-LIB parser. + /// + /// + /// The symbol table of the parser can be initialized using the given sorts and declarations. + /// The symbols in the arrays and + /// don't need to match the names of the sorts and declarations in the arrays + /// and . This is a useful feature since we can use arbitrary names to + /// reference sorts and declarations. + /// + public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null) + { + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Native.Z3_parse_smtlib_string(nCtx, str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); + } + + /// + /// Parse the given file using the SMT-LIB parser. + /// + /// + public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null) + { + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Native.Z3_parse_smtlib_file(nCtx, fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); + } + + /// + /// The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + /// + public uint NumSMTLIBFormulas { get { return Native.Z3_get_smtlib_num_formulas(nCtx); } } + + /// + /// The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + /// + public BoolExpr[] SMTLIBFormulas + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumSMTLIBFormulas; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)Expr.Create(this, Native.Z3_get_smtlib_formula(nCtx, i)); + return res; + } + } + + /// + /// The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + /// + public uint NumSMTLIBAssumptions { get { return Native.Z3_get_smtlib_num_assumptions(nCtx); } } + + /// + /// The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + /// + public BoolExpr[] SMTLIBAssumptions + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumSMTLIBAssumptions; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)Expr.Create(this, Native.Z3_get_smtlib_assumption(nCtx, i)); + return res; + } + } + + /// + /// The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + /// + public uint NumSMTLIBDecls { get { return Native.Z3_get_smtlib_num_decls(nCtx); } } + + /// + /// The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + /// + public FuncDecl[] SMTLIBDecls + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumSMTLIBDecls; + FuncDecl[] res = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + res[i] = new FuncDecl(this, Native.Z3_get_smtlib_decl(nCtx, i)); + return res; + } + } + + /// + /// The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + /// + public uint NumSMTLIBSorts { get { return Native.Z3_get_smtlib_num_sorts(nCtx); } } + + /// + /// The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + /// + public Sort[] SMTLIBSorts + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumSMTLIBSorts; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(this, Native.Z3_get_smtlib_sort(nCtx, i)); + return res; + } + } + + /// + /// Parse the given string using the SMT-LIB2 parser. + /// + /// + /// A conjunction of assertions in the scope (up to push/pop) at the end of the string. + public BoolExpr ParseSMTLIB2String(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null) + { + Contract.Ensures(Contract.Result() != null); + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + return (BoolExpr)Expr.Create(this, Native.Z3_parse_smtlib2_string(nCtx, str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); + } + + /// + /// Parse the given file using the SMT-LIB2 parser. + /// + /// + public BoolExpr ParseSMTLIB2File(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null) + { + Contract.Ensures(Contract.Result() != null); + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + return (BoolExpr)Expr.Create(this, Native.Z3_parse_smtlib2_file(nCtx, fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); + } + #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. + /// + /// + /// Note that the Context must have been created with proof generation support if + /// is set to true here. + /// + /// Indicates whether model generation should be enabled. + /// Indicates whether unsat core generation should be enabled. + /// Indicates whether proof generation should be enabled. + public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) + { + Contract.Ensures(Contract.Result() != null); + + return new Goal(this, models, unsatCores, proofs); + } + #endregion + + #region ParameterSets + /// + /// Creates a new ParameterSet. + /// + public Params MkParams() + { + Contract.Ensures(Contract.Result() != null); + + return new Params(this); + } + #endregion + + #region Tactics + /// + /// The number of supported tactics. + /// + public uint NumTactics + { + get { return Native.Z3_get_num_tactics(nCtx); } + } + + /// + /// The names of all supported tactics. + /// + public string[] TacticNames + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumTactics; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Native.Z3_get_tactic_name(nCtx, i); + return res; + } + } + + /// + /// Returns a string containing a description of the tactic with the given name. + /// + public string TacticDescription(string name) + { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_tactic_get_descr(nCtx, name); + } + + /// + /// Creates a new Tactic. + /// + public Tactic MkTactic(string name) + { + Contract.Ensures(Contract.Result() != null); + + return new Tactic(this, name); + } + + /// + /// Create a tactic that applies to a Goal and + /// then to every subgoal produced by . + /// + public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Requires(ts == null || Contract.ForAll(0, ts.Length, j => ts[j] != null)); + Contract.Ensures(Contract.Result() != null); + + + CheckContextMatch(t1); + CheckContextMatch(t2); + CheckContextMatch(ts); + + IntPtr last = IntPtr.Zero; + if (ts != null && ts.Length > 0) + { + last = ts[ts.Length - 1].NativeObject; + for (int i = ts.Length - 2; i >= 0; i--) + last = Native.Z3_tactic_and_then(nCtx, ts[i].NativeObject, last); + } + if (last != IntPtr.Zero) + { + last = Native.Z3_tactic_and_then(nCtx, t2.NativeObject, last); + return new Tactic(this, Native.Z3_tactic_and_then(nCtx, t1.NativeObject, last)); + } + else + return new Tactic(this, Native.Z3_tactic_and_then(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create a tactic that applies to a Goal and + /// then to every subgoal produced by . + /// + /// + /// Shorthand for AndThen. + /// + public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Requires(ts == null || Contract.ForAll(0, ts.Length, j => ts[j] != null)); + Contract.Ensures(Contract.Result() != null); + + return AndThen(t1, t2, ts); + } + + /// + /// Create a tactic that first applies to a Goal and + /// if it fails then returns the result of applied to the Goal. + /// + public Tactic OrElse(Tactic t1, Tactic t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Native.Z3_tactic_or_else(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create a tactic that applies to a goal for milliseconds. + /// + /// + /// If does not terminate within milliseconds, then it fails. + /// + public Tactic TryFor(Tactic t, uint ms) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new Tactic(this, Native.Z3_tactic_try_for(nCtx, t.NativeObject, ms)); + } + + /// + /// Create a tactic that applies to a given goal if the probe + /// evaluates to true. + /// + /// + /// If evaluates to false, then the new tactic behaves like the skip tactic. + /// + public Tactic When(Probe p, Tactic t) + { + Contract.Requires(p != null); + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + CheckContextMatch(p); + return new Tactic(this, Native.Z3_tactic_when(nCtx, p.NativeObject, t.NativeObject)); + } + + /// + /// Create a tactic that applies to a given goal if the probe + /// evaluates to true and otherwise. + /// + public Tactic Cond(Probe p, Tactic t1, Tactic t2) + { + Contract.Requires(p != null); + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p); + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Native.Z3_tactic_cond(nCtx, p.NativeObject, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Create a tactic that keeps applying until the goal is not + /// modified anymore or the maximum number of iterations is reached. + /// + public Tactic Repeat(Tactic t, uint max = uint.MaxValue) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new Tactic(this, Native.Z3_tactic_repeat(nCtx, t.NativeObject, max)); + } + + /// + /// Create a tactic that just returns the given goal. + /// + public Tactic Skip() + { + Contract.Ensures(Contract.Result() != null); + + return new Tactic(this, Native.Z3_tactic_skip(nCtx)); + } + + /// + /// Create a tactic always fails. + /// + public Tactic Fail() + { + Contract.Ensures(Contract.Result() != null); + + return new Tactic(this, Native.Z3_tactic_fail(nCtx)); + } + + /// + /// Create a tactic that fails if the probe evaluates to false. + /// + public Tactic FailIf(Probe p) + { + Contract.Requires(p != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p); + return new Tactic(this, Native.Z3_tactic_fail_if(nCtx, p.NativeObject)); + } + + /// + /// Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + /// or trivially unsatisfiable (i.e., contains `false'). + /// + public Tactic FailIfNotDecided() + { + Contract.Ensures(Contract.Result() != null); + + return new Tactic(this, Native.Z3_tactic_fail_if_not_decided(nCtx)); + } + + /// + /// Create a tactic that applies using the given set of parameters . + /// + public Tactic UsingParams(Tactic t, Params p) + { + Contract.Requires(t != null); + Contract.Requires(p != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + CheckContextMatch(p); + return new Tactic(this, Native.Z3_tactic_using_params(nCtx, t.NativeObject, p.NativeObject)); + } + + /// + /// Create a tactic that applies using the given set of parameters . + /// + /// Alias for UsingParams + public Tactic With(Tactic t, Params p) + { + Contract.Requires(t != null); + Contract.Requires(p != null); + Contract.Ensures(Contract.Result() != null); + + return UsingParams(t, p); + } + + /// + /// Create a tactic that applies the given tactics in parallel. + /// + public Tactic ParOr(params Tactic[] t) + { + Contract.Requires(t == null || Contract.ForAll(t, tactic => tactic != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new Tactic(this, Native.Z3_tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t))); + } + + /// + /// Create a tactic that applies to a given goal and then + /// to every subgoal produced by . The subgoals are processed in parallel. + /// + public Tactic ParAndThen(Tactic t1, Tactic t2) + { + Contract.Requires(t1 != null); + Contract.Requires(t2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Native.Z3_tactic_par_and_then(nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Interrupt the execution of a Z3 procedure. + /// + /// This procedure can be used to interrupt: solvers, simplifiers and tactics. + public void Interrupt() + { + Native.Z3_interrupt(nCtx); + } + #endregion + + #region Probes + /// + /// The number of supported Probes. + /// + public uint NumProbes + { + get { return Native.Z3_get_num_probes(nCtx); } + } + + /// + /// The names of all supported Probes. + /// + public string[] ProbeNames + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumProbes; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Native.Z3_get_probe_name(nCtx, i); + return res; + } + } + + /// + /// Returns a string containing a description of the probe with the given name. + /// + public string ProbeDescription(string name) + { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_probe_get_descr(nCtx, name); + } + + /// + /// Creates a new Probe. + /// + public Probe MkProbe(string name) + { + Contract.Ensures(Contract.Result() != null); + + return new Probe(this, name); + } + + /// + /// Create a probe that always evaluates to . + /// + public Probe Const(double val) + { + Contract.Ensures(Contract.Result() != null); + + return new Probe(this, Native.Z3_probe_const(nCtx, val)); + } + + /// + /// Create a probe that evaluates to "true" when the value returned by + /// is less than the value returned by + /// + public Probe Lt(Probe p1, Probe p2) + { + Contract.Requires(p1 != null); + Contract.Requires(p2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.Z3_probe_lt(nCtx, p1.NativeObject, p2.NativeObject)); + } + + /// + /// Create a probe that evaluates to "true" when the value returned by + /// is greater than the value returned by + /// + public Probe Gt(Probe p1, Probe p2) + { + Contract.Requires(p1 != null); + Contract.Requires(p2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.Z3_probe_gt(nCtx, p1.NativeObject, p2.NativeObject)); + } + + /// + /// Create a probe that evaluates to "true" when the value returned by + /// is less than or equal the value returned by + /// + public Probe Le(Probe p1, Probe p2) + { + Contract.Requires(p1 != null); + Contract.Requires(p2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.Z3_probe_le(nCtx, p1.NativeObject, p2.NativeObject)); + } + + /// + /// Create a probe that evaluates to "true" when the value returned by + /// is greater than or equal the value returned by + /// + public Probe Ge(Probe p1, Probe p2) + { + Contract.Requires(p1 != null); + Contract.Requires(p2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.Z3_probe_ge(nCtx, p1.NativeObject, p2.NativeObject)); + } + + /// + /// Create a probe that evaluates to "true" when the value returned by + /// is equal to the value returned by + /// + public Probe Eq(Probe p1, Probe p2) + { + Contract.Requires(p1 != null); + Contract.Requires(p2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.Z3_probe_eq(nCtx, p1.NativeObject, p2.NativeObject)); + } + + /// + /// Create a probe that evaluates to "true" when the value + /// and evaluate to "true". + /// + public Probe And(Probe p1, Probe p2) + { + Contract.Requires(p1 != null); + Contract.Requires(p2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.Z3_probe_and(nCtx, p1.NativeObject, p2.NativeObject)); + } + + /// + /// Create a probe that evaluates to "true" when the value + /// or evaluate to "true". + /// + public Probe Or(Probe p1, Probe p2) + { + Contract.Requires(p1 != null); + Contract.Requires(p2 != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.Z3_probe_or(nCtx, p1.NativeObject, p2.NativeObject)); + } + + /// + /// Create a probe that evaluates to "true" when the value + /// does not evaluate to "true". + /// + public Probe Not(Probe p) + { + Contract.Requires(p != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(p); + return new Probe(this, Native.Z3_probe_not(nCtx, p.NativeObject)); + } + #endregion + + #region Solvers + /// + /// Creates a new (incremental) solver. + /// + /// + /// This solver also uses a set of builtin tactics for handling the first + /// check-sat command, and check-sat commands that take more than a given + /// number of milliseconds to be solved. + /// + public Solver MkSolver(Symbol logic = null) + { + Contract.Ensures(Contract.Result() != null); + + if (logic == null) + return new Solver(this, Native.Z3_mk_solver(nCtx)); + else + return new Solver(this, Native.Z3_mk_solver_for_logic(nCtx, logic.NativeObject)); + } + + /// + /// Creates a new (incremental) solver. + /// + /// + public Solver MkSolver(string logic) + { + Contract.Ensures(Contract.Result() != null); + + return MkSolver(MkSymbol(logic)); + } + + /// + /// Creates a new (incremental) solver. + /// + public Solver MkSimpleSolver() + { + Contract.Ensures(Contract.Result() != null); + + return new Solver(this, Native.Z3_mk_simple_solver(nCtx)); + } + + /// + /// Creates a solver that is implemented using the given tactic. + /// + /// + /// The solver supports the commands Push and Pop, but it + /// will always solve each check from scratch. + /// + public Solver MkSolver(Tactic t) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + return new Solver(this, Native.Z3_mk_solver_from_tactic(nCtx, t.NativeObject)); + } + #endregion + + #region Fixedpoints + /// + /// Create a Fixedpoint context. + /// + public Fixedpoint MkFixedpoint() + { + Contract.Ensures(Contract.Result() != null); + + return new Fixedpoint(this); + } + #endregion + + + #region Miscellaneous + /// + /// Wraps an AST. + /// + /// This function is used for transitions between native and + /// managed objects. Note that must be a + /// native object obtained from Z3 (e.g., through ) + /// and that it must have a correct reference count (see e.g., + /// . + /// + /// The native pointer to wrap. + public AST WrapAST(IntPtr nativeObject) + { + Contract.Ensures(Contract.Result() != null); + return AST.Create(this, nativeObject); + } + + /// + /// Unwraps an AST. + /// + /// This function is used for transitions between native and + /// managed objects. It returns the native pointer to the AST. Note that + /// AST objects are reference counted and unwrapping an AST disables automatic + /// reference counting, i.e., all references to the IntPtr that is returned + /// must be handled externally and through native calls (see e.g., + /// ). + /// + /// The AST to unwrap. + public IntPtr UnwrapAST(AST a) + { + return a.NativeObject; + } + + /// + /// Return a string describing all available parameters to Expr.Simplify. + /// + public string SimplifyHelp() + { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_simplify_get_help(nCtx); + } + + /// + /// Retrieves parameter descriptions for simplifier. + /// + public ParamDescrs SimplifyParameterDescriptions + { + get + { + return new ParamDescrs(this, Native.Z3_simplify_get_param_descrs(nCtx)); + } + } + + + /// + /// Enable/disable printing of warning messages to the console. + /// + /// Note that this function is static and effects the behaviour of + /// all contexts globally. + public static void ToggleWarningMessages(bool enabled) + { + Native.Z3_toggle_warning_messages((enabled) ? 1 : 0); + } + #endregion + + #region Error Handling + ///// + ///// A delegate which is executed when an error is raised. + ///// + ///// + ///// Note that it is possible for memory leaks to occur if error handlers + ///// throw exceptions. + ///// + //public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); + + ///// + ///// The OnError event. + ///// + //public event ErrorHandler OnError = null; + #endregion + + #region Parameters + /// + /// Update a mutable configuration parameter. + /// + /// + /// The list of all configuration parameters can be obtained using the Z3 executable: + /// z3.exe -ini? + /// Only a few configuration parameters are mutable once the context is created. + /// An exception is thrown when trying to modify an immutable parameter. + /// + /// + public void UpdateParamValue(string id, string value) + { + Native.Z3_update_param_value(nCtx, id, value); + } + + /// + /// Get a configuration parameter. + /// + /// + /// Returns null if the parameter value does not exist. + /// + /// + public string GetParamValue(string id) + { + IntPtr res = IntPtr.Zero; + int r = Native.Z3_get_param_value(nCtx, id, out res); + if (r == (int)Z3_lbool.Z3_L_FALSE) + return null; + else + return Marshal.PtrToStringAnsi(res); + } + + #endregion + + #region Internal + internal IntPtr m_ctx = IntPtr.Zero; + internal Native.Z3_error_handler m_n_err_handler = null; + internal IntPtr nCtx { get { return m_ctx; } } + + internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) + { + // Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + } + + internal void InitContext() + { + PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; + m_n_err_handler = new Native.Z3_error_handler(NativeErrorHandler); // keep reference so it doesn't get collected. + Native.Z3_set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); + } + + [Pure] + internal void CheckContextMatch(Z3Object other) + { + Contract.Requires(other != null); + + if (!ReferenceEquals(this, other.Context)) + throw new Z3Exception("Context mismatch"); + } + + [Pure] + internal void CheckContextMatch(Z3Object[] arr) + { + Contract.Requires(arr == null || Contract.ForAll(arr, a => a != null)); + + if (arr != null) + { + foreach (Z3Object a in arr) + { + Contract.Assert(a != null); // It was an assume, now we added the precondition, and we made it into an assert + CheckContextMatch(a); + } + } + } + + [ContractInvariantMethod] + private void ObjectInvariant() + { + Contract.Invariant(m_AST_DRQ != null); + Contract.Invariant(m_ASTMap_DRQ != null); + Contract.Invariant(m_ASTVector_DRQ != null); + Contract.Invariant(m_ApplyResult_DRQ != null); + Contract.Invariant(m_FuncEntry_DRQ != null); + Contract.Invariant(m_FuncInterp_DRQ != null); + Contract.Invariant(m_Goal_DRQ != null); + Contract.Invariant(m_Model_DRQ != null); + Contract.Invariant(m_Params_DRQ != null); + Contract.Invariant(m_ParamDescrs_DRQ != null); + Contract.Invariant(m_Probe_DRQ != null); + Contract.Invariant(m_Solver_DRQ != null); + Contract.Invariant(m_Statistics_DRQ != null); + Contract.Invariant(m_Tactic_DRQ != null); + Contract.Invariant(m_Fixedpoint_DRQ != null); + } + + readonly private AST.DecRefQueue m_AST_DRQ = new AST.DecRefQueue(); + readonly private ASTMap.DecRefQueue m_ASTMap_DRQ = new ASTMap.DecRefQueue(); + readonly private ASTVector.DecRefQueue m_ASTVector_DRQ = new ASTVector.DecRefQueue(); + readonly private ApplyResult.DecRefQueue m_ApplyResult_DRQ = new ApplyResult.DecRefQueue(); + readonly private FuncInterp.Entry.DecRefQueue m_FuncEntry_DRQ = new FuncInterp.Entry.DecRefQueue(); + readonly private FuncInterp.DecRefQueue m_FuncInterp_DRQ = new FuncInterp.DecRefQueue(); + readonly private Goal.DecRefQueue m_Goal_DRQ = new Goal.DecRefQueue(); + readonly private Model.DecRefQueue m_Model_DRQ = new Model.DecRefQueue(); + readonly private Params.DecRefQueue m_Params_DRQ = new Params.DecRefQueue(); + readonly private ParamDescrs.DecRefQueue m_ParamDescrs_DRQ = new ParamDescrs.DecRefQueue(); + readonly private Probe.DecRefQueue m_Probe_DRQ = new Probe.DecRefQueue(); + readonly private Solver.DecRefQueue m_Solver_DRQ = new Solver.DecRefQueue(); + readonly private Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue(); + readonly private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.DecRefQueue(); + readonly private Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue(); + + internal AST.DecRefQueue AST_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_AST_DRQ; } } + internal ASTMap.DecRefQueue ASTMap_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_ASTMap_DRQ; } } + internal ASTVector.DecRefQueue ASTVector_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_ASTVector_DRQ; } } + internal ApplyResult.DecRefQueue ApplyResult_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_ApplyResult_DRQ; } } + internal FuncInterp.Entry.DecRefQueue FuncEntry_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_FuncEntry_DRQ; } } + internal FuncInterp.DecRefQueue FuncInterp_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_FuncInterp_DRQ; } } + internal Goal.DecRefQueue Goal_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_Goal_DRQ; } } + internal Model.DecRefQueue Model_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_Model_DRQ; } } + internal Params.DecRefQueue Params_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_Params_DRQ; } } + internal ParamDescrs.DecRefQueue ParamDescrs_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_ParamDescrs_DRQ; } } + internal Probe.DecRefQueue Probe_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_Probe_DRQ; } } + internal Solver.DecRefQueue Solver_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_Solver_DRQ; } } + internal Statistics.DecRefQueue Statistics_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_Statistics_DRQ; } } + internal Tactic.DecRefQueue Tactic_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_Tactic_DRQ; } } + internal Fixedpoint.DecRefQueue Fixedpoint_DRQ { get { Contract.Ensures(Contract.Result() != null); return m_Fixedpoint_DRQ; } } + + + internal uint refCount = 0; + + /// + /// Finalizer. + /// + ~Context() + { + // Console.WriteLine("Context Finalizer from " + System.Threading.Thread.CurrentThread.ManagedThreadId); + Dispose(); + + if (refCount == 0) + { + m_n_err_handler = null; + Native.Z3_del_context(m_ctx); + m_ctx = IntPtr.Zero; + } + else + GC.ReRegisterForFinalize(this); + } + + /// + /// Disposes of the context. + /// + public void Dispose() + { + // Console.WriteLine("Context Dispose from " + System.Threading.Thread.CurrentThread.ManagedThreadId); + AST_DRQ.Clear(this); + ASTMap_DRQ.Clear(this); + ASTVector_DRQ.Clear(this); + ApplyResult_DRQ.Clear(this); + FuncEntry_DRQ.Clear(this); + FuncInterp_DRQ.Clear(this); + Goal_DRQ.Clear(this); + Model_DRQ.Clear(this); + Params_DRQ.Clear(this); + Probe_DRQ.Clear(this); + Solver_DRQ.Clear(this); + Statistics_DRQ.Clear(this); + Tactic_DRQ.Clear(this); + Fixedpoint_DRQ.Clear(this); + + m_boolSort = null; + m_intSort = null; + m_realSort = null; + } + #endregion + } +} diff --git a/Microsoft.Z3/DecRefQUeue.cs b/Microsoft.Z3/DecRefQUeue.cs new file mode 100644 index 000000000..777a5d5af --- /dev/null +++ b/Microsoft.Z3/DecRefQUeue.cs @@ -0,0 +1,92 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + DecRefQueue.cs + +Abstract: + + Z3 Managed API: DecRef Queues + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-16 + +Notes: + +--*/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + [ContractClass(typeof(DecRefQueueContracts))] + internal abstract class DecRefQueue + { + #region Object invariant + + [ContractInvariantMethod] + private void ObjectInvariant() + { + Contract.Invariant(this.m_queue != null); + } + + #endregion + + readonly internal protected Object m_lock = new Object(); + readonly internal protected List m_queue = new List(); + internal const uint m_move_limit = 1024; + + public abstract void IncRef(Context ctx, IntPtr obj); + public abstract void DecRef(Context ctx, IntPtr obj); + + public void IncAndClear(Context ctx, IntPtr o) + { + Contract.Requires(ctx != null); + + IncRef(ctx, o); + if (m_queue.Count >= m_move_limit) Clear(ctx); + } + + public void Add(IntPtr o) + { + if (o == IntPtr.Zero) return; + + lock (m_lock) + { + m_queue.Add(o); + } + } + + public void Clear(Context ctx) + { + Contract.Requires(ctx != null); + + lock (m_lock) + { + foreach (IntPtr o in m_queue) + DecRef(ctx, o); + m_queue.Clear(); + } + } + } + + [ContractClassFor(typeof(DecRefQueue))] + abstract class DecRefQueueContracts : DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Contract.Requires(ctx != null); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Contract.Requires(ctx != null); + } + } +} diff --git a/Microsoft.Z3/Enumerations.cs b/Microsoft.Z3/Enumerations.cs new file mode 100644 index 000000000..8e041ef41 --- /dev/null +++ b/Microsoft.Z3/Enumerations.cs @@ -0,0 +1,257 @@ +// Automatically generated file, generator: mk_z3consts.py + +using System; + +#pragma warning disable 1591 + +namespace Microsoft.Z3 +{ + /// Z3_lbool + public enum Z3_lbool { + Z3_L_TRUE = 1, + Z3_L_UNDEF = 0, + Z3_L_FALSE = -1, + } + + /// Z3_symbol_kind + public enum Z3_symbol_kind { + Z3_INT_SYMBOL = 0, + Z3_STRING_SYMBOL = 1, + } + + /// Z3_parameter_kind + public enum Z3_parameter_kind { + Z3_PARAMETER_FUNC_DECL = 6, + Z3_PARAMETER_DOUBLE = 1, + Z3_PARAMETER_SYMBOL = 3, + Z3_PARAMETER_INT = 0, + Z3_PARAMETER_AST = 5, + Z3_PARAMETER_SORT = 4, + Z3_PARAMETER_RATIONAL = 2, + } + + /// Z3_sort_kind + public enum Z3_sort_kind { + Z3_BV_SORT = 4, + Z3_FINITE_DOMAIN_SORT = 8, + Z3_ARRAY_SORT = 5, + Z3_UNKNOWN_SORT = 1000, + Z3_RELATION_SORT = 7, + Z3_REAL_SORT = 3, + Z3_INT_SORT = 2, + Z3_UNINTERPRETED_SORT = 0, + Z3_BOOL_SORT = 1, + Z3_DATATYPE_SORT = 6, + } + + /// Z3_ast_kind + public enum Z3_ast_kind { + Z3_VAR_AST = 2, + Z3_SORT_AST = 4, + Z3_QUANTIFIER_AST = 3, + Z3_UNKNOWN_AST = 1000, + Z3_FUNC_DECL_AST = 5, + Z3_NUMERAL_AST = 0, + Z3_APP_AST = 1, + } + + /// Z3_decl_kind + public enum Z3_decl_kind { + Z3_OP_LABEL = 1792, + Z3_OP_PR_REWRITE = 1294, + Z3_OP_UNINTERPRETED = 2051, + Z3_OP_SUB = 519, + Z3_OP_ZERO_EXT = 1058, + Z3_OP_ADD = 518, + Z3_OP_IS_INT = 528, + Z3_OP_BREDOR = 1061, + Z3_OP_BNOT = 1051, + Z3_OP_BNOR = 1054, + Z3_OP_PR_CNF_STAR = 1315, + Z3_OP_RA_JOIN = 1539, + Z3_OP_LE = 514, + Z3_OP_SET_UNION = 773, + Z3_OP_PR_UNDEF = 1280, + Z3_OP_BREDAND = 1062, + Z3_OP_LT = 516, + Z3_OP_RA_UNION = 1540, + Z3_OP_BADD = 1028, + Z3_OP_BUREM0 = 1039, + Z3_OP_OEQ = 267, + Z3_OP_PR_MODUS_PONENS = 1284, + Z3_OP_RA_CLONE = 1548, + Z3_OP_REPEAT = 1060, + Z3_OP_RA_NEGATION_FILTER = 1544, + Z3_OP_BSMOD0 = 1040, + Z3_OP_BLSHR = 1065, + Z3_OP_BASHR = 1066, + Z3_OP_PR_UNIT_RESOLUTION = 1304, + Z3_OP_ROTATE_RIGHT = 1068, + Z3_OP_ARRAY_DEFAULT = 772, + Z3_OP_PR_PULL_QUANT = 1296, + Z3_OP_PR_APPLY_DEF = 1310, + Z3_OP_PR_REWRITE_STAR = 1295, + Z3_OP_IDIV = 523, + Z3_OP_PR_GOAL = 1283, + Z3_OP_PR_IFF_TRUE = 1305, + Z3_OP_LABEL_LIT = 1793, + Z3_OP_BOR = 1050, + Z3_OP_PR_SYMMETRY = 1286, + Z3_OP_TRUE = 256, + Z3_OP_SET_COMPLEMENT = 776, + Z3_OP_CONCAT = 1056, + Z3_OP_PR_NOT_OR_ELIM = 1293, + Z3_OP_IFF = 263, + Z3_OP_BSHL = 1064, + Z3_OP_PR_TRANSITIVITY = 1287, + Z3_OP_SGT = 1048, + Z3_OP_RA_WIDEN = 1541, + Z3_OP_PR_DEF_INTRO = 1309, + Z3_OP_NOT = 265, + Z3_OP_PR_QUANT_INTRO = 1290, + Z3_OP_UGT = 1047, + Z3_OP_DT_RECOGNISER = 2049, + Z3_OP_SET_INTERSECT = 774, + Z3_OP_BSREM = 1033, + Z3_OP_RA_STORE = 1536, + Z3_OP_SLT = 1046, + Z3_OP_ROTATE_LEFT = 1067, + Z3_OP_PR_NNF_NEG = 1313, + Z3_OP_PR_REFLEXIVITY = 1285, + Z3_OP_ULEQ = 1041, + Z3_OP_BIT1 = 1025, + Z3_OP_BIT0 = 1026, + Z3_OP_EQ = 258, + Z3_OP_BMUL = 1030, + Z3_OP_ARRAY_MAP = 771, + Z3_OP_STORE = 768, + Z3_OP_PR_HYPOTHESIS = 1302, + Z3_OP_RA_RENAME = 1545, + Z3_OP_AND = 261, + Z3_OP_TO_REAL = 526, + Z3_OP_PR_NNF_POS = 1312, + Z3_OP_PR_AND_ELIM = 1292, + Z3_OP_MOD = 525, + Z3_OP_BUDIV0 = 1037, + Z3_OP_PR_TRUE = 1281, + Z3_OP_BNAND = 1053, + Z3_OP_PR_ELIM_UNUSED_VARS = 1299, + Z3_OP_RA_FILTER = 1543, + Z3_OP_FD_LT = 1549, + Z3_OP_RA_EMPTY = 1537, + Z3_OP_DIV = 522, + Z3_OP_ANUM = 512, + Z3_OP_MUL = 521, + Z3_OP_UGEQ = 1043, + Z3_OP_BSREM0 = 1038, + Z3_OP_PR_TH_LEMMA = 1318, + Z3_OP_BXOR = 1052, + Z3_OP_DISTINCT = 259, + Z3_OP_PR_IFF_FALSE = 1306, + Z3_OP_BV2INT = 1072, + Z3_OP_EXT_ROTATE_LEFT = 1069, + Z3_OP_PR_PULL_QUANT_STAR = 1297, + Z3_OP_BSUB = 1029, + Z3_OP_PR_ASSERTED = 1282, + Z3_OP_BXNOR = 1055, + Z3_OP_EXTRACT = 1059, + Z3_OP_PR_DER = 1300, + Z3_OP_DT_CONSTRUCTOR = 2048, + Z3_OP_GT = 517, + Z3_OP_BUREM = 1034, + Z3_OP_IMPLIES = 266, + Z3_OP_SLEQ = 1042, + Z3_OP_GE = 515, + Z3_OP_BAND = 1049, + Z3_OP_ITE = 260, + Z3_OP_AS_ARRAY = 778, + Z3_OP_RA_SELECT = 1547, + Z3_OP_CONST_ARRAY = 770, + Z3_OP_BSDIV = 1031, + Z3_OP_OR = 262, + Z3_OP_AGNUM = 513, + Z3_OP_PR_PUSH_QUANT = 1298, + Z3_OP_BSMOD = 1035, + Z3_OP_PR_IFF_OEQ = 1311, + Z3_OP_PR_LEMMA = 1303, + Z3_OP_SET_SUBSET = 777, + Z3_OP_SELECT = 769, + Z3_OP_RA_PROJECT = 1542, + Z3_OP_BNEG = 1027, + Z3_OP_UMINUS = 520, + Z3_OP_REM = 524, + Z3_OP_TO_INT = 527, + Z3_OP_PR_QUANT_INST = 1301, + Z3_OP_SGEQ = 1044, + Z3_OP_POWER = 529, + Z3_OP_XOR3 = 1074, + Z3_OP_RA_IS_EMPTY = 1538, + Z3_OP_CARRY = 1073, + Z3_OP_DT_ACCESSOR = 2050, + Z3_OP_PR_TRANSITIVITY_STAR = 1288, + Z3_OP_PR_NNF_STAR = 1314, + Z3_OP_PR_COMMUTATIVITY = 1307, + Z3_OP_ULT = 1045, + Z3_OP_BSDIV0 = 1036, + Z3_OP_SET_DIFFERENCE = 775, + Z3_OP_INT2BV = 1071, + Z3_OP_XOR = 264, + Z3_OP_PR_MODUS_PONENS_OEQ = 1317, + Z3_OP_BNUM = 1024, + Z3_OP_BUDIV = 1032, + Z3_OP_PR_MONOTONICITY = 1289, + Z3_OP_PR_DEF_AXIOM = 1308, + Z3_OP_FALSE = 257, + Z3_OP_EXT_ROTATE_RIGHT = 1070, + Z3_OP_PR_DISTRIBUTIVITY = 1291, + Z3_OP_SIGN_EXT = 1057, + Z3_OP_PR_SKOLEMIZE = 1316, + Z3_OP_BCOMP = 1063, + Z3_OP_RA_COMPLEMENT = 1546, + } + + /// Z3_param_kind + public enum Z3_param_kind { + Z3_PK_BOOL = 1, + Z3_PK_SYMBOL = 3, + Z3_PK_OTHER = 5, + Z3_PK_INVALID = 6, + Z3_PK_UINT = 0, + Z3_PK_STRING = 4, + Z3_PK_DOUBLE = 2, + } + + /// Z3_ast_print_mode + public enum Z3_ast_print_mode { + Z3_PRINT_SMTLIB2_COMPLIANT = 3, + Z3_PRINT_SMTLIB_COMPLIANT = 2, + Z3_PRINT_SMTLIB_FULL = 0, + Z3_PRINT_LOW_LEVEL = 1, + } + + /// Z3_error_code + public enum Z3_error_code { + Z3_INVALID_PATTERN = 6, + Z3_MEMOUT_FAIL = 7, + Z3_NO_PARSER = 5, + Z3_OK = 0, + Z3_INVALID_ARG = 3, + Z3_EXCEPTION = 12, + Z3_IOB = 2, + Z3_INTERNAL_FATAL = 9, + Z3_INVALID_USAGE = 10, + Z3_FILE_ACCESS_ERROR = 8, + Z3_SORT_ERROR = 1, + Z3_PARSER_ERROR = 4, + Z3_DEC_REF_ERROR = 11, + } + + /// Z3_goal_prec + public enum Z3_goal_prec { + Z3_GOAL_UNDER = 1, + Z3_GOAL_PRECISE = 0, + Z3_GOAL_UNDER_OVER = 3, + Z3_GOAL_OVER = 2, + } + +} diff --git a/Microsoft.Z3/Expr.cs b/Microsoft.Z3/Expr.cs new file mode 100644 index 000000000..428381ae8 --- /dev/null +++ b/Microsoft.Z3/Expr.cs @@ -0,0 +1,1677 @@ +/*++ +Copyright () 2012 Microsoft Corporation + +Module Name: + + Expr.cs + +Abstract: + + Z3 Managed API: Expressions + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-20 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Expressions are terms. + /// + [ContractVerification(true)] + public class Expr : AST + { + /// + /// Returns a simplified version of the expression. + /// + /// A set of parameters to configure the simplifier + /// + public Expr Simplify(Params p = null) + { + Contract.Ensures(Contract.Result() != null); + + if (p == null) + return Expr.Create(Context, Native.Z3_simplify(Context.nCtx, NativeObject)); + else + return Expr.Create(Context, Native.Z3_simplify_ex(Context.nCtx, NativeObject, p.NativeObject)); + } + + /// + /// The function declaration of the function that is applied in this expression. + /// + public FuncDecl FuncDecl + { + get { + Contract.Ensures(Contract.Result() != null); + return new FuncDecl(Context, Native.Z3_get_app_decl(Context.nCtx, NativeObject)); } + } + + /// + /// Indicates whether the expression is the true or false expression + /// or something else (Z3_L_UNDEF). + /// + public Z3_lbool BoolValue + { + get { return (Z3_lbool)Native.Z3_get_bool_value(Context.nCtx, NativeObject); } + } + + /// + /// The number of arguments of the expression. + /// + public uint NumArgs + { + get { return Native.Z3_get_app_num_args(Context.nCtx, NativeObject); } + } + + /// + /// The arguments of the expression. + /// + public Expr[] Args + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumArgs; + Expr[] res = new Expr[n]; + for (uint i = 0; i < n; i++) + res[i] = Expr.Create(Context, Native.Z3_get_app_arg(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// Update the arguments of the expression using the arguments + /// The number of new arguments should coincide with the current number of arguments. + /// + public void Update(Expr[] args) + { + Contract.Requires(args != null); + Contract.Requires(Contract.ForAll(args, a => a != null)); + + Context.CheckContextMatch(args); + if (args.Length != NumArgs) + throw new Z3Exception("Number of arguments does not match"); + NativeObject = Native.Z3_update_term(Context.nCtx, NativeObject, (uint)args.Length, Expr.ArrayToNative(args)); + } + + /// + /// Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + /// + /// + /// The result is the new expression. The arrays from and to must have size num_exprs. + /// For every i smaller than num_exprs, we must have that + /// sort of from[i] must be equal to sort of to[i]. + /// + public Expr Substitute(Expr[] from, Expr[] to) + { + Contract.Requires(from != null); + Contract.Requires(to != null); + Contract.Requires(Contract.ForAll(from, f => f != null)); + Contract.Requires(Contract.ForAll(to, t => t != null)); + Contract.Ensures(Contract.Result() != null); + + Context.CheckContextMatch(from); + Context.CheckContextMatch(to); + if (from.Length != to.Length) + throw new Z3Exception("Argument sizes do not match"); + return Expr.Create(Context, Native.Z3_substitute(Context.nCtx, NativeObject, (uint)from.Length, Expr.ArrayToNative(from), Expr.ArrayToNative(to))); + } + + /// + /// Substitute every occurrence of from in the expression with to. + /// + /// + public Expr Substitute(Expr from, Expr to) + { + Contract.Requires(from != null); + Contract.Requires(to != null); + Contract.Ensures(Contract.Result() != null); + + return Substitute(new Expr[] { from }, new Expr[] { to }); + } + + /// + /// Substitute the free variables in the expression with the expressions in + /// + /// + /// For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. + /// + public Expr SubstituteVars(Expr[] to) + { + Contract.Requires(to != null); + Contract.Requires(Contract.ForAll(to, t => t != null)); + Contract.Ensures(Contract.Result() != null); + + Context.CheckContextMatch(to); + return Expr.Create(Context, Native.Z3_substitute_vars(Context.nCtx, NativeObject, (uint)to.Length, Expr.ArrayToNative(to))); + } + + /// + /// Translates (copies) the term to the Context . + /// + /// A context + /// A copy of the term which is associated with + new public Expr Translate(Context ctx) + { + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result() != null); + + if (ReferenceEquals(Context, ctx)) + return this; + else + return Expr.Create(ctx, Native.Z3_translate(Context.nCtx, NativeObject, ctx.nCtx)); + } + + /// + /// Returns a string representation of the expression. + /// + public override string ToString() + { + return base.ToString(); + } + + /// + /// Indicates whether the term is a numeral + /// + public bool IsNumeral + { + get { return Native.Z3_is_numeral_ast(Context.nCtx, NativeObject) != 0; } + } + + /// + /// Indicates whether the term is well-sorted. + /// + /// True if the term is well-sorted, false otherwise. + public bool IsWellSorted + { + get { return Native.Z3_is_well_sorted(Context.nCtx, NativeObject) != 0; } + } + + /// + /// The Sort of the term. + /// + public Sort Sort + { + get { + Contract.Ensures(Contract.Result() != null); + return Sort.Create(Context, Native.Z3_get_sort(Context.nCtx, NativeObject)); } + } + + #region Constants + /// + /// Indicates whether the term represents a constant. + /// + public bool IsConst + { + get { return IsExpr && NumArgs == 0 && FuncDecl.DomainSize == 0; } + } + #endregion + + #region Integer Numerals + /// + /// Indicates whether the term is an integer numeral. + /// + public bool IsIntNum + { + get { return IsNumeral && IsInt; } + } + #endregion + + #region Real Numerals + /// + /// Indicates whether the term is a real numeral. + /// + public bool IsRatNum + { + get { return IsNumeral && IsReal; } + } + #endregion + + #region Algebraic Numbers + /// + /// Indicates whether the term is an algebraic number + /// + public bool IsAlgebraicNumber + { + get { return Native.Z3_is_algebraic_number(Context.nCtx, NativeObject) != 0; } + } + #endregion + + #region Term Kind Tests + + #region Boolean Terms + /// + /// Indicates whether the term has Boolean sort. + /// + public bool IsBool + { + get + { + return (IsExpr && + Native.Z3_is_eq_sort(Context.nCtx, + Native.Z3_mk_bool_sort(Context.nCtx), + Native.Z3_get_sort(Context.nCtx, NativeObject)) != 0); + } + } + + /// + /// Indicates whether the term is the constant true. + /// + public bool IsTrue { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TRUE; } } + + /// + /// Indicates whether the term is the constant false. + /// + public bool IsFalse { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FALSE; } } + + /// + /// Indicates whether the term is an equality predicate. + /// + public bool IsEq { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EQ; } } + + /// + /// Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). + /// + public bool IsDistinct { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_DISTINCT; } } + + /// + /// Indicates whether the term is a ternary if-then-else term + /// + public bool IsITE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ITE; } } + + /// + /// Indicates whether the term is an n-ary conjunction + /// + public bool IsAnd { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_AND; } } + + /// + /// Indicates whether the term is an n-ary disjunction + /// + public bool IsOr { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_OR; } } + + /// + /// Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) + /// + public bool IsIff { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IFF; } } + + /// + /// Indicates whether the term is an exclusive or + /// + public bool IsXor { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_XOR; } } + + /// + /// Indicates whether the term is a negation + /// + public bool IsNot { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_NOT; } } + + /// + /// Indicates whether the term is an implication + /// + public bool IsImplies { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IMPLIES; } } + #endregion + + #region Arithmetic Terms + /// + /// Indicates whether the term is of integer sort. + /// + public bool IsInt + { + get + { + return (Native.Z3_is_numeral_ast(Context.nCtx, NativeObject) != 0 && + Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == (uint)Z3_sort_kind.Z3_INT_SORT); + } + } + + /// + /// Indicates whether the term is of sort real. + /// + public bool IsReal + { + get { return Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == (uint)Z3_sort_kind.Z3_REAL_SORT; } + } + + /// + /// Indicates whether the term is an arithmetic numeral. + /// + public bool IsArithmeticNumeral { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ANUM; } } + + /// + /// Indicates whether the term is a less-than-or-equal + /// + public bool IsLE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LE; } } + + /// + /// Indicates whether the term is a greater-than-or-equal + /// + public bool IsGE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_GE; } } + + /// + /// Indicates whether the term is a less-than + /// + public bool IsLT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LT; } } + + /// + /// Indicates whether the term is a greater-than + /// + public bool IsGT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_GT; } } + + /// + /// Indicates whether the term is addition (binary) + /// + public bool IsAdd { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ADD; } } + + /// + /// Indicates whether the term is subtraction (binary) + /// + public bool IsSub { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SUB; } } + + /// + /// Indicates whether the term is a unary minus + /// + public bool IsUMinus { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UMINUS; } } + + /// + /// Indicates whether the term is multiplication (binary) + /// + public bool IsMul { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_MUL; } } + + /// + /// Indicates whether the term is division (binary) + /// + public bool IsDiv { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_DIV; } } + + /// + /// Indicates whether the term is integer division (binary) + /// + public bool IsIDiv { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IDIV; } } + + /// + /// Indicates whether the term is remainder (binary) + /// + public bool IsRemainder { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_REM; } } + + /// + /// Indicates whether the term is modulus (binary) + /// + public bool IsModulus { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_MOD; } } + + /// + /// Indicates whether the term is a coercion of integer to real (unary) + /// + public bool IsIntToReal { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TO_REAL; } } + + /// + /// Indicates whether the term is a coercion of real to integer (unary) + /// + public bool IsRealToInt { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TO_INT; } } + + /// + /// Indicates whether the term is a check that tests whether a real is integral (unary) + /// + public bool IsRealIsInt { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IS_INT; } } + #endregion + + #region Array Terms + /// + /// Indicates whether the term is of an array sort. + /// + public bool IsArray + { + get + { + return (Native.Z3_is_app(Context.nCtx, NativeObject) != 0 && + (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_ARRAY_SORT); + } + } + + /// + /// Indicates whether the term is an array store. + /// + /// It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + /// Array store takes at least 3 arguments. + public bool IsStore { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_STORE; } } + + /// + /// Indicates whether the term is an array select. + /// + public bool IsSelect { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SELECT; } } + + /// + /// Indicates whether the term is a constant array. + /// + /// For example, select(const(v),i) = v holds for every v and i. The function is unary. + public bool IsConstantArray { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CONST_ARRAY; } } + + /// + /// Indicates whether the term is a default array. + /// + /// For example default(const(v)) = v. The function is unary. + public bool IsDefaultArray { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ARRAY_DEFAULT; } } + + /// + /// Indicates whether the term is an array map. + /// + /// It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. + public bool IsArrayMap { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ARRAY_MAP; } } + + /// + /// Indicates whether the term is an as-array term. + /// + /// An as-array term is n array value that behaves as the function graph of the + /// function passed as parameter. + public bool IsAsArray { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_AS_ARRAY; } } + #endregion + + #region Set Terms + /// + /// Indicates whether the term is set union + /// + public bool IsSetUnion { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_UNION; } } + + /// + /// Indicates whether the term is set intersection + /// + public bool IsSetIntersect { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_INTERSECT; } } + + /// + /// Indicates whether the term is set difference + /// + public bool IsSetDifference { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_DIFFERENCE; } } + + /// + /// Indicates whether the term is set complement + /// + public bool IsSetComplement { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_COMPLEMENT; } } + + /// + /// Indicates whether the term is set subset + /// + public bool IsSetSubset { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_SUBSET; } } + #endregion + + #region Bit-vector terms + /// + /// Indicates whether the terms is of bit-vector sort. + /// + public bool IsBV + { + get { return Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == (uint)Z3_sort_kind.Z3_BV_SORT; } + } + + /// + /// Indicates whether the term is a bit-vector numeral + /// + public bool IsBVNumeral { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNUM; } } + + /// + /// Indicates whether the term is a one-bit bit-vector with value one + /// + public bool IsBVBitOne { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BIT1; } } + + /// + /// Indicates whether the term is a one-bit bit-vector with value zero + /// + public bool IsBVBitZero { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BIT0; } } + + /// + /// Indicates whether the term is a bit-vector unary minus + /// + public bool IsBVUMinus { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNEG; } } + + /// + /// Indicates whether the term is a bit-vector addition (binary) + /// + public bool IsBVAdd { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BADD; } } + + /// + /// Indicates whether the term is a bit-vector subtraction (binary) + /// + public bool IsBVSub { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSUB; } } + + /// + /// Indicates whether the term is a bit-vector multiplication (binary) + /// + public bool IsBVMul { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BMUL; } } + + /// + /// Indicates whether the term is a bit-vector signed division (binary) + /// + public bool IsBVSDiv { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSDIV; } } + + /// + /// Indicates whether the term is a bit-vector unsigned division (binary) + /// + public bool IsBVUDiv { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUDIV; } } + + /// + /// Indicates whether the term is a bit-vector signed remainder (binary) + /// + public bool IsBVSRem { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSREM; } } + + /// + /// Indicates whether the term is a bit-vector unsigned remainder (binary) + /// + public bool IsBVURem { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUREM; } } + + /// + /// Indicates whether the term is a bit-vector signed modulus + /// + public bool IsBVSMod { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSMOD; } } + + /// + /// Indicates whether the term is a bit-vector signed division by zero + /// + internal bool IsBVSDiv0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSDIV0; } } + + /// + /// Indicates whether the term is a bit-vector unsigned division by zero + /// + internal bool IsBVUDiv0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUDIV0; } } + + /// + /// Indicates whether the term is a bit-vector signed remainder by zero + /// + internal bool IsBVSRem0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSREM0; } } + + /// + /// Indicates whether the term is a bit-vector unsigned remainder by zero + /// + internal bool IsBVURem0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUREM0; } } + + /// + /// Indicates whether the term is a bit-vector signed modulus by zero + /// + internal bool IsBVSMod0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSMOD0; } } + + /// + /// Indicates whether the term is an unsigned bit-vector less-than-or-equal + /// + public bool IsBVULE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ULEQ; } } + + /// + /// Indicates whether the term is a signed bit-vector less-than-or-equal + /// + public bool IsBVSLE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SLEQ; } } + + /// + /// Indicates whether the term is an unsigned bit-vector greater-than-or-equal + /// + public bool IsBVUGE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UGEQ; } } + + /// + /// Indicates whether the term is a signed bit-vector greater-than-or-equal + /// + public bool IsBVSGE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SGEQ; } } + + /// + /// Indicates whether the term is an unsigned bit-vector less-than + /// + public bool IsBVULT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ULT; } } + + /// + /// Indicates whether the term is a signed bit-vector less-than + /// + public bool IsBVSLT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SLT; } } + + /// + /// Indicates whether the term is an unsigned bit-vector greater-than + /// + public bool IsBVUGT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UGT; } } + + /// + /// Indicates whether the term is a signed bit-vector greater-than + /// + public bool IsBVSGT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SGT; } } + + /// + /// Indicates whether the term is a bit-wise AND + /// + public bool IsBVAND { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BAND; } } + + /// + /// Indicates whether the term is a bit-wise OR + /// + public bool IsBVOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BOR; } } + + /// + /// Indicates whether the term is a bit-wise NOT + /// + public bool IsBVNOT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNOT; } } + + /// + /// Indicates whether the term is a bit-wise XOR + /// + public bool IsBVXOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BXOR; } } + + /// + /// Indicates whether the term is a bit-wise NAND + /// + public bool IsBVNAND { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNAND; } } + + /// + /// Indicates whether the term is a bit-wise NOR + /// + public bool IsBVNOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNOR; } } + + /// + /// Indicates whether the term is a bit-wise XNOR + /// + public bool IsBVXNOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BXNOR; } } + + /// + /// Indicates whether the term is a bit-vector concatenation (binary) + /// + public bool IsBVConcat { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CONCAT; } } + + /// + /// Indicates whether the term is a bit-vector sign extension + /// + public bool IsBVSignExtension { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SIGN_EXT; } } + + /// + /// Indicates whether the term is a bit-vector zero extension + /// + public bool IsBVZeroExtension { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ZERO_EXT; } } + + /// + /// Indicates whether the term is a bit-vector extraction + /// + public bool IsBVExtract { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXTRACT; } } + + /// + /// Indicates whether the term is a bit-vector repetition + /// + public bool IsBVRepeat { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_REPEAT; } } + + /// + /// Indicates whether the term is a bit-vector reduce OR + /// + public bool IsBVReduceOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BREDOR; } } + + /// + /// Indicates whether the term is a bit-vector reduce AND + /// + public bool IsBVReduceAND { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BREDAND; } } + + /// + /// Indicates whether the term is a bit-vector comparison + /// + public bool IsBVComp { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BCOMP; } } + + /// + /// Indicates whether the term is a bit-vector shift left + /// + public bool IsBVShiftLeft { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSHL; } } + + /// + /// Indicates whether the term is a bit-vector logical shift right + /// + public bool IsBVShiftRightLogical { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BLSHR; } } + + /// + /// Indicates whether the term is a bit-vector arithmetic shift left + /// + public bool IsBVShiftRightArithmetic { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BASHR; } } + + /// + /// Indicates whether the term is a bit-vector rotate left + /// + public bool IsBVRotateLeft { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ROTATE_LEFT; } } + + /// + /// Indicates whether the term is a bit-vector rotate right + /// + public bool IsBVRotateRight { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ROTATE_RIGHT; } } + + /// + /// Indicates whether the term is a bit-vector rotate left (extended) + /// + /// Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. + public bool IsBVRotateLeftExtended { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXT_ROTATE_LEFT; } } + + /// + /// Indicates whether the term is a bit-vector rotate right (extended) + /// + /// Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. + public bool IsBVRotateRightExtended { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXT_ROTATE_RIGHT; } } + + /// + /// Indicates whether the term is a coercion from integer to bit-vector + /// + /// This function is not supported by the decision procedures. Only the most + /// rudimentary simplification rules are applied to this function. + public bool IsIntToBV { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_INT2BV; } } + + /// + /// Indicates whether the term is a coercion from bit-vector to integer + /// + /// This function is not supported by the decision procedures. Only the most + /// rudimentary simplification rules are applied to this function. + public bool IsBVToInt { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BV2INT; } } + + /// + /// Indicates whether the term is a bit-vector carry + /// + /// Compute the carry bit in a full-adder. The meaning is given by the + /// equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) + public bool IsBVCarry { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CARRY; } } + + /// + /// Indicates whether the term is a bit-vector ternary XOR + /// + /// The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) + public bool IsBVXOR3 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_XOR3; } } + + #endregion + + #region Labels + /// + /// Indicates whether the term is a label (used by the Boogie Verification condition generator). + /// + /// The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. + public bool IsLabel { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LABEL; } } + + /// + /// Indicates whether the term is a label literal (used by the Boogie Verification condition generator). + /// + /// A label literal has a set of string parameters. It takes no arguments. + public bool IsLabelLit { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LABEL_LIT; } } + #endregion + + #region Proof Terms + /// + /// Indicates whether the term is a binary equivalence modulo namings. + /// + /// This binary predicate is used in proof terms. + /// It captures equisatisfiability and equivalence modulo renamings. + public bool IsOEQ { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_OEQ; } } + + /// + /// Indicates whether the term is a Proof for the expression 'true'. + /// + public bool IsProofTrue { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRUE; } } + + /// + /// Indicates whether the term is a proof for a fact asserted by the user. + /// + public bool IsProofAsserted { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_ASSERTED; } } + + /// + /// Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. + /// + public bool IsProofGoal { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_GOAL; } } + + /// + /// Indicates whether the term is proof via modus ponens + /// + /// + /// Given a proof for p and a proof for (implies p q), produces a proof for q. + /// T1: p + /// T2: (implies p q) + /// [mp T1 T2]: q + /// The second antecedents may also be a proof for (iff p q). + public bool IsProofModusPonens { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS; } } + + /// + /// Indicates whether the term is a proof for (R t t), where R is a reflexive relation. + /// + /// This proof object has no antecedents. + /// The only reflexive relations that are used are + /// equivalence modulo namings, equality and equivalence. + /// That is, R is either '~', '=' or 'iff'. + public bool IsProofReflexivity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REFLEXIVITY; } } + + /// + /// Indicates whether the term is proof by symmetricity of a relation + /// + /// + /// Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + /// T1: (R t s) + /// [symmetry T1]: (R s t) + /// T1 is the antecedent of this proof object. + /// + public bool IsProofSymmetry { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_SYMMETRY; } } + + /// + /// Indicates whether the term is a proof by transitivity of a relation + /// + /// + /// Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + /// for (R t u). + /// T1: (R t s) + /// T2: (R s u) + /// [trans T1 T2]: (R t u) + /// + public bool IsProofTransitivity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY; } } + + /// + /// Indicates whether the term is a proof by condensed transitivity of a relation + /// + /// + /// Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + /// It combines several symmetry and transitivity proofs. + /// Example: + /// T1: (R a b) + /// T2: (R c b) + /// T3: (R c d) + /// [trans* T1 T2 T3]: (R a d) + /// R must be a symmetric and transitive relation. + /// + /// Assuming that this proof object is a proof for (R s t), then + /// a proof checker must check if it is possible to prove (R s t) + /// using the antecedents, symmetry and transitivity. That is, + /// if there is a path from s to t, if we view every + /// antecedent (R a b) as an edge between a and b. + /// + public bool IsProofTransitivityStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY_STAR; } } + + + /// + /// Indicates whether the term is a monotonicity proof object. + /// + /// + /// T1: (R t_1 s_1) + /// ... + /// Tn: (R t_n s_n) + /// [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + /// Remark: if t_i == s_i, then the antecedent Ti is suppressed. + /// That is, reflexivity proofs are supressed to save space. + /// + public bool IsProofMonotonicity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MONOTONICITY; } } + + /// + /// Indicates whether the term is a quant-intro proof + /// + /// + /// Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + /// T1: (~ p q) + /// [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) + /// + public bool IsProofQuantIntro { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_QUANT_INTRO; } } + + /// + /// Indicates whether the term is a distributivity proof object. + /// + /// + /// Given that f (= or) distributes over g (= and), produces a proof for + /// (= (f a (g c d)) + /// (g (f a c) (f a d))) + /// If f and g are associative, this proof also justifies the following equality: + /// (= (f (g a b) (g c d)) + /// (g (f a c) (f a d) (f b c) (f b d))) + /// where each f and g can have arbitrary number of arguments. + /// + /// This proof object has no antecedents. + /// Remark. This rule is used by the CNF conversion pass and + /// instantiated by f = or, and g = and. + /// + public bool IsProofDistributivity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DISTRIBUTIVITY; } } + + /// + /// Indicates whether the term is a proof by elimination of AND + /// + /// + /// Given a proof for (and l_1 ... l_n), produces a proof for l_i + /// T1: (and l_1 ... l_n) + /// [and-elim T1]: l_i + /// + public bool IsProofAndElimination { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_AND_ELIM; } } + + /// + /// Indicates whether the term is a proof by eliminiation of not-or + /// + /// + /// Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + /// T1: (not (or l_1 ... l_n)) + /// [not-or-elim T1]: (not l_i) + /// + public bool IsProofOrElimination { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NOT_OR_ELIM; } } + + /// + /// Indicates whether the term is a proof by rewriting + /// + /// + /// A proof for a local rewriting step (= t s). + /// The head function symbol of t is interpreted. + /// + /// This proof object has no antecedents. + /// The conclusion of a rewrite rule is either an equality (= t s), + /// an equivalence (iff t s), or equi-satisfiability (~ t s). + /// Remark: if f is bool, then = is iff. + /// + /// Examples: + /// (= (+ x 0) x) + /// (= (+ x 1 2) (+ 3 x)) + /// (iff (or x false) x) + /// + public bool IsProofRewrite { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REWRITE; } } + + /// + /// Indicates whether the term is a proof by rewriting + /// + /// + /// A proof for rewriting an expression t into an expression s. + /// This proof object is used if the parameter PROOF_MODE is 1. + /// This proof object can have n antecedents. + /// The antecedents are proofs for equalities used as substitution rules. + /// The object is also used in a few cases if the parameter PROOF_MODE is 2. + /// The cases are: + /// - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + /// - When converting bit-vectors to Booleans (BIT2BOOL=true) + /// - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) + /// + public bool IsProofRewriteStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REWRITE_STAR; } } + + /// + /// Indicates whether the term is a proof for pulling quantifiers out. + /// + /// + /// A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. + /// + public bool IsProofPullQuant { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PULL_QUANT; } } + + /// + /// Indicates whether the term is a proof for pulling quantifiers out. + /// + /// + /// A proof for (iff P Q) where Q is in prenex normal form. + /// This proof object is only used if the parameter PROOF_MODE is 1. + /// This proof object has no antecedents + /// + public bool IsProofPullQuantStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PULL_QUANT_STAR; } } + + /// + /// Indicates whether the term is a proof for pushing quantifiers in. + /// + /// + /// A proof for: + /// (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + /// (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + /// ... + /// (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + /// This proof object has no antecedents + /// + public bool IsProofPushQuant { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PUSH_QUANT; } } + + /// + /// Indicates whether the term is a proof for elimination of unused variables. + /// + /// + /// A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + /// (forall (x_1 ... x_n) p[x_1 ... x_n])) + /// + /// It is used to justify the elimination of unused variables. + /// This proof object has no antecedents. + /// + public bool IsProofElimUnusedVars { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_ELIM_UNUSED_VARS; } } + + /// + /// Indicates whether the term is a proof for destructive equality resolution + /// + /// + /// A proof for destructive equality resolution: + /// (iff (forall (x) (or (not (= x t)) P[x])) P[t]) + /// if x does not occur in t. + /// + /// This proof object has no antecedents. + /// + /// Several variables can be eliminated simultaneously. + /// + public bool IsProofDER { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DER; } } + + /// + /// Indicates whether the term is a proof for quantifier instantiation + /// + /// + /// A proof of (or (not (forall (x) (P x))) (P a)) + /// + public bool IsProofQuantInst { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_QUANT_INST; } } + + /// + /// Indicates whether the term is a hypthesis marker. + /// + /// Mark a hypothesis in a natural deduction style proof. + public bool IsProofHypothesis { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_HYPOTHESIS; } } + + /// + /// Indicates whether the term is a proof by lemma + /// + /// + /// T1: false + /// [lemma T1]: (or (not l_1) ... (not l_n)) + /// + /// This proof object has one antecedent: a hypothetical proof for false. + /// It converts the proof in a proof for (or (not l_1) ... (not l_n)), + /// when T1 contains the hypotheses: l_1, ..., l_n. + /// + public bool IsProofLemma { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_LEMMA; } } + + /// + /// Indicates whether the term is a proof by unit resolution + /// + /// + /// T1: (or l_1 ... l_n l_1' ... l_m') + /// T2: (not l_1) + /// ... + /// T(n+1): (not l_n) + /// [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') + /// + public bool IsProofUnitResolution { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_UNIT_RESOLUTION; } } + + /// + /// Indicates whether the term is a proof by iff-true + /// + /// + /// T1: p + /// [iff-true T1]: (iff p true) + /// + public bool IsProofIFFTrue { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_TRUE; } } + + /// + /// Indicates whether the term is a proof by iff-false + /// + /// + /// T1: (not p) + /// [iff-false T1]: (iff p false) + /// + public bool IsProofIFFFalse { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_FALSE; } } + + /// + /// Indicates whether the term is a proof by commutativity + /// + /// + /// [comm]: (= (f a b) (f b a)) + /// + /// f is a commutative operator. + /// + /// This proof object has no antecedents. + /// Remark: if f is bool, then = is iff. + /// + public bool IsProofCommutativity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_COMMUTATIVITY; } } + + /// + /// Indicates whether the term is a proof for Tseitin-like axioms + /// + /// + /// Proof object used to justify Tseitin's like axioms: + /// + /// (or (not (and p q)) p) + /// (or (not (and p q)) q) + /// (or (not (and p q r)) p) + /// (or (not (and p q r)) q) + /// (or (not (and p q r)) r) + /// ... + /// (or (and p q) (not p) (not q)) + /// (or (not (or p q)) p q) + /// (or (or p q) (not p)) + /// (or (or p q) (not q)) + /// (or (not (iff p q)) (not p) q) + /// (or (not (iff p q)) p (not q)) + /// (or (iff p q) (not p) (not q)) + /// (or (iff p q) p q) + /// (or (not (ite a b c)) (not a) b) + /// (or (not (ite a b c)) a c) + /// (or (ite a b c) (not a) (not b)) + /// (or (ite a b c) a (not c)) + /// (or (not (not a)) (not a)) + /// (or (not a) a) + /// + /// This proof object has no antecedents. + /// Note: all axioms are propositional tautologies. + /// Note also that 'and' and 'or' can take multiple arguments. + /// You can recover the propositional tautologies by + /// unfolding the Boolean connectives in the axioms a small + /// bounded number of steps (=3). + /// + public bool IsProofDefAxiom { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DEF_AXIOM; } } + + /// + /// Indicates whether the term is a proof for introduction of a name + /// + /// + /// Introduces a name for a formula/term. + /// Suppose e is an expression with free variables x, and def-intro + /// introduces the name n(x). The possible cases are: + /// + /// When e is of Boolean type: + /// [def-intro]: (and (or n (not e)) (or (not n) e)) + /// + /// or: + /// [def-intro]: (or (not n) e) + /// when e only occurs positively. + /// + /// When e is of the form (ite cond th el): + /// [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + /// + /// Otherwise: + /// [def-intro]: (= n e) + /// + public bool IsProofDefIntro { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DEF_INTRO; } } + + /// + /// Indicates whether the term is a proof for application of a definition + /// + /// + /// [apply-def T1]: F ~ n + /// F is 'equivalent' to n, given that T1 is a proof that + /// n is a name for F. + /// + public bool IsProofApplyDef { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_APPLY_DEF; } } + + /// + /// Indicates whether the term is a proof iff-oeq + /// + /// + /// T1: (iff p q) + /// [iff~ T1]: (~ p q) + /// + public bool IsProofIFFOEQ { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_OEQ; } } + + /// + /// Indicates whether the term is a proof for a positive NNF step + /// + /// + /// Proof for a (positive) NNF step. Example: + /// + /// T1: (not s_1) ~ r_1 + /// T2: (not s_2) ~ r_2 + /// T3: s_1 ~ r_1' + /// T4: s_2 ~ r_2' + /// [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + /// (and (or r_1 r_2') (or r_1' r_2))) + /// + /// The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + /// (a) When creating the NNF of a positive force quantifier. + /// The quantifier is retained (unless the bound variables are eliminated). + /// Example + /// T1: q ~ q_new + /// [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + /// + /// (b) When recursively creating NNF over Boolean formulas, where the top-level + /// connective is changed during NNF conversion. The relevant Boolean connectives + /// for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + /// NNF_NEG furthermore handles the case where negation is pushed + /// over Boolean connectives 'and' and 'or'. + /// + public bool IsProofNNFPos { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_POS; } } + + /// + /// Indicates whether the term is a proof for a negative NNF step + /// + /// + /// Proof for a (negative) NNF step. Examples: + /// + /// T1: (not s_1) ~ r_1 + /// ... + /// Tn: (not s_n) ~ r_n + /// [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + /// and + /// T1: (not s_1) ~ r_1 + /// ... + /// Tn: (not s_n) ~ r_n + /// [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + /// and + /// T1: (not s_1) ~ r_1 + /// T2: (not s_2) ~ r_2 + /// T3: s_1 ~ r_1' + /// T4: s_2 ~ r_2' + /// [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + /// (and (or r_1 r_2) (or r_1' r_2'))) + /// + public bool IsProofNNFNeg { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_NEG; } } + + /// + /// Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. + /// + /// + /// A proof for (~ P Q) where Q is in negation normal form. + /// + /// This proof object is only used if the parameter PROOF_MODE is 1. + /// + /// This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. + /// + public bool IsProofNNFStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_STAR; } } + + /// + /// Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. + /// + /// + /// A proof for (~ P Q) where Q is in conjunctive normal form. + /// This proof object is only used if the parameter PROOF_MODE is 1. + /// This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. + /// + public bool IsProofCNFStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_CNF_STAR; } } + + /// + /// Indicates whether the term is a proof for a Skolemization step + /// + /// + /// Proof for: + /// + /// [sk]: (~ (not (forall x (p x y))) (not (p (sk y) y))) + /// [sk]: (~ (exists x (p x y)) (p (sk y) y)) + /// + /// This proof object has no antecedents. + /// + public bool IsProofSkolemize { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_SKOLEMIZE; } } + + /// + /// Indicates whether the term is a proof by modus ponens for equi-satisfiability. + /// + /// + /// Modus ponens style rule for equi-satisfiability. + /// T1: p + /// T2: (~ p q) + /// [mp~ T1 T2]: q + /// + public bool IsProofModusPonensOEQ { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS_OEQ; } } + + /// + /// Indicates whether the term is a proof for theory lemma + /// + /// + /// Generic proof for theory lemmas. + /// + /// The theory lemma function comes with one or more parameters. + /// The first parameter indicates the name of the theory. + /// For the theory of arithmetic, additional parameters provide hints for + /// checking the theory lemma. + /// The hints for arithmetic are: + /// - farkas - followed by rational coefficients. Multiply the coefficients to the + /// inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + /// - triangle-eq - Indicates a lemma related to the equivalence: + /// (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + /// - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. + /// + public bool IsProofTheoryLemma { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TH_LEMMA; } } + #endregion + + #region Relational Terms + /// + /// Indicates whether the term is of an array sort. + /// + public bool IsRelation + { + get + { + return (Native.Z3_is_app(Context.nCtx, NativeObject) != 0 && + (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_RELATION_SORT); + } + } + + /// + /// Indicates whether the term is an relation store + /// + /// + /// Insert a record into a relation. + /// The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + /// correspond to the n columns of the relation. + /// + public bool IsRelationStore { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_STORE; } } + + /// + /// Indicates whether the term is an empty relation + /// + public bool IsEmptyRelation { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_EMPTY; } } + + /// + /// Indicates whether the term is a test for the emptiness of a relation + /// + public bool IsIsEmptyRelation { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_IS_EMPTY; } } + + /// + /// Indicates whether the term is a relational join + /// + public bool IsRelationalJoin { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_JOIN; } } + + /// + /// Indicates whether the term is the union or convex hull of two relations. + /// + /// The function takes two arguments. + public bool IsRelationUnion { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_UNION; } } + + /// + /// Indicates whether the term is the widening of two relations + /// + /// The function takes two arguments. + public bool IsRelationWiden { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_WIDEN; } } + + /// + /// Indicates whether the term is a projection of columns (provided as numbers in the parameters). + /// + /// The function takes one argument. + public bool IsRelationProject { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_PROJECT; } } + + /// + /// Indicates whether the term is a relation filter + /// + /// + /// Filter (restrict) a relation with respect to a predicate. + /// The first argument is a relation. + /// The second argument is a predicate with free de-Brujin indices + /// corresponding to the columns of the relation. + /// So the first column in the relation has index 0. + /// + public bool IsRelationFilter { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_FILTER; } } + + /// + /// Indicates whether the term is an intersection of a relation with the negation of another. + /// + /// + /// Intersect the first relation with respect to negation + /// of the second relation (the function takes two arguments). + /// Logically, the specification can be described by a function + /// + /// target = filter_by_negation(pos, neg, columns) + /// + /// where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + /// target are elements in x in pos, such that there is no y in neg that agrees with + /// x on the columns c1, d1, .., cN, dN. + /// + public bool IsRelationNegationFilter { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_NEGATION_FILTER; } } + + /// + /// Indicates whether the term is the renaming of a column in a relation + /// + /// + /// The function takes one argument. + /// The parameters contain the renaming as a cycle. + /// + public bool IsRelationRename { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_RENAME; } } + + /// + /// Indicates whether the term is the complement of a relation + /// + public bool IsRelationComplement { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_COMPLEMENT; } } + + /// + /// Indicates whether the term is a relational select + /// + /// + /// Check if a record is an element of the relation. + /// The function takes n+1 arguments, where the first argument is a relation, + /// and the remaining n arguments correspond to a record. + /// + public bool IsRelationSelect { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_SELECT; } } + + /// + /// Indicates whether the term is a relational clone (copy) + /// + /// + /// Create a fresh copy (clone) of a relation. + /// The function is logically the identity, but + /// in the context of a register machine allows + /// for terms of kind + /// to perform destructive updates to the first argument. + /// + public bool IsRelationClone { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_CLONE; } } + #endregion + + #region Finite domain terms + /// + /// Indicates whether the term is of an array sort. + /// + public bool IsFiniteDomain + { + get + { + return (Native.Z3_is_app(Context.nCtx, NativeObject) != 0 && + (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_FINITE_DOMAIN_SORT); + } + } + + /// + /// Indicates whether the term is a less than predicate over a finite domain. + /// + public bool IsFiniteDomainLT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FD_LT; } } + #endregion + #endregion + + #region Bound Variables + /// + /// The de-Burijn index of a bound variable. + /// + /// + /// Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + /// the meaning of de-Bruijn indices by indicating the compilation process from + /// non-de-Bruijn formulas to de-Bruijn format. + /// + /// abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + /// abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + /// abs1(x, x, n) = b_n + /// abs1(y, x, n) = y + /// abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + /// abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + /// + /// The last line is significant: the index of a bound variable is different depending + /// on the scope in which it appears. The deeper x appears, the higher is its + /// index. + /// + public uint Index + { + get + { + if (!IsVar) + throw new Z3Exception("Term is not a bound variable."); + + Contract.EndContractBlock(); + + return Native.Z3_get_index_value(Context.nCtx, NativeObject); + } + } + #endregion + + #region Internal + /// Constructor for Expr + internal protected Expr(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } + /// Constructor for Expr + internal protected Expr(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + + #if DEBUG + [Pure] + internal override void CheckNativeObject(IntPtr obj) + { + if (Native.Z3_is_app(Context.nCtx, obj) == 0 && + (Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, obj) != Z3_ast_kind.Z3_VAR_AST && + (Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, obj) != Z3_ast_kind.Z3_QUANTIFIER_AST) + throw new Z3Exception("Underlying object is not a term"); + base.CheckNativeObject(obj); + } + #endif + + [Pure] + internal static Expr Create(Context ctx, FuncDecl f, params Expr[] arguments) + { + Contract.Requires(ctx != null); + Contract.Requires(f != null); + Contract.Ensures(Contract.Result() != null); + + IntPtr obj = Native.Z3_mk_app(ctx.nCtx, f.NativeObject, + AST.ArrayLength(arguments), + AST.ArrayToNative(arguments)); + return Create(ctx, obj); + } + + [Pure] + new internal static Expr Create(Context ctx, IntPtr obj) + { + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result() != null); + + Z3_ast_kind k = (Z3_ast_kind)Native.Z3_get_ast_kind(ctx.nCtx, obj); + if (k == Z3_ast_kind.Z3_QUANTIFIER_AST) + return new Quantifier(ctx, obj); + IntPtr s = Native.Z3_get_sort(ctx.nCtx, obj); + Z3_sort_kind sk = (Z3_sort_kind)Native.Z3_get_sort_kind(ctx.nCtx, s); + + if (Native.Z3_is_algebraic_number(ctx.nCtx, obj) != 0) // is this a numeral ast? + return new AlgebraicNum(ctx, obj); + + if (Native.Z3_is_numeral_ast(ctx.nCtx, obj) != 0) + { + switch (sk) + { + case Z3_sort_kind.Z3_INT_SORT: return new IntNum(ctx, obj); + case Z3_sort_kind.Z3_REAL_SORT: return new RatNum(ctx, obj); + case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); + } + } + + switch (sk) + { + case Z3_sort_kind.Z3_BOOL_SORT: return new BoolExpr(ctx, obj); + case Z3_sort_kind.Z3_INT_SORT: return new IntExpr(ctx, obj); + case Z3_sort_kind.Z3_REAL_SORT: return new RealExpr(ctx, obj); + case Z3_sort_kind.Z3_BV_SORT: return new BitVecExpr(ctx, obj); + case Z3_sort_kind.Z3_ARRAY_SORT: return new ArrayExpr(ctx, obj); + case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); + } + + return new Expr(ctx, obj); + } + #endregion + } + + /// + /// Boolean expressions + /// + public class BoolExpr : Expr + { + #region Internal + /// Constructor for BoolExpr + internal protected BoolExpr(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } + /// Constructor for BoolExpr + internal BoolExpr(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + #endregion + } + + /// + /// Arithmetic expressions (int/real) + /// + public class ArithExpr : Expr + { + #region Internal + /// Constructor for ArithExpr + internal protected ArithExpr(Context ctx) + : base(ctx) + { + Contract.Requires(ctx != null); + } + internal ArithExpr(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } + + /// + /// Int expressions + /// + public class IntExpr : ArithExpr + { + #region Internal + /// Constructor for IntExpr + internal protected IntExpr(Context ctx) + : base(ctx) + { + Contract.Requires(ctx != null); + } + internal IntExpr(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } + + /// + /// Real expressions + /// + public class RealExpr : ArithExpr + { + #region Internal + /// Constructor for RealExpr + internal protected RealExpr(Context ctx) + : base(ctx) + { + Contract.Requires(ctx != null); + } + internal RealExpr(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } + + /// + /// Bit-vector expressions + /// + public class BitVecExpr : Expr + { + + /// + /// The size of the sort of a bit-vector term. + /// + public uint SortSize + { + get { return ((BitVecSort)Sort).Size; } + } + + #region Internal + /// Constructor for BitVecExpr + internal protected BitVecExpr(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } + internal BitVecExpr(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + #endregion + } + + /// + /// Array expressions + /// + public class ArrayExpr : Expr + { + #region Internal + /// Constructor for ArrayExpr + internal protected ArrayExpr(Context ctx) + : base(ctx) + { + Contract.Requires(ctx != null); + } + internal ArrayExpr(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } + + /// + /// Datatype expressions + /// + public class DatatypeExpr : Expr + { + #region Internal + /// Constructor for DatatypeExpr + internal protected DatatypeExpr(Context ctx) + : base(ctx) + { + Contract.Requires(ctx != null); + } + internal DatatypeExpr(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } +} diff --git a/Microsoft.Z3/Fixedpoint.cs b/Microsoft.Z3/Fixedpoint.cs new file mode 100644 index 000000000..ae94c4d24 --- /dev/null +++ b/Microsoft.Z3/Fixedpoint.cs @@ -0,0 +1,305 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Fixedpoints.cs + +Abstract: + + Z3 Managed API: Fixedpoints + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Object for managing fixedpoints + /// + [ContractVerification(true)] + public class Fixedpoint : Z3Object + { + + /// + /// A string that describes all available fixedpoint solver parameters. + /// + public string Help + { + get { + Contract.Ensures(Contract.Result() != null); + return Native.Z3_fixedpoint_get_help(Context.nCtx, NativeObject); + } + } + + /// + /// Sets the fixedpoint solver parameters. + /// + public Params Parameters + { + set + { + Contract.Requires(value != null); + Context.CheckContextMatch(value); + Native.Z3_fixedpoint_set_params(Context.nCtx, NativeObject, value.NativeObject); + } + } + + /// + /// Retrieves parameter descriptions for Fixedpoint solver. + /// + public ParamDescrs ParameterDescriptions + { + get + { + return new ParamDescrs(Context, Native.Z3_fixedpoint_get_param_descrs(Context.nCtx, NativeObject)); + } + } + + + /// + /// Assert a constraint (or multiple) into the fixedpoint solver. + /// + public void Assert(params BoolExpr[] constraints) + { + Contract.Requires(constraints != null); + Contract.Requires(Contract.ForAll(constraints, c => c != null)); + + Context.CheckContextMatch(constraints); + foreach (BoolExpr a in constraints) + { + Native.Z3_fixedpoint_assert(Context.nCtx, NativeObject, a.NativeObject); + } + } + + /// + /// Register predicate as recursive relation. + /// + public void RegisterRelation(FuncDecl f) + { + Contract.Requires(f != null); + + Context.CheckContextMatch(f); + Native.Z3_fixedpoint_register_relation(Context.nCtx, NativeObject, f.NativeObject); + } + + /// + /// Add rule into the fixedpoint solver. + /// + public void AddRule(BoolExpr rule, Symbol name = null) + { + Contract.Requires(rule != null); + + Context.CheckContextMatch(rule); + Native.Z3_fixedpoint_add_rule(Context.nCtx, NativeObject, rule.NativeObject, AST.GetNativeObject(name)); + } + + /// + /// Add table fact to the fixedpoint solver. + /// + public void AddFact(FuncDecl pred, params uint[] args) + { + Contract.Requires(pred != null); + Contract.Requires(args != null); + + Context.CheckContextMatch(pred); + Native.Z3_fixedpoint_add_fact(Context.nCtx, NativeObject, pred.NativeObject, (uint)args.Length, args); + } + + /// + /// Query the fixedpoint solver. + /// A query is a conjunction of constraints. The constraints may include the recursively defined relations. + /// The query is satisfiable if there is an instance of the query variables and a derivation for it. + /// The query is unsatisfiable if there are no derivations satisfying the query variables. + /// + public Status Query(BoolExpr query) + { + Contract.Requires(query != null); + + Context.CheckContextMatch(query); + Z3_lbool r = (Z3_lbool)Native.Z3_fixedpoint_query(Context.nCtx, NativeObject, query.NativeObject); + switch (r) + { + case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE; + case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE; + default: return Status.UNKNOWN; + } + } + + /// + /// Query the fixedpoint solver. + /// A query is an array of relations. + /// The query is satisfiable if there is an instance of some relation that is non-empty. + /// The query is unsatisfiable if there are no derivations satisfying any of the relations. + /// + public Status Query(FuncDecl[] relations) + { + Contract.Requires(relations != null); + Contract.Requires(Contract.ForAll(0, relations.Length, i => relations[i] != null)); + + Context.CheckContextMatch(relations); + Z3_lbool r = (Z3_lbool)Native.Z3_fixedpoint_query_relations(Context.nCtx, NativeObject, + AST.ArrayLength(relations), AST.ArrayToNative(relations)); + switch (r) + { + case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE; + case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE; + default: return Status.UNKNOWN; + } + } + + /// + /// Creates a backtracking point. + /// + /// + public void Push() + { + Native.Z3_fixedpoint_push(Context.nCtx, NativeObject); + } + + /// + /// Backtrack one backtracking point. + /// + /// Note that an exception is thrown if Pop is called without a corresponding Push + /// + public void Pop() + { + Native.Z3_fixedpoint_pop(Context.nCtx, NativeObject); + } + + + /// + /// Update named rule into in the fixedpoint solver. + /// + public void UpdateRule(BoolExpr rule, Symbol name) + { + Contract.Requires(rule != null); + + Context.CheckContextMatch(rule); + Native.Z3_fixedpoint_update_rule(Context.nCtx, NativeObject, rule.NativeObject, AST.GetNativeObject(name)); + } + + /// + /// Retrieve satisfying instance or instances of solver, + /// or definitions for the recursive predicates that show unsatisfiability. + /// + public Expr GetAnswer() + { + IntPtr ans = Native.Z3_fixedpoint_get_answer(Context.nCtx, NativeObject); + return (ans == IntPtr.Zero) ? null : Expr.Create(Context, ans); + } + + /// + /// Retrieve explanation why fixedpoint engine returned status Unknown. + /// + public string GetReasonUnknown() + { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_fixedpoint_get_reason_unknown(Context.nCtx, NativeObject); + } + + /// + /// Retrieve the number of levels explored for a given predicate. + /// + public uint GetNumLevels(FuncDecl predicate) + { + return Native.Z3_fixedpoint_get_num_levels(Context.nCtx, NativeObject, predicate.NativeObject); + } + + /// + /// Retrieve the cover of a predicate. + /// + public Expr GetCoverDelta(int level, FuncDecl predicate) + { + IntPtr res = Native.Z3_fixedpoint_get_cover_delta(Context.nCtx, NativeObject, level, predicate.NativeObject); + return (res == IntPtr.Zero) ? null : Expr.Create(Context, res); + } + + /// + /// Add property about the predicate. + /// The property is added at level. + /// + public void AddCover(int level, FuncDecl predicate, Expr property) + { + Native.Z3_fixedpoint_add_cover(Context.nCtx, NativeObject, level, predicate.NativeObject, property.NativeObject); + } + + /// + /// Retrieve internal string representation of fixedpoint object. + /// + public override string ToString() + { + return Native.Z3_fixedpoint_to_string(Context.nCtx, NativeObject, 0, null); + } + + /// + /// Instrument the Datalog engine on which table representation to use for recursive predicate. + /// + public void SetPredicateRepresentation(FuncDecl f, Symbol[] kinds) + { + Contract.Requires(f != null); + + Native.Z3_fixedpoint_set_predicate_representation(Context.nCtx, NativeObject, + f.NativeObject, AST.ArrayLength(kinds), Symbol.ArrayToNative(kinds)); + + } + + /// + /// Convert benchmark given as set of axioms, rules and queries to a string. + /// + public string ToString(BoolExpr[] queries) + { + + return Native.Z3_fixedpoint_to_string(Context.nCtx, NativeObject, + AST.ArrayLength(queries), AST.ArrayToNative(queries)); + } + + + #region Internal + internal Fixedpoint(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal Fixedpoint(Context ctx) + : base(ctx, Native.Z3_mk_fixedpoint(ctx.nCtx)) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_fixedpoint_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_fixedpoint_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.Fixedpoint_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.Fixedpoint_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/FuncDecl.cs b/Microsoft.Z3/FuncDecl.cs new file mode 100644 index 000000000..b1599bbf4 --- /dev/null +++ b/Microsoft.Z3/FuncDecl.cs @@ -0,0 +1,344 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + FuncDecl.cs + +Abstract: + + Z3 Managed API: Function Declarations + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-16 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Function declarations. + /// + [ContractVerification(true)] + public class FuncDecl : AST + { + /// + /// Comparison operator. + /// + /// True if and share the same context and are equal, false otherwise. + public static bool operator ==(FuncDecl a, FuncDecl b) + { + return Object.ReferenceEquals(a, b) || + (!Object.ReferenceEquals(a, null) && + !Object.ReferenceEquals(b, null) && + a.Context.nCtx == b.Context.nCtx && + Native.Z3_is_eq_func_decl(a.Context.nCtx, a.NativeObject, b.NativeObject) != 0); + } + + /// + /// Comparison operator. + /// + /// True if and do not share the same context or are not equal, false otherwise. + public static bool operator !=(FuncDecl a, FuncDecl b) + { + return !(a == b); + } + + /// + /// Object comparison. + /// + public override bool Equals(object o) + { + FuncDecl casted = o as FuncDecl; + if (casted == null) return false; + return this == casted; + } + + /// + /// A hash code. + /// + public override int GetHashCode() + { + return base.GetHashCode(); + } + + /// + /// A string representations of the function declaration. + /// + public override string ToString() + { + return Native.Z3_func_decl_to_string(Context.nCtx, NativeObject); + } + + /// + /// Returns a unique identifier for the function declaration. + /// + new public uint Id + { + get { return Native.Z3_get_func_decl_id(Context.nCtx, NativeObject); } + } + + /// + /// The arity of the function declaration + /// + public uint Arity + { + get { return Native.Z3_get_arity(Context.nCtx, NativeObject); } + } + + /// + /// The size of the domain of the function declaration + /// + /// + public uint DomainSize + { + get { return Native.Z3_get_domain_size(Context.nCtx, NativeObject); } + } + + /// + /// The domain of the function declaration + /// + public Sort[] Domain + { + get + { + Contract.Ensures(Contract.Result() != null); + + var n = DomainSize; + + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(Context, Native.Z3_get_domain(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The range of the function declaration + /// + public Sort Range + { + get { + Contract.Ensures(Contract.Result() != null); + return Sort.Create(Context, Native.Z3_get_range(Context.nCtx, NativeObject)); } + } + + /// + /// The kind of the function declaration. + /// + public Z3_decl_kind DeclKind + { + get { return (Z3_decl_kind)Native.Z3_get_decl_kind(Context.nCtx, NativeObject); } + } + + /// + /// The name of the function declaration + /// + public Symbol Name + { + get { + Contract.Ensures(Contract.Result() != null); + return Symbol.Create(Context, Native.Z3_get_decl_name(Context.nCtx, NativeObject)); } + } + + /// + /// The number of parameters of the function declaration + /// + public uint NumParameters + { + get { return Native.Z3_get_decl_num_parameters(Context.nCtx, NativeObject); } + } + + /// + /// The parameters of the function declaration + /// + public Parameter[] Parameters + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint num = NumParameters; + Parameter[] res = new Parameter[num]; + for (uint i = 0; i < num; i++) + { + Z3_parameter_kind k = (Z3_parameter_kind)Native.Z3_get_decl_parameter_kind(Context.nCtx, NativeObject, i); + switch (k) + { + case Z3_parameter_kind.Z3_PARAMETER_INT: + res[i] = new Parameter(k, Native.Z3_get_decl_int_parameter(Context.nCtx, NativeObject, i)); + break; + case Z3_parameter_kind.Z3_PARAMETER_DOUBLE: + res[i] = new Parameter(k, Native.Z3_get_decl_double_parameter(Context.nCtx, NativeObject, i)); + break; + case Z3_parameter_kind.Z3_PARAMETER_SYMBOL: + res[i] = new Parameter(k, Symbol.Create(Context, Native.Z3_get_decl_symbol_parameter(Context.nCtx, NativeObject, i))); + break; + case Z3_parameter_kind.Z3_PARAMETER_SORT: + res[i] = new Parameter(k, Sort.Create(Context, Native.Z3_get_decl_sort_parameter(Context.nCtx, NativeObject, i))); + break; + case Z3_parameter_kind.Z3_PARAMETER_AST: + res[i] = new Parameter(k, new AST(Context, Native.Z3_get_decl_ast_parameter(Context.nCtx, NativeObject, i))); + break; + case Z3_parameter_kind.Z3_PARAMETER_FUNC_DECL: + res[i] = new Parameter(k, new FuncDecl(Context, Native.Z3_get_decl_func_decl_parameter(Context.nCtx, NativeObject, i))); + break; + case Z3_parameter_kind.Z3_PARAMETER_RATIONAL: + res[i] = new Parameter(k, Native.Z3_get_decl_rational_parameter(Context.nCtx, NativeObject, i)); + break; + default: + throw new Z3Exception("Unknown function declaration parameter kind encountered"); + } + } + return res; + } + } + + /// + /// Function declarations can have Parameters associated with them. + /// + public class Parameter + { + readonly private Z3_parameter_kind kind; + readonly private int i; + readonly private double d; + readonly private Symbol sym; + readonly private Sort srt; + readonly private AST ast; + readonly private FuncDecl fd; + readonly private string r; + + /// The int value of the parameter. + public int Int { get { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_INT) throw new Z3Exception("parameter is not an int"); return i; } } + /// The double value of the parameter. + public double Double { get { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_DOUBLE) throw new Z3Exception("parameter is not a double "); return d; } } + /// The Symbol value of the parameter. + public Symbol Symbol { get { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_SYMBOL) throw new Z3Exception("parameter is not a Symbol"); return sym; } } + /// The Sort value of the parameter. + public Sort Sort { get { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_SORT) throw new Z3Exception("parameter is not a Sort"); return srt; } } + /// The AST value of the parameter. + public AST AST { get { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_AST) throw new Z3Exception("parameter is not an AST"); return ast; } } + /// The FunctionDeclaration value of the parameter. + public FuncDecl FuncDecl { get { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_FUNC_DECL) throw new Z3Exception("parameter is not a function declaration"); return fd; } } + /// The rational string value of the parameter. + public string Rational { get { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_RATIONAL) throw new Z3Exception("parameter is not a rational string"); return r; } } + + /// + /// The kind of the parameter. + /// + public Z3_parameter_kind ParameterKind { get { return kind; } } + + #region Internal + internal Parameter(Z3_parameter_kind k, int i) + { + this.kind = k; + this.i = i; + } + + internal Parameter(Z3_parameter_kind k, double d) + { + this.kind = k; + this.d = d; + } + + internal Parameter(Z3_parameter_kind k, Symbol s) + { + this.kind = k; + this.sym = s; + } + + internal Parameter(Z3_parameter_kind k, Sort s) + { + this.kind = k; + this.srt = s; + } + + internal Parameter(Z3_parameter_kind k, AST a) + { + this.kind = k; + this.ast = a; + } + + internal Parameter(Z3_parameter_kind k, FuncDecl fd) + { + this.kind = k; + this.fd = fd; + } + + internal Parameter(Z3_parameter_kind k, string r) + { + this.kind = k; + this.r = r; + } + #endregion + } + + #region Internal + internal FuncDecl(Context ctx, IntPtr obj) : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal FuncDecl(Context ctx, Symbol name, Sort[] domain, Sort range) + : base(ctx, Native.Z3_mk_func_decl(ctx.nCtx, name.NativeObject, + AST.ArrayLength(domain), AST.ArrayToNative(domain), + range.NativeObject)) + { + Contract.Requires(ctx != null); + Contract.Requires(name != null); + Contract.Requires(range != null); + } + + internal FuncDecl(Context ctx, string prefix, Sort[] domain, Sort range) + : base(ctx, Native.Z3_mk_fresh_func_decl(ctx.nCtx, prefix, + AST.ArrayLength(domain), AST.ArrayToNative(domain), + range.NativeObject)) + { + Contract.Requires(ctx != null); + Contract.Requires(range != null); + } + + #if DEBUG + internal override void CheckNativeObject(IntPtr obj) + { + if (Native.Z3_get_ast_kind(Context.nCtx, obj) != (uint)Z3_ast_kind.Z3_FUNC_DECL_AST) + throw new Z3Exception("Underlying object is not a function declaration"); + base.CheckNativeObject(obj); + } + #endif + #endregion + + /// + /// Create expression that applies function to arguments. + /// + /// + /// + public Expr this[params Expr[] args] { + get { + Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); + + return Apply(args); + } + } + + /// + /// Create expression that applies function to arguments. + /// + /// + /// + public Expr Apply(params Expr[] args) + { + Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); + + Context.CheckContextMatch(args); + return Expr.Create(Context, this, args); + } + + } +} diff --git a/Microsoft.Z3/FuncInterp.cs b/Microsoft.Z3/FuncInterp.cs new file mode 100644 index 000000000..b6b794028 --- /dev/null +++ b/Microsoft.Z3/FuncInterp.cs @@ -0,0 +1,221 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + FuncInterp.cs + +Abstract: + + Z3 Managed API: Function Interpretations + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// A function interpretation is represented as a finite map and an 'else' value. + /// Each entry in the finite map represents the value of a function given a set of arguments. + /// + [ContractVerification(true)] + public class FuncInterp : Z3Object + { + /// + /// An Entry object represents an element in the finite map used to encode + /// a function interpretation. + /// + public class Entry : Z3Object + { + /// + /// Return the (symbolic) value of this entry. + /// + public Expr Value + { + get { + Contract.Ensures(Contract.Result() != null); + return Expr.Create(Context, Native.Z3_func_entry_get_value(Context.nCtx, NativeObject)); } + } + + /// + /// The number of arguments of the entry. + /// + public uint NumArgs + { + get { return Native.Z3_func_entry_get_num_args(Context.nCtx, NativeObject); } + } + + /// + /// The arguments of the function entry. + /// + public Expr[] Args + { + get + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result().Length == this.NumArgs); + + uint n = NumArgs; + Expr[] res = new Expr[n]; + for (uint i = 0; i < n; i++) + res[i] = Expr.Create(Context, Native.Z3_func_entry_get_arg(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// A string representation of the function entry. + /// + public override string ToString() + { + uint n = NumArgs; + string res = "["; + Expr[] args = Args; + for (uint i = 0; i < n; i++) + res += args[i] + ", "; + return res + Value + "]"; + } + + #region Internal + internal Entry(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_func_entry_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_func_entry_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.FuncEntry_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.FuncEntry_DRQ.Add(o); + base.DecRef(o); + } + #endregion + }; + + /// + /// The number of entries in the function interpretation. + /// + public uint NumEntries + { + get { return Native.Z3_func_interp_get_num_entries(Context.nCtx, NativeObject); } + } + + /// + /// The entries in the function interpretation + /// + public Entry[] Entries + { + get + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.ForAll(0, Contract.Result().Length, + j => Contract.Result()[j] != null)); + + uint n = NumEntries; + Entry[] res = new Entry[n]; + for (uint i = 0; i < n; i++) + res[i] = new Entry(Context, Native.Z3_func_interp_get_entry(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The (symbolic) `else' value of the function interpretation. + /// + public Expr Else + { + get { + Contract.Ensures(Contract.Result() != null); + + return Expr.Create(Context, Native.Z3_func_interp_get_else(Context.nCtx, NativeObject)); } + } + + /// + /// The arity of the function interpretation + /// + public uint Arity + { + get { return Native.Z3_func_interp_get_arity(Context.nCtx, NativeObject); } + } + + /// + /// A string representation of the function interpretation. + /// + public override string ToString() + { + string res = ""; + res += "["; + foreach (Entry e in Entries) + { + uint n = e.NumArgs; + if (n > 1) res += "["; + Expr[] args = e.Args; + for (uint i = 0; i < n; i++) + { + if (i != 0) res += ", "; + res += args[i]; + } + if (n > 1) res += "]"; + res += " -> " + e.Value + ", "; + } + res += "else -> " + Else; + res += "]"; + return res; + } + + #region Internal + internal FuncInterp(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_func_interp_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_func_interp_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.FuncInterp_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.FuncInterp_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Goal.cs b/Microsoft.Z3/Goal.cs new file mode 100644 index 000000000..02edee77f --- /dev/null +++ b/Microsoft.Z3/Goal.cs @@ -0,0 +1,239 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Goal.cs + +Abstract: + + Z3 Managed API: Goal + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// A goal (aka problem). A goal is essentially a set + /// of formulas, that can be solved and/or transformed using + /// tactics and solvers. + /// + [ContractVerification(true)] + public class Goal : Z3Object + { + /// + /// The precision of the goal. + /// + /// + /// Goals can be transformed using over and under approximations. + /// An under approximation is applied when the objective is to find a model for a given goal. + /// An over approximation is applied when the objective is to find a proof for a given goal. + /// + public Z3_goal_prec Precision + { + get { return (Z3_goal_prec)Native.Z3_goal_precision(Context.nCtx, NativeObject); } + } + + /// + /// Indicates whether the goal is precise. + /// + public bool IsPrecise + { + get { return Precision == Z3_goal_prec.Z3_GOAL_PRECISE; } + } + /// + /// Indicates whether the goal is an under-approximation. + /// + public bool IsUnderApproximation + { + get { return Precision == Z3_goal_prec.Z3_GOAL_UNDER; } + } + + /// + /// Indicates whether the goal is an over-approximation. + /// + public bool IsOverApproximation + { + get { return Precision == Z3_goal_prec.Z3_GOAL_OVER; } + } + + /// + /// Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). + /// + public bool IsGarbage + { + get { return Precision == Z3_goal_prec.Z3_GOAL_UNDER_OVER; } + } + + /// + /// Adds the to the given goal. + /// + public void Assert(params BoolExpr[] constraints) + { + Contract.Requires(constraints != null); + Contract.Requires(Contract.ForAll(constraints, c => c != null)); + + Context.CheckContextMatch(constraints); + foreach (BoolExpr c in constraints) + { + Contract.Assert(c != null); // It was an assume, now made an assert just to be sure we do not regress + Native.Z3_goal_assert(Context.nCtx, NativeObject, c.NativeObject); + } + } + + /// + /// Indicates whether the goal contains `false'. + /// + public bool Inconsistent + { + get { return Native.Z3_goal_inconsistent(Context.nCtx, NativeObject) != 0; } + } + + /// + /// The depth of the goal. + /// + /// + /// This tracks how many transformations were applied to it. + /// + public uint Depth + { + get { return Native.Z3_goal_depth(Context.nCtx, NativeObject); } + } + + /// + /// Erases all formulas from the given goal. + /// + public void Reset() + { + Native.Z3_goal_reset(Context.nCtx, NativeObject); + } + + /// + /// The number of formulas in the goal. + /// + public uint Size + { + get { return Native.Z3_goal_size(Context.nCtx, NativeObject); } + } + + /// + /// The formulas in the goal. + /// + public BoolExpr[] Formulas + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = Size; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = new BoolExpr(Context, Native.Z3_goal_formula(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The number of formulas, subformulas and terms in the goal. + /// + public uint NumExprs + { + get { return Native.Z3_goal_num_exprs(Context.nCtx, NativeObject); } + } + + /// + /// Indicates whether the goal is empty, and it is precise or the product of an under approximation. + /// + public bool IsDecidedSat + { + get { return Native.Z3_goal_is_decided_sat(Context.nCtx, NativeObject) != 0; } + } + + /// + /// Indicates whether the goal contains `false', and it is precise or the product of an over approximation. + /// + public bool IsDecidedUnsat + { + get { return Native.Z3_goal_is_decided_unsat(Context.nCtx, NativeObject) != 0; } + } + + /// + /// Translates (copies) the Goal to the target Context . + /// + public Goal Translate(Context ctx) + { + Contract.Requires(ctx != null); + + return new Goal(ctx, Native.Z3_goal_translate(Context.nCtx, NativeObject, ctx.nCtx)); + } + + /// + /// Simplifies the goal. + /// + /// Essentially invokes the `simplify' tactic on the goal. + public Goal Simplify(Params p = null) + { + Tactic t = Context.MkTactic("simplify"); + ApplyResult res = t.Apply(this, p); + + if (res.NumSubgoals == 0) + return Context.MkGoal(); + else + return res.Subgoals[0]; + } + + /// + /// Goal to string conversion. + /// + /// A string representation of the Goal. + public override string ToString() + { + return Native.Z3_goal_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal Goal(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + + internal Goal(Context ctx, bool models, bool unsatCores, bool proofs) + : base(ctx, Native.Z3_mk_goal(ctx.nCtx, (models) ? 1 : 0, (unsatCores) ? 1 : 0, (proofs) ? 1 : 0)) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_goal_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_goal_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.Goal_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.Goal_DRQ.Add(o); + base.DecRef(o); + } + + #endregion + } +} diff --git a/Microsoft.Z3/Log.cs b/Microsoft.Z3/Log.cs new file mode 100644 index 000000000..9058f73f5 --- /dev/null +++ b/Microsoft.Z3/Log.cs @@ -0,0 +1,79 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Log.cs + +Abstract: + + Z3 Managed API: Log + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-15 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Interaction logging for Z3. + /// + /// + /// Note that this is a global, static log and if multiple Context + /// objects are created, it logs the interaction with all of them. + /// + [ContractVerification(true)] + public static class Log + { + private static bool m_is_open = false; + + /// + /// Open an interaction log file. + /// + /// the name of the file to open + /// True if opening the log file succeeds, false otherwise. + public static bool Open(string filename) + { + m_is_open = true; + return Native.Z3_open_log(filename) == 1; + } + + /// + /// Closes the interaction log. + /// + public static void Close() + { + m_is_open = false; + Native.Z3_close_log(); + } + + /// + /// Appends the user-provided string to the interaction log. + /// + public static void Append(string s) + { + Contract.Requires(isOpen()); + + if (!m_is_open) + throw new Z3Exception("Log cannot be closed."); + Native.Z3_append_log(s); + } + + /// + /// Checks whether the interaction log is opened. + /// + /// True if the interaction log is open, false otherwise. + [Pure] + public static bool isOpen() + { + return m_is_open; + } + } +} diff --git a/Microsoft.Z3/Microsoft.Z3.csproj b/Microsoft.Z3/Microsoft.Z3.csproj new file mode 100644 index 000000000..2b82ee89f --- /dev/null +++ b/Microsoft.Z3/Microsoft.Z3.csproj @@ -0,0 +1,380 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {EC3DB697-B734-42F7-9468-5B62821EEB5A} + Library + Properties + Microsoft.Z3 + Microsoft.Z3 + v4.0 + 512 + Client + 0 + + + true + full + false + ..\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + False + False + True + False + False + True + False + True + True + False + False + False + True + False + False + False + True + False + False + True + True + True + False + False + + + + + + + True + Full + %28none%29 + 2 + + + pdbonly + true + ..\external\ + + + prompt + 4 + true + ..\external\Microsoft.Z3.xml + AnyCPU + + + ..\external\ + true + ..\external\Microsoft.Z3.xml + true + pdbonly + AnyCPU + bin\Release\Microsoft.Z3.dll.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 + + + true + ..\x64\Debug\ + DEBUG;TRACE + true + full + x64 + ..\Debug\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + True + False + True + False + False + False + False + False + False + False + False + False + False + False + False + False + True + False + False + True + False + False + False + + + + + + + False + Full + %28none%29 + 0 + + + ..\x64\external_64\ + true + ..\x64\external_64\Microsoft.Z3.xml + true + pdbonly + x64 + ..\release\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + True + False + True + False + False + True + True + True + False + False + False + True + True + False + False + False + True + False + False + True + True + False + False + + + + + -repro + + True + Full + %28none%29 + 2 + + + ..\x64\external\ + true + ..\external\Microsoft.Z3.xml + true + pdbonly + x64 + bin\Release\Microsoft.Z3.dll.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 + + + ..\x64\external_64\ + true + ..\x64\external_64\Microsoft.Z3.xml + true + pdbonly + AnyCPU + bin\Release\Microsoft.Z3.dll.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 + + + ..\x64\external_64\ + true + ..\x64\external_64\Microsoft.Z3.xml + true + pdbonly + x64 + bin\Release\Microsoft.Z3.dll.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 + True + False + True + False + False + False + False + False + False + False + False + False + False + False + False + False + True + False + False + True + False + False + False + + + + + + + False + Full + %28none%29 + 0 + + + true + + + z3.snk + + + false + + + ..\Release_delaysign\ + true + ..\Release_delaysign\Microsoft.Z3.xml + true + pdbonly + AnyCPU + ..\release\Microsoft.Z3.dll.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 + DELAYSIGN + + + bin\x64\Release_delaysign\ + true + ..\x64\external_64\Microsoft.Z3.xml + true + pdbonly + x64 + ..\release\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Z3/Microsoft.Z3_35.csproj b/Microsoft.Z3/Microsoft.Z3_35.csproj new file mode 100644 index 000000000..8cfe8a532 --- /dev/null +++ b/Microsoft.Z3/Microsoft.Z3_35.csproj @@ -0,0 +1,403 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {EC3DB697-B734-42F7-9468-5B62821EEB5A} + Library + Properties + Microsoft.Z3 + Microsoft.Z3 + v3.5 + 512 + Client + 0 + + + true + full + false + bin35\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + False + False + True + False + False + True + False + True + True + False + False + False + True + False + False + False + True + False + False + True + True + True + False + False + + + + + + + True + Full + %28none%29 + 2 + + + pdbonly + true + bin35\external\bin\ + FRAMEWORK_LT_4 + prompt + 4 + true + ..\external\Microsoft.Z3.xml + + + bin35\external\bin\ + true + ..\external\Microsoft.Z3.xml + true + pdbonly + AnyCPU + bin\Release\Microsoft.Z3.dll.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 + FRAMEWORK_LT_4 + + + bin35\external\bin\ + true + ..\external\Microsoft.Z3.xml + true + pdbonly + AnyCPU + bin\Release\Microsoft.Z3.dll.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 + FRAMEWORK_LT_4 + + + true + bin35\x64\Debug\ + DEBUG;TRACE + true + full + x64 + ..\Debug\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + True + False + True + False + False + False + False + False + False + False + False + False + False + False + False + False + True + False + False + True + False + False + False + + + + + + + False + Full + %28none%29 + 0 + + + bin35\external\x64\ + true + ..\x64\external_64\Microsoft.Z3.xml + true + pdbonly + x64 + ..\release\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + True + False + True + False + False + True + True + True + False + False + False + True + True + False + False + False + True + False + False + True + True + False + False + + + + + -repro + + True + Full + %28none%29 + 2 + + + bin35\external\x64 + true + ..\external\Microsoft.Z3.xml + true + pdbonly + x64 + bin\Release\Microsoft.Z3.dll.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 + + + bin35\external_64\x64 + true + ..\x64\external_64\Microsoft.Z3.xml + FRAMEWORK_LT_4 + true + pdbonly + AnyCPU + bin\Release\Microsoft.Z3.dll.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 + + + bin35\external_64\x64 + true + ..\x64\external_64\Microsoft.Z3.xml + true + pdbonly + x64 + bin\Release\Microsoft.Z3.dll.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 + True + False + True + False + False + False + False + False + False + False + False + False + False + False + False + False + True + False + False + True + False + False + False + + + + + + + False + Full + %28none%29 + 0 + FRAMEWORK_LT_4 + + + true + + + z3.snk + + + false + + + bin35\Release_delaysign\ + true + ..\Release_delaysign\Microsoft.Z3.xml + true + pdbonly + AnyCPU + ..\release\Microsoft.Z3.dll.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 + DELAYSIGN + + + bin\x64\Release_delaysign\ + true + ..\x64\external_64\Microsoft.Z3.xml + true + pdbonly + x64 + ..\release\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + + False + ..\..\..\..\Program Files\Microsoft\Contracts\Contracts\v3.5\Microsoft.Contracts.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Z3/Model.cs b/Microsoft.Z3/Model.cs new file mode 100644 index 000000000..d5bcd34b0 --- /dev/null +++ b/Microsoft.Z3/Model.cs @@ -0,0 +1,318 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Model.cs + +Abstract: + + Z3 Managed API: Models + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// A Model contains interpretations (assignments) of constants and functions. + /// + [ContractVerification(true)] + public class Model : Z3Object + { + /// + /// Retrieves the interpretation (the assignment) of in the model. + /// + /// A Constant + /// An expression if the constant has an interpretation in the model, null otherwise. + public Expr ConstInterp(Expr a) + { + Contract.Requires(a != null); + + Context.CheckContextMatch(a); + return ConstInterp(a.FuncDecl); + } + + /// + /// Retrieves the interpretation (the assignment) of in the model. + /// + /// A function declaration of zero arity + /// An expression if the function has an interpretation in the model, null otherwise. + public Expr ConstInterp(FuncDecl f) + { + Contract.Requires(f != null); + + Context.CheckContextMatch(f); + if (f.Arity != 0 || + Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_range(Context.nCtx, f.NativeObject)) == (uint)Z3_sort_kind.Z3_ARRAY_SORT) + throw new Z3Exception("Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp."); + + IntPtr n = Native.Z3_model_get_const_interp(Context.nCtx, NativeObject, f.NativeObject); + if (n == IntPtr.Zero) + return null; + else + return Expr.Create(Context, n); + } + + /// + /// Retrieves the interpretation (the assignment) of a non-constant in the model. + /// + /// A function declaration of non-zero arity + /// A FunctionInterpretation if the function has an interpretation in the model, null otherwise. + public FuncInterp FuncInterp(FuncDecl f) + { + Contract.Requires(f != null); + + Context.CheckContextMatch(f); + + Z3_sort_kind sk = (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_range(Context.nCtx, f.NativeObject)); + + if (f.Arity == 0) + { + IntPtr n = Native.Z3_model_get_const_interp(Context.nCtx, NativeObject, f.NativeObject); + + if (sk == Z3_sort_kind.Z3_ARRAY_SORT) + { + if (n == IntPtr.Zero) + return null; + else + { + if (Native.Z3_is_as_array(Context.nCtx, n) == 0) + throw new Z3Exception("Argument was not an array constant"); + IntPtr fd = Native.Z3_get_as_array_func_decl(Context.nCtx, n); + return FuncInterp(new FuncDecl(Context, fd)); + } + } + else + { + throw new Z3Exception("Constant functions do not have a function interpretation; use ConstInterp"); + } + } + else + { + IntPtr n = Native.Z3_model_get_func_interp(Context.nCtx, NativeObject, f.NativeObject); + if (n == IntPtr.Zero) + return null; + else + return new FuncInterp(Context, n); + } + } + + /// + /// The number of constants that have an interpretation in the model. + /// + public uint NumConsts + { + get { return Native.Z3_model_get_num_consts(Context.nCtx, NativeObject); } + } + + /// + /// The function declarations of the constants in the model. + /// + public FuncDecl[] ConstDecls + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumConsts; + FuncDecl[] res = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + res[i] = new FuncDecl(Context, Native.Z3_model_get_const_decl(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The number of function interpretations in the model. + /// + public uint NumFuncs + { + get { return Native.Z3_model_get_num_funcs(Context.nCtx, NativeObject); } + } + + /// + /// The function declarations of the function interpretations in the model. + /// + public FuncDecl[] FuncDecls + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumFuncs; + FuncDecl[] res = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + res[i] = new FuncDecl(Context, Native.Z3_model_get_func_decl(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// All symbols that have an interpretation in the model. + /// + public FuncDecl[] Decls + { + get + { + Contract.Ensures(Contract.Result() != null); + + var nFuncs = NumFuncs; + var nConsts = NumConsts; + uint n = nFuncs + nConsts; + FuncDecl[] res = new FuncDecl[n]; + for (uint i = 0; i < nConsts; i++) + res[i] = new FuncDecl(Context, Native.Z3_model_get_const_decl(Context.nCtx, NativeObject, i)); + for (uint i = 0; i < nFuncs; i++) + res[nConsts + i] = new FuncDecl(Context, Native.Z3_model_get_func_decl(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. + /// + public class ModelEvaluationFailedException : Z3Exception + { + /// + /// An exception that is thrown when model evaluation fails. + /// + public ModelEvaluationFailedException() : base() { } + } + + /// + /// Evaluates the expression in the current model. + /// + /// + /// This function may fail if contains quantifiers, + /// is partial (MODEL_PARTIAL enabled), or if is not well-sorted. + /// In this case a ModelEvaluationFailedException is thrown. + /// + /// An expression + /// + /// When this flag is enabled, a model value will be assigned to any constant + /// or function that does not have an interpretation in the model. + /// + /// The evaluation of in the model. + public Expr Eval(Expr t, bool completion = false) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + IntPtr v = IntPtr.Zero; + if (Native.Z3_model_eval(Context.nCtx, NativeObject, t.NativeObject, (completion) ? 1 : 0, ref v) == 0) + throw new ModelEvaluationFailedException(); + else + return Expr.Create(Context, v); + } + + /// + /// Alias for Eval. + /// + public Expr Evaluate(Expr t, bool completion = false) + { + Contract.Requires(t != null); + Contract.Ensures(Contract.Result() != null); + + return Eval(t, completion); + } + + /// + /// The number of uninterpreted sorts that the model has an interpretation for. + /// + public uint NumSorts { get { return Native.Z3_model_get_num_sorts(Context.nCtx, NativeObject); } } + + /// + /// The uninterpreted sorts that the model has an interpretation for. + /// + /// + /// Z3 also provides an intepretation for uninterpreted sorts used in a formula. + /// The interpretation for a sort is a finite set of distinct values. We say this finite set is + /// the "universe" of the sort. + /// + /// + /// + public Sort[] Sorts + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumSorts; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(Context, Native.Z3_model_get_sort(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The finite set of distinct values that represent the interpretation for sort . + /// + /// + /// An uninterpreted sort + /// An array of expressions, where each is an element of the universe of + public Expr[] SortUniverse(Sort s) + { + Contract.Requires(s != null); + Contract.Ensures(Contract.Result() != null); + + ASTVector nUniv = new ASTVector(Context, Native.Z3_model_get_sort_universe(Context.nCtx, NativeObject, s.NativeObject)); + uint n = nUniv.Size; + Expr[] res = new Expr[n]; + for (uint i = 0; i < n; i++) + res[i] = Expr.Create(Context, nUniv[i].NativeObject); + return res; + } + + /// + /// Conversion of models to strings. + /// + /// A string representation of the model. + public override string ToString() + { + return Native.Z3_model_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal Model(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_model_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_model_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.Model_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.Model_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Native.cs b/Microsoft.Z3/Native.cs new file mode 100644 index 000000000..81e4a600c --- /dev/null +++ b/Microsoft.Z3/Native.cs @@ -0,0 +1,5210 @@ +// Automatically generated file, generator: api.py +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +#pragma warning disable 1591 + +namespace Microsoft.Z3 +{ + using Z3_config = System.IntPtr; + using Z3_context = System.IntPtr; + using Z3_ast = System.IntPtr; + using Z3_app = System.IntPtr; + using Z3_sort = System.IntPtr; + using Z3_func_decl = System.IntPtr; + using Z3_pattern = System.IntPtr; + using Z3_model = System.IntPtr; + using Z3_literals = System.IntPtr; + using Z3_constructor = System.IntPtr; + using Z3_constructor_list = System.IntPtr; + using Z3_theory = System.IntPtr; + using Z3_theory_data = System.IntPtr; + using Z3_solver = System.IntPtr; + using Z3_goal = System.IntPtr; + using Z3_tactic = System.IntPtr; + using Z3_params = System.IntPtr; + using Z3_probe = System.IntPtr; + using Z3_stats = System.IntPtr; + using Z3_ast_vector = System.IntPtr; + using Z3_ast_map = System.IntPtr; + using Z3_apply_result = System.IntPtr; + using Z3_func_interp = System.IntPtr; + using Z3_func_entry = System.IntPtr; + using Z3_fixedpoint = System.IntPtr; + using Z3_param_descrs = System.IntPtr; + + public class Native + { + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void Z3_error_handler(Z3_context c, Z3_error_code e); + + public unsafe class LIB + { + #if DEBUG + const string Z3_DLL_NAME = "z3_dbg.dll"; + #else + const string Z3_DLL_NAME = "z3.dll"; + #endif + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_set_error_handler(Z3_context a0, Z3_error_handler a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_config Z3_mk_config(); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_del_config(Z3_config a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_set_param_value(Z3_config a0, string a1, string a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_context Z3_mk_context(Z3_config a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_context Z3_mk_context_rc(Z3_config a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_set_logic(Z3_context a0, string a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_del_context(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_inc_ref(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_dec_ref(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_toggle_warning_messages(int a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_update_param_value(Z3_context a0, string a1, string a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_param_value(Z3_context a0, string a1, out IntPtr a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_mk_int_symbol(Z3_context a0, int a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_mk_string_symbol(Z3_context a0, string a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_eq_sort(Z3_context a0, Z3_sort a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_uninterpreted_sort(Z3_context a0, IntPtr a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_bool_sort(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_int_sort(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_real_sort(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_bv_sort(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_array_sort(Z3_context a0, Z3_sort a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_tuple_sort(Z3_context a0, IntPtr a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, [In, Out] ref Z3_func_decl a5, [Out] Z3_func_decl[] a6); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_enumeration_sort(Z3_context a0, IntPtr a1, uint a2, [In] IntPtr[] a3, [Out] Z3_func_decl[] a4, [Out] Z3_func_decl[] a5); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_list_sort(Z3_context a0, IntPtr a1, Z3_sort a2, [In, Out] ref Z3_func_decl a3, [In, Out] ref Z3_func_decl a4, [In, Out] ref Z3_func_decl a5, [In, Out] ref Z3_func_decl a6, [In, Out] ref Z3_func_decl a7, [In, Out] ref Z3_func_decl a8); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_constructor Z3_mk_constructor(Z3_context a0, IntPtr a1, IntPtr a2, uint a3, [In] IntPtr[] a4, [In] Z3_sort[] a5, [In] uint[] a6); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_query_constructor(Z3_context a0, Z3_constructor a1, uint a2, [In, Out] ref Z3_func_decl a3, [In, Out] ref Z3_func_decl a4, [Out] Z3_func_decl[] a5); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_del_constructor(Z3_context a0, Z3_constructor a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_datatype(Z3_context a0, IntPtr a1, uint a2, [In, Out] Z3_constructor[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_constructor_list Z3_mk_constructor_list(Z3_context a0, uint a1, [In] Z3_constructor[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_del_constructor_list(Z3_context a0, Z3_constructor_list a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_mk_datatypes(Z3_context a0, uint a1, [In] IntPtr[] a2, [Out] Z3_sort[] a3, [In, Out] Z3_constructor_list[] a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_eq_ast(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_eq_func_decl(Z3_context a0, Z3_func_decl a1, Z3_func_decl a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_mk_func_decl(Z3_context a0, IntPtr a1, uint a2, [In] Z3_sort[] a3, Z3_sort a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_app(Z3_context a0, Z3_func_decl a1, uint a2, [In] Z3_ast[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_const(Z3_context a0, IntPtr a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_label(Z3_context a0, IntPtr a1, int a2, Z3_ast a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_mk_fresh_func_decl(Z3_context a0, string a1, uint a2, [In] Z3_sort[] a3, Z3_sort a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_fresh_const(Z3_context a0, string a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_true(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_false(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_eq(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_distinct(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_not(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_ite(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_ast a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_iff(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_implies(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_xor(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_and(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_or(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_add(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_mul(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_sub(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_unary_minus(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_div(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_mod(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_rem(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_power(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_algebraic_number(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_algebraic_number_lower(Z3_context a0, Z3_ast a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_algebraic_number_upper(Z3_context a0, Z3_ast a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_lt(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_le(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_gt(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_ge(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_int2real(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_real2int(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_is_int(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvnot(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvredand(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvredor(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvand(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvor(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvxor(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvnand(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvnor(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvxnor(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvneg(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvadd(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsub(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvmul(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvudiv(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsdiv(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvurem(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsrem(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsmod(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvult(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvslt(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvule(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsle(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvuge(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsge(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvugt(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsgt(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_concat(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_extract(Z3_context a0, uint a1, uint a2, Z3_ast a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_sign_ext(Z3_context a0, uint a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_zero_ext(Z3_context a0, uint a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_repeat(Z3_context a0, uint a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvshl(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvlshr(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvashr(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_rotate_left(Z3_context a0, uint a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_rotate_right(Z3_context a0, uint a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_ext_rotate_left(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_ext_rotate_right(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_int2bv(Z3_context a0, uint a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bv2int(Z3_context a0, Z3_ast a1, int a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvadd_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2, int a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvadd_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsub_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsub_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2, int a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvsdiv_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvneg_no_overflow(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvmul_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2, int a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bvmul_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_select(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_store(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_ast a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_const_array(Z3_context a0, Z3_sort a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_map(Z3_context a0, Z3_func_decl a1, uint a2, [In] Z3_ast[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_array_default(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_set_sort(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_empty_set(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_full_set(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_set_add(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_set_del(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_set_union(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_set_intersect(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_set_difference(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_set_complement(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_set_member(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_set_subset(Z3_context a0, Z3_ast a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_numeral(Z3_context a0, string a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_real(Z3_context a0, int a1, int a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_int(Z3_context a0, int a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_unsigned_int(Z3_context a0, uint a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_int64(Z3_context a0, Int64 a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_unsigned_int64(Z3_context a0, UInt64 a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_pattern Z3_mk_pattern(Z3_context a0, uint a1, [In] Z3_ast[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_bound(Z3_context a0, uint a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_forall(Z3_context a0, uint a1, uint a2, [In] Z3_pattern[] a3, uint a4, [In] Z3_sort[] a5, [In] IntPtr[] a6, Z3_ast a7); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_exists(Z3_context a0, uint a1, uint a2, [In] Z3_pattern[] a3, uint a4, [In] Z3_sort[] a5, [In] IntPtr[] a6, Z3_ast a7); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_quantifier(Z3_context a0, int a1, uint a2, uint a3, [In] Z3_pattern[] a4, uint a5, [In] Z3_sort[] a6, [In] IntPtr[] a7, Z3_ast a8); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_quantifier_ex(Z3_context a0, int a1, uint a2, IntPtr a3, IntPtr a4, uint a5, [In] Z3_pattern[] a6, uint a7, [In] Z3_ast[] a8, uint a9, [In] Z3_sort[] a10, [In] IntPtr[] a11, Z3_ast a12); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_forall_const(Z3_context a0, uint a1, uint a2, [In] Z3_app[] a3, uint a4, [In] Z3_pattern[] a5, Z3_ast a6); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_exists_const(Z3_context a0, uint a1, uint a2, [In] Z3_app[] a3, uint a4, [In] Z3_pattern[] a5, Z3_ast a6); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_quantifier_const(Z3_context a0, int a1, uint a2, uint a3, [In] Z3_app[] a4, uint a5, [In] Z3_pattern[] a6, Z3_ast a7); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_mk_quantifier_const_ex(Z3_context a0, int a1, uint a2, IntPtr a3, IntPtr a4, uint a5, [In] Z3_app[] a6, uint a7, [In] Z3_pattern[] a8, uint a9, [In] Z3_ast[] a10, Z3_ast a11); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_ast_id(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_func_decl_id(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_sort_id(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_well_sorted(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_symbol_kind(Z3_context a0, IntPtr a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_symbol_int(Z3_context a0, IntPtr a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_symbol_string(Z3_context a0, IntPtr a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_ast_kind(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_ast_hash(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_numeral_string(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_numeral_decimal_string(Z3_context a0, Z3_ast a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_numerator(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_denominator(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_numeral_small(Z3_context a0, Z3_ast a1, [In, Out] ref Int64 a2, [In, Out] ref Int64 a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_numeral_int(Z3_context a0, Z3_ast a1, [In, Out] ref int a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_numeral_uint(Z3_context a0, Z3_ast a1, [In, Out] ref uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_numeral_uint64(Z3_context a0, Z3_ast a1, [In, Out] ref UInt64 a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_numeral_int64(Z3_context a0, Z3_ast a1, [In, Out] ref Int64 a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_numeral_rational_int64(Z3_context a0, Z3_ast a1, [In, Out] ref Int64 a2, [In, Out] ref Int64 a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_bool_value(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_app_decl(Z3_context a0, Z3_app a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_app_num_args(Z3_context a0, Z3_app a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_app_arg(Z3_context a0, Z3_app a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_index_value(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_quantifier_forall(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_quantifier_weight(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_quantifier_num_patterns(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_pattern Z3_get_quantifier_pattern_ast(Z3_context a0, Z3_ast a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_quantifier_num_no_patterns(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_quantifier_no_pattern_ast(Z3_context a0, Z3_ast a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_quantifier_bound_name(Z3_context a0, Z3_ast a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_quantifier_bound_sort(Z3_context a0, Z3_ast a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_quantifier_body(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_quantifier_num_bound(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_decl_name(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_decl_num_parameters(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_decl_parameter_kind(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_decl_int_parameter(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static double Z3_get_decl_double_parameter(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_decl_symbol_parameter(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_decl_sort_parameter(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_decl_ast_parameter(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_decl_func_decl_parameter(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_decl_rational_parameter(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_sort_name(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_sort(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_domain_size(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_domain(Z3_context a0, Z3_func_decl a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_range(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_sort_kind(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_bv_sort_size(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_array_sort_domain(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_array_sort_range(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_tuple_sort_mk_decl(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_decl_kind(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_tuple_sort_num_fields(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_tuple_sort_field_decl(Z3_context a0, Z3_sort a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_datatype_sort_num_constructors(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_datatype_sort_constructor(Z3_context a0, Z3_sort a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_datatype_sort_recognizer(Z3_context a0, Z3_sort a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_datatype_sort_constructor_accessor(Z3_context a0, Z3_sort a1, uint a2, uint a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_relation_arity(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_relation_column(Z3_context a0, Z3_sort a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_get_finite_domain_sort_size(Z3_context a0, Z3_sort a1, [In, Out] ref UInt64 a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_mk_finite_domain_sort(Z3_context a0, IntPtr a1, UInt64 a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_pattern_num_terms(Z3_context a0, Z3_pattern a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_pattern(Z3_context a0, Z3_pattern a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_simplify(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_simplify_ex(Z3_context a0, Z3_ast a1, Z3_params a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_simplify_get_help(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_param_descrs Z3_simplify_get_param_descrs(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_update_term(Z3_context a0, Z3_ast a1, uint a2, [In] Z3_ast[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_substitute(Z3_context a0, Z3_ast a1, uint a2, [In] Z3_ast[] a3, [In] Z3_ast[] a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_substitute_vars(Z3_context a0, Z3_ast a1, uint a2, [In] Z3_ast[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_sort_to_ast(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_func_decl_to_ast(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_pattern_to_ast(Z3_context a0, Z3_pattern a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_app_to_ast(Z3_context a0, Z3_app a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_app Z3_to_app(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_to_func_decl(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_push(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_pop(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_num_scopes(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_persist_ast(Z3_context a0, Z3_ast a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_assert_cnstr(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_check_and_get_model(Z3_context a0, [In, Out] ref Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_check(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_check_assumptions(Z3_context a0, uint a1, [In] Z3_ast[] a2, [In, Out] ref Z3_model a3, [In, Out] ref Z3_ast a4, [In, Out] ref uint a5, [Out] Z3_ast[] a6); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_implied_equalities(Z3_context a0, uint a1, [In] Z3_ast[] a2, [Out] uint[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_del_model(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_soft_check_cancel(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_search_failure(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_literals Z3_get_relevant_labels(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_literals Z3_get_relevant_literals(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_literals Z3_get_guessed_literals(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_del_literals(Z3_context a0, Z3_literals a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_num_literals(Z3_context a0, Z3_literals a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_label_symbol(Z3_context a0, Z3_literals a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_literal(Z3_context a0, Z3_literals a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_disable_literal(Z3_context a0, Z3_literals a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_block_literals(Z3_context a0, Z3_literals a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_model_inc_ref(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_model_dec_ref(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_model_get_const_interp(Z3_context a0, Z3_model a1, Z3_func_decl a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_interp Z3_model_get_func_interp(Z3_context a0, Z3_model a1, Z3_func_decl a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_model_get_num_consts(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_model_get_const_decl(Z3_context a0, Z3_model a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_model_get_num_funcs(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_model_get_func_decl(Z3_context a0, Z3_model a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_model_eval(Z3_context a0, Z3_model a1, Z3_ast a2, int a3, [In, Out] ref Z3_ast a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_model_get_num_sorts(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_model_get_sort(Z3_context a0, Z3_model a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast_vector Z3_model_get_sort_universe(Z3_context a0, Z3_model a1, Z3_sort a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_as_array(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_as_array_func_decl(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_func_interp_inc_ref(Z3_context a0, Z3_func_interp a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_func_interp_dec_ref(Z3_context a0, Z3_func_interp a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_func_interp_get_num_entries(Z3_context a0, Z3_func_interp a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_entry Z3_func_interp_get_entry(Z3_context a0, Z3_func_interp a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_func_interp_get_else(Z3_context a0, Z3_func_interp a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_func_interp_get_arity(Z3_context a0, Z3_func_interp a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_func_entry_inc_ref(Z3_context a0, Z3_func_entry a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_func_entry_dec_ref(Z3_context a0, Z3_func_entry a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_func_entry_get_value(Z3_context a0, Z3_func_entry a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_func_entry_get_num_args(Z3_context a0, Z3_func_entry a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_func_entry_get_arg(Z3_context a0, Z3_func_entry a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_model_num_constants(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_model_constant(Z3_context a0, Z3_model a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_eval_func_decl(Z3_context a0, Z3_model a1, Z3_func_decl a2, [In, Out] ref Z3_ast a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_array_value(Z3_context a0, Z3_model a1, Z3_ast a2, [In, Out] ref uint a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_get_array_value(Z3_context a0, Z3_model a1, Z3_ast a2, uint a3, [Out] Z3_ast[] a4, [Out] Z3_ast[] a5, [In, Out] ref Z3_ast a6); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_model_num_funcs(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_model_func_decl(Z3_context a0, Z3_model a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_model_func_else(Z3_context a0, Z3_model a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_model_func_num_entries(Z3_context a0, Z3_model a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_model_func_entry_num_args(Z3_context a0, Z3_model a1, uint a2, uint a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_model_func_entry_arg(Z3_context a0, Z3_model a1, uint a2, uint a3, uint a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_model_func_entry_value(Z3_context a0, Z3_model a1, uint a2, uint a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_eval(Z3_context a0, Z3_model a1, Z3_ast a2, [In, Out] ref Z3_ast a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_eval_decl(Z3_context a0, Z3_model a1, Z3_func_decl a2, uint a3, [In] Z3_ast[] a4, [In, Out] ref Z3_ast a5); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_set_ast_print_mode(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_ast_to_string(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_pattern_to_string(Z3_context a0, Z3_pattern a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_sort_to_string(Z3_context a0, Z3_sort a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_func_decl_to_string(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_model_to_string(Z3_context a0, Z3_model a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_benchmark_to_smtlib_string(Z3_context a0, string a1, string a2, string a3, string a4, uint a5, [In] Z3_ast[] a6, Z3_ast a7); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_context_to_string(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_statistics_to_string(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_context_assignment(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_parse_smtlib_string(Z3_context a0, string a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, uint a5, [In] IntPtr[] a6, [In] Z3_func_decl[] a7); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_parse_smtlib_file(Z3_context a0, string a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, uint a5, [In] IntPtr[] a6, [In] Z3_func_decl[] a7); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_smtlib_num_formulas(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_smtlib_formula(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_smtlib_num_assumptions(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_get_smtlib_assumption(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_smtlib_num_decls(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_get_smtlib_decl(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_smtlib_num_sorts(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_sort Z3_get_smtlib_sort(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_smtlib_error(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_parse_z3_string(Z3_context a0, string a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_parse_z3_file(Z3_context a0, string a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_parse_smtlib2_string(Z3_context a0, string a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, uint a5, [In] IntPtr[] a6, [In] Z3_func_decl[] a7); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_parse_smtlib2_file(Z3_context a0, string a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, uint a5, [In] IntPtr[] a6, [In] Z3_func_decl[] a7); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_error_code(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_set_error(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_error_msg(uint a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_get_version([In, Out] ref uint a0, [In, Out] ref uint a1, [In, Out] ref uint a2, [In, Out] ref uint a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_reset_memory(); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_app(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_is_numeral_ast(Z3_context a0, Z3_ast a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_arity(Z3_context a0, Z3_func_decl a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_func_decl Z3_mk_injective_function(Z3_context a0, IntPtr a1, uint a2, [In] Z3_sort[] a3, Z3_sort a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_fixedpoint Z3_mk_fixedpoint(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_inc_ref(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_dec_ref(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_push(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_pop(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_register_relation(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_assert(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_add_rule(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2, IntPtr a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_add_fact(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2, uint a3, [In] uint[] a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_fixedpoint_query(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_fixedpoint_query_relations(Z3_context a0, Z3_fixedpoint a1, uint a2, [In] Z3_func_decl[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_fixedpoint_get_answer(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_update_rule(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2, IntPtr a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_fixedpoint_get_num_levels(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_fixedpoint_get_cover_delta(Z3_context a0, Z3_fixedpoint a1, int a2, Z3_func_decl a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_add_cover(Z3_context a0, Z3_fixedpoint a1, int a2, Z3_func_decl a3, Z3_ast a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_stats Z3_fixedpoint_get_statistics(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_fixedpoint_get_help(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_param_descrs Z3_fixedpoint_get_param_descrs(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_set_params(Z3_context a0, Z3_fixedpoint a1, Z3_params a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_fixedpoint_to_string(Z3_context a0, Z3_fixedpoint a1, uint a2, [In] Z3_ast[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_fixedpoint_get_reason_unknown(Z3_context a0, Z3_fixedpoint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_fixedpoint_set_predicate_representation(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2, uint a3, [In] IntPtr[] a4); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast_vector Z3_fixedpoint_simplify_rules(Z3_context a0, Z3_fixedpoint a1, uint a2, [In] Z3_ast[] a3, uint a4, [In] Z3_func_decl[] a5); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_params Z3_mk_params(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_params_inc_ref(Z3_context a0, Z3_params a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_params_dec_ref(Z3_context a0, Z3_params a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_params_set_bool(Z3_context a0, Z3_params a1, IntPtr a2, int a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_params_set_uint(Z3_context a0, Z3_params a1, IntPtr a2, uint a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_params_set_double(Z3_context a0, Z3_params a1, IntPtr a2, double a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_params_set_symbol(Z3_context a0, Z3_params a1, IntPtr a2, IntPtr a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_params_to_string(Z3_context a0, Z3_params a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_params_validate(Z3_context a0, Z3_params a1, Z3_param_descrs a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_param_descrs_inc_ref(Z3_context a0, Z3_param_descrs a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_param_descrs_dec_ref(Z3_context a0, Z3_param_descrs a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_param_descrs_get_kind(Z3_context a0, Z3_param_descrs a1, IntPtr a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_param_descrs_size(Z3_context a0, Z3_param_descrs a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_param_descrs_get_name(Z3_context a0, Z3_param_descrs a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_interrupt(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_error_msg_ex(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_translate(Z3_context a0, Z3_ast a1, Z3_context a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_goal Z3_mk_goal(Z3_context a0, int a1, int a2, int a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_goal_inc_ref(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_goal_dec_ref(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_goal_precision(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_goal_assert(Z3_context a0, Z3_goal a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_goal_inconsistent(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_goal_depth(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_goal_reset(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_goal_size(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_goal_formula(Z3_context a0, Z3_goal a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_goal_num_exprs(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_goal_is_decided_sat(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_goal_is_decided_unsat(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_goal Z3_goal_translate(Z3_context a0, Z3_goal a1, Z3_context a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_goal_to_string(Z3_context a0, Z3_goal a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_mk_tactic(Z3_context a0, string a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_mk_probe(Z3_context a0, string a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_tactic_inc_ref(Z3_context a0, Z3_tactic a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_tactic_dec_ref(Z3_context a0, Z3_tactic a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_probe_inc_ref(Z3_context a0, Z3_probe a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_probe_dec_ref(Z3_context a0, Z3_probe a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_and_then(Z3_context a0, Z3_tactic a1, Z3_tactic a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_or_else(Z3_context a0, Z3_tactic a1, Z3_tactic a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_par_or(Z3_context a0, uint a1, [In] Z3_tactic[] a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_par_and_then(Z3_context a0, Z3_tactic a1, Z3_tactic a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_try_for(Z3_context a0, Z3_tactic a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_when(Z3_context a0, Z3_probe a1, Z3_tactic a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_cond(Z3_context a0, Z3_probe a1, Z3_tactic a2, Z3_tactic a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_repeat(Z3_context a0, Z3_tactic a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_skip(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_fail(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_fail_if(Z3_context a0, Z3_probe a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_fail_if_not_decided(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_tactic Z3_tactic_using_params(Z3_context a0, Z3_tactic a1, Z3_params a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_const(Z3_context a0, double a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_lt(Z3_context a0, Z3_probe a1, Z3_probe a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_le(Z3_context a0, Z3_probe a1, Z3_probe a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_gt(Z3_context a0, Z3_probe a1, Z3_probe a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_ge(Z3_context a0, Z3_probe a1, Z3_probe a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_eq(Z3_context a0, Z3_probe a1, Z3_probe a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_and(Z3_context a0, Z3_probe a1, Z3_probe a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_or(Z3_context a0, Z3_probe a1, Z3_probe a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_probe Z3_probe_not(Z3_context a0, Z3_probe a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_num_tactics(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_tactic_name(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_get_num_probes(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_get_probe_name(Z3_context a0, uint a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_tactic_get_help(Z3_context a0, Z3_tactic a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_param_descrs Z3_tactic_get_param_descrs(Z3_context a0, Z3_tactic a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_tactic_get_descr(Z3_context a0, string a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_probe_get_descr(Z3_context a0, string a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static double Z3_probe_apply(Z3_context a0, Z3_probe a1, Z3_goal a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_apply_result Z3_tactic_apply(Z3_context a0, Z3_tactic a1, Z3_goal a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_apply_result Z3_tactic_apply_ex(Z3_context a0, Z3_tactic a1, Z3_goal a2, Z3_params a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_apply_result_inc_ref(Z3_context a0, Z3_apply_result a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_apply_result_dec_ref(Z3_context a0, Z3_apply_result a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_apply_result_to_string(Z3_context a0, Z3_apply_result a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_apply_result_get_num_subgoals(Z3_context a0, Z3_apply_result a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_goal Z3_apply_result_get_subgoal(Z3_context a0, Z3_apply_result a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_model Z3_apply_result_convert_model(Z3_context a0, Z3_apply_result a1, uint a2, Z3_model a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_solver Z3_mk_solver(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_solver Z3_mk_simple_solver(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_solver Z3_mk_solver_for_logic(Z3_context a0, IntPtr a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_solver Z3_mk_solver_from_tactic(Z3_context a0, Z3_tactic a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_solver_get_help(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_param_descrs Z3_solver_get_param_descrs(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_solver_set_params(Z3_context a0, Z3_solver a1, Z3_params a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_solver_inc_ref(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_solver_dec_ref(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_solver_push(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_solver_pop(Z3_context a0, Z3_solver a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_solver_reset(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_solver_get_num_scopes(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_solver_assert(Z3_context a0, Z3_solver a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast_vector Z3_solver_get_assertions(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_solver_check(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_solver_check_assumptions(Z3_context a0, Z3_solver a1, uint a2, [In] Z3_ast[] a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_model Z3_solver_get_model(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_solver_get_proof(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast_vector Z3_solver_get_unsat_core(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_solver_get_reason_unknown(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_stats Z3_solver_get_statistics(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_solver_to_string(Z3_context a0, Z3_solver a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_stats_to_string(Z3_context a0, Z3_stats a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_stats_inc_ref(Z3_context a0, Z3_stats a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_stats_dec_ref(Z3_context a0, Z3_stats a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_stats_size(Z3_context a0, Z3_stats a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_stats_get_key(Z3_context a0, Z3_stats a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_stats_is_uint(Z3_context a0, Z3_stats a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_stats_is_double(Z3_context a0, Z3_stats a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_stats_get_uint_value(Z3_context a0, Z3_stats a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static double Z3_stats_get_double_value(Z3_context a0, Z3_stats a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast_vector Z3_mk_ast_vector(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_vector_inc_ref(Z3_context a0, Z3_ast_vector a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_vector_dec_ref(Z3_context a0, Z3_ast_vector a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_ast_vector_size(Z3_context a0, Z3_ast_vector a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_ast_vector_get(Z3_context a0, Z3_ast_vector a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_vector_set(Z3_context a0, Z3_ast_vector a1, uint a2, Z3_ast a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_vector_resize(Z3_context a0, Z3_ast_vector a1, uint a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_vector_push(Z3_context a0, Z3_ast_vector a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast_vector Z3_ast_vector_translate(Z3_context a0, Z3_ast_vector a1, Z3_context a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_ast_vector_to_string(Z3_context a0, Z3_ast_vector a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast_map Z3_mk_ast_map(Z3_context a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_map_inc_ref(Z3_context a0, Z3_ast_map a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_map_dec_ref(Z3_context a0, Z3_ast_map a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_ast_map_contains(Z3_context a0, Z3_ast_map a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast Z3_ast_map_find(Z3_context a0, Z3_ast_map a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_map_insert(Z3_context a0, Z3_ast_map a1, Z3_ast a2, Z3_ast a3); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_map_erase(Z3_context a0, Z3_ast_map a1, Z3_ast a2); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static uint Z3_ast_map_size(Z3_context a0, Z3_ast_map a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_ast_map_reset(Z3_context a0, Z3_ast_map a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static Z3_ast_vector Z3_ast_map_keys(Z3_context a0, Z3_ast_map a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static IntPtr Z3_ast_map_to_string(Z3_context a0, Z3_ast_map a1); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static int Z3_open_log(string a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_append_log(string a0); + + [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public extern static void Z3_close_log(); + + } + + public static void Z3_set_error_handler(Z3_context a0, Z3_error_handler a1) { + LIB.Z3_set_error_handler(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_config Z3_mk_config() { + Z3_config r = LIB.Z3_mk_config(); + return r; + } + + public static void Z3_del_config(Z3_config a0) { + LIB.Z3_del_config(a0); + } + + public static void Z3_set_param_value(Z3_config a0, string a1, string a2) { + LIB.Z3_set_param_value(a0, a1, a2); + } + + public static Z3_context Z3_mk_context(Z3_config a0) { + Z3_context r = LIB.Z3_mk_context(a0); + return r; + } + + public static Z3_context Z3_mk_context_rc(Z3_config a0) { + Z3_context r = LIB.Z3_mk_context_rc(a0); + return r; + } + + public static void Z3_set_logic(Z3_context a0, string a1) { + LIB.Z3_set_logic(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_del_context(Z3_context a0) { + LIB.Z3_del_context(a0); + } + + public static void Z3_inc_ref(Z3_context a0, Z3_ast a1) { + LIB.Z3_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_dec_ref(Z3_context a0, Z3_ast a1) { + LIB.Z3_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_toggle_warning_messages(int a0) { + LIB.Z3_toggle_warning_messages(a0); + } + + public static void Z3_update_param_value(Z3_context a0, string a1, string a2) { + LIB.Z3_update_param_value(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static int Z3_get_param_value(Z3_context a0, string a1, out IntPtr a2) { + int r = LIB.Z3_get_param_value(a0, a1, out a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static IntPtr Z3_mk_int_symbol(Z3_context a0, int a1) { + IntPtr r = LIB.Z3_mk_int_symbol(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static IntPtr Z3_mk_string_symbol(Z3_context a0, string a1) { + IntPtr r = LIB.Z3_mk_string_symbol(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_is_eq_sort(Z3_context a0, Z3_sort a1, Z3_sort a2) { + int r = LIB.Z3_is_eq_sort(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_uninterpreted_sort(Z3_context a0, IntPtr a1) { + Z3_sort r = LIB.Z3_mk_uninterpreted_sort(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_bool_sort(Z3_context a0) { + Z3_sort r = LIB.Z3_mk_bool_sort(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_int_sort(Z3_context a0) { + Z3_sort r = LIB.Z3_mk_int_sort(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_real_sort(Z3_context a0) { + Z3_sort r = LIB.Z3_mk_real_sort(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_bv_sort(Z3_context a0, uint a1) { + Z3_sort r = LIB.Z3_mk_bv_sort(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_array_sort(Z3_context a0, Z3_sort a1, Z3_sort a2) { + Z3_sort r = LIB.Z3_mk_array_sort(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_tuple_sort(Z3_context a0, IntPtr a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, [In, Out] ref Z3_func_decl a5, [Out] Z3_func_decl[] a6) { + Z3_sort r = LIB.Z3_mk_tuple_sort(a0, a1, a2, a3, a4, ref a5, a6); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_enumeration_sort(Z3_context a0, IntPtr a1, uint a2, [In] IntPtr[] a3, [Out] Z3_func_decl[] a4, [Out] Z3_func_decl[] a5) { + Z3_sort r = LIB.Z3_mk_enumeration_sort(a0, a1, a2, a3, a4, a5); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_list_sort(Z3_context a0, IntPtr a1, Z3_sort a2, [In, Out] ref Z3_func_decl a3, [In, Out] ref Z3_func_decl a4, [In, Out] ref Z3_func_decl a5, [In, Out] ref Z3_func_decl a6, [In, Out] ref Z3_func_decl a7, [In, Out] ref Z3_func_decl a8) { + Z3_sort r = LIB.Z3_mk_list_sort(a0, a1, a2, ref a3, ref a4, ref a5, ref a6, ref a7, ref a8); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_constructor Z3_mk_constructor(Z3_context a0, IntPtr a1, IntPtr a2, uint a3, [In] IntPtr[] a4, [In] Z3_sort[] a5, [In] uint[] a6) { + Z3_constructor r = LIB.Z3_mk_constructor(a0, a1, a2, a3, a4, a5, a6); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_query_constructor(Z3_context a0, Z3_constructor a1, uint a2, [In, Out] ref Z3_func_decl a3, [In, Out] ref Z3_func_decl a4, [Out] Z3_func_decl[] a5) { + LIB.Z3_query_constructor(a0, a1, a2, ref a3, ref a4, a5); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_del_constructor(Z3_context a0, Z3_constructor a1) { + LIB.Z3_del_constructor(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_sort Z3_mk_datatype(Z3_context a0, IntPtr a1, uint a2, [In, Out] Z3_constructor[] a3) { + Z3_sort r = LIB.Z3_mk_datatype(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_constructor_list Z3_mk_constructor_list(Z3_context a0, uint a1, [In] Z3_constructor[] a2) { + Z3_constructor_list r = LIB.Z3_mk_constructor_list(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_del_constructor_list(Z3_context a0, Z3_constructor_list a1) { + LIB.Z3_del_constructor_list(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_mk_datatypes(Z3_context a0, uint a1, [In] IntPtr[] a2, [Out] Z3_sort[] a3, [In, Out] Z3_constructor_list[] a4) { + LIB.Z3_mk_datatypes(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static int Z3_is_eq_ast(Z3_context a0, Z3_ast a1, Z3_ast a2) { + int r = LIB.Z3_is_eq_ast(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_is_eq_func_decl(Z3_context a0, Z3_func_decl a1, Z3_func_decl a2) { + int r = LIB.Z3_is_eq_func_decl(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_mk_func_decl(Z3_context a0, IntPtr a1, uint a2, [In] Z3_sort[] a3, Z3_sort a4) { + Z3_func_decl r = LIB.Z3_mk_func_decl(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_app(Z3_context a0, Z3_func_decl a1, uint a2, [In] Z3_ast[] a3) { + Z3_ast r = LIB.Z3_mk_app(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_const(Z3_context a0, IntPtr a1, Z3_sort a2) { + Z3_ast r = LIB.Z3_mk_const(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_label(Z3_context a0, IntPtr a1, int a2, Z3_ast a3) { + Z3_ast r = LIB.Z3_mk_label(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_mk_fresh_func_decl(Z3_context a0, string a1, uint a2, [In] Z3_sort[] a3, Z3_sort a4) { + Z3_func_decl r = LIB.Z3_mk_fresh_func_decl(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_fresh_const(Z3_context a0, string a1, Z3_sort a2) { + Z3_ast r = LIB.Z3_mk_fresh_const(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_true(Z3_context a0) { + Z3_ast r = LIB.Z3_mk_true(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_false(Z3_context a0) { + Z3_ast r = LIB.Z3_mk_false(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_eq(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_eq(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_distinct(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_ast r = LIB.Z3_mk_distinct(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_not(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_not(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_ite(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_ast a3) { + Z3_ast r = LIB.Z3_mk_ite(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_iff(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_iff(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_implies(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_implies(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_xor(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_xor(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_and(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_ast r = LIB.Z3_mk_and(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_or(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_ast r = LIB.Z3_mk_or(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_add(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_ast r = LIB.Z3_mk_add(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_mul(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_ast r = LIB.Z3_mk_mul(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_sub(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_ast r = LIB.Z3_mk_sub(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_unary_minus(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_unary_minus(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_div(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_div(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_mod(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_mod(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_rem(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_rem(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_power(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_power(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_is_algebraic_number(Z3_context a0, Z3_ast a1) { + int r = LIB.Z3_is_algebraic_number(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_algebraic_number_lower(Z3_context a0, Z3_ast a1, uint a2) { + Z3_ast r = LIB.Z3_get_algebraic_number_lower(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_algebraic_number_upper(Z3_context a0, Z3_ast a1, uint a2) { + Z3_ast r = LIB.Z3_get_algebraic_number_upper(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_lt(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_lt(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_le(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_le(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_gt(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_gt(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_ge(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_ge(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_int2real(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_int2real(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_real2int(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_real2int(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_is_int(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_is_int(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvnot(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_bvnot(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvredand(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_bvredand(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvredor(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_bvredor(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvand(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvand(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvor(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvor(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvxor(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvxor(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvnand(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvnand(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvnor(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvnor(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvxnor(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvxnor(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvneg(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_bvneg(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvadd(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvadd(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsub(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsub(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvmul(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvmul(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvudiv(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvudiv(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsdiv(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsdiv(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvurem(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvurem(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsrem(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsrem(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsmod(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsmod(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvult(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvult(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvslt(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvslt(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvule(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvule(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsle(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsle(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvuge(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvuge(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsge(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsge(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvugt(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvugt(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsgt(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsgt(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_concat(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_concat(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_extract(Z3_context a0, uint a1, uint a2, Z3_ast a3) { + Z3_ast r = LIB.Z3_mk_extract(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_sign_ext(Z3_context a0, uint a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_sign_ext(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_zero_ext(Z3_context a0, uint a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_zero_ext(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_repeat(Z3_context a0, uint a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_repeat(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvshl(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvshl(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvlshr(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvlshr(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvashr(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvashr(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_rotate_left(Z3_context a0, uint a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_rotate_left(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_rotate_right(Z3_context a0, uint a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_rotate_right(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_ext_rotate_left(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_ext_rotate_left(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_ext_rotate_right(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_ext_rotate_right(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_int2bv(Z3_context a0, uint a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_int2bv(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bv2int(Z3_context a0, Z3_ast a1, int a2) { + Z3_ast r = LIB.Z3_mk_bv2int(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvadd_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2, int a3) { + Z3_ast r = LIB.Z3_mk_bvadd_no_overflow(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvadd_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvadd_no_underflow(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsub_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsub_no_overflow(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsub_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2, int a3) { + Z3_ast r = LIB.Z3_mk_bvsub_no_underflow(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvsdiv_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvsdiv_no_overflow(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvneg_no_overflow(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_bvneg_no_overflow(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvmul_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2, int a3) { + Z3_ast r = LIB.Z3_mk_bvmul_no_overflow(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bvmul_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_bvmul_no_underflow(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_select(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_select(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_store(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_ast a3) { + Z3_ast r = LIB.Z3_mk_store(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_const_array(Z3_context a0, Z3_sort a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_const_array(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_map(Z3_context a0, Z3_func_decl a1, uint a2, [In] Z3_ast[] a3) { + Z3_ast r = LIB.Z3_mk_map(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_array_default(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_array_default(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_set_sort(Z3_context a0, Z3_sort a1) { + Z3_sort r = LIB.Z3_mk_set_sort(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_empty_set(Z3_context a0, Z3_sort a1) { + Z3_ast r = LIB.Z3_mk_empty_set(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_full_set(Z3_context a0, Z3_sort a1) { + Z3_ast r = LIB.Z3_mk_full_set(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_set_add(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_set_add(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_set_del(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_set_del(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_set_union(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_ast r = LIB.Z3_mk_set_union(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_set_intersect(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_ast r = LIB.Z3_mk_set_intersect(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_set_difference(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_set_difference(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_set_complement(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_mk_set_complement(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_set_member(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_set_member(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_set_subset(Z3_context a0, Z3_ast a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_mk_set_subset(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_numeral(Z3_context a0, string a1, Z3_sort a2) { + Z3_ast r = LIB.Z3_mk_numeral(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_real(Z3_context a0, int a1, int a2) { + Z3_ast r = LIB.Z3_mk_real(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_int(Z3_context a0, int a1, Z3_sort a2) { + Z3_ast r = LIB.Z3_mk_int(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_unsigned_int(Z3_context a0, uint a1, Z3_sort a2) { + Z3_ast r = LIB.Z3_mk_unsigned_int(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_int64(Z3_context a0, Int64 a1, Z3_sort a2) { + Z3_ast r = LIB.Z3_mk_int64(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_unsigned_int64(Z3_context a0, UInt64 a1, Z3_sort a2) { + Z3_ast r = LIB.Z3_mk_unsigned_int64(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_pattern Z3_mk_pattern(Z3_context a0, uint a1, [In] Z3_ast[] a2) { + Z3_pattern r = LIB.Z3_mk_pattern(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_bound(Z3_context a0, uint a1, Z3_sort a2) { + Z3_ast r = LIB.Z3_mk_bound(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_forall(Z3_context a0, uint a1, uint a2, [In] Z3_pattern[] a3, uint a4, [In] Z3_sort[] a5, [In] IntPtr[] a6, Z3_ast a7) { + Z3_ast r = LIB.Z3_mk_forall(a0, a1, a2, a3, a4, a5, a6, a7); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_exists(Z3_context a0, uint a1, uint a2, [In] Z3_pattern[] a3, uint a4, [In] Z3_sort[] a5, [In] IntPtr[] a6, Z3_ast a7) { + Z3_ast r = LIB.Z3_mk_exists(a0, a1, a2, a3, a4, a5, a6, a7); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_quantifier(Z3_context a0, int a1, uint a2, uint a3, [In] Z3_pattern[] a4, uint a5, [In] Z3_sort[] a6, [In] IntPtr[] a7, Z3_ast a8) { + Z3_ast r = LIB.Z3_mk_quantifier(a0, a1, a2, a3, a4, a5, a6, a7, a8); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_quantifier_ex(Z3_context a0, int a1, uint a2, IntPtr a3, IntPtr a4, uint a5, [In] Z3_pattern[] a6, uint a7, [In] Z3_ast[] a8, uint a9, [In] Z3_sort[] a10, [In] IntPtr[] a11, Z3_ast a12) { + Z3_ast r = LIB.Z3_mk_quantifier_ex(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_forall_const(Z3_context a0, uint a1, uint a2, [In] Z3_app[] a3, uint a4, [In] Z3_pattern[] a5, Z3_ast a6) { + Z3_ast r = LIB.Z3_mk_forall_const(a0, a1, a2, a3, a4, a5, a6); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_exists_const(Z3_context a0, uint a1, uint a2, [In] Z3_app[] a3, uint a4, [In] Z3_pattern[] a5, Z3_ast a6) { + Z3_ast r = LIB.Z3_mk_exists_const(a0, a1, a2, a3, a4, a5, a6); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_quantifier_const(Z3_context a0, int a1, uint a2, uint a3, [In] Z3_app[] a4, uint a5, [In] Z3_pattern[] a6, Z3_ast a7) { + Z3_ast r = LIB.Z3_mk_quantifier_const(a0, a1, a2, a3, a4, a5, a6, a7); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_mk_quantifier_const_ex(Z3_context a0, int a1, uint a2, IntPtr a3, IntPtr a4, uint a5, [In] Z3_app[] a6, uint a7, [In] Z3_pattern[] a8, uint a9, [In] Z3_ast[] a10, Z3_ast a11) { + Z3_ast r = LIB.Z3_mk_quantifier_const_ex(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_ast_id(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_ast_id(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_func_decl_id(Z3_context a0, Z3_func_decl a1) { + uint r = LIB.Z3_get_func_decl_id(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_sort_id(Z3_context a0, Z3_sort a1) { + uint r = LIB.Z3_get_sort_id(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_is_well_sorted(Z3_context a0, Z3_ast a1) { + int r = LIB.Z3_is_well_sorted(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_symbol_kind(Z3_context a0, IntPtr a1) { + uint r = LIB.Z3_get_symbol_kind(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_symbol_int(Z3_context a0, IntPtr a1) { + int r = LIB.Z3_get_symbol_int(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_get_symbol_string(Z3_context a0, IntPtr a1) { + IntPtr r = LIB.Z3_get_symbol_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static uint Z3_get_ast_kind(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_ast_kind(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_ast_hash(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_ast_hash(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_get_numeral_string(Z3_context a0, Z3_ast a1) { + IntPtr r = LIB.Z3_get_numeral_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_get_numeral_decimal_string(Z3_context a0, Z3_ast a1, uint a2) { + IntPtr r = LIB.Z3_get_numeral_decimal_string(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_ast Z3_get_numerator(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_get_numerator(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_denominator(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_get_denominator(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_numeral_small(Z3_context a0, Z3_ast a1, [In, Out] ref Int64 a2, [In, Out] ref Int64 a3) { + int r = LIB.Z3_get_numeral_small(a0, a1, ref a2, ref a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_numeral_int(Z3_context a0, Z3_ast a1, [In, Out] ref int a2) { + int r = LIB.Z3_get_numeral_int(a0, a1, ref a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_numeral_uint(Z3_context a0, Z3_ast a1, [In, Out] ref uint a2) { + int r = LIB.Z3_get_numeral_uint(a0, a1, ref a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_numeral_uint64(Z3_context a0, Z3_ast a1, [In, Out] ref UInt64 a2) { + int r = LIB.Z3_get_numeral_uint64(a0, a1, ref a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_numeral_int64(Z3_context a0, Z3_ast a1, [In, Out] ref Int64 a2) { + int r = LIB.Z3_get_numeral_int64(a0, a1, ref a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_numeral_rational_int64(Z3_context a0, Z3_ast a1, [In, Out] ref Int64 a2, [In, Out] ref Int64 a3) { + int r = LIB.Z3_get_numeral_rational_int64(a0, a1, ref a2, ref a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_bool_value(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_bool_value(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_app_decl(Z3_context a0, Z3_app a1) { + Z3_func_decl r = LIB.Z3_get_app_decl(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_app_num_args(Z3_context a0, Z3_app a1) { + uint r = LIB.Z3_get_app_num_args(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_app_arg(Z3_context a0, Z3_app a1, uint a2) { + Z3_ast r = LIB.Z3_get_app_arg(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_index_value(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_index_value(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_is_quantifier_forall(Z3_context a0, Z3_ast a1) { + int r = LIB.Z3_is_quantifier_forall(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_quantifier_weight(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_quantifier_weight(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_quantifier_num_patterns(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_quantifier_num_patterns(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_pattern Z3_get_quantifier_pattern_ast(Z3_context a0, Z3_ast a1, uint a2) { + Z3_pattern r = LIB.Z3_get_quantifier_pattern_ast(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_quantifier_num_no_patterns(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_quantifier_num_no_patterns(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_quantifier_no_pattern_ast(Z3_context a0, Z3_ast a1, uint a2) { + Z3_ast r = LIB.Z3_get_quantifier_no_pattern_ast(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static IntPtr Z3_get_quantifier_bound_name(Z3_context a0, Z3_ast a1, uint a2) { + IntPtr r = LIB.Z3_get_quantifier_bound_name(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_quantifier_bound_sort(Z3_context a0, Z3_ast a1, uint a2) { + Z3_sort r = LIB.Z3_get_quantifier_bound_sort(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_quantifier_body(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_get_quantifier_body(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_quantifier_num_bound(Z3_context a0, Z3_ast a1) { + uint r = LIB.Z3_get_quantifier_num_bound(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static IntPtr Z3_get_decl_name(Z3_context a0, Z3_func_decl a1) { + IntPtr r = LIB.Z3_get_decl_name(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_decl_num_parameters(Z3_context a0, Z3_func_decl a1) { + uint r = LIB.Z3_get_decl_num_parameters(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_decl_parameter_kind(Z3_context a0, Z3_func_decl a1, uint a2) { + uint r = LIB.Z3_get_decl_parameter_kind(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_decl_int_parameter(Z3_context a0, Z3_func_decl a1, uint a2) { + int r = LIB.Z3_get_decl_int_parameter(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static double Z3_get_decl_double_parameter(Z3_context a0, Z3_func_decl a1, uint a2) { + double r = LIB.Z3_get_decl_double_parameter(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static IntPtr Z3_get_decl_symbol_parameter(Z3_context a0, Z3_func_decl a1, uint a2) { + IntPtr r = LIB.Z3_get_decl_symbol_parameter(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_decl_sort_parameter(Z3_context a0, Z3_func_decl a1, uint a2) { + Z3_sort r = LIB.Z3_get_decl_sort_parameter(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_decl_ast_parameter(Z3_context a0, Z3_func_decl a1, uint a2) { + Z3_ast r = LIB.Z3_get_decl_ast_parameter(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_decl_func_decl_parameter(Z3_context a0, Z3_func_decl a1, uint a2) { + Z3_func_decl r = LIB.Z3_get_decl_func_decl_parameter(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_get_decl_rational_parameter(Z3_context a0, Z3_func_decl a1, uint a2) { + IntPtr r = LIB.Z3_get_decl_rational_parameter(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static IntPtr Z3_get_sort_name(Z3_context a0, Z3_sort a1) { + IntPtr r = LIB.Z3_get_sort_name(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_sort(Z3_context a0, Z3_ast a1) { + Z3_sort r = LIB.Z3_get_sort(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_domain_size(Z3_context a0, Z3_func_decl a1) { + uint r = LIB.Z3_get_domain_size(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_domain(Z3_context a0, Z3_func_decl a1, uint a2) { + Z3_sort r = LIB.Z3_get_domain(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_range(Z3_context a0, Z3_func_decl a1) { + Z3_sort r = LIB.Z3_get_range(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_sort_kind(Z3_context a0, Z3_sort a1) { + uint r = LIB.Z3_get_sort_kind(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_bv_sort_size(Z3_context a0, Z3_sort a1) { + uint r = LIB.Z3_get_bv_sort_size(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_array_sort_domain(Z3_context a0, Z3_sort a1) { + Z3_sort r = LIB.Z3_get_array_sort_domain(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_array_sort_range(Z3_context a0, Z3_sort a1) { + Z3_sort r = LIB.Z3_get_array_sort_range(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_tuple_sort_mk_decl(Z3_context a0, Z3_sort a1) { + Z3_func_decl r = LIB.Z3_get_tuple_sort_mk_decl(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_decl_kind(Z3_context a0, Z3_func_decl a1) { + uint r = LIB.Z3_get_decl_kind(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_tuple_sort_num_fields(Z3_context a0, Z3_sort a1) { + uint r = LIB.Z3_get_tuple_sort_num_fields(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_tuple_sort_field_decl(Z3_context a0, Z3_sort a1, uint a2) { + Z3_func_decl r = LIB.Z3_get_tuple_sort_field_decl(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_datatype_sort_num_constructors(Z3_context a0, Z3_sort a1) { + uint r = LIB.Z3_get_datatype_sort_num_constructors(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_datatype_sort_constructor(Z3_context a0, Z3_sort a1, uint a2) { + Z3_func_decl r = LIB.Z3_get_datatype_sort_constructor(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_datatype_sort_recognizer(Z3_context a0, Z3_sort a1, uint a2) { + Z3_func_decl r = LIB.Z3_get_datatype_sort_recognizer(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_datatype_sort_constructor_accessor(Z3_context a0, Z3_sort a1, uint a2, uint a3) { + Z3_func_decl r = LIB.Z3_get_datatype_sort_constructor_accessor(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_relation_arity(Z3_context a0, Z3_sort a1) { + uint r = LIB.Z3_get_relation_arity(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_relation_column(Z3_context a0, Z3_sort a1, uint a2) { + Z3_sort r = LIB.Z3_get_relation_column(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_get_finite_domain_sort_size(Z3_context a0, Z3_sort a1, [In, Out] ref UInt64 a2) { + int r = LIB.Z3_get_finite_domain_sort_size(a0, a1, ref a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_mk_finite_domain_sort(Z3_context a0, IntPtr a1, UInt64 a2) { + Z3_sort r = LIB.Z3_mk_finite_domain_sort(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_pattern_num_terms(Z3_context a0, Z3_pattern a1) { + uint r = LIB.Z3_get_pattern_num_terms(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_pattern(Z3_context a0, Z3_pattern a1, uint a2) { + Z3_ast r = LIB.Z3_get_pattern(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_simplify(Z3_context a0, Z3_ast a1) { + Z3_ast r = LIB.Z3_simplify(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_simplify_ex(Z3_context a0, Z3_ast a1, Z3_params a2) { + Z3_ast r = LIB.Z3_simplify_ex(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_simplify_get_help(Z3_context a0) { + IntPtr r = LIB.Z3_simplify_get_help(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_param_descrs Z3_simplify_get_param_descrs(Z3_context a0) { + Z3_param_descrs r = LIB.Z3_simplify_get_param_descrs(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_update_term(Z3_context a0, Z3_ast a1, uint a2, [In] Z3_ast[] a3) { + Z3_ast r = LIB.Z3_update_term(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_substitute(Z3_context a0, Z3_ast a1, uint a2, [In] Z3_ast[] a3, [In] Z3_ast[] a4) { + Z3_ast r = LIB.Z3_substitute(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_substitute_vars(Z3_context a0, Z3_ast a1, uint a2, [In] Z3_ast[] a3) { + Z3_ast r = LIB.Z3_substitute_vars(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_sort_to_ast(Z3_context a0, Z3_sort a1) { + Z3_ast r = LIB.Z3_sort_to_ast(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_func_decl_to_ast(Z3_context a0, Z3_func_decl a1) { + Z3_ast r = LIB.Z3_func_decl_to_ast(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_pattern_to_ast(Z3_context a0, Z3_pattern a1) { + Z3_ast r = LIB.Z3_pattern_to_ast(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_app_to_ast(Z3_context a0, Z3_app a1) { + Z3_ast r = LIB.Z3_app_to_ast(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_app Z3_to_app(Z3_context a0, Z3_ast a1) { + Z3_app r = LIB.Z3_to_app(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_to_func_decl(Z3_context a0, Z3_ast a1) { + Z3_func_decl r = LIB.Z3_to_func_decl(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_push(Z3_context a0) { + LIB.Z3_push(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_pop(Z3_context a0, uint a1) { + LIB.Z3_pop(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_get_num_scopes(Z3_context a0) { + uint r = LIB.Z3_get_num_scopes(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_persist_ast(Z3_context a0, Z3_ast a1, uint a2) { + LIB.Z3_persist_ast(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_assert_cnstr(Z3_context a0, Z3_ast a1) { + LIB.Z3_assert_cnstr(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static int Z3_check_and_get_model(Z3_context a0, [In, Out] ref Z3_model a1) { + int r = LIB.Z3_check_and_get_model(a0, ref a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_check(Z3_context a0) { + int r = LIB.Z3_check(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_check_assumptions(Z3_context a0, uint a1, [In] Z3_ast[] a2, [In, Out] ref Z3_model a3, [In, Out] ref Z3_ast a4, [In, Out] ref uint a5, [Out] Z3_ast[] a6) { + int r = LIB.Z3_check_assumptions(a0, a1, a2, ref a3, ref a4, ref a5, a6); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_implied_equalities(Z3_context a0, uint a1, [In] Z3_ast[] a2, [Out] uint[] a3) { + uint r = LIB.Z3_get_implied_equalities(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_del_model(Z3_context a0, Z3_model a1) { + LIB.Z3_del_model(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_soft_check_cancel(Z3_context a0) { + LIB.Z3_soft_check_cancel(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_get_search_failure(Z3_context a0) { + uint r = LIB.Z3_get_search_failure(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_literals Z3_get_relevant_labels(Z3_context a0) { + Z3_literals r = LIB.Z3_get_relevant_labels(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_literals Z3_get_relevant_literals(Z3_context a0) { + Z3_literals r = LIB.Z3_get_relevant_literals(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_literals Z3_get_guessed_literals(Z3_context a0) { + Z3_literals r = LIB.Z3_get_guessed_literals(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_del_literals(Z3_context a0, Z3_literals a1) { + LIB.Z3_del_literals(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_get_num_literals(Z3_context a0, Z3_literals a1) { + uint r = LIB.Z3_get_num_literals(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static IntPtr Z3_get_label_symbol(Z3_context a0, Z3_literals a1, uint a2) { + IntPtr r = LIB.Z3_get_label_symbol(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_literal(Z3_context a0, Z3_literals a1, uint a2) { + Z3_ast r = LIB.Z3_get_literal(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_disable_literal(Z3_context a0, Z3_literals a1, uint a2) { + LIB.Z3_disable_literal(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_block_literals(Z3_context a0, Z3_literals a1) { + LIB.Z3_block_literals(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_model_inc_ref(Z3_context a0, Z3_model a1) { + LIB.Z3_model_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_model_dec_ref(Z3_context a0, Z3_model a1) { + LIB.Z3_model_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_ast Z3_model_get_const_interp(Z3_context a0, Z3_model a1, Z3_func_decl a2) { + Z3_ast r = LIB.Z3_model_get_const_interp(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_interp Z3_model_get_func_interp(Z3_context a0, Z3_model a1, Z3_func_decl a2) { + Z3_func_interp r = LIB.Z3_model_get_func_interp(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_model_get_num_consts(Z3_context a0, Z3_model a1) { + uint r = LIB.Z3_model_get_num_consts(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_model_get_const_decl(Z3_context a0, Z3_model a1, uint a2) { + Z3_func_decl r = LIB.Z3_model_get_const_decl(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_model_get_num_funcs(Z3_context a0, Z3_model a1) { + uint r = LIB.Z3_model_get_num_funcs(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_model_get_func_decl(Z3_context a0, Z3_model a1, uint a2) { + Z3_func_decl r = LIB.Z3_model_get_func_decl(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_model_eval(Z3_context a0, Z3_model a1, Z3_ast a2, int a3, [In, Out] ref Z3_ast a4) { + int r = LIB.Z3_model_eval(a0, a1, a2, a3, ref a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_model_get_num_sorts(Z3_context a0, Z3_model a1) { + uint r = LIB.Z3_model_get_num_sorts(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_model_get_sort(Z3_context a0, Z3_model a1, uint a2) { + Z3_sort r = LIB.Z3_model_get_sort(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast_vector Z3_model_get_sort_universe(Z3_context a0, Z3_model a1, Z3_sort a2) { + Z3_ast_vector r = LIB.Z3_model_get_sort_universe(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_is_as_array(Z3_context a0, Z3_ast a1) { + int r = LIB.Z3_is_as_array(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_as_array_func_decl(Z3_context a0, Z3_ast a1) { + Z3_func_decl r = LIB.Z3_get_as_array_func_decl(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_func_interp_inc_ref(Z3_context a0, Z3_func_interp a1) { + LIB.Z3_func_interp_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_func_interp_dec_ref(Z3_context a0, Z3_func_interp a1) { + LIB.Z3_func_interp_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_func_interp_get_num_entries(Z3_context a0, Z3_func_interp a1) { + uint r = LIB.Z3_func_interp_get_num_entries(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_entry Z3_func_interp_get_entry(Z3_context a0, Z3_func_interp a1, uint a2) { + Z3_func_entry r = LIB.Z3_func_interp_get_entry(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_func_interp_get_else(Z3_context a0, Z3_func_interp a1) { + Z3_ast r = LIB.Z3_func_interp_get_else(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_func_interp_get_arity(Z3_context a0, Z3_func_interp a1) { + uint r = LIB.Z3_func_interp_get_arity(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_func_entry_inc_ref(Z3_context a0, Z3_func_entry a1) { + LIB.Z3_func_entry_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_func_entry_dec_ref(Z3_context a0, Z3_func_entry a1) { + LIB.Z3_func_entry_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_ast Z3_func_entry_get_value(Z3_context a0, Z3_func_entry a1) { + Z3_ast r = LIB.Z3_func_entry_get_value(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_func_entry_get_num_args(Z3_context a0, Z3_func_entry a1) { + uint r = LIB.Z3_func_entry_get_num_args(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_func_entry_get_arg(Z3_context a0, Z3_func_entry a1, uint a2) { + Z3_ast r = LIB.Z3_func_entry_get_arg(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_model_num_constants(Z3_context a0, Z3_model a1) { + uint r = LIB.Z3_get_model_num_constants(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_model_constant(Z3_context a0, Z3_model a1, uint a2) { + Z3_func_decl r = LIB.Z3_get_model_constant(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_eval_func_decl(Z3_context a0, Z3_model a1, Z3_func_decl a2, [In, Out] ref Z3_ast a3) { + int r = LIB.Z3_eval_func_decl(a0, a1, a2, ref a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_is_array_value(Z3_context a0, Z3_model a1, Z3_ast a2, [In, Out] ref uint a3) { + int r = LIB.Z3_is_array_value(a0, a1, a2, ref a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_get_array_value(Z3_context a0, Z3_model a1, Z3_ast a2, uint a3, [Out] Z3_ast[] a4, [Out] Z3_ast[] a5, [In, Out] ref Z3_ast a6) { + LIB.Z3_get_array_value(a0, a1, a2, a3, a4, a5, ref a6); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_get_model_num_funcs(Z3_context a0, Z3_model a1) { + uint r = LIB.Z3_get_model_num_funcs(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_model_func_decl(Z3_context a0, Z3_model a1, uint a2) { + Z3_func_decl r = LIB.Z3_get_model_func_decl(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_model_func_else(Z3_context a0, Z3_model a1, uint a2) { + Z3_ast r = LIB.Z3_get_model_func_else(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_model_func_num_entries(Z3_context a0, Z3_model a1, uint a2) { + uint r = LIB.Z3_get_model_func_num_entries(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_model_func_entry_num_args(Z3_context a0, Z3_model a1, uint a2, uint a3) { + uint r = LIB.Z3_get_model_func_entry_num_args(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_model_func_entry_arg(Z3_context a0, Z3_model a1, uint a2, uint a3, uint a4) { + Z3_ast r = LIB.Z3_get_model_func_entry_arg(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_model_func_entry_value(Z3_context a0, Z3_model a1, uint a2, uint a3) { + Z3_ast r = LIB.Z3_get_model_func_entry_value(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_eval(Z3_context a0, Z3_model a1, Z3_ast a2, [In, Out] ref Z3_ast a3) { + int r = LIB.Z3_eval(a0, a1, a2, ref a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_eval_decl(Z3_context a0, Z3_model a1, Z3_func_decl a2, uint a3, [In] Z3_ast[] a4, [In, Out] ref Z3_ast a5) { + int r = LIB.Z3_eval_decl(a0, a1, a2, a3, a4, ref a5); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_set_ast_print_mode(Z3_context a0, uint a1) { + LIB.Z3_set_ast_print_mode(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static string Z3_ast_to_string(Z3_context a0, Z3_ast a1) { + IntPtr r = LIB.Z3_ast_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_pattern_to_string(Z3_context a0, Z3_pattern a1) { + IntPtr r = LIB.Z3_pattern_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_sort_to_string(Z3_context a0, Z3_sort a1) { + IntPtr r = LIB.Z3_sort_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_func_decl_to_string(Z3_context a0, Z3_func_decl a1) { + IntPtr r = LIB.Z3_func_decl_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_model_to_string(Z3_context a0, Z3_model a1) { + IntPtr r = LIB.Z3_model_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_benchmark_to_smtlib_string(Z3_context a0, string a1, string a2, string a3, string a4, uint a5, [In] Z3_ast[] a6, Z3_ast a7) { + IntPtr r = LIB.Z3_benchmark_to_smtlib_string(a0, a1, a2, a3, a4, a5, a6, a7); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_context_to_string(Z3_context a0) { + IntPtr r = LIB.Z3_context_to_string(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_statistics_to_string(Z3_context a0) { + IntPtr r = LIB.Z3_statistics_to_string(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_ast Z3_get_context_assignment(Z3_context a0) { + Z3_ast r = LIB.Z3_get_context_assignment(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_parse_smtlib_string(Z3_context a0, string a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, uint a5, [In] IntPtr[] a6, [In] Z3_func_decl[] a7) { + LIB.Z3_parse_smtlib_string(a0, a1, a2, a3, a4, a5, a6, a7); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_parse_smtlib_file(Z3_context a0, string a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, uint a5, [In] IntPtr[] a6, [In] Z3_func_decl[] a7) { + LIB.Z3_parse_smtlib_file(a0, a1, a2, a3, a4, a5, a6, a7); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_get_smtlib_num_formulas(Z3_context a0) { + uint r = LIB.Z3_get_smtlib_num_formulas(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_smtlib_formula(Z3_context a0, uint a1) { + Z3_ast r = LIB.Z3_get_smtlib_formula(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_smtlib_num_assumptions(Z3_context a0) { + uint r = LIB.Z3_get_smtlib_num_assumptions(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_get_smtlib_assumption(Z3_context a0, uint a1) { + Z3_ast r = LIB.Z3_get_smtlib_assumption(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_smtlib_num_decls(Z3_context a0) { + uint r = LIB.Z3_get_smtlib_num_decls(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_get_smtlib_decl(Z3_context a0, uint a1) { + Z3_func_decl r = LIB.Z3_get_smtlib_decl(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_smtlib_num_sorts(Z3_context a0) { + uint r = LIB.Z3_get_smtlib_num_sorts(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_sort Z3_get_smtlib_sort(Z3_context a0, uint a1) { + Z3_sort r = LIB.Z3_get_smtlib_sort(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_get_smtlib_error(Z3_context a0) { + IntPtr r = LIB.Z3_get_smtlib_error(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_ast Z3_parse_z3_string(Z3_context a0, string a1) { + Z3_ast r = LIB.Z3_parse_z3_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_parse_z3_file(Z3_context a0, string a1) { + Z3_ast r = LIB.Z3_parse_z3_file(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_parse_smtlib2_string(Z3_context a0, string a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, uint a5, [In] IntPtr[] a6, [In] Z3_func_decl[] a7) { + Z3_ast r = LIB.Z3_parse_smtlib2_string(a0, a1, a2, a3, a4, a5, a6, a7); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_parse_smtlib2_file(Z3_context a0, string a1, uint a2, [In] IntPtr[] a3, [In] Z3_sort[] a4, uint a5, [In] IntPtr[] a6, [In] Z3_func_decl[] a7) { + Z3_ast r = LIB.Z3_parse_smtlib2_file(a0, a1, a2, a3, a4, a5, a6, a7); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_error_code(Z3_context a0) { + uint r = LIB.Z3_get_error_code(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_set_error(Z3_context a0, uint a1) { + LIB.Z3_set_error(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static string Z3_get_error_msg(uint a0) { + IntPtr r = LIB.Z3_get_error_msg(a0); + return Marshal.PtrToStringAnsi(r); + } + + public static void Z3_get_version([In, Out] ref uint a0, [In, Out] ref uint a1, [In, Out] ref uint a2, [In, Out] ref uint a3) { + LIB.Z3_get_version(ref a0, ref a1, ref a2, ref a3); + } + + public static void Z3_reset_memory() { + LIB.Z3_reset_memory(); + } + + public static int Z3_is_app(Z3_context a0, Z3_ast a1) { + int r = LIB.Z3_is_app(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_is_numeral_ast(Z3_context a0, Z3_ast a1) { + int r = LIB.Z3_is_numeral_ast(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_arity(Z3_context a0, Z3_func_decl a1) { + uint r = LIB.Z3_get_arity(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_func_decl Z3_mk_injective_function(Z3_context a0, IntPtr a1, uint a2, [In] Z3_sort[] a3, Z3_sort a4) { + Z3_func_decl r = LIB.Z3_mk_injective_function(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_fixedpoint Z3_mk_fixedpoint(Z3_context a0) { + Z3_fixedpoint r = LIB.Z3_mk_fixedpoint(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_fixedpoint_inc_ref(Z3_context a0, Z3_fixedpoint a1) { + LIB.Z3_fixedpoint_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_fixedpoint_dec_ref(Z3_context a0, Z3_fixedpoint a1) { + LIB.Z3_fixedpoint_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_fixedpoint_push(Z3_context a0, Z3_fixedpoint a1) { + LIB.Z3_fixedpoint_push(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_fixedpoint_pop(Z3_context a0, Z3_fixedpoint a1) { + LIB.Z3_fixedpoint_pop(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_fixedpoint_register_relation(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2) { + LIB.Z3_fixedpoint_register_relation(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_fixedpoint_assert(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2) { + LIB.Z3_fixedpoint_assert(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_fixedpoint_add_rule(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2, IntPtr a3) { + LIB.Z3_fixedpoint_add_rule(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_fixedpoint_add_fact(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2, uint a3, [In] uint[] a4) { + LIB.Z3_fixedpoint_add_fact(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static int Z3_fixedpoint_query(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2) { + int r = LIB.Z3_fixedpoint_query(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_fixedpoint_query_relations(Z3_context a0, Z3_fixedpoint a1, uint a2, [In] Z3_func_decl[] a3) { + int r = LIB.Z3_fixedpoint_query_relations(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_fixedpoint_get_answer(Z3_context a0, Z3_fixedpoint a1) { + Z3_ast r = LIB.Z3_fixedpoint_get_answer(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_fixedpoint_update_rule(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2, IntPtr a3) { + LIB.Z3_fixedpoint_update_rule(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_fixedpoint_get_num_levels(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2) { + uint r = LIB.Z3_fixedpoint_get_num_levels(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_fixedpoint_get_cover_delta(Z3_context a0, Z3_fixedpoint a1, int a2, Z3_func_decl a3) { + Z3_ast r = LIB.Z3_fixedpoint_get_cover_delta(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_fixedpoint_add_cover(Z3_context a0, Z3_fixedpoint a1, int a2, Z3_func_decl a3, Z3_ast a4) { + LIB.Z3_fixedpoint_add_cover(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_stats Z3_fixedpoint_get_statistics(Z3_context a0, Z3_fixedpoint a1) { + Z3_stats r = LIB.Z3_fixedpoint_get_statistics(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_fixedpoint_get_help(Z3_context a0, Z3_fixedpoint a1) { + IntPtr r = LIB.Z3_fixedpoint_get_help(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_param_descrs Z3_fixedpoint_get_param_descrs(Z3_context a0, Z3_fixedpoint a1) { + Z3_param_descrs r = LIB.Z3_fixedpoint_get_param_descrs(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_fixedpoint_set_params(Z3_context a0, Z3_fixedpoint a1, Z3_params a2) { + LIB.Z3_fixedpoint_set_params(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static string Z3_fixedpoint_to_string(Z3_context a0, Z3_fixedpoint a1, uint a2, [In] Z3_ast[] a3) { + IntPtr r = LIB.Z3_fixedpoint_to_string(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_fixedpoint_get_reason_unknown(Z3_context a0, Z3_fixedpoint a1) { + IntPtr r = LIB.Z3_fixedpoint_get_reason_unknown(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static void Z3_fixedpoint_set_predicate_representation(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2, uint a3, [In] IntPtr[] a4) { + LIB.Z3_fixedpoint_set_predicate_representation(a0, a1, a2, a3, a4); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_ast_vector Z3_fixedpoint_simplify_rules(Z3_context a0, Z3_fixedpoint a1, uint a2, [In] Z3_ast[] a3, uint a4, [In] Z3_func_decl[] a5) { + Z3_ast_vector r = LIB.Z3_fixedpoint_simplify_rules(a0, a1, a2, a3, a4, a5); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_params Z3_mk_params(Z3_context a0) { + Z3_params r = LIB.Z3_mk_params(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_params_inc_ref(Z3_context a0, Z3_params a1) { + LIB.Z3_params_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_params_dec_ref(Z3_context a0, Z3_params a1) { + LIB.Z3_params_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_params_set_bool(Z3_context a0, Z3_params a1, IntPtr a2, int a3) { + LIB.Z3_params_set_bool(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_params_set_uint(Z3_context a0, Z3_params a1, IntPtr a2, uint a3) { + LIB.Z3_params_set_uint(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_params_set_double(Z3_context a0, Z3_params a1, IntPtr a2, double a3) { + LIB.Z3_params_set_double(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_params_set_symbol(Z3_context a0, Z3_params a1, IntPtr a2, IntPtr a3) { + LIB.Z3_params_set_symbol(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static string Z3_params_to_string(Z3_context a0, Z3_params a1) { + IntPtr r = LIB.Z3_params_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static void Z3_params_validate(Z3_context a0, Z3_params a1, Z3_param_descrs a2) { + LIB.Z3_params_validate(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_param_descrs_inc_ref(Z3_context a0, Z3_param_descrs a1) { + LIB.Z3_param_descrs_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_param_descrs_dec_ref(Z3_context a0, Z3_param_descrs a1) { + LIB.Z3_param_descrs_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_param_descrs_get_kind(Z3_context a0, Z3_param_descrs a1, IntPtr a2) { + uint r = LIB.Z3_param_descrs_get_kind(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_param_descrs_size(Z3_context a0, Z3_param_descrs a1) { + uint r = LIB.Z3_param_descrs_size(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static IntPtr Z3_param_descrs_get_name(Z3_context a0, Z3_param_descrs a1, uint a2) { + IntPtr r = LIB.Z3_param_descrs_get_name(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_interrupt(Z3_context a0) { + LIB.Z3_interrupt(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static string Z3_get_error_msg_ex(Z3_context a0, uint a1) { + IntPtr r = LIB.Z3_get_error_msg_ex(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_ast Z3_translate(Z3_context a0, Z3_ast a1, Z3_context a2) { + Z3_ast r = LIB.Z3_translate(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_goal Z3_mk_goal(Z3_context a0, int a1, int a2, int a3) { + Z3_goal r = LIB.Z3_mk_goal(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_goal_inc_ref(Z3_context a0, Z3_goal a1) { + LIB.Z3_goal_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_goal_dec_ref(Z3_context a0, Z3_goal a1) { + LIB.Z3_goal_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_goal_precision(Z3_context a0, Z3_goal a1) { + uint r = LIB.Z3_goal_precision(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_goal_assert(Z3_context a0, Z3_goal a1, Z3_ast a2) { + LIB.Z3_goal_assert(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static int Z3_goal_inconsistent(Z3_context a0, Z3_goal a1) { + int r = LIB.Z3_goal_inconsistent(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_goal_depth(Z3_context a0, Z3_goal a1) { + uint r = LIB.Z3_goal_depth(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_goal_reset(Z3_context a0, Z3_goal a1) { + LIB.Z3_goal_reset(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_goal_size(Z3_context a0, Z3_goal a1) { + uint r = LIB.Z3_goal_size(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_goal_formula(Z3_context a0, Z3_goal a1, uint a2) { + Z3_ast r = LIB.Z3_goal_formula(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_goal_num_exprs(Z3_context a0, Z3_goal a1) { + uint r = LIB.Z3_goal_num_exprs(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_goal_is_decided_sat(Z3_context a0, Z3_goal a1) { + int r = LIB.Z3_goal_is_decided_sat(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_goal_is_decided_unsat(Z3_context a0, Z3_goal a1) { + int r = LIB.Z3_goal_is_decided_unsat(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_goal Z3_goal_translate(Z3_context a0, Z3_goal a1, Z3_context a2) { + Z3_goal r = LIB.Z3_goal_translate(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_goal_to_string(Z3_context a0, Z3_goal a1) { + IntPtr r = LIB.Z3_goal_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_tactic Z3_mk_tactic(Z3_context a0, string a1) { + Z3_tactic r = LIB.Z3_mk_tactic(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_mk_probe(Z3_context a0, string a1) { + Z3_probe r = LIB.Z3_mk_probe(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_tactic_inc_ref(Z3_context a0, Z3_tactic a1) { + LIB.Z3_tactic_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_tactic_dec_ref(Z3_context a0, Z3_tactic a1) { + LIB.Z3_tactic_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_probe_inc_ref(Z3_context a0, Z3_probe a1) { + LIB.Z3_probe_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_probe_dec_ref(Z3_context a0, Z3_probe a1) { + LIB.Z3_probe_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_tactic Z3_tactic_and_then(Z3_context a0, Z3_tactic a1, Z3_tactic a2) { + Z3_tactic r = LIB.Z3_tactic_and_then(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_or_else(Z3_context a0, Z3_tactic a1, Z3_tactic a2) { + Z3_tactic r = LIB.Z3_tactic_or_else(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_par_or(Z3_context a0, uint a1, [In] Z3_tactic[] a2) { + Z3_tactic r = LIB.Z3_tactic_par_or(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_par_and_then(Z3_context a0, Z3_tactic a1, Z3_tactic a2) { + Z3_tactic r = LIB.Z3_tactic_par_and_then(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_try_for(Z3_context a0, Z3_tactic a1, uint a2) { + Z3_tactic r = LIB.Z3_tactic_try_for(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_when(Z3_context a0, Z3_probe a1, Z3_tactic a2) { + Z3_tactic r = LIB.Z3_tactic_when(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_cond(Z3_context a0, Z3_probe a1, Z3_tactic a2, Z3_tactic a3) { + Z3_tactic r = LIB.Z3_tactic_cond(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_repeat(Z3_context a0, Z3_tactic a1, uint a2) { + Z3_tactic r = LIB.Z3_tactic_repeat(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_skip(Z3_context a0) { + Z3_tactic r = LIB.Z3_tactic_skip(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_fail(Z3_context a0) { + Z3_tactic r = LIB.Z3_tactic_fail(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_fail_if(Z3_context a0, Z3_probe a1) { + Z3_tactic r = LIB.Z3_tactic_fail_if(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_fail_if_not_decided(Z3_context a0) { + Z3_tactic r = LIB.Z3_tactic_fail_if_not_decided(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_tactic Z3_tactic_using_params(Z3_context a0, Z3_tactic a1, Z3_params a2) { + Z3_tactic r = LIB.Z3_tactic_using_params(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_const(Z3_context a0, double a1) { + Z3_probe r = LIB.Z3_probe_const(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_lt(Z3_context a0, Z3_probe a1, Z3_probe a2) { + Z3_probe r = LIB.Z3_probe_lt(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_le(Z3_context a0, Z3_probe a1, Z3_probe a2) { + Z3_probe r = LIB.Z3_probe_le(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_gt(Z3_context a0, Z3_probe a1, Z3_probe a2) { + Z3_probe r = LIB.Z3_probe_gt(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_ge(Z3_context a0, Z3_probe a1, Z3_probe a2) { + Z3_probe r = LIB.Z3_probe_ge(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_eq(Z3_context a0, Z3_probe a1, Z3_probe a2) { + Z3_probe r = LIB.Z3_probe_eq(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_and(Z3_context a0, Z3_probe a1, Z3_probe a2) { + Z3_probe r = LIB.Z3_probe_and(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_or(Z3_context a0, Z3_probe a1, Z3_probe a2) { + Z3_probe r = LIB.Z3_probe_or(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_probe Z3_probe_not(Z3_context a0, Z3_probe a1) { + Z3_probe r = LIB.Z3_probe_not(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_get_num_tactics(Z3_context a0) { + uint r = LIB.Z3_get_num_tactics(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_get_tactic_name(Z3_context a0, uint a1) { + IntPtr r = LIB.Z3_get_tactic_name(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static uint Z3_get_num_probes(Z3_context a0) { + uint r = LIB.Z3_get_num_probes(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_get_probe_name(Z3_context a0, uint a1) { + IntPtr r = LIB.Z3_get_probe_name(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_tactic_get_help(Z3_context a0, Z3_tactic a1) { + IntPtr r = LIB.Z3_tactic_get_help(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_param_descrs Z3_tactic_get_param_descrs(Z3_context a0, Z3_tactic a1) { + Z3_param_descrs r = LIB.Z3_tactic_get_param_descrs(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_tactic_get_descr(Z3_context a0, string a1) { + IntPtr r = LIB.Z3_tactic_get_descr(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_probe_get_descr(Z3_context a0, string a1) { + IntPtr r = LIB.Z3_probe_get_descr(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static double Z3_probe_apply(Z3_context a0, Z3_probe a1, Z3_goal a2) { + double r = LIB.Z3_probe_apply(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_apply_result Z3_tactic_apply(Z3_context a0, Z3_tactic a1, Z3_goal a2) { + Z3_apply_result r = LIB.Z3_tactic_apply(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_apply_result Z3_tactic_apply_ex(Z3_context a0, Z3_tactic a1, Z3_goal a2, Z3_params a3) { + Z3_apply_result r = LIB.Z3_tactic_apply_ex(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_apply_result_inc_ref(Z3_context a0, Z3_apply_result a1) { + LIB.Z3_apply_result_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_apply_result_dec_ref(Z3_context a0, Z3_apply_result a1) { + LIB.Z3_apply_result_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static string Z3_apply_result_to_string(Z3_context a0, Z3_apply_result a1) { + IntPtr r = LIB.Z3_apply_result_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static uint Z3_apply_result_get_num_subgoals(Z3_context a0, Z3_apply_result a1) { + uint r = LIB.Z3_apply_result_get_num_subgoals(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_goal Z3_apply_result_get_subgoal(Z3_context a0, Z3_apply_result a1, uint a2) { + Z3_goal r = LIB.Z3_apply_result_get_subgoal(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_model Z3_apply_result_convert_model(Z3_context a0, Z3_apply_result a1, uint a2, Z3_model a3) { + Z3_model r = LIB.Z3_apply_result_convert_model(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_solver Z3_mk_solver(Z3_context a0) { + Z3_solver r = LIB.Z3_mk_solver(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_solver Z3_mk_simple_solver(Z3_context a0) { + Z3_solver r = LIB.Z3_mk_simple_solver(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_solver Z3_mk_solver_for_logic(Z3_context a0, IntPtr a1) { + Z3_solver r = LIB.Z3_mk_solver_for_logic(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_solver Z3_mk_solver_from_tactic(Z3_context a0, Z3_tactic a1) { + Z3_solver r = LIB.Z3_mk_solver_from_tactic(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_solver_get_help(Z3_context a0, Z3_solver a1) { + IntPtr r = LIB.Z3_solver_get_help(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_param_descrs Z3_solver_get_param_descrs(Z3_context a0, Z3_solver a1) { + Z3_param_descrs r = LIB.Z3_solver_get_param_descrs(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_solver_set_params(Z3_context a0, Z3_solver a1, Z3_params a2) { + LIB.Z3_solver_set_params(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_solver_inc_ref(Z3_context a0, Z3_solver a1) { + LIB.Z3_solver_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_solver_dec_ref(Z3_context a0, Z3_solver a1) { + LIB.Z3_solver_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_solver_push(Z3_context a0, Z3_solver a1) { + LIB.Z3_solver_push(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_solver_pop(Z3_context a0, Z3_solver a1, uint a2) { + LIB.Z3_solver_pop(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_solver_reset(Z3_context a0, Z3_solver a1) { + LIB.Z3_solver_reset(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_solver_get_num_scopes(Z3_context a0, Z3_solver a1) { + uint r = LIB.Z3_solver_get_num_scopes(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_solver_assert(Z3_context a0, Z3_solver a1, Z3_ast a2) { + LIB.Z3_solver_assert(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_ast_vector Z3_solver_get_assertions(Z3_context a0, Z3_solver a1) { + Z3_ast_vector r = LIB.Z3_solver_get_assertions(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_solver_check(Z3_context a0, Z3_solver a1) { + int r = LIB.Z3_solver_check(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_solver_check_assumptions(Z3_context a0, Z3_solver a1, uint a2, [In] Z3_ast[] a3) { + int r = LIB.Z3_solver_check_assumptions(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_model Z3_solver_get_model(Z3_context a0, Z3_solver a1) { + Z3_model r = LIB.Z3_solver_get_model(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_solver_get_proof(Z3_context a0, Z3_solver a1) { + Z3_ast r = LIB.Z3_solver_get_proof(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast_vector Z3_solver_get_unsat_core(Z3_context a0, Z3_solver a1) { + Z3_ast_vector r = LIB.Z3_solver_get_unsat_core(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_solver_get_reason_unknown(Z3_context a0, Z3_solver a1) { + IntPtr r = LIB.Z3_solver_get_reason_unknown(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_stats Z3_solver_get_statistics(Z3_context a0, Z3_solver a1) { + Z3_stats r = LIB.Z3_solver_get_statistics(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_solver_to_string(Z3_context a0, Z3_solver a1) { + IntPtr r = LIB.Z3_solver_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static string Z3_stats_to_string(Z3_context a0, Z3_stats a1) { + IntPtr r = LIB.Z3_stats_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static void Z3_stats_inc_ref(Z3_context a0, Z3_stats a1) { + LIB.Z3_stats_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_stats_dec_ref(Z3_context a0, Z3_stats a1) { + LIB.Z3_stats_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_stats_size(Z3_context a0, Z3_stats a1) { + uint r = LIB.Z3_stats_size(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_stats_get_key(Z3_context a0, Z3_stats a1, uint a2) { + IntPtr r = LIB.Z3_stats_get_key(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static int Z3_stats_is_uint(Z3_context a0, Z3_stats a1, uint a2) { + int r = LIB.Z3_stats_is_uint(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static int Z3_stats_is_double(Z3_context a0, Z3_stats a1, uint a2) { + int r = LIB.Z3_stats_is_double(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static uint Z3_stats_get_uint_value(Z3_context a0, Z3_stats a1, uint a2) { + uint r = LIB.Z3_stats_get_uint_value(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static double Z3_stats_get_double_value(Z3_context a0, Z3_stats a1, uint a2) { + double r = LIB.Z3_stats_get_double_value(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast_vector Z3_mk_ast_vector(Z3_context a0) { + Z3_ast_vector r = LIB.Z3_mk_ast_vector(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_ast_vector_inc_ref(Z3_context a0, Z3_ast_vector a1) { + LIB.Z3_ast_vector_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_ast_vector_dec_ref(Z3_context a0, Z3_ast_vector a1) { + LIB.Z3_ast_vector_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_ast_vector_size(Z3_context a0, Z3_ast_vector a1) { + uint r = LIB.Z3_ast_vector_size(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_ast_vector_get(Z3_context a0, Z3_ast_vector a1, uint a2) { + Z3_ast r = LIB.Z3_ast_vector_get(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_ast_vector_set(Z3_context a0, Z3_ast_vector a1, uint a2, Z3_ast a3) { + LIB.Z3_ast_vector_set(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_ast_vector_resize(Z3_context a0, Z3_ast_vector a1, uint a2) { + LIB.Z3_ast_vector_resize(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_ast_vector_push(Z3_context a0, Z3_ast_vector a1, Z3_ast a2) { + LIB.Z3_ast_vector_push(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_ast_vector Z3_ast_vector_translate(Z3_context a0, Z3_ast_vector a1, Z3_context a2) { + Z3_ast_vector r = LIB.Z3_ast_vector_translate(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_ast_vector_to_string(Z3_context a0, Z3_ast_vector a1) { + IntPtr r = LIB.Z3_ast_vector_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static Z3_ast_map Z3_mk_ast_map(Z3_context a0) { + Z3_ast_map r = LIB.Z3_mk_ast_map(a0); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_ast_map_inc_ref(Z3_context a0, Z3_ast_map a1) { + LIB.Z3_ast_map_inc_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_ast_map_dec_ref(Z3_context a0, Z3_ast_map a1) { + LIB.Z3_ast_map_dec_ref(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static int Z3_ast_map_contains(Z3_context a0, Z3_ast_map a1, Z3_ast a2) { + int r = LIB.Z3_ast_map_contains(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static Z3_ast Z3_ast_map_find(Z3_context a0, Z3_ast_map a1, Z3_ast a2) { + Z3_ast r = LIB.Z3_ast_map_find(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_ast_map_insert(Z3_context a0, Z3_ast_map a1, Z3_ast a2, Z3_ast a3) { + LIB.Z3_ast_map_insert(a0, a1, a2, a3); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static void Z3_ast_map_erase(Z3_context a0, Z3_ast_map a1, Z3_ast a2) { + LIB.Z3_ast_map_erase(a0, a1, a2); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static uint Z3_ast_map_size(Z3_context a0, Z3_ast_map a1) { + uint r = LIB.Z3_ast_map_size(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static void Z3_ast_map_reset(Z3_context a0, Z3_ast_map a1) { + LIB.Z3_ast_map_reset(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + } + + public static Z3_ast_vector Z3_ast_map_keys(Z3_context a0, Z3_ast_map a1) { + Z3_ast_vector r = LIB.Z3_ast_map_keys(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return r; + } + + public static string Z3_ast_map_to_string(Z3_context a0, Z3_ast_map a1) { + IntPtr r = LIB.Z3_ast_map_to_string(a0, a1); + Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0); + if (err != Z3_error_code.Z3_OK) + throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err))); + return Marshal.PtrToStringAnsi(r); + } + + public static int Z3_open_log(string a0) { + int r = LIB.Z3_open_log(a0); + return r; + } + + public static void Z3_append_log(string a0) { + LIB.Z3_append_log(a0); + } + + public static void Z3_close_log() { + LIB.Z3_close_log(); + } + + } + +} + diff --git a/Microsoft.Z3/Numeral.cs b/Microsoft.Z3/Numeral.cs new file mode 100644 index 000000000..fb8af747b --- /dev/null +++ b/Microsoft.Z3/Numeral.cs @@ -0,0 +1,344 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Numeral.cs + +Abstract: + + Z3 Managed API: Numerals + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-20 + +Notes: + +--*/ +using System; +using System.Diagnostics.Contracts; + +#if !FRAMEWORK_LT_4 +using System.Numerics; +#endif + +namespace Microsoft.Z3 +{ + /// + /// Integer Numerals + /// + [ContractVerification(true)] + public class IntNum : IntExpr + { + + #region Internal + internal IntNum(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + + + /// + /// Retrieve the 64-bit unsigned integer value. + /// + public UInt64 UInt64 + { + get + { + UInt64 res = 0; + if (Native.Z3_get_numeral_uint64(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Numeral is not a 64 bit unsigned"); + return res; + } + } + + /// + /// Retrieve the int value. + /// + public int Int + { + get + { + int res = 0; + if (Native.Z3_get_numeral_int(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Numeral is not an int"); + return res; + } + } + + /// + /// Retrieve the 64-bit int value. + /// + public Int64 Int64 + { + get + { + Int64 res = 0; + if (Native.Z3_get_numeral_int64(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Numeral is not an int64"); + return res; + } + } + + /// + /// Retrieve the int value. + /// + public uint UInt + { + get + { + uint res = 0; + if (Native.Z3_get_numeral_uint(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Numeral is not a uint"); + return res; + } + } + +#if !FRAMEWORK_LT_4 + /// + /// Retrieve the BigInteger value. + /// + public BigInteger BigInteger + { + get + { + return BigInteger.Parse(this.ToString()); + } + } +#endif + + /// + /// Returns a string representation of the numeral. + /// + public override string ToString() + { + return Native.Z3_get_numeral_string(Context.nCtx, NativeObject); + } + } + + /// + /// Rational Numerals + /// + [ContractVerification(true)] + public class RatNum : RealExpr + { + /// + /// The numerator of a rational numeral. + /// + public IntNum Numerator + { + get { + Contract.Ensures(Contract.Result() != null); + + return new IntNum(Context, Native.Z3_get_numerator(Context.nCtx, NativeObject)); } + } + + /// + /// The denominator of a rational numeral. + /// + public IntNum Denominator + { + get { + Contract.Ensures(Contract.Result() != null); + + return new IntNum(Context, Native.Z3_get_denominator(Context.nCtx, NativeObject)); } + } + +#if !FRAMEWORK_LT_4 + /// + /// Converts the numerator of the rational to a BigInteger + /// + public BigInteger BigIntNumerator + { + get + { + IntNum n = Numerator; + return BigInteger.Parse(n.ToString()); + } + } + + /// + /// Converts the denominator of the rational to a BigInteger + /// + public BigInteger BigIntDenominator + { + get + { + IntNum n = Denominator; + return BigInteger.Parse(n.ToString()); + } + } +#endif + + /// + /// Returns a string representation in decimal notation. + /// + /// The result has at most decimal places. + public string ToDecimalString(uint precision) + { + return Native.Z3_get_numeral_decimal_string(Context.nCtx, NativeObject, precision); + } + + /// + /// Returns a string representation of the numeral. + /// + public override string ToString() + { + return Native.Z3_get_numeral_string(Context.nCtx, NativeObject); + } + + #region Internal + internal RatNum(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } + + + /// + /// Bit-vector numerals + /// + [ContractVerification(true)] + public class BitVecNum : BitVecExpr + { + /// + /// Retrieve the 64-bit unsigned integer value. + /// + public UInt64 UInt64 + { + get + { + UInt64 res = 0; + if (Native.Z3_get_numeral_uint64(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Numeral is not a 64 bit unsigned"); + return res; + } + } + + /// + /// Retrieve the int value. + /// + public int Int + { + get + { + int res = 0; + if (Native.Z3_get_numeral_int(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Numeral is not an int"); + return res; + } + } + + /// + /// Retrieve the 64-bit int value. + /// + public Int64 Int64 + { + get + { + Int64 res = 0; + if (Native.Z3_get_numeral_int64(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Numeral is not an int64"); + return res; + } + } + + /// + /// Retrieve the int value. + /// + public uint UInt + { + get + { + uint res = 0; + if (Native.Z3_get_numeral_uint(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Numeral is not a uint"); + return res; + } + } + +#if !FRAMEWORK_LT_4 + /// + /// Retrieve the BigInteger value. + /// + public BigInteger BigInteger + { + get + { + return BigInteger.Parse(this.ToString()); + } + } +#endif + + /// + /// Returns a string representation of the numeral. + /// + public override string ToString() + { + return Native.Z3_get_numeral_string(Context.nCtx, NativeObject); + } + + #region Internal + internal BitVecNum(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + #endregion + } + + /// + /// Algebraic numbers + /// + [ContractVerification(true)] + public class AlgebraicNum : ArithExpr + { + /// + /// Return a upper bound for a given real algebraic number. + /// The interval isolating the number is smaller than 1/10^. + /// + /// + /// the precision of the result + /// A numeral Expr of sort Real + public RatNum ToUpper(uint precision) + { + Contract.Ensures(Contract.Result() != null); + + return new RatNum(Context, Native.Z3_get_algebraic_number_upper(Context.nCtx, NativeObject, precision)); + } + + /// + /// Return a lower bound for the given real algebraic number. + /// The interval isolating the number is smaller than 1/10^. + /// + /// + /// + /// A numeral Expr of sort Real + public RatNum ToLower(uint precision) + { + Contract.Ensures(Contract.Result() != null); + + return new RatNum(Context, Native.Z3_get_algebraic_number_lower(Context.nCtx, NativeObject, precision)); + } + + /// + /// Returns a string representation in decimal notation. + /// + /// The result has at most decimal places. + public string ToDecimal(uint precision) + { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_get_numeral_decimal_string(Context.nCtx, NativeObject, precision); + } + + #region Internal + internal AlgebraicNum(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } +} diff --git a/Microsoft.Z3/ParamDescrs.cs b/Microsoft.Z3/ParamDescrs.cs new file mode 100644 index 000000000..f93d449a4 --- /dev/null +++ b/Microsoft.Z3/ParamDescrs.cs @@ -0,0 +1,98 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Parameter.cs + +Abstract: + + Z3 Managed API: Parameter Descriptions + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-20 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// A ParameterSet represents a configuration in the form of Symbol/value pairs. + /// + [ContractVerification(true)] + public class ParamDescrs : Z3Object + { + /// + /// validate a set of parameters. + /// + public void Validate(Params p) + { + Contract.Requires(p != null); + Native.Z3_params_validate(Context.nCtx, p.NativeObject, NativeObject); + } + + /// + /// Retrieve kind of parameter. + /// + public Z3_param_kind GetKind(Symbol name) + { + Contract.Requires(name != null); + return (Z3_param_kind)Native.Z3_param_descrs_get_kind(Context.nCtx, NativeObject, name.NativeObject); + } + + /// + /// Retrieve all names of parameters. + /// + public Symbol[] Names + { + get + { + uint sz = Native.Z3_param_descrs_size(Context.nCtx, NativeObject); + Symbol[] names = new Symbol[sz]; + for (uint i = 0; i < sz; ++i) { + names[i] = Symbol.Create(Context, Native.Z3_param_descrs_get_name(Context.nCtx, NativeObject, i)); + } + return names; + } + } + + #region Internal + internal ParamDescrs(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_param_descrs_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_param_descrs_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.ParamDescrs_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.ParamDescrs_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Params.cs b/Microsoft.Z3/Params.cs new file mode 100644 index 000000000..babe46a74 --- /dev/null +++ b/Microsoft.Z3/Params.cs @@ -0,0 +1,147 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Parameter.cs + +Abstract: + + Z3 Managed API: Parameters + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-20 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// A ParameterSet represents a configuration in the form of Symbol/value pairs. + /// + [ContractVerification(true)] + public class Params : Z3Object + { + /// + /// Adds a parameter setting. + /// + public void Add(Symbol name, bool value) + { + Contract.Requires(name != null); + + Native.Z3_params_set_bool(Context.nCtx, NativeObject, name.NativeObject, (value) ? 1 : 0); + } + + /// + /// Adds a parameter setting. + /// + public void Add(Symbol name, uint value) + { + Contract.Requires(name != null); + + Native.Z3_params_set_uint(Context.nCtx, NativeObject, name.NativeObject, value); + } + + /// + /// Adds a parameter setting. + /// + public void Add(Symbol name, double value) + { + Contract.Requires(name != null); + + Native.Z3_params_set_double(Context.nCtx, NativeObject, name.NativeObject, value); + } + + /// + /// Adds a parameter setting. + /// + public void Add(Symbol name, Symbol value) + { + Contract.Requires(name != null); + Contract.Requires(value != null); + + Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, value.NativeObject); + } + + /// + /// Adds a parameter setting. + /// + public void Add(string name, bool value) + { + Native.Z3_params_set_bool(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, (value) ? 1 : 0); + } + + /// + /// Adds a parameter setting. + /// + public void Add(string name, uint value) + { + Native.Z3_params_set_uint(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value); + } + + /// + /// Adds a parameter setting. + /// + public void Add(string name, double value) + { + Native.Z3_params_set_double(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value); + } + + /// + /// Adds a parameter setting. + /// + public void Add(string name, Symbol value) + { + Contract.Requires(value != null); + + Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value.NativeObject); + } + + /// + /// A string representation of the parameter set. + /// + public override string ToString() + { + return Native.Z3_params_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal Params(Context ctx) + : base(ctx, Native.Z3_mk_params(ctx.nCtx)) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_params_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_params_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.Params_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.Params_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Pattern.cs b/Microsoft.Z3/Pattern.cs new file mode 100644 index 000000000..1ea7bdb38 --- /dev/null +++ b/Microsoft.Z3/Pattern.cs @@ -0,0 +1,75 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Pattern.cs + +Abstract: + + Z3 Managed API: Patterns + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-16 + +Notes: + +--*/ + +using System; +using System.Runtime.InteropServices; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Patterns comprise a list of terms. The list should be + /// non-empty. If the list comprises of more than one term, it is + /// also called a multi-pattern. + /// + [ContractVerification(true)] + public class Pattern : AST + { + /// + /// The number of terms in the pattern. + /// + public uint NumTerms + { + get { return Native.Z3_get_pattern_num_terms(Context.nCtx, NativeObject); } + } + + /// + /// The terms in the pattern. + /// + public Expr[] Terms + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumTerms; + Expr[] res = new Expr[n]; + for (uint i = 0; i < n; i++) + res[i] = Expr.Create(Context, Native.Z3_get_pattern(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// A string representation of the pattern. + /// + public override string ToString() + { + return Native.Z3_pattern_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal Pattern(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } +} diff --git a/Microsoft.Z3/Probe.cs b/Microsoft.Z3/Probe.cs new file mode 100644 index 000000000..5bd38bd3c --- /dev/null +++ b/Microsoft.Z3/Probe.cs @@ -0,0 +1,95 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Probe.cs + +Abstract: + + Z3 Managed API: Probes + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Runtime.InteropServices; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + /// which solver and/or preprocessing step will be used. + /// The complete list of probes may be obtained using the procedures Context.NumProbes + /// and Context.ProbeNames. + /// It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + /// + [ContractVerification(true)] + public class Probe : Z3Object + { + /// + /// Execute the probe over the goal. + /// + /// A probe always produce a double value. + /// "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. + public double Apply(Goal g) + { + Contract.Requires(g != null); + + Context.CheckContextMatch(g); + return Native.Z3_probe_apply(Context.nCtx, NativeObject, g.NativeObject); + } + + /// + /// Apply the probe to a goal. + /// + public double this[Goal g] { get { + Contract.Requires(g != null); + + return Apply(g); } } + + #region Internal + internal Probe(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal Probe(Context ctx, string name) + : base(ctx, Native.Z3_mk_probe(ctx.nCtx, name)) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_probe_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_probe_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.Probe_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.Probe_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Properties/AssemblyInfo.cs b/Microsoft.Z3/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..5e8bcbdb0 --- /dev/null +++ b/Microsoft.Z3/Properties/AssemblyInfo.cs @@ -0,0 +1,39 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security.Permissions; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Z3 .NET Interface")] +[assembly: AssemblyDescription(".NET Interface to the Z3 Theorem Prover")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft Corporation")] +[assembly: AssemblyProduct("Z3")] +[assembly: AssemblyCopyright("Copyright © Microsoft Corporation 2006")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4853ed71-2078-40f4-8117-bc46646bce0e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("4.2.0.0")] +[assembly: AssemblyVersion("4.2.0.0")] +[assembly: AssemblyFileVersion("4.2.0.0")] + diff --git a/Microsoft.Z3/Quantifier.cs b/Microsoft.Z3/Quantifier.cs new file mode 100644 index 000000000..c1f3bc42d --- /dev/null +++ b/Microsoft.Z3/Quantifier.cs @@ -0,0 +1,257 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Quantifier.cs + +Abstract: + + Z3 Managed API: Quantifiers + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-19 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Quantifier expressions. + /// + [ContractVerification(true)] + public class Quantifier : BoolExpr + { + /// + /// Indicates whether the quantifier is universal. + /// + public bool IsUniversal + { + get { return Native.Z3_is_quantifier_forall(Context.nCtx, NativeObject) != 0; } + } + + /// + /// Indicates whether the quantifier is existential. + /// + public bool IsExistential + { + get { return !IsUniversal; } + } + + /// + /// The weight of the quantifier. + /// + public uint Weight + { + get { return Native.Z3_get_quantifier_weight(Context.nCtx, NativeObject); } + } + + /// + /// The number of patterns. + /// + public uint NumPatterns + { + get { return Native.Z3_get_quantifier_num_patterns(Context.nCtx, NativeObject); } + } + + /// + /// The patterns. + /// + public Pattern[] Patterns + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumPatterns; + Pattern[] res = new Pattern[n]; + for (uint i = 0; i < n; i++) + res[i] = new Pattern(Context, Native.Z3_get_quantifier_pattern_ast(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The number of no-patterns. + /// + public uint NumNoPatterns + { + get { return Native.Z3_get_quantifier_num_no_patterns(Context.nCtx, NativeObject); } + } + + /// + /// The no-patterns. + /// + public Pattern[] NoPatterns + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumNoPatterns; + Pattern[] res = new Pattern[n]; + for (uint i = 0; i < n; i++) + res[i] = new Pattern(Context, Native.Z3_get_quantifier_no_pattern_ast(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The number of bound variables. + /// + public uint NumBound + { + get { return Native.Z3_get_quantifier_num_bound(Context.nCtx, NativeObject); } + } + + /// + /// The symbols for the bound variables. + /// + public Symbol[] BoundVariableNames + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumBound; + Symbol[] res = new Symbol[n]; + for (uint i = 0; i < n; i++) + res[i] = Symbol.Create(Context, Native.Z3_get_quantifier_bound_name(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The sorts of the bound variables. + /// + public Sort[] BoundVariableSorts + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumBound; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(Context, Native.Z3_get_quantifier_bound_sort(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The body of the quantifier. + /// + public BoolExpr Body + { + get { + Contract.Ensures(Contract.Result() != null); + + return new BoolExpr(Context, Native.Z3_get_quantifier_body(Context.nCtx, NativeObject)); } + } + + #region Internal + [ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug + internal Quantifier(Context ctx, bool isForall, Sort[] sorts, Symbol[] names, Expr body, + uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, + Symbol quantifierID = null, Symbol skolemID = null + ) + : base(ctx) + { + Contract.Requires(ctx != null); + Contract.Requires(sorts != null); + Contract.Requires(names != null); + Contract.Requires(body != null); + Contract.Requires(sorts.Length == names.Length); + Contract.Requires(Contract.ForAll(sorts, s => s != null)); + Contract.Requires(Contract.ForAll(names, n => n != null)); + Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); + Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); + + Context.CheckContextMatch(patterns); + Context.CheckContextMatch(noPatterns); + Context.CheckContextMatch(sorts); + Context.CheckContextMatch(names); + Context.CheckContextMatch(body); + + if (sorts.Length != names.Length) + throw new Z3Exception("Number of sorts does not match number of names"); + + IntPtr[] _patterns = AST.ArrayToNative(patterns); + + if (noPatterns == null && quantifierID == null && skolemID == null) + { + NativeObject = Native.Z3_mk_quantifier(ctx.nCtx, (isForall) ? 1 : 0, weight, + AST.ArrayLength(patterns), AST.ArrayToNative(patterns), + AST.ArrayLength(sorts), AST.ArrayToNative(sorts), + Symbol.ArrayToNative(names), + body.NativeObject); + } + else + { + NativeObject = Native.Z3_mk_quantifier_ex(ctx.nCtx, (isForall) ? 1 : 0, weight, + AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID), + AST.ArrayLength(patterns), AST.ArrayToNative(patterns), + AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns), + AST.ArrayLength(sorts), AST.ArrayToNative(sorts), + Symbol.ArrayToNative(names), + body.NativeObject); + } + } + + [ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug + internal Quantifier(Context ctx, bool isForall, Expr[] bound, Expr body, + uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, + Symbol quantifierID = null, Symbol skolemID = null + ) + : base(ctx) + { + Contract.Requires(ctx != null); + Contract.Requires(body != null); + + Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); + Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); + Contract.Requires(bound == null || Contract.ForAll(bound, n => n != null)); + + Context.CheckContextMatch(noPatterns); + Context.CheckContextMatch(patterns); + //Context.CheckContextMatch(bound); + Context.CheckContextMatch(body); + + if (noPatterns == null && quantifierID == null && skolemID == null) + { + NativeObject = Native.Z3_mk_quantifier_const(ctx.nCtx, (isForall) ? 1 : 0, weight, + AST.ArrayLength(bound), AST.ArrayToNative(bound), + AST.ArrayLength(patterns), AST.ArrayToNative(patterns), + body.NativeObject); + } + else + { + NativeObject = Native.Z3_mk_quantifier_const_ex(ctx.nCtx, (isForall) ? 1 : 0, weight, + AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID), + AST.ArrayLength(bound), AST.ArrayToNative(bound), + AST.ArrayLength(patterns), AST.ArrayToNative(patterns), + AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns), + body.NativeObject); + } + } + + + internal Quantifier(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + + #if DEBUG + internal override void CheckNativeObject(IntPtr obj) + { + if ((Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, obj) != Z3_ast_kind.Z3_QUANTIFIER_AST) + throw new Z3Exception("Underlying object is not a quantifier"); + base.CheckNativeObject(obj); + } + #endif + #endregion + } +} diff --git a/Microsoft.Z3/Solver.cs b/Microsoft.Z3/Solver.cs new file mode 100644 index 000000000..2403108c1 --- /dev/null +++ b/Microsoft.Z3/Solver.cs @@ -0,0 +1,300 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Solver.cs + +Abstract: + + Z3 Managed API: Solvers + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-22 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Solvers. + /// + [ContractVerification(true)] + public class Solver : Z3Object + { + /// + /// A string that describes all available solver parameters. + /// + public string Help + { + get { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_solver_get_help(Context.nCtx, NativeObject); } + } + + /// + /// Sets the solver parameters. + /// + public Params Parameters + { + set + { + Contract.Requires(value != null); + + Context.CheckContextMatch(value); + Native.Z3_solver_set_params(Context.nCtx, NativeObject, value.NativeObject); + } + } + + /// + /// Retrieves parameter descriptions for solver. + /// + ParamDescrs ParameterDescriptions + { + get + { + return new ParamDescrs(Context, Native.Z3_solver_get_param_descrs(Context.nCtx, NativeObject)); + } + } + + + /// + /// The current number of backtracking points (scopes). + /// + /// + /// + public uint NumScopes + { + get { return Native.Z3_solver_get_num_scopes(Context.nCtx, NativeObject); } + } + + /// + /// Creates a backtracking point. + /// + /// + public void Push() + { + Native.Z3_solver_push(Context.nCtx, NativeObject); + } + + /// + /// Backtracks backtracking points. + /// + /// Note that an exception is thrown if is not smaller than NumScopes + /// + public void Pop(uint n = 1) + { + Native.Z3_solver_pop(Context.nCtx, NativeObject, n); + } + + /// + /// Resets the Solver. + /// + /// This removes all assertions from the solver. + public void Reset() + { + Native.Z3_solver_reset(Context.nCtx, NativeObject); + } + + /// + /// Assert a constraint (or multiple) into the solver. + /// + public void Assert(params BoolExpr[] constraints) + { + Contract.Requires(constraints != null); + Contract.Requires(Contract.ForAll(constraints, c => c != null)); + + Context.CheckContextMatch(constraints); + foreach (BoolExpr a in constraints) + { + Native.Z3_solver_assert(Context.nCtx, NativeObject, a.NativeObject); + } + } + + /// + /// The number of assertions in the solver. + /// + public uint NumAssertions + { + get + { + ASTVector ass = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject)); + return ass.Size; + } + } + + /// + /// The set of asserted formulas. + /// + public BoolExpr[] Assertions + { + get + { + Contract.Ensures(Contract.Result() != null); + + ASTVector ass = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject)); + uint n = ass.Size; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = new BoolExpr(Context, ass[i].NativeObject); + return res; + } + } + + /// + /// Checks whether the assertions in the solver are consistent or not. + /// + /// + /// + /// + /// + /// + public Status Check(params Expr[] assumptions) + { + Z3_lbool r; + if (assumptions == null) + r = (Z3_lbool)Native.Z3_solver_check(Context.nCtx, NativeObject); + else + r = (Z3_lbool)Native.Z3_solver_check_assumptions(Context.nCtx, NativeObject, (uint)assumptions.Length, AST.ArrayToNative(assumptions)); + switch (r) + { + case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE; + case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE; + default: return Status.UNKNOWN; + } + } + + /// + /// The model of the last Check. + /// + /// + /// The result is null if Check was not invoked before, + /// if its results was not SATISFIABLE, or if model production is not enabled. + /// + public Model Model + { + get + { + IntPtr x = Native.Z3_solver_get_model(Context.nCtx, NativeObject); + if (x == IntPtr.Zero) + return null; + else + return new Model(Context, x); + } + } + + /// + /// The proof of the last Check. + /// + /// + /// The result is null if Check was not invoked before, + /// if its results was not UNSATISFIABLE, or if proof production is disabled. + /// + public Expr Proof + { + get + { + IntPtr x = Native.Z3_solver_get_proof(Context.nCtx, NativeObject); + if (x == IntPtr.Zero) + return null; + else + return Expr.Create(Context, x); + } + } + + /// + /// The unsat core of the last Check. + /// + /// + /// The unsat core is a subset of Assertions + /// The result is empty if Check was not invoked before, + /// if its results was not UNSATISFIABLE, or if core production is disabled. + /// + public Expr[] UnsatCore + { + get + { + Contract.Ensures(Contract.Result() != null); + + ASTVector core = new ASTVector(Context, Native.Z3_solver_get_unsat_core(Context.nCtx, NativeObject)); + uint n = core.Size; + Expr[] res = new Expr[n]; + for (uint i = 0; i < n; i++) + res[i] = Expr.Create(Context, core[i].NativeObject); + return res; + } + } + + /// + /// A brief justification of why the last call to Check returned UNKNOWN. + /// + public string ReasonUnknown + { + get + { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_solver_get_reason_unknown(Context.nCtx, NativeObject); + } + } + + /// + /// Solver statistics. + /// + public Statistics Statistics + { + get { + Contract.Ensures(Contract.Result() != null); + + return new Statistics(Context, Native.Z3_solver_get_statistics(Context.nCtx, NativeObject)); } + } + + /// + /// A string representation of the solver. + /// + public override string ToString() + { + return Native.Z3_solver_to_string(Context.nCtx, NativeObject); + } + + #region Internal + internal Solver(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_solver_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_solver_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.Solver_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.Solver_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Sort.cs b/Microsoft.Z3/Sort.cs new file mode 100644 index 000000000..6df3200cf --- /dev/null +++ b/Microsoft.Z3/Sort.cs @@ -0,0 +1,745 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Sort.cs + +Abstract: + + Z3 Managed API: Sorts + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-15 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// The Sort class implements type information for ASTs. + /// + [ContractVerification(true)] + public class Sort : AST + { + /// + /// Comparison operator. + /// + /// A Sort + /// A Sort + /// True if and are from the same context + /// and represent the same sort; false otherwise. + public static bool operator ==(Sort a, Sort b) + { + return Object.ReferenceEquals(a, b) || + (!Object.ReferenceEquals(a, null) && + !Object.ReferenceEquals(b, null) && + a.Context == b.Context && + Native.Z3_is_eq_sort(a.Context.nCtx, a.NativeObject, b.NativeObject) != 0); + } + + /// + /// Comparison operator. + /// + /// A Sort + /// A Sort + /// True if and are not from the same context + /// or represent different sorts; false otherwise. + public static bool operator !=(Sort a, Sort b) + { + return !(a == b); + } + + /// + /// Equality operator for objects of type Sort. + /// + /// + /// + public override bool Equals(object o) + { + Sort casted = o as Sort; + if (casted == null) return false; + return this == casted; + } + + /// + /// Hash code generation for Sorts + /// + /// A hash code + public override int GetHashCode() + { + return base.GetHashCode(); + } + + /// + /// Returns a unique identifier for the sort. + /// + new public uint Id + { + get { return Native.Z3_get_sort_id(Context.nCtx, NativeObject); } + } + + /// + /// The kind of the sort. + /// + public Z3_sort_kind SortKind + { + get { return (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, NativeObject); } + } + + /// + /// The name of the sort + /// + public Symbol Name + { + get { + Contract.Ensures(Contract.Result() != null); + return Symbol.Create(Context, Native.Z3_get_sort_name(Context.nCtx, NativeObject)); } + } + + /// + /// A string representation of the sort. + /// + public override string ToString() + { + return Native.Z3_sort_to_string(Context.nCtx, NativeObject); + } + + #region Internal + /// + /// Sort constructor + /// + internal protected Sort(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } + internal Sort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + + #if DEBUG + internal override void CheckNativeObject(IntPtr obj) + { + if (Native.Z3_get_ast_kind(Context.nCtx, obj) != (uint)Z3_ast_kind.Z3_SORT_AST) + throw new Z3Exception("Underlying object is not a sort"); + base.CheckNativeObject(obj); + } + #endif + + [ContractVerification(true)] + new internal static Sort Create(Context ctx, IntPtr obj) + { + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result() != null); + + switch ((Z3_sort_kind)Native.Z3_get_sort_kind(ctx.nCtx, obj)) + { + case Z3_sort_kind.Z3_ARRAY_SORT: return new ArraySort(ctx, obj); + case Z3_sort_kind.Z3_BOOL_SORT: return new BoolSort(ctx, obj); + case Z3_sort_kind.Z3_BV_SORT: return new BitVecSort(ctx, obj); + case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeSort(ctx, obj); + case Z3_sort_kind.Z3_INT_SORT: return new IntSort(ctx, obj); + case Z3_sort_kind.Z3_REAL_SORT: return new RealSort(ctx, obj); + case Z3_sort_kind.Z3_UNINTERPRETED_SORT: return new UninterpretedSort(ctx, obj); + case Z3_sort_kind.Z3_FINITE_DOMAIN_SORT: return new FiniteDomainSort(ctx, obj); + case Z3_sort_kind.Z3_RELATION_SORT: return new RelationSort(ctx, obj); + default: + throw new Z3Exception("Unknown sort kind"); + } + } + #endregion + } + + /// + /// A Boolean sort. + /// + public class BoolSort : Sort + { + #region Internal + internal BoolSort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + internal BoolSort(Context ctx) : base(ctx, Native.Z3_mk_bool_sort(ctx.nCtx)) { Contract.Requires(ctx != null); } + #endregion + }; + + /// + /// An arithmetic sort, i.e., Int or Real. + /// + public class ArithSort : Sort + { + #region Internal + internal ArithSort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + #endregion + }; + + /// + /// An Integer sort + /// + public class IntSort : ArithSort + { + #region Internal + internal IntSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal IntSort(Context ctx) + : base(ctx, Native.Z3_mk_int_sort(ctx.nCtx)) + { + Contract.Requires(ctx != null); + } + #endregion + } + + /// + /// A real sort + /// + public class RealSort : ArithSort + { + #region Internal + internal RealSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal RealSort(Context ctx) + : base(ctx, Native.Z3_mk_real_sort(ctx.nCtx)) + { + Contract.Requires(ctx != null); + } + #endregion + } + + /// + /// Bit-vector sorts. + /// + public class BitVecSort : Sort + { + /// + /// The size of the bit-vector sort. + /// + public uint Size + { + get { return Native.Z3_get_bv_sort_size(Context.nCtx, NativeObject); } + } + + #region Internal + internal BitVecSort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + internal BitVecSort(Context ctx, uint size) : base(ctx, Native.Z3_mk_bv_sort(ctx.nCtx, size)) { Contract.Requires(ctx != null); } + #endregion + }; + + /// + /// Array sorts. + /// + [ContractVerification(true)] + public class ArraySort : Sort + { + /// + /// The domain of the array sort. + /// + public Sort Domain + { + get { + Contract.Ensures(Contract.Result() != null); + + return Sort.Create(Context, Native.Z3_get_array_sort_domain(Context.nCtx, NativeObject)); } + } + + /// + /// The range of the array sort. + /// + public Sort Range + { + get { + Contract.Ensures(Contract.Result() != null); + + return Sort.Create(Context, Native.Z3_get_array_sort_range(Context.nCtx, NativeObject)); } + } + + #region Internal + internal ArraySort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + internal ArraySort(Context ctx, Sort domain, Sort range) + : base(ctx, Native.Z3_mk_array_sort(ctx.nCtx, domain.NativeObject, range.NativeObject)) + { + Contract.Requires(ctx != null); + Contract.Requires(domain != null); + Contract.Requires(range != null); + } + #endregion + }; + + /// + /// Datatype sorts. + /// + [ContractVerification(true)] + public class DatatypeSort : Sort + { + /// + /// The number of constructors of the datatype sort. + /// + public uint NumConstructors + { + get { return Native.Z3_get_datatype_sort_num_constructors(Context.nCtx, NativeObject); } + } + + /// + /// The constructors. + /// + public FuncDecl[] Constructors + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumConstructors; + FuncDecl[] res = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + res[i] = new FuncDecl(Context, Native.Z3_get_datatype_sort_constructor(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The recognizers. + /// + public FuncDecl[] Recognizers + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumConstructors; + FuncDecl[] res = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + res[i] = new FuncDecl(Context, Native.Z3_get_datatype_sort_recognizer(Context.nCtx, NativeObject, i)); + return res; + } + } + + /// + /// The constructor accessors. + /// + public FuncDecl[][] Accessors + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumConstructors; + FuncDecl[][] res = new FuncDecl[n][]; + for (uint i = 0; i < n; i++) + { + FuncDecl fd = new FuncDecl(Context, Native.Z3_get_datatype_sort_constructor(Context.nCtx, NativeObject, i)); + uint ds = fd.DomainSize; + FuncDecl[] tmp = new FuncDecl[ds]; + for (uint j = 0; j < ds; j++) + tmp[j] = new FuncDecl(Context, Native.Z3_get_datatype_sort_constructor_accessor(Context.nCtx, NativeObject, i, j)); + res[i] = tmp; + } + return res; + } + } + + #region Internal + internal DatatypeSort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } + + internal DatatypeSort(Context ctx, Symbol name, Constructor[] constructors) + : base(ctx, Native.Z3_mk_datatype(ctx.nCtx, name.NativeObject, (uint)constructors.Length, ArrayToNative(constructors))) + { + Contract.Requires(ctx != null); + Contract.Requires(name != null); + Contract.Requires(constructors != null); + } + #endregion + }; + + /// + /// Uninterpreted Sorts + /// + public class UninterpretedSort : Sort + { + #region Internal + internal UninterpretedSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal UninterpretedSort(Context ctx, Symbol s) + : base(ctx, Native.Z3_mk_uninterpreted_sort(ctx.nCtx, s.NativeObject)) + { + Contract.Requires(ctx != null); + Contract.Requires(s != null); + } + #endregion + } + + /// + /// Tuple sorts. + /// + [ContractVerification(true)] + public class TupleSort : Sort + { + /// + /// The constructor function of the tuple. + /// + public FuncDecl MkDecl + { + get { + Contract.Ensures(Contract.Result() != null); + + return new FuncDecl(Context, Native.Z3_get_tuple_sort_mk_decl(Context.nCtx, NativeObject)); } + } + + /// + /// The number of fields in the tuple. + /// + public uint NumFields + { + get { return Native.Z3_get_tuple_sort_num_fields(Context.nCtx, NativeObject); } + } + + /// + /// The field declarations. + /// + public FuncDecl[] FieldDecls + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = NumFields; + FuncDecl[] res = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + res[i] = new FuncDecl(Context, Native.Z3_get_tuple_sort_field_decl(Context.nCtx, NativeObject, i)); + return res; + } + } + + #region Internal + internal TupleSort(Context ctx, Symbol name, uint numFields, Symbol[] fieldNames, Sort[] fieldSorts) + : base(ctx) + { + Contract.Requires(ctx != null); + Contract.Requires(name != null); + + IntPtr t = IntPtr.Zero; + NativeObject = Native.Z3_mk_tuple_sort(ctx.nCtx, name.NativeObject, numFields, + Symbol.ArrayToNative(fieldNames), AST.ArrayToNative(fieldSorts), + ref t, new IntPtr[numFields]); + } + #endregion + }; + + /// + /// Enumeration sorts. + /// + [ContractVerification(true)] + public class EnumSort : Sort + { + /// + /// The function declarations of the constants in the enumeration. + /// + public FuncDecl[] ConstDecls + { + get { + Contract.Ensures(Contract.Result() != null); + + return _constdecls; } + } + + /// + /// The constants in the enumeration. + /// + public Expr[] Consts + { + get { + Contract.Ensures(Contract.Result() != null); + + return _consts; } + } + + /// + /// The test predicates for the constants in the enumeration. + /// + public FuncDecl[] TesterDecls + { + get { + Contract.Ensures(Contract.Result() != null); + + return _testerdecls; + } + } + + #region Object Invariant + + [ContractInvariantMethod] + private void ObjectInvariant() + { + Contract.Invariant(this._constdecls != null); + Contract.Invariant(this._testerdecls != null); + Contract.Invariant(this._consts != null); + } + + + #endregion + + #region Internal + readonly private FuncDecl[] _constdecls = null, _testerdecls = null; + readonly private Expr[] _consts = null; + + internal EnumSort(Context ctx, Symbol name, Symbol[] enumNames) + : base(ctx) + { + Contract.Requires(ctx != null); + Contract.Requires(name != null); + Contract.Requires(enumNames != null); + + int n = enumNames.Length; + IntPtr[] n_constdecls = new IntPtr[n]; + IntPtr[] n_testers = new IntPtr[n]; + NativeObject = Native.Z3_mk_enumeration_sort(ctx.nCtx, name.NativeObject, (uint)n, + Symbol.ArrayToNative(enumNames), n_constdecls, n_testers); + _constdecls = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + _constdecls[i] = new FuncDecl(ctx, n_constdecls[i]); + _testerdecls = new FuncDecl[n]; + for (uint i = 0; i < n; i++) + _testerdecls[i] = new FuncDecl(ctx, n_testers[i]); + _consts = new Expr[n]; + for (uint i = 0; i < n; i++) + _consts[i] = ctx.MkApp(_constdecls[i]); + } + #endregion + }; + + /// + /// List sorts. + /// + [ContractVerification(true)] + public class ListSort : Sort + { + /// + /// The declaration of the nil function of this list sort. + /// + public FuncDecl NilDecl { get { + Contract.Ensures(Contract.Result() != null); + return nilDecl; } } + + /// + /// The empty list. + /// + public Expr Nil + { + get + { + Contract.Ensures(Contract.Result() != null); + return nilConst; + } + } + + /// + /// The declaration of the isNil function of this list sort. + /// + public FuncDecl IsNilDecl + { + get + { + Contract.Ensures(Contract.Result() != null); + return isNilDecl; + } + } + + /// + /// The declaration of the cons function of this list sort. + /// + public FuncDecl ConsDecl + { + get + { + Contract.Ensures(Contract.Result() != null); + return consDecl; + } + } + + /// + /// The declaration of the isCons function of this list sort. + /// + /// + public FuncDecl IsConsDecl + { + get + { + Contract.Ensures(Contract.Result() != null); + return isConsDecl; + } + } + + /// + /// The declaration of the head function of this list sort. + /// + public FuncDecl HeadDecl + { + get + { + Contract.Ensures(Contract.Result() != null); + return headDecl; + } + } + + /// + /// The declaration of the tail function of this list sort. + /// + public FuncDecl TailDecl + { + get + { + Contract.Ensures(Contract.Result() != null); + return tailDecl; + } + } + + #region Object Invariant + + [ContractInvariantMethod] + private void ObjectInvariant() + { + Contract.Invariant(nilConst != null); + Contract.Invariant(nilDecl != null); + Contract.Invariant(isNilDecl != null); + Contract.Invariant(consDecl != null); + Contract.Invariant(isConsDecl != null); + Contract.Invariant(headDecl != null); + Contract.Invariant(tailDecl != null); + } + + + #endregion + + #region Internal + readonly private FuncDecl nilDecl, isNilDecl, consDecl, isConsDecl, headDecl, tailDecl; + readonly private Expr nilConst; + + internal ListSort(Context ctx, Symbol name, Sort elemSort) + : base(ctx) + { + Contract.Requires(ctx != null); + Contract.Requires(name != null); + Contract.Requires(elemSort != null); + + IntPtr inil = IntPtr.Zero, + iisnil = IntPtr.Zero, + icons = IntPtr.Zero, + iiscons = IntPtr.Zero, + ihead = IntPtr.Zero, + itail = IntPtr.Zero; + + NativeObject = Native.Z3_mk_list_sort(ctx.nCtx, name.NativeObject, elemSort.NativeObject, + ref inil, ref iisnil, ref icons, ref iiscons, ref ihead, ref itail); + nilDecl = new FuncDecl(ctx, inil); + isNilDecl = new FuncDecl(ctx, iisnil); + consDecl = new FuncDecl(ctx, icons); + isConsDecl = new FuncDecl(ctx, iiscons); + headDecl = new FuncDecl(ctx, ihead); + tailDecl = new FuncDecl(ctx, itail); + nilConst = ctx.MkConst(nilDecl); + } + #endregion + }; + + /// + /// Relation sorts. + /// + [ContractVerification(true)] + public class RelationSort : Sort + { + /// + /// The arity of the relation sort. + /// + public uint Arity + { + get { return Native.Z3_get_relation_arity(Context.nCtx, NativeObject); } + } + + /// + /// The sorts of the columns of the relation sort. + /// + public Sort[] ColumnSorts + { + get + { + Contract.Ensures(Contract.Result() != null); + + if (m_columnSorts != null) + return m_columnSorts; + + uint n = Arity; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(Context, Native.Z3_get_relation_column(Context.nCtx, NativeObject, i)); + return res; + } + } + + #region Internal + private Sort[] m_columnSorts = null; + + internal RelationSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } + + /// + /// Finite domain sorts. + /// + [ContractVerification(true)] + public class FiniteDomainSort : Sort + { + /// + /// The size of the finite domain sort. + /// + public ulong Size + { + get { ulong res = 0; Native.Z3_get_finite_domain_sort_size(Context.nCtx, NativeObject, ref res); return res; } + } + + #region Internal + internal FiniteDomainSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal FiniteDomainSort(Context ctx, Symbol name, ulong size) + : base(ctx, Native.Z3_mk_finite_domain_sort(ctx.nCtx, name.NativeObject, size)) + { + Contract.Requires(ctx != null); + Contract.Requires(name != null); + + } + #endregion + } + + /// + /// Set sorts. + /// + [ContractVerification(true)] + public class SetSort : Sort + { + #region Internal + internal SetSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal SetSort(Context ctx, Sort ty) + : base(ctx, Native.Z3_mk_set_sort(ctx.nCtx, ty.NativeObject)) + { + Contract.Requires(ctx != null); + Contract.Requires(ty != null); + } + #endregion + } +} diff --git a/Microsoft.Z3/Statistics.cs b/Microsoft.Z3/Statistics.cs new file mode 100644 index 000000000..0897c31ee --- /dev/null +++ b/Microsoft.Z3/Statistics.cs @@ -0,0 +1,206 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Statistics.cs + +Abstract: + + Z3 Managed API: Statistics + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-22 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Objects of this class track statistical information about solvers. + /// + [ContractVerification(true)] + public class Statistics : Z3Object + { + /// + /// Statistical data is organized into pairs of [Key, Entry], where every + /// Entry is either a DoubleEntry or a UIntEntry + /// + public class Entry + { + /// + /// The key of the entry. + /// + readonly public string Key; + /// + /// The uint-value of the entry. + /// + public uint UIntValue { get { return m_uint; } } + /// + /// The double-value of the entry. + /// + public double DoubleValue { get { return m_double; } } + /// + /// True if the entry is uint-valued. + /// + public bool IsUInt { get { return m_is_uint; } } + /// + /// True if the entry is double-valued. + /// + public bool IsDouble { get { return m_is_double; } } + + /// + /// The string representation of the the entry's value. + /// + public string Value + { + get + { + Contract.Ensures(Contract.Result() != null); + + if (IsUInt) + return m_uint.ToString(); + else if (IsDouble) + return m_double.ToString(); + else + throw new Z3Exception("Unknown statistical entry type"); + } + } + + /// + /// The string representation of the Entry. + /// + public override string ToString() + { + return Key + ": " + Value; + } + + #region Internal + readonly private bool m_is_uint = false; + readonly private bool m_is_double = false; + readonly private uint m_uint = 0; + readonly private double m_double = 0.0; + internal Entry(string k, uint v) { Key = k; m_is_uint = true; m_uint = v; } + internal Entry(string k, double v) { Key = k; m_is_double = true; m_double = v; } + #endregion + } + + /// + /// A string representation of the statistical data. + /// + public override string ToString() + { + return Native.Z3_stats_to_string(Context.nCtx, NativeObject); + } + + /// + /// The number of statistical data. + /// + public uint Size + { + get { return Native.Z3_stats_size(Context.nCtx, NativeObject); } + } + + /// + /// The data entries. + /// + public Entry[] Entries + { + get + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result().Length == this.Size); + Contract.Ensures(Contract.ForAll(0, Contract.Result().Length, j => Contract.Result()[j] != null)); + + uint n = Size; + Entry[] res = new Entry[n]; + for (uint i = 0; i < n; i++) + { + Entry e; + string k = Native.Z3_stats_get_key(Context.nCtx, NativeObject, i); + if (Native.Z3_stats_is_uint(Context.nCtx, NativeObject, i) != 0) + e = new Entry(k, Native.Z3_stats_get_uint_value(Context.nCtx, NativeObject, i)); + else if (Native.Z3_stats_is_double(Context.nCtx, NativeObject, i) != 0) + e = new Entry(k, Native.Z3_stats_get_double_value(Context.nCtx, NativeObject, i)); + else + throw new Z3Exception("Unknown data entry value"); + res[i] = e; + } + return res; + } + } + + /// + /// The statistical counters. + /// + public string[] Keys + { + get + { + Contract.Ensures(Contract.Result() != null); + + uint n = Size; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Native.Z3_stats_get_key(Context.nCtx, NativeObject, i); + return res; + } + } + + /// + /// The value of a particular statistical counter. + /// + /// Returns null if the key is unknown. + public Entry this[string key] + { + get + { + uint n = Size; + Entry[] es = Entries; + for (uint i = 0; i < n; i++) + if (es[i].Key == key) + return es[i]; + return null; + } + } + + #region Internal + internal Statistics(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_stats_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_stats_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.Statistics_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.Statistics_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Status.cs b/Microsoft.Z3/Status.cs new file mode 100644 index 000000000..5847f098b --- /dev/null +++ b/Microsoft.Z3/Status.cs @@ -0,0 +1,45 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Status.cs + +Abstract: + + Z3 Managed API: Status + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-15 + +Notes: + +--*/ + +using System; + +namespace Microsoft.Z3 +{ + /// + /// Status values. + /// + public enum Status + { + /// + /// Used to signify an unsatisfiable status. + /// + UNSATISFIABLE = -1, + + /// + /// Used to signify an unknown status. + /// + UNKNOWN = 0, + + /// + /// Used to signify a satisfiable status. + /// + SATISFIABLE = 1 + } + +} diff --git a/Microsoft.Z3/Symbol.cs b/Microsoft.Z3/Symbol.cs new file mode 100644 index 000000000..ba991cdaa --- /dev/null +++ b/Microsoft.Z3/Symbol.cs @@ -0,0 +1,181 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Symbol.cs + +Abstract: + + Z3 Managed API: Symbols + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-16 + +Notes: + +--*/ + +using System; +using System.Runtime.InteropServices; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Symbols are used to name several term and type constructors. + /// + [ContractVerification(true)] + public class Symbol : Z3Object + { + /// + /// The kind of the symbol (int or string) + /// + protected Z3_symbol_kind Kind + { + get { return (Z3_symbol_kind)Native.Z3_get_symbol_kind(Context.nCtx, NativeObject); } + } + + /// + /// Indicates whether the symbol is of Int kind + /// + public bool IsIntSymbol() + { + return Kind == Z3_symbol_kind.Z3_INT_SYMBOL; + } + + /// + /// Indicates whether the symbol is of string kind. + /// + public bool IsStringSymbol() + { + return Kind == Z3_symbol_kind.Z3_STRING_SYMBOL; + } + + /// + /// A string representation of the symbol. + /// + public override string ToString() + { + if (IsIntSymbol()) + return ((IntSymbol)this).Int.ToString(); + else if (IsStringSymbol()) + return ((StringSymbol)this).String; + else + throw new Z3Exception("Unknown symbol kind encountered"); + } + + #region Internal + /// + /// Symbol constructor + /// + internal protected Symbol(Context ctx, IntPtr obj) : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal static Symbol Create(Context ctx, IntPtr obj) + { + Contract.Requires(ctx != null); + Contract.Ensures(Contract.Result() != null); + + switch ((Z3_symbol_kind)Native.Z3_get_symbol_kind(ctx.nCtx, obj)) + { + case Z3_symbol_kind.Z3_INT_SYMBOL: return new IntSymbol(ctx, obj); + case Z3_symbol_kind.Z3_STRING_SYMBOL: return new StringSymbol(ctx, obj); + default: + throw new Z3Exception("Unknown symbol kind encountered"); + } + } + #endregion + } + + /// + /// Numbered symbols + /// + [ContractVerification(true)] + public class IntSymbol : Symbol + { + /// + /// The int value of the symbol. + /// + /// Throws an exception if the symbol is not of int kind. + public int Int + { + get + { + if (!IsIntSymbol()) + throw new Z3Exception("Int requested from non-Int symbol"); + return Native.Z3_get_symbol_int(Context.nCtx, NativeObject); + } + } + + #region Internal + internal IntSymbol(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal IntSymbol(Context ctx, int i) + : base(ctx, Native.Z3_mk_int_symbol(ctx.nCtx, i)) + { + Contract.Requires(ctx != null); + } + + #if DEBUG + internal override void CheckNativeObject(IntPtr obj) + { + if ((Z3_symbol_kind)Native.Z3_get_symbol_kind(Context.nCtx, obj) != Z3_symbol_kind.Z3_INT_SYMBOL) + throw new Z3Exception("Symbol is not of integer kind"); + base.CheckNativeObject(obj); + } + #endif + #endregion + } + + /// + /// Named symbols + /// + [ContractVerification(true)] + public class StringSymbol : Symbol + { + /// + /// The string value of the symbol. + /// + /// Throws an exception if the symbol is not of string kind. + public string String + { + get + { + Contract.Ensures(Contract.Result() != null); + + if (!IsStringSymbol()) + throw new Z3Exception("String requested from non-String symbol"); + return Native.Z3_get_symbol_string(Context.nCtx, NativeObject); + } + } + + #region Internal + internal StringSymbol(Context ctx, IntPtr obj) : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + + internal StringSymbol(Context ctx, string s) : base(ctx, Native.Z3_mk_string_symbol(ctx.nCtx, s)) + { + Contract.Requires(ctx != null); + } + + #if DEBUG + internal override void CheckNativeObject(IntPtr obj) + { + if ((Z3_symbol_kind)Native.Z3_get_symbol_kind(Context.nCtx, obj) != Z3_symbol_kind.Z3_STRING_SYMBOL) + throw new Z3Exception("Symbol is not of string kind"); + + base.CheckNativeObject(obj); + } + #endif + #endregion + } +} diff --git a/Microsoft.Z3/Tactic.cs b/Microsoft.Z3/Tactic.cs new file mode 100644 index 000000000..62d9015f8 --- /dev/null +++ b/Microsoft.Z3/Tactic.cs @@ -0,0 +1,141 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Tactic.cs + +Abstract: + + Z3 Managed API: Tactics + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Tactics are the basic building block for creating custom solvers for specific problem domains. + /// The complete list of tactics may be obtained using Context.NumTactics + /// and Context.TacticNames. + /// It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + /// + [ContractVerification(true)] + public class Tactic : Z3Object + { + /// + /// A string containing a description of parameters accepted by the tactic. + /// + public string Help + { + get + { + Contract.Ensures(Contract.Result() != null); + + return Native.Z3_tactic_get_help(Context.nCtx, NativeObject); } + } + + + /// + /// Retrieves parameter descriptions for Tactics. + /// + public ParamDescrs ParameterDescriptions + { + get + { + return new ParamDescrs(Context, Native.Z3_tactic_get_param_descrs(Context.nCtx, NativeObject)); + } + } + + + /// + /// Execute the tactic over the goal. + /// + public ApplyResult Apply(Goal g, Params p = null) + { + Contract.Requires(g != null); + Contract.Ensures(Contract.Result() != null); + + Context.CheckContextMatch(g); + if (p == null) + return new ApplyResult(Context, Native.Z3_tactic_apply(Context.nCtx, NativeObject, g.NativeObject)); + else + { + Context.CheckContextMatch(p); + return new ApplyResult(Context, Native.Z3_tactic_apply_ex(Context.nCtx, NativeObject, g.NativeObject, p.NativeObject)); + } + } + + /// + /// Apply the tactic to a goal. + /// + public ApplyResult this[Goal g] + { + get + { + Contract.Requires(g != null); + Contract.Ensures(Contract.Result() != null); + + return Apply(g); + } + } + + /// + /// Creates a solver that is implemented using the given tactic. + /// + /// + public Solver Solver + { + get + { + Contract.Ensures(Contract.Result() != null); + + return Context.MkSolver(this); + } + } + + #region Internal + internal Tactic(Context ctx, IntPtr obj) : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal Tactic(Context ctx, string name) : base(ctx, Native.Z3_mk_tactic(ctx.nCtx, name)) + { + Contract.Requires(ctx != null); + } + + internal class DecRefQueue : Z3.DecRefQueue + { + public override void IncRef(Context ctx, IntPtr obj) + { + Native.Z3_tactic_inc_ref(ctx.nCtx, obj); + } + + public override void DecRef(Context ctx, IntPtr obj) + { + Native.Z3_tactic_dec_ref(ctx.nCtx, obj); + } + }; + + internal override void IncRef(IntPtr o) + { + Context.Tactic_DRQ.IncAndClear(Context, o); + base.IncRef(o); + } + + internal override void DecRef(IntPtr o) + { + Context.Tactic_DRQ.Add(o); + base.DecRef(o); + } + #endregion + } +} diff --git a/Microsoft.Z3/Version.cs b/Microsoft.Z3/Version.cs new file mode 100644 index 000000000..15471c831 --- /dev/null +++ b/Microsoft.Z3/Version.cs @@ -0,0 +1,98 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Version.cs + +Abstract: + + Z3 Managed API: Version information + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-16 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Version information. + /// + /// Note that this class is static. + [ContractVerification(true)] + public static class Version + { + static Version() { } + + /// + /// The major version + /// + public static uint Major + { + get + { + uint major = 0, minor = 0, build = 0, revision = 0; + Native.Z3_get_version(ref major, ref minor, ref build, ref revision); + return major; + } + } + + /// + /// The minor version + /// + public static uint Minor + { + get + { + uint major = 0, minor = 0, build = 0, revision = 0; + Native.Z3_get_version(ref major, ref minor, ref build, ref revision); + return minor; + } + } + + /// + /// The build version + /// + public static uint Build + { + get + { + uint major = 0, minor = 0, build = 0, revision = 0; + Native.Z3_get_version(ref major, ref minor, ref build, ref revision); + return build; + } + } + + /// + /// The revision + /// + public static uint Revision + { + get + { + uint major = 0, minor = 0, build = 0, revision = 0; + Native.Z3_get_version(ref major, ref minor, ref build, ref revision); + return revision; + } + } + + /// + /// A string representation of the version information. + /// + new public static string ToString() + { + Contract.Ensures(Contract.Result() != null); + + uint major = 0, minor = 0, build = 0, revision = 0; + Native.Z3_get_version(ref major, ref minor, ref build, ref revision); + return major.ToString() + "." + minor.ToString() + "." + build.ToString() + "." + revision.ToString(); + } + } +} diff --git a/Microsoft.Z3/Z3Exception.cs b/Microsoft.Z3/Z3Exception.cs new file mode 100644 index 000000000..adda43995 --- /dev/null +++ b/Microsoft.Z3/Z3Exception.cs @@ -0,0 +1,44 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Exception.cs + +Abstract: + + Z3 Managed API: Exceptions + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-15 + +Notes: + +--*/ + +using System; + +namespace Microsoft.Z3 +{ + /// + /// The exception base class for error reporting from Z3 + /// + public class Z3Exception : Exception + { + /// + /// Constructor. + /// + public Z3Exception() : base() { } + + /// + /// Constructor. + /// + public Z3Exception(string message) : base(message) { } + + /// + /// Constructor. + /// + public Z3Exception(string message, System.Exception inner) : base(message, inner) { } + } +} diff --git a/Microsoft.Z3/Z3Object.cs b/Microsoft.Z3/Z3Object.cs new file mode 100644 index 000000000..e8654ce21 --- /dev/null +++ b/Microsoft.Z3/Z3Object.cs @@ -0,0 +1,145 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Z3Object.cs + +Abstract: + + Z3 Managed API: Internal Z3 Objects + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-21 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Internal base class for interfacing with native Z3 objects. + /// Should not be used externally. + /// + [ContractVerification(true)] + public class Z3Object : IDisposable + { + /// + /// Finalizer. + /// + ~Z3Object() + { + Dispose(); + } + + /// + /// Disposes of the underlying native Z3 object. + /// + public void Dispose() + { + if (m_n_obj != IntPtr.Zero) + { + DecRef(m_n_obj); + m_n_obj = IntPtr.Zero; + } + + if (m_ctx != null) + { + m_ctx.refCount--; + if (m_ctx.refCount == 0) + GC.ReRegisterForFinalize(m_ctx); + m_ctx = null; + } + + GC.SuppressFinalize(this); + } + + #region Object Invariant + + [ContractInvariantMethod] + private void ObjectInvariant() + { + Contract.Invariant(this.m_ctx != null); + } + + #endregion + + #region Internal + private Context m_ctx = null; + private IntPtr m_n_obj = IntPtr.Zero; + + internal Z3Object(Context ctx) + { + Contract.Requires(ctx != null); + + ctx.refCount++; + m_ctx = ctx; + } + + internal Z3Object(Context ctx, IntPtr obj) + { + Contract.Requires(ctx != null); + + ctx.refCount++; + m_ctx = ctx; + IncRef(obj); + m_n_obj = obj; + } + + internal virtual void IncRef(IntPtr o) { } + internal virtual void DecRef(IntPtr o) { } + + internal virtual void CheckNativeObject(IntPtr obj) { } + + internal virtual IntPtr NativeObject + { + get { return m_n_obj; } + set + { + if (value != IntPtr.Zero) { CheckNativeObject(value); IncRef(value); } + if (m_n_obj != IntPtr.Zero) { DecRef(m_n_obj); } + m_n_obj = value; + } + } + + internal static IntPtr GetNativeObject(Z3Object s) + { + if (s == null) return new IntPtr(); + return s.NativeObject; + } + + internal Context Context + { + get + { + Contract.Ensures(Contract.Result() != null); + return m_ctx; + } + } + + [Pure] + internal static IntPtr[] ArrayToNative(Z3Object[] a) + { + Contract.Ensures(a == null || Contract.Result() != null); + Contract.Ensures(a == null || Contract.Result().Length == a.Length); + + if (a == null) return null; + IntPtr[] an = new IntPtr[a.Length]; + for (uint i = 0; i < a.Length; i++) + if (a[i] != null) an[i] = a[i].NativeObject; + return an; + } + + [Pure] + internal static uint ArrayLength(Z3Object[] a) + { + return (a == null)?0:(uint)a.Length; + } + #endregion + } +} diff --git a/Microsoft.Z3/mk_z3consts.py b/Microsoft.Z3/mk_z3consts.py new file mode 100644 index 000000000..1428313f7 --- /dev/null +++ b/Microsoft.Z3/mk_z3consts.py @@ -0,0 +1,85 @@ +############################################ +# Copyright (c) 2012 Microsoft Corporation +# +# Extract enumeration types from z3_api.h +# +# Author: Leonardo de Moura (leonardo) +# Christoph M. Wintersteiger (cwinter) +############################################ +import re + +blank_pat = re.compile("^ *$") +comment_pat = re.compile("^ *//.*$") +typedef_pat = re.compile("typedef enum *") +typedef2_pat = re.compile("typedef enum { *") +openbrace_pat = re.compile("{ *") +closebrace_pat = re.compile("}.*;") + +api = open('..\\lib\\z3_api.h', 'r') + +DeprecatedEnums = { 'Z3_search_failure' } + +z3consts = open('Enumerations.cs', 'w') +z3consts.write('// Automatically generated file, generator: mk_z3consts.py\n\n') +z3consts.write('using System;\n\n' + '#pragma warning disable 1591\n\n' + 'namespace Microsoft.Z3\n' + '{\n'); + +SEARCHING = 0 +FOUND_ENUM = 1 +IN_ENUM = 2 + +mode = SEARCHING +decls = {} +idx = 0 + +linenum = 1 +for line in api: + m1 = blank_pat.match(line) + m2 = comment_pat.match(line) + if m1 or m2: + # skip blank lines and comments + linenum = linenum + 1 + elif mode == SEARCHING: + m = typedef_pat.match(line) + if m: + mode = FOUND_ENUM + m = typedef2_pat.match(line) + if m: + mode = IN_ENUM + decls = {} + idx = 0 + elif mode == FOUND_ENUM: + m = openbrace_pat.match(line) + if m: + mode = IN_ENUM + decls = {} + idx = 0 + else: + assert False, "Invalid z3_api.h, line: %s" % linenum + else: + assert mode == IN_ENUM + words = re.split('[^\-a-zA-Z0-9_]+', line) + m = closebrace_pat.match(line) + if m: + name = words[1] + if name not in DeprecatedEnums: + z3consts.write(' /// %s\n' % name) + z3consts.write(' public enum %s {\n' % name) + z3consts.write + for k, i in decls.iteritems(): + z3consts.write(' %s = %s,\n' % (k, i)) + z3consts.write(' }\n\n') + mode = SEARCHING + else: + if words[2] != '': + if len(words[2]) > 1 and words[2][1] == 'x': + idx = int(words[2], 16) + else: + idx = int(words[2]) + decls[words[1]] = idx + idx = idx + 1 + linenum = linenum + 1 + +z3consts.write('}\n'); diff --git a/Microsoft.Z3/test_mapi/Program.cs b/Microsoft.Z3/test_mapi/Program.cs new file mode 100644 index 000000000..99f431d2d --- /dev/null +++ b/Microsoft.Z3/test_mapi/Program.cs @@ -0,0 +1,2115 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Program.cs + +Abstract: + + Z3 Managed API: Example program + +Author: + + Christoph Wintersteiger (cwinter) 2012-03-16 + +Notes: + +--*/ + +using System; +using System.Collections; +using System.Collections.Generic; + +using Microsoft.Z3; + +namespace test_mapi +{ + class Program + { + class TestFailedException : Exception + { + public TestFailedException() : base("Check FAILED") { } + }; + + /// + /// Create axiom: function f is injective in the i-th argument. + /// + /// + /// The following axiom is produced: + /// + /// forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i + /// + /// Where, finvis a fresh function declaration. + /// + public static BoolExpr InjAxiom(Context ctx, FuncDecl f, int i) + { + Sort[] domain = f.Domain; + uint sz = f.DomainSize; + + if (i >= sz) + { + Console.WriteLine("failed to create inj axiom"); + return null; + } + + /* declare the i-th inverse of f: finv */ + Sort finv_domain = f.Range; + Sort finv_range = domain[i]; + FuncDecl finv = ctx.MkFuncDecl("f_fresh", finv_domain, finv_range); + + /* allocate temporary arrays */ + Expr[] xs = new Expr[sz]; + Symbol[] names = new Symbol[sz]; + Sort[] types = new Sort[sz]; + + /* fill types, names and xs */ + + for (uint j = 0; j < sz; j++) + { + types[j] = domain[j]; + names[j] = ctx.MkSymbol(String.Format("x_{0}", j)); + xs[j] = ctx.MkBound(j, types[j]); + } + Expr x_i = xs[i]; + + /* create f(x_0, ..., x_i, ..., x_{n-1}) */ + Expr fxs = f[xs]; + + /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ + Expr finv_fxs = finv[fxs]; + + /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ + Expr eq = ctx.MkEq(finv_fxs, x_i); + + /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ + Pattern p = ctx.MkPattern(new Expr[] { fxs }); + + /* create & assert quantifier */ + BoolExpr q = ctx.MkForall( + types, /* types of quantified variables */ + names, /* names of quantified variables */ + eq, + 1, + new Pattern[] { p } /* patterns */); + + return q; + } + + /// + /// Create axiom: function f is injective in the i-th argument. + /// + /// + /// The following axiom is produced: + /// + /// forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i + /// + /// Where, finvis a fresh function declaration. + /// + public static BoolExpr InjAxiomAbs(Context ctx, FuncDecl f, int i) + { + Sort[] domain = f.Domain; + uint sz = f.DomainSize; + + if (i >= sz) + { + Console.WriteLine("failed to create inj axiom"); + return null; + } + + /* declare the i-th inverse of f: finv */ + Sort finv_domain = f.Range; + Sort finv_range = domain[i]; + FuncDecl finv = ctx.MkFuncDecl("f_fresh", finv_domain, finv_range); + + /* allocate temporary arrays */ + Expr[] xs = new Expr[sz]; + + /* fill types, names and xs */ + for (uint j = 0; j < sz; j++) + { + xs[j] = ctx.MkConst(String.Format("x_{0}", j), domain[j]); + } + Expr x_i = xs[i]; + + /* create f(x_0, ..., x_i, ..., x_{n-1}) */ + Expr fxs = f[xs]; + + /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ + Expr finv_fxs = finv[fxs]; + + /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ + Expr eq = ctx.MkEq(finv_fxs, x_i); + + /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ + Pattern p = ctx.MkPattern(new Expr[] { fxs }); + + /* create & assert quantifier */ + BoolExpr q = ctx.MkForall( + xs, /* types of quantified variables */ + eq, /* names of quantified variables */ + 1, + new Pattern[] { p } /* patterns */); + + return q; + } + + /// + /// Assert the axiom: function f is commutative. + /// + /// + /// This example uses the SMT-LIB parser to simplify the axiom construction. + /// + private static BoolExpr CommAxiom(Context ctx, FuncDecl f) + { + Sort t = f.Range; + Sort[] dom = f.Domain; + + if (dom.Length != 2 || + !t.Equals(dom[0]) || + !t.Equals(dom[1])) + { + Console.WriteLine("{0} {1} {2} {3}", dom.Length, dom[0], dom[1], t); + throw new Exception("function must be binary, and argument types must be equal to return type"); + } + + string bench = string.Format("(benchmark comm :formula (forall (x {0}) (y {1}) (= ({2} x y) ({3} y x))))", + t.Name, t.Name, f.Name, f.Name); + ctx.ParseSMTLIBString(bench, new Symbol[] { t.Name }, new Sort[] { t }, new Symbol[] { f.Name }, new FuncDecl[] { f }); + return ctx.SMTLIBFormulas[0]; + } + + /// + /// "Hello world" example: create a Z3 logical context, and delete it. + /// + public static void SimpleExample() + { + Console.WriteLine("SimpleExample"); + + using (Context ctx = new Context()) + { + /* do something with the context */ + + /* be kind to dispose manually and not wait for the GC. */ + ctx.Dispose(); + } + } + + static Model Check(Context ctx, BoolExpr f, Status sat) + { + Solver s = ctx.MkSolver(); + s.Assert(f); + if (s.Check() != sat) + throw new TestFailedException(); + if (sat == Status.SATISFIABLE) + return s.Model; + else + return null; + } + + static void SolveTactical(Context ctx, Tactic t, Goal g, Status sat) + { + Solver s = ctx.MkSolver(t); + Console.WriteLine("\nTactical solver: " + s); + + foreach (BoolExpr a in g.Formulas) + s.Assert(a); + Console.WriteLine("Solver: " + s); + + if (s.Check() != sat) + throw new TestFailedException(); + } + + static ApplyResult ApplyTactic(Context ctx, Tactic t, Goal g) + { + Console.WriteLine("\nGoal: " + g); + + ApplyResult res = t.Apply(g); + Console.WriteLine("Application result: " + res); + + Status q = Status.UNKNOWN; + foreach (Goal sg in res.Subgoals) + if (sg.IsDecidedSat) q = Status.SATISFIABLE; + else if (sg.IsDecidedUnsat) q = Status.UNSATISFIABLE; + + switch (q) + { + case Status.UNKNOWN: + Console.WriteLine("Tactic result: Undecided"); + break; + case Status.SATISFIABLE: + Console.WriteLine("Tactic result: SAT"); + break; + case Status.UNSATISFIABLE: + Console.WriteLine("Tactic result: UNSAT"); + break; + } + + return res; + } + + static void Prove(Context ctx, BoolExpr f, params BoolExpr[] assumptions) + { + Console.WriteLine("Proving: " + f); + Solver s = ctx.MkSolver(); + foreach (BoolExpr a in assumptions) + s.Assert(a); + s.Assert(ctx.MkNot(f)); + Status q = s.Check(); + + switch (q) + { + case Status.UNKNOWN: + Console.WriteLine("Unknown because: " + s.ReasonUnknown); + break; + case Status.SATISFIABLE: + throw new TestFailedException(); + case Status.UNSATISFIABLE: + Console.WriteLine("OK, proof: " + s.Proof); + break; + } + } + + static void Disprove(Context ctx, BoolExpr f, params BoolExpr[] assumptions) + { + Console.WriteLine("Disproving: " + f); + Solver s = ctx.MkSolver(); + foreach (BoolExpr a in assumptions) + s.Assert(a); + s.Assert(ctx.MkNot(f)); + Status q = s.Check(); + + switch (q) + { + case Status.UNKNOWN: + Console.WriteLine("Unknown because: " + s.ReasonUnknown); + break; + case Status.SATISFIABLE: + Console.WriteLine("OK, model: " + s.Model); + break; + case Status.UNSATISFIABLE: + throw new TestFailedException(); + } + } + + static void ModelConverterTest(Context ctx) + { + Console.WriteLine("ModelConverterTest"); + + ArithExpr xr = (ArithExpr)ctx.MkConst(ctx.MkSymbol("x"), ctx.MkRealSort()); + ArithExpr yr = (ArithExpr)ctx.MkConst(ctx.MkSymbol("y"), ctx.MkRealSort()); + Goal g4 = ctx.MkGoal(true, false, true); + g4.Assert(ctx.MkGt(xr, ctx.MkReal(10, 1))); + g4.Assert(ctx.MkEq(yr, ctx.MkAdd(xr, ctx.MkReal(1, 1)))); + g4.Assert(ctx.MkGt(yr, ctx.MkReal(1, 1))); + + ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g4); + if (ar.NumSubgoals == 1 && (ar.Subgoals[0].IsDecidedSat || ar.Subgoals[0].IsDecidedUnsat)) + throw new TestFailedException(); + + ar = ApplyTactic(ctx, ctx.AndThen(ctx.MkTactic("simplify"), ctx.MkTactic("solve-eqs")), g4); + if (ar.NumSubgoals == 1 && (ar.Subgoals[0].IsDecidedSat || ar.Subgoals[0].IsDecidedUnsat)) + throw new TestFailedException(); + + Solver s = ctx.MkSolver(); + foreach (BoolExpr e in ar.Subgoals[0].Formulas) + s.Assert(e); + Status q = s.Check(); + Console.WriteLine("Solver says: " + q); + Console.WriteLine("Model: \n" + s.Model); + Console.WriteLine("Converted Model: \n" + ar.ConvertModel(0, s.Model)); + if (q != Status.SATISFIABLE) + throw new TestFailedException(); + } + + /// + /// A simple array example. + /// + /// + static void ArrayExample1(Context ctx) + { + Console.WriteLine("ArrayExample1"); + + Goal g = ctx.MkGoal(true, false, false); + ArraySort asort = ctx.MkArraySort(ctx.IntSort, ctx.MkBitVecSort(32)); + ArrayExpr aex = (ArrayExpr)ctx.MkConst(ctx.MkSymbol("MyArray"), asort); + Expr sel = ctx.MkSelect(aex, ctx.MkInt(0)); + g.Assert(ctx.MkEq(sel, ctx.MkBV(42, 32))); + Symbol xs = ctx.MkSymbol("x"); + IntExpr xc = (IntExpr)ctx.MkConst(xs, ctx.IntSort); + + Symbol fname = ctx.MkSymbol("f"); + Sort[] domain = { ctx.IntSort }; + FuncDecl fd = ctx.MkFuncDecl(fname, domain, ctx.IntSort); + Expr[] fargs = { ctx.MkConst(xs, ctx.IntSort) }; + IntExpr fapp = (IntExpr)ctx.MkApp(fd, fargs); + + g.Assert(ctx.MkEq(ctx.MkAdd(xc, fapp), ctx.MkInt(123))); + + Solver s = ctx.MkSolver(); + foreach (BoolExpr a in g.Formulas) + s.Assert(a); + Console.WriteLine("Solver: " + s); + + Status q = s.Check(); + Console.WriteLine("Status: " + q); + + if (q != Status.SATISFIABLE) + throw new TestFailedException(); + + Console.WriteLine("Model = " + s.Model); + + Console.WriteLine("Interpretation of MyArray:\n" + s.Model.FuncInterp(aex.FuncDecl)); + Console.WriteLine("Interpretation of x:\n" + s.Model.ConstInterp(xc)); + Console.WriteLine("Interpretation of f:\n" + s.Model.FuncInterp(fd)); + Console.WriteLine("Interpretation of MyArray as Term:\n" + s.Model.FuncInterp(aex.FuncDecl)); + } + + /// + /// Prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)). + /// + /// This example demonstrates how to use the array theory. + public static void ArrayExample2(Context ctx) + { + Console.WriteLine("ArrayExample2"); + + Sort int_type = ctx.IntSort; + Sort array_type = ctx.MkArraySort(int_type, int_type); + + ArrayExpr a1 = (ArrayExpr)ctx.MkConst("a1", array_type); + ArrayExpr a2 = ctx.MkArrayConst("a2", int_type, int_type); + Expr i1 = ctx.MkConst("i1", int_type); + Expr i2 = ctx.MkConst("i2", int_type); + Expr i3 = ctx.MkConst("i3", int_type); + Expr v1 = ctx.MkConst("v1", int_type); + Expr v2 = ctx.MkConst("v2", int_type); + + Expr st1 = ctx.MkStore(a1, i1, v1); + Expr st2 = ctx.MkStore(a2, i2, v2); + + Expr sel1 = ctx.MkSelect(a1, i3); + Expr sel2 = ctx.MkSelect(a2, i3); + + /* create antecedent */ + BoolExpr antecedent = ctx.MkEq(st1, st2); + + /* create consequent: i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3) */ + BoolExpr consequent = ctx.MkOr(new BoolExpr[] { ctx.MkEq(i1, i3), ctx.MkEq(i2, i3), ctx.MkEq(sel1, sel2) }); + + /* prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) */ + BoolExpr thm = ctx.MkImplies(antecedent, consequent); + Console.WriteLine("prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))"); + Console.WriteLine("{0}", (thm)); + Prove(ctx, thm); + } + + /// + /// Show that distinct(a_0, ... , a_n) is + /// unsatisfiable when a_i's are arrays from boolean to + /// boolean and n > 4. + /// + /// This example also shows how to use the distinct construct. + public static void ArrayExample3(Context ctx) + { + Console.WriteLine("ArrayExample3"); + + for (int n = 2; n <= 5; n++) + { + Console.WriteLine("n = {0}", n); + + Sort bool_type = ctx.MkBoolSort(); + Sort array_type = ctx.MkArraySort(bool_type, bool_type); + Expr[] a = new Expr[n]; + + /* create arrays */ + for (int i = 0; i < n; i++) + { + a[i] = ctx.MkConst(String.Format("array_{0}", i), array_type); + } + + /* assert distinct(a[0], ..., a[n]) */ + BoolExpr d = ctx.MkDistinct(a); + Console.WriteLine("{0}", (d)); + + /* context is satisfiable if n < 5 */ + Model model = Check(ctx, d, n < 5 ? Status.SATISFIABLE : Status.UNSATISFIABLE); + if (n < 5) + { + for (int i = 0; i < n; i++) + { + Console.WriteLine("{0} = {1}", + a[i], + model.Evaluate(a[i])); + } + } + } + } + + /// + /// Sudoku solving example. + /// + static void SudokuExample(Context ctx) + { + Console.WriteLine("SudokuExample"); + + // 9x9 matrix of integer variables + IntExpr[][] X = new IntExpr[9][]; + for (uint i = 0; i < 9; i++) + { + X[i] = new IntExpr[9]; + for (uint j = 0; j < 9; j++) + X[i][j] = (IntExpr)ctx.MkConst(ctx.MkSymbol("x_" + (i + 1) + "_" + (j + 1)), ctx.IntSort); + } + + // each cell contains a value in {1, ..., 9} + Expr[][] cells_c = new Expr[9][]; + for (uint i = 0; i < 9; i++) + { + cells_c[i] = new BoolExpr[9]; + for (uint j = 0; j < 9; j++) + cells_c[i][j] = ctx.MkAnd(ctx.MkLe(ctx.MkInt(1), X[i][j]), + ctx.MkLe(X[i][j], ctx.MkInt(9))); + } + + // each row contains a digit at most once + BoolExpr[] rows_c = new BoolExpr[9]; + for (uint i = 0; i < 9; i++) + rows_c[i] = ctx.MkDistinct(X[i]); + + // each column contains a digit at most once + BoolExpr[] cols_c = new BoolExpr[9]; + for (uint j = 0; j < 9; j++) + cols_c[j] = ctx.MkDistinct(X[j]); + + // each 3x3 square contains a digit at most once + BoolExpr[][] sq_c = new BoolExpr[3][]; + for (uint i0 = 0; i0 < 3; i0++) + { + sq_c[i0] = new BoolExpr[3]; + for (uint j0 = 0; j0 < 3; j0++) + { + IntExpr[] square = new IntExpr[9]; + for (uint i = 0; i < 3; i++) + for (uint j = 0; j < 3; j++) + square[3 * i + j] = X[3 * i0 + i][3 * j0 + j]; + sq_c[i0][j0] = ctx.MkDistinct(square); + } + } + + BoolExpr sudoku_c = ctx.MkTrue(); + foreach (BoolExpr[] t in cells_c) + sudoku_c = ctx.MkAnd(ctx.MkAnd(t), sudoku_c); + sudoku_c = ctx.MkAnd(ctx.MkAnd(rows_c), sudoku_c); + sudoku_c = ctx.MkAnd(ctx.MkAnd(cols_c), sudoku_c); + foreach (BoolExpr[] t in sq_c) + sudoku_c = ctx.MkAnd(ctx.MkAnd(t), sudoku_c); + + // sudoku instance, we use '0' for empty cells + int[,] instance = {{0,0,0,0,9,4,0,3,0}, + {0,0,0,5,1,0,0,0,7}, + {0,8,9,0,0,0,0,4,0}, + {0,0,0,0,0,0,2,0,8}, + {0,6,0,2,0,1,0,5,0}, + {1,0,2,0,0,0,0,0,0}, + {0,7,0,0,0,0,5,2,0}, + {9,0,0,0,6,5,0,0,0}, + {0,4,0,9,7,0,0,0,0}}; + + BoolExpr instance_c = ctx.MkTrue(); + for (uint i = 0; i < 9; i++) + for (uint j = 0; j < 9; j++) + instance_c = ctx.MkAnd(instance_c, + (BoolExpr) + ctx.MkITE(ctx.MkEq(ctx.MkInt(instance[i, j]), ctx.MkInt(0)), + ctx.MkTrue(), + ctx.MkEq(X[i][j], ctx.MkInt(instance[i, j])))); + + Solver s = ctx.MkSolver(); + s.Assert(sudoku_c); + s.Assert(instance_c); + + if (s.Check() == Status.SATISFIABLE) + { + Model m = s.Model; + Expr[,] R = new Expr[9, 9]; + for (uint i = 0; i < 9; i++) + for (uint j = 0; j < 9; j++) + R[i, j] = m.Evaluate(X[i][j]); + Console.WriteLine("Sudoku solution:"); + for (uint i = 0; i < 9; i++) + { + for (uint j = 0; j < 9; j++) + Console.Write(" " + R[i, j]); + Console.WriteLine(); + } + } + else + { + Console.WriteLine("Failed to solve sudoku"); + throw new TestFailedException(); + } + } + + /// + /// A basic example of how to use quantifiers. + /// + static void QuantifierExample1(Context ctx) + { + Console.WriteLine("QuantifierExample"); + + Sort[] types = new Sort[3]; + IntExpr[] xs = new IntExpr[3]; + Symbol[] names = new Symbol[3]; + IntExpr[] vars = new IntExpr[3]; + + for (uint j = 0; j < 3; j++) + { + types[j] = ctx.IntSort; + names[j] = ctx.MkSymbol(String.Format("x_{0}", j)); + xs[j] = (IntExpr)ctx.MkConst(names[j], types[j]); + vars[j] = (IntExpr)ctx.MkBound(2 - j, types[j]); // <-- vars reversed! + } + + Expr body_vars = ctx.MkAnd(ctx.MkEq(ctx.MkAdd(vars[0], ctx.MkInt(1)), ctx.MkInt(2)), + ctx.MkEq(ctx.MkAdd(vars[1], ctx.MkInt(2)), + ctx.MkAdd(vars[2], ctx.MkInt(3)))); + + Expr body_const = ctx.MkAnd(ctx.MkEq(ctx.MkAdd(xs[0], ctx.MkInt(1)), ctx.MkInt(2)), + ctx.MkEq(ctx.MkAdd(xs[1], ctx.MkInt(2)), + ctx.MkAdd(xs[2], ctx.MkInt(3)))); + + Expr x = ctx.MkForall(types, names, body_vars, 1, null, null, ctx.MkSymbol("Q1"), ctx.MkSymbol("skid1")); + Console.WriteLine("Quantifier X: " + x.ToString()); + + Expr y = ctx.MkForall(xs, body_const, 1, null, null, ctx.MkSymbol("Q2"), ctx.MkSymbol("skid2")); + Console.WriteLine("Quantifier Y: " + y.ToString()); + } + + static void QuantifierExample2(Context ctx) + { + + Console.WriteLine("QuantifierExample2"); + + Expr q1, q2; + FuncDecl f = ctx.MkFuncDecl("f", ctx.IntSort, ctx.IntSort); + FuncDecl g = ctx.MkFuncDecl("g", ctx.IntSort, ctx.IntSort); + + // Quantifier with Exprs as the bound variables. + { + Expr x = ctx.MkConst("x", ctx.IntSort); + Expr y = ctx.MkConst("y", ctx.IntSort); + Expr f_x = ctx.MkApp(f, x); + Expr f_y = ctx.MkApp(f, y); + Expr g_y = ctx.MkApp(g, y); + Pattern[] pats = new Pattern[] { ctx.MkPattern(new Expr[] { f_x, g_y }) }; + Expr[] no_pats = new Expr[] { f_y }; + Expr[] bound = new Expr[2] { x, y }; + Expr body = ctx.MkAnd(ctx.MkEq(f_x, f_y), ctx.MkEq(f_y, g_y)); + + q1 = ctx.MkForall(bound, body, 1, null, no_pats, ctx.MkSymbol("q"), ctx.MkSymbol("sk")); + + Console.WriteLine("{0}", q1); + } + + // Quantifier with de-Brujin indices. + { + Expr x = ctx.MkBound(1, ctx.IntSort); + Expr y = ctx.MkBound(0, ctx.IntSort); + Expr f_x = ctx.MkApp(f, x); + Expr f_y = ctx.MkApp(f, y); + Expr g_y = ctx.MkApp(g, y); + Pattern[] pats = new Pattern[] { ctx.MkPattern(new Expr[] { f_x, g_y }) }; + Expr[] no_pats = new Expr[] { f_y }; + Symbol[] names = new Symbol[] { ctx.MkSymbol("x"), ctx.MkSymbol("y") }; + Sort[] sorts = new Sort[] { ctx.IntSort, ctx.IntSort }; + Expr body = ctx.MkAnd(ctx.MkEq(f_x, f_y), ctx.MkEq(f_y, g_y)); + + q2 = ctx.MkForall(sorts, names, body, 1, + null, // pats, + no_pats, + ctx.MkSymbol("q"), + ctx.MkSymbol("sk") + ); + Console.WriteLine("{0}", q2); + } + + Console.WriteLine("{0}", (q1.Equals(q2))); + } + + /// + /// Prove that f(x, y) = f(w, v) implies y = v when + /// f is injective in the second argument. + /// + public static void QuantifierExample3() + { + Console.WriteLine("QuantifierExample3"); + + + Dictionary cfg = new Dictionary() { + { "MBQI", "false" }, + { "PROOF_MODE", "2" }, + { "AUTO_CONFIG", "false" } + }; + + /* If quantified formulas are asserted in a logical context, then + the model produced by Z3 should be viewed as a potential model. */ + + using (Context ctx = new Context(cfg)) + { + /* declare function f */ + Sort I = ctx.IntSort; + FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); + + /* f is injective in the second argument. */ + BoolExpr inj = InjAxiom(ctx, f, 1); + + /* create x, y, v, w, fxy, fwv */ + Expr x = ctx.MkIntConst("x"); + Expr y = ctx.MkIntConst("y"); + Expr v = ctx.MkIntConst("v"); + Expr w = ctx.MkIntConst("w"); + Expr fxy = ctx.MkApp(f, x, y); + Expr fwv = ctx.MkApp(f, w, v); + + /* f(x, y) = f(w, v) */ + BoolExpr p1 = ctx.MkEq(fxy, fwv); + + /* prove f(x, y) = f(w, v) implies y = v */ + BoolExpr p2 = ctx.MkEq(y, v); + Prove(ctx, p2, inj, p1); + + /* disprove f(x, y) = f(w, v) implies x = w */ + BoolExpr p3 = ctx.MkEq(x, w); + Disprove(ctx, p3, inj, p1); + } + } + + /// + /// Prove that f(x, y) = f(w, v) implies y = v when + /// f is injective in the second argument. + /// + public static void QuantifierExample4() + { + Console.WriteLine("QuantifierExample4"); + + Dictionary cfg = new Dictionary() { + { "MBQI", "false" }, + { "PROOF_MODE", "2" }, + { "AUTO_CONFIG","false" }}; + + + /* If quantified formulas are asserted in a logical context, then + the model produced by Z3 should be viewed as a potential model. */ + + using (Context ctx = new Context(cfg)) + { + /* declare function f */ + Sort I = ctx.IntSort; + FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); + + /* f is injective in the second argument. */ + BoolExpr inj = InjAxiomAbs(ctx, f, 1); + + /* create x, y, v, w, fxy, fwv */ + Expr x = ctx.MkIntConst("x"); + Expr y = ctx.MkIntConst("y"); + Expr v = ctx.MkIntConst("v"); + Expr w = ctx.MkIntConst("w"); + Expr fxy = ctx.MkApp(f, x, y); + Expr fwv = ctx.MkApp(f, w, v); + + /* f(x, y) = f(w, v) */ + BoolExpr p1 = ctx.MkEq(fxy, fwv); + + /* prove f(x, y) = f(w, v) implies y = v */ + BoolExpr p2 = ctx.MkEq(y, v); + Prove(ctx, p2, inj, p1); + + /* disprove f(x, y) = f(w, v) implies x = w */ + BoolExpr p3 = ctx.MkEq(x, w); + Disprove(ctx, p3, inj, p1); + } + } + + /// + /// Some basic tests. + /// + static void BasicTests(Context ctx) + { + Console.WriteLine("BasicTests"); + + Symbol qi = ctx.MkSymbol(1); + Symbol fname = ctx.MkSymbol("f"); + Symbol x = ctx.MkSymbol("x"); + Symbol y = ctx.MkSymbol("y"); + + Sort bs = ctx.MkBoolSort(); + + Sort[] domain = { bs, bs }; + FuncDecl f = ctx.MkFuncDecl(fname, domain, bs); + Expr fapp = ctx.MkApp(f, ctx.MkConst(x, bs), ctx.MkConst(y, bs)); + + Expr[] fargs2 = { ctx.MkFreshConst("cp", bs) }; + Sort[] domain2 = { bs }; + Expr fapp2 = ctx.MkApp(ctx.MkFreshFuncDecl("fp", domain2, bs), fargs2); + + BoolExpr trivial_eq = ctx.MkEq(fapp, fapp); + BoolExpr nontrivial_eq = ctx.MkEq(fapp, fapp2); + + Goal g = ctx.MkGoal(true, false, true); + g.Assert(trivial_eq); + g.Assert(nontrivial_eq); + Console.WriteLine("Goal: " + g); + + Solver solver = ctx.MkSolver(); + + foreach (BoolExpr a in g.Formulas) + solver.Assert(a); + + if (solver.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + + ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g); + if (ar.NumSubgoals == 1 && (ar.Subgoals[0].IsDecidedSat || ar.Subgoals[0].IsDecidedUnsat)) + throw new TestFailedException(); + + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) + throw new TestFailedException(); + + g.Assert(ctx.MkEq(ctx.MkNumeral(1, ctx.MkBitVecSort(32)), + ctx.MkNumeral(2, ctx.MkBitVecSort(32)))); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + + Goal g2 = ctx.MkGoal(true, true, false); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) + throw new TestFailedException(); + + g2 = ctx.MkGoal(true, true, false); + g2.Assert(ctx.MkFalse()); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + Goal g3 = ctx.MkGoal(true, true, false); + Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort); + Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort); + g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort))); + g3.Assert(ctx.MkEq(yc, ctx.MkNumeral(2, ctx.IntSort))); + BoolExpr constr = ctx.MkEq(xc, yc); + g3.Assert(constr); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g3); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + ModelConverterTest(ctx); + + // Real num/den test. + RatNum rn = ctx.MkReal(42, 43); + Expr inum = rn.Numerator; + Expr iden = rn.Denominator; + Console.WriteLine("Numerator: " + inum + " Denominator: " + iden); + if (inum.ToString() != "42" || iden.ToString() != "43") + throw new TestFailedException(); + + if (rn.ToDecimalString(3) != "0.976?") + throw new TestFailedException(); + + BigIntCheck(ctx, ctx.MkReal("-1231231232/234234333")); + BigIntCheck(ctx, ctx.MkReal("-123123234234234234231232/234234333")); + BigIntCheck(ctx, ctx.MkReal("-234234333")); + BigIntCheck(ctx, ctx.MkReal("234234333/2")); + + + string bn = "1234567890987654321"; + + if (ctx.MkInt(bn).BigInteger.ToString() != bn) + throw new TestFailedException(); + + if (ctx.MkBV(bn, 128).BigInteger.ToString() != bn) + throw new TestFailedException(); + + if (ctx.MkBV(bn, 32).BigInteger.ToString() == bn) + throw new TestFailedException(); + + // Error handling test. + try + { + Expr plus_ri = ctx.MkAdd(ctx.MkInt(1), ctx.MkReal(2)); + throw new TestFailedException(); // unreachable + } + catch (Z3Exception) + { + } + } + + /// + /// Some basic expression casting tests. + /// + static void CastingTest(Context ctx) + { + Console.WriteLine("CastingTest"); + + Sort[] domain = { ctx.BoolSort, ctx.BoolSort }; + FuncDecl f = ctx.MkFuncDecl("f", domain, ctx.BoolSort); + + AST upcast = ctx.MkFuncDecl(ctx.MkSymbol("q"), domain, ctx.BoolSort); + + try + { + FuncDecl downcast = (FuncDecl)f; // OK + } + catch (InvalidCastException) + { + throw new TestFailedException(); + } + + try + { + Expr uc = (Expr)upcast; + throw new TestFailedException(); // should not be reachable! + } + catch (InvalidCastException) + { + } + + Symbol s = ctx.MkSymbol(42); + IntSymbol si = s as IntSymbol; + if (si == null) throw new TestFailedException(); + try + { + IntSymbol si2 = (IntSymbol)s; + } + catch (InvalidCastException) + { + throw new TestFailedException(); + } + + s = ctx.MkSymbol("abc"); + StringSymbol ss = s as StringSymbol; + if (ss == null) throw new TestFailedException(); + try + { + StringSymbol ss2 = (StringSymbol)s; + } + catch (InvalidCastException) + { + throw new TestFailedException(); + } + try + { + IntSymbol si2 = (IntSymbol)s; + throw new TestFailedException(); // unreachable + } + catch + { + } + + Sort srt = ctx.MkBitVecSort(32); + BitVecSort bvs = null; + try + { + bvs = (BitVecSort)srt; + } + catch (InvalidCastException) + { + throw new TestFailedException(); + } + + if (bvs.Size != 32) + throw new TestFailedException(); + + Expr q = ctx.MkAdd(ctx.MkInt(1), ctx.MkInt(2)); + Expr q2 = q.Args[1]; + Sort qs = q2.Sort; + if (qs as IntSort == null) + throw new TestFailedException(); + try + { + IntSort isrt = (IntSort)qs; + } + catch (InvalidCastException) + { + throw new TestFailedException(); + } + + AST a = ctx.MkInt(42); + Expr ae = a as Expr; + if (ae == null) throw new TestFailedException(); + ArithExpr aae = a as ArithExpr; + if (aae == null) throw new TestFailedException(); + IntExpr aie = a as IntExpr; + if (aie == null) throw new TestFailedException(); + IntNum ain = a as IntNum; + if (ain == null) throw new TestFailedException(); + + + Expr[][] earr = new Expr[2][]; + earr[0] = new Expr[2]; + earr[1] = new Expr[2]; + earr[0][0] = ctx.MkTrue(); + earr[0][1] = ctx.MkTrue(); + earr[1][0] = ctx.MkFalse(); + earr[1][1] = ctx.MkFalse(); + foreach (Expr[] ea in earr) + foreach (Expr e in ea) + { + try + { + Expr ns = ctx.MkNot((BoolExpr)e); + BoolExpr ens = (BoolExpr)ns; + } + catch (InvalidCastException) + { + throw new TestFailedException(); + } + } + } + + /// + /// Shows how to read an SMT1 file. + /// + static void SMT1FileTest(string filename) + { + Console.Write("SMT File test "); + + using (Context ctx = new Context(new Dictionary() { { "MODEL", "true" } })) + { + ctx.ParseSMTLIBFile(filename); + + BoolExpr a = ctx.MkAnd(ctx.SMTLIBFormulas); + Console.WriteLine("read formula: " + a); + } + } + + /// + /// Shows how to read an SMT2 file. + /// + static void SMT2FileTest(string filename) + { + System.DateTime before = System.DateTime.Now; + + Console.WriteLine("SMT2 File test "); + System.GC.Collect(); + + using (Context ctx = new Context(new Dictionary() { { "MODEL", "true" } })) + { + Expr a = ctx.ParseSMTLIB2File(filename); + + Console.WriteLine("SMT2 file read time: " + (System.DateTime.Now - before).TotalSeconds + " sec"); + + // Iterate over the formula. + + Queue q = new Queue(); + q.Enqueue(a); + uint cnt = 0; + while (q.Count > 0) + { + AST cur = (AST)q.Dequeue(); + cnt++; + + // This here ... + if (cur is Expr) + if (!(cur.IsVar)) + foreach (Expr c in ((Expr)cur).Args) + q.Enqueue(c); + + // Takes the same time as this: + //switch ((cur).ASTKind) + //{ + // case Z3_ast_kind.Z3_APP_AST: + // foreach (Expr e in ((Expr)cur).Args) + // q.Enqueue(e); + // break; + // case Z3_ast_kind.Z3_QUANTIFIER_AST: + // q.Enqueue(((Quantifier)cur).Args[0]); + // break; + // case Z3_ast_kind.Z3_VAR_AST: break; + // case Z3_ast_kind.Z3_NUMERAL_AST: break; + // case Z3_ast_kind.Z3_FUNC_DECL_AST: break; + // case Z3_ast_kind.Z3_SORT_AST: break; + //} + } + Console.WriteLine(cnt + " ASTs"); + } + + Console.WriteLine("SMT2 file test took " + (System.DateTime.Now - before).TotalSeconds + " sec"); + } + + /// + /// Shows how to use Solver(logic) + /// + /// + static void LogicExample(Context ctx) + { + Console.WriteLine("LogicTest"); + + Context.ToggleWarningMessages(true); + + BitVecSort bvs = ctx.MkBitVecSort(32); + Expr x = ctx.MkConst("x", bvs); + Expr y = ctx.MkConst("y", bvs); + BoolExpr eq = ctx.MkEq(x, y); + + // Use a solver for QF_BV + Solver s = ctx.MkSolver("QF_BV"); + s.Assert(eq); + Status res = s.Check(); + Console.WriteLine("solver result: " + res); + + + // Or perhaps a tactic for QF_BV + Goal g = ctx.MkGoal(true, false, true); + g.Assert(eq); + + Tactic t = ctx.MkTactic("qfbv"); + ApplyResult ar = t.Apply(g); + Console.WriteLine("tactic result: " + ar); + + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) + throw new TestFailedException(); + } + + /// + /// Demonstrates how to use the ParOr tactic. + /// + static void ParOrExample(Context ctx) + { + Console.WriteLine("ParOrExample"); + + BitVecSort bvs = ctx.MkBitVecSort(32); + Expr x = ctx.MkConst("x", bvs); + Expr y = ctx.MkConst("y", bvs); + BoolExpr q = ctx.MkEq(x, y); + + Goal g = ctx.MkGoal(true, false, true); + g.Assert(q); + + Tactic t1 = ctx.MkTactic("qfbv"); + Tactic t2 = ctx.MkTactic("qfbv"); + Tactic p = ctx.ParOr(t1, t2); + + ApplyResult ar = p.Apply(g); + + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) + throw new TestFailedException(); + } + + static void BigIntCheck(Context ctx, RatNum r) + { + Console.WriteLine("Num: " + r.BigIntNumerator); + Console.WriteLine("Den: " + r.BigIntDenominator); + } + + /// + /// Find a model for x xor y. + /// + public static void FindModelExample1(Context ctx) + { + Console.WriteLine("FindModelExample1"); + + BoolExpr x = ctx.MkBoolConst("x"); + BoolExpr y = ctx.MkBoolConst("y"); + BoolExpr x_xor_y = ctx.MkXor(x, y); + + Model model = Check(ctx, x_xor_y, Status.SATISFIABLE); + Console.WriteLine("x = {0}, y = {1}", + model.Evaluate(x), + model.Evaluate(y)); + } + + /// + /// Find a model for x < y + 1, x > 2. + /// Then, assert not(x = y), and find another model. + /// + public static void FindModelExample2(Context ctx) + { + Console.WriteLine("find_model_example2"); + + IntExpr x = ctx.MkIntConst("x"); + IntExpr y = ctx.MkIntConst("y"); + IntExpr one = ctx.MkInt(1); + IntExpr two = ctx.MkInt(2); + + ArithExpr y_plus_one = ctx.MkAdd(y, one); + + BoolExpr c1 = ctx.MkLt(x, y_plus_one); + BoolExpr c2 = ctx.MkGt(x, two); + + BoolExpr q = ctx.MkAnd(c1, c2); + + Console.WriteLine("model for: x < y + 1, x > 2"); + Model model = Check(ctx, q, Status.SATISFIABLE); + Console.WriteLine("x = {0}, y = {1}", + (model.Evaluate(x)), + (model.Evaluate(y))); + + /* assert not(x = y) */ + BoolExpr x_eq_y = ctx.MkEq(x, y); + BoolExpr c3 = ctx.MkNot(x_eq_y); + + q = ctx.MkAnd(q, c3); + + Console.WriteLine("model for: x < y + 1, x > 2, not(x = y)"); + model = Check(ctx, q, Status.SATISFIABLE); + Console.WriteLine("x = {0}, y = {1}", + (model.Evaluate(x)), + (model.Evaluate(y))); + } + + /// + /// Prove x = y implies g(x) = g(y), and + /// disprove x = y implies g(g(x)) = g(y). + /// + /// This function demonstrates how to create uninterpreted + /// types and functions. + public static void ProveExample1(Context ctx) + { + Console.WriteLine("ProveExample1"); + + /* create uninterpreted type. */ + Sort U = ctx.MkUninterpretedSort(ctx.MkSymbol("U")); + + /* declare function g */ + FuncDecl g = ctx.MkFuncDecl("g", U, U); + + /* create x and y */ + Expr x = ctx.MkConst("x", U); + Expr y = ctx.MkConst("y", U); + /* create g(x), g(y) */ + Expr gx = g[x]; + Expr gy = g[y]; + + /* assert x = y */ + BoolExpr eq = ctx.MkEq(x, y); + + /* prove g(x) = g(y) */ + BoolExpr f = ctx.MkEq(gx, gy); + Console.WriteLine("prove: x = y implies g(x) = g(y)"); + Prove(ctx, ctx.MkImplies(eq, f)); + + /* create g(g(x)) */ + Expr ggx = g[gx]; + + /* disprove g(g(x)) = g(y) */ + f = ctx.MkEq(ggx, gy); + Console.WriteLine("disprove: x = y implies g(g(x)) = g(y)"); + Disprove(ctx, ctx.MkImplies(eq, f)); + + + /* Print the model using the custom model printer */ + Model m = Check(ctx, ctx.MkNot(f), Status.SATISFIABLE); + Console.WriteLine(m); + } + + /// + /// Prove not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 . + /// Then, show that z < -1 is not implied. + /// + /// This example demonstrates how to combine uninterpreted functions + /// and arithmetic. + public static void ProveExample2(Context ctx) + { + Console.WriteLine("ProveExample2"); + + /* declare function g */ + Sort I = ctx.IntSort; + + FuncDecl g = ctx.MkFuncDecl("g", I, I); + + /* create x, y, and z */ + IntExpr x = ctx.MkIntConst("x"); + IntExpr y = ctx.MkIntConst("y"); + IntExpr z = ctx.MkIntConst("z"); + + /* create gx, gy, gz */ + Expr gx = ctx.MkApp(g, x); + Expr gy = ctx.MkApp(g, y); + Expr gz = ctx.MkApp(g, z); + + /* create zero */ + IntExpr zero = ctx.MkInt(0); + + /* assert not(g(g(x) - g(y)) = g(z)) */ + ArithExpr gx_gy = ctx.MkSub((IntExpr)gx, (IntExpr)gy); + Expr ggx_gy = ctx.MkApp(g, gx_gy); + BoolExpr eq = ctx.MkEq(ggx_gy, gz); + BoolExpr c1 = ctx.MkNot(eq); + + /* assert x + z <= y */ + ArithExpr x_plus_z = ctx.MkAdd(x, z); + BoolExpr c2 = ctx.MkLe(x_plus_z, y); + + /* assert y <= x */ + BoolExpr c3 = ctx.MkLe(y, x); + + /* prove z < 0 */ + BoolExpr f = ctx.MkLt(z, zero); + Console.WriteLine("prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0"); + Prove(ctx, f, c1, c2, c3); + + /* disprove z < -1 */ + IntExpr minus_one = ctx.MkInt(-1); + f = ctx.MkLt(z, minus_one); + Console.WriteLine("disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1"); + Disprove(ctx, f, c1, c2, c3); + } + + /// + /// Show how push & pop can be used to create "backtracking" points. + /// + /// This example also demonstrates how big numbers can be + /// created in ctx. + public static void PushPopExample1(Context ctx) + { + Console.WriteLine("PushPopExample1"); + + /* create a big number */ + IntSort int_type = ctx.IntSort; + IntExpr big_number = ctx.MkInt("1000000000000000000000000000000000000000000000000000000"); + + /* create number 3 */ + IntExpr three = (IntExpr)ctx.MkNumeral("3", int_type); + + /* create x */ + IntExpr x = ctx.MkIntConst("x"); + + Solver solver = ctx.MkSolver(); + + /* assert x >= "big number" */ + BoolExpr c1 = ctx.MkGe(x, big_number); + Console.WriteLine("assert: x >= 'big number'"); + solver.Assert(c1); + + /* create a backtracking point */ + Console.WriteLine("push"); + solver.Push(); + + /* assert x <= 3 */ + BoolExpr c2 = ctx.MkLe(x, three); + Console.WriteLine("assert: x <= 3"); + solver.Assert(c2); + + /* context is inconsistent at this point */ + if (solver.Check() != Status.UNSATISFIABLE) + throw new TestFailedException(); + + /* backtrack: the constraint x <= 3 will be removed, since it was + asserted after the last ctx.Push. */ + Console.WriteLine("pop"); + solver.Pop(1); + + /* the context is consistent again. */ + if (solver.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + + /* new constraints can be asserted... */ + + /* create y */ + IntExpr y = ctx.MkIntConst("y"); + + /* assert y > x */ + BoolExpr c3 = ctx.MkGt(y, x); + Console.WriteLine("assert: y > x"); + solver.Assert(c3); + + /* the context is still consistent. */ + if (solver.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + } + + /// + /// Tuples. + /// + /// Check that the projection of a tuple + /// returns the corresponding element. + public static void TupleExample(Context ctx) + { + Console.WriteLine("TupleExample"); + + Sort int_type = ctx.IntSort; + TupleSort tuple = ctx.MkTupleSort( + ctx.MkSymbol("mk_tuple"), // name of tuple constructor + new Symbol[] { ctx.MkSymbol("first"), ctx.MkSymbol("second") }, // names of projection operators + new Sort[] { int_type, int_type } // types of projection operators + ); + FuncDecl first = tuple.FieldDecls[0]; // declarations are for projections + FuncDecl second = tuple.FieldDecls[1]; + Expr x = ctx.MkConst("x", int_type); + Expr y = ctx.MkConst("y", int_type); + Expr n1 = tuple.MkDecl[x, y]; + Expr n2 = first[n1]; + BoolExpr n3 = ctx.MkEq(x, n2); + Console.WriteLine("Tuple example: {0}", n3); + Prove(ctx, n3); + } + + /// + /// Simple bit-vector example. + /// + /// + /// This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers + /// + public static void BitvectorExample1(Context ctx) + { + Console.WriteLine("BitvectorExample1"); + + Sort bv_type = ctx.MkBitVecSort(32); + BitVecExpr x = (BitVecExpr)ctx.MkConst("x", bv_type); + BitVecNum zero = (BitVecNum)ctx.MkNumeral("0", bv_type); + BitVecNum ten = ctx.MkBV(10, 32); + BitVecExpr x_minus_ten = ctx.MkBVSub(x, ten); + /* bvsle is signed less than or equal to */ + BoolExpr c1 = ctx.MkBVSLE(x, ten); + BoolExpr c2 = ctx.MkBVSLE(x_minus_ten, zero); + BoolExpr thm = ctx.MkIff(c1, c2); + Console.WriteLine("disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers"); + Disprove(ctx, thm); + } + + /// + /// Find x and y such that: x ^ y - 103 == x * y + /// + public static void BitvectorExample2(Context ctx) + { + Console.WriteLine("BitvectorExample2"); + + /* construct x ^ y - 103 == x * y */ + Sort bv_type = ctx.MkBitVecSort(32); + BitVecExpr x = ctx.MkBVConst("x", 32); + BitVecExpr y = ctx.MkBVConst("y", 32); + BitVecExpr x_xor_y = ctx.MkBVXOR(x, y); + BitVecExpr c103 = (BitVecNum)ctx.MkNumeral("103", bv_type); + BitVecExpr lhs = ctx.MkBVSub(x_xor_y, c103); + BitVecExpr rhs = ctx.MkBVMul(x, y); + BoolExpr ctr = ctx.MkEq(lhs, rhs); + + Console.WriteLine("find values of x and y, such that x ^ y - 103 == x * y"); + + /* find a model (i.e., values for x an y that satisfy the constraint */ + Model m = Check(ctx, ctr, Status.SATISFIABLE); + Console.WriteLine(m); + } + + /// + /// Demonstrates how to use the SMTLIB parser. + /// + public static void ParserExample1(Context ctx) + { + Console.WriteLine("ParserExample1"); + + ctx.ParseSMTLIBString("(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))"); + foreach (BoolExpr f in ctx.SMTLIBFormulas) + Console.WriteLine("formula {0}", f); + + Model m = Check(ctx, ctx.MkAnd(ctx.SMTLIBFormulas), Status.SATISFIABLE); + } + + /// + /// Demonstrates how to initialize the parser symbol table. + /// + public static void ParserExample2(Context ctx) + { + Console.WriteLine("ParserExample2"); + + Symbol[] declNames = { ctx.MkSymbol("a"), ctx.MkSymbol("b") }; + FuncDecl a = ctx.MkConstDecl(declNames[0], ctx.MkIntSort()); + FuncDecl b = ctx.MkConstDecl(declNames[1], ctx.MkIntSort()); + FuncDecl[] decls = new FuncDecl[] { a, b }; + + ctx.ParseSMTLIBString("(benchmark tst :formula (> a b))", + null, null, declNames, decls); + BoolExpr f = ctx.SMTLIBFormulas[0]; + Console.WriteLine("formula: {0}", f); + Check(ctx, f, Status.SATISFIABLE); + } + + /// + /// Demonstrates how to initialize the parser symbol table. + /// + public static void ParserExample3(Context ctx) + { + Console.WriteLine("ParserExample3"); + + /* declare function g */ + Sort I = ctx.MkIntSort(); + FuncDecl g = ctx.MkFuncDecl("g", new Sort[] { I, I }, I); + + BoolExpr ca = CommAxiom(ctx, g); + + ctx.ParseSMTLIBString("(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (gg x 0) (gg 0 y)))))", + null, null, + new Symbol[] { ctx.MkSymbol("gg") }, + new FuncDecl[] { g }); + + BoolExpr thm = ctx.SMTLIBFormulas[0]; + Console.WriteLine("formula: {0}", thm); + Prove(ctx, thm, ca); + } + + /// + /// Display the declarations, assumptions and formulas in a SMT-LIB string. + /// + public static void ParserExample4(Context ctx) + { + Console.WriteLine("ParserExample4"); + + ctx.ParseSMTLIBString + ("(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))"); + foreach (var decl in ctx.SMTLIBDecls) + { + Console.WriteLine("Declaration: {0}", decl); + } + foreach (var f in ctx.SMTLIBAssumptions) + { + Console.WriteLine("Assumption: {0}", f); + } + foreach (var f in ctx.SMTLIBFormulas) + { + Console.WriteLine("Formula: {0}", f); + } + } + + /// + /// Demonstrates how to handle parser errors using Z3 error handling support. + /// + /// + public static void ParserExample5(Context ctx) + { + Console.WriteLine("ParserExample5"); + + try + { + ctx.ParseSMTLIBString( + /* the following string has a parsing error: missing parenthesis */ + "(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))"); + } + catch (Z3Exception e) + { + Console.WriteLine("Z3 error: {0}", e); + } + } + + /// + /// Create an ite-Expr (if-then-else Exprs). + /// + public static void ITEExample(Context ctx) + { + Console.WriteLine("ITEExample"); + + BoolExpr f = ctx.MkFalse(); + Expr one = ctx.MkInt(1); + Expr zero = ctx.MkInt(0); + Expr ite = ctx.MkITE(f, one, zero); + + Console.WriteLine("Expr: {0}", ite); + } + + /// + /// Create an enumeration data type. + /// + public static void EnumExample(Context ctx) + { + Console.WriteLine("EnumExample"); + + Symbol name = ctx.MkSymbol("fruit"); + + EnumSort fruit = ctx.MkEnumSort(ctx.MkSymbol("fruit"), new Symbol[] { ctx.MkSymbol("apple"), ctx.MkSymbol("banana"), ctx.MkSymbol("orange") }); + + Console.WriteLine("{0}", (fruit.Consts[0])); + Console.WriteLine("{0}", (fruit.Consts[1])); + Console.WriteLine("{0}", (fruit.Consts[2])); + + Console.WriteLine("{0}", (fruit.TesterDecls[0])); + Console.WriteLine("{0}", (fruit.TesterDecls[1])); + Console.WriteLine("{0}", (fruit.TesterDecls[2])); + + Expr apple = fruit.Consts[0]; + Expr banana = fruit.Consts[1]; + Expr orange = fruit.Consts[2]; + + /* Apples are different from oranges */ + Prove(ctx, ctx.MkNot(ctx.MkEq(apple, orange))); + + /* Apples pass the apple test */ + Prove(ctx, (BoolExpr)ctx.MkApp(fruit.TesterDecls[0], apple)); + + /* Oranges fail the apple test */ + Disprove(ctx, (BoolExpr)ctx.MkApp(fruit.TesterDecls[0], orange)); + Prove(ctx, (BoolExpr)ctx.MkNot((BoolExpr)ctx.MkApp(fruit.TesterDecls[0], orange))); + + Expr fruity = ctx.MkConst("fruity", fruit); + + /* If something is fruity, then it is an apple, banana, or orange */ + + Prove(ctx, ctx.MkOr(new BoolExpr[] { ctx.MkEq(fruity, apple), ctx.MkEq(fruity, banana), ctx.MkEq(fruity, orange) })); + } + + /// + /// Create a list datatype. + /// + public static void ListExample(Context ctx) + { + Console.WriteLine("ListExample"); + + Sort int_ty; + ListSort int_list; + Expr nil, l1, l2, x, y, u, v; + BoolExpr fml, fml1; + + int_ty = ctx.MkIntSort(); + + int_list = ctx.MkListSort(ctx.MkSymbol("int_list"), int_ty); + + nil = ctx.MkConst(int_list.NilDecl); + l1 = ctx.MkApp(int_list.ConsDecl, ctx.MkInt(1), nil); + l2 = ctx.MkApp(int_list.ConsDecl, ctx.MkInt(2), nil); + + /* nil != cons(1, nil) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(nil, l1))); + + /* cons(2,nil) != cons(1, nil) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(l1, l2))); + + /* cons(x,nil) = cons(y, nil) => x = y */ + x = ctx.MkConst("x", int_ty); + y = ctx.MkConst("y", int_ty); + l1 = ctx.MkApp(int_list.ConsDecl, x, nil); + l2 = ctx.MkApp(int_list.ConsDecl, y, nil); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y))); + + /* cons(x,u) = cons(x, v) => u = v */ + u = ctx.MkConst("u", int_list); + v = ctx.MkConst("v", int_list); + l1 = ctx.MkApp(int_list.ConsDecl, x, u); + l2 = ctx.MkApp(int_list.ConsDecl, y, v); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v))); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y))); + + /* is_nil(u) or is_cons(u) */ + Prove(ctx, ctx.MkOr((BoolExpr)ctx.MkApp(int_list.IsNilDecl, u), + (BoolExpr)ctx.MkApp(int_list.IsConsDecl, u))); + + /* occurs check u != cons(x,u) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1))); + + /* destructors: is_cons(u) => u = cons(head(u),tail(u)) */ + fml1 = ctx.MkEq(u, ctx.MkApp(int_list.ConsDecl, ctx.MkApp(int_list.HeadDecl, u), + ctx.MkApp(int_list.TailDecl, u))); + fml = ctx.MkImplies((BoolExpr)ctx.MkApp(int_list.IsConsDecl, u), fml1); + Console.WriteLine("Formula {0}", fml); + + Prove(ctx, fml); + + Disprove(ctx, fml1); + } + + /// + /// Create a binary tree datatype. + /// + public static void TreeExample(Context ctx) + { + Console.WriteLine("TreeExample"); + + Sort cell; + FuncDecl nil_decl, is_nil_decl, cons_decl, is_cons_decl, car_decl, cdr_decl; + Expr nil, l1, l2, x, y, u, v; + BoolExpr fml, fml1; + string[] head_tail = new string[] { "car", "cdr" }; + Sort[] sorts = new Sort[] { null, null }; + uint[] sort_refs = new uint[] { 0, 0 }; + Constructor nil_con, cons_con; + + nil_con = ctx.MkConstructor("nil", "is_nil", null, null, null); + cons_con = ctx.MkConstructor("cons", "is_cons", head_tail, sorts, sort_refs); + Constructor[] constructors = new Constructor[] { nil_con, cons_con }; + + cell = ctx.MkDatatypeSort("cell", constructors); + + nil_decl = nil_con.ConstructorDecl; + is_nil_decl = nil_con.TesterDecl; + cons_decl = cons_con.ConstructorDecl; + is_cons_decl = cons_con.TesterDecl; + FuncDecl[] cons_accessors = cons_con.AccessorDecls; + car_decl = cons_accessors[0]; + cdr_decl = cons_accessors[1]; + + nil = ctx.MkConst(nil_decl); + l1 = ctx.MkApp(cons_decl, nil, nil); + l2 = ctx.MkApp(cons_decl, l1, nil); + + /* nil != cons(nil, nil) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(nil, l1))); + + /* cons(x,u) = cons(x, v) => u = v */ + u = ctx.MkConst("u", cell); + v = ctx.MkConst("v", cell); + x = ctx.MkConst("x", cell); + y = ctx.MkConst("y", cell); + l1 = ctx.MkApp(cons_decl, x, u); + l2 = ctx.MkApp(cons_decl, y, v); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v))); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y))); + + /* is_nil(u) or is_cons(u) */ + Prove(ctx, ctx.MkOr((BoolExpr)ctx.MkApp(is_nil_decl, u), (BoolExpr)ctx.MkApp(is_cons_decl, u))); + + /* occurs check u != cons(x,u) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1))); + + /* destructors: is_cons(u) => u = cons(car(u),cdr(u)) */ + fml1 = ctx.MkEq(u, ctx.MkApp(cons_decl, ctx.MkApp(car_decl, u), ctx.MkApp(cdr_decl, u))); + fml = ctx.MkImplies((BoolExpr)ctx.MkApp(is_cons_decl, u), fml1); + Console.WriteLine("Formula {0}", fml); + Prove(ctx, fml); + + Disprove(ctx, fml1); + } + + /// + /// Create a forest of trees. + /// + /// + /// forest ::= nil | cons(tree, forest) + /// tree ::= nil | cons(forest, forest) + /// + public static void ForestExample(Context ctx) + { + Console.WriteLine("ForestExample"); + + Sort tree, forest; + FuncDecl nil1_decl, is_nil1_decl, cons1_decl, is_cons1_decl, car1_decl, cdr1_decl; + FuncDecl nil2_decl, is_nil2_decl, cons2_decl, is_cons2_decl, car2_decl, cdr2_decl; + Expr nil1, nil2, t1, t2, t3, t4, f1, f2, f3, l1, l2, x, y, u, v; + + // + // Declare the names of the accessors for cons. + // Then declare the sorts of the accessors. + // For this example, all sorts refer to the new types 'forest' and 'tree' + // being declared, so we pass in null for both sorts1 and sorts2. + // On the other hand, the sort_refs arrays contain the indices of the + // two new sorts being declared. The first element in sort1_refs + // points to 'tree', which has index 1, the second element in sort1_refs array + // points to 'forest', which has index 0. + // + Symbol[] head_tail1 = new Symbol[] { ctx.MkSymbol("head"), ctx.MkSymbol("tail") }; + Sort[] sorts1 = new Sort[] { null, null }; + uint[] sort1_refs = new uint[] { 1, 0 }; // the first item points to a tree, the second to a forest + + Symbol[] head_tail2 = new Symbol[] { ctx.MkSymbol("car"), ctx.MkSymbol("cdr") }; + Sort[] sorts2 = new Sort[] { null, null }; + uint[] sort2_refs = new uint[] { 0, 0 }; // both items point to the forest datatype. + Constructor nil1_con, cons1_con, nil2_con, cons2_con; + Constructor[] constructors1 = new Constructor[2], constructors2 = new Constructor[2]; + Symbol[] sort_names = { ctx.MkSymbol("forest"), ctx.MkSymbol("tree") }; + + /* build a forest */ + nil1_con = ctx.MkConstructor(ctx.MkSymbol("nil"), ctx.MkSymbol("is_nil"), null, null, null); + cons1_con = ctx.MkConstructor(ctx.MkSymbol("cons1"), ctx.MkSymbol("is_cons1"), head_tail1, sorts1, sort1_refs); + constructors1[0] = nil1_con; + constructors1[1] = cons1_con; + + /* build a tree */ + nil2_con = ctx.MkConstructor(ctx.MkSymbol("nil2"), ctx.MkSymbol("is_nil2"), null, null, null); + cons2_con = ctx.MkConstructor(ctx.MkSymbol("cons2"), ctx.MkSymbol("is_cons2"), head_tail2, sorts2, sort2_refs); + constructors2[0] = nil2_con; + constructors2[1] = cons2_con; + + + Constructor[][] clists = new Constructor[][] { constructors1, constructors2 }; + + Sort[] sorts = ctx.MkDatatypeSorts(sort_names, clists); + forest = sorts[0]; + tree = sorts[1]; + + // + // Now that the datatype has been created. + // Query the constructors for the constructor + // functions, testers, and field accessors. + // + nil1_decl = nil1_con.ConstructorDecl; + is_nil1_decl = nil1_con.TesterDecl; + cons1_decl = cons1_con.ConstructorDecl; + is_cons1_decl = cons1_con.TesterDecl; + FuncDecl[] cons1_accessors = cons1_con.AccessorDecls; + car1_decl = cons1_accessors[0]; + cdr1_decl = cons1_accessors[1]; + + nil2_decl = nil2_con.ConstructorDecl; + is_nil2_decl = nil2_con.TesterDecl; + cons2_decl = cons2_con.ConstructorDecl; + is_cons2_decl = cons2_con.TesterDecl; + FuncDecl[] cons2_accessors = cons2_con.AccessorDecls; + car2_decl = cons2_accessors[0]; + cdr2_decl = cons2_accessors[1]; + + + nil1 = ctx.MkConst(nil1_decl); + nil2 = ctx.MkConst(nil2_decl); + f1 = ctx.MkApp(cons1_decl, nil2, nil1); + t1 = ctx.MkApp(cons2_decl, nil1, nil1); + t2 = ctx.MkApp(cons2_decl, f1, nil1); + t3 = ctx.MkApp(cons2_decl, f1, f1); + t4 = ctx.MkApp(cons2_decl, nil1, f1); + f2 = ctx.MkApp(cons1_decl, t1, nil1); + f3 = ctx.MkApp(cons1_decl, t1, f1); + + + /* nil != cons(nil,nil) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(nil1, f1))); + Prove(ctx, ctx.MkNot(ctx.MkEq(nil2, t1))); + + + /* cons(x,u) = cons(x, v) => u = v */ + u = ctx.MkConst("u", forest); + v = ctx.MkConst("v", forest); + x = ctx.MkConst("x", tree); + y = ctx.MkConst("y", tree); + l1 = ctx.MkApp(cons1_decl, x, u); + l2 = ctx.MkApp(cons1_decl, y, v); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v))); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y))); + + /* is_nil(u) or is_cons(u) */ + Prove(ctx, ctx.MkOr((BoolExpr)ctx.MkApp(is_nil1_decl, u), + (BoolExpr)ctx.MkApp(is_cons1_decl, u))); + + /* occurs check u != cons(x,u) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1))); + } + + /// + /// Demonstrate how to use #Eval. + /// + public static void EvalExample1(Context ctx) + { + Console.WriteLine("EvalExample1"); + + IntExpr x = ctx.MkIntConst("x"); + IntExpr y = ctx.MkIntConst("y"); + IntExpr two = ctx.MkInt(2); + + Solver solver = ctx.MkSolver(); + + /* assert x < y */ + solver.Assert(ctx.MkLt(x, y)); + + /* assert x > 2 */ + solver.Assert(ctx.MkGt(x, two)); + + /* find model for the constraints above */ + Model model = null; + if (Status.SATISFIABLE == solver.Check()) + { + model = solver.Model; + Console.WriteLine("{0}", model); + Console.WriteLine("\nevaluating x+y"); + Expr v = model.Evaluate(ctx.MkAdd(x, y)); + if (v != null) + { + Console.WriteLine("result = {0}", (v)); + } + else + { + Console.WriteLine("Failed to evaluate: x+y"); + } + } + else + { + Console.WriteLine("BUG, the constraints are satisfiable."); + } + } + + /// + /// Demonstrate how to use #Eval on tuples. + /// + public static void EvalExample2(Context ctx) + { + Console.WriteLine("EvalExample2"); + + Sort int_type = ctx.IntSort; + TupleSort tuple = ctx.MkTupleSort( + ctx.MkSymbol("mk_tuple"), // name of tuple constructor + new Symbol[] { ctx.MkSymbol("first"), ctx.MkSymbol("second") }, // names of projection operators + new Sort[] { int_type, int_type } // types of projection operators + ); + FuncDecl first = tuple.FieldDecls[0]; // declarations are for projections + FuncDecl second = tuple.FieldDecls[1]; + Expr tup1 = ctx.MkConst("t1", tuple); + Expr tup2 = ctx.MkConst("t2", tuple); + + Solver solver = ctx.MkSolver(); + + /* assert tup1 != tup2 */ + solver.Assert(ctx.MkNot(ctx.MkEq(tup1, tup2))); + /* assert first tup1 = first tup2 */ + solver.Assert(ctx.MkEq(ctx.MkApp(first, tup1), ctx.MkApp(first, tup2))); + + /* find model for the constraints above */ + Model model = null; + if (Status.SATISFIABLE == solver.Check()) + { + model = solver.Model; + Console.WriteLine("{0}", model); + Console.WriteLine("evaluating tup1 {0}", (model.Evaluate(tup1))); + Console.WriteLine("evaluating tup2 {0}", (model.Evaluate(tup2))); + Console.WriteLine("evaluating second(tup2) {0}", + (model.Evaluate(ctx.MkApp(second, tup2)))); + } + else + { + Console.WriteLine("BUG, the constraints are satisfiable."); + } + } + + /// + /// Demonstrate how to use Pushand Popto + /// control the size of models. + /// + /// Note: this test is specialized to 32-bit bitvectors. + public static void CheckSmall(Context ctx, Solver solver, BitVecExpr[] to_minimize) + { + Sort bv32 = ctx.MkBitVecSort(32); + + int num_Exprs = to_minimize.Length; + UInt32[] upper = new UInt32[num_Exprs]; + UInt32[] lower = new UInt32[num_Exprs]; + BitVecExpr[] values = new BitVecExpr[num_Exprs]; + for (int i = 0; i < upper.Length; ++i) + { + upper[i] = UInt32.MaxValue; + lower[i] = 0; + } + bool some_work = true; + int last_index = -1; + UInt32 last_upper = 0; + while (some_work) + { + solver.Push(); + + bool check_is_sat = true; + while (check_is_sat && some_work) + { + // Assert all feasible bounds. + for (int i = 0; i < num_Exprs; ++i) + { + solver.Assert(ctx.MkBVULE(to_minimize[i], ctx.MkBV(upper[i], 32))); + } + + check_is_sat = Status.SATISFIABLE == solver.Check(); + if (!check_is_sat) + { + if (last_index != -1) + { + lower[last_index] = last_upper + 1; + } + break; + } + Console.WriteLine("{0}", solver.Model); + + // narrow the bounds based on the current model. + for (int i = 0; i < num_Exprs; ++i) + { + Expr v = solver.Model.Evaluate(to_minimize[i]); + UInt64 ui = ((BitVecNum)v).UInt64; + if (ui < upper[i]) + { + upper[i] = (UInt32)ui; + } + Console.WriteLine("{0} {1} {2}", i, lower[i], upper[i]); + } + + // find a new bound to add + some_work = false; + last_index = 0; + for (int i = 0; i < num_Exprs; ++i) + { + if (lower[i] < upper[i]) + { + last_upper = (upper[i] + lower[i]) / 2; + last_index = i; + solver.Assert(ctx.MkBVULE(to_minimize[i], ctx.MkBV(last_upper, 32))); + some_work = true; + break; + } + } + } + solver.Pop(); + } + } + + /// + /// Reduced-size model generation example. + /// + public static void FindSmallModelExample(Context ctx) + { + Console.WriteLine("FindSmallModelExample"); + + BitVecExpr x = ctx.MkBVConst("x", 32); + BitVecExpr y = ctx.MkBVConst("y", 32); + BitVecExpr z = ctx.MkBVConst("z", 32); + + Solver solver = ctx.MkSolver(); + + solver.Assert(ctx.MkBVULE(x, ctx.MkBVAdd(y, z))); + CheckSmall(ctx, solver, new BitVecExpr[] { x, y, z }); + } + + /// + /// Simplifier example. + /// + public static void SimplifierExample(Context ctx) + { + Console.WriteLine("SimplifierExample"); + + IntExpr x = ctx.MkIntConst("x"); + IntExpr y = ctx.MkIntConst("y"); + IntExpr z = ctx.MkIntConst("z"); + IntExpr u = ctx.MkIntConst("u"); + + Expr t1 = ctx.MkAdd(x, ctx.MkSub(y, ctx.MkAdd(x, z))); + Expr t2 = t1.Simplify(); + Console.WriteLine("{0} -> {1}", (t1), (t2)); + } + + /// + /// Extract unsatisfiable core example + /// + public static void UnsatCoreAndProofExample() + { + Console.WriteLine("UnsatCoreAndProofExample"); + + Dictionary cfg = new Dictionary() { { "PROOF_MODE", "2" } }; + + using (Context ctx = new Context(cfg)) + { + Solver solver = ctx.MkSolver(); + + BoolExpr pa = ctx.MkBoolConst("PredA"); + BoolExpr pb = ctx.MkBoolConst("PredB"); + BoolExpr pc = ctx.MkBoolConst("PredC"); + BoolExpr pd = ctx.MkBoolConst("PredD"); + BoolExpr p1 = ctx.MkBoolConst("P1"); + BoolExpr p2 = ctx.MkBoolConst("P2"); + BoolExpr p3 = ctx.MkBoolConst("P3"); + BoolExpr p4 = ctx.MkBoolConst("P4"); + BoolExpr[] assumptions = new BoolExpr[] { ctx.MkNot(p1), ctx.MkNot(p2), ctx.MkNot(p3), ctx.MkNot(p4) }; + BoolExpr f1 = ctx.MkAnd(new BoolExpr[] { pa, pb, pc }); + BoolExpr f2 = ctx.MkAnd(new BoolExpr[] { pa, ctx.MkNot(pb), pc }); + BoolExpr f3 = ctx.MkOr(ctx.MkNot(pa), ctx.MkNot(pc)); + BoolExpr f4 = pd; + + solver.Assert(ctx.MkOr(f1, p1)); + solver.Assert(ctx.MkOr(f2, p2)); + solver.Assert(ctx.MkOr(f3, p3)); + solver.Assert(ctx.MkOr(f4, p4)); + Status result = solver.Check(assumptions); + + if (result == Status.UNSATISFIABLE) + { + Console.WriteLine("unsat"); + Console.WriteLine("proof: {0}", solver.Proof); + Console.WriteLine("core: "); + foreach (Expr c in solver.UnsatCore) + { + Console.WriteLine("{0}", c); + } + } + } + } + + public static void FiniteDomainExample(Context ctx) + { + Console.WriteLine("FiniteDomainExample"); + + var s = ctx.MkFiniteDomainSort("S", 10); + var t = ctx.MkFiniteDomainSort("T", 10); + var s1 = ctx.MkNumeral(1, s); + var t1 = ctx.MkNumeral(1, t); + Console.WriteLine("{0}", s); + Console.WriteLine("{0}", t); + Console.WriteLine("{0}", s1); + Console.WriteLine("{0}", ctx.MkNumeral(2, s)); + Console.WriteLine("{0}", t1); + // But you cannot mix numerals of different sorts + // even if the size of their domains are the same: + // Console.WriteLine("{0}", ctx.MkEq(s1, t1)); + } + + static void Main(string[] args) + { + try + { + Context.ToggleWarningMessages(true); + Log.Open("test.log"); + + Console.Write("Z3 Major Version: "); + Console.WriteLine(Microsoft.Z3.Version.Major.ToString()); + Console.Write("Z3 Full Version: "); + Console.WriteLine(Microsoft.Z3.Version.ToString()); + + SimpleExample(); + + using (Context ctx = new Context(new Dictionary() + { { "MODEL", "true"}, + { "PROOF_MODE", "2"} })) + { + BasicTests(ctx); + CastingTest(ctx); + SudokuExample(ctx); + QuantifierExample1(ctx); + QuantifierExample2(ctx); + LogicExample(ctx); + ParOrExample(ctx); + FindModelExample1(ctx); + FindModelExample2(ctx); + ProveExample1(ctx); + ProveExample2(ctx); + PushPopExample1(ctx); + ArrayExample1(ctx); + ArrayExample2(ctx); + ArrayExample3(ctx); + TupleExample(ctx); + BitvectorExample1(ctx); + BitvectorExample2(ctx); + ParserExample1(ctx); + ParserExample2(ctx); + ParserExample3(ctx); + ParserExample4(ctx); + ParserExample5(ctx); + ITEExample(ctx); + EnumExample(ctx); + ListExample(ctx); + TreeExample(ctx); + ForestExample(ctx); + EvalExample1(ctx); + EvalExample2(ctx); + FindSmallModelExample(ctx); + SimplifierExample(ctx); + FiniteDomainExample(ctx); + } + + QuantifierExample3(); + QuantifierExample4(); + UnsatCoreAndProofExample(); + + Log.Close(); + if (Log.isOpen()) + Console.WriteLine("Log is still open!"); + } + catch (Z3Exception ex) + { + Console.WriteLine("Z3 Managed Exception: " + ex.Message); + Console.WriteLine("Stack trace: " + ex.StackTrace); + } + catch (TestFailedException ex) + { + Console.WriteLine("TEST CASE FAILED: " + ex.Message); + } + } + } +} diff --git a/Microsoft.Z3/test_mapi/build-external.cmd b/Microsoft.Z3/test_mapi/build-external.cmd new file mode 100644 index 000000000..c493f0d41 --- /dev/null +++ b/Microsoft.Z3/test_mapi/build-external.cmd @@ -0,0 +1,4 @@ +copy ..\..\bin\Microsoft.Z3.dll . +copy ..\..\bin\Z3.dll . + +csc /reference:Microsoft.Z3.dll /debug:full /platform:x86 /reference:System.Numerics.dll Program.cs \ No newline at end of file diff --git a/Microsoft.Z3/test_mapi/build.cmd b/Microsoft.Z3/test_mapi/build.cmd new file mode 100644 index 000000000..bdcf0f15c --- /dev/null +++ b/Microsoft.Z3/test_mapi/build.cmd @@ -0,0 +1,4 @@ +copy ..\..\x64\release\Microsoft.Z3.dll . +copy ..\..\x64\release\Z3.dll . + +csc /reference:..\..\x64\release\Microsoft.Z3.dll /debug:full /platform:x64 /reference:System.Numerics.dll Program.cs \ No newline at end of file diff --git a/Microsoft.Z3/test_mapi/test_mapi.csproj b/Microsoft.Z3/test_mapi/test_mapi.csproj new file mode 100644 index 000000000..f43ce3915 --- /dev/null +++ b/Microsoft.Z3/test_mapi/test_mapi.csproj @@ -0,0 +1,68 @@ + + + + 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 + + + + + + + + + + + + {EC3DB697-B734-42F7-9468-5B62821EEB5A} + Microsoft.Z3 + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Z3/z3.snk b/Microsoft.Z3/z3.snk new file mode 100644 index 000000000..1c1ac8713 Binary files /dev/null and b/Microsoft.Z3/z3.snk differ diff --git a/Microsoft.Z3V3/AssemblyInfo.cpp b/Microsoft.Z3V3/AssemblyInfo.cpp new file mode 100644 index 000000000..54bea937e --- /dev/null +++ b/Microsoft.Z3V3/AssemblyInfo.cpp @@ -0,0 +1,34 @@ +using namespace System; +using namespace System::Reflection; +using namespace System::Runtime::CompilerServices; +using namespace System::Runtime::InteropServices; +using namespace System::Security::Permissions; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly:AssemblyTitleAttribute("Z3 .NET Interface")]; +[assembly:AssemblyDescriptionAttribute(".NET Interface to the Z3 Theorem Prover")]; +[assembly:AssemblyConfigurationAttribute("")]; +[assembly:AssemblyCompanyAttribute("Microsoft Corporation")]; +[assembly:AssemblyProductAttribute("Z3")]; +[assembly:AssemblyCopyrightAttribute("Copyright (c) Microsoft Corporation 2006")]; +[assembly:AssemblyTrademarkAttribute("")]; +[assembly:AssemblyCultureAttribute("")]; + +[assembly:ComVisible(false)]; +[assembly:CLSCompliantAttribute(true)]; +[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)]; + +[assembly:AssemblyVersionAttribute("4.2.0.0")]; +[assembly:AssemblyFileVersionAttribute("4.2.0.0")]; + +#ifdef DELAYSIGN +[assembly:AssemblyKeyFile("35MSSharedLib1024.snk")]; +[assembly:AssemblyDelaySign(true)]; +#else +[assembly:AssemblyKeyFile("z3.snk")]; +[assembly:AssemblyDelaySign(true)]; +#endif diff --git a/Microsoft.Z3V3/Microsoft.Z3V3.cpp b/Microsoft.Z3V3/Microsoft.Z3V3.cpp new file mode 100644 index 000000000..0e3b08eb2 --- /dev/null +++ b/Microsoft.Z3V3/Microsoft.Z3V3.cpp @@ -0,0 +1,3260 @@ +/*++ +Copyright (c) 2007 Microsoft Corporation + +Module Name: + + Microsoft.Z3V3.cpp + +Abstract: + + Z3 Managed API. + +Author: + + Nikolaj Bjorner (nbjorner) + Leonardo de Moura (leonardo) 2007-06-8 + +Notes: + +--*/ + +//#include "stdafx.h" +#include "Microsoft.Z3V3.h" +#include "..\lib\util.h" +#include "..\lib\z3_private.h" +#include +#include +#include +#include "../lib/rational.h" +#include "../lib/z3_private.h" + + +using namespace System::Text; +using namespace Microsoft::Z3V3; + +// ------------------------------- +// ref_context + +ref_context* ref_context::mk(Z3_context ctx, bool owned, bool scoped) { + return alloc(ref_context, ctx, owned, scoped); +} + +void ref_context::dec_ref() { + --m_count; + if (0 == m_count) { + if (m_owned) { + if (m_dl) { + Z3_fixedpoint_dec_ref(m_ctx, m_dl); + } + Z3_del_context(m_ctx); + } + dealloc(this); + } +} + +void ref_context::inc_ref() { + ++m_count; +} + +Z3_fixedpoint ref_context::dl() { + if (!m_dl) { + m_dl = Z3_mk_fixedpoint(m_ctx); + Z3_fixedpoint_inc_ref(m_ctx, m_dl); + } + return m_dl; +} + + +// ------------------------------- +// static functions + + +static std::string +CreateString( + String^ string + ) +{ + std::string s; + array^ bytes = + Encoding::Convert( + Encoding::Unicode, + Encoding::ASCII, + Encoding::Unicode->GetBytes(string) + ); + + for (int i = 0; i < bytes->Length; ++i) { + s += bytes[i]; + } + return s; +} + +bool Z3Log::Open(String^ filename) { + m_open = true; + return Z3_TRUE == Z3_open_log(CreateString(filename).c_str()); +} + +void Z3Log::Append(String^ s) { + Z3_append_log(CreateString(s).c_str()); +} + +void Z3Log::Close() { + m_open = false; + Z3_close_log(); +} + +template +class scoped_array { +public: + scoped_array(unsigned length) + : m_length(length), + m_data(new T[length]) + { + } + + scoped_array(array^ a) + { + m_length = a?a->Length:0; + m_data = a?(new T[m_length]):0; + for (unsigned i = 0; i < m_length; ++i) { + m_data[i] = a[i]; + } + } + + virtual ~scoped_array() { + delete[] m_data; + } + + T* c_ptr() { return m_data; } + + T const* c_ptr() const { return m_data; } + + T& operator[](int i) { return m_data[i]; } + + unsigned size() { return m_length; } +protected: + unsigned m_length; + T* m_data; +}; + +template +class scoped_Z3_ast_array : public scoped_array { +public: + scoped_Z3_ast_array(array^ asts) + : scoped_array((!asts)?0:asts->Length) + { + for (unsigned i = 0; i < m_length; ++i) { + c_ptr()[i] = static_cast(asts[i].ToPointer()); + } + } + scoped_Z3_ast_array(int length) + : scoped_array(length) {} +}; + + +class scoped_Z3_symbol_array : public scoped_array { +public: + scoped_Z3_symbol_array(array^ symbols) + : scoped_array((!symbols)?0:symbols->Length) + { + for (unsigned i = 0; i < m_length; ++i) { + c_ptr()[i] = symbols[i]->get(); + } + } + + scoped_Z3_symbol_array(Z3_context ctx, array^ symbols) + : scoped_array((!symbols)?0:symbols->Length) + { + for (unsigned i = 0; i < m_length; ++i) { + c_ptr()[i] = Z3_mk_string_symbol(ctx, CreateString(symbols[i]).c_str()); + } + } + + scoped_Z3_symbol_array(unsigned n): scoped_array(n) {} +}; + +static void CopyFuncDecl(scoped_Z3_ast_array& src, + array^ dst) { + SASSERT(dst->Length == src.size()); + for (unsigned i = 0; i < src.size(); ++i) { + dst[i] = FuncDeclPtr(src[i]); + } +} + +static array^ MkArray(unsigned n, Z3_ast const* args) { + array^ result = gcnew array(n); + for (unsigned i = 0; i < n; ++i) { + result[i] = TermPtr(args[i]); + } + return result; +} + +static SearchFailureExplanation ConvertExplanation(Z3_search_failure f) { + switch(f) { + case Z3_NO_FAILURE: + return SearchFailureExplanation::NoFailure; + case Z3_UNKNOWN: + return SearchFailureExplanation::Unknown; + case Z3_TIMEOUT: + return SearchFailureExplanation::TimeOut; + case Z3_MEMOUT_WATERMARK: + return SearchFailureExplanation::MemOut; + case Z3_CANCELED: + return SearchFailureExplanation::UserCanceled; + case Z3_NUM_CONFLICTS: + return SearchFailureExplanation::MaxConflicts; + case Z3_THEORY: + return SearchFailureExplanation::Theory; + case Z3_QUANTIFIERS: + return SearchFailureExplanation::Quantifiers; + } + return SearchFailureExplanation::Unknown; +} + +//---------------------------------------- +// Config + +Config::Config() { m_config = Z3_mk_config(); } + +Config::~Config() { + if (m_config) { + Z3_del_config(m_config); + m_config = 0; + } +} + +Config::!Config() { + if (m_config) { + if (RawContext::m_error_handler ) { + RawContext::m_error_handler->Handler(ErrorCode::NonDisposedConfig); + } + else { + verbose_stream() << "WARNING: configuration was not disposed\n"; + } + } +} + + +void Config::SetParamValue(String^ param_id, String^ param_value) { + Z3_set_param_value(m_config, CreateString(param_id).c_str(), CreateString(param_value).c_str()); +} + + +//---------------------------------------- +// Model + +RawModel::~RawModel() { + Reset(); +} + +RawModel::!RawModel() { + if (m_model) { + if (RawContext::m_error_handler ) { + RawContext::m_error_handler->Handler(ErrorCode::NonDisposedModel); + } + else { + verbose_stream() << "WARNING: model was not disposed\n"; + } + } +} + +void RawModel::Reset() { + if (m_model != 0) { + Z3_del_model(m_context(), m_model); + m_context.dec_ref(); + m_model = 0; + } +} + +array^ RawModel::GetModelConstants() { + unsigned num_consts = Z3_get_model_num_constants(m_context(), m_model); + array^ result = gcnew array(num_consts); + for (unsigned i = 0; i < num_consts; ++i) { + result[i] = FuncDeclPtr(Z3_get_model_constant(m_context(), m_model, i)); + } + return result; +} + + +String^ RawContext::GetNumeralString(TermPtr v) { + return gcnew String(Z3_get_numeral_string(ctx(), get_ast(v))); +} + +int RawContext::GetNumeralInt(TermPtr v) { + int result = 0; + if (!Z3_get_numeral_int(ctx(), get_ast(v), &result)) { + throw gcnew System::ArgumentException("Expecting value of integer type"); + } + return result; +} + +bool RawContext::TryGetNumeralInt(TermPtr v, int% i) { + int result = 0; + if (!Z3_get_numeral_int(ctx(), get_ast(v), &result)) { + return false; + } + i = result; + return true; +} + +unsigned RawContext::GetNumeralUInt(TermPtr v) { + unsigned result = 0; + if (!Z3_get_numeral_uint(ctx(), get_ast(v), &result)) { + throw gcnew System::ArgumentException("Expecting TermPtr of unsigned integer type"); + } + return result; +} + +bool RawContext::TryGetNumeralUInt(TermPtr v, unsigned% u) { + unsigned result = 0; + if (!Z3_get_numeral_uint(ctx(), get_ast(v), &result)) { + return false; + } + u = result; + return true; +} + + +__int64 RawContext::GetNumeralInt64(TermPtr v) { + __int64 result = 0; + if (!Z3_get_numeral_int64(ctx(), get_ast(v), &result)) { + throw gcnew System::ArgumentException("Expecting value of signed 64 bit integer type"); + } + return result; +} + +bool RawContext::TryGetNumeralInt64(TermPtr v, __int64% i) { + __int64 result = 0; + if (!Z3_get_numeral_int64(ctx(), get_ast(v), &result)) { + return false; + } + i = result; + return true; +} + + +unsigned __int64 RawContext::GetNumeralUInt64(TermPtr v) { + unsigned __int64 result = 0; + if (!Z3_get_numeral_uint64(ctx(), get_ast(v), &result)) { + throw gcnew System::ArgumentException("Expecting value of unsigned 64 bit integer type"); + } + return result; +} + +bool RawContext::TryGetNumeralUInt64(TermPtr v, unsigned __int64% u) { + unsigned __int64 result = 0; + if (!Z3_get_numeral_uint64(ctx(), get_ast(v), &result)) { + return false; + } + u = result; + return true; +} + +bool RawContext::TryGetNumeral(TermPtr v, [Out] __int64% num, [Out] __int64% den) { + __int64 _num, _den; + if (!Z3_get_numeral_rational_int64(ctx(), get_ast(v), &_num, &_den)) { + return false; + } + num = _num; + den = _den; + return true; +} + + +void RawContext::GetNumeral(TermPtr v, [Out] System::Numerics::BigInteger% num, [Out] System::Numerics::BigInteger% den) { + rational r; + if (!Z3_get_numeral_rational(ctx(), get_ast(v), r)) { + Z3_error_handler(Z3_INVALID_ARG); + return; + } + rational d = denominator(r); + rational n = numerator(r); + rational ten(10); + bool is_neg = false; + SASSERT(!d.is_neg()); + if (n.is_neg()) { + is_neg = true; + n = -n; + } + num = 0; + System::Numerics::BigInteger mul = 1; + while (n.is_pos()) { + num += mul * mod(n,ten).get_unsigned(); + n = div(n,ten); + mul *= 10; + } + if (is_neg) { + num = -num; + } + den = 0; + mul = 1; + while (d.is_pos()) { + den += mul * mod(d,ten).get_unsigned(); + d = div(d,ten); + mul *= 10; + } +} + + +LBool RawContext::GetBoolValue(TermPtr a) { + switch (Z3_get_bool_value(ctx(), get_ast(a))) { + case Z3_L_FALSE: return LBool::False; + case Z3_L_UNDEF: return LBool::Undef; + case Z3_L_TRUE: return LBool::True; + default: + UNREACHABLE(); + return LBool::Undef; + } +} + + +bool RawModel::TryGetArrayValue(TermPtr v, RawArrayValue^% av) { + unsigned num_entries; + if (!Z3_is_array_value(m_context(), m_model, get_ast(v), & num_entries)) { + return false; + } + scoped_Z3_ast_array _indices(num_entries); + scoped_Z3_ast_array _values(num_entries); + Z3_ast else_value; + Z3_get_array_value(m_context(), m_model, get_ast(v), num_entries, _indices.c_ptr(), _values.c_ptr(), &else_value); + av = gcnew RawArrayValue(); + av->Domain = gcnew array(num_entries); + av->Range = gcnew array(num_entries); + av->ElseCase = TermPtr(else_value); + for (unsigned i = 0; i < num_entries; ++i) { + av->Domain[i] = TermPtr(_indices[i]); + av->Range[i] = TermPtr(_values[i]); + } + return true; +} + +TermPtr RawContext::GetAssignments() { + return TermPtr(Z3_get_context_assignment(ctx())); +} + + +TermPtr RawContext::UpdateTerm(TermPtr t, array^ new_args) { + scoped_Z3_ast_array _new_args(new_args); + return TermPtr(Z3_update_term(ctx(), get_ast(t), + _new_args.size(), _new_args.c_ptr())); +} + +Dictionary^ RawModel::GetFunctionGraphs() { + if (m_graphs) { + return m_graphs; + } + SASSERT(m_model); + unsigned _num_funs = Z3_get_model_num_funcs(m_context(), m_model); + + Dictionary^ graphs = + gcnew Dictionary(); + + for (unsigned i = 0; i < _num_funs; ++i) { + unsigned num_entries = Z3_get_model_func_num_entries(m_context(), m_model, i); + FuncDeclPtr decl = FuncDeclPtr(Z3_get_model_func_decl(m_context(), m_model, i)); + RawFunctionGraph^ graph = gcnew RawFunctionGraph(); + graphs[decl] = graph; + graph->Declaration = decl; + graph->Else = TermPtr(Z3_get_model_func_else(m_context(), m_model, i)); + graph->Entries = gcnew array(num_entries); + + for (unsigned j = 0; j < num_entries; ++j) { + unsigned num_args = Z3_get_model_func_entry_num_args(m_context(), m_model, i, j); + graph->Entries[j] = gcnew RawFunctionEntry(); + graph->Entries[j]->Arguments = gcnew array(num_args); + for (unsigned k = 0; k < num_args; ++k) { + graph->Entries[j]->Arguments[k] = TermPtr(Z3_get_model_func_entry_arg(m_context(), m_model, i, j, k)); + } + graph->Entries[j]->Result = TermPtr(Z3_get_model_func_entry_value(m_context(), m_model, i, j)); + } + } + m_graphs = graphs; + return graphs; +} + +TermPtr RawModel::Eval(TermPtr t) { + Z3_ast v = 0; + if (!Z3_eval(m_context(), m_model, get_ast(t), &v)) { + return IntPtr::Zero; + } + return TermPtr(v); +} + +TermPtr RawModel::Eval(FuncDeclPtr decl, array^ args) { + Z3_ast v = 0; + scoped_Z3_ast_array _args(args); + + if (!Z3_eval_decl(m_context(), m_model, get_func_decl(decl), + _args.size(), _args.c_ptr(), &v)) { + return IntPtr::Zero; + } + return TermPtr(v); +} + +String^ RawModel::ToString() { + return gcnew String(Z3_model_to_string(m_context(), m_model)); +} + +void RawModel::Display(System::IO::TextWriter^ w) { + w->Write(ToString()); +} + +RawTheory^ RawContext::MkTheory(String^ name) { + return gcnew RawTheory(*m_context, name); +} + + +void RawContext::RegisterRelation(FuncDeclPtr r) { + Z3_fixedpoint_register_relation(ctx(), dl(), get_func_decl(r)); +} + +void RawContext::AddRule(TermPtr term, Symbol^ name) { + Z3_fixedpoint_add_rule(ctx(), dl(), get_ast(term), name?name->get():0); +} + +LBool RawContext::Query(TermPtr query) { + switch(Z3_fixedpoint_query(ctx(), dl(), get_ast(query))) { + case Z3_L_FALSE: return LBool::False; + case Z3_L_TRUE: return LBool::True; + default: return LBool::Undef; + } +} + +String^ RawContext::GetQueryStatus() { + return gcnew String(Z3_fixedpoint_get_reason_unknown(ctx(),dl())); +} + +TermPtr RawContext::GetQueryAnswer() { + return TermPtr(Z3_fixedpoint_get_answer(ctx(),dl())); +} + +static void fixedpoint_assign_callback(void* c, Z3_func_decl f, unsigned n, Z3_ast const* _args, unsigned m, Z3_ast const* outs) { + RawContext::fixedpoint_assign_callback(c, f, n, _args, m, outs); +} + +static void fixedpoint_apply_callback(void* c, Z3_func_decl f, unsigned n, Z3_ast const* _args, Z3_ast* out) { + RawContext::fixedpoint_apply_callback(c, f, n, _args, out); +} + +void RawContext::init_fixedpoint_callbacks() { + if (contexts == nullptr) { + contexts = gcnew Dictionary(); + } + if (m_fixedpoint_gch == IntPtr::Zero) { + int id = contexts->Count; + GCHandle h = GCHandle::Alloc(id, GCHandleType::Pinned); + contexts[h] = this; + m_fixedpoint_gch = GCHandle::ToIntPtr(h); + Z3_fixedpoint_init(ctx(), dl(), m_fixedpoint_gch.ToPointer()); + Z3_fixedpoint_set_reduce_assign_callback(ctx(), dl(), ::fixedpoint_assign_callback); + Z3_fixedpoint_set_reduce_app_callback(ctx(), dl(), ::fixedpoint_apply_callback); + } +} + + +void RawContext::fixedpoint_assign_callback(void* ud, Z3_func_decl f, unsigned n, Z3_ast const* args, unsigned m, Z3_ast const* outs) { + RawContext^ ctx = contexts[GCHandle::FromIntPtr(IntPtr(ud))]; + if (ctx->m_fixedpoint_assign != nullptr) { + array^ _args = MkArray(n, args); + array^ _outs = MkArray(m, outs); + ctx->m_fixedpoint_assign(TermPtr(f), _args, _outs); + } +} + +void RawContext::fixedpoint_apply_callback(void* ud, Z3_func_decl f, unsigned n, Z3_ast const* args, Z3_ast* out) { + RawContext^ ctx = contexts[GCHandle::FromIntPtr(IntPtr(ud))]; + if (ctx->m_fixedpoint_apply != nullptr) { + array^ _args = MkArray(n, args); + TermPtr r = ctx->m_fixedpoint_apply(TermPtr(f), _args); + if (out) *out = get_ast(r); + } +} + +String^ RawContext::FixedpointToString(array^ queries) { + scoped_Z3_ast_array _queries(queries); + return gcnew String(Z3_fixedpoint_to_string( + ctx(), dl(), + _queries.size(), _queries.c_ptr())); +} + +array^ RawContext::SimplifyFixedpointRules(array^ rules, array^ output_predicates) { + scoped_Z3_ast_array _rules(rules); + scoped_Z3_ast_array _outputs(output_predicates); + Z3_ast_vector new_rules = Z3_fixedpoint_simplify_rules( + ctx(), dl(), _rules.size(), _rules.c_ptr(), + _outputs.size(), _outputs.c_ptr()); + unsigned num_rules = Z3_ast_vector_size(ctx(), new_rules); + Z3_ast_vector_inc_ref(ctx(), new_rules); + array^ result = gcnew array(num_rules); + for (unsigned i = 0; i < num_rules; ++i) { + result[i] = TermPtr(Z3_ast_vector_get(ctx(), new_rules, i)); + } + Z3_ast_vector_dec_ref(ctx(), new_rules); + return result; +} + +//---------------------------------------- +// RawContext + +static void error_handler(Z3_context ctx, Z3_error_code c) { + ErrorCode code; + switch(c) { + case Z3_OK: code = ErrorCode::Ok; break; + case Z3_SORT_ERROR: code = ErrorCode::TypeError; break; + case Z3_IOB: code = ErrorCode::IndexOutOfBounds; break; + case Z3_INVALID_ARG: code = ErrorCode::InvalidArgument; break; + case Z3_PARSER_ERROR: code = ErrorCode::ParserError; break; + case Z3_NO_PARSER: code = ErrorCode::NoParser; break; + case Z3_INVALID_PATTERN: code = ErrorCode::InvalidPattern; break; + case Z3_MEMOUT_FAIL: throw gcnew OutOfMemoryException(); + case Z3_INTERNAL_FATAL: code = ErrorCode::InternalFatal; break; + case Z3_INVALID_USAGE: code = ErrorCode::InvalidUsage; break; + case Z3_FILE_ACCESS_ERROR: code = ErrorCode::FileAccessError; break; + default: + UNREACHABLE(); + code = ErrorCode::InvalidArgument; break; + } + if (RawContext::m_error_handler ) { + RawContext::m_error_handler->Handler(code); + } + // we throw if you don't + throw gcnew Z3Error(code); +} + + +// ----------------------------- +// LabeledLiterals + + +LabeledLiterals::!LabeledLiterals() { + if (m_labels) { + if (RawContext::m_error_handler ) { + RawContext::m_error_handler->Handler(ErrorCode::NonDisposedLiterals); + } + else { + verbose_stream() << "WARNING: labeled literals have not been disposed\n"; + } + } +} + +// ----------------------------- +// RawTheory + +void RawTheory::static_delete_callback(Z3_theory th) +{ + RawTheory^ theory = GetTheory(th); + if (theory->delete_handler) { + theory->delete_handler(); + } + Z3_theory_data td = Z3_theory_get_ext_data(th); + theories->Remove(GCHandle::FromIntPtr(IntPtr(td))); + GCHandle::FromIntPtr(IntPtr(td)).Free(); +} + +static void static_delete_callback(Z3_theory th) { + RawTheory::static_delete_callback(th); +} + +RawTheory::RawTheory(ref_context& ctx, String^ name): m_context(ctx), m_name(name) +{ + if (!theories) theories = gcnew Dictionary(); + int id = theories->Count; + GCHandle h = GCHandle::Alloc(id, GCHandleType::Pinned); + theories[h] = this; + IntPtr gch = GCHandle::ToIntPtr(h); + m_theory = Z3_mk_theory(ctx(), CreateString(name).c_str(), gch.ToPointer()); + m_context.inc_ref(); + Z3_set_delete_callback(m_theory, ::static_delete_callback); +} + +RawTheory::~RawTheory() { + m_context.dec_ref(); +} + +Z3_bool RawTheory::reduce_eq_callback(Z3_theory th, Z3_ast a, Z3_ast b, Z3_ast* r) { + RawTheory^ theory = GetTheory(th); + TermPtr res = theory->reduce_eq(TermPtr(a), TermPtr(b)); + if (res != TermPtr::Zero) { + *r = get_ast(res); + } + return res != TermPtr::Zero; +} + +static Z3_bool reduce_eq_callback(Z3_theory th, Z3_ast a, Z3_ast b, Z3_ast* r) { + return RawTheory::reduce_eq_callback(th, a, b, r); +} + +void RawTheory::set_reduce_eq(Func2^ value) { + reduce_eq = value; + Z3_set_reduce_eq_callback(m_theory, ::reduce_eq_callback); +} + +Z3_bool RawTheory::reduce_app_callback(Z3_theory th, Z3_func_decl f, unsigned num_args, Z3_ast const args[], Z3_ast* r) { + RawTheory^ theory = GetTheory(th); + array^ argv = MkArray(num_args, args); + TermPtr res = theory->reduce_app(TermPtr(f), argv); + if (r && res != TermPtr::Zero) { + *r = get_ast(res); + } + return res != TermPtr::Zero; +} + +static Z3_bool reduce_app_callback(Z3_theory th, Z3_func_decl f, unsigned num_args, Z3_ast const args[], Z3_ast* r) { + return RawTheory::reduce_app_callback(th, f, num_args, args, r); +} + +void RawTheory::set_reduce_app(Func2^, TermPtr>^ value) { + reduce_app = value; + Z3_set_reduce_app_callback(m_theory, ::reduce_app_callback); +} + +Z3_bool RawTheory::reduce_distinct_callback(Z3_theory th, unsigned n, Z3_ast const args[], Z3_ast* r) { + RawTheory^ theory = GetTheory(th); + TermPtr res = theory->reduce_distinct(MkArray(n, args)); + if (r && res != TermPtr::Zero) { + *r = get_ast(res); + } + return res != TermPtr::Zero; +} + +static Z3_bool reduce_distinct_callback(Z3_theory th, unsigned n, Z3_ast const args[], Z3_ast* r) { + return RawTheory::reduce_distinct_callback(th, n, args, r); +} + +void RawTheory::set_reduce_distinct(Func1^, TermPtr>^ value) { + reduce_distinct = value; + Z3_set_reduce_distinct_callback(m_theory, ::reduce_distinct_callback); +} + +static void new_relevant_callback(Z3_theory t, Z3_ast a) { + RawTheory::GetTheory(t)->new_relevant(TermPtr(a)); +} + +void RawTheory::set_new_relevant(Action^ value) { + new_relevant = value; + Z3_set_new_relevant_callback(m_theory, ::new_relevant_callback); +} + +static void new_app_callback(Z3_theory t, Z3_ast a) { + RawTheory::GetTheory(t)->new_app(TermPtr(a)); +} + +void RawTheory::set_new_app(Action^ value) { + new_app = value; + Z3_set_new_app_callback(m_theory, ::new_app_callback); +} + + +static void new_elem_callback(Z3_theory t, Z3_ast a) { + RawTheory::GetTheory(t)->new_elem(TermPtr(a)); +} + +void RawTheory::set_new_elem(Action^ value) { + new_elem = value; + Z3_set_new_elem_callback(m_theory, ::new_elem_callback); +} + +static void init_search_callback(Z3_theory t) { + RawTheory::GetTheory(t)->init_search(); +} + +void RawTheory::set_init_search(Action0^ value) { + init_search = value; + Z3_set_init_search_callback(m_theory, ::init_search_callback); +} + +static void push_callback(Z3_theory t) { + RawTheory::GetTheory(t)->push(); +} + +void RawTheory::set_push(Action0^ value) { + push = value; + Z3_set_push_callback(m_theory, ::push_callback); +} + + +static void pop_callback(Z3_theory t) { + RawTheory::GetTheory(t)->pop(); +} + +void RawTheory::set_pop(Action0^ value) { + pop = value; + Z3_set_pop_callback(m_theory, ::pop_callback); +} + + +static void reset_callback(Z3_theory t) { + RawTheory::GetTheory(t)->reset(); +} + +void RawTheory::set_reset(Action0^ value) { + reset = value; + Z3_set_reset_callback(m_theory, ::reset_callback); +} + + +static void restart_callback(Z3_theory t) { + RawTheory::GetTheory(t)->restart(); +} + +void RawTheory::set_restart(Action0^ value) { + restart = value; + Z3_set_restart_callback(m_theory, ::restart_callback); +} + + +static Z3_bool final_check_callback(Z3_theory t) { + return RawTheory::GetTheory(t)->final_check(); +} + +void RawTheory::set_final_check(Func0^ value) { + final_check = value; + Z3_set_final_check_callback(m_theory, ::final_check_callback); +} + +static void new_eq_callback(Z3_theory t, Z3_ast a, Z3_ast b) { + RawTheory::GetTheory(t)->new_eq(TermPtr(a), TermPtr(b)); +} + +void RawTheory::set_new_eq(Action2^ value) { + new_eq = value; + Z3_set_new_eq_callback(m_theory, ::new_eq_callback); +} + + +static void new_diseq_callback(Z3_theory t, Z3_ast a, Z3_ast b) { + RawTheory::GetTheory(t)->new_diseq(TermPtr(a), TermPtr(b)); +} + +void RawTheory::set_new_diseq(Action2^ value) { + new_diseq = value; + Z3_set_new_diseq_callback(m_theory, ::new_diseq_callback); +} + +static void new_assignment_callback(Z3_theory t, Z3_ast a, Z3_bool b) +{ + RawTheory::GetTheory(t)->new_assignment(TermPtr(a), b?true:false); +} + +void RawTheory::set_new_assignment(Action2^ value) { + new_assignment = value; + Z3_set_new_assignment_callback(m_theory, ::new_assignment_callback); +} + +FuncDeclPtr RawTheory::MkFuncDecl(Symbol^ n, array^ domain, SortPtr range) { + scoped_Z3_ast_array _domain(domain); + return FuncDeclPtr(Z3_theory_mk_func_decl(m_context(), m_theory, n->get(), + _domain.size(), _domain.c_ptr(), get_sort(range))); +} + + +SortPtr RawTheory::MkSort(String^ s) { + return SortPtr(Z3_theory_mk_sort(m_context(), m_theory, Z3_mk_string_symbol(m_context(), CreateString(s).c_str()))); +} + +TermPtr RawTheory::MkValue(String^ s, SortPtr srt) { + Z3_symbol sym = Z3_mk_string_symbol(m_context(), CreateString(s).c_str()); + return TermPtr(Z3_theory_mk_value(m_context(), m_theory, sym, get_sort(srt))); +} + +TermPtr RawTheory::MkConstant(String^ s, SortPtr srt) { + Z3_symbol sym = Z3_mk_string_symbol(m_context(), CreateString(s).c_str()); + return TermPtr(Z3_theory_mk_constant(m_context(), m_theory, sym, get_sort(srt))); +} + +FuncDeclPtr RawTheory::MkFuncDecl(String^ s, array^ domain, SortPtr range) { + Z3_symbol sym = Z3_mk_string_symbol(m_context(), CreateString(s).c_str()); + scoped_Z3_ast_array _domain(domain); + return FuncDeclPtr(Z3_theory_mk_func_decl(m_context(), m_theory, sym, + _domain.size(), _domain.c_ptr(), get_sort(range))); + +} + + +// ----------------------------- +// Constructor + +Constructor::Constructor( + ref_context& context, + String^ name, + String^ tester, + array^ field_names, + array^ field_sorts, + array^ field_refs + ): + m_context(context), + m_constructor(0), + m_name(name), + m_tester_name(tester), + m_field_names(field_names), + m_field_sorts(field_sorts), + m_field_refs(field_refs), + m_constructor_decl(FuncDeclPtr()), + m_tester(FuncDeclPtr()), + m_accessors(nullptr) +{ + m_context.inc_ref(); +} + + +Z3_constructor Constructor::Get() +{ + if (m_constructor) { + return m_constructor; + } + Z3_symbol _name = Z3_mk_string_symbol(m_context(), CreateString(m_name).c_str()); + Z3_symbol _tester = Z3_mk_string_symbol(m_context(), CreateString(m_tester_name).c_str()); + unsigned num_fields = (!m_field_names)?0:m_field_names->Length; + scoped_Z3_symbol_array _field_names(m_context(), m_field_names); + scoped_Z3_ast_array _field_sorts(m_field_sorts); + scoped_array _field_refs(m_field_refs); + SASSERT(_field_names.size() == _field_sorts.size()); + SASSERT(_field_names.size() == _field_refs.size()); + m_constructor = Z3_mk_constructor(m_context(), _name, _tester, num_fields, + _field_names.c_ptr(), _field_sorts.c_ptr(), _field_refs.c_ptr()); + return m_constructor; +} + +Z3_constructor Constructor::Query() { + Z3_constructor result = 0; + if (!m_accessors) { + SASSERT(m_constructor); + result = m_constructor; + unsigned num_fields = (!m_field_names)?0:m_field_names->Length; + m_accessors = gcnew array(num_fields); + Z3_func_decl constructor_decl, tester_decl; + scoped_array accs(num_fields); + Z3_query_constructor(m_context(), + m_constructor, + num_fields, + &constructor_decl, + &tester_decl, + accs.c_ptr()); + m_constructor_decl = FuncDeclPtr(constructor_decl); + m_tester = FuncDeclPtr(tester_decl); + for (unsigned i = 0; i < num_fields; ++i) { + m_accessors[i] = FuncDeclPtr(accs[i]); + } + m_constructor = 0; + } + SASSERT(!m_constructor); + return result; +} + +Constructor::!Constructor() { + SASSERT(!m_constructor); +} + + +Constructor::~Constructor() { + SASSERT(!m_constructor); + m_context.dec_ref(); +} + + +FuncDeclPtr Constructor::GetConstructor() { + if (!m_constructor && !m_accessors) { + throw gcnew Z3Error(ErrorCode::InvalidUsage); + } + Z3_constructor c = Query(); + SASSERT(!c); + return FuncDeclPtr(m_constructor_decl); +} + +FuncDeclPtr Constructor::GetTester() { + if (!m_constructor && !m_accessors) { + throw gcnew Z3Error(ErrorCode::InvalidUsage); + } + Z3_constructor c = Query(); + SASSERT(!c); + return FuncDeclPtr(m_tester); +} + +array^ Constructor::GetAccessors() { + if (!m_constructor && !m_accessors) { + throw gcnew Z3Error(ErrorCode::InvalidUsage); + } + Z3_constructor c = Query(); + SASSERT(!c); + return m_accessors; +} + + + + +// ----------------------------- +// RawContext + + +void RawContext::Init() { + m_disposed = false; + s_nonempty = false; + if (s_todec == nullptr) { + s_todec = gcnew List >(); + s_monitor = gcnew IntPtr(0); + } + Z3_set_error_handler(ctx(), error_handler); +} + +RawContext::RawContext(Config^ config) { + m_context = ref_context::mk(Z3_mk_context(config->get()), true, true); + Init(); +} + +RawContext::RawContext(Config^ config, ReferenceCounted^ rc) { + m_context = ref_context::mk(Z3_mk_context_rc(config->get()), true, false); + Init(); +} + +RawContext::RawContext() { + m_context = ref_context::mk(Z3_mk_context(0), true, true); + Init(); +} + +void RawContext::SetContext(Z3_context ctx) { + Reset(); + m_context = ref_context::mk(ctx, false, true); +} + +RawContext::!RawContext() { + if (!m_disposed) { + if (RawContext::m_error_handler ) { + RawContext::m_error_handler->Handler(ErrorCode::NonDisposedContext); + } + else { + verbose_stream() << "WARNING: context was not disposed\n"; + } + } +} + + +void +RawContext::Reset() { + System::Threading::Monitor::Enter(s_monitor); + if (!m_disposed) { + m_context->dec_ref(); + m_disposed = true; + } + System::Threading::Monitor::Exit(s_monitor); +} + +RawContext::~RawContext() { + Reset(); +} + +#include "..\lib\vector.h" +#include "..\lib\trace.h" + +void RawContext::EnableDebugTrace(String^ tag) { + static vector pinned; + std::string s = CreateString(tag); + pinned.push_back(new std::string(s)); + enable_trace(pinned.back()->c_str()); +} + +void RawContext::ToggleWarningMessages(bool enabled) { + Z3_toggle_warning_messages(enabled); +} + +void RawContext::UpdateParamValue(String^ p, String^ v) { + Z3_update_param_value(ctx(), CreateString(p).c_str(), CreateString(v).c_str()); +} + +String^ RawContext::GetParamValue(String^ p) { + Z3_string vl = ""; + if (!Z3_get_param_value(ctx(), CreateString(p).c_str(), &vl)) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + return gcnew String(vl); +} + +bool RawContext::SetLogic(String^ l) { + return Z3_TRUE == Z3_set_logic(ctx(), CreateString(l).c_str()); +} + +Symbol^ RawContext::MkSymbol(String^ s) { + return gcnew Symbol(ctx(), Z3_mk_string_symbol(ctx(), CreateString(s).c_str())); +} +Symbol^ RawContext::MkSymbol(int i) { + return gcnew Symbol(ctx(), Z3_mk_int_symbol(ctx(), i)); +} + +SortPtr RawContext::MkSort(Symbol^ s) { + return SortPtr(Z3_mk_uninterpreted_sort(ctx(), s->get())); +} + +SortPtr RawContext::MkSort(String^ s) { + return SortPtr(Z3_mk_uninterpreted_sort(ctx(), Z3_mk_string_symbol(ctx(), CreateString(s).c_str()))); +} + +SortPtr RawContext::MkSort(int i) { + return SortPtr(Z3_mk_uninterpreted_sort(ctx(), Z3_mk_int_symbol(ctx(), i))); +} + +SortPtr RawContext::MkBoolSort() { return SortPtr(Z3_mk_bool_sort(ctx())); } + +SortPtr RawContext::MkIntSort() { return SortPtr(Z3_mk_int_sort(ctx())); } + +SortPtr RawContext::MkRealSort() { return SortPtr(Z3_mk_real_sort(ctx())); } + +SortPtr RawContext::MkBvSort(unsigned sz) { return SortPtr(Z3_mk_bv_sort(ctx(), sz)); } + +SortPtr RawContext::MkArraySort(SortPtr domain, SortPtr range) { + return SortPtr(Z3_mk_array_sort(ctx(), get_sort(domain), get_sort(range))); +} + +SortPtr RawContext::MkFiniteDomainSort(String^ s, unsigned __int64 domain_size) { + return SortPtr(Z3_mk_finite_domain_sort(ctx(), Z3_mk_string_symbol(ctx(), CreateString(s).c_str()), domain_size)); +} + +SortPtr RawContext::MkTupleSort( + Symbol^ mk_tuple_name, + array^ field_names, + array^ field_types, + FuncDeclPtr% mk_tuple_decl, + array^ proj_decls + ) +{ + if (!field_names || + !field_types || + !proj_decls || + field_names->Length != field_types->Length || + field_names->Length != proj_decls->Length) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + scoped_Z3_symbol_array syms(field_names); + scoped_Z3_ast_array types(field_types); + scoped_Z3_ast_array projs(field_names->Length); + Z3_func_decl decl; + + Z3_sort ty = + Z3_mk_tuple_sort( + ctx(), + mk_tuple_name->get(), + syms.size(), + syms.c_ptr(), + types.c_ptr(), + &decl, + projs.c_ptr() + ); + + mk_tuple_decl = FuncDeclPtr(decl); + CopyFuncDecl(projs, proj_decls); + return SortPtr(ty); +} + +SortPtr RawContext::MkTupleSort( + String^ mk_tuple_name, + array^ field_names, + array^ field_types, + FuncDeclPtr% mk_tuple_decl, + array^ proj_decls + ) +{ + Symbol^ tn = MkSymbol(mk_tuple_name); + array^ fields = gcnew array(field_names->Length); + for (int i = 0; i < fields->Length; ++i) { + fields[i] = MkSymbol(field_names[i]); + } + return MkTupleSort(tn, fields, field_types, mk_tuple_decl, proj_decls); + +} + +SortPtr RawContext::MkEnumerationSort( + String^ name, + array^ enum_names, + array^ enum_consts, + array^ enum_testers) { + + Z3_symbol _name(Z3_mk_string_symbol(ctx(), CreateString(name).c_str())); + scoped_Z3_symbol_array _enum_names(ctx(), enum_names); + scoped_Z3_ast_array _enum_consts(enum_consts); + scoped_Z3_ast_array _enum_testers(enum_testers); + unsigned sz = _enum_names.size(); + SASSERT(sz == _enum_consts.size()); + SASSERT(sz == _enum_testers.size()); + Z3_sort s = Z3_mk_enumeration_sort(ctx(), _name, sz, _enum_names.c_ptr(), _enum_consts.c_ptr(), _enum_testers.c_ptr()); + CopyFuncDecl(_enum_consts, enum_consts); + CopyFuncDecl(_enum_testers, enum_testers); + return SortPtr(s); +} + +SortPtr RawContext::MkListSort( + String^ name, + SortPtr elem_sort, + FuncDeclPtr% nil_decl, + FuncDeclPtr% is_nil_decl, + FuncDeclPtr% cons_decl, + FuncDeclPtr% is_cons_decl, + FuncDeclPtr% head_decl, + FuncDeclPtr% tail_decl + ) +{ + Z3_func_decl _nil_decl, _is_nil_decl, _cons_decl, _is_cons_decl, _head_decl, _tail_decl; + Z3_symbol _name = Z3_mk_string_symbol(ctx(), CreateString(name).c_str()); + Z3_sort _elem_sort = get_sort(elem_sort); + + Z3_sort s = Z3_mk_list_sort(ctx(), _name, _elem_sort, + &_nil_decl, &_is_nil_decl, &_cons_decl, + &_is_cons_decl, &_head_decl, &_tail_decl); + + is_nil_decl = FuncDeclPtr(_is_nil_decl); + nil_decl = FuncDeclPtr(_nil_decl); + is_cons_decl = FuncDeclPtr(_is_cons_decl); + cons_decl = FuncDeclPtr(_cons_decl); + head_decl = FuncDeclPtr(_head_decl); + tail_decl = FuncDeclPtr(_tail_decl); + return SortPtr(s); +} + + + +Constructor^ RawContext::MkConstructor( + String^ name, + String^ tester, + array^ field_names, + array^ field_sorts, + array^ field_refs + ) +{ + + int l1 = (!field_names)?0:field_names->Length; + int l2 = (!field_sorts)?0:field_sorts->Length; + int l3 = (!field_refs)?0:field_refs->Length; + if (l1 != l2 || l1 != l3) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + return gcnew Constructor(*m_context, name, tester, + field_names, field_sorts, field_refs); +} + + +SortPtr RawContext::MkDataType( + String^ name, + array^ constructors + ) +{ + Z3_symbol _name = Z3_mk_string_symbol(ctx(), CreateString(name).c_str()); + scoped_array _cons(constructors->Length); + for (int i = 0; i < constructors->Length; ++i) { + _cons[i] = constructors[i]->Get(); + } + Z3_sort s = Z3_mk_datatype(ctx(), _name, _cons.size(), _cons.c_ptr()); + for (int i = 0; i < constructors->Length; ++i) { + Z3_constructor c = constructors[i]->Query(); + Z3_del_constructor(ctx(), c); + } + return SortPtr(s); +} + +array^ RawContext::MkDataTypes( + array^ names, + array^>^ constructors_list + ) +{ + if (!names || + !constructors_list || + names->Length != constructors_list->Length) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + + } + unsigned num_sorts = names->Length; + scoped_array sort_names(num_sorts); + scoped_array clist(num_sorts); + scoped_array sort_sorts(num_sorts); + array^ result = gcnew array(num_sorts); + unsigned num_constructors = 0; + for (unsigned j = 0; j < num_sorts; ++j) { + num_constructors += constructors_list[j]->Length; + } + scoped_array constructor_vec(num_constructors); + svector constructors_q; + unsigned constructor_idx = 0; + + for (unsigned j = 0; j < num_sorts; ++j) { + String^ name = names[j]; + array^ constructors = constructors_list[j]; + + // add sort name + Z3_symbol _name = Z3_mk_string_symbol(ctx(), CreateString(name).c_str()); + sort_names[j] = _name; + + // create constructor_list + scoped_array _cons(constructors->Length); + for (int i = 0; i < constructors->Length; ++i) { + _cons[i] = constructors[i]->Get(); + constructor_vec[constructor_idx++] = _cons[i]; + } + Z3_constructor_list cl = Z3_mk_constructor_list(ctx(), _cons.size(), _cons.c_ptr()); + clist[j] = cl; + } + Z3_mk_datatypes(ctx(), num_sorts, sort_names.c_ptr(), sort_sorts.c_ptr(), clist.c_ptr()); + + for (unsigned j = 0; j < num_sorts; ++j) { + Z3_del_constructor_list(ctx(), clist[j]); + result[j] = SortPtr(sort_sorts[j]); + // populate the constructors + array^ constructors = constructors_list[j]; + for (int i = 0; i < constructors->Length; ++i) { + constructors_q.push_back(constructors[i]->Query()); + } + } + for (unsigned i = 0; i < constructors_q.size(); ++i) { + Z3_constructor c = constructors_q[i]; + if (c) { + Z3_del_constructor(ctx(), c); + } + } + return result; +} + + + +FuncDeclPtr RawContext::MkFuncDecl(Symbol^ s, array^ domain, SortPtr range) { + scoped_Z3_ast_array types(domain); + return FuncDeclPtr(Z3_mk_func_decl(ctx(), s->get(), types.size(), types.c_ptr(), get_sort(range))); +} + +FuncDeclPtr RawContext::MkFuncDecl(String^ s, array^ domain, SortPtr range) { + scoped_Z3_ast_array types(domain); + Z3_symbol sym = Z3_mk_string_symbol(ctx(), CreateString(s).c_str()); + return FuncDeclPtr(Z3_mk_func_decl(ctx(), sym, types.size(), types.c_ptr(), get_sort(range))); +} + +FuncDeclPtr RawContext::MkFuncDecl(Symbol^ s, SortPtr domain, SortPtr range) { + Z3_sort dom[1] = { get_sort(domain) }; + return FuncDeclPtr(Z3_mk_func_decl(ctx(), s->get(), 1, dom, get_sort(range))); +} + +FuncDeclPtr RawContext::MkFuncDecl(Symbol^ s, SortPtr d1, SortPtr d2, SortPtr range) { + Z3_sort dom[2] = { get_sort(d1), get_sort(d2) }; + return FuncDeclPtr(Z3_mk_func_decl(ctx(), s->get(), 2, dom, get_sort(range))); +} + +FuncDeclPtr RawContext::MkFuncDecl(String^ s, SortPtr domain, SortPtr range) { + Z3_sort dom[1] = { get_sort(domain) }; + Z3_symbol sym = Z3_mk_string_symbol(ctx(), CreateString(s).c_str()); + return FuncDeclPtr(Z3_mk_func_decl(ctx(), sym, 1, dom, get_sort(range))); +} + +FuncDeclPtr RawContext::MkFuncDecl(String^ s, SortPtr d1, SortPtr d2, SortPtr range) { + Z3_symbol sym = Z3_mk_string_symbol(ctx(), CreateString(s).c_str()); + Z3_sort dom[2] = { get_sort(d1), get_sort(d2) }; + return FuncDeclPtr(Z3_mk_func_decl(ctx(), sym, 2, dom, get_sort(range))); +} + +TermPtr RawContext::MkApp(FuncDeclPtr d, array^ args) { + scoped_Z3_ast_array z3_args(args); + return TermPtr(Z3_mk_app(ctx(), get_func_decl(d), z3_args.size(), z3_args.c_ptr())); +} + +TermPtr RawContext::MkApp(FuncDeclPtr d, TermPtr arg) { + Z3_ast args[1] = { get_ast(arg) }; + return TermPtr(Z3_mk_app(ctx(), get_func_decl(d), 1, args)); +} + +TermPtr RawContext::MkApp(FuncDeclPtr d, TermPtr arg1, TermPtr arg2) { + Z3_ast args[2] = { get_ast(arg1), get_ast(arg2) }; + return TermPtr(Z3_mk_app(ctx(), get_func_decl(d), 2, args)); +} + +TermPtr RawContext::MkApp(FuncDeclPtr d, TermPtr arg1, TermPtr arg2, TermPtr arg3) { + Z3_ast args[3] = { get_ast(arg1), get_ast(arg2), get_ast(arg3) }; + return TermPtr(Z3_mk_app(ctx(), get_func_decl(d), 3, args)); +} + + +TermPtr RawContext::MkConst(FuncDeclPtr d) { + return TermPtr(Z3_mk_app(ctx(),get_func_decl(d), 0, 0)); +} + +TermPtr RawContext::MkConst(String^ s, SortPtr ty) { + Z3_symbol sym = Z3_mk_string_symbol(ctx(),CreateString(s).c_str()); + Z3_func_decl d = Z3_mk_func_decl(ctx(), sym, 0, 0, get_sort(ty)); + return TermPtr(Z3_mk_app(ctx(), d, 0, 0)); +} + +TermPtr RawContext::MkConst(Symbol^ s, SortPtr ty) { + Z3_func_decl d = Z3_mk_func_decl(ctx(), s->get(), 0, 0, get_sort(ty)); + return TermPtr(Z3_mk_app(ctx(), d, 0, 0)); +} + +FuncDeclPtr RawContext::MkFreshFuncDecl(String^ prefix, array^ domain, SortPtr range) { + scoped_Z3_ast_array types(domain); + return FuncDeclPtr(Z3_mk_fresh_func_decl(ctx(), CreateString(prefix).c_str(), types.size(), types.c_ptr(), get_sort(range))); +} + +TermPtr RawContext::MkFreshConst(String^ prefix, SortPtr ty) { + return TermPtr(Z3_mk_fresh_const(ctx(), CreateString(prefix).c_str(), get_sort(ty))); +} + +TermPtr RawContext::MkLabel(Symbol^ name, bool pos, TermPtr fml) { + return TermPtr(Z3_mk_label(ctx(), name->get(), pos, get_ast(fml))); +} + + +TermPtr RawContext::MkEq(TermPtr l, TermPtr r) { + return TermPtr(Z3_mk_eq(ctx(), get_ast(l), get_ast(r))); +} + +TermPtr RawContext::MkDistinct(array^ _args) { + scoped_Z3_ast_array args(_args); + return TermPtr(Z3_mk_distinct(ctx(), args.size(), args.c_ptr())); +} + +TermPtr RawContext::MkNot(TermPtr arg) { + return TermPtr(Z3_mk_not(ctx(), get_ast(arg))); +} + +TermPtr RawContext::MkIte(TermPtr t1, TermPtr t2, TermPtr t3) { + return TermPtr(Z3_mk_ite(ctx(), get_ast(t1), get_ast(t2), get_ast(t3))); +} + +#define MK_BINARY(fn, t1, t2) return TermPtr(Z3_mk_ ## fn (ctx(), get_ast(t1), get_ast(t2))) + +#define MK_UNARY(fn, t1) return TermPtr(Z3_mk_ ## fn (ctx(), get_ast(t1))) + +#define MK_NARY(fn, _args_) { scoped_Z3_ast_array my_args(_args_); return TermPtr(Z3_mk_ ## fn (ctx(), my_args.size(), my_args.c_ptr())); } + +TermPtr RawContext::MkIff(TermPtr t1, TermPtr t2) { + MK_BINARY(iff, t1, t2); +} + +TermPtr RawContext::MkImplies(TermPtr t1, TermPtr t2) { + MK_BINARY(implies, t1, t2); +} + +TermPtr RawContext::MkXor(TermPtr t1, TermPtr t2) { + MK_BINARY(xor, t1, t2); +} + +TermPtr RawContext::MkAnd(array^ args) { + MK_NARY(and, args); +} + +TermPtr RawContext::MkAnd(TermPtr arg1, TermPtr arg2) { + Z3_ast args[2] = { get_ast(arg1), get_ast(arg2) }; + return TermPtr(Z3_mk_and(ctx(), 2, args)); +} + +TermPtr RawContext::MkOr(array^ args) { + MK_NARY(or, args); +} + +TermPtr RawContext::MkOr(TermPtr arg1, TermPtr arg2) { + Z3_ast args[2] = { get_ast(arg1), get_ast(arg2) }; + return TermPtr(Z3_mk_or(ctx(), 2, args)); +} + +TermPtr RawContext::MkAdd(array^ args) { + MK_NARY(add, args); +} + +TermPtr RawContext::MkAdd(TermPtr arg1, TermPtr arg2) { + Z3_ast args[2] = { get_ast(arg1), get_ast(arg2) }; + return TermPtr(Z3_mk_add(ctx(), 2, args)); +} + +TermPtr RawContext::MkMul(array^ args) { + MK_NARY(mul, args); +} + +TermPtr RawContext::MkMul(TermPtr arg1, TermPtr arg2) { + Z3_ast args[2] = { get_ast(arg1), get_ast(arg2) }; + return TermPtr(Z3_mk_mul(ctx(), 2, args)); +} + +TermPtr RawContext::MkSub(array^ args) { + MK_NARY(sub, args); +} + +TermPtr RawContext::MkSub(TermPtr arg1, TermPtr arg2) { + Z3_ast args[2] = { get_ast(arg1), get_ast(arg2) }; + return TermPtr(Z3_mk_sub(ctx(), 2, args)); +} + +TermPtr RawContext::MkUnaryMinus(TermPtr arg) { + MK_UNARY(unary_minus, arg); +} + +TermPtr RawContext::MkDiv(TermPtr arg1, TermPtr arg2) { + MK_BINARY(div, arg1, arg2); +} + +TermPtr RawContext::MkMod(TermPtr arg1, TermPtr arg2) { + MK_BINARY(mod, arg1, arg2); +} + +TermPtr RawContext::MkRem(TermPtr arg1, TermPtr arg2) { + MK_BINARY(rem, arg1, arg2); +} + +TermPtr RawContext::MkToReal(TermPtr arg) { + MK_UNARY(int2real, arg); +} + + +TermPtr RawContext::MkToInt(TermPtr arg) { + MK_UNARY(real2int, arg); +} + +TermPtr RawContext::MkIsInt(TermPtr arg) { + MK_UNARY(is_int, arg); +} + +TermPtr RawContext::MkLt(TermPtr arg1, TermPtr arg2) { + MK_BINARY(lt, arg1, arg2); +} + +TermPtr RawContext::MkLe(TermPtr arg1, TermPtr arg2) { + MK_BINARY(le, arg1, arg2); +} + +TermPtr RawContext::MkGt(TermPtr arg1, TermPtr arg2) { + MK_BINARY(gt, arg1, arg2); +} + +TermPtr RawContext::MkGe(TermPtr arg1, TermPtr arg2) { + MK_BINARY(ge, arg1, arg2); +} + +TermPtr RawContext::MkBvNot(TermPtr t1) { + MK_UNARY(bvnot, t1); +} + +TermPtr RawContext::MkBvReduceAnd(TermPtr t1) { + MK_UNARY(bvredand, t1); +} + +TermPtr RawContext::MkBvReduceOr(TermPtr t1) { + MK_UNARY(bvredor, t1); +} + +TermPtr RawContext::MkBvAnd(TermPtr t1, TermPtr t2) { + MK_BINARY(bvand, t1, t2); +} + +TermPtr RawContext::MkBvOr(TermPtr t1, TermPtr t2) { + MK_BINARY(bvor, t1, t2); +} + +TermPtr RawContext::MkBvXor(TermPtr t1, TermPtr t2) { + MK_BINARY(bvxor, t1, t2); +} + +TermPtr RawContext::MkBvNand(TermPtr t1, TermPtr t2) { + MK_BINARY(bvnand, t1, t2); +} + +TermPtr RawContext::MkBvNor(TermPtr t1, TermPtr t2) { + MK_BINARY(bvnor, t1, t2); +} + +TermPtr RawContext::MkBvXnor(TermPtr t1, TermPtr t2) { + MK_BINARY(bvxnor, t1, t2); +} + +TermPtr RawContext::MkBvNeg(TermPtr t1) { + MK_UNARY(bvneg, t1); +} + +TermPtr RawContext::MkBvAdd(TermPtr t1, TermPtr t2) { + MK_BINARY(bvadd, t1, t2); +} + +TermPtr RawContext::MkBvSub(TermPtr t1, TermPtr t2) { + MK_BINARY(bvsub, t1, t2); +} + +TermPtr RawContext::MkBvMul(TermPtr t1, TermPtr t2) { + MK_BINARY(bvmul, t1, t2); +} + +TermPtr RawContext::MkBvUdiv(TermPtr t1, TermPtr t2) { + MK_BINARY(bvudiv, t1, t2); +} + +TermPtr RawContext::MkBvSdiv(TermPtr t1, TermPtr t2) { + MK_BINARY(bvsdiv, t1, t2); +} + +TermPtr RawContext::MkBvUrem(TermPtr t1, TermPtr t2) { + MK_BINARY(bvurem, t1, t2); +} +TermPtr RawContext::MkBvSrem(TermPtr t1, TermPtr t2) { + MK_BINARY(bvsrem, t1, t2); +} + +TermPtr RawContext::MkBvSmod(TermPtr t1, TermPtr t2) { + MK_BINARY(bvsmod, t1, t2); +} + +TermPtr RawContext::MkBvUlt(TermPtr t1, TermPtr t2) { + MK_BINARY(bvult, t1, t2); +} + +TermPtr RawContext::MkBvSlt(TermPtr t1, TermPtr t2) { + MK_BINARY(bvslt, t1, t2); +} + +TermPtr RawContext::MkBvUle(TermPtr t1, TermPtr t2) { + MK_BINARY(bvule, t1, t2); +} + +TermPtr RawContext::MkBvSle(TermPtr t1, TermPtr t2) { + MK_BINARY(bvsle, t1, t2); +} + +TermPtr RawContext::MkBvUge(TermPtr t1, TermPtr t2) { + MK_BINARY(bvuge, t1, t2); +} + +TermPtr RawContext::MkBvSge(TermPtr t1, TermPtr t2) { + MK_BINARY(bvsge, t1, t2); +} + +TermPtr RawContext::MkBvUgt(TermPtr t1, TermPtr t2) { + MK_BINARY(bvugt, t1, t2); +} + +TermPtr RawContext::MkBvSgt(TermPtr t1, TermPtr t2) { + MK_BINARY(bvsgt, t1, t2); +} + +TermPtr RawContext::MkBvConcat(TermPtr t1, TermPtr t2) { + MK_BINARY(concat, t1, t2); +} + +TermPtr RawContext::MkBvExtract(unsigned high, unsigned low, TermPtr t) { + return TermPtr(Z3_mk_extract(ctx(), high, low, get_ast(t))); +} + +TermPtr RawContext::MkBvSignExt(unsigned i, TermPtr t) { + return TermPtr(Z3_mk_sign_ext(ctx(), i, get_ast(t))); +} + +TermPtr RawContext::MkBvZeroExt(unsigned i, TermPtr t) { + return TermPtr(Z3_mk_zero_ext(ctx(), i, get_ast(t))); +} + +TermPtr RawContext::MkBvRepeat(unsigned i, TermPtr t) { + return TermPtr(Z3_mk_repeat(ctx(), i, get_ast(t))); +} + +TermPtr RawContext::MkBvShl(TermPtr t1, TermPtr t2) { + MK_BINARY(bvshl, t1, t2); +} + +TermPtr RawContext::MkBvLshr(TermPtr t1, TermPtr t2) { + MK_BINARY(bvlshr, t1, t2); +} + +TermPtr RawContext::MkBvAshr(TermPtr t1, TermPtr t2) { + MK_BINARY(bvashr, t1, t2); +} + +TermPtr RawContext::MkBvRotateLeft(unsigned i, TermPtr t1) { + return TermPtr(Z3_mk_rotate_left(ctx(), i, get_ast(t1))); +} + +TermPtr RawContext::MkBvRotateRight(unsigned i, TermPtr t1) { + return TermPtr(Z3_mk_rotate_right(ctx(), i, get_ast(t1))); +} + +TermPtr RawContext::MkBvRotateLeft(TermPtr t1, TermPtr t2) { + return TermPtr(Z3_mk_ext_rotate_left(ctx(), get_ast(t1), get_ast(t2))); +} + +TermPtr RawContext::MkBvRotateRight(TermPtr t1, TermPtr t2) { + return TermPtr(Z3_mk_ext_rotate_right(ctx(), get_ast(t1), get_ast(t2))); +} + +TermPtr RawContext::MkInt2Bv(unsigned i, TermPtr t1) { + return TermPtr(Z3_mk_int2bv(ctx(), i, get_ast(t1))); +} + +TermPtr RawContext::MkBv2Int(TermPtr t1, bool is_signed) { + return TermPtr(Z3_mk_bv2int(ctx(), get_ast(t1), is_signed)); +} + +TermPtr RawContext::MkBvAddNoOverflow(TermPtr t1, TermPtr t2, bool is_signed) { + return TermPtr(Z3_mk_bvadd_no_overflow(ctx(), get_ast(t1), get_ast(t2), is_signed)); +} + +TermPtr RawContext::MkBvAddNoUnderflow(TermPtr t1, TermPtr t2) { + return TermPtr(Z3_mk_bvadd_no_underflow(ctx(), get_ast(t1), get_ast(t2))); +} + +TermPtr RawContext::MkBvSubNoOverflow(TermPtr t1, TermPtr t2) { + return TermPtr(Z3_mk_bvsub_no_overflow(ctx(), get_ast(t1), get_ast(t2))); +} + +TermPtr RawContext::MkBvSubNoUnderflow(TermPtr t1, TermPtr t2, bool is_signed) { + return TermPtr(Z3_mk_bvsub_no_underflow(ctx(), get_ast(t1), get_ast(t2), is_signed)); +} + +TermPtr RawContext::MkBvSDivNoOverflow(TermPtr t1, TermPtr t2) { + return TermPtr(Z3_mk_bvsdiv_no_overflow(ctx(), get_ast(t1), get_ast(t2))); +} + +TermPtr RawContext::MkBvNegNoOverflow(TermPtr t1) { + return TermPtr(Z3_mk_bvneg_no_overflow(ctx(), get_ast(t1))); +} + +TermPtr RawContext::MkBvMulNoOverflow(TermPtr t1, TermPtr t2, bool is_signed) { + return TermPtr(Z3_mk_bvmul_no_overflow(ctx(), get_ast(t1), get_ast(t2), is_signed)); +} + +TermPtr RawContext::MkBvMulNoUnderflow(TermPtr t1, TermPtr t2) { + return TermPtr(Z3_mk_bvmul_no_underflow(ctx(), get_ast(t1), get_ast(t2))); +} + +TermPtr RawContext::MkArraySelect(TermPtr a, TermPtr i) { + return TermPtr(Z3_mk_select(ctx(), get_ast(a), get_ast(i))); +} + +TermPtr RawContext::MkArrayStore(TermPtr a, TermPtr i, TermPtr v) { + return TermPtr(Z3_mk_store(ctx(), get_ast(a), get_ast(i), get_ast(v))); +} + +TermPtr RawContext::MkArrayMap(FuncDeclPtr d, array^ args) { + scoped_Z3_ast_array _args(args); + return TermPtr(Z3_mk_map(ctx(), get_func_decl(d), _args.size(), _args.c_ptr())); +} + +TermPtr RawContext::MkArrayConst(SortPtr domain, TermPtr v) { + return TermPtr(Z3_mk_const_array(ctx(), get_sort(domain), get_ast(v))); +} + +TermPtr RawContext::MkArrayDefault(TermPtr a) { + return TermPtr(Z3_mk_array_default(ctx(), get_ast(a))); +} + +TermPtr RawContext::MkSetUnion(array^ sets) { + scoped_Z3_ast_array _sets(sets); + return TermPtr(Z3_mk_set_union(ctx(), _sets.size(), _sets.c_ptr())); +} + +TermPtr RawContext::MkSetUnion(TermPtr set1, TermPtr set2) { + Z3_ast args[2] = { get_ast(set1), get_ast(set2) }; + return TermPtr(Z3_mk_set_union(ctx(), 2, args)); +} + +TermPtr RawContext::MkSetIntersect(array^ sets) { + scoped_Z3_ast_array _sets(sets); + return TermPtr(Z3_mk_set_intersect(ctx(), _sets.size(), _sets.c_ptr())); +} + +TermPtr RawContext::MkSetIntersect(TermPtr set1, TermPtr set2) { + Z3_ast args[2] = { get_ast(set1), get_ast(set2) }; + return TermPtr(Z3_mk_set_intersect(ctx(), 2, args)); +} + +FuncDeclPtr RawContext::MkInjectiveFunction(String^ name, array^ domain, SortPtr range) { + scoped_Z3_ast_array types(domain); + Z3_symbol sym = Z3_mk_string_symbol(ctx(), CreateString(name).c_str()); + return FuncDeclPtr(Z3_mk_injective_function(ctx(), sym, types.size(), types.c_ptr(), get_sort(range))); +} + +FuncDeclPtr RawContext::MkInjectiveFunction(Symbol^ name, array^ domain, SortPtr range) { + scoped_Z3_ast_array types(domain); + return FuncDeclPtr(Z3_mk_injective_function(ctx(), name->get(), types.size(), types.c_ptr(), get_sort(range))); +} + + +TermPtr RawContext::MkNumeral(String^ numeral, SortPtr ty) { + return TermPtr(Z3_mk_numeral(ctx(), CreateString(numeral).c_str(), get_sort(ty))); +} + +TermPtr RawContext::MkNumeral(int n, SortPtr ty) { + return TermPtr(Z3_mk_int(ctx(), n, get_sort(ty))); +} + +TermPtr RawContext::MkNumeral(unsigned n, SortPtr ty) { + return TermPtr(Z3_mk_unsigned_int(ctx(), n, get_sort(ty))); +} + +TermPtr RawContext::MkNumeral(__int64 n, SortPtr ty) { + return TermPtr(Z3_mk_int64(ctx(), n, get_sort(ty))); +} + +TermPtr RawContext::MkNumeral(unsigned __int64 n, SortPtr ty) { + return TermPtr(Z3_mk_unsigned_int64(ctx(), n, get_sort(ty))); +} + +PatternPtr RawContext::MkPattern(array^ terms) { + scoped_Z3_ast_array args(terms); + return PatternPtr(Z3_mk_pattern(ctx(), args.size(), args.c_ptr())); +} + +TermPtr RawContext::MkBound(unsigned index, SortPtr ty) { + return TermPtr(Z3_mk_bound(ctx(), index, get_sort(ty))); +} + +TermPtr RawContext::MkForall( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + TermPtr body + ) +{ + scoped_Z3_ast_array _patterns(patterns); + scoped_Z3_ast_array _types(types); + scoped_Z3_symbol_array _names(names); + return TermPtr( + Z3_mk_forall( + ctx(), + weight, + _patterns.size(), + _patterns.c_ptr(), + _types.size(), + _types.c_ptr(), + _names.c_ptr(), + get_ast(body) + ) + ); +} + +TermPtr RawContext::MkForall( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + TermPtr body + ) +{ + if (!names) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + array^ nameSymbols = gcnew array(names->Length); + for (int i = 0; i < nameSymbols->Length; ++i) { + nameSymbols[i] = MkSymbol(names[i]); + } + return MkForall(weight, patterns, types, nameSymbols, body); +} + +TermPtr RawContext::MkForall( + unsigned weight, + array^ bound, + array^ patterns, + TermPtr body + ) +{ + scoped_Z3_ast_array _bound(bound); + scoped_Z3_ast_array _patterns(patterns); + return TermPtr( + Z3_mk_forall_const( + ctx(), + weight, + _bound.size(), + _bound.c_ptr(), + _patterns.size(), + _patterns.c_ptr(), + get_ast(body) + )); +} + +TermPtr RawContext::MkExists( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + TermPtr body + ) +{ + scoped_Z3_ast_array _patterns(patterns); + scoped_Z3_ast_array _types(types); + scoped_Z3_symbol_array _names(names); + return TermPtr( + Z3_mk_exists( + ctx(), + weight, + _patterns.size(), + _patterns.c_ptr(), + _types.size(), + _types.c_ptr(), + _names.c_ptr(), + get_ast(body) + ) + ); +} + +TermPtr RawContext::MkExists( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + TermPtr body + ) +{ + if (!names) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + array^ nameSymbols = gcnew array(names->Length); + for (int i = 0; i < nameSymbols->Length; ++i) { + nameSymbols[i] = MkSymbol(names[i]); + } + return MkExists(weight, patterns, types, nameSymbols, body); +} + +TermPtr RawContext::MkExists( + unsigned weight, + array^ bound, + array^ patterns, + TermPtr body + ) +{ + scoped_Z3_ast_array _bound(bound); + scoped_Z3_ast_array _patterns(patterns); + return TermPtr( + Z3_mk_exists_const( + ctx(), + weight, + _bound.size(), + _bound.c_ptr(), + _patterns.size(), + _patterns.c_ptr(), + get_ast(body) + )); +} + +TermPtr RawContext::MkQuantifier( + bool is_forall, + unsigned weight, + Symbol^ quantifier_id, + Symbol^ skolem_id, + array^ patterns, + array^ no_patterns, + array^ types, + array^ names, + TermPtr body + ) +{ + scoped_Z3_ast_array _patterns(patterns); + scoped_Z3_ast_array _no_patterns(no_patterns); + scoped_Z3_ast_array _types(types); + scoped_Z3_symbol_array _names(names); + return TermPtr( + Z3_mk_quantifier_ex( + ctx(), + is_forall, + weight, + quantifier_id?quantifier_id->get():0, + skolem_id?skolem_id->get():0, + _patterns.size(), + _patterns.c_ptr(), + _no_patterns.size(), + _no_patterns.c_ptr(), + _types.size(), + _types.c_ptr(), + _names.c_ptr(), + get_ast(body) + ) + ); +} + +TermPtr RawContext::MkQuantifier( + bool is_forall, + unsigned weight, + Symbol^ quantifier_id, + Symbol^ skolem_id, + array^ patterns, + array^ no_patterns, + array^ bound, + TermPtr body + ) +{ + scoped_Z3_ast_array _patterns(patterns); + scoped_Z3_ast_array _no_patterns(no_patterns); + scoped_Z3_ast_array _bound(bound); + return TermPtr( + Z3_mk_quantifier_const_ex( + ctx(), + is_forall, + weight, + quantifier_id?quantifier_id->get():0, + skolem_id?skolem_id->get():0, + _bound.size(), _bound.c_ptr(), + _patterns.size(), + _patterns.c_ptr(), + _no_patterns.size(), + _no_patterns.c_ptr(), + get_ast(body) + ) + ); +} + +unsigned RawContext::GetTermId(TermPtr t) { + return Z3_get_ast_id(ctx(), get_ast(t)); +} + +unsigned RawContext::GetFuncDeclId(FuncDeclPtr t) { + return Z3_get_func_decl_id(ctx(), get_func_decl(t)); +} + +unsigned RawContext::GetSortId(SortPtr t) { + return Z3_get_sort_id(ctx(), get_sort(t)); +} + +SymbolKind RawContext::GetSymbolKind(Symbol^ s) { + switch(Z3_get_symbol_kind(ctx(), s->get())) { + case Z3_INT_SYMBOL: + return SymbolKind::Int; + case Z3_STRING_SYMBOL: + return SymbolKind::String; + default: + UNREACHABLE(); + } + return SymbolKind::Int; +} + +int RawContext::GetSymbolInt(Symbol^ s) { + return Z3_get_symbol_int(ctx(), s->get()); +} + +String^ Symbol::ToString() { + return gcnew String(Z3_get_symbol_string(m_ctx, m_symbol)); +} + +String^ RawContext::GetSymbolString(Symbol^ s) { + return gcnew String(Z3_get_symbol_string(ctx(), s->get())); +} + +bool RawContext::IsEq(TermPtr t1, TermPtr t2) { + return Z3_TRUE == Z3_is_eq_ast(ctx(), get_ast(t1), get_ast(t2)); +} + +bool RawContext::IsWellSorted(TermPtr t) { + return Z3_is_well_sorted(ctx(), get_ast(t)) == Z3_TRUE; +} + +TermKind RawContext::GetTermKind(TermPtr a) { + switch(Z3_get_ast_kind(ctx(), get_ast(a))) { + case Z3_NUMERAL_AST: + return TermKind::Numeral; + case Z3_APP_AST: + return TermKind::App; + case Z3_VAR_AST: + return TermKind::Var; + case Z3_QUANTIFIER_AST: + return TermKind::Quantifier; + case Z3_UNKNOWN_AST: + return TermKind::Unknown; + } + UNREACHABLE(); + return TermKind::Unknown; +} + +DeclKind RawContext::GetDeclKind(FuncDeclPtr d) { + switch(Z3_get_decl_kind(ctx(), get_func_decl(d))) { + case Z3_OP_TRUE: return DeclKind::True; + case Z3_OP_FALSE: return DeclKind::False; + case Z3_OP_EQ: return DeclKind::Eq; + case Z3_OP_DISTINCT: return DeclKind::Distinct; + case Z3_OP_ITE: return DeclKind::Ite; + case Z3_OP_AND: return DeclKind::And; + case Z3_OP_OR: return DeclKind::Or; + case Z3_OP_IFF: return DeclKind::Iff; + case Z3_OP_XOR: return DeclKind::Xor; + case Z3_OP_NOT: return DeclKind::Not; + case Z3_OP_IMPLIES: return DeclKind::Implies; + case Z3_OP_ANUM: return DeclKind::ArithNum; + case Z3_OP_LE: return DeclKind::Le; + case Z3_OP_GE: return DeclKind::Ge; + case Z3_OP_LT: return DeclKind::Lt; + case Z3_OP_GT: return DeclKind::Gt; + case Z3_OP_ADD: return DeclKind::Add; + case Z3_OP_SUB: return DeclKind::Sub; + case Z3_OP_UMINUS: return DeclKind::Uminus; + case Z3_OP_MUL: return DeclKind::Mul; + case Z3_OP_DIV: return DeclKind::Div; + case Z3_OP_IDIV: return DeclKind::IDiv; + case Z3_OP_REM: return DeclKind::Rem; + case Z3_OP_MOD: return DeclKind::Mod; + case Z3_OP_TO_REAL: return DeclKind::ToReal; + case Z3_OP_TO_INT: return DeclKind::ToInt; + case Z3_OP_IS_INT: return DeclKind::IsInt; + case Z3_OP_STORE: return DeclKind::Store; + case Z3_OP_SELECT: return DeclKind::Select; + case Z3_OP_CONST_ARRAY: return DeclKind::ConstArray; + case Z3_OP_ARRAY_DEFAULT: return DeclKind::DefaultArray; + case Z3_OP_ARRAY_MAP: return DeclKind::MapArray; + case Z3_OP_SET_UNION: return DeclKind::Union; + case Z3_OP_SET_INTERSECT: return DeclKind::Intersect; + case Z3_OP_SET_DIFFERENCE: return DeclKind::Difference; + case Z3_OP_SET_COMPLEMENT: return DeclKind::Complement; + case Z3_OP_SET_SUBSET: return DeclKind::Subset; + case Z3_OP_AS_ARRAY: return DeclKind::AsArray; + case Z3_OP_BNUM: return DeclKind::BitNum; + case Z3_OP_BIT1: return DeclKind::Bit1 ; + case Z3_OP_BIT0: return DeclKind::Bit0 ; + case Z3_OP_BNEG: return DeclKind::BNeg ; + case Z3_OP_BADD: return DeclKind::BAdd ; + case Z3_OP_BSUB: return DeclKind::BSub ; + case Z3_OP_BMUL: return DeclKind::BMul ; + + case Z3_OP_BSDIV: return DeclKind::BSDiv ; + case Z3_OP_BUDIV: return DeclKind::BUDiv ; + case Z3_OP_BSREM: return DeclKind::BSRem ; + case Z3_OP_BUREM: return DeclKind::BURem ; + case Z3_OP_BSMOD: return DeclKind::BSMod ; + + // special functions to record the division by 0 cases + // these are internal functions + case Z3_OP_BSDIV0: return DeclKind::BSDiv0 ; + case Z3_OP_BUDIV0: return DeclKind::BUDiv0 ; + case Z3_OP_BSREM0: return DeclKind::BSRem0 ; + case Z3_OP_BUREM0: return DeclKind::BURem0 ; + case Z3_OP_BSMOD0: return DeclKind::BSMod0 ; + + case Z3_OP_ULEQ: return DeclKind::BULeq ; + case Z3_OP_SLEQ: return DeclKind::BSLeq ; + case Z3_OP_UGEQ: return DeclKind::BUGeq ; + case Z3_OP_SGEQ: return DeclKind::BSGeq ; + case Z3_OP_ULT: return DeclKind::BULt ; + case Z3_OP_SLT: return DeclKind::BSLt ; + case Z3_OP_UGT: return DeclKind::BUGt ; + case Z3_OP_SGT: return DeclKind::BSGt ; + + case Z3_OP_BAND: return DeclKind::BAnd ; + case Z3_OP_BOR: return DeclKind::BOr ; + case Z3_OP_BNOT: return DeclKind::BNot; + case Z3_OP_BXOR: return DeclKind::BXor ; + case Z3_OP_BNAND: return DeclKind::BNand ; + case Z3_OP_BNOR: return DeclKind::BNor ; + case Z3_OP_BXNOR: return DeclKind::BXnor ; + + case Z3_OP_CONCAT: return DeclKind::BConcat ; + case Z3_OP_SIGN_EXT: return DeclKind::BSignExt ; + case Z3_OP_ZERO_EXT: return DeclKind::BZeroExt ; + case Z3_OP_EXTRACT: return DeclKind::BExtract ; + case Z3_OP_REPEAT: return DeclKind::BRepeat ; + + case Z3_OP_BREDOR: return DeclKind::BRedOr ; + case Z3_OP_BREDAND: return DeclKind::BRedAnd ; + case Z3_OP_BCOMP: return DeclKind::BComp ; + + case Z3_OP_BSHL: return DeclKind::BShl ; + case Z3_OP_BLSHR: return DeclKind::BLShr ; + case Z3_OP_BASHR: return DeclKind::BAShr ; + case Z3_OP_ROTATE_LEFT: return DeclKind::BRotateLeft ; + case Z3_OP_ROTATE_RIGHT: return DeclKind::BRotateRight ; + case Z3_OP_EXT_ROTATE_LEFT: return DeclKind::BExtRotateLeft ; + case Z3_OP_EXT_ROTATE_RIGHT: return DeclKind::BExtRotateRight ; + + case Z3_OP_INT2BV: return DeclKind::BInt2Bv ; + case Z3_OP_BV2INT: return DeclKind::BBv2Int ; + case Z3_OP_CARRY: return DeclKind::BCarry; + case Z3_OP_XOR3: return DeclKind::BXor3; + + case Z3_OP_PR_ASSERTED: return DeclKind::PrAsserted ; + case Z3_OP_PR_GOAL: return DeclKind::PrGoal ; + case Z3_OP_PR_MODUS_PONENS: return DeclKind::PrModusPonens ; + case Z3_OP_PR_REFLEXIVITY: return DeclKind::PrReflexivity ; + case Z3_OP_PR_SYMMETRY: return DeclKind::PrSymmetry ; + case Z3_OP_PR_TRANSITIVITY: return DeclKind::PrTransitivity ; + case Z3_OP_PR_TRANSITIVITY_STAR: return DeclKind::PrTransitivityStar ; + case Z3_OP_PR_MONOTONICITY: return DeclKind::PrMonotonicity ; + case Z3_OP_PR_QUANT_INTRO: return DeclKind::PrQuantIntro ; + case Z3_OP_PR_DISTRIBUTIVITY: return DeclKind::PrDistributivity ; + case Z3_OP_PR_AND_ELIM: return DeclKind::PrAndElim ; + case Z3_OP_PR_NOT_OR_ELIM: return DeclKind::PrNotOrElim ; + case Z3_OP_PR_REWRITE: return DeclKind::PrRewrite ; + case Z3_OP_PR_REWRITE_STAR: return DeclKind::PrRewriteStar ; + case Z3_OP_PR_PULL_QUANT: return DeclKind::PrPullQuant ; + case Z3_OP_PR_PULL_QUANT_STAR: return DeclKind::PrPullQuantStar ; + case Z3_OP_PR_PUSH_QUANT: return DeclKind::PrPushQuant ; + case Z3_OP_PR_ELIM_UNUSED_VARS: return DeclKind::PrElimUnusedVars ; + case Z3_OP_PR_DER: return DeclKind::PrDer ; + case Z3_OP_PR_QUANT_INST: return DeclKind::PrQuantInst ; + case Z3_OP_PR_HYPOTHESIS: return DeclKind::PrHypothesis ; + case Z3_OP_PR_LEMMA: return DeclKind::PrLemma ; + case Z3_OP_PR_UNIT_RESOLUTION: return DeclKind::PrUnitResolution ; + case Z3_OP_PR_IFF_TRUE: return DeclKind::PrIffTrue ; + case Z3_OP_PR_IFF_FALSE: return DeclKind::PrIffFalse ; + case Z3_OP_PR_COMMUTATIVITY: return DeclKind::PrCommutativity ; + case Z3_OP_PR_DEF_AXIOM: return DeclKind::PrDefAxiom ; + case Z3_OP_PR_DEF_INTRO: return DeclKind::PrDefIntro ; + case Z3_OP_PR_APPLY_DEF: return DeclKind::PrApplyDef ; + case Z3_OP_PR_IFF_OEQ: return DeclKind::PrIffOeq ; + case Z3_OP_PR_NNF_POS: return DeclKind::PrNnfPos ; + case Z3_OP_PR_NNF_NEG: return DeclKind::PrNnfNeg ; + case Z3_OP_PR_NNF_STAR: return DeclKind::PrNnfStar ; + case Z3_OP_PR_SKOLEMIZE: return DeclKind::PrSkolemize ; + case Z3_OP_PR_CNF_STAR: return DeclKind::PrCnfStar ; + case Z3_OP_PR_MODUS_PONENS_OEQ: return DeclKind::PrModusPonensOeq ; + case Z3_OP_PR_TH_LEMMA: return DeclKind::PrThLemma ; + case Z3_OP_LABEL: return DeclKind::Label; + case Z3_OP_LABEL_LIT: return DeclKind::LabelLit; + case Z3_OP_RA_STORE: return DeclKind::RaStore; + case Z3_OP_RA_EMPTY: return DeclKind::RaEmpty; + case Z3_OP_RA_IS_EMPTY: return DeclKind::RaIsEmpty; + case Z3_OP_RA_JOIN: return DeclKind::RaJoin; + case Z3_OP_RA_UNION: return DeclKind::RaUnion; + case Z3_OP_RA_WIDEN: return DeclKind::RaWiden; + case Z3_OP_RA_PROJECT: return DeclKind::RaProject; + case Z3_OP_RA_FILTER: return DeclKind::RaFilter; + case Z3_OP_RA_NEGATION_FILTER: return DeclKind::RaNegationFilter; + case Z3_OP_RA_RENAME: return DeclKind::RaRename; + case Z3_OP_RA_COMPLEMENT: return DeclKind::RaComplement; + case Z3_OP_RA_SELECT: return DeclKind::RaSelect; + case Z3_OP_RA_CLONE: return DeclKind::RaClone; + + case Z3_OP_UNINTERPRETED: return DeclKind::Uninterpreted; + default: + UNREACHABLE(); + return DeclKind::Uninterpreted; + } +} + +array^ RawContext::GetDeclParameters(FuncDeclPtr d) { + Z3_func_decl fd = get_func_decl(d); + unsigned num_params = Z3_get_decl_num_parameters(ctx(), fd); + array^ params = gcnew array(num_params); + for (unsigned i = 0; i < num_params; ++i) { + switch(Z3_get_decl_parameter_kind(ctx(), fd, i)) { + case Z3_PARAMETER_INT: + params[i] = gcnew IntParameter(Z3_get_decl_int_parameter(ctx(), fd, i)); + break; + case Z3_PARAMETER_DOUBLE: + params[i] = gcnew DoubleParameter(Z3_get_decl_double_parameter(ctx(), fd, i)); + break; + case Z3_PARAMETER_RATIONAL: { + Z3_string s = Z3_get_decl_rational_parameter(ctx(), fd, i); + params[i] = gcnew RationalParameter(gcnew String(s)); + break; + } + case Z3_PARAMETER_SYMBOL: { + Z3_symbol s = Z3_get_decl_symbol_parameter(ctx(), fd, i); + params[i] = gcnew SymbolParameter(gcnew Symbol(ctx(), s)); + break; + } + case Z3_PARAMETER_SORT: + params[i] = gcnew SortPtrParameter(SortPtr(Z3_get_decl_sort_parameter(ctx(), fd, i))); + break; + case Z3_PARAMETER_AST: + params[i] = gcnew TermPtrParameter(TermPtr(Z3_get_decl_ast_parameter(ctx(), fd, i))); + break; + case Z3_PARAMETER_FUNC_DECL: + params[i] = gcnew FuncDeclPtrParameter(FuncDeclPtr(Z3_get_decl_func_decl_parameter(ctx(), fd, i))); + break; + default: + UNREACHABLE(); + break; + } + } + return params; +} + +FuncDeclPtr RawContext::GetAppDecl(AppPtr a) { + if (GetTermKind(a) != TermKind::App) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + return FuncDeclPtr(Z3_get_app_decl(ctx(), get_const_ast(a))); +} + +array^ RawContext::GetAppArgs(AppPtr a) { + if (GetTermKind(a) != TermKind::App) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + + unsigned num_args = Z3_get_app_num_args(ctx(), get_const_ast(a)); + array^ result = gcnew array(num_args); + for (unsigned i = 0; i < num_args; ++i) { + result[i] = TermPtr(Z3_get_app_arg(ctx(), get_const_ast(a), i)); + } + return result; +} + +RawQuantifier^ RawContext::GetQuantifier(TermPtr a) { + if (GetTermKind(a) != TermKind::Quantifier) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + RawQuantifier^ t = gcnew RawQuantifier(); + Z3_ast ast = get_ast(a); + t->IsForall = Z3_TRUE == Z3_is_quantifier_forall(ctx(), ast); + t->Weight = Z3_get_quantifier_weight(ctx(), ast); + t->Patterns = gcnew array(Z3_get_quantifier_num_patterns(ctx(), ast)); + t->NoPatterns = gcnew array(Z3_get_quantifier_num_no_patterns(ctx(), ast)); + t->Sorts = gcnew array(Z3_get_quantifier_num_bound(ctx(), ast)); + t->Names = gcnew array(Z3_get_quantifier_num_bound(ctx(), ast)); + t->Body = TermPtr(Z3_get_quantifier_body(ctx(), ast)); + for (int i = 0; i < t->Sorts->Length; ++i) { + t->Sorts[i] = SortPtr(Z3_get_quantifier_bound_sort(ctx(), ast, i)); + t->Names[i] = gcnew Symbol(ctx(), Z3_get_quantifier_bound_name(ctx(), ast, i)); + } + for (int i = 0; i < t->Patterns->Length; ++i) { + t->Patterns[i] = PatternPtr(Z3_get_quantifier_pattern_ast(ctx(), ast, i)); + } + for (int i = 0; i < t->NoPatterns->Length; ++i) { + t->NoPatterns[i] = TermPtr(Z3_get_quantifier_no_pattern_ast(ctx(), ast, i)); + } + return t; +}; + +array^ RawContext::GetPatternTerms(PatternPtr p) { + unsigned np = Z3_get_pattern_num_terms(ctx(), get_pattern(p)); + array^ result = gcnew array(np); + for (unsigned i = 0; i < np; ++i) { + result[i] = TermPtr(Z3_get_pattern(ctx(), get_pattern(p), i)); + } + return result; +} + +Symbol^ RawContext::GetDeclName(FuncDeclPtr d) { + return gcnew Symbol(ctx(), Z3_get_decl_name(ctx(), get_func_decl(d))); +} + +Symbol^ RawContext::GetSortName(SortPtr ty) { + return gcnew Symbol(ctx(), Z3_get_sort_name(ctx(), get_sort(ty))); +} + +SortPtr RawContext::GetSort(TermPtr a) { + return SortPtr(Z3_get_sort(ctx(), get_ast(a))); +} + +array^ RawContext::GetDomain(FuncDeclPtr d) { + unsigned num_args = Z3_get_domain_size(ctx(), get_func_decl(d)); + array^ result = gcnew array(num_args); + for (unsigned i = 0; i < num_args; ++i) { + result[i] = TermPtr(Z3_get_domain(ctx(), get_func_decl(d), i)); + } + return result; +} + + +SortPtr RawContext::GetRange(FuncDeclPtr d) { + return SortPtr(Z3_get_range(ctx(), get_func_decl(d))); +} + +SortKind RawContext::GetSortKind(SortPtr t) { + switch(Z3_get_sort_kind(ctx(), get_sort(t))) { + case Z3_UNINTERPRETED_SORT: return SortKind::Uninterpreted; + case Z3_BOOL_SORT: return SortKind::Bool; + case Z3_INT_SORT: return SortKind::Int; + case Z3_REAL_SORT: return SortKind::Real; + case Z3_BV_SORT: return SortKind::BitVector; + case Z3_ARRAY_SORT: return SortKind::Array; + case Z3_DATATYPE_SORT: return SortKind::Datatype; + case Z3_UNKNOWN_SORT: return SortKind::Unknown; + default: UNREACHABLE(); return SortKind::Unknown; + } +} + +SearchFailureExplanation RawContext::GetSearchFailureExplanation() { + return ConvertExplanation(Z3_get_search_failure(ctx())); +} + +unsigned RawContext::GetBvSortSize(SortPtr t) { + return Z3_get_bv_sort_size(ctx(), get_sort(t)); +} + +SortPtr RawContext::GetArraySortDomain(SortPtr t) { + return SortPtr(Z3_get_array_sort_domain(ctx(), get_sort(t))); +} + +SortPtr RawContext::GetArraySortRange(SortPtr t) { + return SortPtr(Z3_get_array_sort_range(ctx(), get_sort(t))); +} + +FuncDeclPtr RawContext::GetTupleConstructor(SortPtr t) { + return FuncDeclPtr(Z3_get_tuple_sort_mk_decl(ctx(), get_sort(t))); +} + +array^ RawContext::GetTupleFields(SortPtr t) { + unsigned num_args = Z3_get_tuple_sort_num_fields(ctx(), get_sort(t)); + array^ result = gcnew array(num_args); + for (unsigned i = 0; i < num_args; ++i) { + result[i] = FuncDeclPtr(Z3_get_tuple_sort_field_decl(ctx(), get_sort(t), i)); + } + return result; +} + +void RawContext::Push() { + Z3_push(ctx()); +} + +void RawContext::Pop(unsigned num_scopes) { + Z3_pop(ctx(), num_scopes); +} + +unsigned RawContext::GetNumScopes() { + return Z3_get_num_scopes(ctx()); +} + +void RawContext::PersistTerm(TermPtr t, unsigned num_scopes) { + Z3_persist_ast(ctx(), get_ast(t), num_scopes); +} + +void RawContext::IncRef(IntPtr ast) { + Z3_inc_ref(ctx(), get_ast(ast)); + // decrement reference counts of whatever is gc'ed. + if (s_nonempty) { + System::Threading::Monitor::Enter(s_monitor); + for (int i = 0; i < s_todec->Count; ++i) { + AstPtr a = s_todec[i].Key; + RawContext^ c = s_todec[i].Value; + SASSERT(c->ref_context().is_ref_counted()); + Z3_dec_ref(c->ctx(), get_ast(a)); + c->ref_context().dec_ref(); + } + s_todec->Clear(); + s_nonempty = false; + System::Threading::Monitor::Exit(s_monitor); + } +} + +void RawContext::EnqueueDecRef(IntPtr ast) { + System::Threading::Monitor::Enter(s_monitor); + s_todec->Add(KeyValuePair(ast, this)); + s_nonempty = true; + System::Threading::Monitor::Exit(s_monitor); +} + +void RawContext::AssertCnstr(TermPtr a) { + Z3_assert_cnstr(ctx(), get_ast(a)); +} + +LBool RawContext::CheckAndGetModel(RawModel^% m) { + m = nullptr; + Z3_model model = 0; + Z3_lbool lb = Z3_check_and_get_model(ctx(), & model); + + if (model) { + m = gcnew RawModel(*m_context, model); + } + else { + m = nullptr; + } + return ToLBool(lb); +} + +LBool RawContext::Check() { + Z3_lbool lb = Z3_check(ctx()); + return ToLBool(lb); +} + +LBool RawContext::CheckAssumptions(RawModel^% m, array^ assumptions, TermPtr% proof, array^% core) { + scoped_Z3_ast_array _assumptions(assumptions); + scoped_Z3_ast_array _core(assumptions); + unsigned core_size = 0; + Z3_ast _proof = 0; + Z3_model model = 0; + Z3_lbool lb = Z3_check_assumptions( + ctx(), + _assumptions.size(), + _assumptions.c_ptr(), + &model, + &_proof, + &core_size, + _core.c_ptr()); + + core = gcnew array(core_size); + for (unsigned i = 0; i < core_size; ++i) { + core[i] = TermPtr(_core[i]); + } + if(_proof) { + proof = TermPtr(_proof); + } + if (model) { + m = gcnew RawModel(*m_context, model); + } + return ToLBool(lb); +} + +void RawContext::SoftCheckCancel() { + Z3_soft_check_cancel(ctx()); +} + +LBool RawContext::GetImpliedEqualities( + [In] array^ terms, + [Out] array^% class_ids) { + scoped_Z3_ast_array _terms(terms); + scoped_array _class_ids(_terms.size()); + Z3_lbool lb = Z3_get_implied_equalities(ctx(), _terms.size(), _terms.c_ptr(), _class_ids.c_ptr()); + class_ids = gcnew array(_terms.size()); + for (unsigned i = 0; i < _terms.size(); ++i) { + class_ids[i] = _class_ids[i]; + } + return ToLBool(lb); +} + +LabeledLiterals^ RawContext::GetRelevantLabels() { + Z3_literals lbls = Z3_get_relevant_labels(ctx()); + return gcnew LabeledLiterals(*m_context, lbls); +} + +LabeledLiterals^ RawContext::GetRelevantLiterals() { + Z3_literals lbls = Z3_get_relevant_literals(ctx()); + return gcnew LabeledLiterals(*m_context, lbls); +} + +LabeledLiterals^ RawContext::GetGuessedLiterals() { + Z3_literals lbls = Z3_get_guessed_literals(ctx()); + return gcnew LabeledLiterals(*m_context, lbls); +} + +void RawContext::BlockLiterals(LabeledLiterals^ lbls) { + Z3_block_literals(ctx(), lbls->Get()); +} + +TermPtr RawContext::Simplify(TermPtr a) { + return TermPtr(Z3_simplify(ctx(), get_ast(a))); +} + + +String^ RawContext::ToString() { + return gcnew String(Z3_context_to_string(ctx())); +} + +void RawContext::SetPrintMode(PrintMode mode) { + Z3_ast_print_mode m = Z3_PRINT_SMTLIB_FULL; + switch(mode) { + case PrintMode::SmtlibFull: + m = Z3_PRINT_SMTLIB_FULL; + break; + case PrintMode::LowLevel: + m = Z3_PRINT_LOW_LEVEL; + break; + case PrintMode::Smtlib2Compliant: + m = Z3_PRINT_SMTLIB2_COMPLIANT; + break; + case PrintMode::SmtlibCompliant: + m = Z3_PRINT_SMTLIB_COMPLIANT; + break; + default: + UNREACHABLE(); + break; + } + Z3_set_ast_print_mode(ctx(), m); +} + +void RawContext::Display(System::IO::TextWriter^ w) { + w->Write(ToString()); +} + +String^ RawContext::BenchmarkToSmtlib( + String^ name, + String^ logic, + String^ status, + String^ attributes, + array^ assumptions, + TermPtr formula) { + scoped_Z3_ast_array _assumptions(assumptions); + return gcnew String(Z3_benchmark_to_smtlib_string( + ctx(), + (name )?CreateString(name).c_str():0, + (logic )?CreateString(logic).c_str():0, + (status )?CreateString(status).c_str():0, + (attributes )?CreateString(attributes).c_str():0, + _assumptions.size(), + _assumptions.c_ptr(), + get_ast(formula))); +} + + +void RawContext::ParseSmtlibString( + String^ string, + [In] array^ sorts, + [In] array^ old_decls, + [Out] array^% assumptions, + [Out] array^% formulas, + [Out] array^% new_decls, + [Out] array^% new_sorts, + [Out] String^% parser_out + ) +{ + scoped_Z3_ast_array _types(sorts); + scoped_Z3_ast_array _decls(old_decls); + scoped_Z3_symbol_array _sort_names(_types.size()); + scoped_Z3_symbol_array _decl_names(_decls.size()); + for (unsigned i = 0; i < _sort_names.size(); ++i) { + _sort_names[i] = Z3_get_sort_name(ctx(), _types[i]); + } + for (unsigned i = 0; i < _decl_names.size(); ++i) { + _decl_names[i] = Z3_get_decl_name(ctx(), _decls[i]); + } + + try { + Z3_parse_smtlib_string( + ctx(), + CreateString(string).c_str(), + _types.size(), + _sort_names.c_ptr(), + _types.c_ptr(), + _decls.size(), + _decl_names.c_ptr(), + _decls.c_ptr() + ); + } + catch(...) { + parser_out = gcnew String(Z3_get_smtlib_error(ctx())); + throw; + } + parser_out = gcnew String(Z3_get_smtlib_error(ctx())); + + unsigned count = Z3_get_smtlib_num_formulas(ctx()); + formulas = gcnew array(count); + for (unsigned i = 0; i < count; ++i) { + formulas[i] = TermPtr(Z3_get_smtlib_formula(ctx(), i)); + } + + count = Z3_get_smtlib_num_assumptions(ctx()); + assumptions = gcnew array(count); + for (unsigned i = 0; i < count; ++i) { + assumptions[i] = TermPtr(Z3_get_smtlib_assumption(ctx(), i)); + } + + count = Z3_get_smtlib_num_decls(ctx()); + new_decls = gcnew array(count); + for (unsigned i = 0; i < count; ++i) { + new_decls[i] = FuncDeclPtr(Z3_get_smtlib_decl(ctx(), i)); + } + count = Z3_get_smtlib_num_sorts(ctx()); + new_sorts = gcnew array(count); + for (unsigned i = 0; i < count; ++i) { + new_sorts[i] = SortPtr(Z3_get_smtlib_sort(ctx(), i)); + } +} + +void RawContext::ParseSmtlibFile( + String^ file, + [In] array^ sorts, + [In] array^ old_decls, + [Out] array^% assumptions, + [Out] array^% formulas, + [Out] array^% new_decls, + [Out] array^% new_sorts, + [Out] String^% parser_out + ) +{ + scoped_Z3_ast_array _sorts(sorts); + scoped_Z3_ast_array _decls(old_decls); + scoped_Z3_symbol_array _sort_names(_sorts.size()); + scoped_Z3_symbol_array _decl_names(_decls.size()); + for (unsigned i = 0; i < _sort_names.size(); ++i) { + _sort_names[i] = Z3_get_sort_name(ctx(), _sorts[i]); + } + for (unsigned i = 0; i < _decl_names.size(); ++i) { + _decl_names[i] = Z3_get_decl_name(ctx(), _decls[i]); + } + + try { + Z3_parse_smtlib_file( + ctx(), + CreateString(file).c_str(), + _sorts.size(), + _sort_names.c_ptr(), + _sorts.c_ptr(), + _decls.size(), + _decl_names.c_ptr(), + _decls.c_ptr() + ); + } + catch(...) { + parser_out = gcnew String(Z3_get_smtlib_error(ctx())); + throw; + } + parser_out = gcnew String(Z3_get_smtlib_error(ctx())); + + unsigned count = Z3_get_smtlib_num_formulas(ctx()); + formulas = gcnew array(count); + for (unsigned i = 0; i < count; ++i) { + formulas[i] = TermPtr(Z3_get_smtlib_formula(ctx(), i)); + } + + count = Z3_get_smtlib_num_assumptions(ctx()); + assumptions = gcnew array(count); + for (unsigned i = 0; i < count; ++i) { + assumptions[i] = TermPtr(Z3_get_smtlib_assumption(ctx(), i)); + } + + count = Z3_get_smtlib_num_decls(ctx()); + new_decls = gcnew array(count); + for (unsigned i = 0; i < count; ++i) { + new_decls[i] = FuncDeclPtr(Z3_get_smtlib_decl(ctx(), i)); + } + count = Z3_get_smtlib_num_sorts(ctx()); + new_sorts = gcnew array(count); + for (unsigned i = 0; i < count; ++i) { + new_sorts[i] = SortPtr(Z3_get_smtlib_sort(ctx(), i)); + } +} + + + + + +TermPtr RawContext::ParseZ3String(String^ s) { + return TermPtr(Z3_parse_z3_string(ctx(), CreateString(s).c_str())); +} + +TermPtr RawContext::ParseZ3File(String^ file) { + return TermPtr(Z3_parse_z3_file(ctx(), CreateString(file).c_str())); +} + + +#define PROCESS_SMTLIB2(_fn) \ + scoped_Z3_ast_array _sorts(sorts); \ + scoped_Z3_ast_array _decls(decls); \ + scoped_Z3_symbol_array _sort_names(_sorts.size()); \ + scoped_Z3_symbol_array _decl_names(_decls.size()); \ + for (unsigned i = 0; i < _sort_names.size(); ++i) { \ + _sort_names[i] = Z3_get_sort_name(ctx(), _sorts[i]); \ + std::cout << Z3_get_symbol_string(ctx(), _sort_names[i]) << "\n"; \ + } \ + for (unsigned i = 0; i < _decl_names.size(); ++i) { \ + _decl_names[i] = Z3_get_decl_name(ctx(), _decls[i]); \ + std::cout << Z3_get_symbol_string(ctx(), _decl_names[i]) << "\n"; \ + } \ + return TermPtr(_fn(ctx(), CreateString(s).c_str(), \ + _sorts.size(), _sort_names.c_ptr(), _sorts.c_ptr(), \ + _decls.size(), _decl_names.c_ptr(), _decls.c_ptr())); \ + + +TermPtr RawContext::ParseSmtlib2String(String^ s, array^ sorts, array^ decls) { + PROCESS_SMTLIB2(Z3_parse_smtlib2_string); +} + +TermPtr RawContext::ParseSmtlib2File(String^ s, array^ sorts, array^ decls) { + PROCESS_SMTLIB2(Z3_parse_smtlib2_file); +} + +TermPtr RawContext::ExecSmtlib2String(String^ s, array^ sorts, array^ decls) { + PROCESS_SMTLIB2(Z3_exec_smtlib2_string); +} + +TermPtr RawContext::ExecSmtlib2File(String^ s, array^ sorts, array^ decls) { + PROCESS_SMTLIB2(Z3_exec_smtlib2_file); +} + +void RawContext::SetErrorHandler(IErrorHandler^ h) { + m_error_handler = h; +} + + +String^ RawContext::GetErrorMessage(ErrorCode h) { + Z3_error_code code; + switch(h) { + case ErrorCode::Ok: code = Z3_OK; break; + case ErrorCode::TypeError: code = Z3_SORT_ERROR; break; + case ErrorCode::IndexOutOfBounds: code = Z3_IOB; break; + case ErrorCode::InvalidArgument: code = Z3_INVALID_ARG; break; + case ErrorCode::ParserError: code = Z3_PARSER_ERROR; break; + case ErrorCode::NoParser: code = Z3_NO_PARSER; break; + case ErrorCode::InvalidUsage: code = Z3_INVALID_USAGE; break; + case ErrorCode::InternalFatal: + case ErrorCode::FileAccessError: + code = Z3_INVALID_ARG; + break; + default: + UNREACHABLE(); + code = Z3_INVALID_ARG; + } + return gcnew String(Z3_get_error_msg(code)); +} + +void RawContext::ResetMemory() { + Z3_reset_memory(); +} + +String^ RawContext::ToString(AstPtr a) { + return gcnew String(Z3_ast_to_string(ctx(), get_ast(a))); +} + +void RawContext::Display(System::IO::TextWriter^ w, AstPtr a) { + w->Write(ToString(a)); +} + + +void RawContext::GetVersion(unsigned% major, unsigned% minor, unsigned% build_number, unsigned% version_number) { + unsigned ma, mi, bn, vn; + Z3_get_version(&ma,&mi,&bn,&vn); + major = ma; + minor = mi; + build_number = bn; + version_number = vn; +} + +// ----------------------------- +// Ast + +Ast::Ast(RawContext^ c, AstPtr a) : m_ast(a), m_ctx(c) { + SASSERT(m_ast != IntPtr(0)); + if (c->ref_context().is_ref_counted()) { + c->IncRef(a); + c->ref_context().inc_ref(); + } +} + +Ast::!Ast() { + if (m_ctx->ref_context().is_ref_counted()) { + m_ctx->EnqueueDecRef(m_ast); + } +} + +Ast::~Ast() {} + +bool Ast::Equals(Object^ obj) { + if (!obj) { + return false; + } + Ast^ a = dynamic_cast(obj); + if (!a) { + return false; + } + return a->GetPtr() == GetPtr(); +} + +int Ast::GetHashCode() { + return GetId(); +} + +String^ Ast::ToString() { + return m_ctx->ToString(m_ast); +} + +int Ast::CompareTo(Object^ other) { + Ast^ a = dynamic_cast(other); + if (!a) { + return -1; + } + return GetId() - a->GetId(); +} + +#if 0 +bool Ast::operator==(Object^ other) { + return this->Equals(other); +} + +bool Ast::operator!=(Object^ other) { + return !this->Equals(other); +} +#endif + +String^ Sort::GetName() { + return m_ctx->GetSymbolString(m_ctx->GetSortName(m_ast)); +} + +String^ FuncDecl::GetDeclName() { + return m_ctx->GetSymbolString(m_ctx->GetDeclName(m_ast)); +} + +DeclKind FuncDecl::GetKind() { + return m_ctx->GetDeclKind(m_ast); +} + +// ---------------------------- +// Term +// Assumption: contexts are equal +// Note: overloading && and || is possible, +// but C# does not seem to perform the +// correct type inference when they are used. + +Term^ Term::operator!(Term^ t) { + return gcnew Term(t->m_ctx, t->m_ctx->MkNot(t())); +} + +Term^ Term::operator+(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkAdd(t1(), t2())); +} + +Term^ Term::operator^(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkXor(t1(), t2())); +} + +Term^ Term::operator&(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkAnd(t1(), t2())); +} + +Term^ Term::operator|(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkOr(t1(), t2())); +} +Term^ Term::operator*(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkMul(t1(), t2())); +} + +Term^ Term::operator-(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkSub(t1(), t2())); +} + +Term^ Term::operator/(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkDiv(t1(), t2())); +} + +Term^ Term::operator<(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkLt(t1(), t2())); +} + +Term^ Term::operator<=(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkLe(t1(), t2())); +} + +Term^ Term::operator>(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkGt(t1(), t2())); +} + +Term^ Term::operator>=(Term^ t1, Term^ t2) { + return gcnew Term(t1->m_ctx, t1->m_ctx->MkGe(t1(), t2())); +} + +Term^ Term::operator[](Term^ index) { + return gcnew Term(m_ctx, m_ctx->MkArraySelect(m_ast, index())); +} + +TermKind Term::GetKind() { + return m_ctx->GetTermKind(m_ast); +} + +FuncDecl^ Term::GetAppDecl() { + return gcnew FuncDecl(m_ctx, m_ctx->GetAppDecl(m_ast)); +} + +array^ Term::GetAppArgs() { + return Context::CopyTermArray(m_ctx, m_ctx->GetAppArgs(m_ast)); +} + +Sort^ Term::GetSort() { + return gcnew Sort(m_ctx, m_ctx->GetSort(m_ast)); +} + +String^ Term::GetNumeralString() { + return m_ctx->GetNumeralString(m_ast); +} + +unsigned Term::GetVarIndex() { + return m_ctx->GetVarIndex(m_ast); +} + +Quantifier^ Term::GetQuantifier() { + return Context::GetQuantifier(m_ctx, this); +} +// ----------------------------- +// Context + + +LBool Context::CheckAndGetModel(Model^% m) { + RawModel^ md = nullptr; + LBool is_sat = m_ctx->CheckAndGetModel(md); + if (md ) { + m = gcnew Model(md, this); + } + else { + md = nullptr; + } + return is_sat; +} + +LBool Context::CheckAssumptions( + Model^% m, array^ assumptions, Term^% proof, array^% core) { + RawModel^ md = nullptr; + array^ _core = nullptr; + TermPtr _proof; + LBool is_sat = m_ctx->CheckAssumptions(md, CopyArray(assumptions), _proof, _core); + core = nullptr; + proof = nullptr; + m = nullptr; + if (md ) { + m = gcnew Model(md, this); + } + if (_proof != TermPtr()) { + proof = gcnew Term(m_ctx, _proof); + } + if (_core ) { + core = CopyTermArray(_core); + } + return is_sat; +} + +void Context::SoftCheckCancel() { + m_ctx->SoftCheckCancel(); +} + + +LBool Context::GetImpliedEqualities( + [In] array^ terms, + [Out] array^% class_ids) { + return m_ctx->GetImpliedEqualities(CopyArray(terms), class_ids); +} + + + +Quantifier^ Context::GetQuantifier(RawContext^ ctx, Term^ t) { + RawQuantifier^ q0 = ctx->GetQuantifier(t()); + Quantifier^ q = gcnew Quantifier(); + q->IsForall = q0->IsForall; + q->Weight = q0->Weight; + q->Patterns = gcnew array(q0->Patterns->Length); + for (int i = 0; i < q0->Patterns->Length; ++i) { + q->Patterns[i] = gcnew Pattern(ctx, q0->Patterns[i]); + } + q->NoPatterns = gcnew array(q0->NoPatterns->Length); + for (int i = 0; i < q0->NoPatterns->Length; ++i) { + q->NoPatterns[i] = gcnew Term(ctx, q0->Patterns[i]); + } + q->Names = q0->Names; + q->Body = gcnew Term(ctx, q0->Body); + q->Sorts = CopySortArray(ctx, q0->Sorts); + return q; +} + + +Sort^ Context::MkTupleSort( + Symbol^ mk_tuple_name, + array^ field_names, + array^ field_types, + FuncDecl^% mk_tuple_decl, + array^ proj_decl + ) { + array^ ftypes = gcnew array(field_types->Length); + for (int i = 0; i < field_types->Length; ++i) { + ftypes[i] = field_types[i](); + } + array^ pdecls = gcnew array(proj_decl->Length); + FuncDeclPtr mk_tupled; + SortPtr res = m_ctx->MkTupleSort(mk_tuple_name, field_names, ftypes, mk_tupled, pdecls); + for (int i = 0; i < pdecls->Length; ++i) { + proj_decl[i] = gcnew FuncDecl(m_ctx,pdecls[i]); + } + mk_tuple_decl = gcnew FuncDecl(m_ctx,mk_tupled); + return gcnew Sort(m_ctx,res); +} + +Sort^ Context::MkTupleSort( + String^ mk_tuple_name, + array^ field_names, + array^ field_types, + FuncDecl^% mk_tuple_decl, + array^ proj_decl + ) { + array^ ftypes = gcnew array(field_types->Length); + for (int i = 0; i < field_types->Length; ++i) { + ftypes[i] = field_types[i](); + } + array^ pdecls = gcnew array(proj_decl->Length); + FuncDeclPtr mk_tupled; + SortPtr res = m_ctx->MkTupleSort(mk_tuple_name, field_names, ftypes, mk_tupled, pdecls); + for (int i = 0; i < pdecls->Length; ++i) { + proj_decl[i] = gcnew FuncDecl(m_ctx,pdecls[i]); + } + mk_tuple_decl = gcnew FuncDecl(m_ctx,mk_tupled); + return gcnew Sort(m_ctx,res); +} + +Sort^ Context::MkEnumerationSort( + String^ name, + array^ enum_names, + array^ enum_consts, + array^ enum_testers) { + + array^ _enum_consts = CopyArray(enum_consts); + array^ _enum_testers = CopyArray(enum_testers); + + SortPtr s = m_ctx->MkEnumerationSort(name, enum_names, _enum_consts, _enum_testers); + + for (int i = 0; i < enum_consts->Length; ++i) { + enum_consts[i] = gcnew FuncDecl(m_ctx, _enum_consts[i]); + enum_testers[i] = gcnew FuncDecl(m_ctx, _enum_testers[i]); + } + return gcnew Sort(m_ctx, s); +} + +Sort^ Context::MkListSort( + String^ name, + Sort^ elem_sort, + FuncDecl^% nil_decl, + FuncDecl^% is_nil_decl, + FuncDecl^% cons_decl, + FuncDecl^% is_cons_decl, + FuncDecl^% head_decl, + FuncDecl^% tail_decl + ) { + FuncDeclPtr a, b, c, d, e, f; + SortPtr s = m_ctx->MkListSort(name, elem_sort(), a, b, c, d, e, f); + nil_decl = gcnew FuncDecl(m_ctx, a); + is_nil_decl = gcnew FuncDecl(m_ctx, b); + cons_decl = gcnew FuncDecl(m_ctx, c); + is_cons_decl = gcnew FuncDecl(m_ctx, d); + head_decl = gcnew FuncDecl(m_ctx, e); + tail_decl = gcnew FuncDecl(m_ctx, f); + return gcnew Sort(m_ctx, s); +} + +Constructor^ Context::MkConstructor( + String^ name, + String^ tester, + array^ field_names, + array^ field_sorts, + array^ field_refs + ) { + return m_ctx->MkConstructor(name, tester, field_names, CopyArray(field_sorts), field_refs); +} + + +FuncDecl^ Context::GetConstructor(Constructor^ c) { + return gcnew FuncDecl(m_ctx, m_ctx->GetConstructor(c)); +} + +FuncDecl^ Context::GetTester(Constructor^ c) { + return gcnew FuncDecl(m_ctx, m_ctx->GetTester(c)); +} + +array^ Context::GetAccessors(Constructor^ c) { + array^ result = m_ctx->GetAccessors(c); + return CopyAstArray(result); +} + + +bool Model::TryGetArrayValue(Term^ v, ArrayValue^% av) { + RawArrayValue^ _av = nullptr; + if (m_model->TryGetArrayValue(v(), _av)) { + av = gcnew ArrayValue(); + av->ElseCase = gcnew Term(m_ctx->GetContext, _av->ElseCase); + av->Domain = m_ctx->CopyAstArray(_av->Domain); + av->Range = m_ctx->CopyAstArray(_av->Range); + return true; + } + else { + return false; + } +} + +array^ Context::GetDeclParameters(FuncDecl^ d) { + Z3_context ctx = m_ctx->ctx(); + Z3_func_decl fd = get_func_decl(d()); + unsigned num_params = Z3_get_decl_num_parameters(ctx, fd); + array^ params = gcnew array(num_params); + for (unsigned i = 0; i < num_params; ++i) { + switch(Z3_get_decl_parameter_kind(ctx, fd, i)) { + case Z3_PARAMETER_INT: + params[i] = gcnew IntParameter(Z3_get_decl_int_parameter(ctx, fd, i)); + break; + case Z3_PARAMETER_DOUBLE: + params[i] = gcnew DoubleParameter(Z3_get_decl_double_parameter(ctx, fd, i)); + break; + case Z3_PARAMETER_RATIONAL: { + Z3_string s = Z3_get_decl_rational_parameter(ctx, fd, i); + params[i] = gcnew RationalParameter(gcnew String(s)); + break; + } + case Z3_PARAMETER_SYMBOL: { + Z3_symbol s = Z3_get_decl_symbol_parameter(ctx, fd, i); + params[i] = gcnew SymbolParameter(gcnew Symbol(ctx, s)); + break; + } + case Z3_PARAMETER_SORT: + params[i] = gcnew SortParameter(gcnew Sort(m_ctx,SortPtr(Z3_get_decl_sort_parameter(ctx, fd, i)))); + break; + case Z3_PARAMETER_AST: + params[i] = gcnew TermParameter(gcnew Term(m_ctx,TermPtr(Z3_get_decl_ast_parameter(ctx, fd, i)))); + break; + case Z3_PARAMETER_FUNC_DECL: + params[i] = gcnew FuncDeclParameter(gcnew FuncDecl(m_ctx, FuncDeclPtr(Z3_get_decl_func_decl_parameter(ctx, fd, i)))); + break; + default: + UNREACHABLE(); + break; + } + } + return params; +} + +String^ Context::BenchmarkToSmtlib( + String^ name, + String^ logic, + String^ status, + String^ attributes, + array^ assumptions, + Term^ formula) { + return m_ctx->BenchmarkToSmtlib(name, logic, status, attributes, CopyArray(assumptions), formula()); + } + +void Context::ParseSmtlibString( + String^ string, + [In] array^ types, + [In] array^ old_decls, + [Out] array^% assumptions, + [Out] array^% formulas, + [Out] array^% new_decls, + [Out] array^% new_sorts, + [Out] String^% parser_out + ) { + array^ _assumptions = nullptr; + array^ _formulas = nullptr; + array^ _new_decls = nullptr; + array^ _new_sorts = nullptr; + m_ctx->ParseSmtlibString(string, CopyArray(types), CopyArray(old_decls), + _assumptions, _formulas, _new_decls, _new_sorts, parser_out); + assumptions = CopyTermArray(_assumptions); + formulas = CopyTermArray(_formulas); + new_decls = CopyAstArray(_new_decls); + new_sorts = CopyAstArray(_new_sorts); +} + + +void Context::ParseSmtlibFile( + String^ file, + [In] array^ types, + [In] array^ old_decls, + [Out] array^% assumptions, + [Out] array^% formulas, + [Out] array^% new_decls, + [Out] array^% new_sorts, + [Out] String^% parser_out + ) { + array^ _assumptions = nullptr; + array^ _formulas = nullptr; + array^ _new_decls = nullptr; + array^ _new_sorts = nullptr; + m_ctx->ParseSmtlibFile(file, CopyArray(types), CopyArray(old_decls), + _assumptions, _formulas, _new_decls, _new_sorts, parser_out); + assumptions = CopyAstArray(_assumptions); + formulas = CopyAstArray(_formulas); + new_decls = CopyAstArray(_new_decls); + new_sorts = CopyAstArray(_new_sorts); +} + +// ----------------------------- +// Model + +ArrayValue^ Model::Mk(RawArrayValue^ av) { + ArrayValue^ res = gcnew ArrayValue(); + res->Domain = m_ctx->CopyTermArray(av->Domain); + res->Range = m_ctx->CopyTermArray(av->Range); + res->ElseCase = gcnew Term(m_ctx->GetContext, av->ElseCase); + return res; +} + +FunctionEntry^ Model::Mk(RawFunctionEntry^ fe) { + FunctionEntry^ res = gcnew FunctionEntry(); + res->Arguments = m_ctx->CopyTermArray(fe->Arguments); + res->Result = gcnew Term(m_ctx->GetContext, fe->Result); + return res; +} + +FunctionGraph^ Model::Mk(RawFunctionGraph^ fg) { + FunctionGraph^ res = gcnew FunctionGraph(); + res->Declaration = gcnew FuncDecl(m_ctx->GetContext, fg->Declaration); + res->Entries = gcnew array(fg->Entries->Length); + for (int i = 0; i < fg->Entries->Length; ++i) { + res->Entries[i] = Mk(fg->Entries[i]); + } + res->Else = gcnew Term(m_ctx->GetContext, fg->Else); + return res; +} + +Dictionary^ Model::Mk(Dictionary^ fgs) { + Dictionary^ res = + gcnew Dictionary(); + + Dictionary::Enumerator e = fgs->GetEnumerator(); + while(e.MoveNext()) { + KeyValuePair^ kv = e.Current; + res->Add(gcnew FuncDecl(m_ctx->GetContext, kv->Key), Mk(kv->Value)); + } + return res; +} + +Theory^ Context::MkTheory(String^ name) { + return gcnew Theory(this, name); +} diff --git a/Microsoft.Z3V3/Microsoft.Z3V3.h b/Microsoft.Z3V3/Microsoft.Z3V3.h new file mode 100644 index 000000000..d457a63f2 --- /dev/null +++ b/Microsoft.Z3V3/Microsoft.Z3V3.h @@ -0,0 +1,4775 @@ +/*++ +Copyright (c) 2007 Microsoft Corporation + +Module Name: + + Microsoft.Z3V3.h + +Abstract: + + Z3 Managed API. + +Author: + + Nikolaj Bjorner (nbjorner) + Leonardo de Moura (leonardo) 2007-06-8 + +Notes: + + This API is deprecated and support for this is discontinued. + It is superseeded by the new Microsoft.Z3 API. + +--*/ + +#ifndef _MICROSOFT_Z3V3_H__ +#define _MICROSOFT_Z3V3_H__ + +struct _Z3_model {}; +struct _Z3_config {}; +struct _Z3_context {}; +struct _Z3_func_decl {}; +struct _Z3_app {}; +struct _Z3_sort {}; +struct _Z3_symbol {}; +struct _Z3_ast {}; +struct _Z3_literals {}; +struct _Z3_pattern {}; +struct _Z3_constructor {}; +struct _Z3_constructor_list {}; +typedef _Z3_literals *Z3_literals; +struct _Z3_theory {}; +struct _Z3_ast_vector {}; +struct _Z3_fixedpoint {}; + +using namespace System; +using namespace System::Collections::Generic; +using namespace System::Runtime::InteropServices; +using namespace System::Numerics; + + +#include "..\lib\z3.h" + +namespace Microsoft { +namespace Z3V3 { + + class ref_context { + unsigned m_count; + bool m_owned; + bool m_scoped; + Z3_context m_ctx; + Z3_fixedpoint m_dl; + ref_context(Z3_context ctx, bool owned, bool scoped): m_count(1), m_owned(owned), m_scoped(scoped), m_ctx(ctx), m_dl(0) {} + public: + static ref_context* mk(Z3_context ctx, bool owned, bool scoped); + void dec_ref(); + void inc_ref(); + Z3_context operator()() { return m_ctx; } + ~ref_context() {} + bool is_ref_counted() const { return !is_scoped(); } + bool is_scoped() const { return m_scoped; } + Z3_fixedpoint dl(); + }; + +/** + \defgroup mapi Managed (.NET) API +*/ +/*@{*/ + + public ref class Z3Log { + static bool m_open = false; + public: + /** + \brief Log assertions to a file. + + \sa Close + + Returns \c true if the open succeeds, otherwise \c false. + */ + static bool Open(String^ filename); + + /** + \brief Return true if the log is open. + */ + static bool IsOpen() { return m_open; } + + /** + \brief Append user comment to log. + + \sa Open + */ + static void Append(String^ string); + + /** + \brief Close file with logged API calls. + + \sa Open + */ + static void Close(); + }; + + /** + \brief Symbol. + + Wrapper class for string or integer symbols. + This class remains unsafe. You cannot access the ToString() + method after the owning context has been deleted. + We don't use dispose pattern here. I believe it would be too + awkward to manage. + */ + public ref class Symbol { + Z3_context m_ctx; + Z3_symbol m_symbol; + internal: + Symbol(Z3_context c, Z3_symbol s) : m_ctx(c), m_symbol(s) { } + Z3_symbol get() { return m_symbol; } + public: + virtual String^ ToString() override; + }; + + /** + \brief Lifted Booleans. + + The result of m_context->Check() is a lifted Boolean. When Z3 is unable to + decide whether the result is satisfiable or unsatisfiable it returns + Undef. + */ + + public enum class LBool + { + True, + False, + Undef + }; + + /** + \brief Z3 error codes. + + - Ok, + - TypeError: User tried to build an invalid (type incorrect) AST. + - IndexOutOfBounds: Index out of bounds + - InvalidArgument:: Invalid argument was provided + - ParserError: An error occurred when parsing a string or file. + - NoParser: Parser output is not available, that is, user didn't invoke ParseSmtlibString or ParseSmtlibFile. + - InvalidPattern: An invalid pattern was used to build a quantifier. + - InternalFatal: An internal fatal error was encountered. + - InvalidUsage: The API was used in an invalid context. + - FileAccessError: File access failed for an inaccessible file. + - NonDisposedConfig A configuration was not disposed explictly. + - NonDisposedContext: A context was not disposed explictly. + - NonDisposedLiterals: A conflict literal set was not disposed explicitly. + - NonDisposedModel: A model was not disposed of explicitly. + + There is no error code for out of memory errors. + Z3 will throw the library exception OutOfMemoryException + if memory allocation fails. Users should call ResetMemory() + to reclaim all allocated resources. + + */ + + public enum class ErrorCode + { + Ok, + TypeError, + IndexOutOfBounds, + InvalidArgument, + ParserError, + NoParser, + InvalidPattern, + InternalFatal, + InvalidUsage, + FileAccessError, + NonDisposedConfig, + NonDisposedContext, + NonDisposedLiterals, + NonDisposedModel + }; + + /** + \brief Z3 pretty printing modes used when pretty printing terms. + + - SmtlibFull: Print AST nodes in SMTLIB verbose format. + - LowLevel: Print AST nodes using a low-level format. + - SmtlibCompliant Print AST in SMTLIB 1.x compliant format. + - Smtlib2Compliant Print AST in SMTLIB 1.x compliant format. + */ + public enum class PrintMode + { + SmtlibFull, + LowLevel, + SmtlibCompliant, + Smtlib2Compliant + }; + + /** + \brief Z3 error exceptions contain an \c ErrorCode. + + A \c Z3Error exception gets raised on errors caused by + malformed calls into the #Context. + */ + public ref class Z3Error : Exception { + public: + Z3Error(ErrorCode c) { Code = c; InternalCode = 0; } + Z3Error(int i) { Code = ErrorCode::Ok; InternalCode = i; } + ErrorCode Code; + int InternalCode; + }; + + + /// @cond 0 + typedef IntPtr AstPtr; + typedef IntPtr SortPtr; + typedef IntPtr FuncDeclPtr; + typedef IntPtr TermPtr; + typedef IntPtr PatternPtr; + typedef IntPtr AppPtr; + + + Z3_func_decl get_func_decl(FuncDeclPtr t) { + if (t == IntPtr::Zero) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + return static_cast(t.ToPointer()); + } + Z3_ast get_ast(TermPtr t) { + if (t == IntPtr::Zero) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + return static_cast(t.ToPointer()); + } + Z3_sort get_sort(SortPtr t) { + if (t == IntPtr::Zero) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + return static_cast(t.ToPointer()); + } + Z3_app get_const_ast(AppPtr c) { + if (c == IntPtr::Zero) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + return static_cast(c.ToPointer()); + } + Z3_pattern get_pattern(PatternPtr p) { + if (p == IntPtr::Zero) { + throw gcnew Z3Error(ErrorCode::InvalidArgument); + } + return static_cast(p.ToPointer()); + } + + /// @endcond + + + + /** + \brief In Z3, a symbol can be represented using integers and strings (See #GetSymbolKind). + + \sa MkIntSymbol + \sa MkStringSymbol + */ + public enum class SymbolKind + { + Int, + String + }; + + /** + \brief The different kinds of Z3 sorts (See #GetSortKind). + */ + public enum class SortKind + { + Uninterpreted, + Bool, + Int, + Real, + BitVector, + Array, + Datatype, + Unknown + }; + + /** + \brief Different failure kinds. + + - NoFailure + - Unknown: + - TimeOut: + - MemOut: + - UserCanceled: + - MaxConflicts: + - Theory: + - Quantifiers: + + */ + public enum class SearchFailureExplanation + { + NoFailure, + Unknown, + TimeOut, + MemOut, + UserCanceled, + MaxConflicts, + Theory, + Quantifiers + }; + + /** + \brief The different kinds of Z3 Terms. + + - Numeral: numerals + - App: constant and applications + - Var: bound variables + - Quantifier: quantifiers + - Unknown: internal + */ + public enum class TermKind + { + Numeral, + App, + Var, + Quantifier, + Unknown + }; + + + /** \brief Different kinds of Z3 built-in declarations (See #GetDeclKind) + + */ + public enum class DeclKind + { + // Basic operators + True, + False, + Eq, + Distinct, + Ite, + And, + Or, + Iff, + Xor, + Not, + Implies, + // Arithmetic + ArithNum, + Le, + Ge, + Lt, + Gt, + Add, + Sub, + Uminus, + Mul, + Div, + IDiv, + Rem, + Mod, + ToReal, + ToInt, + IsInt, + // Arrays + Store, + Select, + ConstArray, + DefaultArray, + MapArray, + Union, + Intersect, + Difference, + Complement, + Subset, + AsArray, + // Bit-vectors. + + BitNum, + Bit1, + Bit0, + BNeg, + BAdd, + BSub, + BMul, + BSDiv, + BUDiv, + BSRem, + BURem, + BSMod, + + BSDiv0, + BUDiv0, + BSRem0, + BURem0, + BSMod0, + BULeq, + BSLeq, + BUGeq, + BSGeq, + BULt, + BSLt, + BUGt, + BSGt, + BAnd, + BOr, + BNot, + BXor, + BNand, + BNor, + BXnor, + BConcat, + BSignExt, + BZeroExt, + BExtract, + BRepeat, + BRedOr, + BRedAnd, + BComp, + + BShl, + BLShr, + BAShr, + BRotateLeft, + BRotateRight, + BExtRotateLeft, + BExtRotateRight, + BInt2Bv, + BBv2Int, + BCarry, + BXor3, + + PrAsserted, + PrGoal, + PrModusPonens, + PrReflexivity, + PrTransitivity, + PrTransitivityStar, + PrSymmetry, + PrMonotonicity, + PrQuantIntro, + PrDistributivity, + PrAndElim, + PrNotOrElim, + PrRewrite, + PrRewriteStar, + PrPullQuant, + PrPullQuantStar, + PrPushQuant, + PrElimUnusedVars, + PrDer, + PrQuantInst, + PrHypothesis, + PrLemma, + PrUnitResolution, + PrIffTrue, + PrIffFalse, + PrCommutativity, + PrDefAxiom, + PrDefIntro, + PrApplyDef, + PrIffOeq, + PrNnfPos, + PrNnfNeg, + PrNnfStar, + PrSkolemize, + PrCnfStar, + PrModusPonensOeq, + PrThLemma, + + RaStore, + RaEmpty, + RaIsEmpty, + RaJoin, + RaUnion, + RaWiden, + RaProject, + RaFilter, + RaNegationFilter, + RaRename, + RaComplement, + RaSelect, + RaClone, + + Label, + LabelLit, + Uninterpreted + }; + + + /** + \brief IErrorHandler is an abstract (interface) class for passing + an error handler. + + The \c Handler method takes as argument an \c ErrorCode and processes + it. + */ + public interface class IErrorHandler + { + public: + virtual void Handler(ErrorCode code) = 0; + }; + + /// @cond 0 + LBool ToLBool(Z3_lbool b) { + switch(b) { + case Z3_L_FALSE: return LBool::False; + case Z3_L_TRUE: return LBool::True; + default: return LBool::Undef; + } + } + /// @endcond + + /** + \brief Container for labeled literals. + + A satisfiable state can be queried for a set of labeled literals that are satisfied. + + */ + + public ref class LabeledLiterals { + ref_context& m_context; + Z3_literals m_labels; + internal: + LabeledLiterals(ref_context& ctx, Z3_literals lbls): m_context(ctx), m_labels(lbls) { ctx.inc_ref(); } + Z3_literals Get() { return m_labels; } + TermPtr GetLiteral(unsigned idx) { return TermPtr(Z3_get_literal(m_context(), m_labels, idx)); } + protected: + !LabeledLiterals(); + public: + ~LabeledLiterals() { if (m_labels) { Z3_del_literals(m_context(), m_labels); } m_labels = 0; m_context.dec_ref(); } + unsigned GetNumLabels() { return Z3_get_num_literals(m_context(), m_labels); } + void Disable(unsigned idx) { Z3_disable_literal(m_context(), m_labels, idx); } + Symbol^ GetLabel(unsigned idx) { return gcnew Symbol(m_context(), Z3_get_label_symbol(m_context(), m_labels, idx)); } + }; + + + /** + \brief Container for constructor declarations. + + */ + + public ref class Constructor { + ref_context& m_context; + Z3_constructor m_constructor; + FuncDeclPtr m_constructor_decl; + FuncDeclPtr m_tester; + array^ m_accessors; + + !Constructor(); + + internal: + String^ m_name; + String^ m_tester_name; + array^ m_field_names; + array^ m_field_sorts; + array^ m_field_refs; + + Constructor( + ref_context& context, + String^ name, + String^ tester, + array^ field_names, + array^ field_sorts, + array^ field_refs + ); + + Z3_constructor Query(); + Z3_constructor Get(); + FuncDeclPtr GetConstructor(); + FuncDeclPtr GetTester(); + array^ GetAccessors(); + public: + ~Constructor(); + }; + + + + /** + \brief Configuration + + Configuration can be set prior to creating an instance + of the Z3 Context. + + To set a parameter create an instance of the Params class + and call the SetParamValue() method. + + The set of legal parameters can be found by executing z3.exe /ini? + */ + public ref class Config + { + /// @cond 0 + Z3_config m_config; + /// @endcond + internal: + /// @cond 0 + Z3_config get() { return m_config; } + /// @endcond + + protected: + !Config(); + + public: + /** + \brief Create configuration context. + + Create a configuration context to supply configurations to the + Z3 #Context. Callers must explicitly close the configuration + in order to collect the resources allocated in the configuration. + */ + Config(); + + /// \brief Configuration destructor. + ~Config(); + + /** + \brief Set parameter to specified value. + + The list of all configuration parameters can be obtained using the Z3 executable: + + \verbatim + z3.exe /ini? + \endverbatim + */ + void SetParamValue(String^ name, String^ value); + }; + + + /** + \brief Z3 Parameter values. + */ + public interface class IRawParameter { }; + public interface class IParameter { }; + + public ref class IntParameter : public IRawParameter, public IParameter { + int m_value; + internal: + IntParameter(int i) : m_value(i) {} + public: + property int Int { int get() { return m_value; } } + virtual String^ ToString() override { return m_value.ToString(); } + }; + + public ref class DoubleParameter : public IRawParameter, public IParameter { + double m_value; + internal: + DoubleParameter(double i) : m_value(i) {} + public: + property double Double { double get() { return m_value; } } + virtual String^ ToString() override { return m_value.ToString(); } + }; + + public ref class RationalParameter : public IRawParameter, public IParameter { + String^ m_value; + internal: + RationalParameter(String^ s): m_value(s) {} + public: + property String^ GetRational { String^ get() { return m_value; } } + virtual String^ ToString() override { return m_value; } + }; + + public ref class SymbolParameter : public IRawParameter, public IParameter { + Symbol^ m_value; + internal: + SymbolParameter(Symbol^ s): m_value(s) {} + public: + property Symbol^ GetSymbol { Symbol^ get() { return m_value; } } + }; + + public ref class TermPtrParameter : public IRawParameter { + TermPtr m_value; + internal: + TermPtrParameter(TermPtr t) : m_value(t) {} + public: + property TermPtr GetTerm { TermPtr get() { return m_value; } } + }; + + public ref class SortPtrParameter : public IRawParameter { + SortPtr m_value; + internal: + SortPtrParameter(SortPtr t) : m_value(t) {} + public: + property SortPtr GetSort { SortPtr get() { return m_value; } } + }; + + public ref class FuncDeclPtrParameter : public IRawParameter { + FuncDeclPtr m_value; + internal: + FuncDeclPtrParameter(FuncDeclPtr t) : m_value(t) {} + public: + property FuncDeclPtr GetFuncDecl { FuncDeclPtr get() { return m_value; } } + }; + + + + + /** + \brief Z3 Array Value object. + */ + public ref class RawArrayValue { + public: + array^ Domain; + array^ Range; + TermPtr ElseCase; + }; + + /** + \brief Z3 Function entry object. + + A FunctionEntry object summarizes what a function maps to + based on a given set of argument values. + */ + public ref class RawFunctionEntry { + public: + array^ Arguments; + TermPtr Result; + }; + + /** + \brief Z3 Function graph object. + + The finite function graph of an uninterpreted function + is represented as a list of #FunctionEntry entries, together + with a default value. The domain values not listed in the + #FunctionEntry array map to the default value \c Else. + + \param Declaration contains the function declaration Ast. + \param Entries contains the array of entries where the function + is defined explicitly. + \param Contains the default value of the function; where the function + maps to a default value. + */ + public ref class RawFunctionGraph { + public: + FuncDeclPtr Declaration; + array^ Entries; + TermPtr Else; + }; + + public ref class RawQuantifier { + public: + bool IsForall; + unsigned Weight; + array^ Patterns; + array^ NoPatterns; + array^ Sorts; + array^ Names; + TermPtr Body; + }; + + ref class RawModel; + + public delegate void Action0(); + + generic + public delegate void Action2( + T obj1, + S obj2 + ); + generic + public delegate void Action3( + T obj1, + S obj2, + U obj3 + ); + + + generic + public delegate T Func0(); + + generic + public delegate S Func1( + T obj + ); + + generic + public delegate U Func2( + T obj1, + S obj2 + ); + + + /** + \brief Z3 RawModel object. + */ + public ref class RawModel { + ref_context& m_context; + Z3_model m_model; + Dictionary^ m_graphs; + internal: + RawModel(ref_context& c, Z3_model m) : m_context(c), m_model(m), m_graphs(nullptr) { c.inc_ref(); } + + void Reset(); + protected: + !RawModel(); + public: + ~RawModel(); + + + /** + \brief Return the constants assigned by the given model. + */ + array^ GetModelConstants(); + + /** + \brief Return the function interpretations in the given model. + + A function interpretation is represented as a finite map and an 'else' value. + Each entry in the finite map represents the value of a function given a set of arguments. + */ + Dictionary^ GetFunctionGraphs(); + + /** + \brief Evaluate the AST node \c t in the given model. + + Return the result as a non-zero value. The + returned value is null if the term does not evaluate to a fixed value + in the current model. + term to a value. + + + The evaluation may fail for the following reasons: + + - \c t contains a quantifier or bound variable. + + - the model \c m is partial, that is, it doesn't have a complete interpretation for free functions. + That is, the option PARTIAL_MODELS=true was used. + + - the evaluator doesn't have support for some interpreted operator. + + - \c t is type incorrect (see #TypeCheck). + + - The result of an intepreted operator in \c t is undefined (e.g. division by zero). + */ + TermPtr Eval(TermPtr); + + TermPtr Eval(FuncDeclPtr, array^ args); + + + /** + \brief Return decomposed sequence of stores as an array value. + */ + bool TryGetArrayValue(TermPtr a,[Out] RawArrayValue^% av); + + /** + \brief Convert the given model into a string. + */ + virtual String^ ToString() override; + + /** + \brief Display model to TextWriter + */ + void Display(System::IO::TextWriter^ w); + }; + + public ref class ReferenceCounted {}; + + public ref class TermProofPtr { + TermPtr m_term; + TermPtr m_proof; // proof is optional, use IntPtr::Zero for absence of proofs. + public: + TermProofPtr(TermPtr term, TermPtr proof): m_term(term), m_proof(proof) {} + property TermPtr GetTerm { TermPtr get() { return m_term; } } + property TermPtr Proof { TermPtr get() { return m_proof; } } + }; + + ref class RawTheory; + /** + \brief Z3 API object. + */ + public ref class RawContext : public MarshalByRefObject + { + ref_context* m_context; + bool m_disposed; + static List >^ s_todec; + static IntPtr^ s_monitor; + static bool s_nonempty; + + void Init(); + internal: + static IErrorHandler^ m_error_handler = nullptr; + + Z3_context ctx() { return (*m_context)(); } + Z3_fixedpoint dl() { return m_context->dl(); } + ref_context& ref_context() { return *m_context; } + + /** + \brief Increment and decrement reference counters on + terms, sorts and declarations. + + These methods are required when the context is created + using the ReferenceCounted argument. + */ + void IncRef(AstPtr ast); + + void EnqueueDecRef(AstPtr ast); + + protected: + + !RawContext(); + public: + /** + \brief Create a logical context using the given configuration. + + After a context is created, the configuration cannot be changed. + All main interaction with Z3 happens in the context of a \c Context. + + All contexts that are created must be disposed (call Dispose). + Failure to dispose contexts cause memory leaks. + Garbage collection will not free resources allocated in contexts. + */ + + RawContext(Config^ config); + + /** + \brief Create a logical context using the given configuration. + + This constructor is similar to the default RawContext constructor. + Reference counts to terms, functions, and sorts that are created + over the API have to be handled explicitly by the caller, however. + + Terms (sorts, declarations) created by the context have initially + reference count 0, and the caller has to explicitly manage the reference counts. + This mode is more flexible, but also very error prone. + + Use the metheods AddRef and DecRef on terms, sorts, declarations to + control the reference counts. + + All contexts that are created must be disposed (call Dispose). + Failure to dispose contexts cause memory leaks. + Garbage collection will not free resources allocated in contexts. + */ + RawContext(Config^ config, ReferenceCounted^ rc); + + RawContext(); + + void SetContext(Z3_context ctx); + + void Reset(); + + ~RawContext(); + + /** + @name Tracing and logging + */ + /*@{*/ + + /** + \brief Enable low-level debug tracing. + + This method only works with debug builds. + */ + void EnableDebugTrace(String^ tag); + + /** + \brief Enable or disable warning messages sent to the console out/error. + + Warnings are printed after passing \c true, warning messages are + suppressed after calling this method with \c false. + */ + void ToggleWarningMessages(bool enabled); + + /** + \brief Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + + \verbatim + z3.exe -ini? + \endverbatim + + Only a few configuration parameters are mutable once the context is created. + The error handler is invoked when trying to modify an immutable parameter. + + \sa SetParamValue + */ + void UpdateParamValue(String^ param_id, String^ value); + + /** + \brief Get a configuration parameter. + + \sa Z3_mk_config + \sa Z3_set_param_value + */ + String^ GetParamValue(String^ param_id); + + /** + \brief Configure the SMTLIB logic to be used in the given logical context. + */ + + bool SetLogic(String^ logic); + + /*@}*/ + + + /** + @name Symbols + */ + /*@{*/ + /** + \brief Create a Z3 symbol using an intege or a string. + + Symbols are used to name several term and type constructors. + + */ + Symbol^ MkSymbol(int i); + + Symbol^ MkSymbol(String^ s); + /*@}*/ + + /** + @name Types + */ + /*@{*/ + + /** + \brief Create a free (uninterpreted) type using the given name (symbol). + + Two free types are considered the same iff the have the same name. + */ + SortPtr MkSort(Symbol^ s); + + SortPtr MkSort(String^ s); + + SortPtr MkSort(int i); + + + /** + \brief Create the boolean type. + + This type is used to create propositional variables and predicates. + */ + SortPtr MkBoolSort(); + + /** + \brief Create an integer type. + + This type is not the int type found in programming languages. + A machine integer can be represented using bit-vectors. The function + #MkBvType creates a bit-vector type. + + \sa MkBvType + */ + SortPtr MkIntSort(); + + /** + \brief Create a real type. + + This type is not a floating point number. + Z3 does not have support for floating point numbers yet. + */ + SortPtr MkRealSort(); + + + /** + \brief Create a bit-vector type of the given size. + + This type can also be seen as a machine integer. + + \remark The size of the bitvector type must be greater than zero. + */ + SortPtr MkBvSort(unsigned sz); + + /** + \brief Create an array type. + + We usually represent the array type as: [domain -> range]. + Arrays are usually used to model the heap/memory in software verification. + + \sa MkArraySelect + \sa MkArrayStore + \sa MkArrayMap + \sa MkConstArray + */ + + SortPtr MkArraySort(SortPtr domain, SortPtr range); + + /** + \brief Create a named finite domain sort. + + To create constants that belong to the finite domain, + use MkNumeral for creating numerals and pass a numeric + constant together with the sort returned by this call. + */ + SortPtr MkFiniteDomainSort(String^ name, unsigned __int64 domain_size); + + + /** + \brief Create a tuple type. + + + A tuple with \c n fields has a constructor and \c n projections. + This function will also declare the constructor and projection functions. + + \param mk_tuple_name name of the constructor function associated with the tuple type. + \param field_names name of the projection functions. + \param field_types type of the tuple fields. + \param mk_tuple_decl output parameter that will contain the constructor declaration. + \param proj_decl output parameter that will contain the projection function declarations. + This field must be a buffer of size \c num_fields allocated by the user. + */ + SortPtr MkTupleSort( + Symbol^ mk_tuple_name, + array^ field_names, + array^ field_types, + [Out] FuncDeclPtr% mk_tuple_decl, + [In] [Out] array^ proj_decl + ); + + SortPtr MkTupleSort( + String^ mk_tuple_name, + array^ field_names, + array^ field_types, + [Out] FuncDeclPtr% mk_tuple_decl, + [In, Out] array^ proj_decl + ); + + /** + \brief create an enumeration type. + + \param name - name of enumeration sort. + \param enum_names - names of enumerated elements. + \param enum_consts - output function declarations for enumerated elements. + \param enum_testers - output function declarations for enumeration testers. + + */ + SortPtr MkEnumerationSort( + String^ name, + array^ enum_names, + array^ enum_consts, + array^ enum_testers); + + /** + \brief create list sort. + + \param name of resulting list type. + \param elem_sort sort of elements. + \param nil_decl function declaration for nil. + \param is_nil_decl function declaration for nil tester. + \param cons_decl function declaration for cons constructor. + \param is_cons_decl function declaration for cons tester. + \param head_decl function declaration for head accessor. + \param tail_decl function declaration for tail accessor. + + */ + SortPtr MkListSort( + String^ name, + SortPtr elem_sort, + [Out] FuncDeclPtr% nil_decl, + [Out] FuncDeclPtr% is_nil_decl, + [Out] FuncDeclPtr% cons_decl, + [Out] FuncDeclPtr% is_cons_decl, + [Out] FuncDeclPtr% head_decl, + [Out] FuncDeclPtr% tail_decl + ); + + + /** + \brief create constructor object for datatype declarations. + The object must be disposed with manually. + + Use the methods #GetConstructor, #GetTester, and #GetAccessors to + retrieve the function declarations for constructors, tester and accessors + after the datatype has been declared. + + A field_ref is the index of the (mutually) recursive datatype. + For example, if you declare a single recursive datatype, then + a reference to the recursive datatype that is being declared is + the number 0. If you declare two mutually recursive datatypes, then + the reference to the second recursive datatype is 1. + + */ + + Constructor^ MkConstructor( + String^ name, + String^ tester, + array^ field_names, + array^ field_sorts, + array^ field_refs + ); + + /** + \brief retrieve constructor function declaration. + */ + FuncDeclPtr GetConstructor(Constructor^ c) { return c->GetConstructor(); } + + /** + \brief retrieve test function for constructor. + */ + FuncDeclPtr GetTester(Constructor^ c) { return c->GetTester(); } + + /** + \brief retrieve accessors for datatype. + */ + array^ GetAccessors(Constructor^ c) { return c->GetAccessors(); } + + /** + \brief create datatype sort. + */ + SortPtr MkDataType( + String^ name, + array^ constructors + ); + + + /** + \brief create datatype sorts. + + \param names array of names for the recursive datatypes. + \param constructors array of arrays of constructors. + */ + array^ MkDataTypes( + array^ names, + array^>^ constructors + ); + + /*@}*/ + + /** + @name Constants and Applications + */ + + /*@{*/ + + /** + \brief Declare a constant or function. + + \param s name of the constant or function. + \param domain array containing the type of each argument. + The array must contain domain_size elements. It is 0 whe declaring a constant. + \param range type of the constant or the return type of the function. + + After declaring a constant or function, the function + #MkApp can be used to create a constant or function + application. + + \sa MkApp + */ + FuncDeclPtr MkFuncDecl(Symbol^ s, array^ domain, SortPtr range); + + FuncDeclPtr MkFuncDecl(String^ s, array^ domain, SortPtr range); + + FuncDeclPtr MkConstDecl(Symbol^ s, SortPtr ty) { + return MkFuncDecl(s, gcnew array(0), ty); + } + FuncDeclPtr MkFuncDecl(Symbol^ s, SortPtr domain, SortPtr range); + + FuncDeclPtr MkFuncDecl(Symbol^ s, SortPtr d1, SortPtr d2, SortPtr range); + + FuncDeclPtr MkConstDecl(String^ s, SortPtr ty) { + return MkFuncDecl(s, gcnew array(0), ty); + } + FuncDeclPtr MkFuncDecl(String^ s, SortPtr domain, SortPtr range); + + FuncDeclPtr MkFuncDecl(String^ s, SortPtr d1, SortPtr d2, SortPtr range); + + + /** + \brief Create a constant or function application. + + \sa MkFuncDecl + */ + AppPtr MkApp(FuncDeclPtr d, array^ args); + AppPtr MkApp(FuncDeclPtr d, TermPtr arg); + AppPtr MkApp(FuncDeclPtr d, TermPtr arg1, TermPtr arg2); + AppPtr MkApp(FuncDeclPtr d, TermPtr arg1, TermPtr arg2, TermPtr arg3); + + /** + \brief Declare and create a constant. + + \sa MkApp + \sa MkFuncDecl + */ + AppPtr MkConst(FuncDeclPtr d); + AppPtr MkConst(String^ s, SortPtr ty); + AppPtr MkConst(Symbol^ s, SortPtr ty); + + + /** + \brief Declare a fresh constant or function. + + Z3 will generate an unique name for this function declaration. + + \sa MkFuncDecl + */ + FuncDeclPtr MkFreshFuncDecl(String^ prefix, array^ domain, SortPtr range); + + /** + \brief Declare and create a fresh constant. + + \sa MkFuncDecl + \sa MkApp + */ + TermPtr MkFreshConst(String^ prefix, SortPtr ty); + + /** + \brief Create labeled formula. + + */ + TermPtr MkLabel(Symbol^ name, bool pos, TermPtr fml); + + /** + \brief Create an AST node representing \c true. + */ + TermPtr MkTrue() { return TermPtr(Z3_mk_true(ctx())); } + + + /** + \brief Create an AST node representing \c false. + */ + TermPtr MkFalse() { return TermPtr(Z3_mk_false(ctx())); } + + + /** + \brief Create an AST node representing l = r. + + The nodes \c l and \c r must have the same type. + */ + TermPtr MkEq(TermPtr l, TermPtr r); + + + /** + \brief Create an AST node representing distinct(args[0], ..., args[args.Length-1]). + + The \c distinct construct is used for declaring the arguments pairwise distinct. + That is, Forall 0 <= i < j < args.Length. not args[i] = args[j]. + + All arguments must have the same type. + + \remark The number of arguments of a distinct construct must be greater than one. + */ + TermPtr MkDistinct(array^ args); + + + /** + \brief Create an AST node representing not(a). + + The node \c a must have Boolean type. + */ + virtual TermPtr MkNot(TermPtr arg); + + /** + \brief + Create an AST node representing an if-then-else: ite(t1, t2, t3). + + The node \c t1 must have Boolean type, \c t2 and \c t3 must have the same type. + The type of the new node is equal to the type of \c t2 and \c t3. + */ + TermPtr MkIte(TermPtr t1, TermPtr t2, TermPtr t3); + + /** + \brief Create an AST node representing t1 iff t2. + + The nodes \c t1 and \c t2 must have Boolean type. + */ + TermPtr MkIff(TermPtr t1, TermPtr t2); + + /** + \brief Create an AST node representing t1 implies t2. + + The nodes \c t1 and \c t2 must have Boolean type. + */ + TermPtr MkImplies(TermPtr t1, TermPtr t2); + + /** + \brief Create an AST node representing t1 xor t2. + + The nodes \c t1 and \c t2 must have Boolean type. + */ + TermPtr MkXor(TermPtr t1, TermPtr t2); + + /** + \brief Create an AST node representing args[0] and ... and args[args.Length-1]. + + All arguments must have Boolean type. + + \remark The number of arguments must be greater than zero. + */ + TermPtr MkAnd(array^ args); + TermPtr MkAnd(TermPtr arg1, TermPtr arg2); + + /** + \brief Create an AST node representing args[0] or ... or args[args.Length-1]. + + All arguments must have Boolean type. + + \remark The number of arguments must be greater than zero. + */ + TermPtr MkOr(array^ args); + TermPtr MkOr(TermPtr arg1, TermPtr arg2); + + /** + \brief Create an AST node representing args[0] + ... + args[args.Length-1]. + + All arguments must have int or real type. + + \remark The number of arguments must be greater than zero. + */ + TermPtr MkAdd(array^ args); + TermPtr MkAdd(TermPtr arg1, TermPtr arg2); + + /** + \brief Create an AST node representing args[0] * ... * args[args.Length-1]. + + All arguments must have int or real type. + + \remark Z3 has limited support for non-linear arithmetic. + \remark The number of arguments must be greater than zero. + */ + TermPtr MkMul(array^ args); + TermPtr MkMul(TermPtr arg1, TermPtr arg2); + + /** + \brief Create an AST node representing args[0] - ... - args[args.Length - 1]. + + All arguments must have int or real type. + + \remark The number of arguments must be greater than zero. + */ + TermPtr MkSub(array^ args); + TermPtr MkSub(TermPtr arg1, TermPtr arg2); + + /** + \brief Create an AST node representing - arg. + + The argument must have int or real type. + */ + TermPtr MkUnaryMinus(TermPtr arg); + + /** + \brief Create integer or real division. + + The nodes \c arg1 and \c arg2 must have the same type, and must be int or real. + */ + TermPtr MkDiv(TermPtr arg1, TermPtr arg2); + + /** + \brief Create integer modulus + + The nodes \c arg1 and \c arg2 must have integer type. + */ + TermPtr MkMod(TermPtr arg1, TermPtr arg2); + + /** + \brief Create integer remainder + + The nodes \c arg1 and \c arg2 must have integer type. + */ + TermPtr MkRem(TermPtr arg1, TermPtr arg2); + + /** + \brief Create coercion from integer to real + + The node \c arg must have integer type. + */ + TermPtr MkToReal(TermPtr arg); + + /** + \brief Create coercion from real to integer (floor) + + The node \c arg must have real type. + */ + TermPtr MkToInt(TermPtr arg); + + /** + \brief Check if real is an integer value. + + The node \c arg must have real type. + */ + TermPtr MkIsInt(TermPtr arg); + + + + /** + \brief Create less than. + + The nodes \c arg1 and \c arg2 must have the same type, and must be int or real. + */ + TermPtr MkLt(TermPtr arg1, TermPtr arg2); + + /** + \brief Create less than or equal to. + + The nodes \c arg1 and \c arg2 must have the same type, and must be int or real. + */ + TermPtr MkLe(TermPtr arg1, TermPtr arg2); + + /** + \brief Create greater than. + + The nodes \c arg1 and \c arg2 must have the same type, and must be int or real. + */ + TermPtr MkGt(TermPtr arg1, TermPtr arg2); + + /** + \brief Create greater than or equal to. + + The nodes \c arg1 and \c arg2 must have the same type, and must be int or real. + */ + TermPtr MkGe(TermPtr arg1, TermPtr arg2); + + /** + \brief Bitwise negation. + + The node \c arg1 must have a bit-vector type. + */ + TermPtr MkBvNot(TermPtr t1); + + /** + \brief Take conjunction of bits in vector. + + The node \c arg1 must have a bit-vector type. + */ + TermPtr MkBvReduceAnd(TermPtr t1); + + /** + \brief Take disjunction of bits in vector. + + The node \c arg1 must have a bit-vector type. + */ + TermPtr MkBvReduceOr(TermPtr t1); + + /** + \brief Bitwise and. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvAnd(TermPtr t1, TermPtr t2); + + /** + \brief Bitwise or. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvOr(TermPtr t1, TermPtr t2); + + /** + \brief Bitwise exclusive-or. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvXor(TermPtr t1, TermPtr t2); + + /** + \brief Bitwise nand. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvNand(TermPtr t1, TermPtr t2); + + /** + \brief Bitwise nor. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvNor(TermPtr t1, TermPtr t2); + + /** + \brief Bitwise xnor. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvXnor(TermPtr t1, TermPtr t2); + + /** + \brief Standard two's complement unary minus. + + The node \c t1 must have bit-vector type. + */ + TermPtr MkBvNeg(TermPtr t1); + + /** + \brief Standard two's complement addition. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvAdd(TermPtr t1, TermPtr t2); + + /** + \brief Standard two's complement subtraction. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSub(TermPtr t1, TermPtr t2); + + /** + \brief Standard two's complement multiplication. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvMul(TermPtr t1, TermPtr t2); + + /** + \brief Unsigned division. + + It is defined as the \c floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvUdiv(TermPtr t1, TermPtr t2); + + /** + \brief Two's complement signed division. + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSdiv(TermPtr t1, TermPtr t2); + + /** + \brief Unsigned remainder. + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + + If t2 is zero, then the result is undefined. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvUrem(TermPtr t1, TermPtr t2); + + /** + \brief Two's complement signed remainder (sign follows dividend). + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + + \sa MkBvSmod + */ + TermPtr MkBvSrem(TermPtr t1, TermPtr t2); + + /** + \brief Two's complement signed remainder (sign follows divisor). + + If t2 is zero, then the result is undefined. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + + \sa MkBvSrem + */ + TermPtr MkBvSmod(TermPtr t1, TermPtr t2); + + /** + \brief Unsigned less than. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvUlt(TermPtr t1, TermPtr t2); + + /** + \brief Two's complement signed less than. + + It abbreviates: + \code + (or (and (= (extract[|m-1|:|m-1|] s) bit1) + (= (extract[|m-1|:|m-1|] t) bit0)) + (and (= (extract[|m-1|:|m-1|] s) (extract[|m-1|:|m-1|] t)) + (bvult s t))) + \endcode + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSlt(TermPtr t1, TermPtr t2); + + /** + \brief Unsigned less than or equal to. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvUle(TermPtr t1, TermPtr t2); + + /** + \brief Two's complement signed less than or equal to. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSle(TermPtr t1, TermPtr t2); + + /** + \brief Unsigned greater than or equal to. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvUge(TermPtr t1, TermPtr t2); + + /** + \brief Two's complement signed greater than or equal to. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSge(TermPtr t1, TermPtr t2); + + /** + \brief Unsigned greater than. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvUgt(TermPtr t1, TermPtr t2); + + /** + \brief Two's complement signed greater than. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSgt(TermPtr t1, TermPtr t2); + + /** + \brief Concatenate the given bit-vectors. + + The nodes \c t1 and \c t2 must have (possibly different) bit-vector types + + The result is a bit-vector of size n1+n2, where \c n1 (\c n2) is the size + of \c t1 (\c t2). + */ + TermPtr MkBvConcat(TermPtr t1, TermPtr t2); + + /** + \brief Extract the bits \c high down to \c low from a bitvector of + size \c m to yield a new bitvector of size \c n, where n = + high - low + 1. + + The node \c t must have a bit-vector type. + */ + TermPtr MkBvExtract(unsigned high, unsigned low, TermPtr t); + + /** + \brief Sign-extend of the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given + bit-vector. + + The node \c t must have a bit-vector type. + */ + TermPtr MkBvSignExt(unsigned i, TermPtr t); + + /** + \brief Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. + + The node \c t1 must have a bit-vector type. + */ + TermPtr MkBvZeroExt(unsigned i, TermPtr t); + + /** + \brief Repeat the bit-vector i times. + + The node \c t1 must have a bit-vector type. + */ + TermPtr MkBvRepeat(unsigned i, TermPtr t); + + /** + \brief Shift left. + + It is equivalent to multiplication by 2^x where \c x is the value of the + third argument. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvShl(TermPtr t1, TermPtr t2); + + /** + \brief Logical shift right. + + It is equivalent to unsigned division by 2^x where \c x is the + value of the third argument. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvLshr(TermPtr t1, TermPtr t2); + + /** + \brief Arithmetic shift right. + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvAshr(TermPtr t1, TermPtr t2); + + /** + \brief Rotate bits of \c t1 to the left \c i times. + + The node \c t1 must have a bit-vector type. + */ + TermPtr MkBvRotateLeft(unsigned i, TermPtr t1); + + /** + \brief Rotate bits of \c t1 to the right \c i times. + + The node \c t1 must have a bit-vector type. + */ + TermPtr MkBvRotateRight(unsigned i, TermPtr t1); + + /** + \brief Rotate bits of \c t1 to the left \c t2 times. + + The node \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvRotateLeft(TermPtr t1, TermPtr t2); + + /** + \brief Rotate bits of \c t1 to the right \c t2 times. + + The node \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvRotateRight(TermPtr t1, TermPtr t2); + + /** + \brief Convert bit vector to integer. + + The node \c t1 must have a bit-vector type. + */ + TermPtr MkBv2Int(TermPtr t1, bool is_signed); + + /** + \brief Convert integer to bit vector. + + The node \c t1 must have a integer type. + */ + TermPtr MkInt2Bv(unsigned size, TermPtr t1); + + /** + \brief Check that addition does not overflow. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvAddNoOverflow(TermPtr t1, TermPtr t2, bool is_signed); + + /** + \brief Check that addition does not underflow. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvAddNoUnderflow(TermPtr t1, TermPtr t2); + + /** + \brief Check that subtraction does not overflow. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSubNoOverflow(TermPtr t1, TermPtr t2); + + /** + \brief Check that subtraction does not underflow. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSubNoUnderflow(TermPtr t1, TermPtr t2, bool is_signed); + + /** + \brief Check that division does not overflow. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvSDivNoOverflow(TermPtr t1, TermPtr t2); + + /** + \brief Check that negation does not overflow. + */ + TermPtr MkBvNegNoOverflow(TermPtr t1); + + /** + \brief Check that multiplication does not overflow. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvMulNoOverflow(TermPtr t1, TermPtr t2, bool is_signed); + + /** + \brief Check that multiplication does not underflow. + + The nodes \c t1 and \c t2 must have the same bit-vector type. + */ + TermPtr MkBvMulNoUnderflow(TermPtr t1, TermPtr t2); + + /** + \brief Array read. + + The node \c a must have an array type [domain -> range], and \c i must have the type \c domain. + The type of the result is \c range. + + \sa MkArraySort + \sa MkArrayStore + */ + TermPtr MkArraySelect(TermPtr a, TermPtr i); + + /** + \brief Array update. + + The node \c a must have an array type [domain -> range], \c i must have type \c domain, + \c v must have type range. The type of the result is [domain -> range]. + + \sa MkArraySort + \sa MkArraySelect + */ + TermPtr MkArrayStore(TermPtr a, TermPtr i, TermPtr v); + + /** + \brief Array map. + + The \c n nodes \c args must be of array sorts [domain_i -> range_i]. + The function declaration \c f must have type range_1 .. range_n -> range. + \c v must have sort range. The sort of the result is [domain_i -> range]. + + \sa MkArraySort + \sa MkArraySelect + \sa MkArrayStore + */ + TermPtr MkArrayMap(FuncDeclPtr d, array^ args); + + /** + \brief Constant array. + + The node \c a must have an array type [range], \c domain indicates the domain + of the array. + The type of the result is [domain -> range]. + + \sa MkArraySort + \sa MkArraySelect + \sa MkArrayStore + */ + TermPtr MkArrayConst(SortPtr domain, TermPtr v); + + /** + \brief Access the array default. + + The node \c a must have an array type [domain -> range]. + The type of the result is [range]. The result is a term + whose value holds the default array value. That is, models should + ensure that the default for a (ElseCase) evaluates to the + same value as MkArrayDefault(a). + + \sa MkArraySort + \sa MkArraySelect + \sa MkArrayStore + \sa MkArrayconst + */ + TermPtr MkArrayDefault(TermPtr a); + + /*@}*/ + + + /** + @name Sets + */ + /*@{*/ + + /** + \brief Create Set type. + */ + SortPtr MkSetSort(SortPtr ty) { return SortPtr(Z3_mk_set_sort(ctx(), get_sort(ty))); } + + /** + \brief Create the empty set. + */ + TermPtr MkEmptySet(SortPtr ty) { return TermPtr(Z3_mk_empty_set(ctx(), get_sort(ty))); } + + /** + \brief Create the full set. + */ + TermPtr MkFullSet(SortPtr ty) { return TermPtr(Z3_mk_full_set(ctx(), get_sort(ty))); } + + /** + \brief Add an element to a set. + + The first argument must be a set, the second an element. + */ + TermPtr MkSetAdd(TermPtr set, TermPtr elem) { + return TermPtr(Z3_mk_set_add(ctx(), get_ast(set), get_ast(elem))); + } + + /** + \brief Remove an element to a set. + + The first argument must be a set, the second an element. + */ + TermPtr MkSetDel(TermPtr set, TermPtr elem) { + return TermPtr(Z3_mk_set_del(ctx(), get_ast(set), get_ast(elem))); + } + + /** + \brief Take the union of a arrays of sets. + + The arguments must all be of the same type and all be of set types. + */ + TermPtr MkSetUnion(array^ sets); + TermPtr MkSetUnion(TermPtr set1, TermPtr set2); + + /** + \brief Take the intersection of a arrays of sets. + */ + TermPtr MkSetIntersect(array^ sets); + TermPtr MkSetIntersect(TermPtr set1, TermPtr set2); + + /** + \brief Take the set difference between two sets. + */ + TermPtr MkSetDifference(TermPtr arg1, TermPtr arg2) { + return TermPtr(Z3_mk_set_difference(ctx(), get_ast(arg1), get_ast(arg2))); + } + /** + \brief Take the complement of a set. + */ + TermPtr MkSetComplement(TermPtr arg) { + return TermPtr(Z3_mk_set_complement(ctx(), get_ast(arg))); + } + + /** + \brief Check for set membership. + + The first argument should be an element type of the set. + */ + TermPtr MkSetMember(TermPtr elem, TermPtr set) { + return TermPtr(Z3_mk_set_member(ctx(), get_ast(elem), get_ast(set))); + } + + /** + \brief Check for subsetness of sets. + */ + TermPtr MkSetSubset(TermPtr arg1, TermPtr arg2) { + return TermPtr(Z3_mk_set_subset(ctx(), get_ast(arg1), get_ast(arg2))); + } + /*@}*/ + + + /** + @name Injective functions + */ + /*@{*/ + + /** + \brief Create injective function + */ + + FuncDeclPtr MkInjectiveFunction(String^ name, array^ domain, SortPtr range); + + FuncDeclPtr MkInjectiveFunction(Symbol^ name, array^ domain, SortPtr range); + + /*@}*/ + + + + /** + @name Numerals + */ + /*@{*/ + + /** + \brief Create a numeral of a given type. + + \param numeral An integer, or a string representing the numeral value in decimal notation. + If the given type is a real, then the numeral can be a rational, that is, a string of the form [num]* / [num]*. + \param ty The type of the numeral. In the current implementation, the given type can be an int, real, or bit-vectors of arbitrary size. + + */ + TermPtr MkNumeral(String^ numeral, SortPtr ty); + TermPtr MkNumeral(int n, SortPtr ty); + TermPtr MkNumeral(unsigned n, SortPtr ty); + TermPtr MkNumeral(__int64 n, SortPtr ty); + TermPtr MkNumeral(unsigned __int64 n, SortPtr ty); + + /** + \brief Create a numeral of type Int. + */ + TermPtr MkIntNumeral(String^ n) { return MkNumeral(n, MkIntSort()); } + TermPtr MkIntNumeral(int n) { return MkNumeral(n, MkIntSort()); } + TermPtr MkIntNumeral(unsigned n) { return MkNumeral(n, MkIntSort()); } + TermPtr MkIntNumeral(__int64 n) { return MkNumeral(n, MkIntSort()); } + TermPtr MkIntNumeral(unsigned __int64 n) { return MkNumeral(n, MkIntSort()); } + + + /** + \brief Create a numeral of type Real. + */ + TermPtr MkRealNumeral(String^ n) { return MkNumeral(n, MkRealSort()); } + TermPtr MkRealNumeral(int n) { return MkNumeral(n, MkRealSort()); } + TermPtr MkRealNumeral(unsigned n) { return MkNumeral(n, MkRealSort()); } + TermPtr MkRealNumeral(__int64 n) { return MkNumeral(n, MkRealSort()); } + TermPtr MkRealNumeral(unsigned __int64 n) { return MkNumeral(n, MkRealSort()); } + + /*@}*/ + + /** + @name Quantifiers + */ + /*@{*/ + + /** + \brief Create a pattern for quantifier instantiation. + + Z3 uses pattern matching to instantiate quantifiers. If a + pattern is not provided for a quantifier, then Z3 will + automatically compute a set of patterns for it. However, for + optimal performance, the user should provide the patterns. + + Patterns comprise an array of terms. The array of terms + passed to MkPattern should be + non-empty. If the array comprises of more than one term, it is + a called a multi-pattern. + + In general, one can pass in an array of (multi-)patterns in the + quantifier constructor. + + To summarize, each quantifier takes an array of alternative multi-patterns. + The quantifier is instantiated for every multi-pattern that is matched. + Each multi-pattern is an array of terms. All terms must match for the + multi-pattern to trigger instantiation. + Create a multi-pattern using MkPattern. + Create an array of multi-patterns and pass it to the quantifier constructor. + If you just want a multi-pattern with a single term, then pass in the singleton array + + + For example, if you want to create the multi-pattern + consisting of the two terms: \ccode{(store A I V)} + and \ccode{(select A J)} + where A, I, J, V are bound variables, create the pattern + +
+           pattern1 = context.MkPattern(new TermPtr[]{ 
+                             context.MkArrayStore(A,I,V),
+                             context.MkArraySelect(A,J)
+                                      })
+           
+ Then form the array +
 
+                 new PatternPtr[]{ pattern1 }
+
+           
+ and pass it to the + function \ccode{MkForall} or \ccode{MkExists}. + Suppose you also want to have the quantifier be instantiated if + the pattern \ccode{(select (store A I V) J)} is matched, then create the + pattern: +
+           pattern2 = context.MkPattern(new TermPtr[] {
+                                         context.MkArraySelect(context.MkArrayStore(A,I,V),J) })
+           
+ Then form the array: +
+                 new PatternPtr[] { pattern1, pattern2 }
+           
+ + \sa MkForall + \sa MkExists + */ + PatternPtr MkPattern(array^ terms); + + /** + \brief Create a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + \verbatim + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + \endverbatim + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper x appears, the higher is its + index. + + \param index de-Bruijn index + \param ty type of the bound variable + + \sa MkForall + \sa MkExists + */ + TermPtr MkBound(unsigned index, SortPtr ty); + + /** + \brief Create a forall formula. + + \param weight quantifiers are associated with weights indicating the importance + of using the quantifier during instantiation. By default, pass the weight 0. + \param patterns array containing the patterns created using #MkPattern. + \param types array containing the types of the bound variables. + \param names array containing the names as symbols of the bound variables. + \param body the body of the quantifier. + + \sa MkPattern + \sa MkBound + \sa MkExists + */ + TermPtr MkForall( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + TermPtr body + ); + + /** + \brief Create a forall formula. + + \param weight quantifiers are associated with weights indicating the importance + of using the quantifier during instantiation. By default, pass the weight 0. + \param patterns array containing the patterns created using #MkPattern. + \param types array containing the types of the bound variables. + \param names array containing the names as strings of the bound variables. + \param body the body of the quantifier. + + \sa MkPattern + \sa MkBound + \sa MkExists + */ + TermPtr MkForall( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + TermPtr body + ); + + /** + \brief Create a forall formula. + + This function allows creating a forall without using de-Bruijn indices in the body or patterns. + It is sometimes convenient to create the body of a quantifier without de-Bruijn indices, but + instead use constants. These constants have to be replaced by de-Bruijn indices for the + internal representation. This function allows the caller to hand over the task to Z3 of abstracting + the constants into bound variables, so that each occurrence of the variables in the array + bound gets replaced by a de-Bruijn index. + + \param weight quantifiers are associated with weights indicating the importance + of using the quantifier during instantiation. By default, pass the weight 0. + \param bound array containing the constants to be abstracted as bound variables. + \param patterns array containing the patterns created using #MkPattern. + \param body the body of the quantifier. + + \sa MkPattern + \sa MkExists + */ + TermPtr MkForall( + unsigned weight, + array^ bound, + array^ patterns, + TermPtr body + ); + + /** + \brief Create an exists formula. Similar to #MkForall. + + \sa MkPattern + \sa MkBound + \sa MkForall + */ + TermPtr MkExists( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + TermPtr body + ); + + TermPtr MkExists( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + TermPtr body + ); + + TermPtr MkExists( + unsigned weight, + array^ bound, + array^ patterns, + TermPtr body + ); + + /** + \brief Create a quantifier with no-pattern directives and symbols. + + Use de-Bruijn indexing. + + \sa MkPattern + \sa MkBound + \sa MkForall + \sa MkExists + */ + + TermPtr MkQuantifier( + bool is_forall, + unsigned weight, + array^ patterns, + array^ no_patterns, + array^ types, + array^ names, + TermPtr body + ) + { + return MkQuantifier(is_forall, weight, nullptr, nullptr, patterns, no_patterns, types, names, body); + } + + + TermPtr MkQuantifier( + bool is_forall, + unsigned weight, + Symbol^ quantifier_id, + Symbol^ skolem_id, + array^ patterns, + array^ no_patterns, + array^ types, + array^ names, + TermPtr body + ); + + + + /** + \brief Create a quantifier with no-pattern directives and symbols. + + Abstract terms as the bound variables. + + \sa MkPattern + \sa MkBound + \sa MkForall + \sa MkExists + */ + + TermPtr MkQuantifier( + bool is_forall, + unsigned weight, + Symbol^ quantifier_id, + Symbol^ skolem_id, + array^ patterns, + array^ no_patterns, + array^ bound, + TermPtr body + ); + + + /*@}*/ + + + /** + @name Accessors + */ + /*@{*/ + + /** + \brief Return a unique identifier for \c t. + */ + + unsigned GetTermId(TermPtr t); + + /** + \brief Return a unique identifier for \c f. + */ + unsigned GetFuncDeclId(FuncDeclPtr f); + + /** + \brief Return a unique identifier for \c s. + */ + unsigned GetSortId(SortPtr s); + + + /** + \brief Return \c SymbolKind.Int if the symbol was constructed + using #MkIntSymbol, and \c SymbolKind.String if the symbol + was constructed using #MkStringSymbol. + */ + SymbolKind GetSymbolKind(Symbol^ s); + + /** + \brief Return the symbol int value. + + \pre GetSymbolKind(s) == SymbolKind.Int + + \sa MkIntSymbol + */ + int GetSymbolInt(Symbol^ s); + + /** + \brief Return the symbol name. + + \pre GetSymbolKind(s) = SymbolKind.String + + \sa MkStringSymbol + */ + String^ GetSymbolString(Symbol^ s); + + /** + \brief Return \c true if the two given AST nodes are equal. + */ + bool IsEq(TermPtr t1, TermPtr t2); + + /** + \brief Return \c true if \c t is well sorted. + */ + bool IsWellSorted(TermPtr t); + + /** + \brief Return the kind of the given AST. + */ + TermKind GetTermKind(TermPtr a); + + /** + \brief Return the kind of the built-in operator. + + \pre GetTermKind(a) == TermKind.App + */ + DeclKind GetDeclKind(FuncDeclPtr d); + + /** + \brief Return auxiliary parameters associated with the built-in operator. + For example, the operator for bit-vector extraction uses + two parameters, the upper and lower bit-index for extraction. + */ + array^ GetDeclParameters(FuncDeclPtr d); + + /** + \brief Return the declaration of a constant or function application. + + \pre GetTermKind(a) == TermKind.App + */ + FuncDeclPtr GetAppDecl(AppPtr a); + + /** + \brief Return the arguments of an application. If \c t + is an constant, then array is empty. + */ + array^ GetAppArgs(AppPtr a); + + /** + \brief Return the number of a numeric ast. + + \pre GetTermKind(a) == TermKind.Numeral + */ + String^ GetNumeralString(TermPtr a); + + /** + \brief Similar to #GetNumeralString, but only succeeds if + the value can fit in a machine int. Throw InvalidArgument if the call fails. + + \pre GetTermKind(v) == TermKind.Numeral && IsInt32(v) + + \sa GetNumeralString + */ + int GetNumeralInt(TermPtr v); + + bool TryGetNumeralInt(TermPtr v, [Out] int% i); + + /** + \brief Similar to #GetNumeralString, but only succeeds if + the value can fit in a machine unsigned int. Throw InvalidArgument if the call fails. + + \pre GetTermKind(v) == TermKind.Numeral + + \sa GetNumeralString + */ + unsigned int GetNumeralUInt(TermPtr v); + + bool TryGetNumeralUInt(TermPtr v, [Out] unsigned int% u); + + + /** + \brief Similar to #GetNumeralString, but only succeeds if + the value can fit in a machine unsigned long long int. Throw InvalidArgument if the call fails. + + \pre GetTermKind(v) == TermKind.Numeral + + \sa GetNumeralString + */ + unsigned __int64 GetNumeralUInt64(TermPtr v); + + bool TryGetNumeralUInt64(TermPtr v, [Out] unsigned __int64% u); + + + /** + \brief Similar to #GetNumeralString, but only succeeds if + the value can fit in a machine long long int. Throw InvalidArgument if the call fails. + + \pre GetTermKind(v) == TermKind.Numeral + + */ + __int64 GetNumeralInt64(TermPtr v); + + bool TryGetNumeralInt64(TermPtr v, [Out] __int64% i); + + /** + \brief Similar to #GetNumeralString, but only succeeds if + the value can fit in a machine long long int. Throw InvalidArgument if the call fails. + + \pre GetTermKind(v) == TermKind.Numeral + + \sa GetNumeralString + */ + + bool TryGetNumeral(TermPtr v, [Out] __int64% num, [Out] __int64% den); + + void GetNumeral(TermPtr v, [Out] System::Numerics::BigInteger% num, [Out] System::Numerics::BigInteger% den); + + /** + \brief Return the Boolean value of a truth constant. Return LBool::Undef if a is not a boolean constant (true or false). + + \pre GetTermKind(a) == TermKind.App + */ + LBool GetBoolValue(TermPtr a); + + + /** + \brief Return the index of a de-Brujin bound variable. + + \pre GetTermKind(a) == TermKind.Var + */ + unsigned GetVarIndex(TermPtr a) { + return Z3_get_index_value(ctx(), get_ast(a)); + } + + /** + \brief Return components of a quantifier. + + \pre GetTermKind(a) = TermKind.Quantifier + */ + RawQuantifier^ GetQuantifier(TermPtr a); + + + /** + \brief Return array of terms in the pattern. + + \pre GetTermKind(a) = TermKind.Pattern + */ + array^ GetPatternTerms(PatternPtr p); + + /** + \brief Return the constant declaration name as a symbol. + */ + Symbol^ GetDeclName(FuncDeclPtr d); + + /** + \brief Return the type name as a symbol. + */ + Symbol^ GetSortName(SortPtr ty); + + /** + \brief Return the type of an AST node. + + The AST node must be a constant, application, numeral, bound variable, or quantifier. + */ + SortPtr GetSort(TermPtr a); + + /** + \brief Return the domain of a function declaration. + + */ + array^ GetDomain(FuncDeclPtr d); + + + /** + \brief Return the range of the given declaration. + + If \c d is a constant (i.e., has zero arguments), then this + function returns the type of the constant. + */ + SortPtr GetRange(FuncDeclPtr d); + + /** + \brief Return the type kind (e.g., array, tuple, int, bool, etc). + + \sa SortKind + */ + SortKind GetSortKind(SortPtr t); + + /** + \brief Return the size of the given bit-vector type. + + \pre GetSortKind(t) = SortKind.Bv + + \sa MkBvSort + \sa GetSortKind + */ + unsigned GetBvSortSize(SortPtr t); + + /** + \brief Return the domain of the given array type. + + \pre GetSortKind(t) == SortKind.Array + + \sa MkArraySort + \sa GetSortKind + */ + SortPtr GetArraySortDomain(SortPtr t); + + /** + \brief Return the range of the given array type. + + \pre GetSortKind(t) == SortKind.Array + + \sa MkArraySort + \sa GetSortKind + */ + SortPtr GetArraySortRange(SortPtr t); + + /** + \brief Return the constructor declaration of the given tuple + type. + + \pre GetSortKind(t) == SortKind.Tuple + + \sa MkTupleSort + \sa GetSortKind + */ + FuncDeclPtr GetTupleConstructor(SortPtr t); + + /** + \brief Return the field declarations of a given tuple type. + + \pre GetSortKind(t) == SortKind.Tuple + + + \sa MkTupleSort + \sa GetSortKind + */ + array^ GetTupleFields(SortPtr t); + + /*@}*/ + + /** + @name Modifiers + */ + /*@{*/ + + /** + \brief Update the arguments of a term or quantifier. + \pre The number of arguments passed in new_args should + be the same as number of arguments to the term t. + */ + TermPtr UpdateTerm(TermPtr t, array^ new_args); + + /*@}*/ + + + /** + @name Constraints + */ + /*@{*/ + + /** + \brief Create a backtracking point. + + The logical context can be viewed as a stack of contexts. The + scope level is the number of elements on this stack. The stack + of contexts is simulated using trail (undo) stacks. + + \sa Pop + \sa PersistTerm + */ + void Push(); + + /** + \brief Backtrack. + + Restores the context from the top of the stack, and pops it off the + stack. Any changes to the logical context (by #AssertCnstr or + other functions) between the matching #Push and \c Pop + operators are flushed, and the context is completely restored to + what it was right before the #Push. + + \param num_scopes number of scopes to pop. Default value is 1. + + \sa Push + \sa PersistTerm + */ + void Pop(unsigned num_scopes); + + void Pop() { Pop(1); } + + unsigned GetNumScopes(); + + + /** + \brief Persist a term during num_scopes of pops. + + Normally, references to terms are no longer valid when + popping scopes beyond the level where the terms are created. + If you want to reference a term below the scope where it + was created, use this method to specify how many pops + the term should survive. + The current scope level is given as the current + total number of calls to push subtracted by the + total number of calls to pop. + If num_scopes is larger or equal to the current + scope level, then the term pointer persists throughout + the life-time of the context. + + Example usage: + + context.Push(); + context.Push(); + Term t = context.MkNumeral(1, context.MkIntSort()); + context.PersistTerm(t, 1); + context.Pop(); + // reference to t is valid. + context.Pop(); + // reference to t is not valid. + */ + void PersistTerm(TermPtr t, unsigned num_scopes); + + + /** + \brief Assert a constraing into the logical context. + + After one assertion, the logical context may become + inconsistent. + + The functions #Check or #CheckAndGetModel should be + used to check whether the logical context is consistent or not. + + \sa Check + \sa CheckAndGetModel + */ + void AssertCnstr(TermPtr a); + + /** + \brief Check whether the given logical context is consistent or not. + + If the logical context is not unsatisfiable (i.e., the return value is different from \c false) + and model construction is enabled (see #Config), then a model is stored in \c m. Otherwise, + the value \c null is stored in \c m. + The caller is responsible for deleting the model using its Dispose method. + + \remark Model construction must be enabled using configuration + parameters (See, #Config). + + \sa Check + */ + LBool CheckAndGetModel([Out] RawModel^% m); + + /** + \brief Check whether the given logical context is consistent or not. + + The function #CheckAndGetModel should be used when models are needed. + + */ + LBool Check(); + + /** + \brief Check whether the given logical context is consistent or + not with respect to auxiliary assumptions. + + If the logical context is not unsatisfiable (i.e., the return value is different from \c false) + and model construction is enabled (see #Config), then a model is stored in \c m. Otherwise, + the value \c null is stored in \c m. + The caller is responsible for deleting the model using its Dispose method. + If the logical context is unsatisfiable, then a proof object is return and stored + in \c proof. + An unsatisfiable core (subset) for the set of supplied assumptions is returned. + + \remark Model construction must be enabled using configuration + parameters (See, #Config). + + \param m returned model. + \param assumptions array of auxiliary assumptions. + \param proof proof object. Proofs must be enabled for this value to be returned. + \param core subset of assumptions that is an unsatisfiable core. + + \sa Check + */ + LBool CheckAssumptions([Out] RawModel^% m, + [In] array^ assumptions, + [Out] TermPtr% proof, + [Out] array^% core); + + /** + \brief Cancel the current search initiated using #Check, #CheckAndGetModel, or #CheckAssumptions. + + \sa Check + \sa CheckAndGetModel + \sa CheckAssumptions + */ + void SoftCheckCancel(); + + + + /** + \brief Retrieve congruence class representatives for terms. + + The function can be used for relying on Z3 to identify equal terms under the current + set of assumptions. The array of terms and array of class identifiers should have + the same length. The class identifiers are numerals that are assigned to the same + value for their corresponding terms if the current context forces the terms to be + equal. You cannot deduce that terms corresponding to different numerals must be different, + (especially when using non-convex theories). + Also note that not necessarily all implied equalities are returned by this call. + Only the set of implied equalities that follow from simple constraint and + equality propagation is discovered. + + A side-effect of the function is a satisfiability check. + The function return LBool.False if the current assertions are not satisfiable. + + \sa Check + */ + + LBool GetImpliedEqualities( + [In] array^ terms, + [Out] array^% class_ids + ); + + + /** + \brief Obtain explanation for search failure. + + \sa Check() + */ + SearchFailureExplanation GetSearchFailureExplanation(); + + + /** + \brief Return conjunction of literals and formulas assigned to true in the current state. + */ + TermPtr GetAssignments(); + + /** + \brief Retrieve set of labels set in current satisfying assignment. + */ + LabeledLiterals^ GetRelevantLabels(); + + /** + \brief Retrieve set of literals satisfying the current assignment. + */ + LabeledLiterals^ GetRelevantLiterals(); + + /** + \brief Retrieve set of guessed literals satisfying the current assignment. + */ + LabeledLiterals^ GetGuessedLiterals(); + + /** + \brief Block the combination of remaining non-disabled labels. + + Subsequent calls to Check will not contain satisfying assignments with the same + combination of labels. + */ + void BlockLiterals(LabeledLiterals^ labels); + + /** + \brief Obtain literal corresponding to index in list of literals. + */ + TermPtr GetLiteral(LabeledLiterals^ labels, unsigned idx) { + return labels->GetLiteral(idx); + } + + /** + \brief Interface to simplifier. + + Provides an interface to the AST simplifier used by Z3. + It allows clients to piggyback on top of the AST simplifier + for their own term manipulation. + */ + TermPtr Simplify(TermPtr a); + + + /*@}*/ + + /** + @name String conversion + */ + /*@{*/ + + + /** + \brief Select mode for the format used for pretty-printing AST nodes. + + The default mode for pretty printing AST nodes is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PrintMode.SmtlibFull. + To print shared common subexpressions only once, use the PrintMode.LowLevel + mode. + */ + + void SetPrintMode(PrintMode mode); + + /** + \brief Convert the given AST node into a string. + */ + String^ ToString(AstPtr a); + + void Display(System::IO::TextWriter^ w, AstPtr a); + + /** + \brief Convert the given logical context into a string. + + This function is mainly used for debugging purposes. It displays + the internal structure of a logical context. + */ + virtual String^ ToString() override; + + void Display(System::IO::TextWriter^ w); + + /** + \brief Convert the given logical context into a string. + + This function is mainly used for debugging purposes. It displays + the internal structure of a logical context. + */ + String^ StatisticsToString() { + return gcnew String(Z3_statistics_to_string(ctx())); + } + + void DisplayStatistics(System::IO::TextWriter^ w) { + w->Write(StatisticsToString()); + } + + /** + \brief Convert the given benchmark into SMT-LIB formatted string. + */ + String^ BenchmarkToSmtlib(String^ name, + String^ logic, + String^ status, + String^ attributes, + array^ assumptions, + TermPtr formula); + + /*@}*/ + + /** + @name Parser interface + */ + /*@{*/ + /** + \brief Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given types and declarations. + The symbols in the arrays \c type_names and \c decl_names don't need to match the names + of the types and declarations in the arrays \c types and \c decls. This is an useful feature + since we can use arbitrary names to reference types and declarations defined using the C API. + + The formulas, assumptions and declarations defined in \c str. + + \param string The string contianing the SMT-LIB benchmark + \param sorts List of auxiliary sorts used in SMT-LIB benchmark. + \param decls List of declarations to be used for parsing the SMT-LIB string. + \param assumptions Returned set of assumptions. + \param formulas Returned set of formulas. + \param new_decls Additional declarations from the SMT-LIB benchmark. + \param new_sorts Additional sorts fromt he SMT-LIB benchmark. + \param parser_out String containing error messages from parsing. + */ + void ParseSmtlibString( + String^ string, + [In] array^ sorts, + [In] array^ decls, + [Out] array^% assumptions, + [Out] array^% formulas, + [Out] array^% new_decls, + [Out] array^% new_sorts, + [Out] String^% parser_out + ); + + /** + \brief Similar to #ParseSmtlibString, but reads the benchmark from a file. + */ + void ParseSmtlibFile( + String^ file, + [In] array^ sorts, + [In] array^ decls, + [Out] array^% assumptions, + [Out] array^% formulas, + [Out] array^% new_decls, + [Out] array^% new_sorts, + [Out] String^% parser_out + ); + + + /** + \brief Parse a string in the native Z3 format. + + Return conjunction of Asserts occurring in the string. + */ + TermPtr ParseZ3String(String^ s); + + /** + \brief Parse a file containing formulas in Z3's native format. + + Return conjunction of Asserts occurring in the file. + */ + TermPtr ParseZ3File(String^ filename); + + /** + \brief Parse a string in the SMT-LIB2 format. + + Return conjunction of Asserts occurring in the string. + */ + TermPtr ParseSmtlib2String(String^ s, array^ sorts, array^ decls); + + /** + \brief Parse a file containing formulas in SMT-LIB2 format. + + Return conjunction of Asserts occurring in the file. + */ + TermPtr ParseSmtlib2File(String^ filename, array^ sorts, array^ decls); + + /** + \brief Execute commands from a string in the SMT-LIB2 format. + + Return conjunction of Asserts modulo push/pop. + */ + TermPtr ExecSmtlib2String(String^ s, array^ sorts, array^ decls); + + /** + \brief Execute commands from a file containing formulas in SMT-LIB2 format. + + Return conjunction of Asserts modulo push/pop. + */ + TermPtr ExecSmtlib2File(String^ filename, array^ sorts, array^ decls); + /*@}*/ + + /** + @name Errors + */ + /*{@*/ + + /** + \brief Register a Z3 error handler. + + A call to a Z3 function throw Z3Error when + it is not used correctly. An error handler can be registered + and will be called in this case prior to throwing Z3Error. + */ + static void SetErrorHandler(IErrorHandler^ h); + + /** + \brief Return a string describing the given error code. + */ + static String^ GetErrorMessage(ErrorCode err); + + /** + \brief Free all resources allocated for Z3. + */ + static void ResetMemory(); + + /*@}*/ + + + /** + @name Miscellaneous + */ + /*@{*/ + + /** + \brief Return Z3 version number information. + */ + void GetVersion( + [Out] unsigned % major, + [Out] unsigned % minor, + [Out] unsigned % build_number, + [Out] unsigned % revision_number); + /*@}*/ + + + /** + \brief Create user theory. + */ + + RawTheory^ MkTheory(String^ name); + + internal: + static Dictionary^ contexts; + + public: + + /** + \brief Register fixed-point rules. + */ + + void RegisterRelation(FuncDeclPtr relation); + + void AddRule(TermPtr rule, Symbol^ name); + + /** + \brief post a query. + The return value is LBool.True if the query is satisfiabl,e + it is LBool.False if it is not satisfiabled, and Undef on + timeouts or approximation. + */ + LBool Query(TermPtr query); + + /** + \brief retrieve details on the search satus. + */ + String^ GetQueryStatus(); + + /** + \brief retrieve formula that satisfies the previous query, + assuming the return value was LBool.True + */ + TermPtr GetQueryAnswer(); + + String^ FixedpointToString(array^ queries); + + array^ SimplifyFixedpointRules(array^ rules, array^ output_predicates); + + // functions for creating custom Fixedpoint relations. + internal: + static void fixedpoint_assign_callback(void*, Z3_func_decl, unsigned, Z3_ast const[], unsigned, Z3_ast const[]); + static void fixedpoint_apply_callback(void*, Z3_func_decl, unsigned, Z3_ast const[], Z3_ast*); + IntPtr m_fixedpoint_gch; + private: + Action3^, array^>^ m_fixedpoint_assign; + Func2^, TermPtr>^ m_fixedpoint_apply; + void init_fixedpoint_callbacks(); + public: + property Action3^, array^>^ FixedpointAssign { + void set(Action3^, array^>^ value) { + m_fixedpoint_assign = value; + init_fixedpoint_callbacks(); + } + } + property Func2^, TermPtr>^ FixedpointApply { + void set(Func2^, TermPtr>^ value) { + m_fixedpoint_apply = value; + init_fixedpoint_callbacks(); + } + } + + }; + + public ref class RawTheory { + typedef GCHandle GCHandle; + typedef GCHandleType GCHandleType; + private: + Z3_theory m_theory; + ref_context& m_context; + String^ m_name; + static Dictionary^ theories; + protected: + !RawTheory() {} + public: + property String^ Name { String^ get() { return m_name; } } + internal: + RawTheory(ref_context& ctx, String^ name); + ~RawTheory(); + + static RawTheory^ GetTheory(Z3_theory th) { + Z3_theory_data td = Z3_theory_get_ext_data(th); + return theories[GCHandle::FromIntPtr(IntPtr(td))]; + } + + + // Delete Handler + private: + Action0^ delete_handler; + internal: + static void static_delete_callback(Z3_theory th); + + public: + property Action0^ DeleteHandler + { + void set(Action0^ value) + { + delete_handler = value; + } + } + + // ReduceEq + internal: + static Z3_bool reduce_eq_callback(Z3_theory th, Z3_ast a, Z3_ast b, Z3_ast* r); + private: + Func2^ reduce_eq; + void set_reduce_eq(Func2^ value); + public: + property Func2^ ReduceEq { + void set(Func2^ value) { + set_reduce_eq(value); + } + } + + + // ReduceApp + private: + Func2^, TermPtr>^ reduce_app; + void set_reduce_app(Func2^, TermPtr>^ value); + public: + property Func2^, TermPtr>^ ReduceApp { + void set(Func2^, TermPtr>^ value) { + set_reduce_app(value); + } + } + internal: + static Z3_bool reduce_app_callback(Z3_theory th, Z3_func_decl f, unsigned num_args, Z3_ast const args[], Z3_ast* r); + + // Reduce distinct + private: + Func1^, TermPtr>^ reduce_distinct; + void set_reduce_distinct(Func1^, TermPtr>^ value); + internal: + static Z3_bool reduce_distinct_callback(Z3_theory th, unsigned n, Z3_ast const args[], Z3_ast* r); + public: + property Func1^, TermPtr>^ ReduceDistinct { + void set(Func1^, TermPtr>^ value) { + set_reduce_distinct(value); + } + } + + // NewRelevant + internal: + Action^ new_relevant; + private: + void set_new_relevant(Action^ value); + public: + property Action^ NewRelevant { + void set(Action^ value) { + set_new_relevant(value); + } + } + + // NewApp + private: + void set_new_app(Action^ value); + internal: + Action^ new_app; + public: + property Action^ NewApp { + void set(Action^ value) { + set_new_app(value); + } + } + + // NewElem + private: + void set_new_elem(Action^ value); + internal: + Action^ new_elem; + public: + property Action^ NewElem { + void set(Action^ value) { + set_new_elem(value); + } + } + + // InitSearch + private: + void set_init_search(Action0^ value); + internal: + Action0^ init_search; + public: + property Action0^ InitSearch { + void set(Action0^ value) { set_init_search(value); } + } + + // Push + private: + void set_push(Action0^ value); + internal: + Action0^ push; + public: + property Action0^ Push { + void set(Action0^ value) { set_push(value); } + } + + // Pop + private: + void set_pop(Action0^ value); + internal: + Action0^ pop; + public: + property Action0^ Pop { + void set(Action0^ value) { set_pop(value); } + } + + // Restart + private: + void set_restart(Action0^ value); + internal: + Action0^ restart; + public: + property Action0^ Restart { + void set(Action0^ value) { set_restart(value); } + } + + // Reset + private: + void set_reset(Action0^ value); + internal: + Action0^ reset; + public: + property Action0^ Reset { + void set(Action0^ value) { set_reset(value); } + } + + + // FinalCheck + private: + void set_final_check(Func0^ value); + internal: + Func0^ final_check; + public: + property Func0^ FinalCheck { + void set(Func0^ value) { set_final_check(value); } + } + + + // NewEq + private: + void set_new_eq(Action2^ value); + internal: + Action2^ new_eq; + public: + property Action2^ NewEq + { + void set(Action2^ value) { set_new_eq(value); } + } + + + // NewDiseq + private: + void set_new_diseq(Action2^ value); + internal: + Action2^ new_diseq; + public: + property Action2^ NewDiseq + { + void set(Action2^ value) { set_new_diseq(value); } + } + + // NewAssignment + internal: + Action2^ new_assignment; + private: + void set_new_assignment(Action2^ value); + public: + property Action2^ NewAssignment { + void set(Action2^ value) { + set_new_assignment(value); + } + } + + void AssertTheoryAxiom(TermPtr ax) + { + Z3_theory_assert_axiom(m_theory, get_ast(ax)); + } + + void AssumeEq(TermPtr lhs, TermPtr rhs) + { + Z3_theory_assume_eq(m_theory, get_ast(lhs), get_ast(rhs)); + } + + void EnableTheoryAxiomSimplification(bool flag) + { + Z3_theory_enable_axiom_simplification(m_theory, flag); + } + + TermPtr GetEqcRoot(TermPtr n) + { + return TermPtr(Z3_theory_get_eqc_root(m_theory, get_ast(n))); + } + + TermPtr GetEqcNext(TermPtr n) + { + return TermPtr(Z3_theory_get_eqc_next(m_theory, get_ast(n))); + } + + + array^ GetParents(TermPtr n) { + unsigned np = Z3_theory_get_num_parents(m_theory, get_ast(n)); + array^ result = gcnew array(np); + for (unsigned i = 0; i < np; ++i) + { + result[i] = TermPtr(Z3_theory_get_parent(m_theory, get_ast(n), i)); + } + return result; + } + + bool IsTheoryValue(TermPtr a) + { + return 0 != Z3_theory_is_value(m_theory, get_ast(a)); + } + + bool IsTheoryDecl(FuncDeclPtr d) + { + return 0 != Z3_theory_is_decl(m_theory, get_func_decl(d)); + } + + array^ GetElems() + { + unsigned n = Z3_theory_get_num_elems(m_theory); + array^ result = gcnew array(n); + for (unsigned i = 0; i < n; ++i) + { + result[i] = TermPtr(Z3_theory_get_elem(m_theory, i)); + } + return result; + } + + array^ GetApps() + { + unsigned n = Z3_theory_get_num_apps(m_theory); + array^ result = gcnew array(n); + for (unsigned i = 0; i < n; ++i) + { + result[i] = TermPtr(Z3_theory_get_app(m_theory, i)); + } + return result; + } + + SortPtr MkSort(Symbol^ s) + { + return SortPtr(Z3_theory_mk_sort(m_context(), m_theory, s->get())); + } + + TermPtr MkValue(Symbol^ s, SortPtr srt) + { + return TermPtr(Z3_theory_mk_value(m_context(), m_theory, s->get(), get_sort(srt))); + } + + TermPtr MkConstant(Symbol^ s, SortPtr srt) + { + return TermPtr(Z3_theory_mk_constant(m_context(), m_theory, s->get(), get_sort(srt))); + } + + FuncDeclPtr MkFuncDecl(Symbol^ n, array^ domain, SortPtr range); + + SortPtr MkSort(String^ s); + + TermPtr MkValue(String^ s, SortPtr srt); + + TermPtr MkConstant(String^ s, SortPtr srt); + + FuncDeclPtr MkFuncDecl(String^ n, array^ domain, SortPtr range); + + }; + + + ref class Context; + ref class Model; + ref class Theory; + + public ref class Ast : public System::IComparable { + protected: + AstPtr m_ast; + RawContext^ m_ctx; + !Ast(); + internal: + Ast(RawContext^ c, AstPtr a); + AstPtr GetPtr() { return m_ast; } + AstPtr operator()() { return m_ast; } + public: + ~Ast(); + + /** + \brief Test equality of asts. + */ + virtual bool Equals(Object^ obj) override; + + /** + \brief Obtain hash code. + */ + virtual int GetHashCode() override; + + /** + \brief Pretty print term, sort or declaration. + */ + virtual String^ ToString() override; + + /** + \brief Implement IComparable::CompareTo + */ + virtual int CompareTo(Object^ other); + + /** + \brief overload ==, != + */ + // virtual bool operator==(Object^ other); + + // virtual bool operator!=(Object^ other); + + virtual unsigned GetId() { return m_ctx->GetTermId(m_ast); } + }; + + public ref class Sort : public Ast{ + internal: + Sort(RawContext^ c, SortPtr a) : Ast(c,a) {} + public: + String^ GetName(); + virtual unsigned GetId() override { return m_ctx->GetSortId(m_ast); } + }; + + public ref class FuncDecl : public Ast { + internal: + FuncDecl(RawContext^ c, FuncDeclPtr a) : Ast(c,a) {} + public: + String^ GetDeclName(); + DeclKind GetKind(); + virtual unsigned GetId() override { return m_ctx->GetFuncDeclId(m_ast); } + }; + + public ref class Term : public Ast { + internal: + Term(RawContext^ c, TermPtr a) : Ast(c,a) {} + public: + /** + \brief Overloading of Boolean operators. + + \pre Argument type is Boolean. + */ + static Term^ operator!(Term^ t1); + static Term^ operator&(Term^ t1, Term^ t2); + static Term^ operator|(Term^ t1, Term^ t2); + static Term^ operator^(Term^ t1, Term^ t2); + /** + \brief Overloading of common arithmetical operators. + + \pre Argument types are integers or reals. + */ + static Term^ operator+(Term^ t1, Term^ t2); + static Term^ operator*(Term^ t1, Term^ t2); + static Term^ operator/(Term^ t1, Term^ t2); + static Term^ operator-(Term^ t1, Term^ t2); + static Term^ operator>(Term^ t1, Term^ t2); + static Term^ operator<(Term^ t1, Term^ t2); + static Term^ operator>=(Term^ t1, Term^ t2); + static Term^ operator<=(Term^ t1, Term^ t2); + + /** + \brief Overloading of array select. + + \pre Argument is an index, the main term is of array type. + */ + Term^ operator[](Term^ index); + + TermKind GetKind(); + FuncDecl^ GetAppDecl(); + array^ GetAppArgs(); + Sort^ GetSort(); + String^ GetNumeralString(); + unsigned GetVarIndex(); + ref class Quantifier^ GetQuantifier(); + }; + + public ref class Pattern : public Ast { + internal: + Pattern(RawContext^ c, PatternPtr a) : Ast(c,a) {} + }; + + public ref class Quantifier { + public: + bool IsForall; + unsigned Weight; + array^ Patterns; + array^ NoPatterns; + array^ Sorts; + array^ Names; + Term^ Body; + }; + + public ref class ArrayValue { + public: + array^ Domain; + array^ Range; + Term^ ElseCase; + }; + + public ref class TermParameter : public IParameter { + Term^ m_value; + internal: + TermParameter(Term^ t) : m_value(t) {} + public: + virtual String^ ToString() override { return m_value->ToString(); } + property Term^ GetTerm { Term^ get() { return m_value; } } + }; + + public ref class SortParameter : public IParameter { + Sort^ m_value; + internal: + SortParameter(Sort^ s): m_value(s) {} + public: + property Sort^ GetSort { Sort^ get() { return m_value; } } + virtual String^ ToString() override { return m_value->ToString(); } + }; + + public ref class FuncDeclParameter : public IParameter { + FuncDecl^ m_value; + internal: + FuncDeclParameter(FuncDecl^ d): m_value(d) {} + public: + property FuncDecl^ GetFuncDecl { FuncDecl^ get() { return m_value; } } + virtual String^ ToString() override { return m_value->ToString(); } + }; + + /** + \brief Term and optional proof object returned by user-simplifier + */ + public ref class TermProof { + Term^ m_term; + Term^ m_proof; // proof is optional, use null for absence of proofs. + public: + TermProof(Term^ term, Term^ proof): m_term(term), m_proof(proof) {} + property Term^ GetTerm { Term^ get() { return m_term; } } + property Term^ Proof { Term^ get() { return m_proof; } } + }; + + /** + \brief Type safe contexts. + */ + public ref class Context { + + /// @cond 0 + RawContext^ m_ctx; + + + public: + template + array^ CopyArray(array^ a) { + if (!a) { + return gcnew array(0); + } + int len = a->Length; + array^ result = gcnew array(len); + for (int i = 0; i < len; ++i) { + if (a[i]) { + result[i] = a[i](); + } + else { + result[i] = IntPtr(0); + } + } + return result; + } + + array^ CopyArray(array^ a) { + return CopyArray(a); + } + + array^ CopyArray(array^ a) { + return CopyArray(a); + } + + array^ CopyArray(array^ a) { + return CopyArray(a); + } + + array^ CopyArray(array^ a) { + return CopyArray(a); + } + internal: + + template + static array^ CopyAstArray(RawContext^ ctx, array^ a) { + if (!a) return nullptr; + int len = a->Length; + array^ result = gcnew array(len); + + for (int i = 0; i < len; ++i) { + if (a[i] != IntPtr(0)) { + result[i] = gcnew T(ctx,a[i]); + } + else { + result[i] = nullptr; + } + } + return result; + } + + public: + template + array^ CopyAstArray(array^ a) { + return CopyAstArray(m_ctx, a); + } + + + array^ CopySortArray(array^ a) { + return CopyAstArray(a); + } + + array^ CopyTermArray(array^ a) { + return CopyAstArray(a); + } + + array^ CopyFuncDeclArray(array^ a) { + return CopyAstArray(a); + } + internal: + static array^ CopyTermArray(RawContext^ ctx, array^ a) { + return CopyAstArray(ctx, a); + } + + static array^ CopySortArray(RawContext^ ctx, array^ a) { + return CopyAstArray(ctx, a); + } + static Quantifier^ GetQuantifier(RawContext^ ctx, Term^ term); + + internal: + property RawContext^ GetContext { RawContext^ get() { return m_ctx; } } + + /// @endcond + + + public: + /** + \brief Create a type safe version of a context. + + Terms and models created using the type safe context are wrapped within + objects. The object wrappers prevent confusing the \ccode{IntPtr} type used for + terms, sorts and values with arbitrary instances. + + Each method in #Context is paired with a corresponding method in Context. + + \sa Context. + */ + + Context() { m_ctx = gcnew RawContext(); } + + Context(Config^ config) : m_ctx(gcnew RawContext(config)) {} + + Context(Config^ config, ReferenceCounted^ rc) : m_ctx(gcnew RawContext(config, rc)) {} + + /** + \brief Set the context from an externally created context. + */ + void SetContext(Z3_context ctx){ m_ctx->SetContext(ctx); } + + /** + \brief Dispose method for type safe contexts. + */ + ~Context() { m_ctx->Reset(); } + + /** + \brief Enable low-level debug tracing. + + This method only works with debug builds. + */ + + void EnableDebugTrace(String^ tag) { m_ctx->EnableDebugTrace(tag); } + + /** + \brief Enable or disable warning messages sent to the console out/error. + + Warnings are printed after passing \c true, warning messages are + suppressed after calling this method with \c false. + */ + + void ToggleWarningMessages(bool enabled) { m_ctx->ToggleWarningMessages(enabled); } + + void UpdateParamValue(String^ param_id, String^ value) { m_ctx->UpdateParamValue(param_id, value); } + + String^ GetParamValue(String^ param_id) { + return m_ctx->GetParamValue(param_id); + } + + /** + \brief Configure the SMTLIB logic to be used in the given logical context. + */ + + bool SetLogic(String^ logic) { return m_ctx->SetLogic(logic); } + + /** + @name Symbols + */ + /*@{*/ + Symbol^ MkSymbol(int i) { return m_ctx->MkSymbol(i); } + + Symbol^ MkSymbol(String^ s) { return m_ctx->MkSymbol(s); } + /*@}*/ + + /** + @name Modifiers + */ + /*@{*/ + + /** + \brief Update the arguments of a term or quantifier. + \pre The number of arguments passed in new_args should + be the same as number of arguments to the term t. + */ + Term^ UpdateTerm(Term^ t, array^ new_args) { + return gcnew Term(m_ctx, m_ctx->UpdateTerm(t(), CopyArray(new_args))); + } + + /*@}*/ + + /** + @name Constraints + */ + /*@{*/ + void Push() { m_ctx->Push(); } + void Pop(unsigned num_scopes) { m_ctx->Pop(num_scopes); } + void Pop() { Pop(1); } + unsigned GetNumScopes() { return m_ctx->GetNumScopes(); } + void PersistTerm(Term^ t, unsigned num_scopes) { + m_ctx->PersistTerm(t(), num_scopes); + } + LBool Check() { return m_ctx->Check(); } + LBool CheckAndGetModel([Out] Model^% m); + LBool CheckAssumptions([Out] Model^% m, + [In] array^ assumptions, + [Out] Term^% proof, + [Out] array^% core); + void SoftCheckCancel(); + + LBool GetImpliedEqualities( + [In] array^ terms, + [Out] array^% class_ids); + + SearchFailureExplanation GetSearchFailureExplanation() { return m_ctx->GetSearchFailureExplanation(); } + LabeledLiterals^ GetRelevantLabels() { return m_ctx->GetRelevantLabels(); } + LabeledLiterals^ GetRelevantLiterals() { return m_ctx->GetRelevantLiterals(); } + LabeledLiterals^ GetGuessedLiterals() { return m_ctx->GetGuessedLiterals(); } + void BlockLiterals(LabeledLiterals^ lbls) { m_ctx->BlockLiterals(lbls); } + Term^ GetLiteral(LabeledLiterals^ lbls, unsigned idx) { return gcnew Term(m_ctx, m_ctx->GetLiteral(lbls, idx)); } + Term^ Simplify(Term^ a) { return gcnew Term(m_ctx,m_ctx->Simplify(a())); } + void AssertCnstr(Term^ a) { m_ctx->AssertCnstr(a()); } + /*@}*/ + + virtual String^ ToString() override { return m_ctx->ToString(); } + + void Display(System::IO::TextWriter^ w) { m_ctx->Display(w); } + Term^ GetAssignments() { return gcnew Term(m_ctx, m_ctx->GetAssignments()); } + String^ StatisticsToString() { return m_ctx->StatisticsToString(); } + void DisplayStatistics(System::IO::TextWriter^ w) { m_ctx->DisplayStatistics(w); } + + /** + \brief Convert the given benchmark into SMT-LIB formatted string. + */ + String^ BenchmarkToSmtlib(String^ name, + String^ logic, + String^ status, + String^ attributes, + array^ assumptions, + Term^ formula); + + void ParseSmtlibString( + String^ string, + [In] array^ sorts, + [In] array^ decls, + [Out] array^% assumptions, + [Out] array^% formulas, + [Out] array^% new_decls, + [Out] array^% new_sorts, + [Out] String^% parser_out + ); + + + void ParseSmtlibFile( + String^ file, + [In] array^ sorts, + [In] array^ decls, + [Out] array^% assumptions, + [Out] array^% formulas, + [Out] array^% new_decls, + [Out] array^% new_sorts, + [Out] String^% parser_out + ); + + + Term^ ParseZ3String(String^ s) { + return gcnew Term(m_ctx,m_ctx->ParseZ3String(s)); + } + + Term^ ParseZ3File(String^ s) { + return gcnew Term(m_ctx,m_ctx->ParseZ3File(s)); + } + + Term^ ParseSmtlib2String(String^ s, array^ sorts, array^ decls) { + return gcnew Term(m_ctx,m_ctx->ParseSmtlib2String(s, CopyArray(sorts), CopyArray(decls))); + } + + Term^ ParseSmtlib2File(String^ s, array^ sorts, array^ decls) { + return gcnew Term(m_ctx,m_ctx->ParseSmtlib2File(s, CopyArray(sorts), CopyArray(decls))); + } + + Term^ ExecSmtlib2String(String^ s, array^ sorts, array^ decls) { + return gcnew Term(m_ctx,m_ctx->ExecSmtlib2String(s, CopyArray(sorts), CopyArray(decls))); + } + + Term^ ExecSmtlib2File(String^ s, array^ sorts, array^ decls) { + return gcnew Term(m_ctx,m_ctx->ExecSmtlib2File(s, CopyArray(sorts), CopyArray(decls))); + } + + static void SetErrorHandler(IErrorHandler^ h) { + RawContext::SetErrorHandler(h); + } + + static String^ GetErrorMessage(ErrorCode err) { + return RawContext::GetErrorMessage(err); + } + + static void ResetMemory() { + RawContext::ResetMemory(); + } + + + void SetPrintMode(PrintMode mode) { m_ctx->SetPrintMode(mode); } + + String^ ToString(Ast^ a) { return m_ctx->ToString(a()); } + + void Display(System::IO::TextWriter^ w, Ast^ a) { m_ctx->Display(w, a()); } + + + Sort^ MkIntSort() { return gcnew Sort(m_ctx,m_ctx->MkIntSort()); } + Sort^ MkBoolSort() { return gcnew Sort(m_ctx,m_ctx->MkBoolSort()); } + Sort^ MkSort(Symbol^ s) { return gcnew Sort(m_ctx,m_ctx->MkSort(s)); } + Sort^ MkSort(String^ s) { return gcnew Sort(m_ctx,m_ctx->MkSort(s)); } + Sort^ MkSort(int i) { return gcnew Sort(m_ctx,m_ctx->MkSort(i)); } + Sort^ MkFiniteDomainSort(String^ s, unsigned __int64 domain_size) { return gcnew Sort(m_ctx, m_ctx->MkFiniteDomainSort(s, domain_size)); } + Sort^ MkRealSort() { return gcnew Sort(m_ctx,m_ctx->MkRealSort()); } + Sort^ MkBvSort(unsigned sz) { return gcnew Sort(m_ctx,m_ctx->MkBvSort(sz)); } + Sort^ MkArraySort(Sort^ domain, Sort^ range) { return gcnew Sort(m_ctx,m_ctx->MkArraySort(domain(), range())); } + + Sort^ MkTupleSort( + Symbol^ mk_tuple_name, + array^ field_names, + array^ field_types, + [Out] FuncDecl^% mk_tuple_decl, + [In, Out] array^ proj_decl + ); + + Sort^ MkTupleSort( + String^ mk_tuple_name, + array^ field_names, + array^ field_types, + [Out] FuncDecl^% mk_tuple_decl, + [In, Out] array^ proj_decl + ); + + Sort^ MkEnumerationSort( + String^ name, + array^ enum_names, + array^ enum_consts, + array^ enum_testers); + + Sort^ MkListSort( + String^ name, + Sort^ elem_sort, + [Out] FuncDecl^% nil_decl, + [Out] FuncDecl^% is_nil_decl, + [Out] FuncDecl^% cons_decl, + [Out] FuncDecl^% is_cons_decl, + [Out] FuncDecl^% head_decl, + [Out] FuncDecl^% tail_decl + ); + + Constructor^ MkConstructor( + String^ name, + String^ tester, + array^ field_names, + array^ field_sorts, + array^ field_refs + ); + + + FuncDecl^ GetConstructor(Constructor^ c); + + FuncDecl^ GetTester(Constructor^ c); + + array^ GetAccessors(Constructor^ c); + + /** + \brief create datatype sort. + */ + + Sort^ MkDataType( + String^ name, + array^ constructors + ) { + return gcnew Sort(m_ctx, m_ctx->MkDataType(name, constructors)); + } + + /** + \brief create datatype sort. + */ + + array^ MkDataTypes( + array^ names, + array^>^ constructors + ) { + return CopySortArray(m_ctx->MkDataTypes(names, constructors)); + } + + + FuncDecl^ MkFuncDecl(Symbol^ s, array^ domain, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkFuncDecl(s, CopyArray(domain), range())); + } + + FuncDecl^ MkFuncDecl(String^ s, array^ domain, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkFuncDecl(s, CopyArray(domain), range())); + } + + FuncDecl^ MkConstDecl(Symbol^ s, Sort^ ty) { + return MkFuncDecl(s, gcnew array(0), ty); + } + FuncDecl^ MkFuncDecl(Symbol^ s, Sort^ domain, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkFuncDecl(s, domain(), range())); + } + FuncDecl^ MkFuncDecl(Symbol^ s, Sort^ d1, Sort^ d2, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkFuncDecl(s, d1(), d2(), range())); + } + FuncDecl^ MkConstDecl(String^ s, Sort^ ty) { + return MkFuncDecl(s, gcnew array(0), ty); + } + FuncDecl^ MkFuncDecl(String^ s, Sort^ domain, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkFuncDecl(s, domain(), range())); + } + FuncDecl^ MkFuncDecl(String^ s, Sort^ d1, Sort^ d2, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkFuncDecl(s, d1(), d2(), range())); + } + Term^ MkApp(FuncDecl^ d, array^ args) { + return gcnew Term(m_ctx,m_ctx->MkApp(d(), CopyArray(args))); + } + Term^ MkApp(FuncDecl^ d, Term^ arg) { + return gcnew Term(m_ctx,m_ctx->MkApp(d(), arg())); + } + Term^ MkApp(FuncDecl^ d, Term^ arg1, Term^ arg2) { + return gcnew Term(m_ctx,m_ctx->MkApp(d(), arg1(), arg2())); + } + Term^ MkApp(FuncDecl^ d, Term^ arg1, Term^ arg2, Term^ arg3) { + return gcnew Term(m_ctx,m_ctx->MkApp(d(), arg1(), arg2(), arg3())); + } + Term^ MkConst(FuncDecl^ d) { + return gcnew Term(m_ctx,m_ctx->MkConst(d())); + } + Term^ MkConst(String^ s, Sort^ ty) { + return gcnew Term(m_ctx,m_ctx->MkConst(s,ty())); + } + Term^ MkConst(Symbol^ s, Sort^ ty) { + return gcnew Term(m_ctx,m_ctx->MkConst(s, ty())); + } + FuncDecl^ MkFreshFuncDecl(String^ prefix, array^ domain, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkFreshFuncDecl(prefix, CopyArray(domain), range())); + } + Term^ MkFreshConst(String^ prefix, Sort^ ty) { + return gcnew Term(m_ctx,m_ctx->MkFreshConst(prefix, ty())); + } + Term^ MkTrue() { return gcnew Term(m_ctx,m_ctx->MkTrue()); } + Term^ MkFalse() { return gcnew Term(m_ctx,m_ctx->MkFalse()); } + Term^ MkLabel(Symbol^ name, bool pos, Term^ fml) { return gcnew Term(m_ctx,m_ctx->MkLabel(name, pos, fml())); } + + Term^ MkEq(Term^ l, Term^ r) { return gcnew Term(m_ctx,m_ctx->MkEq(l(), r())); } + Term^ MkDistinct(array^ args) { + return gcnew Term(m_ctx,m_ctx->MkDistinct(CopyArray(args))); + } + Term^ MkNot(Term^ arg) { return gcnew Term(m_ctx,m_ctx->MkNot(arg())); } + Term^ MkIte(Term^ t1, Term^ t2, Term^ t3) { + return gcnew Term(m_ctx,m_ctx->MkIte(t1(), t2(), t3())); + } + Term^ MkIff(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkIff(t1(), t2())); } + Term^ MkImplies(Term^ t1, Term^ t2) {return gcnew Term(m_ctx,m_ctx->MkImplies(t1(), t2()));} + Term^ MkXor(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkXor(t1(), t2())); } + Term^ MkAnd(array^ args) { return gcnew Term(m_ctx,m_ctx->MkAnd(CopyArray(args))); } + Term^ MkAnd(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkAnd(t1(), t2())); } + Term^ MkOr(array^ args) { return gcnew Term(m_ctx,m_ctx->MkOr(CopyArray(args))); } + Term^ MkOr(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkOr(t1(), t2())); } + Term^ MkAdd(array^ args) { return gcnew Term(m_ctx,m_ctx->MkAdd(CopyArray(args))); } + Term^ MkAdd(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkAdd(t1(), t2())); } + Term^ MkMul(array^ args) { return gcnew Term(m_ctx,m_ctx->MkMul(CopyArray(args))); } + Term^ MkMul(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkMul(t1(), t2())); } + Term^ MkSub(array^ args) { return gcnew Term(m_ctx,m_ctx->MkSub(CopyArray(args))); } + Term^ MkSub(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkSub(t1(), t2())); } + Term^ MkUnaryMinus(Term^ arg) { return gcnew Term(m_ctx,m_ctx->MkUnaryMinus(arg())); } + Term^ MkDiv(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkDiv(t1(), t2())); } + Term^ MkMod(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkMod(t1(), t2())); } + Term^ MkRem(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkRem(t1(), t2())); } + Term^ MkToReal(Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkToReal(t1())); } + Term^ MkToInt(Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkToInt(t1())); } + Term^ MkIsInt(Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkIsInt(t1())); } + Term^ MkLt(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkLt(t1(), t2())); } + Term^ MkLe(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkLe(t1(), t2())); } + Term^ MkGt(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkGt(t1(), t2())); } + Term^ MkGe(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkGe(t1(), t2())); } + Term^ MkBvNot(Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkBvNot(t1())); } + Term^ MkBvReduceAnd(Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkBvReduceAnd(t1())); } + Term^ MkBvRedcueOr(Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkBvReduceOr(t1())); } + Term^ MkBvAnd(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvAnd(t1(), t2())); } + Term^ MkBvOr(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvOr(t1(), t2())); } + Term^ MkBvXor(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvXor(t1(), t2())); } + Term^ MkBvNand(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvNand(t1(), t2())); } + Term^ MkBvNor(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvNor(t1(), t2())); } + Term^ MkBvXnor(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvXnor(t1(), t2())); } + Term^ MkBvNeg(Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkBvNeg(t1())); } + Term^ MkBvAdd(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvAdd(t1(), t2())); } + Term^ MkBvSub(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvSub(t1(), t2())); } + Term^ MkBvMul(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvMul(t1(), t2())); } + Term^ MkBvUdiv(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvUdiv(t1(), t2())); } + Term^ MkBvSdiv(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvSdiv(t1(), t2())); } + Term^ MkBvUrem(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvUrem(t1(), t2())); } + Term^ MkBvSrem(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvSrem(t1(), t2())); } + Term^ MkBvSmod(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvSmod(t1(), t2())); } + Term^ MkBvUlt(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvUlt(t1(), t2())); } + Term^ MkBvSlt(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvSlt(t1(), t2())); } + Term^ MkBvUle(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvUle(t1(), t2())); } + Term^ MkBvSle(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvSle(t1(), t2())); } + Term^ MkBvUge(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvUge(t1(), t2())); } + Term^ MkBvSge(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvSge(t1(), t2())); } + Term^ MkBvUgt(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvUgt(t1(), t2())); } + Term^ MkBvSgt(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvSgt(t1(), t2())); } + Term^ MkBvConcat(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvConcat(t1(), t2())); } + Term^ MkBvExtract(unsigned high, unsigned low, Term^ t) { + return gcnew Term(m_ctx,m_ctx->MkBvExtract(high, low, t())); + } + Term^ MkBvSignExt(unsigned i, Term^ t) { + return gcnew Term(m_ctx,m_ctx->MkBvSignExt(i, t())); + } + Term^ MkBvZeroExt(unsigned i, Term^ t) { + return gcnew Term(m_ctx,m_ctx->MkBvZeroExt(i, t())); + } + Term^ MkBvRepeat(unsigned i, Term^ t) { + return gcnew Term(m_ctx,m_ctx->MkBvRepeat(i, t())); + } + Term^ MkBvShl(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvShl(t1(), t2())); } + Term^ MkBvLshr(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvLshr(t1(), t2())); } + Term^ MkBvAshr(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvAshr(t1(), t2())); } + Term^ MkBvRotateLeft(unsigned i, Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkBvRotateLeft(i,t1())); } + Term^ MkBvRotateRight(unsigned i, Term^ t1) { return gcnew Term(m_ctx,m_ctx->MkBvRotateRight(i,t1())); } + Term^ MkBvRotateLeft(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvRotateLeft(t1(), t2())); } + Term^ MkBvRotateRight(Term^ t1, Term^ t2) { return gcnew Term(m_ctx,m_ctx->MkBvRotateRight(t1(), t2())); } + Term^ MkBv2Int(Term^ t1, bool is_signed) { return gcnew Term(m_ctx, m_ctx->MkBv2Int(t1(), is_signed)); } + Term^ MkInt2Bv(unsigned n, Term^ t1) { return gcnew Term(m_ctx, m_ctx->MkInt2Bv(n, t1())); } + Term^ MkBvAddNoOverflow(Term^ t1, Term^ t2, bool is_signed) { + return gcnew Term(m_ctx,m_ctx->MkBvAddNoOverflow(t1(), t2(), is_signed)); + } + Term^ MkBvAddNoUnderflow(Term^ t1, Term^ t2) { + return gcnew Term(m_ctx,m_ctx->MkBvAddNoUnderflow(t1(), t2())); + } + Term^ MkBvSubNoOverflow(Term^ t1, Term^ t2) { + return gcnew Term(m_ctx,m_ctx->MkBvSubNoOverflow(t1(), t2())); + } + Term^ MkBvSubNoUnderflow(Term^ t1, Term^ t2, bool is_signed) { + return gcnew Term(m_ctx,m_ctx->MkBvSubNoUnderflow(t1(), t2(), is_signed)); + } + Term^ MkBvSDivNoOverflow(Term^ t1, Term^ t2) { + return gcnew Term(m_ctx,m_ctx->MkBvSDivNoOverflow(t1(), t2())); + } + Term^ MkBvNegNoOverflow(Term^ t1) { + return gcnew Term(m_ctx,m_ctx->MkBvNegNoOverflow(t1())); + } + Term^ MkBvMulNoOverflow(Term^ t1, Term^ t2, bool is_signed) { + return gcnew Term(m_ctx,m_ctx->MkBvMulNoOverflow(t1(), t2(), is_signed)); + } + Term^ MkBvMulNoUnderflow(Term^ t1, Term^ t2) { + return gcnew Term(m_ctx,m_ctx->MkBvMulNoUnderflow(t1(), t2())); + } + Term^ MkArraySelect(Term^ a, Term^ i) { return gcnew Term(m_ctx,m_ctx->MkArraySelect(a(), i())); } + Term^ MkArrayStore(Term^ a, Term^ i, Term^ v) { + return gcnew Term(m_ctx,m_ctx->MkArrayStore(a(), i(), v())); + } + Term^ MkArrayMap(FuncDecl^ f, array^ args) { + return gcnew Term(m_ctx, m_ctx->MkArrayMap(f(), CopyArray(args))); + } + Term^ MkArrayConst(Sort^ domain, Term^ v) { return gcnew Term(m_ctx,m_ctx->MkArrayConst(domain(), v())); } + Term^ MkArrayDefault(Term^ a) { return gcnew Term(m_ctx,m_ctx->MkArrayDefault(a())); } + Sort^ MkSetSort(Sort^ ty) { return gcnew Sort(m_ctx,m_ctx->MkSetSort(ty())); } + Term^ MkEmptySet(Sort^ ty) { return gcnew Term(m_ctx,m_ctx->MkEmptySet(ty())); } + Term^ MkFullSet(Sort^ ty) { return gcnew Term(m_ctx,m_ctx->MkFullSet(ty())); } + Term^ MkSetAdd(Term^ set, Term^ elem) { return gcnew Term(m_ctx,m_ctx->MkSetAdd(set(), elem())); } + Term^ MkSetDel(Term^ set, Term^ elem) { return gcnew Term(m_ctx,m_ctx->MkSetDel(set(), elem())); } + Term^ MkSetUnion(array^ sets) { + return gcnew Term(m_ctx,m_ctx->MkSetUnion(CopyArray(sets))); + } + Term^ MkSetUnion(Term^ set1, Term^ set2) { + return gcnew Term(m_ctx,m_ctx->MkSetUnion(set1(), set2())); + } + Term^ MkSetIntersect(array^ sets) { + return gcnew Term(m_ctx,m_ctx->MkSetIntersect(CopyArray(sets))); + } + Term^ MkSetIntersect(Term^ set1, Term^ set2) { + return gcnew Term(m_ctx,m_ctx->MkSetIntersect(set1(), set2())); + } + Term^ MkSetDifference(Term^ t1, Term^ t2) { + return gcnew Term(m_ctx,m_ctx->MkSetDifference(t1(), t2())); + } + Term^ MkSetComplement(Term^ arg) { + return gcnew Term(m_ctx,m_ctx->MkSetComplement(arg())); + } + Term^ MkSetMember(Term^ elem, Term^ set) { + return gcnew Term(m_ctx,m_ctx->MkSetMember(elem(), set())); + } + Term^ MkSetSubset(Term^ t1, Term^ t2) { + return gcnew Term(m_ctx,m_ctx->MkSetSubset(t1(), t2())); + } + + FuncDecl^ MkInjectiveFunction(String^ name, array^ domain, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkInjectiveFunction(name, CopyArray(domain), range())); + } + FuncDecl^ MkInjectiveFunction(Symbol^ name, array^ domain, Sort^ range) { + return gcnew FuncDecl(m_ctx,m_ctx->MkInjectiveFunction(name, CopyArray(domain), range())); + } + + Term^ MkNumeral(String^ numeral, Sort^ ty) { + return gcnew Term(m_ctx,m_ctx->MkNumeral(numeral, ty())); + } + Term^ MkNumeral(int n, Sort^ ty) { return gcnew Term(m_ctx,m_ctx->MkNumeral(n, ty())); } + Term^ MkNumeral(unsigned n, Sort^ ty) { return gcnew Term(m_ctx,m_ctx->MkNumeral(n, ty())); } + Term^ MkNumeral(__int64 n, Sort^ ty) { return gcnew Term(m_ctx,m_ctx->MkNumeral(n, ty())); } + Term^ MkNumeral(unsigned __int64 n, Sort^ ty) { return gcnew Term(m_ctx,m_ctx->MkNumeral(n, ty())); } + + Term^ MkIntNumeral(String^ n) { return MkNumeral(n, MkIntSort()); } + Term^ MkIntNumeral(int n) { return MkNumeral(n, MkIntSort()); } + Term^ MkIntNumeral(unsigned n) { return MkNumeral(n, MkIntSort()); } + Term^ MkIntNumeral(__int64 n) { return MkNumeral(n, MkIntSort()); } + Term^ MkIntNumeral(unsigned __int64 n) { return MkNumeral(n, MkIntSort()); } + + Term^ MkRealNumeral(String^ n) { return MkNumeral(n, MkRealSort()); } + Term^ MkRealNumeral(int n) { return MkNumeral(n, MkRealSort()); } + Term^ MkRealNumeral(unsigned n) { return MkNumeral(n, MkRealSort()); } + Term^ MkRealNumeral(__int64 n) { return MkNumeral(n, MkRealSort()); } + Term^ MkRealNumeral(unsigned __int64 n) { return MkNumeral(n, MkRealSort()); } + + Pattern^ MkPattern(array^ terms) { return gcnew Pattern(m_ctx,m_ctx->MkPattern(CopyArray(terms))); } + Term^ MkBound(unsigned index, Sort^ ty) { return gcnew Term(m_ctx,m_ctx->MkBound(index, ty())); } + + Term^ MkForall( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + Term^ body + ) { + return gcnew Term(m_ctx,m_ctx->MkForall(weight, CopyArray(patterns), CopyArray(types), names, body())); + } + + Term^ MkForall( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + Term^ body + ) { + return gcnew Term(m_ctx,m_ctx->MkForall(weight, CopyArray(patterns), CopyArray(types), names, body())); + } + + Term^ MkForall( + unsigned weight, + array^ bound, + array^ patterns, + Term^ body + ) { + return gcnew Term(m_ctx,m_ctx->MkForall(weight, CopyArray(bound), CopyArray(patterns), body())); + } + + + Term^ MkExists( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + Term^ body + ) { + return gcnew Term(m_ctx,m_ctx->MkExists(weight, CopyArray(patterns), CopyArray(types), names, body())); + } + + Term^ MkExists( + unsigned weight, + array^ patterns, + array^ types, + array^ names, + Term^ body + ) { + return gcnew Term(m_ctx,m_ctx->MkExists(weight, CopyArray(patterns), CopyArray(types), names, body())); + } + + Term^ MkExists( + unsigned weight, + array^ bound, + array^ patterns, + Term^ body + ) { + return gcnew Term(m_ctx,m_ctx->MkExists(weight, CopyArray(bound), CopyArray(patterns), body())); + } + + + + Term^ MkQuantifier( + bool is_forall, + unsigned weight, + array^ patterns, + array^ no_patterns, + array^ types, + array^ names, + Term^ body + ) { + return MkQuantifier(is_forall, weight, nullptr, nullptr, patterns, no_patterns, types, names, body); + } + + Term^ MkQuantifier( + bool is_forall, + unsigned weight, + Symbol^ quantifier_id, + Symbol^ skolem_id, + array^ patterns, + array^ no_patterns, + array^ types, + array^ names, + Term^ body + ) { + return gcnew Term(m_ctx,m_ctx->MkQuantifier( + is_forall, weight, + quantifier_id, skolem_id, + CopyArray(patterns), + CopyArray(no_patterns), + CopyArray(types), + names, + body())); + } + + Term^ MkQuantifier( + bool is_forall, + unsigned weight, + Symbol^ quantifier_id, + Symbol^ skolem_id, + array^ patterns, + array^ no_patterns, + array^ bound, + Term^ body + ) { + return gcnew Term(m_ctx,m_ctx->MkQuantifier( + is_forall, weight, + quantifier_id, skolem_id, + CopyArray(patterns), + CopyArray(no_patterns), + CopyArray(bound), + body())); + } + + SymbolKind GetSymbolKind(Symbol^ s) { return m_ctx->GetSymbolKind(s); } + int GetSymbolInt(Symbol^ s) { return m_ctx->GetSymbolInt(s); } + String^ GetSymbolString(Symbol^ s) { return m_ctx->GetSymbolString(s); } + bool IsEq(Term^ t1, Term^ t2) { return m_ctx->IsEq(t1(), t2()); } + bool IsWellSorted(Term^ t) { return m_ctx->IsWellSorted(t()); } + TermKind GetTermKind(Term^ a) { return m_ctx->GetTermKind(a()); } + DeclKind GetDeclKind(FuncDecl^ d) { return m_ctx->GetDeclKind(d()); } + array^ GetDeclParameters(FuncDecl^ d); + FuncDecl^ GetAppDecl(Term^ a) { return gcnew FuncDecl(m_ctx,m_ctx->GetAppDecl(a())); } + array^ GetAppArgs(Term^ a) { return CopyTermArray(m_ctx->GetAppArgs(a())); } + String^ GetNumeralString(Term^ a) { return m_ctx->GetNumeralString(a()); } + int GetNumeralInt(Term^ v) { return m_ctx->GetNumeralInt(v()); } + bool TryGetNumeralInt(Term^ v, [Out] int% i) { return m_ctx->TryGetNumeralInt(v(), i); } + unsigned int GetNumeralUInt(Term^ v) { return m_ctx->GetNumeralUInt(v()); } + bool TryGetNumeralUInt(Term^ v, [Out] unsigned int% u) { return m_ctx->TryGetNumeralUInt(v(), u); } + __int64 GetNumeralInt64(Term^ v) { return m_ctx->GetNumeralInt64(v()); } + bool TryGetNumeralInt64(Term^ v, [Out] __int64% i) { return m_ctx->TryGetNumeralInt64(v(), i); } + unsigned __int64 GetNumeralUInt64(Term^ v) { return m_ctx->GetNumeralUInt64(v()); } + bool TryGetNumeralUInt64(Term^ v, [Out] unsigned __int64% u) { return m_ctx->TryGetNumeralUInt64(v(), u); } + bool TryGetNumeral(Term^ v, [Out] __int64% num, [Out] __int64% den) { return m_ctx->TryGetNumeral(v(), num, den); } + void GetNumeral(Term^ v, [Out] System::Numerics::BigInteger% num, [Out] System::Numerics::BigInteger% den) { + m_ctx->GetNumeral(v(), num, den); + } + + LBool GetBoolValue(Term^ v) { return m_ctx->GetBoolValue(v()); } + + unsigned GetVarIndex(Term^ a) { return m_ctx->GetVarIndex(a()); } + Quantifier^ GetQuantifier(Term^ a) { return GetQuantifier(m_ctx, a); } + + array^ GetPatternTerms(Pattern^ p) { return CopyTermArray(m_ctx->GetPatternTerms(p())); } + Symbol^ GetDeclName(FuncDecl^ d) { return m_ctx->GetDeclName(d()); } + Symbol^ GetSortName(Sort^ ty) { return m_ctx->GetSortName(ty()); } + Sort^ GetSort(Term^ a) { return gcnew Sort(m_ctx,m_ctx->GetSort(a())); } + array^ GetDomain(FuncDecl^ d) { return CopySortArray(m_ctx->GetDomain(d())); } + Sort^ GetRange(FuncDecl^ d) { return gcnew Sort(m_ctx,m_ctx->GetRange(d())); } + SortKind GetSortKind(Sort^ t) { return m_ctx->GetSortKind(t()); } + unsigned GetBvSortSize(Sort^ t) { return m_ctx->GetBvSortSize(t()); } + Sort^ GetArraySortDomain(Sort^ t) { return gcnew Sort(m_ctx,m_ctx->GetArraySortDomain(t())); } + Sort^ GetArraySortRange(Sort^ t) { return gcnew Sort(m_ctx,m_ctx->GetArraySortRange(t())); } + FuncDecl^ GetTupleConstructor(Sort^ t) { return gcnew FuncDecl(m_ctx,m_ctx->GetTupleConstructor(t())); } + array^ GetTupleFields(Sort^ t) { return CopyFuncDeclArray(m_ctx->GetTupleFields(t())); } + + Theory^ MkTheory(String^ name); + + void RegisterRelation(FuncDecl^ r) { m_ctx->RegisterRelation(r()); } + + void AddRule(Term^ rule, Symbol^ name) { m_ctx->AddRule(rule(), name); } + + LBool Query(Term^ query) { return m_ctx->Query(query()); } + + String^ GetQueryStatus() { return m_ctx->GetQueryStatus(); } + + Term^ GetQueryAnswer() { return gcnew Term(m_ctx, m_ctx->GetQueryAnswer()); } + + String^ FixedpointkToString(array^ queries) { + return m_ctx->FixedpointToString(CopyArray(queries)); + } + array^ SimplifyFixedpointRules(array^ rules, array^ output_predicates) { + return CopyTermArray(m_ctx->SimplifyFixedpointRules(CopyArray(rules), CopyArray(output_predicates))); + } + // functions for creating custom Fixedpoint relations. + + private: + Action3^, array^>^ m_assign_callback; + void AssignCallbackAux(FuncDeclPtr f, array^ args, array^ outs) { + m_assign_callback(gcnew FuncDecl(m_ctx, f), CopyAstArray(args), CopyAstArray(outs)); + } + Func2^, Term^>^ m_apply_callback; + TermPtr ApplyCallbackAux(FuncDeclPtr f, array^ args) { + return m_apply_callback(gcnew FuncDecl(m_ctx, f), CopyAstArray(args))(); + } + public: + property Action3^, array^>^ FixedpointAssign { + void set(Action3^, array^>^ value) { + m_assign_callback = value; + m_ctx->FixedpointAssign = gcnew Action3^, array^>(this,&Context::AssignCallbackAux); + } + } + property Func2^, Term^>^ FixedpointApply { + void set(Func2^, Term^>^ value) { + m_apply_callback = value; + m_ctx->FixedpointApply = gcnew Func2^, TermPtr>(this,&Context::ApplyCallbackAux); + } + } + }; + + public ref class FunctionEntry { + public: + array^ Arguments; + Term^ Result; + }; + + public ref class FunctionGraph { + public: + FuncDecl^ Declaration; + array^ Entries; + Term^ Else; + }; + + + public ref class Model { + RawModel^ m_model; + Context^ m_ctx; + + ArrayValue^ Mk(RawArrayValue^ av); + FunctionEntry^ Mk(RawFunctionEntry^ fe); + FunctionGraph^ Mk(RawFunctionGraph^ fg); + Dictionary^ Mk(Dictionary^ fgs); + + internal: + property Context^ GetContext { Context^ get() { return m_ctx; }} + property RawModel^ GetModel { RawModel^ get() { return m_model; }} + + Model(RawModel^ m, Context^ c) : m_model(m), m_ctx(c) {} + + public: + ~Model() { m_model->Reset(); } + + array^ GetModelConstants() { + return m_ctx->CopyFuncDeclArray(m_model->GetModelConstants()); + } + + bool TryGetArrayValue(Term^ a, [Out] ArrayValue^% av); + + Dictionary^ GetFunctionGraphs() { return Mk(m_model->GetFunctionGraphs()); } + + Term^ Eval(Term^ t) { return gcnew Term(m_ctx->GetContext, m_model->Eval(t())); } + + Term^ Eval(FuncDecl^ d, array^ args) { + return gcnew Term(m_ctx->GetContext, m_model->Eval(d(), m_ctx->CopyArray(args))); + } + + void Display(System::IO::TextWriter^ w) { m_model->Display(w); } + + }; + + public ref class Theory + { + Context^ m_context; + RawTheory^ m_theory; + + public: + property String^ Name { String^ get() { return m_theory->Name; } } + + internal: + Theory(Context^ ctx, String^ name) + { + m_context = ctx; + m_theory = gcnew RawTheory(ctx->GetContext->ref_context(), name); + } + + private: + array^ MkTerms(array^ ts) + { + return m_context->CopyAstArray(ts); + } + Term^ MkTerm(TermPtr t) { return gcnew Term(m_context->GetContext, t); } + FuncDecl^ MkFuncDecl(FuncDeclPtr f) { return gcnew FuncDecl(m_context->GetContext, f); } + + TermPtr GetTermPtr(Term^ t) + { + if (t) return t(); + return IntPtr::Zero; + } + + public: + property Action0^ DeleteHandler + { + void set(Action0^ value) + { + m_theory->DeleteHandler = value; + } + } + private: + Func2^ reduce_eq; + TermPtr ReduceEqAux(TermPtr a, TermPtr b) { + return GetTermPtr(reduce_eq(MkTerm(a), MkTerm(b))); + } + public: + property Func2^ ReduceEq + { + void set(Func2^ value) + { + reduce_eq = value; + m_theory->ReduceEq = gcnew Func2(this,&Theory::ReduceEqAux); + } + } + private: + Func2^, Term^>^ reduce_app; + TermPtr ReduceAppAux(FuncDeclPtr a, array^ b) { + return GetTermPtr(reduce_app(MkFuncDecl(a), MkTerms(b))); + } + public: + property Func2^, Term^>^ ReduceApp + { + void set(Func2^, Term^>^ value) + { + reduce_app = value; + m_theory->ReduceApp = gcnew Func2^,TermPtr>(this,&Theory::ReduceAppAux); + } + } + private: + Func1^, Term^>^ reduce_distinct; + TermPtr ReduceDistinctAux(array^ args) { + return GetTermPtr(reduce_distinct(MkTerms(args))); + } + + public: + property Func1^, Term^>^ ReduceDistinct + { + void set(Func1^, Term^>^ value) + { + reduce_distinct = value; + m_theory->ReduceDistinct = gcnew Func1^,TermPtr>(this, &Theory::ReduceDistinctAux); + } + } + private: + Action^ new_app; + void NewAppAux(TermPtr a) { return new_app(MkTerm(a)); } + public: + property Action^ NewApp + { + void set(Action^ value) + { + new_app = value; + m_theory->NewApp = gcnew Action(this, &Theory::NewAppAux); + } + } + private: + Action^ new_elem; + void NewElemAux(TermPtr a) { return new_elem(MkTerm(a)); } + public: + property Action^ NewElem + { + void set(Action^ value) + { + new_elem = value; + m_theory->NewElem = gcnew Action(this, &Theory::NewElemAux); + } + } + property Action0^ InitSearch + { + void set(Action0^ value) + { + m_theory->InitSearch = value; + } + } + property Action0^ Push + { + void set(Action0^ value) + { + m_theory->Push = value; + } + } + property Action0^ Pop + { + void set(Action0^ value) + { + m_theory->Pop = value; + } + } + property Action0^ Reset + { + void set(Action0^ value) + { + m_theory->Reset = value; + } + } + property Action0^ Restart + { + void set(Action0^ value) + { + m_theory->Restart = value; + } + } + + property Func0^ FinalCheck + { + void set(Func0^ value) + { + m_theory->FinalCheck = value; + } + } + private: + Action2^ new_eq; + void NewEqAux(TermPtr a, TermPtr b) { + new_eq(MkTerm(a), MkTerm(b)); + } + public: + property Action2^ NewEq + { + void set(Action2^ value) + { + new_eq = value; + m_theory->NewEq = gcnew Action2(this, &Theory::NewEqAux); + } + } + private: + Action2^ new_diseq; + void NewDiseqAux(TermPtr a, TermPtr b) { + new_diseq(MkTerm(a), MkTerm(b)); + } + public: + property Action2^ NewDiseq + { + void set(Action2^ value) + { + new_diseq = value; + m_theory->NewDiseq = gcnew Action2(this, &Theory::NewDiseqAux); + } + } + private: + Action2^ new_assignment; + void NewAssignmentAux(TermPtr a, bool b) { + new_assignment(MkTerm(a), b); + } + public: + property Action2^ NewAssignment + { + void set(Action2^ value) + { + new_assignment = value; + m_theory->NewAssignment = gcnew Action2(this, &Theory::NewAssignmentAux); + } + } + private: + Action^ new_relevant; + void NewRelevantAux(TermPtr a) { new_relevant(MkTerm(a)); } + public: + property Action^ NewRelevant + { + void set(Action^ value) { + new_relevant = value; + m_theory->NewRelevant = gcnew Action(this, &Theory::NewRelevantAux); + } + } + + void AssertTheoryAxiom(Term^ ax) + { + m_theory->AssertTheoryAxiom(ax()); + } + + void AssumeEq(Term^ lhs, Term^ rhs) + { + m_theory->AssumeEq(lhs(), rhs()); + } + + + void EnableTheoryAxiomSimplification(bool flag) + { + m_theory->EnableTheoryAxiomSimplification(flag); + } + + Term^ GetEqcRoot(Term^ n) + { + return MkTerm(m_theory->GetEqcRoot(n())); + } + + Term^ GetEqcNext(Term^ n) + { + return MkTerm(m_theory->GetEqcNext(n())); + } + + array^ GetParents(Term^ n) + { + return MkTerms(m_theory->GetParents(n())); + } + + bool IsTheoryValue(Term^ a) + { + return m_theory->IsTheoryValue(a()); + } + + bool IsTheoryDecl(FuncDecl^ d) + { + return m_theory->IsTheoryDecl(d()); + } + + array^ GetElems() + { + return MkTerms(m_theory->GetElems()); + } + + array^ GetApps() + { + return MkTerms(m_theory->GetApps()); + } + + + Sort^ MkSort(Symbol^ s) + { + return gcnew Sort(m_context->GetContext,m_theory->MkSort(s)); + } + + Term^ MkValue(Symbol^ s, Sort^ srt) + { + return MkTerm(m_theory->MkValue(s, srt())); + } + + Term^ MkConstant(Symbol^ s, Sort^ srt) + { + return MkTerm(m_theory->MkConstant(s, srt())); + } + + FuncDecl^ MkFuncDecl(Symbol^ n, array^ domain, Sort^ range) + { + array^ dom = gcnew array(domain->Length); + for (int i = 0; i < domain->Length; ++i) dom[i] = domain[i](); + return gcnew FuncDecl(m_context->GetContext, m_theory->MkFuncDecl(n, dom, range())); + } + + Sort^ MkSort(String^ s) + { + return gcnew Sort(m_context->GetContext,m_theory->MkSort(s)); + } + + Term^ MkValue(String^ s, Sort^ srt) + { + return MkTerm(m_theory->MkValue(s, srt())); + } + + Term^ MkConstant(String^ s, Sort^ srt) + { + return MkTerm(m_theory->MkConstant(s, srt())); + } + + FuncDecl^ MkFuncDecl(String^ n, array^ domain, Sort^ range) + { + return this->MkFuncDecl(m_context->MkSymbol(n), domain, range); + } + + + }; + + +/*@}*/ + +}; +}; + +#endif diff --git a/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj b/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj new file mode 100644 index 000000000..bdf4c5229 --- /dev/null +++ b/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj @@ -0,0 +1,1686 @@ + + + + + bench + Win32 + + + bench + x64 + + + commercial + Win32 + + + commercial + x64 + + + debug_opt + Win32 + + + debug_opt + x64 + + + Debug + Win32 + + + Debug + x64 + + + external_64 + Win32 + + + external_64 + x64 + + + external_dbg + Win32 + + + external_dbg + x64 + + + external_parallel_x64 + Win32 + + + external_parallel_x64 + x64 + + + external_parallel + Win32 + + + external_parallel + x64 + + + external + Win32 + + + external + x64 + + + mpi_debug + Win32 + + + mpi_debug + x64 + + + mpi_release + Win32 + + + mpi_release + x64 + + + parallel_debug + Win32 + + + parallel_debug + x64 + + + parallel_release + Win32 + + + parallel_release + x64 + + + ReleaseD + Win32 + + + ReleaseD + x64 + + + Release_delaysign + Win32 + + + Release_delaysign + x64 + + + release_mt + Win32 + + + release_mt + x64 + + + release_static + Win32 + + + release_static + x64 + + + Release + Win32 + + + Release + x64 + + + smtcomp + Win32 + + + smtcomp + x64 + + + Trace + Win32 + + + Trace + x64 + + + + {F008F2C4-D652-4A58-8DEF-DB83E2355454} + Microsoft.Z3V3 + ManagedCProj + Microsoft.Z3V3 + + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + Application + + + DynamicLibrary + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + true + + + Application + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + Application + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + Unicode + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + WIN32;_DEBUG;Z3DEBUG;_WINDOWS;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + $(OutDir)Microsoft.Z3V3.dll + true + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + $(OutDir)Microsoft.Z3V3.dll + true + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + Disabled + false + D:\tvm\src\zofty\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;Z3DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + /LTCG %(AdditionalOptions) + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + Disabled + false + D:\tvm\src\zofty\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + /LTCG %(AdditionalOptions) + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + true + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;_Z3_COMMERCIAL;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)35MSSharedLib1024.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + true + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;_Z3_COMMERCIAL;_AMD64_;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)35MSSharedLib1024.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + Disabled + WIN32;_DEBUG;Z3DEBUG;_WINDOWS;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + $(OutDir)Microsoft.Z3V3.dll + true + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + Disabled + WIN32;_DEBUG;Z3DEBUG;_WINDOWS;_TRACE;_BUILD_PARALLEL_SMT;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Create + Level3 + ProgramDatabase + + + $(OutDir)Microsoft.Z3V3.dll + true + true + false + + + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Create + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;_BUILD_PARALLEL_SMT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Create + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + MultiThreadedDLL + + + $(OutDir)Microsoft.Z3V3.dll + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + Disabled + WIN32;_DEBUG;Z3DEBUG;_WINDOWS;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + $(OutDir)Microsoft.Z3V3.dll + true + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX86 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;_BUILD_PARALLEL_SMT;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Create + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + false + WIN32;NDEBUG;_WINDOWS;DELAYSIGN;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + false + + + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)35MSSharedLib1024.snk" + + + + + X64 + + + false + WIN32;NDEBUG;_WINDOWS;DELAYSIGN;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + + + $(OutDir)Microsoft.Z3V3.dll + true + MachineX64 + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)35MSSharedLib1024.snk" + + + + + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + + + sn.exe -Ra "$(TargetPath)" "$(ProjectDir)z3.snk" + + + + + true + true + + + true + true + + + + true + true + + + + + + + + + + + + {4a7e5a93-19d8-4382-8950-fb2edec7a76e} + false + + + + + + \ No newline at end of file diff --git a/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj.user b/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj.user new file mode 100644 index 000000000..ace9a86ac --- /dev/null +++ b/Microsoft.Z3V3/Microsoft.Z3V3.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Microsoft.Z3V3/z3.snk b/Microsoft.Z3V3/z3.snk new file mode 100644 index 000000000..1c1ac8713 Binary files /dev/null and b/Microsoft.Z3V3/z3.snk differ diff --git a/README b/README new file mode 100644 index 000000000..14cf735c5 --- /dev/null +++ b/README @@ -0,0 +1,52 @@ +Z3 is a theorem prover from Microsoft Research. +Z3 is licensed under MSR-LA (Microsoft Research License Agreement). +See http://z3.codeplex.com/license for more information about this license. +Z3 can be built using Visual Studio Command Prompt, Visual Studio and make/gcc. + +1) Building Z3 on Windows using Visual Studio Command Prompt + +- Open a Visual Studio Command Prompt, then execute one of the following commands to build the desired component. + +- For building all components, execute + msbuild z3-prover.sln /p:configuration=external + All components will be located at /external + +- For building all components (64-bit), execute + msbuild z3-prover.sln /p:configuration=external_64 /p:platform=x64 + All components will be located at /external_64 + +- For building all components (in debug mode), execute + msbuild z3-prover.sln + All components will be located at /debug + +1) Building Z3 using g++/make +Your machine must also have the following commands to be able to build Z3: +autoconf, sed, awk, dos2unix commands + + +- Open a shell +- For building the z3 executable, execute + + autoconf + ./configure + make + +The z3 executable will be located at bin/external/ + +- If you want a static library for Z3 + + make a + +- If you also want the z3 shared library, execute + + make so + + for libz3.so (on Linux) + + make dylib + + for libz3.dylib (on OSX) + +Remark: the Z3 makefile imports the source file list from Visual Studio project files. +To add new source files to the Z3 core, you must include them at: lib/lib.vcxproj + diff --git a/c++/README.txt b/c++/README.txt new file mode 100644 index 000000000..05d1be082 --- /dev/null +++ b/c++/README.txt @@ -0,0 +1,23 @@ +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 + +Use 'build.sh' to build the test application using g++. +The script 'exec.sh' adds the bin directory to the path. So, +example.exe can find z3.dll. + +Remark: the scripts 'build.sh' and 'exec.sh' assumes you are in a +Cygwin or Mingw shell. + diff --git a/c++/build-external-linux.sh b/c++/build-external-linux.sh new file mode 100644 index 000000000..d439d5995 --- /dev/null +++ b/c++/build-external-linux.sh @@ -0,0 +1 @@ +g++ -fopenmp -o example -I ../../include example.cpp -L ../../lib -lz3 diff --git a/c++/build-external-osx.sh b/c++/build-external-osx.sh new file mode 100644 index 000000000..d439d5995 --- /dev/null +++ b/c++/build-external-osx.sh @@ -0,0 +1 @@ +g++ -fopenmp -o example -I ../../include example.cpp -L ../../lib -lz3 diff --git a/c++/build-external.cmd b/c++/build-external.cmd new file mode 100644 index 000000000..08932d5a3 --- /dev/null +++ b/c++/build-external.cmd @@ -0,0 +1 @@ +cl /EHsc /I ..\..\include /I . ..\..\bin\z3.lib example.cpp diff --git a/c++/build-external.sh b/c++/build-external.sh new file mode 100644 index 000000000..f338ca44b --- /dev/null +++ b/c++/build-external.sh @@ -0,0 +1 @@ +g++ -fopenmp -o example.exe -I ../../include ../../bin/z3.dll example.cpp diff --git a/c++/build.cmd b/c++/build.cmd new file mode 100644 index 000000000..64ff98f31 --- /dev/null +++ b/c++/build.cmd @@ -0,0 +1 @@ +cl /W3 /EHsc /I ..\lib ..\debug\z3_dbg.lib example.cpp diff --git a/c++/example.cpp b/c++/example.cpp new file mode 100644 index 000000000..469282e40 --- /dev/null +++ b/c++/example.cpp @@ -0,0 +1,701 @@ +#include"z3++.h" +using namespace z3; + +/** + Demonstration of how Z3 can be used to prove validity of + De Morgan's Duality Law: {e not(x and y) <-> (not x) or ( not y) } +*/ +void demorgan() { + std::cout << "de-Morgan example\n"; + + context c; + + expr x = c.bool_const("x"); + expr y = c.bool_const("y"); + expr conjecture = !(x && y) == (!x || !y); + + solver s(c); + // adding the negation of the conjecture as a constraint. + s.add(!conjecture); + std::cout << s << "\n"; + switch (s.check()) { + case unsat: std::cout << "de-Morgan is valid\n"; break; + case sat: std::cout << "de-Morgan is not valid\n"; break; + case unknown: std::cout << "unknown\n"; break; + } +} + +/** + \brief Find a model for x >= 1 and y < x + 3. +*/ +void find_model_example1() { + std::cout << "find_model_example1\n"; + context c; + expr x = c.int_const("x"); + expr y = c.int_const("y"); + solver s(c); + + s.add(x >= 1); + s.add(y < x + 3); + std::cout << s.check() << "\n"; + + model m = s.get_model(); + std::cout << m << "\n"; + // traversing the model + for (unsigned i = 0; i < m.size(); i++) { + func_decl v = m[i]; + // this problem contains only constants + assert(v.arity() == 0); + std::cout << v.name() << " = " << m.get_const_interp(v) << "\n"; + } + // we can evaluate expressions in the model. + std::cout << "x + y + 1 = " << m.eval(x + y + 1) << "\n"; +} + + +/** + \brief Prove x = y implies g(x) = g(y), and + disprove x = y implies g(g(x)) = g(y). + + This function demonstrates how to create uninterpreted types and + functions. +*/ +void prove_example1() { + std::cout << "prove_example1\n"; + + context c; + expr x = c.int_const("x"); + expr y = c.int_const("y"); + sort I = c.int_sort(); + func_decl g = function("g", I, I); + + solver s(c); + expr conjecture1 = implies(x == y, g(x) == g(y)); + std::cout << "conjecture 1\n" << conjecture1 << "\n"; + s.add(!conjecture1); + if (s.check() == unsat) + std::cout << "proved" << "\n"; + else + std::cout << "failed to prove" << "\n"; + + s.reset(); // remove all assertions from solver s + + expr conjecture2 = implies(x == y, g(g(x)) == g(y)); + std::cout << "conjecture 2\n" << conjecture2 << "\n"; + s.add(!conjecture2); + if (s.check() == unsat) { + std::cout << "proved" << "\n"; + } + else { + std::cout << "failed to prove" << "\n"; + model m = s.get_model(); + std::cout << "counterexample:\n" << m << "\n"; + std::cout << "g(g(x)) = " << m.eval(g(g(x))) << "\n"; + std::cout << "g(y) = " << m.eval(g(y)) << "\n"; + } +} + +/** + \brief Prove not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 . + Then, show that z < -1 is not implied. + + This example demonstrates how to combine uninterpreted functions and arithmetic. +*/ +void prove_example2() { + std::cout << "prove_example1\n"; + + context c; + expr x = c.int_const("x"); + expr y = c.int_const("y"); + expr z = c.int_const("z"); + sort I = c.int_sort(); + func_decl g = function("g", I, I); + + expr conjecture1 = implies(g(g(x) - g(y)) != g(z) && x + z <= y && y <= x, + z < 0); + + solver s(c); + s.add(!conjecture1); + std::cout << "conjecture 1:\n" << conjecture1 << "\n"; + if (s.check() == unsat) + std::cout << "proved" << "\n"; + else + std::cout << "failed to prove" << "\n"; + + expr conjecture2 = implies(g(g(x) - g(y)) != g(z) && x + z <= y && y <= x, + z < -1); + s.reset(); + s.add(!conjecture2); + std::cout << "conjecture 2:\n" << conjecture2 << "\n"; + if (s.check() == unsat) { + std::cout << "proved" << "\n"; + } + else { + std::cout << "failed to prove" << "\n"; + std::cout << "counterexample:\n" << s.get_model() << "\n"; + } +} + +/** + \brief Nonlinear arithmetic example 1 +*/ +void nonlinear_example1() { + std::cout << "nonlinear example 1\n"; + config cfg; + cfg.set(":auto-config", true); + context c(cfg); + + expr x = c.real_const("x"); + expr y = c.real_const("y"); + expr z = c.real_const("z"); + + solver s(c); + + s.add(x*x + y*y == 1); // x^2 + y^2 == 1 + s.add(x*x*x + z*z*z < c.real_val("1/2")); // x^3 + z^3 < 1/2 + s.add(z != 0); + std::cout << s.check() << "\n"; + model m = s.get_model(); + std::cout << m << "\n"; + c.set(":pp-decimal", true); // set decimal notation + std::cout << "model in decimal notation\n"; + std::cout << m << "\n"; + c.set(":pp-decimal-precision", 50); // increase number of decimal places to 50. + std::cout << "model using 50 decimal places\n"; + std::cout << m << "\n"; +} + +/** + \brief Simple function that tries to prove the given conjecture using the following steps: + 1- create a solver + 2- assert the negation of the conjecture + 3- checks if the result is unsat. +*/ +void prove(expr conjecture) { + context & c = conjecture.ctx(); + solver s(c); + s.add(!conjecture); + std::cout << "conjecture:\n" << conjecture << "\n"; + if (s.check() == unsat) { + std::cout << "proved" << "\n"; + } + else { + std::cout << "failed to prove" << "\n"; + std::cout << "counterexample:\n" << s.get_model() << "\n"; + } +} + +/** + \brief Simple bit-vector example. This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers +*/ +void bitvector_example1() { + std::cout << "bitvector example 1\n"; + context c; + expr x = c.bv_const("x", 32); + + // using signed <= + prove((x - 10 <= 0) == (x <= 10)); + + // using unsigned <= + prove(ule(x - 10, 0) == ule(x, 10)); +} + +/** + \brief Find x and y such that: x ^ y - 103 == x * y +*/ +void bitvector_example2() { + std::cout << "bitvector example 2\n"; + context c; + expr x = c.bv_const("x", 32); + expr y = c.bv_const("y", 32); + solver s(c); + // In C++, the operator == has higher precedence than ^. + s.add((x ^ y) - 103 == x * y); + std::cout << s << "\n"; + std::cout << s.check() << "\n"; + std::cout << s.get_model() << "\n"; +} + +/** + \brief Mixing C and C++ APIs. +*/ +void capi_example() { + std::cout << "capi example\n"; + context c; + expr x = c.bv_const("x", 32); + expr y = c.bv_const("y", 32); + // Invoking a C API function, and wrapping the result using an expr object. + expr r = to_expr(c, Z3_mk_bvsrem(c, x, y)); + std::cout << "r: " << r << "\n"; +} + +/** + \brief Demonstrate how to evaluate expressions in a model. +*/ +void eval_example1() { + std::cout << "eval example 1\n"; + context c; + expr x = c.int_const("x"); + expr y = c.int_const("y"); + solver s(c); + + /* assert x < y */ + s.add(x < y); + /* assert x > 2 */ + s.add(x > 2); + + std::cout << s.check() << "\n"; + + model m = s.get_model(); + std::cout << "Model:\n" << m << "\n"; + std::cout << "x+y = " << m.eval(x+y) << "\n"; +} + +/** + \brief Several contexts can be used simultaneously. +*/ +void two_contexts_example1() { + std::cout << "two contexts example 1\n"; + context c1, c2; + + expr x = c1.int_const("x"); + expr n = x + 1; + // We cannot mix expressions from different contexts, but we can copy + // an expression from one context to another. + // The following statement copies the expression n from c1 to c2. + expr n1 = to_expr(c2, Z3_translate(c1, n, c2)); + std::cout << n1 << "\n"; +} + +/** + \brief Demonstrates how to catch API usage errors. + */ +void error_example() { + std::cout << "error example\n"; + + context c; + expr x = c.bool_const("x"); + + // Error using the C API can be detected using Z3_get_error_code. + // The next call fails because x is a constant. + Z3_ast arg = Z3_get_app_arg(c, x, 0); + if (Z3_get_error_code(c) != Z3_OK) { + std::cout << "last call failed.\n"; + } + + // The C++ layer converts API usage errors into exceptions. + try { + // The next call fails because x is a Boolean. + expr n = x + 1; + } + catch (exception ex) { + std::cout << "failed: " << ex << "\n"; + } + + // The functions to_expr, to_sort and to_func_decl also convert C API errors into exceptions. + try { + expr arg = to_expr(c, Z3_get_app_arg(c, x, 0)); + } + catch (exception ex) { + std::cout << "failed: " << ex << "\n"; + } +} + +/** + \brief Demonstrate different ways of creating rational numbers: decimal and fractional representations. +*/ +void numeral_example() { + std::cout << "numeral example\n"; + context c; + + expr n1 = c.real_val("1/2"); + expr n2 = c.real_val("0.5"); + expr n3 = c.real_val(1, 2); + std::cout << n1 << " " << n2 << " " << n3 << "\n"; + prove(n1 == n2 && n1 == n3); + + n1 = c.real_val("-1/3"); + n2 = c.real_val("-0.3333333333333333333333333333333333"); + std::cout << n1 << " " << n2 << "\n"; + prove(n1 != n2); +} + +/** + \brief Test ite-term (if-then-else terms). +*/ +void ite_example() { + std::cout << "if-then-else example\n"; + context c; + + expr f = c.bool_val(false); + expr one = c.int_val(1); + expr zero = c.int_val(0); + expr ite = to_expr(c, Z3_mk_ite(c, f, one, zero)); + + std::cout << "term: " << ite << "\n"; +} + +/** + \brief Unsat core example +*/ +void unsat_core_example() { + std::cout << "unsat core example\n"; + context c; + expr p1 = c.bool_const("p1"); + expr p2 = c.bool_const("p2"); + expr p3 = c.bool_const("p3"); + expr x = c.int_const("x"); + expr y = c.int_const("y"); + solver s(c); + s.add(implies(p1, x > 10)); + s.add(implies(p1, y > x)); + s.add(implies(p2, y < 5)); + s.add(implies(p3, y > 0)); + expr assumptions[3] = { p1, p2, p3 }; + std::cout << s.check(3, assumptions) << "\n"; + expr_vector core = s.unsat_core(); + std::cout << core << "\n"; + std::cout << "size: " << core.size() << "\n"; + for (unsigned i = 0; i < core.size(); i++) { + std::cout << core[i] << "\n"; + } + // Trying again without p2 + expr assumptions2[2] = { p1, p3 }; + std::cout << s.check(2, assumptions2) << "\n"; +} + +void tactic_example1() { + /* + Z3 implements a methodology for orchestrating reasoning engines where "big" symbolic + reasoning steps are represented as functions known as tactics, and tactics are composed + using combinators known as tacticals. Tactics process sets of formulas called Goals. + + When a tactic is applied to some goal G, four different outcomes are possible. The tactic succeeds + in showing G to be satisfiable (i.e., feasible); succeeds in showing G to be unsatisfiable (i.e., infeasible); + produces a sequence of subgoals; or fails. When reducing a goal G to a sequence of subgoals G1, ..., Gn, + we face the problem of model conversion. A model converter construct a model for G using a model for some subgoal Gi. + + In this example, we create a goal g consisting of three formulas, and a tactic t composed of two built-in tactics: + simplify and solve-eqs. The tactic simplify apply transformations equivalent to the ones found in the command simplify. + The tactic solver-eqs eliminate variables using Gaussian elimination. Actually, solve-eqs is not restricted + only to linear arithmetic. It can also eliminate arbitrary variables. + Then, sequential composition combinator & applies simplify to the input goal and solve-eqs to each subgoal produced by simplify. + In this example, only one subgoal is produced. + */ + std::cout << "tactic example 1\n"; + context c; + expr x = c.real_const("x"); + expr y = c.real_const("y"); + goal g(c); + g.add(x > 0); + g.add(y > 0); + g.add(x == y + 2); + std::cout << g << "\n"; + tactic t1(c, "simplify"); + tactic t2(c, "solve-eqs"); + tactic t = t1 & t2; + apply_result r = t(g); + std::cout << r << "\n"; +} + +void tactic_example2() { + /* + In Z3, we say a clause is any constraint of the form (f_1 || ... || f_n). + The tactic split-clause will select a clause in the input goal, and split it n subgoals. + One for each subformula f_i. + */ + std::cout << "tactic example 2\n"; + context c; + expr x = c.real_const("x"); + expr y = c.real_const("y"); + goal g(c); + g.add(x < 0 || x > 0); + g.add(x == y + 1); + g.add(y < 0); + tactic t(c, "split-clause"); + apply_result r = t(g); + for (unsigned i = 0; i < r.size(); i++) { + std::cout << "subgoal " << i << "\n" << r[i] << "\n"; + } +} + +void tactic_example3() { + /* + - The choice combinator t | s first applies t to the given goal, if it fails then returns the result of s applied to the given goal. + - repeat(t) Keep applying the given tactic until no subgoal is modified by it. + - repeat(t, n) Keep applying the given tactic until no subgoal is modified by it, or the number of iterations is greater than n. + - try_for(t, ms) Apply tactic t to the input goal, if it does not return in ms millisenconds, it fails. + - with(t, params) Apply the given tactic using the given parameters. + */ + std::cout << "tactic example 3\n"; + context c; + expr x = c.real_const("x"); + expr y = c.real_const("y"); + expr z = c.real_const("z"); + goal g(c); + g.add(x == 0 || x == 1); + g.add(y == 0 || y == 1); + g.add(z == 0 || z == 1); + g.add(x + y + z > 2); + // split all clauses + tactic split_all = repeat(tactic(c, "split-clause") | tactic(c, "skip")); + std::cout << split_all(g) << "\n"; + tactic split_at_most_2 = repeat(tactic(c, "split-clause") | tactic(c, "skip"), 1); + std::cout << split_at_most_2(g) << "\n"; + // In the tactic split_solver, the tactic solve-eqs discharges all but one goal. + // Note that, this tactic generates one goal: the empty goal which is trivially satisfiable (i.e., feasible) + tactic split_solve = split_all & tactic(c, "solve-eqs"); + std::cout << split_solve(g) << "\n"; +} + +void tactic_example4() { + /* + A tactic can be converted into a solver object using the method mk_solver(). + If the tactic produces the empty goal, then the associated solver returns sat. + If the tactic produces a single goal containing False, then the solver returns unsat. + Otherwise, it returns unknown. + + In this example, the tactic t implements a basic bit-vector solver using equation solving, + bit-blasting, and a propositional SAT solver. + We use the combinator `with` to configure our little solver. + We also include the tactic `aig` which tries to compress Boolean formulas using And-Inverted Graphs. + */ + std::cout << "tactic example 4\n"; + context c; + params p(c); + p.set(":mul2concat", true); + tactic t = + with(tactic(c, "simplify"), p) & + tactic(c, "solve-eqs") & + tactic(c, "bit-blast") & + tactic(c, "aig") & + tactic(c, "sat"); + solver s = t.mk_solver(); + expr x = c.bv_const("x", 16); + expr y = c.bv_const("y", 16); + s.add(x*32 + y == 13); + // In C++, the operator < has higher precedence than &. + s.add((x & y) < 10); + s.add(y > -100); + std::cout << s.check() << "\n"; + model m = s.get_model(); + std::cout << m << "\n"; + std::cout << "x*32 + y = " << m.eval(x*32 + y) << "\n"; + std::cout << "x & y = " << m.eval(x & y) << "\n"; +} + +void tactic_example5() { + /* + The tactic smt wraps the main solver in Z3 as a tactic. + */ + std::cout << "tactic example 5\n"; + context c; + expr x = c.int_const("x"); + expr y = c.int_const("y"); + solver s = tactic(c, "smt").mk_solver(); + s.add(x > y + 1); + std::cout << s.check() << "\n"; + std::cout << s.get_model() << "\n"; +} + +void tactic_example6() { + /* + In this example, we show how to implement a solver for integer arithmetic using SAT. + The solver is complete only for problems where every variable has a lower and upper bound. + */ + std::cout << "tactic example 6\n"; + context c; + params p(c); + p.set(":arith-lhs", true); + p.set(":som", true); // sum-of-monomials normal form + solver s = + (with(tactic(c, "simplify"), p) & + tactic(c, "normalize-bounds") & + tactic(c, "lia2pb") & + tactic(c, "pb2bv") & + tactic(c, "bit-blast") & + tactic(c, "sat")).mk_solver(); + expr x = c.int_const("x"); + expr y = c.int_const("y"); + expr z = c.int_const("z"); + s.add(x > 0 && x < 10); + s.add(y > 0 && y < 10); + s.add(z > 0 && z < 10); + s.add(3*y + 2*x == z); + std::cout << s.check() << "\n"; + std::cout << s.get_model() << "\n"; + s.reset(); + s.add(3*y + 2*x == z); + std::cout << s.check() << "\n"; +} + +void tactic_example7() { + /* + Tactics can be combined with solvers. + For example, we can apply a tactic to a goal, produced a set of subgoals, + then select one of the subgoals and solve it using a solver. + This example demonstrates how to do that, and + how to use model converters to convert a model for a subgoal into a model for the original goal. + */ + std::cout << "tactic example 7\n"; + context c; + tactic t = + tactic(c, "simplify") & + tactic(c, "normalize-bounds") & + tactic(c, "solve-eqs"); + expr x = c.int_const("x"); + expr y = c.int_const("y"); + expr z = c.int_const("z"); + goal g(c); + g.add(x > 10); + g.add(y == x + 3); + g.add(z > y); + apply_result r = t(g); + // r contains only one subgoal + std::cout << r << "\n"; + solver s(c); + goal subgoal = r[0]; + for (unsigned i = 0; i < subgoal.size(); i++) { + s.add(subgoal[i]); + } + std::cout << s.check() << "\n"; + model m = s.get_model(); + std::cout << "model for subgoal:\n" << m << "\n"; + std::cout << "model for original goal:\n" << r.convert_model(m) << "\n"; +} + +void tactic_example8() { + /* + Probes (aka formula measures) are evaluated over goals. + Boolean expressions over them can be built using relational operators and Boolean connectives. + The tactic fail_if(cond) fails if the given goal does not satisfy the condition cond. + Many numeric and Boolean measures are available in Z3. + + In this example, we build a simple tactic using fail_if. + It also shows that a probe can be applied directly to a goal. + */ + std::cout << "tactic example 8\n"; + context c; + + expr x = c.int_const("x"); + expr y = c.int_const("y"); + expr z = c.int_const("z"); + + goal g(c); + g.add(x + y + z > 0); + + probe p(c, "num-consts"); + std::cout << "num-consts: " << p(g) << "\n"; + + tactic t = fail_if(p > 2); + try { + t(g); + } + catch (exception) { + std::cout << "tactic failed...\n"; + } + std::cout << "trying again...\n"; + g.reset(); + g.add(x + y > 0); + std::cout << t(g) << "\n"; +} + +void tactic_example9() { + /* + The combinator (tactical) cond(p, t1, t2) is a shorthand for: + + (fail_if(p) & t1) | t2 + + The combinator when(p, t) is a shorthand for: + + cond(p, t, tactic(c, "skip")) + + The tactic skip just returns the input goal. + This example demonstrates how to use the cond combinator. + */ + std::cout << "tactic example 9\n"; + context c; + + expr x = c.int_const("x"); + expr y = c.int_const("y"); + expr z = c.int_const("z"); + + goal g(c); + g.add(x*x - y*y >= 0); + + probe p(c, "num-consts"); + tactic t = cond(p > 2, tactic(c, "simplify"), tactic(c, "factor")); + std::cout << t(g) << "\n"; + + g.reset(); + g.add(x + x + y + z >= 0); + g.add(x*x - y*y >= 0); + std::cout << t(g) << "\n"; +} + +void visit(expr const & e) { + if (e.is_app()) { + unsigned num = e.num_args(); + for (unsigned i = 0; i < num; i++) { + visit(e.arg(i)); + } + // do something + // Example: print the visited expression + func_decl f = e.decl(); + std::cout << "application of " << f.name() << ": " << e << "\n"; + } + else if (e.is_quantifier()) { + visit(e.body()); + // do something + } + else { + assert(e.is_var()); + // do something + } +} + +void tst_visit() { + std::cout << "visit example\n"; + context c; + + expr x = c.int_const("x"); + expr y = c.int_const("y"); + expr z = c.int_const("z"); + expr f = x*x - y*y >= 0; + + visit(f); +} + +int main() { + try { + demorgan(); std::cout << "\n"; + find_model_example1(); std::cout << "\n"; + prove_example1(); std::cout << "\n"; + prove_example2(); std::cout << "\n"; + nonlinear_example1(); std::cout << "\n"; + bitvector_example1(); std::cout << "\n"; + bitvector_example2(); std::cout << "\n"; + capi_example(); std::cout << "\n"; + eval_example1(); std::cout << "\n"; + two_contexts_example1(); std::cout << "\n"; + error_example(); std::cout << "\n"; + numeral_example(); std::cout << "\n"; + ite_example(); std::cout << "\n"; + unsat_core_example(); std::cout << "\n"; + tactic_example1(); std::cout << "\n"; + tactic_example2(); std::cout << "\n"; + tactic_example3(); std::cout << "\n"; + tactic_example4(); std::cout << "\n"; + tactic_example5(); std::cout << "\n"; + tactic_example6(); std::cout << "\n"; + tactic_example7(); std::cout << "\n"; + tactic_example8(); std::cout << "\n"; + tactic_example9(); std::cout << "\n"; + tst_visit(); std::cout << "\n"; + std::cout << "done\n"; + } + catch (exception & ex) { + std::cout << "unexpected error: " << ex << "\n"; + } + return 0; +} diff --git a/c++/exec-external-linux.sh b/c++/exec-external-linux.sh new file mode 100644 index 000000000..f46e9ea89 --- /dev/null +++ b/c++/exec-external-linux.sh @@ -0,0 +1,2 @@ +export LD_LIBRARY_PATH=../../lib:$LD_LIBRARY_PATH +./example diff --git a/c++/exec-external-osx.sh b/c++/exec-external-osx.sh new file mode 100644 index 000000000..9f9762b54 --- /dev/null +++ b/c++/exec-external-osx.sh @@ -0,0 +1,2 @@ +export DYLD_LIBRARY_PATH=../../lib:$DYLD_LIBRARY_PATH +./example diff --git a/c++/exec-external.cmd b/c++/exec-external.cmd new file mode 100644 index 000000000..8a5d53453 --- /dev/null +++ b/c++/exec-external.cmd @@ -0,0 +1,5 @@ +@echo off +SETLOCAL +set PATH=..\..\bin;%PATH% +example.exe +ENDLOCAL diff --git a/c++/exec-external.sh b/c++/exec-external.sh new file mode 100644 index 000000000..39e7eb58c --- /dev/null +++ b/c++/exec-external.sh @@ -0,0 +1,2 @@ +export PATH=../../bin:$PATH +./example.exe diff --git a/c++/z3++.h b/c++/z3++.h new file mode 100644 index 000000000..5d85b09c4 --- /dev/null +++ b/c++/z3++.h @@ -0,0 +1,1342 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + + Thin C++ layer on top of the Z3 C API. + Main features: + - Smart pointers for all Z3 objects. + - Object-Oriented interface. + - Operator overloading. + - Exceptions for signining Z3 errors + + The C API can be used simultaneously with the C++ layer. + However, if you use the C API directly, you will have to check the error conditions manually. + Of course, you can invoke the method check_error() of the context object. +Author: + + Leonardo (leonardo) 2012-03-28 + +Notes: + +--*/ +#ifndef __Z3PP_H_ +#define __Z3PP_H_ + +#include +#include +#include +#include +#include +#include + +namespace z3 { + + class exception; + class config; + class context; + class symbol; + class params; + class ast; + class sort; + class func_decl; + class expr; + class solver; + class goal; + class tactic; + class probe; + class model; + class func_interp; + class func_entry; + class statistics; + class apply_result; + class fixedpoint; + + /** + \brief Exception used to sign API usage errors. + */ + class exception { + std::string m_msg; + public: + exception(char const * msg):m_msg(msg) {} + char const * msg() const { return m_msg.c_str(); } + friend std::ostream & operator<<(std::ostream & out, exception const & e) { out << e.msg(); return out; } + }; + + /** + \brief Z3 global configuration object. + */ + class config { + Z3_config m_cfg; + config(config const & s); + config & operator=(config const & s); + public: + config() { m_cfg = Z3_mk_config(); } + ~config() { Z3_del_config(m_cfg); } + operator Z3_config() const { return m_cfg; } + /** + \brief Add a global configuration. + */ + void set(char const * param, char const * value) { Z3_set_param_value(m_cfg, param, value); } + void set(char const * param, bool value) { Z3_set_param_value(m_cfg, param, value ? "true" : "false"); } + void set(char const * param, int value) { + std::ostringstream oss; + oss << value; + Z3_set_param_value(m_cfg, param, oss.str().c_str()); + } + }; + + /** + \brief A Context manages all other Z3 objects, global configuration options, etc. + */ + class context { + Z3_context m_ctx; + static void error_handler(Z3_context c, Z3_error_code e) { /* do nothing */ } + void init(config & c) { + m_ctx = Z3_mk_context_rc(c); + Z3_set_error_handler(m_ctx, error_handler); + Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT); + } + context(context const & s); + context & operator=(context const & s); + public: + context() { config c; init(c); } + context(config & c) { init(c); } + ~context() { Z3_del_context(m_ctx); } + operator Z3_context() const { return m_ctx; } + + /** + \brief Auxiliary method used to check for API usage errors. + */ + void check_error() const { + Z3_error_code e = Z3_get_error_code(m_ctx); + if (e != Z3_OK) + throw exception(Z3_get_error_msg_ex(m_ctx, e)); + } + + void set(char const * param, char const * value) { Z3_update_param_value(m_ctx, param, value); } + void set(char const * param, bool value) { Z3_update_param_value(m_ctx, param, value ? "true" : "false"); } + void set(char const * param, int value) { + std::ostringstream oss; + oss << value; + Z3_update_param_value(m_ctx, param, oss.str().c_str()); + } + + void interrupt() { Z3_interrupt(m_ctx); } + + symbol str_symbol(char const * s); + symbol int_symbol(int n); + + sort bool_sort(); + sort int_sort(); + sort real_sort(); + sort bv_sort(unsigned sz); + sort array_sort(sort d, sort r); + + func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range); + func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range); + func_decl function(char const * name, sort const & domain, sort const & range); + func_decl function(char const * name, sort const & d1, sort const & d2, sort const & range); + func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & range); + func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & range); + func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & d5, sort const & range); + + expr constant(symbol const & name, sort const & s); + expr constant(char const * name, sort const & s); + expr bool_const(char const * name); + expr int_const(char const * name); + expr real_const(char const * name); + expr bv_const(char const * name, unsigned sz); + + expr bool_val(bool b); + + expr int_val(int n); + expr int_val(unsigned n); + expr int_val(__int64 n); + expr int_val(__uint64 n); + expr int_val(char const * n); + + expr real_val(int n, int d); + expr real_val(int n); + expr real_val(unsigned n); + expr real_val(__int64 n); + expr real_val(__uint64 n); + expr real_val(char const * n); + + expr bv_val(int n, unsigned sz); + expr bv_val(unsigned n, unsigned sz); + expr bv_val(__int64 n, unsigned sz); + expr bv_val(__uint64 n, unsigned sz); + expr bv_val(char const * n, unsigned sz); + + expr num_val(int n, sort const & s); + }; + + template + class array { + T * m_array; + unsigned m_size; + array(array const & s); + array & operator=(array const & s); + public: + array(unsigned sz):m_size(sz) { m_array = new T[sz]; } + ~array() { delete[] m_array; } + unsigned size() const { return m_size; } + T & operator[](unsigned i) { assert(i < m_size); return m_array[i]; } + T const & operator[](unsigned i) const { assert(i < m_size); return m_array[i]; } + T const * ptr() const { return m_array; } + T * ptr() { return m_array; } + }; + + class object { + protected: + context * m_ctx; + public: + object(context & c):m_ctx(&c) {} + object(object const & s):m_ctx(s.m_ctx) {} + context & ctx() const { return *m_ctx; } + void check_error() const { m_ctx->check_error(); } + friend void check_context(object const & a, object const & b) { assert(a.m_ctx == b.m_ctx); } + }; + + class symbol : public object { + Z3_symbol m_sym; + public: + symbol(context & c, Z3_symbol s):object(c), m_sym(s) {} + symbol(symbol const & s):object(s), m_sym(s.m_sym) {} + symbol & operator=(symbol const & s) { m_ctx = s.m_ctx; m_sym = s.m_sym; return *this; } + operator Z3_symbol() const { return m_sym; } + Z3_symbol_kind kind() const { return Z3_get_symbol_kind(ctx(), m_sym); } + std::string str() const { assert(kind() == Z3_STRING_SYMBOL); return Z3_get_symbol_string(ctx(), m_sym); } + int to_int() const { assert(kind() == Z3_INT_SYMBOL); return Z3_get_symbol_int(ctx(), m_sym); } + friend std::ostream & operator<<(std::ostream & out, symbol const & s) { + if (s.kind() == Z3_INT_SYMBOL) + out << "k!" << s.to_int(); + else + out << s.str().c_str(); + return out; + } + }; + + class params : public object { + Z3_params m_params; + public: + params(context & c):object(c) { m_params = Z3_mk_params(c); Z3_params_inc_ref(ctx(), m_params); } + params(params const & s):object(s), m_params(s.m_params) { Z3_params_inc_ref(ctx(), m_params); } + ~params() { Z3_params_dec_ref(ctx(), m_params); } + operator Z3_params() const { return m_params; } + params & operator=(params const & s) { + Z3_params_inc_ref(s.ctx(), s.m_params); + Z3_params_dec_ref(ctx(), m_params); + m_ctx = s.m_ctx; + m_params = s.m_params; + return *this; + } + void set(char const * k, bool b) { Z3_params_set_bool(ctx(), m_params, ctx().str_symbol(k), b); } + void set(char const * k, unsigned n) { Z3_params_set_uint(ctx(), m_params, ctx().str_symbol(k), n); } + void set(char const * k, double n) { Z3_params_set_double(ctx(), m_params, ctx().str_symbol(k), n); } + void set(char const * k, symbol const & s) { Z3_params_set_symbol(ctx(), m_params, ctx().str_symbol(k), s); } + friend std::ostream & operator<<(std::ostream & out, params const & p) { out << Z3_params_to_string(p.ctx(), p); return out; } + }; + + class ast : public object { + protected: + Z3_ast m_ast; + public: + ast(context & c):object(c), m_ast(0) {} + ast(context & c, Z3_ast n):object(c), m_ast(n) { Z3_inc_ref(ctx(), m_ast); } + ast(ast const & s):object(s), m_ast(s.m_ast) { Z3_inc_ref(ctx(), m_ast); } + ~ast() { if (m_ast) Z3_dec_ref(*m_ctx, m_ast); } + operator Z3_ast() const { return m_ast; } + ast & operator=(ast const & s) { Z3_inc_ref(s.ctx(), s.m_ast); if (m_ast) Z3_dec_ref(ctx(), m_ast); m_ctx = s.m_ctx; m_ast = s.m_ast; return *this; } + Z3_ast_kind kind() const { Z3_ast_kind r = Z3_get_ast_kind(ctx(), m_ast); check_error(); return r; } + unsigned hash() const { unsigned r = Z3_get_ast_hash(ctx(), m_ast); check_error(); return r; } + friend std::ostream & operator<<(std::ostream & out, ast const & n) { out << Z3_ast_to_string(n.ctx(), n.m_ast); return out; } + + /** + \brief Return true if the ASTs are structurally identical. + */ + friend bool eq(ast const & a, ast const & b) { return Z3_is_eq_ast(a.ctx(), a, b) != 0; } + }; + + class sort : public ast { + public: + sort(context & c):ast(c) {} + sort(context & c, Z3_sort s):ast(c, reinterpret_cast(s)) {} + sort(sort const & s):ast(s) {} + operator Z3_sort() const { return reinterpret_cast(m_ast); } + sort & operator=(sort const & s) { return static_cast(ast::operator=(s)); } + Z3_sort_kind sort_kind() const { return Z3_get_sort_kind(*m_ctx, *this); } + + bool is_bool() const { return sort_kind() == Z3_BOOL_SORT; } + bool is_int() const { return sort_kind() == Z3_INT_SORT; } + bool is_real() const { return sort_kind() == Z3_REAL_SORT; } + bool is_arith() const { return is_int() || is_real(); } + bool is_bv() const { return sort_kind() == Z3_BV_SORT; } + bool is_array() const { return sort_kind() == Z3_ARRAY_SORT; } + bool is_datatype() const { return sort_kind() == Z3_DATATYPE_SORT; } + bool is_relation() const { return sort_kind() == Z3_RELATION_SORT; } + bool is_finite_domain() const { return sort_kind() == Z3_FINITE_DOMAIN_SORT; } + + unsigned bv_size() const { assert(is_bv()); unsigned r = Z3_get_bv_sort_size(ctx(), *this); check_error(); return r; } + + sort array_domain() const { assert(is_array()); Z3_sort s = Z3_get_array_sort_domain(ctx(), *this); check_error(); return sort(ctx(), s); } + sort array_range() const { assert(is_array()); Z3_sort s = Z3_get_array_sort_range(ctx(), *this); check_error(); return sort(ctx(), s); } + }; + + class func_decl : public ast { + public: + func_decl(context & c):ast(c) {} + func_decl(context & c, Z3_func_decl n):ast(c, reinterpret_cast(n)) {} + func_decl(func_decl const & s):ast(s) {} + operator Z3_func_decl() const { return reinterpret_cast(m_ast); } + func_decl & operator=(func_decl const & s) { return static_cast(ast::operator=(s)); } + + unsigned arity() const { return Z3_get_arity(ctx(), *this); } + sort domain(unsigned i) const { assert(i < arity()); Z3_sort r = Z3_get_domain(ctx(), *this, i); check_error(); return sort(ctx(), r); } + sort range() const { Z3_sort r = Z3_get_range(ctx(), *this); check_error(); return sort(ctx(), r); } + symbol name() const { Z3_symbol s = Z3_get_decl_name(ctx(), *this); check_error(); return symbol(ctx(), s); } + Z3_decl_kind decl_kind() const { return Z3_get_decl_kind(ctx(), *this); } + + bool is_const() const { return arity() == 0; } + + expr operator()(unsigned n, expr const * args) const; + expr operator()(expr const & a) const; + expr operator()(int a) const; + expr operator()(expr const & a1, expr const & a2) const; + expr operator()(expr const & a1, int a2) const; + expr operator()(int a1, expr const & a2) const; + expr operator()(expr const & a1, expr const & a2, expr const & a3) const; + expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const; + expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const; + }; + + class expr : public ast { + public: + expr(context & c):ast(c) {} + expr(context & c, Z3_ast n):ast(c, reinterpret_cast(n)) {} + expr(expr const & n):ast(n) {} + expr & operator=(expr const & n) { return static_cast(ast::operator=(n)); } + + sort get_sort() const { Z3_sort s = Z3_get_sort(*m_ctx, m_ast); check_error(); return sort(*m_ctx, s); } + + bool is_bool() const { return get_sort().is_bool(); } + bool is_int() const { return get_sort().is_int(); } + bool is_real() const { return get_sort().is_real(); } + bool is_arith() const { return get_sort().is_arith(); } + bool is_bv() const { return get_sort().is_bv(); } + bool is_array() const { return get_sort().is_array(); } + bool is_datatype() const { return get_sort().is_datatype(); } + bool is_relation() const { return get_sort().is_relation(); } + bool is_finite_domain() const { return get_sort().is_finite_domain(); } + + bool is_numeral() const { return kind() == Z3_NUMERAL_AST; } + bool is_app() const { return kind() == Z3_APP_AST || kind() == Z3_NUMERAL_AST; } + bool is_quantifier() const { return kind() == Z3_QUANTIFIER_AST; } + bool is_var() const { return kind() == Z3_VAR_AST; } + + bool is_well_sorted() const { bool r = Z3_is_well_sorted(ctx(), m_ast) != 0; check_error(); return r; } + + operator Z3_app() const { assert(is_app()); return reinterpret_cast(m_ast); } + func_decl decl() const { Z3_func_decl f = Z3_get_app_decl(ctx(), *this); check_error(); return func_decl(ctx(), f); } + unsigned num_args() const { unsigned r = Z3_get_app_num_args(ctx(), *this); check_error(); return r; } + expr arg(unsigned i) const { Z3_ast r = Z3_get_app_arg(ctx(), *this, i); check_error(); return expr(ctx(), r); } + + expr body() const { assert(is_quantifier()); Z3_ast r = Z3_get_quantifier_body(ctx(), *this); check_error(); return expr(ctx(), r); } + + friend expr operator!(expr const & a) { + assert(a.is_bool()); + Z3_ast r = Z3_mk_not(a.ctx(), a); + a.check_error(); + return expr(a.ctx(), r); + } + + friend expr operator&&(expr const & a, expr const & b) { + check_context(a, b); + assert(a.is_bool() && b.is_bool()); + Z3_ast args[2] = { a, b }; + Z3_ast r = Z3_mk_and(a.ctx(), 2, args); + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator&&(expr const & a, bool b) { return a && a.ctx().bool_val(b); } + friend expr operator&&(bool a, expr const & b) { return b.ctx().bool_val(a) && b; } + + friend expr operator||(expr const & a, expr const & b) { + check_context(a, b); + assert(a.is_bool() && b.is_bool()); + Z3_ast args[2] = { a, b }; + Z3_ast r = Z3_mk_or(a.ctx(), 2, args); + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator||(expr const & a, bool b) { return a || a.ctx().bool_val(b); } + friend expr operator||(bool a, expr const & b) { return b.ctx().bool_val(a) || b; } + + friend expr implies(expr const & a, expr const & b) { + check_context(a, b); + assert(a.is_bool() && b.is_bool()); + Z3_ast r = Z3_mk_implies(a.ctx(), a, b); + a.check_error(); + return expr(a.ctx(), r); + } + + friend expr operator==(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r = Z3_mk_eq(a.ctx(), a, b); + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator==(expr const & a, int b) { assert(a.is_arith() || a.is_bv()); return a == a.ctx().num_val(b, a.get_sort()); } + friend expr operator==(int a, expr const & b) { assert(b.is_arith() || b.is_bv()); return b.ctx().num_val(a, b.get_sort()) == b; } + + friend expr operator!=(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast args[2] = { a, b }; + Z3_ast r = Z3_mk_distinct(a.ctx(), 2, args); + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator!=(expr const & a, int b) { assert(a.is_arith() || a.is_bv()); return a != a.ctx().num_val(b, a.get_sort()); } + friend expr operator!=(int a, expr const & b) { assert(b.is_arith() || b.is_bv()); return b.ctx().num_val(a, b.get_sort()) != b; } + + friend expr operator+(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r; + if (a.is_arith() && b.is_arith()) { + Z3_ast args[2] = { a, b }; + r = Z3_mk_add(a.ctx(), 2, args); + } + else if (a.is_bv() && b.is_bv()) { + r = Z3_mk_bvadd(a.ctx(), a, b); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator+(expr const & a, int b) { return a + a.ctx().num_val(b, a.get_sort()); } + friend expr operator+(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) + b; } + + friend expr operator*(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r; + if (a.is_arith() && b.is_arith()) { + Z3_ast args[2] = { a, b }; + r = Z3_mk_mul(a.ctx(), 2, args); + } + else if (a.is_bv() && b.is_bv()) { + r = Z3_mk_bvmul(a.ctx(), a, b); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator*(expr const & a, int b) { return a * a.ctx().num_val(b, a.get_sort()); } + friend expr operator*(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) * b; } + + /** + \brief Power operator + */ + friend expr pw(expr const & a, expr const & b) { + assert(a.is_arith() && b.is_arith()); + check_context(a, b); + Z3_ast r = Z3_mk_power(a.ctx(), a, b); + a.check_error(); + return expr(a.ctx(), r); + } + friend expr pw(expr const & a, int b) { return pw(a, a.ctx().num_val(b, a.get_sort())); } + friend expr pw(int a, expr const & b) { return pw(b.ctx().num_val(a, b.get_sort()), b); } + + friend expr operator/(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r; + if (a.is_arith() && b.is_arith()) { + r = Z3_mk_div(a.ctx(), a, b); + } + else if (a.is_bv() && b.is_bv()) { + r = Z3_mk_bvsdiv(a.ctx(), a, b); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator/(expr const & a, int b) { return a / a.ctx().num_val(b, a.get_sort()); } + friend expr operator/(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) / b; } + + friend expr operator-(expr const & a) { + Z3_ast r; + if (a.is_arith()) { + r = Z3_mk_unary_minus(a.ctx(), a); + } + else if (a.is_bv()) { + r = Z3_mk_bvneg(a.ctx(), a); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + + friend expr operator-(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r; + if (a.is_arith() && b.is_arith()) { + Z3_ast args[2] = { a, b }; + r = Z3_mk_sub(a.ctx(), 2, args); + } + else if (a.is_bv() && b.is_bv()) { + r = Z3_mk_bvsub(a.ctx(), a, b); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator-(expr const & a, int b) { return a - a.ctx().num_val(b, a.get_sort()); } + friend expr operator-(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) - a; } + + friend expr operator<=(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r; + if (a.is_arith() && b.is_arith()) { + r = Z3_mk_le(a.ctx(), a, b); + } + else if (a.is_bv() && b.is_bv()) { + r = Z3_mk_bvsle(a.ctx(), a, b); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator<=(expr const & a, int b) { return a <= a.ctx().num_val(b, a.get_sort()); } + friend expr operator<=(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) <= a; } + + friend expr operator>=(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r; + if (a.is_arith() && b.is_arith()) { + r = Z3_mk_ge(a.ctx(), a, b); + } + else if (a.is_bv() && b.is_bv()) { + r = Z3_mk_bvsge(a.ctx(), a, b); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator>=(expr const & a, int b) { return a >= a.ctx().num_val(b, a.get_sort()); } + friend expr operator>=(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) >= a; } + + friend expr operator<(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r; + if (a.is_arith() && b.is_arith()) { + r = Z3_mk_lt(a.ctx(), a, b); + } + else if (a.is_bv() && b.is_bv()) { + r = Z3_mk_bvslt(a.ctx(), a, b); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator<(expr const & a, int b) { return a < a.ctx().num_val(b, a.get_sort()); } + friend expr operator<(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) < a; } + + friend expr operator>(expr const & a, expr const & b) { + check_context(a, b); + Z3_ast r; + if (a.is_arith() && b.is_arith()) { + r = Z3_mk_gt(a.ctx(), a, b); + } + else if (a.is_bv() && b.is_bv()) { + r = Z3_mk_bvsgt(a.ctx(), a, b); + } + else { + // operator is not supported by given arguments. + assert(false); + } + a.check_error(); + return expr(a.ctx(), r); + } + friend expr operator>(expr const & a, int b) { return a > a.ctx().num_val(b, a.get_sort()); } + friend expr operator>(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) > a; } + + friend expr operator&(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = Z3_mk_bvand(a.ctx(), a, b); return expr(a.ctx(), r); } + friend expr operator&(expr const & a, int b) { return a & a.ctx().num_val(b, a.get_sort()); } + friend expr operator&(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) & b; } + + friend expr operator^(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = Z3_mk_bvxor(a.ctx(), a, b); return expr(a.ctx(), r); } + friend expr operator^(expr const & a, int b) { return a ^ a.ctx().num_val(b, a.get_sort()); } + friend expr operator^(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) ^ b; } + + friend expr operator|(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = Z3_mk_bvor(a.ctx(), a, b); return expr(a.ctx(), r); } + friend expr operator|(expr const & a, int b) { return a | a.ctx().num_val(b, a.get_sort()); } + friend expr operator|(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) | b; } + + friend expr operator~(expr const & a) { Z3_ast r = Z3_mk_bvnot(a.ctx(), a); return expr(a.ctx(), r); } + + expr simplify() const { Z3_ast r = Z3_simplify(ctx(), m_ast); check_error(); return expr(ctx(), r); } + expr simplify(params const & p) const { Z3_ast r = Z3_simplify_ex(ctx(), m_ast, p); check_error(); return expr(ctx(), r); } + }; + + /** + \brief Wraps a Z3_ast as an expr object. It also checks for errors. + This function allows the user to use the whole C API with the C++ layer defined in this file. + */ + inline expr to_expr(context & c, Z3_ast a) { + c.check_error(); + assert(Z3_get_ast_kind(c, a) == Z3_APP_AST || + Z3_get_ast_kind(c, a) == Z3_NUMERAL_AST || + Z3_get_ast_kind(c, a) == Z3_VAR_AST || + Z3_get_ast_kind(c, a) == Z3_QUANTIFIER_AST); + return expr(c, a); + } + + inline sort to_sort(context & c, Z3_sort s) { + c.check_error(); + return sort(c, s); + } + + inline func_decl to_func_decl(context & c, Z3_func_decl f) { + c.check_error(); + return func_decl(c, f); + } + + /** + \brief unsigned less than or equal to operator for bitvectors. + */ + inline expr ule(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvule(a.ctx(), a, b)); } + inline expr ule(expr const & a, int b) { return ule(a, a.ctx().num_val(b, a.get_sort())); } + inline expr ule(int a, expr const & b) { return ule(b.ctx().num_val(a, b.get_sort()), a); } + /** + \brief unsigned less than operator for bitvectors. + */ + inline expr ult(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvult(a.ctx(), a, b)); } + inline expr ult(expr const & a, int b) { return ult(a, a.ctx().num_val(b, a.get_sort())); } + inline expr ult(int a, expr const & b) { return ult(b.ctx().num_val(a, b.get_sort()), a); } + /** + \brief unsigned greater than or equal to operator for bitvectors. + */ + inline expr uge(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvuge(a.ctx(), a, b)); } + inline expr uge(expr const & a, int b) { return uge(a, a.ctx().num_val(b, a.get_sort())); } + inline expr uge(int a, expr const & b) { return uge(b.ctx().num_val(a, b.get_sort()), a); } + /** + \brief unsigned greater than operator for bitvectors. + */ + inline expr ugt(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvugt(a.ctx(), a, b)); } + inline expr ugt(expr const & a, int b) { return ugt(a, a.ctx().num_val(b, a.get_sort())); } + inline expr ugt(int a, expr const & b) { return ugt(b.ctx().num_val(a, b.get_sort()), a); } + /** + \brief unsigned division operator for bitvectors. + */ + inline expr udiv(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvudiv(a.ctx(), a, b)); } + inline expr udiv(expr const & a, int b) { return udiv(a, a.ctx().num_val(b, a.get_sort())); } + inline expr udiv(int a, expr const & b) { return udiv(b.ctx().num_val(a, b.get_sort()), a); } + + template class cast_ast; + + template<> class cast_ast { + public: + ast operator()(context & c, Z3_ast a) { return ast(c, a); } + }; + + template<> class cast_ast { + public: + expr operator()(context & c, Z3_ast a) { + assert(Z3_get_ast_kind(c, a) == Z3_NUMERAL_AST || + Z3_get_ast_kind(c, a) == Z3_APP_AST || + Z3_get_ast_kind(c, a) == Z3_QUANTIFIER_AST || + Z3_get_ast_kind(c, a) == Z3_VAR_AST); + return expr(c, a); + } + }; + + template<> class cast_ast { + public: + sort operator()(context & c, Z3_ast a) { + assert(Z3_get_ast_kind(c, a) == Z3_SORT_AST); + return sort(c, reinterpret_cast(a)); + } + }; + + template<> class cast_ast { + public: + func_decl operator()(context & c, Z3_ast a) { + assert(Z3_get_ast_kind(c, a) == Z3_FUNC_DECL_AST); + return func_decl(c, reinterpret_cast(a)); + } + }; + + template + class ast_vector_tpl : public object { + Z3_ast_vector m_vector; + void init(Z3_ast_vector v) { Z3_ast_vector_inc_ref(ctx(), v); m_vector = v; } + public: + ast_vector_tpl(context & c):object(c) { init(Z3_mk_ast_vector(c)); } + ast_vector_tpl(context & c, Z3_ast_vector v):object(c) { init(v); } + ast_vector_tpl(ast_vector_tpl const & s):object(s), m_vector(s.m_vector) { Z3_ast_vector_inc_ref(ctx(), m_vector); } + ~ast_vector_tpl() { Z3_ast_vector_dec_ref(ctx(), m_vector); } + operator Z3_ast_vector() const { return m_vector; } + unsigned size() const { return Z3_ast_vector_size(ctx(), m_vector); } + T operator[](unsigned i) const { Z3_ast r = Z3_ast_vector_get(ctx(), m_vector, i); check_error(); return cast_ast()(ctx(), r); } + void push_back(T const & e) { Z3_ast_vector_push(ctx(), m_vector, e); check_error(); } + void resize(unsigned sz) { Z3_ast_vector_resize(ctx(), m_vector, sz); check_error(); } + T back() const { return operator[](size() - 1); } + void pop_back() { assert(size() > 0); resize(size() - 1); } + bool empty() const { return size() == 0; } + ast_vector_tpl & operator=(ast_vector_tpl const & s) { + Z3_ast_vector_inc_ref(s.ctx(), s.m_vector); + Z3_ast_vector_dec_ref(ctx(), m_vector); + m_ctx = s.m_ctx; + m_vector = s.m_vector; + return *this; + } + friend std::ostream & operator<<(std::ostream & out, ast_vector_tpl const & v) { out << Z3_ast_vector_to_string(v.ctx(), v); return out; } + }; + + typedef ast_vector_tpl ast_vector; + typedef ast_vector_tpl expr_vector; + typedef ast_vector_tpl sort_vector; + typedef ast_vector_tpl func_decl_vector; + + class func_entry : public object { + Z3_func_entry m_entry; + void init(Z3_func_entry e) { + m_entry = e; + Z3_func_entry_inc_ref(ctx(), m_entry); + } + public: + func_entry(context & c, Z3_func_entry e):object(c) { init(e); } + func_entry(func_entry const & s):object(s) { init(s.m_entry); } + ~func_entry() { Z3_func_entry_dec_ref(ctx(), m_entry); } + operator Z3_func_entry() const { return m_entry; } + func_entry & operator=(func_entry const & s) { + Z3_func_entry_inc_ref(s.ctx(), s.m_entry); + Z3_func_entry_dec_ref(ctx(), m_entry); + m_ctx = s.m_ctx; + m_entry = s.m_entry; + return *this; + } + expr value() const { Z3_ast r = Z3_func_entry_get_value(ctx(), m_entry); check_error(); return expr(ctx(), r); } + unsigned num_args() const { unsigned r = Z3_func_entry_get_num_args(ctx(), m_entry); check_error(); return r; } + expr arg(unsigned i) const { Z3_ast r = Z3_func_entry_get_arg(ctx(), m_entry, i); check_error(); return expr(ctx(), r); } + }; + + class func_interp : public object { + Z3_func_interp m_interp; + void init(Z3_func_interp e) { + m_interp = e; + Z3_func_interp_inc_ref(ctx(), m_interp); + } + public: + func_interp(context & c, Z3_func_interp e):object(c) { init(e); } + func_interp(func_interp const & s):object(s) { init(s.m_interp); } + ~func_interp() { Z3_func_interp_dec_ref(ctx(), m_interp); } + operator Z3_func_interp() const { return m_interp; } + func_interp & operator=(func_interp const & s) { + Z3_func_interp_inc_ref(s.ctx(), s.m_interp); + Z3_func_interp_dec_ref(ctx(), m_interp); + m_ctx = s.m_ctx; + m_interp = s.m_interp; + return *this; + } + expr else_value() const { Z3_ast r = Z3_func_interp_get_else(ctx(), m_interp); check_error(); return expr(ctx(), r); } + unsigned num_entries() const { unsigned r = Z3_func_interp_get_num_entries(ctx(), m_interp); check_error(); return r; } + func_entry entry(unsigned i) const { Z3_func_entry e = Z3_func_interp_get_entry(ctx(), m_interp, i); check_error(); return func_entry(ctx(), e); } + }; + + class model : public object { + Z3_model m_model; + void init(Z3_model m) { + m_model = m; + Z3_model_inc_ref(ctx(), m); + } + public: + model(context & c, Z3_model m):object(c) { init(m); } + model(model const & s):object(s) { init(s.m_model); } + ~model() { Z3_model_dec_ref(ctx(), m_model); } + operator Z3_model() const { return m_model; } + model & operator=(model const & s) { + Z3_model_inc_ref(s.ctx(), s.m_model); + Z3_model_dec_ref(ctx(), m_model); + m_ctx = s.m_ctx; + m_model = s.m_model; + return *this; + } + + expr eval(expr const & n, bool model_completion=false) const { + check_context(*this, n); + Z3_ast r; + Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r); + check_error(); + if (status == Z3_FALSE) + throw exception("failed to evaluate expression"); + return expr(ctx(), r); + } + + unsigned num_consts() const { return Z3_model_get_num_consts(ctx(), m_model); } + unsigned num_funcs() const { return Z3_model_get_num_funcs(ctx(), m_model); } + func_decl get_const_decl(unsigned i) const { Z3_func_decl r = Z3_model_get_const_decl(ctx(), m_model, i); check_error(); return func_decl(ctx(), r); } + func_decl get_func_decl(unsigned i) const { Z3_func_decl r = Z3_model_get_func_decl(ctx(), m_model, i); check_error(); return func_decl(ctx(), r); } + unsigned size() const { return num_consts() + num_funcs(); } + func_decl operator[](unsigned i) const { return i < num_consts() ? get_const_decl(i) : get_func_decl(i - num_consts()); } + + expr get_const_interp(func_decl c) const { + check_context(*this, c); + Z3_ast r = Z3_model_get_const_interp(ctx(), m_model, c); + check_error(); + return expr(ctx(), r); + } + func_interp get_func_interp(func_decl f) const { + check_context(*this, f); + Z3_func_interp r = Z3_model_get_func_interp(ctx(), m_model, f); + check_error(); + return func_interp(ctx(), r); + } + + friend std::ostream & operator<<(std::ostream & out, model const & m) { out << Z3_model_to_string(m.ctx(), m); return out; } + }; + + class stats : public object { + Z3_stats m_stats; + void init(Z3_stats e) { + m_stats = e; + Z3_stats_inc_ref(ctx(), m_stats); + } + public: + stats(context & c):object(c), m_stats(0) {} + stats(context & c, Z3_stats e):object(c) { init(e); } + stats(stats const & s):object(s) { init(s.m_stats); } + ~stats() { if (m_stats) Z3_stats_dec_ref(ctx(), m_stats); } + operator Z3_stats() const { return m_stats; } + stats & operator=(stats const & s) { + Z3_stats_inc_ref(s.ctx(), s.m_stats); + if (m_stats) Z3_stats_dec_ref(ctx(), m_stats); + m_ctx = s.m_ctx; + m_stats = s.m_stats; + return *this; + } + unsigned size() const { return Z3_stats_size(ctx(), m_stats); } + std::string key(unsigned i) const { Z3_string s = Z3_stats_get_key(ctx(), m_stats, i); check_error(); return s; } + bool is_uint(unsigned i) const { Z3_bool r = Z3_stats_is_uint(ctx(), m_stats, i); check_error(); return r != 0; } + bool is_double(unsigned i) const { Z3_bool r = Z3_stats_is_double(ctx(), m_stats, i); check_error(); return r != 0; } + unsigned uint_value(unsigned i) const { unsigned r = Z3_stats_get_uint_value(ctx(), m_stats, i); check_error(); return r; } + double double_value(unsigned i) const { double r = Z3_stats_get_double_value(ctx(), m_stats, i); check_error(); return r; } + friend std::ostream & operator<<(std::ostream & out, stats const & s) { out << Z3_stats_to_string(s.ctx(), s); return out; } + }; + + enum check_result { + unsat, sat, unknown + }; + + inline std::ostream & operator<<(std::ostream & out, check_result r) { + if (r == unsat) out << "unsat"; + else if (r == sat) out << "sat"; + else out << "unknown"; + return out; + } + + inline check_result to_check_result(Z3_lbool l) { + if (l == Z3_L_TRUE) return sat; + else if (l == Z3_L_FALSE) return unsat; + return unknown; + } + + class solver : public object { + Z3_solver m_solver; + void init(Z3_solver s) { + m_solver = s; + Z3_solver_inc_ref(ctx(), s); + } + public: + solver(context & c):object(c) { init(Z3_mk_solver(c)); } + solver(context & c, Z3_solver s):object(c) { init(s); } + solver(context & c, char const * logic):object(c) { init(Z3_mk_solver_for_logic(c, c.str_symbol(logic))); } + solver(solver const & s):object(s) { init(s.m_solver); } + ~solver() { Z3_solver_dec_ref(ctx(), m_solver); } + operator Z3_solver() const { return m_solver; } + solver & operator=(solver const & s) { + Z3_solver_inc_ref(s.ctx(), s.m_solver); + Z3_solver_dec_ref(ctx(), m_solver); + m_ctx = s.m_ctx; + m_solver = s.m_solver; + return *this; + } + void set(params const & p) { Z3_solver_set_params(ctx(), m_solver, p); check_error(); } + void push() { Z3_solver_push(ctx(), m_solver); check_error(); } + void pop(unsigned n = 1) { Z3_solver_pop(ctx(), m_solver, n); check_error(); } + void reset() { Z3_solver_reset(ctx(), m_solver); check_error(); } + void add(expr const & e) { assert(e.is_bool()); Z3_solver_assert(ctx(), m_solver, e); check_error(); } + check_result check() { Z3_lbool r = Z3_solver_check(ctx(), m_solver); check_error(); return to_check_result(r); } + check_result check(unsigned n, expr * const assumptions) { + array _assumptions(n); + for (unsigned i = 0; i < n; i++) { + check_context(*this, assumptions[i]); + _assumptions[i] = assumptions[i]; + } + Z3_lbool r = Z3_solver_check_assumptions(ctx(), m_solver, n, _assumptions.ptr()); + check_error(); + return to_check_result(r); + } + check_result check(expr_vector assumptions) { + unsigned n = assumptions.size(); + array _assumptions(n); + for (unsigned i = 0; i < n; i++) { + check_context(*this, assumptions[i]); + _assumptions[i] = assumptions[i]; + } + Z3_lbool r = Z3_solver_check_assumptions(ctx(), m_solver, n, _assumptions.ptr()); + check_error(); + return to_check_result(r); + } + model get_model() const { Z3_model m = Z3_solver_get_model(ctx(), m_solver); check_error(); return model(ctx(), m); } + std::string reason_unknown() const { Z3_string r = Z3_solver_get_reason_unknown(ctx(), m_solver); check_error(); return r; } + stats statistics() const { Z3_stats r = Z3_solver_get_statistics(ctx(), m_solver); check_error(); return stats(ctx(), r); } + expr_vector unsat_core() const { Z3_ast_vector r = Z3_solver_get_unsat_core(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); } + expr_vector assertions() const { Z3_ast_vector r = Z3_solver_get_assertions(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); } + expr proof() const { Z3_ast r = Z3_solver_get_proof(ctx(), m_solver); check_error(); return expr(ctx(), r); } + friend std::ostream & operator<<(std::ostream & out, solver const & s) { out << Z3_solver_to_string(s.ctx(), s); return out; } + }; + + class goal : public object { + Z3_goal m_goal; + void init(Z3_goal s) { + m_goal = s; + Z3_goal_inc_ref(ctx(), s); + } + public: + goal(context & c, bool models=true, bool unsat_cores=false, bool proofs=false):object(c) { init(Z3_mk_goal(c, models, unsat_cores, proofs)); } + goal(context & c, Z3_goal s):object(c) { init(s); } + goal(goal const & s):object(s) { init(s.m_goal); } + ~goal() { Z3_goal_dec_ref(ctx(), m_goal); } + operator Z3_goal() const { return m_goal; } + goal & operator=(goal const & s) { + Z3_goal_inc_ref(s.ctx(), s.m_goal); + Z3_goal_dec_ref(ctx(), m_goal); + m_ctx = s.m_ctx; + m_goal = s.m_goal; + return *this; + } + void add(expr const & f) { check_context(*this, f); Z3_goal_assert(ctx(), m_goal, f); check_error(); } + unsigned size() const { return Z3_goal_size(ctx(), m_goal); } + expr operator[](unsigned i) const { Z3_ast r = Z3_goal_formula(ctx(), m_goal, i); check_error(); return expr(ctx(), r); } + Z3_goal_prec precision() const { return Z3_goal_precision(ctx(), m_goal); } + bool inconsistent() const { return Z3_goal_inconsistent(ctx(), m_goal) != 0; } + unsigned depth() const { return Z3_goal_depth(ctx(), m_goal); } + void reset() { Z3_goal_reset(ctx(), m_goal); } + unsigned num_exprs() const { return Z3_goal_num_exprs(ctx(), m_goal); } + bool is_decided_sat() const { return Z3_goal_is_decided_sat(ctx(), m_goal) != 0; } + bool is_decided_unsat() const { return Z3_goal_is_decided_unsat(ctx(), m_goal) != 0; } + friend std::ostream & operator<<(std::ostream & out, goal const & g) { out << Z3_goal_to_string(g.ctx(), g); return out; } + }; + + class apply_result : public object { + Z3_apply_result m_apply_result; + void init(Z3_apply_result s) { + m_apply_result = s; + Z3_apply_result_inc_ref(ctx(), s); + } + public: + apply_result(context & c, Z3_apply_result s):object(c) { init(s); } + apply_result(apply_result const & s):object(s) { init(s.m_apply_result); } + ~apply_result() { Z3_apply_result_dec_ref(ctx(), m_apply_result); } + operator Z3_apply_result() const { return m_apply_result; } + apply_result & operator=(apply_result const & s) { + Z3_apply_result_inc_ref(s.ctx(), s.m_apply_result); + Z3_apply_result_dec_ref(ctx(), m_apply_result); + m_ctx = s.m_ctx; + m_apply_result = s.m_apply_result; + return *this; + } + unsigned size() const { return Z3_apply_result_get_num_subgoals(ctx(), m_apply_result); } + goal operator[](unsigned i) const { Z3_goal r = Z3_apply_result_get_subgoal(ctx(), m_apply_result, i); check_error(); return goal(ctx(), r); } + goal operator[](int i) const { assert(i >= 0); return this->operator[](static_cast(i)); } + model convert_model(model const & m, unsigned i = 0) const { + check_context(*this, m); + Z3_model new_m = Z3_apply_result_convert_model(ctx(), m_apply_result, i, m); + check_error(); + return model(ctx(), new_m); + } + friend std::ostream & operator<<(std::ostream & out, apply_result const & r) { out << Z3_apply_result_to_string(r.ctx(), r); return out; } + }; + + class tactic : public object { + Z3_tactic m_tactic; + void init(Z3_tactic s) { + m_tactic = s; + Z3_tactic_inc_ref(ctx(), s); + } + public: + tactic(context & c, char const * name):object(c) { Z3_tactic r = Z3_mk_tactic(c, name); check_error(); init(r); } + tactic(context & c, Z3_tactic s):object(c) { init(s); } + tactic(tactic const & s):object(s) { init(s.m_tactic); } + ~tactic() { Z3_tactic_dec_ref(ctx(), m_tactic); } + operator Z3_tactic() const { return m_tactic; } + tactic & operator=(tactic const & s) { + Z3_tactic_inc_ref(s.ctx(), s.m_tactic); + Z3_tactic_dec_ref(ctx(), m_tactic); + m_ctx = s.m_ctx; + m_tactic = s.m_tactic; + return *this; + } + solver mk_solver() const { Z3_solver r = Z3_mk_solver_from_tactic(ctx(), m_tactic); check_error(); return solver(ctx(), r); } + apply_result apply(goal const & g) const { + check_context(*this, g); + Z3_apply_result r = Z3_tactic_apply(ctx(), m_tactic, g); + check_error(); + return apply_result(ctx(), r); + } + apply_result operator()(goal const & g) const { + return apply(g); + } + std::string help() const { char const * r = Z3_tactic_get_help(ctx(), m_tactic); check_error(); return r; } + friend tactic operator&(tactic const & t1, tactic const & t2) { + check_context(t1, t2); + Z3_tactic r = Z3_tactic_and_then(t1.ctx(), t1, t2); + t1.check_error(); + return tactic(t1.ctx(), r); + } + friend tactic operator|(tactic const & t1, tactic const & t2) { + check_context(t1, t2); + Z3_tactic r = Z3_tactic_or_else(t1.ctx(), t1, t2); + t1.check_error(); + return tactic(t1.ctx(), r); + } + friend tactic repeat(tactic const & t, unsigned max=UINT_MAX) { + Z3_tactic r = Z3_tactic_repeat(t.ctx(), t, max); + t.check_error(); + return tactic(t.ctx(), r); + } + friend tactic with(tactic const & t, params const & p) { + Z3_tactic r = Z3_tactic_using_params(t.ctx(), t, p); + t.check_error(); + return tactic(t.ctx(), r); + } + friend tactic try_for(tactic const & t, unsigned ms) { + Z3_tactic r = Z3_tactic_try_for(t.ctx(), t, ms); + t.check_error(); + return tactic(t.ctx(), r); + } + }; + + class probe : public object { + Z3_probe m_probe; + void init(Z3_probe s) { + m_probe = s; + Z3_probe_inc_ref(ctx(), s); + } + public: + probe(context & c, char const * name):object(c) { Z3_probe r = Z3_mk_probe(c, name); check_error(); init(r); } + probe(context & c, double val):object(c) { Z3_probe r = Z3_probe_const(c, val); check_error(); init(r); } + probe(context & c, Z3_probe s):object(c) { init(s); } + probe(probe const & s):object(s) { init(s.m_probe); } + ~probe() { Z3_probe_dec_ref(ctx(), m_probe); } + operator Z3_probe() const { return m_probe; } + probe & operator=(probe const & s) { + Z3_probe_inc_ref(s.ctx(), s.m_probe); + Z3_probe_dec_ref(ctx(), m_probe); + m_ctx = s.m_ctx; + m_probe = s.m_probe; + return *this; + } + double apply(goal const & g) const { double r = Z3_probe_apply(ctx(), m_probe, g); check_error(); return r; } + double operator()(goal const & g) const { return apply(g); } + friend probe operator<=(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_le(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + } + friend probe operator<=(probe const & p1, double p2) { return p1 <= probe(p1.ctx(), p2); } + friend probe operator<=(double p1, probe const & p2) { return probe(p2.ctx(), p1) <= p2; } + friend probe operator>=(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_ge(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + } + friend probe operator>=(probe const & p1, double p2) { return p1 >= probe(p1.ctx(), p2); } + friend probe operator>=(double p1, probe const & p2) { return probe(p2.ctx(), p1) >= p2; } + friend probe operator<(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_lt(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + } + friend probe operator<(probe const & p1, double p2) { return p1 < probe(p1.ctx(), p2); } + friend probe operator<(double p1, probe const & p2) { return probe(p2.ctx(), p1) < p2; } + friend probe operator>(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_gt(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + } + friend probe operator>(probe const & p1, double p2) { return p1 > probe(p1.ctx(), p2); } + friend probe operator>(double p1, probe const & p2) { return probe(p2.ctx(), p1) > p2; } + friend probe operator==(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_eq(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + } + friend probe operator==(probe const & p1, double p2) { return p1 == probe(p1.ctx(), p2); } + friend probe operator==(double p1, probe const & p2) { return probe(p2.ctx(), p1) == p2; } + friend probe operator&&(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_and(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + } + friend probe operator||(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_or(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + } + friend probe operator!(probe const & p) { + Z3_probe r = Z3_probe_not(p.ctx(), p); p.check_error(); return probe(p.ctx(), r); + } + }; + + inline tactic fail_if(probe const & p) { + Z3_tactic r = Z3_tactic_fail_if(p.ctx(), p); + p.check_error(); + return tactic(p.ctx(), r); + } + inline tactic when(probe const & p, tactic const & t) { + check_context(p, t); + Z3_tactic r = Z3_tactic_when(t.ctx(), p, t); + t.check_error(); + return tactic(t.ctx(), r); + } + inline tactic cond(probe const & p, tactic const & t1, tactic const & t2) { + check_context(p, t1); check_context(p, t2); + Z3_tactic r = Z3_tactic_cond(t1.ctx(), p, t1, t2); + t1.check_error(); + return tactic(t1.ctx(), r); + } + + inline symbol context::str_symbol(char const * s) { Z3_symbol r = Z3_mk_string_symbol(m_ctx, s); check_error(); return symbol(*this, r); } + inline symbol context::int_symbol(int n) { Z3_symbol r = Z3_mk_int_symbol(m_ctx, n); check_error(); return symbol(*this, r); } + + inline sort context::bool_sort() { Z3_sort s = Z3_mk_bool_sort(m_ctx); check_error(); return sort(*this, s); } + inline sort context::int_sort() { Z3_sort s = Z3_mk_int_sort(m_ctx); check_error(); return sort(*this, s); } + inline sort context::real_sort() { Z3_sort s = Z3_mk_real_sort(m_ctx); check_error(); return sort(*this, s); } + inline sort context::bv_sort(unsigned sz) { Z3_sort s = Z3_mk_bv_sort(m_ctx, sz); check_error(); return sort(*this, s); } + inline sort context::array_sort(sort d, sort r) { Z3_sort s = Z3_mk_array_sort(m_ctx, d, r); check_error(); return sort(*this, s); } + + inline func_decl context::function(symbol const & name, unsigned arity, sort const * domain, sort const & range) { + array args(arity); + for (unsigned i = 0; i < arity; i++) { + check_context(domain[i], range); + args[i] = domain[i]; + } + Z3_func_decl f = Z3_mk_func_decl(m_ctx, name, arity, args.ptr(), range); + check_error(); + return func_decl(*this, f); + } + + inline func_decl context::function(char const * name, unsigned arity, sort const * domain, sort const & range) { + return function(range.ctx().str_symbol(name), arity, domain, range); + } + + inline func_decl context::function(char const * name, sort const & domain, sort const & range) { + check_context(domain, range); + Z3_sort args[1] = { domain }; + Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 1, args, range); + check_error(); + return func_decl(*this, f); + } + + inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & range) { + check_context(d1, range); check_context(d2, range); + Z3_sort args[2] = { d1, d2 }; + Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 2, args, range); + check_error(); + return func_decl(*this, f); + } + + inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & range) { + check_context(d1, range); check_context(d2, range); check_context(d3, range); + Z3_sort args[3] = { d1, d2, d3 }; + Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 3, args, range); + check_error(); + return func_decl(*this, f); + } + + inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & range) { + check_context(d1, range); check_context(d2, range); check_context(d3, range); check_context(d4, range); + Z3_sort args[4] = { d1, d2, d3, d4 }; + Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 4, args, range); + check_error(); + return func_decl(*this, f); + } + + inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & d5, sort const & range) { + check_context(d1, range); check_context(d2, range); check_context(d3, range); check_context(d4, range); check_context(d5, range); + Z3_sort args[5] = { d1, d2, d3, d4, d5 }; + Z3_func_decl f = Z3_mk_func_decl(m_ctx, str_symbol(name), 5, args, range); + check_error(); + return func_decl(*this, f); + } + + inline expr context::constant(symbol const & name, sort const & s) { + Z3_ast r = Z3_mk_const(m_ctx, name, s); + check_error(); + return expr(*this, r); + } + inline expr context::constant(char const * name, sort const & s) { return constant(str_symbol(name), s); } + inline expr context::bool_const(char const * name) { return constant(name, bool_sort()); } + inline expr context::int_const(char const * name) { return constant(name, int_sort()); } + inline expr context::real_const(char const * name) { return constant(name, real_sort()); } + inline expr context::bv_const(char const * name, unsigned sz) { return constant(name, bv_sort(sz)); } + + inline expr context::bool_val(bool b) { return b ? expr(*this, Z3_mk_true(m_ctx)) : expr(*this, Z3_mk_false(m_ctx)); } + + inline expr context::int_val(int n) { Z3_ast r = Z3_mk_int(m_ctx, n, int_sort()); check_error(); return expr(*this, r); } + inline expr context::int_val(unsigned n) { Z3_ast r = Z3_mk_unsigned_int(m_ctx, n, int_sort()); check_error(); return expr(*this, r); } + inline expr context::int_val(__int64 n) { Z3_ast r = Z3_mk_int64(m_ctx, n, int_sort()); check_error(); return expr(*this, r); } + inline expr context::int_val(__uint64 n) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, int_sort()); check_error(); return expr(*this, r); } + inline expr context::int_val(char const * n) { Z3_ast r = Z3_mk_numeral(m_ctx, n, int_sort()); check_error(); return expr(*this, r); } + + inline expr context::real_val(int n, int d) { Z3_ast r = Z3_mk_real(m_ctx, n, d); check_error(); return expr(*this, r); } + inline expr context::real_val(int n) { Z3_ast r = Z3_mk_int(m_ctx, n, real_sort()); check_error(); return expr(*this, r); } + inline expr context::real_val(unsigned n) { Z3_ast r = Z3_mk_unsigned_int(m_ctx, n, real_sort()); check_error(); return expr(*this, r); } + inline expr context::real_val(__int64 n) { Z3_ast r = Z3_mk_int64(m_ctx, n, real_sort()); check_error(); return expr(*this, r); } + inline expr context::real_val(__uint64 n) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, real_sort()); check_error(); return expr(*this, r); } + inline expr context::real_val(char const * n) { Z3_ast r = Z3_mk_numeral(m_ctx, n, real_sort()); check_error(); return expr(*this, r); } + + inline expr context::bv_val(int n, unsigned sz) { Z3_ast r = Z3_mk_int(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); } + inline expr context::bv_val(unsigned n, unsigned sz) { Z3_ast r = Z3_mk_unsigned_int(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); } + inline expr context::bv_val(__int64 n, unsigned sz) { Z3_ast r = Z3_mk_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); } + inline expr context::bv_val(__uint64 n, unsigned sz) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); } + inline expr context::bv_val(char const * n, unsigned sz) { Z3_ast r = Z3_mk_numeral(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); } + + inline expr context::num_val(int n, sort const & s) { Z3_ast r = Z3_mk_int(m_ctx, n, s); check_error(); return expr(*this, r); } + + inline expr func_decl::operator()(unsigned n, expr const * args) const { + array _args(n); + for (unsigned i = 0; i < n; i++) { + check_context(*this, args[i]); + _args[i] = args[i]; + } + Z3_ast r = Z3_mk_app(ctx(), *this, n, _args.ptr()); + check_error(); + return expr(ctx(), r); + + } + inline expr func_decl::operator()(expr const & a) const { + check_context(*this, a); + Z3_ast args[1] = { a }; + Z3_ast r = Z3_mk_app(ctx(), *this, 1, args); + ctx().check_error(); + return expr(ctx(), r); + } + inline expr func_decl::operator()(int a) const { + Z3_ast args[1] = { ctx().num_val(a, domain(0)) }; + Z3_ast r = Z3_mk_app(ctx(), *this, 1, args); + ctx().check_error(); + return expr(ctx(), r); + } + inline expr func_decl::operator()(expr const & a1, expr const & a2) const { + check_context(*this, a1); check_context(*this, a2); + Z3_ast args[2] = { a1, a2 }; + Z3_ast r = Z3_mk_app(ctx(), *this, 2, args); + ctx().check_error(); + return expr(ctx(), r); + } + inline expr func_decl::operator()(expr const & a1, int a2) const { + check_context(*this, a1); + Z3_ast args[2] = { a1, ctx().num_val(a2, domain(1)) }; + Z3_ast r = Z3_mk_app(ctx(), *this, 2, args); + ctx().check_error(); + return expr(ctx(), r); + } + inline expr func_decl::operator()(int a1, expr const & a2) const { + check_context(*this, a2); + Z3_ast args[2] = { ctx().num_val(a1, domain(0)), a2 }; + Z3_ast r = Z3_mk_app(ctx(), *this, 2, args); + ctx().check_error(); + return expr(ctx(), r); + } + inline expr func_decl::operator()(expr const & a1, expr const & a2, expr const & a3) const { + check_context(*this, a1); check_context(*this, a2); check_context(*this, a3); + Z3_ast args[3] = { a1, a2, a3 }; + Z3_ast r = Z3_mk_app(ctx(), *this, 3, args); + ctx().check_error(); + return expr(ctx(), r); + } + inline expr func_decl::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const { + check_context(*this, a1); check_context(*this, a2); check_context(*this, a3); check_context(*this, a4); + Z3_ast args[4] = { a1, a2, a3, a4 }; + Z3_ast r = Z3_mk_app(ctx(), *this, 4, args); + ctx().check_error(); + return expr(ctx(), r); + } + inline expr func_decl::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const { + check_context(*this, a1); check_context(*this, a2); check_context(*this, a3); check_context(*this, a4); check_context(*this, a5); + Z3_ast args[5] = { a1, a2, a3, a4, a5 }; + Z3_ast r = Z3_mk_app(ctx(), *this, 5, args); + ctx().check_error(); + return expr(ctx(), r); + } + + inline expr to_real(expr const & a) { Z3_ast r = Z3_mk_int2real(a.ctx(), a); a.check_error(); return expr(a.ctx(), r); } + + inline func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range) { + return range.ctx().function(name, arity, domain, range); + } + inline func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range) { + return range.ctx().function(name, arity, domain, range); + } + inline func_decl function(char const * name, sort const & domain, sort const & range) { + return range.ctx().function(name, domain, range); + } + inline func_decl function(char const * name, sort const & d1, sort const & d2, sort const & range) { + return range.ctx().function(name, d1, d2, range); + } + inline func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & range) { + return range.ctx().function(name, d1, d2, d3, range); + } + inline func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & range) { + return range.ctx().function(name, d1, d2, d3, d4, range); + } + inline func_decl function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & d5, sort const & range) { + return range.ctx().function(name, d1, d2, d3, d4, d5, range); + } + + inline expr select(expr const & a, expr const & i) { + check_context(a, i); + Z3_ast r = Z3_mk_select(a.ctx(), a, i); + a.check_error(); + return expr(a.ctx(), r); + } + inline expr select(expr const & a, int i) { return select(a, a.ctx().num_val(i, a.get_sort().array_domain())); } + inline expr store(expr const & a, expr const & i, expr const & v) { + check_context(a, i); check_context(a, v); + Z3_ast r = Z3_mk_store(a.ctx(), a, i, v); + a.check_error(); + return expr(a.ctx(), r); + } + inline expr store(expr const & a, int i, expr const & v) { return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), v); } + inline expr store(expr const & a, expr i, int v) { return store(a, i, a.ctx().num_val(v, a.get_sort().array_range())); } + inline expr store(expr const & a, int i, int v) { + return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), a.ctx().num_val(v, a.get_sort().array_range())); + } + inline expr const_array(sort const & d, expr const & v) { + check_context(d, v); + Z3_ast r = Z3_mk_const_array(d.ctx(), d, v); + d.check_error(); + return expr(d.ctx(), r); + } + + +}; + +template class z3::ast_vector_tpl; +template class z3::ast_vector_tpl; +template class z3::ast_vector_tpl; +template class z3::ast_vector_tpl; + +#endif + diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..66a6f75c3 --- /dev/null +++ b/configure.in @@ -0,0 +1,113 @@ +AC_PREREQ(2.50) +AC_INIT(lib/util.h) + +ARITH="internal" +AC_ARG_WITH([gmp], [AS_HELP_STRING([--with-gmp], [Use GMP for multi-precision naturals (default=no)])], [use_gmp=yes], [use_gmp=no]) +AS_IF([test "$use_gmp" = "yes"],[ + ARITH="gmp" + CPPFLAGS="$CPPFLAGS -D_MP_GMP" +],[ + CPPFLAGS="$CPPFLAGS -D_MP_INTERNAL" +]) +AC_SUBST(EXTRA_LIB_SRCS) + +AC_PATH_PROG([D2U], [dos2unix], [no], [~/bin$PATH_SEPARATOR$PATH]) +AS_IF([test "$D2U" = "no"], [AC_MSG_ERROR(dos2unix not found)]) +AC_SUBST(D2U) + +AC_PROG_CXX(g++) +AC_PROG_MAKE_SET + +AC_LANG_CPLUSPLUS + +host_os=`uname -s` + +AS_IF([test "$host_os" = "Darwin"], [ + PLATFORM=osx + SO_EXT=dylib + SLIBFLAGS="-dynamiclib -fopenmp" + COMP_VERSIONS="-compatibility_version \$(Z3_VERSION) -current_version \$(Z3_VERSION)" + STATIC_FLAGS= + CPPFLAGS+=" -mmacosx-version-min=10.4" +], [test "$host_os" = "Linux"], [ + PLATFORM=linux + SO_EXT=so + LDFLAGS=-lrt + SLIBFLAGS="-shared -fopenmp" + COMP_VERSIONS= + STATIC_FLAGS=-static +], [ + AC_MSG_ERROR([Unknown host platform: $host_os]) +]) +AC_SUBST(PLATFORM) +AC_SUBST(SO_EXT) +AC_SUBST(SLIBFLAGS) +AC_SUBST(COMP_VERSIONS) +AC_SUBST(STATIC_FLAGS) + +cat > tst64.c < tmp.sh + dnl mv tmp.sh test_capi/build-external-linux.sh + dnl sed 's|lz3-gmp|lz3|' test_user_theory/build-external-linux.sh > tmp.sh + dnl mv tmp.sh test_user_theory/build-external-linux.sh +else + CXXFLAGS="" + dnl In 64-bit systems it is not possible to build a dynamic library using static gmp. + dnl EXTRA_LIBS="\$(BIN_DIR)/lib\$(Z3)-gmp.so" +fi +rm -f tst64.c +rm -f tst64 + +AC_SUBST(GMP_STATIC_LIB) +GMP_STATIC_LIB="" + +if test "$ARITH" = "gmp"; then + AC_CHECK_HEADER([gmp.h], GMP='gmp', AC_MSG_ERROR([GMP include file not found])) + AC_SUBST(LIBS) + AC_CHECK_LIB(gmp, __gmpz_cmp, LIBS="-lgmp $LIBS", AC_MSG_ERROR([GMP library not found])) + dnl Look for libgmp.a at /usr/local/lib and /usr/lib + dnl TODO: make the following test more robust... + if test -e /usr/local/lib/libgmp.a; then + GMP_STATIC_LIB="/usr/local/lib/libgmp.a" + else if test -e /usr/lib/libgmp.a; then + GMP_STATIC_LIB="/usr/lib/libgmp.a" + else if test -e /usr/lib/libgmp.dll.a; then + GMP_STATIC_LIB="/usr/lib/libgmp.dll.a" + else + AC_MSG_ERROR([Failed to find libgmp.a]) + fi fi fi +fi + +AC_PROG_CXXCPP + +AC_OUTPUT(Makefile) + +cat < + + + + commercial + Win32 + + + commercial + x64 + + + Debug + Win32 + + + Debug + x64 + + + external_64 + Win32 + + + external_64 + x64 + + + external_dbg + Win32 + + + external_dbg + x64 + + + external_parallel_x64 + Win32 + + + external_parallel_x64 + x64 + + + external_parallel + Win32 + + + external_parallel + x64 + + + external + Win32 + + + external + x64 + + + mpi_debug + Win32 + + + mpi_debug + x64 + + + mpi_release + Win32 + + + mpi_release + x64 + + + parallel_debug + Win32 + + + parallel_debug + x64 + + + parallel_release + Win32 + + + parallel_release + x64 + + + release_mt + Win32 + + + release_mt + x64 + + + release_static + Win32 + + + release_static + x64 + + + Release + Win32 + + + Release + x64 + + + smtcomp + Win32 + + + smtcomp + x64 + + + trace + Win32 + + + trace + x64 + + + + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6} + dll + Win32Proj + + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + Application + + + DynamicLibrary + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + 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)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + z3_dbg + z3_dbg + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3_dbg + z3 + z3_dbg + z3 + z3 + z3 + z3 + z3 + z3 + z3_dbg + z3 + z3 + z3 + z3 + z3_dbg + z3 + z3_dbg + z3 + z3 + z3 + z3 + z3 + z3 + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + $(OutDir)z3_dbg.dll + z3_dbg.def + true + $(TargetDir)z3_dll.pdb + Windows + false + + + MachineX86 + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3_dbg.dll + z3_dbg.def + true + $(TargetDir)z3_dll.pdb + Windows + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + WIN32;NDEBUG;Z3DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3_dbg.dll + z3_dbg.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;Z3DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3_dbg.dll + z3_dbg.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + $(OutDir)z3_dbg.dll + z3_dbg.def + true + $(TargetDir)z3_dll.pdb + Windows + false + + + MachineX86 + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3_dbg.dll + z3_dbg.def + true + $(TargetDir)z3_dll.pdb + Windows + false + + + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;ASYNC_COMMANDS;_Z3_BUILD_PARALLEL_SMT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + $(OutDir)z3_dbg.dll + z3_dbg.def + true + $(TargetDir)z3_dll.pdb + Windows + false + + + MachineX86 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + $(OutDir)z3.dll + z3.def + true + $(TargetDir)z3_dll.pdb + Windows + true + true + MachineX64 + + + + + + + + + + + + + + + + + + {4a7e5a93-19d8-4382-8950-fb2edec7a76e} + false + + + + + + \ No newline at end of file diff --git a/dll/dll.vcxproj.user b/dll/dll.vcxproj.user new file mode 100644 index 000000000..ace9a86ac --- /dev/null +++ b/dll/dll.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/dll/mk_def.py b/dll/mk_def.py new file mode 100644 index 000000000..6e9fe92ac --- /dev/null +++ b/dll/mk_def.py @@ -0,0 +1,24 @@ +import re + +pat1 = re.compile(".*Z3_API.*") +api = open('..\lib\z3_api.h', 'r') + +z3def = open('z3.def', 'w') +z3dbgdef = open('z3_dbg.def', 'w') + +z3def.write('LIBRARY "Z3"\nEXPORTS\n') +z3dbgdef.write('LIBRARY "Z3_DBG"\nEXPORTS\n') + +num = 1 +for line in api: + m = pat1.match(line) + if m: + words = re.split('\W+', line) + i = 0 + for w in words: + if w == 'Z3_API': + f = words[i+1] + z3def.write('\t%s @%s\n' % (f, num)) + z3dbgdef.write('\t%s @%s\n' % (f, num)) + i = i + 1 + num = num + 1 diff --git a/dll/resource.h b/dll/resource.h new file mode 100644 index 000000000..1bf905c58 --- /dev/null +++ b/dll/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by dll.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/dll/z3.def b/dll/z3.def new file mode 100644 index 000000000..11ec21baa --- /dev/null +++ b/dll/z3.def @@ -0,0 +1,521 @@ +LIBRARY "Z3" +EXPORTS + Z3_mk_config @1 + Z3_del_config @2 + Z3_set_param_value @3 + Z3_mk_context @4 + Z3_mk_context_rc @5 + Z3_del_context @6 + Z3_inc_ref @7 + Z3_dec_ref @8 + Z3_update_param_value @9 + Z3_get_param_value @10 + Z3_interrupt @11 + Z3_mk_params @12 + Z3_params_inc_ref @13 + Z3_params_dec_ref @14 + Z3_params_set_bool @15 + Z3_params_set_uint @16 + Z3_params_set_double @17 + Z3_params_set_symbol @18 + Z3_params_to_string @19 + Z3_params_validate @20 + Z3_param_descrs_inc_ref @21 + Z3_param_descrs_dec_ref @22 + Z3_param_descrs_get_kind @23 + Z3_param_descrs_size @24 + Z3_param_descrs_get_name @25 + Z3_mk_int_symbol @26 + Z3_mk_string_symbol @27 + Z3_mk_uninterpreted_sort @28 + Z3_mk_bool_sort @29 + Z3_mk_int_sort @30 + Z3_mk_real_sort @31 + Z3_mk_bv_sort @32 + Z3_mk_finite_domain_sort @33 + Z3_mk_array_sort @34 + Z3_mk_tuple_sort @35 + Z3_mk_enumeration_sort @36 + Z3_mk_list_sort @37 + Z3_mk_constructor @38 + Z3_del_constructor @39 + Z3_mk_datatype @40 + Z3_mk_constructor_list @41 + Z3_del_constructor_list @42 + Z3_mk_datatypes @43 + Z3_query_constructor @44 + Z3_mk_func_decl @45 + Z3_mk_app @46 + Z3_mk_const @47 + Z3_mk_fresh_func_decl @48 + Z3_mk_fresh_const @49 + Z3_mk_true @50 + Z3_mk_false @51 + Z3_mk_eq @52 + Z3_mk_distinct @53 + Z3_mk_not @54 + Z3_mk_ite @55 + Z3_mk_iff @56 + Z3_mk_implies @57 + Z3_mk_xor @58 + Z3_mk_and @59 + Z3_mk_or @60 + Z3_mk_add @61 + Z3_mk_mul @62 + Z3_mk_sub @63 + Z3_mk_unary_minus @64 + Z3_mk_div @65 + Z3_mk_mod @66 + Z3_mk_rem @67 + Z3_mk_power @68 + Z3_mk_lt @69 + Z3_mk_le @70 + Z3_mk_gt @71 + Z3_mk_ge @72 + Z3_mk_int2real @73 + Z3_mk_real2int @74 + Z3_mk_is_int @75 + Z3_mk_bvnot @76 + Z3_mk_bvredand @77 + Z3_mk_bvredor @78 + Z3_mk_bvand @79 + Z3_mk_bvor @80 + Z3_mk_bvxor @81 + Z3_mk_bvnand @82 + Z3_mk_bvnor @83 + Z3_mk_bvxnor @84 + Z3_mk_bvneg @85 + Z3_mk_bvadd @86 + Z3_mk_bvsub @87 + Z3_mk_bvmul @88 + Z3_mk_bvudiv @89 + Z3_mk_bvsdiv @90 + Z3_mk_bvurem @91 + Z3_mk_bvsrem @92 + Z3_mk_bvsmod @93 + Z3_mk_bvult @94 + Z3_mk_bvslt @95 + Z3_mk_bvule @96 + Z3_mk_bvsle @97 + Z3_mk_bvuge @98 + Z3_mk_bvsge @99 + Z3_mk_bvugt @100 + Z3_mk_bvsgt @101 + Z3_mk_concat @102 + Z3_mk_extract @103 + Z3_mk_sign_ext @104 + Z3_mk_zero_ext @105 + Z3_mk_repeat @106 + Z3_mk_bvshl @107 + Z3_mk_bvlshr @108 + Z3_mk_bvashr @109 + Z3_mk_rotate_left @110 + Z3_mk_rotate_right @111 + Z3_mk_ext_rotate_left @112 + Z3_mk_ext_rotate_right @113 + Z3_mk_int2bv @114 + Z3_mk_bv2int @115 + Z3_mk_bvadd_no_overflow @116 + Z3_mk_bvadd_no_underflow @117 + Z3_mk_bvsub_no_overflow @118 + Z3_mk_bvsub_no_underflow @119 + Z3_mk_bvsdiv_no_overflow @120 + Z3_mk_bvneg_no_overflow @121 + Z3_mk_bvmul_no_overflow @122 + Z3_mk_bvmul_no_underflow @123 + Z3_mk_select @124 + Z3_mk_store @125 + Z3_mk_const_array @126 + Z3_mk_map @127 + Z3_mk_array_default @128 + Z3_mk_set_sort @129 + Z3_mk_empty_set @130 + Z3_mk_full_set @131 + Z3_mk_set_add @132 + Z3_mk_set_del @133 + Z3_mk_set_union @134 + Z3_mk_set_intersect @135 + Z3_mk_set_difference @136 + Z3_mk_set_complement @137 + Z3_mk_set_member @138 + Z3_mk_set_subset @139 + Z3_mk_numeral @140 + Z3_mk_real @141 + Z3_mk_int @142 + Z3_mk_unsigned_int @143 + Z3_mk_int64 @144 + Z3_mk_unsigned_int64 @145 + Z3_mk_pattern @146 + Z3_mk_bound @147 + Z3_mk_forall @148 + Z3_mk_exists @149 + Z3_mk_quantifier @150 + Z3_mk_quantifier_ex @151 + Z3_mk_forall_const @152 + Z3_mk_exists_const @153 + Z3_mk_quantifier_const @154 + Z3_mk_quantifier_const_ex @155 + Z3_get_symbol_kind @156 + Z3_get_symbol_int @157 + Z3_get_symbol_string @158 + Z3_get_sort_name @159 + Z3_get_sort_id @160 + Z3_sort_to_ast @161 + Z3_is_eq_sort @162 + Z3_get_sort_kind @163 + Z3_get_bv_sort_size @164 + Z3_get_finite_domain_sort_size @165 + Z3_get_array_sort_domain @166 + Z3_get_array_sort_range @167 + Z3_get_tuple_sort_mk_decl @168 + Z3_get_tuple_sort_num_fields @169 + Z3_get_tuple_sort_field_decl @170 + Z3_get_datatype_sort_num_constructors @171 + Z3_get_datatype_sort_constructor @172 + Z3_get_datatype_sort_recognizer @173 + Z3_get_datatype_sort_constructor_accessor @174 + Z3_get_relation_arity @175 + Z3_get_relation_column @176 + Z3_func_decl_to_ast @177 + Z3_is_eq_func_decl @178 + Z3_get_func_decl_id @179 + Z3_get_decl_name @180 + Z3_get_decl_kind @181 + Z3_get_domain_size @182 + Z3_get_arity @183 + Z3_get_domain @184 + Z3_get_range @185 + Z3_get_decl_num_parameters @186 + Z3_get_decl_parameter_kind @187 + Z3_get_decl_int_parameter @188 + Z3_get_decl_double_parameter @189 + Z3_get_decl_symbol_parameter @190 + Z3_get_decl_sort_parameter @191 + Z3_get_decl_ast_parameter @192 + Z3_get_decl_func_decl_parameter @193 + Z3_get_decl_rational_parameter @194 + Z3_app_to_ast @195 + Z3_get_app_decl @196 + Z3_get_app_num_args @197 + Z3_get_app_arg @198 + Z3_is_eq_ast @199 + Z3_get_ast_id @200 + Z3_get_ast_hash @201 + Z3_get_sort @202 + Z3_is_well_sorted @203 + Z3_get_bool_value @204 + Z3_get_ast_kind @205 + Z3_is_app @206 + Z3_is_numeral_ast @207 + Z3_is_algebraic_number @208 + Z3_to_app @209 + Z3_to_func_decl @210 + Z3_get_numeral_string @211 + Z3_get_numeral_decimal_string @212 + Z3_get_numerator @213 + Z3_get_denominator @214 + Z3_get_numeral_small @215 + Z3_get_numeral_int @216 + Z3_get_numeral_uint @217 + Z3_get_numeral_uint64 @218 + Z3_get_numeral_int64 @219 + Z3_get_numeral_rational_int64 @220 + Z3_get_algebraic_number_lower @221 + Z3_get_algebraic_number_upper @222 + Z3_pattern_to_ast @223 + Z3_get_pattern_num_terms @224 + Z3_get_pattern @225 + Z3_get_index_value @226 + Z3_is_quantifier_forall @227 + Z3_get_quantifier_weight @228 + Z3_get_quantifier_num_patterns @229 + Z3_get_quantifier_pattern_ast @230 + Z3_get_quantifier_num_no_patterns @231 + Z3_get_quantifier_no_pattern_ast @232 + Z3_get_quantifier_bound_name @233 + Z3_get_quantifier_bound_sort @234 + Z3_get_quantifier_body @235 + Z3_get_quantifier_num_bound @236 + Z3_simplify @237 + Z3_simplify_ex @238 + Z3_simplify_get_help @239 + Z3_simplify_get_param_descrs @240 + Z3_update_term @241 + Z3_substitute @242 + Z3_substitute_vars @243 + Z3_translate @244 + Z3_model_inc_ref @245 + Z3_model_dec_ref @246 + Z3_model_eval @247 + Z3_model_get_const_interp @248 + Z3_model_get_func_interp @249 + Z3_model_get_num_consts @250 + Z3_model_get_const_decl @251 + Z3_model_get_num_funcs @252 + Z3_model_get_func_decl @253 + Z3_model_get_num_sorts @254 + Z3_model_get_sort @255 + Z3_model_get_sort_universe @256 + Z3_is_as_array @257 + Z3_get_as_array_func_decl @258 + Z3_func_interp_inc_ref @259 + Z3_func_interp_dec_ref @260 + Z3_func_interp_get_num_entries @261 + Z3_func_interp_get_entry @262 + Z3_func_interp_get_else @263 + Z3_func_interp_get_arity @264 + Z3_func_entry_inc_ref @265 + Z3_func_entry_dec_ref @266 + Z3_func_entry_get_value @267 + Z3_func_entry_get_num_args @268 + Z3_func_entry_get_arg @269 + Z3_open_log @270 + Z3_append_log @271 + Z3_close_log @272 + Z3_toggle_warning_messages @273 + Z3_set_ast_print_mode @274 + Z3_ast_to_string @275 + Z3_pattern_to_string @276 + Z3_sort_to_string @277 + Z3_func_decl_to_string @278 + Z3_model_to_string @279 + Z3_benchmark_to_smtlib_string @280 + Z3_parse_smtlib2_string @281 + Z3_parse_smtlib2_file @282 + Z3_parse_smtlib_string @283 + Z3_parse_smtlib_file @284 + Z3_get_smtlib_num_formulas @285 + Z3_get_smtlib_formula @286 + Z3_get_smtlib_num_assumptions @287 + Z3_get_smtlib_assumption @288 + Z3_get_smtlib_num_decls @289 + Z3_get_smtlib_decl @290 + Z3_get_smtlib_num_sorts @291 + Z3_get_smtlib_sort @292 + Z3_get_smtlib_error @293 + Z3_parse_z3_string @294 + Z3_parse_z3_file @295 + Z3_get_error_code @296 + Z3_set_error_handler @297 + Z3_set_error @298 + Z3_get_error_msg @299 + Z3_get_error_msg_ex @300 + Z3_get_version @301 + Z3_reset_memory @302 + Z3_mk_theory @303 + Z3_theory_get_ext_data @304 + Z3_theory_mk_sort @305 + Z3_theory_mk_value @306 + Z3_theory_mk_constant @307 + Z3_theory_mk_func_decl @308 + Z3_theory_get_context @309 + Z3_set_delete_callback @310 + Z3_set_reduce_app_callback @311 + Z3_set_reduce_eq_callback @312 + Z3_set_reduce_distinct_callback @313 + Z3_set_new_app_callback @314 + Z3_set_new_elem_callback @315 + Z3_set_init_search_callback @316 + Z3_set_push_callback @317 + Z3_set_pop_callback @318 + Z3_set_restart_callback @319 + Z3_set_reset_callback @320 + Z3_set_final_check_callback @321 + Z3_set_new_eq_callback @322 + Z3_set_new_diseq_callback @323 + Z3_set_new_assignment_callback @324 + Z3_set_new_relevant_callback @325 + Z3_theory_assert_axiom @326 + Z3_theory_assume_eq @327 + Z3_theory_enable_axiom_simplification @328 + Z3_theory_get_eqc_root @329 + Z3_theory_get_eqc_next @330 + Z3_theory_get_num_parents @331 + Z3_theory_get_parent @332 + Z3_theory_is_value @333 + Z3_theory_is_decl @334 + Z3_theory_get_num_elems @335 + Z3_theory_get_elem @336 + Z3_theory_get_num_apps @337 + Z3_theory_get_app @338 + Z3_mk_fixedpoint @339 + Z3_fixedpoint_inc_ref @340 + Z3_fixedpoint_dec_ref @341 + Z3_fixedpoint_add_rule @342 + Z3_fixedpoint_add_fact @343 + Z3_fixedpoint_assert @344 + Z3_fixedpoint_query @345 + Z3_fixedpoint_query_relations @346 + Z3_fixedpoint_get_answer @347 + Z3_fixedpoint_get_reason_unknown @348 + Z3_fixedpoint_update_rule @349 + Z3_fixedpoint_get_num_levels @350 + Z3_fixedpoint_get_cover_delta @351 + Z3_fixedpoint_add_cover @352 + Z3_fixedpoint_get_statistics @353 + Z3_fixedpoint_register_relation @354 + Z3_fixedpoint_set_predicate_representation @355 + Z3_fixedpoint_simplify_rules @356 + Z3_fixedpoint_set_params @357 + Z3_fixedpoint_get_help @358 + Z3_fixedpoint_get_param_descrs @359 + Z3_fixedpoint_to_string @360 + Z3_fixedpoint_push @361 + Z3_fixedpoint_pop @362 + Z3_fixedpoint_init @363 + Z3_fixedpoint_set_reduce_assign_callback @364 + Z3_fixedpoint_set_reduce_app_callback @365 + Z3_mk_ast_vector @366 + Z3_ast_vector_inc_ref @367 + Z3_ast_vector_dec_ref @368 + Z3_ast_vector_size @369 + Z3_ast_vector_get @370 + Z3_ast_vector_set @371 + Z3_ast_vector_resize @372 + Z3_ast_vector_push @373 + Z3_ast_vector_translate @374 + Z3_ast_vector_to_string @375 + Z3_mk_ast_map @376 + Z3_ast_map_inc_ref @377 + Z3_ast_map_dec_ref @378 + Z3_ast_map_contains @379 + Z3_ast_map_find @380 + Z3_ast_map_insert @381 + Z3_ast_map_erase @382 + Z3_ast_map_reset @383 + Z3_ast_map_size @384 + Z3_ast_map_keys @385 + Z3_ast_map_to_string @386 + Z3_mk_goal @387 + Z3_goal_inc_ref @388 + Z3_goal_dec_ref @389 + Z3_goal_precision @390 + Z3_goal_assert @391 + Z3_goal_inconsistent @392 + Z3_goal_depth @393 + Z3_goal_reset @394 + Z3_goal_size @395 + Z3_goal_formula @396 + Z3_goal_num_exprs @397 + Z3_goal_is_decided_sat @398 + Z3_goal_is_decided_unsat @399 + Z3_goal_translate @400 + Z3_goal_to_string @401 + Z3_mk_tactic @402 + Z3_tactic_inc_ref @403 + Z3_tactic_dec_ref @404 + Z3_mk_probe @405 + Z3_probe_inc_ref @406 + Z3_probe_dec_ref @407 + Z3_tactic_and_then @408 + Z3_tactic_or_else @409 + Z3_tactic_par_or @410 + Z3_tactic_par_and_then @411 + Z3_tactic_try_for @412 + Z3_tactic_when @413 + Z3_tactic_cond @414 + Z3_tactic_repeat @415 + Z3_tactic_skip @416 + Z3_tactic_fail @417 + Z3_tactic_fail_if @418 + Z3_tactic_fail_if_not_decided @419 + Z3_tactic_using_params @420 + Z3_probe_const @421 + Z3_probe_lt @422 + Z3_probe_gt @423 + Z3_probe_le @424 + Z3_probe_ge @425 + Z3_probe_eq @426 + Z3_probe_and @427 + Z3_probe_or @428 + Z3_probe_not @429 + Z3_get_num_tactics @430 + Z3_get_tactic_name @431 + Z3_get_num_probes @432 + Z3_get_probe_name @433 + Z3_tactic_get_help @434 + Z3_tactic_get_param_descrs @435 + Z3_tactic_get_descr @436 + Z3_probe_get_descr @437 + Z3_probe_apply @438 + Z3_tactic_apply @439 + Z3_tactic_apply_ex @440 + Z3_apply_result_inc_ref @441 + Z3_apply_result_dec_ref @442 + Z3_apply_result_to_string @443 + Z3_apply_result_get_num_subgoals @444 + Z3_apply_result_get_subgoal @445 + Z3_apply_result_convert_model @446 + Z3_mk_solver @447 + Z3_mk_simple_solver @448 + Z3_mk_solver_for_logic @449 + Z3_mk_solver_from_tactic @450 + Z3_solver_get_help @451 + Z3_solver_get_param_descrs @452 + Z3_solver_set_params @453 + Z3_solver_inc_ref @454 + Z3_solver_dec_ref @455 + Z3_solver_push @456 + Z3_solver_pop @457 + Z3_solver_reset @458 + Z3_solver_get_num_scopes @459 + Z3_solver_assert @460 + Z3_solver_get_assertions @461 + Z3_solver_check @462 + Z3_solver_check_assumptions @463 + Z3_solver_get_model @464 + Z3_solver_get_proof @465 + Z3_solver_get_unsat_core @466 + Z3_solver_get_reason_unknown @467 + Z3_solver_get_statistics @468 + Z3_solver_to_string @469 + Z3_stats_to_string @470 + Z3_stats_inc_ref @471 + Z3_stats_dec_ref @472 + Z3_stats_size @473 + Z3_stats_get_key @474 + Z3_stats_is_uint @475 + Z3_stats_is_double @476 + Z3_stats_get_uint_value @477 + Z3_stats_get_double_value @478 + Z3_mk_injective_function @479 + Z3_set_logic @480 + Z3_push @481 + Z3_pop @482 + Z3_get_num_scopes @483 + Z3_persist_ast @484 + Z3_assert_cnstr @485 + Z3_check_and_get_model @486 + Z3_check @487 + Z3_check_assumptions @488 + Z3_get_implied_equalities @489 + Z3_del_model @490 + Z3_soft_check_cancel @491 + Z3_get_search_failure @492 + Z3_mk_label @493 + Z3_get_relevant_labels @494 + Z3_get_relevant_literals @495 + Z3_get_guessed_literals @496 + Z3_del_literals @497 + Z3_get_num_literals @498 + Z3_get_label_symbol @499 + Z3_get_literal @500 + Z3_disable_literal @501 + Z3_block_literals @502 + Z3_get_model_num_constants @503 + Z3_get_model_constant @504 + Z3_get_model_num_funcs @505 + Z3_get_model_func_decl @506 + Z3_eval_func_decl @507 + Z3_is_array_value @508 + Z3_get_array_value @509 + Z3_get_model_func_else @510 + Z3_get_model_func_num_entries @511 + Z3_get_model_func_entry_num_args @512 + Z3_get_model_func_entry_arg @513 + Z3_get_model_func_entry_value @514 + Z3_eval @515 + Z3_eval_decl @516 + Z3_context_to_string @517 + Z3_statistics_to_string @518 + Z3_get_context_assignment @519 diff --git a/dll/z3_dbg.def b/dll/z3_dbg.def new file mode 100644 index 000000000..274eca2c0 --- /dev/null +++ b/dll/z3_dbg.def @@ -0,0 +1,521 @@ +LIBRARY "Z3_DBG" +EXPORTS + Z3_mk_config @1 + Z3_del_config @2 + Z3_set_param_value @3 + Z3_mk_context @4 + Z3_mk_context_rc @5 + Z3_del_context @6 + Z3_inc_ref @7 + Z3_dec_ref @8 + Z3_update_param_value @9 + Z3_get_param_value @10 + Z3_interrupt @11 + Z3_mk_params @12 + Z3_params_inc_ref @13 + Z3_params_dec_ref @14 + Z3_params_set_bool @15 + Z3_params_set_uint @16 + Z3_params_set_double @17 + Z3_params_set_symbol @18 + Z3_params_to_string @19 + Z3_params_validate @20 + Z3_param_descrs_inc_ref @21 + Z3_param_descrs_dec_ref @22 + Z3_param_descrs_get_kind @23 + Z3_param_descrs_size @24 + Z3_param_descrs_get_name @25 + Z3_mk_int_symbol @26 + Z3_mk_string_symbol @27 + Z3_mk_uninterpreted_sort @28 + Z3_mk_bool_sort @29 + Z3_mk_int_sort @30 + Z3_mk_real_sort @31 + Z3_mk_bv_sort @32 + Z3_mk_finite_domain_sort @33 + Z3_mk_array_sort @34 + Z3_mk_tuple_sort @35 + Z3_mk_enumeration_sort @36 + Z3_mk_list_sort @37 + Z3_mk_constructor @38 + Z3_del_constructor @39 + Z3_mk_datatype @40 + Z3_mk_constructor_list @41 + Z3_del_constructor_list @42 + Z3_mk_datatypes @43 + Z3_query_constructor @44 + Z3_mk_func_decl @45 + Z3_mk_app @46 + Z3_mk_const @47 + Z3_mk_fresh_func_decl @48 + Z3_mk_fresh_const @49 + Z3_mk_true @50 + Z3_mk_false @51 + Z3_mk_eq @52 + Z3_mk_distinct @53 + Z3_mk_not @54 + Z3_mk_ite @55 + Z3_mk_iff @56 + Z3_mk_implies @57 + Z3_mk_xor @58 + Z3_mk_and @59 + Z3_mk_or @60 + Z3_mk_add @61 + Z3_mk_mul @62 + Z3_mk_sub @63 + Z3_mk_unary_minus @64 + Z3_mk_div @65 + Z3_mk_mod @66 + Z3_mk_rem @67 + Z3_mk_power @68 + Z3_mk_lt @69 + Z3_mk_le @70 + Z3_mk_gt @71 + Z3_mk_ge @72 + Z3_mk_int2real @73 + Z3_mk_real2int @74 + Z3_mk_is_int @75 + Z3_mk_bvnot @76 + Z3_mk_bvredand @77 + Z3_mk_bvredor @78 + Z3_mk_bvand @79 + Z3_mk_bvor @80 + Z3_mk_bvxor @81 + Z3_mk_bvnand @82 + Z3_mk_bvnor @83 + Z3_mk_bvxnor @84 + Z3_mk_bvneg @85 + Z3_mk_bvadd @86 + Z3_mk_bvsub @87 + Z3_mk_bvmul @88 + Z3_mk_bvudiv @89 + Z3_mk_bvsdiv @90 + Z3_mk_bvurem @91 + Z3_mk_bvsrem @92 + Z3_mk_bvsmod @93 + Z3_mk_bvult @94 + Z3_mk_bvslt @95 + Z3_mk_bvule @96 + Z3_mk_bvsle @97 + Z3_mk_bvuge @98 + Z3_mk_bvsge @99 + Z3_mk_bvugt @100 + Z3_mk_bvsgt @101 + Z3_mk_concat @102 + Z3_mk_extract @103 + Z3_mk_sign_ext @104 + Z3_mk_zero_ext @105 + Z3_mk_repeat @106 + Z3_mk_bvshl @107 + Z3_mk_bvlshr @108 + Z3_mk_bvashr @109 + Z3_mk_rotate_left @110 + Z3_mk_rotate_right @111 + Z3_mk_ext_rotate_left @112 + Z3_mk_ext_rotate_right @113 + Z3_mk_int2bv @114 + Z3_mk_bv2int @115 + Z3_mk_bvadd_no_overflow @116 + Z3_mk_bvadd_no_underflow @117 + Z3_mk_bvsub_no_overflow @118 + Z3_mk_bvsub_no_underflow @119 + Z3_mk_bvsdiv_no_overflow @120 + Z3_mk_bvneg_no_overflow @121 + Z3_mk_bvmul_no_overflow @122 + Z3_mk_bvmul_no_underflow @123 + Z3_mk_select @124 + Z3_mk_store @125 + Z3_mk_const_array @126 + Z3_mk_map @127 + Z3_mk_array_default @128 + Z3_mk_set_sort @129 + Z3_mk_empty_set @130 + Z3_mk_full_set @131 + Z3_mk_set_add @132 + Z3_mk_set_del @133 + Z3_mk_set_union @134 + Z3_mk_set_intersect @135 + Z3_mk_set_difference @136 + Z3_mk_set_complement @137 + Z3_mk_set_member @138 + Z3_mk_set_subset @139 + Z3_mk_numeral @140 + Z3_mk_real @141 + Z3_mk_int @142 + Z3_mk_unsigned_int @143 + Z3_mk_int64 @144 + Z3_mk_unsigned_int64 @145 + Z3_mk_pattern @146 + Z3_mk_bound @147 + Z3_mk_forall @148 + Z3_mk_exists @149 + Z3_mk_quantifier @150 + Z3_mk_quantifier_ex @151 + Z3_mk_forall_const @152 + Z3_mk_exists_const @153 + Z3_mk_quantifier_const @154 + Z3_mk_quantifier_const_ex @155 + Z3_get_symbol_kind @156 + Z3_get_symbol_int @157 + Z3_get_symbol_string @158 + Z3_get_sort_name @159 + Z3_get_sort_id @160 + Z3_sort_to_ast @161 + Z3_is_eq_sort @162 + Z3_get_sort_kind @163 + Z3_get_bv_sort_size @164 + Z3_get_finite_domain_sort_size @165 + Z3_get_array_sort_domain @166 + Z3_get_array_sort_range @167 + Z3_get_tuple_sort_mk_decl @168 + Z3_get_tuple_sort_num_fields @169 + Z3_get_tuple_sort_field_decl @170 + Z3_get_datatype_sort_num_constructors @171 + Z3_get_datatype_sort_constructor @172 + Z3_get_datatype_sort_recognizer @173 + Z3_get_datatype_sort_constructor_accessor @174 + Z3_get_relation_arity @175 + Z3_get_relation_column @176 + Z3_func_decl_to_ast @177 + Z3_is_eq_func_decl @178 + Z3_get_func_decl_id @179 + Z3_get_decl_name @180 + Z3_get_decl_kind @181 + Z3_get_domain_size @182 + Z3_get_arity @183 + Z3_get_domain @184 + Z3_get_range @185 + Z3_get_decl_num_parameters @186 + Z3_get_decl_parameter_kind @187 + Z3_get_decl_int_parameter @188 + Z3_get_decl_double_parameter @189 + Z3_get_decl_symbol_parameter @190 + Z3_get_decl_sort_parameter @191 + Z3_get_decl_ast_parameter @192 + Z3_get_decl_func_decl_parameter @193 + Z3_get_decl_rational_parameter @194 + Z3_app_to_ast @195 + Z3_get_app_decl @196 + Z3_get_app_num_args @197 + Z3_get_app_arg @198 + Z3_is_eq_ast @199 + Z3_get_ast_id @200 + Z3_get_ast_hash @201 + Z3_get_sort @202 + Z3_is_well_sorted @203 + Z3_get_bool_value @204 + Z3_get_ast_kind @205 + Z3_is_app @206 + Z3_is_numeral_ast @207 + Z3_is_algebraic_number @208 + Z3_to_app @209 + Z3_to_func_decl @210 + Z3_get_numeral_string @211 + Z3_get_numeral_decimal_string @212 + Z3_get_numerator @213 + Z3_get_denominator @214 + Z3_get_numeral_small @215 + Z3_get_numeral_int @216 + Z3_get_numeral_uint @217 + Z3_get_numeral_uint64 @218 + Z3_get_numeral_int64 @219 + Z3_get_numeral_rational_int64 @220 + Z3_get_algebraic_number_lower @221 + Z3_get_algebraic_number_upper @222 + Z3_pattern_to_ast @223 + Z3_get_pattern_num_terms @224 + Z3_get_pattern @225 + Z3_get_index_value @226 + Z3_is_quantifier_forall @227 + Z3_get_quantifier_weight @228 + Z3_get_quantifier_num_patterns @229 + Z3_get_quantifier_pattern_ast @230 + Z3_get_quantifier_num_no_patterns @231 + Z3_get_quantifier_no_pattern_ast @232 + Z3_get_quantifier_bound_name @233 + Z3_get_quantifier_bound_sort @234 + Z3_get_quantifier_body @235 + Z3_get_quantifier_num_bound @236 + Z3_simplify @237 + Z3_simplify_ex @238 + Z3_simplify_get_help @239 + Z3_simplify_get_param_descrs @240 + Z3_update_term @241 + Z3_substitute @242 + Z3_substitute_vars @243 + Z3_translate @244 + Z3_model_inc_ref @245 + Z3_model_dec_ref @246 + Z3_model_eval @247 + Z3_model_get_const_interp @248 + Z3_model_get_func_interp @249 + Z3_model_get_num_consts @250 + Z3_model_get_const_decl @251 + Z3_model_get_num_funcs @252 + Z3_model_get_func_decl @253 + Z3_model_get_num_sorts @254 + Z3_model_get_sort @255 + Z3_model_get_sort_universe @256 + Z3_is_as_array @257 + Z3_get_as_array_func_decl @258 + Z3_func_interp_inc_ref @259 + Z3_func_interp_dec_ref @260 + Z3_func_interp_get_num_entries @261 + Z3_func_interp_get_entry @262 + Z3_func_interp_get_else @263 + Z3_func_interp_get_arity @264 + Z3_func_entry_inc_ref @265 + Z3_func_entry_dec_ref @266 + Z3_func_entry_get_value @267 + Z3_func_entry_get_num_args @268 + Z3_func_entry_get_arg @269 + Z3_open_log @270 + Z3_append_log @271 + Z3_close_log @272 + Z3_toggle_warning_messages @273 + Z3_set_ast_print_mode @274 + Z3_ast_to_string @275 + Z3_pattern_to_string @276 + Z3_sort_to_string @277 + Z3_func_decl_to_string @278 + Z3_model_to_string @279 + Z3_benchmark_to_smtlib_string @280 + Z3_parse_smtlib2_string @281 + Z3_parse_smtlib2_file @282 + Z3_parse_smtlib_string @283 + Z3_parse_smtlib_file @284 + Z3_get_smtlib_num_formulas @285 + Z3_get_smtlib_formula @286 + Z3_get_smtlib_num_assumptions @287 + Z3_get_smtlib_assumption @288 + Z3_get_smtlib_num_decls @289 + Z3_get_smtlib_decl @290 + Z3_get_smtlib_num_sorts @291 + Z3_get_smtlib_sort @292 + Z3_get_smtlib_error @293 + Z3_parse_z3_string @294 + Z3_parse_z3_file @295 + Z3_get_error_code @296 + Z3_set_error_handler @297 + Z3_set_error @298 + Z3_get_error_msg @299 + Z3_get_error_msg_ex @300 + Z3_get_version @301 + Z3_reset_memory @302 + Z3_mk_theory @303 + Z3_theory_get_ext_data @304 + Z3_theory_mk_sort @305 + Z3_theory_mk_value @306 + Z3_theory_mk_constant @307 + Z3_theory_mk_func_decl @308 + Z3_theory_get_context @309 + Z3_set_delete_callback @310 + Z3_set_reduce_app_callback @311 + Z3_set_reduce_eq_callback @312 + Z3_set_reduce_distinct_callback @313 + Z3_set_new_app_callback @314 + Z3_set_new_elem_callback @315 + Z3_set_init_search_callback @316 + Z3_set_push_callback @317 + Z3_set_pop_callback @318 + Z3_set_restart_callback @319 + Z3_set_reset_callback @320 + Z3_set_final_check_callback @321 + Z3_set_new_eq_callback @322 + Z3_set_new_diseq_callback @323 + Z3_set_new_assignment_callback @324 + Z3_set_new_relevant_callback @325 + Z3_theory_assert_axiom @326 + Z3_theory_assume_eq @327 + Z3_theory_enable_axiom_simplification @328 + Z3_theory_get_eqc_root @329 + Z3_theory_get_eqc_next @330 + Z3_theory_get_num_parents @331 + Z3_theory_get_parent @332 + Z3_theory_is_value @333 + Z3_theory_is_decl @334 + Z3_theory_get_num_elems @335 + Z3_theory_get_elem @336 + Z3_theory_get_num_apps @337 + Z3_theory_get_app @338 + Z3_mk_fixedpoint @339 + Z3_fixedpoint_inc_ref @340 + Z3_fixedpoint_dec_ref @341 + Z3_fixedpoint_add_rule @342 + Z3_fixedpoint_add_fact @343 + Z3_fixedpoint_assert @344 + Z3_fixedpoint_query @345 + Z3_fixedpoint_query_relations @346 + Z3_fixedpoint_get_answer @347 + Z3_fixedpoint_get_reason_unknown @348 + Z3_fixedpoint_update_rule @349 + Z3_fixedpoint_get_num_levels @350 + Z3_fixedpoint_get_cover_delta @351 + Z3_fixedpoint_add_cover @352 + Z3_fixedpoint_get_statistics @353 + Z3_fixedpoint_register_relation @354 + Z3_fixedpoint_set_predicate_representation @355 + Z3_fixedpoint_simplify_rules @356 + Z3_fixedpoint_set_params @357 + Z3_fixedpoint_get_help @358 + Z3_fixedpoint_get_param_descrs @359 + Z3_fixedpoint_to_string @360 + Z3_fixedpoint_push @361 + Z3_fixedpoint_pop @362 + Z3_fixedpoint_init @363 + Z3_fixedpoint_set_reduce_assign_callback @364 + Z3_fixedpoint_set_reduce_app_callback @365 + Z3_mk_ast_vector @366 + Z3_ast_vector_inc_ref @367 + Z3_ast_vector_dec_ref @368 + Z3_ast_vector_size @369 + Z3_ast_vector_get @370 + Z3_ast_vector_set @371 + Z3_ast_vector_resize @372 + Z3_ast_vector_push @373 + Z3_ast_vector_translate @374 + Z3_ast_vector_to_string @375 + Z3_mk_ast_map @376 + Z3_ast_map_inc_ref @377 + Z3_ast_map_dec_ref @378 + Z3_ast_map_contains @379 + Z3_ast_map_find @380 + Z3_ast_map_insert @381 + Z3_ast_map_erase @382 + Z3_ast_map_reset @383 + Z3_ast_map_size @384 + Z3_ast_map_keys @385 + Z3_ast_map_to_string @386 + Z3_mk_goal @387 + Z3_goal_inc_ref @388 + Z3_goal_dec_ref @389 + Z3_goal_precision @390 + Z3_goal_assert @391 + Z3_goal_inconsistent @392 + Z3_goal_depth @393 + Z3_goal_reset @394 + Z3_goal_size @395 + Z3_goal_formula @396 + Z3_goal_num_exprs @397 + Z3_goal_is_decided_sat @398 + Z3_goal_is_decided_unsat @399 + Z3_goal_translate @400 + Z3_goal_to_string @401 + Z3_mk_tactic @402 + Z3_tactic_inc_ref @403 + Z3_tactic_dec_ref @404 + Z3_mk_probe @405 + Z3_probe_inc_ref @406 + Z3_probe_dec_ref @407 + Z3_tactic_and_then @408 + Z3_tactic_or_else @409 + Z3_tactic_par_or @410 + Z3_tactic_par_and_then @411 + Z3_tactic_try_for @412 + Z3_tactic_when @413 + Z3_tactic_cond @414 + Z3_tactic_repeat @415 + Z3_tactic_skip @416 + Z3_tactic_fail @417 + Z3_tactic_fail_if @418 + Z3_tactic_fail_if_not_decided @419 + Z3_tactic_using_params @420 + Z3_probe_const @421 + Z3_probe_lt @422 + Z3_probe_gt @423 + Z3_probe_le @424 + Z3_probe_ge @425 + Z3_probe_eq @426 + Z3_probe_and @427 + Z3_probe_or @428 + Z3_probe_not @429 + Z3_get_num_tactics @430 + Z3_get_tactic_name @431 + Z3_get_num_probes @432 + Z3_get_probe_name @433 + Z3_tactic_get_help @434 + Z3_tactic_get_param_descrs @435 + Z3_tactic_get_descr @436 + Z3_probe_get_descr @437 + Z3_probe_apply @438 + Z3_tactic_apply @439 + Z3_tactic_apply_ex @440 + Z3_apply_result_inc_ref @441 + Z3_apply_result_dec_ref @442 + Z3_apply_result_to_string @443 + Z3_apply_result_get_num_subgoals @444 + Z3_apply_result_get_subgoal @445 + Z3_apply_result_convert_model @446 + Z3_mk_solver @447 + Z3_mk_simple_solver @448 + Z3_mk_solver_for_logic @449 + Z3_mk_solver_from_tactic @450 + Z3_solver_get_help @451 + Z3_solver_get_param_descrs @452 + Z3_solver_set_params @453 + Z3_solver_inc_ref @454 + Z3_solver_dec_ref @455 + Z3_solver_push @456 + Z3_solver_pop @457 + Z3_solver_reset @458 + Z3_solver_get_num_scopes @459 + Z3_solver_assert @460 + Z3_solver_get_assertions @461 + Z3_solver_check @462 + Z3_solver_check_assumptions @463 + Z3_solver_get_model @464 + Z3_solver_get_proof @465 + Z3_solver_get_unsat_core @466 + Z3_solver_get_reason_unknown @467 + Z3_solver_get_statistics @468 + Z3_solver_to_string @469 + Z3_stats_to_string @470 + Z3_stats_inc_ref @471 + Z3_stats_dec_ref @472 + Z3_stats_size @473 + Z3_stats_get_key @474 + Z3_stats_is_uint @475 + Z3_stats_is_double @476 + Z3_stats_get_uint_value @477 + Z3_stats_get_double_value @478 + Z3_mk_injective_function @479 + Z3_set_logic @480 + Z3_push @481 + Z3_pop @482 + Z3_get_num_scopes @483 + Z3_persist_ast @484 + Z3_assert_cnstr @485 + Z3_check_and_get_model @486 + Z3_check @487 + Z3_check_assumptions @488 + Z3_get_implied_equalities @489 + Z3_del_model @490 + Z3_soft_check_cancel @491 + Z3_get_search_failure @492 + Z3_mk_label @493 + Z3_get_relevant_labels @494 + Z3_get_relevant_literals @495 + Z3_get_guessed_literals @496 + Z3_del_literals @497 + Z3_get_num_literals @498 + Z3_get_label_symbol @499 + Z3_get_literal @500 + Z3_disable_literal @501 + Z3_block_literals @502 + Z3_get_model_num_constants @503 + Z3_get_model_constant @504 + Z3_get_model_num_funcs @505 + Z3_get_model_func_decl @506 + Z3_eval_func_decl @507 + Z3_is_array_value @508 + Z3_get_array_value @509 + Z3_get_model_func_else @510 + Z3_get_model_func_num_entries @511 + Z3_get_model_func_entry_num_args @512 + Z3_get_model_func_entry_arg @513 + Z3_get_model_func_entry_value @514 + Z3_eval @515 + Z3_eval_decl @516 + Z3_context_to_string @517 + Z3_statistics_to_string @518 + Z3_get_context_assignment @519 diff --git a/maxsat/README-external.txt b/maxsat/README-external.txt new file mode 100644 index 000000000..ea7de14fa --- /dev/null +++ b/maxsat/README-external.txt @@ -0,0 +1,25 @@ +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 + +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. + + +2) Using gcc + +Use 'build.sh' to build the MaxSAT application using gcc. +The script 'exec.sh' adds the bin directory to the path. So, +maxsat.exe can find z3.dll. + +Remark: the scripts 'build.sh' and 'exec.sh' assumes you are in a +Cygwin or Mingw shell. diff --git a/maxsat/README-linux.txt b/maxsat/README-linux.txt new file mode 100644 index 000000000..a575dbf21 --- /dev/null +++ b/maxsat/README-linux.txt @@ -0,0 +1,8 @@ +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 gcc. + +Use 'build.sh' to build the MaxSAT application using gcc. +The script 'exec.sh' adds the lib directory to the path. So, +maxsat can find libz3.so. + diff --git a/maxsat/README-osx.txt b/maxsat/README-osx.txt new file mode 100644 index 000000000..c969b2516 --- /dev/null +++ b/maxsat/README-osx.txt @@ -0,0 +1,8 @@ +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 gcc. + +Use 'build.sh' to build the MaxSAT application using gcc. +The script 'exec.sh' adds the lib directory to the path. So, +maxsat can find libz3.dylib. + diff --git a/maxsat/build-external-linux.sh b/maxsat/build-external-linux.sh new file mode 100644 index 000000000..9074e5a3f --- /dev/null +++ b/maxsat/build-external-linux.sh @@ -0,0 +1 @@ +gcc -fopenmp -o maxsat maxsat.c -I ../../include -L ../../lib -lz3 diff --git a/maxsat/build-external-osx.sh b/maxsat/build-external-osx.sh new file mode 100644 index 000000000..eca55574e --- /dev/null +++ b/maxsat/build-external-osx.sh @@ -0,0 +1 @@ +gcc -fopenmp -o maxsat maxsat.c -I ../../include -L ../../lib -lz3 diff --git a/maxsat/build-external.cmd b/maxsat/build-external.cmd new file mode 100644 index 000000000..d71fb0e9b --- /dev/null +++ b/maxsat/build-external.cmd @@ -0,0 +1 @@ +cl /I ..\..\include ..\..\bin\z3.lib maxsat.c diff --git a/maxsat/build-external.sh b/maxsat/build-external.sh new file mode 100644 index 000000000..4be278a14 --- /dev/null +++ b/maxsat/build-external.sh @@ -0,0 +1 @@ +gcc -o maxsat.exe -I ../../include ../../bin/z3.dll maxsat.c diff --git a/maxsat/build-static-linux.sh b/maxsat/build-static-linux.sh new file mode 100644 index 000000000..3b6a2bbe8 --- /dev/null +++ b/maxsat/build-static-linux.sh @@ -0,0 +1,4 @@ +# Note: Z3 was built using C++, so libz3.a has C++ dependencies. +# You can use gcc to link the program, but you need tell it +# to link the C++ libraries +g++ -fopenmp -static -I../../include -L../../lib maxsat.c -lz3 -o maxsat diff --git a/maxsat/build-static-osx.sh b/maxsat/build-static-osx.sh new file mode 100644 index 000000000..1a54e0355 --- /dev/null +++ b/maxsat/build-static-osx.sh @@ -0,0 +1,4 @@ +# Note: Z3 was built using C++, so libz3.a has C++ dependencies. +# You can use gcc to link the program, but you need tell it +# to link the C++ libraries +g++ -fopenmp -I../../include maxsat.c ../../lib/libz3.a -o maxsat diff --git a/maxsat/ex.smt b/maxsat/ex.smt new file mode 100644 index 000000000..14ac0db89 --- /dev/null +++ b/maxsat/ex.smt @@ -0,0 +1,11 @@ +(benchmark ex + :logic AUFLIA + :extrafuns ((x Int) (y Int) (z Int)) + :assumption (> x 0) + :assumption (<= x -1) + :assumption (or (> x 0) (< y 1)) + :assumption (> y 2) + :assumption (> y 3) + :assumption (<= y -1) + :formula (= z (+ x y))) + \ No newline at end of file diff --git a/maxsat/exec-external-linux.sh b/maxsat/exec-external-linux.sh new file mode 100644 index 000000000..e366b5570 --- /dev/null +++ b/maxsat/exec-external-linux.sh @@ -0,0 +1,2 @@ +export LD_LIBRARY_PATH=../../lib:$LD_LIBRARY_PATH +./maxsat $1 diff --git a/maxsat/exec-external-osx.sh b/maxsat/exec-external-osx.sh new file mode 100644 index 000000000..e1df46aaa --- /dev/null +++ b/maxsat/exec-external-osx.sh @@ -0,0 +1,2 @@ +export DYLD_LIBRARY_PATH=../../lib:$DYLD_LIBRARY_PATH +./maxsat $1 diff --git a/maxsat/exec-external.cmd b/maxsat/exec-external.cmd new file mode 100644 index 000000000..9610dec88 --- /dev/null +++ b/maxsat/exec-external.cmd @@ -0,0 +1,5 @@ +@echo off +SETLOCAL +set PATH=..\..\bin;%PATH% +maxsat.exe %1 +ENDLOCAL diff --git a/maxsat/exec-external.sh b/maxsat/exec-external.sh new file mode 100644 index 000000000..6b2815614 --- /dev/null +++ b/maxsat/exec-external.sh @@ -0,0 +1,2 @@ +export PATH=../../bin:$PATH +./maxsat.exe $1 diff --git a/maxsat/maxsat.c b/maxsat/maxsat.c new file mode 100644 index 000000000..5ca707811 --- /dev/null +++ b/maxsat/maxsat.c @@ -0,0 +1,632 @@ +/* + Simple MAXSAT solver on top of the Z3 API. +*/ +#include +#include +#include +#include + +/** + \defgroup maxsat_ex MaxSAT/MaxSMT examples +*/ +/*@{*/ + +/** + \brief Exit gracefully in case of error. +*/ +void error(char * msg) +{ + fprintf(stderr, "%s\n", msg); + exit(1); +} + +/** + \brief Create a logical context. + Enable model construction only. +*/ +Z3_context mk_context() +{ + Z3_config cfg; + Z3_context ctx; + cfg = Z3_mk_config(); + Z3_set_param_value(cfg, "MODEL", "true"); + ctx = Z3_mk_context(cfg); + Z3_del_config(cfg); + return ctx; +} + +/** + \brief Create a variable using the given name and type. +*/ +Z3_ast mk_var(Z3_context ctx, const char * name, Z3_sort ty) +{ + Z3_symbol s = Z3_mk_string_symbol(ctx, name); + return Z3_mk_const(ctx, s, ty); +} + +/** + \brief Create a boolean variable using the given name. +*/ +Z3_ast mk_bool_var(Z3_context ctx, const char * name) +{ + Z3_sort ty = Z3_mk_bool_sort(ctx); + return mk_var(ctx, name, ty); +} + +/** + \brief Create a fresh boolean variable. +*/ +Z3_ast mk_fresh_bool_var(Z3_context ctx) +{ + return Z3_mk_fresh_const(ctx, "k", Z3_mk_bool_sort(ctx)); +} + +/** + \brief Create an array with \c num_vars fresh boolean variables. +*/ +Z3_ast * mk_fresh_bool_var_array(Z3_context ctx, unsigned num_vars) +{ + Z3_ast * result = (Z3_ast *) malloc(sizeof(Z3_ast) * num_vars); + unsigned i; + for (i = 0; i < num_vars; i++) { + result[i] = mk_fresh_bool_var(ctx); + } + return result; +} + +/** + \brief Delete array of boolean variables. +*/ +void del_bool_var_array(Z3_ast * arr) +{ + free(arr); +} + +/** + \brief Create a binary OR. +*/ +Z3_ast mk_binary_or(Z3_context ctx, Z3_ast in_1, Z3_ast in_2) +{ + Z3_ast args[2] = { in_1, in_2 }; + return Z3_mk_or(ctx, 2, args); +} + +/** + \brief Create a ternary OR. +*/ +Z3_ast mk_ternary_or(Z3_context ctx, Z3_ast in_1, Z3_ast in_2, Z3_ast in_3) +{ + Z3_ast args[3] = { in_1, in_2, in_3 }; + return Z3_mk_or(ctx, 3, args); +} + +/** + \brief Create a binary AND. +*/ +Z3_ast mk_binary_and(Z3_context ctx, Z3_ast in_1, Z3_ast in_2) +{ + Z3_ast args[2] = { in_1, in_2 }; + return Z3_mk_and(ctx, 2, args); +} + + +/** + \brief Get hard constraints from a SMT-LIB file. We assume hard constraints + are formulas preceeded with the keyword :formula. + Return an array containing all formulas read by the last Z3_parse_smtlib_file invocation. + It will store the number of formulas in num_cnstrs. +*/ +Z3_ast * get_hard_constraints(Z3_context ctx, unsigned * num_cnstrs) +{ + Z3_ast * result; + unsigned i; + *num_cnstrs = Z3_get_smtlib_num_formulas(ctx); + result = (Z3_ast *) malloc(sizeof(Z3_ast) * (*num_cnstrs)); + for (i = 0; i < *num_cnstrs; i++) { + result[i] = Z3_get_smtlib_formula(ctx, i); + } + return result; +} + +/** + \brief Get soft constraints from a SMT-LIB file. We assume soft constraints + are formulas preceeded with the keyword :assumption. + Return an array containing all assumptions read by the last Z3_parse_smtlib_file invocation. + It will store the number of formulas in num_cnstrs. +*/ +Z3_ast * get_soft_constraints(Z3_context ctx, unsigned * num_cnstrs) +{ + Z3_ast * result; + unsigned i; + *num_cnstrs = Z3_get_smtlib_num_assumptions(ctx); + result = (Z3_ast *) malloc(sizeof(Z3_ast) * (*num_cnstrs)); + for (i = 0; i < *num_cnstrs; i++) { + result[i] = Z3_get_smtlib_assumption(ctx, i); + } + return result; +} + +/** + \brief Free the given array of cnstrs that was allocated using get_hard_constraints or get_soft_constraints. +*/ +void free_cnstr_array(Z3_ast * cnstrs) +{ + free(cnstrs); +} + +/** + \brief Assert hard constraints stored in the given array. +*/ +void assert_hard_constraints(Z3_context ctx, unsigned num_cnstrs, Z3_ast * cnstrs) +{ + unsigned i; + for (i = 0; i < num_cnstrs; i++) { + Z3_assert_cnstr(ctx, cnstrs[i]); + } +} + +/** + \brief Assert soft constraints stored in the given array. + This funtion will assert each soft-constraint C_i as (C_i or k_i) where k_i is a fresh boolean variable. + It will also return an array containing these fresh variables. +*/ +Z3_ast * assert_soft_constraints(Z3_context ctx, unsigned num_cnstrs, Z3_ast * cnstrs) +{ + unsigned i; + Z3_ast * aux_vars; + aux_vars = mk_fresh_bool_var_array(ctx, num_cnstrs); + for (i = 0; i < num_cnstrs; i++) { + Z3_ast assumption = cnstrs[i]; + Z3_assert_cnstr(ctx, mk_binary_or(ctx, assumption, aux_vars[i])); + } + return aux_vars; +} + +/** + \brief Create a full adder with inputs \c in_1, \c in_2 and \c cin. + The output of the full adder is stored in \c out, and the carry in \c c_out. +*/ +void mk_full_adder(Z3_context ctx, Z3_ast in_1, Z3_ast in_2, Z3_ast cin, Z3_ast * out, Z3_ast * cout) +{ + *cout = mk_ternary_or(ctx, mk_binary_and(ctx, in_1, in_2), mk_binary_and(ctx, in_1, cin), mk_binary_and(ctx, in_2, cin)); + *out = Z3_mk_xor(ctx, Z3_mk_xor(ctx, in_1, in_2), cin); +} + +/** + \brief Create an adder for inputs of size \c num_bits. + The arguments \c in1 and \c in2 are arrays of bits of size \c num_bits. + + \remark \c result must be an array of size \c num_bits + 1. +*/ +void mk_adder(Z3_context ctx, unsigned num_bits, Z3_ast * in_1, Z3_ast * in_2, Z3_ast * result) +{ + Z3_ast cin, cout, out; + unsigned i; + cin = Z3_mk_false(ctx); + for (i = 0; i < num_bits; i++) { + mk_full_adder(ctx, in_1[i], in_2[i], cin, &out, &cout); + result[i] = out; + cin = cout; + } + result[num_bits] = cout; +} + +/** + \brief Given \c num_ins "numbers" of size \c num_bits stored in \c in. + Create floor(num_ins/2) adder circuits. Each circuit is adding two consecutive "numbers". + The numbers are stored one after the next in the array \c in. + That is, the array \c in has size num_bits * num_ins. + Return an array of bits containing \c ceil(num_ins/2) numbers of size \c (num_bits + 1). + If num_ins/2 is not an integer, then the last "number" in the output, is the last "number" in \c in with an appended "zero". +*/ +void mk_adder_pairs(Z3_context ctx, unsigned num_bits, unsigned num_ins, Z3_ast * in, unsigned * out_num_ins, Z3_ast * out) +{ + unsigned out_num_bits = num_bits + 1; + unsigned i = 0; + Z3_ast * _in = in; + Z3_ast * _out = out; + *out_num_ins = (num_ins % 2 == 0) ? (num_ins / 2) : (num_ins / 2) + 1; + for (i = 0; i < num_ins / 2; i++) { + mk_adder(ctx, num_bits, _in, _in + num_bits, _out); + _in += num_bits; + _in += num_bits; + _out += out_num_bits; + } + if (num_ins % 2 != 0) { + for (i = 0; i < num_bits; i++) { + _out[i] = _in[i]; + } + _out[num_bits] = Z3_mk_false(ctx); + } +} + +/** + \brief Create a counter circuit to count the number of "ones" in lits. + The function returns an array of bits (i.e. boolean expressions) containing the output of the circuit. + The size of the array is stored in out_sz. +*/ +Z3_ast * mk_counter_circuit(Z3_context ctx, unsigned n, Z3_ast * lits, unsigned * out_sz) +{ + unsigned num_ins = n; + unsigned num_bits = 1; + Z3_ast * aux_1; + Z3_ast * aux_2; + if (n == 0) + return 0; + aux_1 = (Z3_ast *) malloc(sizeof(Z3_ast) * (n + 1)); + aux_2 = (Z3_ast *) malloc(sizeof(Z3_ast) * (n + 1)); + memcpy(aux_1, lits, sizeof(Z3_ast) * n); + while (num_ins > 1) { + unsigned new_num_ins; + Z3_ast * tmp; + mk_adder_pairs(ctx, num_bits, num_ins, aux_1, &new_num_ins, aux_2); + num_ins = new_num_ins; + num_bits++; +#ifdef MAXSAT_DEBUG + { + unsigned i; + printf("num_bits: %d, num_ins: %d \n", num_bits, num_ins); + for (i = 0; i < num_ins * num_bits; i++) { + printf("bit %d:\n%s\n", i, Z3_ast_to_string(ctx, aux_2[i])); + } + printf("-----------\n"); + } +#endif + tmp = aux_1; + aux_1 = aux_2; + aux_2 = tmp; + } + *out_sz = num_bits; + free(aux_2); + return aux_1; +} + +/** + \brief Return the \c idx bit of \c val. +*/ +int get_bit(unsigned val, unsigned idx) +{ + unsigned mask = 1 << (idx & 31); + return (val & mask) != 0; +} + +/** + \brief Given an integer val encoded in n bits (boolean variables), assert the constraint that val <= k. +*/ +void assert_le_k(Z3_context ctx, unsigned n, Z3_ast * val, unsigned k) +{ + Z3_ast i1, i2, not_val, out; + unsigned idx; + not_val = Z3_mk_not(ctx, val[0]); + if (get_bit(k, 0)) + out = Z3_mk_true(ctx); + else + out = not_val; + for (idx = 1; idx < n; idx++) { + not_val = Z3_mk_not(ctx, val[idx]); + if (get_bit(k, idx)) { + i1 = not_val; + i2 = out; + } + else { + i1 = Z3_mk_false(ctx); + i2 = Z3_mk_false(ctx); + } + out = mk_ternary_or(ctx, i1, i2, mk_binary_and(ctx, not_val, out)); + } + // printf("at-most-k:\n%s\n", Z3_ast_to_string(ctx, out)); + Z3_assert_cnstr(ctx, out); +} + +/** + \brief Assert that at most \c k literals in \c lits can be true, + where \c n is the number of literals in lits. + + We use a simple encoding using an adder (counter). + An interesting exercise consists in implementing more sophisticated encodings. +*/ +void assert_at_most_k(Z3_context ctx, unsigned n, Z3_ast * lits, unsigned k) +{ + Z3_ast * counter_bits; + unsigned counter_bits_sz; + if (k >= n || n <= 1) + return; /* nothing to be done */ + counter_bits = mk_counter_circuit(ctx, n, lits, &counter_bits_sz); + assert_le_k(ctx, counter_bits_sz, counter_bits, k); + del_bool_var_array(counter_bits); +} + +/** + \brief Assert that at most one literal in \c lits can be true, + where \c n is the number of literals in lits. +*/ +void assert_at_most_one(Z3_context ctx, unsigned n, Z3_ast * lits) +{ + assert_at_most_k(ctx, n, lits, 1); +} + +/** + \brief Small test for the at-most-one constraint. +*/ +void tst_at_most_one() +{ + Z3_context ctx = mk_context(); + Z3_ast k1 = mk_bool_var(ctx, "k1"); + Z3_ast k2 = mk_bool_var(ctx, "k2"); + Z3_ast k3 = mk_bool_var(ctx, "k3"); + Z3_ast k4 = mk_bool_var(ctx, "k4"); + Z3_ast k5 = mk_bool_var(ctx, "k5"); + Z3_ast k6 = mk_bool_var(ctx, "k6"); + Z3_ast args1[5] = { k1, k2, k3, k4, k5 }; + Z3_ast args2[3] = { k4, k5, k6 }; + Z3_model m = 0; + Z3_lbool result; + printf("testing at-most-one constraint\n"); + assert_at_most_one(ctx, 5, args1); + assert_at_most_one(ctx, 3, args2); + printf("it must be sat...\n"); + result = Z3_check_and_get_model(ctx, &m); + if (result != Z3_L_TRUE) + error("BUG"); + printf("model:\n%s\n", Z3_model_to_string(ctx, m)); + if (m) { + Z3_del_model(ctx, m); + } + Z3_assert_cnstr(ctx, mk_binary_or(ctx, k2, k3)); + Z3_assert_cnstr(ctx, mk_binary_or(ctx, k1, k6)); + printf("it must be sat...\n"); + result = Z3_check_and_get_model(ctx, &m); + if (result != Z3_L_TRUE) + error("BUG"); + printf("model:\n%s\n", Z3_model_to_string(ctx, m)); + if (m) { + Z3_del_model(ctx, m); + } + Z3_assert_cnstr(ctx, mk_binary_or(ctx, k4, k5)); + printf("it must be unsat...\n"); + result = Z3_check_and_get_model(ctx, &m); + if (result != Z3_L_FALSE) + error("BUG"); + Z3_del_context(ctx); +} + +/** + \brief Return the number of soft-constraints that were disable by the given model. + A soft-constraint was disabled if the associated auxiliary variable was assigned to true. +*/ +unsigned get_num_disabled_soft_constraints(Z3_context ctx, Z3_model m, unsigned num_soft_cnstrs, Z3_ast * aux_vars) +{ + unsigned i; + unsigned num_disabled = 0; + Z3_ast t = Z3_mk_true(ctx); + for (i = 0; i < num_soft_cnstrs; i++) { + Z3_ast val; + if (Z3_eval(ctx, m, aux_vars[i], &val) == Z3_TRUE) { + // printf("%s", Z3_ast_to_string(ctx, aux_vars[i])); + // printf(" -> %s\n", Z3_ast_to_string(ctx, val)); + if (Z3_is_eq_ast(ctx, val, t)) { + num_disabled++; + } + } + } + return num_disabled; +} + +/** + \brief Naive maxsat procedure based on linear search and at-most-k + constraint. Return the number of soft-constraints that can be + satisfied. Return -1 if the hard-constraints cannot be + satisfied. That is, the formula cannot be satisfied even if all + soft-constraints are ignored. + + Exercise: use binary search to implement MaxSAT. + Hint: you will need to use an answer literal to retract the at-most-k constraint. +*/ +int naive_maxsat(Z3_context ctx, unsigned num_hard_cnstrs, Z3_ast * hard_cnstrs, unsigned num_soft_cnstrs, Z3_ast * soft_cnstrs) +{ + Z3_ast * aux_vars; + Z3_lbool is_sat; + unsigned r, k; + assert_hard_constraints(ctx, num_hard_cnstrs, hard_cnstrs); + printf("checking whether hard constraints are satisfiable...\n"); + is_sat = Z3_check(ctx); + if (is_sat == Z3_L_FALSE) { + // It is not possible to make the formula satisfiable even when ignoring all soft constraints. + return -1; + } + if (num_soft_cnstrs == 0) + return 0; // nothing to be done... + aux_vars = assert_soft_constraints(ctx, num_soft_cnstrs, soft_cnstrs); + // Perform linear search. + r = 0; + k = num_soft_cnstrs - 1; + for (;;) { + Z3_model m; + unsigned num_disabled; + // at most k soft-constraints can be ignored. + printf("checking whether at-most %d soft-constraints can be ignored.\n", k); + assert_at_most_k(ctx, num_soft_cnstrs, aux_vars, k); + is_sat = Z3_check_and_get_model(ctx, &m); + if (is_sat == Z3_L_FALSE) { + printf("unsat\n"); + return num_soft_cnstrs - k - 1; + } + num_disabled = get_num_disabled_soft_constraints(ctx, m, num_soft_cnstrs, aux_vars); + if (num_disabled > k) { + error("BUG"); + } + if (m) { + Z3_del_model(ctx, m); + } + printf("sat\n"); + k = num_disabled; + if (k == 0) { + // it was possible to satisfy all soft-constraints. + return num_soft_cnstrs; + } + k--; + } +} + +/** + \brief Implement one step of the Fu&Malik algorithm. + See fu_malik_maxsat function for more details. + + Input: soft constraints + aux-vars (aka answer literals) + Output: done/not-done when not done return updated set of soft-constraints and aux-vars. + - if SAT --> terminates + - if UNSAT + * compute unsat core + * add blocking variable to soft-constraints in the core + - replace soft-constraint with the one with the blocking variable + - we should also add an aux-var + - replace aux-var with a new one + * add at-most-one constraint with blocking +*/ +int fu_malik_maxsat_step(Z3_context ctx, unsigned num_soft_cnstrs, Z3_ast * soft_cnstrs, Z3_ast * aux_vars) +{ + // create assumptions + Z3_ast * assumptions = (Z3_ast*) malloc(sizeof(Z3_ast) * num_soft_cnstrs); + Z3_ast * core = (Z3_ast*) malloc(sizeof(Z3_ast) * num_soft_cnstrs); + unsigned core_size; + Z3_ast dummy_proof; // we don't care about proofs in this example + Z3_model m; + Z3_lbool is_sat; + unsigned i = 0; + for (i = 0; i < num_soft_cnstrs; i++) { + // Recall that we asserted (soft_cnstrs[i] \/ aux_vars[i]) + // So using (NOT aux_vars[i]) as an assumption we are actually forcing the soft_cnstrs[i] to be considered. + assumptions[i] = Z3_mk_not(ctx, aux_vars[i]); + core[i] = 0; + } + + is_sat = Z3_check_assumptions(ctx, num_soft_cnstrs, assumptions, &m, &dummy_proof, &core_size, core); + if (is_sat != Z3_L_FALSE) { + return 1; // done + } + else { + Z3_ast * block_vars = (Z3_ast*) malloc(sizeof(Z3_ast) * core_size); + unsigned k = 0; + // update soft-constraints and aux_vars + for (i = 0; i < num_soft_cnstrs; i++) { + unsigned j; + // check whether assumption[i] is in the core or not + for (j = 0; j < core_size; j++) { + if (assumptions[i] == core[j]) + break; + } + if (j < core_size) { + // assumption[i] is in the unsat core... so soft_cnstrs[i] is in the unsat core + Z3_ast block_var = mk_fresh_bool_var(ctx); + Z3_ast new_aux_var = mk_fresh_bool_var(ctx); + soft_cnstrs[i] = mk_binary_or(ctx, soft_cnstrs[i], block_var); + aux_vars[i] = new_aux_var; + block_vars[k] = block_var; + k++; + // Add new constraint containing the block variable. + // Note that we are using the new auxiliary variable to be able to use it as an assumption. + Z3_assert_cnstr(ctx, mk_binary_or(ctx, soft_cnstrs[i], new_aux_var)); + } + } + assert_at_most_one(ctx, k, block_vars); + return 0; // not done. + } +} + +/** + \brief Fu & Malik procedure for MaxSAT. This procedure is based on + unsat core extraction and the at-most-one constraint. + + Return the number of soft-constraints that can be + satisfied. Return -1 if the hard-constraints cannot be + satisfied. That is, the formula cannot be satisfied even if all + soft-constraints are ignored. + + For more information on the Fu & Malik procedure: + + Z. Fu and S. Malik, On solving the partial MAX-SAT problem, in International + Conference on Theory and Applications of Satisfiability Testing, 2006. +*/ +int fu_malik_maxsat(Z3_context ctx, unsigned num_hard_cnstrs, Z3_ast * hard_cnstrs, unsigned num_soft_cnstrs, Z3_ast * soft_cnstrs) +{ + Z3_ast * aux_vars; + Z3_lbool is_sat; + unsigned k; + assert_hard_constraints(ctx, num_hard_cnstrs, hard_cnstrs); + printf("checking whether hard constraints are satisfiable...\n"); + is_sat = Z3_check(ctx); + if (is_sat == Z3_L_FALSE) { + // It is not possible to make the formula satisfiable even when ignoring all soft constraints. + return -1; + } + if (num_soft_cnstrs == 0) + return 0; // nothing to be done... + /* + Fu&Malik algorithm is based on UNSAT-core extraction. + We accomplish that using auxiliary variables (aka answer literals). + */ + aux_vars = assert_soft_constraints(ctx, num_soft_cnstrs, soft_cnstrs); + k = 0; + for (;;) { + printf("iteration %d\n", k); + if (fu_malik_maxsat_step(ctx, num_soft_cnstrs, soft_cnstrs, aux_vars)) { + return num_soft_cnstrs - k; + } + k++; + } +} + +#define NAIVE_MAXSAT 0 +#define FU_MALIK_MAXSAT 1 + +/** + \brief Finds the maximal number of assumptions that can be satisfied. + An assumption is any formula preceeded with the :assumption keyword. + "Hard" constraints can be supported by using the :formula keyword. + + Input: file in SMT-LIB format, and MaxSAT algorithm to be used: 0 - Naive, 1 - Fu&Malik's algo. + Output: the maximum number of assumptions that can be satisfied. +*/ +int smtlib_maxsat(char * file_name, int approach) +{ + Z3_context ctx; + unsigned num_hard_cnstrs, num_soft_cnstrs; + Z3_ast * hard_cnstrs, * soft_cnstrs; + unsigned result; + ctx = mk_context(); + Z3_parse_smtlib_file(ctx, file_name, 0, 0, 0, 0, 0, 0); + hard_cnstrs = get_hard_constraints(ctx, &num_hard_cnstrs); + soft_cnstrs = get_soft_constraints(ctx, &num_soft_cnstrs); + switch (approach) { + case NAIVE_MAXSAT: + result = naive_maxsat(ctx, num_hard_cnstrs, hard_cnstrs, num_soft_cnstrs, soft_cnstrs); + break; + case FU_MALIK_MAXSAT: + result = fu_malik_maxsat(ctx, num_hard_cnstrs, hard_cnstrs, num_soft_cnstrs, soft_cnstrs); + break; + default: + /* Exercise: implement your own MaxSAT algorithm.*/ + error("Not implemented yet."); + break; + } + free_cnstr_array(hard_cnstrs); + free_cnstr_array(soft_cnstrs); + return result; +} + +int main(int argc, char * argv[]) { +#if 1 + int r; + if (argc != 2) { + error("usage: maxsat [filename.smt]."); + } + r = smtlib_maxsat(argv[1], FU_MALIK_MAXSAT); + printf("result: %d\n", r); +#else + tst_at_most_one(); +#endif + return 0; +} + +/*@}*/ + diff --git a/maxsat/maxsat.vcxproj b/maxsat/maxsat.vcxproj new file mode 100644 index 000000000..1679dd545 --- /dev/null +++ b/maxsat/maxsat.vcxproj @@ -0,0 +1,163 @@ + + + + + commercial_64 + Win32 + + + commercial + Win32 + + + Debug + Win32 + + + Release + Win32 + + + + {7C154132-AAAB-4F60-B652-F8C51A63D244} + Win32Proj + maxsat + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + true + + + false + + + false + + + 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 + + + + + + + + {4a7e5a93-19d8-4382-8950-fb2edec7a76e} + true + false + false + true + false + + + + + + \ No newline at end of file diff --git a/maxsat/maxsat.vcxproj.user b/maxsat/maxsat.vcxproj.user new file mode 100644 index 000000000..ace9a86ac --- /dev/null +++ b/maxsat/maxsat.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/shell/datalog_frontend.cpp b/shell/datalog_frontend.cpp new file mode 100644 index 000000000..83ad81b0a --- /dev/null +++ b/shell/datalog_frontend.cpp @@ -0,0 +1,278 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + datalog_frontend.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-05-18. + +Revision History: + +--*/ + + +#include +#include +#include +#include"stopwatch.h" +#include"front_end_params.h" +#include"datalog_parser.h" +#include"arith_decl_plugin.h" +#include"dl_compiler.h" +#include"dl_context.h" +#include"dl_mk_filter_rules.h" +#include"dl_finite_product_relation.h" +#include"datalog_frontend.h" +#include"timeout.h" + +static stopwatch g_overall_time; +static stopwatch g_piece_timer; +static unsigned t_parsing = 0; + +static datalog::context * g_ctx = 0; +static datalog::rule_set * g_orig_rules; +static datalog::instruction_block * g_code; +static datalog::execution_context * g_ectx; +static front_end_params * g_params; + +datalog_params::datalog_params(): + m_default_table("sparse") +{} + +void datalog_params::register_params(ini_params& p) { + p.register_symbol_param("DEFAULT_TABLE", m_default_table, "Datalog engine: default table (sparse)"); +} + +static void display_statistics( + std::ostream& out, + datalog::context& ctx, + datalog::rule_set& orig_rules, + datalog::instruction_block& code, + datalog::execution_context& ex_ctx, + front_end_params& params, + bool verbose + ) +{ + g_piece_timer.stop(); + unsigned t_other = static_cast(g_piece_timer.get_seconds()*1000); + g_overall_time.stop(); + + code.process_all_costs(); + { + params_ref p(ctx.get_params()); + p.set_bool(":output-profile", true); + p.set_uint(":profile-milliseconds-threshold", 100); + ctx.updt_params(p); + + out << "--------------\n"; + out << "original rules\n"; + orig_rules.display(out); + + out << "---------------\n"; + out << "generated rules\n"; + ctx.display_rules(out); + + out << "--------------\n"; + out << "instructions \n"; + code.display(ctx, out); + + out << "--------------\n"; + out << "big relations \n"; + ex_ctx.report_big_relations(1000, out); + } + out << "--------------\n"; + out << "relation sizes\n"; + ctx.get_rmanager().display_relation_sizes(out); + + if (verbose) { + out << "--------------\n"; + out << "rules\n"; + ctx.display_rules(out); + } + + out << "Time: " << static_cast(g_overall_time.get_seconds()*1000) << "ms\n"; + out << "Parsing: " << t_parsing << "ms, other: " << t_other << "ms\n"; +} + + +static void display_statistics() { + if (g_ctx) { + display_statistics(std::cout, *g_ctx, *g_orig_rules, *g_code, *g_ectx, *g_params, true); + } +} + +static void on_timeout() { + display_statistics(); + exit(0); +} + +static void on_ctrl_c(int) { + signal (SIGINT, SIG_DFL); + display_statistics(); + raise(SIGINT); +} + + +unsigned read_datalog(char const * file, datalog_params const& dl_params, front_end_params & front_end_params) { + IF_VERBOSE(1, verbose_stream() << "Z3 Datalog Engine\n";); + ast_manager m; + g_overall_time.start(); + register_on_timeout_proc(on_timeout); + signal(SIGINT, on_ctrl_c); + params_ref params; + params.set_sym(":engine", symbol("datalog")); + params.set_sym(":default-table", dl_params.m_default_table); + + datalog::context ctx(m, front_end_params, params); + size_t watermark = front_end_params.m_memory_high_watermark; + if (watermark == 0) { + memory::set_high_watermark(static_cast(UINT_MAX)); + } + datalog::relation_manager & rmgr = ctx.get_rmanager(); + datalog::relation_plugin & inner_plg = *rmgr.get_relation_plugin(symbol("tr_hashtable")); + SASSERT(&inner_plg); + rmgr.register_plugin(alloc(datalog::finite_product_relation_plugin, inner_plg, rmgr)); + + g_piece_timer.reset(); + g_piece_timer.start(); + + bool wpa_benchmark = datalog::is_directory(std::string(file)); + if (wpa_benchmark) { + scoped_ptr parser = datalog::wpa_parser::create(ctx, m); + if (!parser->parse_directory(file)) { + std::cerr << "ERROR: failed to parse file\n"; + return 1; + } + } + else { + scoped_ptr parser = datalog::parser::create(ctx, m); + if (!parser->parse_file(file)) { + std::cerr << "ERROR: failed to parse file\n"; + return 1; + } + } + + g_piece_timer.stop(); + t_parsing = static_cast(g_piece_timer.get_seconds()*1000); + IF_VERBOSE(1, verbose_stream() << "parsing finished\n";); + IF_VERBOSE(1, verbose_stream() << "running saturation...\n";); + g_piece_timer.reset(); + g_piece_timer.start(); + //all rules were added + ctx.close(); + + TRACE("dl_compiler", ctx.display(tout);); + + datalog::rule_set original_rules(ctx.get_rules()); + datalog::decl_set original_predicates; + ctx.collect_predicates(original_predicates); + + datalog::instruction_block rules_code; + datalog::instruction_block termination_code; + datalog::execution_context ex_ctx(ctx); + + IF_VERBOSE(10, original_rules.display_deps(verbose_stream());); + + g_ctx = &ctx; + g_orig_rules = &original_rules; + g_code = &rules_code; + g_ectx = &ex_ctx; + g_params = &front_end_params; + + try { + g_piece_timer.reset(); + g_piece_timer.start(); + + bool early_termination; + unsigned timeout = ctx.initial_restart_timeout(); + if(timeout == 0) { + timeout = UINT_MAX; + } + do { + model_converter_ref mc; // ignored + proof_converter_ref pc; // ignored + ctx.transform_rules(mc, pc); + + datalog::compiler::compile(ctx, ctx.get_rules(), rules_code, termination_code); + + TRACE("dl_compiler", rules_code.display(ctx, tout);); + + rules_code.make_annotations(ex_ctx); + + ex_ctx.set_timelimit(timeout); + SASSERT(!ex_ctx.should_terminate()); + + early_termination = !rules_code.perform(ex_ctx); + if(early_termination) { + IF_VERBOSE(10, ex_ctx.report_big_relations(1000, verbose_stream());); + if (memory::above_high_watermark()) { + throw out_of_memory_error(); + } + } + ex_ctx.reset_timelimit(); + TRUSTME( termination_code.perform(ex_ctx) ); + ctx.saturation_was_run(); + + if (early_termination) { + IF_VERBOSE(1, verbose_stream() << "restarting saturation\n";); + + uint64 new_timeout = static_cast(timeout)*ctx.initial_restart_timeout(); + if(new_timeout>UINT_MAX) { + timeout=UINT_MAX; + } + else { + timeout=static_cast(new_timeout); + } + + rules_code.process_all_costs(); + rules_code.reset(); + termination_code.reset(); + ex_ctx.reset(); + ctx.reopen(); + ctx.restrict_predicates(original_predicates); + ctx.replace_rules(original_rules); + ctx.close(); + } + } while (early_termination); + + + TRACE("dl_compiler", ctx.display(tout); + rules_code.display(ctx, tout);); + + if (ctx.get_params().get_bool(":output-tuples", true)) { + ctx.display_output_facts(std::cout); + } + + display_statistics( + std::cout, + ctx, + original_rules, + rules_code, + ex_ctx, + front_end_params, + false); + + } + catch (out_of_memory_error) { + std::cout << "\n\nOUT OF MEMORY!\n\n"; + display_statistics( + std::cout, + ctx, + original_rules, + rules_code, + ex_ctx, + front_end_params, + true); + return ERR_MEMOUT; + } + register_on_timeout_proc(0); + return 0; +} + diff --git a/shell/datalog_frontend.h b/shell/datalog_frontend.h new file mode 100644 index 000000000..52a9273d5 --- /dev/null +++ b/shell/datalog_frontend.h @@ -0,0 +1,32 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + datalog_frontend.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-05-18. + +Revision History: + +--*/ +#ifndef _DATALOG_FRONTEND_H_ +#define _DATALOG_FRONTEND_H_ + +struct datalog_params { + symbol m_default_table; + datalog_params(); + virtual void register_params(ini_params& p); +}; + +unsigned read_datalog(char const * file, datalog_params const& dl_params, front_end_params & front_end_params); + + +#endif /* _DATALOG_FRONTEND_H_ */ + diff --git a/shell/dimacs_frontend.cpp b/shell/dimacs_frontend.cpp new file mode 100644 index 000000000..cf64ed110 --- /dev/null +++ b/shell/dimacs_frontend.cpp @@ -0,0 +1,106 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + dimacs_frontend.cpp + +Abstract: + + Frontend for reading dimacs input files + +Author: + + Leonardo de Moura (leonardo) 2011-07-26. + +Revision History: + +--*/ +#include +#include +#include +#include"timeout.h" +#include"dimacs.h" +#include"sat_solver.h" +#include"front_end_params.h" + +extern bool g_display_statistics; +static sat::solver * g_solver = 0; +static clock_t g_start_time; + +static void display_statistics() { + clock_t end_time = clock(); + if (g_solver && g_display_statistics) { + std::cout.flush(); + std::cerr.flush(); + + statistics st; + g_solver->collect_statistics(st); + st.update("total time", ((static_cast(end_time) - static_cast(g_start_time)) / CLOCKS_PER_SEC)); + st.display_smt2(std::cout); + } +} + +static void on_timeout() { + display_statistics(); + exit(0); +} + +static void on_ctrl_c(int) { + signal (SIGINT, SIG_DFL); + display_statistics(); + raise(SIGINT); +} + +static void display_model(sat::solver const & s) { + sat::model const & m = s.get_model(); + for (unsigned i = 1; i < m.size(); i++) { + switch (m[i]) { + case l_false: std::cout << "-" << i << " "; break; + case l_undef: break; + case l_true: std::cout << i << " "; break; + } + } + std::cout << "\n"; +} + +unsigned read_dimacs(char const * file_name, front_end_params & front_end_params) { + g_start_time = clock(); + register_on_timeout_proc(on_timeout); + signal(SIGINT, on_ctrl_c); + params_ref p; + p.set_bool(":produce-models", front_end_params.m_model); + sat::solver solver(p, 0); + g_solver = &solver; + + if (file_name) { + std::ifstream in(file_name); + if (in.bad() || in.fail()) { + std::cerr << "(error \"failed to open file '" << file_name << "'\")" << std::endl; + exit(ERR_OPEN_FILE); + } + parse_dimacs(in, solver); + } + else { + parse_dimacs(std::cin, solver); + } + IF_VERBOSE(20, solver.display_status(verbose_stream());); + + lbool r = solver.check(); + switch (r) { + case l_true: + std::cout << "sat\n"; + if (front_end_params.m_model) + display_model(solver); + break; + case l_undef: + std::cout << "unknown\n"; + break; + case l_false: + std::cout << "unsat\n"; + break; + } + if (g_display_statistics) + display_statistics(); + return 0; +} diff --git a/shell/dimacs_frontend.h b/shell/dimacs_frontend.h new file mode 100644 index 000000000..22ab63529 --- /dev/null +++ b/shell/dimacs_frontend.h @@ -0,0 +1,25 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + dimacs_frontend.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2011-07-26. + +Revision History: + +--*/ +#ifndef _DIMACS_FRONTEND_H_ +#define _DIMACS_FRONTEND_H_ + +unsigned read_dimacs(char const * benchmark_file, front_end_params & front_end_params); + +#endif /* _DATALOG_FRONTEND_H_ */ + diff --git a/shell/main.cpp b/shell/main.cpp new file mode 100644 index 000000000..b426f2885 --- /dev/null +++ b/shell/main.cpp @@ -0,0 +1,459 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + main.cpp + +Abstract: + + Z3 command line tool. + +Author: + + Leonardo de Moura (leonardo) 2006-10-10. + Nikolaj Bjorner (nbjorner) + +Revision History: + +--*/ +#include +#include"memory_manager.h" +#include"trace.h" +#include"debug.h" +#include"util.h" +#include"pp.h" +#include"smtlib_frontend.h" +#include"z3_log_frontend.h" +#include"warning.h" +#include"version.h" +#include"datalog_frontend.h" +#include"dimacs_frontend.h" +#include"timeout.h" +#include"z3_exception.h" +#include"error_codes.h" + +typedef enum { IN_UNSPECIFIED, IN_SMTLIB, IN_SMTLIB_2, IN_DATALOG, IN_DIMACS, IN_Z3_LOG } input_kind; + +std::string g_aux_input_file; +char const * g_input_file = 0; +bool g_standard_input = false; +input_kind g_input_kind = IN_UNSPECIFIED; +front_end_params * g_front_end_params = 0; +bool g_display_statistics = false; +bool g_display_istatistics = false; + +#ifdef _WINDOWS +#define OPT "/" +#else +#define OPT "-" +#endif + +void error(const char * msg) { + std::cerr << "Error: " << msg << "\n"; + std::cerr << "For usage information: z3 " << OPT << "h\n"; + exit(ERR_CMD_LINE); +} + +void display_usage() { + std::cout << "Z3 [version " << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "]. (C) Copyright 2006 Microsoft Corp.\n"; + std::cout << "Usage: z3 [options] [" << OPT << "file:]file\n"; + std::cout << "\nInput format:\n"; + std::cout << " " << OPT << "smt use parser for SMT input format.\n"; + std::cout << " " << OPT << "smt2 use parser for SMT 2 input format.\n"; + std::cout << " " << OPT << "dl use parser for Datalog input format.\n"; + std::cout << " " << OPT << "dimacs use parser for DIMACS input format.\n"; + std::cout << " " << OPT << "log use parser for Z3 log input format.\n"; + std::cout << " " << OPT << "in read formula from standard input.\n"; + std::cout << "\nMiscellaneous:\n"; + std::cout << " " << OPT << "h, " << OPT << "? prints this message.\n"; + std::cout << " " << OPT << "version prints version number of Z3.\n"; + std::cout << " " << OPT << "v:level be verbose, where is the verbosity level.\n"; + std::cout << " " << OPT << "nw disable warning messages.\n"; + std::cout << " " << OPT << "ini:file configuration file.\n"; + std::cout << " " << OPT << "ini? display all available INI file parameters.\n"; + std::cout << " --" << " all remaining arguments are assumed to be part of the input file name. This option allows Z3 to read files with strange names such as: -foo.smt2.\n"; + std::cout << "\nResources:\n"; + // timeout and memout are now available on Linux and OSX too. + std::cout << " " << OPT << "T:timeout set the timeout (in seconds).\n"; + std::cout << " " << OPT << "t:timeout set the soft timeout (in seconds). It only kills the current query.\n"; + std::cout << " " << OPT << "memory:Megabytes set a limit for virtual memory consumption.\n"; + // + std::cout << "\nOutput:\n"; + std::cout << " " << OPT << "st display statistics.\n"; + std::cout << "\nSearch heuristics:\n"; + std::cout << " " << OPT << "rs:num random seed.\n"; +#if defined(Z3DEBUG) || defined(_TRACE) + std::cout << "\nDebugging support:\n"; +#endif +#ifdef _TRACE + std::cout << " " << OPT << "tr:tag enable trace messages tagged with .\n"; +#endif +#ifdef Z3DEBUG + std::cout << " " << OPT << "dbg:tag enable assertions tagged with .\n"; +#endif +} + +class extra_params : public datalog_params { + bool & m_statistics; +public: + extra_params(): + m_statistics(g_display_statistics) { + } + + virtual void register_params(ini_params & p) { + datalog_params::register_params(p); + p.register_bool_param("STATISTICS", m_statistics, "display statistics"); + } +}; + +ini_params* g_params = 0; +extra_params* g_extra_params = 0; +bool g_params_initialized = false; + +void init_params() { + if (!g_params_initialized) { + z3_bound_num_procs(); + g_front_end_params = new front_end_params(); + g_params = new ini_params(); + g_extra_params = new extra_params(); + register_verbosity_level(*g_params); + register_warning(*g_params); + register_pp_params(*g_params); + g_front_end_params->register_params(*g_params); + g_extra_params->register_params(*g_params); + g_params_initialized = true; + } +} + +void del_params() { + if (g_front_end_params != NULL) + g_front_end_params->close_trace_file(); + delete g_extra_params; + delete g_params; + delete g_front_end_params; + g_extra_params = 0; + g_params = 0; + g_front_end_params = 0; +} + + +void read_ini_file(const char * file_name) { + std::ifstream in(file_name); + if (in.bad() || in.fail()) { + std::cerr << "Error: failed to open init file \"" << file_name << "\".\n"; + exit(ERR_INI_FILE); + } + g_params->read_ini_file(in); +} + +void display_ini_help() { + g_params->display_params(std::cout); +} + +void display_config() { + if (g_front_end_params->m_display_config) { + display_ini_help(); + } +} + +void display_ini_doc() { + g_params->display_params_documentation(std::cout); +} + +void parse_cmd_line_args(int argc, char ** argv) { + int i = 1; + char * eq_pos = 0; + while (i < argc) { + char * arg = argv[i]; + + if (arg[0] == '-' && arg[1] == '-' && arg[2] == 0) { + // Little hack used to read files with strange names such as -foo.smt2 + // z3 -- -foo.smt2 + i++; + g_aux_input_file = ""; + for (; i < argc; i++) { + g_aux_input_file += argv[i]; + if (i < argc - 1) + g_aux_input_file += " "; + } + if (g_front_end_params->m_interactive) { + warning_msg("ignoring input file in interactive mode."); + } + else if (g_input_file) { + warning_msg("input file was already specified."); + } + else { + g_input_file = g_aux_input_file.c_str(); + } + break; + } + + if (arg[0] == '-' +#ifdef _WINDOWS + || arg[0] == '/' +#endif + ) { + char * opt_name = arg + 1; + char * opt_arg = 0; + char * colon = strchr(arg, ':'); + if (colon) { + opt_arg = colon + 1; + *colon = 0; + } + if (strcmp(opt_name, "h") == 0 || strcmp(opt_name, "?") == 0 || strcmp(opt_name, "help") == 0) { + display_usage(); + exit(0); + } + if (strcmp(opt_name, "version") == 0) { +#ifdef _EXTERNAL_RELEASE + std::cout << "Z3 version " << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "\n"; +#else + std::cout + << "Z3 version (major minor build revision): " + << Z3_MAJOR_VERSION << " " + << Z3_MINOR_VERSION << " " + << Z3_BUILD_NUMBER << " " + << Z3_REVISION_NUMBER << "\n"; +#endif + exit(0); + } + else if (strcmp(opt_name, "smt") == 0) { + g_input_kind = IN_SMTLIB; + } + else if (strcmp(opt_name, "smt2") == 0) { + g_input_kind = IN_SMTLIB_2; + } + else if (strcmp(opt_name, "in") == 0) { + g_standard_input = true; + } + else if (strcmp(opt_name, "dimacs") == 0) { + g_input_kind = IN_DIMACS; + } + else if (strcmp(opt_name, "log") == 0) { + g_input_kind = IN_Z3_LOG; + } + else if (strcmp(opt_name, "st") == 0) { + g_display_statistics = true; + } + else if (strcmp(opt_name, "ist") == 0) { + g_display_istatistics = true; + } + else if (strcmp(opt_name, "v") == 0) { + if (!opt_arg) + error("option argument (/v:level) is missing."); + long lvl = strtol(opt_arg, 0, 10); + set_verbosity_level(lvl); + } + else if (strcmp(opt_name, "vldt") == 0) { + g_front_end_params->m_model_validate = true; + } + else if (strcmp(opt_name, "file") == 0) { + g_input_file = opt_arg; + } + else if (strcmp(opt_name, "r") == 0) { + if (!opt_arg) { + error("optional argument (/r:level) is missing."); + } + g_front_end_params->m_relevancy_lvl = strtol(opt_arg, 0, 10); + } + else if (strcmp(opt_name, "rd") == 0) { + if (!opt_arg) { + error("optional argument (/rd:num) is missing."); + } + g_front_end_params->m_random_var_freq = static_cast(strtol(opt_arg, 0, 10)) / 100.0; + } + else if (strcmp(opt_name, "rs") == 0) { + if (!opt_arg) { + error("optional argument (/rs:num) is missing."); + } + long seed = strtol(opt_arg, 0, 10); + g_front_end_params->m_random_seed = seed; + g_front_end_params->m_arith_random_seed = seed; + } + else if (strcmp(opt_name, "T") == 0) { + if (!opt_arg) + error("option argument (/T:timeout) is missing."); + long tm = strtol(opt_arg, 0, 10); + set_timeout(tm * 1000); + } + else if (strcmp(opt_name, "t") == 0) { + if (!opt_arg) + error("option argument (/t:timeout) is missing."); + long tm = strtol(opt_arg, 0, 10); + g_front_end_params->m_soft_timeout = tm*1000; + } + else if (strcmp(opt_name, "nw") == 0) { + enable_warning_messages(false); + } + else if (strcmp(opt_name, "ini") == 0) { + if (!opt_arg) + error("option argument (/ini:file) is missing."); + read_ini_file(opt_arg); + } + else if (strcmp(opt_name, "ini?") == 0) { + display_ini_help(); + exit(0); + } + else if (strcmp(opt_name, "geninidoc") == 0) { + display_ini_doc(); + exit(0); + } +#ifdef _TRACE + else if (strcmp(opt_name, "tr") == 0) { + if (!opt_arg) + error("option argument (/tr:tag) is missing."); + enable_trace(opt_arg); + } +#endif +#ifdef Z3DEBUG + else if (strcmp(opt_name, "dbg") == 0) { + if (!opt_arg) + error("option argument (/dbg:tag) is missing."); + enable_debug(opt_arg); + } +#endif + else if (strcmp(opt_name, "memory") == 0) { + if (!opt_arg) + error("option argument (/memory:val) is missing."); + g_front_end_params->m_memory_high_watermark = strtoul(opt_arg, 0, 10); + } + else { + std::cerr << "Error: invalid command line option: " << arg << "\n"; + std::cerr << "For usage information: z3 " << OPT << "h\n"; + exit(ERR_CMD_LINE); + } + } + else if (argv[i][0] != '"' && (eq_pos = strchr(argv[i], '='))) { + char * key = argv[i]; + *eq_pos = 0; + char * value = eq_pos+1; + g_params->set_param_value(key, value); + } + else { + if (g_front_end_params->m_interactive) { + warning_msg("ignoring input file in interactive mode."); + } + else if (g_input_file) { + warning_msg("input file was already specified."); + } + else { + g_input_file = arg; + } + } + i++; + } +} + +char const * get_extension(char const * file_name) { + if (file_name == 0) + return 0; + char const * last_dot = 0; + for (;;) { + char const * tmp = strchr(file_name, '.'); + if (tmp == 0) { + return last_dot; + } + last_dot = tmp + 1; + file_name = last_dot; + } +} + +class global_state_initialiser { +public: + global_state_initialiser() { + memory::initialize(0); +#if defined(_WINDOWS) && defined(_Z3_BUILD_PARALLEL_SMT) + memory::mem->set_threaded_mode(true); +#endif + init_params(); + } + + void reset() { + del_params(); + memory::finalize(); + } + + ~global_state_initialiser() { + reset(); + } +}; + +int main(int argc, char ** argv) { + try{ + unsigned return_value = 0; + global_state_initialiser global_state; + memory::exit_when_out_of_memory(true, "ERROR: out of memory"); + parse_cmd_line_args(argc, argv); + memory::set_high_watermark(static_cast(g_front_end_params->m_memory_high_watermark) * 1024 * 1024); + memory::set_max_size(static_cast(g_front_end_params->m_memory_max_size) * 1024 * 1024); + g_front_end_params->open_trace_file(); + DEBUG_CODE( + if (g_front_end_params->m_copy_params != -1) { + g_front_end_params->copy_params(g_front_end_params->m_copy_params); + TRACE("copy_params", g_params->display_params(tout);); + }); + if (g_input_file && g_standard_input) { + error("using standard input to read formula."); + } + if (!g_input_file && !g_front_end_params->m_interactive && !g_standard_input) { + error("input file was not specified."); + } + + if (g_input_kind == IN_UNSPECIFIED) { + g_input_kind = IN_SMTLIB; + char const * ext = get_extension(g_input_file); + if (ext) { + if (strcmp(ext, "datalog") == 0 || strcmp(ext, "dl") == 0) { + g_input_kind = IN_DATALOG; + } + else if (strcmp(ext, "dimacs") == 0 || strcmp(ext, "cnf") == 0) { + g_input_kind = IN_DIMACS; + } + else if (strcmp(ext, "log") == 0) { + g_input_kind = IN_Z3_LOG; + } + else if (strcmp(ext, "smt2") == 0) { + g_input_kind = IN_SMTLIB_2; + } + else if (strcmp(ext, "smt") == 0) { + g_input_kind = IN_SMTLIB; + } + } + } + switch (g_input_kind) { + case IN_SMTLIB: + return_value = read_smtlib_file(g_input_file, *g_front_end_params); + break; + case IN_SMTLIB_2: + memory::exit_when_out_of_memory(true, "(error \"out of memory\")"); + return_value = read_smtlib2_commands(g_input_file, *g_front_end_params); + break; + case IN_DIMACS: + return_value = read_dimacs(g_input_file, *g_front_end_params); + break; + case IN_DATALOG: + read_datalog(g_input_file, *g_extra_params, *g_front_end_params); + break; + case IN_Z3_LOG: + replay_z3_log(g_input_file); + break; + default: + UNREACHABLE(); + } + global_state.reset(); +#ifdef _WINDOWS + _CrtDumpMemoryLeaks(); +#endif + return return_value; + } + catch (z3_exception & ex) { + // unhandled exception + std::cerr << "ERROR: " << ex.msg() << "\n"; + if (ex.has_error_code()) + return ex.error_code(); + else + return ERR_INTERNAL_FATAL; + } +} + diff --git a/shell/options.h b/shell/options.h new file mode 100644 index 000000000..951062ff0 --- /dev/null +++ b/shell/options.h @@ -0,0 +1,67 @@ + +/** + \page cmdline Command line options + + \section informat Input format + + Z3 understands a set of default file extensions, and will invoke a parser based on the extension. + + - \ext{smt2} - SMT-LIB 2 format, this is the preferred input format. + + - \ext{dimacs}, \ext{cnf} - DIMACS format used by regular SAT solvers. + + - \ext{dl} - Datalog input format. + + - \ext{smt} - (deprecated) SMT-LIB 1 format. + + You can tell Z3 explicitly which grammar the input belongs to by using the following options: + + \cmdopt{smt2} use parser for SMT-LIB 2.0 input format. + + \cmdopt{dimacs} use dimacs parser to read the input file. + + \section cmdlinemis Miscellaneous + + \cmdopt{h\, ?} prints the help message. + + \cmdopt{version} prints version number of Z3. + + \cmdopt{v:level} be verbose, where is the verbosity level. + + \cmdopt{nw} disable warning messages. + + \cmdopt{ini:file} configuration file. + Several parameters are available besides the ones listed by \ty{/h}. + These parameters can be loaded from an initialization file by using + this option. + + \cmdopt{ini?} display all available INI file parameters. + + The available \ref config can also be supplied on the command + line as a pair parameter-name=parameter-value. + + \section cmdlineres Resources + + \cmdopt{T:timeout} set the timeout (in seconds). + Setting this option causes the entire process to exit. + It is a reliable way to kill Z3. + + \cmdopt{t:timeout} set the soft timeout (in seconds). + It only kills the current query. + + \cmdopt{memory:Megabytes} set a limit for virtual memory consumption. + This limit for virtual memory consumption is approximate, but in + general a good guideline for controlling the memory consumption of Z3. If the + memory consumption exceeds the specified number of Megabytes, Z3 exits with a warning + message. + + \section cmdlineout Output + + \cmdopt{st} display statistics. + This option can be used to dump various statistics about the search, + such as number of splits, conflict clauses, and quantifier instantiations. + + \section cmdlinesearch Search heuristics + + \cmdopt{rs:num} random seed. +*/ diff --git a/shell/resource.h b/shell/resource.h new file mode 100644 index 000000000..dde3ba323 --- /dev/null +++ b/shell/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by shell.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/shell/shell.rc b/shell/shell.rc new file mode 100644 index 000000000..ce6ee41f9 --- /dev/null +++ b/shell/shell.rc @@ -0,0 +1,102 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 4,2,0,0 + PRODUCTVERSION 4,2,0,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Microsoft" + VALUE "FileDescription", "Z3 shell" + VALUE "FileVersion" "4,2,0,0" + VALUE "InternalName", "Z3 shell" + VALUE "LegalCopyright", "(c) Microsoft Corporation. All rights reserved." + VALUE "OriginalFilename", "z3.exe" + VALUE "ProductName", "Z3" + VALUE "ProductVersion", "4,2,0,0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/shell/shell.vcxproj b/shell/shell.vcxproj new file mode 100644 index 000000000..35c11a5da --- /dev/null +++ b/shell/shell.vcxproj @@ -0,0 +1,1630 @@ + + + + + bench + Win32 + + + bench + x64 + + + commercial + Win32 + + + commercial + x64 + + + debug_opt + Win32 + + + debug_opt + x64 + + + Debug + Win32 + + + Debug + x64 + + + external_64 + Win32 + + + external_64 + x64 + + + external_dbg + Win32 + + + external_dbg + x64 + + + external_parallel_x64 + Win32 + + + external_parallel_x64 + x64 + + + external_parallel + Win32 + + + external_parallel + x64 + + + external + Win32 + + + external + x64 + + + mpi_debug + Win32 + + + mpi_debug + x64 + + + mpi_release + Win32 + + + mpi_release + x64 + + + parallel_debug + Win32 + + + parallel_debug + x64 + + + parallel_release + Win32 + + + parallel_release + x64 + + + ReleaseD + Win32 + + + ReleaseD + x64 + + + release_mt + Win32 + + + release_mt + x64 + + + release_static + Win32 + + + release_static + x64 + + + Release + Win32 + + + Release + x64 + + + smtcomp + Win32 + + + smtcomp + x64 + + + Trace + Win32 + + + Trace + x64 + + + + {BF547582-F16D-4BE5-B9AB-8B6A9364B447} + shell + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + + + Application + + + Application + + + Application + + + Application + Unicode + true + + + Application + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + + + 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)\ + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + z3 + + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;Z3DEBUG;_CONSOLE;_TRACE;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + %(DelayLoadDLLs) + true + Console + 8388608 + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;Z3DEBUG;_DEBUG;_CONSOLE;_TRACE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;ASYNC_COMMANDS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 33554432 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;Z3DEBUG;NDEBUG;_CONSOLE;_WINDOWS;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;Z3DEBUG;_CONSOLE;_WINDOWS;_DEBUG;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + Full + true + Speed + true + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + + + MultiThreadedDLL + false + StreamingSIMDExtensions2 + Fast + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + Full + true + Speed + true + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + + + MultiThreadedDLL + false + StreamingSIMDExtensions2 + Fast + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_Z3_COMMERCIAL;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_EXTERNAL_RELEASE;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_Z3_COMMERCIAL;_EXTERNAL_RELEASE;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;Z3DEBUG;_CONSOLE;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;Z3DEBUG;_CONSOLE;_TRACE;_WINDOWS;_Z3_BUILD_PARALLEL_SMT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + C:\Program Files\Microsoft HPC Pack 2008 SDK\Lib\i386;%(AdditionalLibraryDirectories) + %(DelayLoadDLLs) + true + Console + 8388608 + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;Z3DEBUG;_DEBUG;_CONSOLE;_Z3_BUILD_PARALLEL_SMT;_TRACE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + true + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_Z3_BUILD_PARALLEL_SMT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + %(AdditionalLibraryDirectories) + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + $(OutDir)z3shell.lib + + + + + false + ..\lib;C:\Program Files\Microsoft HPC Pack 2008 SDK\Include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_Z3_BUILD_PARALLEL_SMT;_Z3_BUILD_PARALLEL_MPI;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;msmpi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + C:\Program Files\Microsoft HPC Pack 2008 SDK\Lib\i386;%(AdditionalLibraryDirectories) + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + ..\lib;C:\Program Files\Microsoft HPC Pack 2008 SDK\Include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;_WINDOWS;_AMD64_;_Z3_BUILD_PARALLEL_SMT;_Z3_BUILD_PARALLEL_MPI;%(PreprocessorDefinitions) + MultiThreadedDLL + + + psapi.lib;msmpi.lib;%(AdditionalDependencies) + $(OutDir)z3shell.lib + + + + + Disabled + ..\lib;C:\Program Files\Microsoft HPC Pack 2008 SDK\Include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;Z3DEBUG;_CONSOLE;_TRACE;_WINDOWS;_Z3_BUILD_PARALLEL_SMT;_Z3_BUILD_PARALLEL_MPI;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + psapi.lib;msmpi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + C:\Program Files\Microsoft HPC Pack 2008 SDK\Lib\i386;%(AdditionalLibraryDirectories) + %(DelayLoadDLLs) + true + Console + 8388608 + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;SMTCOMP;%(PreprocessorDefinitions) + MultiThreadedDLL + false + + + Level4 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;ASYNC_COMMANDS;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 33554432 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_EXTERNAL_RELEASE;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + true + Console + 8388608 + true + true + MachineX64 + $(OutDir)z3shell.lib + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_EXTERNAL_RELEASE;_Z3_BUILD_PARALLEL_SMT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + %(AdditionalLibraryDirectories) + true + Console + 8388608 + true + true + false + + + MachineX86 + $(OutDir)z3shell.lib + $(OutDir)z3shell.lib + + + + + X64 + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_Z3_BUILD_PARALLEL_SMT;_EXTERNAL_RELEASE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + $(OutDir)z3.exe + MachineX64 + $(OutDir)z3shell.lib + + + + + + + + + + + + + + + + + + + + + {4a7e5a93-19d8-4382-8950-fb2edec7a76e} + false + + + + + + \ No newline at end of file diff --git a/shell/shell.vcxproj.user b/shell/shell.vcxproj.user new file mode 100644 index 000000000..ace9a86ac --- /dev/null +++ b/shell/shell.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/shell/simple_sat.cpp b/shell/simple_sat.cpp new file mode 100644 index 000000000..d949198fe --- /dev/null +++ b/shell/simple_sat.cpp @@ -0,0 +1,118 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + simple_sat.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2006-10-10. + +Revision History: + +--*/ +#include +#include +#include"front_end_params.h" +#include"sat_def.h" +#include"dimacs_parser.h" +#include"timeit.h" +#include"mem_stat.h" + +class simple_sat_solver : public no_extension { + const front_end_params & m_params; + sat_solver * m_sat; + unsigned m_num_vars; + svector m_model; +public: + simple_sat_solver(const front_end_params & p): + m_params(p), + m_sat(new sat_solver(*this, p)), + m_num_vars(0) { + } + + ~simple_sat_solver() { + delete m_sat; + } + + static bool enable_ref_counters() { + return false; + } + + void mk_var() { + m_sat->mk_var(); + m_num_vars++; + } + + void mk_clause(const literal_vector & lits) { + m_sat->mk_main_clause(lits); + } + + unsigned get_num_vars() const { + return m_num_vars; + } + + lbool check() { + return m_sat->check(); + } + + void mk_model() { + if (m_params.m_build_model) { + m_sat->save_assignment(m_model); + } + } + + void display_model(std::ostream & out) const { + int sz = m_model.size(); + for (int i = 1; i < sz; i++) { + if (m_model[i] == l_true) { + out << i << " "; + } + else if (m_model[i] == l_false) { + out << -i << " "; + } + } + out << "\n"; + } + + void display_statistics(std::ostream & out) const { + m_sat->display_statistics(out); + } +}; + +extern bool g_display_statistics; +extern front_end_params g_front_end_params; + +void solve_cnf(const char * file) { + clock_t start_time = clock(); + simple_sat_solver solver(g_front_end_params); + std::ifstream in(file); + parse_dimacs(in, solver); + lbool r = solver.check(); + clock_t end_time = clock(); + switch(r) { + case l_false: + std::cout << "unsat\n"; + break; + case l_undef: + std::cout << "unknown\n"; + break; + case l_true: + std::cout << "sat\n"; + if (g_front_end_params.m_build_model) { + solver.display_model(std::cout); + } + break; + } + if (g_display_statistics) { + solver.display_statistics(std::cerr); + memory::display_max_usage(std::cerr); + std::cerr << "time: " << ((static_cast(end_time) - static_cast(start_time)) / CLOCKS_PER_SEC) << "\n"; + } +} + diff --git a/shell/simple_sat.h b/shell/simple_sat.h new file mode 100644 index 000000000..260e9d65e --- /dev/null +++ b/shell/simple_sat.h @@ -0,0 +1,26 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + simple_sat.h + +Abstract: + + Simple SAT solver using the Z3 SAT template. + +Author: + + Leonardo de Moura (leonardo) 2006-10-10. + +Revision History: + +--*/ + +#ifndef _SIMPLE_SAT_H_ +#define _SIMPLE_SAT_H_ + +void solve_cnf(const char * file); + +#endif /* _SIMPLE_SAT_H_ */ + diff --git a/shell/smtlib_frontend.cpp b/shell/smtlib_frontend.cpp new file mode 100644 index 000000000..1b1299971 --- /dev/null +++ b/shell/smtlib_frontend.cpp @@ -0,0 +1,138 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + smtlib_frontend.cpp + +Abstract: + + Frontend for reading Smtlib input files + +Author: + + Nikolaj Bjorner (nbjorner) 2006-11-3. + +Revision History: + + Leonardo de Moura: new SMT 2.0 front-end, removed support for .smtc files and smtcmd_solver object. + +--*/ +#include +#include +#include +#include"smtlib_solver.h" +#include"timeout.h" +#include"smt2parser.h" +#include"dl_cmds.h" +#include"dbg_cmds.h" +#include"polynomial_cmds.h" +#include"subpaving_cmds.h" +#include"smt_strategic_solver.h" + +#include"tactic2solver.h" +#include"qfnra_nlsat_tactic.h" + +extern bool g_display_statistics; +extern void display_config(); +static clock_t g_start_time; +static smtlib::solver* g_solver = 0; +static cmd_context * g_cmd_context = 0; + +static void display_statistics() { + display_config(); + clock_t end_time = clock(); + if ((g_solver || g_cmd_context) && g_display_statistics) { + std::cout.flush(); + std::cerr.flush(); + if (g_solver) { + g_solver->display_statistics(); + memory::display_max_usage(std::cout); + std::cout << "time: " << ((static_cast(end_time) - static_cast(g_start_time)) / CLOCKS_PER_SEC) << " secs\n"; + } + else if (g_cmd_context) { + g_cmd_context->set_regular_stream("stdout"); + g_cmd_context->display_statistics(true, ((static_cast(end_time) - static_cast(g_start_time)) / CLOCKS_PER_SEC)); + } + } +} + +static void on_timeout() { + display_statistics(); + exit(0); +} + +static void on_ctrl_c(int) { + signal (SIGINT, SIG_DFL); + display_statistics(); + raise(SIGINT); +} + +unsigned read_smtlib_file(char const * benchmark_file, front_end_params & front_end_params) { + g_start_time = clock(); + register_on_timeout_proc(on_timeout); + signal(SIGINT, on_ctrl_c); + smtlib::solver solver(front_end_params); + g_solver = &solver; + + bool ok = true; + + ok = solver.solve_smt(benchmark_file); + if (!ok) { + if (benchmark_file) { + std::cerr << "ERROR: solving '" << benchmark_file << "'.\n"; + } + else { + std::cerr << "ERROR: solving input stream.\n"; + } + } + + display_statistics(); + register_on_timeout_proc(0); + g_solver = 0; + return solver.get_error_code(); +} + +unsigned read_smtlib2_commands(char const* file_name, front_end_params& front_end_params) { + g_start_time = clock(); + register_on_timeout_proc(on_timeout); + signal(SIGINT, on_ctrl_c); + cmd_context ctx(front_end_params); + + // temporary hack until strategic_solver is ported to new tactic framework + if (front_end_params.m_nlsat) { + tactic2solver_cmd * s = alloc(tactic2solver_cmd); + s->set_tactic(alloc(qfnra_nlsat_fct)); + ctx.set_solver(s); + } + else { + solver * s = mk_smt_strategic_solver(ctx); + ctx.set_solver(s); + } + install_dl_cmds(ctx); + install_dbg_cmds(ctx); + install_polynomial_cmds(ctx); + install_subpaving_cmds(ctx); + + g_cmd_context = &ctx; + register_on_timeout_proc(on_timeout); + signal(SIGINT, on_ctrl_c); + + bool result = true; + if (file_name) { + std::ifstream in(file_name); + if (in.bad() || in.fail()) { + std::cerr << "(error \"failed to open file '" << file_name << "'\")" << std::endl; + exit(ERR_OPEN_FILE); + } + result = parse_smt2_commands(ctx, in); + } + else { + result = parse_smt2_commands(ctx, std::cin, true); + } + + display_statistics(); + g_cmd_context = 0; + return result ? 0 : 1; +} + diff --git a/shell/smtlib_frontend.h b/shell/smtlib_frontend.h new file mode 100644 index 000000000..0db1571e4 --- /dev/null +++ b/shell/smtlib_frontend.h @@ -0,0 +1,35 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + smtlib_frontend.h + +Abstract: + + Smtlib frontend. + +Author: + + Leonardo de Moura (leonardo) 2006-11-2. + +Revision History: + +--*/ +#ifndef _SMTLIB_FRONTEND_H_ +#define _SMTLIB_FRONTEND_H_ + +#include"front_end_params.h" + +unsigned read_smtlib_file(char const * benchmark_file, front_end_params & front_end_params); + +unsigned read_smtlib_commands(char const* command_file, front_end_params& front_end_params); +unsigned read_smtlib2_commands(char const* command_file, front_end_params& front_end_params); + +#ifdef _Z3_BUILD_PARALLEL_MPI +unsigned start_mpi_subordinate(front_end_params& front_end_params); +#endif + +#endif /* _SMTLIB_FRONTEND_H_ */ + + diff --git a/shell/z3_log_frontend.cpp b/shell/z3_log_frontend.cpp new file mode 100644 index 000000000..0b5686c66 --- /dev/null +++ b/shell/z3_log_frontend.cpp @@ -0,0 +1,56 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + z3_log_frontend.cpp + +Abstract: + + Z3 log frontend. + Replay a log generated by Z3 + +Author: + + Leonardo de Moura (leonardo) 2011-09-26. + +Revision History: + +--*/ +#include +#include +#include +#include"util.h" +#include"error_codes.h" +#include"z3_replayer.h" + +static void solve(char const * stream_name, std::istream & in) { + clock_t start_time = clock(); + z3_replayer r(in); + try { + r.parse(); + } + catch (z3_exception & ex) { + std::cerr << "Error at line " << r.get_line() << ": " << ex.msg() << std::endl; + } + clock_t end_time = clock(); + memory::display_max_usage(std::cout); + std::cout << "time: " << ((static_cast(end_time) - static_cast(start_time)) / CLOCKS_PER_SEC) << "\n"; +} + +void replay_z3_log(char const * file_name) { + if (!file_name) { + solve(file_name, std::cin); + } + else { + std::ifstream in(file_name); + if (in.bad() || in.fail()) { + std::cerr << "Error: failed to open file \"" << file_name << "\".\n"; + exit(ERR_OPEN_FILE); + } + solve(file_name, in); + } + exit(0); +} + + diff --git a/shell/z3_log_frontend.h b/shell/z3_log_frontend.h new file mode 100644 index 000000000..bd2c5258a --- /dev/null +++ b/shell/z3_log_frontend.h @@ -0,0 +1,27 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + z3_log_frontend.h + +Abstract: + + Z3 log frontend. + Replay a log generated by Z3 + +Author: + + Leonardo de Moura (leonardo) 2011-09-26. + +Revision History: + +--*/ +#ifndef _Z3_LOG_FRONTEND_H_ +#define _Z3_LOG_FRONTEND_H_ + +void replay_z3_log(char const * benchmark_file); + +#endif /* _Z3_FRONTEND_H_ */ + + diff --git a/test/ackermanize.cpp b/test/ackermanize.cpp new file mode 100644 index 000000000..b61f79440 --- /dev/null +++ b/test/ackermanize.cpp @@ -0,0 +1,42 @@ +#include "ackermanize.h" +#include "smtparser.h" +#include "ast_pp.h" + +void tst_ackermanize() +{ + ast_manager manager; + + smtlib::parser* parser = smtlib::parser::create(manager); + ackermanize ack(manager); + + ast_ref fD(manager); + ast_ref xD(manager); + ast_ref AD(manager); + ast_ref A(manager); + ast_ref<> a1(manager), a2(manager), a3(manager), a4(manager), + a5(manager), a6(manager), a7(manager); + ast_ref<> r(manager); + + AD = manager.mk_type_decl(symbol("A")); + A = manager.mk_type(AD.get()); + fD = manager.mk_const_decl(symbol("f"), A.get(), A.get(), A.get()); + a1 = manager.mk_const(manager.mk_const_decl(symbol("a1"), A.get())); + a2 = manager.mk_const(manager.mk_const_decl(symbol("a2"), A.get())); + a3 = manager.mk_const(manager.mk_const_decl(symbol("a3"), A.get())); + a4 = manager.mk_const(manager.mk_const_decl(symbol("a4"), A.get())); + a5 = manager.mk_const(manager.mk_const_decl(symbol("a5"), A.get())); + a6 = manager.mk_const(manager.mk_const_decl(symbol("a6"), A.get())); + a7 = manager.mk_const(manager.mk_const_decl(symbol("a7"), A.get())); + + r = manager.mk_const(manager.get_basic_family_id(), + OP_EQ, + manager.mk_const(fD.get(), a1.get(), a2.get()), + manager.mk_const(fD.get(), a2.get(), a3.get())); + + TRACE("ackermanize", tout << mk_pp(r.get()) << std::endl;); + + ack.reduce(r); + + TRACE("ackermanize", tout << mk_pp(r.get()) << std::endl;); + +} diff --git a/test/algebraic.cpp b/test/algebraic.cpp new file mode 100644 index 000000000..064803fe1 --- /dev/null +++ b/test/algebraic.cpp @@ -0,0 +1,569 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + algebraic.cpp + +Abstract: + + Test Algebraic Numbers + +Author: + + Leonardo (leonardo) 2011-11-22 + +Notes: + +--*/ +#include"algebraic_numbers.h" +#include"polynomial_var2value.h" +#include"mpbq.h" + +static void display_anums(std::ostream & out, scoped_anum_vector const & rs) { + out << "numbers in decimal:\n"; + algebraic_numbers::manager & m = rs.m(); + for (unsigned i = 0; i < rs.size(); i++) { + m.display_decimal(out, rs[i], 10); + out << "\n"; + } + out << "numbers as root objects\n"; + for (unsigned i = 0; i < rs.size(); i++) { + m.display_root(out, rs[i]); + out << "\n"; + } + out << "numbers as intervals\n"; + for (unsigned i = 0; i < rs.size(); i++) { + m.display_interval(out, rs[i]); + out << "\n"; + } +} + +static void tst1() { + unsynch_mpq_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + p = 3*x - 2; + + algebraic_numbers::manager am(nm); + scoped_anum_vector rs1(am); + std::cout << "p: " << p << "\n"; + am.isolate_roots(p, rs1); + display_anums(std::cout, rs1); + SASSERT(rs1.size() == 1); + std::cout.flush(); + + p = (x^2) - 2; + std::cout << "p: " << p << "\n"; + rs1.reset(); + am.isolate_roots(p, rs1); + display_anums(std::cout, rs1); + SASSERT(rs1.size() == 2); + + scoped_anum sqrt2(am); + am.set(sqrt2, rs1[1]); + + scoped_mpq q(nm); + nm.set(q, 1, 3); + scoped_anum aq(am); + am.set(aq, q); // create algebraic number representing 1/3 + + am.add(sqrt2, aq, aq); + std::cout << "sqrt(2) + 1/3: "; + am.display_decimal(std::cout, aq, 10); std::cout << " "; am.display_interval(std::cout, aq); + std::cout << " "; am.display_root(std::cout, aq); std::cout << "\n"; + + am.set(aq, q); + am.add(rs1[0], aq, aq); + std::cout << "-sqrt(2) + 1/3: "; + am.display_decimal(std::cout, aq, 10); std::cout << " "; am.display_interval(std::cout, aq); + std::cout << " "; am.display_root(std::cout, aq); std::cout << "\n"; + + p = ((x^5) - x - 1)*(x-1)*(x-2); + std::cout << "p: " << p << "\n"; + rs1.reset(); + am.isolate_roots(p, rs1); + display_anums(std::cout, rs1); + SASSERT(rs1.size() == 3); + + scoped_anum gauss(am); + am.set(gauss, rs1[1]); + + std::cout << "compare(" << sqrt2 << ", " << gauss << "): " << am.compare(sqrt2, gauss) << "\n"; + + statistics st; + am.collect_statistics(st); + st.display_smt2(std::cout); + + p = ((x^2) - 2)*((x^2) - 3); + std::cout << "p: " << p << "\n"; + rs1.reset(); + am.isolate_roots(p, rs1); + display_anums(std::cout, rs1); + SASSERT(rs1.size() == 4); + + scoped_anum hidden_sqrt2(am); + am.set(hidden_sqrt2, rs1[2]); + + std::cout << "compare(" << sqrt2 << ", " << hidden_sqrt2 << "): " << am.compare(sqrt2, hidden_sqrt2) << "\n"; + st.reset(); + am.collect_statistics(st); + st.display_smt2(std::cout); + + std::cout << "sqrt(2)^4: " << (sqrt2^4) << "\n"; + + SASSERT(is_int(power(sqrt2, 4))); + SASSERT(power(sqrt2, 4) == 4); + + scoped_anum sqrt2_gauss(am); + am.add(sqrt2, gauss, sqrt2_gauss); + std::cout << "sqrt2 + gauss: " << sqrt2_gauss << " "; am.display_root(std::cout, sqrt2_gauss); std::cout << "\n"; + + std::cout << "sqrt2*sqrt2: " << sqrt2*sqrt2 << "\n"; + std::cout << "sqrt2*sqrt2 == 2: " << (sqrt2*sqrt2 == 2) << std::endl; + + scoped_anum three(am); + am.set(three, -3); + + std::cout << "(-3)^(1/5): " << root(three, 5) << "\n"; + std::cout << "sqrt(2)^(1/3): " << root(sqrt2, 3) << "\n"; + std::cout << "as-root-object(sqrt(2)^(1/3)): " << root_obj_pp(root(sqrt2, 3)) << "\n"; + std::cout << "(sqrt(2) + 1)^(1/3): " << root(sqrt2 + 1, 3) << "\n"; + std::cout << "as-root-object((sqrt(2) + 1)^(1/3)): " << root_obj_pp(root(sqrt2 + 1, 3)) << "\n"; + std::cout << "(sqrt(2) + gauss)^(1/5): " << root(sqrt2 + gauss, 5) << "\n"; + std::cout << "as-root-object(sqrt(2) + gauss)^(1/5): " << root_obj_pp(root(sqrt2 + gauss, 5)) << "\n"; + std::cout << "(sqrt(2) / sqrt(2)): " << sqrt2 / hidden_sqrt2 << "\n"; + std::cout << "(sqrt(2) / gauss): " << sqrt2 / gauss << "\n"; + std::cout << "(sqrt(2) / gauss) 30 digits: " << decimal_pp(sqrt2 / gauss, 30) << "\n"; + std::cout << "as-root-object(sqrt(2) / gauss): " << root_obj_pp(sqrt2 / gauss) << "\n"; + std::cout << "is_int(sqrt(2)^(1/3)): " << am.is_int(root(sqrt2, 3)) << "\n"; + + scoped_anum tmp(am); + scoped_anum four(am); + am.set(four, 4); + am.set(tmp, sqrt2); + am.inv(tmp); + std::cout << "1/sqrt(2): " << tmp << "\n"; + am.mul(tmp, four, tmp); + std::cout << "4*1/sqrt(2): " << tmp << " " << root_obj_pp(tmp) << "\n"; + am.mul(tmp, sqrt2, tmp); + std::cout << "sqrt(2)*4*(1/sqrt2): " << tmp << " " << root_obj_pp(tmp) << "\n"; + std::cout << "is_int(sqrt(2)*4*(1/sqrt2)): " << am.is_int(tmp) << ", after is-int: " << tmp << "\n"; + + p = (998*x - 1414)*((x^2) - 15); + std::cout << "p: " << p << "\n"; + rs1.reset(); + am.isolate_roots(p, rs1); + + std::cout << "is-rational(sqrt2): " << am.is_rational(sqrt2) << "\n"; + + scoped_anum qr(am); + am.set(qr, rs1[1]); + + std::cout << "qr: " << root_obj_pp(qr); + std::cout << ", is-rational: " << am.is_rational(qr) << ", val: " << root_obj_pp(qr) << "\n"; + + return; + + std::cout << "compare(" << sqrt2 << ", " << gauss << "): " << am.compare(sqrt2, gauss) << "\n"; + + p = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225; + std::cout << "p: " << p << "\n"; + rs1.reset(); + am.isolate_roots(p, rs1); + display_anums(std::cout, rs1); +} + +void tst_refine_mpbq() { + unsynch_mpq_manager qm; + mpbq_manager bqm(qm); + scoped_mpq q1(qm); + qm.set(q1, 5, 7); + scoped_mpbq l(bqm); + scoped_mpbq u(bqm); + std::cout << "using refine upper...\n"; + bqm.to_mpbq(q1, l); + bqm.set(u, l); + bqm.mul2(u); + for (unsigned i = 0; i < 20; i++) { + std::cout << l << " < " << q1 << " < " << u << "\n"; + bqm.display_decimal(std::cout, l, 20); std::cout << " < "; + qm.display_decimal(std::cout, q1, 20); std::cout << " < "; + bqm.display_decimal(std::cout, u, 20); std::cout << std::endl; + bqm.refine_upper(q1, l, u); + } + std::cout << "using refine lower...\n"; + bqm.to_mpbq(q1, l); + bqm.set(u, l); + bqm.mul2(u); + for (unsigned i = 0; i < 20; i++) { + std::cout << l << " < " << q1 << " < " << u << "\n"; + bqm.display_decimal(std::cout, l, 20); std::cout << " < "; + qm.display_decimal(std::cout, q1, 20); std::cout << " < "; + bqm.display_decimal(std::cout, u, 20); std::cout << std::endl; + bqm.refine_lower(q1, l, u); + } +} + +void tst_mpbq_root() { + unsynch_mpq_manager qm; + mpbq_manager bqm(qm); + // scoped_mpbq q(bqm); + // q.set(q1, 1.4142135 , 7); + +} + +static void tst_wilkinson() { + // Test Wilkinson Polynomial + unsynch_mpq_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + for (int i = 1; i <= 20; i++) { + if (i > 1) + p = p*(x - i); + else + p = (x - i); + } + std::cout << "Wilkinson's polynomial: " << p << "\n"; + + algebraic_numbers::manager am(nm); + scoped_anum_vector rs1(am); + std::cout << "p: " << p << "\n"; + am.isolate_roots(p, rs1); + display_anums(std::cout, rs1); + SASSERT(rs1.size() == 20); + for (unsigned i = 0; i < rs1.size(); i++) { + SASSERT(am.is_int(rs1[i])); + } +} + +static void tst_dejan() { + unsynch_mpq_manager qm; + algebraic_numbers::manager am(qm); + + scoped_anum two101(am); + am.set(two101, 2); + am.root(two101, 11, two101); + + scoped_anum two103(am); + am.set(two103, 2); + am.root(two103, 7, two103); + + std::cout << "two101: " << two101 << " " << root_obj_pp(two101) << std::endl; + std::cout << "two103: " << two103 << " " << root_obj_pp(two103) << std::endl; + + scoped_anum sum1(am); + am.add(two103, two101, sum1); + std::cout << "sum1: " << sum1 << " " << root_obj_pp(sum1) << "\n"; +} + +static void tst_select_small(mpbq_manager & m, scoped_mpbq const & l, scoped_mpbq const & u, bool expected) { + scoped_mpbq r(m); + std::cout << "----------\n"; + std::cout << "lower: " << l << " as decimal: "; m.display_decimal(std::cout, l); std::cout << std::endl; + std::cout << "upper: " << u << " as decimal: "; m.display_decimal(std::cout, u); std::cout << std::endl; + VERIFY(m.select_small(l, u, r) == expected); + std::cout << "choice: " << r << " as decimal: "; m.display_decimal(std::cout, r); std::cout << std::endl; +} + +static void tst_select_small(mpbq_manager & m, int64 n1, unsigned k1, int64 n2, unsigned k2, bool expected) { + scoped_mpbq l(m); + scoped_mpbq u(m); + m.set(l, n1, k1); + m.set(u, n2, k2); + tst_select_small(m, l, u, expected); +} + +static void tst_select_small() { + unsynch_mpz_manager m; + mpbq_manager bqm(m); + tst_select_small(bqm, 1, 3, 3, 2, true); + tst_select_small(bqm, 10000000000000ll, 40, 11000, 10, true); + tst_select_small(bqm, 10000000000000ll, 40, 10001, 10, true); + tst_select_small(bqm, 1, 0, 1, 0, true); + tst_select_small(bqm, 1, 0, 2, 0, true); + tst_select_small(bqm, -1, 0, -1, 0, true); + tst_select_small(bqm, -2, 0, -1, 0, true); + tst_select_small(bqm, 0, 0, 1100, 10, true); + tst_select_small(bqm, 7, 3, 1001, 10, true); + tst_select_small(bqm, 1000, 10, 1001, 10, true); + scoped_mpbq l1(bqm); + l1 = 11; + bqm.power(l1, 64, l1); + scoped_mpbq l2(bqm); + l2 = l1 + 1; + bqm.div2k(l1, 64*3); + bqm.div2k(l2, 64*3); + tst_select_small(bqm, l1, l2, true); + l1 = 11; + bqm.power(l1, 64, l1); + l2 = l1 + 256; + bqm.div2k(l1, 64*3); + bqm.div2k(l2, 64*3); + tst_select_small(bqm, l1, l2, true); +} + +static void tst_eval_sign(polynomial_ref const & p, anum_manager & am, + polynomial::var x0, anum const & v0, polynomial::var x1, anum const & v1, polynomial::var x2, anum const & v2, + int expected) { + polynomial::simple_var2value x2v(am); + x2v.push_back(x0, v0); + x2v.push_back(x1, v1); + x2v.push_back(x2, v2); + std::cout << "--------------\n"; + std::cout << "p: " << p << "\n"; + std::cout << "x0 -> "; am.display_root(std::cout, v0); std::cout << "\n"; + std::cout << "x1 -> "; am.display_root(std::cout, v1); std::cout << "\n"; + std::cout << "x2 -> "; am.display_root(std::cout, v2); std::cout << "\n"; + int s = am.eval_sign_at(p, x2v); + SASSERT((s == 0) == (expected == 0)); + SASSERT((s < 0) == (expected < 0)); + SASSERT((s > 0) == (expected > 0)); + std::cout << "sign: " << s << "\n"; +} + +static void tst_eval_sign() { + enable_trace("anum_eval_sign"); + unsynch_mpq_manager qm; + polynomial::manager pm(qm); + algebraic_numbers::manager am(qm); + polynomial_ref x0(pm); + polynomial_ref x1(pm); + polynomial_ref x2(pm); + x0 = pm.mk_polynomial(pm.mk_var()); + x1 = pm.mk_polynomial(pm.mk_var()); + x2 = pm.mk_polynomial(pm.mk_var()); + + polynomial_ref p(pm); + p = x0*x1 + (x1^2) + x2 + 2; + scoped_anum v0(am), v1(am), v2(am); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1); + am.set(v2, -2); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 0); + am.set(v1, 1); + am.set(v0, -3); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, -1); + + am.set(v0, 2); + am.root(v0, 2, v0); + am.set(v1, 0); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 0); + am.set(v2, 1); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1); + am.set(v2, -3); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, -1); + + am.set(v1, 1); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1); + am.set(v2, -4); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1); + am.set(v2, -5); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, -1); + + am.set(v2, -2); + am.set(v1, v0); + am.neg(v1); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 0); + + am.set(v2, -3); + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, -1); + p = x0*x1 + (x1^2) - x2 + 2; + tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1); + +} + +static void tst_isolate_roots(polynomial_ref const & p, anum_manager & am, + polynomial::var x0, anum const & v0, polynomial::var x1, anum const & v1, polynomial::var x2, anum const & v2) { + polynomial::simple_var2value x2v(am); + x2v.push_back(x0, v0); + x2v.push_back(x1, v1); + x2v.push_back(x2, v2); + std::cout << "--------------\n"; + std::cout << "p: " << p << "\n"; + std::cout << "x0 -> "; am.display_root(std::cout, v0); std::cout << "\n"; + std::cout << "x1 -> "; am.display_root(std::cout, v1); std::cout << "\n"; + std::cout << "x2 -> "; am.display_root(std::cout, v2); std::cout << "\n"; + scoped_anum_vector roots(am); + svector signs; + am.isolate_roots(p, x2v, roots, signs); + SASSERT(roots.size() + 1 == signs.size()); + std::cout << "roots:\n"; + for (unsigned i = 0; i < roots.size(); i++) { + am.display_root(std::cout, roots[i]); std::cout << " "; am.display_decimal(std::cout, roots[i]); std::cout << "\n"; + } + std::cout << "signs:\n"; + for (unsigned i = 0; i < signs.size(); i++) { + if (i > 0) + std::cout << " 0 "; + if (signs[i] < 0) std::cout << "-"; + else if (signs[i] == 0) std::cout << "0"; + else std::cout << "+"; + } + std::cout << "\n"; +} + +static void tst_isolate_roots() { + enable_trace("isolate_roots"); + unsynch_mpq_manager qm; + polynomial::manager pm(qm); + algebraic_numbers::manager am(qm); + polynomial_ref x0(pm); + polynomial_ref x1(pm); + polynomial_ref x2(pm); + polynomial_ref x3(pm); + x0 = pm.mk_polynomial(pm.mk_var()); + x1 = pm.mk_polynomial(pm.mk_var()); + x2 = pm.mk_polynomial(pm.mk_var()); + x3 = pm.mk_polynomial(pm.mk_var()); + + polynomial_ref p(pm); + p = x3*x1 + 1; + + scoped_anum v0(am), v1(am), v2(am); + + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + am.set(v1, 1); + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + am.set(v1, 2); + am.root(v1, 2, v1); + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x1 + x2)*x3 + 1; + am.set(v2, v1); + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x1 + x2)*x3 + x1*x2 + 2; + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x1 + x2)*(x3^3) + x1*x2 + 2; + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x1 + x2)*(x3^2) - x1*x2 - 2; + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = x0*(x1 + x2)*(x3^2) - x0*x1*x2 - 2; + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x1 - x2)*x3 + x1*x2 - 2; + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x1 - x2)*(x3^3) + x1*x2 - 2; + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x3 - x0)*(x3 - x0 - x1); + am.set(v0, 2); + am.root(v0, 2, v0); // x2 -> sqrt(2) + am.set(v1, 3); + am.root(v1, 2, v1); // x1 -> sqrt(3) + am.reset(v2); + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x3 - x0)*((x3 - x0 - x1)^2); + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); + + p = (x3 - x0)*(x3 - 2)*((x3 - 1)^2)*(x3 - x1); + tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2); +} + +static void pp(polynomial_ref const & p, polynomial::var x) { + unsigned d = degree(p, x); + for (unsigned i = 0; i <= d; i++) { + std::cout << "(" << coeff(p, x, i) << ") "; + } + std::cout << "\n"; +} + +static void ex1() { + unsynch_mpq_manager qm; + polynomial::manager pm(qm); + polynomial_ref x(pm); + polynomial_ref a(pm); + polynomial_ref b(pm); + polynomial_ref c(pm); + x = pm.mk_polynomial(pm.mk_var()); + a = pm.mk_polynomial(pm.mk_var()); + b = pm.mk_polynomial(pm.mk_var()); + c = pm.mk_polynomial(pm.mk_var()); + polynomial_ref p(pm); + p = (a + 2*b)*(x^3) + x*a + (b^2); + polynomial_ref p1(pm); + p1 = derivative(p, 0); + polynomial_ref h2(pm); + unsigned d; + h2 = pseudo_remainder(p, p1, 0, d); + std::cout << "d: " << d << "\n"; + std::cout << "p: "; pp(p, 0); std::cout << "\np': "; pp(p1, 0); std::cout << "\nh2: "; pp(h2, 0); std::cout << "\n"; + polynomial_ref h3(pm); + h3 = pseudo_remainder(p1, h2, 0, d); + std::cout << "d: " << d << "\n"; + std::cout << "h3: "; pp(h3, 0); std::cout << "\n"; + + algebraic_numbers::manager am(qm); + scoped_anum v1(am), v2(am); + am.set(v1, 2); + am.root(v1, 3, v1); + am.set(v2, 3); + am.root(v2, 3, v2); + + polynomial::simple_var2value x2v(am); + x2v.push_back(1, v1); + x2v.push_back(2, v2); + std::cout << "sign(h3(v1,v2)): " << am.eval_sign_at(h3, x2v) << "\n"; + scoped_anum v0(am); + am.set(v0, -1); + x2v.push_back(0, v0); + std::cout << "sign(h2(v1,v2)): " << am.eval_sign_at(h2, x2v) << "\n"; + std::cout << "sign(p'(v1,v2)): " << am.eval_sign_at(p1, x2v) << "\n"; + std::cout << "sign(p(v1,v2)): " << am.eval_sign_at(p, x2v) << "\n"; + + polynomial::simple_var2value x2v2(am); + x2v2.push_back(1, v1); + x2v2.push_back(2, v2); + scoped_mpq tmp(qm); + qm.set(tmp, -1); + qm.div(tmp, mpz(2), tmp); + std::cout << "tmp: "; qm.display(std::cout, tmp); std::cout << " "; qm.display_decimal(std::cout, tmp, 10); std::cout << "\n"; + am.set(v0, tmp); + x2v2.push_back(0, v0); + std::cout << "v0: " << v0 << "\n"; + std::cout << "sign(h2(v1,v2)): " << am.eval_sign_at(h2, x2v2) << "\n"; + std::cout << "sign(p'(v1,v2)): " << am.eval_sign_at(p1, x2v2) << "\n"; + std::cout << "sign(p(v1,v2)): " << am.eval_sign_at(p, x2v2) << "\n"; +} + +static void tst_root() { + unsynch_mpq_manager qm; + algebraic_numbers::manager am(qm); + scoped_anum v1(am), v2(am); + am.set(v1, 4); + am.root(v1, 2, v2); + std::cout << "root: " << v2 << "\n"; + am.set(v1, 4); + am.root(v1, 4, v2); + std::cout << "root: " << root_obj_pp(v2) << "\n"; + +} + +void tst_algebraic() { + // enable_trace("resultant_bug"); + // enable_trace("poly_sign"); + disable_trace("algebraic"); + // enable_trace("mpbq_bug"); + // enable_trace("mpz_mul2k"); + // enable_trace("mpz_gcd"); + tst_root(); + tst_isolate_roots(); + ex1(); + tst_eval_sign(); + tst_select_small(); + tst_dejan(); + tst_wilkinson(); + tst1(); + tst_refine_mpbq(); +} diff --git a/test/api.cpp b/test/api.cpp new file mode 100644 index 000000000..b5aff7935 --- /dev/null +++ b/test/api.cpp @@ -0,0 +1,458 @@ +#ifdef _WINDOWS +#include "z3.h" +#include "z3_private.h" +#include +#include "util.h" +#include "trace.h" +#include +#include "trace.h" + +void bv_invariant() { + +#define SET(_i, _v) m[_i] = _v +#define GET(_ty,_i) reinterpret_cast<_ty>(m[_i]) + + std::map m; + Z3_config cfg = Z3_mk_config(); + Z3_set_param_value(cfg,"MODEL","true"); + Z3_context ctx = Z3_mk_context(cfg); + Z3_model _m = 0; + enable_trace("after_internalization"); + enable_trace("final_check"); + enable_trace("bv"); + enable_trace("propagate_atoms"); + enable_trace("assign_core"); + enable_trace("bv_bug"); + enable_trace("bv_bit_prop"); + enable_trace("mark_as_relevant_core"); +{SET(0x03BC7FD8, Z3_mk_bv_sort(ctx,32));} +{SET(0x03BCCD88, Z3_mk_int(ctx,0,GET(Z3_sort,0x03BC7FD8)));} +{SET(0x03BCCE08, Z3_mk_int(ctx,1,GET(Z3_sort,0x03BC7FD8)));} +{SET(0x03BC9428, Z3_mk_eq(ctx,GET(Z3_ast,0x03BCCD88),GET(Z3_ast,0x03BCCD88)));} +{SET(0x03CEC820, Z3_get_app_decl(ctx,GET(Z3_app,0x03BC9428)));} +{Z3_mk_string_symbol(ctx,"null");} +{Z3_mk_string_symbol(ctx,"isnull");} +{SET(0x03CEC870, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"null"),Z3_mk_string_symbol(ctx,"isnull"),0,0,0,0));} +{Z3_mk_string_symbol(ctx,"ArgumentException");} +{Z3_mk_string_symbol(ctx,"isArgumentException");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CEC8C0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"ArgumentException"),Z3_mk_string_symbol(ctx,"isArgumentException"),1,args03CEE130,args03CEE160,args03CEE190));} +{Z3_mk_string_symbol(ctx,"String");} +{Z3_mk_string_symbol(ctx,"isString");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CEC910, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"String"),Z3_mk_string_symbol(ctx,"isString"),1,args03CEE130,args03CEE160,args03CEE190));} +{Z3_mk_string_symbol(ctx,"MethodBase");} +{Z3_mk_string_symbol(ctx,"isMethodBase");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CEC960, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"MethodBase"),Z3_mk_string_symbol(ctx,"isMethodBase"),1,args03CEE130,args03CEE160,args03CEE190));} +{Z3_mk_string_symbol(ctx,"Exception");} +{Z3_mk_string_symbol(ctx,"isException");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CEC9B0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Exception"),Z3_mk_string_symbol(ctx,"isException"),1,args03CEE130,args03CEE160,args03CEE190));} +{Z3_mk_string_symbol(ctx,"Object");} +{Z3_mk_string_symbol(ctx,"isObject");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CECA00, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Object"),Z3_mk_string_symbol(ctx,"isObject"),1,args03CEE130,args03CEE160,args03CEE190));} +{Z3_mk_string_symbol(ctx,"Box");} +{Z3_mk_string_symbol(ctx,"isBox");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03CECA50, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Term");} +{Z3_mk_string_symbol(ctx,"isTerm");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9430, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Term"),Z3_mk_string_symbol(ctx,"isTerm"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Box");} +{Z3_mk_string_symbol(ctx,"isBox");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9480, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"SystemException");} +{Z3_mk_string_symbol(ctx,"isSystemException");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9520, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"SystemException"),Z3_mk_string_symbol(ctx,"isSystemException"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"RuntimeFieldHandle");} +{Z3_mk_string_symbol(ctx,"isRuntimeFieldHandle");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE94D0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"RuntimeFieldHandle"),Z3_mk_string_symbol(ctx,"isRuntimeFieldHandle"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Box");} +{Z3_mk_string_symbol(ctx,"isBox");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9570, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"RuntimeTypeHandle");} +{Z3_mk_string_symbol(ctx,"isRuntimeTypeHandle");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE95C0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"RuntimeTypeHandle"),Z3_mk_string_symbol(ctx,"isRuntimeTypeHandle"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Box");} +{Z3_mk_string_symbol(ctx,"isBox");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9610, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"NullReferenceException");} +{Z3_mk_string_symbol(ctx,"isNullReferenceException");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9660, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"NullReferenceException"),Z3_mk_string_symbol(ctx,"isNullReferenceException"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"InvalidCastException");} +{Z3_mk_string_symbol(ctx,"isInvalidCastException");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE96B0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"InvalidCastException"),Z3_mk_string_symbol(ctx,"isInvalidCastException"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"IndexOutOfRangeException");} +{Z3_mk_string_symbol(ctx,"isIndexOutOfRangeException");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9700, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"IndexOutOfRangeException"),Z3_mk_string_symbol(ctx,"isIndexOutOfRangeException"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"StackOverflowException");} +{Z3_mk_string_symbol(ctx,"isStackOverflowException");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9750, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"StackOverflowException"),Z3_mk_string_symbol(ctx,"isStackOverflowException"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"ExecutionEngineException");} +{Z3_mk_string_symbol(ctx,"isExecutionEngineException");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE97A0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"ExecutionEngineException"),Z3_mk_string_symbol(ctx,"isExecutionEngineException"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Box");} +{Z3_mk_string_symbol(ctx,"isBox");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE97F0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Value");} +{Z3_mk_string_symbol(ctx,"isValue");} +{Z3_mk_string_symbol(ctx,"value");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"value"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9840, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Value"),Z3_mk_string_symbol(ctx,"isValue"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Value");} +{Z3_mk_string_symbol(ctx,"isValue");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9890, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Value"),Z3_mk_string_symbol(ctx,"isValue"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Int32[]");} +{Z3_mk_string_symbol(ctx,"isInt32[]");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE98E0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Int32[]"),Z3_mk_string_symbol(ctx,"isInt32[]"),1,args03CEE160,args03CEE190,args03CEE1C0));} +{Z3_mk_string_symbol(ctx,"Add");} +{Z3_mk_string_symbol(ctx,"isAdd");} +{Z3_mk_string_symbol(ctx,"left");} +{Z3_mk_string_symbol(ctx,"right");} +{Z3_symbol args03BEA4A0[2] = {Z3_mk_string_symbol(ctx,"left"), Z3_mk_string_symbol(ctx,"right"), }; Z3_sort args03BEA548[2] = {GET(Z3_sort,0x00000000), GET(Z3_sort,0x00000000), }; unsigned args03BEA580[2] = {0, 0, }; SET(0x03BE9930, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Add"),Z3_mk_string_symbol(ctx,"isAdd"),2,args03BEA4A0,args03BEA548,args03BEA580));} +{Z3_mk_string_symbol(ctx,"Add");} +{Z3_mk_string_symbol(ctx,"isAdd");} +{Z3_mk_string_symbol(ctx,"refId");} +{Z3_symbol args03CEE190[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE1C0[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1F0[1] = {0, }; SET(0x03BE9980, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Add"),Z3_mk_string_symbol(ctx,"isAdd"),1,args03CEE190,args03CEE1C0,args03CEE1F0));} +{Z3_mk_string_symbol(ctx,"address");} +{Z3_mk_string_symbol(ctx,"isaddress");} +{Z3_mk_string_symbol(ctx,"enc");} +{Z3_mk_string_symbol(ctx,"value1");} +{Z3_mk_string_symbol(ctx,"value2");} +{Z3_symbol args03BEA580[3] = {Z3_mk_string_symbol(ctx,"enc"), Z3_mk_string_symbol(ctx,"value1"), Z3_mk_string_symbol(ctx,"value2"), }; Z3_sort args03BEA628[3] = {GET(Z3_sort,0x03BC7FD8), GET(Z3_sort,0x00000000), GET(Z3_sort,0x00000000), }; unsigned args03BEA660[3] = {0, 0, 0, }; SET(0x03BE99D0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"address"),Z3_mk_string_symbol(ctx,"isaddress"),3,args03BEA580,args03BEA628,args03BEA660));} +{Z3_mk_string_symbol(ctx,"object");} +{Z3_constructor args03BEAC18[25] = {GET(Z3_constructor,0x03CEC870), GET(Z3_constructor,0x03CEC8C0), GET(Z3_constructor,0x03CEC910), GET(Z3_constructor,0x03CEC960), GET(Z3_constructor,0x03CEC9B0), GET(Z3_constructor,0x03CECA00), GET(Z3_constructor,0x03CECA50), GET(Z3_constructor,0x03BE9430), GET(Z3_constructor,0x03BE9480), GET(Z3_constructor,0x03BE9520), GET(Z3_constructor,0x03BE94D0), GET(Z3_constructor,0x03BE9570), GET(Z3_constructor,0x03BE95C0), GET(Z3_constructor,0x03BE9610), GET(Z3_constructor,0x03BE9660), GET(Z3_constructor,0x03BE96B0), GET(Z3_constructor,0x03BE9700), GET(Z3_constructor,0x03BE9750), GET(Z3_constructor,0x03BE97A0), GET(Z3_constructor,0x03BE97F0), GET(Z3_constructor,0x03BE9840), GET(Z3_constructor,0x03BE9890), GET(Z3_constructor,0x03BE98E0), GET(Z3_constructor,0x03BE9930), GET(Z3_constructor,0x03BE9980), }; SET(0x03CEE1C0, Z3_mk_constructor_list(ctx,25,args03BEAC18));} +{Z3_mk_string_symbol(ctx,"address");} +{Z3_constructor args03CEE1F0[1] = {GET(Z3_constructor,0x03BE99D0), }; SET(0x03CEE220, Z3_mk_constructor_list(ctx,1,args03CEE1F0));} +{Z3_symbol args03BEA580[2] = {Z3_mk_string_symbol(ctx,"object"), Z3_mk_string_symbol(ctx,"address"), }; Z3_sort args03BEA660[2] = {GET(Z3_sort,0x03BCD088), GET(Z3_sort,0x03BCD0C8), }; Z3_constructor_list args03BEA628[2] = {GET(Z3_constructor_list,0x03CEE1C0), GET(Z3_constructor_list,0x03CEE220), }; Z3_mk_datatypes(ctx,2, args03BEA580, args03BEA660, args03BEA628);SET(0x03BCD088, args03BEA660[0]);SET(0x03BCD0C8, args03BEA660[1]);} +{Z3_del_constructor_list(ctx,GET(Z3_constructor_list,0x03CEE1C0));} +{Z3_del_constructor_list(ctx,GET(Z3_constructor_list,0x03CEE220));} +{Z3_func_decl out002DE0DC; Z3_func_decl out002DE0E0; Z3_query_constructor(ctx,GET(Z3_constructor,0x03CEC870), 0, &out002DE0DC, &out002DE0E0, 0);SET(0x03BEAC30, out002DE0DC);SET(0x03BEB2F0, out002DE0E0);} +{Z3_func_decl out002DE0E0; Z3_func_decl out002DE0E4; Z3_func_decl args03CEE220[1] = {GET(Z3_func_decl,0x03BEB380), }; Z3_query_constructor(ctx,GET(Z3_constructor,0x03BE9840), 1, &out002DE0E0, &out002DE0E4, args03CEE220);SET(0x03BEB1D0, out002DE0E0);SET(0x03BEB338, out002DE0E4);SET(0x03BEB380, args03CEE220[0]);} +{Z3_func_decl out002DE0E0; Z3_func_decl out002DE0E4; Z3_func_decl args03BEA580[2] = {0, GET(Z3_func_decl,0x03BEC478), }; Z3_query_constructor(ctx,GET(Z3_constructor,0x03BE9930), 2, &out002DE0E0, &out002DE0E4, args03BEA580);SET(0x03BE9A20, out002DE0E0);SET(0x03BEB3C8, out002DE0E4);SET(0x03BEC430, args03BEA580[0]);SET(0x03BEC478, args03BEA580[1]); } +{Z3_func_decl out002DE0DC; Z3_func_decl out002DE0E0; Z3_func_decl args03BEA580[3] = {GET(Z3_func_decl,0x03BEC508), GET(Z3_func_decl,0x03BEC550), GET(Z3_func_decl,0x03BEC598), }; Z3_query_constructor(ctx,GET(Z3_constructor,0x03BE99D0), 3, &out002DE0DC, &out002DE0E0, args03BEA580);SET(0x03BE9A70, out002DE0DC);SET(0x03BEC4C0, out002DE0E0);SET(0x03BEC508, args03BEA580[0]);SET(0x03BEC550, args03BEA580[1]);SET(0x03BEC598, args03BEA580[2]);} +{SET(0x03BEB7F0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEAC30),0,0));} +{SET(0x03BCD088, Z3_get_domain(ctx,GET(Z3_func_decl,0x03BEC430),0));} +{SET(0x03BEB4F0, Z3_mk_bound(ctx,0,GET(Z3_sort,0x03BCD088)));} +{Z3_ast args03CEE220[1] = {GET(Z3_ast,0x03BEB4F0), }; SET(0x03BEC5E0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEC430),1,args03CEE220));} +{SET(0x03BEB4F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC5E0),0));} +{SET(0x03BEC628, Z3_mk_eq(ctx,GET(Z3_ast,0x03BEC5E0),GET(Z3_ast,0x03BEB7F0)));} +{SET(0x03BE9AC0, Z3_get_app_decl(ctx,GET(Z3_app,0x03BEC628)));} +{Z3_ast args03CEE220[1] = {GET(Z3_ast,0x03BEC5E0), }; SET(0x03BEC670, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03CEE220));} +{Z3_ast args03CEE220[1] = {GET(Z3_ast,0x03BEC5E0), }; SET(0x03BEC6B8, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB3C8),1,args03CEE220));} +{Z3_ast args03BEA580[2] = {GET(Z3_ast,0x03BEC670), GET(Z3_ast,0x03BEC6B8), }; SET(0x03BEC700, Z3_mk_or(ctx,2,args03BEA580));} +{SET(0x03BEC670, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC700),0));} +{SET(0x03BEC6B8, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC700),1));} +{Z3_ast args03BEA580[3] = {GET(Z3_ast,0x03BEC670), GET(Z3_ast,0x03BEC6B8), GET(Z3_ast,0x03BEC628), }; SET(0x03BE9B10, Z3_mk_or(ctx,3,args03BEA580));} +{Z3_mk_string_symbol(ctx,"x0");} +{Z3_sort args03CEE250[1] = {GET(Z3_sort,0x03BCD088), }; Z3_symbol args03CEE1F0[1] = {Z3_mk_string_symbol(ctx,"x0"), }; SET(0x03BED418, Z3_mk_quantifier(ctx,1,0,0,0,1,args03CEE250,args03CEE1F0,GET(Z3_ast,0x03BE9B10)));} +{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03BED418));} +{SET(0x03BCD088, Z3_get_domain(ctx,GET(Z3_func_decl,0x03BEC478),0));} +{Z3_ast args03CEE1F0[1] = {GET(Z3_ast,0x03BEB4F0), }; SET(0x03BEC790, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEC478),1,args03CEE1F0));} +{Z3_ast args03BEAB30[2] = {GET(Z3_ast,0x03BEC790), GET(Z3_ast,0x03BEB7F0), }; SET(0x03BEC820, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03BEAB30));} +{Z3_ast args03CEE1F0[1] = {GET(Z3_ast,0x03BEC790), }; SET(0x03BEC868, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03CEE1F0));} +{Z3_ast args03CEE1F0[1] = {GET(Z3_ast,0x03BEC790), }; SET(0x03BEC8B0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB3C8),1,args03CEE1F0));} +{Z3_ast args03BEAB30[2] = {GET(Z3_ast,0x03BEC868), GET(Z3_ast,0x03BEC8B0), }; SET(0x03BEC8F8, Z3_mk_or(ctx,2,args03BEAB30));} +{SET(0x03BEC868, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC8F8),0));} +{SET(0x03BEC8B0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC8F8),1));} +{Z3_ast args03BEAB30[3] = {GET(Z3_ast,0x03BEC868), GET(Z3_ast,0x03BEC8B0), GET(Z3_ast,0x03BEC820), }; SET(0x03BE9BB0, Z3_mk_or(ctx,3,args03BEAB30));} +{Z3_mk_string_symbol(ctx,"x0");} +{Z3_sort args03CEE280[1] = {GET(Z3_sort,0x03BCD088), }; Z3_symbol args03CEE2B0[1] = {Z3_mk_string_symbol(ctx,"x0"), }; SET(0x03BEE758, Z3_mk_quantifier(ctx,1,0,0,0,1,args03CEE280,args03CEE2B0,GET(Z3_ast,0x03BE9BB0)));} +{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03BEE758));} +{SET(0x03BEB8F0, Z3_mk_fresh_const(ctx,"x",GET(Z3_sort,0x03BCD088)));} +{Z3_ast args03BEAB30[2] = {GET(Z3_ast,0x03BEB8F0), GET(Z3_ast,0x03BEB7F0), }; SET(0x03BEC9D0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03BEAB30));} +{Z3_ast args03CEE2B0[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03BECA18, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03CEE2B0));} +{Z3_ast args03CEE2B0[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03BECA60, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB3C8),1,args03CEE2B0));} +{Z3_ast args03BEAB30[2] = {GET(Z3_ast,0x03BECA18), GET(Z3_ast,0x03BECA60), }; SET(0x03BECAA8, Z3_mk_or(ctx,2,args03BEAB30));} +{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03BECAA8),0));} +{SET(0x03BECA60, Z3_get_app_arg(ctx,GET(Z3_app,0x03BECAA8),1));} +{Z3_ast args03BEAB30[3] = {GET(Z3_ast,0x03BECA18), GET(Z3_ast,0x03BECA60), GET(Z3_ast,0x03BEC9D0), }; SET(0x03BE9C50, Z3_mk_or(ctx,3,args03BEAB30));} +{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03BE9C50));} +Z3_push(ctx); +{(Z3_check_and_get_model(ctx,0));} +{SET(0x03BFD780, Z3_mk_int(ctx,2,GET(Z3_sort,0x03BC7FD8)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFD780), 10);} +{SET(0x03C0DC08, Z3_mk_not(ctx,GET(Z3_ast,0x03BEC9D0)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DC08), 10);} +{SET(0x03C094A0, Z3_mk_ite(ctx,GET(Z3_ast,0x03BECA18),GET(Z3_ast,0x03BEB8F0),GET(Z3_ast,0x03BEB7F0)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C094A0), 10);} +{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094A0),0));} +{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094A0),1));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094A0),2));} +{SET(0x03C0DC50, Z3_mk_not(ctx,GET(Z3_ast,0x03BECA18)));} +{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DC50),0));} +{Z3_ast args03C03310[1] = {GET(Z3_ast,0x03BEC9D0), }; SET(0x03C0DC98, Z3_mk_or(ctx,1,args03C03310));} +{SET(0x03C0DCE0, Z3_mk_implies(ctx,GET(Z3_ast,0x03BECA18),GET(Z3_ast,0x03C0DC98)));} +{SET(0x03C0DD28, Z3_mk_not(ctx,GET(Z3_ast,0x03C0DCE0)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DD28), 10);} +{SET(0x03C0DCE0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD28),0));} +{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),0));} +{SET(0x03C0DC98, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),1));} +{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DC98),0));} +{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),0));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),1));} +{Z3_ast args03C07F90[3] = {GET(Z3_ast,0x03BCCE08), GET(Z3_ast,0x03BEB7F0), GET(Z3_ast,0x03BEB7F0), }; SET(0x03C094F0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9A70),3,args03C07F90));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C094F0), 10);} +{Z3_ast args03C07F90[3] = {GET(Z3_ast,0x03BFD780), GET(Z3_ast,0x03BEB7F0), GET(Z3_ast,0x03BEB7F0), }; SET(0x03C09540, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9A70),3,args03C07F90));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C09540), 10);} +{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),0));} +{SET(0x03C0DC98, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),1));} +{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DC98),0));} +{Z3_pop(ctx,1);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BECA18), GET(Z3_ast,0x03BEC9D0), }; SET(0x03BFF5D8, Z3_mk_or(ctx,2,args03BFED58));} +{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03BFF5D8),0));} +{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BFF5D8),1));} +{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),0));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),1));} +Z3_push(ctx); +{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03C0D980, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB380),1,args03BC3DF8));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0D980), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0D980), GET(Z3_ast,0x03BCCE08), }; SET(0x03C0D9C8, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0D9C8), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0D980), GET(Z3_ast,0x03BFD780), }; SET(0x03C0DD70, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DD70), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0D9C8), GET(Z3_ast,0x03C0DD70), }; SET(0x03C0DDB8, Z3_mk_or(ctx,2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DDB8), 10);} +{SET(0x03C0DCE0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD28),0));} +{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),0));} +{SET(0x03C0DC98, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),1));} +{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DC98),0));} +{Z3_pop(ctx,1);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BECA60), GET(Z3_ast,0x03BEC9D0), }; SET(0x03C0DE00, Z3_mk_or(ctx,2,args03BFED58));} +{SET(0x03BECA60, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DE00),0));} +{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DE00),1));} +{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),0));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),1));} +Z3_push(ctx); +{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03BFF590, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEC430),1,args03BC3DF8));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFF590), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFF590), GET(Z3_ast,0x03BEB7F0), }; SET(0x03C0DE90, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DE90), 10);} +{SET(0x03C0DE48, Z3_mk_not(ctx,GET(Z3_ast,0x03C0DE90)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DE48), 10);} +{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BFF590), }; SET(0x03BFFC08, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03BC3DF8));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFFC08), 10);} +{SET(0x03C00440, Z3_mk_ite(ctx,GET(Z3_ast,0x03BFFC08),GET(Z3_ast,0x03BFF590),GET(Z3_ast,0x03BEB7F0)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C00440), 10);} +{SET(0x03BFFC08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00440),0));} +{SET(0x03BFF590, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00440),1));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00440),2));} +{SET(0x03C0DED8, Z3_mk_not(ctx,GET(Z3_ast,0x03BFFC08)));} +{SET(0x03BFFC08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DED8),0));} +{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03C0DE90), }; SET(0x03C0DF20, Z3_mk_or(ctx,1,args03BC3DF8));} +{SET(0x03C0DF68, Z3_mk_implies(ctx,GET(Z3_ast,0x03BFFC08),GET(Z3_ast,0x03C0DF20)));} +{SET(0x03C0DFB0, Z3_mk_not(ctx,GET(Z3_ast,0x03C0DF68)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DFB0), 10);} +{SET(0x03C0DF68, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DFB0),0));} +{SET(0x03BCCE08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094F0),0));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094F0),1));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094F0),2));} +{SET(0x03BFD780, Z3_get_app_arg(ctx,GET(Z3_app,0x03C09540),0));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C09540),1));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C09540),2));} +{SET(0x03BFFC08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DF68),0));} +{SET(0x03C0DF20, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DF68),1));} +{SET(0x03C0DE90, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DF20),0));} +{Z3_pop(ctx,1);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFFC08), GET(Z3_ast,0x03C0DE90), }; SET(0x03C0DFF8, Z3_mk_or(ctx,2,args03BFED58));} +{SET(0x03BFFC08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DFF8),0));} +{SET(0x03C0DE90, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DFF8),1));} +{SET(0x03BFF590, Z3_get_app_arg(ctx,GET(Z3_app,0x03BFFC08),0));} +{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BFF590),0));} +{SET(0x03BFF590, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DE90),0));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DE90),1));} +Z3_push(ctx); +{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BFF590), }; SET(0x03C0E040, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB380),1,args03BC3DF8));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E040), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E040), GET(Z3_ast,0x03BCCE08), }; SET(0x03C0E088, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E088), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E040), GET(Z3_ast,0x03BFD780), }; SET(0x03C0E0D0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E0D0), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E088), GET(Z3_ast,0x03C0E0D0), }; SET(0x03C0E118, Z3_mk_or(ctx,2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E118), 10);} +{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03BFF7D0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEC478),1,args03BC3DF8));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFF7D0), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFF7D0), GET(Z3_ast,0x03BEB7F0), }; SET(0x03C0E1A8, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E1A8), 10);} +{SET(0x03C0E160, Z3_mk_not(ctx,GET(Z3_ast,0x03C0E1A8)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E160), 10);} +{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BFF7D0), }; SET(0x03BFF980, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03BC3DF8));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFF980), 10);} +{SET(0x03C00580, Z3_mk_ite(ctx,GET(Z3_ast,0x03BFF980),GET(Z3_ast,0x03BFF7D0),GET(Z3_ast,0x03BEB7F0)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C00580), 10);} +{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00580),0));} +{SET(0x03BFF7D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00580),1));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00580),2));} +{SET(0x03C0E1F0, Z3_mk_not(ctx,GET(Z3_ast,0x03BFF980)));} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E1A8), GET(Z3_ast,0x03C0E1F0), }; SET(0x03C0E238, Z3_mk_or(ctx,2,args03BFED58));} +{SET(0x03C0E1A8, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E238),0));} +{SET(0x03C0E1F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E238),1));} +{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E1F0),0));} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFF980), GET(Z3_ast,0x03C0E160), }; SET(0x03C0E280, Z3_mk_and(ctx,2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E280), 10);} +{SET(0x03C0E2C8, Z3_mk_not(ctx,GET(Z3_ast,0x03C0E280)));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E2C8), 10);} +{SET(0x03C0E280, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E2C8),0));} +{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),0));} +{SET(0x03C0E160, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),1));} +{SET(0x03C0E1A8, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E160),0));} +{Z3_pop(ctx,1);} +Z3_push(ctx); +{Z3_pop(ctx,1);} +{SET(0x03C0E280, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E2C8),0));} +{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),0));} +{SET(0x03C0E160, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),1));} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFF980), GET(Z3_ast,0x03C0E1A8), }; SET(0x03C0E310, Z3_mk_or(ctx,2,args03BFED58));} +{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E310),0));} +{SET(0x03C0E1A8, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E310),1));} +{SET(0x03BFF7D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E1A8),0));} +{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E1A8),1));} +Z3_push(ctx); +{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BFF7D0), }; SET(0x03C0E358, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB380),1,args03BC3DF8));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E358), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E358), GET(Z3_ast,0x03BCCE08), }; SET(0x03C0E3A0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E3A0), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E358), GET(Z3_ast,0x03BFD780), }; SET(0x03C0E3E8, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E3E8), 10);} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E3A0), GET(Z3_ast,0x03C0E3E8), }; SET(0x03BEEC08, Z3_mk_or(ctx,2,args03BFED58));} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03BEEC08), 10);} +{SET(0x03C0DCE0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD28),0));} +{Z3_pop(ctx,1);} +Z3_push(ctx); +{SET(0x03C0E280, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E2C8),0));} +{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),0));} +{SET(0x03C0E160, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),1));} +{Z3_pop(ctx,1);} +{Z3_ast args03BEEC50[7] = {GET(Z3_ast,0x03BFF980), GET(Z3_ast,0x03C0DE48), GET(Z3_ast,0x03C0DFB0), GET(Z3_ast,0x03C0DCE0), GET(Z3_ast,0x03C0E118), GET(Z3_ast,0x03C0E160), GET(Z3_ast,0x03BEEC08), }; SET(0x03BEE6E8, Z3_mk_and(ctx,7,args03BEEC50));} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0DD28), GET(Z3_ast,0x03C0DDB8), }; SET(0x03BEEC50, Z3_mk_and(ctx,2,args03BFED58));} +{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BEE6E8), GET(Z3_ast,0x03BEEC50), }; SET(0x03BEEC98, Z3_mk_or(ctx,2,args03BFED58));} +{SET(0x03BEE6E8, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEEC98),0));} +{SET(0x03BEEC50, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEEC98),1));} +{SET(0x03C0DD28, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEEC50),0));} +{SET(0x03C0DDB8, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEEC50),1));} +{SET(0x03C0D9C8, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DDB8),0));} +{SET(0x03C0DD70, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DDB8),1));} +{SET(0x03C0D980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD70),0));} +{SET(0x03BFD780, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD70),1));} +{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0D980),0));} +Z3_push(ctx); +{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03C0DC08));} +{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03BEEC98));} +Z3_push(ctx); +{(Z3_check_and_get_model(ctx,&_m));} +{Z3_ast out002DE120; Z3_eval(ctx,_m, GET(Z3_ast,0x03BEB8F0), &out002DE120);SET(0x03C14AE8, out002DE120);} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C14AE8), 2);} +{Z3_ast args03C123F8[2] = {GET(Z3_ast,0x03BEB8F0), GET(Z3_ast,0x03C14AE8), }; SET(0x03C14B78, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03C123F8));} +{Z3_ast args03BC3F18[1] = {GET(Z3_ast,0x03C14B78), }; SET(0x03C14B30, Z3_mk_and(ctx,1,args03BC3F18));} +{SET(0x03C14BC0, Z3_mk_not(ctx,GET(Z3_ast,0x03C14B30)));} +{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03C14BC0));} +{(Z3_check_and_get_model(ctx,&_m));} +{Z3_ast out002DE120; Z3_eval(ctx,_m, GET(Z3_ast,0x03BEB8F0), &out002DE120);SET(0x03C127D0, out002DE120);} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C127D0), 2);} +{Z3_ast args03C037E8[2] = {GET(Z3_ast,0x03BEB8F0), GET(Z3_ast,0x03C127D0), }; SET(0x03C028D0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03C037E8));} +{Z3_ast args03BC3EE8[1] = {GET(Z3_ast,0x03C028D0), }; SET(0x03C1F100, Z3_mk_and(ctx,1,args03BC3EE8));} +{SET(0x03C1F148, Z3_mk_not(ctx,GET(Z3_ast,0x03C1F100)));} +{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03C1F148));} +{(Z3_check_and_get_model(ctx,&_m));} +{Z3_ast out002DE120; Z3_eval(ctx,_m, GET(Z3_ast,0x03BEB8F0), &out002DE120);SET(0x03C1F5C8, out002DE120);} +{Z3_persist_ast(ctx,GET(Z3_ast,0x03C1F5C8), 2);} +{Z3_ast args03C05F78[2] = {GET(Z3_ast,0x03BEB8F0), GET(Z3_ast,0x03C1F5C8), }; SET(0x03C23580, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03C05F78));} +{Z3_ast args03CEE490[1] = {GET(Z3_ast,0x03C23580), }; SET(0x03C23538, Z3_mk_and(ctx,1,args03CEE490));} +{SET(0x03C235C8, Z3_mk_not(ctx,GET(Z3_ast,0x03C23538)));} +{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03C235C8));} +//{Z3_check(ctx);} +} + +void test_apps() { + Z3_config cfg = Z3_mk_config(); + Z3_set_param_value(cfg,"MODEL","true"); + Z3_context ctx = Z3_mk_context(cfg); + Z3_symbol A = Z3_mk_string_symbol(ctx, "A"); + Z3_symbol F = Z3_mk_string_symbol(ctx, "f"); + Z3_sort SA = Z3_mk_uninterpreted_sort(ctx, A); + Z3_func_decl f = Z3_mk_func_decl(ctx, F, 1, &SA, SA); + Z3_symbol X = Z3_mk_string_symbol(ctx, "x"); + Z3_ast x = Z3_mk_const(ctx, X, SA); + Z3_ast fx = Z3_mk_app(ctx, f, 1, &x); + Z3_ast ffx = Z3_mk_app(ctx, f, 1, &fx); + Z3_ast fffx = Z3_mk_app(ctx, f, 1, &ffx); + Z3_ast ffffx = Z3_mk_app(ctx, f, 1, &fffx); + Z3_ast fffffx = Z3_mk_app(ctx, f, 1, &ffffx); + + Z3_ast fml = Z3_mk_not(ctx, Z3_mk_eq(ctx, x, fffffx)); + + Z3_assert_cnstr(ctx, fml); + Z3_lbool r = Z3_check(ctx); + std::cout << r << "\n"; + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void test_bvneg() { + Z3_config cfg = Z3_mk_config(); + Z3_set_param_value(cfg,"MODEL","true"); + Z3_context ctx = Z3_mk_context(cfg); + + { + Z3_sort bv30 = Z3_mk_bv_sort(ctx, 30); + Z3_ast x30 = Z3_mk_fresh_const(ctx, "x", bv30); + Z3_ast fml = Z3_mk_eq(ctx, Z3_mk_int(ctx, -1, bv30), + Z3_mk_bvadd(ctx, Z3_mk_int(ctx, 0, bv30), + x30)); + Z3_assert_cnstr(ctx, fml); + Z3_lbool r = Z3_check(ctx); + std::cout << r << "\n"; + } + + { + Z3_sort bv31 = Z3_mk_bv_sort(ctx, 31); + Z3_ast x31 = Z3_mk_fresh_const(ctx, "x", bv31); + Z3_ast fml = Z3_mk_eq(ctx, Z3_mk_int(ctx, -1, bv31), + Z3_mk_bvadd(ctx, Z3_mk_int(ctx, 0, bv31), + x31)); + Z3_assert_cnstr(ctx, fml); + Z3_lbool r = Z3_check(ctx); + std::cout << r << "\n"; + } + + { + Z3_sort bv32 = Z3_mk_bv_sort(ctx, 32); + Z3_ast x32 = Z3_mk_fresh_const(ctx, "x", bv32); + Z3_ast fml = Z3_mk_eq(ctx, + Z3_mk_int(ctx,-1, bv32), + Z3_mk_bvadd(ctx, Z3_mk_int(ctx, 0, bv32), + x32)); + Z3_assert_cnstr(ctx, fml); + Z3_lbool r = Z3_check(ctx); + std::cout << r << "\n"; + } + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void tst_api() { + test_apps(); + test_bvneg(); + bv_invariant(); +} +#else +void tst_api() { +} +#endif diff --git a/test/api_bug.cpp b/test/api_bug.cpp new file mode 100644 index 000000000..917ac7dd6 --- /dev/null +++ b/test/api_bug.cpp @@ -0,0 +1,42 @@ +#include "z3.h" +#include "stdio.h" + +void tst_api_bug() { + unsigned vmajor, vminor, vbuild, vrevision; + + Z3_get_version(&vmajor, &vminor, &vbuild, &vrevision); + + printf("Using Z3 Version %u.%u (build %u, revision %u)\n", vmajor, vminor, vbuild, vrevision); + + + Z3_config cfg = Z3_mk_config(); + Z3_set_param_value(cfg, "MODEL", "true"); + Z3_context ctx = Z3_mk_context(cfg); + + Z3_sort is = Z3_mk_int_sort(ctx); + Z3_sort ss = Z3_mk_set_sort(ctx, is); + Z3_ast e = Z3_mk_empty_set(ctx, is); + // { 42 } + Z3_ast fortytwo = Z3_mk_set_add(ctx, e, Z3_mk_int(ctx, 42, is)); + // { 42, 43 } + Z3_ast fortythree = Z3_mk_set_add(ctx, fortytwo, Z3_mk_int(ctx, 43, is)); + // { 42 } U { 42, 43 } + + Z3_ast uargs[2] = { fortytwo, fortythree }; + Z3_ast u = Z3_mk_set_union(ctx, 2, uargs); + + Z3_symbol sym = Z3_mk_string_symbol(ctx, "mySet"); + Z3_ast s = Z3_mk_const(ctx, sym, ss); + Z3_ast c = Z3_mk_eq(ctx, s, u); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, c); + + Z3_model m; + printf("result %d\n", Z3_check_and_get_model(ctx, &m)); + + Z3_string ms = Z3_model_to_string(ctx, m); + printf("model : %s\n", ms); +} + + diff --git a/test/arith_rewriter.cpp b/test/arith_rewriter.cpp new file mode 100644 index 000000000..04b018646 --- /dev/null +++ b/test/arith_rewriter.cpp @@ -0,0 +1,16 @@ +#include "arith_rewriter.h" +#include "bv_decl_plugin.h" +#include "ast_pp.h" + +void tst_arith_rewriter() { + ast_manager m; + m.register_decl_plugins(); + arith_rewriter ar(m); + arith_util au(m); + expr_ref t1(m), t2(m), result(m); + t1 = au.mk_numeral(rational(0),false); + t2 = au.mk_numeral(rational(-3),false); + expr* args[2] = { t1, t2 }; + ar.mk_mul(2, args, result); + std::cout << mk_pp(result, m) << "\n"; +} diff --git a/test/arith_simplifier_plugin.cpp b/test/arith_simplifier_plugin.cpp new file mode 100644 index 000000000..0ea1c2675 --- /dev/null +++ b/test/arith_simplifier_plugin.cpp @@ -0,0 +1,67 @@ +#include "arith_eq_solver.h" +#include "front_end_params.h" + +typedef rational numeral; +typedef vector row; + +static void test_solve_integer_equations( + arith_eq_solver& asimp, + vector& rows + ) +{ + row r_unsat; + + if (asimp.solve_integer_equations(rows, r_unsat)) { + std::cout << "solved\n"; + } + else { + std::cout << "not solved\n"; + for (unsigned i = 0; i < r_unsat.size(); ++i) { + std::cout << " " << r_unsat[i]; + } + std::cout << "\n"; + } +} + +void tst_arith_simplifier_plugin() { + front_end_params params; + ast_manager m; + arith_eq_solver asimp(m); + + row r1; + row r2; + + r1.push_back(numeral(1)); + r1.push_back(numeral(2)); + r1.push_back(numeral(1)); + r1.push_back(numeral(2)); + + r2.push_back(numeral(1)); + r2.push_back(numeral(2)); + r2.push_back(numeral(1)); + r2.push_back(numeral(2)); + + vector rows; + rows.push_back(r1); + rows.push_back(r2); + +#if 0 + test_solve_integer_equations(asimp, rows); + + rows[1][3] = numeral(3); + test_solve_integer_equations(asimp, rows); +#endif + + rows[0][0] = numeral(1); + rows[0][1] = numeral(3); + rows[0][2] = numeral(0); + rows[0][3] = numeral(0); + + rows[1][0] = numeral(1); + rows[1][1] = numeral(0); + rows[1][2] = numeral(3); + rows[1][3] = numeral(1); + + test_solve_integer_equations(asimp, rows); + +} diff --git a/test/array_property_expander.cpp b/test/array_property_expander.cpp new file mode 100644 index 000000000..6b43efa8f --- /dev/null +++ b/test/array_property_expander.cpp @@ -0,0 +1,53 @@ +#include "array_property_expander.h" +#include "array_property_recognizer.h" +#include "smtparser.h" +#include "array_decl_plugin.h" +#include "ast_pp.h" +#include + +static void test_array_expand(ast_manager& m, expr* fml) { + std::cout << mk_pp(fml, m) << "\n"; + expr_ref_vector result(m); + array_property_expander exp(m); + array_property_recognizer rec(m); + exp(1, &fml, result); + std::cout << mk_pp(result[0].get(), m) << "\n"; + std::cout << rec(1, &fml) << "\n"; +} + + +static void parse_string(char const* fml) { + ast_manager m; + m.register_plugin(symbol("array"), alloc(array_decl_plugin)); + scoped_ptr parser = smtlib::parser::create(m); + parser->initialize_smtlib(); + + std::ostringstream buffer; + buffer << "(benchmark array :status unknown :logic AUFLIA \n" + << ":extrafuns ((A (Array Int Int)) (B (Array Int Int)))\n" + << ":extrafuns ((C (Array Int (Array Int Int))))\n" + << ":extrafuns ((D (Array Int Bool Int)))\n" + << ":extrafuns ((i Int) (j Int))\n" + << ":extrafuns ((f Int Int))\n" + << ":formula " << fml << ")"; + 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_array_expand(m, *it); + } +} + + +void tst_array_property_expander() { + parse_string("(= A B)"); + parse_string("(= A (store B i 4))"); + parse_string("(= C (store C 0 (store (select C 0) i 1)))"); + parse_string("(exists (i Int) (= C (store C 0 (store (select C 0) i 1))))"); + parse_string("(forall (i Int) (b Bool) (= D (store D i b 4)))"); + parse_string("(= (const[Array] 3) A)"); + parse_string("(= (map[f] A) B)"); + +} + diff --git a/test/ast.cpp b/test/ast.cpp new file mode 100644 index 000000000..fce8dafc6 --- /dev/null +++ b/test/ast.cpp @@ -0,0 +1,157 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_ast.cpp + +Abstract: + + Test AST module + +Author: + + Leonardo de Moura (leonardo) 2006-09-29. + +Revision History: + +--*/ +#include "ast.h" + +static void tst1() { + ast_manager m; + + family_id fid = m.get_basic_family_id(); + + sort_ref b(m.mk_bool_sort(), m); + expr_ref a(m.mk_const(symbol("a"), b.get()), m); + expr_ref c(m.mk_const(symbol("c"), b.get()), m); + expr_ref i1(m.mk_app(fid, OP_AND, a.get(), c.get()), m); + expr_ref i2(m.mk_app(fid, OP_AND, a.get(), c.get()), m); + expr_ref i3(m.mk_app(fid, OP_OR, a.get(), c.get()), m); + SASSERT(i1.get() == i2.get()); + SASSERT(i1.get() != i3.get()); + + // TODO use smart pointers to track references +// ast_manager m; +// ast_ref n1(m.mk_numeral(rational(2,3)), m); +// ast_ref n2(m.mk_numeral(rational(2,3)), m); +// SASSERT(n1 == n2); +// ast_ref n3(m.mk_numeral(rational(1,2)), m); +// SASSERT(n1 != n3); +// ast_ref v1 (m.mk_var(1), m); +// ast_ref v2 (m.mk_var(2), m); +// ast_ref v3 (m.mk_var(1), m); +// SASSERT(v1 != v2); +// SASSERT(v1 == v3); +// TRACE("ast", tout << "reseting v1\n";); +// v1.reset(); +// TRACE("ast", tout << "overwriting v3\n";); +// v3 = v2; + +// ast_ref t1(m.mk_type_decl(symbol("int"), 0), m); +// ast_ref i(m.mk_type(t1.get(), 0, 0), m); + +// ast_ref foo_decl(m.mk_const_decl(symbol("foo"), i.get(), i.get()), m); +// ast_ref x_decl(m.mk_const_decl(symbol("x"), i.get()), m); + +// ast_ref x(m.mk_const(x_decl.get()), m); +// ast_ref foo_x(m.mk_const(foo_decl.get(), x.get()), m); +// ast_ref foo_foo_x(m.mk_const(foo_decl.get(), foo_x.get()), m); +// ast_ref foo_foo_x2(m.mk_const(foo_decl.get(), m.mk_const(foo_decl.get(), m.mk_const(x_decl.get()))), m); +// SASSERT(foo_foo_x2 == foo_foo_x); +} + +void tst2() { +// ast_manager m; +// ast_vector m_nodes(m); + +// m_nodes.push_back(m.mk_var(1)); +// m_nodes.push_back(m.mk_numeral(rational(1,2))); +// m_nodes.push_back(m.mk_var(2)); +// m_nodes[1] = m.mk_var(3); +// SASSERT(m_nodes[1]->kind() == AST_VAR); +// SASSERT(m_nodes.get(1)->kind() == AST_VAR); +// m_nodes.pop_back(); +// SASSERT(m_nodes.size() == 2); +// SASSERT(!m_nodes.empty()); +// m_nodes.set(1, m.mk_var(4)); +// SASSERT(&(m_nodes.get_manager()) == &m); +} + +static void tst3() { +// ast_manager m; +// ast_ref<> n(m.mk_var(1), m); +// n = m.mk_var(1); +// TRACE("ast", tout << n->get_id() << "\n";); +} + +static void tst4() { +// ast_manager m; +// ast_ref<> n1(m.mk_var(1), m); +// ast_ref<> n2(m.mk_var(2), m); +// ast_ref<> n3(m.mk_var(3), m); +// weak_memoize wm1; +// #ifdef Z3DEBUG +// int r; +// #endif +// SASSERT(!wm1.find(n1, r)); +// wm1.insert(n2, 10); +// SASSERT(!wm1.find(n1, r)); +// SASSERT(wm1.find(n2, r) && r == 10); +// wm1.insert(n2, 20); +// SASSERT(!wm1.find(n1, r)); +// SASSERT(wm1.find(n2, r) && r == 20); +// wm1.insert(n1, 0); +// SASSERT(wm1.find(n1, r) && r == 0); +// SASSERT(wm1.find(n2, r) && r == 20); +} + +static void tst5() { + ast_manager m; + sort_ref b(m.mk_bool_sort(), m); + expr_ref a1(m.mk_const(symbol("a1"), b.get()), m); + expr_ref a2(m.mk_const(symbol("a2"), b.get()), m); + expr_array arr1; + expr_array arr2; + expr_array arr3; + m.push_back(arr1, a1); + m.push_back(arr1, a2); + m.pop_back(arr1, arr2); + m.set(arr2, 0, a2, arr3); + SASSERT(m.size(arr1) == 2); + SASSERT(m.size(arr2) == 1); + SASSERT(m.size(arr3) == 1); + SASSERT(m.get(arr1, 0) == a1); + SASSERT(m.get(arr1, 1) == a2); + SASSERT(m.get(arr2, 0) == a1); + SASSERT(m.get(arr3, 0) == a2); + m.del(arr1); + m.del(arr2); + m.del(arr3); +} + + +struct foo { + unsigned m_id; + unsigned short m_ref_count; + unsigned char m_kind; + unsigned char m_arity; + bool m_val1:1; + bool m_val2:1; +}; + +void tst_ast() { + TRACE("ast", + tout << "sizeof(ast): " << sizeof(ast) << "\n"; + tout << "sizeof(expr): " << sizeof(expr) << "\n"; + tout << "sizeof(app): " << sizeof(app) << "\n"; + ); + TRACE("ast", tout << "sizeof(foo): " << sizeof(foo) << "\n";); + tst1(); + tst2(); + tst3(); + tst4(); + tst5(); +} + diff --git a/test/ast_pp.cpp b/test/ast_pp.cpp new file mode 100644 index 000000000..414b26411 --- /dev/null +++ b/test/ast_pp.cpp @@ -0,0 +1,59 @@ +/*++ +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/test/ast_smt_pp.cpp b/test/ast_smt_pp.cpp new file mode 100644 index 000000000..05fd5748e --- /dev/null +++ b/test/ast_smt_pp.cpp @@ -0,0 +1,90 @@ +/*++ +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/test/bit_blaster.cpp b/test/bit_blaster.cpp new file mode 100644 index 000000000..d864032f5 --- /dev/null +++ b/test/bit_blaster.cpp @@ -0,0 +1,123 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + bit_blaster.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-05. + +Revision History: + +--*/ + +#include"bit_blaster.h" +#include"ast_pp.h" +#include"ast_ll_pp.h" + +void mk_bits(ast_manager & m, char const * prefix, unsigned sz, expr_ref_vector & r) { + sort_ref b(m); + b = m.mk_bool_sort(); + for (unsigned i = 0; i < sz; ++i) { + char buffer[128]; +#ifdef _WINDOWS + sprintf_s(buffer, ARRAYSIZE(buffer), "%s%d.smt", prefix, i); +#else + sprintf(buffer, "%s%d.smt", prefix, i); +#endif + r.push_back(m.mk_const(symbol(buffer), b)); + } +} + +void display(std::ostream & out, expr_ref_vector & r, bool ll=true) { + ast_mark v; + for (unsigned i = 0; i < r.size(); i++) { + if (ll) + ast_ll_pp(out, r.get_manager(), r.get(i), v); + else + out << mk_pp(r.get(i), r.get_manager()); + out << "\n"; + } +} + +void tst_adder(ast_manager & m, unsigned sz) { +// expr_ref_vector a(m); +// expr_ref_vector b(m); +// expr_ref_vector c(m); +// mk_bits(m, "a", sz, a); +// mk_bits(m, "b", sz, b); +// bool t = true; +// bit_blaster blaster(m, t); +// blaster.mk_adder(sz, a.c_ptr(), b.c_ptr(), c); +// TRACE("bit_blaster", display(tout, c);); +} + +void tst_multiplier(ast_manager & m, unsigned sz) { +// expr_ref_vector a(m); +// expr_ref_vector b(m); +// expr_ref_vector c(m); +// mk_bits(m, "a", sz, a); +// mk_bits(m, "b", sz, b); +// bool t = true; +// bit_blaster blaster(m, t); +// blaster.mk_multiplier(sz, a.c_ptr(), b.c_ptr(), c); +// TRACE("bit_blaster", display(tout, c);); +} + +void tst_le(ast_manager & m, unsigned sz) { +// expr_ref_vector a(m); +// expr_ref_vector b(m); +// expr_ref out(m); +// mk_bits(m, "a", sz, a); +// mk_bits(m, "b", sz, b); +// bool t = true; +// bit_blaster blaster(m, t); +// blaster.mk_ule(sz, a.c_ptr(), b.c_ptr(), out); +// TRACE("bit_blaster", tout << mk_pp(out, m) << "\n";); +// blaster.mk_sle(sz, a.c_ptr(), b.c_ptr(), out); +// TRACE("bit_blaster", tout << mk_pp(out, m) << "\n";); +} + +void tst_eqs(ast_manager & m, unsigned sz) { +// expr_ref_vector a(m); +// expr_ref_vector b(m); +// expr_ref out(m); +// mk_bits(m, "a", sz, a); +// bool t = true; +// bit_blaster blaster(m, t); +// blaster.mk_eqs(sz, a.c_ptr(), b); +// TRACE("bit_blaster", display(tout, b, false);); +} + +void tst_sh(ast_manager & m, unsigned sz) { +// expr_ref_vector a(m); +// expr_ref_vector b(m); +// expr_ref_vector c(m); +// mk_bits(m, "a", sz, a); +// mk_bits(m, "b", sz, b); +// bool t = true; +// bit_blaster blaster(m, t); +// blaster.mk_shl(sz, a.c_ptr(), b.c_ptr(), c); +// TRACE("bit_blaster", tout << "shl\n"; display(tout, c);); +// c.reset(); +// blaster.mk_lshr(sz, a.c_ptr(), b.c_ptr(), c); +// TRACE("bit_blaster", tout << "lshr\n"; display(tout, c);); +// c.reset(); +// blaster.mk_ashr(sz, a.c_ptr(), b.c_ptr(), c); +// TRACE("bit_blaster", tout << "ashr " << c.size() << "\n"; display(tout, c, false);); +} + +void tst_bit_blaster() { + ast_manager m; + tst_adder(m, 4); + tst_multiplier(m, 4); + tst_le(m, 4); + tst_eqs(m, 8); + tst_sh(m, 4); +} diff --git a/test/bit_vector.cpp b/test/bit_vector.cpp new file mode 100644 index 000000000..2b67c3a71 --- /dev/null +++ b/test/bit_vector.cpp @@ -0,0 +1,291 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_bitvector.cpp + +Abstract: + + Test bitvector module + +Author: + + Leonardo de Moura (leonardo) 2006-10-03. + +Revision History: + +--*/ +#include +#include +#include"bit_vector.h" +#include"vector.h" + +static void tst1() { + bit_vector v1; + svector v2; + unsigned n = rand()%10000; + for (unsigned i = 0; i < n; i++) { + int op = rand()%6; + if (op <= 1) { + bool val = (rand()%2) != 0; + v1.push_back(val); + v2.push_back(val); + SASSERT(v1.size() == v2.size()); + } + else if (op <= 3) { + SASSERT(v1.size() == v2.size()); + if (v1.size() > 0) { + bool val = (rand()%2) != 0; + unsigned idx = rand()%v1.size(); + SASSERT(v1.get(idx) == v2[idx]); + v1.set(idx, val); + v2[idx] = val; + SASSERT(v1.get(idx) == v2[idx]); + } + } + else if (op <= 4) { + SASSERT(v1.size() == v2.size()); + if (v1.size() > 0) { + unsigned idx = rand()%v1.size(); + SASSERT(v1.get(idx) == v2[idx]); + } + } + else if (op <= 5) { + SASSERT(v1.size() == v2.size()); + for (unsigned j = 0; j < v1.size(); j++) { + SASSERT(v1.get(j) == v2[j]); + } + } + } +} + +static void tst2() { + bit_vector b; + b.push_back(true); + b.push_back(false); + b.push_back(true); + b.resize(30); + SASSERT(b.get(0) == true); + SASSERT(b.get(1) == false); + SASSERT(b.get(2) == true); + SASSERT(b.get(3) == false); + SASSERT(b.get(29) == false); +} + +static void tst_shift() { + bit_vector b; + b.resize(111); + b.set(105); + b.set(99); + b.set(98); + b.set(90); + b.set(80); + b.set(75); + b.set(33); + b.set(32); + b.set(31); + b.set(30); + b.set(10); + std::cout << "b: " << b << "\n"; + b.shift_right(16); + std::cout << "b: " << b << "\n"; + b.shift_right(1); + std::cout << "b: " << b << "\n"; + b.shift_right(32); + std::cout << "b: " << b << "\n"; + b.shift_right(42); + std::cout << "b: " << b << "\n"; + b.shift_right(16); + std::cout << "b: " << b << "\n"; + b.shift_right(63); + std::cout << "b: " << b << "\n"; +} + +static void tst_or() { + { + bit_vector b1; + bit_vector b2; + b1.resize(5); + b2.resize(10); + b1.set(4); + b2.set(8); + b2.set(3); + b2.set(2); + b2.set(1); + std::cout << b1 << "\n"; + std::cout << b2 << "\n"; + b1 |= b2; + SASSERT(b1.size() == 10); + std::cout << b1 << "\n"; + SASSERT(b1 != b2); + SASSERT(b1 != b2); + b1.unset(4); + SASSERT(b1 == b2); + b1.unset(3); + SASSERT(b1 != b2); + } + { + bit_vector b1; + bit_vector b2; + b1.resize(2); + b2.resize(5); + b1.set(0); + b2.set(4); + b1 |= b2; + SASSERT(b1 != b2); + b2.set(0); + SASSERT(b1 == b2); + std::cout << "-----\n"; + std::cout << b1 << "\n"; + } + { + bit_vector b1; + bit_vector b2; + b1.resize(10); + b2.resize(10); + b1.set(5); + b2.set(8); + b2.set(3); + b2.resize(5); + b1 |= b2; + SASSERT(!b1.get(8)); + SASSERT(b1.get(5)); + SASSERT(b1.get(3)); + } + { + bit_vector b1; + bit_vector b2; + b1.resize(123); + b2.resize(126); + b2.set(124); + b1.set(122); + b1.set(100); + b2.set(100); + b1.set(80); + b2.set(80); + b1.set(4); + b2.set(4); + SASSERT(b1!=b2); + b2.resize(123); + SASSERT(b1!=b2); + b1.resize(120); + b2.resize(120); + SASSERT(b1==b2); + b1.unset(80); + b1.unset(100); + SASSERT(b1!=b2); + b1 |= b2; + SASSERT(b1 == b2); + } + { + bit_vector b1; + bit_vector b2; + b1.resize(5); + b2.resize(10); + b2.set(8); + b1.set(4); + b2.set(1); + b1.set(0); + b1 |= b2; + SASSERT(b1.size() == 10); + SASSERT(b1.get(8) && b1.get(4) && b1.get(1) && b1.get(0) && !b1.get(9)); + } + { + bit_vector b1; + bit_vector b2; + b1.resize(32); + b2.resize(32); + b1.set(1); + b1.set(5); + b2.set(8); + b2.set(0); + b1 |= b2; + SASSERT(b1.get(1) && b1.get(5) && b1.get(8) && b1.get(0) && !b1.get(11)); + std::cout << "b1(size32): " << b1 << "\n"; + } +} + +static void tst_and() { + { + bit_vector b1; + bit_vector b2; + b1.resize(5); + b2.resize(3); + b2.set(2); + b1.set(2); + b1.set(4); + std::cout << "------\nb1: " << b1 << "\n"; + b1 &= b2; + std::cout << "------\nb1: " << b1 << "\n"; + SASSERT(!b1.get(4)); + SASSERT(b1.get(2)); + } + { + bit_vector b1; + bit_vector b2; + b1.resize(241); + b2.resize(128); + b1.set(240); + b1.set(232); + b1.set(127); + b1.set(128); + b1.set(8); + b2.set(127); + b2.set(5); + b1 &= b2; + SASSERT(!b1.get(240) && !b1.get(232) && !b1.get(128) && b1.get(127) && !b1.get(8) && !b1.get(5)); + } +} + +static void tst_crash() { + { + bit_vector b; + b.push_back(true); + b.resize(64); + SASSERT(!b.get(63)); + SASSERT(b.get(0)); + SASSERT(!b.get(1)); + } + { + bit_vector b; + b.push_back(false); + b.resize(64, true); + SASSERT(b.get(63)); + SASSERT(!b.get(0)); + SASSERT(b.get(1)); + } +} + +static void tst_bv_reset() { + bit_vector b; + bool bit = true; + for (unsigned sz = 1; sz < 84; ++sz) { + b.reset(); + b.resize(sz, bit); + for (unsigned i = 0; i < sz; ++i) { + SASSERT(bit == b.get(i)); + } + for (unsigned sz2 = sz; sz2 < sz+10; ++sz2) { + b.resize(sz2, !bit); + for (unsigned i = sz; i < sz2; ++i) { + SASSERT(bit != b.get(i)); + } + } + bit = !bit; + } +} + +void tst_bit_vector() { + tst_crash(); + tst_shift(); + tst_or(); + tst_and(); + tst_bv_reset(); + return; + tst2(); + for (unsigned i = 0; i < 20; i++) { + std::cerr << i << std::endl; + tst1(); + } +} diff --git a/test/bits.cpp b/test/bits.cpp new file mode 100644 index 000000000..7254a177d --- /dev/null +++ b/test/bits.cpp @@ -0,0 +1,203 @@ +// Test some bit hacks +#include"util.h" +#include"debug.h" +#include"vector.h" +#include"mpz.h" +#include"bit_util.h" + +static void tst_shl(unsigned src_sz, unsigned const * src, unsigned k, + unsigned dst_sz, unsigned const * dst, bool trace = true) { + if (trace) { + std::cout << "shl({"; + for (unsigned i = 0; i < src_sz; i++) { + if (i > 0) std::cout << ", "; + std::cout << src[i]; + } + std::cout << "}, " << k << ")" << std::endl; + } + svector actual_dst; + actual_dst.resize(dst_sz, 0xAAAAAAAA); + for (unsigned sz = 1; sz <= dst_sz; sz++) { + if (trace) + std::cout << " for sz = " << sz << std::endl; + shl(src_sz, src, k, sz, actual_dst.c_ptr()); + SASSERT(!has_one_at_first_k_bits(sz, actual_dst.c_ptr(), k)); + for (unsigned i = 0; i < sz; i++) { + if (trace && dst[i] != actual_dst[i]) + std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n"; + SASSERT(dst[i] == actual_dst[i]); + } + if (sz == src_sz) { + unsigned nz1 = nlz(sz, src); + if (nz1 >= k && !is_zero(sz, src)) { + unsigned nz2 = nlz(sz, actual_dst.c_ptr()); + if (nz1 - k != nz2) { + if (trace) + std::cout << "nlz BUG, nlz1: " << nz1 << ", k: " << k << ", nlz2: " << nz2 << std::endl; + UNREACHABLE(); + } + } + } + if (sz >= src_sz + (k/32) + 1) { + svector new_src; + new_src.resize(sz, 0xAAAAAAAA); + shr(sz, actual_dst.c_ptr(), k, new_src.c_ptr()); + for (unsigned i = 0; i < src_sz; i++) { + if (trace && src[i] != new_src[i]) { + std::cout << "shr BUG, inverting shl, at bit[" << i << "], " << new_src[i] << ", expected: " << src[i] << std::endl; + } + SASSERT(src[i] == new_src[i]); + } + } + } + if (trace) + std::cout << " shift by 1, k times" << std::endl; + copy(src_sz, src, dst_sz, actual_dst.c_ptr()); + for (unsigned i = 0; i < k; i++) { + shl(dst_sz, actual_dst.c_ptr(), 1, dst_sz, actual_dst.c_ptr()); + } + for (unsigned i = 0; i < dst_sz; i++) { + if (trace && dst[i] != actual_dst[i]) + std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n"; + SASSERT(dst[i] == actual_dst[i]); + } + if (src_sz <= dst_sz) { + if (trace) + std::cout << " self-shl" << std::endl; + shl(src_sz, src, k, src_sz, const_cast(src)); + for (unsigned i = 0; i < src_sz; i++) { + if (trace && src[i] != dst[i]) + std::cout << "UNEXPECTED RESULT at [" << i << "]: " << src[i] << ", expected: " << dst[i] << "\n"; + SASSERT(src[i] == actual_dst[i]); + } + } +} + +static void tst_shl() { + { + unsigned src[2] = {0, 2}; unsigned dst[2] = {0, 2<<10}; + tst_shl(2, src, 10, 2, dst); + } + { + unsigned src[2] = {2, 0}; unsigned dst[2] = {0, 2<<10}; + tst_shl(2, src, 42, 2, dst); + } + { + unsigned src[2] = {0, 0}; unsigned dst[3] = {0, 0, 0}; + tst_shl(2, src, 1, 3, dst); + } + { + unsigned src[2] = {0x80000009, 5}; unsigned dst[2] = {18, 11}; + tst_shl(2, src, 1, 2, dst); + } + { + unsigned src[2] = {0x80000009, 0x80000005}; unsigned dst[2] = {18, 11}; + tst_shl(2, src, 1, 2, dst); + } + { + unsigned src[2] = {0x80000009, 0x80000005}; unsigned dst[3] = {18, 11, 1}; + tst_shl(2, src, 1, 3, dst); + } + { + unsigned src[2] = {0x80000009, 0x80000005}; unsigned dst[3] = {0, 18, 11}; + tst_shl(2, src, 33, 3, dst); + } + { + unsigned src[2] = {0x80000009, 0x80000005}; unsigned dst[4] = {0, 18, 11, 1}; + tst_shl(2, src, 33, 4, dst); + } + { + unsigned src[2] = {0xFFFFFFFF, 0xFFFFFFFF}; unsigned dst[2] = {0xFFFFFFF0, 0xFFFFFFFF}; + tst_shl(2, src, 4, 2, dst); + } +} + +static void tst_shr(unsigned src_sz, unsigned const * src, unsigned k, + unsigned const * dst, bool trace = true) { + if (trace) { + std::cout << "shr({"; + for (unsigned i = 0; i < src_sz; i++) { + if (i > 0) std::cout << ", "; + std::cout << src[i]; + } + std::cout << "}, " << k << ")" << std::endl; + } + svector actual_dst; + actual_dst.resize(src_sz, 0xAAAAAAAA); + shr(src_sz, src, k, actual_dst.c_ptr()); + for (unsigned i = 0; i < src_sz; i++) { + if (trace && dst[i] != actual_dst[i]) + std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n"; + SASSERT(dst[i] == actual_dst[i]); + } +} + +static void tst_shr() { + { + unsigned src[2] = {0, 0}; unsigned dst[2] = {0, 0}; + tst_shr(2, src, 1, dst); + } +} + +static void tst_shl_rand(unsynch_mpz_manager & m, unsigned sz, unsigned k, bool trace = true) { + // create a random bitvector of of size sz + svector src; + for (unsigned i = 0; i < sz; i++) { + src.push_back(rand()); + } + // convert src into a mpz number + scoped_mpz _src(m); + scoped_mpz tmp(m); + unsigned i = sz; + while (i > 0) { + --i; + m.mul2k(_src, 32); + m.set(tmp, src[i]); + m.add(_src, tmp, _src); + } + // shift left by multiplying by 2^k + scoped_mpz _dst(m); + m.set(_dst, _src); + m.mul2k(_dst, k); + // convert _dst into a vector of unsigned values + svector dst; + scoped_mpz max(m); + m.set(max, 1); + m.mul2k(max, 32); + while (!m.is_zero(_dst)) { + m.mod(_dst, max, tmp); + SASSERT(m.is_uint64(tmp) && m.get_uint64(tmp) < UINT_MAX); + dst.push_back(static_cast(m.get_uint64(tmp))); + m.div(_dst, max, _dst); + } + while (dst.size() < src.size()) + dst.push_back(0); + dst.push_back(0); + unsigned word_shift = (k / 32); + for (unsigned i = 0; i < word_shift; i++) + dst.push_back(0); + tst_shl(src.size(), src.c_ptr(), k, dst.size(), dst.c_ptr(), trace); +} + +static void tst_shl_rand(unsigned N, unsigned sz, unsigned k, bool trace = false) { + unsynch_mpz_manager m; + for (unsigned i = 0; i < N; i++) { + unsigned _sz = rand() % sz; + if (_sz == 0) + _sz = 1; + unsigned _k = rand() % k; + if (_k == 0) + _k = 1; + tst_shl_rand(m, _sz, _k, trace); + } +} + +void tst_bits() { + tst_shr(); + tst_shl(); + tst_shl_rand(100000, 4, 100); +} + + + + diff --git a/test/buffer.cpp b/test/buffer.cpp new file mode 100644 index 000000000..a23fb3c74 --- /dev/null +++ b/test/buffer.cpp @@ -0,0 +1,48 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + buffer.cpp + +Abstract: + + Test buffers. + +Author: + + Leonardo de Moura (leonardo) 2011-03-03. + +Revision History: + +--*/ +#include"ptr_scoped_buffer.h" + +typedef std::pair point; + +template class ptr_scoped_buffer; + +static void tst1() { + ptr_scoped_buffer b; + SASSERT(b.empty()); + b.push_back(alloc(point, 10, 20)); + SASSERT(!b.empty()); + point * p1 = alloc(point, 30, 20); + b.push_back(p1); + SASSERT(b.get(1) == p1); + b.push_back(alloc(point, 40, 20)); + SASSERT(b.size() == 3); + b.pop_back(); + SASSERT(b.get(0) != p1); + SASSERT(b.get(1) == p1); + point * p2 = alloc(point, 30, 20); + SASSERT(b.get(0) != p2); + b.set(0, p2); + SASSERT(b.get(0) == p2); + SASSERT(b.size() == 2); + b.push_back(alloc(point, 40, 40)); +} + +void tst_buffer() { + tst1(); +} diff --git a/test/buildpar.bat b/test/buildpar.bat new file mode 100644 index 000000000..4e70ec32c --- /dev/null +++ b/test/buildpar.bat @@ -0,0 +1 @@ +cl /I ..\lib /MDd /LD ..\test\par_dll.cpp /link ..\parallel_debug\z3lib.lib /lib ..\parallel_debug\msbig_rational.lib \ No newline at end of file diff --git a/test/bv_simplifier_plugin.cpp b/test/bv_simplifier_plugin.cpp new file mode 100644 index 000000000..9c9a7100b --- /dev/null +++ b/test/bv_simplifier_plugin.cpp @@ -0,0 +1,310 @@ +#include "bv_simplifier_plugin.h" +#include "arith_decl_plugin.h" +#include "ast_pp.h" + +class tst_bv_simplifier_plugin_cls { + ast_manager m_manager; + bv_simplifier_params m_bv_params; + basic_simplifier_plugin m_bsimp; + arith_util m_arith; + bv_simplifier_plugin m_simp; + bv_util m_bv_util; + family_id m_fid; + + void get_num(expr* e, unsigned bv_size, rational& r) { + unsigned bv_size0; + if (!m_bv_util.is_numeral(e, r, bv_size0)) { + UNREACHABLE(); + } + SASSERT(bv_size == bv_size0); + } + + unsigned u32(expr* e) { + rational r; + std::cout << mk_pp(e,m_manager) << "\n"; + get_num(e, 32, r); + return r.get_unsigned(); + } + + unsigned char u8(expr* e) { + rational r; + get_num(e, 8, r); + return static_cast(r.get_unsigned()); + } + int i32(expr* e) { + return static_cast(u32(e)); + } + + uint64 u64(expr* e) { + rational r; + get_num(e, 64, r); + return r.get_uint64(); + } + + int64 i64(expr* e) { + rational r; + get_num(e, 64, r); + if (r >= power(rational(2), 63)) { + r -= power(rational(2), 64); + } + return r.get_int64(); + } + + bool ast2bool(expr* e) { + if (m_manager.is_true(e)) { + return true; + } + if (m_manager.is_false(e)) { + return false; + } + UNREACHABLE(); + return false; + } + + bool bit2bool(expr* e) { + rational r; + get_num(e, 1, r); + return 0 != r.get_unsigned(); + } + + expr* mk_int(unsigned i) { + return m_arith.mk_numeral(rational(i), true); + } + +public: + + tst_bv_simplifier_plugin_cls() : + m_bv_util(m_manager), + m_bsimp(m_manager), + m_arith(m_manager), + m_simp(m_manager, m_bsimp, m_bv_params), + m_fid(m_manager.get_family_id("bv")) { + m_manager.register_decl_plugins(); + } + + ~tst_bv_simplifier_plugin_cls() {} + + void test_num(unsigned a) { + expr_ref e(m_manager), e1(m_manager); + app_ref ar(m_manager); + int sa = static_cast(a); + uint64 a64 = static_cast(a); + + e1 = m_bv_util.mk_numeral(rational(a), 32); + expr* const es[1] = { e1.get() }; + + ar = m_manager.mk_app(m_fid, OP_BNEG, e1.get()); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((0-a) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BNOT, e1.get()); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((~a) == u32(e.get())); + + parameter params[2] = { parameter(32), parameter(32) }; + ar = m_manager.mk_app(m_fid, OP_SIGN_EXT, 1, params, 1, es); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((int64)(int)a) == i64(e.get())); + + ar = m_manager.mk_app(m_fid, OP_ZERO_EXT, 1, params, 1, es); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((uint64)a) == u64(e.get())); + + params[0] = parameter(7); + params[1] = parameter(0); + ar = m_manager.mk_app(m_fid, OP_EXTRACT, 2, params, 1, es); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((unsigned char)a) == u8(e.get())); + + params[0] = parameter(2); + ar = m_manager.mk_app(m_fid, OP_REPEAT, 1, params, 1, es); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((a64 << 32) | a64) == u64(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BREDOR, e1.get()); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a != 0) == bit2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BREDAND, e1.get()); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a == 0xFFFFFFFF) == bit2bool(e.get())); + + params[0] = parameter(8); + + ar = m_manager.mk_app(m_fid, OP_ROTATE_LEFT, 1, params, 1, es); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((a << 8) | (a >> 24)) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_ROTATE_RIGHT, 1, params, 1, es); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((a >> 8) | (a << 24)) == u32(e.get())); + + params[0] = parameter(m_manager.mk_sort(m_manager.get_family_id("arith"), INT_SORT)); + ar = m_manager.mk_app(m_fid, OP_BV2INT, 1, params, 1, es); + expr* es2[1] = { ar.get() }; + params[0] = parameter(32); + ar = m_manager.mk_app(m_fid, OP_INT2BV, 1, params, 1, es2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(a == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BIT0); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(!bit2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BIT1); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(bit2bool(e.get())); + + } + + void test_pair(unsigned a, unsigned b) { + + expr_ref e(m_manager), e1(m_manager), e2(m_manager); + app_ref ar(m_manager); + int sa = static_cast(a); + int sb = static_cast(b); + uint64 a64 = static_cast(a); + uint64 b64 = static_cast(b); + + e1 = m_bv_util.mk_numeral(rational(a), 32); + e2 = m_bv_util.mk_numeral(rational(b), 32); + expr* const e1e2[] = { e1.get(), e2.get() }; + + + ar = m_manager.mk_app(m_fid, OP_BADD, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a + b) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BSUB, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a - b) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BMUL, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a * b) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BAND, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a & b) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BOR, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a | b) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BNOR, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(~(a | b) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BXOR, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a ^ b) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BXNOR, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((~(a ^ b)) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BNAND, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((~(a & b)) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_ULEQ, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a <= b) == ast2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_UGEQ, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a >= b) == ast2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_ULT, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a < b) == ast2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_UGT, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a > b) == ast2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_SLEQ, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((sa <= sb) == ast2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_SGEQ, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((sa >= sb) == ast2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_SLT, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((sa < sb) == ast2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_SGT, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((sa > sb) == ast2bool(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BSHL, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((b>=32)?0:(a << b)) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BLSHR, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((b>=32)?0:(a >> b)) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BASHR, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((sa >> b) == i32(e.get())); + + if (b != 0) { + ar = m_manager.mk_app(m_fid, OP_BSDIV, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((sa / sb) == i32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BUDIV, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a / b) == u32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BSREM, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + //SASSERT((sa % sb) == i32(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BUREM, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a % b) == u32(e.get())); + + // TBD: BSMOD. + } + + ar = m_manager.mk_app(m_fid, OP_CONCAT, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT(((a64 << 32) | b64) == u64(e.get())); + + ar = m_manager.mk_app(m_fid, OP_BCOMP, 2, e1e2); + m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); + SASSERT((a == b) == bit2bool(e.get())); + } + + void test() { + unsigned_vector nums; + nums.push_back(0); + nums.push_back(1); + nums.push_back(-1); + nums.push_back(2); + nums.push_back(31); + nums.push_back(32); + nums.push_back(33); + nums.push_back(435562); + nums.push_back(-43556211); + // TBD add some random numbers. + + + for (unsigned i = 0; i < nums.size(); ++i) { + test_num(nums[i]); + for (unsigned j = 0; j < nums.size(); ++j) { + test_pair(nums[i], nums[j]); + } + } + } +}; + + +void tst_bv_simplifier_plugin() { + tst_bv_simplifier_plugin_cls tst_cls; + tst_cls.test(); +} diff --git a/test/chashtable.cpp b/test/chashtable.cpp new file mode 100644 index 000000000..7d55fe01f --- /dev/null +++ b/test/chashtable.cpp @@ -0,0 +1,183 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + chashtable.cpp + +Abstract: + + Hashtable with chaining. + +Author: + + Leonardo de Moura (leonardo) 2011-04-14. + +Revision History: + +--*/ +#include"chashtable.h" +#include"hashtable.h" +#include"hash.h" +#include"util.h" + +typedef chashtable > int_table; +typedef cmap > int_map; + +template class chashtable >; +template class cmap >; + +template +static void display(T const & beg, T const & end) { + for (T it = beg; it != end; ++it) + std::cout << *it << " "; + std::cout << "\n"; +} + +static void tst1() { + int_table t; + t.insert(10); + SASSERT(t.contains(10)); + t.insert(20); + SASSERT(t.contains(20)); + t.insert(30); + SASSERT(t.contains(30)); + SASSERT(t.size() == 3); + display(t.begin(), t.end()); + t.erase(20); + SASSERT(!t.contains(20)); + SASSERT(t.size() == 2); +} + +struct dummy_hash { + unsigned operator()(int v) const { return v % 2; } +}; + +typedef chashtable > dint_table; + +template class chashtable >; + +static void tst2() { + dint_table t; + t.insert(10); + t.insert(12); + SASSERT(t.used_slots() == 1); + display(t.begin(), t.end()); + t.insert(13); + display(t.begin(), t.end()); + SASSERT(t.used_slots() == 2); + t.insert(14); + SASSERT(t.used_slots() == 2); + SASSERT(t.size() == 4); + display(t.begin(), t.end()); + t.erase(12); + SASSERT(!t.contains(12)); + SASSERT(t.size() == 3); + SASSERT(t.contains(10)); + SASSERT(!t.contains(12)); + SASSERT(t.contains(14)); + SASSERT(t.contains(13)); + t.insert(16); + SASSERT(t.size() == 4); + t.insert(18); + SASSERT(t.size() == 5); + SASSERT(t.used_slots() == 2); + display(t.begin(), t.end()); + t.erase(10); + display(t.begin(), t.end()); + SASSERT(!t.contains(10)); + SASSERT(!t.contains(12)); + SASSERT(t.contains(14)); + SASSERT(t.contains(13)); + SASSERT(t.contains(16)); + SASSERT(t.contains(18)); +} + +static void tst3() { + dint_table t; + t.insert(10); + t.insert(12); + SASSERT(t.used_slots() == 1); + SASSERT(t.contains(10)); + SASSERT(t.contains(12)); + t.erase(12); + t.erase(10); + SASSERT(t.size() == 0); + SASSERT(t.empty()); + SASSERT(t.used_slots() == 0); + t.insert(10); + SASSERT(t.used_slots() == 1); + SASSERT(t.contains(10)); + SASSERT(t.size() == 1); +} + +typedef int_hashtable > int_set; + +template +static void tst4(unsigned num, unsigned N) { + int_set s; + T t; + for (unsigned i = 0; i < num; i++) { + int v = rand() % N; + if (rand() % 3 == 2) { + TRACE("chashtable", tout << "erase " << v << "\n";); + s.erase(v); + t.erase(v); + SASSERT(!t.contains(v)); + } + else { + TRACE("chashtable", tout << "insert " << v << "\n";); + s.insert(v); + t.insert(v); + SASSERT(t.contains(v)); + } + SASSERT(s.size() == t.size()); + SASSERT(s.empty() == t.empty()); + } + std::cout << "size: " << s.size() << " " << t.size() << "\n"; + int_set::iterator it1 = s.begin(); + int_set::iterator end1 = s.end(); + for(; it1 != end1; ++it1) { + SASSERT(t.contains(*it1)); + } + + typename T::iterator it2 = t.begin(); + typename T::iterator end2 = t.end(); + for(; it2 != end2; ++it2) { + SASSERT(s.contains(*it2)); + SASSERT(t.contains(*it2)); + } +} + +static void tst5() { + dint_table t; + t.insert(4); + t.insert(9); + t.insert(8); + t.insert(1); + t.erase(1); + t.insert(7); + t.insert(1); + t.insert(2); +} + +static void tst6() { + int_map m; + m.insert(10, 4); + SASSERT(m.contains(10)); + DEBUG_CODE({ + int r; + SASSERT(m.find(10, r) && r == 4); + }); +} + +void tst_chashtable() { + tst1(); + tst2(); + tst3(); + tst6(); + tst4(1000,10); + tst4(10000,10); + tst4(50000,1000); + tst5(); +} diff --git a/test/check_assumptions.cpp b/test/check_assumptions.cpp new file mode 100644 index 000000000..dce982345 --- /dev/null +++ b/test/check_assumptions.cpp @@ -0,0 +1,43 @@ +#include "memory_manager.h" +#include "front_end_params.h" +#include "ast.h" +#include "arith_decl_plugin.h" +#include "bv_decl_plugin.h" +#include "smt_context.h" + +void tst_check_assumptions() +{ + memory::initialize(0); + front_end_params params; + ast_manager mgr; + mgr.register_decl_plugins(); + + sort_ref b(mgr.mk_bool_sort(), mgr); + func_decl_ref pPred(mgr.mk_func_decl(symbol("p"), 0, static_cast(0), b), mgr); + func_decl_ref qPred(mgr.mk_func_decl(symbol("q"), 0, static_cast(0), b), mgr); + func_decl_ref rPred(mgr.mk_func_decl(symbol("r"), 0, static_cast(0), b), mgr); + + app_ref p(mgr.mk_app(pPred,0,static_cast(0)), mgr); + app_ref q(mgr.mk_app(qPred,0,static_cast(0)), mgr); + app_ref r(mgr.mk_app(rPred,0,static_cast(0)), mgr); + app_ref pOqOr(mgr.mk_or(p,q,r), mgr); + + app_ref np(mgr.mk_not(p), mgr); + app_ref nq(mgr.mk_not(q), mgr); + app_ref nr(mgr.mk_not(r), mgr); + + smt::context ctx(mgr, params); + ctx.assert_expr(pOqOr); + + expr * npE = np.get(); + lbool res1 = ctx.check(1, &npE); + SASSERT(res1==l_true); + + ctx.assert_expr(npE); + + + expr * assumpt[] = { nq.get(), nr.get() }; + //here it should crash + lbool res2 = ctx.check(2, assumpt); +} + diff --git a/test/core_theory.cpp b/test/core_theory.cpp new file mode 100644 index 000000000..cd46951cb --- /dev/null +++ b/test/core_theory.cpp @@ -0,0 +1,821 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + core_theory.cpp + +Abstract: + + Test core theory + +Author: + + Leonardo de Moura (leonardo) 2006-10-20. + +Revision History: + +--*/ +#include"core_theory.h" +#include"theory_diff_logic.h" + +class core_theory_tester { + static void tst1() { + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + enode * n1 = t.mk_const(); + SASSERT(n1->check_invariant()); + enode * n2 = t.mk_const(); + SASSERT(n2->check_invariant()); + enode * app1 = t.mk_app_core(1, n1, n2); + enode * app2 = t.mk_app_core(1, n2, n2); + enode * app3 = t.mk_app_core(1, n1, n2); + SASSERT(app1 != app2); + SASSERT(app1 == app3); + + literal l1 = t.mk_eq(n1, n2); + literal l2 = t.mk_eq(n2, n1); + literal l4 = t.mk_eq(n2, app1); + SASSERT(l1 == l2); + SASSERT(l1 != l4); + + SASSERT(n1->get_root() != n2->get_root()); + + t.assert_lit(l1); + t.assert_lit(l4); + t.propagate(); + + SASSERT(n1->get_root() == n2->get_root()); + TRACE("core_theory", t.display(tout);); + } + + static void tst2() { + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + enode * a1 = t.mk_app_core(1, n1, n2); + + literal l1 = t.mk_eq(n1, n2); + t.assert_lit(l1); + t.propagate(); + + t.push_scope(); + + literal l2 = t.mk_eq(n1, n3); + t.assign(l2, mk_axiom()); + + enode * a2 = t.mk_app_core(1, n1, n1); + enode * a3 = t.mk_app_core(1, n1, n3); + + TRACE("core_theory", t.display(tout);); + + t.propagate(); + SASSERT(t.is_equal(a1, a2)); + SASSERT(!t.is_equal(a1, a3)); + t.m_sat->mark_as_relevant(l2.var()); + t.propagate(); + SASSERT(t.is_equal(a1, a2)); + SASSERT(t.is_equal(a1, a3)); + + t.pop_scope(1); + + t.propagate(); + SASSERT(to_app(a1)->get_cg() == a1); + TRACE("core_theory", t.display(tout);); + } + + static void tst3() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + enode * a1 = t.mk_app_core(1, n1, n2); + + literal l1 = t.mk_eq(n1, n2); + t.assert_lit(l1); + t.propagate(); + + t.push_scope(); + + literal l2 = t.mk_eq(n1, n3); + t.assign(l2, mk_axiom()); + + enode * a2 = t.mk_app_core(1, n1, n1); + enode * a3 = t.mk_app_core(1, n1, n3); + + TRACE("core_theory", t.display(tout);); + + t.propagate(); + SASSERT(t.is_equal(a1, a2)); + SASSERT(t.is_equal(a1, a3)); + + t.pop_scope(1); + + t.propagate(); + SASSERT(to_app(a1)->get_cg() == a1); + TRACE("core_theory", t.display(tout);); + } + + static void tst8() { + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_const(); + enode * n5 = t.mk_const(); + enode * n6 = t.mk_const(); + + t.push_scope(); + + t.assert_lit(~t.mk_eq(n1, n2)); + t.assert_lit(t.mk_eq(n1, n3)); + t.assert_lit(t.mk_eq(n2, n4)); + t.assert_lit(t.mk_eq(n3, n6)); + t.assert_lit(t.mk_eq(n1, n5)); + t.propagate(); + + SASSERT(!t.inconsistent()); + + t.assert_lit(t.mk_eq(n3, n4)); + TRACE("core_theory", t.display(tout);); + t.propagate(); + + SASSERT(t.inconsistent()); + + t.pop_scope(1); + } + + static void tst9() { + TRACE("core_theory", tout << "tst9\n";); + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + t.push_scope(); + enode * n = t.mk_const(); + unsigned id = n->get_id(); + t.pop_scope(1); + TRACE("core_theory", tout << "after pop\n";); + n = t.mk_const(); + SASSERT(id == n->get_id()); + TRACE("core_theory", tout << "end of tst9\n";); + } + + static void tst10() { + TRACE("core_theory", tout << "tst10\n";); + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + t.push_scope(); + enode * n = t.mk_const(); + unsigned id = n->get_id(); + t.inc_weak_ref(id); + t.pop_scope(1); + TRACE("core_theory", tout << "after pop\n";); + n = t.mk_const(); + SASSERT(id + 1 == n->get_id()); + t.dec_weak_ref(id); + n = t.mk_const(); + SASSERT(id = n->get_id()); + TRACE("core_theory", tout << "end of tst10\n";); + } + + static void tst11() { + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + t.add_eq(n1, n2, proto_eq_proof::mk_axiom()); + enode * f1 = t.mk_app_core(1, n1); + enode * f2 = t.mk_app_core(1, n2); + t.propagate(); + SASSERT(t.is_equal(f1, f2)); + t.push_scope(); + literal l1 = t.mk_lit(); + literal l2 = t.mk_eq(f1, f2); + t.mk_main_clause(l1, l2); + SASSERT(t.get_assignment(l2) == l_true); + t.pop_scope(1); + SASSERT(t.get_assignment(l2) == l_true); + } + + static void tst12() { + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + t.add_diseq(n1, n2, proto_diseq_proof::mk_axiom()); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_const(); + t.add_eq(n1, n3, proto_eq_proof::mk_axiom()); + t.add_eq(n2, n4, proto_eq_proof::mk_axiom()); + t.propagate(); + SASSERT(t.is_diseq(n3, n4)); + t.push_scope(); + literal l1 = t.mk_lit(); + literal l2 = t.mk_eq(n3, n4); + t.mk_main_clause(l1, l2); + SASSERT(t.get_assignment(l2) == l_false); + t.pop_scope(1); + SASSERT(t.get_assignment(l2) == l_false); + } + + static void tst13() { + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_app_core(1, n1); + enode * n5 = t.mk_app_core(1, n4); + enode * n6 = t.mk_app_core(1, n3); + enode * n7 = t.mk_app_core(1, n6); + + SASSERT(!t.is_relevant(n1)); + SASSERT(!t.is_relevant(n2)); + SASSERT(!t.is_relevant(n3)); + SASSERT(!t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(!t.is_relevant(n6)); + SASSERT(!t.is_relevant(n7)); + + t.add_eq(n6, n1, proto_eq_proof::mk_axiom()); + + SASSERT(!t.is_relevant(n1)); + SASSERT(!t.is_relevant(n2)); + SASSERT(!t.is_relevant(n3)); + SASSERT(!t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(!t.is_relevant(n6)); + SASSERT(!t.is_relevant(n7)); + + t.push_scope(); + + t.assert_lit(t.mk_eq(n7,n2)); + t.propagate(); + SASSERT(t.is_equal(n7, n2)); + + SASSERT(t.is_relevant(n1)); + SASSERT(t.is_relevant(n2)); + SASSERT(t.is_relevant(n3)); + SASSERT(t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(t.is_relevant(n6)); + SASSERT(t.is_relevant(n7)); + + t.pop_scope(1); + + SASSERT(!t.is_relevant(n1)); + SASSERT(!t.is_relevant(n2)); + SASSERT(!t.is_relevant(n3)); + SASSERT(!t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(!t.is_relevant(n6)); + SASSERT(!t.is_relevant(n7)); + } + + static void tst14() { + core_theory t; + t.m_params.m_relevancy_lvl = 2; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_app_core(1, n1); + enode * n5 = t.mk_app_core(1, n4); + enode * n6 = t.mk_app_core(1, n3); + enode * n7 = t.mk_app_core(1, n6); + + t.assert_lit(t.mk_eq(n1,n2)); + t.propagate(); + + SASSERT(t.is_relevant(n1)); + SASSERT(t.is_relevant(n2)); + SASSERT(!t.is_relevant(n3)); + SASSERT(!t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(!t.is_relevant(n6)); + SASSERT(!t.is_relevant(n7)); + + t.push_scope(); + t.assign_eq(n2, n3, proto_eq_proof::mk_axiom()); + t.propagate(); + + SASSERT(t.is_relevant(n1)); + SASSERT(t.is_relevant(n2)); + SASSERT(t.is_relevant(n3)); + SASSERT(!t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(!t.is_relevant(n6)); + SASSERT(!t.is_relevant(n7)); + + t.pop_scope(1); + + SASSERT(t.is_relevant(n1)); + SASSERT(t.is_relevant(n2)); + SASSERT(!t.is_relevant(n3)); + SASSERT(!t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(!t.is_relevant(n6)); + SASSERT(!t.is_relevant(n7)); + + t.push_scope(); + t.assign_eq(n2, n7, proto_eq_proof::mk_axiom()); + t.propagate(); + + SASSERT(t.is_relevant(n1)); + SASSERT(t.is_relevant(n2)); + SASSERT(t.is_relevant(n3)); + SASSERT(!t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(t.is_relevant(n6)); + SASSERT(t.is_relevant(n7)); + + t.pop_scope(1); + + SASSERT(t.is_relevant(n1)); + SASSERT(t.is_relevant(n2)); + SASSERT(!t.is_relevant(n3)); + SASSERT(!t.is_relevant(n4)); + SASSERT(!t.is_relevant(n5)); + SASSERT(!t.is_relevant(n6)); + SASSERT(!t.is_relevant(n7)); + } + + static void tst15() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + literal l1 = t.mk_lit(); + literal l2 = t.mk_lit(); + literal l3 = t.mk_lit(); + literal l4 = t.mk_lit(); + + t.push_scope(); + t.assign(l1, mk_axiom()); + t.push_scope(); + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * a1 = t.mk_app_core(1, n1); + enode * a2 = t.mk_app_core(1, n2); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_const(); + + literal eq1 = t.mk_eq(a1, n3); + t.assign(eq1, mk_axiom()); + + t.push_scope(); + literal eq2 = t.mk_eq(a2, n4); + t.assign(eq2, mk_axiom()); + + TRACE("core_theory", tout << "eq1: " << eq1 << ", eq2: " << eq2 << "\n";); + + t.mk_transient_clause(~eq2, l3); + t.mk_transient_clause(~eq2, l4); + t.mk_transient_clause(~eq1, l2); + literal_vector lits; + lits.push_back(~l4); lits.push_back(~l3); lits.push_back(~l2); lits.push_back(~l1); + t.mk_transient_clause(lits); + SASSERT(t.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + t.m_sat->resolve_conflict(); + SASSERT(r); + SASSERT(t.m_sat->m_scope_lvl == 2); + SASSERT(t.m_sat->m_ref_count[eq1.var()] > 0); + SASSERT(t.m_sat->m_ref_count[eq2.var()] > 0); + t.pop_scope(2); + SASSERT(n1->get_ref_count() > 0); + SASSERT(n2->get_ref_count() > 0); + SASSERT(a1->get_ref_count() > 0); + SASSERT(a2->get_ref_count() > 0); + t.push_scope(); + literal eq3 = t.mk_eq(n1, n2); + t.assign(eq3, mk_axiom()); + t.propagate(); + TRACE("core_theory", t.display(tout);); + SASSERT(a1->get_root() == a2->get_root()); +#ifdef Z3DEBUG + t.m_sat->del_learned_clauses(); +#endif + t.pop_scope(1); + } + + static void tst16(bool use_relevancy) { + core_theory t; + t.m_params.m_relevancy_lvl = use_relevancy ? 2 : 0; + + literal l0 = t.mk_lit(); + literal l1 = t.mk_lit(); + literal l2 = t.mk_lit(); + literal l3 = t.mk_lit(); + literal l4 = t.mk_lit(); + + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_app_core(1, n1); + + t.push_scope(); + t.assign(l0, mk_axiom()); + + t.push_scope(); + t.assign(l1, mk_axiom()); + + t.push_scope(); + enode * n5 = t.mk_app_core(1, n2); + enode * n6 = t.mk_const(); + literal eq1 = t.mk_eq(n5, n6); + t.assign(eq1, mk_axiom()); + t.mk_transient_clause(~l1, l2); + t.mk_transient_clause(~eq1, l3); + t.mk_transient_clause(~eq1, l4); + literal_vector lits; + lits.push_back(~l4); lits.push_back(~l3); lits.push_back(~l2); + t.mk_transient_clause(lits); + SASSERT(t.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + t.m_sat->resolve_conflict(); + SASSERT(r); + t.propagate(); + SASSERT(t.m_sat->m_scope_lvl == 2); + SASSERT(t.m_sat->m_ref_count[eq1.var()] > 0); + SASSERT(t.m_sat->get_assignment(eq1) == l_false); + + t.pop_scope(1); + SASSERT(t.m_sat->m_scope_lvl == 1); + SASSERT(t.m_sat->m_ref_count[eq1.var()] > 0); + SASSERT(t.m_sat->get_assignment(eq1) == l_undef); + + t.push_scope(); + SASSERT(n5->get_ref_count() == 1); + t.add_eq(n1, n2, proto_eq_proof::mk_axiom()); + SASSERT(to_app(n4)->get_cg() == n5); + if (use_relevancy) { + t.mark_as_relevant(n5); + } + SASSERT(!use_relevancy || n5->get_ref_count() == 3); + SASSERT(use_relevancy || n5->get_ref_count() == 2); + SASSERT(n5->get_root() != n4->get_root()); + SASSERT(!use_relevancy || t.is_relevant(n5)); + t.propagate(); + SASSERT(n5->get_root() == n4->get_root()); + SASSERT(!use_relevancy || n5->get_ref_count() == 4); + SASSERT(use_relevancy || n5->get_ref_count() == 3); +#ifdef Z3DEBUG + t.m_sat->del_learned_clauses(); +#endif + SASSERT(!use_relevancy || n5->get_ref_count() == 3); + SASSERT(use_relevancy || n5->get_ref_count() == 2); + + SASSERT(t.m_sat->m_ref_count[eq1.var()] == 0); + + t.pop_scope(1); + } + + static void tst17() { + theory_idl idl; + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + t.add_theory(&idl); + + literal l0 = t.mk_lit(); + literal l1 = t.mk_lit(); + literal l2 = t.mk_lit(); + literal l3 = t.mk_lit(); + literal l4 = t.mk_lit(); + enode * n1 = t.mk_const(); + + t.push_scope(); + t.assign(l0, mk_axiom()); + + t.push_scope(); + t.assign(l1, mk_axiom()); + + t.push_scope(); + enode * n2 = idl.mk_offset(n1, rational(1)); + enode * n3 = t.mk_const(); + literal eq1 = t.mk_eq(n2, n3); + t.assign(eq1, mk_axiom()); + t.mk_transient_clause(~l1, l2); + t.mk_transient_clause(~eq1, l3); + t.mk_transient_clause(~eq1, l4); + literal_vector lits; + lits.push_back(~l4); lits.push_back(~l3); lits.push_back(~l2); + t.mk_transient_clause(lits); + SASSERT(t.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + t.m_sat->resolve_conflict(); + SASSERT(r); + t.propagate(); + SASSERT(t.m_sat->m_scope_lvl == 2); + SASSERT(t.m_sat->m_ref_count[eq1.var()] > 0); + SASSERT(t.m_sat->get_assignment(eq1) == l_false); + + t.pop_scope(1); + SASSERT(t.m_sat->m_scope_lvl == 1); + SASSERT(t.m_sat->m_ref_count[eq1.var()] > 0); + SASSERT(t.m_sat->get_assignment(eq1) == l_undef); + SASSERT(n2->get_ref_count() == 1); + unsigned n2_id = n2->get_id(); + + // n2 is still alive +#ifdef Z3DEBUG + t.m_sat->del_learned_clauses(); +#endif + // n2 is dead + SASSERT(t.m_enodes[n2_id] == 0); + // n2_id cannot be reused since its weak_counter > 0 + // SASSERT(t.m_weak_counters[n2_id] > 0); + + enode * n4 = idl.mk_offset(n1, rational(1)); + SASSERT(n4->get_id() != n2_id); + SASSERT(n4->get_id() < static_cast(t.m_next_id)); + } + + static void tst18() { + core_theory t; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + enode * a1 = t.mk_app_core(1, n1, n2); + + literal l1 = t.mk_eq(n1, n3); + t.assert_lit(l1); + t.propagate(); + + enode * args[2] = { n3, n2 }; + + SASSERT(t.get_enode_eq_to_app(1, 2, args) != 0); + SASSERT(a1->get_root() == t.get_enode_eq_to_app(1, 2, args)->get_root()); + } + + static void tst19() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + literal l1 = t.mk_eq(n1, n2); + literal l2 = t.mk_eq(n2, n3); + literal l3 = t.mk_eq(n1, n3); + + enode * n4 = t.mk_const(); + enode * n5 = t.mk_const(); + enode * n6 = t.mk_const(); + enode * n7 = t.mk_const(); + + literal l4 = t.mk_eq(n4, n5); + literal l5 = t.mk_eq(n6, n7); + literal l6 = t.mk_eq(n5, n7); + literal l7 = t.mk_eq(n4, n6); + + t.mk_main_clause(l3, l7); + + t.push_scope(); + t.assign(l1, mk_axiom()); + t.assign(~l2, mk_axiom()); + t.assign(l4, mk_axiom()); + t.assign(l5, mk_axiom()); + t.assign(~l6, mk_axiom()); + t.propagate(); + SASSERT(t.inconsistent()); + t.m_sat->resolve_conflict(); + } + + static void tst20() { + theory_idl idl; + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + t.add_theory(&idl); + + enode * n1 = t.mk_const(); + enode * n2 = idl.mk_offset(n1, rational(1)); + enode * n3 = idl.mk_offset(n2, rational(1)); + enode * n4 = idl.mk_offset(n1, rational(2)); + SASSERT(n4 == n3); + + enode * r1 = idl.mk_num(rational(1)); + enode * r2 = idl.mk_offset(r1, rational(1)); + enode * r3 = idl.mk_num(rational(2)); + SASSERT(r2 == r3); + } + + static void tst21() { + enable_debug("add_eq"); + enable_debug("core_invariant"); + theory_idl idl; + core_theory t; + t.m_params.m_relevancy_lvl = 0; + t.add_theory(&idl); + theory_id idl_id = idl.get_id(); + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_const(); + enode * n5 = t.mk_const(); + literal l1 = t.mk_eq(n1, n2); + literal l2 = t.mk_eq(n1, n3); + literal l3 = t.mk_eq(n4, n5); + literal l4 = t.mk_eq(n4, n3); + + t.push_scope(); + t.assign(l1, mk_axiom()); + t.propagate(); + SASSERT(n2->get_root() == n2); + t.push_scope(); + t.assign(l2, mk_axiom()); + t.propagate(); + t.push_scope(); + t.assign(l3, mk_axiom()); + t.propagate(); + SASSERT(n5->get_root() == n5); + SASSERT(n4->get_root() == n5); + t.push_scope(); + t.assign(l4, mk_axiom()); + t.propagate(); + SASSERT(n2->get_root() == n2); + enode * o1 = idl.mk_offset(n4, rational(1)); + SASSERT(n4->get_th_var(idl_id) != null_theory_var); + SASSERT(n2->get_th_var(idl_id) == n4->get_th_var(idl_id)); + t.pop_scope(1); + SASSERT(n4->get_th_var(idl_id) != null_theory_var); + SASSERT(n5->get_th_var(idl_id) == n4->get_th_var(idl_id)); + SASSERT(n2->get_th_var(idl_id) == null_theory_var); + t.pop_scope(1); + SASSERT(n4->get_th_var(idl.get_id()) != null_theory_var); + SASSERT(n5->get_th_var(idl_id) == null_theory_var); + SASSERT(n2->get_th_var(idl_id) == null_theory_var); + } + + static void tst22() { + enable_debug("add_eq"); + enable_debug("core_invariant"); + theory_idl idl; + core_theory t; + t.m_params.m_relevancy_lvl = 0; + t.add_theory(&idl); + theory_id idl_id = idl.get_id(); + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_const(); + enode * n5 = t.mk_const(); + enode * o1 = idl.mk_offset(n2, rational(1)); + literal l1 = t.mk_eq(n1, n2); + literal l2 = t.mk_eq(n1, n3); + literal l3 = t.mk_eq(n4, n5); + literal l4 = t.mk_eq(n4, n3); + + t.push_scope(); + t.assign(l1, mk_axiom()); + t.propagate(); + SASSERT(n2->get_root() == n2); + + t.push_scope(); + t.assign(l2, mk_axiom()); + t.propagate(); + + t.push_scope(); + t.assign(l3, mk_axiom()); + t.propagate(); + SASSERT(n5->get_root() == n5); + SASSERT(n4->get_root() == n5); + + t.push_scope(); + t.assign(l4, mk_axiom()); + t.propagate(); + SASSERT(n2->get_root() == n2); + enode * o2 = idl.mk_offset(n4, rational(1)); + SASSERT(n4->get_th_var(idl_id) != null_theory_var); + SASSERT(n2->get_th_var(idl_id) != null_theory_var); + SASSERT(n2->get_th_var(idl_id) != n4->get_th_var(idl_id)); + + t.pop_scope(1); + SASSERT(n2->get_th_var(idl_id) != null_theory_var); + SASSERT(n4->get_th_var(idl_id) != null_theory_var); + SASSERT(n4->get_th_var(idl_id) == n5->get_th_var(idl_id)); + + t.pop_scope(1); + SASSERT(n2->get_th_var(idl_id) != null_theory_var); + SASSERT(n4->get_th_var(idl_id) != null_theory_var); + SASSERT(n5->get_th_var(idl_id) == null_theory_var); + } + + static void tst23() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + enable_trace("th_diseq_prop_bug"); + enable_trace("add_eq"); + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_true_term(); + enode * d[2] = {n1, n2}; + t.assert_distinct_class(2, d); + enode * n3 = t.mk_const(); + enode * n4 = t.mk_const(); + + literal l1 = t.mk_eq(n3, n4); + literal l2 = t.mk_eq(n4, n1); + literal l3 = t.mk_eq(n3, n2); + t.push_scope(); + t.assign(l1, mk_axiom()); + t.propagate(); + SASSERT(n3->get_root() == n4->get_root()); + t.push_scope(); + t.assign(l2, mk_axiom()); + t.propagate(); + SASSERT(n3->get_root() == n1->get_root()); + SASSERT(t.is_diseq(n3, n2)); + SASSERT(t.get_assignment(l3) == l_false); + SASSERT(t.m_sat->m_explanation[l3.var()].kind() == EXPL_EXT); + literal_vector antecedents; + t.get_antecedents(~l3, t.m_sat->m_explanation[l3.var()].obj(), antecedents); + } + +public: + static void run_tests() { + tst1(); + tst2(); + tst3(); + tst8(); + tst9(); + tst10(); + tst11(); + tst12(); + tst13(); + tst14(); + tst15(); + tst16(false); + tst16(true); + tst17(); + tst18(); + tst19(); + tst20(); + tst21(); + tst22(); + tst23(); + } +}; + +struct foo { + bool_var m_var; // boolean variable associated with the equation + enode * m_lhs; + enode * m_rhs; +}; + +struct bar { + bool m_v1:1; + bool m_v2:1; + bool m_v3:1; + bool m_v4:1; + bool m_v5:1; + bool m_v6:1; + bool m_v7:1; + bool m_v8:1; +}; + +struct bar2 { + bool m_v1:1; + bool m_v2:1; + unsigned m_val:30; +}; + +void tst_core_theory() { + TRACE("core_theory", tout << "sizeof(equation): " << sizeof(equation) << "\n";); + TRACE("core_theory", tout << "sizeof(foo): " << sizeof(foo) << "\n";); + TRACE("core_theory", tout << "sizeof(bar): " << sizeof(bar) << "\n";); + TRACE("core_theory", tout << "sizeof(bar2): " << sizeof(bar2) << "\n";); + TRACE("core_theory", tout << "sizeof(theory_var_list): " << sizeof(theory_var_list) << "\n";); + TRACE("core_theory", tout << "sizeof(enode): " << sizeof(enode) << "\n";); + enable_debug("cg_bug"); + core_theory_tester::run_tests(); +} + diff --git a/test/datalog_parser.cpp b/test/datalog_parser.cpp new file mode 100644 index 000000000..489808aba --- /dev/null +++ b/test/datalog_parser.cpp @@ -0,0 +1,80 @@ +#include "datalog_parser.h" +#include "ast_pp.h" +#include "arith_decl_plugin.h" +#include "dl_context.h" +#include "front_end_params.h" + +using namespace datalog; + + +static void dparse_string(char const* str) { + ast_manager m; + front_end_params params; + m.register_decl_plugins(); + + context ctx(m, params); + parser* p = parser::create(ctx,m); + + bool res=p->parse_string(str); + + if (!res) { + std::cout << "Parser did not succeed on string\n"<get_num_rules(); + for (unsigned j = 0; j < num_rules; ++j) { + rule* r = p->get_rules()[j]; + std::cout << mk_pp(r->head(), m) << "\n"; + for (unsigned i = 0; i < r->size(); ++i) { + std::cout << "body: " << mk_pp((*r)[i], m) << "\n"; + } + } +#endif + dealloc(p); +} + +static void dparse_file(char const* file) { + ast_manager m; + front_end_params params; + m.register_decl_plugins(); + + context ctx(m, params); + parser* p = parser::create(ctx,m); + + if (!p->parse_file(file)) { + std::cout << "Failed to parse file\n"; + } +#if 0 + unsigned num_rules = p->get_num_rules(); + for (unsigned j = 0; j < num_rules; ++j) { + rule* r = p->get_rules()[j]; + std::cout << mk_pp(r->head(), m) << "\n"; + for (unsigned i = 0; i < r->size(); ++i) { + std::cout << "body: " << mk_pp((*r)[i], m) << "\n"; + } + } +#endif + dealloc(p); +} + + + +void tst_datalog_parser() { + dparse_string("\nH :- C1(X,a,b), C2(Y,a,X) ."); + dparse_string("N 128\n\nH :- C1(X,a,b), C2(Y,a,X) ."); + dparse_string("N 128\nI 128\n\nC1(x : N, y : N, z : I)\nC2(x : N, y : N, z : N)\nH :- C1(X,a,b), C2(Y,a,X) ."); + dparse_string("\nH :- C1(X,a,b), nC2(Y,a,X) ."); + dparse_string("\nH :- C1(X,a,b),nC2(Y,a,X)."); + dparse_string("\nH :- C1(X,a,b),\\\nC2(Y,a,X)."); + dparse_string("\nH :- C1(X,a\\,\\b), C2(Y,a,X) ."); +} + +void tst_datalog_parser_file(char** argv, int argc, int & i) { + if (i + 1 < argc) { + dparse_file(argv[i+1]); + i++; + } +} + + diff --git a/test/diff_logic.cpp b/test/diff_logic.cpp new file mode 100644 index 000000000..f577ebfd6 --- /dev/null +++ b/test/diff_logic.cpp @@ -0,0 +1,174 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + diff_logic.cpp + +Abstract: + + Unit tests for difference logic + +Author: + + Leonardo de Moura (leonardo) 2006-11-22. + +Revision History: + +--*/ +#ifdef _WINDOWS +#include"rational.h" +#include"diff_logic.h" +#include"smt_literal.h" +#include"util.h" +#include"debug.h" + +struct diff_logic_ext { + typedef rational numeral; + typedef smt::literal explanation; +}; + +template class dl_graph; + +typedef dl_graph dlg; + +struct tst_dl_functor { + smt::literal_vector m_literals; + void operator()(smt::literal l) { + m_literals.push_back(l); + } +}; + +static void tst1() { + dlg g; + smt::literal l; + g.init_var(1); + g.init_var(2); + g.init_var(3); + g.enable_edge(g.add_edge(1, 2, rational(1), l)); + g.enable_edge(g.add_edge(2, 3, rational(2), l)); + g.push(); + g.enable_edge(g.add_edge(1, 3, rational(4), l)); + g.init_var(4); + g.enable_edge(g.add_edge(1, 4, rational(5), l)); + g.enable_edge(g.add_edge(4, 2, rational(0), l)); + g.pop(1); +} + +static void tst2() { + dlg g; + rational w; + smt::literal l1(1); + smt::literal l2(2); + smt::literal l3(3); + smt::literal l4(4); + smt::literal l5(5); + smt::literal l6(6); + g.init_var(0); + g.init_var(1); + g.init_var(2); + g.init_var(3); + g.init_var(4); + smt::literal d; + SASSERT(g.enable_edge(g.add_edge(1, 2, rational(-1), l1))); + SASSERT(g.get_edge_weight(1, 2, w, d) && w == rational(-1)); + SASSERT(!g.get_edge_weight(2, 3, w, d)); + SASSERT(g.enable_edge(g.add_edge(2, 3, rational(-2), l2))); + SASSERT(g.enable_edge(g.add_edge(1, 4, rational(1), l3))); + SASSERT(g.get_edge_weight(1, 2, w, d) && w == rational(-1)); + SASSERT(g.get_edge_weight(1, 4, w, d) && w == rational(1)); + SASSERT(!g.get_edge_weight(1, 3, w, d)); + SASSERT(g.enable_edge(g.add_edge(2, 4, rational(10), l6))); + SASSERT(g.is_feasible()); + g.push(); + SASSERT(g.enable_edge(g.add_edge(3, 0, rational(2), l4))); + SASSERT(!g.enable_edge(g.add_edge(0, 1, rational(-1), l5))); + SASSERT(!g.is_feasible()); + TRACE("diff_logic", g.display(tout);); + struct proc { + svector found; + proc(): + found(7, false) { + } + void operator()(smt::literal l) { + found[l.var()] = true; + } + }; + proc p; + g.traverse_neg_cycle(true, p); + SASSERT(p.found[0] == false); + SASSERT(p.found[1] == true); + SASSERT(p.found[2] == true); + SASSERT(p.found[3] == false); + SASSERT(p.found[4] == true); + SASSERT(p.found[5] == true); + SASSERT(p.found[6] == false); + g.pop(1); + SASSERT(g.is_feasible()); + TRACE("diff_logic", g.display(tout);); +} + +static int add_edge(dlg& g, dl_var src, dl_var dst, int weight, unsigned lit) { + int id = g.add_edge(src, dst, rational(weight), smt::literal(lit)); + bool ok = g.enable_edge(id); + SASSERT(ok); + return id; +} + +static void tst3() { + dlg g; + for (unsigned i = 1; i <= 10; ++i) { + g.init_var(i); + } + add_edge(g, 1, 2, 1, 12); + add_edge(g, 1, 3, 1, 13); + add_edge(g, 1, 4, 1, 14); + add_edge(g, 2, 5, 1, 25); + add_edge(g, 2, 6, 1, 26); + add_edge(g, 3, 5, 1, 35); + add_edge(g, 4, 5, 1, 45); + add_edge(g, 4, 6, 1, 46); + int xy = add_edge(g, 5, 6, 1, 56); + add_edge(g, 5, 7, 1, 57); + add_edge(g, 5, 9, 1, 59); + add_edge(g, 6, 7, 1, 67); + add_edge(g, 6, 8, 1, 68); + add_edge(g, 6, 9, 1, 69); + add_edge(g, 6, 10, 1, 610); + add_edge(g, 8, 10, 1, 810); + add_edge(g, 9, 10, 1, 910); + TRACE("diff_logic", g.display(tout);); + + int e38 = g.add_edge(3, 8, rational(3), smt::literal(38)); + std::cout << "Edge: " << e38 << "\n"; + + svector subsumed; + g.find_subsumed(xy, subsumed); + + for (unsigned i = 0; i < subsumed.size(); ++i) { + std::cout << "subsumed: " << subsumed[i] << "\n"; + SASSERT(e38 == subsumed[i]); + + tst_dl_functor tst_fn; + + g.explain_subsumed_lazy(xy, subsumed[i], tst_fn); + + for (unsigned j = 0; j < tst_fn.m_literals.size(); ++j) { + std::cout << tst_fn.m_literals[j] << " "; + } + std::cout << "\n"; + + } + + +} + +void tst_diff_logic() { + tst1(); + tst2(); + tst3(); +} +#else +void tst_diff_logic() { +} +#endif diff --git a/test/dimacs.cpp b/test/dimacs.cpp new file mode 100644 index 000000000..ca857be0e --- /dev/null +++ b/test/dimacs.cpp @@ -0,0 +1,75 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_dimacs.cpp + +Abstract: + + Test dimacs parser + +Author: + + Leonardo de Moura (leonardo) 2006-10-02. + +Revision History: + +--*/ + +#include +#include +#ifdef _WINDOWS +#include +#include +#endif +#include"trace.h" +#include"dimacs_parser.h" + +class dummy_sat { + unsigned m_num_vars; +public: + dummy_sat():m_num_vars(0) {} + unsigned get_num_vars() { + return m_num_vars; + } + void mk_var() { + TRACE("dimacs", tout << "making variable: p" << m_num_vars << "\n";); + m_num_vars++; + } + void mk_clause(literal_vector & lits) { + TRACE("dimacs", tout << "making clause: " << lits << "\n";); + } +}; + +static void tst1() +{ +#ifdef _WINDOWS + dummy_sat solver; + const char * base = "."; + std::string pattern(base); + pattern += "\\*.cnf"; + + char buffer[MAX_PATH]; + + WIN32_FIND_DATAA data; + HANDLE h = FindFirstFileA(pattern.c_str(),&data); + + while (h != INVALID_HANDLE_VALUE) { + StringCchPrintfA(buffer, ARRAYSIZE(buffer), "%s\\%s", base, data.cFileName); + + TRACE("dimacs", tout << "Parsing: " << buffer << "\n";); + + std::ifstream s(buffer); + + parse_dimacs(s, solver); + + if (!FindNextFileA(h,&data)) + break; + } +#endif +} + +void tst_dimacs() { + tst1(); +} diff --git a/test/distinct.cpp b/test/distinct.cpp new file mode 100644 index 000000000..e1595c37d --- /dev/null +++ b/test/distinct.cpp @@ -0,0 +1,296 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + distinct.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2006-11-03. + +Revision History: + +--*/ +#include"core_theory.h" + +class distinct_tester { + static void tst1() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + enode * d[3] = {n1, n2, n3}; + + enode * n4 = t.mk_const(); + enode * n5 = t.mk_const(); + enode * n6 = t.mk_const(); + + t.assert_distinct_class(3, d); + TRACE("distinct", t.display(tout);); + t.propagate(); + + t.push(); + + t.assert_lit(t.mk_eq(n1, n2)); + t.propagate(); + SASSERT(t.inconsistent()); + + t.pop(1); + SASSERT(!t.inconsistent()); + TRACE("distinct", t.display(tout);); + + t.push_scope(); + + t.assign(t.mk_eq(n1, n4), mk_axiom()); + t.assign(t.mk_eq(n2, n5), mk_axiom()); + t.assign(t.mk_eq(n2, n6), mk_axiom()); + t.propagate(); + SASSERT(!t.inconsistent()); + + t.assign(t.mk_eq(n4,n5), mk_axiom()); + t.propagate(); + TRACE("distinct", t.display(tout);); + SASSERT(t.inconsistent()); + } + + static void tst2() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + t.assert_lit(t.mk_eq(n1,n3)); + t.propagate(); + + enode * d[3] = {n1, n2, n3}; + + t.assert_distinct_class(3, d); + SASSERT(t.inconsistent()); + } + + static void tst3() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + t.assert_lit(t.mk_eq(n1,n3)); + + enode * d[3] = {n1, n2, n3}; + + t.assert_distinct_class(3, d); + + t.propagate(); + SASSERT(t.inconsistent()); + } + + static void tst4() { +#ifdef ENABLE_DISTINCT_CLASSES_SUPPORT + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + t.push(); + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + enode * d1[3] = {n1, n2, n3}; + + t.assert_distinct_class(3, d1); + + SASSERT(n1->get_distinct_classes() == 1); + SASSERT(n2->get_distinct_classes() == 1); + SASSERT(n3->get_distinct_classes() == 1); + + enode * n4 = t.mk_const(); + enode * n5 = t.mk_const(); + enode * n6 = t.mk_const(); + + enode * d2[3] = {n4, n5, n6}; + + t.assert_distinct_class(3, d2); + + SASSERT(n4->get_distinct_classes() == 2); + SASSERT(n5->get_distinct_classes() == 2); + SASSERT(n6->get_distinct_classes() == 2); + + enode * n7 = t.mk_const(); + enode * n8 = t.mk_const(); + enode * n9 = t.mk_const(); + + enode * d3[3] = {n7, n8, n9}; + + t.assert_distinct_class(3, d3); + + SASSERT(n7->get_distinct_classes() == 4); + SASSERT(n8->get_distinct_classes() == 4); + SASSERT(n9->get_distinct_classes() == 4); + + enode * n10 = t.mk_const(); + enode * n11 = t.mk_const(); + enode * n12 = t.mk_const(); + + enode * d4[3] = {n10, n11, n12}; + + t.assert_distinct_class(3, d4); + + SASSERT(n10->get_distinct_classes() == 8); + SASSERT(n11->get_distinct_classes() == 8); + SASSERT(n12->get_distinct_classes() == 8); + + t.push_scope(); + + t.assign(t.mk_eq(n7, n1), mk_axiom()); + t.propagate(); + SASSERT(!t.inconsistent()); + SASSERT(n1->get_root()->get_distinct_classes() == 5); + + t.push_scope(); + + t.assign(t.mk_eq(n11, n5), mk_axiom()); + t.propagate(); + SASSERT(!t.inconsistent()); + SASSERT(n5->get_root()->get_distinct_classes() == 10); + + t.push_scope(); + t.assign(t.mk_eq(n7, n3), mk_axiom()); + t.propagate(); + SASSERT(t.inconsistent()); + + t.pop_scope(1); + SASSERT(!t.inconsistent()); + + t.push_scope(); + + t.assign(t.mk_eq(n11, n1), mk_axiom()); + t.propagate(); + SASSERT(!t.inconsistent()); + SASSERT(n1->get_root()->get_distinct_classes() == 15); + + t.pop_scope(1); + + SASSERT(!t.inconsistent()); + SASSERT(n1->get_root()->get_distinct_classes() == 5); + SASSERT(n11->get_root()->get_distinct_classes() == 10); + SASSERT(n5->get_root()->get_distinct_classes() == 10); + + t.pop_scope(1); + SASSERT(n1->get_root()->get_distinct_classes() == 5); + SASSERT(n7->get_root()->get_distinct_classes() == 5); + SASSERT(n11->get_root()->get_distinct_classes() == 8); + SASSERT(n5->get_root()->get_distinct_classes() == 2); + + t.pop_scope(1); + SASSERT(n1->get_root()->get_distinct_classes() == 1); + SASSERT(n7->get_root()->get_distinct_classes() == 4); + SASSERT(n11->get_root()->get_distinct_classes() == 8); + SASSERT(n5->get_root()->get_distinct_classes() == 2); + + SASSERT(t.m_num_distinct_classes == 4); + + t.pop(1); + + SASSERT(t.m_num_distinct_classes == 0); +#endif + } + + static void tst5() { +#ifdef ENABLE_DISTINCT_CLASSES_SUPPORT + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + t.push(); + + enode * n1; + enode * n2; + enode * n3; + + for (unsigned i = 0; i < 40; i++) { + n1 = t.mk_const(); + n2 = t.mk_const(); + n3 = t.mk_const(); + + enode * d1[3] = {n1, n2, n3}; + + t.assert_distinct_class(3, d1); + } + + SASSERT(t.m_num_distinct_classes == 32); + SASSERT(n1->get_root()->get_distinct_classes() == 0); + + t.push_scope(); + t.assign(t.mk_eq(n1, n3), mk_axiom()); + t.propagate(); + + SASSERT(t.inconsistent()); + + t.pop_scope(1); + SASSERT(!t.inconsistent()); + + t.pop(1); + SASSERT(t.m_num_distinct_classes == 0); + + n1 = t.mk_const(); + n2 = t.mk_const(); + n3 = t.mk_const(); + + enode * d1[3] = {n1, n2, n3}; + + t.assert_distinct_class(3, d1); + SASSERT(n1->get_root()->get_distinct_classes() == 1); +#endif + } + + static void tst6() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + t.push_scope(); + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + enode * d1[3] = {n1, n2, n3}; + + t.assert_distinct_class(3, d1); + + SASSERT(t.m_num_distinct_classes == 0); + SASSERT(n1->get_root()->get_distinct_classes() == 0); + + t.assign(t.mk_eq(n1, n3), mk_axiom()); + t.propagate(); + + SASSERT(t.inconsistent()); + } + +public: + + static void run_tests() { + tst1(); + tst2(); + tst3(); + tst4(); + tst5(); + tst6(); + } +}; + + +void tst_distinct() { + enable_trace("core_theory_conflict"); + distinct_tester::run_tests(); +} + diff --git a/test/dl_context.cpp b/test/dl_context.cpp new file mode 100644 index 000000000..3ac9095a5 --- /dev/null +++ b/test/dl_context.cpp @@ -0,0 +1,89 @@ +#include "datalog_parser.h" +#include "ast_pp.h" +#include "arith_decl_plugin.h" +#include "dl_context.h" +#include "front_end_params.h" + +using namespace datalog; + + +static lbool dl_context_eval_unary_predicate(ast_manager & m, context & ctx, char const* problem_text, + const char * pred_name) { + parser* p = parser::create(ctx,m); + TRUSTME( p->parse_string(problem_text) ); + dealloc(p); + + func_decl * pred = ctx.try_get_predicate_decl(symbol(pred_name)); + SASSERT(pred); + SASSERT(pred->get_arity()==1); + app_ref query_app(m.mk_app(pred, m.mk_var(0, pred->get_domain()[0])), m); + + lbool status = ctx.query(query_app); + SASSERT(status != l_undef); + return status; +} + +static void dl_context_simple_query_test(params_ref & params) { + ast_manager m; + dl_decl_util decl_util(m); + + front_end_params fparams; + context ctx(m, fparams); + ctx.updt_params(params); + + lbool status = dl_context_eval_unary_predicate(m, ctx, "Z 64\n\nP(x:Z)\nP(\"a\").", "P"); + +#if 0 + // TBD: + //zero corresponds to the first constant the datalog parser encountered, in our case "a" + app_ref c_0(decl_util.mk_constant(0, res1->get_signature()[0]), m); + app_ref c_1(decl_util.mk_constant(1, res1->get_signature()[0]), m); + relation_fact f(m); + f.push_back(c_0); + SASSERT(res1->contains_fact(f)); + f[0]=c_1; + SASSERT(!res1->contains_fact(f)); +#endif +} + +void dl_context_saturate_file(params_ref & params, const char * f) { + ast_manager m; + dl_decl_util decl_util(m); + front_end_params fparams; + context ctx(m, fparams); + ctx.updt_params(params); + + datalog::parser * parser = datalog::parser::create(ctx, m); + if (!parser->parse_file(f)) { + warning_msg("ERROR: failed to parse file"); + return; + } + dealloc(parser); + std::cerr << "Saturating...\n"; + ctx.dl_saturate(); + std::cerr << "Done\n"; +} + +void tst_dl_context() { + symbol relations[] = { symbol("tr_skip"), symbol("tr_sparse"), symbol("tr_hashtable"), symbol("smt_relation2") }; + const unsigned rel_cnt = sizeof(relations)/sizeof(symbol); + + const char * test_file = "c:\\tvm\\src\\benchmarks\\datalog\\t0.datalog"; + + params_ref params; + for(unsigned rel_index=0; rel_index=0; eager_checking--) { + params.set_bool(":eager-emptiness-checking", eager_checking!=0); + + std::cerr << "Testing " << relations[rel_index] << "\n"; + std::cerr << "Eager emptiness checking " << (eager_checking!=0 ? "on" : "off") << "\n"; + dl_context_simple_query_test(params); + dl_context_saturate_file(params, test_file); + } + } + +} + + + diff --git a/test/dl_product_relation.cpp b/test/dl_product_relation.cpp new file mode 100644 index 000000000..2711f3e00 --- /dev/null +++ b/test/dl_product_relation.cpp @@ -0,0 +1,353 @@ +#ifdef _WINDOWS +#include "dl_context.h" +#include "dl_finite_product_relation.h" +#include "dl_sparse_table.h" + +namespace datalog { + + + typedef scoped_rel table_aptr; + + class collector_of_reduced : public table_row_pair_reduce_fn { + idx_set & m_acc; + public: + collector_of_reduced(idx_set & accumulator) : m_acc(accumulator) {} + + virtual void operator()(table_element * func_columns, const table_element * merged_func_columns) { + m_acc.insert(static_cast(merged_func_columns[0])); + } + }; + + + void test_functional_columns(front_end_params fparams, params_ref& params) { + ast_manager m; + context ctx(m, fparams); + ctx.updt_params(params); + relation_manager & rmgr(ctx.get_rmanager()); + + sparse_table_plugin & plugin = + static_cast(*ctx.get_rmanager().get_table_plugin(symbol("sparse"))); + SASSERT(&plugin); + table_signature sig2; + sig2.push_back(2); + sig2.push_back(2); + sig2.set_functional_columns(1); + SASSERT(plugin.can_handle_signature(sig2)); + + table_fact f00; + f00.push_back(0); + f00.push_back(0); + table_fact f01; + f01.push_back(0); + f01.push_back(1); + table_fact f11; + f11.push_back(1); + f11.push_back(1); + + { + table_aptr t0 = plugin.mk_empty(sig2); + SASSERT(t0->empty()); + t0->add_fact(f00); + SASSERT(!t0->empty()); + SASSERT(t0->get_size_estimate_rows()==1); + t0->add_fact(f01); + SASSERT(t0->get_size_estimate_rows()==1); + t0->add_fact(f11); + SASSERT(t0->get_size_estimate_rows()==2); + + unsigned rem_cols0[]={0}; + scoped_ptr project0 = rmgr.mk_project_fn(*t0, 1, rem_cols0); + table_aptr t1 = (*project0)(*t0); + SASSERT(t1->get_size_estimate_rows()==2); + SASSERT(t1->get_signature().functional_columns()==0); //project on non-functional column cancels functional + + unsigned rem_cols1[]={1}; + scoped_ptr project1 = rmgr.mk_project_fn(*t0, 1, rem_cols1); + table_aptr t2 = (*project1)(*t0); + SASSERT(t2->get_size_estimate_rows()==2); + + idx_set acc; + collector_of_reduced * reducer = alloc(collector_of_reduced, acc); + scoped_ptr rproject = rmgr.mk_project_with_reduce_fn(*t0, 1, rem_cols0, reducer); + table_aptr rt = (*rproject)(*t0); + SASSERT(acc.num_elems()==1); + SASSERT(rt->get_size_estimate_rows()==1); + } + { + table_aptr t0 = plugin.mk_empty(sig2); + t0->add_fact(f01); + + unsigned join_cols[]={1}; + scoped_ptr join0 = rmgr.mk_join_fn(*t0, *t0, 1, join_cols, join_cols); + table_aptr t1 = (*join0)(*t0, *t0); + SASSERT(t1->get_signature().size()==4); + SASSERT(t1->get_signature().functional_columns()==2); + + table_fact f0011; + f0011.push_back(0); + f0011.push_back(0); + f0011.push_back(1); + f0011.push_back(1); + SASSERT(t1->contains_fact(f0011)); + table_fact f0111 = f0011; + f0111[1] = 1; + SASSERT(!t1->contains_fact(f0111)); + } + + { + table_aptr t0 = plugin.mk_empty(sig2); + t0->display(std::cout<<"0:"); + SASSERT(t0->get_signature().functional_columns()==1); + + table_fact aux_fact; + + aux_fact = f01; + TRUSTME( t0->suggest_fact(aux_fact) ); + t0->display(std::cout<<"1:"); + SASSERT(t0->contains_fact(f01)); + SASSERT(aux_fact[1]==1); + + aux_fact = f00; + TRUSTME( !t0->suggest_fact(aux_fact) ); + t0->display(std::cout<<"2:"); + SASSERT(t0->contains_fact(f01)); + SASSERT(!t0->contains_fact(f00)); + SASSERT(aux_fact[1]==1); + + t0->ensure_fact(f00); + t0->display(std::cout<<"3:"); + SASSERT(t0->contains_fact(f00)); + SASSERT(!t0->contains_fact(f01)); + } + } + + void test_finite_product_relation(front_end_params fparams, params_ref& params) { + ast_manager m; + context ctx(m, fparams); + ctx.updt_params(params); + dl_decl_util dl_util(m); + relation_manager & rmgr = ctx.get_rmanager(); + + relation_plugin & rel_plugin = *ctx.get_rmanager().get_relation_plugin(params.get_sym(":default-relation", symbol("sparse"))); + SASSERT(&rel_plugin); + finite_product_relation_plugin plg(rel_plugin, rmgr); + + sort_ref byte_srt_ref(dl_util.mk_sort(symbol("BYTE"), 256), m); + relation_sort byte_srt = byte_srt_ref; + + relation_signature sig2; + sig2.push_back(byte_srt); + sig2.push_back(byte_srt); + relation_signature sig3(sig2); + sig3.push_back(byte_srt); + relation_signature sig4(sig3); + sig4.push_back(byte_srt); + + app_ref seven_ref(dl_util.mk_numeral(7, byte_srt), m); + app_ref nine_ref(dl_util.mk_numeral(9, byte_srt), m); + + relation_element seven = seven_ref; + relation_element nine = nine_ref; + + relation_fact f7(m); + f7.push_back(seven); + relation_fact f9(m); + f9.push_back(nine); + + relation_fact f77(f7); + f77.push_back(seven); + relation_fact f79(f7); + f79.push_back(nine); + relation_fact f97(f9); + f97.push_back(seven); + relation_fact f99(f9); + f99.push_back(nine); + + relation_fact f779(f77); + f779.push_back(nine); + relation_fact f799(f79); + f799.push_back(nine); + relation_fact f977(f97); + f977.push_back(seven); + + relation_fact f7797(f779); + f7797.push_back(seven); + relation_fact f7997(f799); + f7997.push_back(seven); + + + bool table_cols2[] = { true, false }; + bool table_cols3[] = { true, false, false }; + bool table_cols4[] = { true, true, false, false }; + scoped_rel r1 = plg.mk_empty(sig2, table_cols2); + scoped_rel r2 = r1->clone(); + scoped_rel r3 = r2->clone(); + + SASSERT(!r1->contains_fact(f77)); + r1->add_fact(f77); + SASSERT(r1->contains_fact(f77)); + + r2->add_fact(f79); + r3->add_fact(f99); + + + r2->display( std::cout << "r2 0\n"); + scoped_rel r4 = r2->clone(); + r2->display( std::cout << "r2 1\n"); + + r4->display( std::cout << "r4 0\n"); + SASSERT(!r4->contains_fact(f77)); + SASSERT(r4->contains_fact(f79)); + r4->add_fact(f77); + r4->display( std::cout << "r4 1\n"); + SASSERT(r4->contains_fact(f77)); + SASSERT(r4->contains_fact(f79)); + r4->add_fact(f99); + r4->display( std::cout << "r4 2\n"); + SASSERT(r4->contains_fact(f99)); + + + std::cout << "------ testing union ------\n"; + r2->display( std::cout << "r2\n"); + scoped_ptr union_op = rmgr.mk_union_fn(*r1, *r2, r3.get()); + SASSERT(union_op); + (*union_op)(*r1, *r2, r3.get()); + + r1->display( std::cout << "r1\n"); + r2->display( std::cout << "r2\n"); + r3->display( std::cout << "r3\n"); + + SASSERT(r1->contains_fact(f77)); + SASSERT(r1->contains_fact(f79)); + SASSERT(!r1->contains_fact(f99)); + + SASSERT(!r3->contains_fact(f77)); + SASSERT(r3->contains_fact(f79)); + SASSERT(r3->contains_fact(f99)); + + std::cout << "------ testing join ------\n"; + + r1->reset(); + r1->add_fact(f77); + r1->add_fact(f79); + r1->add_fact(f97); + r2->reset(); + r2->add_fact(f97); + r2->add_fact(f99); + + unsigned col0[] = { 0 }; + unsigned col1[] = { 1 }; + scoped_ptr join_tt = rmgr.mk_join_fn(*r1, *r2, 1, col0, col0); + scoped_ptr join_tr = rmgr.mk_join_fn(*r1, *r2, 1, col0, col1); + scoped_ptr join_rr = rmgr.mk_join_fn(*r1, *r2, 1, col1, col1); + + r1->display( std::cout << "r1\n"); + r2->display( std::cout << "r2\n"); + + scoped_rel jr_tt = (*join_tt)(*r1, *r2); + scoped_rel jr_tr = (*join_tr)(*r1, *r2); + scoped_rel jr_rr = (*join_rr)(*r1, *r2); + + jr_tt->display( std::cout << "tt\n"); + jr_tr->display( std::cout << "tr\n"); + jr_rr->display( std::cout << "rr\n"); + + + SASSERT(!jr_tt->contains_fact(f7797)); + SASSERT(jr_tr->contains_fact(f7797)); + SASSERT(jr_rr->contains_fact(f7797)); + + + std::cout << "------ testing project ------\n"; + + scoped_rel r31 = plg.mk_empty(sig3, table_cols3); + r31->add_fact(f779); + r31->add_fact(f977); + r31->add_fact(f799); + + unsigned rem_1_rel[] = { 1 }; + unsigned rem_2_rel[] = { 1, 2 }; + unsigned rem_1_table[] = { 0 }; + + scoped_ptr proj_1r = rmgr.mk_project_fn(*r31, 1, rem_1_rel); + scoped_ptr proj_2r = rmgr.mk_project_fn(*r31, 2, rem_2_rel); + scoped_ptr proj_1t = rmgr.mk_project_fn(*r31, 1, rem_1_table); + + scoped_rel sr_1r = (*proj_1r)(*r31); + scoped_rel sr_2r = (*proj_2r)(*r31); + scoped_rel sr_1t = (*proj_1t)(*r31); + + SASSERT(sr_1r->contains_fact(f79)); + SASSERT(sr_1r->contains_fact(f97)); + SASSERT(!sr_1r->contains_fact(f77)); + + SASSERT(sr_2r->contains_fact(f7)); + SASSERT(sr_2r->contains_fact(f9)); + + SASSERT(sr_1t->contains_fact(f79)); + SASSERT(!sr_1t->contains_fact(f97)); + SASSERT(sr_1t->contains_fact(f77)); + SASSERT(sr_1t->contains_fact(f99)); + + std::cout << "------ testing filter_interpreted ------\n"; + + scoped_rel r41 = plg.mk_empty(sig4, table_cols4); + + r41->add_fact(f7797); + r41->add_fact(f7997); + + app_ref cond(m.mk_and( + m.mk_not(m.mk_eq(m.mk_var(1,byte_srt), m.mk_var(2,byte_srt))), //#1!=#2 + m.mk_not(m.mk_eq(m.mk_var(3,byte_srt), m.mk_var(2,byte_srt))) //#3!=#2 + ), m); + scoped_ptr i_filter = rmgr.mk_filter_interpreted_fn(*r41, cond); + (*i_filter)(*r41); + + SASSERT(r41->contains_fact(f7797)); + SASSERT(!r41->contains_fact(f7997)); + + std::cout << "------ testing filter_by_negation ------\n"; + + r31->reset(); + r31->add_fact(f779); + r31->add_fact(f977); + r31->add_fact(f799); + + r1->reset(); + r1->add_fact(f77); + r1->add_fact(f79); + + unsigned nf_r31_cols[] = {1, 0, 1}; + unsigned nf_r1_cols[] = {0, 0, 1}; + scoped_ptr neg_filter = rmgr.mk_filter_by_negation_fn(*r31, *r1, 3, + nf_r31_cols, nf_r1_cols); + (*neg_filter)(*r31, *r1); + + SASSERT(!r31->contains_fact(f779)); + SASSERT(r31->contains_fact(f977)); + SASSERT(r31->contains_fact(f799)); + + + } +} + + + + + +using namespace datalog; + +void tst_dl_product_relation() { + front_end_params fparams; + params_ref params; + + test_functional_columns(fparams, params); + + params.set_sym(":default-relation", symbol("tr_sparse")); + test_finite_product_relation(fparams, params); + +} +#else +void tst_dl_product_relation() { +} +#endif diff --git a/test/dl_query.cpp b/test/dl_query.cpp new file mode 100644 index 000000000..9d99c6ee6 --- /dev/null +++ b/test/dl_query.cpp @@ -0,0 +1,239 @@ +#include "datalog_parser.h" +#include "ast_pp.h" +#include "dl_table_relation.h" +#include "dl_context.h" +#include "front_end_params.h" +#include"stopwatch.h" + +using namespace datalog; + +void dl_query_ask_ground_query(context & ctx, func_decl * pred, relation_fact & f, bool should_be_successful) { + expr * const * q_args = reinterpret_cast(f.c_ptr()); + app * query = ctx.get_manager().mk_app(pred, q_args); + + lbool is_sat = ctx.query(query); + + std::cerr << "@@ query should succeed: " << should_be_successful << "\n"; + SASSERT(is_sat != l_undef); + if((is_sat != l_true) == should_be_successful) { + std::cerr<<"wrong ground query answer!\n"; + UNREACHABLE(); + } +} + +void dl_query_ask_for_last_arg(context & ctx, func_decl * pred, relation_fact & f, bool should_be_successful) { + ast_manager & m = ctx.get_manager(); + expr_ref_vector query_args(m); + push_into_vector(query_args, f); + query_args.pop_back(); + query_args.push_back(m.mk_var(0, pred->get_domain(query_args.size()))); + app * query = ctx.get_manager().mk_app(pred, query_args.c_ptr()); + + lbool is_sat = ctx.query(query); + std::cerr << "@@ last arg query should succeed: " << should_be_successful << "\n"; + SASSERT(is_sat != l_undef); + + relation_fact res_fact(m); + res_fact.push_back(f.back()); + + if(ctx.result_contains_fact(res_fact)!=should_be_successful) { + std::cerr<<"wrong arg query answer!\n"; + UNREACHABLE(); + } +} + +void dl_query_test(ast_manager & m, front_end_params & fparams, params_ref& params, + context & ctx_b, char const* problem_file, unsigned test_count, + bool use_magic_sets) { + + dl_decl_util decl_util(m); + relation_manager & rel_mgr_b = ctx_b.get_rmanager(); + + context ctx_q(m, fparams); + params.set_bool(":magic-sets-for-queries", use_magic_sets); + ctx_q.updt_params(params); + { + parser* p = parser::create(ctx_q,m); + TRUSTME( p->parse_file(problem_file) ); + dealloc(p); + } + relation_manager & rel_mgr_q = ctx_b.get_rmanager(); + + decl_set out_preds = ctx_b.get_output_predicates(); + decl_set::iterator it = out_preds.begin(); + decl_set::iterator end = out_preds.end(); + for(; it!=end; ++it) { + func_decl * pred_b = *it; + std::cerr << "Checking queries on relation " << pred_b->get_name() << "\n"; + func_decl * pred_q = ctx_q.try_get_predicate_decl(symbol(pred_b->get_name().bare_str())); + SASSERT(pred_q); + + relation_base & rel_b = ctx_b.get_relation(pred_b); + + relation_signature sig_b = rel_b.get_signature(); + relation_signature sig_q = ctx_q.get_relation(pred_q).get_signature(); + SASSERT(sig_b.size()==sig_q.size()); + + std::cerr << "Queries on random facts...\n"; + relation_fact f_b(m); + relation_fact f_q(m); + for(unsigned attempt=0; attempt(rel_b); + table_base & table_b = tr_b.get_table(); + + table_fact tf; + unsigned table_sz = table_b.get_size_estimate_rows(); + + table_base::iterator fit = table_b.begin(); + table_base::iterator fend = table_b.end(); + for(; fit!=fend; ++fit) { + if(rand()%std::max(1u,table_sz/test_count)!=0) { + continue; + } + fit->get_fact(tf); + rel_mgr_q.table_fact_to_relation(sig_q, tf, f_q); + dl_query_ask_ground_query(ctx_q, pred_q, f_q, true); + dl_query_ask_for_last_arg(ctx_q, pred_q, f_q, true); + } + std::cerr << "Done.\n"; + } +} + +void dl_query_test_wpa(front_end_params & fparams, params_ref& params) { + params.set_bool(":magic-sets-for-queries", true); + ast_manager m; + m.register_decl_plugins(); + arith_util arith(m); + const char * problem_dir = "C:\\tvm\\src\\z3_2\\debug\\test\\w0.datalog"; + dl_decl_util dl_util(m); + + std::cerr << "Testing queries on " << problem_dir <<"\n"; + context ctx(m, fparams); + ctx.updt_params(params); + { + wpa_parser* p = wpa_parser::create(ctx, m); + TRUSTME( p->parse_directory(problem_dir) ); + dealloc(p); + } + + const unsigned attempts = 10; + + func_decl * v_pred = ctx.try_get_predicate_decl(symbol("V")); + SASSERT(v_pred); + sort * var_sort = v_pred->get_domain(0); + + uint64 var_sz; + TRUSTME( ctx.try_get_sort_constant_count(var_sort, var_sz) ); + + for(unsigned attempt=0; attemptparse_file(problem_file) ); + dealloc(p); + } + ctx_base.dl_saturate(); + + for(unsigned use_restarts=0; use_restarts<=1; use_restarts++) { + params.set_uint(":initial-restart-timeout", use_restarts ? 100 : 0); + for(unsigned use_similar=0; use_similar<=1; use_similar++) { + params.set_uint(":similarity-compressor", use_similar != 0); + + for(unsigned use_magic_sets=0; use_magic_sets<=1; use_magic_sets++) { + stopwatch watch; + watch.start(); + std::cerr << "------- " << (use_restarts ? "With" : "Without") << " restarts -------\n"; + std::cerr << "------- " << (use_similar ? "With" : "Without") << " similar compressor -------\n"; + std::cerr << "------- " << (use_magic_sets ? "With" : "Without") << " magic sets -------\n"; + dl_query_test(m, fparams, params, ctx_base, problem_file, 1, use_magic_sets!=0); + watch.stop(); + std::cout << (use_restarts ? "With" : "Without") << " restarts\n"; + std::cout << (use_similar ? "With" : "Without") << " similar compressor\n"; + std::cout << (use_magic_sets ? "With" : "Without") << " magic sets\n"; + std::cout << "Time: " << watch.get_current_seconds() << "\n\n"; + std::cerr << "Time: " << watch.get_current_seconds() << "\n"; + + } + } + } +} + + + diff --git a/test/dl_relation.cpp b/test/dl_relation.cpp new file mode 100644 index 000000000..095751cb6 --- /dev/null +++ b/test/dl_relation.cpp @@ -0,0 +1,288 @@ +#ifdef _WINDOWS +#include "dl_context.h" +#include "dl_interval_relation.h" +#include "dl_bound_relation.h" +#include "dl_product_relation.h" +#include "util.h" + +namespace datalog { + + static void test_interval_relation() { + front_end_params params; + ast_manager ast_m; + context ctx(ast_m, params); + arith_util autil(ast_m); + relation_manager & m = ctx.get_rmanager(); + m.register_plugin(alloc(interval_relation_plugin, m)); + interval_relation_plugin& ip = dynamic_cast(*m.get_relation_plugin(symbol("interval_relation"))); + SASSERT(&ip); + + relation_signature sig; + sort* int_sort = autil.mk_int(); + sig.push_back(int_sort); + sig.push_back(int_sort); + sig.push_back(int_sort); + sig.push_back(int_sort); + + interval_relation& i1 = dynamic_cast(*ip.mk_empty(sig)); + interval_relation& i2 = dynamic_cast(*ip.mk_full(0, sig)); + + i1.display(std::cout); + i2.display(std::cout); + SASSERT(i1.empty()); + SASSERT(!i2.empty()); + + app_ref cond1(ast_m), cond2(ast_m), cond3(ast_m); + app_ref cond4(ast_m), cond5(ast_m), cond6(ast_m); + app_ref num1(ast_m); + cond1 = autil.mk_le(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true)); + cond2 = autil.mk_le(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(1), true)); + cond3 = autil.mk_le(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(2), true)); + cond4 = autil.mk_ge(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true)); + cond5 = autil.mk_ge(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(0), true)); + cond6 = autil.mk_ge(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(5), true)); + num1 = autil.mk_numeral(rational(4), true); + i2.filter_interpreted(cond1); + i2.display(std::cout); + // x0 <= 0 + + unsigned cols1[2] = { 1, 2}; + unsigned cols2[2] = { 2, 3}; + relation_join_fn* join1 = ip.mk_join_fn(i1, i2, 2, cols1, cols2); + relation_transformer_fn* proj1 = ip.mk_project_fn(i1, 2, cols2); + relation_transformer_fn* ren1 = ip.mk_rename_fn(i1, 2, cols2); + relation_union_fn* union1 = ip.mk_union_fn(i1, i2, &i1); + relation_mutator_fn* filterId1 = ip.mk_filter_identical_fn(i1, 2, cols1); + relation_mutator_fn* filterEq1 = ip.mk_filter_equal_fn(i1, num1, 2); + relation_mutator_fn* filterCond1 = ip.mk_filter_interpreted_fn(i1, cond2); + + relation_base* i3 = (*join1)(i2, i2); + i3->display(std::cout); + + relation_transformer_fn* proj2 = ip.mk_project_fn(*i3, 2, cols2); + + (*filterEq1)(i2); + i2.display(std::cout); + // x0 <= 0 + // x2 = 4 + + (*filterId1)(i2); + i2.display(std::cout); + // x0 <= 0 + // x1 = x2 = 4 + relation_fact fact1(ast_m); + fact1.push_back(autil.mk_numeral(rational(0), true)); + fact1.push_back(autil.mk_numeral(rational(4), true)); + fact1.push_back(autil.mk_numeral(rational(4), true)); + fact1.push_back(autil.mk_numeral(rational(5), true)); + SASSERT(i2.contains_fact(fact1)); + fact1[0] = autil.mk_numeral(rational(-1), true); + SASSERT(i2.contains_fact(fact1)); + fact1[0] = autil.mk_numeral(rational(1), true); + SASSERT(!i2.contains_fact(fact1)); + + relation_base* i5 = (*ren1)(i2); + i2.display(std::cout << "Orig\n"); + i5->display(std::cout << "renamed 2 |-> 3 |-> 2\n"); + + (*filterCond1)(i2); + i2.display(std::cout); + // empty + SASSERT(i2.empty()); + + relation_base* i4 = (*proj2)(*i3); + i4->display(std::cout); + + i1.deallocate(); + i2.deallocate(); + i3->deallocate(); + i4->deallocate(); + i5->deallocate(); + dealloc(join1); + dealloc(proj1); + dealloc(ren1); + dealloc(union1); + dealloc(filterId1); + dealloc(filterEq1); + dealloc(filterCond1); + } + + static void test_bound_relation() { + + std::cout << "bound relation\n"; + + front_end_params params; + ast_manager ast_m; + context ctx(ast_m, params); + arith_util autil(ast_m); + relation_manager & m = ctx.get_rmanager(); + m.register_plugin(alloc(bound_relation_plugin, m)); + bound_relation_plugin& br = dynamic_cast(*m.get_relation_plugin(symbol("bound_relation"))); + SASSERT(&br); + + relation_signature sig; + sort* int_sort = autil.mk_int(); + sig.push_back(int_sort); + sig.push_back(int_sort); + sig.push_back(int_sort); + sig.push_back(int_sort); + + bound_relation& i1 = dynamic_cast(*br.mk_empty(sig)); + bound_relation& i2 = dynamic_cast(*br.mk_full(0, sig)); + + i1.display(std::cout << "empty:\n"); + i2.display(std::cout << "full:\n"); + SASSERT(i1.empty()); + SASSERT(!i2.empty()); + + app_ref cond1(ast_m), cond2(ast_m), cond3(ast_m); + app_ref cond4(ast_m), cond5(ast_m), cond6(ast_m); + app_ref num1(ast_m); + cond1 = autil.mk_lt(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true)); + cond2 = autil.mk_lt(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(1), true)); + cond3 = autil.mk_lt(ast_m.mk_var(2, int_sort), ast_m.mk_var(3, int_sort)); + cond4 = autil.mk_ge(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true)); + cond5 = autil.mk_ge(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(0), true)); + cond6 = autil.mk_ge(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(5), true)); + + app_ref lt_x0x1(ast_m), lt_x1x2(ast_m), lt_x0x3(ast_m), lt_x0x2(ast_m); + lt_x0x1 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(1, int_sort)); + lt_x1x2 = autil.mk_lt(ast_m.mk_var(1, int_sort), ast_m.mk_var(2, int_sort)); + lt_x0x2 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(2, int_sort)); + lt_x0x3 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(3, int_sort)); + + num1 = autil.mk_numeral(rational(4), true); + + unsigned cols1[2] = { 1, 2}; + unsigned cols2[2] = { 2, 3}; + unsigned cols3[3] = { 0, 2, 3 }; + relation_join_fn* join1 = br.mk_join_fn(i1, i2, 2, cols1, cols2); + relation_transformer_fn* proj1 = br.mk_project_fn(i1, 2, cols2); + relation_transformer_fn* ren1 = br.mk_rename_fn(i1, 3, cols3); + relation_union_fn* union1 = br.mk_union_fn(i1, i2, &i1); + relation_mutator_fn* filterId1 = br.mk_filter_identical_fn(i1, 2, cols1); + relation_mutator_fn* filterEq1 = br.mk_filter_equal_fn(i1, num1, 2); + relation_mutator_fn* filterCond1 = br.mk_filter_interpreted_fn(i1, cond3); + + relation_base* i3 = (*join1)(i2, i2); + i3->display(std::cout); + + relation_transformer_fn* proj2 = br.mk_project_fn(*i3, 2, cols2); + + (*filterEq1)(i2); + i2.display(std::cout << "no-op still full\n"); + // no-op + + (*filterCond1)(i2); + i2.display(std::cout << "x2 < x3\n"); + // x2 < x3 + + (*filterId1)(i2); + i2.display(std::cout << "id\n"); + // x1 = x2 < x3 + relation_fact fact1(ast_m); + + i2.display(std::cout << "Orig\n"); + std::cout << "renamed "; + for (unsigned i = 0; i < 3; ++i) { + std::cout << cols3[i] << " "; + } + std::cout << "\n"; + relation_base* i5 = (*ren1)(i2); + i5->display(std::cout); + + //SASSERT(i2.empty()); + + relation_base* i4 = (*proj2)(*i3); + i4->display(std::cout); + + // test that equivalence classes are expanded. + // { x1 = x3, x0 < x1 x1 < x2} u { x2 = x3, x0 < x3 } = { x0 < x3 } + { + relation_base* b1 = br.mk_full(0, sig); + relation_base* b2 = br.mk_full(0, sig); + unsigned x1x3[2] = { 1, 3 }; + unsigned x2x3[2] = { 2, 3 }; + scoped_ptr id1 = br.mk_filter_identical_fn(*b1, 2, x1x3); + scoped_ptr ltx0x1 = br.mk_filter_interpreted_fn(*b1, lt_x0x1); + scoped_ptr ltx1x2 = br.mk_filter_interpreted_fn(*b1, lt_x1x2); + scoped_ptr ltx0x3 = br.mk_filter_interpreted_fn(*b2, lt_x0x3); + scoped_ptr id2 = br.mk_filter_identical_fn(*b2, 2, x2x3); + (*id1)(*b1); + (*ltx0x1)(*b1); + (*ltx1x2)(*b1); + b2->display(std::cout << "b2:\n"); + (*id2)(*b2); + b2->display(std::cout << "b2:\n"); + (*ltx0x3)(*b2); + b2->display(std::cout << "b2:\n"); + scoped_ptr u = br.mk_union_fn(*b1, *b2, 0); + b1->display(std::cout << "b1:\n"); + b2->display(std::cout << "b2:\n"); + (*u)(*b1, *b2, 0); + + b1->display(std::cout << "b1 u b2:\n"); + + // TBD check property; + + b1->deallocate(); + b2->deallocate(); + } + + // test that equivalence classes are expanded. + // { x1 = x2 = x3, x0 < x1} u { x1 = x3, x0 < x3, x0 < x2 } = { x0 < x2, x0 < x3 } + { + relation_base* b1 = br.mk_full(0, sig); + relation_base* b2 = br.mk_full(0, sig); + unsigned x0x3[2] = { 0, 3 }; + unsigned x1x3[2] = { 1, 3 }; + unsigned x2x3[2] = { 2, 3 }; + scoped_ptr id1 = br.mk_filter_identical_fn(*b1, 2, x1x3); + scoped_ptr id2 = br.mk_filter_identical_fn(*b1, 2, x2x3); + scoped_ptr ltx0x1 = br.mk_filter_interpreted_fn(*b1, lt_x0x1); + scoped_ptr ltx0x2 = br.mk_filter_interpreted_fn(*b2, lt_x0x2); + scoped_ptr ltx0x3 = br.mk_filter_interpreted_fn(*b2, lt_x0x3); + scoped_ptr id3 = br.mk_filter_identical_fn(*b2, 2, x1x3); + (*id1)(*b1); + (*id2)(*b1); + (*ltx0x1)(*b1); + (*id3)(*b2); + (*ltx0x2)(*b2); + (*ltx0x3)(*b2); + scoped_ptr u = br.mk_union_fn(*b1, *b2, 0); + b1->display(std::cout << "b1:\n"); + b2->display(std::cout << "b2:\n"); + (*u)(*b1, *b2, 0); + b1->display(std::cout << "b1 u b2:\n"); + + // TBD check property; + + b1->deallocate(); + b2->deallocate(); + } + + i1.deallocate(); + i2.deallocate(); + i3->deallocate(); + i4->deallocate(); + i5->deallocate(); + dealloc(join1); + dealloc(proj1); + dealloc(ren1); + dealloc(union1); + dealloc(filterId1); + dealloc(filterEq1); + dealloc(filterCond1); + } + +} + +void tst_dl_relation() { + datalog::test_interval_relation(); + datalog::test_bound_relation(); +} + +#else +void tst_dl_relation() { +} +#endif diff --git a/test/dl_rule_set.cpp b/test/dl_rule_set.cpp new file mode 100644 index 000000000..d68bdc3c7 --- /dev/null +++ b/test/dl_rule_set.cpp @@ -0,0 +1,118 @@ +/*++ +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/test/dl_smt_relation.cpp b/test/dl_smt_relation.cpp new file mode 100644 index 000000000..bf34688ea --- /dev/null +++ b/test/dl_smt_relation.cpp @@ -0,0 +1,233 @@ +#include "dl_smt_relation.h" +#include "arith_decl_plugin.h" +#include "dl_context.h" +#include "z3.h" +#include "z3_private.h" + + +namespace datalog { + + void test_smt_relation_unit() { + ast_manager m; + m.register_decl_plugins(); + arith_util a(m); + sort* int_sort = a.mk_int(); + sort* real_sort = a.mk_real(); + front_end_params params; + context ctx(m, params); + relation_manager & rm = ctx.get_rmanager(); + relation_signature sig1; + sig1.push_back(int_sort); + sig1.push_back(int_sort); + sig1.push_back(real_sort); + + smt_relation_plugin plugin(rm); + + scoped_rel r1 = plugin.mk_empty(sig1); + + // add_fact + relation_fact fact1(m); + fact1.push_back(a.mk_numeral(rational(1), true)); + fact1.push_back(a.mk_numeral(rational(2), true)); + fact1.push_back(a.mk_numeral(rational(3), false)); + + relation_fact fact2(m); + fact2.push_back(a.mk_numeral(rational(2), true)); + fact2.push_back(a.mk_numeral(rational(2), true)); + fact2.push_back(a.mk_numeral(rational(3), false)); + + r1->add_fact(fact1); + r1->display(std::cout << "r1: "); + + + // contains_fact + SASSERT(r1->contains_fact(fact1)); + SASSERT(!r1->contains_fact(fact2)); + + // empty + scoped_rel r2 = plugin.mk_empty(sig1); + SASSERT(!r1->empty()); + SASSERT(r2->empty()); + + // clone + scoped_rel r3 = r1->clone(); + + // complement? + r2->add_fact(fact2); + scoped_rel r4 = dynamic_cast(*r2).complement(0); + r4->display(std::cout << "complement r4: " ); + + // join + unsigned col_cnt = 2; + unsigned cols1[2] = {1, 2}; + unsigned cols2[2] = {0, 2}; + scoped_ptr joinfn = plugin.mk_join_fn(*r1, *r4, col_cnt, cols1, cols2); + scoped_rel r5 = (*joinfn)(*r1, *r4); + r5->display(std::cout<< "join r5: "); + + relation_fact fact3(m); + fact3.push_back(a.mk_numeral(rational(1), true)); + fact3.push_back(a.mk_numeral(rational(2), true)); + fact3.push_back(a.mk_numeral(rational(3), false)); + fact3.push_back(a.mk_numeral(rational(2), true)); + fact3.push_back(a.mk_numeral(rational(2), true)); + fact3.push_back(a.mk_numeral(rational(3), false)); + SASSERT(!r5->contains_fact(fact3)); + fact3[5] = a.mk_numeral(rational(4), false); + SASSERT(!r5->contains_fact(fact3)); + fact3[5] = a.mk_numeral(rational(3), false); + fact3[4] = a.mk_numeral(rational(3), true); + SASSERT(r5->contains_fact(fact3)); + + // project + unsigned removed_cols[2] = { 1, 4 }; + scoped_ptr projfn = plugin.mk_project_fn(*r5, col_cnt, removed_cols); + scoped_rel r6 = (*projfn)(*r5); + r6->display(std::cout<< "project r6: "); + + // rename + unsigned cycle[3] = { 0, 2, 4 }; + unsigned cycle_len = 3; + scoped_rel renamefn = plugin.mk_rename_fn(*r5, cycle_len, cycle); + scoped_rel r7 = (*renamefn)(*r5); + r7->display(std::cout << "rename r7: "); + + // union + // widen + relation_base* delta = 0; + scoped_ptr widenfn = plugin.mk_widen_fn(*r1, *r2, delta); + scoped_ptr unionfn = plugin.mk_union_fn(*r1, *r2, delta); + scoped_rel r8 = r1->clone(); + (*unionfn)(*r8,*r2,0); + r8->display(std::cout << "union r8: "); + + // filter_identical + unsigned identical_cols[2] = { 1, 3 }; + scoped_ptr filti = plugin.mk_filter_identical_fn(*r5, col_cnt, identical_cols); + scoped_rel r9 = r1->clone(); + (*filti)(*r9); + r9->display(std::cout << "filter identical r9: "); + + // filter_equal + app_ref value(m); + value = m.mk_const(symbol("x"), int_sort); + scoped_rel eqn = plugin.mk_filter_equal_fn(*r5, value.get(), 3); + scoped_rel r10 = r1->clone(); + (*eqn)(*r10); + r10->display(std::cout << "filter equal r10: "); + + + // filter_interpreted + app_ref cond(m); + cond = a.mk_lt(m.mk_var(3, int_sort), m.mk_var(4, int_sort)); + scoped_rel filtint = plugin.mk_filter_interpreted_fn(*r5, cond); + scoped_rel r11 = r5->clone(); + (*filtint)(*r11); + r11->display(std::cout << "filter interpreted r11: "); + + } + + void test_smt_relation_api() { + + enable_trace("smt_relation"); + enable_trace("smt_relation2"); + enable_trace("quant_elim"); + Z3_config cfg = Z3_mk_config(); + Z3_set_param_value(cfg, "DL_DEFAULT_RELATION", "smt_relation2"); + Z3_context ctx = Z3_mk_context(cfg); + Z3_fixedpoint dl = Z3_mk_fixedpoint(ctx); + Z3_fixedpoint_inc_ref(ctx,dl); + Z3_del_config(cfg); + + Z3_sort int_sort = Z3_mk_int_sort(ctx); + Z3_sort bool_sort = Z3_mk_bool_sort(ctx); + Z3_func_decl nil_decl, is_nil_decl; + Z3_func_decl cons_decl, is_cons_decl, head_decl, tail_decl; + + Z3_sort list = Z3_mk_list_sort( + ctx, + Z3_mk_string_symbol(ctx, "list"), + int_sort, + &nil_decl, + &is_nil_decl, + &cons_decl, + &is_cons_decl, + &head_decl, + &tail_decl); + + Z3_sort listint[2] = { list, int_sort }; + Z3_symbol p_sym = Z3_mk_string_symbol(ctx, "p"); + Z3_symbol q_sym = Z3_mk_string_symbol(ctx, "q"); + + + Z3_func_decl p = Z3_mk_func_decl(ctx, p_sym, 2, listint, bool_sort); + Z3_func_decl q = Z3_mk_func_decl(ctx, q_sym, 2, listint, bool_sort); + Z3_fixedpoint_register_relation(ctx, dl, p); + Z3_fixedpoint_register_relation(ctx, dl, q); + + + Z3_ast zero = Z3_mk_numeral(ctx, "0", int_sort); + Z3_ast one = Z3_mk_numeral(ctx, "1", int_sort); + Z3_ast two = Z3_mk_numeral(ctx, "2", int_sort); + Z3_ast x = Z3_mk_bound(ctx, 0, list); + Z3_ast y = Z3_mk_bound(ctx, 1, int_sort); + Z3_ast z = Z3_mk_bound(ctx, 2, list); + Z3_ast zero_x[2] = { zero, x }; + Z3_ast fx = Z3_mk_app(ctx, cons_decl, 2, zero_x); + Z3_ast zero_fx[2] = { zero, fx }; + Z3_ast ffx = Z3_mk_app(ctx, cons_decl, 2, zero_fx); + Z3_ast xy[2] = { x, y }; + Z3_ast zy[2] = { z, y }; + Z3_ast ffxy[2] = { ffx, y }; + Z3_ast fxy[2] = { fx, y }; + Z3_ast zero_nil[2] = { zero, Z3_mk_app(ctx, nil_decl, 0, 0) }; + Z3_ast f0 = Z3_mk_app(ctx, cons_decl, 2, zero_nil); + Z3_ast zero_f0[2] = { zero, f0 }; + Z3_ast f1 = Z3_mk_app(ctx, cons_decl, 2, zero_f0); + Z3_ast zero_f1[2] = { zero, f1 }; + Z3_ast f2 = Z3_mk_app(ctx, cons_decl, 2, zero_f1); + Z3_ast zero_f2[2] = { zero, f2 }; + Z3_ast f3 = Z3_mk_app(ctx, cons_decl, 2, zero_f2); + Z3_ast zero_f3[2] = { zero, f3 }; + Z3_ast f4 = Z3_mk_app(ctx, cons_decl, 2, zero_f3); + Z3_ast zero_f4[2] = { zero, f4 }; + Z3_ast f5 = Z3_mk_app(ctx, cons_decl, 2, zero_f4); + Z3_ast zero_z[2] = { zero, z }; + Z3_ast fz = Z3_mk_app(ctx, cons_decl, 2, zero_z); + + Z3_ast pxy = Z3_mk_app(ctx, p, 2, xy); + Z3_ast pzy = Z3_mk_app(ctx, p, 2, zy); + Z3_ast qxy = Z3_mk_app(ctx, q, 2, xy); + Z3_ast qzy = Z3_mk_app(ctx, q, 2, zy); + Z3_ast even_y = Z3_mk_eq(ctx, zero, Z3_mk_mod(ctx, y, two)); + Z3_ast odd_y = Z3_mk_eq(ctx, one, Z3_mk_mod(ctx, y, two)); + + + // p(x, y) :- odd(y), p(z,y), f(z) = x . // dead rule. + // q(x, y) :- p(f(f(x)), y). + // p(x, y) :- q(f(x), y) // x decreases + // p(x, y) :- even y, x = f^5(0) // initial condition. + + Z3_ast body1[3] = { pzy, Z3_mk_eq(ctx, fz, x), odd_y }; + Z3_ast body2[2] = { pzy, Z3_mk_eq(ctx, ffx, z) }; + Z3_ast body3[2] = { qzy, Z3_mk_eq(ctx, fx, z) }; + Z3_ast body4[2] = { even_y, Z3_mk_eq(ctx, x, f5) }; + Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 3, body1), pxy), 0); + Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body2), qxy), 0); + Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body3), pxy), 0); + Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body4), pxy), 0); + + Z3_lbool r = Z3_fixedpoint_query(ctx, dl, pxy); + if (r != l_undef) { + std::cout << Z3_ast_to_string(ctx, Z3_fixedpoint_get_answer(ctx, dl)) << "\n"; + } + + Z3_del_context(ctx); + + } +}; + +void tst_dl_smt_relation() { + datalog::test_smt_relation_api(); + datalog::test_smt_relation_unit(); +} diff --git a/test/dl_table.cpp b/test/dl_table.cpp new file mode 100644 index 000000000..a29ef48d8 --- /dev/null +++ b/test/dl_table.cpp @@ -0,0 +1,110 @@ +#ifdef _WINDOWS +#include "dl_context.h" +#include "dl_table.h" +#include "dl_skip_table.h" + +typedef datalog::table_base* (*mk_table_fn)(datalog::relation_manager& m, datalog::table_signature& sig); + +static datalog::table_base* mk_bv_table(datalog::relation_manager& m, datalog::table_signature& sig) { + datalog::table_plugin * p = m.get_table_plugin(symbol("bitvector")); + SASSERT(p); + return p->mk_empty(sig); +} + +static datalog::table_base* mk_skip_table(datalog::relation_manager& m, datalog::table_signature& sig) { + datalog::table_plugin * p = m.get_table_plugin(symbol("skip")); + SASSERT(p); + return p->mk_empty(sig); +} + + +static void test_table(mk_table_fn mk_table) { + datalog::table_signature sig; + sig.push_back(2); + sig.push_back(4); + sig.push_back(8); + sig.push_back(4); + front_end_params params; + ast_manager ast_m; + datalog::context ctx(ast_m, params); + datalog::relation_manager & m = ctx.get_rmanager(); + + ctx.get_rmanager().register_plugin(alloc(datalog::bitvector_table_plugin, ctx.get_rmanager())); + + datalog::table_base* _tbl = mk_table(m, sig); + datalog::table_base& table = *_tbl; + datalog::table_fact row, row1, row2, row3; + row.push_back(1); + row.push_back(3); + row.push_back(7); + row.push_back(2); + row1 = row; + row[3] = 3; + row2 = row; + row[0] = 0; + row[3] = 1; + row3 = row; + table.add_fact(row1); + table.add_fact(row2); + table.display(std::cout); + + datalog::table_base::iterator it = table.begin(); + datalog::table_base::iterator end = table.end(); + for (; it != end; ++it) { + it->get_fact(row); + for (unsigned j = 0; j < row.size(); ++j) { + std::cout << row[j] << " "; + } + std::cout << "\n"; + } + + SASSERT(table.contains_fact(row1)); + SASSERT(table.contains_fact(row2)); + SASSERT(!table.contains_fact(row3)); +#if 0 + table.remove_facts(1, &row1); + SASSERT(!table.contains_fact(row1)); +#endif + table.add_fact(row1); + + datalog::table_base* _tbl2 = mk_table(m, sig); + datalog::table_base& table2 = *_tbl2; + table2.add_fact(row2); + table2.add_fact(row3); + + unsigned cols1[1] = { 1 }; + unsigned cols2[1] = { 3 }; + + datalog::table_join_fn * j1 = m.mk_join_fn(table2, table, 1, cols1, cols2); + datalog::table_base* _tbl3 = (*j1)(table2,table); + _tbl3->display(std::cout); + + datalog::table_join_fn * j2 = m.mk_join_fn(table2, table, 1, cols1, cols1); + datalog::table_base* _tbl4 = (*j2)(table2,table); + _tbl4->display(std::cout); + + dealloc(j1); + dealloc(j2); + _tbl->deallocate(); + (_tbl2->deallocate()); + (_tbl3->deallocate()); + (_tbl4->deallocate()); + +} + +void test_dl_bitvector_table() { + test_table(mk_bv_table); +} + +void test_dl_skip_table() { + test_table(mk_skip_table); +} + +void tst_dl_table() { + test_dl_bitvector_table(); + test_dl_skip_table(); +} +#else +void tst_dl_table() { +} +#endif diff --git a/test/dl_util.cpp b/test/dl_util.cpp new file mode 100644 index 000000000..601fd630a --- /dev/null +++ b/test/dl_util.cpp @@ -0,0 +1,51 @@ +#include "dl_util.h" + +using namespace datalog; + + +void dl_util_two_array_sort() { + const unsigned num = 97; + unsigned a1[num]; + unsigned a2[num]; + + for(unsigned i=0; i + +Author: + + Leonardo de Moura (leonardo) 2011-04-28 + +Revision History: + +--*/ +#include +#include"z3_exception.h" + +class ex { +public: + virtual ~ex() {} + virtual char const * msg() const = 0; +}; + +class ex1 : public ex { + char const * m_msg; +public: + ex1(char const * m):m_msg(m) {} + virtual char const * msg() const { return m_msg; } +}; + +class ex2 : public ex { + std::string m_msg; +public: + ex2(char const * m):m_msg(m) {} + virtual char const * msg() const { return m_msg.c_str(); } +}; + +static void th() { + throw ex2("testing exception"); +} + +static void tst1() { + try { + th(); + } + catch (ex & e) { + std::cerr << e.msg() << "\n"; + } +} + +static void tst2() { + try { + throw default_exception("Format %d %s", 12, "twelve"); + } + catch (z3_exception& ex) { + std::cerr << ex.msg() << "\n"; + } +} + +void tst_ex() { + tst1(); + tst2(); +} diff --git a/test/expr_context_simplifier.cpp b/test/expr_context_simplifier.cpp new file mode 100644 index 000000000..91bd29ca7 --- /dev/null +++ b/test/expr_context_simplifier.cpp @@ -0,0 +1,43 @@ +#include "expr_context_simplifier.h" +#include "smtparser.h" +#include "ast_pp.h" + +static void simplify_formula(ast_manager& m, expr* e) { + expr_ref result(m); + expr_context_simplifier simp(m); + + simp(e, result); + + TRACE("expr_context_simplifier", + tout + << mk_pp(e, m) << " |-> " + << mk_pp(result.get(), m) << "\n";); + +} + +void tst_expr_context_simplifier() { + ast_manager m; + + smtlib::parser* parser = smtlib::parser::create(m); + m.register_decl_plugins(); + + parser->initialize_smtlib(); + + parser->parse_string( + "(benchmark samples :logic QF_LIA \n" + " :extrafuns ((x Int) (y Int) (z Int) (u Int)) \n" + " :formula (and (<= 1 x) (or (<= 1 x) (<= x y))) \n" + " :formula (and (<= 2 (ite (<= z 1) (ite (<= z 1) x y) (* 2 x))) (<= x y)) \n" + ")" + ); + + smtlib::benchmark* b = parser->get_benchmark(); + + smtlib::symtable const * table = b->get_symtable(); + + for (unsigned j = 0; j < b->get_num_formulas(); ++j) { + simplify_formula(m, b->begin_formulas()[j]); + } + + dealloc(parser); +} diff --git a/test/expr_delta.cpp b/test/expr_delta.cpp new file mode 100644 index 000000000..fae80336d --- /dev/null +++ b/test/expr_delta.cpp @@ -0,0 +1,127 @@ +#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/test/expr_pattern_match.cpp b/test/expr_pattern_match.cpp new file mode 100644 index 000000000..4e1fef1ed --- /dev/null +++ b/test/expr_pattern_match.cpp @@ -0,0 +1,50 @@ +#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" + +void tst_expr_pattern_match() { + ast_manager manager; + manager.register_decl_plugins(); + + 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/test/expr_rand.cpp b/test/expr_rand.cpp new file mode 100644 index 000000000..fec4e5d3f --- /dev/null +++ b/test/expr_rand.cpp @@ -0,0 +1,104 @@ +#include "expr_rand.h" +#include "ast_pp.h" +#include "bv_decl_plugin.h" +#include "array_decl_plugin.h" +#include "arith_decl_plugin.h" +#include "ast_smt_pp.h" +#include +#include + +static unsigned rand_seed = 1; + +void tst_expr_arith(unsigned num_files) { + ast_manager m; + m.register_decl_plugins(); + + expr_rand er(m); + er.seed(rand_seed); + er.initialize_arith(20); + + family_id fid = m.get_family_id("arith"); + sort* int_ty = m.mk_sort(fid, INT_SORT, 0, 0); + sort* real_ty = m.mk_sort(fid, REAL_SORT, 0, 0); + + er.initialize_array(3, int_ty, int_ty); + er.initialize_array(3, int_ty, real_ty); + + er.initialize_basic(20); + + for (unsigned i = 0; i < num_files; ++i) { + expr_ref e(m); + er.get_next(m.mk_bool_sort(), e); + ast_smt_pp pp(m); + + pp.set_logic("QF_AUFLIA"); + std::ostringstream buffer; + buffer << "random_arith_" << i << ".smt"; + std::cout << buffer.str() << "\n"; + std::ofstream file(buffer.str().c_str()); + pp.display(file, e.get()); + file.close(); + } + +} + +void tst_expr_rand(unsigned num_files) { + ast_manager m; + + m.register_plugin(symbol("bv"), alloc(bv_decl_plugin)); + m.register_plugin(symbol("array"), alloc(array_decl_plugin)); + + expr_rand er(m); + er.initialize_bv(20); + er.seed(rand_seed); + parameter p1(1); + parameter p2(2); + parameter p8(8); + parameter p32(32); + family_id bvfid = m.get_family_id("bv"); + sort* bv1 = m.mk_sort(bvfid, BV_SORT, 1, &p1); + sort* bv2 = m.mk_sort(bvfid, BV_SORT, 1, &p2); + sort* bv8 = m.mk_sort(bvfid, BV_SORT, 1, &p8); + sort* bv32 = m.mk_sort(bvfid, BV_SORT, 1, &p32); + er.initialize_array(3, bv8, bv32); + er.initialize_array(3, bv1, bv1); + er.initialize_array(3, bv1, bv2); + er.initialize_array(3, bv2, bv1); + er.initialize_array(3, bv2, bv2); + er.initialize_array(3, bv8, bv8); + er.initialize_array(3, bv32, bv32); + er.initialize_basic(20); + + for (unsigned i = 0; i < num_files; ++i) { + expr_ref e(m); + er.get_next(m.mk_bool_sort(), e); + ast_smt_pp pp(m); + + pp.set_logic("QF_AUFBV"); + std::ostringstream buffer; + buffer << "random_bv_" << i << ".smt"; + std::cout << buffer.str() << "\n"; + std::ofstream file(buffer.str().c_str()); + pp.display(file, e.get()); + file.close(); + + } +} + +void tst_expr_rand(char** argv, int argc, int& i) { + if (i + 1 < argc) { + unsigned num_files = atol(argv[i+1]); + i += 1; + if (i + 1 < argc && 0 == strncmp(argv[i+1],"/rs:",3)) { + rand_seed = atol(argv[i+1]+4); + std::cout << "random seed:" << rand_seed << "\n"; + i += 1; + } + + if (i + 1 < argc && 0 == strcmp(argv[i+1],"/arith")) { + tst_expr_arith(num_files); + return; + } + tst_expr_rand(num_files); + } +} diff --git a/test/ext_numeral.cpp b/test/ext_numeral.cpp new file mode 100644 index 000000000..c2f337d68 --- /dev/null +++ b/test/ext_numeral.cpp @@ -0,0 +1,397 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + ext_numeral.cpp + +Abstract: + + Unit tests for ext_numeral template. + +Author: + + Leonardo (leonardo) 2012-07-18 + +Notes: + +--*/ +#include +#include"mpq.h" +#include"ext_numeral.h" + +#define MK_TST_UNARY(NAME) \ +static void tst_ ## NAME(int a, ext_numeral_kind ak, int expected_c, ext_numeral_kind expected_ck) { \ + unsynch_mpq_manager m; \ + scoped_mpq _a(m); \ + m.set(_a, a); \ + NAME(m, _a, ak); \ + SASSERT(ak == expected_ck); \ + if (expected_ck == EN_NUMERAL) { \ + scoped_mpq _expected_c(m); \ + m.set(_expected_c, expected_c); \ + SASSERT(m.eq(_a, _expected_c)); \ + } \ +} + +MK_TST_UNARY(neg); +MK_TST_UNARY(inv); + +#define MK_TST_BIN_CORE(FUN_NAME, OP_NAME) \ +static void FUN_NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, int expected_c, ext_numeral_kind expected_ck) { \ + unsynch_mpq_manager m; \ + scoped_mpq _a(m), _b(m), _c(m); \ + m.set(_a, a); \ + m.set(_b, b); \ + ext_numeral_kind ck; \ + OP_NAME(m, _a, ak, _b, bk, _c, ck); \ + SASSERT(ck == expected_ck); \ + if (expected_ck == EN_NUMERAL) { \ + scoped_mpq _expected_c(m); \ + m.set(_expected_c, expected_c); \ + SASSERT(m.eq(_c, _expected_c)); \ + } \ +} + +#define MK_TST_BIN(NAME) MK_TST_BIN_CORE(tst_ ## NAME, NAME) + +#define MK_TST_COMM_BIN(NAME) \ +MK_TST_BIN_CORE(tst_ ## NAME ## _core, NAME) \ +static void tst_ ## NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, int expected_c, ext_numeral_kind expected_ck) { \ + tst_ ## NAME ## _core(a, ak, b, bk, expected_c, expected_ck); \ + tst_ ## NAME ## _core(b, bk, a, ak, expected_c, expected_ck); \ +} + +MK_TST_COMM_BIN(add); +MK_TST_BIN(sub); +MK_TST_COMM_BIN(mul); + +static void tst1() { + tst_neg(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY); + tst_neg(30, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY); + tst_neg(0, EN_NUMERAL, 0, EN_NUMERAL); + tst_neg(10, EN_NUMERAL, -10, EN_NUMERAL); + tst_neg(-7, EN_NUMERAL, 7, EN_NUMERAL); + tst_neg(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_neg(30, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_neg(-7, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY); + + tst_inv(0, EN_MINUS_INFINITY, 0, EN_NUMERAL); + tst_inv(0, EN_PLUS_INFINITY, 0, EN_NUMERAL); + tst_inv(1, EN_NUMERAL, 1, EN_NUMERAL); + tst_inv(-1, EN_NUMERAL, -1, EN_NUMERAL); + + tst_add(0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_add(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_add(0, EN_MINUS_INFINITY, -1, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_add(0, EN_MINUS_INFINITY, 1, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_add(1, EN_MINUS_INFINITY, -1, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_add(1, EN_NUMERAL, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_add(-1, EN_NUMERAL, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_add(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY); + + tst_add(0, EN_NUMERAL, 2, EN_NUMERAL, 2, EN_NUMERAL); + tst_add(-3, EN_NUMERAL, 4, EN_NUMERAL, 1, EN_NUMERAL); + tst_add(-2, EN_NUMERAL, 0, EN_NUMERAL, -2, EN_NUMERAL); + tst_add(3, EN_NUMERAL, 4, EN_NUMERAL, 7, EN_NUMERAL); + + tst_add(0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY); + tst_add(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_add(0, EN_PLUS_INFINITY, 1, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_add(0, EN_PLUS_INFINITY, -1, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_add(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY); + tst_add(-1, EN_NUMERAL, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY); + tst_add(1, EN_NUMERAL, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY); + + tst_mul(0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY); + tst_mul(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_mul(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_mul(0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY); + + tst_mul(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, 0, EN_NUMERAL); + tst_mul(0, EN_MINUS_INFINITY, 1, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_mul(0, EN_MINUS_INFINITY, 5, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_mul(0, EN_MINUS_INFINITY, -1, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_mul(0, EN_MINUS_INFINITY, -5, EN_NUMERAL, 0, EN_PLUS_INFINITY); + + tst_mul(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, 0, EN_NUMERAL); + tst_mul(0, EN_PLUS_INFINITY, 1, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_mul(0, EN_PLUS_INFINITY, 5, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_mul(0, EN_PLUS_INFINITY, -1, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_mul(0, EN_PLUS_INFINITY, -5, EN_NUMERAL, 0, EN_MINUS_INFINITY); + + tst_mul(0, EN_NUMERAL, 3, EN_NUMERAL, 0, EN_NUMERAL); + tst_mul(2, EN_NUMERAL, 3, EN_NUMERAL, 6, EN_NUMERAL); + tst_mul(-2, EN_NUMERAL, 3, EN_NUMERAL, -6, EN_NUMERAL); + + tst_sub(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY); + tst_sub(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_sub(0, EN_PLUS_INFINITY, -10, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_sub(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, 0, EN_PLUS_INFINITY); + + tst_sub(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_sub(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_sub(0, EN_MINUS_INFINITY, -10, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_sub(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, 0, EN_MINUS_INFINITY); + + tst_sub(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY); + tst_sub(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_sub(0, EN_MINUS_INFINITY, 3, EN_NUMERAL, 0, EN_MINUS_INFINITY); + tst_sub(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, 0, EN_MINUS_INFINITY); + + tst_sub(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY); + tst_sub(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_sub(0, EN_PLUS_INFINITY, 3, EN_NUMERAL, 0, EN_PLUS_INFINITY); + tst_sub(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, 0, EN_PLUS_INFINITY); + + tst_sub(0, EN_NUMERAL, 2, EN_NUMERAL, -2, EN_NUMERAL); + tst_sub(3, EN_NUMERAL, 2, EN_NUMERAL, 1, EN_NUMERAL); + tst_sub(3, EN_NUMERAL, -3, EN_NUMERAL, 6, EN_NUMERAL); + tst_sub(3, EN_NUMERAL, 3, EN_NUMERAL, 0, EN_NUMERAL); + tst_sub(3, EN_NUMERAL, 0, EN_NUMERAL, 3, EN_NUMERAL); + tst_sub(-3, EN_NUMERAL, -5, EN_NUMERAL, 2, EN_NUMERAL); +} + +#define MK_TST_REL_CORE(FUN_NAME, OP_NAME) \ +static void FUN_NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, bool expected) { \ + unsynch_mpq_manager m; \ + scoped_mpq _a(m), _b(m); \ + m.set(_a, a); \ + m.set(_b, b); \ + bool r = OP_NAME(m, _a, ak, _b, bk); \ + SASSERT(r == expected); \ +} + +#define MK_TST_REL(NAME) MK_TST_REL_CORE(tst_ ## NAME, NAME) + +#define MK_TST_SYMM_REL(NAME) \ +MK_TST_REL_CORE(tst_ ## NAME ## _core, NAME) \ +static void tst_ ## NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, bool expected) { \ + tst_ ## NAME ## _core(a, ak, b, bk, expected); \ + tst_ ## NAME ## _core(b, bk, a, ak, expected); \ +} + +MK_TST_SYMM_REL(eq); +MK_TST_SYMM_REL(neq); +MK_TST_REL(lt); +MK_TST_REL(gt); +MK_TST_REL(le); +MK_TST_REL(ge); + +static void tst2() { + tst_eq(0, EN_NUMERAL, 0, EN_NUMERAL, true); + tst_eq(0, EN_NUMERAL, 2, EN_NUMERAL, false); + tst_eq(3, EN_NUMERAL, 0, EN_NUMERAL, false); + tst_eq(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, false); + tst_eq(0, EN_PLUS_INFINITY, 3, EN_NUMERAL, false); + tst_eq(0, EN_PLUS_INFINITY, -2, EN_NUMERAL, false); + tst_eq(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, false); + + tst_neq(0, EN_NUMERAL, 0, EN_NUMERAL, false); + tst_neq(0, EN_NUMERAL, 2, EN_NUMERAL, true); + tst_neq(3, EN_NUMERAL, 0, EN_NUMERAL, true); + tst_neq(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, true); + tst_neq(0, EN_PLUS_INFINITY, 3, EN_NUMERAL, true); + tst_neq(0, EN_PLUS_INFINITY, -2, EN_NUMERAL, true); + tst_neq(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, true); + + tst_lt(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, true); + tst_lt(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, true); + tst_lt(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, true); + tst_lt(30, EN_MINUS_INFINITY, 10, EN_NUMERAL, true); + tst_lt(20, EN_MINUS_INFINITY, 0, EN_NUMERAL, true); + tst_lt(-20, EN_MINUS_INFINITY, -3, EN_NUMERAL, true); + tst_lt(0, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY, true); + tst_lt(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, true); + tst_lt(10, EN_MINUS_INFINITY, -30, EN_PLUS_INFINITY, true); + + tst_lt(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, false); + tst_lt(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, false); + tst_lt(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, false); + tst_lt(30, EN_PLUS_INFINITY, 10, EN_NUMERAL, false); + tst_lt(20, EN_PLUS_INFINITY, 0, EN_NUMERAL, false); + tst_lt(-20, EN_PLUS_INFINITY, -3, EN_NUMERAL, false); + tst_lt(0, EN_PLUS_INFINITY, 10, EN_MINUS_INFINITY, false); + tst_lt(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, false); + tst_lt(10, EN_PLUS_INFINITY, -30, EN_MINUS_INFINITY, false); + + tst_lt(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, true); + tst_lt(20, EN_NUMERAL, 10, EN_PLUS_INFINITY, true); + tst_lt(-20, EN_NUMERAL, -100, EN_PLUS_INFINITY, true); + tst_lt(0, EN_NUMERAL, 10, EN_NUMERAL, true); + tst_lt(0, EN_NUMERAL, 0, EN_NUMERAL, false); + tst_lt(10, EN_NUMERAL, 10, EN_NUMERAL, false); + tst_lt(0, EN_NUMERAL, -3, EN_NUMERAL, false); + tst_lt(30, EN_NUMERAL, 10, EN_NUMERAL, false); + tst_lt(30, EN_NUMERAL, 40, EN_NUMERAL, true); + tst_lt(20, EN_NUMERAL, 0, EN_NUMERAL, false); + tst_lt(-20, EN_NUMERAL, -3, EN_NUMERAL, true); + tst_lt(0, EN_NUMERAL, 10, EN_MINUS_INFINITY, false); + tst_lt(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, false); + tst_lt(10, EN_NUMERAL, -30, EN_MINUS_INFINITY, false); + + tst_le(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, true); + tst_le(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, true); + tst_le(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, true); + tst_le(30, EN_MINUS_INFINITY, 10, EN_NUMERAL, true); + tst_le(20, EN_MINUS_INFINITY, 0, EN_NUMERAL, true); + tst_le(-20, EN_MINUS_INFINITY, -3, EN_NUMERAL, true); + tst_le(0, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY, true); + tst_le(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, true); + tst_le(10, EN_MINUS_INFINITY, -30, EN_PLUS_INFINITY, true); + + tst_le(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, false); + tst_le(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, false); + tst_le(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, false); + tst_le(30, EN_PLUS_INFINITY, 10, EN_NUMERAL, false); + tst_le(20, EN_PLUS_INFINITY, 0, EN_NUMERAL, false); + tst_le(-20, EN_PLUS_INFINITY, -3, EN_NUMERAL, false); + tst_le(0, EN_PLUS_INFINITY, 10, EN_MINUS_INFINITY, false); + tst_le(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, false); + tst_le(10, EN_PLUS_INFINITY, -30, EN_MINUS_INFINITY, false); + + tst_le(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, true); + tst_le(20, EN_NUMERAL, 10, EN_PLUS_INFINITY, true); + tst_le(-20, EN_NUMERAL, -100, EN_PLUS_INFINITY, true); + tst_le(0, EN_NUMERAL, 10, EN_NUMERAL, true); + tst_le(0, EN_NUMERAL, 0, EN_NUMERAL, true); + tst_le(10, EN_NUMERAL, 10, EN_NUMERAL, true); + tst_le(0, EN_NUMERAL, -3, EN_NUMERAL, false); + tst_le(30, EN_NUMERAL, 10, EN_NUMERAL, false); + tst_le(30, EN_NUMERAL, 40, EN_NUMERAL, true); + tst_le(20, EN_NUMERAL, 0, EN_NUMERAL, false); + tst_le(-20, EN_NUMERAL, -3, EN_NUMERAL, true); + tst_le(0, EN_NUMERAL, 10, EN_MINUS_INFINITY, false); + tst_le(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, false); + tst_le(10, EN_NUMERAL, -30, EN_MINUS_INFINITY, false); + + + tst_ge(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, false); + tst_ge(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, false); + tst_ge(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, false); + tst_ge(30, EN_MINUS_INFINITY, 10, EN_NUMERAL, false); + tst_ge(20, EN_MINUS_INFINITY, 0, EN_NUMERAL, false); + tst_ge(-20, EN_MINUS_INFINITY, -3, EN_NUMERAL, false); + tst_ge(0, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY, false); + tst_ge(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, false); + tst_ge(10, EN_MINUS_INFINITY, -30, EN_PLUS_INFINITY, false); + + tst_ge(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, true); + tst_ge(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, true); + tst_ge(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, true); + tst_ge(30, EN_PLUS_INFINITY, 10, EN_NUMERAL, true); + tst_ge(20, EN_PLUS_INFINITY, 0, EN_NUMERAL, true); + tst_ge(-20, EN_PLUS_INFINITY, -3, EN_NUMERAL, true); + tst_ge(0, EN_PLUS_INFINITY, 10, EN_MINUS_INFINITY, true); + tst_ge(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, true); + tst_ge(10, EN_PLUS_INFINITY, -30, EN_MINUS_INFINITY, true); + + tst_ge(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, false); + tst_ge(20, EN_NUMERAL, 10, EN_PLUS_INFINITY, false); + tst_ge(-20, EN_NUMERAL, -100, EN_PLUS_INFINITY, false); + tst_ge(0, EN_NUMERAL, 10, EN_NUMERAL, false); + tst_ge(0, EN_NUMERAL, 0, EN_NUMERAL, true); + tst_ge(10, EN_NUMERAL, 10, EN_NUMERAL, true); + tst_ge(0, EN_NUMERAL, -3, EN_NUMERAL, true); + tst_ge(30, EN_NUMERAL, 10, EN_NUMERAL, true); + tst_ge(30, EN_NUMERAL, 40, EN_NUMERAL, false); + tst_ge(20, EN_NUMERAL, 0, EN_NUMERAL, true); + tst_ge(-20, EN_NUMERAL, -3, EN_NUMERAL, false); + tst_ge(0, EN_NUMERAL, 10, EN_MINUS_INFINITY, true); + tst_ge(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, true); + tst_ge(10, EN_NUMERAL, -30, EN_MINUS_INFINITY, true); + + + tst_gt(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, false); + tst_gt(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, false); + tst_gt(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, false); + tst_gt(30, EN_MINUS_INFINITY, 10, EN_NUMERAL, false); + tst_gt(20, EN_MINUS_INFINITY, 0, EN_NUMERAL, false); + tst_gt(-20, EN_MINUS_INFINITY, -3, EN_NUMERAL, false); + tst_gt(0, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY, false); + tst_gt(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, false); + tst_gt(10, EN_MINUS_INFINITY, -30, EN_PLUS_INFINITY, false); + + tst_gt(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, true); + tst_gt(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, true); + tst_gt(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, true); + tst_gt(30, EN_PLUS_INFINITY, 10, EN_NUMERAL, true); + tst_gt(20, EN_PLUS_INFINITY, 0, EN_NUMERAL, true); + tst_gt(-20, EN_PLUS_INFINITY, -3, EN_NUMERAL, true); + tst_gt(0, EN_PLUS_INFINITY, 10, EN_MINUS_INFINITY, true); + tst_gt(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, true); + tst_gt(10, EN_PLUS_INFINITY, -30, EN_MINUS_INFINITY, true); + + tst_gt(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, false); + tst_gt(20, EN_NUMERAL, 10, EN_PLUS_INFINITY, false); + tst_gt(-20, EN_NUMERAL, -100, EN_PLUS_INFINITY, false); + tst_gt(0, EN_NUMERAL, 10, EN_NUMERAL, false); + tst_gt(0, EN_NUMERAL, 0, EN_NUMERAL, false); + tst_gt(10, EN_NUMERAL, 10, EN_NUMERAL, false); + tst_gt(0, EN_NUMERAL, -3, EN_NUMERAL, true); + tst_gt(30, EN_NUMERAL, 10, EN_NUMERAL, true); + tst_gt(30, EN_NUMERAL, 40, EN_NUMERAL, false); + tst_gt(20, EN_NUMERAL, 0, EN_NUMERAL, true); + tst_gt(-20, EN_NUMERAL, -3, EN_NUMERAL, false); + tst_gt(0, EN_NUMERAL, 10, EN_MINUS_INFINITY, true); + tst_gt(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, true); + tst_gt(10, EN_NUMERAL, -30, EN_MINUS_INFINITY, true); +} + +static void tst3() { + unsynch_mpq_manager m; + scoped_mpq a(m); + SASSERT(is_zero(m, a, EN_NUMERAL)); + SASSERT(!is_zero(m, a, EN_PLUS_INFINITY)); + SASSERT(!is_zero(m, a, EN_MINUS_INFINITY)); + SASSERT(!is_pos(m, a, EN_NUMERAL)); + SASSERT(is_pos(m, a, EN_PLUS_INFINITY)); + SASSERT(!is_pos(m, a, EN_MINUS_INFINITY)); + SASSERT(!is_infinite(EN_NUMERAL)); + SASSERT(is_infinite(EN_PLUS_INFINITY)); + SASSERT(is_infinite(EN_MINUS_INFINITY)); + SASSERT(!is_neg(m, a, EN_NUMERAL)); + SASSERT(!is_neg(m, a, EN_PLUS_INFINITY)); + SASSERT(is_neg(m, a, EN_MINUS_INFINITY)); + m.set(a, 10); + SASSERT(!is_zero(m, a, EN_NUMERAL)); + SASSERT(is_pos(m, a, EN_NUMERAL)); + SASSERT(!is_neg(m, a, EN_NUMERAL)); + SASSERT(!is_infinite(EN_NUMERAL)); + m.set(a, -5); + SASSERT(!is_zero(m, a, EN_NUMERAL)); + SASSERT(!is_pos(m, a, EN_NUMERAL)); + SASSERT(is_neg(m, a, EN_NUMERAL)); + SASSERT(!is_infinite(EN_NUMERAL)); + ext_numeral_kind ak; + ak = EN_MINUS_INFINITY; + reset(m, a, ak); + SASSERT(is_zero(m, a, EN_NUMERAL)); + { + std::ostringstream buffer; + display(buffer, m, a, ak); + SASSERT(buffer.str() == "0"); + } + { + std::ostringstream buffer; + m.set(a, -10); + display(buffer, m, a, ak); + SASSERT(buffer.str() == "-10"); + } + { + std::ostringstream buffer; + display(buffer, m, a, EN_PLUS_INFINITY); + SASSERT(buffer.str() == "oo"); + } + { + std::ostringstream buffer; + display(buffer, m, a, EN_MINUS_INFINITY); + SASSERT(buffer.str() == "-oo"); + } +} + +void tst_ext_numeral() { + tst1(); + tst2(); + tst3(); +} diff --git a/test/f2n.cpp b/test/f2n.cpp new file mode 100644 index 000000000..0ae9ea1dd --- /dev/null +++ b/test/f2n.cpp @@ -0,0 +1,68 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + f2n.cpp + +Abstract: + + +Author: + + Leonardo de Moura (leonardo) 2012-08-17. + +Revision History: + +--*/ +#include"f2n.h" +#include"hwf.h" +#include"mpf.h" + +static void tst1() { + hwf_manager hm; + f2n m(hm); + hwf a, b; + m.set(a, 11, 3); + m.floor(a, b); + std::cout << "floor(11/3): " << m.to_double(b) << "\n"; + m.ceil(a, b); + std::cout << "ceil(11/3): " << m.to_double(b) << "\n"; + m.set(a, -11, 3); + m.floor(a, b); + std::cout << "floor(-11/3): " << m.to_double(b) << "\n"; + m.ceil(a, b); + std::cout << "ceil(-11/3): " << m.to_double(b) << "\n"; + m.set(a, 11, 1); + m.floor(a, b); + std::cout << "floor(11): " << m.to_double(b) << "\n"; + m.ceil(a, b); + std::cout << "ceil(11): " << m.to_double(b) << "\n"; +} + +static void tst2() { + std::cout << "using mpf...\n"; + mpf_manager fm; + f2n m(fm); + scoped_mpf a(fm), b(fm); + m.set(a, 11, 3); + m.floor(a, b); + std::cout << "floor(11/3): " << m.to_double(b) << "\n"; + m.ceil(a, b); + std::cout << "ceil(11/3): " << m.to_double(b) << "\n"; + m.set(a, -11, 3); + m.floor(a, b); + std::cout << "floor(-11/3): " << m.to_double(b) << "\n"; + m.ceil(a, b); + std::cout << "ceil(-11/3): " << m.to_double(b) << "\n"; + m.set(a, 11, 1); + m.floor(a, b); + std::cout << "floor(11): " << m.to_double(b) << "\n"; + m.ceil(a, b); + std::cout << "ceil(11): " << m.to_double(b) << "\n"; +} + +void tst_f2n() { + tst1(); + tst2(); +} diff --git a/test/factor_rewriter.cpp b/test/factor_rewriter.cpp new file mode 100644 index 000000000..110df86a3 --- /dev/null +++ b/test/factor_rewriter.cpp @@ -0,0 +1,18 @@ +#include "factor_rewriter.h" +#include "bv_decl_plugin.h" +#include "ast_pp.h" + +void tst_factor_rewriter() { + ast_manager m; + m.register_decl_plugins(); + + factor_rewriter_star fw(m); + arith_util a(m); + expr_ref fml1(m), fml2(m); + expr_ref z(m.mk_const(symbol("z"), a.mk_real()), m); + expr_ref two(a.mk_numeral(rational(2),false),m); + expr_ref zero(a.mk_numeral(rational(0),false),m); + fml1 = a.mk_le(zero, a.mk_mul(two, z, z)); + fw(fml1, fml2); + std::cout << mk_pp(fml1, m) << " -> " << mk_pp(fml2, m) << "\n"; +} diff --git a/test/fingerprint.cpp b/test/fingerprint.cpp new file mode 100644 index 000000000..396009f0c --- /dev/null +++ b/test/fingerprint.cpp @@ -0,0 +1,101 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + fingerprint.cpp + +Abstract: + + Test fingerprint support + +Author: + + Leonardo de Moura (leonardo) 2006-10-29. + +Revision History: + +--*/ +#include"core_theory.h" + +bool add_fingerprint(core_theory & t, void * data, enode * n1) { + enode * c[1]; + c[0] = n1; + return t.add_fingerprint(data, 1, c); +} + +bool add_fingerprint(core_theory & t, void * data, enode * n1, enode * n2) { + enode * c[2]; + c[0] = n1; + c[1] = n2; + return t.add_fingerprint(data, 2, c); +} + +bool add_fingerprint(core_theory & t, void * data, enode * n1, enode * n2, enode * n3, enode * n4, enode * n5, enode * n6, enode * n7, enode * n8, enode * n9) { + enode * c[9]; + c[0] = n1; + c[1] = n2; + c[2] = n3; + c[3] = n4; + c[4] = n5; + c[5] = n6; + c[6] = n7; + c[7] = n8; + c[8] = n9; + return t.add_fingerprint(data, 9, c); +} + +class fingerprint_tester { + + static void tst1() { + core_theory t; + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + void * d1 = reinterpret_cast(1); + + SASSERT(add_fingerprint(t, 0, n1)); + SASSERT(!add_fingerprint(t, 0, n1)); + SASSERT(add_fingerprint(t, 0, n2)); + + SASSERT(add_fingerprint(t, d1, n1)); + SASSERT(!add_fingerprint(t, d1, n1)); + SASSERT(add_fingerprint(t, d1, n2)); + SASSERT(add_fingerprint(t, d1, n1, n2)); + SASSERT(add_fingerprint(t, d1, n2, n1)); + SASSERT(!add_fingerprint(t, d1, n1, n2)); + SASSERT(!add_fingerprint(t, d1, n2, n1)); + + t.push_scope(); + + SASSERT(add_fingerprint(t, 0, n3)); + SASSERT(add_fingerprint(t, d1, n3)); + SASSERT(add_fingerprint(t, d1, n1, n1, n1, n1, n1, n1, n2, n1, n2)); + SASSERT(!add_fingerprint(t, d1, n1, n1, n1, n1, n1, n1, n2, n1, n2)); + SASSERT(add_fingerprint(t, d1, n1, n1, n1, n1, n1, n1, n2, n1, n1)); + SASSERT(!add_fingerprint(t, d1, n1, n1, n1, n1, n1, n1, n2, n1, n1)); + + t.pop_scope(1); + + SASSERT(!add_fingerprint(t, 0, n1)); + SASSERT(!add_fingerprint(t, 0, n2)); + SASSERT(!add_fingerprint(t, d1, n1, n2)); + SASSERT(!add_fingerprint(t, d1, n2, n1)); + SASSERT(add_fingerprint(t, 0, n3)); + SASSERT(add_fingerprint(t, d1, n3)); + SASSERT(add_fingerprint(t, d1, n1, n1, n1, n1, n1, n1, n2, n1, n2)); + SASSERT(!add_fingerprint(t, d1, n1, n1, n1, n1, n1, n1, n2, n1, n2)); + SASSERT(add_fingerprint(t, d1, n1, n1, n1, n1, n1, n1, n2, n1, n1)); + SASSERT(!add_fingerprint(t, d1, n1, n1, n1, n1, n1, n1, n2, n1, n1)); + } + +public: + + static void run_tests() { + tst1(); + } +}; + +void tst_fingerprint() { + fingerprint_tester::run_tests(); +} diff --git a/test/for_each_file.cpp b/test/for_each_file.cpp new file mode 100644 index 000000000..d217aa5f1 --- /dev/null +++ b/test/for_each_file.cpp @@ -0,0 +1,79 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + foreach_file.cpp + +Abstract: + + Traverse files in a directory that match a given suffix. + Apply a method to each of the files. + +Author: + + Nikolaj Bjorner (nbjorner) 2006-11-3. + +Revision History: + +--*/ +#ifdef _WINDOWS +#include +#include +#include +#include "for_each_file.h" + +bool for_each_file(for_each_file_proc& proc, const char* base, const char* suffix) +{ + std::string pattern(base); + pattern += "\\"; + pattern += suffix; + + char buffer[MAX_PATH]; + + WIN32_FIND_DATAA data; + HANDLE h = FindFirstFileA(pattern.c_str(),&data); + + while (h != INVALID_HANDLE_VALUE) { + + StringCchPrintfA(buffer, ARRAYSIZE(buffer), "%s\\%s", base, data.cFileName); + + if (!proc(buffer)) { + return false; + } + + if (!FindNextFileA(h,&data)) { + break; + } + } + + // + // Now recurse through sub-directories. + // + + pattern = base; + pattern += "\\*"; + h = FindFirstFileA(pattern.c_str(),&data); + + while (h != INVALID_HANDLE_VALUE) { + + if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + data.cFileName[0] != '.' + ){ + std::string subdir(base); + subdir += "\\"; + subdir += data.cFileName; + if (!for_each_file(proc, subdir.c_str(), suffix)) { + return false; + } + } + + if (!FindNextFileA(h,&data)) { + break; + } + } + + return true; +}; +#endif + diff --git a/test/for_each_file.h b/test/for_each_file.h new file mode 100644 index 000000000..29fad7c3c --- /dev/null +++ b/test/for_each_file.h @@ -0,0 +1,33 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + foreach_file.h + +Abstract: + + Traverse files in a directory that match a given suffix. + Apply a method to each of the files. + +Author: + + Nikolaj Bjorner (nbjorner) 2006-11-3. + +Revision History: + +--*/ +#pragma once + +#ifndef _FOR_EACH_FILE_H_ +#define _FOR_EACH_FILE_H_ + +struct for_each_file_proc { + virtual bool operator()(const char* file_path) = 0; +}; + +bool for_each_file(for_each_file_proc& proc, const char* base, const char* suffix); + + +#endif /* _FOR_EACH_FILE_H_ */ + diff --git a/test/fvi.cpp b/test/fvi.cpp new file mode 100644 index 000000000..6861699a8 --- /dev/null +++ b/test/fvi.cpp @@ -0,0 +1,158 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + fvi.cpp + +Abstract: + + Feature Vector Indexing. + +Author: + + Leonardo de Moura (leonardo) 2008-02-01. + +Revision History: + +--*/ +#ifdef _WINDOWS +#include"fvi_def.h" +#include"trace.h" + +typedef vector data; + +static int to_feature(int val) { + return val % 4; +} + +static std::ostream & operator<<(std::ostream & out, data const & d) { + out << "["; + data::const_iterator it = d.begin(); + data::const_iterator end = d.end(); + for (bool first = true; it != end; ++it, first = false) + out << (first ? "" : " ") << *it << ":" << to_feature(*it); + out << "]"; + return out; +} + +#define NUM_FEATURES 5 + +struct to_feature_vector { + unsigned m_num_features; + + to_feature_vector(unsigned n):m_num_features(n) {} + + void operator()(data * d, unsigned * f) { + for (unsigned i = 0; i < m_num_features; i++) { + f[i] = to_feature((*d)[i]); + } + } +}; + +struct data_hash { + unsigned operator()(data * d) const { + unsigned r = 0; + data::iterator it = d->begin(); + data::iterator end = d->end(); + for (; it != end; ++it) + r += *it; + return r; + } +}; + +ptr_vector g_datas; + +static void collect() { + std::for_each(g_datas.begin(), g_datas.end(), delete_proc()); +} + +static data * mk_random_data() { + data * d = alloc(data); + for (unsigned i = 0; i < NUM_FEATURES; i++) + d->push_back(rand() % 1000); + g_datas.push_back(d); + return d; +} + +struct le_visitor { + data * m_data; + + le_visitor(data * d):m_data(d) {} + + bool operator()(data * other) { + // TRACE("fvi", tout << *other << " <= " << *m_data << "\n";); + for (unsigned i = 0; i < NUM_FEATURES; i++) { + SASSERT(to_feature((*other)[i]) <= to_feature((*m_data)[i])); + } + return true; + } +}; + +static void tst1(unsigned n1) { + typedef fvi data_set; + data_set index1(NUM_FEATURES, to_feature_vector(NUM_FEATURES)); + ptr_vector index2; + + for (unsigned i = 0; i < n1; i++) { + int op = rand()%6; + if (op < 3) { + data * d = mk_random_data(); + if (!index1.contains(d)) { + // TRACE("fvi", tout << "inserting: " << *d << "\n";); + index1.insert(d); + index2.push_back(d); + SASSERT(std::find(index2.begin(), index2.end(), d) != index2.end()); + SASSERT(index1.contains(d)); + } + } + else if (op < 4) { + if (!index2.empty()) { + unsigned idx = rand() % index2.size(); + if (index2[idx]) { + SASSERT(index1.contains(index2[idx])); + } + } + } + else if (op < 5) { + if (!index2.empty()) { + unsigned idx = rand() % index2.size(); + if (index2[idx]) { + // TRACE("fvi", tout << "erasing: " << *(index2[idx]) << "\n";); + index1.erase(index2[idx]); + SASSERT(!index1.contains(index2[idx])); + index2[idx] = 0; + } + } + } + else { + if (!index2.empty()) { + unsigned idx = rand() % index2.size(); + data * d = index2[idx]; + if (d) + index1.visit(d, le_visitor(d)); + } + } + } + + TRACE("fvi", + data_set::statistics s; + index1.stats(s); + tout << "size: " << s.m_size << "\n"; + tout << "num. nodes: " << s.m_num_nodes << "\n"; + tout << "num. leaves: " << s.m_num_leaves << "\n"; + tout << "min. leaf size: " << s.m_min_leaf_size << "\n"; + tout << "max. leaf size: " << s.m_max_leaf_size << "\n"; + ); +} + +void tst_fvi() { + for (unsigned i = 0; i < 1000; i++) + tst1(100); + tst1(10000); + collect(); +} +#else +void tst_fvi() { +} +#endif diff --git a/test/gate.cpp b/test/gate.cpp new file mode 100644 index 000000000..8acabc9ec --- /dev/null +++ b/test/gate.cpp @@ -0,0 +1,472 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + gate.cpp + +Abstract: + + Test SAT gates + +Author: + + Leonardo de Moura (leonardo) 2006-11-02. + +Revision History: + +--*/ +#include"sat_def.h" + +class gate_extension : public no_extension { +public: + bool relevancy_enabled() { + return true; + } + + bool gates_enabled() { + return true; + } +}; + + +class gate_no_rel_extension : public no_extension { +public: + bool relevancy_enabled() { + return false; + } + + bool gates_enabled() { + return true; + } +}; + +class sat_gate_tester { + + static void tst1() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + + SASSERT(solver.mk_or(l1, l2, l3) == solver.mk_or(l3, l1, l2)); + + SASSERT(solver.mk_or(l1, l1, l3) == solver.mk_or(l3, l1)); + + SASSERT(solver.mk_or(l1, l1, l1) == l1); + + SASSERT(solver.mk_or(l1, false_literal, l1) == l1); + + SASSERT(solver.mk_or(l1, true_literal, l1) == true_literal); + + solver.assert_lit(l1); + + SASSERT(solver.mk_or(l1, l2, l3) == true_literal); + + literal l4 = solver.mk_or(l2, l3); + + SASSERT(l4 != true_literal && l4 != false_literal); + + solver.push(); + + solver.assert_lit(l2); + + solver.propagate(); + + SASSERT(solver.get_assignment(l4) == l_true); + + solver.pop(1); + + SASSERT(solver.get_assignment(l4) == l_undef); + + solver.push(); + + solver.assert_lit(~l2); + + solver.assert_lit(~l3); + + solver.propagate(); + + SASSERT(solver.get_assignment(l4) == l_false); + + solver.pop(1); + + SASSERT(solver.get_assignment(l4) == l_undef); + + SASSERT(l4 == ~solver.mk_and(~l2, ~l3)); + } + + static void tst1a() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + + SASSERT(solver.mk_or(l1, l2, l3) == solver.mk_or(l3, l1, l2)); + + SASSERT(solver.mk_or(l1, l1, l3) == solver.mk_or(l3, l1)); + + SASSERT(solver.mk_or(l1, l1, l1) == l1); + + SASSERT(solver.mk_or(l1, false_literal, l1) == l1); + + SASSERT(solver.mk_or(l1, true_literal, l1) == true_literal); + + solver.assert_lit(l1); + + SASSERT(solver.mk_or(l1, l2, l3) != true_literal); + + literal l4 = solver.mk_or(l2, l3); + + SASSERT(l4 != true_literal && l4 != false_literal); + + solver.push(); + + solver.assert_lit(l2); + + solver.propagate(); + + SASSERT(solver.get_assignment(l4) == l_true); + + solver.pop(1); + + SASSERT(solver.get_assignment(l4) == l_undef); + + solver.push(); + + solver.assert_lit(~l2); + + solver.assert_lit(~l3); + + solver.propagate(); + + SASSERT(solver.get_assignment(l4) == l_false); + + solver.pop(1); + + SASSERT(solver.get_assignment(l4) == l_undef); + + SASSERT(l4 == ~solver.mk_and(~l2, ~l3)); + } + + static void tst2() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + + SASSERT(solver.mk_iff(l1, l2) == solver.mk_iff(l2, l1)); + + SASSERT(solver.mk_iff(l1, true_literal) == l1); + + SASSERT(solver.mk_iff(l1, false_literal) == ~l1); + + SASSERT(solver.mk_iff(true_literal, l2) == l2); + + SASSERT(solver.mk_iff(false_literal, l2) == ~l2); + + SASSERT(solver.mk_iff(l1, l1) == true_literal); + + SASSERT(solver.mk_iff(l1, ~l1) == false_literal); + } + + static void tst3() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + + solver.push(); + + literal l3 = solver.mk_or(l1, l2); + SASSERT(solver.m_ref_count[l3.var()] == 1); + + solver.pop(1); + } + + static void tst4() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + + literal l3 = solver.mk_or(l1, l2); + + solver.reset(); + + l1 = solver.mk_var(); + + } + + static void tst5() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + + solver.push_scope(); + + solver.assign(l1, mk_axiom()); + + solver.propagate(); + + solver.push_scope(); + + literal l4 = solver.mk_or(l1, l2); + + solver.mk_main_clause(l4, l3); + + SASSERT(solver.get_assignment(l4) == l_true); + + solver.pop_scope(1); + + SASSERT(solver.get_assignment(l4) == l_true); + } + + static void tst6() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + literal l4 = solver.mk_var(); + + SASSERT(solver.mk_ite(l1, l2, l3) == solver.mk_ite(~l1, l3, l2)); + + SASSERT(solver.mk_ite(l1, l2, l2) == l2); + + solver.assert_lit(l1); + + solver.push_scope(); + + SASSERT(solver.mk_ite(l1, l2, l3) == l2); + + SASSERT(solver.mk_ite(~l1, l2, l3) == l3); + } + + static void tst6a() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + literal l4 = solver.mk_var(); + + SASSERT(solver.mk_ite(l1, l2, l3) == solver.mk_ite(~l1, l3, l2)); + + SASSERT(solver.mk_ite(l1, l2, l2) == l2); + + solver.assert_lit(l1); + + solver.push_scope(); + + SASSERT(solver.mk_ite(l1, l2, l3) != l2); + + SASSERT(solver.mk_ite(~l1, l2, l3) != l3); + } + + static void tst7() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_uniq(l1); + SASSERT(l1 != l2); + + solver.push(); + + solver.assert_lit(l1); + solver.propagate(); + + SASSERT(solver.get_assignment(l1) == l_true); + SASSERT(solver.get_assignment(l2) == l_true); + + solver.pop(1); + solver.propagate(); + + SASSERT(solver.get_assignment(l1) == l_undef); + SASSERT(solver.get_assignment(l2) == l_undef); + + solver.assert_lit(~l1); + solver.propagate(); + + SASSERT(solver.get_assignment(l1) == l_false); + SASSERT(solver.get_assignment(l2) == l_false); + } + + static void tst8() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_uniq(l1); + SASSERT(l1 != l2); + + solver.push_scope(); + + solver.assert_lit(l1); + solver.propagate(); + + SASSERT(solver.get_assignment(l1) == l_true); + SASSERT(solver.get_assignment(l2) == l_true); + + solver.pop_scope(1); + solver.propagate(); + + SASSERT(solver.get_assignment(l1) == l_true); + SASSERT(solver.get_assignment(l2) == l_true); + } + + static void tst9() { + sat_solver s; + + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + literal l3 = s.mk_var(); + + s.push_scope(); + s.assign(l1, mk_axiom()); + s.push_scope(); + literal l4 = s.mk_var(); + literal l5 = s.mk_var(); + literal l6 = s.mk_or(l4, l5); + s.assign(l6, mk_axiom()); + s.mk_transient_clause(~l6, l3); + s.mk_transient_clause(~l6, l2); + s.mk_transient_clause(literal_vector(~l3, ~l1, ~l2)); + SASSERT(s.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + s.resolve_conflict(); + SASSERT(r); + SASSERT(s.m_scope_lvl == 1); + SASSERT(s.m_ref_count[l4.var()] > 0); + SASSERT(s.m_ref_count[l5.var()] > 0); + SASSERT(s.m_ref_count[l6.var()] > 0); + s.pop_scope(1); + SASSERT(s.get_assignment(l1) == l_undef); + SASSERT(s.get_assignment(l4) == l_undef); + SASSERT(s.get_assignment(l5) == l_undef); + SASSERT(s.get_assignment(l6) == l_undef); + SASSERT(s.m_ref_count[l4.var()] > 0); + SASSERT(s.m_ref_count[l5.var()] > 0); + SASSERT(s.m_ref_count[l6.var()] > 0); + s.push_scope(); + s.assign(~l4, mk_axiom()); + s.propagate(); +#ifdef Z3DEBUG + s.del_learned_clauses(); +#endif + s.pop_scope(1); + } + + static void tst10() { + sat_solver s; + + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + literal l3 = s.mk_var(); + + s.push_scope(); + s.assign(l1, mk_axiom()); + s.push_scope(); + literal l4 = s.mk_var(); + literal l5 = s.mk_var(); + literal l6 = s.mk_iff(l4, l5); + literal l7 = s.mk_var(); + literal l8 = s.mk_or(l6, l7); + s.assign(l8, mk_axiom()); + s.mk_transient_clause(~l8, l3); + s.mk_transient_clause(~l8, l2); + s.mk_transient_clause(literal_vector(~l3, ~l1, ~l2)); + SASSERT(s.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + s.resolve_conflict(); + SASSERT(r); + SASSERT(s.m_scope_lvl == 1); + s.pop_scope(1); + SASSERT(s.m_ref_count[l4.var()] > 0); + SASSERT(s.m_ref_count[l5.var()] > 0); + SASSERT(s.m_ref_count[l6.var()] > 0); + SASSERT(s.m_ref_count[l7.var()] > 0); + SASSERT(s.m_ref_count[l8.var()] > 0); + s.push_scope(); + s.assign(~l1, mk_axiom()); + s.push_scope(); + s.assign(l5, mk_axiom()); + s.mk_transient_clause(~l5, ~l4); + s.propagate(); + SASSERT(s.get_assignment(l6) == l_false); + SASSERT(s.get_assignment(l8) == l_undef); +#ifdef Z3DEBUG + s.del_learned_clauses(); + SASSERT(s.m_ref_count[l7.var()] == 0); + SASSERT(s.m_ref_count[l8.var()] == 0); + SASSERT(s.m_ref_count[l4.var()] > 0); + SASSERT(s.m_ref_count[l5.var()] > 0); + SASSERT(s.m_ref_count[l6.var()] > 0); +#endif + s.mk_transient_clause(l6, l3); + s.mk_transient_clause(l6, l2); + s.mk_transient_clause(literal_vector(~l3, l1, ~l2)); + SASSERT(s.inconsistent()); +#ifdef Z3DEBUG + r = +#endif + s.resolve_conflict(); + SASSERT(r); + } + + static void tst11() { + sat_solver s; + + literal l0 = s.mk_var(); + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + + s.push_scope(); + s.assign(~l1, mk_axiom()); + s.assign(~l2, mk_axiom()); + s.push_scope(); + literal l3 = s.mk_or(l1, l2); + SASSERT(s.get_assignment(l3) == l_false); + s.mk_main_clause(l0, l1, l3); + SASSERT(s.m_ref_count[l3.var()] == 3); + s.pop_scope(1); + SASSERT(s.m_ref_count[l3.var()] == 2); + SASSERT(s.get_assignment(l3) == l_false); + s.assert_lit(l1); + s.propagate(); + SASSERT(s.inconsistent()); + } + +public: + static void run_tests() { + enable_trace("del_gate"); + enable_trace("sat_solver"); + enable_trace("gate"); + enable_trace("del_learned_clauses"); + tst1(); + tst1a(); + tst2(); + tst3(); + tst4(); + tst5(); + tst6(); + tst6a(); + tst7(); + tst8(); + tst9(); + tst10(); + tst11(); + } +}; + +void tst_gate() { + sat_gate_tester::run_tests(); +} diff --git a/test/get_implied_equalities.cpp b/test/get_implied_equalities.cpp new file mode 100644 index 000000000..223689bbd --- /dev/null +++ b/test/get_implied_equalities.cpp @@ -0,0 +1,115 @@ +#include "z3.h" +#include "trace.h" +#include "debug.h" + +static Z3_ast mk_var(Z3_context ctx, char const* name, Z3_sort s) { + return Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, name), s); +} + +static Z3_ast mk_int_var(Z3_context ctx, char const* name) { + return mk_var(ctx, name, Z3_mk_int_sort(ctx)); +} + + + +static void tst_get_implied_equalities1() { + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_del_config(cfg); + Z3_sort int_ty = Z3_mk_int_sort(ctx); + Z3_ast a = mk_int_var(ctx,"a"); + Z3_ast b = mk_int_var(ctx,"b"); + Z3_ast c = mk_int_var(ctx,"c"); + Z3_ast d = mk_int_var(ctx,"d"); + Z3_func_decl f = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx,"f"), 1, &int_ty, int_ty); + Z3_ast fa = Z3_mk_app(ctx, f, 1, &a); + Z3_ast fb = Z3_mk_app(ctx, f, 1, &b); + Z3_ast fc = Z3_mk_app(ctx, f, 1, &c); + unsigned const num_terms = 7; + unsigned i; + Z3_ast terms[7] = { a, b, c, d, fa, fb, fc }; + unsigned class_ids[7] = { 0, 0, 0, 0, 0, 0, 0 }; + + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, a, b)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, b, d)); + Z3_assert_cnstr(ctx, Z3_mk_le(ctx, fa, fc)); + Z3_assert_cnstr(ctx, Z3_mk_le(ctx, fc, d)); + + Z3_get_implied_equalities(ctx, num_terms, terms, class_ids); + for (i = 0; i < num_terms; ++i) { + printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); + } + SASSERT(class_ids[1] == class_ids[0]); + SASSERT(class_ids[2] != class_ids[0]); + SASSERT(class_ids[3] == class_ids[0]); + SASSERT(class_ids[4] != class_ids[0]); + SASSERT(class_ids[5] != class_ids[0]); + SASSERT(class_ids[6] != class_ids[0]); + SASSERT(class_ids[4] == class_ids[5]); + + printf("asserting b <= f(a)\n"); + Z3_assert_cnstr(ctx, Z3_mk_le(ctx, b, fa)); + Z3_get_implied_equalities(ctx, num_terms, terms, class_ids); + for (i = 0; i < num_terms; ++i) { + printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); + } + SASSERT(class_ids[1] == class_ids[0]); + SASSERT(class_ids[2] != class_ids[0]); + SASSERT(class_ids[3] == class_ids[0]); + SASSERT(class_ids[4] == class_ids[0]); + SASSERT(class_ids[5] == class_ids[0]); + SASSERT(class_ids[6] == class_ids[0]); + + + /* delete logical context */ + Z3_del_context(ctx); +} + +static void tst_get_implied_equalities2() { + enable_trace("after_search"); + enable_trace("get_implied_equalities"); + enable_trace("implied_equalities"); + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_del_config(cfg); + Z3_sort int_ty = Z3_mk_int_sort(ctx); + Z3_sort a_ty = Z3_mk_array_sort(ctx, int_ty, int_ty); + Z3_ast a = mk_int_var(ctx,"a"); + Z3_ast b = mk_int_var(ctx,"b"); + Z3_ast c = mk_int_var(ctx,"c"); + Z3_ast d = mk_int_var(ctx,"d"); + Z3_ast one = Z3_mk_numeral(ctx, "1", int_ty); + Z3_ast two = Z3_mk_numeral(ctx, "2", int_ty); + Z3_ast x = Z3_mk_const_array(ctx, int_ty, one); + Z3_ast y = Z3_mk_store(ctx, x, one, a); + Z3_ast z = Z3_mk_store(ctx, y, two , b); + Z3_ast u = Z3_mk_store(ctx, x, two , b); + Z3_ast v = Z3_mk_store(ctx, u, one , a); + unsigned const num_terms = 5; + unsigned i; + Z3_ast terms[5] = { x, y, z, u, v}; + unsigned class_ids[5] = { 0, 0, 0, 0, 0}; + + Z3_get_implied_equalities(ctx, num_terms, terms, class_ids); + for (i = 0; i < num_terms; ++i) { + printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); + } + + SASSERT(class_ids[1] != class_ids[0]); + SASSERT(class_ids[2] != class_ids[0]); + SASSERT(class_ids[3] != class_ids[0]); + SASSERT(class_ids[4] != class_ids[0]); + SASSERT(class_ids[4] == class_ids[2]); + SASSERT(class_ids[2] != class_ids[1]); + SASSERT(class_ids[3] != class_ids[1]); + SASSERT(class_ids[4] != class_ids[1]); + SASSERT(class_ids[3] != class_ids[2]); + + /* delete logical context */ + Z3_del_context(ctx); +} + +void tst_get_implied_equalities() { + tst_get_implied_equalities1(); + tst_get_implied_equalities2(); +} diff --git a/test/grobner.cpp b/test/grobner.cpp new file mode 100644 index 000000000..92ba2c854 --- /dev/null +++ b/test/grobner.cpp @@ -0,0 +1,93 @@ +/*++ +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" + +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); + m.register_decl_plugins(); + 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/test/hashtable.cpp b/test/hashtable.cpp new file mode 100644 index 000000000..b01518985 --- /dev/null +++ b/test/hashtable.cpp @@ -0,0 +1,135 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_hashtable.cpp + +Abstract: + + Test hashtable module + +Author: + + Leonardo de Moura (leonardo) 2006-09-12. + +Revision History: + +--*/ +#ifdef _WINDOWS +#include +#include +#include + +#include"hashtable.h" + +#ifndef Z3DEBUG +#undef SASSERT +#define SASSERT(COND) { if (!(COND)) std::cerr << "ERROR: " << #COND << "\n"; } ((void) 0) +#endif + +struct int_hash_proc { unsigned operator()(int x) const { return x * 3; } }; +typedef int_hashtable > int_set; +typedef stdext::hash_set > > safe_int_set; +// typedef safe_int_set int_set; + +inline bool contains(int_set & h, int i) { + // return h.find(i) != h.end(); + return h.contains(i); +} + +const int N = 10000; +int vals[N]; + +static void tst1() { + int_set h1; + int size = 0; + for (int i = 1; i < N; i ++) { + int v = rand() % (N / 2); + h1.insert(v); + vals[i] = v; + SASSERT(contains(h1, v)); + } + std::cout << "step1\n"; std::cout.flush(); + for (int i = 1; i < N; i ++) { + SASSERT(contains(h1, vals[i])); + } + std::cout << "step2\n"; std::cout.flush(); + for (int i = 1; i < N; i += 2) { + h1.erase(vals[i]); + SASSERT(!contains(h1, vals[i])); + } + std::cout << "step3\n"; std::cout.flush(); + for (int i = 1; i < N; i += 2) { + h1.insert(vals[i]); + } + std::cout << "step4\n"; std::cout.flush(); + for (int i = 1; i < N; i ++) { + SASSERT(contains(h1, vals[i])); + } +} + +static void tst2() { + int_set h1; + safe_int_set h2; + int N = rand() % 1000; + for (int i = 0; i < N; i++) { + int v = rand()%1000; + if (rand() % 3 == 2) { + h1.erase(v); + h2.erase(v); + SASSERT(!contains(h1, v)); + } + else { + h1.insert(v); + h2.insert(v); + SASSERT(contains(h1, v)); + } + } + { + safe_int_set::iterator it = h2.begin(); + safe_int_set::iterator end = h2.end(); + for(; it != end; ++it) { + SASSERT(contains(h1, *it)); + } + } + { + int_set::iterator it = h1.begin(); + int_set::iterator end = h1.end(); + int n = 0; + for (; it != end; ++it) { + SASSERT(contains(h1, *it)); + n++; + } + SASSERT(n == h1.size()); + } + SASSERT(h1.size() == h2.size()); + // std::cout << "size: " << h1.size() << ", capacity: " << h1.capacity() << "\n"; std::cout.flush(); +} + +static void tst3() { + int_set h1; + h1.insert(10); + h1.insert(20); + h1.insert(30); + h1.erase(20); + int_set h2(h1); + SASSERT(h1.contains(10)); + SASSERT(!h1.contains(20)); + SASSERT(h1.contains(30)); + SASSERT(h2.contains(10)); + SASSERT(!h2.contains(20)); + SASSERT(h2.contains(30)); + SASSERT(h2.size() == 2); +} + +void tst_hashtable() { + tst3(); + for (int i = 0; i < 100; i++) + tst2(); + tst1(); +} +#else +void tst_hashtable() { +} +#endif diff --git a/test/heap.cpp b/test/heap.cpp new file mode 100644 index 000000000..e745463ff --- /dev/null +++ b/test/heap.cpp @@ -0,0 +1,133 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_heap.cpp + +Abstract: + + Test heap template. + +Author: + + Leonardo de Moura (leonardo) 2006-09-18. + +Revision History: + +--*/ +#include +#include"heap.h" +#include"hashtable.h" +#include"trace.h" + +struct lt_proc { bool operator()(int v1, int v2) const { return v1 < v2; } }; +typedef heap int_heap; +struct int_hash_proc { unsigned operator()(int v) const { return v * 17; }}; +typedef int_hashtable > int_set; +#define N 10000 + +static void tst1() { + int_heap h(N); + int_set t; + for (int i = 0; i < N * 3; i++) { + int val = rand() % N; + if (!h.contains(val)) { + SASSERT(!t.contains(val)); + h.insert(val); + t.insert(val); + } + else { + SASSERT(t.contains(val)); + } + } + SASSERT(h.check_invariant()); + int_set::iterator it = t.begin(); + int_set::iterator end = t.end(); + for (; it != end; ++it) { + SASSERT(h.contains(*it)); + } + int last = -1; + while (!h.empty()) { + int m1 = h.min_value(); + int m2 = h.erase_min(); + SASSERT(m1 == m2); + SASSERT(last < m2); + } +} + +int g_value[N]; + +struct lt_proc2 { bool operator()(int v1, int v2) const { SASSERT(v1 < N && v2 < N); return g_value[v1] < g_value[v2]; } }; +typedef heap int_heap2; + +static void init_values() { + for (unsigned i = 0; i < N; i++) + g_value[i] = rand(); +} + +static void dump_heap(const int_heap2 & h, std::ostream & out) { + // int_heap2::const_iterator it = h.begin(); + // int_heap2::const_iterator end = h.end(); + // for (; it != end; ++it) { + // out << *it << ":" << g_value[*it] << " "; + // } + // out << "\n"; +} + +static void tst2() { + int_heap2 h(N); + for (int i = 0; i < N * 10; i++) { + if (i % 1000 == 0) std::cout << "i: " << i << std::endl; + int cmd = rand() % 10; + if (cmd <= 3) { + // insert + int val = rand() % N; + if (!h.contains(val)) { + TRACE("heap", tout << "inserting: " << val << "\n";); + h.insert(val); + TRACE("heap", dump_heap(h, tout);); + SASSERT(h.contains(val)); + } + } + else if (cmd <= 6) { + int val = rand() % N; + if (h.contains(val)) { + TRACE("heap", tout << "removing: " << val << "\n";); + h.erase(val); + TRACE("heap", dump_heap(h, tout);); + SASSERT(!h.contains(val)); + } + } + else if (cmd <= 8) { + // increased & decreased + int val = rand() % N; + int old_v = g_value[val]; + int new_v = rand(); + if (h.contains(val)) { + g_value[val] = new_v; + if (old_v < new_v) { + TRACE("heap", tout << "value of: " << val << " increased old: " << old_v << " new: " << new_v << "\n";); + h.increased(val); + } + else { + TRACE("heap", tout << "value of: " << val << " decreased old: " << old_v << " new: " << new_v << "\n";); + h.decreased(val); + } + } + } + else { + SASSERT(h.check_invariant()); + } + } + SASSERT(h.check_invariant()); +} + +void tst_heap() { + // enable_debug("heap"); + enable_trace("heap"); + tst1(); + init_values(); + tst2(); +} + diff --git a/test/horn_subsume_model_converter.cpp b/test/horn_subsume_model_converter.cpp new file mode 100644 index 000000000..c99a50c87 --- /dev/null +++ b/test/horn_subsume_model_converter.cpp @@ -0,0 +1,60 @@ + +#include "horn_subsume_model_converter.h" +#include "arith_decl_plugin.h" +#include "model_smt2_pp.h" + +void tst_horn_subsume_model_converter() { + ast_manager m; + m.register_decl_plugins(); + arith_util a(m); + + ptr_vector ints; + ints.push_back(a.mk_int()); + ints.push_back(a.mk_int()); + ints.push_back(a.mk_int()); + + func_decl_ref p(m), q(m), r(m); + p = m.mk_func_decl(symbol("p"), 2, ints.c_ptr(), m.mk_bool_sort()); + q = m.mk_func_decl(symbol("q"), 2, ints.c_ptr(), m.mk_bool_sort()); + r = m.mk_func_decl(symbol("r"), 2, ints.c_ptr(), m.mk_bool_sort()); + + ref mc = alloc(horn_subsume_model_converter,m); + model_ref mr = alloc(model, m); + + mc->insert(p, m.mk_app(q, a.mk_numeral(rational(1), true), a.mk_numeral(rational(2), true))); + + model_converter_ref mcr = mc.get(); + apply(mcr, mr, 0); + model_smt2_pp(std::cout, m, *mr.get(), 0); + + mr = alloc(model, m); + mc->insert(p, m.mk_app(q, a.mk_numeral(rational(3), true), a.mk_numeral(rational(5), true))); + apply(mcr, mr, 0); + model_smt2_pp(std::cout, m, *mr.get(), 0); + + mr = alloc(model, m); + mc->insert(p, m.mk_app(r, m.mk_var(0,a.mk_int()), m.mk_var(1, a.mk_int()))); + apply(mcr, mr, 0); + model_smt2_pp(std::cout, m, *mr.get(), 0); + + mr = alloc(model, m); + app_ref head1(m); + expr_ref body1(m), body2(m); + func_decl_ref pred(m); + head1 = m.mk_app(p, m.mk_var(0, a.mk_int()), m.mk_var(0, a.mk_int())); + body1 = m.mk_app(q, m.mk_var(1, a.mk_int()), m.mk_var(2, a.mk_int())); + VERIFY(mc->mk_horn(head1, body1, pred, body2)); + mc->insert(pred, body2); + apply(mcr, mr, 0); + model_smt2_pp(std::cout, m, *mr.get(), 0); + + mr = alloc(model, m); + head1 = m.mk_app(p, m.mk_var(0, a.mk_int()), m.mk_var(0, a.mk_int())); + body1 = m.mk_app(q, m.mk_var(1, a.mk_int()), m.mk_var(0, a.mk_int())); + VERIFY(mc->mk_horn(head1, body1, pred, body2)); + mc->insert(pred, body2); + apply(mcr, mr, 0); + model_smt2_pp(std::cout, m, *mr.get(), 0); + + +} diff --git a/test/hwf.cpp b/test/hwf.cpp new file mode 100644 index 000000000..9c940f1d9 --- /dev/null +++ b/test/hwf.cpp @@ -0,0 +1,117 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + hwf.cpp + +Abstract: + + hwf repros... + +Author: + + Leonardo de Moura (leonardo) 2012-08-23. + +Revision History: + +--*/ +#include"hwf.h" +#include"f2n.h" +#include"rational.h" + +static void bug_set_double() { + hwf_manager m; + hwf a; + + m.set(a, 0.1); + SASSERT(m.is_regular(a)); + + m.set(a, 1.1); + SASSERT(m.is_regular(a)); + + m.set(a, 11.3); + SASSERT(m.is_regular(a)); + + m.set(a, 0.0); + SASSERT(m.is_regular(a)); +} + +static void bug_to_rational() { + hwf_manager m; + hwf a; + + unsynch_mpq_manager mq; + scoped_mpq r(mq); + + double ad, rd; + + m.set(a, 0.0); + m.to_rational(a, r); + ad = m.to_double(a); + rd = mq.get_double(r); + SASSERT(ad == rd); + + m.set(a, 1.0); + m.to_rational(a, r); + ad = m.to_double(a); + rd = mq.get_double(r); + SASSERT(ad == rd); + + m.set(a, 1.5); + m.to_rational(a, r); + ad = m.to_double(a); + rd = mq.get_double(r); + SASSERT(ad == rd); + + m.set(a, 0.875); + m.to_rational(a, r); + ad = m.to_double(a); + rd = mq.get_double(r); + SASSERT(ad == rd); + + m.set(a, -1.0); + m.to_rational(a, r); + ad = m.to_double(a); + rd = mq.get_double(r); + SASSERT(ad == rd); + + m.set(a, -1.5); + m.to_rational(a, r); + ad = m.to_double(a); + rd = mq.get_double(r); + SASSERT(ad == rd); + + m.set(a, -0.875); + m.to_rational(a, r); + ad = m.to_double(a); + rd = mq.get_double(r); + SASSERT(ad == rd); + + m.set(a, 0.1); + m.to_rational(a, r); + ad = m.to_double(a); + rd = mq.get_double(r); + double diff = (ad-rd); +#ifdef _WINDOWS + // CMW: This one depends on the rounding mode, + // which is implicit in both hwf::set and in mpq::to_double. + SASSERT(diff >= -DBL_EPSILON && diff <= DBL_EPSILON); +#endif +} + +static void bug_is_int() { + unsigned raw_val[2] = { 2147483648, 1077720461 }; + double val = *(double*)(raw_val); + std::cout << val << "\n"; + hwf_manager m; + hwf a; + m.set(a, val); + SASSERT(!m.is_int(a)); +} + +void tst_hwf() { + bug_is_int(); + bug_set_double(); + bug_to_rational(); +} diff --git a/test/im_float_config.h b/test/im_float_config.h new file mode 100644 index 000000000..45452dc42 --- /dev/null +++ b/test/im_float_config.h @@ -0,0 +1,72 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + im_float_config.h + +Abstract: + + Auxiliary class for testing intervals with software floats end points. + +Author: + + Leonardo de Moura (leonardo) 2012-08-21. + +Revision History: + +--*/ +#ifndef _IM_FLOAT_CONFIG_H_ +#define _IM_FLOAT_CONFIG_H_ + +#include"f2n.h" +#include"mpf.h" +#include"hwf.h" + +template +class im_float_config { + f2n m_manager; +public: + typedef f2n numeral_manager; + typedef typename f_manager::numeral numeral; + + im_float_config(f_manager & m, unsigned ebits = 11, unsigned sbits = 53):m_manager(m, ebits, sbits) {} + + struct interval { + numeral m_lower; + numeral m_upper; + }; + + void round_to_minus_inf() { m_manager.round_to_minus_inf(); } + void round_to_plus_inf() { m_manager.round_to_plus_inf(); } + void set_rounding(bool up) { m_manager.set_rounding(up); } + + // Getters + numeral const & lower(interval const & a) const { return a.m_lower; } + numeral const & upper(interval const & a) const { return a.m_upper; } + numeral & lower(interval & a) { return a.m_lower; } + numeral & upper(interval & a) { return a.m_upper; } + bool lower_is_inf(interval const & a) const { return m_manager.m().is_ninf(a.m_lower); } + bool upper_is_inf(interval const & a) const { return m_manager.m().is_pinf(a.m_upper); } + bool lower_is_open(interval const & a) const { return lower_is_inf(a); } + bool upper_is_open(interval const & a) const { return upper_is_inf(a); } + + // Setters + void set_lower(interval & a, numeral const & n) { m_manager.set(a.m_lower, n); } + void set_upper(interval & a, numeral const & n) { m_manager.set(a.m_upper, n); } + void set_lower_is_open(interval & a, bool v) {} + void set_upper_is_open(interval & a, bool v) {} + void set_lower_is_inf(interval & a, bool v) { if (v) m_manager.m().mk_ninf(m_manager.ebits(), m_manager.sbits(), a.m_lower); } + void set_upper_is_inf(interval & a, bool v) { if (v) m_manager.m().mk_pinf(m_manager.ebits(), m_manager.sbits(), a.m_upper); } + + // Reference to numeral manager + numeral_manager & m() const { return const_cast(m_manager); } +}; + +template +inline void del_f_interval(im_float_config & cfg, typename im_float_config::interval & a) { + cfg.m().del(a.m_lower); + cfg.m().del(a.m_upper); +} + +#endif diff --git a/test/imdd.cpp b/test/imdd.cpp new file mode 100644 index 000000000..74f2f4746 --- /dev/null +++ b/test/imdd.cpp @@ -0,0 +1,582 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + imdd.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-10-14. + +Revision History: + +--*/ +#include"imdd.h" + +static void tst0() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m), d4(m); + d1 = m.mk_empty(1); + d2 = m.mk_empty(1); + m.insert_dupdt(d1, 10, 20); + m.insert_dupdt(d1, 31, 50); + m.insert_dupdt(d2, 1, 5); + m.insert_dupdt(d2, 11, 13); + m.mk_product(d1, d2, d4); + m.mk_product(d4, d2, d4); + m.mk_product_dupdt(d1, d2); + std::cout << "d1:\n" << mk_ll_pp(d1, m) << "\n-------\n"; + m.mk_product_dupdt(d1, d2); + std::cout << "d4:\n" << mk_ll_pp(d4, m) << "\nd1:\n" << mk_ll_pp(d1, m) << "\nd2:\n" << mk_ll_pp(d2, m) << "\n"; + std::cout << d1 << "\n" << d2 << "\n"; + m.mk_product_dupdt(d1, d1); + std::cout << "d1 X d1:\n" << mk_ll_pp(d1, m) << "\n"; +} + +static void add_triple(imdd_manager & m, imdd_ref & d, unsigned l1, unsigned u1, unsigned l2, unsigned u2, unsigned l3, unsigned u3, + bool destructive = false, bool memoize = true) { + unsigned lowers[3] = {l1, l2, l3}; + unsigned uppers[3] = {u1, u2, u3}; + if (destructive) + m.add_facts_dupdt(d, 3, lowers, uppers, memoize); + else + m.add_facts(d, d, 3, lowers, uppers, memoize); + // std::cout << mk_ll_pp(d, m) << "\n"; +} + +static void add_pair(imdd_manager & m, imdd_ref & d, unsigned l1, unsigned u1, unsigned l2, unsigned u2, bool destructive = false, bool memoize = true) { + unsigned lowers[2] = {l1, l2}; + unsigned uppers[2] = {u1, u2}; + if (destructive) + m.add_facts_dupdt(d, 2, lowers, uppers, memoize); + else + m.add_facts(d, d, 2, lowers, uppers, memoize); + // std::cout << mk_ll_pp(d, m) << "\n"; +} + +static void add_some_facts(imdd_manager & m, imdd_ref & d, bool destructive = false, bool memoize = true) { + std::cout << "destructive: " << destructive << ", memoize: " << memoize << std::endl; + add_triple(m, d, 1, 10, 3, 3, 0, 100, destructive, memoize); + std::cout << mk_ll_pp(d, m) << std::endl; + SASSERT(m.contains(d, 2, 3, 20)); + SASSERT(!m.contains(d, 2, 4, 20)); + SASSERT(!m.contains(d, 2, 3, 200)); + SASSERT(!m.contains(d, 0, 3, 200)); + SASSERT(m.contains(d,1,3,0)); + add_triple(m, d, 3, 6, 3, 4, 7, 101, destructive, memoize); + std::cout << mk_ll_pp(d, m) << std::endl; + add_triple(m, d, 3, 6, 2, 2, 7, 101, destructive, memoize); + std::cout << mk_ll_pp(d, m) << std::endl; + add_triple(m, d, 3, 6, 5, 6, 7, 101, destructive, memoize); + SASSERT(m.contains(d, 2, 3, 20)); + std::cout << mk_ll_pp(d, m) << std::endl; + SASSERT(!m.contains(d, 2, 4, 20)); + SASSERT(m.contains(d, 3, 4, 20)); + SASSERT(!m.contains(d, 2, 3, 200)); + SASSERT(!m.contains(d, 0, 3, 200)); + SASSERT(m.contains(d,1,3,0)); +} + +static void tst1() { + std::cout << "--------------------------------\n"; + imdd_manager m; + { + imdd_ref d(m); + d = m.mk_empty(3); + add_some_facts(m, d); + } + { + imdd_ref d(m); + d = m.mk_empty(3); + add_some_facts(m, d, true, false); + m.defrag(d); + std::cout << mk_ll_pp(d, m) << "\n"; + } +} + +static void tst2() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 10, 20, 11, 21, 12, 22); + add_triple(m, d1, 30, 40, 31, 41, 32, 42); + d2 = m.mk_empty(3); + add_triple(m, d2, 15, 22, 15, 23, 7, 18); + add_triple(m, d2, 28, 42, 29, 39, 34, 46); + add_triple(m, d2, 28, 42, 29, 39, 100, 200); + add_triple(m, d2, 28, 42, 50, 60, 100, 200); + std::cout << mk_ll_pp(d1, m) << "\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + m.mk_union(d1, d2, d3); + SASSERT(m.subsumes(d3, d1)); + SASSERT(m.subsumes(d3, d2)); + SASSERT(!m.subsumes(d1, d3)); + SASSERT(!m.subsumes(d2, d3)); + std::cout << "d3: " << d3.get() << "\n" << mk_ll_pp(d3, m) << "\n"; + m.mk_union_dupdt(d1, d2, false); + std::cout << "d1: " << d1.get() << "\n" << mk_ll_pp(d1, m) << "\n"; + SASSERT(m.is_equal(d1, d3)); + SASSERT(!m.is_equal(d2, d3)); + SASSERT(!m.is_equal(d2, d1)); + std::cout << "memory(d1): " << m.memory(d1) << "\n"; +} + +static void tst3() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m); + d1 = m.mk_empty(3); + unsigned mins[3] = {0,0,0}; + unsigned maxs[3] = {127, 511, 255}; + + m.mk_complement(d1, d1, 3, mins, maxs); + std::cout << d1 << "\n"; + m.mk_complement(d1, d1, 3, mins, maxs); + std::cout << d1 << "\n"; + SASSERT(d1->empty()); + + d1 = m.mk_empty(3); + add_triple(m, d1, 10, 20, 11, 21, 12, 22); + add_triple(m, d1, 30, 40, 31, 41, 32, 42); + std::cout << d1 << "\n"; + m.mk_complement(d1, d1, 3, mins, maxs); + std::cout << mk_ll_pp(d1,m) << "\n"; + m.mk_filter_equal(d1, d1, 1, 15); + std::cout << "after selecting second column = 15\n" << mk_ll_pp(d1,m) << "\n"; +} + +static void tst4() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 1, 2, 2, 5, 4, 4); + add_triple(m, d1, 3, 4, 3, 4, 2, 5); + std::cout << "testing iterator:\n"; + imdd_manager::iterator it = m.begin(d1); + imdd_manager::iterator end = m.end(d1); + for (; it != end; ++it) { + unsigned * tuple = *it; + std::cout << "["; + for (unsigned i = 0; i < d1->get_arity(); i++) { + if (i > 0) + std::cout << ", "; + std::cout << tuple[i]; + } + std::cout << "]\n"; + } +} + +static void tst5() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + std::cout.flush(); + d1 = m.mk_empty(3); + add_triple(m, d1, 5, 100, 10, 20, 3, 10); + std::cout << mk_ll_pp(d1,m) << std::endl; + add_triple(m, d1, 5, 100, 34, 50, 98, 110); + std::cout << mk_ll_pp(d1,m) << std::endl; + unsigned vals[3] = {6, 8, 3}; + SASSERT(!m.contains(d1, 3, vals)); + add_triple(m, d1, 6, 25, 8, 30, 14, 50); + std::cout << mk_ll_pp(d1,m) << std::endl; + SASSERT(!m.contains(d1, 3, vals)); + unsigned vars[2] = {0, 2}; + d2 = d1; + d3 = d1; + m.mk_filter_identical(d1, d1, 2, vars); + vars[1] = 1; + std::cout << "d1:\n" << mk_ll_pp(d1,m) << "\n"; + m.mk_filter_identical(d2, d2, 2, vars); + std::cout << "d2:\n" << mk_ll_pp(d2,m) << "\n"; + vars[0] = 1; + vars[1] = 2; + m.mk_filter_identical(d3, d3, 2, vars); + std::cout << "d3:\n" << mk_ll_pp(d3,m) << "\n"; +} + +static void add_5tuple(imdd_manager & m, imdd_ref & d, unsigned l1, unsigned u1, unsigned l2, unsigned u2, unsigned l3, unsigned u3, + unsigned l4, unsigned u4, unsigned l5, unsigned u5, bool destructive = false, bool memoize = true) { + unsigned lowers[5] = {l1, l2, l3, l4, l5}; + unsigned uppers[5] = {u1, u2, u3, u4, u5}; + if (destructive) + m.add_facts_dupdt(d, 5, lowers, uppers, memoize); + else + m.add_facts(d, d, 5, lowers, uppers, memoize); + // std::cout << mk_ll_pp(d, m) << "\n"; +} + +static void tst6() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m); + std::cout.flush(); + d1 = m.mk_empty(5); + // TODO: make a more complicated mk_filter_identical example +} + +static void tst7() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d2(m), d3(m); + d2 = m.mk_empty(3); + add_triple(m, d2, 15, 22, 15, 23, 7, 18); + add_triple(m, d2, 28, 42, 29, 39, 34, 46); + add_triple(m, d2, 28, 42, 29, 39, 100, 200); + add_triple(m, d2, 28, 42, 50, 60, 100, 200); + std::cout << "mk_project\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + unsigned vars[1] = {1}; + m.mk_project(d2, d3, 1, vars); + std::cout << mk_ll_pp(d3, m) << "\n"; +} + +static void tst8() { + std::cout << "--------------------------------\n"; + // enable_trace("mk_swap_bug"); + imdd_manager m; + imdd_ref d2(m), d3(m); + d2 = m.mk_empty(3); + add_triple(m, d2, 15, 22, 15, 23, 7, 18); + add_triple(m, d2, 28, 42, 29, 39, 34, 46); + add_triple(m, d2, 28, 42, 29, 39, 100, 200); + add_triple(m, d2, 28, 42, 50, 60, 100, 200); + std::cout << mk_ll_pp(d2, m) << "\n"; + m.mk_swap(d2, d3, 0); + std::cout << "after swap 0<->1\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; + m.mk_swap(d2, d3, 1); + std::cout << "after swap 1<->2\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; +} + +static void tst9() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d2(m), d3(m); + d2 = m.mk_empty(5); + add_5tuple(m, d2, 2,2, 3,3, 1, 1, 5, 10, 100, 200); + std::cout << mk_ll_pp(d2, m) << "\n"; + add_5tuple(m, d2, 2,2, 3,3, 1, 1, 15, 20, 100, 200); + std::cout << mk_ll_pp(d2, m) << "\n"; + add_5tuple(m, d2, 4,4, 5,5, 1, 1, 5, 10, 100, 200); + std::cout << mk_ll_pp(d2, m) << "\n"; + add_5tuple(m, d2, 4,4, 5,5, 1, 1, 15, 20, 100, 200); + std::cout << mk_ll_pp(d2, m) << "\n"; + m.mk_swap(d2, d3, 2); + std::cout << "after swap 2<->3\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; +} + +static void tst10() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 5, 100, 10, 20, 3, 10); + add_triple(m, d1, 5, 100, 34, 50, 98, 110); + m.add_bounded_var(d1, d2, 0, 66, 72); + std::cout << mk_ll_pp(d1, m) << "\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + m.add_bounded_var(d1, d3, 1, 64, 73); + std::cout << mk_ll_pp(d3, m) << "\n"; +} + +static void tst11() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 5, 100, 10, 20, 3, 10); + add_triple(m, d1, 5, 100, 34, 50, 98, 110); + add_triple(m, d1, 20, 30, 5, 25, 11, 13); + m.mk_filter_distinct(d1, d2, 1, 2); + std::cout << mk_ll_pp(d1, m) << "\n"; + std::cout << "filter_distinct(1,2):\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +static void tst12() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 1, 10, 5, 25, 10, 13); + m.mk_filter_distinct(d1, d2, 1, 2); + std::cout << mk_ll_pp(d1, m) << "\n"; + std::cout << "filter_distinct(1,2):\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +static void tst13() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 5, 25, 1, 10, 10, 13); + add_triple(m, d1, 5, 25, 20, 30, 10, 13); + m.mk_filter_distinct(d1, d2, 0, 2); + std::cout << mk_ll_pp(d1, m) << "\n"; + std::cout << "filter_distinct(0,2):\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +static void tst14() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 5, 25, 1, 10, 10, 13); + add_triple(m, d1, 5, 25, 20, 30, 15, 18); + std::cout << "destructive version\n"; + std::cout << mk_ll_pp(d1, m) << "\n"; + m.mk_filter_distinct_dupdt(d1, 0, 2); + std::cout << "filter_distinct(0,2):\n"; + std::cout << mk_ll_pp(d1, m) << "\n"; +} + +static void tst15() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 5, 5, 1, 10, 5, 5); + std::cout << mk_ll_pp(d1, m) << "\n"; + m.mk_filter_distinct(d1, d2, 0, 2); + std::cout << "filter_distinct(0,2):\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +static void tst16() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 5, 15, 1, 10, 50, 500); + std::cout << mk_ll_pp(d1, m) << "\n"; + m.mk_filter_disequal(d1, d2, 1, 4); + std::cout << "filter_disequal(var1,4):\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +static void tst17() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(3); + add_triple(m, d1, 5, 15, 10, 10, 50, 500); + std::cout << mk_ll_pp(d1, m) << "\n"; + m.mk_filter_disequal(d1, d2, 1, 10); + std::cout << "filter_disequal(var1,10):\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +static void tst18() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d1(m), d2(m), d3(m); + d1 = m.mk_empty(2); + add_pair(m, d1, 1112, 1290, 1302, 1302); + std::cout << mk_ll_pp(d1, m) << "\n"; + m.mk_swap(d1, d2, 0); + std::cout << "mk_swap 0:\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +static void tst19() { + std::cout << "--------------------------------\n"; + imdd_manager m; + imdd_ref d2(m), d3(m); + d2 = m.mk_empty(3); + add_triple(m, d2, 15, 22, 15, 23, 7, 18); + add_triple(m, d2, 28, 42, 29, 39, 34, 46); + add_triple(m, d2, 28, 42, 29, 39, 100, 200); + add_triple(m, d2, 28, 42, 50, 60, 100, 200); + std::cout << "mk_project_dupdt\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + unsigned vars[1] = {1}; + m.mk_project_dupdt(d2, 1, vars); + std::cout << "new table\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +static void init(unsigned* v, unsigned a, unsigned b, unsigned c) { + v[0] = a; + v[1] = b; + v[2] = c; +} + +static void tst20() { + std::cout << "--------------------------------\n"; + std::cout << "remove_facts\n"; + imdd_manager m; + imdd_ref d2(m), d3(m); + d2 = m.mk_empty(3); + add_triple(m, d2, 15, 22, 15, 23, 7, 18); + add_triple(m, d2, 28, 42, 29, 39, 34, 46); + add_triple(m, d2, 28, 42, 29, 39, 100, 200); + add_triple(m, d2, 28, 42, 50, 60, 100, 200); + std::cout << mk_ll_pp(d2, m) << "\n"; + // + // [15, 22] -> #1:{ + // [15, 23] -> {[7, 18]}*$80}*$80 + // [28, 42] -> #2:{ + // [29, 39] -> {[34, 46], [100, 200]}*$160 + // [50, 60] -> {[100, 200]}*$80}*$80}$80 + // + unsigned lowers[3] = {23,1,1}; + unsigned uppers[3] = {24,1,1}; + + m.remove_facts(d2, d3, 3, lowers, uppers); + std::cout << "new table (no change)\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; + + lowers[0] = 22; + m.remove_facts(d2, d3, 3, lowers, uppers); + std::cout << "new table (no change)\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; + + init(lowers, 22, 15, 0); + init(uppers, 24, 23, 0); + m.remove_facts(d2, d3, 3, lowers, uppers); + std::cout << "new table (no change)\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; + + init(lowers, 22, 15, 7); + init(uppers, 24, 23, 18); + m.remove_facts(d2, d3, 3, lowers, uppers); + std::cout << "new table (narrow first interval)\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; + + init(lowers, 22, 15, 8); + init(uppers, 24, 23, 18); + m.remove_facts(d2, d3, 3, lowers, uppers); + std::cout << "new table (split first interval)\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; + + init(lowers, 22, 15, 8); + init(uppers, 24, 23, 17); + m.remove_facts(d2, d3, 3, lowers, uppers); + std::cout << "new table (split first interval)\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; + + init(lowers, 22, 15, 8); + init(uppers, 24, 23, 19); + m.remove_facts(d2, d3, 3, lowers, uppers); + std::cout << "new table (split first interval)\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; + + init(lowers, 30, 20, 120); + init(uppers, 40, 60, 140); + m.remove_facts(d2, d3, 3, lowers, uppers); + std::cout << "new table (split second interval)\n"; + std::cout << mk_ll_pp(d3, m) << "\n"; +} + + +static void tst21() { + std::cout << "--------------------------------\n"; + std::cout << "remove_facts\n"; + imdd_manager m; + imdd_ref d2(m), d3(m); + d2 = m.mk_empty(3); + add_triple(m, d2, 15, 22, 15, 23, 7, 18); + add_triple(m, d2, 28, 42, 29, 39, 34, 46); + add_triple(m, d2, 28, 42, 29, 39, 100, 200); + add_triple(m, d2, 28, 42, 50, 60, 100, 200); + std::cout << mk_ll_pp(d2, m) << "\n"; + // + // [15, 22] -> #1:{ + // [15, 23] -> {[7, 18]}*$80}*$80 + // [28, 42] -> #2:{ + // [29, 39] -> {[34, 46], [100, 200]}*$160 + // [50, 60] -> {[100, 200]}*$80}*$80}$80 + // + unsigned lowers[3] = {23,1,1}; + unsigned uppers[3] = {24,1,1}; + + d3 = d2; + m.remove_facts_dupdt(d2, 3, lowers, uppers); + std::cout << "new table (no change)\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + d2 = d3; + + lowers[0] = 22; + m.remove_facts_dupdt(d2, 3, lowers, uppers); + std::cout << "new table (no change)\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + + init(lowers, 22, 15, 0); + init(uppers, 24, 23, 0); + m.remove_facts_dupdt(d2, 3, lowers, uppers); + std::cout << "new table (no change)\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + + init(lowers, 22, 15, 7); + init(uppers, 24, 23, 18); + m.remove_facts_dupdt(d2, 3, lowers, uppers); + std::cout << "new table (narrow first interval)\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + + init(lowers, 22, 15, 8); + init(uppers, 24, 23, 18); + m.remove_facts_dupdt(d2, 3, lowers, uppers); + std::cout << "new table (split first interval)\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + + init(lowers, 22, 15, 8); + init(uppers, 24, 23, 17); + m.remove_facts_dupdt(d2, 3, lowers, uppers); + std::cout << "new table (split first interval)\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + + init(lowers, 22, 15, 8); + init(uppers, 24, 23, 19); + m.remove_facts_dupdt(d2, 3, lowers, uppers); + std::cout << "new table (split first interval)\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; + + init(lowers, 30, 20, 120); + init(uppers, 40, 60, 140); + m.remove_facts_dupdt(d2, 3, lowers, uppers); + std::cout << "new table (split second interval)\n"; + std::cout << mk_ll_pp(d2, m) << "\n"; +} + +void tst_imdd() { + // enable_trace("imdd_add_bug"); + // enable_trace("add_facts_bug"); + enable_trace("mk_distinct_imdd"); + enable_trace("mk_union_core"); + tst0(); + tst1(); + tst2(); + tst3(); + tst4(); + tst5(); + tst6(); + tst7(); + tst19(); + tst8(); + tst9(); + tst10(); + tst11(); + tst12(); + tst13(); + tst14(); + tst15(); + tst16(); + tst17(); + tst18(); + tst20(); + tst21(); +} + diff --git a/test/inf_rational.cpp b/test/inf_rational.cpp new file mode 100644 index 000000000..cb025a789 --- /dev/null +++ b/test/inf_rational.cpp @@ -0,0 +1,183 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_inf_rational.cpp + +Abstract: + + Test for Rational numbers with infinitesimals + +Author: + + Leonardo de Moura (leonardo) 2006-09-18. + Nikolaj Bjorner (nbjorner) 2006-10-24. + +Revision History: + +--*/ + +#include"inf_rational.h" + +static void tst0() { + inf_rational n(rational(0), false); + TRACE("inf_rational", tout << n << "\n";); + SASSERT(n < inf_rational::zero()); + SASSERT(!(n >= inf_rational::zero())); +} + +void test_inc_dec( + inf_rational& r, + inf_rational const & b_8_5, + inf_rational const & b_7_5, + inf_rational const & b_7_10, + inf_rational const & b_17_10 + ) +{ + r += rational(1,5); + SASSERT (r == b_8_5); + r -= rational(1,5); + SASSERT (r == b_7_5); + + r += inf_rational(1,5); + SASSERT (r == b_8_5); + r -= inf_rational(1,5); + SASSERT (r == b_7_5); + + r /= rational(2,1); + SASSERT (r == b_7_10); + inf_rational r_pre = r++; + SASSERT (r_pre == b_7_10); + SASSERT (r == b_17_10); + inf_rational r_post = --r; + SASSERT (r_post == b_7_10); + SASSERT (r == b_7_10); + r_post = ++r; + SASSERT (r_post == b_17_10); + SASSERT (r == b_17_10); + r_pre = r--; + SASSERT (r_pre == b_17_10); + SASSERT (r == b_7_10); + + r_pre = r; + r_pre += inf_rational(1,2); + r_post = r_pre; + r_post -= inf_rational(1,2); + SASSERT(r == r_post); + SASSERT(r + inf_rational(1,2) == r_pre); + + r_pre = r; + r_pre /= rational(2,1); + r_post = r_pre; + r_post /= rational(1,2); + SASSERT(r == r_post); + SASSERT(rational(1,2) * r == r_pre); + SASSERT(r == r_pre / rational(1,2)); + +} + +void +tst_inf_rational() +{ + tst0(); + + inf_rational r1; + inf_rational r2(r1); + SASSERT (r1 == r2); + inf_rational r3(1); + inf_rational r4(0); + SASSERT (r4 == r1); + SASSERT (r3 != r4); + inf_rational r5(0,1); + inf_rational r6(1,1); + inf_rational r7(2,2); + inf_rational r8(7,5); + SASSERT (r1 == r5); + SASSERT (r6 == r3); + SASSERT (r7 == r3); + inf_rational r9(rational(7,5)); + SASSERT (r8 == r9); + r9.reset(); + SASSERT (r1 == r9); + SASSERT (r1.is_int()); + SASSERT (!r8.is_int()); + SASSERT (0 == r1.get_int64()); + r9 = r8; + SASSERT (r8 == r9); + inf_rational n = numerator(r7); + inf_rational d = denominator(r7); + + + { + inf_rational b_8_5 = inf_rational(8,5); + inf_rational b_7_5 = inf_rational(7,5); + inf_rational b_7_10 = inf_rational(7,10); + inf_rational b_17_10 = inf_rational(17,10); + + inf_rational r = r9; + test_inc_dec(r, b_8_5, b_7_5, b_7_10, b_17_10); + } + + { + inf_rational b_8_5 = inf_rational(rational(8,5),true); + inf_rational b_7_5 = inf_rational(rational(7,5),true); + inf_rational b_7_10 = inf_rational(rational(7,5),true) / rational(2); + inf_rational b_17_10 = b_7_10 + inf_rational(1); + + inf_rational r (rational(7,5),true); + test_inc_dec(r, b_8_5, b_7_5, b_7_10, b_17_10); + } + + + SASSERT(inf_rational(rational(1,2),true) > inf_rational(rational(1,2))); + SASSERT(inf_rational(rational(1,2),false) < inf_rational(rational(1,2))); + SASSERT(inf_rational(rational(1,2),true) >= inf_rational(rational(1,2))); + SASSERT(inf_rational(rational(1,2)) >= inf_rational(rational(1,2),false)); + SASSERT(inf_rational(rational(1,2),false) != inf_rational(rational(1,2))); + SASSERT(inf_rational(rational(1,2),true) != inf_rational(rational(1,2))); + SASSERT(inf_rational(rational(1,2),false) != inf_rational(rational(1,2),true)); + + inf_rational h_neg(rational(1,2),false); + inf_rational h_pos(rational(1,2),true); + + h_neg.neg(); + SASSERT(h_neg == -inf_rational(rational(1,2),false)); + h_neg.neg(); + SASSERT(h_neg == inf_rational(rational(1,2),false)); + + SASSERT(r1.is_zero() && !r1.is_one() && !r1.is_neg() && r1.is_nonneg() && r1.is_nonpos() && !r1.is_pos()); + SASSERT(!r3.is_zero() && r3.is_one() && !r3.is_neg() && r3.is_nonneg() && !r3.is_nonpos() && r3.is_pos()); + + SASSERT(floor(inf_rational(rational(1,2),false)) == rational()); + SASSERT(floor(inf_rational(rational(1,2))) == rational()); + SASSERT(floor(inf_rational(rational(),false)) == rational(-1)); + SASSERT(floor(inf_rational(rational())) == rational()); + SASSERT(floor(inf_rational(rational(),true)) == rational()); + SASSERT(floor(inf_rational(rational(1),false)) == rational()); + SASSERT(floor(inf_rational(rational(1))) == rational(1)); + SASSERT(floor(inf_rational(rational(1),true)) == rational(1)); + + SASSERT(ceil(inf_rational(rational(1,2),false)) == rational(1)); + SASSERT(ceil(inf_rational(rational(1,2))) == rational(1)); + SASSERT(ceil(inf_rational(rational(),false)) == rational()); + SASSERT(ceil(inf_rational(rational())) == rational()); + SASSERT(ceil(inf_rational(rational(),true)) == rational(1)); + SASSERT(ceil(inf_rational(rational(1),false)) == rational(1)); + SASSERT(ceil(inf_rational(rational(1))) == rational(1)); + SASSERT(ceil(inf_rational(rational(1),true)) == rational(2)); + + unsigned h = r9.hash(); + + inf_rational x(rational(1,2),true); + inf_rational y(1,2); + x.swap(y); + SASSERT (x == inf_rational(1,2)); + SASSERT (y == inf_rational(rational(1,2),true)); + + SASSERT(inf_rational(1,2) == abs(-inf_rational(1,2))); + +} + + + diff --git a/test/ini_file.cpp b/test/ini_file.cpp new file mode 100644 index 000000000..d3114c037 --- /dev/null +++ b/test/ini_file.cpp @@ -0,0 +1,50 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + ini_file.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2007-05-10. + +Revision History: + +--*/ +#include +#include"ini_file.h" +#include"debug.h" + +static void tst1() { + ini_params p; + int p1; + p.register_int_param("ipar1", 0, 100, p1); + int p2; + p.register_int_param("ipar2", -100, 100, p2); + bool p3; + p.register_bool_param("bpar1", p3); + bool p4; + p.register_bool_param("bpar2", p4); + unsigned p5; + p.register_unsigned_param("upar1", 0, 100, p5); + double p6; + p.register_percentage_param("ppar1", p6); + std::istringstream in("ipar1 = 100 ipar2=-30 bpar1 = true ;; COMMENT\n bpar2 = false upar1=30 ppar1 = 10"); + p.read_ini_file(in); + SASSERT(p1 == 100); + SASSERT(p2 == -30); + SASSERT(p3); + SASSERT(!p4); + SASSERT(p5 == 30); + SASSERT(p6 == 0.1); +} + +void tst_ini_file() { + tst1(); +} + diff --git a/test/interval.cpp b/test/interval.cpp new file mode 100644 index 000000000..4621c0416 --- /dev/null +++ b/test/interval.cpp @@ -0,0 +1,471 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + interval.h + +Abstract: + + Goodies/Templates for interval arithmetic + +Author: + + Leonardo de Moura (leonardo) 2012-07-19. + +Revision History: + +--*/ +#include +#include"interval_def.h" +#include"dependency.h" +#include"mpq.h" +#include"ast.h" +#include"debug.h" + +template class interval_manager; +typedef im_default_config::interval interval; + +static void display_preamble(std::ostream & out) { + out << "(set-info :status unsat)\n"; + out << "(set-option :auto-config true)\n"; + out << "(set-option :numeral-as-real true)\n"; + out << "(declare-const a Real)\n"; + out << "(declare-const b Real)\n"; +} + +static void display_smt2_pos_numeral(std::ostream & out, unsynch_mpq_manager & m, mpq const & n) { + if (m.is_int(n)) { + m.display(out, n); + } + else { + out << "(/ "; + m.display(out, n.numerator()); + out << " "; + m.display(out, n.denominator()); + out << ")"; + } +} + +static void display_smt2_numeral(std::ostream & out, unsynch_mpq_manager & m, mpq const & n) { + if (m.is_neg(n)) { + scoped_mpq n_copy(m); + n_copy = n; + out << "(- "; + n_copy.neg(); + display_smt2_pos_numeral(out, m, n_copy); + out << ")"; + } + else { + display_smt2_pos_numeral(out, m, n); + } +} + +static void display_constraint(std::ostream & out, unsynch_mpq_manager & m, char const * a, interval const & i, + bool include_lower = true, bool include_upper = true) { + out << "(and true"; + if (!i.m_lower_inf && include_lower) { + out << " (" << (i.m_lower_open ? "<" : "<=") << " "; + display_smt2_numeral(out, m, i.m_lower); + out << " " << a << ")"; + } + if (!i.m_upper_inf && include_upper) { + out << " (" << (i.m_upper_open ? "<" : "<=") << " " << a << " "; + display_smt2_numeral(out, m, i.m_upper); + out << ")"; + } + out << ")"; +} + +static void assert_hyp(std::ostream & out, unsynch_mpq_manager & m, char const * a, interval const & i, + bool include_lower = true, bool include_upper = true) { + out << "(assert "; + display_constraint(out, m, a, i, include_lower, include_upper); + out << ")\n"; +} + +static void assert_conj(std::ostream & out, unsynch_mpq_manager & m, char const * a, interval const & i, + bool include_lower = true, bool include_upper = true) { + out << "(assert (not "; + display_constraint(out, m, a, i, include_lower, include_upper); + out << "))\n"; +} + +static bool mk_interval(im_default_config & cfg, interval & a, bool l_inf, bool l_open, int l_val, bool u_inf, bool u_open, int u_val) { + if (!l_inf && !u_inf) { + if (l_val > u_val) + return false; + if (l_val == u_val && (l_open || u_open)) + return false; + } + + if (l_inf) { + a.m_lower_open = true; + a.m_lower_inf = true; + } + else { + a.m_lower_open = l_open; + a.m_lower_inf = false; + cfg.m().set(a.m_lower, l_val); + } + + if (u_inf) { + a.m_upper_open = true; + a.m_upper_inf = true; + } + else { + a.m_upper_open = u_open; + a.m_upper_inf = false; + cfg.m().set(a.m_upper, u_val); + } + + return true; +} + +static void mk_random_interval(im_default_config & cfg, interval & a, unsigned magnitude) { + switch (rand()%3) { + case 0: + // Neg, Neg + if (rand()%4 == 0) { + a.m_lower_open = true; + a.m_lower_inf = true; + + a.m_upper_open = (rand()%2 == 0); + a.m_upper_inf = false; + cfg.m().set(a.m_upper, -static_cast((rand()%magnitude))); + } + else { + a.m_upper_open = (rand()%2 == 0); + a.m_upper_inf = false; + int upper = -static_cast((rand()%magnitude)); + cfg.m().set(a.m_upper, upper); + + a.m_lower_open = (rand()%2 == 0); + a.m_lower_inf = false; + cfg.m().set(a.m_lower, upper - static_cast(rand()%magnitude) - (a.m_lower_open || a.m_upper_open ? 1 : 0)); + } + break; + case 1: + // Neg, Pos + + if (rand()%4 == 0) { + a.m_lower_open = true; + a.m_lower_inf = true; + } + else { + a.m_lower_open = (rand()%2 == 0); + a.m_lower_inf = false; + cfg.m().set(a.m_lower, -static_cast((rand()%magnitude)) - 1); + } + + if (rand()%4 == 0) { + a.m_upper_open = true; + a.m_upper_inf = true; + } + else { + a.m_upper_open = (rand()%2 == 0); + a.m_upper_inf = false; + cfg.m().set(a.m_upper, rand()%magnitude + 1); + } + break; + default: + // Neg, Neg + if (rand()%4 == 0) { + a.m_upper_open = true; + a.m_upper_inf = true; + + a.m_lower_open = (rand()%2 == 0); + a.m_lower_inf = false; + cfg.m().set(a.m_lower, (rand()%magnitude)); + } + else { + a.m_lower_open = (rand()%2 == 0); + a.m_lower_inf = false; + int lower = (rand()%magnitude); + cfg.m().set(a.m_lower, lower); + + a.m_upper_open = (rand()%2 == 0); + a.m_upper_inf = false; + cfg.m().set(a.m_upper, lower + rand()%magnitude + (a.m_lower_open || a.m_upper_open ? 1 : 0)); + } + break; + } +} + +static void del_interval(im_default_config & cfg, interval & a) { + cfg.m().del(a.m_lower); + cfg.m().del(a.m_upper); +} + +#define BUFFER_SZ 256 +static int g_problem_id = 0; +static char g_buffer[BUFFER_SZ]; + +char const * get_next_file_name() { +#ifdef _WINDOWS + sprintf_s(g_buffer, BUFFER_SZ, "interval_lemma_%d.smt2", g_problem_id); +#else + sprintf(g_buffer, "interval_lemma_%d.smt2", g_problem_id); +#endif + g_problem_id++; + return g_buffer; +} + +static void display_lemmas(unsynch_mpq_manager & nm, char const * result_term, + interval const & a, interval const & b, interval const & r, interval_deps const & deps) { + { + std::ofstream out(get_next_file_name()); + display_preamble(out); + assert_hyp(out, nm, "a", a, dep_in_lower1(deps.m_lower_deps), dep_in_upper1(deps.m_lower_deps)); + assert_hyp(out, nm, "b", b, dep_in_lower2(deps.m_lower_deps), dep_in_upper2(deps.m_lower_deps)); + assert_conj(out, nm, result_term, r, true, false); + out << "(check-sat)\n"; + } + { + std::ofstream out(get_next_file_name()); + display_preamble(out); + assert_hyp(out, nm, "a", a, dep_in_lower1(deps.m_upper_deps), dep_in_upper1(deps.m_upper_deps)); + assert_hyp(out, nm, "b", b, dep_in_lower2(deps.m_upper_deps), dep_in_upper2(deps.m_upper_deps)); + assert_conj(out, nm, result_term, r, false, true); + out << "(check-sat)\n"; + } +} + +#define MK_BINARY(NAME, RES_TERM) \ +static void tst_ ## NAME(unsigned N, unsigned magnitude) { \ + unsynch_mpq_manager nm; \ + im_default_config imc(nm); \ + interval_manager im(imc); \ + interval a, b, r; \ + \ + for (unsigned i = 0; i < N; i++) { \ + mk_random_interval(imc, a, magnitude); \ + mk_random_interval(imc, b, magnitude); \ + interval_deps deps; \ + im.NAME(a, b, r, deps); \ + \ + display_lemmas(nm, RES_TERM, a, b, r, deps); \ + } \ + del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); \ +} + +MK_BINARY(mul, "(* a b)"); +MK_BINARY(add, "(+ a b)"); +MK_BINARY(sub, "(- a b)"); + +static void tst_neg(unsigned N, unsigned magnitude) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + interval a, b, r; + + for (unsigned i = 0; i < N; i++) { + mk_random_interval(imc, a, magnitude); + interval_deps deps; + im.neg(a, r, deps); + display_lemmas(nm, "(- a)", a, b, r, deps); + } + del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); +} + +static void tst_pw_2(unsigned N, unsigned magnitude) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + interval a, b, r; + + for (unsigned i = 0; i < N; i++) { + mk_random_interval(imc, a, magnitude); + interval_deps deps; + im.power(a, 2, r, deps); + display_lemmas(nm, "(* a a)", a, b, r, deps); + } + del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); +} + +static void tst_pw_3(unsigned N, unsigned magnitude) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + interval a, b, r; + + for (unsigned i = 0; i < N; i++) { + mk_random_interval(imc, a, magnitude); + interval_deps deps; + im.power(a, 3, r, deps); + display_lemmas(nm, "(* a a a)", a, b, r, deps); + } + del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); +} + +static void tst_root_2(unsigned N, unsigned magnitude, unsigned precision) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + interval a, b, r; + scoped_mpq p(nm); + p = precision; + nm.inv(p); + + unsigned i = 0; + while (i < N) { + mk_random_interval(imc, a, magnitude); + if (!im.lower_is_neg(a)) { + i++; + interval_deps deps; + im.nth_root(a, 2, p, r, deps); + display_lemmas(nm, "(^ a (/ 1.0 2.0))", a, b, r, deps); + } + } + del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); +} + +static void tst_root_3(unsigned N, unsigned magnitude, unsigned precision) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + interval a, b, r; + scoped_mpq p(nm); + p = precision; + nm.inv(p); + + unsigned i = 0; + while (i < N) { + mk_random_interval(imc, a, magnitude); + i++; + interval_deps deps; + im.nth_root(a, 3, p, r, deps); + display_lemmas(nm, "(^ a (/ 1.0 3.0))", a, b, r, deps); + } + del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); +} + +static void tst_inv(unsigned N, unsigned magnitude) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + interval a, b, r; + + for (unsigned i = 0; i < N; i++) { + while (true) { + mk_random_interval(imc, a, magnitude); + if (!im.contains_zero(a)) + break; + } + interval_deps deps; + im.inv(a, r, deps); + display_lemmas(nm, "(/ 1 a)", a, b, r, deps); + } + del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); +} + +static void tst_div(unsigned N, unsigned magnitude) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + interval a, b, r; + + for (unsigned i = 0; i < N; i++) { + mk_random_interval(imc, a, magnitude); + while (true) { + mk_random_interval(imc, b, magnitude); + if (!im.contains_zero(b)) + break; + } + interval_deps deps; + im.div(a, b, r, deps); + display_lemmas(nm, "(/ a b)", a, b, r, deps); + } + del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); +} + +#include"im_float_config.h" + +static void tst_float() { + unsynch_mpq_manager qm; + mpf_manager fm; + im_float_config ifc(fm); + interval_manager > im(ifc); + im_float_config::interval a, b, c; + scoped_mpq minus_one_third(qm), one_third(qm), two_third(qm), minus_two_third(qm); + qm.set(minus_one_third, -1, 3); + qm.set(one_third, 1, 3); + qm.set(two_third, 2, 3); + qm.set(minus_two_third, -2, 3); + + ifc.round_to_minus_inf(); + ifc.m().set(a.m_lower, minus_one_third); + ifc.round_to_plus_inf(); + ifc.m().set(a.m_upper, two_third); + + ifc.round_to_minus_inf(); + ifc.m().set(b.m_lower, minus_two_third); + ifc.round_to_plus_inf(); + ifc.m().set(b.m_upper, one_third); + + im.display(std::cout, a); + std::cout << "\n"; + im.display(std::cout, b); + std::cout << "\n"; + interval_deps deps; + im.add(a, b, c, deps); + im.display(std::cout, c); + std::cout << "\n"; + + del_f_interval(ifc, a); del_f_interval(ifc, b); del_f_interval(ifc, c); +} + +void tst_pi() { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + interval r; + for (unsigned i = 0; i < 8; i++) { + im.pi(i, r); + nm.display_decimal(std::cout, im.lower(r), 32); std::cout << " "; + nm.display_decimal(std::cout, im.upper(r), 32); std::cout << "\n"; + SASSERT(nm.lt(im.lower(r), im.upper(r))); + } + del_interval(imc, r); +} + +static void tst_pi_float() { + std::cout << "pi float...\n"; + unsynch_mpq_manager qm; + mpf_manager fm; + im_float_config ifc(fm, 22, 106); + interval_manager > im(ifc); + scoped_mpq q(qm); + im_float_config::interval r; + for (unsigned i = 0; i < 8; i++) { + im.pi(i, r); + fm.to_rational(im.lower(r), q); + qm.display_decimal(std::cout, q, 32); std::cout << " "; + fm.to_rational(im.upper(r), q); + qm.display_decimal(std::cout, q, 32); std::cout << "\n"; + } + del_f_interval(ifc, r); +} + +#define NUM_TESTS 1000 +#define SMALL_MAG 3 +#define MID_MAG 10 + +void tst_interval() { + // enable_trace("interval_bug"); + // tst_float(); + // return; + // enable_trace("interval_nth_root"); + // tst_pi(); + // tst_pi_float(); + tst_root_2(NUM_TESTS, MID_MAG, 100); + tst_root_3(NUM_TESTS, MID_MAG, 100); + tst_div(NUM_TESTS, SMALL_MAG); + tst_inv(NUM_TESTS, SMALL_MAG); + tst_pw_2(NUM_TESTS, SMALL_MAG); + tst_pw_3(NUM_TESTS, SMALL_MAG); + tst_neg(NUM_TESTS, SMALL_MAG); + tst_sub(NUM_TESTS, SMALL_MAG); + tst_mul(NUM_TESTS, SMALL_MAG); + tst_add(NUM_TESTS, SMALL_MAG); +} diff --git a/test/interval_arithmetic.cpp b/test/interval_arithmetic.cpp new file mode 100644 index 000000000..bffe3ea27 --- /dev/null +++ b/test/interval_arithmetic.cpp @@ -0,0 +1,243 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + interval_arithmetic.cpp + +Abstract: + + Test interval arithmetic + +Author: + + Nikolaj Bjorner (nbjorner) 2006-12-05. + +Revision History: + +--*/ +#include +#include"interval_arithmetic.h" +#include"trace.h" + + +template +void tst_ext_number() { + typedef ext_number num; + num zero; + num one(1); + num eps(num::epsilon()); + num m_eps(num::epsilon().neg()); + num two(number(2)); + num half(number(1,2)); + num inf = num::infinity(); + num eps1 = num::epsilon(); + num three(number(3)); + num three_e = num::plus(three, num::epsilon()); + SASSERT(zero.get_sign() == num::ZERO); + SASSERT(one.get_sign() == num::POSITIVE); + SASSERT(m_eps.get_sign() == num::NEGATIVE); + SASSERT(inf.get_sign() == num::POSITIVE); + SASSERT(zero.is_zero()); + SASSERT(!one.is_zero()); + SASSERT(!inf.is_zero()); + SASSERT(inf.is_infinite()); + SASSERT(!one.is_infinite()); + SASSERT(one.is_pos()); + SASSERT(m_eps.is_neg()); + SASSERT(one != zero); + SASSERT(inf != one); + SASSERT(inf != zero); + SASSERT(zero == zero); + SASSERT(zero < one); + SASSERT(eps < two); + SASSERT(zero < eps); + SASSERT(zero < inf); + SASSERT(zero == min(zero, eps)); + SASSERT(zero == min(zero, inf)); + SASSERT(eps == max(zero, eps)); + SASSERT(inf == max(zero, inf)); + SASSERT(min(zero,eps) == min(eps,zero)); + SASSERT(num::plus(zero, eps) == eps); + SASSERT(num::plus(zero, one) == one); + SASSERT(num::plus(zero, inf) == inf); + SASSERT(num::plus(inf, inf) == inf); + SASSERT(inf.neg() < inf); + SASSERT(inf.neg() < zero); + SASSERT(num::minus(zero, one) == one.neg()); + SASSERT(num::minus(zero, eps) == eps.neg()); + SASSERT(num::minus(zero, inf) == inf.neg()); + SASSERT(num::minus(zero, inf.neg()) == inf); + SASSERT(num::minus(inf, inf.neg()) == inf); + + // sup_mult, inf_mult + SASSERT(sup_mult(zero, one) == zero); + SASSERT(sup_mult(one, one) == one); + SASSERT(sup_mult(one, one.neg()) == one.neg()); + SASSERT(inf_mult(zero, one) == zero); + SASSERT(inf_mult(one, one) == one); + SASSERT(inf_mult(one, one.neg()) == one.neg()); + + // sup_div, inf_div + SASSERT(one < sup_div(three_e, three)); + SASSERT(inf_div(three, three_e) < one); + SASSERT(inf_div(three_e, three) < two); + SASSERT(inf_div(three.neg(), three_e.neg()) < one); + SASSERT(one < sup_div(three_e.neg(), three.neg())); + SASSERT(inf_div(three_e.neg(), three.neg()) < two); + + // sup_power, inf_power + SASSERT(sup_power(one,3) == one); + SASSERT(sup_power(one,3) > zero); + SASSERT(sup_power(num::plus(one, num::epsilon()),3) > one); + + SASSERT(sup_power(one,2) == one); + SASSERT(sup_power(one,2) > zero); + SASSERT(sup_power(num::plus(one, num::epsilon()),2) > one); + + // sup_root, inf_root + SASSERT(sup_root(one,2) >= zero); + SASSERT(inf_root(one,2) <= one); + SASSERT(sup_root(zero,2) >= zero); + SASSERT(inf_root(zero,2) <= zero); + +} + +template +void tst_interval() +{ + typedef interval interval; + typedef ext_number ext_num; + ext_num m_inf(ext_num::infinity().neg()); + ext_num m_three(ext_num(3).neg()); + ext_num m_three_m_e(ext_num::plus(ext_num(3), ext_num::epsilon()).neg()); + ext_num m_three_p_e(ext_num::plus(ext_num(3), ext_num::epsilon().neg()).neg()); + ext_num m_eps(ext_num::epsilon().neg()); + ext_num zero(0); + ext_num eps(ext_num::epsilon()); + ext_num three(ext_num(3)); + ext_num three_m_e(ext_num::minus(ext_num(3), ext_num::epsilon())); + ext_num three_p_e(ext_num::plus(ext_num(3), ext_num::epsilon())); + ext_num inf(ext_num::infinity()); + ext_num nums[] = { m_inf, m_three_m_e, m_three, m_three_p_e, m_eps, zero, eps, three_m_e, three, three_p_e, inf }; + + unsigned n_nums = 11; + // + // add_lower + // add_upper + // + for (unsigned i = 0; i < n_nums; ++i) { + for (unsigned j = i+1; j < n_nums; ++j) { + + for (unsigned k = 0; k < n_nums; ++k) { + interval i1(nums[i], nums[j]); + bool ok = i1.add_lower(nums[k]); + TRACE("interval_arithmetic", tout << "lower: " << ok << " " + << nums[k] << " " << i1 << std::endl;); + } + + for (unsigned k = 0; k < n_nums; ++k) { + interval i1(nums[i], nums[j]); + bool ok = i1.add_upper(nums[k]); + TRACE("interval_arithmetic", tout << "upper: " << ok << " " + << nums[k] << " " << i1 << std::endl;); + } + } + } + + // + // + + // * + // - + // quotient + // + for (unsigned i = 0; i < n_nums; ++i) { + for (unsigned j = i+1; j < n_nums; ++j) { + interval i1(nums[i],nums[j]); + + interval x = i1.power(0); + interval y = i1.power(1); + interval z = i1.power(2); + interval x1 = i1.power(3); + + for (unsigned k = 0; k < n_nums; ++k) { + for (unsigned l = k+1; l < n_nums; ++l) { + interval i2(nums[k],nums[l]); + interval i3 = i1 + i2; + interval i4 = i1 - i2; + interval i5 = i1 * i2; + TRACE("interval_arithmetic", tout << i1 << " + " << i2 << " = " << i3 << std::endl;); + TRACE("interval_arithmetic", tout << i1 << " - " << i2 << " = " << i4 << std::endl;); + TRACE("interval_arithmetic", tout << i1 << " * " << i2 << " = " << i5 << std::endl;); + SASSERT(i5 == i2 * i1); + vector intervals; + interval::quotient(i1, i2, intervals); + TRACE("interval_arithmetic", + tout << i1 << " / " << i2 << " = " ; + for (unsigned idx = 0; idx < intervals.size(); ++idx) { + tout << intervals[idx] << " "; + } + tout << std::endl; + ); + + unsigned changed_bounds; + x = i1; + y = i2; + z = i3; + TRACE("interval_arithmetic", tout << "check: " << i1 << "=" << i2 << "*" << i3 << std::endl;); + if (interval::check_mult(x, y, z, changed_bounds)) { + TRACE("interval_arithmetic", tout << x << "=" << y << "*" << z << std::endl;); + SASSERT (!!(changed_bounds & 0x1) == (x.low() != i1.low())); + SASSERT (!!(changed_bounds & 0x2) == (x.high() != i1.high())); + SASSERT (!!(changed_bounds & 0x4) == (y.low() != i2.low())); + SASSERT (!!(changed_bounds & 0x8) == (y.high() != i2.high())); + SASSERT (!!(changed_bounds & 0x10) == (z.low() != i3.low())); + SASSERT (!!(changed_bounds & 0x20) == (z.high() != i3.high())); + } + else { + TRACE("interval_arithmetic", tout << "unsat" << std::endl;); + } + + x = i1; + y = i2; + if (interval::check_power(x, y, 3, changed_bounds)) { + TRACE("interval_arithmetic", + tout << "check: " << i1 << "=" << i2 << "^3" << " -> " + << x << " = " << y << "^3" << std::endl;); + } + else { + TRACE("interval_arithmetic", tout << "unsat: " << i1 << "=" << i2 << "^4" << std::endl;); + } + + + x = i1; + y = i2; + if (interval::check_power(x, y, 4, changed_bounds)) { + TRACE("interval_arithmetic", + tout << "check: " << i1 << "=" << i2 << "^4" << " -> " + << x << " = " << y << "^4" << std::endl;); + } + else { + TRACE("interval_arithmetic", tout << "unsat: " << i1 << "=" << i2 << "^4" << std::endl;); + } + } + } + } + } + + + // check_mult(i1, i2, i3, change_bounds); + + // check_power(i1, i2, power, changed_bounds); +} + +struct eps1 { rational operator()() { return rational(1); } }; +struct eps0 { inf_rational operator()() { return inf_rational(rational(0),true); } }; + +void tst_interval_arithmetic() { + TRACE("interval_arithmetic", tout << "starting interval_arithmetic test...\n";); + tst_ext_number(); + tst_ext_number(); + tst_interval(); + tst_interval(); +} diff --git a/test/interval_skip_list.cpp b/test/interval_skip_list.cpp new file mode 100644 index 000000000..bda85c86e --- /dev/null +++ b/test/interval_skip_list.cpp @@ -0,0 +1,716 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + interval_skip_list.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-10-05. + +Revision History: + +--*/ + +#include"interval_skip_list.h" +#include"map.h" +#include"vector.h" + +typedef sl_manager_base slist_manager; +template class interval_skip_list, 4, 4, false, slist_manager> >; +typedef interval_skip_list, 4, 4, false, slist_manager> > slist; +typedef u_map u2u_map; +typedef unsigned_isp_set<4, 4, slist_manager> uset; + +static void tst1() { + slist_manager m; + slist l(m); + SASSERT(l.check_invariant()); + SASSERT(l.empty()); + // l.display_physical(std::cout); + l.insert(m, 20, 30, 5); + l.insert(m, 31, 32, 5); + l.insert(m, 18, 19, 5); + // l.display_physical(std::cout); + SASSERT(l.check_invariant()); + l.insert(m, 10, 15, 8); + SASSERT(l.check_invariant()); + // l.display_physical(std::cout); + l.insert(m, 5, 25, 7); + SASSERT(l.check_invariant()); + // l.display_physical(std::cout); + l.insert(m, 23, 27, 5); + // l.display_physical(std::cout); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +static void tst2() { + slist_manager(m); + slist l(m); + for(unsigned i = 0; i < 50; i++) { + l.insert(m,i,i,i*10); + } + // l.display_physical(std::cout); + SASSERT(l.check_invariant()); + for (unsigned i = 0; i < 25; i++) { + l.insert(m,i*2,i*2+1,i*20+1); + } + // l.display_physical(std::cout); + SASSERT(l.check_invariant()); + for (unsigned i = 0; i < 15; i++) { + l.insert(m,i*3,i*3+2,i*30+1); + } + SASSERT(l.check_invariant()); + // l.display_physical(std::cout); + // l.compress(4); + // l.display_physical(std::cout); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +static bool check_interval(slist & l, unsigned k1, unsigned k2, unsigned val) { + for (unsigned i = k1; i <= k2; i++) { + DEBUG_CODE({ + unsigned _val; + SASSERT(l.contains(i, _val) && _val == val); + }); + } + return true; +} + +static bool check_no_interval(slist & l, unsigned k1, unsigned k2) { + for (unsigned i = k1; i <= k2; i++) { + DEBUG_CODE({ + unsigned _val; + SASSERT(!l.contains(i, _val)); + }); + } + return true; +} + +static void tst4() { + slist_manager m; + slist l(m); + l.insert(m, 1, 10, 0); + l.insert(m, 2, 5, 1); + SASSERT(check_no_interval(l,0,0)); + SASSERT(check_interval(l,1,1,0)); + SASSERT(check_interval(l,2,5,1)); + SASSERT(check_interval(l,6,10,0)); + SASSERT(check_no_interval(l,11,20)); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +static void tst5() { + slist_manager m; + slist l(m); + l.insert(m, 1, 5, 0); + l.insert(m, 8, 100, 1); + l.insert(m, 8, 20, 1); + SASSERT(check_no_interval(l,0,0)); + SASSERT(check_interval(l,1,5,0)); + SASSERT(check_no_interval(l,6,7)); + SASSERT(check_interval(l,8,100,1)); + SASSERT(check_no_interval(l,101,200)); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +static void tst6() { + slist_manager m; + slist l(m); + l.insert(m, 1, 5, 0); + l.insert(m, 8, 100, 1); + l.insert(m, 3, 20, 1); + SASSERT(check_no_interval(l,0,0)); + SASSERT(check_interval(l,1,2,0)); + SASSERT(check_interval(l,3,100,1)); + SASSERT(check_no_interval(l,101,200)); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +static void tst7() { + slist_manager m; + slist l(m); + l.insert(m, 1, 5, 0); + l.insert(m, 8, 100, 1); + l.insert(m, 2, 12, 0); + SASSERT(check_no_interval(l,0,0)); + SASSERT(check_interval(l,1,12,0)); + SASSERT(check_interval(l,13,100,1)); + SASSERT(check_no_interval(l,101,200)); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +static void tst8() { + slist_manager m; + slist l(m); + for (unsigned i = 0; i < 100; i++) { + l.insert(m, 10*i, 10*i+5, i); + } + SASSERT(!l.empty()); + l.insert(m, 0, 10000, 0); + SASSERT(!l.has_more_than_k_entries(1)); + // l.display_physical(std::cout); + l.deallocate(m); +} + +struct for_each_contains { + slist const & m_other; + + for_each_contains(slist const & other):m_other(other) {} + + bool operator()(unsigned b, unsigned e, unsigned v) { + for (unsigned i = b; i <= e; i++) { + DEBUG_CODE({ + unsigned _v; + SASSERT(m_other.contains(i, _v)); + SASSERT(v == _v); + }); + } + return true; + } +}; + +static void random_tsts(unsigned num_ops, unsigned max_key, unsigned max_val, unsigned max_interval_size) { + slist_manager m; + slist m1(m); + u2u_map m2; + for (unsigned i = 0; i < num_ops; i++) { + SASSERT(m1.check_invariant()); + TRACE("interval_skip_list", tout << "i: " << i << "\n"; m1.display_physical(tout);); + // std::cout << i << std::endl; + int op = rand()%8; + if (op < 3) { + unsigned bg = rand() % max_key; + unsigned sz = rand() % max_interval_size; + if (sz == 0) sz = 1; + unsigned val = rand() % max_val; + m1.insert(m, bg, bg+sz, val); + for (unsigned j = bg; j <= bg+sz; j++) { + DEBUG_CODE({ + unsigned _val; + SASSERT(m1.contains(j, _val)); + CTRACE("interval_skip_list", val != _val, tout << "i: " << i << ", j: " << j << ", val: " << val << ", _val: " << _val << "\n"; m1.display_physical(tout);); + SASSERT(val == _val); + TRACE("interval_skip_list", tout << "[insert]: " << j << " -> " << val << "\n";); + }); + m2.insert(j, val); + } + } + else if (op < 4) { + unsigned bg = rand() % max_key; + unsigned sz = rand() % max_interval_size; + if (sz == 0) sz = 1; + m1.erase(m, bg, bg+sz); + for (unsigned i = bg; i <= bg+sz; i++) { + m2.erase(i); + } + } + else if (op < 5) { + slist m1_copy(m); + m1_copy.copy(m, m1); + for_each_contains proc1(m1); + for_each_contains proc2(m1_copy); + m1.for_each(proc2); + m1_copy.for_each(proc1); + // m1.display_physical(std::cout); + // std::cout << "COPY===>\n"; + // m1_copy->display_physical(std::cout); + m1_copy.deallocate(m); + } + else if (op < 6) { + m1.compress(m, 3); + } + else { + SASSERT(m1.check_invariant()); + u2u_map::iterator it = m2.begin(); + u2u_map::iterator end = m2.end(); + for (; it != end; ++it) { + DEBUG_CODE({ + unsigned _val; + CTRACE("interval_skip_list", !m1.contains(it->m_key, _val), + tout << it->m_key << " -> " << it->m_value << "\n"; + m1.display_physical(tout);); + SASSERT(m1.contains(it->m_key, _val)); + SASSERT(it->m_value == _val); + }); + } + } + } + // m1.display_physical(std::cout); + // m1.compress(4); + // m1.display_physical(std::cout); + m1.deallocate(m); +} + +static void tst9() { + slist_manager m; + slist l(m); + l.insert(m,10,10,1); + l.insert(m,9,9,0); + l.insert(m,8,8,2); + l.insert(m,7,7,3); + l.insert(m,6,8,3); + SASSERT(!l.has_more_than_k_buckets(1)); + SASSERT(check_no_interval(l,0,5)); + SASSERT(check_interval(l,6,8,3)); + SASSERT(check_interval(l,9,9,0)); + SASSERT(check_interval(l,10,10,1)); + SASSERT(check_no_interval(l,11,20)); + l.deallocate(m); +} + +static void tst10() { + slist_manager m; + slist l(m); + l.insert(m,10,10,1); + l.insert(m,13,16,2); + l.insert(m,17,28,3); + l.remove(m,12,19); + SASSERT(l.check_invariant()); + SASSERT(check_no_interval(l,0,9)); + SASSERT(check_interval(l,10,10,1)); + SASSERT(check_no_interval(l,12,19)); + SASSERT(check_interval(l,20,28,3)); + SASSERT(check_no_interval(l,29,100)); + l.remove(m,10,11); + SASSERT(l.check_invariant()); + SASSERT(check_no_interval(l,0,19)); + SASSERT(check_interval(l,20,28,3)); + SASSERT(check_no_interval(l,29,100)); + l.remove(m,0,1000); + SASSERT(l.empty()); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +static void tst11() { + slist_manager m; + slist l(m); + l.insert(m,11,20,1); + l.insert(m,21,30,2); + l.insert(m,31,40,3); + l.insert(m,41,50,4); + l.insert(m,51,60,5); + l.compress(m,4); + SASSERT(check_no_interval(l,0,10)); + SASSERT(check_interval(l,11,20,1)); + SASSERT(check_interval(l,21,30,2)); + SASSERT(check_interval(l,31,40,3)); + SASSERT(check_interval(l,41,50,4)); + SASSERT(check_interval(l,51,60,5)); + SASSERT(check_no_interval(l,61,100)); + SASSERT(l.check_invariant()); + l.remove(m, 25, 26); + SASSERT(check_no_interval(l,0,10)); + SASSERT(check_interval(l,11,20,1)); + SASSERT(check_interval(l,21,24,2)); + SASSERT(check_no_interval(l,25,26)); + SASSERT(check_interval(l,27,30,2)); + SASSERT(check_interval(l,31,40,3)); + SASSERT(check_interval(l,41,50,4)); + SASSERT(check_interval(l,51,60,5)); + SASSERT(check_no_interval(l,61,100)); + SASSERT(l.check_invariant()); + l.remove(m, 44,48); + SASSERT(check_no_interval(l,0,10)); + SASSERT(check_interval(l,11,20,1)); + SASSERT(check_interval(l,21,24,2)); + SASSERT(check_no_interval(l,25,26)); + SASSERT(check_interval(l,27,30,2)); + SASSERT(check_interval(l,31,40,3)); + SASSERT(check_interval(l,41,43,4)); + SASSERT(check_no_interval(l,44,48)); + SASSERT(check_interval(l,49,50,4)); + SASSERT(check_interval(l,51,60,5)); + SASSERT(check_no_interval(l,61,100)); + SASSERT(l.check_invariant()); + l.remove(m, 22,24); + SASSERT(check_no_interval(l,0,10)); + SASSERT(check_interval(l,11,20,1)); + SASSERT(check_interval(l,21,21,2)); + SASSERT(check_no_interval(l,22,26)); + SASSERT(check_interval(l,27,30,2)); + SASSERT(check_interval(l,31,40,3)); + SASSERT(check_interval(l,41,43,4)); + SASSERT(check_no_interval(l,44,48)); + SASSERT(check_interval(l,49,50,4)); + SASSERT(check_interval(l,51,60,5)); + SASSERT(check_no_interval(l,61,100)); + SASSERT(l.check_invariant()); + l.remove(m, 42,49); + SASSERT(check_no_interval(l,0,10)); + SASSERT(check_interval(l,11,20,1)); + SASSERT(check_interval(l,21,21,2)); + SASSERT(check_no_interval(l,22,26)); + SASSERT(check_interval(l,27,30,2)); + SASSERT(check_interval(l,31,40,3)); + SASSERT(check_interval(l,41,41,4)); + SASSERT(check_no_interval(l,42,49)); + SASSERT(check_interval(l,50,50,4)); + SASSERT(check_interval(l,51,60,5)); + SASSERT(check_no_interval(l,61,100)); + SASSERT(l.check_invariant()); + // l.display_physical(std::cout); + l.deallocate(m); +} + +static void tst12() { + slist_manager m; + slist l(m); + l.insert(m,10,10,0); + l.insert(m,9,9,0); + SASSERT(l.check_invariant()); + l.insert(m,8,9,1); + SASSERT(l.check_invariant()); + l.insert(m,7,7,2); + SASSERT(l.check_invariant()); + l.insert(m,6,6,3); + SASSERT(l.check_invariant()); + l.insert(m,4,5,2); + SASSERT(l.check_invariant()); + l.insert(m,3,9,0); + // l.display_physical(std::cout); + l.deallocate(m); +} + +static void tst13() { + slist_manager m; + uset s(m); + s.insert(m, 10, 30); + s.insert(m, 32, 40); + s.display(std::cout); + std::cout << ", mem: " << s.memory() << "\n"; + s.deallocate(m); +} + +struct obj { + unsigned m_val; + unsigned m_ref_count; + void inc_ref() { + m_ref_count++; + } + void dec_ref() { + SASSERT(m_ref_count > 0); + m_ref_count--; + if (m_ref_count == 0) + dealloc(this); + } + obj(unsigned v):m_val(v), m_ref_count(0) { + } +}; + +std::ostream & operator<<(std::ostream & out, obj * o) { + out << o->m_val << "{" << o->m_ref_count << "}"; + return out; +} + +struct obj_slist_manager : public sl_manager_base { + void inc_ref_eh(obj * v) { + v->inc_ref(); + } + + void dec_ref_eh(obj * v) { + v->dec_ref(); + } +}; + +struct inc_ref_functor { + unsigned_vector & refs; + inc_ref_functor(unsigned_vector & r):refs(r) {} + bool operator()(unsigned b, unsigned e, obj * val) { + refs[val->m_val]++; + return true; + } +}; + +template class interval_skip_list, 16, 16, true, obj_slist_manager> >; +typedef interval_skip_list, 16, 16, true, obj_slist_manager> > obj_slist; + +void random_tsts_ref(unsigned num_ops, unsigned num_objs, unsigned max_key, unsigned max_interval_size) { + obj_slist_manager m; + obj_slist l(m); + ptr_vector objs; + unsigned_vector refs; + for (unsigned i = 0; i < num_objs; i++) { + objs.push_back(alloc(obj, i)); + objs.back()->inc_ref(); + refs.push_back(1); + } + + for (unsigned i = 0; i < num_ops; i++) { + SASSERT(l.check_invariant()); + TRACE("interval_skip_list", tout << "i: " << i << "\n"; l.display_physical(tout); tout << "\n";); + int op = rand()%5; + if (op < 3) { + unsigned bg = rand() % max_key; + unsigned sz = rand() % max_interval_size; + if (sz == 0) sz = 1; + unsigned val = rand() % num_objs; + TRACE("interval_skip_list", tout << "[inserting]: [" << bg << ", " << (bg+sz) << "] -> " << objs[val] << "\n";); + l.insert(m, bg, bg+sz, objs[val]); + SASSERT(objs[val]->m_ref_count > 1); + } + else if (op < 4) { + unsigned bg = rand() % max_key; + unsigned sz = rand() % max_interval_size; + if (sz == 0) sz = 1; + TRACE("interval_skip_list", tout << "[erasing]: [" << bg << ", " << (bg+sz) << "]\n";); + l.erase(m, bg, bg+sz); + } + else if (op < 5) { + obj_slist l_copy(m); + l_copy.copy(m, l); + TRACE("interval_skip_list", tout << "[copying]\n";); + l_copy.deallocate(m); + TRACE("interval_skip_list", tout << "[deleting copy]\n";); + } + else { + TRACE("interval_skip_list", tout << "[compressing]\n";); + l.compress(m, 3); + } + // check ref-counts + inc_ref_functor proc(refs); + l.for_each(proc); + for (unsigned i = 0; i < num_objs; i++) { + CTRACE("interval_skip_list", refs[i] != objs[i]->m_ref_count, + tout << "i: " << i << ", objs[i]: " << objs[i] << ", refs[i]: " << refs[i] << "\n\n"; + l.display_physical(tout);); + SASSERT(refs[i] == objs[i]->m_ref_count); + refs[i] = 1; + } + } + l.deallocate(m); + for (unsigned i = 0; i < num_objs; i++) { + SASSERT(objs[i]->m_ref_count == 1); + objs[i]->dec_ref(); + } +} + +void tst_ref() { + obj_slist_manager m; + obj_slist l(m); + for (unsigned i = 0; i < 30; i++) { + obj * n = alloc(obj, i); + l.insert(m, i*10, i*10+3, n); + // l.display_physical(std::cout); + // std::cout << "memory: " << l.memory() << "\n"; + } + l.deallocate(m); + +} + +void tst_push_back_aux(slist::push_back_proc & push_back, unsigned num_ops, unsigned max_int, unsigned max_sep, unsigned max_val) { + unsigned prev_key; + + if (push_back.empty()) + prev_key = 0; + else + prev_key = push_back.last_key(); + + for (unsigned i = 0; i < num_ops; i++) { + unsigned next_key = prev_key + 1; + next_key += (rand() % max_sep); + unsigned sz = rand() % max_int; + if (sz == 0) sz = 1; + unsigned val = rand() % max_val; + push_back(next_key, next_key+sz, val); + SASSERT(!push_back.empty()); + prev_key = push_back.last_key(); + } +} + +void tst_push_back1(unsigned num_ops, unsigned max_int, unsigned max_sep, unsigned max_val) { + slist_manager m; + slist l(m); + slist::push_back_proc push_back(m, l); + + tst_push_back_aux(push_back, num_ops, max_int, max_sep, max_val); + // l.display_physical(std::cout); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +void tst_push_back2(unsigned num_ops, unsigned max_int, unsigned max_sep, unsigned max_val) { + slist_manager m; + slist l(m); + + // insert some random values before creating push_back functor + for (unsigned i = 0; i < num_ops; i++) { + unsigned next_key = rand() % (num_ops * max_int/2); + unsigned sz = rand() % max_int; + if (sz == 0) sz = 1; + unsigned val = rand() % max_val; + l.insert(m, next_key, next_key+sz, val); + } + + slist::push_back_proc push_back(m, l); + + tst_push_back_aux(push_back, num_ops, max_int, max_sep, max_val); + + // l.display_physical(std::cout); + SASSERT(l.check_invariant()); + l.deallocate(m); +} + +void tst_find_geq1() { + slist_manager m; + slist l(m); + l.insert(m, 10, 20, 4); + l.insert(m, 23, 30, 3); + l.insert(m, 40, 45, 10); + l.insert(m, 50, 66, 1); + l.insert(m, 100, 120, 21); + l.insert(m, 140, 200, 2); + slist::iterator it = l.find_geq(22); + SASSERT(it->begin_key() == 23); + it = l.find_geq(42); + SASSERT(it->begin_key() == 40); + it.move_to(130); + SASSERT(it->begin_key() == 140); + it.move_to(400); + SASSERT(it == l.end()); + it = l.find_geq(300); + SASSERT(it == l.end()); + it = l.find_geq(9); + SASSERT(it->begin_key() == 10); + it.move_to(105); + SASSERT(it->begin_key() == 100); + it = l.find_geq(15); + SASSERT(it->begin_key() == 10); + it.move_to(31); + SASSERT(it->begin_key() == 40); + it = l.find_geq(22); + SASSERT(it->begin_key() == 23); + it = l.find_geq(124); + SASSERT(it->begin_key() == 140); + it = l.find_geq(102); + SASSERT(it->begin_key() == 100); + // l.display_physical(std::cout); + l.deallocate(m); +} + +struct add42 { + unsigned operator()(unsigned v) { return v + 42; } +}; + +void tst_move_to() { + slist_manager m; + slist l(m); + for (unsigned i = 0; i < 500; i++) + l.insert(m, i*10, i*10 + 5, i); + l.compress(m, 4); + slist::iterator it = l.find_geq(137); + SASSERT(it->begin_key() == 140); + it.move_to(947); + SASSERT(it->begin_key() == 950); + it.move_to(4955); + SASSERT(it->begin_key() == 4950); + it.move_to(4955); + SASSERT(it->begin_key() == 4950); + it.move_to(4956); + SASSERT(it->begin_key() == 4960); + it.move_to(4982); + SASSERT(it->begin_key() == 4980); + it.move_to(4987); + SASSERT(it->begin_key() == 4990); + it.move_to(4990); + SASSERT(it->begin_key() == 4990); + it.move_to(4995); + SASSERT(it->begin_key() == 4990); + it.move_to(4996); + SASSERT(it.at_end()); + // l.display_physical(std::cout); + add42 f; + // l.display(std::cout); std::cout << "\n"; + l.update_values(m, f); + // l.display(std::cout); std::cout << "\n"; + l.deallocate(m); +} + +static void tst_ext_iterator() { + slist_manager m; + slist l(m); + for (unsigned i = 0; i < 20; i++) + l.insert(m, i*10, i*10 + 5, i); + l.compress(m, 4); + l.display_physical(std::cout); std::cout << "\n"; + slist::ext_iterator it; + slist::ext_iterator end; + SASSERT(end.at_end()); + l.move_geq(it, 92); + SASSERT(!it.at_end()); + SASSERT(it->begin_key() == 90); + it++; + SASSERT(it->begin_key() == 100); + it.erase(m); + SASSERT(it->begin_key() == 110); + it.erase(m); + SASSERT(it->begin_key() == 120); + it.erase(m); + it.erase(m); + it.erase(m); + it.erase(m); + SASSERT(it->begin_key() == 160); + SASSERT(l.check_invariant()); + l.display_physical(std::cout); std::cout << "\n"; + l.move_geq(it, 0); + SASSERT(it->begin_key() == 0); + it.erase(m); + SASSERT(it->begin_key() == 10); + it.erase(m); + SASSERT(it->begin_key() == 20); + it.erase(m); + SASSERT(it->begin_key() == 30); + it.erase(m); + SASSERT(it->begin_key() == 40); + it.erase(m); + SASSERT(it->begin_key() == 50); + l.display_physical(std::cout); std::cout << "\n"; + l.deallocate(m); +} + +void tst_interval_skip_list() { + std::cout << "unsigned map stats:\n"; + slist::display_size_info(std::cout); + std::cout << "\nunsigned set stats:\n"; + uset::display_size_info(std::cout); + std::cout << "\n"; + tst1(); +// enable_trace("interval_skip_list_insert_bug"); +// enable_trace("interval_skip_list_bug"); +// enable_trace("del_entries_upto_bug"); +// enable_trace("insert_inside_bug"); +// enable_trace("insert_at_bug"); + tst2(); + tst4(); + tst5(); + tst6(); + tst7(); + tst8(); + tst9(); + tst10(); + tst11(); + tst12(); + tst13(); + tst_find_geq1(); + tst_move_to(); + tst_push_back1(300, 4, 2, 10); + tst_push_back2(300, 4, 2, 10); + random_tsts(1000, 20, 20, 5); + random_tsts_ref(1000, 20, 20, 5); + tst_ref(); + tst_ext_iterator(); +} + + diff --git a/test/list.cpp b/test/list.cpp new file mode 100644 index 000000000..5672f4246 --- /dev/null +++ b/test/list.cpp @@ -0,0 +1,44 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + list.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2007-07-10. + +Revision History: + +--*/ +#include"trace.h" +#include"util.h" +#include"region.h" +#include"list.h" + +static void tst1() { + region r; + list * l1 = new (r) list(10); + list * l2 = new (r) list(20, l1); + list * l3 = new (r) list(30); + list * l4 = new (r) list(40, l3); + SASSERT(append(r, l1, static_cast *>(0)) == l1); + SASSERT(append(r, l2, static_cast *>(0)) == l2); + SASSERT(append(r, static_cast *>(0), l2) == l2); + SASSERT(append(r, static_cast *>(0), static_cast *>(0)) == 0); + TRACE("list", display(tout, l2->begin(), l2->end()); tout << "\n";); + list * l5 = append(r, l4, l2); + TRACE("list", display(tout, l5->begin(), l5->end()); tout << "\n";); + list * l6 = append(r, l5, l5); + TRACE("list", display(tout, l6->begin(), l6->end()); tout << "\n";); +} + +void tst_list() { + tst1(); +} + diff --git a/test/main.cpp b/test/main.cpp new file mode 100644 index 000000000..cc3c59158 --- /dev/null +++ b/test/main.cpp @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include"util.h" +#include"trace.h" +#include"debug.h" +#include"timeit.h" +#include"warning.h" +#include "memory_manager.h" + +// +// Unit tests fail by asserting. +// If they return, we assume the unit test succeeds +// and print "PASS" to indicate success. +// + +#define TST(MODULE) { \ + std::string s("test "); \ + s += #MODULE; \ + void tst_##MODULE(); \ + if (do_display_usage) \ + std::cout << #MODULE << "\n"; \ + for (int i = 0; i < argc; i++) \ + if (strcmp(argv[i], #MODULE) == 0) { \ + enable_trace(#MODULE); \ + enable_debug(#MODULE); \ + timeit timeit(true, s.c_str()); \ + tst_##MODULE(); \ + std::cout << "PASS" << std::endl; \ + } \ +} + +#define TST_ARGV(MODULE) { \ + std::string s("test "); \ + s += #MODULE; \ + void tst_##MODULE(char** argv, int argc, int& i); \ + if (do_display_usage) \ + std::cout << #MODULE << "\n"; \ + for (int i = 0; i < argc; i++) \ + if (strcmp(argv[i], #MODULE) == 0) { \ + enable_trace(#MODULE); \ + enable_debug(#MODULE); \ + timeit timeit(true, s.c_str()); \ + tst_##MODULE(argv, argc, i); \ + std::cout << "PASS" << std::endl; \ + } \ +} + +void error(const char * msg) { + std::cerr << "Error: " << msg << "\n"; + std::cerr << "For usage information: test /h\n"; + exit(1); +} + +void display_usage() { + std::cout << "Z3 unit tests [version 1.0]. (C) Copyright 2006 Microsoft Corp.\n"; + std::cout << "Usage: test [options] [module names]\n"; + std::cout << "\nMisc.:\n"; + std::cout << " /h prints this message.\n"; + std::cout << " /v:level be verbose, where is the verbosity level.\n"; + std::cout << " /w enable warning messages.\n"; +#if defined(Z3DEBUG) || defined(_TRACE) + std::cout << "\nDebugging support:\n"; +#endif +#ifdef _TRACE + std::cout << " /tr:tag enable trace messages tagged with .\n"; +#endif +#ifdef Z3DEBUG + std::cout << " /dbg:tag enable assertions tagged with .\n"; +#endif +} + +void parse_cmd_line_args(int argc, char ** argv, bool& do_display_usage) { + int i = 1; + while (i < argc) { + char * arg = argv[i]; + + if (arg[0] == '-' || arg[0] == '/') { + char * opt_name = arg + 1; + char * opt_arg = 0; + char * colon = strchr(arg, ':'); + if (colon) { + opt_arg = colon + 1; + *colon = 0; + } + if (strcmp(opt_name, "h") == 0 || + strcmp(opt_name, "?") == 0) { + display_usage(); + do_display_usage = true; + return; + } + else if (strcmp(opt_name, "v") == 0) { + if (!opt_arg) + error("option argument (/v:level) is missing."); + long lvl = strtol(opt_arg, 0, 10); + set_verbosity_level(lvl); + } + else if (strcmp(opt_name, "w") == 0) { + enable_warning_messages(true); + } +#ifdef _TRACE + else if (strcmp(opt_name, "tr") == 0) { + if (!opt_arg) + error("option argument (/tr:tag) is missing."); + enable_trace(opt_arg); + } +#endif +#ifdef Z3DEBUG + else if (strcmp(opt_name, "dbg") == 0) { + if (!opt_arg) + error("option argument (/dbg:tag) is missing."); + enable_debug(opt_arg); + } +#endif + } + i++; + } +} + + +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); + TST(region); + 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); + TST(splay_tree); + TST(fvi); + TST(proof_checker); + TST(simplifier); + TST(bv_simplifier_plugin); + 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); + TST(no_overflow); + TST(memory); + TST(parallel); + 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); + TST(mpq); + TST(mpf); + TST(total_order); + TST(dl_table); + TST(dl_context); + TST(dl_smt_relation); + TST(dl_query); + TST(dl_util); + TST(dl_product_relation); + TST(dl_relation); + TST(imdd); + TST(array_property_expander); + TST(parray); + TST(stack); + TST(escaped); + TST(buffer); + TST(chashtable); + TST(ex); + TST(nlarith_util); + TST(api_bug); + TST(arith_rewriter); + TST(check_assumptions); + TST(smt_context); + TST(theory_dl); + TST(model_retrieval); + TST(factor_rewriter); + TST(smt2print_parse); + TST(substitution); + TST(polynomial); + TST(upolynomial); + TST(algebraic); + TST(polynomial_factorization); + TST(prime_generator); + TST(permutation); + TST(nlsat); + TST(qe_defs); + TST(ext_numeral); + TST(interval); + TST(quant_solve); + TST(f2n); + TST(hwf); + TST(trigo); + TST(bits); + TST(mpbq); + TST(mpfx); + TST(mpff); + TST(horn_subsume_model_converter); + TST(model2expr); +} + +void initialize_mam() {} +void finalize_mam() {} + diff --git a/test/map.cpp b/test/map.cpp new file mode 100644 index 000000000..833da23a8 --- /dev/null +++ b/test/map.cpp @@ -0,0 +1,45 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_map.cpp + +Abstract: + + Test simple mapping. + +Author: + + Leonardo de Moura (leonardo) 2006-10-14. + +Revision History: + +--*/ +#include"map.h" +#include"str_hashtable.h" + +static void tst1() { + map str2int; + str2int.insert("foo", 35); + SASSERT(str2int.contains("foo")); + SASSERT(str2int.find_iterator("foo") != str2int.end()); + SASSERT((*(str2int.find_iterator("foo"))).m_value == 35); + SASSERT(str2int.size() == 1); + str2int.insert("boo", 32); + SASSERT(str2int.contains("foo")); + SASSERT(str2int.find_iterator("foo") != str2int.end()); + SASSERT((*(str2int.find_iterator("foo"))).m_value == 35); + SASSERT(str2int.contains("boo")); + SASSERT(str2int.find_iterator("boo") != str2int.end()); + SASSERT((*(str2int.find_iterator("boo"))).m_value == 32); + SASSERT(str2int.size() == 2); + str2int.remove("boo"); + SASSERT(str2int.size() == 1); + SASSERT(!str2int.contains("boo")); + SASSERT(str2int.contains("foo")); +} + +void tst_map() { + tst1(); +} diff --git a/test/matcher.cpp b/test/matcher.cpp new file mode 100644 index 000000000..aaab9905c --- /dev/null +++ b/test/matcher.cpp @@ -0,0 +1,113 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + matcher.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-04-16. + +Revision History: + +--*/ +#ifdef _WINDOWS +#include"matcher.h" +#include"ast_pp.h" + +void tst_match(ast_manager & m, app * t, app * i) { + substitution s(m); + s.reserve(2, 10); // reserving a big number of variables to be safe. + + matcher match(m); + std::cout << "Is " << mk_pp(i, m) << " an instance of " << mk_pp(t, m) << "\n"; + if (match(t, i, s)) { + std::cout << "yes\n"; + s.display(std::cout); + } + else { + std::cout << "no\n"; + } + + s.reset(); + + if (t->get_decl() == i->get_decl()) { + // trying to match the arguments of t and i + std::cout << "Are the arguments of " << mk_pp(i, m) << " an instance of the arguments of " << mk_pp(t, m) << "\n"; + unsigned num_args = t->get_num_args(); + unsigned j; + for (j = 0; j < num_args; j++) { + if (!match(t->get_arg(j), i->get_arg(j), s)) + break; + } + if (j == num_args) { + std::cout << "yes\n"; + s.display(std::cout); + + // create some dummy term to test for applying the substitution. + sort_ref S( m.mk_sort(symbol("S")), m); + sort * domain[3] = {S, S, S}; + func_decl_ref r( m.mk_func_decl(symbol("r"), 3, domain, S), m); + expr_ref x1( m.mk_var(0, S), m); + expr_ref x2( m.mk_var(1, S), m); + expr_ref x3( m.mk_var(2, S), m); + app_ref rxyzw( m.mk_app(r, x1.get(), x2.get(), x3.get()), m); + expr_ref result(m); + unsigned deltas[2] = {0,0}; + s.apply(2, deltas, expr_offset(rxyzw, 0), result); + std::cout << "applying substitution to\n" << mk_pp(rxyzw,m) << "\nresult:\n" << mk_pp(result,m) << "\n"; + } + else { + std::cout << "no\n"; + } + } + + std::cout << "\n"; +} + +void tst1() { + ast_manager m; + sort_ref s( m.mk_sort(symbol("S")), m); + func_decl_ref g( m.mk_func_decl(symbol("g"), s, s), m); + func_decl_ref h( m.mk_func_decl(symbol("h"), s, s), m); + sort * domain[2] = {s, s}; + func_decl_ref f( m.mk_func_decl(symbol("f"), 2, domain, s), m); + app_ref a( m.mk_const(symbol("a"), s), m); + app_ref b( m.mk_const(symbol("b"), s), m); + expr_ref x( m.mk_var(0, s), m); + expr_ref y( m.mk_var(1, s), m); + app_ref gx( m.mk_app(g, x), m); + app_ref fgx_x( m.mk_app(f, gx.get(), x.get()), m); + app_ref ha( m.mk_app(h, a.get()), m); + app_ref gha( m.mk_app(g, ha.get()), m); + app_ref fgha_ha( m.mk_app(f, gha.get(), ha.get()), m); + tst_match(m, fgx_x, fgha_ha); + + app_ref fgha_gha( m.mk_app(f, gha.get(), gha.get()), m); + tst_match(m, fgx_x, fgha_gha); + + app_ref fxy( m.mk_app(f, x.get(), y.get()), m); + app_ref fyx( m.mk_app(f, y.get(), x.get()), m); + tst_match(m, fxy, fyx); + + app_ref fygx( m.mk_app(f, y.get(), gx.get()), m); + tst_match(m, fxy, fygx); + + tst_match(m, fygx, fxy); + +} + + + +void tst_matcher() { + tst1(); +} +#else +void tst_matcher() { +} +#endif diff --git a/test/memory.cpp b/test/memory.cpp new file mode 100644 index 000000000..8fb09fb3d --- /dev/null +++ b/test/memory.cpp @@ -0,0 +1,54 @@ +#ifdef _WINDOWS +#include "z3.h" +#include "z3_private.h" +#include +#include "util.h" +#include "trace.h" + +static bool oom = false; + + +static void err_handler(Z3_context c, Z3_error_code e) { + oom = true; + throw std::bad_alloc(); +} + +static void hit_me(char const* wm) { + Z3_config cfg; + Z3_context ctx; + + oom = false; + + cfg = Z3_mk_config(); + Z3_set_param_value(cfg, "MEMORY_MAX_SIZE", wm); + ctx = Z3_mk_context(cfg); + Z3_set_error_handler(ctx, &err_handler); + + unsigned i; + for (i = 1; !oom ; ++i) { + try { + Z3_mk_bv_sort(ctx,i); + + } + catch (std::bad_alloc) { + std::cout << "caught\n"; + } + } + + std::cout << "oom " << i << "\n"; +} + +void tst_memory() { + hit_me("1"); + Z3_reset_memory(); + hit_me("2"); + Z3_reset_memory(); + hit_me("3"); + Z3_reset_memory(); + +} + +#else +void tst_memory() { +} +#endif diff --git a/test/model2expr.cpp b/test/model2expr.cpp new file mode 100644 index 000000000..3040ddadc --- /dev/null +++ b/test/model2expr.cpp @@ -0,0 +1,49 @@ +#include "model2expr.h" +#include "ast_pp.h" +#include "arith_decl_plugin.h" +#include "model_smt2_pp.h" + +void tst_model2expr() { + ast_manager m; + m.register_decl_plugins(); + arith_util a(m); + + ptr_vector ints; + ints.push_back(a.mk_int()); + ints.push_back(a.mk_int()); + ints.push_back(a.mk_int()); + + func_decl_ref p(m), q(m), x(m); + p = m.mk_func_decl(symbol("p"), 2, ints.c_ptr(), a.mk_int()); + q = m.mk_func_decl(symbol("q"), 2, ints.c_ptr(), a.mk_int()); + x = m.mk_const_decl(symbol("x"), a.mk_int()); + expr_ref n0(m), n1(m), n2(m); + n0 = a.mk_numeral(rational(0), true); + n1 = a.mk_numeral(rational(1), true); + n2 = a.mk_numeral(rational(2), true); + + model_ref md = alloc(model, m); + func_interp* fip = alloc(func_interp, m, 2); + func_interp* fiq = alloc(func_interp, m, 2); + expr_ref_vector args(m); + args.push_back(n1); + args.push_back(n2); + fip->insert_entry(args.c_ptr(), n1); + fiq->insert_entry(args.c_ptr(), n1); + args[0] = n0; + args[1] = n1; + fip->insert_entry(args.c_ptr(), n2); + fiq->insert_entry(args.c_ptr(), n2); + + fip->set_else(n0); + + md->register_decl(x, a.mk_numeral(rational(0), true)); + md->register_decl(p, fip); // full + md->register_decl(q, fiq); // partial + + expr_ref result(m); + model2expr(md, result); + + model_smt2_pp(std::cout, m, *md, 0); + std::cout << mk_pp(result, m) << "\n"; +} diff --git a/test/model_retrieval.cpp b/test/model_retrieval.cpp new file mode 100644 index 000000000..96d956b0e --- /dev/null +++ b/test/model_retrieval.cpp @@ -0,0 +1,62 @@ + +#include "ast.h" +#include "front_end_params.h" +#include "smt_context.h" +#include "arith_decl_plugin.h" +#include "bv_decl_plugin.h" +#include "array_decl_plugin.h" +#include "model_v2_pp.h" + +void tst_model_retrieval() +{ + memory::initialize(0); + front_end_params params; + params.m_model = true; + + + ast_manager m; + m.register_decl_plugins(); + + family_id array_fid = m.get_family_id(symbol("array")); + array_util au(m); + array_decl_plugin& ad = *static_cast(m.get_plugin(array_fid)); + + + // arr_s and select_fn creation copy-pasted from z3.cpp + + parameter sparams[2] = { parameter(to_sort(m.mk_bool_sort())), parameter(to_sort(m.mk_bool_sort())) }; + sort_ref arr_s(m.mk_sort(array_fid, ARRAY_SORT, 2, sparams), m); + + sort * domain2[2] = {arr_s, m.mk_bool_sort()}; + func_decl_ref select_fn( + m.mk_func_decl(array_fid, OP_SELECT, 2, arr_s->get_parameters(), 2, domain2), m); + + + app_ref a1(m.mk_const(symbol("a1"), arr_s), m); + app_ref a2(m.mk_const(symbol("a2"), arr_s), m); + + // (= true (select a1 true)) + app_ref fml(m.mk_eq(m.mk_true(), + m.mk_app(select_fn.get(), a1, m.mk_true())), m); + + smt::context ctx(m, params); + ctx.assert_expr(fml); + lbool check_result = ctx.check(); + std::cout<<((check_result==l_true) ? "satisfiable" : + (check_result==l_false) ? "unsatisfiable" : "unknown")<<"\n"; + ref model; + ctx.get_model(model); + model_v2_pp(std::cout, *model, false); + expr_ref a1_val(model->get_const_interp(a1->get_decl()), m); + + app_ref fml2(m.mk_eq(a2, a1_val), m); + ctx.assert_expr(fml2); + std::cout<<"--------------------------\n"; + ctx.display(std::cout); + std::cout<<"--------------------------\n"; + check_result = ctx.check(); + ctx.display(std::cout); + std::cout<<"--------------------------\n"; + std::cout<<((check_result==l_true) ? "satisfiable" : + (check_result==l_false) ? "unsatisfiable" : "unknown")<<"\n"; +} diff --git a/test/mpbq.cpp b/test/mpbq.cpp new file mode 100644 index 000000000..97f8822a9 --- /dev/null +++ b/test/mpbq.cpp @@ -0,0 +1,60 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + mpbq.cpp + +Abstract: + + mpbq tests... + +Author: + + Leonardo de Moura (leonardo) 2012-09-20 + +Revision History: + +--*/ +#include "mpbq.h" + +static void tst1() { + unsynch_mpz_manager zm; + mpbq_manager m(zm); + scoped_mpbq a(m), b(m); + m.set(a, INT_MAX); + a = a + 1; + a = a * a; + a = a*3 - 1; + a = a * a - 5; + a = a * a - 7; + m.div2k(a, 67); + std::cout << a << "\n"; + b = a; + m.approx(b, 32, true); + std::cout << b << "\n"; + b = a; + m.approx(b, 32, false); + std::cout << b << "\n"; + b = a; m.neg(b); + m.approx(b, 32, true); + std::cout << b << "\n"; + b = a; m.neg(b); + m.approx(b, 32, false); + std::cout << b << "\n"; +} + +static void tst2() { + unsynch_mpz_manager zm; + mpbq_manager m(zm); + scoped_mpbq a(m), b(m); + m.set(a, 5); + m.set(b, 3); + m.approx_div(a, b, a, 128); + std::cout << a << "\n"; + } + +void tst_mpbq() { + tst1(); + tst2(); +} diff --git a/test/mpf.cpp b/test/mpf.cpp new file mode 100644 index 000000000..d12675b6d --- /dev/null +++ b/test/mpf.cpp @@ -0,0 +1,88 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + mpf.cpp + +Abstract: + + mpf repros... + +Author: + + Leonardo de Moura (leonardo) 2012-08-21. + +Revision History: + +--*/ +#include"mpf.h" +#include"f2n.h" + +static void bug_set_int() { + mpf_manager fm; + scoped_mpf a(fm); + + fm.set(a, 11, 53, 3); + SASSERT(fm.to_double(a) == 3.0); + + fm.set(a, 11, 53, 0); + SASSERT(fm.to_double(a) == 0.0); + + fm.set(a, 11, 53, -1); + SASSERT(fm.to_double(a) == -1.0); + + fm.set(a, 11, 53, INT_MAX); + SASSERT(fm.to_double(a) == (double)INT_MAX); + + fm.set(a, 11, 53, INT_MIN); + SASSERT(fm.to_double(a) == (double)INT_MIN); + + fm.set(a, 8, 24, 3); + SASSERT(fm.to_float(a) == 3.0); + SASSERT(fm.to_double(a) == 3.0); + + fm.set(a, 8, 24, 0); + SASSERT(fm.to_float(a) == 0.0); + SASSERT(fm.to_double(a) == 0.0); + + fm.set(a, 8, 24, -1); + SASSERT(fm.to_float(a) == -1.0); + SASSERT(fm.to_double(a) == -1.0); + + fm.set(a, 8, 24, INT_MIN); + SASSERT(fm.to_float(a) == (float)INT_MIN); + + // CMW: This one depends on the rounding mode, but fm.set(..., int) doesn't have one. + // fm.set(a, 8, 24, INT_MAX); + // SASSERT(fm.to_float(a) == (float)INT_MAX); +} + +static void bug_set_double() { + mpf_manager fm; + scoped_mpf a(fm); + + fm.set(a, 11, 53, 2.5); + SASSERT(fm.to_double(a) == 2.5); + + fm.set(a, 11, 53, -42.25); + SASSERT(fm.to_double(a) == -42.25); + + fm.set(a, 8, 24, (double)2.5); + SASSERT(fm.to_double(a) == 2.5); + + fm.set(a, 8, 24, (double)-42.25); + SASSERT(fm.to_double(a) == -42.25); + + fm.set(a, 8, 24, (float)2.5); + SASSERT(fm.to_float(a) == 2.5); + + fm.set(a, 8, 24, (float)-42.25); + SASSERT(fm.to_float(a) == -42.25); +} + +void tst_mpf() { + enable_trace("mpf_mul_bug"); + bug_set_int(); + bug_set_double(); +} diff --git a/test/mpff.cpp b/test/mpff.cpp new file mode 100644 index 000000000..4b811689e --- /dev/null +++ b/test/mpff.cpp @@ -0,0 +1,666 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + mpff.cpp + +Abstract: + + mpff tests... + +Author: + + Leonardo de Moura (leonardo) 2012-09-12. + +Revision History: + +--*/ +#include +#include"mpff.h" +#include"mpz.h" +#include"mpq.h" + +static void tst1() { + try { + mpff_manager m; + // m.round_to_minus_inf(); + scoped_mpff a(m), b(m); + m.set(a, 100); + m.set(b, -33); + std::cout << "a: " << a << ", b: " << b << "\n"; + std::cout << "a*b: " << a*b << "\n"; + for (unsigned i = 0; i < 100; i++) { + a = a*a; + std::cout << i << ": " << a << "\n"; + } + } + catch (z3_exception & ex) { + std::cout << ex.msg() << "\n"; + } +} + +static void tst2() { + mpff_manager m; + scoped_mpff a(m), b(m); + m.set(a, static_cast(100)); + m.set(b, static_cast(-100)); + std::cout << "[test2], a: " << a << ", b: " << b << "\n"; +} + +static void tst3() { + mpff_manager m; + scoped_mpff a(m), b(m), c(m); + m.set(a, 1); + m.set(b, 3); + m.div(a, b, c); + std::cout << "[div] c: " << c << "\n"; + m.round_to_plus_inf(); + m.reset(c); + m.div(a, b, c); + std::cout << "[div] c: " << c << "\n"; +} + +static void tst4() { + unsynch_mpz_manager zm; + mpff_manager m; + scoped_mpz a(zm); + scoped_mpff b(m); + zm.set(a, 2); + zm.power(a, 512, a); + m.set(b, zm, a); + std::cout << "[mpz->mpff] a: " << a << ", b: " << b << "\n"; +} + +static void tst5() { + mpff_manager m; + scoped_mpff a(m), b(m); + m.set(a, static_cast(1) << 63); + m.display_raw(std::cout, a); std::cout << "\n"; + SASSERT(m.is_zero(b)); + SASSERT(m.lt(b, a)); + m.set(b, -1); + SASSERT(m.lt(b, a)); +} + +static void tst6() { + mpff_manager m; + scoped_mpff a(m), b(m), one(m); + m.set(a, 1, 3); + std::cout << "mpff(1/3) " << a << "\n"; + b = a; + m.next(b); + SASSERT(m.lt(a, b)); + std::cout << "b: " << b << "\n"; + m.prev(b); + SASSERT(m.eq(a, b)); + m.ceil(b); + std::cout << "b: " << b << "\n"; + m.set(b, 4, 3); + std::cout << "b: " << b << "\n"; + m.ceil(b); + std::cout << "b: " << b << "\n"; +} + +static void tst7() { + mpff_manager m; + scoped_mpff a(m); + m.set(a, 2); + m.display_smt2(std::cout, a); std::cout << "\n"; + m.set(a, -2); + m.display_smt2(std::cout, a); std::cout << "\n"; + m.set(a, 1, 3); + m.display_smt2(std::cout, a); std::cout << "\n"; +} + +// if (!qm.le(qa, qt)) { TRACE("mpff_bug", tout << fa << "\n" << qa << "\n" << qt << "\n";); UNREACHABLE(); } \ + + +#define MK_BIN_OP(OP) \ +static void tst_ ## OP ## _core(int64 n1, uint64 d1, int64 n2, uint64 d2, unsigned precision = 2, unsigned exp = 0) { \ + TRACE("mpff_bug", tout << n1 << "/" << d1 << ", " << n2 << "/" << d2 << "\n";); \ + unsynch_mpq_manager qm; \ + scoped_mpq qa(qm), qb(qm), qc(qm), qt(qm); \ + \ + mpff_manager fm(precision); \ + scoped_mpff fa(fm), fb(fm), fc1(fm), fc2(fm); \ + fm.set(fa, n1, d1); \ + if (exp != 0) { int _exp = rand() % exp; if (rand() % 2 == 0) _exp = -_exp; fm.set_exponent(fa, _exp); } \ + fm.to_mpq(fa, qm, qa); \ + fm.set(fb, n2, d2); \ + if (exp != 0) { int _exp = rand() % exp; if (rand() % 2 == 0) _exp = -_exp; fm.set_exponent(fb, _exp); } \ + fm.to_mpq(fb, qm, qb); \ + qm.OP(qa, qb, qc); \ + { \ + fm.round_to_plus_inf(); \ + fm.OP(fa, fb, fc1); \ + fm.to_mpq(fc1, qm, qt); \ + SASSERT(qm.le(qc, qt)); \ + } \ + { \ + fm.round_to_minus_inf(); \ + fm.OP(fa, fb, fc2); \ + fm.to_mpq(fc2, qm, qt); \ + SASSERT(qm.le(qt, qc)); \ + } \ + SASSERT(fm.le(fc2, fc1)); \ +} + +MK_BIN_OP(add); +MK_BIN_OP(sub); +MK_BIN_OP(mul); +MK_BIN_OP(div); + +#define MK_BIN_RANDOM_TST(OP) \ + static void tst_ ## OP(unsigned N, unsigned max, unsigned prec = 2, bool is_div = false) { \ + for (unsigned i = 0; i < N; i++) { \ + int n1 = rand() % max; \ + int d1 = rand() % max + 1; \ + int n2 = rand() % max; \ + int d2 = rand() % max + 1; \ + if (rand () % 2 == 0) \ + n1 = -n1; \ + if (rand () % 2 == 0) \ + n2 = -n2; \ + if (is_div && n2 == 0) n2 = 1; \ + tst_ ## OP ## _core(n1, d1, n2, d2, prec); \ + tst_ ## OP ## _core(n1, d1, n2, d2, prec, 512); \ + } \ +} + +MK_BIN_RANDOM_TST(add) +MK_BIN_RANDOM_TST(sub) +MK_BIN_RANDOM_TST(mul) +MK_BIN_RANDOM_TST(div) + +static void tst_bug() { + unsynch_mpq_manager qm; + mpff_manager fm; + fm.round_to_plus_inf(); + scoped_mpff a(fm); + fm.set(a, 41, 36); + scoped_mpq b(qm), c(qm); + qm.set(b, 41, 36); + fm.to_mpq(a, qm, c); + SASSERT(qm.le(b, c)); +} + +static void tst_bug2() { + mpff_manager fm(4); + scoped_mpff a(fm), b(fm); + fm.set(b, 1); + fm.sub(a, b, b); + fm.set(a, -1); + SASSERT(fm.eq(a, b)); + fm.set(a, 1); + fm.set(b, 0); + fm.sub(a, b, a); + fm.set(b, 1); + SASSERT(fm.eq(a, b)); + fm.set(a, 1); + fm.set(b, 1); + fm.sub(a, b, a); + SASSERT(fm.is_zero(a)); +} + +static void tst_set64(unsigned N, unsigned prec) { + mpff_manager fm(prec); + scoped_mpff a(fm); + + fm.set(a, INT64_MAX); + SASSERT(fm.is_int64(a)); + SASSERT(fm.is_uint64(a)); + fm.inc(a); + SASSERT(!fm.is_int64(a)); + SASSERT(fm.is_uint64(a)); + SASSERT(fm.is_int(a)); + fm.dec(a); + SASSERT(fm.is_int64(a)); + SASSERT(fm.is_uint64(a)); + fm.dec(a); + SASSERT(fm.is_int64(a)); + SASSERT(fm.is_uint64(a)); + + fm.set(a, INT64_MIN); + SASSERT(fm.is_int64(a)); + SASSERT(!fm.is_uint64(a)); + fm.dec(a); + SASSERT(!fm.is_int64(a)); + SASSERT(!fm.is_uint64(a)); + SASSERT(fm.is_int(a)); + fm.inc(a); + SASSERT(fm.is_int64(a)); + SASSERT(!fm.is_uint64(a)); + fm.inc(a); + SASSERT(fm.is_int64(a)); + SASSERT(!fm.is_uint64(a)); + + fm.set(a, UINT64_MAX); + SASSERT(fm.is_uint64(a)); + SASSERT(!fm.is_int64(a)); + fm.inc(a); + SASSERT(!fm.is_uint64(a)); + SASSERT(!fm.is_int64(a)); + fm.dec(a); + SASSERT(fm.is_uint64(a)); + SASSERT(!fm.is_int64(a)); + fm.dec(a); + SASSERT(fm.is_uint64(a)); + SASSERT(!fm.is_int64(a)); + + for (unsigned i = 0; i < N; i++) { + { + uint64 v = (static_cast(rand()) << 32) + static_cast(rand()); + fm.set(a, v); + SASSERT(fm.is_uint64(a)); + + v = (static_cast(rand() % 3) << 32) + static_cast(rand()); + fm.set(a, v); + SASSERT(fm.is_uint64(a)); + } + { + int64 v = (static_cast(rand() % INT_MAX) << 32) + static_cast(rand()); + if (rand()%2 == 0) + v = -v; + fm.set(a, v); + SASSERT(fm.is_int64(a)); + + + v = (static_cast(rand() % 3) << 32) + static_cast(rand()); + if (rand()%2 == 0) + v = -v; + fm.set(a, v); + SASSERT(fm.is_int64(a)); + } + } +} + +static void tst_capacity(unsigned prec = 2) { + mpff_manager m(prec); + scoped_mpff_vector v(m); + scoped_mpff a(m); + for (unsigned i = 0; i < 50000; i++) { + m.set(a, i); + v.push_back(a); + SASSERT(m.is_int(v.back())); + SASSERT(m.is_int64(v.back())); + SASSERT(m.is_uint64(v.back())); + } + for (unsigned i = 0; i < 50000; i++) { + SASSERT(m.get_int64(v[i]) == i); + } +} + +static void tst_power(unsigned prec = 2) { + mpff_manager m(prec); + scoped_mpff a(m), b(m); + + // 0^k == 0 + SASSERT(m.is_zero(a)); + m.power(a, 10, a); + SASSERT(m.is_zero(a)); + + // a != 0 ==> a^0 == 1 + m.set(a, 33); + m.power(a, 0, a); + SASSERT(m.is_one(a)); + m.set(a, -33); + m.power(a, 0, a); + SASSERT(m.is_one(a)); + + // a^1 == a + m.set(a, 33); + m.power(a, 1, b); + SASSERT(m.eq(a, b)); + m.set(a, -33); + m.power(a, 1, b); + SASSERT(m.eq(a, b)); + + // checking special support for powers of 2 +#ifdef Z3DEBUG + unsigned k; +#endif + m.set(a, 1); + SASSERT(m.is_power_of_two(a, k) && k == 0); + m.set(a, 2); + SASSERT(m.is_power_of_two(a, k) && k == 1); + m.set(a, 3); + SASSERT(!m.is_power_of_two(a, k)); + m.set(a, 4); + SASSERT(m.is_power_of_two(a, k) && k == 2); + m.set(a, -4); + SASSERT(!m.is_power_of_two(a, k)); + m.set(a, 8); + SASSERT(m.is_power_of_two(a, k) && k == 3); + m.set(a, 0); + SASSERT(!m.is_power_of_two(a)); + + m.set(a, UINT_MAX); + m.inc(a); + SASSERT(m.is_power_of_two(a, k) && k == 32); + SASSERT(m.get_uint64(a) == static_cast(UINT_MAX) + 1); + m.power(a, 2, a); + SASSERT(m.is_power_of_two(a, k) && k == 64); + m.power(a, 4, a); + SASSERT(m.is_power_of_two(a, k) && k == 256); + m.round_to_plus_inf(); + m.inc(a); + SASSERT(!m.is_power_of_two(a, k)); + + m.set(a, -4); + m.power(a, 3, a); + m.set(b, -64); + SASSERT(m.eq(a, b)); + m.set(a, -4); + m.power(a, 4, a); + m.set(b, 256); + SASSERT(m.eq(a, b)); + + // additional tests + m.set(a, 5); + m.power(a, 3, a); + m.set(b, 5*5*5); + SASSERT(m.eq(a,b)); + + m.set(a, -5); + m.power(a, 3, a); + m.set(b, -5*5*5); + SASSERT(m.eq(a,b)); +} + +static void tst_sgn(unsigned prec) { + mpff_manager m(prec); + scoped_mpff a(m), b(m); + SASSERT(m.is_zero(a) && !m.is_pos(a) && !m.is_neg(a) && m.is_nonpos(a) && m.is_nonneg(a)); + m.set(a, 3); + SASSERT(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a)); + m.set(a, -3); + SASSERT(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a)); + m.set(a, 8); + m.power(a, 256, a); + SASSERT(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a)); + b = a; + m.neg(a); + SASSERT(m.neq(a, b)); + SASSERT(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a)); + m.neg(a); + SASSERT(m.eq(a, b)); + + + m.set(a, 1); + SASSERT(m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a) && m.is_abs_one(a)); + m.neg(a); + SASSERT(!m.is_one(a) && !m.is_zero(a) && m.is_minus_one(a) && m.is_abs_one(a)); + m.set(a, 3); + SASSERT(!m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a)); + + m.set(a, 3); + b = a; + m.abs(a); + SASSERT(m.eq(a, b)); + m.set(a, -3); + b = a; + m.abs(a); + SASSERT(!m.eq(a,b) && m.is_pos(a)); + + m.set(a, 1); + m.swap(a, a); + SASSERT(m.is_one(a)); + m.set(b, -1); + m.swap(a, b); + SASSERT(m.is_one(b) && m.is_minus_one(a)); + m.neg(a); + SASSERT(m.eq(a, b)); +} + +static void tst_limits(unsigned prec) { + mpff_manager m(prec); + scoped_mpff a(m), b(m), two(m); + m.set_max(a); + SASSERT(m.is_pos(a)); + m.set_min(b); + SASSERT(m.is_neg(b)); + m.neg(a); + SASSERT(m.eq(a, b)); + + m.set_max(a); + m.set_max(b); + m.round_to_minus_inf(); + m.inc(a); + SASSERT(m.eq(a, b)); + m.dec(a); + SASSERT(m.lt(a, b)); + m.set_max(a); + m.round_to_plus_inf(); + bool overflow = false; + try { m.inc(a); } + catch (mpff_manager::overflow_exception) { overflow = true; } + SASSERT(overflow); + m.set_max(a); + m.dec(a); + SASSERT(m.eq(a, b)); + + + m.set_min(a); + m.set_min(b); + m.round_to_minus_inf(); + m.inc(a); + SASSERT(m.eq(a, b)); + overflow = true; + try { m.dec(a); } + catch (mpff_manager::overflow_exception) { overflow = true; } + SASSERT(overflow); + m.round_to_plus_inf(); + m.set_min(a); + m.inc(a); + SASSERT(m.gt(a,b)); + m.set_min(a); + m.dec(a); + SASSERT(m.eq(a,b)); + + m.set_plus_epsilon(a); + m.set_plus_epsilon(b); + SASSERT(!m.is_zero(a) && m.is_pos(a)); + m.set(two, 2); + m.round_to_plus_inf(); + m.div(a, two, a); + SASSERT(m.eq(a, b)); + m.round_to_minus_inf(); + m.div(a, two, a); + SASSERT(m.is_zero(a)); + m.round_to_plus_inf(); + m.set_plus_epsilon(a); + m.add(a, a, a); + SASSERT(m.gt(a, b)); + m.round_to_minus_inf(); + m.set_plus_epsilon(a); + m.add(a, a, a); + SASSERT(m.gt(a, b)); + m.set_plus_epsilon(a); + m.sub(a, a, a); + SASSERT(m.is_zero(a)); + m.set_plus_epsilon(a); + SASSERT(m.is_plus_epsilon(a)); + SASSERT(!m.is_minus_epsilon(a)); + m.neg(a); + SASSERT(!m.is_plus_epsilon(a)); + SASSERT(m.is_minus_epsilon(a)); + + for (unsigned i = 0; i < 2; i++) { + m.set_rounding(i == 0); + + m.set_plus_epsilon(a); + m.floor(a); + SASSERT(m.is_zero(a)); + m.set_plus_epsilon(a); + m.ceil(a); + SASSERT(m.is_one(a)); + + m.set_minus_epsilon(a); + m.floor(a); + SASSERT(m.is_minus_one(a)); + m.set_minus_epsilon(a); + m.ceil(a); + SASSERT(m.is_zero(a)); + } + + m.set_minus_epsilon(a); + m.set_minus_epsilon(b); + SASSERT(!m.is_zero(a) && m.is_neg(a)); + m.set(two, 2); + m.round_to_minus_inf(); + m.div(a, two, a); + SASSERT(m.eq(a, b)); + m.round_to_plus_inf(); + m.div(a, two, a); + SASSERT(m.is_zero(a)); + m.round_to_plus_inf(); + m.set_minus_epsilon(a); + m.add(a, a, a); + SASSERT(m.lt(a, b)); + m.round_to_minus_inf(); + m.set_minus_epsilon(a); + m.add(a, a, a); + SASSERT(m.lt(a, b)); + m.set_minus_epsilon(a); + m.sub(a, a, a); + SASSERT(m.is_zero(a)); + m.set_minus_epsilon(a); + SASSERT(!m.is_plus_epsilon(a)); + SASSERT(m.is_minus_epsilon(a)); + m.neg(a); + SASSERT(m.is_plus_epsilon(a)); + SASSERT(!m.is_minus_epsilon(a)); +} + +static void tst_add_corner(unsigned prec) { + mpff_manager m(prec); + scoped_mpff a(m), b(m); +} + +static void tst_decimal(int64 n, uint64 d, bool to_plus_inf, unsigned prec, char const * expected, unsigned decimal_places = UINT_MAX) { + mpff_manager m(prec); + scoped_mpff a(m); + m.set_rounding(to_plus_inf); + m.set(a, n, d); + m.display(std::cout, a); std::cout << std::endl; + m.display_decimal(std::cout, a, decimal_places); std::cout << std::endl; + std::ostringstream buffer; + m.display_decimal(buffer, a, decimal_places); + SASSERT(strcmp(expected, buffer.str().c_str()) == 0); +} + +static void tst_decimal() { + tst_decimal(1, 3, false, 2, "0.3333333333333333333152632971252415927665424533188343048095703125"); + tst_decimal(1, 3, false, 4, "0.33333333333333333333333333333333333333235375470764809374335938621898146193515111203602326039874270691143465228378772735595703125"); + tst_decimal(-1, 3, true, 2, "-0.3333333333333333333152632971252415927665424533188343048095703125"); + tst_decimal(-1, 3, false, 2, "-0.33333333333333333334236835143737920361672877334058284759521484375"); + tst_decimal(0, 1, false, 2, "0"); + tst_decimal(2, 1, false, 2, "2"); + tst_decimal(-3, 1, false, 2, "-3"); + tst_decimal(INT64_MAX, 1, false, 2, "9223372036854775807"); + tst_decimal(4, 5, false, 2, "0.79999999999999999995663191310057982263970188796520233154296875"); + tst_decimal(4, 5, false, 2, "0.7999999999?", 10); + tst_decimal(32, 5, true, 2, "6.4000000000000000000867361737988403547205962240695953369140625"); + tst_decimal(32, 5, false, 2, "6.39999999999999999965305530480463858111761510372161865234375"); + tst_decimal(-32, 5, false, 2, "-6.4000000000000000000867361737988403547205962240695953369140625"); + tst_decimal(-32, 5, true, 2, "-6.39999999999999999965305530480463858111761510372161865234375"); +} + +static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) { + mpff_manager m; + scoped_mpff a(m); + m.set(a, n, d); + SASSERT(m.prev_power_of_two(a) == expected); +} + +static void tst_prev_power_2() { + tst_prev_power_2(-10, 1, 0); + tst_prev_power_2(0, 1, 0); + tst_prev_power_2(1, 1, 0); + tst_prev_power_2(2, 1, 1); + tst_prev_power_2(3, 1, 1); + tst_prev_power_2(4, 1, 2); + tst_prev_power_2(5, 1, 2); + tst_prev_power_2(8, 1, 3); + tst_prev_power_2(9, 1, 3); + tst_prev_power_2(9, 2, 2); + tst_prev_power_2(9, 4, 1); + tst_prev_power_2(9, 5, 0); + tst_prev_power_2((1ll << 60) + 1, 1, 60); + tst_prev_power_2((1ll << 60), 1, 60); + tst_prev_power_2((1ll << 60) - 1, 1, 59); + tst_prev_power_2((1ll << 60), 3, 58); +} + +static void tst_div(unsigned prec) { + mpff_manager m(prec); + scoped_mpff a(m), b(m), c(m); + m.round_to_plus_inf(); + m.set(a, 1); + m.set(b, UINT64_MAX); + m.div(a, b, c); + m.display_raw(std::cout, a); std::cout << "\n"; + m.display_raw(std::cout, b); std::cout << "\n"; + std::cout << a << "/" << b << " <= " << c << "\n"; + // 10...0 0...0 + // 11111 +} + +void tst_mpff() { + disable_trace("mpff"); + enable_trace("mpff_trace"); + // enable_trace("mpff_bug"); + // enable_trace("mpff_to_mpq"); + // + tst_div(2); + tst_prev_power_2(); + tst_decimal(); + tst_div_core(679, 396, 279, 756, 2, 0); + tst_limits(2); + tst_limits(4); + tst_sgn(2); + tst_sgn(4); + tst_sgn(8); + tst_power(2); + tst_power(4); + tst_power(18); + tst_capacity(2); + tst_capacity(4); + tst_capacity(8); + tst_capacity(16); + tst_set64(1000, 2); + tst_set64(1000, 4); + tst_set64(1000, 6); + tst_bug2(); + + tst_sub(1000, 1024, 2); + tst_sub(1000, 1024, 4); + tst_div(1000, 1024, 2, true); + tst_div(1000, 1024, 4, true); + tst_mul(1000, 1024, 2); + tst_mul(1000, 1024, 4); + tst_add(1000, 1024, 2); + tst_add(1000, 1024, 4); + + tst_sub(1000, UINT_MAX, 2); + tst_sub(1000, UINT_MAX, 4); + tst_div(1000, UINT_MAX, 2, true); + tst_div(1000, UINT_MAX, 4, true); + tst_mul(1000, UINT_MAX, 2); + tst_mul(1000, UINT_MAX, 4); + tst_add(1000, UINT_MAX, 2); + tst_add(1000, UINT_MAX, 4); + + tst_bug2(); + tst_bug(); + tst_add_core(1,1, 1,1); + tst_add_core(1,3, 2,3); + tst1(); + tst2(); + tst3(); + tst4(); + tst5(); + tst6(); + tst7(); +} diff --git a/test/mpfx.cpp b/test/mpfx.cpp new file mode 100644 index 000000000..9e8882a26 --- /dev/null +++ b/test/mpfx.cpp @@ -0,0 +1,67 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + mpfx.cpp + +Abstract: + + Multi precision fixed point numbers. + +Author: + + Leonardo de Moura (leonardo) 2012-09-19 + +Revision History: + +--*/ +#include"mpfx.h" + +static void tst1() { + mpfx_manager m; + scoped_mpfx a(m), b(m), c(m); + m.set(a, 1); + m.set(b, 2); + std::cout << a << " + " << b << " == " << (a+b) << "\n"; + m.set(a, 5); + m.set(c, 3); + m.display_raw(std::cout, (a*a*b)/c); std::cout << "\n"; + m.display_decimal(std::cout, (a*a*b)/c); std::cout << "\n"; + m.display_decimal(std::cout, (a*a*b)/c, 10); std::cout << "\n"; + m.round_to_plus_inf(); + m.display_decimal(std::cout, (a*a*b)/c); std::cout << "\n"; + m.set(a, -1, 4); + m.display_decimal(std::cout, a); std::cout << "\n"; +} + +static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) { + mpfx_manager m; + scoped_mpfx a(m); + m.set(a, n, d); + SASSERT(m.prev_power_of_two(a) == expected); +} + +static void tst_prev_power_2() { + tst_prev_power_2(-10, 1, 0); + tst_prev_power_2(0, 1, 0); + tst_prev_power_2(1, 1, 0); + tst_prev_power_2(2, 1, 1); + tst_prev_power_2(3, 1, 1); + tst_prev_power_2(4, 1, 2); + tst_prev_power_2(5, 1, 2); + tst_prev_power_2(8, 1, 3); + tst_prev_power_2(9, 1, 3); + tst_prev_power_2(9, 2, 2); + tst_prev_power_2(9, 4, 1); + tst_prev_power_2(9, 5, 0); + tst_prev_power_2((1ll << 60) + 1, 1, 60); + tst_prev_power_2((1ll << 60), 1, 60); + tst_prev_power_2((1ll << 60) - 1, 1, 59); + tst_prev_power_2((1ll << 60), 3, 58); +} + +void tst_mpfx() { + tst_prev_power_2(); + tst1(); +} diff --git a/test/mpq.cpp b/test/mpq.cpp new file mode 100644 index 000000000..5c221d617 --- /dev/null +++ b/test/mpq.cpp @@ -0,0 +1,170 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + mpq.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-06-21. + +Revision History: + +--*/ + +#include"mpq.h" +#include"rational.h" +#include"timeit.h" + +static void tst0() { + synch_mpq_manager m; + mpq a, b; + m.set(a, 2, 3); + m.set(b, 4, 3); + m.div(a, b, b); + SASSERT(m.eq(b, m.mk_q(1, 2))); +} + +static void tst1() { + synch_mpq_manager m; + char const * str = "1002034040050606089383838288182"; + mpz v; + m.set(v, str); + std::cout << str << "\n" << m.to_string(v) << "\n"; + mpz v2, v3; + m.mul(v, m.mk_z(-2), v2); + std::cout << "*-2 = \n" << m.to_string(v2) << "\n"; + m.add(v, v2, v3); + m.neg(v3); + SASSERT(m.eq(v, v3)); + SASSERT(m.le(v, v3)); + SASSERT(m.ge(v, v3)); + SASSERT(m.lt(v2, v)); + SASSERT(m.le(v2, v)); + SASSERT(m.gt(v, v2)); + SASSERT(m.ge(v, v2)); + SASSERT(m.neq(v, v2)); + SASSERT(!m.neq(v, v3)); + m.del(v); + m.del(v2); + m.del(v3); +} + +static void mk_random_num_str(unsigned buffer_sz, char * buffer) { + unsigned div_pos; + unsigned sz = (rand() % (buffer_sz-2)) + 1; + if (rand() % 2 == 0) { + // integer + div_pos = sz + 1; + } + else { + div_pos = rand() % sz; + if (div_pos == 0) + div_pos++; + } + SASSERT(sz < buffer_sz); + for (unsigned i = 0; i < sz-1; i++) { + if (i == div_pos && i < sz-2) { + buffer[i] = '/'; + i++; + buffer[i] = '1' + (rand() % 9); + } + else { + buffer[i] = '0' + (rand() % 10); + } + } + buffer[sz-1] = 0; +} + +static void bug1() { + synch_mpq_manager m; + mpq a; + mpq b; + m.set(a, 2); + m.set(b, 1, 2); + m.inv(a, a); + SASSERT(m.eq(a, b)); +} + +static void bug2() { + synch_mpq_manager m; + mpq a; + mpq b; + m.set(a, -2); + m.set(b, -1, 2); + m.inv(a, a); + SASSERT(m.eq(a, b)); +} + +static void tst2() { + unsynch_mpq_manager m; + scoped_mpq a(m); + m.set(a, 1, 3); + std::cout << "1/3: "; + m.display_decimal(std::cout, a, 10); + std::cout << "\n1/4: "; + m.set(a, 1, 4); + m.display_decimal(std::cout, a, 10); + std::cout << "\n"; +} + +static void set_str_bug() { + unsynch_mpq_manager m; + scoped_mpq a(m); + scoped_mpq b(m); + m.set(a, "1.0"); + std::cout << a << "\n"; + m.set(b, 1); + SASSERT(a == b); + m.set(a, "1.1"); + std::cout << a << "\n"; + m.set(b, 11, 10); + SASSERT(a == b); + m.set(a, "1/3"); + m.set(b, 1, 3); + std::cout << a << "\n"; + SASSERT(a == b); +} + +static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) { + unsynch_mpq_manager m; + scoped_mpq a(m); + m.set(a, n, d); + SASSERT(m.prev_power_of_two(a) == expected); +} + +static void tst_prev_power_2() { + tst_prev_power_2(-10, 1, 0); + tst_prev_power_2(0, 1, 0); + tst_prev_power_2(1, 1, 0); + tst_prev_power_2(2, 1, 1); + tst_prev_power_2(3, 1, 1); + tst_prev_power_2(4, 1, 2); + tst_prev_power_2(5, 1, 2); + tst_prev_power_2(8, 1, 3); + tst_prev_power_2(9, 1, 3); + tst_prev_power_2(9, 2, 2); + tst_prev_power_2(9, 4, 1); + tst_prev_power_2(9, 5, 0); + tst_prev_power_2((1ll << 60) + 1, 1, 60); + tst_prev_power_2((1ll << 60), 1, 60); + tst_prev_power_2((1ll << 60) - 1, 1, 59); + tst_prev_power_2((1ll << 60), 3, 58); +} + +void tst_mpq() { + tst_prev_power_2(); + set_str_bug(); + bug2(); + bug1(); + tst0(); + tst1(); + tst2(); +} + + diff --git a/test/mpz.cpp b/test/mpz.cpp new file mode 100644 index 000000000..70b49f5a7 --- /dev/null +++ b/test/mpz.cpp @@ -0,0 +1,510 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + mpz.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-06-18. + +Revision History: + +--*/ + +#include"mpz.h" +#include"rational.h" +#include"timeit.h" +#include"scoped_numeral.h" + +static void tst1() { + synch_mpz_manager m; + char const * str = "1002034040050606089383838288182"; + mpz v; + m.set(v, str); + std::cout << str << "\n" << m.to_string(v) << "\n"; + mpz v2, v3; + m.mul(v, m.mk_z(-2), v2); + std::cout << "*-2 = \n" << m.to_string(v2) << "\n"; + m.add(v, v2, v3); + m.neg(v3); + SASSERT(m.eq(v, v3)); + SASSERT(m.le(v, v3)); + SASSERT(m.ge(v, v3)); + SASSERT(m.lt(v2, v)); + SASSERT(m.le(v2, v)); + SASSERT(m.gt(v, v2)); + SASSERT(m.ge(v, v2)); + SASSERT(m.neq(v, v2)); + SASSERT(!m.neq(v, v3)); + m.del(v); + m.del(v2); + m.del(v3); +} + +static void tst2() { + synch_mpz_manager m; + mpz v1, v2, v3; + m.set(v1, static_cast(UINT_MAX)); + m.add(v1, m.mk_z(1), v2); + m.mul(v2, v2, v3); + std::cout << "v2:\n" << m.to_string(v2) << "\n"; + std::cout << "v2*v2:\n" << m.to_string(v3) << "\n"; + m.del(v1); + m.del(v2); + m.del(v3); +} + +static void tst2b() { + synch_mpz_manager m; + mpz v1, v2, v3; + m.set(v1, static_cast(UINT_MAX)); + m.add(v1, m.mk_z(1), v2); + m.mul(v2, v2, v3); + std::cout << "v2:\n" << m.to_string(v2) << "\n"; + std::cout << "v2*v2:\n" << m.to_string(v3) << "\n"; + m.mul(v2, v2, v2); + m.mul(v2, v2, v2); + m.mul(v2, v2, v2); + std::cout << "v2: " << m.to_string(v2) << "\n"; + m.del(v1); + m.del(v2); + m.del(v3); +} + +static void mk_random_num_str(unsigned buffer_sz, char * buffer) { + unsigned sz = (rand() % (buffer_sz-2)) + 1; + SASSERT(sz < buffer_sz); + for (unsigned i = 0; i < sz-1; i++) { + buffer[i] = '0' + (rand() % 10); + } + if (rand() % 2 == 0) + buffer[0] = '-'; + buffer[sz-1] = 0; +} + +static void bug1() { + synch_mpz_manager m; + mpz v1; + m.set(v1, "1002043949858757875676767675747473"); + mpz v2; + m.sub(v1, v1, v2); + SASSERT(m.is_zero(v2)); + m.del(v1); + m.del(v2); +} + +static void bug2() { + synch_mpz_manager m; + mpz v1, v2, vout; + m.set(v1, "78160958900072552148646898355155840547214990303507678364419557473408815232466629049311995556059463490539128818602490221544425042127795"); + m.set(v2, "403412298227858394469856607272647132163832860126054679347881638761723785858733108109249157334220127"); + m.sub(v1, v2, vout); + m.del(v1); + m.del(v2); + m.del(vout); +} + +static void bug3() { + synch_mpz_manager m; + mpz v1, v2; + m.set(v1, INT_MIN); + m.set(v2, INT_MAX); + m.add(v2, m.mk_z(1), v2); + m.neg(v1); + SASSERT(m.eq(v1, v2)); + m.del(v1); + m.del(v2); +} + +static void bug4() { + synch_mpz_manager m; + mpz x, y; + m.set(y, 4294967295ull); + m.set(x, 4026531839ull); + mpz result1; + m.bitwise_or(x, y, result1); + + mpz result2; + m.set(result2, x); + m.bitwise_or(result2, y, result2); + + std::cout << m.to_string(result1) << " " << m.to_string(result2) << "\n"; + SASSERT(m.eq(result1, result2)); + m.del(x); m.del(y); m.del(result1); m.del(result2); +} + +void tst_div2k(synch_mpz_manager & m, mpz const & v, unsigned k) { + mpz x, y, two(2), pw; + m.machine_div2k(v, k, x); + m.power(two, k, pw); + m.machine_div(v, pw, y); + bool is_eq = m.eq(x, y); + CTRACE("mpz_2k", !is_eq, tout << "div: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";); + SASSERT(is_eq); + m.del(x); + m.del(y); + m.del(pw); +} + +void tst_div2k(synch_mpz_manager & m, int v, unsigned k) { + mpz x; + m.set(x, v); + tst_div2k(m, x, k); + m.del(x); +} + +void tst_div2k(synch_mpz_manager & m, char const * v, unsigned k) { + mpz x; + m.set(x, v); + tst_div2k(m, x, k); + m.del(x); +} + +void tst_mul2k(synch_mpz_manager & m, mpz const & v, unsigned k) { + mpz x, y, two(2), pw; + m.mul2k(v, k, x); + m.power(two, k, pw); + m.mul(v, pw, y); + bool is_eq = m.eq(x, y); + CTRACE("mpz_2k", !is_eq, tout << "mul: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";); + SASSERT(is_eq); + m.del(x); + m.del(y); + m.del(pw); +} + +void tst_mul2k(synch_mpz_manager & m, int v, unsigned k) { + mpz x; + m.set(x, v); + tst_mul2k(m, x, k); + m.del(x); +} + +void tst_mul2k(synch_mpz_manager & m, char const * v, unsigned k) { + mpz x; + m.set(x, v); + tst_mul2k(m, x, k); + m.del(x); +} + +static void tst_2k() { + synch_mpz_manager m; + tst_mul2k(m, 120, 32); + tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 22); + tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 22); + + tst_div2k(m, 3, 1); + tst_div2k(m, 3, 2); + tst_div2k(m, 3, 0); + tst_div2k(m, 120, 32); + tst_div2k(m, 120, 0); + tst_div2k(m, 81, 2); + tst_div2k(m, -3, 1); + tst_div2k(m, -3, 2); + tst_div2k(m, -3, 0); + tst_div2k(m, -102, 4); + tst_div2k(m, 0, 3); + tst_div2k(m, 0, 1000); + tst_div2k(m, 7, 10000); + tst_div2k(m, -7, 1000); + tst_div2k(m, -7, 2); + tst_div2k(m, "1029384848584832828327176162636436484", 4); + tst_div2k(m, "1029384848584832828327176162636436484", 100); + tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 1); + tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 0); + tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 4); + tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 7); + tst_div2k(m, "102938484858483282832717616263643648433838737661626264364583983298239291919", 100); + tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 100); + tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 177); + tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 77); + tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 32); + tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 64); + tst_div2k(m, "-11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 64); + tst_div2k(m, "-11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 128); + tst_div2k(m, "-1092983874757371817626399990000000", 100); + tst_div2k(m, "-109298387475737181762639999000000231", 8); + tst_div2k(m, "-109298387475737181762639999000000231", 16); + tst_div2k(m, "-109298387475737181762639999000000231", 17); + tst_div2k(m, "-109298387475737181762639999000000231", 32); + + + tst_mul2k(m, 3, 1); + tst_mul2k(m, 3, 2); + tst_mul2k(m, 3, 0); + tst_mul2k(m, 120, 32); + tst_mul2k(m, 120, 0); + tst_mul2k(m, 81, 2); + tst_mul2k(m, -3, 1); + tst_mul2k(m, -3, 2); + tst_mul2k(m, -3, 0); + tst_mul2k(m, -102, 4); + tst_mul2k(m, 0, 3); + tst_mul2k(m, 0, 1000); + tst_mul2k(m, 7, 10000); + tst_mul2k(m, -7, 1000000); + tst_mul2k(m, -7, 2); + tst_mul2k(m, "1029384848584832828327176162636436484", 4); + tst_mul2k(m, "1029384848584832828327176162636436484", 100); + tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 1); + tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 0); + tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 4); + tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 22); + tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 7); + tst_mul2k(m, "102938484858483282832717616263643648433838737661626264364583983298239291919", 100); + tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 100); + tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 177); + tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 77); + tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 32); + tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 64); + tst_mul2k(m, "-11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 64); + tst_mul2k(m, "-11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 128); + tst_mul2k(m, "-1092983874757371817626399990000000", 100); + tst_mul2k(m, "-109298387475737181762639999000000231", 8); + tst_mul2k(m, "-109298387475737181762639999000000231", 16); + tst_mul2k(m, "-109298387475737181762639999000000231", 17); + tst_mul2k(m, "-109298387475737181762639999000000231", 32); +} + +void tst_int_min_bug() { + synch_mpz_manager m; + mpz intmin(INT_MIN); + mpz big; + mpz expected; + mpz r; + m.set(big, UINT64_MAX); + m.set(expected, "18446744075857035263"); + m.sub(big, intmin, r); + std::cout << "r: " << m.to_string(r) << "\nexpected: " << m.to_string(expected) << "\n"; + SASSERT(m.eq(r, expected)); + m.del(intmin); + m.del(big); + m.del(expected); + m.del(r); +} + +void tst_scoped() { + synch_mpz_manager m; + scoped_synch_mpz a(m); + scoped_synch_mpz b(m); + m.set(a, 1000231); + m.set(b, "102928187172727273"); + std::cout << "a: " << m.to_string(a) << "\n"; + std::cout << "b: " << m.to_string(b) << "\n"; + m.mul(a, b, b); + std::cout << "b: " << m.to_string(b) << "\n"; +} + +#define NUM_PRIMES 168 +unsigned g_primes[NUM_PRIMES] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997 }; + +// Return a big number by multipling powers of the first NUM_PRIMES. +// - ratio: rand() % ratio == 0 is used to decide whether a specific prime will be included or not. +// - max_pw: if condition above is satisfied, then we use (rand() % max_pw) + 1 as the power. +void mk_big_num(unsynch_mpz_manager & m, unsigned ratio, unsigned max_pw, mpz & r) { + scoped_mpz tmp(m); + m.set(r, 1); + for (unsigned i = 0; i < NUM_PRIMES; i++) { + if ((rand() % ratio) == 0) { + m.power(mpz(g_primes[i]), (rand() % max_pw) + 1, tmp); + m.mul(r, tmp, r); + } + } + if ((rand() % 2) == 0) + m.neg(r); +} + +void slow_gcd(unsynch_mpz_manager & m, mpz const & a, mpz const & b, mpz & c) { + scoped_mpz tmp1(m); + scoped_mpz tmp2(m); + scoped_mpz aux(m); + m.set(tmp1, a); + m.set(tmp2, b); + m.abs(tmp1); + m.abs(tmp2); + if (m.le(tmp1, tmp2)) + m.swap(tmp1, tmp2); + if (m.is_zero(tmp2)) { + m.set(c, tmp1); + return; + } + for(;;) { + m.rem(tmp1, tmp2, aux); + if (m.is_zero(aux)) { + m.set(c, tmp2); + return; + } + m.set(tmp1, tmp2); + m.set(tmp2, aux); + } +} + +void rand_tst_gcd(unsigned num, unsigned ratio, unsigned pw) { + unsynch_mpz_manager m; + scoped_mpz a(m); + scoped_mpz b(m); + scoped_mpz g1(m); + scoped_mpz g2(m); + + for (unsigned i = 0; i < num; i++) { + mk_big_num(m, ratio, pw, a); + mk_big_num(m, ratio, pw, b); + slow_gcd(m, a, b, g1); + m.gcd(a, b, g2); + std::cout << "a: " << m.to_string(a) << "\n"; + std::cout << "b: " << m.to_string(b) << "\n"; + std::cout << "g1: " << m.to_string(g1) << "\n"; + std::cout << "g2: " << m.to_string(g2) << "\n"; + std::cout << "\n"; + if (!m.eq(g1, g2)) { + std::cout << "\n\nBUG\n\n"; + UNREACHABLE(); + } + } +} + +void tst_gcd() { + unsynch_mpz_manager m; + scoped_mpz a(m); + scoped_mpz b(m); + scoped_mpz g(m); + m.set(a, "125141154046000416200229049397707776"); + m.set(b, "67062117506072642958648904906464"); + m.gcd(a, b, g); + std::cout << "g: " << m.to_string(g) << "\n"; + m.set(a, "664877781119188360263909568610284290708591605105963082581413244598320881431041311468785283029437655134762231312337924555674674176"); + m.set(b, "21691055098083293041646678174999125628463716392747356050705870375852789453851926624107939885328471215366825649627326658281728580399051770334114658498352848410853519374962852431831492868108719406669605254329669417322836882756478295264"); + for (unsigned i = 0; i < 50000; i++) { + m.del(g); + m.gcd(a, b, g); + // slow_gcd(m, a, b, g); + } + std::cout << "g: " << m.to_string(g) << "\n"; +} + +void tst_log2(unsynch_mpz_manager & m, mpz const & a) { + scoped_mpz b(m); + unsigned k = m.log2(a); + m.power(mpz(2), k, b); + SASSERT(m.is_zero(a) || m.le(b, a)); + m.power(mpz(2), k+1, b); + SASSERT(m.le(a, b)); + + scoped_mpz neg_a(m); + m.set(neg_a, a); + m.neg(neg_a); + k = m.mlog2(neg_a); + m.power(mpz(2), k, b); + m.neg(b); + SASSERT(m.is_zero(neg_a) || m.le(neg_a, b)); + m.power(mpz(2), k+1, b); + m.neg(b); + SASSERT(m.le(b, neg_a)); +} + +void tst_log2() { + unsynch_mpz_manager m; + for (unsigned i = 0; i <= 64; i++) + std::cout << "log2(" << i << "): " << m.log2(mpz(i)) << "\n"; + for (unsigned i = 0; i < 1000; i++) + tst_log2(m, mpz(i)); + scoped_mpz a(m); + m.set(a, "1029489380487098723984579237"); + for (unsigned i = 0; i < 1000; i++) { + m.inc(a); + tst_log2(m, a); + } +} + +void tst_root() { + unsynch_mpz_manager m; + scoped_mpz a(m); + m.set(a, 213); + VERIFY(!m.root(a, 5)); + std::cout << "213^{1/5}: " << a << "\n"; + SASSERT(m.eq(a, mpz(3))); + m.set(a, -213); + VERIFY(!m.root(a, 5)); + std::cout << "-213^{1/5}: " << a << "\n"; + SASSERT(m.eq(a, mpz(-2))); + m.set(a, 0); + VERIFY(m.root(a, 3)); + SASSERT(m.is_zero(a)); + m.set(a, 8); + VERIFY(m.root(a, 3)); + SASSERT(m.eq(a, mpz(2))); + m.set(a, -8); + VERIFY(m.root(a, 3)); + SASSERT(m.eq(a, mpz(-2))); +} + +void tst_gcd_bug() { + unsynch_mpz_manager m; + scoped_mpz a(m), b(m), g(m); + m.set(a, INT_MIN); + m.set(b, INT_MIN); + m.gcd(a, b, g); + std::cout << "g: " << g << "\n"; +} + +void tst_div2k_bug() { + unsynch_mpz_manager m; + scoped_mpz a(m), b(m), g(m); + m.set(a, UINT_MAX); + m.machine_div2k(a, 32, b); + std::cout << "a: " << a << ", b: " << b << "\n"; +} + + +static void tst5() { + unsynch_mpz_manager m; + scoped_mpz a(m); + a = 1; + std::cout << "1 -> " << m.log2(a) << "\n"; + a = 5; + std::cout << "5 -> " << m.log2(a) << "\n"; + a = 16; + std::cout << "16 -> " << m.log2(a) << "\n"; + a = INT_MAX; + std::cout << "INT_MAX -> " << m.log2(a) << "\n"; + a = INT_MAX/4; + std::cout << "INT_MAX/4 -> " << m.log2(a) << "\n"; +} + +static void tst_pw2() { + unsynch_mpz_manager m; + scoped_mpz a(m); + for (unsigned i = 0; i < 128; i++) { + m.power(mpz(2), i, a); + std::cout << "i: " << i << ", a: " << a << std::endl; + } +} + +void tst_mpz() { + disable_trace("mpz"); + enable_trace("mpz_2k"); + tst_pw2(); + tst5(); + tst_div2k_bug(); + rand_tst_gcd(50, 3, 2); + tst_2k(); + tst_gcd_bug(); + tst_root(); + tst_log2(); + // tst_gcd(); + tst_scoped(); + tst_int_min_bug(); + bug4(); + bug3(); + bug1(); + bug2(); + tst1(); + tst2(); + tst2b(); +} diff --git a/test/nlarith_util.cpp b/test/nlarith_util.cpp new file mode 100644 index 000000000..87d5f9594 --- /dev/null +++ b/test/nlarith_util.cpp @@ -0,0 +1,45 @@ +#include "nlarith_util.h" +#include "arith_decl_plugin.h" +#include "ast_pp.h" + +void tst_nlarith_util() { + ast_manager M; + M.register_decl_plugins(); + arith_util A(M); + sort_ref R(A.mk_real(), M); + app_ref one(A.mk_numeral(rational(1), false), M); + app_ref two(A.mk_numeral(rational(2), false), M); + app_ref ten(A.mk_numeral(rational(10), false), M); + app_ref x(M.mk_const(symbol("x"), R), M); + app_ref y(M.mk_const(symbol("y"), R), M); + app_ref z(M.mk_const(symbol("z"), R), M); + + expr_ref p1(A.mk_le(A.mk_add(A.mk_mul(x,x,y), y), one), M); + expr_ref p2(A.mk_le(A.mk_add(A.mk_mul(x,x,y), z), one), M); + + enable_trace("nlarith"); + nlarith::util u(M); + nlarith::branch_conditions bc(M); + + + expr_ref_vector preds(M), branches(M); + vector substs; + expr* lits[2] = { p1.get(), p2.get() }; + if (!u.create_branches(x.get(), 2, lits, bc)) { + std::cout << "Failed to create branches\n"; + return; + } + + for (unsigned i = 0; i < preds.size(); ++i) { + std::cout << "Pred: " << mk_pp(preds[i].get(), M) << "\n"; + } + + for (unsigned i = 0; i < branches.size(); ++i) { + std::cout << "Branch:\n" << mk_pp(branches[i].get(), M) << "\n"; + for (unsigned j = 0; j < substs[i].size(); ++j) { + std::cout << mk_pp(preds[j].get(), M) << " |-> " + << mk_pp(substs[i][j].get(), M) << "\n"; + } + } + +} diff --git a/test/nlsat.cpp b/test/nlsat.cpp new file mode 100644 index 000000000..aa79df99e --- /dev/null +++ b/test/nlsat.cpp @@ -0,0 +1,306 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + nlsat.cpp + +Abstract: + + nlsat procedure + +Author: + + Leonardo (leonardo) 2012-01-09 + +Notes: + +--*/ +#include"nlsat_assignment.h" +#include"nlsat_interval_set.h" +#include"nlsat_evaluator.h" +#include"nlsat_solver.h" +#include"util.h" + +nlsat::interval_set_ref tst_interval(nlsat::interval_set_ref const & s1, + nlsat::interval_set_ref const & s2, + unsigned expected_num_intervals, + bool check_num_intervals = true) { + nlsat::interval_set_manager & ism = s1.m(); + nlsat::interval_set_ref r(ism); + std::cout << "------------------\n"; + std::cout << "s1: " << s1 << "\n"; + std::cout << "s2: " << s2 << "\n"; + r = ism.mk_union(s1, s2); + std::cout << "union(s1, s2): " << r << std::endl; + SASSERT(!check_num_intervals || ism.num_intervals(r) == expected_num_intervals); + SASSERT(ism.subset(s1, r)); + SASSERT(ism.subset(s2, r)); + if (ism.set_eq(s1, s2)) { + SASSERT(ism.set_eq(s1, r)); + SASSERT(ism.set_eq(s2, r)); + } + else { + SASSERT(ism.subset(s1, s2) || !ism.subset(r, s2)); + SASSERT(ism.subset(s2, s1) || !ism.subset(r, s1)); + } + nlsat::interval_set_ref r2(ism); + r2 = ism.mk_union(s2, s1); + SASSERT(ism.set_eq(r, r2)); + anum zero; + nlsat::interval_set_ref full(ism); + nlsat::literal dummy(131, false); + full = ism.mk(true, true, zero, true, true, zero, dummy); + SASSERT(ism.set_eq(r, full) == ism.is_full(r)); + return r; +} + +static void tst3() { + enable_trace("nlsat_interval"); + unsynch_mpq_manager qm; + anum_manager am(qm); + small_object_allocator allocator; + nlsat::interval_set_manager ism(am, allocator); + + scoped_anum sqrt2(am), m_sqrt2(am), two(am), m_two(am), three(am), one(am), zero(am); + am.set(two, 2); + am.set(m_two, -2); + am.set(one, 1); + am.root(two, 2, sqrt2); + am.set(m_sqrt2, sqrt2); + am.neg(m_sqrt2); + am.set(three, 3); + + nlsat::literal p1(1, false); + nlsat::literal p2(2, false); + nlsat::literal p3(3, false); + nlsat::literal p4(4, false); + nlsat::literal np2(2, true); + + nlsat::interval_set_ref s1(ism), s2(ism), s3(ism), s4(ism); + s1 = ism.mk_empty(); + std::cout << "s1: " << s1 << "\n"; + s2 = ism.mk(true, true, zero, false, false, sqrt2, np2); + std::cout << "s2: " << s2 << "\n"; + s3 = ism.mk(false, false, zero, false, false, two, p1); + std::cout << "s3: " << s3 << "\n"; + s4 = ism.mk_union(s2, s3); + std::cout << "s4: " << s4 << "\n"; + + // Case + // s1: [ ... ] + // s2: [ ... ] + s1 = ism.mk(false, false, zero, false, false, two, p1); + s2 = ism.mk(false, false, zero, false, false, two, p2); + tst_interval(s1, s2, 1); + + // Case + // s1: [ ... ] + // s2: [ ... ] + s1 = ism.mk(false, false, zero, false, false, two, p1); + s2 = ism.mk(false, false, m_sqrt2, false, false, one, p2); + s3 = ism.mk_union(s1, s2); + tst_interval(s1, s2, 2); + + // Case + // s1: [ ... ] + // s2: [ ... ] + s1 = ism.mk(false, false, m_sqrt2, false, false, one, p1); + s2 = ism.mk(false, false, zero, false, false, two, p2); + tst_interval(s1, s2, 2); + + // Case + // s1: [ ... ] + // s2: [ ... ] + s1 = ism.mk(false, false, m_sqrt2, false, false, one, p1); + s2 = ism.mk(false, false, two, false, false, three, p2); + tst_interval(s1, s2, 2); + + // Case + // s1: [ ... ] + // s2: [ ... ] + s1 = ism.mk(false, false, m_sqrt2, false, false, three, p1); + s2 = ism.mk(false, false, zero, false, false, two, p2); + tst_interval(s1, s2, 1); + + // Case + // s1: [ ... ] + // s2: [ ... ] [ ... ] + s1 = ism.mk(false, false, m_two, false, false, two, p1); + s2 = ism.mk(false, false, m_sqrt2, false, false, zero, p2); + s3 = ism.mk(false, false, one, false, false, three, p2); + s2 = ism.mk_union(s2, s3); + tst_interval(s1, s2, 2); + + // Case + // s1: [ ... ] + // s2: [ ... ] + s1 = ism.mk(false, false, m_two, false, false, two, p1); + s2 = ism.mk(false, false, two, false, false, three, p2); + tst_interval(s1, s2, 2); + s2 = ism.mk(true, false, two, false, false, three, p2); + tst_interval(s1, s2, 2); + s2 = ism.mk(true, false, two, false, false, three, p1); + tst_interval(s1, s2, 1); + s1 = ism.mk(false, false, m_two, true, false, two, p1); + tst_interval(s1, s2, 2); + s1 = ism.mk(false, false, two, false, false, two, p1); + s2 = ism.mk(false, false, two, false, false, three, p2); + tst_interval(s1, s2, 1); + + // Case + // s1: [ ... ] [ ... ] + // s2: [ .. ] [ ... ] [ ... ] + s1 = ism.mk(false, false, m_two, false, false, zero, p1); + s3 = ism.mk(false, false, one, false, false, three, p1); + s1 = ism.mk_union(s1, s3); + s2 = ism.mk(true, true, zero, false, false, m_sqrt2, p2); + tst_interval(s1, s2, 3); + s3 = ism.mk(false, false, one, false, false, sqrt2, p2); + s2 = ism.mk_union(s2, s3); + s3 = ism.mk(false, false, two, true, true, zero, p2); + s2 = ism.mk_union(s2, s3); + tst_interval(s1, s2, 4); + + // Case + s1 = ism.mk(true, true, zero, false, false, one, p1); + s2 = ism.mk(true, false, one, true, true, zero, p2); + tst_interval(s1, s2, 2); + s2 = ism.mk(true, false, one, false, false, two, p2); + s3 = ism.mk(false, false, two, true, true, zero, p1); + s2 = ism.mk_union(s2, s3); + tst_interval(s1, s2, 3); +} + +static nlsat::interval_set_ref mk_random(nlsat::interval_set_manager & ism, anum_manager & am, int range, int space, int tries, bool minus_inf, bool plus_inf, + nlsat::literal lit) { + static random_gen gen; + SASSERT(range > 0); + SASSERT(space > 0); + nlsat::interval_set_ref r(ism), curr(ism); + scoped_anum lower(am); + scoped_anum upper(am); + int prev = -range + (gen() % (space*4)); + + if (gen() % 3 == 0 && minus_inf) { + int next = prev + (gen() % space); + bool open = gen() % 2 == 0; + am.set(upper, next); + r = ism.mk(true, true, lower, open, false, upper, lit); + prev = next; + } + + for (int i = 0; i < tries; i++) { + int l = prev + (gen() % space); + int u = l + (gen() % space); + bool lower_open = gen() % 2 == 0; + bool upper_open = gen() % 2 == 0; + if ((lower_open || upper_open) && l == u) + u++; + am.set(lower, l); + am.set(upper, u); + curr = ism.mk(lower_open, false, lower, upper_open, false, upper, lit); + r = ism.mk_union(r, curr); + prev = u; + } + + if (gen() % 3 == 0 && plus_inf) { + int next = prev + (gen() % space); + bool open = gen() % 2 == 0; + am.set(lower, next); + curr = ism.mk(open, false, lower, true, true, upper, lit); + r = ism.mk_union(r, curr); + } + return r; +} + +static void check_subset_result(nlsat::interval_set_ref const & s1, + nlsat::interval_set_ref const & s2, + nlsat::interval_set_ref const & r, + nlsat::literal l1, + nlsat::literal l2) { + nlsat::interval_set_manager ism(s1.m()); + nlsat::interval_set_ref tmp(ism); + unsigned num = ism.num_intervals(r); + nlsat::literal_vector lits; + ism.get_justifications(r, lits); + SASSERT(lits.size() <= 2); + for (unsigned i = 0; i < num; i++) { + tmp = ism.get_interval(r, i); + ism.get_justifications(tmp, lits); + SASSERT(lits.size() == 1); + if (lits[0] == l1) { + SASSERT(ism.subset(tmp, s1)); + } + else { + SASSERT(lits[0] == l2); + SASSERT(ism.subset(tmp, s2)); + } + } +} + +static void tst4() { + enable_trace("nlsat_interval"); + unsynch_mpq_manager qm; + anum_manager am(qm); + small_object_allocator allocator; + nlsat::interval_set_manager ism(am, allocator); + nlsat::interval_set_ref s1(ism), s2(ism), r(ism); + + nlsat::literal l1(1, false); + nlsat::literal l2(2, false); + + for (unsigned i = 0; i < 100; i++) { + s1 = mk_random(ism, am, 20, 3, 10, true, true, l1); + s2 = mk_random(ism, am, 20, 3, 10, true, true, l2); + r = tst_interval(s1, s2, 0, false); + check_subset_result(s1, s2, r, l1, l2); + } + + for (unsigned i = 0; i < 100; i++) { + s1 = mk_random(ism, am, 200, 100, 20, true, true, l1); + s2 = mk_random(ism, am, 200, 100, 20, true, true, l2); + r = tst_interval(s1, s2, 0, false); + check_subset_result(s1, s2, r, l1, l2); + } +} + +static void tst5() { + params_ref ps; + nlsat::solver s(ps); + unsynch_mpq_manager & qm = s.qm(); + anum_manager & am = s.am(); + nlsat::pmanager & pm = s.pm(); + nlsat::assignment as(am); + small_object_allocator allocator; + nlsat::interval_set_manager ism(am, allocator); + nlsat::evaluator ev(as, pm, allocator); + nlsat::var x0, x1; + x0 = pm.mk_var(); + x1 = pm.mk_var(); + polynomial_ref p(pm); + polynomial_ref _x0(pm), _x1(pm); + _x0 = pm.mk_polynomial(x0); + _x1 = pm.mk_polynomial(x1); + p = (_x0^2) + (_x1^2) - 2; + nlsat::poly * _p[1] = { p.get() }; + bool is_even[1] = { false }; + nlsat::bool_var b = s.mk_ineq_atom(nlsat::atom::GT, 1, _p, is_even); + nlsat::atom * a = s.bool_var2atom(b); + SASSERT(a != 0); + nlsat::interval_set_ref i(ism); + scoped_anum zero(am); + am.set(zero, 0); + as.set(0, zero); + i = ev.infeasible_intervals(a, true); + std::cout << "1) " << i << "\n"; + as.set(1, zero); + i = ev.infeasible_intervals(a, true); + std::cout << "2) " << i << "\n"; +} + +void tst_nlsat() { + tst5(); + tst4(); + tst3(); +} diff --git a/test/no_overflow.cpp b/test/no_overflow.cpp new file mode 100644 index 000000000..4dd3a2287 --- /dev/null +++ b/test/no_overflow.cpp @@ -0,0 +1,711 @@ +/*++ +Copyright (c) 2009 Microsoft Corporation + +Module Name: + + no_overflow.cpp + +Abstract: + + Test non-overflowing checks for arithmetic. + +Author: + + Yannick Moy (t-yanmoy) 2009-02-17. + +Revision History: + +--*/ +#ifdef _WINDOWS + +#include "z3.h" +#include "trace.h" +#include "rational.h" + +#define TEST(TEST_NAME, TEST_OUTCOME, NEG_TEST_OUTCOME) \ + do { \ + if (TEST_NAME != NULL) \ + { \ + Z3_push(ctx); \ + Z3_assert_cnstr(ctx, TEST_NAME); \ + SASSERT(Z3_check(ctx) == TEST_OUTCOME); \ + Z3_pop(ctx, 1); \ + \ + Z3_push(ctx); \ + Z3_assert_cnstr(ctx, Z3_mk_not(ctx, TEST_NAME)); \ + SASSERT(Z3_check(ctx) == NEG_TEST_OUTCOME); \ + Z3_pop(ctx, 1); \ + } \ + } while (0) + +#define TEST_NO_OVERFLOW TEST(test_ovfl, Z3_L_TRUE, Z3_L_FALSE) +#define TEST_OVERFLOW TEST(test_ovfl, Z3_L_FALSE, Z3_L_TRUE) + +#define TEST_NO_OVERFLOW_IFF(COND) \ + do { \ + if (COND) { \ + TEST_NO_OVERFLOW; \ + } \ + else { \ + TEST_OVERFLOW; \ + } \ + } while (0) + +#define TEST_NO_UNDERFLOW TEST(test_udfl, Z3_L_TRUE, Z3_L_FALSE) +#define TEST_UNDERFLOW TEST(test_udfl, Z3_L_FALSE, Z3_L_TRUE) + +#define TEST_NO_UNDERFLOW_IFF(COND) \ + do { \ + if (COND) { \ + TEST_NO_UNDERFLOW; \ + } \ + else { \ + TEST_UNDERFLOW; \ + } \ + } while (0) + +#define TEST_ANY(TEST_NAME) \ + do { \ + Z3_push(ctx); \ + Z3_assert_cnstr(ctx, TEST_NAME); \ + Z3_check(ctx); /* ignore result of check */ \ + Z3_pop(ctx, 1); \ + } while (0) + +#define TEST_ANY_OVERFLOW TEST_ANY(test_ovfl) +#define TEST_ANY_UNDERFLOW TEST_ANY(test_udfl) + +Z3_ast mk_min(Z3_context ctx, Z3_sort bv, bool is_signed) { + unsigned bvsize = Z3_get_bv_sort_size(ctx, bv); + if (! is_signed) return Z3_mk_numeral(ctx, "0", bv); + unsigned sz = bvsize - 1; + rational min_bound = power(rational(2), sz); + min_bound.neg(); + return Z3_mk_numeral(ctx, min_bound.to_string().c_str(), bv); +} + +Z3_ast mk_max(Z3_context ctx, Z3_sort bv, bool is_signed) { + unsigned bvsize = Z3_get_bv_sort_size(ctx, bv); + unsigned sz = is_signed ? bvsize - 1 : bvsize; + rational max_bound = power(rational(2), sz); + --max_bound; + return Z3_mk_numeral(ctx, max_bound.to_string().c_str(), bv); +} + +void test_add(unsigned bvsize, bool is_signed) { + + TRACE("no_overflow", tout << "test_add: bvsize = " << bvsize << ", is_signed = " << is_signed << "\n";); + + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize); + + Z3_ast min = mk_min(ctx, bv, is_signed); + Z3_ast max = mk_max(ctx, bv, is_signed); + Z3_ast t1; + Z3_ast t2; + Z3_ast test_ovfl; + Z3_ast test_udfl; + + t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv); + t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv); + test_ovfl = Z3_mk_bvadd_no_overflow(ctx, t1, t2, is_signed); + test_udfl = is_signed ? Z3_mk_bvadd_no_underflow(ctx, t1, t2) : NULL; + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW_IFF(bvsize == 1 && is_signed); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW_IFF(! (bvsize == 1 && is_signed)); + Z3_pop(ctx, 1); + + if (is_signed) { + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW; + TEST_UNDERFLOW; + Z3_pop(ctx, 1); + } + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW_IFF(! is_signed); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW_IFF(bvsize == 1 && is_signed); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void test_sub(unsigned bvsize, bool is_signed) { + + TRACE("no_overflow", tout << "test_sub: bvsize = " << bvsize << ", is_signed = " << is_signed << "\n";); + + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize); + + Z3_ast min = mk_min(ctx, bv, is_signed); + Z3_ast max = mk_max(ctx, bv, is_signed); + Z3_ast t1; + Z3_ast t2; + Z3_ast test_ovfl; + Z3_ast test_udfl; + + t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv); + t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv); + test_ovfl = is_signed ? Z3_mk_bvsub_no_overflow(ctx, t1, t2) : NULL; + test_udfl = Z3_mk_bvsub_no_underflow(ctx, t1, t2, is_signed); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW_IFF(! (bvsize == 1 && is_signed)); + TEST_NO_UNDERFLOW_IFF(is_signed); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW_IFF(is_signed); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW_IFF(bvsize == 1 || is_signed); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW_IFF(! (bvsize == 1 && is_signed)); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW_IFF(! (bvsize != 1 && is_signed)); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW_IFF(bvsize == 1 && is_signed); + Z3_pop(ctx, 1); + + if (is_signed) { + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "-1", bv))); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + } + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW_IFF(bvsize == 1 && is_signed); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW_IFF(! is_signed); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void test_neg(unsigned bvsize) { + + TRACE("no_overflow", tout << "test_neg: bvsize = " << bvsize << "\n";); + + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize); + + Z3_ast min = mk_min(ctx, bv, /* is_signed = */ true); + Z3_ast max = mk_max(ctx, bv, /* is_signed = */ true); + Z3_ast t1; + Z3_ast test_ovfl; + + t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv); + test_ovfl = Z3_mk_bvneg_no_overflow(ctx, t1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + TEST_NO_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW_IFF(bvsize != 1); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv))); + TEST_NO_OVERFLOW_IFF(bvsize != 1); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max)); + TEST_NO_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + TEST_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void test_mul(unsigned bvsize, bool is_signed) { + + TRACE("no_overflow", tout << "test_mul: bvsize = " << bvsize << ", is_signed = " << is_signed << "\n";); + + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize); + + Z3_ast min = mk_min(ctx, bv, is_signed); + Z3_ast max = mk_max(ctx, bv, is_signed); + Z3_ast t1; + Z3_ast t2; + Z3_ast test_ovfl; + Z3_ast test_udfl; + + t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv); + t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv); + test_ovfl = Z3_mk_bvmul_no_overflow(ctx, t1, t2, is_signed); + test_udfl = is_signed ? Z3_mk_bvmul_no_underflow(ctx, t1, t2) : NULL; + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW_IFF(! (bvsize == 1 && is_signed)); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "0", bv))); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW_IFF(! (bvsize == 1 && is_signed)); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + if (is_signed) { + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "-1", bv))); + TEST_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + } + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW_IFF(! is_signed); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW; + TEST_NO_UNDERFLOW_IFF(! (bvsize != 1 && is_signed)); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max)); + TEST_NO_OVERFLOW_IFF(bvsize == 1); + TEST_NO_UNDERFLOW; + Z3_pop(ctx, 1); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void test_div(unsigned bvsize) { + + TRACE("no_overflow", tout << "test_div: bvsize = " << bvsize << "\n";); + + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize); + + Z3_ast min = mk_min(ctx, bv, /* is_signed = */ true); + Z3_ast max = mk_max(ctx, bv, /* is_signed = */ true); + Z3_ast t1; + Z3_ast t2; + Z3_ast test_ovfl; + + t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv); + t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv); + test_ovfl = Z3_mk_bvsdiv_no_overflow(ctx, t1, t2); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW_IFF(bvsize != 1); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "-1", bv))); + TEST_NO_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "0", bv))); + TEST_ANY_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "0", bv))); + TEST_ANY_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv))); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "0", bv))); + TEST_ANY_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "-1", bv))); + TEST_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); + TEST_NO_OVERFLOW_IFF(bvsize != 1); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW_IFF(bvsize != 1); + Z3_pop(ctx, 1); + + Z3_push(ctx); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min)); + TEST_NO_OVERFLOW; + Z3_pop(ctx, 1); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +typedef Z3_ast (Z3_API *NO_OVFL_ARITH_FUNC)(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed); +typedef Z3_ast (Z3_API *ARITH_FUNC)(Z3_context ctx, Z3_ast t1, Z3_ast t2); + +typedef enum { OVFL_FUNC, UDFL_FUNC } overflow_type; + +typedef struct { + std::string name; + NO_OVFL_ARITH_FUNC no_overflow_func; + ARITH_FUNC func; + overflow_type type; + int extsize; // negative size indicates size of arguments should be doubled + bool do_unsigned; + bool non_zero; // second argument should not be null (for division) + bool sign_compar; // whether signed comparison should be used even for unsigned operation +} Equivalence_params; + +Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) { + return Z3_mk_bvsdiv_no_overflow(ctx, t1, t2); +} + +Z3_ast Z3_API Z3_mk_bvneg_no_overflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) { + return Z3_mk_bvneg_no_overflow(ctx, t1); +} + +Z3_ast Z3_API Z3_mk_bvneg_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2) { + return Z3_mk_bvneg(ctx, t1); +} + +Z3_ast Z3_API Z3_mk_bvadd_no_underflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) { + return Z3_mk_bvadd_no_underflow(ctx, t1, t2); +} + +Z3_ast Z3_API Z3_mk_bvsub_no_overflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) { + return Z3_mk_bvsub_no_overflow(ctx, t1, t2); +} + +Z3_ast Z3_API Z3_mk_bvmul_no_underflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) { + return Z3_mk_bvmul_no_underflow(ctx, t1, t2); +} + +void test_equiv(Equivalence_params params, unsigned bvsize, bool is_signed) { + + TRACE("no_overflow", tout << "test_" << params.name << "_equiv: bvsize = " << bvsize << ", is_signed = " << is_signed << "\n";); + + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize); + + Z3_ast min = mk_min(ctx, bv, is_signed); + Z3_ast max = mk_max(ctx, bv, is_signed); + Z3_ast t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv); + Z3_ast t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv); + Z3_ast real_test = (*params.no_overflow_func)(ctx, t1, t2, is_signed); + + Z3_ast cond = NULL; + if (params.non_zero) + { + cond = Z3_mk_not(ctx, Z3_mk_eq(ctx, t2, Z3_mk_int(ctx, 0, bv))); + } + + unsigned extsize = params.extsize < 0 ? bvsize : params.extsize; + if (is_signed) { + min = Z3_mk_sign_ext(ctx, extsize, min); + max = Z3_mk_sign_ext(ctx, extsize, max); + t1 = Z3_mk_sign_ext(ctx, extsize, t1); + t2 = Z3_mk_sign_ext(ctx, extsize, t2); + } + else { + min = Z3_mk_zero_ext(ctx, extsize, min); + max = Z3_mk_zero_ext(ctx, extsize, max); + t1 = Z3_mk_zero_ext(ctx, extsize, t1); + t2 = Z3_mk_zero_ext(ctx, extsize, t2); + } + + Z3_ast r = (*params.func)(ctx, t1, t2); + Z3_ast check; + if (is_signed) { + check = (params.type == UDFL_FUNC) ? Z3_mk_bvsle(ctx, min, r) : Z3_mk_bvsle(ctx, r, max); + } + else { + if (params.sign_compar) + { + // check with signed comparison for subtraction of unsigned + check = (params.type == UDFL_FUNC) ? Z3_mk_bvsle(ctx, min, r) : Z3_mk_bvsle(ctx, r, max); + } + else + { + check = (params.type == UDFL_FUNC) ? Z3_mk_bvule(ctx, min, r) : Z3_mk_bvule(ctx, r, max); + } + } + + Z3_push(ctx); + Z3_ast equiv = Z3_mk_iff(ctx, real_test, check); + if (cond != NULL) + { + equiv = Z3_mk_implies(ctx, cond, equiv); + } + Z3_assert_cnstr(ctx, Z3_mk_not(ctx, equiv)); + SASSERT(Z3_check(ctx) == Z3_L_FALSE); + Z3_pop(ctx, 1); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +//void debug_mul() { +// +// unsigned bvsize = 2; +// bool is_signed = true; +// +// Z3_config cfg = Z3_mk_config(); +// Z3_context ctx = Z3_mk_context(cfg); +// Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize); +// +// Z3_ast min = mk_min(ctx, bv, is_signed); +// Z3_ast max = mk_max(ctx, bv, is_signed); +// Z3_ast t1; +// Z3_ast t2; +// Z3_ast test_udfl; +// +// t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv); +// t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv); +// test_udfl = Z3_mk_bvmul_no_underflow(ctx, t1, t2); +// +// Z3_push(ctx); +// Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv))); +// Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); +// //TEST_NO_UNDERFLOW; +// Z3_assert_cnstr(ctx, test_udfl); +// SASSERT(Z3_check(ctx) == Z3_TRUE); +// Z3_pop(ctx, 1); +// +// Z3_del_config(cfg); +// Z3_del_context(ctx); +//} + +#define BVSIZES 4 +#define TESTNUM 3 + +#define EQUIV_BVSIZES 4 +#define EQUIV_TESTNUM 8 + +typedef void (*TESTFUN)(unsigned bvsize, bool is_signed); + +void tst_no_overflow() { + + unsigned bvsizes[BVSIZES] = { 1, 16, 32, 42 }; + TESTFUN tests[TESTNUM] = { test_add, test_sub, test_mul }; + + for (int i = 0; i < BVSIZES; ++i) { + for (int j = 0; j < TESTNUM; ++j) { + tests[j](bvsizes[i], /* is_signed = */ true); + tests[j](bvsizes[i], /* is_signed = */ false); + } + test_neg(bvsizes[i]); + test_div(bvsizes[i]); + } + + unsigned equiv_bvsizes[EQUIV_BVSIZES] = { 1, 2, 7, 16 }; + // before performing the bound test, arguments are extended by a few bits to prevent overflow: + // * 1 is the default + // * 2 is used for subtraction, so that 1 bit is used for the sign event for unsigned subtraction + // * -1 to indicate that the bitsize should be doubled for multiplication + Equivalence_params equiv_tests[EQUIV_TESTNUM] = { + { "ovfl_add", Z3_mk_bvadd_no_overflow, Z3_mk_bvadd, OVFL_FUNC, + 1, /* do_unsigned = */ true, /* non_zero = */ false, /* sign_compar = */ false }, + { "udfl_add", Z3_mk_bvadd_no_underflow_wrapper, Z3_mk_bvadd, UDFL_FUNC, + 1, /* do_unsigned = */ false, /* non_zero = */ false, /* sign_compar = */ false }, + { "ovfl_sub", Z3_mk_bvsub_no_overflow_wrapper, Z3_mk_bvsub, OVFL_FUNC, + 1, /* do_unsigned = */ false, /* non_zero = */ false, /* sign_compar = */ false }, + { "udfl_sub", Z3_mk_bvsub_no_underflow, Z3_mk_bvsub, UDFL_FUNC, + 2, /* do_unsigned = */ true, /* non_zero = */ false, /* sign_compar = */ true }, + { "ovfl_mul", Z3_mk_bvmul_no_overflow, Z3_mk_bvmul, OVFL_FUNC, + -1, /* do_unsigned = */ true, /* non_zero = */ false, /* sign_compar = */ false }, + { "udfl_mul", Z3_mk_bvmul_no_underflow_wrapper, Z3_mk_bvmul, UDFL_FUNC, + -1, /* do_unsigned = */ false, /* non_zero = */ false, /* sign_compar = */ false }, + { "ovfl_div", Z3_mk_bvsdiv_no_overflow_wrapper, Z3_mk_bvsdiv, OVFL_FUNC, + 1, /* do_unsigned = */ false, /* non_zero = */ true, /* sign_compar = */ false }, + { "ovfl_neg", Z3_mk_bvneg_no_overflow_wrapper, Z3_mk_bvneg_wrapper, OVFL_FUNC, + 1, /* do_unsigned = */ false, /* non_zero = */ false, /* sign_compar = */ false }, + }; + + for (int i = 0; i < EQUIV_BVSIZES; ++i) { + for (int j = 0; j < EQUIV_TESTNUM; ++j) { + test_equiv(equiv_tests[j], equiv_bvsizes[i], /* is_signed = */ true); + if (equiv_tests[j].do_unsigned) { + test_equiv(equiv_tests[j], equiv_bvsizes[i], /* is_signed = */ false); + } + } + } +} +#else +void tst_no_overflow() { +} +#endif diff --git a/test/object_allocator.cpp b/test/object_allocator.cpp new file mode 100644 index 000000000..caac3aa93 --- /dev/null +++ b/test/object_allocator.cpp @@ -0,0 +1,121 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + object_allocator.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-06-09. + +Revision History: + +--*/ + +#include"rational.h" +#include"object_allocator.h" + +struct cell { + rational m_coeff; + unsigned m_i; + unsigned m_j; + cell * m_next_row; + cell * m_next_col; +public: + static unsigned g_num_allocated_cells; + static unsigned g_num_deallocated_cells; + static unsigned g_num_recycled_cells; + + cell() { + g_num_allocated_cells++; + } + + ~cell() { + g_num_deallocated_cells++; + } + + void reset() { + m_coeff.reset(); + g_num_recycled_cells++; + } +}; + +unsigned cell::g_num_allocated_cells = 0; +unsigned cell::g_num_deallocated_cells = 0; +unsigned cell::g_num_recycled_cells = 0; + +typedef object_allocator > cell_allocator; + +static void tst1() { + cell_allocator m; + + cell * c1 = m.allocate(); + cell * c2 = m.allocate(); + + c1->m_coeff = rational(10); + m.recycle(c1); + + cell * c3 = m.allocate(); + SASSERT(c3->m_coeff.is_zero()); +} + +static void tst2() { + cell_allocator m; + SASSERT(m.capacity() >= 2); + cell_allocator::worker_object_allocator m1 = m.get_worker_allocator(0); + cell_allocator::worker_object_allocator m2 = m.get_worker_allocator(1); + m.enable_concurrent(true); + + vector > object_coeff_pairs; + unsigned num_resets = 0; + + for (unsigned i = 0; i < 100000; i++) { + unsigned idx = rand() % 6; + if (idx < 4) { + cell * c; + if (idx < 2) + c = m1.allocate(); + else + c = m2.allocate(); + SASSERT(c->m_coeff.is_zero()); + int val = rand(); + c->m_coeff = rational(val); + object_coeff_pairs.push_back(std::make_pair(c, val)); + } + else { + if (!object_coeff_pairs.empty()) { + unsigned idx = rand() % object_coeff_pairs.size(); + cell * c = object_coeff_pairs[idx].first; + CTRACE("object_allocator", c->m_coeff != rational(object_coeff_pairs[idx].second), tout << c->m_coeff << " != " << rational(object_coeff_pairs[idx].second) << "\n";); + SASSERT(c->m_coeff == rational(object_coeff_pairs[idx].second)); + if (idx < 5) + m1.recycle(c); + else + m2.recycle(c); + object_coeff_pairs.erase(object_coeff_pairs.begin() + idx); + } + } + + if (rand() % 5000 == 0) { + m.enable_concurrent(false); + m.reset(); + object_coeff_pairs.reset(); + m.enable_concurrent(true); + num_resets++; + } + } + TRACE("object_allocator", tout << "num. resets: " << num_resets << "\n";); +} + +void tst_object_allocator() { + tst1(); + tst2(); + TRACE("object_allocator", tout << "num. allocated cells: " << cell::g_num_allocated_cells << "\nnum. deallocated cells: " << cell::g_num_deallocated_cells << + "\nnum. recycled cells: " << cell::g_num_recycled_cells << "\n";); + SASSERT(cell::g_num_allocated_cells == cell::g_num_deallocated_cells); +} diff --git a/test/old_interval.cpp b/test/old_interval.cpp new file mode 100644 index 000000000..91096a629 --- /dev/null +++ b/test/old_interval.cpp @@ -0,0 +1,201 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + interval.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-12-10. + +Revision History: + +--*/ +#include"old_interval.h" + +static void tst1() { + ext_numeral inf(true); + ext_numeral minus_inf(false); + ext_numeral zero(0); + + SASSERT(ext_numeral(10) + ext_numeral(3) == ext_numeral(13)); + SASSERT(inf + zero == inf); + SASSERT(minus_inf + zero == minus_inf); + SASSERT(minus_inf + ext_numeral(3) == minus_inf); + SASSERT(inf + inf == inf); + SASSERT(minus_inf + minus_inf == minus_inf); + SASSERT(minus_inf + ext_numeral(10) == minus_inf); + SASSERT(minus_inf + ext_numeral(-10) == minus_inf); + SASSERT(inf + ext_numeral(10) == inf); + SASSERT(inf + ext_numeral(-10) == inf); + + SASSERT(ext_numeral(10) - ext_numeral(3) == ext_numeral(7)); + SASSERT(inf - zero == inf); + SASSERT(minus_inf - zero == minus_inf); + SASSERT(minus_inf - ext_numeral(3) == minus_inf); + SASSERT(inf - minus_inf == inf); + SASSERT(minus_inf - inf == minus_inf); + SASSERT(zero - minus_inf == inf); + SASSERT(zero - inf == minus_inf); + SASSERT(ext_numeral(-10) - minus_inf == inf); + SASSERT(ext_numeral(10) - minus_inf == inf); + SASSERT(ext_numeral(-10) - inf == minus_inf); + SASSERT(ext_numeral(10) - inf == minus_inf); + + SASSERT(ext_numeral(10) * inf == inf); + SASSERT(ext_numeral(-10) * inf == minus_inf); + SASSERT(zero * inf == zero); + SASSERT(zero * minus_inf == zero); + SASSERT(zero * ext_numeral(10) == zero); + SASSERT(ext_numeral(10) * ext_numeral(-20) == ext_numeral(-200)); + SASSERT(ext_numeral(3) * ext_numeral(2) == ext_numeral(6)); + SASSERT(inf * inf == inf); + SASSERT(inf * minus_inf == minus_inf); + SASSERT(minus_inf * minus_inf == inf); + SASSERT(minus_inf * inf == minus_inf); + SASSERT(minus_inf * ext_numeral(10) == minus_inf); + SASSERT(minus_inf * ext_numeral(-10) == inf); + + SASSERT(minus_inf < inf); + SASSERT(!(inf < minus_inf)); + SASSERT(minus_inf < ext_numeral(10)); + SASSERT(ext_numeral(-3) < inf); + SASSERT(ext_numeral(-10) < ext_numeral(4)); + SASSERT(ext_numeral(2) < ext_numeral(10)); + SASSERT(!(inf < ext_numeral(30))); + SASSERT(!(ext_numeral(10) < minus_inf)); + SASSERT(!(inf < inf)); + SASSERT(!(minus_inf < minus_inf)); + SASSERT(!(zero < zero)); + SASSERT(!(ext_numeral(10) < ext_numeral(10))); + SASSERT(inf > minus_inf); + SASSERT(inf > zero); + SASSERT(inf > ext_numeral(10)); + SASSERT(ext_numeral(10) > minus_inf); + SASSERT(zero > minus_inf); + SASSERT(!(zero > inf)); + SASSERT(!(minus_inf > inf)); + SASSERT(inf >= minus_inf); + SASSERT(inf >= inf); + SASSERT(minus_inf >= minus_inf); + SASSERT(inf >= zero); + SASSERT(zero >= minus_inf); + SASSERT(inf <= inf); + SASSERT(minus_inf <= minus_inf); + SASSERT(zero <= inf); + SASSERT(minus_inf <= zero); + + ext_numeral val(10); + val.neg(); + SASSERT(val == ext_numeral(-10)); + val = inf; + val.neg(); + SASSERT(val == minus_inf); + val.neg(); + SASSERT(val == inf); + + SASSERT(minus_inf.sign()); + SASSERT(!zero.sign()); + SASSERT(!inf.sign()); + SASSERT(ext_numeral(-10).sign()); + SASSERT(!ext_numeral(10).sign()); + + SASSERT(inf.is_infinite()); + SASSERT(minus_inf.is_infinite()); + SASSERT(!zero.is_infinite()); + SASSERT(!ext_numeral(10).is_infinite()); + SASSERT(!inf.is_zero()); + SASSERT(!minus_inf.is_zero()); + SASSERT(zero.is_zero()); + SASSERT(!ext_numeral(10).is_zero()); +} + +class interval_tester { + v_dependency_manager m; + + interval singleton(int i) { return interval(m, rational(i)); } + interval all() { return interval(m); } + interval l(int i, bool o = false, int idx = 0) { return interval(m, rational(i), o, true, idx == 0 ? 0 : m.mk_leaf(reinterpret_cast(idx))); } + interval r(int i, bool o = false, int idx = 0) { return interval(m, rational(i), o, false, idx == 0 ? 0 : m.mk_leaf(reinterpret_cast(idx))); } + interval b(int l, int u, bool lo = false, bool uo = false, int idx_l = 0, int idx_u = 0) { + return interval(m, rational(l), lo, idx_l == 0 ? 0 : m.mk_leaf(reinterpret_cast(idx_l)), rational(u), uo, idx_u == 0 ? 0 : m.mk_leaf(reinterpret_cast(idx_u))); + } + + void bugs() { + interval r1 = l(0); + interval r2 = b(-1, 0, false, true); + r1 *= r2; + } + + void tst1() { + std::cerr << singleton(10) << "\n"; + std::cerr << all() << "\n"; + std::cerr << l(-10) << "\n"; + std::cerr << r(10) << "\n"; + std::cerr << l(-10, true) << "\n"; + std::cerr << r(10, true) << "\n"; + std::cerr << b(2, 10) << "\n"; + std::cerr << wd(b(-5, 5, true, false, 1, 2) * b(-5, 5, false, true, 3, 4)) << "\n"; + std::cerr << wd(l(2, false, 1) / b(2, 6, false, false, 2, 3)) << "\n"; + std::cerr << wd(expt(b(-2, 3, true, false, 1, 2), 2)) << "\n"; + std::cerr << wd(expt(b(-4, 3, true, false, 1, 2), 2)) << "\n"; + std::cerr << wd(expt(b(2, 4, true, false, 1, 2), 2)) << "\n"; + std::cerr << wd(expt(b(0, 3, true, false, 1, 2), 2)) << "\n"; + std::cerr << wd(expt(b(-4, -2, true, false, 1, 2), 2)) << "\n"; + std::cerr << b(2, 10, false, false, 1, 2) << " * " << l(10, false, 3).inv() << " = " << wd(b(2, 10, false, false, 1, 2) / l(10, false, 3)) << "\n"; + std::cerr << b(-2, -1, false, true) << " * " << b(-3,0) << " = "; std::cerr.flush(); + std::cerr << (b(-2, -1, false, true) * b(-3,0)) << "\n"; + std::cerr << b(1, 2, true, false) << " * " << b(0,3) << " = "; std::cerr.flush(); + std::cerr << (b(1, 2, true, false) * b(0,3)) << "\n"; + std::cerr << b(1, 2, true, true) << " * " << b(-3,0) << " = "; std::cerr.flush(); + std::cerr << (b(1, 2, true, true) * b(-3,0)) << "\n"; + std::cerr << b(10,20) << " / " << b(0,1,true,false) << " = "; std::cerr.flush(); + std::cerr << (b(10,20)/b(0,1,true,false)) << "\n"; + std::cerr << (b(10,20)/b(0,2,true,false)) << "\n"; + } + +public: + void run() { + bugs(); + tst1(); + } +}; + +#include"basic_interval.h" +#include"mpz.h" +#include"scoped_numeral.h" + +static void tst2() { + typedef basic_interval_manager mpzi_manager; + typedef mpzi_manager::interval mpzi; + typedef mpzi_manager::scoped_interval scoped_mpzi; + + unsynch_mpz_manager nm; + mpzi_manager m(nm); + scoped_mpzi x(m), y(m), z(m); + + m.set(x, mpz(1), mpz(2)); + m.set(y, mpz(-2), mpz(3)); + m.add(x, y, z); + std::cout << "x: " << x << ", y: " << y << ", z: " << z << "\n"; + SASSERT(nm.eq(z.lower(), mpz(-1))); + SASSERT(nm.eq(z.upper(), mpz(5))); + m.mul(x, y, z); + std::cout << "x: " << x << ", y: " << y << ", z: " << z << "\n"; + SASSERT(nm.eq(z.lower(), mpz(-4))); + SASSERT(nm.eq(z.upper(), mpz(6))); +} + +void tst_old_interval() { + tst2(); + enable_trace("interval_bug"); + interval_tester tester; + tester.run(); + tst1(); +} + diff --git a/test/optional.cpp b/test/optional.cpp new file mode 100644 index 000000000..81b84cd59 --- /dev/null +++ b/test/optional.cpp @@ -0,0 +1,74 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_optional.cpp + +Abstract: + + Test optional module + +Author: + + Leonardo de Moura (leonardo) 2006-09-29. + +Revision History: + +--*/ +#include"trace.h" +#include"debug.h" +#include"optional.h" + +static void tst1() { + optional v; + SASSERT(!v); + SASSERT(v == false); + v = 10; + SASSERT(v); + SASSERT(*v == 10); + TRACE("optional", tout << sizeof(v) << "\n";); +} + +struct OptFoo { + int m_x; + int m_y; + + OptFoo(int x, int y):m_x(x), m_y(y) { + TRACE("optional", tout << "OptFoo created: " << m_x << " : " << m_y << "\n";); + } + + ~OptFoo() { + TRACE("optional", tout << "OptFoo deleted: " << m_x << " : " << m_y << "\n";); + } +}; + +static void tst2() { + optional v; + SASSERT(!v); + v = OptFoo(10, 20); + SASSERT(v->m_x == 10); + SASSERT(v->m_y == 20); + v = OptFoo(200, 300); + SASSERT(v->m_x == 200); + SASSERT(v->m_y == 300); + TRACE("optional", tout << sizeof(v) << "\n";); +} + +static void tst3() { + optional v; + SASSERT(!v); + int x = 10; + v = &x; + SASSERT(v); + SASSERT(*v == &x); + TRACE("optional", tout << sizeof(v) << "\n";); + SASSERT(*(*v) == 10); +} + +void tst_optional() { + tst1(); + tst2(); + tst3(); +} + diff --git a/test/par_dll.cpp b/test/par_dll.cpp new file mode 100644 index 000000000..b83df67b8 --- /dev/null +++ b/test/par_dll.cpp @@ -0,0 +1,58 @@ +#include "z3.h" +#include "windows.h" + +class thread_check { + + CRITICAL_SECTION m_cs; + + static DWORD __stdcall do_check(LPVOID _this) { + thread_check* th = static_cast(_this); + Z3_config cfg = Z3_mk_config(); + Z3_set_param_value(cfg,"MODEL","true"); + Z3_context ctx = Z3_mk_context(cfg); + Z3_parse_smtlib_string(ctx, "(benchmark b :logic QF_UF :extrafuns ((f U U) (x U)) :formula (= (f x) x))", 0, 0, 0, 0, 0, 0); + Z3_ast f = Z3_get_smtlib_formula(ctx, 0); + Z3_assert_cnstr(ctx, f); + Z3_model m = 0; + Z3_lbool r = Z3_check_and_get_model(ctx,&m); + EnterCriticalSection(&th->m_cs); + printf("%d\n", r); + LeaveCriticalSection(&th->m_cs); + if (m) { + Z3_del_model(ctx, m); + } + return 0; + } + + +public: + thread_check() { + InitializeCriticalSection(&m_cs); + } + + ~thread_check() { + DeleteCriticalSection(&m_cs); + } + + void do_checks(unsigned num_threads) { + HANDLE* handles = new HANDLE[num_threads]; + for (unsigned i = 0; i < num_threads; ++i) { + HANDLE hThread = CreateThread(NULL, 0, &thread_check::do_check, this, 0, 0); + handles[i] = hThread; + } + + WaitForMultipleObjects(num_threads, handles, TRUE, INFINITE); + + for (unsigned i = 0; i < num_threads; ++i) { + CloseHandle(handles[i]); + } + delete[] handles; + } +}; + +extern "C" +__declspec(dllexport) int ChessTestRun() { + thread_check tc; + tc.do_checks(2); + return 0; +} diff --git a/test/parallel.cpp b/test/parallel.cpp new file mode 100644 index 000000000..14f4d4b08 --- /dev/null +++ b/test/parallel.cpp @@ -0,0 +1,70 @@ +#ifdef _WINDOWS + +#include "z3.h" +#include "z3_private.h" +#include +#include "util.h" +#include "trace.h" +#include +#include "trace.h" +#include "vector.h" +#include "buffer.h" +#undef ARRAYSIZE +#include "windows.h" + +class thread_check { + + CRITICAL_SECTION m_cs; + + static DWORD __stdcall do_check(LPVOID _this) { + thread_check* th = static_cast(_this); + Z3_config cfg = Z3_mk_config(); + Z3_set_param_value(cfg,"MODEL","true"); + Z3_context ctx = Z3_mk_context(cfg); + Z3_parse_smtlib_string(ctx, "(benchmark b :logic QF_UF :extrafuns ((f U U) (x U)) :formula (= (f x) x))", 0, 0, 0, 0, 0, 0); + Z3_ast f = Z3_get_smtlib_formula(ctx, 0); + Z3_assert_cnstr(ctx, f); + Z3_model m = 0; + Z3_lbool r = Z3_check_and_get_model(ctx,&m); + EnterCriticalSection(&th->m_cs); + printf("%d\n", r); + LeaveCriticalSection(&th->m_cs); + if (m) { + Z3_del_model(ctx, m); + } + return 0; + } + + +public: + thread_check() { + InitializeCriticalSection(&m_cs); + } + + ~thread_check() { + DeleteCriticalSection(&m_cs); + } + + void do_checks(unsigned num_threads) { + ptr_buffer handles; + for (unsigned i = 0; i < num_threads; ++i) { + HANDLE hThread = CreateThread(NULL, 0, &thread_check::do_check, this, 0, 0); + handles.push_back(hThread); + } + + WaitForMultipleObjects(handles.size(), handles.c_ptr(), TRUE, INFINITE); + + for (unsigned i = 0; i < handles.size(); ++i) { + CloseHandle(handles[i]); + } + } +}; + +void tst_parallel() { + thread_check tc; + tc.do_checks(2); +} +#else +void tst_parallel() { +} +#endif diff --git a/test/parray.cpp b/test/parray.cpp new file mode 100644 index 000000000..77e8dc15d --- /dev/null +++ b/test/parray.cpp @@ -0,0 +1,314 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + parray.cpp + +Abstract: + + Test persistent arrays. + +Author: + + Leonardo de Moura (leonardo) 2011-02-23. + +Revision History: + +--*/ +#include"parray.h" +#include"small_object_allocator.h" +#include"ast.h" + +template +struct int_parray_config { + typedef int value; + typedef dummy_value_manager value_manager; + typedef small_object_allocator allocator; + static const bool ref_count = false; + static const bool preserve_roots = PRESERVE_ROOTS; + static const unsigned max_trail_sz = 8; + static const unsigned factor = 2; +}; + + +template +static void tst1() { + typedef parray_manager > int_parray_manager; + typedef typename int_parray_manager::ref int_array; + + dummy_value_manager vm; + small_object_allocator a; + int_parray_manager m(vm, a); + + int_array a1; + int_array a2; + int_array a3; + + m.mk(a1); + SASSERT(m.size(a1) == 0); + m.push_back(a1, 10, a2); + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n";); + SASSERT(m.size(a1) == 0); + SASSERT(m.size(a2) == 1); + m.push_back(a1, 20, a1); + m.push_back(a1, 30, a1); + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n";); + SASSERT(m.get(a1, 0) == 20); + SASSERT(m.get(a1, 1) == 30); + SASSERT(m.get(a2, 0) == 10); + SASSERT(m.size(a1) == 2); + SASSERT(m.size(a2) == 1); + SASSERT(m.size(a3) == 0); + m.push_back(a2, 100, a3); + SASSERT(m.size(a3) == 2); + SASSERT(m.get(a3, 0) == 10); + SASSERT(m.get(a3, 1) == 100); + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n"; + m.display_info(tout, a3); tout << "\n";); + m.push_back(a2, 50); + SASSERT(m.get(a2, 0) == 10); + SASSERT(m.get(a2, 1) == 50); + SASSERT(m.size(a2) == 2); + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n"; + m.display_info(tout, a3); tout << "\n";); + m.del(a1); + m.del(a2); + m.del(a3); +} + +template +static void tst2() { + typedef parray_manager > int_parray_manager; + typedef typename int_parray_manager::ref int_array; + + TRACE("parray", tout << "tst2\n";); + dummy_value_manager vm; + small_object_allocator a; + int_parray_manager m(vm, a); + + int_array a1; + int_array a2; + + for (unsigned i = 0; i < 100; i++) + m.push_back(a1, i); + SASSERT(m.size(a1) == 100); + m.push_back(a1, 100, a2); + for (unsigned i = 0; i < 10; i++) + m.push_back(a2, i+101); + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n";); + SASSERT(m.get(a1, 0) == 0); + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n";); + for (unsigned i = 0; i < m.size(a1); i++) { + SASSERT(m.get(a1, i) == i); + } + for (unsigned i = 0; i < m.size(a2); i++) { + SASSERT(m.get(a2, i) == i); + } + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n";); + m.unshare(a1); + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n";); + m.del(a1); + m.del(a2); +} + +template +static void tst3() { + typedef parray_manager > int_parray_manager; + typedef typename int_parray_manager::ref int_array; + + TRACE("parray", tout << "tst3\n";); + dummy_value_manager vm; + small_object_allocator a; + int_parray_manager m(vm, a); + + int_array a1; + int_array a2; + int_array a3; + int_array a4; + + for (unsigned i = 0; i < 20; i++) + m.push_back(a1, i); + SASSERT(m.size(a1) == 20); + m.set(a1, 0, 1, a2); + for (unsigned i = 1; i < 20; i++) { + if (i == 6) { + m.copy(a2, a3); + m.pop_back(a3); + m.pop_back(a3); + m.push_back(a3, 40); + } + m.set(a2, i, i+1); + } + m.pop_back(a2, a4); + m.pop_back(a4); + m.push_back(a4, 30); + + for (unsigned i = 0; i < 20; i++) { + SASSERT(m.get(a2, i) == i+1); + } + TRACE("parray", + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n"; + m.display_info(tout, a3); tout << "\n"; + m.display_info(tout, a4); tout << "\n"; + ); + SASSERT(m.get(a1, 10) == 10); + TRACE("parray", + tout << "after rerooting...\n"; + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n"; + m.display_info(tout, a3); tout << "\n"; + m.display_info(tout, a4); tout << "\n"; + ); + SASSERT(m.size(a1) == 20); + SASSERT(m.size(a2) == 20); + SASSERT(m.size(a3) == 19); + SASSERT(m.size(a4) == 19); + for (unsigned i = 0; i < 20; i++) { + SASSERT(m.get(a1, i) == i); + SASSERT(m.get(a2, i) == i+1); + SASSERT(i >= 18 || m.get(a4, i) == i+1); + SASSERT(i >= 6 || m.get(a3, i) == i+1); + SASSERT(!(6 <= i && i <= 17) || m.get(a3, i) == i); + } + SASSERT(m.get(a4, 18) == 30); + SASSERT(m.get(a3, 18) == 40); + TRACE("parray", + tout << "after many gets...\n"; + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n"; + m.display_info(tout, a3); tout << "\n"; + m.display_info(tout, a4); tout << "\n"; + ); + m.unshare(a1); + TRACE("parray", + tout << "after unshare...\n"; + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n"; + m.display_info(tout, a3); tout << "\n"; + m.display_info(tout, a4); tout << "\n"; + ); + m.reroot(a4); + TRACE("parray", + tout << "after reroot...\n"; + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n"; + m.display_info(tout, a3); tout << "\n"; + m.display_info(tout, a4); tout << "\n"; + ); + m.unshare(a2); + TRACE("parray", + tout << "after second unshare...\n"; + m.display_info(tout, a1); tout << "\n"; + m.display_info(tout, a2); tout << "\n"; + m.display_info(tout, a3); tout << "\n"; + m.display_info(tout, a4); tout << "\n"; + ); + m.del(a1); + m.del(a2); + m.del(a3); + m.del(a4); +} + +#if 0 +// Moved to ast.cpp +struct expr_array_config { + typedef expr * value; + typedef ast_manager value_manager; + typedef small_object_allocator allocator; + static const bool ref_count = true; + static const bool preserve_roots = true; + static const unsigned max_trail_sz = 8; + static const unsigned factor = 2; +}; + +typedef parray_manager expr_array_manager; +typedef expr_array_manager::ref expr_array; + +static void tst4() { + TRACE("parray", tout << "tst4\n";); + ast_manager m; + expr_array_manager m2(m, m.get_allocator()); + + expr_array a1; + expr_array a2; + + expr * v0 = m.mk_var(0, m.mk_bool_sort()); + expr * v1 = m.mk_var(1, m.mk_bool_sort()); + expr * v2 = m.mk_var(2, m.mk_bool_sort()); + expr * v3 = m.mk_var(3, m.mk_bool_sort()); + + m2.push_back(a1, v0); + m2.push_back(a1, v1); + m2.push_back(a1, v2, a2); + m2.push_back(a1, v3); + m2.push_back(a2, v2); + m2.pop_back(a1); + TRACE("parray", + m2.display_info(tout, a1); tout << "\n"; + m2.display_info(tout, a2); tout << "\n"; + ); + m2.reroot(a1); + TRACE("parray", + m2.display_info(tout, a1); tout << "\n"; + m2.display_info(tout, a2); tout << "\n"; + ); + m2.del(a1); + m2.del(a2); +} +#endif + +static void tst5() { + ast_manager m; + expr_array a1; + expr_array a2; + + m.mk(a1); + for (unsigned i = 0; i < 100; i++) { + m.push_back(a1, m.mk_var(i, m.mk_bool_sort())); + } + + unsigned long long mem = memory::get_max_used_memory(); + std::cout << "max. heap size: " << static_cast(mem)/static_cast(1024*1024) << " Mbytes\n"; + + m.copy(a1, a2); + + for (unsigned i = 0; i < 1000000; i++) { + m.set(a1, i % 100, m.mk_var(rand() % 100, m.mk_bool_sort())); + } + + mem = memory::get_max_used_memory(); + std::cout << "max. heap size: " << static_cast(mem)/static_cast(1024*1024) << " Mbytes\n"; + + m.del(a2); + m.del(a1); +} + +void tst_parray() { + // enable_trace("parray_mem"); + tst1(); + tst2(); + tst3(); + tst1(); + tst2(); + tst3(); + // tst4(); + tst5(); +} diff --git a/test/permutation.cpp b/test/permutation.cpp new file mode 100644 index 000000000..0fa3fcaff --- /dev/null +++ b/test/permutation.cpp @@ -0,0 +1,84 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + permutation.cpp + +Abstract: + + Simple abstraction for managing permutations. + +Author: + + Leonardo de Moura (leonardo) 2012-01-04 + +Revision History: + +--*/ +#include"permutation.h" +#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]]; + } +} + +static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) { + unsigned_vector data; + unsigned_vector p; + unsigned_vector new_data; + data.resize(sz); + p.resize(sz); + new_data.resize(sz); + random_gen g; + for (unsigned i = 0; i < sz; i++) + p[i] = i; + // fill data with random numbers + for (unsigned i = 0; i < sz; i++) + data[i] = g() % max; + for (unsigned k = 0; k < num_tries; k ++) { + shuffle(p.size(), p.c_ptr(), g); + // std::cout << "p: "; display(std::cout, p.begin(), p.end()); std::cout << "\n"; + // std::cout << "data: "; display(std::cout, data.begin(), data.end()); std::cout << "\n"; + apply_permutation_copy(sz, data.c_ptr(), p.c_ptr(), new_data.c_ptr()); + apply_permutation(sz, data.c_ptr(), p.c_ptr()); + // std::cout << "data: "; display(std::cout, data.begin(), data.end()); std::cout << "\n"; + for (unsigned i = 0; i < 0; i++) + SASSERT(data[i] == new_data[i]); + } +} + +void tst_permutation() { + tst1(10, 1000, 5); + tst1(10, 1000, 1000); + tst1(10, 1000, UINT_MAX); + tst1(100, 1000, 33); + tst1(100, 1000, 1000); + tst1(100, 1000, UINT_MAX); + tst1(1000, 1000, 121); + tst1(1000, 1000, 1000); + tst1(1000, 1000, UINT_MAX); + tst1(33, 1000, 121); + tst1(33, 1000, 1000); + tst1(33, 1000, UINT_MAX); + tst1(121, 1000, 121); + tst1(121, 1000, 1000); + tst1(121, 1000, UINT_MAX); + for (unsigned i = 0; i < 1000; i++) { + tst1(1000, 2, 333); + tst1(1000, 2, 10000); + tst1(1000, 2, UINT_MAX); + } + random_gen g; + for (unsigned i = 0; i < 100000; i++) { + unsigned sz = (g() % 131) + 1; + tst1(sz, 1, sz*2); + tst1(sz, 1, UINT_MAX); + tst1(sz, 1, sz/2 + 1); + } +} diff --git a/test/polynomial.cpp b/test/polynomial.cpp new file mode 100644 index 000000000..d5e20edd2 --- /dev/null +++ b/test/polynomial.cpp @@ -0,0 +1,1850 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + polynomial.cpp + +Abstract: + + Goodies for creating and handling polynomials. + +Author: + + Leonardo (leonardo) 2011-11-15 + +Notes: + +--*/ +#include"polynomial.h" +#include"polynomial_factorization.h" +#include"polynomial_var2value.h" +#include"polynomial_cache.h" +#include"linear_eq_solver.h" + +static void tst1() { + std::cout << "\n----- Basic testing -------\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + std::cout << x0 << " " << x1 << " " << x2 << "\n"; + polynomial_ref p(m); + p = (x0^3) + x1*x0 + 2; + std::cout << p << "\n"; + std::cout << "max_var(p): " << max_var(p) << "\n"; + SASSERT(max_var(p) == 1); + std::cout << (2*x2 - x1*x0) << "\n"; + std::cout << (p + (2*x2 - x1*x0)) << "\n"; + std::cout << (p*p + 2*x2) << "\n"; + std::cout << derivative(p*p + 2*x2, 0) << "\n"; + polynomial_ref q(m); + q = (x0^4) + x0 + 1; + std::cout << "q(x): " << q << "\n"; + std::cout << "q(y): " << compose_y(q, 2) << "\n"; + std::cout << "q(x-y): " << compose_x_minus_y(q, 2) << "\n"; + q = (x0 - 1)*(x0 - 2)*(x0 - 1)*(x0 + 2); + std::cout << "q: " << q << "\n"; + polynomial_ref s(m); + s = (x0 - 1)*((x0 + 3)^2); + std::cout << "s: " << s << "\n"; +} + +static void tst_pseudo_div(polynomial_ref const & A, polynomial_ref const & B, polynomial::var x) { + polynomial::manager & m = A.m(); + std::cout << "---- Pseudo-division test ----\n"; + std::cout << "A: " << A << "\n"; + std::cout << "B: " << B << "\n"; + std::cout << "x: " << x << "\n"; + polynomial_ref Q(m); + polynomial_ref R(m); + unsigned d; + Q = pseudo_division(A, B, x, d, R); + std::cout << "d: " << d << "\n"; + std::cout << "Q: " << Q << "\n"; + std::cout << "R: " << R << "\n"; + polynomial_ref l_B(m); + l_B = coeff(B, x, degree(B, x)); + std::cout << "l_B: " << l_B << "\n"; + polynomial_ref l_B_d(m); + l_B_d = l_B^d; + polynomial_ref t(m); + std::cout << "l_B^d: " << l_B_d << "\n"; + std::cout << "Q * B + R: " << Q * B + R << "\n"; + std::cout << "l_B_d * A: " << l_B_d * A << "\n"; + SASSERT(eq((Q * B + R), (l_B_d * A))); +} + +static void tst2() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q(m); + p = ((x0 - 1)^2)*x2 + (x1^2)*((x2 - 2)^2) + 1; + q = (x0 - 1)*x2 + (x1^3)*(x2 - 2) + (x0 - 2)*(x1 - 2) + 10; + tst_pseudo_div(p, q, 0); +} + + +static void tst3() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q(m); + p = (x1^2) + (x0^2) - 1; + q = (x1*x0) - 1; + tst_pseudo_div(p, q, 1); +} + +static void tst4() { + std::cout << "---- Testing renaming/reordering ----\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + polynomial_ref p1 = x2 + ((x0 - 1)^2)*x1 + (x2^3) + 10; + polynomial_ref p2 = x0*x1*x2 + x1*(x2^3) + ((x0 - 2)^2); + std::cout << "p1: " << p1 << "\n"; + std::cout << "p2: " << p2 << "\n"; + polynomial::var new_order[3] = { 2, 0, 1 }; + m.rename(3, new_order); + std::cout << "----- x0 -> x2, x1 -> x0, x2 -> x1 \n"; + std::cout << "p1: " << p1 << "\n"; + std::cout << "p2: " << p2 << "\n"; +} + +static void tst_quasi_resultant(polynomial_ref const & p, polynomial_ref const & q, polynomial::var x) { + std::cout << "---- Testing quasi-resultants ---- \n"; + std::cout << "p : " << p << "\n"; + std::cout << "q : " << q << "\n"; + std::cout << "x : " << x << "\n--->\n"; + std::cout << quasi_resultant(p, q, x) << "\n"; +} + +static void tst5() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q(m); + p = ((x0 - x1)^2) - 2; + q = (x1^2) - 3; + // sqrt(2) + sqrt(3) must be a root of the quasi-resultant + tst_quasi_resultant(p, q, 1); +} + +static void tst6() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q(m); + p = (x0 - 2)*(x0 - 3)*(x0 + 2); + std::cout << "p(x0): " << p << "\n"; + std::cout << "p(-x0): " << compose_minus_x(p) << "\n"; + std::cout << "x^3*p(1/x0): " << compose_1_div_x(p) << "\n"; + std::cout << "p(x0 - x1): " << compose_x_minus_y(p, 1) << "\n"; + std::cout << "x1^3*p(x0/x1): " << compose_x_div_y(p, 1) << "\n"; +} + +static void tst7() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q1(m); + polynomial_ref q2(m); + p = (x0 - x1)*(x2 - 1); + q1 = (x0^2) - 2; + q2 = (x1^2) - 2; + polynomial_ref r(m); + r = quasi_resultant(p, q1, 0); + std::cout << "1) r: " << r << "\n"; + r = quasi_resultant(r, q2, 1); + std::cout << "2) r: " << r << "\n"; +} + +static void tst8() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref sqrt2(m); + polynomial_ref sqrt3(m); + p = x2 - (x0*x1 - (x0^2) + 1); + sqrt3 = (x0^2) - 3; + sqrt2 = (x1^2) - 2; + polynomial_ref r(m); + r = quasi_resultant(p, sqrt2, 1); + r = quasi_resultant(r, sqrt3, 0); + std::cout << "r: " << r << "\n"; +} + + +static void tst9() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref sqrt2(m); + p = ((x0^3) - 1)*(x1^2) - 1; + sqrt2 = ((x0^2) - 2)*(x0 - 2); // added garbage to polynomial + // sqrt2 = (x0^2) - 2; // added garbage to polynomial + // p(sqrt(2), x1) has the roots -0.7395 and 0.7395 + polynomial_ref r(m); + r = quasi_resultant(p, sqrt2, 0); + std::cout << "p: " << p << "\n"; + std::cout << "sqrt2: " << sqrt2 << "\n"; + std::cout << "r: " << r << "\n"; + // r contains the roots -0.7395 and 0.7395, plus garbage roots: 0, -0.3779, 0.3779 + polynomial_ref q(m); + q = x2 - (((x0^3) - 1)*(x1^2) - 1); + std::cout << "q: " << q << "\n"; + polynomial_ref r2(m); + TRACE("polynomial", tout << "QUASI_RESULTANT: q, sqrt2.....\n";); + r2 = quasi_resultant(q, sqrt2, 0); + // TRACE("polynomial", tout << "QUASI_RESULTANT: sqrt2, q.....\n";); + // std::cout << "r2: " << r2 << "\n"; + // r2 = quasi_resultant(sqrt2, q, 0); + // std::cout << "r2: " << r2 << "\n"; + // return; + std::cout << "r2: " << r2 << "\n"; + r2 = normalize(quasi_resultant(r2, r, 1)); + std::cout << "r2: " << r2 << "\n"; + polynomial_ref_vector seq(m); + r2 = normalize(quasi_resultant(sqrt2, q, 0)); + // sturm_seq(r2, seq); + std::cout << "r2:\n" << r2 << "\n"; +} + +static void tst10() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + polynomial_ref A(m); + polynomial_ref B(m); + polynomial_ref g(m); + polynomial_ref h(m); + polynomial_ref R(m); + A = x2 - (((x0^3) - 1)*(x1^2) - 1); + B = ((x0^2) - 2)*(x0 - 2); + std::cout << "A: " << A << "\nB: " << B << "\n"; + unsigned d; + R = pseudo_remainder(A, B, 0, d); + std::cout << "R: " << R << "\n"; + // second iteration + std::cout << "second iteration...\n"; + A = B; + B = R; + g = coeff(A, 0, degree(A, 0)); + std::cout << "A: " << A << "\nB: " << B << "\ng: " << g << "\n"; + R = pseudo_remainder(A, B, 0, d); + std::cout << "R: " << R << "\n"; + // third iteration + std::cout << "third iteration...\n"; + A = B; + B = R; + g = coeff(A, 0, degree(A, 0)); + std::cout << "A: " << A << "\nB: " << B << "\ng: " << g << "\n"; + R = pseudo_remainder(A, B, 0, d); + std::cout << "R: " << R << "\n"; + +} + +static void tst11() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q(m); + q = ((x1^2) + 1)*(x2 + 1); + p = (x3 + 1)*q; + polynomial_ref d(m); + d = exact_div(p, q); + std::cout << "p: " << p << "\nq: " << q << "\nd: " << d << "\n"; + SASSERT(eq(q * d, p)); + + q = ((x1^3) + x1 + 1)*((x2^2) + x2 + x2 + 1)*((x3^2) + 2); + p = (x1 + (x3^2) + x3 + x2 + (x2^2) + 1)*((x1^3) + x1 + 1)*((x2^2) + x2 + x2 + 1)*((x3^2) + 2); + d = exact_div(p, q); + std::cout << "p: " << p << "\nq: " << q << "\nd: " << d << "\n"; + SASSERT(eq(q * d, p)); +} + +static void tst_discriminant(polynomial_ref const & p, polynomial::var x, polynomial_ref const & expected) { + polynomial::manager & m = p.m(); + polynomial_ref r(m); + r = discriminant(p, x); + std::cout << "r: " << r << "\n"; + std::cout << "expected: " << expected << "\n"; + SASSERT(eq(r, expected)); + m.lex_sort(r); + std::cout << "r (sorted): " << r << "\n"; +} + +static void tst_discriminant(polynomial_ref const & p, polynomial_ref const & expected) { + tst_discriminant(p, max_var(p), expected); +} + +static void tst_discriminant() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref a(m); + polynomial_ref b(m); + polynomial_ref c(m); + polynomial_ref d(m); + polynomial_ref x(m); + a = m.mk_polynomial(m.mk_var()); + b = m.mk_polynomial(m.mk_var()); + c = m.mk_polynomial(m.mk_var()); + d = m.mk_polynomial(m.mk_var()); + x = m.mk_polynomial(m.mk_var()); + tst_discriminant(a*(x^2) + b*x + c, + (b^2) - 4*a*c); + tst_discriminant(a*(x^3) + b*(x^2) + c*x + d, + (b^2)*(c^2) - 4*a*(c^3) - 4*(b^3)*d + 18*a*b*c*d - 27*(a^2)*(d^2)); + tst_discriminant(a*(x^3) + b*(x^2) + c*(x^2) + d, + -4*(b^3)*d - 12*(b^2)*c*d - 12*b*(c^2)*d - 4*(c^3)*d - 27*(a^2)*(d^2)); + tst_discriminant(a*(x^3) + b*(x^2) + c*(x^2) + d, + -4*(b^3)*d - 12*(b^2)*c*d - 12*b*(c^2)*d - 4*(c^3)*d - 27*(a^2)*(d^2)); + tst_discriminant(a*(x^3) + (b^2)*d*(x^2) + c*(x^2) + d, + -4*(b^6)*(d^4) - 12*(b^4)*c*(d^3) - 12*(b^2)*(c^2)*(d^2) - 4*(c^3)*d - 27*(a^2)*(d^2)); + tst_discriminant(a*(x^4) + b*(x^2) + c, + 16*a*(b^4)*c - 128*(a^2)*(b^2)*(c^2) + 256*(a^3)*(c^3)); + polynomial_ref one(m); + one = m.mk_const(rational(1)); + tst_discriminant(x, one); + tst_discriminant(3*x, one); + polynomial_ref zero(m); + zero = m.mk_zero(); + tst_discriminant(one, zero); + tst_discriminant(a*(x^7) + b, + -823543*(a^6)*(b^6)); + tst_discriminant(((a^2)+(b^2)+c)*(x^4) + (d + a*b)*x + a, + -27*(a^8)*(b^4) - 54*(a^6)*(b^6) - 27*(a^4)*(b^8) - 54*(a^6)*(b^4)*c - 54*(a^4)*(b^6)*c - + 108*(a^7)*(b^3)*d - 216*(a^5)*(b^5)*d - 108*(a^3)*(b^7)*d - 27*(a^4)*(b^4)*(c^2) - + 216*(a^5)*(b^3)*c*d - 216*(a^3)*(b^5)*c*d - 162*(a^6)*(b^2)*(d^2) - 324*(a^4)*(b^4)*(d^2) - + 162*(a^2)*(b^6)*(d^2) + 256*(a^9) + 768*(a^7)*(b^2) + 768*(a^5)*(b^4) + 256*(a^3)*(b^6) - + 108*(a^3)*(b^3)*(c^2)*d - 324*(a^4)*(b^2)*c*(d^2) - 324*(a^2)*(b^4)*c*(d^2) - + 108*(a^5)*b*(d^3) - 216*(a^3)*(b^3)*(d^3) - 108*a*(b^5)*(d^3) + 768*(a^7)*c + + 1536*(a^5)*(b^2)*c + 768*(a^3)*(b^4)*c - 162*(a^2)*(b^2)*(c^2)*(d^2) - 216*(a^3)*b*c*(d^3) - + 216*a*(b^3)*c*(d^3) - 27*(a^4)*(d^4) - 54*(a^2)*(b^2)*(d^4) - 27*(b^4)*(d^4) + 768*(a^5)*(c^2) + + 768*(a^3)*(b^2)*(c^2) - 108*a*b*(c^2)*(d^3) - 54*(a^2)*c*(d^4) - 54*(b^2)*c*(d^4) + + 256*(a^3)*(c^3) - 27*(c^2)*(d^4)); + tst_discriminant((x^5) + a*(x^2) + a, + 108*(a^6) + 3125*(a^4)); + tst_discriminant((x^5) + (a*b)*(x^2) + a, + 108*(a^6)*(b^5) + 3125*(a^4)); + tst_discriminant((x^5) + (a*b*c)*(x^2) + a, + 108*(a^6)*(b^5)*(c^5) + 3125*(a^4)); + tst_discriminant((x^5) + (a*b*c + d)*(x^2) + a, + 108*(a^6)*(b^5)*(c^5) + 540*(a^5)*(b^4)*(c^4)*d + 1080*(a^4)*(b^3)*(c^3)*(d^2) + + 1080*(a^3)*(b^2)*(c^2)*(d^3) + 540*(a^2)*b*c*(d^4) + 108*a*(d^5) + 3125*(a^4)); + tst_discriminant((x^4) + a*(x^2) + (a + c)*x + (c^2), + 16*(a^4)*(c^2) - 128*(a^2)*(c^4) + 256*(c^6) - 4*(a^5) - 8*(a^4)*c + 140*(a^3)*(c^2) + + 288*(a^2)*(c^3) + 144*a*(c^4) - 27*(a^4) - 108*(a^3)*c - 162*(a^2)*(c^2) - 108*a*(c^3) - + 27*(c^4)); + tst_discriminant((x^4) + (a + b)*(x^2) + (a + c)*x, + -4*(a^5) - 12*(a^4)*b - 12*(a^3)*(b^2) - 4*(a^2)*(b^3) - 8*(a^4)*c - 24*(a^3)*b*c - + 24*(a^2)*(b^2)*c - 8*a*(b^3)*c - 4*(a^3)*(c^2) - 12*(a^2)*b*(c^2) - 12*a*(b^2)*(c^2) - + 4*(b^3)*(c^2) - 27*(a^4) - 108*(a^3)*c - 162*(a^2)*(c^2) - 108*a*(c^3) - 27*(c^4)); + tst_discriminant((x^4) + (a + c)*x + (c^2), + 256*(c^6) - 27*(a^4) - 108*(a^3)*c - 162*(a^2)*(c^2) - 108*a*(c^3) - 27*(c^4) + ); + tst_discriminant((x^4) + (a + b)*(x^2) + (a + c)*x + (c^2), + 16*(a^4)*(c^2) + 64*(a^3)*b*(c^2) + 96*(a^2)*(b^2)*(c^2) + 64*a*(b^3)*(c^2) + 16*(b^4)*(c^2) - + 128*(a^2)*(c^4) - 256*a*b*(c^4) - 128*(b^2)*(c^4) + 256*(c^6) - 4*(a^5) - 12*(a^4)*b - + 12*(a^3)*(b^2) - 4*(a^2)*(b^3) - 8*(a^4)*c - 24*(a^3)*b*c - 24*(a^2)*(b^2)*c - 8*a*(b^3)*c + + 140*(a^3)*(c^2) + 132*(a^2)*b*(c^2) - 12*a*(b^2)*(c^2) - 4*(b^3)*(c^2) + 288*(a^2)*(c^3) + + 288*a*b*(c^3) + 144*a*(c^4) + 144*b*(c^4) - 27*(a^4) - 108*(a^3)*c - 162*(a^2)*(c^2) - + 108*a*(c^3) - 27*(c^4)); + tst_discriminant((a + c)*(x^3) + (a + b)*(x^2) + (a + c)*x + (c^2), + -27*(a^2)*(c^4) - 54*a*(c^5) - 27*(c^6) + 14*(a^3)*(c^2) + 6*(a^2)*b*(c^2) - + 12*a*(b^2)*(c^2) - 4*(b^3)*(c^2) + 36*(a^2)*(c^3) + 36*a*b*(c^3) + 18*a*(c^4) + 18*b*(c^4) + - 3*(a^4) + 2*(a^3)*b + (a^2)*(b^2) - 14*(a^3)*c + 4*(a^2)*b*c + 2*a*(b^2)*c - + 23*(a^2)*(c^2) + 2*a*b*(c^2) + (b^2)*(c^2) - 16*a*(c^3) - 4*(c^4)); + tst_discriminant((a^4) - 2*(a^3) + (a^2) - 3*(b^2)*a + 2*(b^4), + max_var(a), + 2048*(b^12) - 4608*(b^10) + 37*(b^8) + 12*(b^6)); + tst_discriminant((a^4) - 2*(a^3) + (a^2) - 3*(b^2)*a + 2*(b^4), + max_var(b), + 2048*(a^12) - 12288*(a^11) + 26112*(a^10) - 22528*(a^9) + 5664*(a^8) + 960*(a^7) + + 32*(a^6)); + tst_discriminant((x^4) + a*(x^2) + b*x + c, + -4*(a^3)*(b^2) + 16*(a^4)*c - 27*(b^4) + 144*a*(b^2)*c - 128*(a^2)*(c^2) + 256*(c^3)); + tst_discriminant((((a-1)^2) + a*b + ((b-1)^2) - 1)*(x^3) + (a*b)*(x^2) + ((a^2) - (b^2))*x + c*a, + -4*(a^8) - 4*(a^7)*b + 9*(a^6)*(b^2) + 12*(a^5)*(b^3) - 2*(a^4)*(b^4) - 12*(a^3)*(b^5) - + 7*(a^2)*(b^6) + 4*a*(b^7) + 4*(b^8) + 18*(a^6)*b*c + 18*(a^5)*(b^2)*c - 4*(a^4)*(b^3)*c - + 18*(a^3)*(b^4)*c - 18*(a^2)*(b^5)*c - 27*(a^6)*(c^2) - 54*(a^5)*b*(c^2) - 81*(a^4)*(b^2)*(c^2) + - 54*(a^3)*(b^3)*(c^2) - 27*(a^2)*(b^4)*(c^2) + 8*(a^7) + 8*(a^6)*b - 24*(a^5)*(b^2) - + 24*(a^4)*(b^3) + 24*(a^3)*(b^4) + 24*(a^2)*(b^5) - 8*a*(b^6) - 8*(b^7) - 36*(a^5)*b*c - + 36*(a^4)*(b^2)*c + 36*(a^3)*(b^3)*c + 36*(a^2)*(b^4)*c + 108*(a^5)*(c^2) + 216*(a^4)*b*(c^2) + + 216*(a^3)*(b^2)*(c^2) + 108*(a^2)*(b^3)*(c^2) - 4*(a^6) + 12*(a^4)*(b^2) - 12*(a^2)*(b^4) + + 4*(b^6) + 18*(a^4)*b*c - 18*(a^2)*(b^3)*c - 162*(a^4)*(c^2) - 270*(a^3)*b*(c^2) - + 162*(a^2)*(b^2)*(c^2) + 108*(a^3)*(c^2) + 108*(a^2)*b*(c^2) - 27*(a^2)*(c^2)); +} + +static void tst_resultant(polynomial_ref const & p, polynomial_ref const & q, polynomial::var x, polynomial_ref const & expected) { + polynomial::manager & m = p.m(); + polynomial_ref r(m); + std::cout << "----------------\n"; + std::cout << "p: " << p << "\n"; + std::cout << "q: " << q << std::endl; + r = resultant(p, q, x); + std::cout << "r: " << r << "\n"; + std::cout << "expected: " << expected << "\n"; + if (degree(p, x) > 0 && degree(q, x) > 0) + std::cout << "quasi-resultant: " << quasi_resultant(p, q, x) << "\n"; + SASSERT(eq(r, expected)); + m.lex_sort(r); + std::cout << "r (sorted): " << r << "\n"; +} + +static void tst_resultant(polynomial_ref const & p, polynomial_ref const & q, polynomial_ref const & expected) { + tst_resultant(p, q, max_var(p), expected); +} + +static void tst_resultant() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref a(m); + polynomial_ref b(m); + polynomial_ref c(m); + polynomial_ref d(m); + polynomial_ref x(m); + a = m.mk_polynomial(m.mk_var()); + b = m.mk_polynomial(m.mk_var()); + c = m.mk_polynomial(m.mk_var()); + d = m.mk_polynomial(m.mk_var()); + x = m.mk_polynomial(m.mk_var()); + + tst_resultant((((a-1)^2) + a*b + ((b-1)^2) - 1)*(x^3) + (a*b)*(x^2) + ((a^2) - (b^2))*x + c*a, + a*b*(x^2) - (a^2) - (b^2), + -4*(a^9)*b - (a^10) - 9*(a^8)*(b^2) - 11*(a^7)*(b^3) - 14*(a^6)*(b^4) - 10*(a^5)*(b^5) - + 10*(a^4)*(b^6) - 3*(a^3)*(b^7) - 5*(a^2)*(b^8) - (b^10) + 2*(a^6)*(b^3)*c + 2*(a^4)*(b^5)*c + + (a^5)*(b^3)*(c^2) + 4*(a^9) + 12*(a^8)*b + 24*(a^7)*(b^2) + 32*(a^6)*(b^3) + 40*(a^5)*(b^4) + + 32*(a^4)*(b^5) + 24*(a^3)*(b^6) + 16*(a^2)*(b^7) + 4*a*(b^8) + 4*(b^9) - 6*(a^8) - + 12*(a^7)*b - 24*(a^6)*(b^2) - 32*(a^5)*(b^3) - 36*(a^4)*(b^4) - 28*(a^3)*(b^5) - + 24*(a^2)*(b^6) - 8*a*(b^7) - 6*(b^8) + 4*(a^7) + 4*(a^6)*b + 12*(a^5)*(b^2) + 12*(a^4)*(b^3) + + 12*(a^3)*(b^4) + 12*(a^2)*(b^5) + 4*a*(b^6) + 4*(b^7) - (a^6) - 3*(a^4)*(b^2) - + 3*(a^2)*(b^4) - (b^6)); + + + tst_resultant(a*(x^5) + b, + c*x + d, + a*(d^5) - b*(c^5)); + tst_resultant(a*(x^5) + 3*(c + d)*(x^2) + 2*b, + c*x + d, + -2*b*(c^5) - 3*(c^4)*(d^2) - 3*(c^3)*(d^3) + a*(d^5)); + tst_resultant(c*x + d, + a*(x^5) + 3*(c + d)*(x^2) + 2*b, + 2*b*(c^5) + 3*(c^4)*(d^2) + 3*(c^3)*(d^3) - a*(d^5)); + tst_resultant((x^2) - (a^3)*(x^2) + b + 1, + -49*(x^10) + 21*(x^8) + 5*(x^6) - (x^4), + (a^18)*(b^4) + 4*(a^18)*(b^3) + 6*(a^18)*(b^2) - 10*(a^15)*(b^5) + 4*(a^18)*b - + 56*(a^15)*(b^4) + (a^18) - 124*(a^15)*(b^3) - 17*(a^12)*(b^6) - 136*(a^15)*(b^2) - + 52*(a^12)*(b^5) - 74*(a^15)*b + 10*(a^12)*(b^4) + 308*(a^9)*(b^7) - 16*(a^15) + + 220*(a^12)*(b^3) + 2224*(a^9)*(b^6) + 335*(a^12)*(b^2) + 6776*(a^9)*(b^5) - 49*(a^6)*(b^8) + + 208*(a^12)*b + 11280*(a^9)*(b^4) - 1316*(a^6)*(b^7) + 48*(a^12) + 11060*(a^9)*(b^3) - + 7942*(a^6)*(b^6) - 2058*(a^3)*(b^9) + 6368*(a^9)*(b^2) - 22660*(a^6)*(b^5) - + 18424*(a^3)*(b^8) + 1984*(a^9)*b - 36785*(a^6)*(b^4) - 72380*(a^3)*(b^7) + 2401*(b^10) + + 256*(a^9) - 36064*(a^6)*(b^3) - 163592*(a^3)*(b^6) + 26068*(b^9) - 21216*(a^6)*(b^2) - + 234058*(a^3)*(b^5) + 126518*(b^8) - 6912*(a^6)*b - 219344*(a^3)*(b^4) + 361508*(b^7) - + 960*(a^6) - 134208*(a^3)*(b^3) + 673537*(b^6) - 51456*(a^3)*(b^2) + 855056*(b^5) - + 11136*(a^3)*b + 749104*(b^4) - 1024*(a^3) + 447232*(b^3) + 174144*(b^2) + 39936*b + 4096); + tst_resultant(((a - x)^2) + 2, + (x^5) - x - 1, + (a^10) + 10*(a^8) + 38*(a^6) - 2*(a^5) + 100*(a^4) + 40*(a^3) + 121*(a^2) - 38*a + 19); + tst_resultant(c - (((a^3) - 1)*(b^2) - 1), + ((a^2) - 2)*(a - 2), + max_var(a), + -49*(b^6) + 21*(b^4)*c + 21*(b^4) + 5*(b^2)*(c^2) + 10*(b^2)*c - (c^3) + 5*(b^2) - 3*(c^2) - 3*c - 1); + tst_resultant(-49*(b^6) + 21*(b^4)*c + 21*(b^4) + 5*(b^2)*(c^2) + 10*(b^2)*c - (c^3) + 5*(b^2) - 3*(c^2) - 3*c - 1, + (7*(b^4) - 2*(b^2) - 1), + max_var(b), + 117649*(c^12) + 1075648*(c^11) + 1651888*(c^10) - 12293120*(c^9) - 46560192*(c^8) + - 9834496*(c^7) + 186855424*(c^6) + 314703872*(c^5) + 157351936*(c^4)); + tst_resultant(144*(b^2) + 96*(a^2)*b + 9*(a^4) + 105*(a^2) + 70*a - 98, + a*(b^2) + 6*a*b + (a^3) + 9*a, + max_var(b), + 81*(a^10) + 3330*(a^8) + 1260*(a^7) - 37395*(a^6) - 45780*(a^5) - 32096*(a^4) + + 167720*(a^3) + 1435204*(a^2)); + tst_resultant(144*(b^2) + 96*(a^2)*b + 9*(a^4) + 105*(a^2) + 70*a - 98, + a*(b^2) + 6*a*b + (a^3) + 9*a, + max_var(a), + 11664*(b^10) + 31104*(b^9) - 119394*(b^8) - 1550448*(b^7) - 2167524*(b^6) + + 7622712*(b^5) + 46082070*(b^4) + 46959720*(b^3) - 9774152*(b^2) - 35007168*b - + 13984208); + polynomial_ref n1(m); + polynomial_ref n2(m); + polynomial_ref one(m); + n1 = m.mk_const(rational(10)); + n2 = m.mk_const(rational(100)); + one = m.mk_const(rational(1)); + tst_resultant(n1, (x^2) + 2*x + 1, max_var(x), n2); + tst_resultant(n1, 2*x + 1, max_var(x), n1); + tst_resultant(n1, n2, 0, one); + tst_resultant((x^2) + 2*x + 1, n1, max_var(x), n2); + tst_resultant(2*x + 1, n1, max_var(x), n1); + tst_resultant((x^2) + 8*x + 1, n1, max_var(x), n2); +} + +static void tst_compose() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + p = (x0^3) - x0 + 3; + std::cout << "p: " << p << "\np(x - y): " << compose_x_minus_y(p, 1) + << "\np(x + y): " << compose_x_plus_y(p, 1) << "\np(x - x): " << compose_x_minus_y(p, 0) << "\np(x + x): " << compose_x_plus_y(p, 0) << "\n"; + SASSERT(eq(compose_x_minus_y(p, 1), (x0^3) - 3*(x0^2)*x1 + 3*x0*(x1^2) - (x1^3) - x0 + x1 + 3)); + SASSERT(eq(compose_x_plus_y(p, 1), (x0^3) + 3*(x0^2)*x1 + 3*x0*(x1^2) + (x1^3) - x0 - x1 + 3)); +} + +void tst_prem() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + polynomial_ref y(m); + x = m.mk_polynomial(m.mk_var()); + y = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q(m); + p = (x^2) - 2; + q = y*(x^3); + std::cout << "p: " << p << "\n"; + std::cout << "q: " << q << "\n"; + // unsigned d; + std::cout << "srem: " << exact_pseudo_remainder(q, p, 0) << "\n"; +} + +void tst_sqrt() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + polynomial_ref y(m); + x = m.mk_polynomial(m.mk_var()); + y = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + p = (4*x*y + 3*(x^2)*y + (y^2) + 3)^4; + polynomial_ref q(m); + VERIFY(sqrt(p, q)); + SASSERT(eq(p, q*q)); + std::cout << "p: " << p << "\n"; + std::cout << "q: " << q << "\n"; + p = p - 1; + SASSERT(!sqrt(p, q)); +} + +static void tst_content(polynomial_ref const & p, polynomial::var x, polynomial_ref const & expected) { + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + std::cout << "content(p): " << content(p, x) << std::endl; + std::cout << "expected: " << expected << std::endl; + SASSERT(eq(content(p, x), expected)); +} + +static void tst_primitive(polynomial_ref const & p, polynomial::var x, polynomial_ref const & expected) { + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + std::cout << "primitive(p): " << primitive(p, x) << std::endl; + std::cout << "expected: " << expected << std::endl; + SASSERT(eq(primitive(p, x), expected)); +} + +static void tst_gcd(polynomial_ref const & p, polynomial_ref const & q, polynomial_ref const & expected) { + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + std::cout << "q: " << q << std::endl; + polynomial_ref r(p.m()); + r = gcd(p, q); + std::cout << "gcd(p, q): " << r << std::endl; + std::cout << "expected: " << expected << std::endl; + SASSERT(eq(r, expected)); +} + +static void tst_gcd() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + polynomial_ref three(m); + three = m.mk_const(mpz(3)); + + std::cout << "tst_gcd\n======================\n"; + + tst_gcd(((x0^2) + x0*x1 + 1)*(x2*x2 + x3 + 2)*(x3*x1 + 2)*(x3*x1*x1 + x1*x2 + 1), + ((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)*(x3*x1 + x1*x2 + 17), + ((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)); + + tst_gcd((-1)*((x0^2) + x0*x1 + 1)*(x2*x2 + x3 + 2)*(x3*x1 + 2)*(x3*x1*x1 + x1*x2 + 1), + ((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)*(x3*x1 + x1*x2 + 17), + ((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)); + + tst_gcd(((x0^2) + x0*x1 + 1)*(x2*x2 + x3 + 2)*(x3*x1 + 2)*(x3*x1*x1 + x1*x2 + 1), + (-1)*((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)*(x3*x1 + x1*x2 + 17), + ((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)); + + tst_gcd((-1)*((x0^2) + x0*x1 + 1)*(x2*x2 + x3 + 2)*(x3*x1 + 2)*(x3*x1*x1 + x1*x2 + 1), + (-1)*((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)*(x3*x1 + x1*x2 + 17), + ((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)); + + tst_gcd(21*(x0 + 1), 6*x0^2, three); + tst_content(x0*x1 + x0, 1, x0); + tst_primitive(x0*x1 + x0, 1, x1 + 1); + tst_primitive((x1^2) + x0*x1 + x0, 1, (x1^2) + x0*x1 + x0); + tst_primitive((x0 + 1)*(2*x1) + 1, 1, (x0 + 1)*(2*x1) + 1); + tst_primitive((x0 + 1)*(2*x1) + (x0^2)*(x0 + 1), 1, 2*x1 + (x0^2)); + tst_primitive((x0 + 1)*(x2 + 1)*(x2^2)*(x0 + 1)*(x1^2) + (x0 + 1)*(x2^2)*x1 + (x0+1)*(x0+1), 1, + (x2 + 1)*(x2^2)*(x0 + 1)*(x1^2) + (x2^2)*x1 + (x0+1)); + tst_primitive((x0 + (x3^2))*(x2 + x3 + 1)*(x2^2)*(x1^2) + + (x0 + (x3^2))*(x2 + x3 + 1)*x1 + + (x0 + (x3^2))*(x2 + x3 + 1)*(x3^2), + 1, + (x2^2)*(x1^2) + x1 + (x3^2)); + tst_content((x0 + (x3^2))*(x2 + x3 + 1)*(x2^2)*(x1^2) + + (x0 + (x3^2))*(x2 + x3 + 1)*x1 + + (x0 + (x3^2))*(x2 + x3 + 1)*(x3^2), + 1, + (x0 + (x3^2))*(x2 + x3 + 1)); + tst_primitive(4*(x0 + (x3^2))*(x2 + x3 + 1)*(x2^2)*(x1^2) + + 2*(x0 + (x3^2))*(x2 + x3 + 1)*x1 + + 4*(x0 + (x3^2))*(x2 + x3 + 1)*(x3^2), + 1, + 2*(x2^2)*(x1^2) + x1 + 2*(x3^2)); + tst_gcd(63*((x0^2) + x0*x1 + 1)*(x2*x2 + x3 + 2)*(x3*x1 + 2)*(x3*x1*x1 + x1*x2 + 1), + 14*((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)*(x3*x1 + x1*x2 + 17), + 7*((x0^2) + x0*x1 + 1)*(x3*x1*x1 + x1*x2 + 1)); +} + +static void tst_psc(polynomial_ref const & p, polynomial_ref const & q, polynomial::var x, polynomial_ref const & first, polynomial_ref const & second) { + polynomial::manager & m = p.m(); + polynomial_ref_vector S(m); + std::cout << "---------" << std::endl; + std::cout << "p: " << p << std::endl; + std::cout << "q: " << q << std::endl; + m.psc_chain(p, q, x, S); + unsigned sz = S.size(); + for (unsigned i = 0; i < sz; i++) { + std::cout << "S_" << i << ": " << polynomial_ref(S.get(i), m) << std::endl; + } + if (sz > 0) { + SASSERT(m.eq(S.get(0), first) || m.eq(S.get(0), neg(first))); + } + if (sz > 1) { + SASSERT(m.eq(S.get(1), second) || m.eq(S.get(1), neg(second))); + } + if (sz > 0) { + polynomial_ref Res(m); + Res = resultant(p, q, x); + SASSERT(m.eq(Res, S.get(0)) || m.eq(S.get(0), neg(Res))); + } +} + +static void tst_psc_perf(polynomial_ref const & p, polynomial_ref const & q, polynomial::var x) { + polynomial::manager & m = p.m(); + polynomial_ref_vector S(m); + std::cout << "---------" << std::endl; + std::cout << "p: " << p << std::endl; + std::cout << "q: " << q << std::endl; + m.psc_chain(p, q, x, S); + unsigned sz = S.size(); + for (unsigned i = 0; i < sz; i++) { + std::cout << "S_" << i << ": " << m.size(S.get(i)) << std::endl; // polynomial_ref(S.get(i), m) << std::endl; + } +} + +static void tst_psc() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + polynomial_ref x4(m); + polynomial_ref x5(m), x6(m), x7(m), x8(m), x9(m), x10(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + x4 = m.mk_polynomial(m.mk_var()); + x5 = m.mk_polynomial(m.mk_var()); + x6 = m.mk_polynomial(m.mk_var()); + x7 = m.mk_polynomial(m.mk_var()); + x8 = m.mk_polynomial(m.mk_var()); + x9 = m.mk_polynomial(m.mk_var()); + x10 = m.mk_polynomial(m.mk_var()); + tst_psc(x0*(x1^2) + (x0 + 1)*x1 + 2, x0*x1 + 3, 1, + 6*x0 - (x0^2), x0); + tst_psc(x0*(x1^4) + (x0 + 1)*(x1^3) + 2, x0*(x1^3) + 3, 1, + 72*(x0^3) - (x0^4) - 27*(x0^2) - 27*(x0), 9*(x0^3)); + polynomial_ref & a = x0; + polynomial_ref & b = x1; + polynomial_ref & c = x2; + polynomial_ref & d = x3; + polynomial_ref & e = x4; + polynomial_ref & f = x5; + polynomial_ref & g = x6; + polynomial_ref & h = x7; + polynomial_ref & i = x8; + polynomial_ref & x = x9; + tst_psc((x^4) + a*(x^2) + b*x + c, 4*(x^3) + 2*a*x + b, 9, + 16*(a^4)*c - 4*(a^3)*(b^2) - 128*(a^2)*(c^2) + 144*a*(b^2)*c - 27*(b^4) + 256*(c^3), 8*(a^3) - 32*a*c + 36*(b^2)); + polynomial_ref & y = x10; + + tst_psc(((y^2) + 6)*(x - 1) - y*((x^2) + 1), ((x^2) + 6)*(y - 1) - x*((y^2) + 1), 10, + 2*(x^6) - 22*(x^5) + 102*(x^4) - 274*(x^3) + 488*(x^2) - 552*x + 288, + 5*x - (x^2) - 6 + ); + + tst_psc(((y^3) + 6)*(x - 1) - y*((x^3) + 1), ((x^3) + 6)*(y - 1) - x*((y^3) + 1), 10, + 3*(x^11) - 3*(x^10) - 37*(x^9) + 99*(x^8) + 51*(x^7) - 621*(x^6) + 1089*(x^5) - 39*(x^4) - 3106*(x^3) + 5868*(x^2) - 4968*x + 1728, + (x^6) - 10*(x^4) + 12*(x^3) + 25*(x^2) - 60*x + 36); + + polynomial_ref p = (x^6) + a * (x^3) + b; + polynomial_ref q = (x^6) + c * (x^3) + d; + + tst_psc(p, q, 9, + (b^6) - 3*a*(b^5)*c + 3*(a^2)*(b^4)*(c^2) + 3*(b^5)*(c^2) - (a^3)*(b^3)*(c^3) - + 6*a*(b^4)*(c^3) + 3*(a^2)*(b^3)*(c^4) + 3*(b^4)*(c^4) - 3*a*(b^3)*(c^5) + (b^3)*(c^6) + + 3*(a^2)*(b^4)*d - 6*(b^5)*d - 6*(a^3)*(b^3)*c*d + 9*a*(b^4)*c*d + + 3*(a^4)*(b^2)*(c^2)*d + 6*(a^2)*(b^3)*(c^2)*d - 12*(b^4)*(c^2)*d - 9*(a^3)*(b^2)*(c^3)*d + + 6*a*(b^3)*(c^3)*d + 9*(a^2)*(b^2)*(c^4)*d - 6*(b^3)*(c^4)*d - 3*a*(b^2)*(c^5)*d + + 3*(a^4)*(b^2)*(d^2) - 12*(a^2)*(b^3)*(d^2) + 15*(b^4)*(d^2) - 3*(a^5)*b*c*(d^2) + + 6*(a^3)*(b^2)*c*(d^2) - 6*a*(b^3)*c*(d^2) + 9*(a^4)*b*(c^2)*(d^2) - + 18*(a^2)*(b^2)*(c^2)*(d^2) + 18*(b^3)*(c^2)*(d^2) - 9*(a^3)*b*(c^3)*(d^2) + + 6*a*(b^2)*(c^3)*(d^2) + 3*(a^2)*b*(c^4)*(d^2) + 3*(b^2)*(c^4)*(d^2) + (a^6)*(d^3) - + 6*(a^4)*b*(d^3) + 18*(a^2)*(b^2)*(d^3) - 20*(b^3)*(d^3) - 3*(a^5)*c*(d^3) + + 6*(a^3)*b*c*(d^3) - 6*a*(b^2)*c*(d^3) + 3*(a^4)*(c^2)*(d^3) + 6*(a^2)*b*(c^2)*(d^3) - + 12*(b^2)*(c^2)*(d^3) - (a^3)*(c^3)*(d^3) - 6*a*b*(c^3)*(d^3) + 3*(a^4)*(d^4) - + 12*(a^2)*b*(d^4) + 15*(b^2)*(d^4) - 6*(a^3)*c*(d^4) + 9*a*b*c*(d^4) + + 3*(a^2)*(c^2)*(d^4) + 3*b*(c^2)*(d^4) + 3*(a^2)*(d^5) - 6*b*(d^5) - + 3*a*c*(d^5) + (d^6), + 3*(a^2)*c - (a^3) - 3*a*(c^2) + (c^3) + ); + + + tst_psc(x, + a * x + b * c + d - e, + 9, + b*c + d - e, a); + + polynomial_ref zero(m); + zero = m.mk_zero(); + + tst_psc( a*d*x + a*c*f + a*e - b*a, + d*x + c*f + e - b, + 9, zero, zero); + + +#if 0 + tst_psc_perf((x^7) + a*(x^3) + b*(x^2) + c*x + d, + (x^7) + e*(x^3) + f*(x^2) + g*x + h, + 9); + + tst_psc_perf((x^15) + a * (x^10) + b, + (x^15) + c * (x^10) + d, + 9); + + tst_psc_perf((y^5) + a * (y^4) + b * (y^3) + c * (y^2) + d * y + e, + (y^5) + f * (y^4) + g * (y^3) + h * (y^2) + i * y + x, + 10); +#endif +} + +static void tst_vars(polynomial_ref const & p, unsigned sz, polynomial::var * xs) { + polynomial::var_vector r; + p.m().vars(p, r); + std::cout << "---------------\n"; + std::cout << "p: " << p << "\nvars: "; + for (unsigned i = 0; i < r.size(); i++) { + std::cout << r[i] << " "; + } + std::cout << std::endl; + SASSERT(r.size() == sz); + std::sort(r.begin(), r.end()); + std::sort(xs, xs + sz); + for (unsigned i = 0; i < r.size(); i++) { + SASSERT(r[i] == xs[i]); + } +} + +static void tst_vars() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + polynomial_ref x4(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + x4 = m.mk_polynomial(m.mk_var()); + polynomial::var s023[3] = {0, 2, 3}; + polynomial::var s14[2] = {1, 4}; + polynomial::var s012[3] = {0, 1, 2}; + polynomial::var s3[1] = {3}; + polynomial::var s01234[5] = {0, 1, 2, 3, 4}; + + tst_vars((x0 + 1)*((x0^2) + (x3^2))*(x2*x3), 3, s023); + tst_vars((x0 + x2)*((x0^2) + (x3^2))*(x2*x3), 3, s023); + tst_vars(((x1 + x4 + 1)^5), 2, s14); + tst_vars(((x1 + x4*x2 + 1)^4) + x0 + (x3^2), 5, s01234); + tst_vars((x3 + 1)^5, 1, s3); + tst_vars(x0*x1*x2, 3, s012); + tst_vars(x0*x1*x2 + 1, 3, s012); +} + +static void tst_sqf(polynomial_ref const & p, polynomial_ref const & expected) { + polynomial_ref r(p.m()); + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + r = square_free(p); + std::cout << "sqf(p): " << r << std::endl; + std::cout << "expected: " << expected << std::endl; + SASSERT(is_square_free(r)); + SASSERT(!eq(r, p) || is_square_free(p)); + SASSERT(eq(expected, r)); +} + +static void tst_sqf() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + tst_sqf(((x0 + x1)^2)*((x0^2) - 3)*((x2*x2 + x3 + 1)^3), + (x0 + x1)*((x0^2) - 3)*(x2*x2 + x3 + 1)); + tst_sqf((x0 + x1)*(x0 - x1), (x0 + x1)*(x0 - x1)); + tst_sqf(((x0 + x1)^3)*(x0 - x1), (x0 + x1)*(x0 - x1)); + polynomial_ref c1(m); + c1 = m.mk_const(rational(3)); + tst_sqf(c1, c1); + polynomial_ref z(m); + z = m.mk_zero(); + tst_sqf(z, z); + tst_sqf((x0 + x1 + x2 + x3)^5, (x0 + x1 + x2 + x3)); + tst_sqf(((x0 + x1 + x2 + x3)^5) + 1, ((x0 + x1 + x2 + x3)^5) + 1); +} + +static void tst_substitute(polynomial_ref const & p, + polynomial::var x1, mpz const & v1, + polynomial::var x2, mpz const & v2, + polynomial_ref const & expected) { + polynomial::numeral_manager & nm = p.m().m(); + polynomial::var xs[2] = { x1, x2 }; + scoped_mpz_vector vs(nm); + vs.push_back(v1); + vs.push_back(v2); + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + polynomial_ref r(p.m()); + r = p.m().substitute(p, 2, xs, vs.c_ptr()); + std::cout << "r: " << r << std::endl; + std::cout << "expected: " << expected << std::endl; + SASSERT(eq(r, expected)); + p.m().lex_sort(r); + std::cout << "r (sorted): " << r << std::endl; +} + +static void tst_substitute() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + tst_substitute(x0 + x1*x0 + x3, 1, mpz(1), 3, mpz(2), 2*x0 + 2); + tst_substitute((x0^2) + x1*x0 + x3, 0, mpz(2), 3, mpz(2), 2*x1 + 6); + tst_substitute((x0 + x1 + x2)^3, 0, mpz(2), 2, mpz(3), (x1 + 5)^3); + tst_substitute(((x0 + x1 + x2)^3) + ((x0*x1 + x3)^2), 0, mpz(2), 2, mpz(3), ((x1 + 5)^3) + ((2*x1 + x3)^2)); + tst_substitute((x0 + x1 + 1)^5, 2, mpz(2), 3, mpz(3), (x0 + x1 + 1)^5); + polynomial_ref zero(m); + zero = m.mk_zero(); + tst_substitute(zero, 2, mpz(2), 3, mpz(3), zero); +} + +static void tst_qsubstitute(polynomial_ref const & p, + unsynch_mpq_manager & qm, + polynomial::var x1, rational const & v1, + polynomial::var x2, rational const & v2, + polynomial_ref const & expected) { + polynomial::var xs[2] = { x1, x2 }; + scoped_mpq_vector vs(qm); + vs.push_back(v1.to_mpq()); + vs.push_back(v2.to_mpq()); + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + polynomial_ref r(p.m()); + r = p.m().substitute(p, 2, xs, vs.c_ptr()); + std::cout << "r: " << r << std::endl; + std::cout << "expected (modulo a constant): " << expected << std::endl; + SASSERT(eq(r, normalize(expected))); + p.m().lex_sort(r); + std::cout << "r (sorted): " << r << std::endl; +} + +static void tst_qsubstitute() { + unsynch_mpq_manager qm; + polynomial::manager m(qm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + tst_qsubstitute(x0 + x1 + x2, qm, 0, rational(1)/rational(2), 1, rational(3), 2*x2 + 2*3 + 1); + tst_qsubstitute((x0^2)*x2 + x1 + x2*x0, qm, 0, rational(3)/rational(2), 1, rational(3), 9*x2 + (4*3) + (2*3)*x2); + tst_qsubstitute(x0*x1*x2*(x3^2) + (x0^3)*x3 + (x1^2)*x0, qm, + 0, rational(5)/rational(2), + 1, rational(7)/rational(3), + (2*2*3*7*5)*x2*(x3^2) + (5*5*5*3*3)*x3 + (7*7*5*2*2)); + tst_qsubstitute((x2 + x3)^3, qm, + 0, rational(5)/rational(2), + 1, rational(7)/rational(3), + (x2 + x3)^3); + tst_qsubstitute((x0 + x1 + x2 + x3)^3, qm, + 0, rational(5)/rational(2), + 2, rational(7)/rational(3), + (6*x1 + 6*x3 + 15 + 14)^3); + tst_qsubstitute((x0 + 2*x1 + 11*(x2^2)*x3 + x2 + (x3^2))^3, qm, + 0, rational(5)/rational(2), + 3, rational(7)/rational(3), + ((2*3*3*2)*x1 + (11*2*3*7)*(x2^2) + (2*3*3)*x2 + (5*9 + 7*7*2))^3); + polynomial_ref zero(m); + zero = m.mk_zero(); + tst_qsubstitute(zero, qm, + 0, rational(5)/rational(2), + 3, rational(7)/rational(3), + zero); +} + +void tst_mfact(polynomial_ref const & p, unsigned num_distinct_factors) { + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + polynomial::factors fs(p.m()); + factor(p, fs); + std::cout << "factors:\n"; + std::cout << p.m().m().to_string(fs.get_constant()) << "\n"; + for (unsigned i = 0; i < fs.distinct_factors(); i++) { + std::cout << "*(" << fs[i] << ")^" << fs.get_degree(i) << std::endl; + } + SASSERT(fs.distinct_factors() == num_distinct_factors); + polynomial_ref p2(p.m()); + fs.multiply(p2); + SASSERT(eq(p, p2)); +} + +static void tst_mfact() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + polynomial_ref x4(m); + polynomial_ref x5(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + x4 = m.mk_polynomial(m.mk_var()); + x5 = m.mk_polynomial(m.mk_var()); + polynomial_ref & x = x0; + + tst_mfact((x0 - (x1^3))*(x0 - ((x2^3) - 2)), 2); + tst_mfact((((x3^3) + 1)*x0 - (x1^3))*(x0 - ((x2^3) - 2)), 2); + tst_mfact((((x3^3) + 1)*x0 - (x1^3))*((x3 - 1)*x0 - ((x2^3) - 2)), 2); + tst_mfact((((x3^3) + 1)*x0 - (x1^3))*((-1)*x0 - ((x2^3) - 2)), 2); + tst_mfact((-1)*(x0 - (x1^3))*(x0 - ((x2^3) - 2)), 2); + tst_mfact((-1)*(x0 - (x1^3) + (x1^2) + 2)*(x0 - ((x2^3) - 2)), 2); + + tst_mfact(((x0 - (x1^3))*(x0 - ((x2^3) - 2)))^2, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*(x0 - ((x2^3) - 2)))^2, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*((x3 - 1)*x0 - ((x2^3) - 2)))^2, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*((-1)*x0 - ((x2^3) - 2)))^2, 2); + tst_mfact(((-1)*(x0 - (x1^3))*(x0 - ((x2^3) - 2)))^2, 2); + tst_mfact(((-1)*(x0 - (x1^3) + (x1^2) + 2)*(x0 - ((x2^3) - 2)))^2, 2); + + tst_mfact(((x0 - (x1^3))*(x0 - ((x2^3) - 2)))^3, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*(x0 - ((x2^3) - 2)))^3, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*((x3 - 1)*x0 - ((x2^3) - 2)))^3, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*((-1)*x0 - ((x2^3) - 2)))^3, 2); + tst_mfact(((-1)*(x0 - (x1^3))*(x0 - ((x2^3) - 2)))^3, 2); + tst_mfact(((-1)*(x0 - (x1^3) + (x1^2) + 2)*(x0 - ((x2^3) - 2)))^3, 2); + + tst_mfact(((x0 - (x1^3))*(x0 - ((x2^3) - 2)))^4, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*(x0 - ((x2^3) - 2)))^4, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*((x3 - 1)*x0 - ((x2^3) - 2)))^4, 2); + tst_mfact(((((x3^3) + 1)*x0 - (x1^3))*((-1)*x0 - ((x2^3) - 2)))^4, 2); + tst_mfact(((-1)*(x0 - (x1^3))*(x0 - ((x2^3) - 2)))^4, 2); + tst_mfact(((-1)*(x0 - (x1^3) + (x1^2) + 2)*(x0 - ((x2^3) - 2)))^4, 2); + + tst_mfact(((x^5) - (x^2) + 1)*((-1)*x + 1)*((x^2) - 2*x + 3), 3); + tst_mfact(11*((x^5) - (x^2) + 1)*((-1)*x + 1)*((x^2) - 2*x + 3), 3); + tst_mfact(11*(7*(x^5) - (x^2) + 1)*((-1)*(x^2) + 1)*((x^2) - 2*x + 3), 4); + tst_mfact(11*(7*(x^5) - (x^2) + 1)*((-1)*(x^2) + 1)*((x^2) - 2*x + 3)*((x^7) - x +2), 5); + tst_mfact((7*(x^5) - (x^2) + 1)*((-1)*(x^2) + 1)*((x^2) - 2*x + 3)*((x^7) - x +2)*((x^3) - x + 1), 6); + tst_mfact((7*(x^5) - (x^2) + 1)*((-1)*(x^2) + 1)*((x^2) - 2*x + 3)*((x^7) - x +2)*((x^3) - x + 1)*((x^7) - (x^5) + (x^3) + (x^2) + x + 3), 7); + tst_mfact((7*(x^5) - (x^2) + 1)*((-1)*(x^2) + 1)*((x^2) - 2*x + 3)*((x^7) - x +2)* + ((x^3) - x + 1)*((x^7) - (x^5) + (x^3) + (x^2) + x + 3)*(x - (x^3) + 11)* + (x - 10)*(x - 9)*(33*x + 12)*((x^5) - x + 1), + 12); + tst_mfact((x^4) + (x^2) - 20, 3); + tst_mfact((-11)*((x^5) - (x^2) + 1)*((-1)*x + 1)*((x^2) - 2*x + 3), 3); + tst_mfact(x0 - 2*(x0^2) + 1, 2); + tst_mfact((x0 + 1)*(x0 - 1)*(x0 + 2)*(((x1^5) - x1 - 1)^2), 4); + tst_mfact((x0 + 1)*((x1 + 2)^2), 2); + tst_mfact(7*(x0 + 1)*((x1 + 2)^2), 2); + tst_mfact(11*(x0 + 1)*((x1 + 2)^2)*((x1 - x3)^4), 3); + tst_mfact(11*(x0 + 1)*((x1 + 2)^2)*((x1 - x3)^4)*(((x0*(x2^2) + (x0 + x1)*x2 + x1))^3), 5); + tst_mfact((11*(x0 + 1)*((x1 + 2)^2))^3, 2); + tst_mfact((3*(x0 + 1)*(x1 + 2))^3, 2); + tst_mfact((3*(x0 + 1)*(2*x1 + 2))^3, 2); + tst_mfact(3*(2*(x0^2) + 4*(x1^2))*x2, 2); + tst_mfact(13*((x0 - x2)^6)*((x1 - x2)^5)*((x0 - x3)^7), 3); + tst_mfact((x0+1)^100, 1); + tst_mfact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 3); + tst_mfact(((x0^4) - 8*(x0^2)), 2); + tst_mfact((x0^5) - 2*(x0^3) + x0 - 1, 1); + tst_mfact( (x0^25) - 4*(x0^21) - 5*(x0^20) + 6*(x0^17) + 11*(x0^16) + 10*(x0^15) - 4*(x0^13) - 7*(x0^12) - 9*(x0^11) - 10*(x0^10) + + (x0^9) + (x0^8) + (x0^7) + (x0^6) + 3*(x0^5) + x0 - 1, 2); + tst_mfact( (x0^25) - 10*(x0^21) - 10*(x0^20) - 95*(x0^17) - 470*(x0^16) - 585*(x0^15) - 40*(x0^13) - 1280*(x0^12) - 4190*(x0^11) - 3830*(x0^10) + 400*(x0^9)+ 1760*(x0^8) + 760*(x0^7) - 2280*(x0^6) + 449*(x0^5) + 640*(x0^3) - 640*(x0^2) + 240*x0 - 32, 2); + tst_mfact( x0^10, 1); + polynomial_ref c(m); + c = m.mk_zero(); + tst_mfact(c, 0); + c = m.mk_const(mpz(3)); + tst_mfact(c, 0); + tst_mfact(x0, 1); + tst_mfact(x0 + x1, 1); + tst_mfact(x0 - x1, 1); + tst_mfact( (x0^10) - 10*(x0^8) + 38*(x0^6) - 2*(x0^5) - 100*(x0^4) - 40*(x0^3) + 121*(x0^2) - 38*x0 - 17, 1); + tst_mfact( (x0^50) - 10*(x0^40) + 38*(x0^30) - 2*(x0^25) - 100*(x0^20) - 40*(x0^15) + 121*(x0^10) - 38*(x0^5) - 17, 1); + polynomial_ref & y = x0; + tst_mfact( (((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^10) + + 10*(((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^9) + + 35*(((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^8) + + 40*(((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^7) + - 32*(((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^6) + - 82*(((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^5) + - 30*(((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^4) + - 140*(((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^3) + - 284*(((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y)^2) + - 168*((y^5) + 5*(y^4) + 10*(y^3) + 10*(y^2) + 5*y) + - 47, 1); + tst_mfact( (y^4) - 404*(y^2) + 39204, 2); + tst_mfact( ((y^5) - 15552)* + ((y^20)- 15708*(y^15) + rational("138771724")*(y^10)- rational("432104148432")*(y^5) + rational("614198284585616")), + 2); + tst_mfact( (y^25) - + rational("3125")*(y^21) - + rational("15630")*(y^20) + + rational("3888750")*(y^17) + + rational("38684375")*(y^16) + + rational("95765635")*(y^15) - + rational("2489846500")*(y^13) - + rational("37650481875")*(y^12) - + rational("190548065625")*(y^11) - + rational("323785250010")*(y^10) + + rational("750249453025")*(y^9) + + rational("14962295699875")*(y^8) + + rational("111775113235000")*(y^7) + + rational("370399286731250")*(y^6) + + rational("362903064503129")*(y^5) - + rational("2387239013984400")*(y^4) - + rational("23872390139844000")*(y^3) - + rational("119361950699220000")*(y^2) - + rational("298404876748050000")*y - + rational("298500366308609376"), 2); + + tst_mfact( rational("54")*(y^24) - (y^27) - 324*(y^21) + rational("17496")*(y^18) - 34992*(y^15)+ rational("1889568")*(y^12)- 1259712*(y^9) + rational("68024448")*(y^6), 3); + + tst_mfact( ((y^3)- 432)*(((y^3)+54)^2)*((y^6)+108)*((y^6)+6912)*((y^6)- 324*(y^3)+37044), + 5); + + tst_mfact( ((y^6)- 6*(y^4) - 864*(y^3) + 12*(y^2) - 5184*y + 186616)* + (((y^6) - 6*(y^4) + 108*(y^3) + 12*(y^2) + 648*y + 2908)^2)* + ((y^12) - 12*(y^10) + 60*(y^8) + 56*(y^6) + 6720*(y^4) + 12768*(y^2) + 13456)* + ((y^12) - 12*(y^10) + 60*(y^8) + 13664*(y^6) + 414960*(y^4) + 829248*(y^2) + 47886400)* + ((y^12) - 12*(y^10) - 648*(y^9)+ 60*(y^8) + 178904*(y^6) + 15552*(y^5) + 1593024*(y^4) - 24045984*(y^3) + 5704800*(y^2) - 143995968*y + 1372010896), + 5); + + { + polynomial_ref q1(m); + polynomial_ref q2(m); + polynomial_ref q3(m); + polynomial_ref q4(m); + polynomial_ref q5(m); + polynomial_ref p(m); + q1 = (x0^3) - 2; + q2 = (x1^3) - 2; + q3 = (x2^3) - 2; + q4 = (x3^2) - 2; + q5 = (x4^7) - x4 + 3; + p = x5 - x0 - 2*x1 /* - 3*x2 - x3 */ + x4; + p = resultant(p, q1, 0); + std::cout << "finished resultant 1... size: " << size(p) << std::endl; + p = resultant(p, q2, 1); + std::cout << "finished resultant 2... size: " << size(p) << std::endl; + // p = resultant(p, q3, 2); + std::cout << "finished resultant 3... size: " << size(p) << std::endl; + // p = resultant(p, q4, 3); + std::cout << "finished resultant 4... size: " << size(p) << std::endl; + p = resultant(p, q5, 4); + tst_mfact(p, 2); + } +} + + +static void tst_zp() { + unsynch_mpz_manager z; + polynomial::manager pm(z); + + polynomial_ref x(pm); + polynomial_ref y(pm); + x = pm.mk_polynomial(pm.mk_var()); + y = pm.mk_polynomial(pm.mk_var()); + + polynomial_ref p(pm); + polynomial_ref q(pm); + p = (x^4) + 2*(x^3) + 2*(x^2) + x; + q = (x^3) + x + 1; + std::cout << "p: " << p << "\n"; + std::cout << "q: " << q << "\n"; + std::cout << "gcd: " << gcd(p, q) << "\n"; + + { + polynomial::scoped_set_zp setZ3(pm, 3); + polynomial_ref p3(pm); + polynomial_ref q3(pm); + p3 = normalize(p); + q3 = normalize(q); + std::cout << "p[Z_3]: " << p3 << "\n"; + std::cout << "q[Z_3]: " << q3 << "\n"; + std::cout << "gcd[Z_3]: " << gcd(p3, q3) << "\n"; + } + + std::cout << "back into Z[x,y]\ngcd: " << gcd(p, q) << "\n"; + + p = 5*(x^2)*(y^2) + 3*(x^3) + 7*(y^3) + 3; + { + polynomial::scoped_set_zp setZ11(pm, 11); + polynomial_ref p11(pm); + + std::cout << "---------------\n"; + p11 = normalize(p); + std::cout << "p[Z_11]: " << p11 << "\n"; + p11 = pm.mk_glex_monic(p11); + std::cout << "monic p[Z_11]: " << p11 << "\n"; + } + std::cout << "back into Z[x,y]\n"; + std::cout << "p: " << p << "\n"; + std::cout << "gcd: " << gcd(p, q) << "\n"; +} + +static void tst_translate(polynomial_ref const & p, polynomial::var x0, int v0, polynomial::var x1, int v1, polynomial::var x2, int v2, + polynomial_ref const & expected) { + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + polynomial::var xs[3] = { x0, x1, x2 }; + mpz vs[3] = { mpz(v0), mpz(v1), mpz(v2) }; + polynomial_ref r(p.m()); + p.m().translate(p, 3, xs, vs, r); + std::cout << "r: " << r << std::endl; + SASSERT(eq(expected, r)); +} + +static void tst_translate() { + unsynch_mpq_manager qm; + polynomial::manager m(qm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + tst_translate((x0^2) + x1 + 1, 0, 1, 1, 2, 3, 0, + (x0^2) + 2*x0 + x1 + 4 + ); + tst_translate(x3 + 1, 0, 1, 1, 2, 2, 3, + x3 + 1 + ); + tst_translate(x3 + 1, 0, 1, 1, 2, 3, 0, + x3 + 1 + ); + tst_translate(x3 + 1, 0, 1, 1, 2, 3, 10, + x3 + 11 + ); + tst_translate((x0^3)*(x1^2) + (x0^2)*(x1^3) + 10, 0, -3, 1, -2, 3, 0, + (x0^3)*(x1^2) + (x0^2)*(x1^3) - 4*(x0^3)*x1 - 15*(x0^2)*(x1^2) - 6*x0*(x1^3) + 4*(x0^3) + + 48*(x0^2)*x1 + 63*x0*(x1^2) + 9*(x1^3) - 44*(x0^2) - 180*x0*x1 - 81*(x1^2) + + 156*x0 + 216*x1 - 170 + ); +} + +static void tst_p25() { + unsynch_mpq_manager qm; + polynomial::manager m(qm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + polynomial_ref x4(m); + polynomial_ref x5(m); + polynomial_ref x6(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + x4 = m.mk_polynomial(m.mk_var()); + x5 = m.mk_polynomial(m.mk_var()); + x6 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + p = (x0 + x1 + x2 + x3 + x4 + x5 + x6)^25; + std::cout << "size(p): " << size(p) << "\n"; +} + +static void tst_mm() { + unsynch_mpq_manager qm; + // pm1 and pm2 share the same monomial manager + polynomial::manager * pm1_ptr = alloc(polynomial::manager, qm); + polynomial::manager & pm1 = *pm1_ptr; + polynomial::manager pm2(qm, &pm1.mm()); + polynomial::manager pm3(qm); // pm3 has its own manager + polynomial_ref p2(pm2); + { + polynomial_ref x0(pm1); + polynomial_ref x1(pm1); + polynomial_ref x2(pm1); + x0 = pm1.mk_polynomial(pm1.mk_var()); + x1 = pm1.mk_polynomial(pm1.mk_var()); + x2 = pm1.mk_polynomial(pm1.mk_var()); + polynomial_ref p1(pm1); + p1 = (x0 + x1 + x2)^2; + + std::cout << "p1: " << p1 << "\n"; + p2 = convert(pm1, p1, pm2); + std::cout << "p2: " << p2 << "\n"; + SASSERT(pm1.get_monomial(p1, 0) == pm2.get_monomial(p2, 0)); + + polynomial_ref p3(pm3); + p3 = convert(pm1, p1, pm3); + SASSERT(pm1.get_monomial(p1, 0) != pm3.get_monomial(p3, 0)); + } + dealloc(pm1_ptr); + // p2 is still ok + std::cout << "p2: " << p2 << "\n"; +} + +static void tst_eval(polynomial_ref const & p, polynomial::var x0, rational v0, polynomial::var x1, rational v1, polynomial::var x2, rational v2, + rational expected) { + TRACE("eval_bug", tout << "tst_eval, " << p << "\n";); + std::cout << "p: " << p << "\nx" << x0 << " -> " << v0 << "\nx" << x1 << " -> " << v1 << "\nx" << x2 << " -> " << v2 << "\n"; + unsynch_mpq_manager qm; + polynomial::simple_var2value x2v(qm); + x2v.push_back(x0, v0.to_mpq()); + x2v.push_back(x1, v1.to_mpq()); + x2v.push_back(x2, v2.to_mpq()); + scoped_mpq r(qm); + p.m().eval(p, x2v, r); + std::cout << "r: " << r << "\nexpected: " << expected << "\n"; + scoped_mpq ex(qm); + qm.set(ex, expected.to_mpq()); + SASSERT(qm.eq(r, ex)); +} + +static void tst_eval() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + tst_eval(2000*x1 - x0, 0, rational(1), 1, rational(2), 2, rational(3), rational(3999)); + tst_eval(x0 + 1, 0, rational(1), 1, rational(2), 2, rational(3), rational(2)); + tst_eval((x0^3) + x0 + 1, 0, rational(2), 1, rational(2), 2, rational(3), rational(11)); + tst_eval((x0^3) - 2*x0 + 1, 0, rational(2), 1, rational(2), 2, rational(3), rational(5)); + tst_eval((x0^3) - 2*x0 + 1, 0, rational(-2), 1, rational(2), 2, rational(3), rational(-3)); + tst_eval((x0^4) - 2*x0 + x1 + 1, 0, rational(-2), 1, rational(10), 2, rational(3), rational(31)); + tst_eval((x0^4) - 2*x0 + ((x0^3) + 1)*x1 + 1, 0, rational(-2), 1, rational(10), 2, rational(3), rational(-49)); + tst_eval(((x0^4) - 2*x0)*(x1^2) + ((x0^3) + 1)*x1 + (x0^2) + 1, 0, rational(-2), 1, rational(10), 2, rational(3), rational(1935)); + tst_eval(((x0^4) - 2*x0)*(x1^2)*(x2^3) + ((x0^3) + 1)*x1 + (x0^2) + 1, 0, rational(-2), 1, rational(10), 2, rational(0), rational(-65)); + tst_eval(((x0^4) - 2*x0)*((x1^2) + 1)*(x2^3) + ((x0^3) + 1)*x1 + (x0^2) + 1, 0, rational(-2), 1, rational(10), 2, rational(1, 2), rational(375, 2)); + tst_eval(x0*x1*x2, 0, rational(2), 1, rational(3), 2, rational(1), rational(6)); + tst_eval(x0*x1*x2 + 1, 0, rational(2), 1, rational(3), 2, rational(1), rational(7)); + polynomial_ref one(m); + one = x0 - x0 + 1; + tst_eval(one, 0, rational(2), 1, rational(3), 2, rational(1), rational(1)); + tst_eval(x0*(x1^2)*x2 + 1, 0, rational(2), 1, rational(3), 2, rational(1), rational(19)); + tst_eval(x0*(x1^2)*x2 + x1 + 1, 0, rational(2), 1, rational(3), 2, rational(1), rational(22)); + tst_eval(x0*(x1^2)*x2 + x1 + 1 + (x2^2)*(2*x1 - 1), 0, rational(2), 1, rational(3), 2, rational(1), rational(27)); + tst_eval((x0^5) + 1, 0, rational(2), 1, rational(3), 2, rational(1), rational(33)); + tst_eval((x0^5) + x0*x1 + 1, 0, rational(2), 1, rational(1), 2, rational(5), rational(35)); + tst_eval((x1^5) + x0*x1 + 1, 0, rational(2), 1, rational(1), 2, rational(5), rational(4)); + tst_eval((x1^5) + x0*(x1^2) + 1, 0, rational(2), 1, rational(-2), 2, rational(5), rational(-23)); +} + +static void tst_mk_unique() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + polynomial::cache uniq(m); + polynomial_ref p(m); + polynomial_ref q(m); + polynomial_ref r(m); + + p = (x0^3) + (x2^5) + x0*x1 + x0*x1*x1 + 3*x0*x0 + 5; + q = x0*x1*x1 + (x0^3) + 3*x0*x0 + (x2^5) + 5 + x0*x1; + r = x0*x1*x1 + (x0^3) + 3*x0*x0 + (x2^5) + 6 + x0*x1; + std::cout << "p: " << p << "\n"; + std::cout << "q: " << q << "\n"; + std::cout << "r: " << r << "\n"; + SASSERT(m.eq(p, q)); + SASSERT(!m.eq(p, r)); + SASSERT(p.get() != q.get()); + q = uniq.mk_unique(q); + p = uniq.mk_unique(p); + r = uniq.mk_unique(r); + std::cout << "after mk_unique\np: " << p << "\n"; + std::cout << "q: " << q << "\n"; + std::cout << "r: " << r << "\n"; + SASSERT(m.eq(p, q)); + SASSERT(!m.eq(r, q)); + SASSERT(p.get() == q.get()); +} + +struct dummy_del_eh : public polynomial::manager::del_eh { + unsigned m_counter; + dummy_del_eh():m_counter(0) {} + virtual void operator()(polynomial::polynomial * p) { + m_counter++; + } +}; + +static void tst_del_eh() { + dummy_del_eh eh1; + dummy_del_eh eh2; + + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + + m.add_del_eh(&eh1); + x1 = 0; + SASSERT(eh1.m_counter == 1); + + m.add_del_eh(&eh2); + x1 = m.mk_polynomial(m.mk_var()); + x1 = 0; + SASSERT(eh1.m_counter == 2); + SASSERT(eh2.m_counter == 1); + m.remove_del_eh(&eh1); + x0 = 0; + x1 = m.mk_polynomial(m.mk_var()); + x1 = 0; + SASSERT(eh1.m_counter == 2); + SASSERT(eh2.m_counter == 3); + m.remove_del_eh(&eh2); + x1 = m.mk_polynomial(m.mk_var()); + x1 = 0; + SASSERT(eh1.m_counter == 2); + SASSERT(eh2.m_counter == 3); +} + +static void tst_const_coeff() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + + scoped_mpz c(nm); + + polynomial_ref p(m); + + p = (x0^2)*x1 + 3*x0 + x1; + SASSERT(!m.const_coeff(p, 0, 2, c)); + SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); + SASSERT(!m.const_coeff(p, 0, 0, c)); + + p = (x0^2)*x1 + 3*x0 + x1 + 1; + SASSERT(!m.const_coeff(p, 0, 2, c)); + SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); + SASSERT(!m.const_coeff(p, 0, 0, c)); + + p = (x0^2)*x1 + 3*x0 + 1; + SASSERT(!m.const_coeff(p, 0, 2, c)); + SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); + SASSERT(m.const_coeff(p, 0, 0, c) && c == 1); + + p = x1 + 3*x0 + 1; + SASSERT(m.const_coeff(p, 0, 2, c) && c == 0); + SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); + SASSERT(!m.const_coeff(p, 0, 0, c)); + + p = 5*(x0^2) + 3*x0 + 7; + SASSERT(m.const_coeff(p, 0, 5, c) && c == 0); + SASSERT(m.const_coeff(p, 0, 2, c) && c == 5); + SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); + SASSERT(m.const_coeff(p, 0, 0, c) && c == 7); + + p = 5*(x0^2) + 3*x0; + SASSERT(m.const_coeff(p, 0, 0, c) && c == 0); + + p = - x0*x1 - x1 + 1; + SASSERT(!m.const_coeff(p, 0, 1, c)); +} + +static void tst_gcd2() { + // enable_trace("mgcd"); + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + polynomial_ref x1(m); + polynomial_ref x2(m); + polynomial_ref x3(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref one(m); + one = m.mk_const(mpz(1)); + + tst_gcd(one, one, one); + + tst_gcd((5*x0 + 3*x1)*(x1 + 2)*(x2 + 3), + (10*x0 + 6*x1)*(x1 + 2)*(x2 + 5), + (5*x0 + 3*x1)*(x1 + 2)); + + tst_gcd((x0 + 1)*(x1 + 2)*(x2 + 3), + (x0 + 1)*(x1 + 2)*(x2 + 5), + (x0 + 1)*(x1 + 2)); + + tst_gcd(((x1^2) + 2*(x2^2) + 3*(x3^3))*(x1 + x2 + x3 + 1), + ((x1^2) + 2*(x2^2) + 3*(x3^3))*(x1 + x2 + x3 + 2), + ((x1^2) + 2*(x2^2) + 3*(x3^3))); + + tst_gcd(5*(x1^3) + 11 + 7*(x0^2), + 5*(x1^3) + 13 + 7*(x0^2), + one); + + tst_gcd((5*3*(x1^2) + 5*6*(x2^2) + 5*21*(x3^3))*(5*(x1^3) + 7*(x0^2) + 11), + (7*3*(x1^2) + 7*6*(x2^2) + 7*21*(x3^3))*(5*(x1^3) + 7*(x0^2) + 13), + (3*(x1^2) + 6*(x2^2) + 21*(x3^3))); + + tst_gcd((x2^6)*(x3^6) - 4*(x2^3)*(x3^6) + 2*(x2^6)*(x3^3) - 8*(x2^3)*(x3^3) + 4*(x1^3)*(x2^3)*(x3^3) - 8*(x1^3)*(x3^3) + + 4*(x3^6) + 8*(x3^3) + (x2^6) - 4*(x2^3) + 4*(x1^3)*(x2^3) - 8*(x1^3) + 4 + (x1^6), + (-2)*(x2^3)*(x3^6) - 4*(x2^3)*(x3^3) + 4*(x3^6) + 8*(x3^3) - 2*(x1^3)*(x3^3) - 2*(x2^3) + 4 - 2*(x1^3), + one); + + tst_gcd((x1^2) - 2*x0 + 1 + (x0^2) + x0*x1 - 2*x1, + x0*x1, + one); + + tst_gcd((5*3*(x1^2) + 5*6*(x2^2) + 5*21*(x3^3))*(x1 + x2 + x3 + 1)*(5*(x1^3) + 7*(x0^2) + 11), + (7*3*(x1^2) + 7*6*(x2^2) + 7*21*(x3^3))*(x1 + x2 + x3 + 2)*(5*(x1^3) + 7*(x0^2) + 13), + (3*(x1^2) + 6*(x2^2) + 21*(x3^3))); + + p = 169*(x1^12)*(x2^16) - 468*x0*(x1^11)*(x2^16) + 428*(x0^2)*(x1^10)*(x2^16) - 92*(x0^3)*(x1^9)*(x2^16) - 82*(x0^4)*(x1^8)*(x2^16) + 52*(x0^5)*(x1^7)*(x2^16) - 4*(x0^6)*(x1^6)*(x2^16) - 4*(x0^7)*(x1^5)*(x2^16) + (x0^8)*(x1^4)*(x2^16) - 581*(x1^14)*(x2^14) + 1828*x0*(x1^13)*(x2^14) - 2452*(x0^2)*(x1^12)*(x2^14) + 548*(x0^3)*(x1^11)*(x2^14) + 1002*(x0^4)*(x1^10)*(x2^14) - 756*(x0^5)*(x1^9)*(x2^14) + 124*(x0^6)*(x1^8)*(x2^14) + 44*(x0^7)*(x1^7)*(x2^14) - 13*(x0^8)*(x1^6)*(x2^14) + 895*(x1^16)*(x2^12) - 1556*x0*(x1^15)*(x2^12) + 2864*(x0^2)*(x1^14)*(x2^12); + tst_gcd(p, derivative(p, 2), (x1^4)*(x2^11)); + + tst_gcd((11*5*3)*((x0^2) + 1)*(x1 + 3), + (11*5*7)*((x0^2) + 1)*(x1 + 5), + (11*5)*((x0^2) + 1)); + + p = (x0^4)*(x3^8) - 2*(x0^4)*(x3^7) - 2*(x0^3)*(x2^3)*(x3^7) + 4*(x0^3)*(x3^7) + 2*(x0^4)*(x3^5) - 4*(x0^4)*(x3^4) - 4*(x0^3)*(x2^3)*(x3^4) + 8*(x0^3)*(x3^4) - 2*(x0^3)*(x1^3)*(x3^5) + 4*(x0^3)*(x1^3)*(x3^4) + 4*(x0^2)*(x1^3)*(x2^3)*(x3^4) - 8*(x0^2)*(x1^3)*(x3^4) + (x0^4)*(x3^6) + 2*(x0^3)*(x2^3)*(x3^6) - 4*(x0^3)*(x3^6) + 2*(x0^4)*(x3^3) + 4*(x0^3)*(x2^3)*(x3^3) - 8*(x0^3)*(x3^3) - 2*(x0^3)*(x1^3)*(x3^3) - 4*(x0^2)*(x1^3)*(x2^3)*(x3^3) + 8*(x0^2)*(x1^3)*(x3^3) + (x0^2)*(x2^6)*(x3^6) - 4*(x0^2)*(x2^3)*(x3^6) + 2*(x0^2)*(x2^6)*(x3^3) - 8*(x0^2)*(x2^3)*(x3^3) - 2*x0*(x1^3)*(x2^6)*(x3^3) + 8*x0*(x1^3)*(x2^3)*(x3^3) + 4*(x0^2)*(x3^6) + 8*(x0^2)*(x3^3) - 8*x0*(x1^3)*(x3^3) + (x0^4)*(x3^2) - 2*(x0^4)*x3 - 2*(x0^3)*(x2^3)*x3 + 4*(x0^3)*x3 - 2*(x0^3)*(x1^3)*(x3^2) + 4*(x0^3)*(x1^3)*x3 + 4*(x0^2)*(x1^3)*(x2^3)*x3 - 8*(x0^2)*(x1^3)*x3 + (x0^4) + 2*(x0^3)*(x2^3) - 4*(x0^3) - 2*(x0^3)*(x1^3) - 4*(x0^2)*(x1^3)*(x2^3) + 8*(x0^2)*(x1^3) + (x0^2)*(x2^6) - 4*(x0^2)*(x2^3) - 2*x0*(x1^3)*(x2^6) + 8*x0*(x1^3)*(x2^3) + 4*(x0^2) - 8*x0*(x1^3) + (x0^2)*(x1^6)*(x3^2) - 2*(x0^2)*(x1^6)*x3 - 2*x0*(x1^6)*(x2^3)*x3 + 4*x0*(x1^6)*x3 + (x0^2)*(x1^6) + 2*x0*(x1^6)*(x2^3) - 4*x0*(x1^6) + (x1^6)*(x2^6) - 4*(x1^6)*(x2^3) + 4*(x1^6); + + // polynomial_ref p1(m); + // p1 = derivative(p, 0); + // polynomial_ref g(m); + // for (unsigned i = 0; i < 50; i++) + // g = gcd(p, p1); + // return; + + tst_gcd(p, derivative(p, 1), + x0*(x2^6)*(x3^3) - (x1^3)*(x2^6) - 2*(x0^2)*(x2^3)*(x3^4) + 2*x0*(x1^3)*(x2^3)*x3 + 2*(x0^2)*(x2^3)*(x3^3) + (x0^3)*(x3^5) - 2*x0*(x1^3)*(x2^3) + x0*(x2^6) - (x0^2)*(x1^3)*(x3^2) - 4*x0*(x2^3)*(x3^3) - 2*(x0^3)*(x3^4) + 4*(x1^3)*(x2^3) + 2*(x0^2)*(x1^3)*x3 - 2*(x0^2)*(x2^3)*x3 + (x0^3)*(x3^3) + 4*(x0^2)*(x3^4) - (x0^2)*(x1^3) + 2*(x0^2)*(x2^3) - 4*x0*(x1^3)*x3 + (x0^3)*(x3^2) - 4*(x0^2)*(x3^3) + 4*x0*(x1^3) - 4*x0*(x2^3) - 2*(x0^3)*x3 + 4*x0*(x3^3) + (x0^3) - 4*(x1^3) + 4*(x0^2)*x3 - 4*(x0^2) + 4*x0 + ); + + tst_gcd(p, derivative(p, 0), + neg((-1)*x0*(x2^3)*(x3^3) + (x1^3)*(x2^3) + (x0^2)*(x3^4) - x0*(x1^3)*x3 - (x0^2)*(x3^3) + x0*(x1^3) - x0*(x2^3) + 2*x0*(x3^3) - 2*(x1^3) + (x0^2)*x3 - (x0^2) + 2*x0)); + + tst_gcd(p, derivative(p, 2), + neg((-1)*(x0^2)*(x2^3)*(x3^6) + 2*x0*(x1^3)*(x2^3)*(x3^3) + (x0^3)*(x3^7) - (x1^6)*(x2^3) - 2*(x0^2)*(x1^3)*(x3^4) - (x0^3)*(x3^6) + x0*(x1^6)*x3 + 2*(x0^2)*(x1^3)*(x3^3) - 2*(x0^2)*(x2^3)*(x3^3) + 2*(x0^2)*(x3^6) - x0*(x1^6) + 2*x0*(x1^3)*(x2^3) - 4*x0*(x1^3)*(x3^3) + 2*(x0^3)*(x3^4) + 2*(x1^6) - 2*(x0^2)*(x1^3)*x3 - 2*(x0^3)*(x3^3) + 2*(x0^2)*(x1^3) - (x0^2)*(x2^3) + 4*(x0^2)*(x3^3) - 4*x0*(x1^3) + (x0^3)*x3 - (x0^3) + 2*(x0^2)) + ); + + tst_gcd(((11*5*3)*(x0^2) + 1)*(x1 + 3), + ((11*5*3)*(x0^2) + 1)*(x1 + 5), + ((11*5*3)*(x0^2) + 1)); + + return; + p = 169*(x1^12)*(x2^16) - 468*x0*(x1^11)*(x2^16) + 428*(x0^2)*(x1^10)*(x2^16) - 92*(x0^3)*(x1^9)*(x2^16) - 82*(x0^4)*(x1^8)*(x2^16) + 52*(x0^5)*(x1^7)*(x2^16) - 4*(x0^6)*(x1^6)*(x2^16) - 4*(x0^7)*(x1^5)*(x2^16) + (x0^8)*(x1^4)*(x2^16) - 581*(x1^14)*(x2^14) + 1828*x0*(x1^13)*(x2^14) - 2452*(x0^2)*(x1^12)*(x2^14) + 548*(x0^3)*(x1^11)*(x2^14) + 1002*(x0^4)*(x1^10)*(x2^14) - 756*(x0^5)*(x1^9)*(x2^14) + 124*(x0^6)*(x1^8)*(x2^14) + 44*(x0^7)*(x1^7)*(x2^14) - 13*(x0^8)*(x1^6)*(x2^14) + 895*(x1^16)*(x2^12) - 1556*x0*(x1^15)*(x2^12) + 2864*(x0^2)*(x1^14)*(x2^12) + 520*(x0^3)*(x1^13)*(x2^12) - 5402*(x0^4)*(x1^12)*(x2^12) + 3592*(x0^5)*(x1^11)*(x2^12) - 156*(x0^6)*(x1^10)*(x2^12) - 680*(x0^7)*(x1^9)*(x2^12) + 171*(x0^8)*(x1^8)*(x2^12) + 12*(x0^9)*(x1^7)*(x2^12) - 4*(x0^10)*(x1^6)*(x2^12) - 957*(x1^18)*(x2^10) - 1132*x0*(x1^17)*(x2^10) + 206*(x0^2)*(x1^16)*(x2^10) + 588*(x0^3)*(x1^15)*(x2^10) + 6861*(x0^4)*(x1^14)*(x2^10) - 5016*(x0^5)*(x1^13)*(x2^10) - 2756*(x0^6)*(x1^12)*(x2^10) + 3952*(x0^7)*(x1^11)*(x2^10) - 1143*(x0^8)*(x1^10)*(x2^10) - 124*(x0^9)*(x1^9)*(x2^10) + 30*(x0^10)*(x1^8)*(x2^10) + 4*(x0^11)*(x1^7)*(x2^10) - (x0^12)*(x1^6)*(x2^10) + 1404*(x1^20)*(x2^8) + 684*x0*(x1^19)*(x2^8) - 1224*(x0^2)*(x1^18)*(x2^8) - 4412*(x0^3)*(x1^17)*(x2^8) - 1442*(x0^4)*(x1^16)*(x2^8) + 4164*(x0^5)*(x1^15)*(x2^8) + 4116*(x0^6)*(x1^14)*(x2^8) - 5308*(x0^7)*(x1^13)*(x2^8) + 392*(x0^8)*(x1^12)*(x2^8) + 1600*(x0^9)*(x1^11)*(x2^8) - 468*(x0^10)*(x1^10)*(x2^8) - 24*(x0^11)*(x1^9)*(x2^8) + 6*(x0^12)*(x1^8)*(x2^8) - 594*(x1^22)*(x2^6) - 324*x0*(x1^21)*(x2^6) + 1980*(x0^2)*(x1^20)*(x2^6) + 1136*(x0^3)*(x1^19)*(x2^6) + 405*(x0^4)*(x1^18)*(x2^6) - 3916*(x0^5)*(x1^17)*(x2^6) - 396*(x0^6)*(x1^16)*(x2^6) + 1876*(x0^7)*(x1^15)*(x2^6) + 1108*(x0^8)*(x1^14)*(x2^6) - 2064*(x0^9)*(x1^13)*(x2^6) + 248*(x0^10)*(x1^12)*(x2^6) + 380*(x0^11)*(x1^11)*(x2^6) - 95*(x0^12)*(x1^10)*(x2^6) + 81*(x1^24)*(x2^4) + 108*x0*(x1^23)*(x2^4) - 432*(x0^2)*(x1^22)*(x2^4) - 276*(x0^3)*(x1^21)*(x2^4) + 481*(x0^4)*(x1^20)*(x2^4) + 144*(x0^5)*(x1^19)*(x2^4) + 788*(x0^6)*(x1^18)*(x2^4) - 1152*(x0^7)*(x1^17)*(x2^4) + 231*(x0^8)*(x1^16)*(x2^4) + 244*(x0^9)*(x1^15)*(x2^4) + 396*(x0^10)*(x1^14)*(x2^4) - 476*(x0^11)*(x1^13)*(x2^4) + 119*(x0^12)*(x1^12)*(x2^4) + 72*(x0^4)*(x1^22)*(x2^2) - 96*(x0^5)*(x1^21)*(x2^2) - 40*(x0^6)*(x1^20)*(x2^2) - 32*(x0^7)*(x1^19)*(x2^2) + 340*(x0^8)*(x1^18)*(x2^2) - 368*(x0^9)*(x1^17)*(x2^2) + 112*(x0^10)*(x1^16)*(x2^2) + 16*(x0^11)*(x1^15)*(x2^2) - 4*(x0^12)*(x1^14)*(x2^2) + 16*(x0^8)*(x1^20) - 64*(x0^9)*(x1^19) + 96*(x0^10)*(x1^18) - 64*(x0^11)*(x1^17) + 16*(x0^12)*(x1^16); + polynomial_ref p_prime(m); + p_prime = derivative(p, 2); + tst_gcd(p, p_prime, x1^4); +} + +static void tst_gcd3() { + enable_trace("polynomial_gcd"); + enable_trace("polynomial_gcd_detail"); + enable_trace("mpzzp"); + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q(m); + p = (x^8) + (x^6) + (x^4) + (x^3) + (x^2) + 1; + q = (x^6) + (x^4) + x + 1; + { + polynomial::scoped_set_zp setZ2(m, 2); + std::cout << "Z_p: " << nm.to_string(m.p()) << "\n"; + tst_gcd(normalize(p), normalize(q), x + 1); + } + { + polynomial::scoped_set_zp setZ3(m, 3); + std::cout << "Z_p: " << nm.to_string(m.p()) << "\n"; + polynomial_ref one(m); + one = m.mk_const(mpz(1)); + tst_gcd(normalize(p), normalize(q), one); + } +} + +static void tst_gcd4() { + enable_trace("mgcd"); + // enable_trace("CRA"); + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m); + polynomial_ref q(m); + p = (15*x + 15)*((x + 2)^8)*(10000*x + 1)*(x + 3); + q = (6*x + 6)*((x + 20)^8)*(10000*x + 3)*(x + 30); + tst_gcd(p, q, 3*x + 3); + p = (3*x + 2)*((x + 2)^8)*(10000*x + 1)*(x + 3); + q = (3*x + 2)*((x + 20)^8)*(10000*x + 3)*(x + 30); + tst_gcd(p, q, 3*x + 2); + p = ((3*x + 2)*((x + 2)^8)*(10000*x + 1)*(x + 3))^3; + q = ((3*x + 2)*((x + 20)^8)*(10000*x + 3)*(x + 30))^3; + tst_gcd(p, q, (3*x + 2)^3); + p = ((x + 3)^10)*((x^5) - x - 1)*(x + 1)*(x + 2)*(x + 4)*(10000*x + 33)*(x + 6)*(x + 11)*(x+33)* + ((x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225)* + (1000000*x + 1)*(333333333*x + 1)*(77777777*x + 1)*(11111111*x + 1)*(x + 128384747)*(x + 82837437)*(x + 22848481); + tst_gcd(p, derivative(p, 0), (x + 3)^9); +} + +static void tst_newton_interpolation() { + // enable_trace("newton"); + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + polynomial_ref y(m); + x = m.mk_polynomial(m.mk_var()); + y = m.mk_polynomial(m.mk_var()); + polynomial_ref p1(m), p2(m), p3(m); + p1 = (-9)*y - 21; + p2 = (-3)*y + 20; + p3 = 5*y - 36; + scoped_mpz_vector ins(nm); + ins.push_back(mpz(0)); ins.push_back(mpz(1)); ins.push_back(mpz(2)); + polynomial::polynomial * outs[3] = { p1.get(), p2.get(), p3.get() }; + polynomial_ref r(m); + { + polynomial::scoped_set_zp setZ97(m, 97); + m.newton_interpolation(0, 2, ins.c_ptr(), outs, r); + } + std::cout << "interpolation result: " << r << "\n"; + SASSERT(m.eq((x^2)*y + 5*x*y + 41*x - 9*y - 21, r)); +} + +static void tst_slow_mod_gcd() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m), x1(m), x2(m), x3(m), x4(m), x5(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + x4 = m.mk_polynomial(m.mk_var()); + x5 = m.mk_polynomial(m.mk_var()); + polynomial_ref p(m), q(m), b(m); + polynomial_ref p_prime(m); + + p = ((x0^3)*x1*x2*x3*x4*x5 + x0*x1*x2*x3*(x4^3)*x5 + x0*x1*x2*x3*x4*(x5^3) - x0*x1*x2*x3*x4*x5 - 2)^2; + q = derivative(p, 0); + tst_gcd(p, q, (x0^3)*x1*x2*x3*x4*x5 + x0*x1*x2*x3*(x4^3)*x5 + x0*x1*x2*x3*x4*(x5^3) - x0*x1*x2*x3*x4*x5 - 2); + + b = (x0^10) + (x1^10) + (x2^10) + (x3^10); + p = b*(x0 + 1); + q = b*(x0 + 2); + tst_gcd(p, q, b); + + return; + p = (x0^8) * + (((x0^3)*x1*x2*x3*x4*x5 + x0*(x1^3)*x2*x3*x4*x5 + x0*x1*(x2^3)*x3*x4*x5 + x0*x1*x2*(x3^3)*x4*x5 + + x0*x1*x2*x3*(x4^3)*x5 + x0*x1*x2*x3*x4*(x5^3) - x0*x1*x2*x3*x4*x5 - 2)^2) * + (((x0^3)*x1*x2*x3*x4*x5 + x0*(x1^3)*x2*x3*x4*x5 + x0*x1*(x2^3)*x3*x4*x5 + x0*x1*x2*(x3^3)*x4*x5 + + x0*x1*x2*x3*(x4^3)*x5 + x0*x1*x2*x3*x4*(x5^3) - x0*x1*x2*x3*x4*x5 + 2)^2); + p_prime = derivative(p, 0); + tst_gcd(p, p_prime, + (x0^7) * + ((x0^3)*x1*x2*x3*x4*x5 + x0*(x1^3)*x2*x3*x4*x5 + x0*x1*(x2^3)*x3*x4*x5 + x0*x1*x2*(x3^3)*x4*x5 + + x0*x1*x2*x3*(x4^3)*x5 + x0*x1*x2*x3*x4*(x5^3) - x0*x1*x2*x3*x4*x5 - 2) * + ((x0^3)*x1*x2*x3*x4*x5 + x0*(x1^3)*x2*x3*x4*x5 + x0*x1*(x2^3)*x3*x4*x5 + x0*x1*x2*(x3^3)*x4*x5 + + x0*x1*x2*x3*(x4^3)*x5 + x0*x1*x2*x3*x4*(x5^3) - x0*x1*x2*x3*x4*x5 + 2)); +} + +void tst_linear_solver() { + unsynch_mpq_manager qm; + scoped_mpq_vector as(qm); + scoped_mpq b(qm); + scoped_mpq_vector xs(qm); + linear_eq_solver solver(qm); + + solver.resize(3); + xs.resize(3); + + as.reset(); + as.push_back(mpq(2)); as.push_back(mpq(1)); as.push_back(mpq(-1)); qm.set(b, 8); + solver.add(0, as.c_ptr(), b); + + as.reset(); + as.push_back(mpq(-3)); as.push_back(mpq(-1)); as.push_back(mpq(2)); qm.set(b, -11); + solver.add(1, as.c_ptr(), b); + + as.reset(); + as.push_back(mpq(-2)); as.push_back(mpq(1)); as.push_back(mpq(2)); qm.set(b, -3); + solver.add(2, as.c_ptr(), b); + + VERIFY(solver.solve(xs.c_ptr())); + SASSERT(qm.eq(xs[0], mpq(2))); + SASSERT(qm.eq(xs[1], mpq(3))); + SASSERT(qm.eq(xs[2], mpq(-1))); +} + +static void tst_lex(polynomial_ref const & p1, polynomial_ref const & p2, int lex_expected, polynomial::var min, int lex2_expected) { + polynomial::manager & m = p1.m(); + std::cout << "compare "; + m.display(std::cout, m.get_monomial(p1, 0)); + std::cout << " "; + m.display(std::cout, m.get_monomial(p2, 0)); + std::cout << " "; std::cout.flush(); + int r1 = lex_compare(m.get_monomial(p1, 0), m.get_monomial(p2, 0)); + int r2 = lex_compare2(m.get_monomial(p1, 0), m.get_monomial(p2, 0), min); + SASSERT(r1 == lex_expected); + SASSERT(r2 == lex2_expected); + std::cout << r1 << " " << r2 << "\n"; + SASSERT(lex_compare(m.get_monomial(p2, 0), m.get_monomial(p1, 0)) == -r1); + SASSERT(lex_compare2(m.get_monomial(p2, 0), m.get_monomial(p1, 0), min) == -r2); +} + +static void tst_lex() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m), x1(m), x2(m), x3(m), x4(m), x5(m); + x0 = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + x4 = m.mk_polynomial(m.mk_var()); + x5 = m.mk_polynomial(m.mk_var()); + + polynomial_ref one(m); + one = m.mk_const(mpz(1)); + + tst_lex(x0*x4*x1, (x0^10)*(x1^3), 1, 4, -1); + tst_lex(x0*x3*(x1^2)*x4, x0*(x3^2)*(x1^2)*x4, -1, 3, -1); + tst_lex((x0^2)*x3*(x1^2)*x4, x0*(x3^2)*(x1^2)*x4, -1, 3, 1); + tst_lex(x0*x3*(x1^2)*x4, x0*x3*(x1^2)*x4, 0, 3, 0); + tst_lex(x0*(x3^2)*(x1^2)*x4, x0*x3*(x1^2)*x4, 1, 3, 1); + tst_lex((x1^2)*x4, x0*x2*x3*x4*x5, -1, 1, -1); + tst_lex((x1^2)*x3*x4, x0*x1, 1, 1, 1); + tst_lex(x1*x3*x4, x2*x3*x4, -1, 2, 1); + tst_lex(x1*x3*x4, x2*x3*x4, -1, 1, -1); + tst_lex(x1*x3*x4, x0*x2*x3*x4, -1, 1, -1); + tst_lex(x3, x4, -1, 1, -1); + tst_lex(x3, x4, -1, 4, 1); + tst_lex(x2*x3, x4, -1, 1, -1); + tst_lex(x2*x3, x4, -1, 4, 1); + tst_lex(x3, x2*x4, -1, 1, -1); + tst_lex(x3, x2*x4, -1, 4, 1); + tst_lex(x3, x2*x4, -1, 4, 1); + tst_lex(one, x3, -1, 1, -1); + tst_lex(one, x3, -1, 3, -1); + tst_lex(x3, one, 1, 3, 1); + tst_lex(x4*x5, (x4^3)*x5, -1, 4, -1); +} + +static void tst_divides() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + x0 = m.mk_polynomial(m.mk_var()); + polynomial_ref q(m); + polynomial_ref p(m); + + q = 16*(x0^27) - 1984*(x0^26) + 1762*(x0^25) + 17351*(x0^24) - 14165*(x0^23) + 16460*(x0^22) + 2919*(x0^21) - 16823*(x0^20) + 1530*(x0^19) + + 10646*(x0^18) + 19217*(x0^17); + p = 16*(x0^39) - 3648*(x0^38) + 338136*(x0^37) - 16037936*(x0^36) + 392334357*(x0^35) - rational("3851617443")*(x0^34) - + rational("14636221526")*(x0^33) + rational("377151717618")*(x0^32) + rational("677140776981")*(x0^31) - rational("4308280094419")*(x0^30) + + rational("312708087606")*(x0^29) + rational("8205543533730")*(x0^28) + rational("3331586202704")*(x0^27) - rational("15291636627072")*(x0^26) + + rational("433482645282")*(x0^25) + rational("7397104817486")*(x0^24) + rational("1021197979053")*(x0^23) - rational("1373737505247")*(x0^22) - + rational("639394669026")*(x0^21) - rational("118513560618")*(x0^20) - rational("10405319535")*(x0^19) - rational("358722675")*(x0^18); + std::cout << "----------------------\n"; + std::cout << "q: " << q << "\n"; + std::cout << "p: " << p << std::endl; + std::cout << "divides(q, p): " << m.divides(q, p) << "\n"; +} + +void tst_polynomial() { + set_verbosity_level(1000); + // enable_trace("factor"); + // enable_trace("poly_bug"); + // enable_trace("factor_bug"); + disable_trace("polynomial"); + enable_trace("psc_chain_classic"); + enable_trace("Lazard"); + // enable_trace("eval_bug"); + // enable_trace("mgcd"); + tst_psc(); + return; + tst_eval(); + tst_divides(); + tst_gcd2(); + tst_slow_mod_gcd(); + tst_gcd(); + + tst_lex(); + tst_linear_solver(); + tst_newton_interpolation(); + tst_resultant(); + // + // tst_gcd4(); + // tst_gcd3(); + tst_zp(); + tst_const_coeff(); + tst_psc(); + tst_del_eh(); + tst_mk_unique(); + tst_qsubstitute(); + tst_substitute(); + tst_discriminant(); + tst_mfact(); + tst_mm(); + // tst_p25(); + // return; + tst_translate(); + // enable_trace("mpz_gcd"); + tst_vars(); + tst_sqf(); + enable_trace("resultant"); + enable_trace("psc"); + disable_trace("polynomial"); + enable_trace("pseudo_remainder"); + enable_trace("resultant_bug"); + tst_sqrt(); + tst_prem(); + tst_compose(); + tst11(); + tst10(); + tst9(); + tst8(); + tst7(); + tst6(); + tst5(); + tst3(); + tst2(); + tst1(); + tst4(); +} diff --git a/test/polynomial_factorization.cpp b/test/polynomial_factorization.cpp new file mode 100644 index 000000000..c8dda5313 --- /dev/null +++ b/test/polynomial_factorization.cpp @@ -0,0 +1,742 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + polynomial_factorization.cpp + +Abstract: + + Testing of factorization. + +Author: + + Dejan (t-dejanj) 2011-11-29 + +Notes: + +--*/ +#include"upolynomial_factorization_int.h" +#include"timeit.h" +#include"polynomial.h" + +#if 0 +#include"polynomial_factorization.h" +#endif + +using namespace std; + +// some prime numbers +unsigned primes[] = { + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 +}; + +// [i,l]: how many factors the Knuth example has over p_i, when i = 0 it's Z, p_1 = 2, for l=0 distinct, for l = 1 total +unsigned knuth_factors[2][11] = { + // x^8 + x^6 + 10*x^4 + 10*x^3 + 8*x^2 + 2*x + 8 + {2, 2, 3, 3, 2, 3, 1, 4, 3, 1, 1}, + {8, 2, 3, 3, 2, 3, 1, 4, 3, 1, 1}, +}; + +// [k,l,i]: how many factors the S_k has over p_i, when i = 0 it's Z, p_1 = 2, for l=0 distinct, for l = 1 total +unsigned swinnerton_dyer_factors[5][2][11] = { + // S1 = (x^2) - 2 + { + // 2, 3, 5, 7,11,13,17,19,23,29, Z + {1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1}, + {2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1} + }, + // S2 = (x^4) - 10*(x^2) + 1 + { + {1, 1, 2, 2, 2, 2, 2, 2, 4, 2, 1}, + {4, 2, 2, 2, 2, 2, 2, 2, 4, 2, 1} + }, + // S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576 + { + {1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 1}, + {8, 6, 4, 4, 4, 4, 4, 4, 4, 4, 1} + }, + // S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225 + { + {1, 4, 3, 4, 8, 8, 8, 8, 8, 8, 1}, + {16, 12, 10, 8, 8, 8, 8, 8, 8, 8, 1} + }, + // SA = S1*S2*S3*S4 + { + //p = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, Z + { 2, 6, 3, 6, 15, 11, 16, 15, 18, 15, 1}, + {30, 21, 17, 16, 15, 15, 16, 15, 18, 15, 1} + } +}; + +int random_polynomial[20][2][11] = { + { + // 3*x^10 + 2*x^9 + 4*x^8 + 4*x^7 + 4*x^6 + x^5 + 3*x^2 + 3*x + { 4, 3, 4, 4, 3, 4, 4, 4, 3, 4, 2 }, + { 7, 7, 4, 4, 3, 4, 4, 4, 3, 4, 2 }, + }, + { + // 4*x^9 + 4*x^8 + x^7 + x^6 + 2*x^5 + 3*x^4 + 4*x^2 + 4*x + { 2, 2, 3, 3, 4, 2, 5, 3, 4, 2, 2 }, + { 5, 2, 3, 3, 4, 2, 5, 3, 5, 2, 2 }, + }, + { + // 3*x^10 + 4*x^9 + 3*x^8 + x^6 + 4*x^5 + 4*x^4 + x^2 + { 3, 2, 4, 4, 5, 3, 4, 2, 4, 5, 2 }, + { 6, 3, 5, 5, 6, 4, 5, 3, 5, 7, 3 }, + }, + { + // x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^4 + 3*x^3 + x^2 + 4*x + { 3, 4, 4, 3, 3, 3, 4, 4, 5, 3, 2 }, + { 8, 4, 4, 3, 3, 3, 4, 4, 5, 3, 2 }, + }, + { + // x^9 + 2*x^8 + 3*x^7 + x^6 + 2*x^5 + 4*x^4 + 3*x^2 + { 3, 3, 3, 3, 4, 4, 4, 3, 3, 4, 2 }, + { 5, 6, 4, 5, 5, 6, 5, 4, 4, 5, 3 }, + }, + { + // x^10 + x^9 + 4*x^7 + x^6 + 3*x^5 + x^4 + x^3 + x + { 3, 2, 3, 3, 3, 5, 3, 2, 4, 4, 2 }, + { 3, 2, 3, 3, 3, 5, 3, 2, 4, 4, 2 }, + }, + { + // 4*x^10 + 4*x^9 + x^8 + 2*x^7 + 3*x^6 + 4*x^5 + 3*x^4 + x^3 + 2*x^2 + 4*x + { 3, 3, 2, 5, 3, 4, 2, 4, 5, 5, 2 }, + { 5, 3, 2, 5, 3, 4, 2, 4, 5, 5, 2 }, + }, + { + // 3*x^10 + 4*x^9 + 3*x^8 + x^7 + x^6 + 2*x^5 + x^4 + 2*x^3 + 2*x^2 + x + { 3, 4, 6, 4, 4, 4, 4, 6, 6, 4, 3 }, + { 4, 4, 7, 4, 4, 4, 4, 6, 6, 4, 3 }, + }, + { + // 4*x^10 + x^9 + x^7 + 2*x^5 + 3*x^3 + x^2 + 4*x + { 3, 3, 3, 4, 4, 5, 4, 5, 2, 4, 2 }, + { 4, 4, 3, 4, 4, 5, 4, 5, 2, 4, 2 }, + }, + { + // x^10 + 3*x^9 + 3*x^8 + x^7 + 3*x^6 + 3*x^5 + 3*x^4 + x^2 + 3*x + { 2, 3, 4, 4, 3, 3, 4, 3, 3, 4, 2 }, + { 2, 4, 5, 4, 3, 3, 4, 3, 3, 4, 2 }, + }, + { + // x^10 + x^9 + 2*x^8 + x^7 + 4*x^6 + 2*x^5 + 3*x^4 + 4*x^3 + x^2 + 2*x + { 3, 4, 4, 3, 3, 3, 3, 4, 5, 3, 2 }, + { 4, 4, 4, 3, 3, 3, 3, 4, 5, 3, 2 }, + }, + { + // 3*x^9 + x^8 + 3*x^7 + 3*x^6 + x^5 + 2*x^4 + 4*x^3 + 4*x^2 + 3*x + { 4, 3, 3, 3, 5, 3, 6, 4, 2, 2, 2 }, + { 6, 4, 3, 3, 5, 3, 6, 4, 2, 2, 2 }, + }, + { + // 2*x^10 + 3*x^9 + 2*x^8 + 4*x^7 + x^6 + 3*x^5 + 2*x^3 + 3*x^2 + 2*x + 2 + { 3, 3, 3, 5, 4, 5, 6, 7, 4, 6, 3 }, + { 8, 4, 3, 7, 4, 5, 6, 7, 4, 7, 3 }, + }, + { + // 3*x^10 + x^9 + 4*x^8 + 2*x^7 + x^6 + 4*x^5 + x^4 + 3*x^3 + x + 2 + { 3, 3, 3, 2, 6, 4, 4, 4, 3, 3, 2 }, + { 3, 3, 3, 2, 6, 5, 4, 5, 3, 3, 2 }, + }, + { + // 4*x^10 + 2*x^9 + x^8 + x^6 + x^5 + 3*x^4 + 4*x^3 + x^2 + x + { 3, 4, 2, 4, 4, 4, 4, 2, 3, 3, 2 }, + { 6, 4, 2, 4, 4, 4, 4, 2, 3, 3, 2 }, + }, + { + // 4*x^10 + 2*x^7 + 4*x^6 + 2*x^3 + x + { 1, 3, 3, 3, 4, 4, 4, 3, 3, 2, 2 }, + { 1, 3, 3, 3, 4, 4, 4, 3, 3, 2, 2 }, + }, + { + // 4*x^10 + x^9 + x^8 + 4*x^7 + 4*x^4 + 2*x^2 + x + 4 + { 3, 4, 2, 5, 3, 6, 3, 6, 3, 3, 2 }, + { 3, 6, 2, 5, 3, 6, 3, 6, 3, 3, 2 }, + }, + { + // 3*x^10 + 2*x^8 + x^7 + x^6 + 3*x^4 + 3*x^3 + 4*x^2 + 3*x + { 4, 3, 4, 3, 3, 3, 2, 4, 4, 3, 2 }, + { 5, 4, 4, 3, 3, 3, 2, 4, 4, 3, 2 }, + }, + { + // x^10 + 2*x^9 + 2*x^6 + 4*x^3 + 4*x^2 + { 1, 2, 2, 3, 3, 4, 3, 3, 3, 3, 2 }, + { 10, 3, 3, 4, 4, 6, 4, 4, 4, 4, 3 }, + }, + { + // x^10 + 2*x^9 + 2*x^8 + 4*x^7 + 4*x^6 + x^5 + x^3 + x^2 + 3*x + { 2, 4, 2, 3, 3, 3, 5, 5, 6, 2, 2 }, + { 2, 5, 2, 3, 3, 3, 5, 5, 6, 2, 2 }, + } +}; + +static void tst_square_free_finite_1() { + polynomial::numeral_manager nm; + polynomial::manager pm(nm); + + // example from Knuth, p. 442 + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + // polynomials \prod_{i < p} (x - i)^i + for (unsigned prime_i = 0; prime_i < 5; ++ prime_i) + { + int p = primes[prime_i]; + + // make the polynomial + polynomial_ref f(pm); + f = x - 1; + for (int i = 2; i < p; ++ i) { + f = f*((x + (-i))^i); + } + cout << "Factoring " << f << " into square-free over Z_" << p << endl; + + // convert to univariate over Z_p + upolynomial::zp_manager upm(nm); + upm.set_zp(p); + upolynomial::numeral_vector f_u; + upm.to_numeral_vector(f, f_u); + + cout << "Input: "; upm.display(cout, f_u); cout << endl; + + // factor it + upolynomial::zp_factors f_factors(upm); + cout << "Start: " << f_factors << endl; + + upolynomial::zp_square_free_factor(upm, f_u, f_factors); + + upolynomial::numeral_vector mult; + f_factors.multiply(mult); + cout << "Multiplied: "; upm.display(cout, mult); cout << endl; + + SASSERT(upm.eq(mult, f_u)); + + // remove the temps + upm.reset(f_u); + upm.reset(mult); + } +} + +static void tst_factor_finite_1() { + + polynomial::numeral_manager nm; + polynomial::manager pm(nm); + + // example from Knuth, p. 442 + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + polynomial_ref K(pm); + K = (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8; + + // factor them for all the prime numbers + for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) + { + // make the Z_p + unsigned prime = primes[prime_i]; + upolynomial::zp_manager upm(nm); + upm.set_zp(prime); + + // make the polynomial in Z_p + upolynomial::numeral_vector K_u; + upm.to_numeral_vector(K, K_u); + + cout << "Factoring " << K << "("; upm.display(cout, K_u); cout << ") in Z_" << prime << endl; + cout << "Expecting " << knuth_factors[0][prime_i] << " distinct factors, " << knuth_factors[1][prime_i] << " total" << endl; + + // factor it + upolynomial::zp_factors factors(upm); + bool factorized = upolynomial::zp_factor(upm, K_u, factors); + + // check the result + unsigned distinct = factors.distinct_factors(); + unsigned total = factors.total_factors(); + + cout << "Got " << factors << endl; + cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl; + + SASSERT(knuth_factors[0][prime_i] == distinct); + SASSERT(knuth_factors[1][prime_i] == total); + + upolynomial::numeral_vector multiplied; + factors.multiply(multiplied); + SASSERT(upm.eq(K_u, multiplied)); + upm.reset(multiplied); + + // remove the temp + upm.reset(K_u); + } +} + +static void tst_factor_finite_2() { + + polynomial::numeral_manager nm; + polynomial::manager pm(nm); + + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + // Swinnerton-Dyer polynomials (irreducible, modular factors of degree at most 2) + polynomial_ref S1 = (x^2) - 2; + polynomial_ref S2 = (x^4) - 10*(x^2) + 1; + polynomial_ref S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576; + polynomial_ref S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225; + + vector S; + S.push_back(S1); + S.push_back(S2); + S.push_back(S3); + S.push_back(S4); + S.push_back(S1*S2*S3*S4); + + // factor all the S_i them for all the prime numbers + for (unsigned S_i = 0; S_i < S.size(); ++ S_i) { + for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) { + unsigned prime = primes[prime_i]; + + upolynomial::zp_manager upm(nm); + upm.set_zp(prime); + + upolynomial::numeral_vector S_i_u; + upm.to_numeral_vector(S[S_i], S_i_u); + + cout << "Factoring "; upm.display(cout, S_i_u); cout << " over Z_" << prime << endl; + cout << "Expecting " << swinnerton_dyer_factors[S_i][0][prime_i] << " distinct factors, " << swinnerton_dyer_factors[S_i][1][prime_i] << " total" << endl; + + upolynomial::zp_factors factors(upm); + upolynomial::zp_factor(upm, S_i_u, factors); + + // check the result + unsigned distinct = factors.distinct_factors(); + unsigned total = factors.total_factors(); + + cout << "Got " << factors << endl; + cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl; + + SASSERT(swinnerton_dyer_factors[S_i][0][prime_i] == distinct); + SASSERT(swinnerton_dyer_factors[S_i][1][prime_i] == total); + + upolynomial::numeral_vector multiplied; + factors.multiply(multiplied); + SASSERT(upm.eq(S_i_u, multiplied)); + upm.reset(multiplied); + + // remove the temp + upm.reset(S_i_u); + } + } +} + +static void tst_factor_finite_3() { + + polynomial::numeral_manager nm; + polynomial::manager pm(nm); + + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + // random polynomials + vector random_p; + random_p.push_back( 3*(x^10) + 2*(x^9) + 4*(x^8) + 4*(x^7) + 4*(x^6) + 1*(x^5) + 3*(x^2) + 3*x + 0 ); + random_p.push_back( 4*(x^9) + 4*(x^8) + 1*(x^7) + 1*(x^6) + 2*(x^5) + 3*(x^4) + 4*(x^2) + 4*x + 0 ); + random_p.push_back( 3*(x^10) + 4*(x^9) + 3*(x^8) + 1*(x^6) + 4*(x^5) + 4*(x^4) + 1*(x^2) + 0 ); + random_p.push_back( 1*(x^10) + 4*(x^9) + 1*(x^8) + 3*(x^7) + 3*(x^4) + 3*(x^3) + 1*(x^2) + 4*x + 0 ); + random_p.push_back( 1*(x^9) + 2*(x^8) + 3*(x^7) + 1*(x^6) + 2*(x^5) + 4*(x^4) + 3*(x^2) + 0 ); + random_p.push_back( 1*(x^10) + 1*(x^9) + 4*(x^7) + 1*(x^6) + 3*(x^5) + 1*(x^4) + 1*(x^3) + 1*x + 0 ); + random_p.push_back( 4*(x^10) + 4*(x^9) + 1*(x^8) + 2*(x^7) + 3*(x^6) + 4*(x^5) + 3*(x^4) + 1*(x^3) + 2*(x^2) + 4*x + 0 ); + random_p.push_back( 3*(x^10) + 4*(x^9) + 3*(x^8) + 1*(x^7) + 1*(x^6) + 2*(x^5) + 1*(x^4) + 2*(x^3) + 2*(x^2) + 1*x + 0 ); + random_p.push_back( 4*(x^10) + 1*(x^9) + 1*(x^7) + 2*(x^5) + 3*(x^3) + 1*(x^2) + 4*x + 0 ); + random_p.push_back( 1*(x^10) + 3*(x^9) + 3*(x^8) + 1*(x^7) + 3*(x^6) + 3*(x^5) + 3*(x^4) + 1*(x^2) + 3*x + 0 ); + random_p.push_back( 1*(x^10) + 1*(x^9) + 2*(x^8) + 1*(x^7) + 4*(x^6) + 2*(x^5) + 3*(x^4) + 4*(x^3) + 1*(x^2) + 2*x + 0 ); + random_p.push_back( 3*(x^9) + 1*(x^8) + 3*(x^7) + 3*(x^6) + 1*(x^5) + 2*(x^4) + 4*(x^3) + 4*(x^2) + 3*x + 0 ); + random_p.push_back( 2*(x^10) + 3*(x^9) + 2*(x^8) + 4*(x^7) + 1*(x^6) + 3*(x^5) + 2*(x^3) + 3*(x^2) + 2*x + 2 ); + random_p.push_back( 3*(x^10) + 1*(x^9) + 4*(x^8) + 2*(x^7) + 1*(x^6) + 4*(x^5) + 1*(x^4) + 3*(x^3) + 1*x + 2 ); + random_p.push_back( 4*(x^10) + 2*(x^9) + 1*(x^8) + 1*(x^6) + 1*(x^5) + 3*(x^4) + 4*(x^3) + 1*(x^2) + 1*x + 0 ); + random_p.push_back( 4*(x^10) + 2*(x^7) + 4*(x^6) + 2*(x^3) + 1*x + 0 ); + random_p.push_back( 4*(x^10) + 1*(x^9) + 1*(x^8) + 4*(x^7) + 4*(x^4) + 2*(x^2) + 1*x + 4 ); + random_p.push_back( 3*(x^10) + 2*(x^8) + 1*(x^7) + 1*(x^6) + 3*(x^4) + 3*(x^3) + 4*(x^2) + 3*x + 0 ); + random_p.push_back( 1*(x^10) + 2*(x^9) + 2*(x^6) + 4*(x^3) + 4*(x^2) + 0 ); + random_p.push_back( 1*(x^10) + 2*(x^9) + 2*(x^8) + 4*(x^7) + 4*(x^6) + 1*(x^5) + 1*(x^3) + 1*(x^2) + 3*x + 0 ); + + // factor all the randoms them for all the prime numbers + for (unsigned random_i = 0; random_i < random_p.size(); ++ random_i) { + for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) { + unsigned prime = primes[prime_i]; + + upolynomial::zp_manager upm(nm); + upm.set_zp(prime); + + upolynomial::numeral_vector poly; + upm.to_numeral_vector(random_p[random_i], poly); + + cout << "Factoring "; upm.display(cout, poly); cout << " over Z_" << prime << endl; + cout << "Expecting " << swinnerton_dyer_factors[random_i][0][prime_i] << " distinct factors, " << random_polynomial[random_i][1][prime_i] << " total" << endl; + + upolynomial::zp_factors factors(upm); + upolynomial::zp_factor(upm, poly, factors); + + // check the result + unsigned distinct = factors.distinct_factors(); + unsigned total = factors.total_factors(); + + cout << "Got " << factors << endl; + cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl; + + SASSERT(random_polynomial[random_i][0][prime_i] == distinct); + SASSERT(random_polynomial[random_i][1][prime_i] == total); + + upolynomial::numeral_vector multiplied; + factors.multiply(multiplied); + bool equal = upm.eq(poly, multiplied); + cout << (equal ? "equal" : "not equal") << endl; + SASSERT(equal); + upm.reset(multiplied); + + // remove the temp + upm.reset(poly); + } + } +} + +static void tst_factor_enumeration() { + polynomial::numeral_manager nm; + polynomial::manager pm(nm); + + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + vector factors; + for (int i = 0; i < 5; ++ i) { + polynomial_ref factor(pm); + factor = x + i; + factors.push_back(factor); + } + + upolynomial::manager upm(nm); + + upolynomial::zp_manager upm_13(nm); + upm_13.set_zp(13); + upolynomial::zp_factors factors_13(upm_13); + + upolynomial::numeral constant; + nm.set(constant, 10); + factors_13.set_constant(constant); + + for (unsigned i = 0; i < 5; ++ i) { + upolynomial::numeral_vector ufactor; + upm_13.to_numeral_vector(factors[i], ufactor); + factors_13.push_back(ufactor, 1); + upm.reset(ufactor); + } + + cout << "All: " << factors_13 << endl; + + upolynomial::factorization_degree_set degrees(factors_13); + degrees.display(cout); cout << endl; + + scoped_mpz_vector left(nm), right(nm); + upolynomial::ufactorization_combination_iterator it(factors_13, degrees); + unsigned i = 0; + it.display(cout); + bool remove = false; + while (it.next(remove)) { + it.left(left); + it.right(right); + cout << "Left " << i << ": "; upm.display(cout, left); cout << endl; + cout << "Right " << i << ": "; upm.display(cout, right); cout << endl; + i ++; + if (i % 3 == 0) { + remove = true; + } else { + remove = false; + } + it.display(cout); + } + // SASSERT(i == 15); + + return; + + for (unsigned i = 0; i < 5; ++ i) { + factors_13.set_degree(i, factors_13.get_degree(i) + i); + } + cout << "Different: " << factors_13 << " of degree " << factors_13.get_degree() << endl; + upolynomial::factorization_degree_set degrees1(factors_13); + degrees1.display(cout); cout << endl; // [0, ..., 15] + + polynomial_ref tmp1 = (x^3) + 1; + polynomial_ref tmp2 = (x^5) + 2; + polynomial_ref tmp3 = (x^7) + 3; + upolynomial::numeral_vector up1, up2, up3; + upm_13.to_numeral_vector(tmp1, up1); + upm_13.to_numeral_vector(tmp2, up2); + upm_13.to_numeral_vector(tmp3, up3); + upolynomial::zp_factors tmp(upm_13); + tmp.push_back(up1, 1); + tmp.push_back(up2, 1); + tmp.push_back(up3, 1); + upm_13.reset(up1); + upm_13.reset(up2); + upm_13.reset(up3); + + cout << "Different: " << tmp << " of degree " << tmp.get_degree() << endl; + upolynomial::factorization_degree_set degrees2(tmp); + degrees2.display(cout); cout << endl; + + tmp1 = (x^2) + 1; + tmp2 = (x^10) + 2; + tmp3 = x + 3; + upm_13.to_numeral_vector(tmp1, up1); + upm_13.to_numeral_vector(tmp2, up2); + upm_13.to_numeral_vector(tmp3, up3); + tmp.clear(); + tmp.push_back(up1, 2); + tmp.push_back(up2, 1); + tmp.push_back(up3, 1); + cout << "Different: " << tmp << " of degree " << tmp.get_degree() << endl; + upm_13.reset(up1); + upm_13.reset(up2); + upm_13.reset(up3); + upolynomial::factorization_degree_set degrees3(tmp); + degrees3.display(cout); cout << endl; + degrees1.intersect(degrees3); + degrees1.display(cout); cout << endl; +} + +static void tst_factor_square_free_univariate_1(unsigned max_length) { + + polynomial::numeral_manager nm; + upolynomial::numeral test; + upolynomial::numeral p; + nm.set(test, -9); + nm.set(p, 5); + nm.mod(test, p, test); + + polynomial::manager pm(nm); + + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + cout << "R. = QQ['x']" << endl; + + // let's start with \prod (p_i x^{p_{i+1} - p_{i+1}) + unsigned n_primes = sizeof(primes)/sizeof(unsigned); + max_length = std::min(max_length, n_primes); + for(unsigned length = 1; length < max_length; ++ length) { + + // starting from prime_i going for length + for(unsigned start_i = 0; start_i < n_primes; ++ start_i) { + + polynomial_ref f(pm); + + bool first = true; + for (unsigned prime_i = 0; prime_i < length; ++ prime_i) { + int p1 = primes[(start_i + prime_i) % n_primes]; + int p2 = primes[(start_i + prime_i + 1) % n_primes]; + if (first) { + f = (p1*(x^p2) - p2); + first = false; + } else { + f = f*(p1*(x^p2) - p2); + } + } + + upolynomial::manager upm(nm); + scoped_mpz_vector f_u(nm); + upm.to_numeral_vector(f, f_u); + + cout << "factoring "; upm.display(cout, f_u); cout << endl; + cout << "expecting " << length << " factors "; + upolynomial::factors factors(upm); + bool ok = upolynomial::factor_square_free(upm, f_u, factors); + cout << "got " << factors << endl; + + SASSERT(factors.distinct_factors() == length); + } + } +} + +static void tst_factor_square_free_univariate_2() { + polynomial::numeral_manager nm; + polynomial::manager pm(nm); + + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + // Swinnerton-Dyer polynomials (irreducible, modular factors of degree at most 2) + polynomial_ref S1 = (x^2) - 2; + polynomial_ref S2 = (x^4) - 10*(x^2) + 1; + polynomial_ref S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576; + polynomial_ref S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225; + + vector S; + S.push_back(S1); + S.push_back(S2); + S.push_back(S3); + S.push_back(S4); + + upolynomial::manager upm(nm); + + // factor all the S_i them for all the prime numbers + for (unsigned S_i = 0; S_i < S.size(); ++ S_i) { + upolynomial::numeral_vector S_i_u; + upm.to_numeral_vector(S[S_i], S_i_u); + + cout << "Factoring "; upm.display(cout, S_i_u); cout << " over Z " << endl; + upolynomial::factors factors(upm); + upolynomial::factor_square_free(upm, S_i_u, factors); + + // check the result + cout << "Got " << factors << endl; + + // remove the temp + upm.reset(S_i_u); + } +} + +static void tst_factor_square_free_univariate_3() { + polynomial::numeral_manager nm; + polynomial::manager pm(nm); + + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + polynomial_ref deg70 = (x^70) - 6*(x^65) - (x^60) + 60*(x^55) - 54*(x^50) - 230*(x^45) + 274*(x^40) + 542*(x^35) - 615*(x^30) - 1120*(x^25) + 1500*(x^20) - 160*(x^15) - 395*(x^10) + 76*(x^5) + 34; + + upolynomial::manager upm(nm); + upolynomial::numeral_vector deg70_u; + + upm.to_numeral_vector(deg70, deg70_u); + + cout << "Factoring "; upm.display(cout, deg70_u); cout << " over Z " << endl; + upolynomial::factors factors(upm); + upolynomial::factor_square_free(upm, deg70_u, factors); + + cout << "Got " << factors << endl; + + upm.reset(deg70_u); +} + +void tst_factor_swinnerton_dyer_big(unsigned max) { + polynomial::numeral_manager nm; + polynomial::manager pm(nm); + + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + vector roots; + vector vars; + + unsigned n = std::min(max, static_cast(sizeof(primes)/sizeof(unsigned))); + for(unsigned prime_i = 0; prime_i < n; ++ prime_i) { + + int prime = primes[prime_i]; + + cout << "Computing Swinnerton-Dyer[" << prime_i + 1 << "]" << endl; + + polynomial_ref y(pm); + vars.push_back(pm.mk_var()); + y = pm.mk_polynomial(vars.back()); + + polynomial_ref p(pm); + p = (y^2) - prime; + roots.push_back(p); + + polynomial_ref computation = x; + for (unsigned i = 0; i < roots.size(); ++ i) { + polynomial_ref var(pm); + var = pm.mk_polynomial(vars[i]); + computation = computation - var; + } + + { + timeit timer(true, "computing swinnerton-dyer"); + + for (unsigned i = 0; i < roots.size(); ++ i) { + polynomial_ref tmp(pm); + pm.resultant(computation, roots[i], vars[i], tmp); + computation = tmp; + } + } + + cout << "Computed Swinnerton-Dyer[" << prime_i + 1 << "], degree = " << pm.total_degree(computation) << ", size = " << pm.size(computation) << endl; + + cout << "Starting factoring " << endl; + + { + timeit timer(true, "factoring swinnerton-dyer"); + + upolynomial::manager upm(nm); + scoped_mpz_vector sd_u(nm); + upm.to_numeral_vector(computation, sd_u); + upolynomial::factors factors(upm); + upolynomial::factor_square_free(upm, sd_u, factors); + cout << "Got " << factors.distinct_factors() << " factors" << endl; + } + + } +} + +static void tst_factor_square_free_multivariate_1(unsigned max_n) { +#if 0 + polynomial::numeral_manager nm; + upolynomial::numeral test; + upolynomial::numeral p; + nm.set(test, -9); + nm.set(p, 5); + nm.mod(test, p, test); + + polynomial::manager pm(nm); + + polynomial_ref x(pm); + x = pm.mk_polynomial(pm.mk_var()); + + polynomial_ref y(pm); + y = pm.mk_polynomial(pm.mk_var()); + + // lets start simple x^n - y^n + for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) { + unsigned prime = primes[prime_i]; + + if (prime > max_n) { + break; + } + + polynomial_ref f = (x^prime) - (y^prime); + cout << "factoring: " << f << endl; + + // factor + polynomial::factors factors(pm); + polynomial::factor_square_free_primitive(f, factors); + + cout << "got: " << factors << endl; + } +#endif +} + + +void tst_polynomial_factorization() { + + enable_trace("polynomial::factorization"); + // enable_trace("polynomial::factorization::bughunt"); + enable_trace("polynomial::factorization::multivariate"); + // enable_trace("upolynomial"); + + // Z_p square-free factorization tests + // tst_square_free_finite_1(); + + // Z_p factorization tests + // tst_factor_finite_1(); + // tst_factor_finite_2(); + // tst_factor_finite_3(); + + // Z factorization + // tst_factor_enumeration(); + // tst_factor_square_free_univariate_1(3); + // tst_factor_square_free_univariate_2(); + // tst_factor_square_free_univariate_3(); + // tst_factor_swinnerton_dyer_big(3); + + // Multivariate factorization + tst_factor_square_free_multivariate_1(3); +} diff --git a/test/prime_generator.cpp b/test/prime_generator.cpp new file mode 100644 index 000000000..a2610b35e --- /dev/null +++ b/test/prime_generator.cpp @@ -0,0 +1,42 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + prime_generator.cpp + +Abstract: + + Prime generator + +Author: + + Leonardo (leonardo) 2011-12-23 + +Notes: + +--*/ +#include"mpz.h" +#include"prime_generator.h" + +void tst_prime_generator() { + unsynch_mpz_manager m; + scoped_mpz sqrt_p(m); + + prime_generator gen; + for (unsigned i = 0; i < 10000; i++) { + uint64 p = gen(i); + std::cout << p << ", "; + if (i % 11 == 0) std::cout << "\n"; + std::cout.flush(); + if (p == 2) + continue; + m.set(sqrt_p, p); + m.root(sqrt_p, 2); + uint64 k = m.get_uint64(sqrt_p); + for (uint64 i = 2; i <= k; i++) { + SASSERT(p % i != 0); + } + } + std::cout << std::endl; +} diff --git a/test/proof_checker.cpp b/test/proof_checker.cpp new file mode 100644 index 000000000..12a5245e6 --- /dev/null +++ b/test/proof_checker.cpp @@ -0,0 +1,29 @@ +#include "proof_checker.h" +#include "ast_ll_pp.h" + +void tst_checker1() { + ast_manager m(PGM_FINE); + expr_ref a(m); + proof_ref p1(m), p2(m), p3(m), p4(m); + bool result; + expr_ref_vector side_conditions(m); + + a = m.mk_const(symbol("a"), m.mk_bool_sort()); + p1 = m.mk_hypothesis(a.get()); + p2 = m.mk_hypothesis(m.mk_not(a.get())); + ast_ll_pp(std::cout, m, p1.get()); + ast_ll_pp(std::cout, m, p2.get()); + proof* proofs[2] = { p1.get(), p2.get() }; + p3 = m.mk_unit_resolution(2, proofs); + p4 = m.mk_lemma(p3.get(), a.get()); + ast_ll_pp(std::cout, m, p4.get()); + proof_checker checker(m); + p4 = m.mk_lemma(p3.get(), m.mk_or(a.get(), m.mk_not(a.get()))); + ast_ll_pp(std::cout, m, p4.get()); + result = checker.check(p4.get(), side_conditions); + SASSERT(result); +} + +void tst_proof_checker() { + tst_checker1(); +} diff --git a/test/qe_defs.cpp b/test/qe_defs.cpp new file mode 100644 index 000000000..0620a3b59 --- /dev/null +++ b/test/qe_defs.cpp @@ -0,0 +1,86 @@ +#include "arith_decl_plugin.h" +#include "qe.h" +#include "ast_pp.h" +#include "smtparser.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; + m.register_decl_plugins(); + 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/test/quant_elim.cpp b/test/quant_elim.cpp new file mode 100644 index 000000000..0947b5583 --- /dev/null +++ b/test/quant_elim.cpp @@ -0,0 +1,485 @@ +#include "ast.h" +#include "front_end_params.h" +#include "simplifier.h" +#include "qe.h" +#include "basic_simplifier_plugin.h" +#include "arith_simplifier_plugin.h" +#include "array_simplifier_plugin.h" +#include "bv_simplifier_plugin.h" +#include "ast_pp.h" +#include "smtlib.h" +#include "smtparser.h" +#include "lbool.h" +#include + + +static void test_qe(ast_manager& m, lbool expected_outcome, expr* fml, char const* option) { + + // enable_trace("bit2int"); + //enable_trace("gomory_cut"); + enable_trace("final_check_arith"); + enable_trace("arith_final_check"); + //enable_trace("arith_branching"); + enable_trace("theory_arith_int"); + enable_trace("presburger"); + enable_trace("quant_elim"); + // enable_trace("arith_simplifier_plugin"); + // enable_trace("non_linear"); + // enable_trace("gomory_cut_detail"); + // enable_trace("arith"); + // enable_trace("bv"); + // enable_trace("after_search"); + // enable_trace("bv_bit_prop"); + + simplifier simp(m); + front_end_params params; + params.m_quant_elim = true; + + std::cout << mk_pp(fml, m) << "\n"; + qe::expr_quant_elim qe(m, params); + expr_ref result(m); + qe(m.mk_true(), fml, result); + std::cout << " -> " << mk_pp(result, m) << " " << expected_outcome << "\n"; + if (expected_outcome == l_true && !m.is_true(result)) { + std::cout << "ERROR: expected true, instead got " << ast_pp(result, m).c_str() << "\n"; + //exit(-1); + } + if (expected_outcome == l_false && !m.is_false(result)) { + std::cout << "ERROR: expected false, instead got " << ast_pp(result, m).c_str() << "\n"; + //exit(-1); + } +} + +static void test_formula(lbool expected_outcome, char const* fml) { + ast_manager m; + m.register_decl_plugins(); + scoped_ptr parser = smtlib::parser::create(m); + parser->initialize_smtlib(); + + std::ostringstream buffer; + buffer << "(benchmark presburger :status unknown :logic AUFLIA :extrapreds ((p1) (p2) (p3)) " + << ":extrafuns ((a Int) (b Int))\n" + << ":datatypes ((list (nil) (cons (hd Int) (tl list))))\n" + << ":datatypes ((cell (cnil) (ccons (car cell) (cdr cell))))\n" + << ":extrasorts (U)\n" + << ":extrafuns ((f U U))\n" + << ":formula " << fml << ")"; + 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_qe(m, expected_outcome, *it, 0); + } +} + +void tst_quant_elim() { + + test_formula(l_false,"(forall (x Int) (y Int) (or (= x 0) (< (* 5 y) (* 6 x)) (> (* 5 y) (* 6 x))))"); + + test_formula(l_false, "(forall (a Int) (b Int) (exists (x Int) (and (< a (* 20 x)) (< (* 20 x) b))))"); + + test_formula(l_undef, "(exists (u U) (= (f u) u))"); + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 7 v))))))))"); + + + test_formula(l_true, "(forall (x Int) (y Int) (implies (= (* 6 x) (* 5 y)) (exists (d Int) (= y (* 3 d)))))"); + + test_formula(l_undef, "(exists (x Int) (= (- a (mod x 4)) 0))"); + // return; + + + // test_formula(l_true, "(exists (x Int) (y Int) (= 1 (+ (* 5 x) (* 3 y))))"); + + + test_formula(l_undef, "(exists (a Bool) (b Bool) (or (and p1 a) (and p2 (not b))))"); + + + test_formula(l_false, + "(forall (x Int) (q1 Int) (q2 Int) (r1 Int) (r2 Int) " + " (implies " + " (and (< x 4699) " + " (= (* 2622 x) (+ (* 65536 q1) r1)) " + " (<= 0 q1) " + " (<= 0 r1) " + " (< r1 65536) " + " (= x (+ (* 100 q2) r2)) " + " (<= 0 q2) " + " (<= 0 r2) " + " (< r2 100)) " + " (= q1 q2)))"); + + + + test_formula(l_undef, + "(forall (l list) (or (= l nil) (exists (x Int) (ll list) (= l (cons x ll)))))"); + + + + + + + test_formula(l_false, "(exists (x Real) (forall (y Real) (>= x y)))"); + test_formula(l_false, "(exists (x Real) (forall (y Real) (> x y)))"); + test_formula(l_false, "(exists (x Real) (forall (y Real) (< x y)))"); + test_formula(l_false, "(exists (x Real) (forall (y Real) (<= x y)))"); + + test_formula(l_true, "(exists (x Real) (exists (y Real) (< x y)))"); + test_formula(l_true, "(exists (x Real) (exists (y Real) (<= x y)))"); + test_formula(l_true, "(exists (x Real) (exists (y Real) (>= x y)))"); + test_formula(l_true, "(exists (x Real) (exists (y Real) (> x y)))"); + + test_formula(l_true, "(forall (x Real) (exists (y Real) (< x y)))"); + test_formula(l_true, "(forall (x Real) (exists (y Real) (<= x y)))"); + test_formula(l_true, "(forall (x Real) (exists (y Real) (>= x y)))"); + test_formula(l_true, "(forall (x Real) (exists (y Real) (> x y)))"); + + test_formula(l_false, "(forall (x Real) (forall (y Real) (< x y)))"); + test_formula(l_false, "(forall (x Real) (forall (y Real) (<= x y)))"); + test_formula(l_false, "(forall (x Real) (forall (y Real) (>= x y)))"); + test_formula(l_false, "(forall (x Real) (forall (y Real) (> x y)))"); + + + + + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 5 v))))))))"); + + + test_formula(l_false, "(forall (d Int) (implies (>= d 0) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (+ (* 3 x) (* 5 y)))))))"); + + test_formula(l_true, "(forall (y Int) (implies (exists (d Int) (= y (* 6 d))) (exists (d Int) (= y (* 2 d)))))"); + + test_formula(l_true, "(forall (y Int) (implies (exists (d Int) (= y (* 65 d))) (exists (d Int) (= y (* 5 d)))))"); + + + test_formula(l_true, + "(exists (z Int) (forall (w Int) (exists (x Int) (y Int) " + " (or (and (< (+ (* 3 x) w) 2) (< 1 (- (+ (* 2 x) z) w))) " + " (and (< z (* 2 y)) (> z y))))))"); + + + test_formula(l_true, "(exists (x Int) (y Int) (and (> x 0) (>= y 0) (= 1 (- (* 3 x) (* 5 y)))))"); + + + test_formula(l_true, + "(exists (a Int) (b Int) " + " (and (not (= a 1)) (= a b) (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a))))))"); + + + + test_formula(l_true, + "(forall (x Int) (iff (and (not (= 0 (mod x 2))) (= 0 (mod (- x 1) 3))) " + " (or (= 0 (mod (- x 1) 12)) (= 0 (mod (- x 7) 12)))))"); + + + + + + + test_formula(l_false, "(exists (x Int) (and (< (* 3 x) 2) (< 1 (* 2 x))))"); + + + test_formula(l_true, "(forall (x Int) (y Int) (or (= 0 (mod x 5)) (not (= (* 6 x) (* 5 y)))))"); + + + test_formula(l_false, "(forall (x Int) (exists (y Int) (= x (* 2 y))))"); + test_formula(l_false, + "(forall (x Int) " + " (implies (not (= 0 (mod x 2))) " + " (or (= 0 (mod (- x 1) 4)) " + " (= 0 (mod (- x 1) 8)) " + " (= 0 (mod (- x 3) 8)) " + " (= 0 (mod (- x 1) 6)) " + " (= 0 (mod (- x 1) 14)) " + " (= 0 (mod (- x 9) 14)) " + " (= 0 (mod (- x 11) 14)) " + " (= 0 (mod (- x 5) 24)) " + " (= 0 (mod (- x 11) 24))))) "); + + test_formula(l_true, + "(forall (x Int) (iff (and (not (= 0 (mod x 2))) (= 0 (mod (- x 1) 3))) " + " (or (= 0 (mod (- x 1) 12)) (= 0 (mod (- x 7) 12)))))"); + + + + + test_formula(l_false, + "(forall (d Int) (c Int) (b Int) " + " (and (= c 0) (= d (* b c)) (= d 0)))"); + + + + + //return; + + test_formula(l_undef, "(exists (k!12 Int) (k!11 Int) (and (= (ite (= k!11 0) 0 k!11) k!11) (not (= (ite (= k!12 (+ 1)) 1 0) 0))))"); + //return; + + + + + + test_formula(l_false, + "(forall (a Int) (b Int) (x Int) (y Int) (z Int) " + " (implies (and (= (+ a 2) b) (= x (+ 1 (- b a))) (= y (- b 2)) (= z 3)) false))"); + + + + test_formula(l_false, + "(exists (a Int) (b Int) " + " (and (> a 1) (> b 1) (= a b) (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a))))))"); + + + + test_formula(l_true, "(forall (d Int) (implies true (exists (x Int) (y Int) (and true true (= d (+ (* 3 x) (* 5 y)))))))"); + + // This one takes forever without bit-vectors + test_formula(l_true, "(forall (d Int) (implies (>= d 8) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (+ (* 3 x) (* 5 y)))))))"); + + test_formula(l_true, "(forall (d Int) (implies (>= d 0) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (- (* 3 x) (* 5 y)))))))"); + + + test_formula(l_false, "(exists (x Int) (y Int) (z Int) (= 1 (- (* 4 x) (* 6 y))))"); + + //return; + + + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 8 v))))))))"); + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 8 v))))))))"); + +#if 0 + + // too slow. + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 7 u) (* 8 v))))))))"); + + +#endif + + test_formula(l_true, "(forall (x Int) (exists (y Int) (and (<= (* 2 y) x) (< x (* 2 (+ y 1))))))"); + + + test_formula(l_false, "(exists (x Int) (y Int) (and (> y 0) (> y (* 2 x)) (< y (+ x 2)) (= 0 (mod y 2))))"); + + test_formula(l_false, "(exists (x Int) (and (< (* 3 x) 3) (< 1 (* 2 x))))"); + + + test_formula(l_true, "(exists (x Int) (and (< (* 3 x) 4) (< 1 (* 2 x))))"); + + test_formula(l_false, "(exists (x Int) (and (< (+ (* 3 x) 1) 10) (> (- (* 7 x) 6) 7) (= 0 (mod x 3))))"); + + + test_formula(l_false, "(exists (x Int) (y Int) (and (< (- 1 (* 5 y)) x) (< (+ 1 y) (* 13 x)) (< (+ x 2) 0) (> y 0)))"); + + test_formula(l_false, "(exists (x Int) (y Int) (and (< (- 1 (* 5 y)) x) (< (+ 1 y) (* 13 x)) (< x -2)))"); + + test_formula(l_true, "(exists (w Int) (z Int) (y Int) (x Int) (and (< (- 1 (* 5 y)) (+ x (* 2 z))) (< (+ 1 y w (* -4 z)) (* 13 x)) (< x -2) (> z 0)))"); + + + + test_formula(l_true, + "(forall (w Int) " + " (exists (z Int) (y Int) (x Int) " + " (and (< (- 1 (* 5 y)) (+ x (* 2 z))) " + " (< (- (+ 1 y) (* 4 z)) (* 13 x)) " + " (< x -2) (> z 0) (< x 10)))) "); + + + test_formula(l_false, + "(forall (d Int) (c Int) (b Int) " + " (and (= c 0) (= d (* b c)) (= d 4)))"); + + test_formula(l_undef, + "(exists (d Int) (c Int) (b Int) " + " (and (= c 0) (= d (* b c)) (= d 0)))"); + + test_formula(l_undef, + "(exists (d Int) (c Int) (b Int) " + " (and (= c 0) (= d (* b c)) (= d 4)))"); + + + + // Tests from Harrison's HOL-light version of Cooper. + + test_formula(l_true, "(forall (x Int) (y Int) (not (= (+ 1 (* 2 x)) (* 2 y))))"); + + + test_formula(l_false, "(exists (x Int) (y Int) (= 1 (- (* 4 x) (* 6 y))))"); + + + + // "(forall (x Int) (implies (< b x) (<= a x)))" + // "(forall (x Int) (implies (< b x) (< a x)))" + + + test_formula(l_false, "(forall (d Int) (implies (>= d 0) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (+ (* 3 x) (* 5 y)))))))"); + + test_formula(l_true, "(forall (d Int) (implies true (exists (x Int) (y Int) (and true true (= d (+ (* 3 x) (* 5 y)))))))"); + + // This one takes forever without bit-vectors + test_formula(l_true, "(forall (d Int) (implies (>= d 8) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (+ (* 3 x) (* 5 y)))))))"); + + test_formula(l_true, "(forall (d Int) (implies (>= d 0) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (- (* 3 x) (* 5 y)))))))"); + + test_formula(l_true, "(exists (x Int) (y Int) (and (> x 0) (>= y 0) (= 1 (- (* 3 x) (* 5 y)))))"); + + test_formula(l_false, "(exists (x Int) (y Int) (z Int) (= 1 (- (* 4 x) (* 6 y))))"); + + // "(forall (x Int) (implies (< b (* 3 x)) (a < (* 3 x))))" + + test_formula(l_false, "(forall (x Int) (y Int) (implies (<= x y) (< (+ 1 (* 2 x)) (* 2 y))))"); + + + test_formula(l_true, "(forall (x Int) (y Int) (z Int) (implies (= (+ 1 (* 2 x)) (* 2 y)) (> (+ x y z) 129)))"); + + // Formula examples from Cooper's paper. + + + test_formula(l_true, "(forall (a Int) (exists (b Int) (or (< a (+ (* 4 b) (* 3 a))) (and (not (< a b)) (> a (+ b 1))))))"); + + test_formula(l_false, "(exists (y Int) (forall (x Int) (and (> (+ x (* 5 y)) 1) (> (- (* 13 x) y) 1) (< (+ x 2) 0))))"); + + // Harrison's formulas: + + test_formula(l_false, "(forall (x Int) (y Int) (implies (and (>= x 0) (>= y 0)) (or (< (- (* 12 x) (* 8 y)) 0) (> (- (* 12 x) (* 8 y)) 2))))"); + + + // test_formula(l_true, "(exists (x Int) (y Int) (= 1 (+ (* 5 x) (* 3 y))))"); + + + test_formula(l_false, "(exists (x Int) (y Int) (= 1 (+ (* 5 x) (* 10 y))))"); + + test_formula(l_true, "(exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= 1 (- (* 5 x) (* 6 y)))))"); + + test_formula(l_true, "(exists (x Int) (y Int) (z Int) (w Int) (= 1 (+ (* 2 w) (* 3 x) (* 4 y) (* 5 z))))"); + + test_formula(l_true, "(exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= 1 (- (* 5 x) (* 3 y)))))"); + + test_formula(l_true, "(exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= 1 (- (* 3 x) (* 5 y)))))"); + + test_formula(l_false,"(exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= 1 (- (* 6 x) (* 3 y)))))"); + + test_formula(l_true, "(forall (x Int) (y Int) (or (= 0 (mod x 5)) (= 0 (mod y 6)) (not (= (* 6 x) (* 5 y)))))"); + + + test_formula(l_false,"(forall (x Int) (y Int) (or (not (= (* 6 x) (* 5 y)))))"); + + + + // Positive variant of the Bezout theorem (see the exercise). *) + + test_formula(l_true, "(forall (z Int) (implies (> z 7) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= (+ (* 3 x) (* 5 y)) z)))))"); + + test_formula(l_false,"(forall (z Int) (implies (> z 2) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= (+ (* 3 x) (* 5 y)) z)))))"); + + test_formula(l_true, + "(forall (z Int) (implies (<= z 7) " + " (iff (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= z (+ (* 3 x) (* 5 y))))) " + " (not (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= (- 7 z) (+ (* 3 x) (* 5 y))))))))) "); + + // Basic result about congruences. + + test_formula(l_true, + "(forall (x Int) " + " (iff (and (not (exists (m Int) (= x (* 2 m)))) (exists (m Int) (= x (+ (* 3 m) 1)))) " + " (or (exists (m Int) (= x (+ (* 12 m) 1))) (exists (m Int) (= x (+ (* 12 m) 7))))))"); + + + + + + // Inspired by the Collatz conjecture. + + test_formula(l_false, + "(forall (a Int) (b Int) (x Int) (y Int) (z Int) " + " (implies (and (= (+ a 2) b) (= x (+ 1 (- b a))) (= y (- b 2)) (= z 3)) false))"); + + test_formula(l_true, + "(exists (a Int) (b Int) " + " (and (not (= a 1)) (= a b) (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a))))))"); + + + test_formula(l_false, + "(exists (a Int) (b Int) " + " (and (> a 1) (> b 1) (= a b) (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a))))))"); + + test_formula(l_false, + "(exists (a Int) (b Int) " + " (and (> a 1) (> b 1) " + " (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a)))) " + " (or (= b (* 2 a)) (= (* 2 a) (+ 1 (* 3 b))))))"); + +#if 0 + // Bob Constable's "stamp problem". + + test_formula(l_true, + "(forall (x Int) (implies (>= x 8) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 5 v)))))))"); + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 5 v))))))))"); + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 7 v))))))))"); + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 8 v))))))))"); + + test_formula(l_true, + "(exists (l Int) (forall (x Int) (implies (>= x l) " + " (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 7 u) (* 8 v))))))))"); +#endif + + // Example from reciprocal mult: (2622 * x)>>16 = x/100 within a range. + + + test_formula(l_true, + "(forall (x Int) (y Int) " + " (iff (exists (d Int) (= (+ x y) (* 2 d))) " + " (iff (exists (d Int) (= x (* 2 d))) (exists (d Int) (= y (* 2 d))))))"); + + test_formula(l_true, + "(forall (n Int) " + " (implies (and (< 0 n) (< n 2400)) " + " (or (and (<= n 2) (<= 2 (* 2 n))) " + " (and (<= n 3) (<= 3 (* 2 n))) " + " (and (<= n 5) (<= 5 (* 2 n))) " + " (and (<= n 7) (<= 7 (* 2 n))) " + " (and (<= n 13) (<= 13 (* 2 n))) " + " (and (<= n 23) (<= 23 (* 2 n))) " + " (and (<= n 43) (<= 43 (* 2 n))) " + " (and (<= n 83) (<= 83 (* 2 n))) " + " (and (<= n 163) (<= 163 (* 2 n))) " + " (and (<= n 317) (<= 317 (* 2 n))) " + " (and (<= n 631) (<= 631 (* 2 n))) " + " (and (<= n 1259) (<= 1259 (* 2 n))) " + " (and (<= n 2503) (<= 2503 (* 2 n)))))) "); + + + + + memory::finalize(); +#ifdef _WINDOWS + _CrtDumpMemoryLeaks(); +#endif + exit(0); +} + + diff --git a/test/quant_solve.cpp b/test/quant_solve.cpp new file mode 100644 index 000000000..096ae33de --- /dev/null +++ b/test/quant_solve.cpp @@ -0,0 +1,157 @@ +#include "ast.h" +#include "front_end_params.h" +#include "qe.h" +#include "arith_decl_plugin.h" +#include "ast_pp.h" +#include "lbool.h" +#include +#include "expr_replacer.h" +#include "smt_solver.h" + +static void validate_quant_solution(ast_manager& m, app* x, expr* fml, expr* t, expr* new_fml) { + // verify: + // new_fml <=> fml[t/x] + scoped_ptr rep = mk_expr_simp_replacer(m); + expr_substitution sub(m); + sub.insert(x, t); + 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)); + 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); +} + +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); + 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()); + } + } + else { + std::cout << "failed\n"; + } +} + +static void test_quant_solver_rec(ast_manager& m, unsigned num_vars, app* const* xs, expr* fml) { + if (num_vars == 0) { + return; + } + 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); + 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()); + } + } + } + else { + std::cout << "failed\n"; + } +} + + + +static void test_quant_solve1() { + ast_manager m; + arith_util ar(m); + + m.register_decl_plugins(); + 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()); + + + 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()); + + 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()); +} + + +void tst_quant_solve() { + + test_quant_solve1(); + + memory::finalize(); +#ifdef _WINDOWS + _CrtDumpMemoryLeaks(); +#endif + exit(0); +} + + diff --git a/test/random.cpp b/test/random.cpp new file mode 100644 index 000000000..a813b0f08 --- /dev/null +++ b/test/random.cpp @@ -0,0 +1,35 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + random.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2007-08-24. + +Revision History: + +--*/ + +#include"util.h" +#include"trace.h" + +static void tst1() { + random_gen r(0); + TRACE("random", + for (unsigned i = 0; i < 1000; i++) { + tout << r() << "\n"; + }); +} + +void tst_random() { + tst1(); +} + + diff --git a/test/rational.cpp b/test/rational.cpp new file mode 100644 index 000000000..9cbcdb00e --- /dev/null +++ b/test/rational.cpp @@ -0,0 +1,481 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_rational.cpp + +Abstract: + + Test rationals + +Author: + + Leonardo de Moura (leonardo) 2006-09-26. + +Revision History: + +--*/ +#include +#include"vector.h" +#include"rational.h" +#include"trace.h" +#include"ext_gcd.h" +#include"timeit.h" + +static void tst1() { + rational r1(1); + rational r2(1,2); + rational r3(2,4); + SASSERT(r2 == r3); + SASSERT(r1 != r2); + SASSERT(r2 + r3 == r1); + SASSERT(r1.is_pos()); + SASSERT((r2 - r1).is_neg()); + SASSERT((r2 - r3).is_zero()); + SASSERT(floor(r2).is_zero()); + SASSERT(ceil(r2).is_one()); + // std::cout << "-r2: " << (-r2) << ", floor(-r2):" << floor(-r2) << "\n"; + SASSERT(floor(-r2).is_minus_one()); + SASSERT(ceil(-r2).is_zero()); + SASSERT(floor(r1) == r1); + SASSERT(ceil(r1) == r1); + rational r4(3,5); + SASSERT(r3 * r4 == rational(3, 10)); + SASSERT(r3 / r4 == rational(5, 6)); + rational r5(2,3); + SASSERT(r4 * r5 == rational(2, 5)); + --r2; + SASSERT(r2 == -r3); + r2.neg(); + SASSERT(r2 == r3); + --r2; + r2 = abs(r2); + SASSERT(r2 == r3); + --r2; + ++r2; + SASSERT(r2 == r3); + SASSERT(r2 == abs(r2)); + SASSERT(r4 * rational(1) == r4); + SASSERT((r4 * rational(0)).is_zero()); + SASSERT(r4 * rational(-1) == -r4); + SASSERT(rational(1) * r4 == r4); + SASSERT((rational(0) * r4).is_zero()); + SASSERT(rational(-1) * r4 == -r4); + SASSERT(r4 + rational(0) == r4); + SASSERT(ceil(r4).is_one()); + // std::cout << "r3: " << r3 << ", r4: " << r4 << ", -r4: " << -r4 << ", r3 / (-r4): " << (r3 / (-r4)) << "\n"; + SASSERT(r3 / (-r4) == rational(5,-6)); + SASSERT(div(rational(7), rational(2)) == rational(3)); + SASSERT(rational(7) % rational(4) == rational(3)); + SASSERT(div(rational(7), rational(-2)) == rational(-3)); + SASSERT(rational(3) + rational(5) == rational(8)); + SASSERT(rational("13/10") + rational("7/10") == rational(2)); + SASSERT(rational("100/20") == rational(5)); + SASSERT(gcd(rational(12), rational(8)) == rational(4)); + SASSERT(ceil(rational(-3,2)) == rational(-1)); + SASSERT(floor(rational(-3,2)) == rational(-2)); + SASSERT(ceil(rational(3,2)) == rational(2)); + SASSERT(floor(rational(3,2)) == rational(1)); + SASSERT(rational(3).is_pos()); + SASSERT(rational(0).is_nonneg()); + SASSERT(rational(3).is_pos()); + SASSERT(rational(3).is_nonneg()); + SASSERT(rational(0).is_nonneg()); + SASSERT(!rational(3).is_zero()); + SASSERT(!rational(-3).is_zero()); + SASSERT(rational(0).is_zero()); + SASSERT(rational(1).is_one()); + SASSERT(!rational(2).is_one()); + SASSERT(rational(3,4) >= rational(2,8)); + SASSERT(rational(3,4) <= rational(7,8)); + SASSERT(rational(3,4) <= rational(3,4)); + SASSERT(rational(3,4) >= rational(3,4)); + SASSERT(rational(3,4) > rational(2,8)); + SASSERT(rational(3,4) < rational(7,8)); + TRACE("rational", tout << rational(3,4) << "\n";); + TRACE("rational", tout << rational(7,9) << "\n";); + TRACE("rational", tout << rational(-3,7) << "\n";); + TRACE("rational", tout << rational(5,8) << "\n";); + TRACE("rational", tout << rational(4,2) << "\n";); + SASSERT(rational(3) + rational(2) == rational(5)); + SASSERT(rational(3) - rational(2) == rational(1)); + SASSERT(rational(3) * rational(2) == rational(6)); + SASSERT(rational(6) / rational(2) == rational(3)); + SASSERT(rational(6) % rational(4) == rational(2)); + SASSERT(power(rational(2),0) == rational(1)); + SASSERT(power(rational(2),1) == rational(2)); + SASSERT(power(rational(2),3) == rational(8)); +} + +static void tst2() { + rational r1("10000000000000000000000000000000000"); + rational r2("10000000000000000000000000000000000/3"); + rational r3("20000000000000000000000000000000000/6"); + TRACE("rational", tout << r1 << std::endl;); + TRACE("rational", tout << r2 << std::endl;); + TRACE("rational", tout << r3 << std::endl;); + + SASSERT(r2 == r3); + SASSERT(r1 != r2); + SASSERT(rational(2)*r2 + r3 == r1); + SASSERT(r1.is_pos()); + SASSERT((r2 - r1).is_neg()); + SASSERT((r2 - r3).is_zero()); + // std::cout << "===> " << floor(r2) << "\n"; + { + rational r0("1/3000000000000000000000000"); + SASSERT(ceil(r0).is_one()); + SASSERT(floor(-r0).is_minus_one()); + SASSERT(ceil(-r0).is_zero()); + } + SASSERT(floor(r1) == r1); + SASSERT(ceil(r1) == r1); + rational r4("300000000/5"); + SASSERT(rational(1,2) * r4 == rational("300000000/10")); + SASSERT(rational(1,2) / r4 == rational("5/600000000")); + rational r5(2,3); + SASSERT(r4 * r5 == rational("200000000/5")); + rational r6("10000000000000000000000000000000003/3"); + --r6; + SASSERT(r6 == r2); + r6.neg(); + SASSERT(r6 != r2); + SASSERT(abs(r6) == r2); + --r2; + ++r2; + r2.neg(); + SASSERT(r2 == r6); + SASSERT(r6 * rational(1) == r6); + SASSERT((r6 * rational(0)).is_zero()); + SASSERT(r6 * rational(-1) == -r6); + SASSERT(rational(1) * r6 == r6); + SASSERT((rational(0) * r6).is_zero()); + SASSERT(rational(-1) * r6 == -r6); + SASSERT(r6 + rational(0) == r6); + + SASSERT(rational("300000000000000").is_pos()); + SASSERT(rational("0000000000000000000").is_nonneg()); + SASSERT(rational("0000000000000000000").is_nonpos()); + SASSERT(rational("3000000000000000000/2").is_pos()); + SASSERT(rational("3000000000000000000/2").is_nonneg()); + SASSERT((-rational("3000000000000000000/2")).is_neg()); + SASSERT(!rational("3000000000000000000/2").is_neg()); + SASSERT(!rational("3000000000000000000/2").is_zero()); + SASSERT(!rational("3000000000000000000/2").is_one()); + SASSERT(rational("99999999999/2") >= rational("23/2")); + SASSERT(rational("99999999999/2") > rational("23/2")); + SASSERT(rational("23/2") <= rational("99999999999/2")); + SASSERT(rational("23/2") < rational("99999999999/2")); + SASSERT(!(rational("99999999999/2") < rational("23/2"))); + + + rational int64_max("9223372036854775807"); + rational int64_min(-int64_max - rational(1)); + // is_int64 + SASSERT(int64_max.is_int64()); + SASSERT(int64_min.is_int64()); + SASSERT(rational(0).is_int64()); + SASSERT(rational(1).is_int64()); + SASSERT(rational(-1).is_int64()); + SASSERT(!(int64_max + rational(1)).is_int64()); + SASSERT(!(int64_min - rational(1)).is_int64()); + + // is_uint64 + SASSERT(int64_max.is_uint64()); + SASSERT(!int64_min.is_uint64()); + SASSERT(rational(0).is_uint64()); + SASSERT(rational(1).is_uint64()); + SASSERT(!rational(-1).is_uint64()); + SASSERT((int64_max + rational(1)).is_uint64()); + SASSERT(!(int64_min - rational(1)).is_uint64()); + + rational uint64_max(rational(1) + (rational(2) * int64_max)); + SASSERT(uint64_max.is_uint64()); + + // get_int64, get_uint64 + uint64 u1 = uint64_max.get_uint64(); + uint64 u2 = UINT64_MAX; + SASSERT(u1 == u2); + std::cout << "int64_max: " << int64_max << ", INT64_MAX: " << INT64_MAX << ", int64_max.get_int64(): " << int64_max.get_int64() << ", int64_max.get_uint64(): " << int64_max.get_uint64() << "\n"; + SASSERT(int64_max.get_int64() == INT64_MAX); + SASSERT(int64_min.get_int64() == INT64_MIN); + + // extended Euclid: + +} + +void tst3() { + rational n1 = power(rational(2), 32); + TRACE("rational", tout << "n1: " << n1 << "\n";); + rational n2 = div(n1, rational(2)); + rational n3 = div(rational(2), n2); + TRACE("rational", + tout << "n1: " << n1 << "\n"; + tout << "n2: " << n2 << "\n"; + tout << "n3: " << n3 << "\n";); + rational n4 = n1 - rational(3); + rational n5 = div(n4, rational(2)); + TRACE("rational", + tout << "n4: " << n4 << "\n"; + tout << "n5: " << n5 << "\n";); + SASSERT(n5 == rational("2147483646")); +} + +void tst4() { + rational n1("4294967293"); + TRACE("rational", tout << "n1: " << n1 << "\n";); + rational n2 = div(n1, rational(2)); +} + +void tst5() { + rational n1(1); + n1.neg(); + rational n2("4294967295"); + n1 /= n2; + TRACE("rational", tout << n1 << " " << n2 << " " << n1.is_big() << " " << n2.is_big() << "\n";); + n1 *= n2; + TRACE("rational", tout << "after: " << n1 << " " << n2 << "\n";); + SASSERT(n1.is_minus_one()); +} + +void tst6() { + rational t1(5); + rational t2(3); + rational a, b, g; + + g = gcd(t1, t2, a, b); + + t1 = rational(15); + t2 = rational(25); + + g = gcd(t1, t2, a, b); + t1.neg(); + g = gcd(t1, t2, a, b); + t2.neg(); + g = gcd(t1, t2, a, b); + t1.neg(); + g = gcd(t1, t2, a, b); + + std::swap(t1, t2); + + g = gcd(t1, t2, a, b); + t1.neg(); + g = gcd(t1, t2, a, b); + t2.neg(); + g = gcd(t1, t2, a, b); + t1.neg(); + g = gcd(t1, t2, a, b); + +} + +class rational_tester { +public: + static void tst1() { + rational n1(-1); + rational n2(8); + SASSERT((n1 % n2).is_minus_one()); + SASSERT(mod(n1, n2) == rational(7)); + } + + static void tst_hash(int val) { + rational n1(val); + rational n2("10203939394995449949494394932929"); + rational n3(val); + n2 = n3; + SASSERT(n1.hash() == n2.hash()); + } + + static void tst2() { + tst_hash(0); + for (int i = 0; i <= 10000; i++) { + int r = rand() % INT_MAX; + if (rand()%2 == 1) r = -r; + tst_hash(r); + } + } +}; + +static void tst7() { + rational p; + p = power(rational(2), 32); + for (unsigned i = 1; i < 1000; i++) { + rational n(i); + rational x; + rational y; + rational gcd; + extended_gcd(n, p, gcd, x, y); + TRACE("gcd", tout << n << " " << p << ": " << gcd << " " << x << " " << y << "\n";); + SASSERT(!mod(n, rational(2)).is_one() || mod(n * x, p).is_one()); + } +} + +static void tst8() { + rational r; + SASSERT(!rational(-4).is_int_perfect_square(r) && r.is_zero()); + SASSERT(!rational(-3).is_int_perfect_square(r) && r.is_zero()); + SASSERT(!rational(-2).is_int_perfect_square(r) && r.is_zero()); + SASSERT(!rational(-1).is_int_perfect_square(r) && r.is_zero()); + SASSERT(rational(0).is_int_perfect_square(r) && r.is_zero()); + SASSERT(rational(1).is_int_perfect_square(r) && r.is_one()); + SASSERT(!rational(2).is_int_perfect_square(r) && r == rational(2)); + SASSERT(!rational(3).is_int_perfect_square(r) && r == rational(2)); + SASSERT(rational(4).is_int_perfect_square(r) && r == rational(2)); + SASSERT(!rational(5).is_int_perfect_square(r) && r == rational(3)); + SASSERT(!rational(6).is_int_perfect_square(r) && r == rational(3)); + SASSERT(!rational(7).is_int_perfect_square(r) && r == rational(3)); + SASSERT(!rational(8).is_int_perfect_square(r) && r == rational(3)); + SASSERT(rational(9).is_int_perfect_square(r) && r == rational(3)); + SASSERT(!rational(10).is_int_perfect_square(r) && r == rational(4)); + SASSERT(!rational(11).is_int_perfect_square(r) && r == rational(4)); + SASSERT(!rational(12).is_int_perfect_square(r) && r == rational(4)); + SASSERT(!rational(13).is_int_perfect_square(r) && r == rational(4)); + SASSERT(!rational(14).is_int_perfect_square(r) && r == rational(4)); + SASSERT(!rational(15).is_int_perfect_square(r) && r == rational(4)); + SASSERT(rational(16).is_int_perfect_square(r) && r == rational(4)); + SASSERT(!rational(17).is_int_perfect_square(r) && r == rational(5)); + SASSERT(!rational(18).is_int_perfect_square(r) && r == rational(5)); + SASSERT(!rational(19).is_int_perfect_square(r) && r == rational(5)); + SASSERT(!rational(20).is_int_perfect_square(r) && r == rational(5)); + SASSERT(!rational(21).is_int_perfect_square(r) && r == rational(5)); + SASSERT(!rational(22).is_int_perfect_square(r) && r == rational(5)); + SASSERT(!rational(23).is_int_perfect_square(r) && r == rational(5)); + SASSERT(!rational(24).is_int_perfect_square(r) && r == rational(5)); + SASSERT(rational(25).is_int_perfect_square(r) && r == rational(5)); + SASSERT(!rational(26).is_int_perfect_square(r) && r == rational(6)); + SASSERT(rational(36).is_int_perfect_square(r) && r == rational(6)); + + SASSERT(rational(1,9).is_perfect_square(r) && r == rational(1,3)); + SASSERT(rational(4,9).is_perfect_square(r) && r == rational(2,3)); +} + + +static void tstmod(rational const& m, rational const& n) { + // + // (=> (distinct n 0) + // (let ((q (div m n)) (r (mod m n))) + // (and (= m (+ (* n q) r)) + // (<= 0 r (- (abs n) 1)))))) + // + + rational q = div(m,n); + rational r = mod(m,n); + std::cout << m << " " << n << " " << q << " " << r << "\n"; + std::cout << m << " == " << n*q+r << "\n"; + + SASSERT(m == (n * q) + r); + SASSERT(rational::zero() <= r); + SASSERT(r < abs(n)); + +} + +static void tst9() { + // record semantics of rational div/mod. + tstmod(rational("41000000000000"),rational("-7000000000000")); + tstmod(rational("-41000000000000"),rational("-7000000000000")); + tstmod(rational("-41000000000000"),rational("7000000000000")); + tstmod(rational("41000000000000"),rational("7000000000000")); + + tstmod(rational(41),rational(-7)); + tstmod(rational(-41),rational(-7)); + tstmod(rational(-41),rational(7)); + tstmod(rational(41),rational(7)); +} + +#define NUM_RATIONALS 1000000 +#define MAGNITUDE 10000 + +static void tst10(bool use_ints) { + if (use_ints) + std::cout << "Testing multiplication performace using small ints\n"; + else + std::cout << "Testing multiplication performace using small rationals\n"; + vector vals; + vector vals2; + vector fvals; + vals.resize(NUM_RATIONALS); + vals2.resize(NUM_RATIONALS); + fvals.resize(NUM_RATIONALS); + for (unsigned i = 0; i < NUM_RATIONALS; i++) { + int r1 = rand() % MAGNITUDE; + int r2 = use_ints ? 1 : rand() % MAGNITUDE; + if (r2 == 0) r2 = 1; + if (rand() % 2 == 0) r1 = -r1; + vals[i] = rational(r1, r2); + vals2[i] = rational(r1, r2); + fvals[i] = ((float)r1) / ((float)r2); + } + { + timeit t(true, "multiplication with rationals"); + for (unsigned i = 0; i < NUM_RATIONALS - 1; i++) { + vals[i] *= vals[i+1]; + } + } + { + timeit t(true, "multiplication with floats: "); + for (unsigned i = 0; i < NUM_RATIONALS - 1; i++) { + fvals[i] *= fvals[i+1]; + } + } + std::cout << "\n"; +} + +#define NUM_RATIONALS2 10000 +#define MAGNITUDE2 100000000 + +static void tst11(bool use_ints) { + vector vals; + vector fvals; + vals.resize(NUM_RATIONALS2); + fvals.resize(NUM_RATIONALS2); + for (unsigned i = 0; i < NUM_RATIONALS2; i++) { + int r1 = rand() % MAGNITUDE2; + int r2 = use_ints ? 1 : rand() % MAGNITUDE2; + if (r2 == 0) r2 = 1; + if (rand() % 2 == 0) r1 = -r1; + vals[i] = rational(r1, r2); + fvals[i] = ((float)r1) / ((float)r2); + } + { + timeit t(true, "multiplication with big rationals"); + for (unsigned j = 0; j < 10; j++) + for (unsigned i = 0; i < NUM_RATIONALS2-1; i++) { + vals[i] *= vals[i+1]; + } + } + { + timeit t(true, "multiplication with floats: "); + for (unsigned j = 0; j < 10; j++) + for (unsigned i = 0; i < NUM_RATIONALS2-1; i++) { + fvals[i] *= fvals[i+1]; + } + } + std::cout << "\n"; +} + + +void tst_rational() { + TRACE("rational", tout << "starting rational test...\n";); + std::cout << "sizeof(rational): " << sizeof(rational) << "\n"; + rational r1("10000000000000000000000000000000001"); + r1.hash(); + tst1(); + tst2(); + tst3(); + tst4(); + tst5(); + std::cout << "running tst6" << std::endl; + tst6(); + std::cout << "running tst7" << std::endl; + tst7(); + std::cout << "running tst8" << std::endl; + tst8(); + std::cout << "running tst9" << std::endl; + tst9(); + std::cout << "running rational_tester::tst1" << std::endl; + rational_tester::tst1(); + rational_tester::tst2(); + tst11(true); + tst10(true); + tst10(false); +} diff --git a/test/region.cpp b/test/region.cpp new file mode 100644 index 000000000..83127d552 --- /dev/null +++ b/test/region.cpp @@ -0,0 +1,29 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_region.cpp + +Abstract: + + Test region memory allocator. + +Author: + + Leonardo de Moura (leonardo) 2006-09-14. + +Revision History: + +--*/ +#include +#include"region.h" + +static void tst1() { + // TODO +} + +void tst_region() { + tst1(); +} + diff --git a/test/relevancy.cpp b/test/relevancy.cpp new file mode 100644 index 000000000..7a6ca016a --- /dev/null +++ b/test/relevancy.cpp @@ -0,0 +1,653 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + relevancy.cpp + +Abstract: + + Test relevancy propagation. + +Author: + + Leonardo de Moura (leonardo) 2006-11-03. + +Revision History: + +--*/ +#include"sat_def.h" + +class relevancy_extension : public no_extension { +public: + bool relevancy_enabled() { + return true; + } + + bool gates_enabled() { + return true; + } +}; + +class sat_relevancy_tester { + + static void tst1() { + sat_solver solver; + + literal l1 = solver.mk_var(); + + SASSERT(!solver.is_relevant(l1.var())); + + solver.assert_lit(l1); + + SASSERT(solver.is_relevant(l1.var())); + } + + static void tst2() { + sat_solver solver; + + literal l1 = solver.mk_var(); + + solver.push_scope(); + + SASSERT(!solver.is_relevant(l1.var())); + + solver.assert_lit(l1); + + SASSERT(solver.is_relevant(l1.var())); + + solver.pop_scope(1); + + SASSERT(solver.is_relevant(l1.var())); + } + + static void tst3() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + + literal l4 = solver.mk_ite(l1, l2, l3); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(!solver.is_relevant(l4)); + + solver.mark_as_relevant(l4.var()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + + solver.push_scope(); + + solver.assign(l1, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + + solver.pop_scope(1); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + + solver.assign(~l1, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + } + + static void tst4() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + literal l4 = solver.mk_ite(l1, l2, l3); + solver.propagate(); + + solver.push_scope(); + + solver.assign(l1, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(!solver.is_relevant(l4)); + + solver.mark_as_relevant(l4.var()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + + solver.pop_scope(1); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(!solver.is_relevant(l4)); + + solver.assign(~l1, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(!solver.is_relevant(l4)); + + solver.mark_as_relevant(l4.var()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + } + + static void tst5() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + + solver.push_scope(); + + solver.assign(l1, mk_axiom()); + solver.propagate(); + + literal l4 = solver.mk_ite(l1, l2, l3); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(!solver.is_relevant(l4)); + + solver.mark_as_relevant(l4.var()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + } + + static void tst6() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_iff(l1, l2); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.push_scope(); + + solver.mark_as_relevant(l3.var()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.pop_scope(1); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.push_scope(); + + solver.mark_as_relevant(l2.var()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.pop_scope(1); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + } + + static void tst7() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_or(l1, l2); + + solver.push_scope(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.mark_as_relevant(l3.var()); + solver.assign(l3, mk_axiom()); + solver.assign(l2, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.assign(l1, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.pop_scope(1); + solver.propagate(); + solver.push_scope(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.mark_as_relevant(l3.var()); + solver.assign(l3, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.assign(l1, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.assign(l2, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.pop_scope(1); + solver.propagate(); + solver.push_scope(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.assign(~l3, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.mark_as_relevant(l3.var()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.pop_scope(1); + solver.propagate(); + solver.push_scope(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.mark_as_relevant(l3.var()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.assign(~l3, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + } + + static void tst8() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_or(l1, l2); + + solver.push_scope(); + + solver.mark_as_relevant(l3.var()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.assign(l1, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.assign(l2, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.pop_scope(1); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + } + + static void tst9() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_or(l1, l2); + + solver.mark_as_relevant(l3.var()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + + solver.assign(l1, mk_axiom()); + solver.assign(l2, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1) || solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l1) != solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + } + + static void tst10() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_or(l1, l2); + + solver.assign(l1, mk_axiom()); + solver.assign(l2, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + + solver.mark_as_relevant(l3.var()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1) || solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l1) != solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + } + + static void tst11() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_iff(l1, l2); + literal l4 = solver.mk_var(); + literal l5 = solver.mk_or(l3, l4); + + solver.propagate(); + solver.push_scope(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(!solver.is_relevant(l4)); + SASSERT(!solver.is_relevant(l5)); + + solver.assign(l3, mk_axiom()); + solver.mark_as_relevant(l5.var()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(solver.is_relevant(l2)); + SASSERT(solver.is_relevant(l3)); + SASSERT(!solver.is_relevant(l4)); + SASSERT(solver.is_relevant(l5)); + + solver.assign(l4, mk_axiom()); + solver.propagate(); + SASSERT(!solver.is_relevant(l4)); + + solver.pop_scope(1); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(!solver.is_relevant(l4)); + SASSERT(!solver.is_relevant(l5)); + + solver.assign(l4, mk_axiom()); + solver.mark_as_relevant(l5.var()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + SASSERT(solver.is_relevant(l5)); + + solver.assign(l1, mk_axiom()); + solver.assign(l2, mk_axiom()); + solver.assign(l3, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + SASSERT(!solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l4)); + SASSERT(solver.is_relevant(l5)); + } + + static void tst12(clause_kind k) { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + + solver.mk_aux_clause(l1, l2, k); + + solver.push_scope(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + + solver.assign(l1, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + + solver.assign(l2, mk_axiom()); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + + solver.pop_scope(1); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + } + + static void tst13(clause_kind k) { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + + solver.mk_aux_clause(l1, l2, k); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + + solver.assign(l1, mk_axiom()); + solver.assign(l2, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + SASSERT(!solver.is_relevant(l2)); + } + + static void tst14() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + + solver.push_scope(); + + solver.assign(l1, mk_axiom()); + + solver.mk_aux_clause(l1, l2, CLS_MAIN); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + } + + static void tst15() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + + solver.push_scope(); + + solver.assign(l1, mk_axiom()); + solver.propagate(); + + SASSERT(!solver.is_relevant(l1)); + + solver.push_scope(); + + solver.mk_aux_clause(l1, l2, CLS_MAIN); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + + solver.pop_scope(1); + solver.propagate(); + + SASSERT(solver.is_relevant(l1)); + } + + static void tst16() { + sat_solver solver; + + literal l1 = solver.mk_var(); + + solver.push_scope(); + solver.assert_lit(l1); + solver.propagate(); + SASSERT(solver.is_relevant(l1)); + SASSERT(solver.get_assignment(l1) == l_true); + solver.assert_lit(l1); + solver.pop_scope(1); + SASSERT(solver.get_assignment(l1) == l_true); + SASSERT(solver.is_relevant(l1)); + } + + static void tst17() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + solver.assert_nonrelevant_lit(l1); + solver.mk_aux_clause(l1, l2, CLS_MAIN); + solver.check(); + SASSERT(solver.get_assignment(l1) == l_true || solver.get_assignment(l2) == l_true); + SASSERT(solver.is_relevant(l1) || solver.is_relevant(l2)); + } + + static void tst18() { + sat_solver solver; + + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + solver.assert_nonrelevant_lit(l1); + literal l3 = solver.mk_or(l1, l2); + SASSERT(l3 != true_literal); + solver.assert_lit(l3); + lbool r = solver.check(); + SASSERT(r == l_true); + SASSERT(solver.is_relevant(l3)); + SASSERT(solver.is_relevant(l1)); + } + +public: + + static void run_tests() { + tst1(); + tst2(); + tst3(); + tst4(); + tst5(); + tst6(); + tst7(); + tst8(); + tst9(); + tst10(); + tst11(); + tst12(CLS_MAIN); + tst12(CLS_TRANSIENT); + tst13(CLS_AUXILIARY); + tst13(CLS_EXT_LEMMA); + tst13(CLS_EXTERNAL); + tst14(); + tst15(); + tst16(); + tst17(); + tst18(); + } + +}; + +void tst_relevancy() { + sat_relevancy_tester::run_tests(); +} diff --git a/test/sat.cpp b/test/sat.cpp new file mode 100644 index 000000000..71cf6af40 --- /dev/null +++ b/test/sat.cpp @@ -0,0 +1,389 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_sat.cpp + +Abstract: + + Test SAT solver + +Author: + + Leonardo de Moura (leonardo) 2006-10-05. + +Revision History: + +--*/ + +#include"sat_def.h" + +class sat_tester { + + static void tst1() { + sat_solver solver; + solver.push_user_scope(); + solver.push_scope(); + literal l1 = solver.mk_var(); + SASSERT(solver.m_ref_count[l1.var()] == 1); + solver.assert_lit(l1); + SASSERT(solver.m_ref_count[l1.var()] == 2); + SASSERT(solver.m_weak_ref_count[l1.var()] == 1); + SASSERT(solver.get_assignment(l1) == l_true); + SASSERT(solver.m_level[l1.var()] == 1); + literal l2 = solver.mk_var(); + SASSERT(solver.m_ref_count[l2.var()] == 1); + SASSERT(solver.get_assignment(l2) == l_undef); + SASSERT(solver.m_level.size() == 3); + SASSERT(solver.m_free_var_indices.size() == 0); + solver.pop_scope(1); + SASSERT(solver.m_free_var_indices.size() == 2); + SASSERT(solver.m_ref_count[l1.var()] == 0); + } + + template + static void tst2() { + sat_solver solver; + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + literal l4 = solver.mk_var(); + solver.mk_aux_clause(~l1, ~l2, l3, CLS_MAIN); + solver.mk_aux_clause(~l3, ~l4, CLS_MAIN); + solver.push_scope(); + solver.assign(l1, mk_axiom()); + solver.assign(l2, mk_axiom()); + SASSERT(solver.get_assignment(l3) == l_undef); + SASSERT(solver.get_assignment(l4) == l_undef); + solver.propagate(); + SASSERT(solver.get_assignment(l3) == l_true); + SASSERT(solver.get_assignment(l4) == l_false); + solver.pop_scope(1); + SASSERT(solver.get_assignment(l1) == l_undef); + SASSERT(solver.get_assignment(l2) == l_undef); + SASSERT(solver.get_assignment(l3) == l_undef); + SASSERT(solver.get_assignment(l4) == l_undef); + } + + static void tst3() { + sat_solver solver; + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + solver.push_scope(); + SASSERT(solver.m_ref_count[l1.var()] == 1); + solver.mk_aux_clause(~l1, l2, CLS_TRANSIENT); + SASSERT(solver.m_ref_count[l1.var()] == 2); + solver.assign(l1, mk_axiom()); + solver.propagate(); + SASSERT(solver.get_assignment(l2) == l_true); + SASSERT(solver.m_transient_clauses.size() == 1); + TRACE("sat_ext", tout << "ref_count: " << solver.m_ref_count[l1.var()] << ", scope_lvl: " << solver.m_scope_lvl << "\n";); + SASSERT(solver.m_ref_count[l1.var()] == 3); + SASSERT(solver.m_ref_count[l2.var()] == 3); + solver.pop_scope(1); + solver.assign(l1, mk_axiom()); + solver.propagate(); + SASSERT(solver.get_assignment(l2) == l_undef); + SASSERT(solver.m_transient_clauses.size() == 0); + SASSERT(solver.m_ref_count[l1.var()] == 2); + SASSERT(solver.m_ref_count[l2.var()] == 1); + } + + static void tst4() { + sat_solver solver; + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + literal l4 = solver.mk_var(); + solver.push_user_scope(); + solver.mk_aux_clause(~l1, l2, l4, CLS_MAIN); + solver.push_user_scope(); + solver.mk_aux_clause(~l1, ~l2, l3, CLS_MAIN); + solver.push_scope(); + solver.mk_aux_clause(~l3, ~l4, CLS_TRANSIENT); + solver.mk_aux_clause(~l1, ~l4, CLS_MAIN); + SASSERT(solver.m_ref_count[l1.var()] == 4); + SASSERT(solver.m_ref_count[l2.var()] == 3); + SASSERT(solver.m_ref_count[l3.var()] == 3); + SASSERT(solver.m_ref_count[l4.var()] == 4); + SASSERT(solver.m_main_clauses.size() == 3); + SASSERT(solver.m_transient_clauses.size() == 1); + solver.pop_scope(2); + SASSERT(solver.m_ref_count[l1.var()] == 2); + SASSERT(solver.m_ref_count[l2.var()] == 2); + SASSERT(solver.m_ref_count[l3.var()] == 1); + SASSERT(solver.m_ref_count[l4.var()] == 2); + SASSERT(solver.m_main_clauses.size() == 1); + SASSERT(solver.m_transient_clauses.size() == 0); + solver.assign(l1, mk_axiom()); + SASSERT(solver.get_assignment(l4) == l_undef); + solver.pop_scope(1); + SASSERT(solver.m_main_clauses.size() == 0); + SASSERT(solver.m_ref_count[l1.var()] == 1); + SASSERT(solver.m_ref_count[l2.var()] == 1); + SASSERT(solver.m_ref_count[l3.var()] == 1); + SASSERT(solver.m_ref_count[l4.var()] == 1); + } + + template + static void tst5() { + sat_solver solver; + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + solver.push_scope(); + solver.assign(l1, mk_axiom()); + solver.push_scope(); + solver.mk_aux_clause(~l1, l2, CLS_MAIN); + SASSERT(solver.get_assignment(l2) == l_true); + solver.pop_scope(1); + SASSERT(solver.get_assignment(l2) == l_true); + solver.pop_scope(1); + SASSERT(solver.get_assignment(l2) == l_undef); + SASSERT(solver.m_main_clauses.size() == 1); + } + + static void tst6() { + sat_solver solver; + + literal l = solver.mk_var(); + solver.assert_lit(l); + SASSERT(!solver.inconsistent()); + solver.push_scope(); + solver.assign(~l, mk_axiom()); + SASSERT(solver.inconsistent()); + solver.pop_scope(1); + SASSERT(!solver.inconsistent()); + } + + class no_ref_count : public no_extension { + public: + static bool ref_counters_enabled() { + return false; + } + }; + + static void tst7() { + sat_solver solver; + literal l1 = solver.mk_var(); + solver.push_user_scope(); + literal l2 = solver.mk_var(); + SASSERT(solver.get_var_vector_size() == 3); + solver.pop_scope(1); + SASSERT(solver.get_var_vector_size() == 2); + } + + static void tst8() { + literal l[2]; + l[0] = true_literal; + l[1] = true_literal; + clause * cls = clause::mk_clause(2, l, CLS_EXTERNAL); + SASSERT(cls->kind() == CLS_EXTERNAL); + dealloc(cls); + } + + static void tst9() { + sat_solver solver; + + solver.push_scope(); + literal l1 = solver.mk_var(); + literal l2 = solver.mk_var(); + literal l3 = solver.mk_var(); + solver.mk_aux_clause(l1, l2, l3, CLS_MAIN); + solver.pop_scope(1); + SASSERT(solver.m_ref_count[l1.var()] == 1); + SASSERT(solver.get_assignment(l1) == l_undef); + solver.assert_lit(~l2); + solver.assert_lit(~l3); + solver.propagate(); + SASSERT(solver.get_assignment(l1) == l_true); + SASSERT(solver.m_main_clauses.size() == 1); + SASSERT(solver.m_ref_count[l1.var()] == 2); + solver.simplify_clauses(); + SASSERT(solver.m_main_clauses.size() == 0); + SASSERT(solver.m_ref_count[l1.var()] == 1); + SASSERT(solver.m_weak_ref_count[l1.var()] == 1); + SASSERT(solver.get_assignment(l1) == l_true); + } + + static void tst10() { + sat_solver s; + + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + literal l3 = s.mk_var(); + + s.push_scope(); + s.assign(l1, mk_axiom()); + s.push_scope(); + literal l4 = s.mk_var(); + s.assign(l4, mk_axiom()); + s.mk_aux_clause(~l4, l3, CLS_TRANSIENT); + s.mk_aux_clause(~l4, l2, CLS_TRANSIENT); + s.mk_aux_clause(~l3, ~l1, ~l2, CLS_TRANSIENT); + SASSERT(s.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + s.resolve_conflict(); + SASSERT(r); + SASSERT(s.m_scope_lvl == 1); + SASSERT(s.m_ref_count[l4.var()] > 0); + s.pop_scope(1); + SASSERT(s.get_assignment(l1) == l_undef); + SASSERT(s.get_assignment(l4) == l_undef); + s.push_scope(); + s.assign(l4, mk_axiom()); +#ifdef Z3DEBUG + s.del_learned_clauses(); +#endif + s.pop_scope(1); + } + + static void tst11() { + // out-of-order conflict bug. + sat_solver s; + + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + s.push_scope(); + s.assign(l1, mk_axiom()); + s.assign(l2, mk_axiom()); + s.push_scope(); + s.mk_aux_clause(~l1, ~l2, CLS_TRANSIENT); + s.propagate(); + s.resolve_conflict(); + } + + static void tst12() { + // out-of-order conflict bug. + sat_solver s; + + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + literal l3 = s.mk_var(); + s.push_scope(); + s.assign(l1, mk_axiom()); + s.assign(l2, mk_axiom()); + s.push_scope(); + s.assign(l3, mk_axiom()); + s.mk_aux_clause(~l1, ~l2, CLS_TRANSIENT); + s.propagate(); + s.resolve_conflict(); + } + + static void tst13() { + sat_solver s; + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + literal l3 = s.mk_var(); + s.push_scope(); + s.assign(l1, mk_axiom()); + s.push_scope(); + s.assign(l2, mk_axiom()); + s.push_scope(); + s.mk_aux_clause(~l1, l3, CLS_MAIN); + s.propagate(); + SASSERT(!s.inconsistent()); + SASSERT(s.get_assignment(l3) == l_true); + s.mk_aux_clause(~l1, ~l2, CLS_TRANSIENT); + s.propagate(); + SASSERT(s.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + s.resolve_conflict(); + SASSERT(r); + SASSERT(s.get_assignment(l3) == l_true); + TRACE("sat", tout << l3 << " : " << s.get_assignment(l3) << " : " << s.m_level[l3.var()] << " : " << s.m_scope_lvl << "\n";); + } + + static void tst14() { + sat_solver s; + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + s.push_scope(); + s.assign(~l1, mk_axiom()); + s.push_scope(); + s.assign(~l2, mk_axiom()); + s.assert_lit(l1); + SASSERT(s.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + s.resolve_conflict(); + SASSERT(r); + SASSERT(s.get_assignment(l1) == l_true); + } + + static void tst15() { + sat_solver s; + literal l1 = s.mk_var(); + literal l2 = s.mk_var(); + s.push_scope(); + s.assign(~l1, mk_axiom()); + s.push_scope(); + s.assign(~l2, mk_axiom()); + s.assert_lit(l1); + SASSERT(s.inconsistent()); +#ifdef Z3DEBUG + bool r = +#endif + s.resolve_conflict(); + SASSERT(r); + SASSERT(s.get_assignment(l1) == l_true); + } + + static void tst16() { + sat_solver s; + s.push_scope(); + literal l1 = s.mk_var(); + bool_var v1 = l1.var(); + s.inc_weak_ref(v1); + s.pop_scope(1); + SASSERT(s.get_ref_count(v1) == 0); + literal l2 = s.mk_var(); + SASSERT(l2.var() != v1); + s.dec_weak_ref(v1); + literal l3 = s.mk_var(); + SASSERT(l3.var() == v1); + } + +public: + static void run_tests() { + enable_trace("sat_ext"); + enable_trace("backtrack"); + enable_trace("mk_clause"); + enable_debug("mk_clause"); + enable_trace("propagate"); + enable_trace("simplify"); + enable_trace("del_learned_clauses"); + enable_debug("sat_invariant"); + TRACE("sat_ext", tout << "running SAT solver tests...\n";); + tst1(); + tst2(); + tst2(); + tst3(); + tst4(); + tst5(); + tst5(); + tst6(); + tst7(); + tst8(); + tst9(); + tst10(); + tst11(); + tst12(); + tst13(); + tst14(); + tst15(); + tst16(); + } +}; + +void tst_sat() { + TRACE("sat", tout << "sizeof(clause): " << sizeof(clause) << "\n";); + sat_tester::run_tests(); +} + + diff --git a/test/simple_parser.cpp b/test/simple_parser.cpp new file mode 100644 index 000000000..189fcd2cf --- /dev/null +++ b/test/simple_parser.cpp @@ -0,0 +1,61 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + simple_parser.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-14. + +Revision History: + +--*/ +#include"cost_parser.h" +#include"cost_evaluator.h" +#include"arith_decl_plugin.h" +#include"ast_pp.h" +#include"well_sorted.h" +#include"warning.h" + +void tst_simple_parser() { + ast_manager m; + m.register_decl_plugins(); + arith_util m_util(m); + cost_parser p(m); + var_ref_vector vs(m); + cost_evaluator eval(m); + p.add_var("x"); + p.add_var("y"); + expr_ref r(m); + p.parse_string("(+ x (* y x))", r); + TRACE("simple_parser", tout << mk_pp(r, m) << "\n";); + p.parse_string("(+ x (* y x) x)", r); + float vals[2] = { 2.0f, 3.0f }; + TRACE("simple_parser", + tout << mk_pp(r, m) << "\n"; + tout << "val: " << eval(r, 2, vals) << "\n";); + p.parse_string("(+ x (* y x) x", r); // << error + p.parse_string("(x)", r); // << error + p.parse_string("(+ x))", r); // <<< this is accepted + TRACE("simple_parser", tout << mk_pp(r, m) << "\n";); + p.parse_string(")x)", r); // error + p.parse_string("(+ x (* 10 y) 2)", r); + TRACE("simple_parser", + tout << mk_pp(r, m) << "\n"; + tout << "val: " << eval(r, 2, vals) << "\n";); + p.parse_string("(ite (and (> x 3) (<= y 4)) 2 10)", r); + TRACE("simple_parser", + tout << mk_pp(r, m) << "\n"; + tout << "val: " << eval(r, 2, vals) << "\n";); + p.parse_string("(ite (or (> x 3) (<= y 4)) 2 10)", r); + TRACE("simple_parser", + tout << mk_pp(r, m) << "\n"; + tout << "val: " << eval(r, 2, vals) << "\n";); +} + diff --git a/test/simplex_polynomial.cpp b/test/simplex_polynomial.cpp new file mode 100644 index 000000000..2c4515f78 --- /dev/null +++ b/test/simplex_polynomial.cpp @@ -0,0 +1,45 @@ +#include "simplex_polynomial.h" + +void tst_simplex_polynomial() +{ + polynomial p1, p2, p3, p4; + simplex_variable v1(1), v2(2), v3(3), v4(4), v5(5); + monomial m1(v1), m2(v2), m3(v3), m4(v4); + + m1 = monomial(v1); + m1 *= monomial(v2); + m1 *= monomial(v1); + + m1.display(std::cout) << std::endl; + m1.normalize(); + m1.display(std::cout) << std::endl; + + m2 = m1; + SASSERT(m1 == m2); + + p1 = polynomial(rational(1,2)); + SASSERT(p1.is_const()); + + p1 += polynomial(v1); + SASSERT(!p1.is_const()); + + p1 += polynomial(v2); + p1 *= polynomial(v2); + p1 -= polynomial(v3); + p1 += polynomial(rational(2,3)); + + p1.normalize(); + p1.display(std::cout) << std::endl; + SASSERT(p1[0].size() == 0); // first element is a constant. + + + p1 = polynomial(v1); + p2 = polynomial(v2); + p3 = polynomial(v3); + p3 += p2; + p3 *= p1; + + p3.display(std::cout) << std::endl; // multiplication distributes. + SASSERT(p3.size() == 2); + +} diff --git a/test/simplifier.cpp b/test/simplifier.cpp new file mode 100644 index 000000000..dbe5f5074 --- /dev/null +++ b/test/simplifier.cpp @@ -0,0 +1,214 @@ +#ifdef _WINDOWS +#include "z3.h" +#include "z3_private.h" +#include +#include "util.h" +#include "trace.h" + +void ev_const(Z3_context ctx, Z3_ast e) { + Z3_ast r = Z3_simplify(ctx, e); + TRACE("simplifier", + tout << Z3_ast_to_string(ctx, e) << " -> "; + tout << Z3_ast_to_string(ctx, r) << "\n";); + Z3_ast_kind k = Z3_get_ast_kind(ctx, r); + SASSERT(k == Z3_NUMERAL_AST || + (k == Z3_APP_AST && + (Z3_OP_TRUE == Z3_get_decl_kind(ctx,Z3_get_app_decl(ctx, Z3_to_app(ctx, r))) || + Z3_OP_FALSE == Z3_get_decl_kind(ctx,Z3_get_app_decl(ctx, Z3_to_app(ctx, r)))))); +} + +void test_bv() { + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort bv1 = Z3_mk_bv_sort(ctx,1); + Z3_sort bv2 = Z3_mk_bv_sort(ctx,2); + Z3_sort bv72 = Z3_mk_bv_sort(ctx,72); + Z3_ast bit1_1 = Z3_mk_numeral(ctx, "1", bv1); + Z3_ast bit3_2 = Z3_mk_numeral(ctx, "3", bv2); + + Z3_ast e = Z3_mk_eq(ctx, bit3_2, Z3_mk_sign_ext(ctx, 1, bit1_1)); + SASSERT(Z3_simplify(ctx, e) == Z3_mk_true(ctx)); + TRACE("simplifier", tout << Z3_ast_to_string(ctx, e) << "\n";); + + Z3_ast b12 = Z3_mk_numeral(ctx, "12", bv72); + Z3_ast b13 = Z3_mk_numeral(ctx, "13", bv72); + + ev_const(ctx, Z3_mk_bvnot(ctx,b12)); + ev_const(ctx, Z3_mk_bvnot(ctx,Z3_simplify(ctx, Z3_mk_bvnot(ctx, b12)))); + ev_const(ctx, Z3_mk_bvand(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvor(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvxor(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvnand(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvnor(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvxnor(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvneg(ctx,b12)); + ev_const(ctx, Z3_mk_bvadd(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvsub(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvmul(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvudiv(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvsdiv(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvsrem(ctx,b12,b13)); + + ev_const(ctx, Z3_mk_bvuge(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvsge(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvugt(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvsgt(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvule(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvult(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvsle(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvslt(ctx,b12,b13)); + + ev_const(ctx, Z3_mk_concat(ctx,b12,b13)); + ev_const(ctx, Z3_mk_extract(ctx,43,1,b13)); + ev_const(ctx, Z3_mk_sign_ext(ctx,33,b13)); + ev_const(ctx, Z3_mk_zero_ext(ctx,33,b13)); + ev_const(ctx, Z3_mk_bvshl(ctx,b12,b13)); + + ev_const(ctx, Z3_mk_bvshl(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvlshr(ctx,b12,b13)); + ev_const(ctx, Z3_mk_bvashr(ctx,b12,b13)); + + ev_const(ctx, Z3_mk_rotate_left(ctx,21,b13)); + ev_const(ctx, Z3_mk_rotate_right(ctx,21,b13)); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void test_datatypes() { + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort int_ty, int_list; + Z3_func_decl nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl; + Z3_ast nil, l1; + + int_ty = Z3_mk_int_sort(ctx); + + int_list = Z3_mk_list_sort(ctx, Z3_mk_string_symbol(ctx, "int_list"), int_ty, + &nil_decl, &is_nil_decl, &cons_decl, &is_cons_decl, &head_decl, &tail_decl); + + nil = Z3_mk_app(ctx, nil_decl, 0, 0); + + Z3_ast a = Z3_simplify(ctx, Z3_mk_app(ctx, is_nil_decl, 1, &nil)); + SASSERT(a == Z3_mk_true(ctx)); + + a = Z3_simplify(ctx, Z3_mk_app(ctx, is_cons_decl, 1, &nil)); + SASSERT(a == Z3_mk_false(ctx)); + + Z3_ast one = Z3_mk_numeral(ctx, "1", int_ty); + Z3_ast args[2] = { one, nil }; + l1 = Z3_mk_app(ctx, cons_decl, 2, args); + SASSERT(nil == Z3_simplify(ctx, Z3_mk_app(ctx, tail_decl, 1, &l1))); + SASSERT(one == Z3_simplify(ctx, Z3_mk_app(ctx, head_decl, 1, &l1))); + + SASSERT(Z3_mk_false(ctx) == Z3_simplify(ctx, Z3_mk_eq(ctx, nil, l1))); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + + +void test_skolemize_bug() { + Z3_config cfg = Z3_mk_config(); + Z3_set_param_value(cfg, "MODEL", "true"); + Z3_set_param_value(cfg, "QUANT_FM","true"); + Z3_set_param_value(cfg, "FM","true"); + Z3_context ctx = Z3_mk_context(cfg); + Z3_del_config(cfg); + + Z3_sort Real = Z3_mk_real_sort(ctx); + Z3_ast x = Z3_mk_bound(ctx, 0, Real); + Z3_symbol x_name = Z3_mk_string_symbol(ctx, "x"); + Z3_ast y = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, "y"), Real); + Z3_ast xp = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, "xp"), Real); + Z3_ast n0 = Z3_mk_numeral(ctx, "0", Real); + Z3_ast n1 = Z3_mk_numeral(ctx, "1", Real); + Z3_ast args1[2] = { x, n1 }; + Z3_ast args2[2] = { x, y }; + Z3_ast args[2] = { Z3_mk_eq(ctx, Z3_mk_add(ctx, 2, args1), xp), + Z3_mk_ge(ctx, Z3_mk_add(ctx, 2, args2), n0) }; + Z3_ast f = Z3_mk_and(ctx, 2, args); + Z3_ast f2 = Z3_mk_exists(ctx, 0, 0, 0, 1, &Real, &x_name, f); + std::cout << Z3_ast_to_string(ctx, f2) << "\n"; + Z3_ast f3 = Z3_simplify(ctx, f2); + std::cout << Z3_ast_to_string(ctx, f3) << "\n"; + +} + + +void test_bool() { + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + + Z3_ast a = Z3_simplify(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, Z3_mk_false(ctx), Z3_mk_true(ctx)))); + Z3_ast b = Z3_simplify(ctx, Z3_mk_not(ctx, Z3_mk_iff(ctx, Z3_mk_false(ctx), Z3_mk_true(ctx)))); + SASSERT(Z3_mk_true(ctx) == a); + SASSERT(Z3_mk_true(ctx) == b); + TRACE("simplifier", tout << Z3_ast_to_string(ctx, a) << "\n";); + TRACE("simplifier", tout << Z3_ast_to_string(ctx, b) << "\n";); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void test_array() { + + Z3_config cfg = Z3_mk_config(); + Z3_context ctx = Z3_mk_context(cfg); + Z3_sort i = Z3_mk_int_sort(ctx); + Z3_ast n1 = Z3_mk_numeral(ctx, "1", i); + Z3_ast n2 = Z3_mk_numeral(ctx, "2", i); + Z3_ast n3 = Z3_mk_numeral(ctx, "3", i); + Z3_ast n4 = Z3_mk_numeral(ctx, "4", i); + Z3_ast s1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"s1"), i); + Z3_ast s2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"s2"), i); + + Z3_ast c1 = Z3_mk_const_array(ctx, i, n1); + Z3_ast x1 = Z3_mk_store(ctx, Z3_mk_store(ctx, c1, n2, n3), n1, n4); + Z3_ast x2 = Z3_mk_store(ctx, Z3_mk_store(ctx, c1, n1, n4), n2, n3); + Z3_ast x3 = Z3_mk_store(ctx, Z3_mk_store(ctx, c1, s1, n1), n2, n3); + Z3_ast x4 = Z3_mk_store(ctx, Z3_mk_store(ctx, Z3_mk_store(ctx, c1, n2, n3), n1, n4), n2, n3); + Z3_ast xs[4] = { x1, x2, x3, x4}; + Z3_ast exy = Z3_mk_eq(ctx, x2, x1); + Z3_ast rxy = Z3_simplify(ctx, exy); + + SASSERT(rxy == Z3_mk_true(ctx)); + SASSERT(Z3_simplify(ctx, Z3_mk_eq(ctx, x2, x3)) == Z3_mk_false(ctx)); + + for (unsigned i = 0; i < 4; ++i) { + for (unsigned j = 0; j < 4; ++j) { + exy = Z3_mk_eq(ctx, xs[i], xs[j]); + rxy = Z3_simplify(ctx, exy); + + TRACE("simplifier", + tout << Z3_ast_to_string(ctx, exy); + tout << " -> " << Z3_ast_to_string(ctx, rxy) << "\n"; + ); + } + } + + Z3_ast sel1 = Z3_mk_select(ctx, x1, n1); + Z3_ast sel2 = Z3_mk_select(ctx, x1, n4); + + TRACE("simplifier", + tout << Z3_ast_to_string(ctx, Z3_simplify(ctx, sel1)) << "\n"; + tout << Z3_ast_to_string(ctx, Z3_simplify(ctx, sel2)) << "\n"; + ); + + Z3_del_config(cfg); + Z3_del_context(ctx); +} + +void tst_simplifier() { + + test_array(); + test_bv(); + test_datatypes(); + test_bool(); + test_skolemize_bug(); +} + +#else +void tst_simplifier() { +} +#endif diff --git a/test/small_object_allocator.cpp b/test/small_object_allocator.cpp new file mode 100644 index 000000000..1e74a734b --- /dev/null +++ b/test/small_object_allocator.cpp @@ -0,0 +1,34 @@ +#include +#include"util.h" +#include"trace.h" +#include"small_object_allocator.h" + +void tst_small_object_allocator() { + small_object_allocator soa; + + char * p1 = new (soa) char[13]; + char * q1 = new (soa) char[14]; + char * p2 = new (soa) char[13]; + TRACE("small_object_allocator", + tout << "p1: " << (void*)p1 << " q1: " << (void*)q1 << " p2: " << (void*)p2 << "\n";); + soa.deallocate(13,p1); + char * p3 = new (soa) char[13]; + TRACE("small_object_allocator", tout << "p3: " << (void*)p3 << "\n";); + + char * r1 = new (soa) char[1]; + char * r2 = new (soa) char[1]; + char * r3 = new (soa) char[1]; + char * r4 = new (soa) char[1]; + TRACE("small_object_allocator", + tout << "r1: " << (void*)r1 << " r2: " << (void*)r2 << " r3: " << (void*)r3 << " r4: " << (void*)r4 << "\n";); + + soa.deallocate(1,r1); + soa.deallocate(1,r3); + r1 = new (soa) char[1]; + soa.deallocate(1,r4); + r4 = new (soa) char[1]; + r3 = new (soa) char[1]; + TRACE("small_object_allocator", + tout << "r1: " << (void*)r1 << " r2: " << (void*)r2 << " r3: " << (void*)r3 << " r4: " << (void*)r4 << "\n";); + +} diff --git a/test/smt2print_parse.cpp b/test/smt2print_parse.cpp new file mode 100644 index 000000000..39543d141 --- /dev/null +++ b/test/smt2print_parse.cpp @@ -0,0 +1,103 @@ +// This is to test the print-parse facilities over the API +// for SMT-LIB2. + +#include "z3.h" +#include + +void test_print(Z3_context ctx, Z3_ast a) { + Z3_set_ast_print_mode(ctx, Z3_PRINT_SMTLIB2_COMPLIANT); + char const* spec1 = Z3_benchmark_to_smtlib_string(ctx, "test", 0, 0, 0, 0, 0, a); + std::cout << spec1 << "\n"; + + Z3_ast b = + Z3_parse_smtlib2_string(ctx, + spec1, + 0, + 0, + 0, + 0, + 0, + 0); + + char const* spec2 = Z3_ast_to_string(ctx, b); + std::cout << spec2 << "\n"; +} + +void test_parseprint(char const* spec) { + Z3_context ctx = Z3_mk_context(0); + std::cout << spec << "\n"; + + Z3_ast a = + Z3_parse_smtlib2_string(ctx, + spec, + 0, + 0, + 0, + 0, + 0, + 0); + + test_print(ctx, a); + + Z3_del_context(ctx); +} + +void tst_smt2print_parse() { + + // test basic datatypes + char const* spec1 = + "(declare-datatypes (T) ((list (nil) (cons (car T) (cdr list)))))\n" + "(declare-const x Int)\n" + "(declare-const l (list Int))\n" + "(declare-fun f ((list Int)) Bool)\n" + "(assert (f (cons x l)))\n"; + + test_parseprint(spec1); + + // test basic arrays + char const* spec2 = + "(declare-const x Int)\n" + "(declare-const a (Array Int Int))\n" + "(declare-const b (Array (Array Int Int) Bool))\n" + "(assert (select b a))\n" + "(assert (= b ((as const (Array (Array Int Int) Bool)) true)))\n" + "(assert (= b (store b a true)))\n" + "(declare-const b1 (Array Bool Bool))\n" + "(declare-const b2 (Array Bool Bool))\n" + "(assert (= ((as const (Array Bool Bool)) false) ((_ map and) b1 b2)))\n"; + + // TBD: const, map, store + + test_parseprint(spec2); + + // Test mutually recursive datatypes + char const* spec3 = + "(declare-datatypes () ((list (nil) (cons (car tree) (cdr list))) (tree (leaf) (node (n list)))))\n" + "(declare-const x tree)\n" + "(declare-const l list)\n" + "(declare-fun f (list) Bool)\n" + "(assert (f (cons x l)))\n"; + + test_parseprint(spec3); + + // Test arithmetic + char const* spec4 = + "(declare-const x Real)\n" + "(declare-const y Int)\n" + "(assert (= x 0.0))\n" + "(assert (= y 6))\n" + "(assert (> (/ x 1.4) (to_real y)))"; + + test_parseprint(spec4); + + // Test bit-vectors + char const* spec5 = + "(declare-const x (_ BitVec 4))\n" + "(declare-const y (_ BitVec 4))\n" + "(assert (bvule x (bvmul y (concat ((_ extract 2 0) x) ((_ extract 3 3) #xf0)))))"; + + test_parseprint(spec5); + + // Test ? + +} diff --git a/test/smt_context.cpp b/test/smt_context.cpp new file mode 100644 index 000000000..48ac71077 --- /dev/null +++ b/test/smt_context.cpp @@ -0,0 +1,28 @@ +#include "smt_context.h" + +void tst_smt_context() +{ + front_end_params params; + + ast_manager m; + m.register_decl_plugins(); + + smt::context ctx(m, params); + + app_ref a1(m.mk_const(symbol("a"), m.mk_bool_sort()), m); + app_ref b1(m.mk_const(symbol("b"), m.mk_bool_sort()), m); + app_ref c1(m.mk_const(symbol("c"), m.mk_bool_sort()), m); + app_ref na1(m.mk_not(a1), m); + ctx.assert_expr(na1); + ctx.assert_expr(m.mk_or(c1.get(), b1.get())); + + { + app_ref nc(m.mk_not(c1), m); + ptr_vector assumptions; + assumptions.push_back(nc.get()); + + ctx.check(assumptions.size(), assumptions.c_ptr()); + } + + ctx.check(); +} diff --git a/test/smtparser.cpp b/test/smtparser.cpp new file mode 100644 index 000000000..6aa6f0e06 --- /dev/null +++ b/test/smtparser.cpp @@ -0,0 +1,52 @@ +#ifdef _WINDOWS +#include +#include +#include +#include +#include "smtparser.h" +#include "for_each_file.h" +#include "array_decl_plugin.h" +#include "bv_decl_plugin.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); + ast_manager.register_decl_plugins(); + + 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/test/splay_tree.cpp b/test/splay_tree.cpp new file mode 100644 index 000000000..d5533ff7c --- /dev/null +++ b/test/splay_tree.cpp @@ -0,0 +1,175 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + splay_tree.cpp + +Abstract: + + Splay trees + +Author: + + Leonardo de Moura (leonardo) 2008-01-31. + +Revision History: + +--*/ + +#include"splay_tree_map.h" +#include"splay_tree_def.h" +#include"trace.h" +#include"vector.h" +#include"map.h" +#include"timeit.h" + +struct icomp { + int operator()(int k1, int k2) const { + return k1 - k2; + } +}; + +struct visitor { + bool m_out; + int m_prev; + unsigned m_num; + + visitor(bool f = true):m_out(f), m_prev(-1), m_num(0) {} + + void operator()(int k, int d) { + SASSERT(m_prev < k); + SASSERT(d == 2 * k); + m_num++; + m_prev = k; + if (m_out) { + TRACE_CODE(tout << k << " ";); + } + } +}; + +static void tst1(unsigned n) { + splay_tree_map s1; + svector s2(n, false); + unsigned size = 0; + + unsigned num_op = rand()%1000; + for (unsigned i = 0; i < num_op; i++) { + unsigned op = rand()%5; + if (op < 3) { + unsigned idx = rand() % n; + TRACE("splay_tree_detail", tout << "inserting: " << idx << "\n";); + if (!s2[idx]) { + size++; + } + s2[idx] = true; + s1.insert(idx, idx*2); + } + else if (op < 4) { + unsigned idx = rand() % n; + TRACE("splay_tree_detail", tout << "erasing: " << idx << "\n";); + if (s2[idx]) { + size--; + } + s2[idx] = false; + s1.erase(idx); + } + else { + SASSERT((size == 0) == s1.empty()); + for (unsigned idx = 0; idx < n; idx++) { + unsigned idx2 = rand() % n; + DEBUG_CODE( + int v; + SASSERT(s2[idx2] == s1.find(idx2, v)); + SASSERT(!s2[idx2] || v == 2*idx2); + ); + } + } + + TRACE("splay_tree", + visitor v; + s1.visit(v); + tout << "\n"; + int idx = rand()%n; + tout << "smaller than: " << idx << "\n"; + visitor v2; + s1.visit_le(v2, idx); + tout << "\n"; + tout << "greater than: " << idx << "\n"; + visitor v3; + s1.visit_ge(v3, idx); + tout << "\n";); + + visitor v(false); + s1.visit(v); + CTRACE("splay_tree", v.m_num != size, s1.display(tout); tout << "\n";); + SASSERT(v.m_num == size); + } + s1.reset(); + SASSERT(s1.empty()); + TRACE("splay_tree", + visitor v;; + s1.visit(v); + SASSERT(v.m_num == 0); + tout << "\n";); +} + +static void tst_perf(int n1, int n2, int n3, int n4, int n5) { + u_map values1; + svector idxs; + splay_tree_map values2; + + { + timeit t(true, "building: "); + for (int i = 0; i < n2; i++) { + int idx = rand() % n1; + idxs.push_back(idx); + values1.insert(idxs[i], i); + } + + for (int i = 0; i < n2; i++) { + values2.insert(idxs[i], i); + } + + } + + int s1, s2; + { + timeit t(true, "u_map: "); + s1 = 0; + for (int j = 0; j < n4; j++) { + for (int i = 0; i < n5; i++) { + int v; + values1.find(idxs[i], v); + s1 += v; + } + } + } + std::cout << s1 << "\n"; + { + timeit t(true, "splay_tree: "); + s2 = 0; + for (int j = 0; j < n4; j++) { + for (int i = 0; i < n5; i++) { + int v; + values2.find(idxs[i], v); + s2 += v; + } + } + // for (int i = 0; i < n5; i++) { + // std::cout << idxs[i] << " "; + // } + std::cout << "\n"; + // values2.display(std::cout); + } + std::cout << s2 << "\n"; + +} + +void tst_splay_tree() { + for (unsigned i = 0; i < 100; i++) { + tst1(1 + rand()%31); + tst1(1 + rand()%100); + } + // tst_perf(10000000, 1000000, 10000, 1000000, 100); +} diff --git a/test/stack.cpp b/test/stack.cpp new file mode 100644 index 000000000..6a4dd3cd8 --- /dev/null +++ b/test/stack.cpp @@ -0,0 +1,75 @@ +/*++ +Copyright (c) 2007 Microsoft Corporation + +Module Name: + + stack.cpp + +Abstract: + Low level stack (aka stack-based allocator). + +Author: + + Leonardo (leonardo) 2011-02-27 + +Notes: + +--*/ +#include +#include"stack.h" +#include"vector.h" + +typedef std::pair point; + +static void tst1() { + stack s; + + point * p1 = new (s) point(10, 20); + point * p2 = new (s) point(30, 40); + void * ptr = s.allocate(16000); + SASSERT(p2->first == 30 && p2->second == 40); + SASSERT(p1->first == 10 && p1->second == 20); + s.deallocate(static_cast(ptr)); + s.deallocate(p2); + s.deallocate(p1); +} + +static void tst2(unsigned num, unsigned del_rate) { + ptr_vector ptrs; + stack s; + for (unsigned i = 0; i < num; i++) { + SASSERT(ptrs.empty() == s.empty()); + SASSERT(s.empty() || ptrs.back() == s.top()); + if (!ptrs.empty() && rand() % del_rate == 0) { + s.deallocate(); + ptrs.pop_back(); + } + else { + unsigned size; + if (rand()%10 == 0) { + size = 8192 + rand()%800; + } + else { + size = rand()%100; + } + char * ptr = static_cast(s.allocate(size)); + ptrs.push_back(ptr); + } + } + while (s.empty()) { + SASSERT(ptrs.empty() == s.empty()); + SASSERT(s.empty() || ptrs.back() == s.top()); + s.deallocate(); + ptrs.pop_back(); + } +} + +void tst_stack() { + tst1(); + tst2(1000, 10); + tst2(2000, 2); + tst2(100000, 10); + tst2(300000, 5); + tst2(300000, 2); + tst2(300000, 7); +} diff --git a/test/string_buffer.cpp b/test/string_buffer.cpp new file mode 100644 index 000000000..67d60528c --- /dev/null +++ b/test/string_buffer.cpp @@ -0,0 +1,52 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_string_buffer.cpp + +Abstract: + + Test string buffer + +Author: + + Leonardo de Moura (leonardo) 2006-10-14. + +Revision History: + +--*/ +#include +#include"debug.h" +#include"string_buffer.h" +#include"trace.h" + +static void tst1() { + string_buffer<> b; + b << "Testing" << 10 << true; + SASSERT(strcmp(b.c_str(), "Testing10true") == 0); +} + +static void tst2() { + string_buffer<> b; + for (unsigned i = 0; i < 10000; i++) { + int r = rand() % 10; + b << r; + } + TRACE("string_buffer", tout << b.c_str() << "\n";); + SASSERT(strlen(b.c_str()) == 10000); +} + +static void tst3() { + string_buffer<32> b; + string_buffer<128> b2; + b2 << "World"; + b << "Hello" << " " << b2; + SASSERT(strcmp(b.c_str(), "Hello World") == 0); +} + +void tst_string_buffer() { + tst1(); + tst2(); + tst3(); +} diff --git a/test/substitution.cpp b/test/substitution.cpp new file mode 100644 index 000000000..80549c72d --- /dev/null +++ b/test/substitution.cpp @@ -0,0 +1,37 @@ +#include "expr_substitution.h" +#include "front_end_params.h" +#include "substitution.h" +#include "unifier.h" +#include "bv_decl_plugin.h" +#include "ast_pp.h" +#include "arith_decl_plugin.h" + + +void tst_substitution() +{ + memory::initialize(0); + front_end_params params; + params.m_model = true; + + enable_trace("subst_bug"); + + ast_manager m; + m.register_decl_plugins(); + + var_ref v1(m.mk_var(0, m.mk_bool_sort()), m); + var_ref v2(m.mk_var(1, m.mk_bool_sort()), m); + + substitution subst(m); + subst.reserve(1,2); + unifier unif(m); + + bool ok1 = unif(v1.get(), v2.get(), subst, false); + bool ok2 = unif(v2.get(), v1.get(), subst, false); + + expr_ref res(m); + + TRACE("substitution", subst.display(tout);); + TRACE("substitution", tout << ok1 << " " << ok2 << "\n";); + subst.display(std::cout); + subst.apply(v1.get(), res); +} diff --git a/test/symbol.cpp b/test/symbol.cpp new file mode 100644 index 000000000..c87955116 --- /dev/null +++ b/test/symbol.cpp @@ -0,0 +1,59 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_symbol.cpp + +Abstract: + + Test symbol class. + +Author: + + Leonardo de Moura (leonardo) 2006-09-13. + +Revision History: + +--*/ +#include +#include"symbol.h" +#include"debug.h" + +static void tst1() { + symbol s1("foo"); + symbol s2("boo"); + symbol s3("foo"); + SASSERT(s1 != s2); + SASSERT(s1 == s3); + std::cout << s1 << " " << s2 << " " << s3 << "\n"; + SASSERT(s1 == "foo"); + SASSERT(s1 != "boo"); + SASSERT(s2 != "foo"); + SASSERT(s3 == "foo"); + SASSERT(s2 == "boo"); + + SASSERT(lt(s2, s1)); + SASSERT(!lt(s1, s2)); + SASSERT(!lt(s1, s3)); + SASSERT(lt(symbol("abcc"), symbol("abcd"))); + SASSERT(!lt(symbol("abcd"), symbol("abcc"))); + SASSERT(lt(symbol("abc"), symbol("abcc"))); + SASSERT(!lt(symbol("abcd"), symbol("abc"))); + SASSERT(lt(symbol(10), s1)); + SASSERT(!lt(s1, symbol(10))); + SASSERT(lt(symbol(10), symbol(20))); + SASSERT(!lt(symbol(20), symbol(10))); + SASSERT(!lt(symbol(10), symbol(10))); + SASSERT(lt(symbol("a"), symbol("b"))); + SASSERT(!lt(symbol("z"), symbol("b"))); + SASSERT(!lt(symbol("zzz"), symbol("b"))); + SASSERT(lt(symbol("zzz"), symbol("zzzb"))); +} + +void tst_symbol() { + tst1(); +} + + + diff --git a/test/symbol_table.cpp b/test/symbol_table.cpp new file mode 100644 index 000000000..f67ef6f66 --- /dev/null +++ b/test/symbol_table.cpp @@ -0,0 +1,47 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_symbol_table.cpp + +Abstract: + + Test symbol table module. + +Author: + + Leonardo de Moura (leonardo) 2006-09-19. + +Revision History: + +--*/ +#include"symbol_table.h" + +static void tst1() { + symbol_table t; + t.insert(symbol("foo"), 35); + SASSERT(t.contains(symbol("foo"))); + SASSERT(!t.contains(symbol("boo"))); + t.begin_scope(); + t.insert(symbol("boo"), 20); + SASSERT(t.contains(symbol("boo"))); +#ifdef Z3DEBUG + int tmp; +#endif + SASSERT(t.find(symbol("boo"), tmp) && tmp == 20); + SASSERT(t.find(symbol("foo"), tmp) && tmp == 35); + t.insert(symbol("foo"), 100); + SASSERT(t.find(symbol("foo"), tmp) && tmp == 100); + t.end_scope(); + SASSERT(t.find(symbol("foo"), tmp) && tmp == 35); + SASSERT(!t.contains(symbol("boo"))); + t.reset(); + SASSERT(!t.contains(symbol("boo"))); + SASSERT(!t.contains(symbol("foo"))); +} + +void tst_symbol_table() { + tst1(); +} + diff --git a/test/symmetry.cpp b/test/symmetry.cpp new file mode 100644 index 000000000..ff0a84dff --- /dev/null +++ b/test/symmetry.cpp @@ -0,0 +1,1104 @@ +#ifdef _WINDOWS +#include "vector.h" +#include "region.h" +#include "trail.h" +#include "nat_set.h" +#include "stream_buffer.h" +#include "obj_hashtable.h" + +class partition { +public: + class id { + friend class partition; + unsigned m_id; + id(unsigned idx): m_id(idx) {} + unsigned get_id() const { return m_id; } + public: + id() : m_id(0) {} + bool operator==(id const& other) const { return m_id == other.m_id; } + bool operator!=(id const& other) const { return m_id != other.m_id; } + std::ostream& display(std::ostream& out) const { + return out << "p" << m_id; + } + }; +private: + static const unsigned invalid_length = 0xFFFFFFFF; + + unsigned_vector m_vertices; // permutation of vertices + svector m_roots; // pointers to class roots, the position in m_vertices that contains the root. + unsigned_vector m_lengths; // length of equivalence class, valid at root position. + unsigned_vector m_length_trail; + unsigned_vector m_offset_trail; + unsigned_vector m_length_lim; + + bool invariant() const { + if (m_roots.size() != m_vertices.size()) { + return false; + } + if (m_roots.size() != m_lengths.size()) { + return false; + } + for (unsigned i = 0; i < m_roots.size(); ++i) { + if (!is_root(m_vertices[m_roots[m_vertices[i]].get_id()])) { + return false; + } + } + return true; + } + + bool is_root(id class_id) const { + return + class_id.m_id < m_vertices.size() && + m_roots[m_vertices[class_id.m_id]] == class_id; + } + +public: + + class mark { + partition& m_partition; + nat_set m_mark; + + public: + mark(partition& p): m_partition(p) { + m_mark.assure_domain(p.m_roots.size()); + } + + void reset() { + m_mark.reset(); + } + + bool test_and_set(id class_id0) { + if (m_mark.contains(class_id0.m_id)) { + return false; + } + m_mark.insert(class_id0.m_id); + return true; + } + }; + + partition(unsigned size) { + for (unsigned i = 0; i < size; ++i) { + m_vertices.push_back(i); + m_roots.push_back(id(0)); + m_lengths.push_back(invalid_length); + } + m_lengths[0] = size; + } + + void push_scope() { + SASSERT(invariant()); + m_length_lim.push_back(m_length_trail.size()); + } + + void pop_scope(unsigned num_scopes) { + if (num_scopes == 0) { + return; + } + unsigned lvl = m_length_lim.size(); + SASSERT(num_scopes <= lvl); + unsigned new_lvl = lvl - num_scopes; + unsigned old_size = m_length_lim[new_lvl]; + // + // NB. backtracking could be expensive in the case where + // we partition the same class multiple times during + // one level. Alternative is to maintain level indication + // together with length to avoid pushing redundant length + // constraints on the stack. + // + for (unsigned i = m_length_trail.size(); i > old_size; ) { + --i; + unsigned offset = m_offset_trail[i]; + unsigned length = m_length_trail[i]; + id class_id(offset); + if (length != invalid_length) { + for (unsigned j = 0; j < length; ++j) { + m_roots[m_vertices[offset + j]] = class_id; + } + } + m_lengths[offset] = length; + } + m_length_trail.shrink(old_size); + m_offset_trail.shrink(old_size); + m_length_lim.shrink(new_lvl); + SASSERT(invariant()); + } + + unsigned get_size(id class_id) const { + SASSERT(is_root(class_id)); + return m_lengths[class_id.m_id]; + } + + unsigned * get_elems(id class_id) { + SASSERT(is_root(class_id)); + return m_vertices.begin() + class_id.m_id; + } + + unsigned const * get_elems(id class_id) const { + return m_vertices.begin() + class_id.m_id; + } + + void mk_partition(unsigned length, unsigned const* vertices) { + SASSERT(m_vertices.begin() <= vertices); + SASSERT(vertices < m_vertices.begin() + m_vertices.size()); + unsigned offset = static_cast(vertices - m_vertices.begin()); + m_length_trail.push_back(m_lengths[offset]); + m_offset_trail.push_back(offset); + m_lengths[offset] = length; + id class_id(offset); + for (unsigned i = 0; i < length; ++i) { + m_roots[vertices[i]] = class_id; + } + } + + id operator[](unsigned v) const { + return m_roots[v]; + } + + void display(std::ostream& out) { + for (unsigned i = 0; i < m_vertices.size(); ++i) { + out << m_vertices[i] << " |-> " << m_roots[m_vertices[i]].m_id << "\n"; + } + } + + void copy_vertices(unsigned_vector& vertices) { + vertices = m_vertices; + } + + void split(id id, unsigned v, unsigned pos) { + // split class id into two parts. + // put var v at position pos in a singleton class. + // + // TBD: can swap into last place to save updates to ids. + // TBD: nothing ensures vertices are invariant under backtracking. + // TBD: the new partitions should be added to m_todo in + // the refiner. + // + unsigned offset = id.get_id(); + if (pos > offset) { + unsigned length = m_lengths[offset]; + std::swap(m_vertices.begin()[pos],m_vertices.begin()[offset]); + SASSERT(length > 1); + mk_partition(1, m_vertices.begin()+offset); + mk_partition(length-1,m_vertices.begin()+offset+1); + } + } + + bool next_split(id& class_id) { + // + // TBD: find first non-singleton partition that is not already + // split on. + // + return false; + } + +}; + +class graph { + // vertex adjacency graph: + vector > m_in; + vector > m_out; + unsigned m_max_degree; + + +public: + graph() : m_max_degree(0) {} + + void add_vertex(unsigned v) { + if (get_num_vertices() <= v) { + m_out.resize(v+1,vector()); + m_in.resize(v+1,vector()); + } + SASSERT(get_num_vertices() == m_in.size()); + SASSERT(get_num_vertices() == m_out.size()); + SASSERT(v < get_num_vertices()); + } + + + void add_edge(unsigned src, unsigned dst) { + SASSERT(src < get_num_vertices()); + SASSERT(dst < get_num_vertices()); + m_out[src].push_back(dst); + m_in[dst].push_back(src); + if (m_out[src].size() > m_max_degree) { + m_max_degree = m_out[src].size(); + } + } + + unsigned get_num_in(unsigned dst) const { + return m_in[dst].size(); + } + + unsigned get_src(unsigned dst, unsigned idx) const { + return m_in[dst][idx]; + } + + unsigned get_dst(unsigned src, unsigned idx) const { + return m_out[src][idx]; + } + + unsigned get_num_out(unsigned src) const { + return m_out[src].size(); + } + + unsigned get_num_vertices() const { + return m_in.size(); + } + + unsigned get_max_degree() const { + return m_max_degree; + } +}; + +class partition_refiner { + + partition& m_partition; + graph& m_graph; + partition::mark m_mark; + + + // + // Temporary variables. + // + svector m_todo; + svector m_inverse; + + // + // For bucketizing bisimilar nodes. + // + vector m_non_empty_buckets; + vector m_buckets; + + +public: + partition_refiner(partition& p, graph& g): m_partition(p), m_graph(g), m_mark(p) { + m_buckets.resize(m_graph.get_max_degree()+1); + } + + void add_refine_class(partition::id id) { + m_todo.push_back(id); + } + + // + // + // compute equivalence classes for vertices + // based on partition refinement. + // + // m_todo contains node classes to partition refine. + // + void partition_refinement() { + for (unsigned i = 0; i < m_todo.size(); ++i) { + partition_refinement(m_todo[i]); + } + m_todo.reset(); + } + + +private: + + // + // refine classes with vertices entering id_dst + // TBD: if we already refined id_dst, then avoid redundant re-refining? + // + void partition_refinement(partition::id id_dst) { + m_mark.reset(); + unsigned class_sz = m_partition.get_size(id_dst); + unsigned const* elems = m_partition.get_elems(id_dst); + for (unsigned j = 0; j < class_sz; ++j) { + unsigned dst = elems[j]; + unsigned in_degree = m_graph.get_num_in(dst); + for (unsigned k = 0; k < in_degree; ++k) { + unsigned src = m_graph.get_src(dst,k); + partition::id id_src = m_partition[src]; + if (m_mark.test_and_set(id_src)) { + partition_refinement(id_src, id_dst); + } + } + } + } + + // + // refined partition algorithm based on + // counting number of edges to id_dst. + // + void partition_refinement(partition::id id_src, partition::id id_dst) { + + unsigned src_sz = m_partition.get_size(id_src); + unsigned* src_elems = m_partition.get_elems(id_src); + // + // First pass: count number of connections to id_dst. + // Move vertices with 0 count into prefix. + // Count max-count + // + unsigned max_count = 0; + unsigned num_max_count = 0; + unsigned num_zeros = 0; + for (unsigned j = 0; j < src_sz; ++j) { + unsigned src = src_elems[j]; + unsigned count = 0; + unsigned out_degree = m_graph.get_num_out(src); + for (unsigned k = 0; k < out_degree; ++k) { + unsigned dst = m_graph.get_dst(src,k); + if (m_partition[dst] == id_src) { + ++count; + } + } + if (count > max_count) { + max_count = count; + num_max_count = 1; + } + else if (count == max_count) { + ++num_max_count; + } + if (count == 0) { + SASSERT(num_zeros <= j); + if (num_zeros < j) { + std::swap(src_elems[j],src_elems[num_zeros]); + } + ++num_zeros; + } + else { + m_buckets[count].push_back(src); + if (m_buckets[count].size() == 1) { + m_non_empty_buckets.push_back(count); + } + } + } + // + // All vertices have the same degree. + // + if (num_max_count == src_sz) { + reset_buckets(); + return; + } + + // + // at least two vertices have different counts + // reaching id_src. + // + + // + // Second pass: refine [src_elems+num_zeros..src_elems+src_size-1] based on count-sort. + // + + SASSERT(m_non_empty_buckets.size() >= 1); + + unsigned largest_bucket_pos = 0; + unsigned largest_bucket_sz = num_zeros; + unsigned pos = num_zeros; + if (num_zeros > 0) { + m_partition.mk_partition(num_zeros, src_elems); + } + for (unsigned i = 0; i < m_non_empty_buckets.size(); ++i) { + unsigned bucket_id = m_non_empty_buckets[i]; + unsigned_vector const& bucket = m_buckets[bucket_id]; + unsigned bucket_sz = bucket.size(); + SASSERT(bucket_sz > 0); + for (unsigned j = 0; j < bucket_sz; ++j) { + src_elems[pos+j] = bucket[j]; + } + if (largest_bucket_sz < bucket_sz) { + largest_bucket_sz = bucket_sz; + largest_bucket_pos = pos; + } + m_partition.mk_partition(bucket_sz, src_elems+pos); + pos += bucket_sz; + } + + // + // Insert all partitions except for largest_bucket_pos. + // + pos = 0; + if (num_zeros > 0 && largest_bucket_pos != 0) { + m_todo.push_back(m_partition[src_elems[0]]); + } + pos += num_zeros; + for (unsigned i = 0; i < m_non_empty_buckets.size(); ++i) { + unsigned sz = m_buckets[m_non_empty_buckets[i]].size(); + if (pos != largest_bucket_pos) { + m_todo.push_back(m_partition[src_elems[pos]]); + } + pos += sz; + } + + // reset buckets that were used. + reset_buckets(); + } + + void reset_buckets() { + for (unsigned i = 0; i < m_non_empty_buckets.size(); ++i) { + m_buckets[m_non_empty_buckets[i]].reset(); + } + m_non_empty_buckets.reset(); + } +}; + +class automorphism_search { + struct stats { + unsigned m_nodes; + unsigned m_max_level; + stats() : m_nodes(0), m_max_level(0) {} + }; + bool m_first; + unsigned_vector m_first_permutation; + partition_refiner m_refiner; + stats m_stats; + partition& m_partition; + graph& m_graph; + unsigned_vector m_num_elems; + ptr_vector m_elems; + +public: + + automorphism_search(partition& p, graph& g): + m_first(true), + m_refiner(p,g), + m_partition(p), + m_graph(g) + {} + + void search_main() { + search(); + } +private: + + bool propagate(partition::id& id) { + m_refiner.partition_refinement(); + + if (m_partition.next_split(id)) { + return true; + } + + if (m_first) { + m_first = false; + m_partition.copy_vertices(m_first_permutation); + pop_scope(1); + } + else { + // not the first node. + // process this. + // TBD + + } + return false; + } + + // + // enumerate elements from partition id: + // + + void search() { + partition::id id; + unsigned num_elems; + unsigned * elems; + + while (true) { + if (propagate(id)) { + push_scope(); + num_elems = m_partition.get_size(id); + elems = m_partition.get_elems(id); + SASSERT(num_elems > 0); + m_num_elems.push_back(num_elems); + m_elems.push_back(elems); + } + else if (get_level() == 0) { + return; + } + else { + num_elems = m_num_elems.back(); + elems = m_elems.back(); + } + + // TBD orbits. + + if (num_elems == 0) { + pop_scope(1); + } + else { + m_partition.split(id, elems[0], 0); // TBD + --m_num_elems.back(); + ++m_elems.back(); + } + } + } + + // TBD: + void push_scope() {} + + void pop_scope(unsigned num_scopes) {} + + unsigned get_level() { return 0; } + +}; + +void tst_symmetry0() { + graph g; + partition p(6); + for (unsigned i = 0; i < 6; ++i) { + g.add_vertex(i); + } + for (unsigned i = 0; i < 3; ++i) { + g.add_edge(i,i+3); + } + g.add_edge(0,1); + g.add_edge(1,2); + g.add_edge(2,0); + partition_refiner r(p,g); + r.add_refine_class(p[0]); + r.partition_refinement(); + p.display(std::cout); +} + +#include "ast.h" +#include "smtparser.h" +#include "array_decl_plugin.h" +#include "bv_decl_plugin.h" +#include "arith_decl_plugin.h" +#include "ast_pp.h" +#include "basic_simplifier_plugin.h" +#include "front_end_params.h" +#include "smt_context.h" + +class expr_symmetry_graph { + template + class labeling : public obj_map { + unsigned m_count; + u_map m_inverse; + public: + labeling() : m_count(0) {} + + unsigned get_count() const { return m_count; } + + unsigned get_label(T* e) { + unsigned lbl = 0; + if (!find(e, lbl)) { + insert(e, ++m_count); + lbl = m_count; + m_inverse.insert(lbl, e); + } + return lbl; + } + + unsigned get_existing_label(T* e) { + unsigned lbl = 0; + if (!find(e, lbl)) { + UNREACHABLE(); + } + return lbl; + } + + T* get_inverse(unsigned n) { + T* a = 0; + if (!m_inverse.find(n, a)) { + return 0; + } + return a; + } + }; + + ast_manager m_mgr; + labeling m_node_id; + expr_ref_vector m_formulas; + expr_ref_vector m_symmetry_breakers; + expr_ref_vector m_aux_preds; + + typedef obj_map func_decl_map; + + + bool is_labeled_function(func_decl* d) { + if (d->is_commutative() || d->get_arity() <= 1) { + return false; + } + if (m_mgr.is_distinct(d)) { + return false; + } + + return true; + } + + // TBD: we are not really interested in symmetries on unit literals. + + void print_graph(std::ostream& out, unsigned num_exprs, expr *const* exprs) { + ptr_vector todo; + ast_mark mark; + unsigned num_vertices = 0, num_edges = 0; + unsigned num_arity_colors = 0; + labeling node_color; + func_decl_map arity_color_map; + + todo.append(num_exprs, exprs); + while (!todo.empty()) { + expr* e = todo.back(); + todo.pop_back(); + if (m_node_id.contains(e)) { + continue; + } + m_node_id.get_label(e); + + ++num_vertices; + if (is_app(e)) { + app* a = to_app(e); + func_decl* d = a->get_decl(); + node_color.get_label(d); + unsigned arity = a->get_num_args(); + todo.append(arity, a->get_args()); + if (!is_labeled_function(d)) { + num_edges += arity; + } + else { + num_edges += 2*arity; + if (!arity_color_map.contains(d)) { + arity_color_map.insert(d,num_arity_colors); + num_arity_colors += arity; + } + } + } + } + num_vertices = m_node_id.get_count() + num_arity_colors; + + out << "p edge " << num_vertices << " " << num_edges << "\n"; + + // print graph + + // print nodes used for arities: + func_decl_map::iterator it = arity_color_map.begin(); + func_decl_map::iterator end = arity_color_map.end(); + for (; it != end; ++it) { + func_decl const* d = (*it).m_key; + unsigned offset = (*it).m_value; + for (unsigned i = 0; i < d->get_arity(); ++i) { + out << "n " << offset + m_node_id.get_count() + i << " " << i + 1 << "\n"; + } + } + + todo.append(num_exprs, exprs); + while (!todo.empty()) { + expr* e = todo.back(); + todo.pop_back(); + if (mark.is_marked(e)) { + continue; + } + mark.mark(e,true); + unsigned id = m_node_id.get_existing_label(e); + + if (is_app(e)) { + app* a = to_app(e); + func_decl* d = a->get_decl(); + unsigned arity = a->get_num_args(); + unsigned offset; + + todo.append(arity, a->get_args()); + out << "c " << d->get_name() << "\n"; + if(m_mgr.is_value(a) || arity > 0) { + out << "n " << id << " " << node_color.get_label(d) << "\n"; + } + else { + out << "n " << id << " 0\n"; + } + + if (is_labeled_function(d) && !arity_color_map.find(d,offset)) { + UNREACHABLE(); + } + for (unsigned i = 0; i < arity; ++i) { + unsigned id2 = m_node_id.get_existing_label(a->get_arg(i)); + if (!is_labeled_function(d)) { + out << "e " << id << " " << id2 << "\n"; + } + else { + unsigned color = offset + m_node_id.get_count() + i; + out << "e " << id << " " << color << "\n"; + out << "e " << color << " " << id2 << "\n"; + } + } + } + } + } + +public: + expr_symmetry_graph() : + m_formulas(m_mgr), + m_symmetry_breakers(m_mgr), + m_aux_preds(m_mgr) { + } + + void parse_file(char const* file_path, char const* file_tmp) { + + smtlib::parser* parser = smtlib::parser::create(m_mgr); + m_mgr.register_decl_plugins(); + 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(); + + smtlib::theory::expr_iterator it = b->begin_formulas(); + smtlib::theory::expr_iterator end = b->end_formulas(); + for (; it != end; ++it) { + m_formulas.push_back(*it); + } + it = b->begin_axioms(); + end = b->end_axioms(); + for (; it != end; ++it) { + m_formulas.push_back(*it); + } + + std::ofstream out(file_tmp); + + if (out.bad() || out.fail()) { + std::cerr << "Error: failed to open file \"" << file_tmp << "\" for writing.\n"; + exit(ERR_OPEN_FILE); + } + print_graph(out, m_formulas.size(), m_formulas.c_ptr()); + out.close(); + + dealloc(parser); + } + +private: + static void skip_blank(stream_buffer& inp) { + while (*inp == ' ' || *inp == '\t' || *inp == '\r') { + ++inp; + } + } + + + static bool read_line(stream_buffer& inp) { + while (*inp != EOF && *inp != '\n') { + ++inp; + } + if (*inp == EOF) { + return false; + } + ++inp; + return true; + } + + + enum token_type { + t_undef, + t_eof, + t_alpha, + t_digit, + t_special + }; + + static token_type get_token_type(int c) { + if ('0' <= c && c <= '9') { + return t_digit; + } + if ('a' <= c && c <= 'z') { + return t_alpha; + } + if ('A' <= c && c <= 'Z') { + return t_alpha; + } + return t_special; + } + + static bool read_token(stream_buffer& in, std::string& token, token_type& ty1) { + skip_blank(in); + ty1 = t_undef; + if (*in == EOF) { + ty1 = t_eof; + return false; + } + token.clear(); + while (*in != '\n' && + *in != ' ' && + *in != '\r' && + *in != '\t' && + *in != EOF) { + token_type ty2 = get_token_type(*in); + if (ty1 == t_undef) { + ty1 = ty2; + token.push_back(*in); + ++in; + } + else if (ty2 != t_special && ty1 == ty2) { + token.push_back(*in); + ++in; + } + else { + break; + } + } + return true; + } + + static bool read_token(stream_buffer& in, char const* token) { + token_type ty; + std::string s; + return + read_token(in, s, ty) && + 0 == strcmp(s.c_str(), token); + } + + static bool read_unsigned(char const* token, unsigned& u) { + u = 0; + while (*token) { + if ('0' <= *token && *token <= '9') { + u = 10*u + (*token - '0'); + ++token; + } + else { + return false; + } + } + return true; + } + + static bool read_unsigned(stream_buffer& in, unsigned& u) { + std::string token; + token_type ty = t_undef; + if (!(read_token(in, token, ty) && ty == t_digit)) { + return false; + } + return read_unsigned(token.c_str(), u); + } + + void print_cycle(unsigned_vector const& permutation) { + for (unsigned i = 0; i < permutation.size(); ++i) { + ast* a = m_node_id.get_inverse(permutation[i]); + if (a) { + std::cout << mk_pp(a, m_mgr) << " "; + } + } + std::cout << "\n"; + } + + + void mk_symmetry_breaker(vector const& permutation) { + expr_ref p(m_mgr); + p = m_mgr.mk_true(); + expr_ref_vector preds(m_mgr); + basic_simplifier_plugin util(m_mgr); + for (unsigned i = 0; i < permutation.size(); ++i) { + unsigned_vector const& cycle = permutation[i]; + if (cycle.size() <= 1) { + continue; + } + unsigned n = cycle[0]; + expr* first = m_node_id.get_inverse(n); + if (!first) { + continue; + } + + if (m_mgr.is_or(first) || m_mgr.is_not(first) || m_mgr.is_implies(first) || m_mgr.is_and(first)) { + continue; + } + if (!m_mgr.is_bool(first)) { + continue; + } + // cycle has at least 2 elements, all elements are predicates + // that are not Boolean connectives. + for (unsigned j = 0; j + 1 < cycle.size(); ++j) { + expr_ref q(m_mgr), a(m_mgr), b(m_mgr), ab(m_mgr), ba(m_mgr), e(m_mgr), abq(m_mgr); + if (j + 2 < cycle.size() || i + 1 < permutation.size()) { + q = m_mgr.mk_fresh_const("p",m_mgr.mk_bool_sort()); + m_aux_preds.push_back(q.get()); + } + else { + q = m_mgr.mk_true(); + } + a = m_node_id.get_inverse(cycle[j]); + b = m_node_id.get_inverse(cycle[j+1]); + util.mk_implies(a,b,ab); + util.mk_implies(b,a,ba); + util.mk_and(ab, q, abq); + util.mk_implies(p,abq,e); + m_symmetry_breakers.push_back(e.get()); + + util.mk_and(ba.get(),q.get(),p); + } + } + } + + + + bool read_cycle(stream_buffer& in, vector& permutation) { + unsigned_vector cycle; + unsigned n; + token_type ty; + std::string token; + if (!(read_token(in, token, ty) && ty == t_special && strcmp(token.c_str(),"(") == 0)) { + std::cout << "read (\n"; + return false; + } + if (!read_unsigned(in, n)) { + std::cout << "read unsigned\n"; + return false; + } + cycle.push_back(n); + while (true) { + if (!read_token(in, token, ty)) { + std::cout << "read next token\n"; + return false; + } + if (0 == strcmp(token.c_str(),")")) { + break; + } + if (0 != strcmp(token.c_str(),",")) { + std::cout << "read ,\n"; + return false; + } + if (!read_token(in, token, ty)) { + std::cout << "read next token\n"; + return false; + } + if (!read_unsigned(token.c_str(), n)) { + std::cout << "read number\n"; + return false; + } + cycle.push_back(n); + } + // print_cycle(cycle); + permutation.push_back(cycle); + return true; + } + + bool read_permutation(stream_buffer& in) { + vector permutation; + while (*in != '\n') { + if (!read_cycle(in, permutation)) { + return false; + } + } + ++in; + mk_symmetry_breaker(permutation); + return true; + } + +public: + void parse_generators(char const* symmetry_file) { + std::fstream in(symmetry_file); + if (in.bad() || in.fail()) { + std::cerr << "Error: failed to open file \"" << symmetry_file << "\" for reading.\n"; + exit(ERR_OPEN_FILE); + } + { + stream_buffer in_buf(in); + + while (true) { + if (!read_token(in_buf, "Generator")) { + if (read_line(in_buf)) { + continue; + } + break; + } + if (!read_token(in_buf, ":")) { + break; + } + if (!read_permutation(in_buf)) { + std::cout << "Could not read generator\n"; + char buffer[2] = { *in_buf, 0 }; + std::cout << buffer << "\n"; + break; + } + std::cout << "Read generator\n"; + // convert back to symmetry breaking. + } + } + + in.close(); + + } + +public: + static void run_bliss(char const* file_in, char const* file_out) { + char const* bliss_exe = "C:\\users\\nbjorner\\Documents\\Downloads\\bliss-0.50\\bliss-0.50\\bliss.exe"; + char buffer[4024]; +#if _WINDOWS + sprintf_s(buffer, ARRAYSIZE(buffer), "%s -directed %s > %s", bliss_exe, file_in, file_out); +#else + sprintf(buffer, "%s -directed %s > %s", bliss_exe, file_in, file_out); +#endif + system(buffer); + } + + void print_symmetry_breakers(const char* out_file) { + std::ofstream out(out_file); + if (out.bad() || out.fail()) { + std::cerr << "Error: failed to open file \"" << out_file << "\" for writing.\n"; + exit(ERR_OPEN_FILE); + } + out << ":extrapreds ("; + for (unsigned i = 0; i < m_aux_preds.size(); ++i) { + out << "(" << mk_pp(m_aux_preds[i].get(), m_mgr) << ") "; + } + out << ")\n"; + for (unsigned i = 0; i < m_symmetry_breakers.size(); ++i) { + out << ":assumption " << mk_pp(m_symmetry_breakers[i].get(), m_mgr) << "\n"; + } + out.close(); + } + + + void prove_with_symmetry_breakers() { + front_end_params params; + smt::context ctx(m_mgr, params); + for (unsigned i = 0; i < m_formulas.size(); ++i) { + ctx.assert_expr(m_formulas[i].get()); + } + for (unsigned i = 0; i < m_symmetry_breakers.size(); ++i) { + ctx.assert_expr(m_symmetry_breakers[i].get()); + } + lbool result = ctx.setup_and_check(); + std::cout << result << "\n"; + ctx.display_statistics(std::cout); + } + +}; + +void tst_symmetry_parse(char** argv, int argc, int& i) { + if (i+2 < argc) { + char const* file_in = argv[i+1]; + char const* file_tmp1 = "C:\\tmp\\bliss_in.txt"; + char const* file_tmp2 = "C:\\tmp\\bliss_out.txt"; + char const* file_out = argv[i+2]; + expr_symmetry_graph graph; + graph.parse_file(file_in, file_tmp1); + graph.run_bliss(file_tmp1, file_tmp2); + graph.parse_generators(file_tmp2); + graph.print_symmetry_breakers(file_out); + i += 2; + } + else { + std::cout << "usage .smt .smt \n"; + } +} + +void tst_symmetry_prove(char** argv, int argc, int& i) { + if (i+1 < argc) { + char const* file_in = argv[i+1]; + char const* file_tmp1 = "C:\\tmp\\bliss_in.txt"; + char const* file_tmp2 = "C:\\tmp\\bliss_out.txt"; + expr_symmetry_graph graph; + graph.parse_file(file_in, file_tmp1); + graph.run_bliss(file_tmp1, file_tmp2); + graph.parse_generators(file_tmp2); + graph.prove_with_symmetry_breakers(); + i += 1; + } + else { + std::cout << "usage .smt\n"; + } +} + +void tst_symmetry() { + char const* arg = "C:\\tvm\\src\\benchmarks\\zap\\smt-lib\\QF_IDL\\queens_bench\\toroidal_bench\\toroidal_queen2-1.smt"; + expr_symmetry_graph graph; + graph.parse_file(arg, 0); +} +#else +void tst_symmetry_parse(char** argv, int argc, int& i) { +} + +void tst_symmetry_prove(char** argv, int argc, int& i) { +} + +void tst_symmetry() { +} +#endif diff --git a/test/template_models.cpp b/test/template_models.cpp new file mode 100644 index 000000000..eb4c52dd0 --- /dev/null +++ b/test/template_models.cpp @@ -0,0 +1,101 @@ +#include "ast_fm.h" +#include "smtparser.h" +#include "ast_pp.h" + +static void +simplify_formula( + ast_manager& ast_manager, + smtlib::symtable* table, + smtlib::parser* parser, + ast* formula + ) +{ +// front_end_params params; +// std::cout << std::make_pair(&ast_manager, formula) << std::endl; + +// const_decl_ast *le_decl = 0, *add_decl = 0, *mul_decl = 0; +// const_decl_ast *lt_decl = 0, *gt_decl = 0, *f_decl = 0; +// type_decl_ast* int_decl = 0; +// type_ast* int_type = 0; + +// table->find1("<=", le_decl); +// table->find1("+", add_decl); +// table->find1("*", mul_decl); +// table->find1("f", f_decl); +// table->find1("<", lt_decl); +// table->find1(">", gt_decl); +// table->find("Int", int_decl); +// int_type = ast_manager.mk_type(int_decl); + + +// ast_simplifier simplifier(ast_manager, params); + +// #if 0 +// iast_arith_simplifier* arith = +// simplifier.add_arithmetic( +// null_theory_id, // TBD +// add_decl, +// mul_decl, +// le_decl, +// false +// ); + +// arith->register_lt(lt_decl); +// arith->register_gt(gt_decl); +// #endif +// ast_fm fm(ast_manager, simplifier, le_decl, add_decl, mul_decl); + +// ast_function_replace replace(ast_manager); + +// ast_ref<> templ(ast_manager); +// templ = ast_manager.mk_const(add_decl, +// ast_manager.mk_var(0,int_type), +// ast_manager.mk_numeral(rational(2), int_type)); + +// ast_ref<> result(ast_manager); + +// // +// // Replace f by \lambda x . x + 2 in formula. +// // + +// replace(formula, f_decl, 1, templ.get(), result); + +// std::cout << "substituted:" +// << std::make_pair(&ast_manager, result.get()) << std::endl; + +// // +// // Eliminate quantified variables from the formula. +// // +// fm.eliminate(result.get(), result); + +// std::cout << "projected:" +// << std::make_pair(&ast_manager, result.get()) << std::endl; + +} + +void tst_template_models() +{ + const char* spec = + "(benchmark template_models :logic QF_LIA \n" + ":extrafuns ((f Int Int) (b Int) (c Int))\n" + ":formula (forall (x Int) (and (< (f x) (f (+ x 1))) (> (f b) b) (> (f c) b))))"; + + ast_manager ast_manager; + smtlib::parser* parser = smtlib::parser::create(ast_manager); + + parser->initialize_smtlib(); + + parser->parse_string(spec); + + smtlib::benchmark* b = parser->get_benchmark(); + + smtlib::symtable* table = b->get_symtable(); + vector formulas; + b->get_formulas(formulas); + for (unsigned j = 0; j < formulas.size(); ++j) { + simplify_formula(ast_manager, table, + parser, formulas[j].m_formula); + } + + dealloc(parser); +} diff --git a/test/test.vcxproj b/test/test.vcxproj new file mode 100644 index 000000000..ea2ce4e97 --- /dev/null +++ b/test/test.vcxproj @@ -0,0 +1,1571 @@ + + + + + bench + Win32 + + + bench + x64 + + + commercial_64 + Win32 + + + commercial_64 + x64 + + + commercial + Win32 + + + commercial + x64 + + + debug_opt + Win32 + + + debug_opt + x64 + + + Debug + Win32 + + + Debug + x64 + + + external_64 + Win32 + + + external_64 + x64 + + + external_dbg + Win32 + + + external_dbg + x64 + + + external_parallel_x64 + Win32 + + + external_parallel_x64 + x64 + + + external_parallel + Win32 + + + external_parallel + x64 + + + external + Win32 + + + external + x64 + + + mpi_debug + Win32 + + + mpi_debug + x64 + + + mpi_release + Win32 + + + mpi_release + x64 + + + parallel_debug + Win32 + + + parallel_debug + x64 + + + parallel_release + Win32 + + + parallel_release + x64 + + + ReleaseD + Win32 + + + ReleaseD + x64 + + + release_mt + Win32 + + + release_mt + x64 + + + release_static + Win32 + + + release_static + x64 + + + Release + Win32 + + + Release + x64 + + + smtcomp + Win32 + + + smtcomp + x64 + + + Trace + Win32 + + + Trace + x64 + + + + {21A10ECD-32E2-4F27-A03D-81D855A048CC} + test + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + + + Application + + + Application + + + Application + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + Default + Neither + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;Z3DEBUG;_CONSOLE;_TRACE;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + /debug /debugtype:cv,fixup %(AdditionalOptions) + $(OutDir)test.exe + true + Console + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;Z3DEBUG;_CONSOLE;_TRACE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + /debug /debugtype:cv,fixup %(AdditionalOptions) + $(OutDir)test.exe + true + Console + MachineX64 + + + + + MaxSpeed + AnySuitable + Speed + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_TRACE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_TRACE;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;Z3DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;Z3DEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;Z3DEBUG;_CONSOLE;_TRACE;_WINDOWS;_Z3_BUILD_PARALLEL_SMT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + /debug /debugtype:cv,fixup %(AdditionalOptions) + $(OutDir)test.exe + C:\Program Files\Microsoft HPC Pack 2008 SDK\Lib\i386;%(AdditionalLibraryDirectories) + true + Console + false + + + MachineX86 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;ASYNC_COMMANDS;_Z3_BUILD_PARALLEL_SMT;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + psapi.lib;%(AdditionalDependencies) + true + Console + true + true + false + + + MachineX86 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;Z3DEBUG;_CONSOLE;_TRACE;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + /debug /debugtype:cv,fixup %(AdditionalOptions) + $(OutDir)test.exe + true + Console + false + + + MachineX86 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + false + ..\lib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + MachineX64 + + + + + X64 + + + ..\lib + WIN32;_DEBUG;Z3DEBUG;_CONSOLE;_TRACE;_WINDOWS;_AMD64_;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {4a7e5a93-19d8-4382-8950-fb2edec7a76e} + false + + + + + + \ No newline at end of file diff --git a/test/test.vcxproj.user b/test/test.vcxproj.user new file mode 100644 index 000000000..ace9a86ac --- /dev/null +++ b/test/test.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/test_util.h b/test/test_util.h new file mode 100644 index 000000000..c83a94dbf --- /dev/null +++ b/test/test_util.h @@ -0,0 +1,44 @@ +#pragma once + +#include "stopwatch.h" + +struct test_context { + bool test_ok; + unsigned test_fails; + unsigned fails; + double test_time; + stopwatch test_timer; + + test_context() : fails(0) {} +}; + +#undef min +#undef max + +#define TEST_CLASS(context, CLASS_NAME, TYPE, CALL_DESTRUCTORS) \ + context.test_fails = 0; \ + cout << "" << #CLASS_NAME << "<" << #TYPE << ">" << endl; \ + CLASS_NAME ## _test< TYPE, CALL_DESTRUCTORS >::run_tests(context); \ + context.fails += context.test_fails; + +#define TEST_METHOD(context, METHOD) \ + cout << "\t" << #METHOD << "... "; \ + context.test_timer.reset(); \ + context.test_ok = test_ ## METHOD; \ + context.test_time = context.test_timer.get_seconds(); \ + if (context.test_ok) { \ + cout << "PASS"; \ + if (context.test_time > 0) { \ + cout << "(" << context.test_time << "s)"; \ + } \ + cout << endl; \ + } \ + else { \ + cout << "FAIL"; \ + if (context.test_time > 0) { \ + cout << "(" << context.test_time << "s)"; \ + } \ + cout << endl; \ + ++ context.test_fails; \ + } \ + diff --git a/test/th_propagation.cpp b/test/th_propagation.cpp new file mode 100644 index 000000000..b57e1e9b3 --- /dev/null +++ b/test/th_propagation.cpp @@ -0,0 +1,65 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + th_propagation.cpp + +Abstract: + + Test theory propagation. + +Author: + + Leonardo de Moura (leonardo) 2006-11-07. + +Revision History: + +--*/ +#include"core_theory.h" + +class th_propagation_tester { + static void tst1() { + core_theory t; + t.m_params.m_relevancy_lvl = 0; + + enode * n1 = t.mk_const(); + enode * n2 = t.mk_const(); + enode * n3 = t.mk_const(); + + literal eq1 = t.mk_eq(n1,n2); + literal eq2 = t.mk_eq(n2,n3); + literal eq3 = t.mk_eq(n1,n3); + + literal l1 = t.mk_lit(); + literal l2 = t.mk_lit(); + t.mk_main_clause(l1, l2, ~eq3); + t.mk_main_clause(~l2, ~eq3); + t.mk_main_clause(~l1, ~eq2); + + t.push_scope(); + t.assign(eq1, mk_axiom()); + t.propagate(); + + t.push_scope(); + t.assign(eq2, mk_axiom()); + t.propagate(); + SASSERT(t.get_assignment(eq3) == l_true); + SASSERT(t.inconsistent()); + bool r = t.m_sat->resolve_conflict(); + SASSERT(r); + } + +public: + static void run_tests() { + enable_trace("th_prop"); + enable_trace("scope"); + enable_trace("conflict"); + tst1(); + } +}; + +void tst_th_propagation() { + th_propagation_tester::run_tests(); +} + diff --git a/test/theory_dl.cpp b/test/theory_dl.cpp new file mode 100644 index 000000000..9d5796963 --- /dev/null +++ b/test/theory_dl.cpp @@ -0,0 +1,35 @@ +#include "smt_context.h" +#include "dl_decl_plugin.h" +#include "ast_pp.h" +#include "model_v2_pp.h" + +void tst_theory_dl() { + ast_manager m; + front_end_params params; + params.m_model = true; + datalog::dl_decl_util u(m); + smt::context ctx(m, params); + m.register_decl_plugins(); + expr_ref a(m), b(m), c(m); + sort_ref s(m); + s = u.mk_sort(symbol("S"),111); + a = m.mk_const(symbol("a"),s); + b = m.mk_const(symbol("b"),s); + ctx.assert_expr(u.mk_lt(a, b)); + ctx.check(); + ref md; + ctx.get_model(md); + model_v2_pp(std::cout, *md.get()); + + + c = m.mk_const(symbol("c"),s); + ctx.assert_expr(u.mk_lt(b, c)); + ctx.check(); + ctx.get_model(md); + model_v2_pp(std::cout, *md.get()); + + ctx.assert_expr(u.mk_lt(c, a)); + std::cout << ctx.check() << "\n"; + + +} diff --git a/test/timeout.cpp b/test/timeout.cpp new file mode 100644 index 000000000..4e2e83847 --- /dev/null +++ b/test/timeout.cpp @@ -0,0 +1,16 @@ + +#include "timeout.h" +#include "trace.h" + +#ifdef _WINDOWS + +#include "windows.h" + +void tst_timeout() { +} + +#else +void tst_timeout() { +} + +#endif diff --git a/test/total_order.cpp b/test/total_order.cpp new file mode 100644 index 000000000..2fa22065f --- /dev/null +++ b/test/total_order.cpp @@ -0,0 +1,162 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + total_order.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2010-07-01. + +Revision History: + +--*/ + +#include"total_order.h" +#include"timeit.h" + +static void tst1() { + uint_total_order to; + to.insert(1); + to.insert_after(1, 2); + to.insert_after(1, 3); + SASSERT(to.lt(1, 2)); + SASSERT(to.lt(3, 2)); + SASSERT(to.lt(1, 3)); + SASSERT(!to.lt(2, 3)); + SASSERT(!to.lt(3, 1)); + SASSERT(!to.lt(2, 2)); + std::cout << to << "\n"; +} + +static void tst2() { + uint_total_order to; + to.insert(1); + to.insert_after(1, 2); + to.insert_after(2, 3); + for (unsigned i = 0; i < 1000; i++) { + to.move_after(3, 1); + to.move_after(1, 2); + to.move_after(2, 3); + SASSERT(to.lt(1,2)); + SASSERT(to.lt(2,3)); + } +} + +static void tst3(unsigned sz, unsigned num_rounds) { + uint_total_order to; + to.insert(0); + for (unsigned i = 0; i < sz; i++) { + to.insert_after(i, i+1); + } + for (unsigned i = 0; i < num_rounds; i++) { + unsigned v1 = rand() % sz; + unsigned v2 = rand() % sz; + if (v1 != v2) + to.move_after(v1, v2); + if (i % 1000 == 0) { + std::cout << "*"; + std::cout.flush(); + } + } + std::cout << std::endl; +} + +void move_after(unsigned_vector & v, unsigned_vector & inv_v, unsigned a, unsigned b) { + if (a == b) + return; + // std::cout << std::endl; + // display(std::cout, v.begin(), v.end()); std::cout << std::endl; + // std::cout << "move_after(" << a << ", " << b << ")\n"; + unsigned pos_a = inv_v[a]; + unsigned pos_b = inv_v[b]; + SASSERT(pos_a != pos_b); + if (pos_b < pos_a) { + for (unsigned i = pos_b; i < pos_a; i++) { + v[i] = v[i+1]; + inv_v[v[i+1]] = i; + } + v[pos_a] = b; + inv_v[b] = pos_a; + SASSERT(inv_v[b] == inv_v[a] + 1); + } + else { + SASSERT(pos_b > pos_a); + for (unsigned i = pos_b; i > pos_a + 1; i--) { + v[i] = v[i-1]; + inv_v[v[i-1]] = i; + } + v[pos_a+1] = b; + inv_v[b] = pos_a+1; + SASSERT(inv_v[b] == inv_v[a] + 1); + } + // display(std::cout, v.begin(), v.end()); std::cout << std::endl; +} + +static void tst4(unsigned sz, unsigned num_rounds) { + uint_total_order to; + unsigned_vector v; + unsigned_vector inv_v; + to.insert(0); + v.push_back(0); + inv_v.push_back(0); + for (unsigned i = 0; i < sz; i++) { + to.insert_after(i, i+1); + v.push_back(i+1); + inv_v.push_back(i+1); + } + for (unsigned i = 0; i < num_rounds; i++) { + unsigned v1 = rand() % sz; + unsigned v2 = rand() % sz; + if (v1 != v2) { + to.move_after(v1, v2); + move_after(v, inv_v, v1, v2); + } + for (unsigned k = 0; k < sz - 1; k++) { + SASSERT(inv_v[v[k]] == k); + SASSERT(to.lt(v[k], v[k+1])); + } + if (i % 1000 == 0) { + std::cout << "*"; + std::cout.flush(); + } + } + std::cout << std::endl; +} + +static void bad_case(unsigned sz, unsigned num_rounds) { + uint_total_order to; + to.insert(0); + for (unsigned i = 0; i < sz; i++) { + to.insert_after(i, i+1); + } + for (unsigned i = 0; i < num_rounds; i++) { + to.move_after(sz, 0); + for (unsigned j = 0; j < sz; j++) { + to.move_after(j, j+1); + } + if (i % 10 == 0) { + std::cout << "*"; + std::cout.flush(); + } + } + std::cout << std::endl; +} + + +void tst_total_order() { + bad_case(100, 1000); + tst1(); + tst2(); + tst4(3, 1000000); + tst4(100, 100000); + tst4(512, 100000); + tst4(1000, 100000); + tst3(100, 100000); + tst3(1000, 100000); +} diff --git a/test/trail.cpp b/test/trail.cpp new file mode 100644 index 000000000..c883c7558 --- /dev/null +++ b/test/trail.cpp @@ -0,0 +1,42 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + trail.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2007-02-26. + +Revision History: + +--*/ +#include"core_theory.h" + +void tst_trail() { + core_theory t; + bvalue v(10); + t.push(); + v.set(t, 20); + v.set(t, 30); + SASSERT(v.get() == 30); + t.pop(1); + SASSERT(v.get() == 10); + t.push(); + t.push(); + v.set(t, 100); + SASSERT(v.get() == 100); + t.pop(2); + SASSERT(v.get() == 10); + t.push(); + t.push(); + v.set(t, 40); + SASSERT(v.get() == 40); + t.pop(1); + SASSERT(v.get() == 10); +} diff --git a/test/trigo.cpp b/test/trigo.cpp new file mode 100644 index 000000000..66805ed45 --- /dev/null +++ b/test/trigo.cpp @@ -0,0 +1,174 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + trigo.cpp + +Abstract: + + Test trigonometric primitives in the interval class. + +Author: + + Leonardo de Moura (leonardo) 2012-08-20 + +Revision History: + +--*/ +#include +#include"interval_def.h" +#include"dependency.h" +#include"mpq.h" +#include"ast.h" +#include"debug.h" +#include"im_float_config.h" + +#define PREC 100000 + +static void tst_sine_core(std::ostream & out, unsynch_mpq_manager & nm, interval_manager & im, mpq & a, unsigned k) { + scoped_mpq lo(nm), hi(nm); + im.sine(a, k, lo, hi); + nm.display(out, lo); + out << " <= Sin["; nm.display(out, a); out << "]\n"; + out << "Sin["; nm.display(out, a); out << "] <= "; + nm.display(out, hi); + out << "\n"; +} + +static void tst_sine(std::ostream & out, unsigned N, unsigned k) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + scoped_mpq a(nm); + nm.set(a, 0); + tst_sine_core(out, nm, im, a, 1); + for (unsigned i = 0; i < N; i++) { + nm.set(a, 4 * (rand() % PREC), PREC); + if (rand() % 2 == 0) + nm.neg(a); + tst_sine_core(out, nm, im, a, k); + } +} + + +static void tst_cosine_core(std::ostream & out, unsynch_mpq_manager & nm, interval_manager & im, mpq & a, unsigned k) { + scoped_mpq lo(nm), hi(nm); + im.cosine(a, k, lo, hi); + nm.display(out, lo); + out << " <= Cos["; nm.display(out, a); out << "]\n"; + out << "Cos["; nm.display(out, a); out << "] <= "; + nm.display(out, hi); + out << "\n"; +} + +static void tst_cosine(std::ostream & out, unsigned N, unsigned k) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + scoped_mpq a(nm); + nm.set(a, 0); + tst_cosine_core(out, nm, im, a, 1); + for (unsigned i = 0; i < N; i++) { + nm.set(a, 4 * (rand() % PREC), PREC); + if (rand() % 2 == 0) + nm.neg(a); + tst_cosine_core(out, nm, im, a, k); + } +} + + +template +static void tst_float_sine_core(std::ostream & out, + fmanager & fm, + interval_manager > & im, + typename fmanager::numeral & a, + unsigned k) { + _scoped_numeral lo(fm), hi(fm); + im.sine(a, k, lo, hi); + out << fm.to_rational_string(lo) << " <= Sin[" << fm.to_rational_string(a) << "]\n"; + out << "Sin[" << fm.to_rational_string(a) << "] <= " << fm.to_rational_string(hi) << "\n"; +} + +const unsigned EBITS = 11; +const unsigned SBITS = 53; + +template +static void tst_float_sine(std::ostream & out, unsigned N, unsigned k) { + fmanager fm; + im_float_config ifc(fm, EBITS, SBITS); + interval_manager > im(ifc); + _scoped_numeral a(fm); + fm.set(a, EBITS, SBITS, static_cast(0)); + tst_float_sine_core(out, fm, im, a, 1); + + // fm.set(a, EBITS, SBITS, MPF_ROUND_TOWARD_POSITIVE, 25336, 100000); + // tst_float_sine_core(out, fm, im, a, k); + // return; + for (unsigned i = 0; i < N; i++) { + unsigned n = 4 * (rand() % PREC); + unsigned d = PREC; + TRACE("sine", tout << "next-val : " << n << "/" << d << "\n";); + fm.set(a, EBITS, SBITS, MPF_ROUND_TOWARD_POSITIVE, n, d); + if (rand() % 2 == 0) + fm.neg(a); + tst_float_sine_core(out, fm, im, a, k); + } +} + +static void tst_mpf_bug() { + mpf_manager fm; + scoped_mpf a(fm), b(fm), c(fm); + fm.set(a, EBITS, SBITS, 2); + fm.set(b, EBITS, SBITS, 3); + std::cout << "a: " << fm.to_double(a) << "\n"; + std::cout << "b: " << fm.to_double(b) << "\n"; + fm.mul(MPF_ROUND_TOWARD_NEGATIVE, a, b, c); + std::cout << "c: " << fm.to_double(c) << "\n"; +} + +static void tst_e(std::ostream & out) { + unsynch_mpq_manager nm; + im_default_config imc(nm); + interval_manager im(imc); + im_default_config::interval r; + for (unsigned i = 0; i < 64; i++) { + im.e(i, r); + out << nm.to_string(im.lower(r)) << " <= E\n"; + out << "E <= " << nm.to_string(im.upper(r)) << "\n"; + } + im.del(r); +} + +static void tst_e_float(std::ostream & out) { + std::cout << "e float...\n"; + unsynch_mpq_manager qm; + mpf_manager fm; + im_float_config ifc(fm); + interval_manager > im(ifc); + scoped_mpq q(qm); + im_float_config::interval r; + for (unsigned i = 0; i < 64; i++) { + im.e(i, r); + out << fm.to_rational_string(im.lower(r)) << " <= E\n"; + out << "E <= " << fm.to_rational_string(im.upper(r)) << "\n"; + } + del_f_interval(ifc, r); +} + +void tst_trigo() { + // enable_trace("sine"); + // enable_trace("sine_bug"); + // enable_trace("mpf_mul_bug"); + std::ofstream out("trigo-lemmas.math"); + tst_e_float(out); + tst_e(out); + tst_float_sine(out, 100, 5); + tst_float_sine(out, 100, 7); + tst_sine(out, 200, 3); + tst_sine(out, 200, 5); + tst_sine(out, 200, 9); + tst_cosine(out, 200, 3); + tst_cosine(out, 200, 5); + tst_cosine(out, 200, 9); +} diff --git a/test/uint_set.cpp b/test/uint_set.cpp new file mode 100644 index 000000000..582a1d42f --- /dev/null +++ b/test/uint_set.cpp @@ -0,0 +1,150 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + uint_set.cpp + +Abstract: + + Test sets of unsigned integers. + +Author: + + Leonardo de Moura (leonardo) 2006-12-07. + +Revision History: + +--*/ + +#include"uint_set.h" +#include"vector.h" + +static void tst1(unsigned n) { + uint_set s1; + svector s2(n, false); + unsigned size = 0; + + unsigned num_op = rand()%1000; + for (unsigned i = 0; i < num_op; i++) { + unsigned op = rand()%3; + if (op < 2) { + unsigned idx = rand() % n; + if (!s2[idx]) { + size++; + } + s2[idx] = true; + s1.insert(idx); + } + else { + unsigned idx = rand() % n; + if (s2[idx]) { + size--; + } + s2[idx] = false; + s1.remove(idx); + } + SASSERT(s1.num_elems() == size); + SASSERT((size == 0) == s1.empty()); + for (unsigned idx = 0; idx < n; idx++) { + SASSERT(s2[idx] == s1.contains(idx)); + } + } +} + +static void tst2(unsigned n) { + uint_set s; + SASSERT(s.empty()); + unsigned val = rand()%n; + s.insert(val); + SASSERT(!s.empty()); + SASSERT(s.num_elems() == 1); + for (unsigned i = 0; i < 100; i++) { + unsigned val2 = rand()%n; + if (val != val2) { + SASSERT(!s.contains(val2)); + } + } + s.remove(val); + SASSERT(s.num_elems() == 0); + SASSERT(s.empty()); +} + +static void tst3(unsigned n) { + SASSERT(n > 10); + uint_set s1; + uint_set s2; + SASSERT(s1 == s2); + s1.insert(3); + SASSERT(s1.num_elems() == 1); + SASSERT(s2.num_elems() == 0); + SASSERT(s1 != s2); + s2.insert(5); + SASSERT(s2.num_elems() == 1); + SASSERT(s1 != s2); + SASSERT(!s1.subset_of(s2)); + s2 |= s1; + SASSERT(s1.subset_of(s2)); + SASSERT(s2.num_elems() == 2); + SASSERT(s1 != s2); + s1 |= s2; + SASSERT(s1.subset_of(s2)); + SASSERT(s2.subset_of(s1)); + SASSERT(s1.num_elems() == 2); + SASSERT(s2.num_elems() == 2); + SASSERT(s1 == s2); + s1.insert(9); + SASSERT(s1.num_elems() == 3); + SASSERT(s2.num_elems() == 2); + s1.insert(9); + SASSERT(s1.num_elems() == 3); + SASSERT(s2.num_elems() == 2); + SASSERT(s2.subset_of(s1)); + SASSERT(!s1.subset_of(s2)); + SASSERT(s1 != s2); + uint_set s3(s1); + SASSERT(s1 == s3); + SASSERT(s1.subset_of(s3)); + SASSERT(s3.subset_of(s1)); + SASSERT(s2 != s3); + uint_set s4(s2); + SASSERT(s2 == s4); + SASSERT(s2.subset_of(s4)); + SASSERT(s4.subset_of(s2)); + SASSERT(s2 != s3); + for (unsigned i = 0; i < n; i++) { + uint_set s5; + s5.insert(i); + SASSERT(s1.contains(i) == s5.subset_of(s1)); + } +} + +static void tst4() { + uint_set s; + s.insert(32); + SASSERT(s.contains(32)); + SASSERT(!s.contains(31)); + SASSERT(!s.contains(0)); + s.remove(32); + SASSERT(!s.contains(32)); + SASSERT(!s.contains(31)); + SASSERT(!s.contains(0)); +} + +void tst_uint_set() { + for (unsigned i = 0; i < 100; i++) { + tst1(1 + rand()%31); + tst1(1 + rand()%100); + } + for (unsigned i = 0; i < 1000; i++) { + tst2(1); + tst2(10); + tst2(31); + tst2(32); + tst2(100); + } + tst3(12); + tst3(100); + tst4(); +} + diff --git a/test/upolynomial.cpp b/test/upolynomial.cpp new file mode 100644 index 000000000..80bc8f278 --- /dev/null +++ b/test/upolynomial.cpp @@ -0,0 +1,1068 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + upolynomial.cpp + +Abstract: + + Goodies for creating and handling univariate polynomials. + +Author: + + Leonardo (leonardo) 2011-12-01 + +Notes: + +--*/ +#include"upolynomial.h" +#include"timeit.h" + +static void tst1() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + upolynomial::manager um(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = (x - 1)*(x + 1)*(x + 2)*(x + 3)*(x - 3); + std::cout << "p: " << p << "\n"; + // convert p into an univariate polynomial + upolynomial::scoped_numeral_vector q(um); + um.to_numeral_vector(p, q); + std::cout << "q: "; um.display(std::cout, q); std::cout << "\n"; + + std::cout << "degree(q): " << um.degree(q) << "\n"; + + // display coefficients of q + std::cout << "expanded q: "; + for (unsigned i = 0; i < q.size(); i++) + std::cout << nm.to_string(q[i]) << " "; + std::cout << "\n"; + + // traverse coefficients of q adding 1 + for (unsigned i = 0; i < q.size(); i++) { + nm.add(q[i], mpz(1), q[i]); + } + // All operations in upolynomial::manager assume the leading coefficient of q is not zero. + // So, if we perform destructive operations on these coefficients, we must execute the "trim" operation + // before invoking another operation of upolynomial::manager + um.trim(q); + + // q after adding 1 to all coefficients + std::cout << "new q: "; um.display(std::cout, q); std::cout << "\n"; + + // q^2 + um.mul(q.size(), q.c_ptr(), q.size(), q.c_ptr(), q); + std::cout << "new q^2: "; um.display(std::cout, q); std::cout << "\n"; + + // using pw for (q^2)^3 + um.pw(q.size(), q.c_ptr(), 3, q); + std::cout << "new (q^2)^3: "; um.display(std::cout, q); std::cout << "\n"; +} + +static void tst_isolate_roots(polynomial_ref const & p, unsigned prec, mpbq_manager & bqm, mpbq_vector & roots, mpbq_vector & lowers, mpbq_vector & uppers) { + upolynomial::manager um(p.m().m()); + upolynomial::scoped_numeral_vector q(um); + um.to_numeral_vector(p, q); + std::cout << "isolating roots of: "; um.display(std::cout, q); std::cout << "\n"; + { + timeit timer(true, "isolate time"); + um.isolate_roots(q.size(), q.c_ptr(), bqm, roots, lowers, uppers); + } + + upolynomial::scoped_upolynomial_sequence sseq(um), fseq(um); + { + timeit timer(true, "sturm time"); + um.sturm_seq(q.size(), q.c_ptr(), sseq); + // um.display(std::cout, sseq); std::cout << "\n"; + } + + // Fourier sequence is sensitive to repeated roots... we remove them by taking the square free component. + upolynomial::scoped_numeral_vector q_sqf(um); + { + timeit timer(true, "sqf time"); + um.square_free(q.size(), q.c_ptr(), q_sqf); + std::cout << "square free part: "; um.display(std::cout, q_sqf); std::cout << "\n"; + } + + { + timeit timer(true, "fourier time"); + um.fourier_seq(q_sqf.size(), q_sqf.c_ptr(), fseq); + } + + // um.display(std::cout, fseq); + + std::cout << "num. roots: " << roots.size() + lowers.size() << "\n"; + std::cout << "sign var(-oo): " << um.sign_variations_at_minus_inf(sseq) << "\n"; + std::cout << "sign var(+oo): " << um.sign_variations_at_plus_inf(sseq) << "\n"; + SASSERT(roots.size() + lowers.size() == um.sign_variations_at_minus_inf(sseq) - um.sign_variations_at_plus_inf(sseq)); + std::cout << "roots:"; + for (unsigned i = 0; i < roots.size(); i++) { + SASSERT(um.eval_sign_at(q.size(), q.c_ptr(), roots[i]) == 0); + std::cout << " "; bqm.display_decimal(std::cout, roots[i], prec); + } + { + timeit timer(true, "interval check"); + std::cout << "\n"; + std::cout << "intervals:"; + for (unsigned i = 0; i < lowers.size(); i++) { + std::cout << " ("; + bqm.display_decimal(std::cout, lowers[i], prec); + std::cout << ", "; + bqm.display_decimal(std::cout, uppers[i], prec); + std::cout << ")"; + // Check interval with Sturm sequence. Small detail: Sturm sequence is for close intervals. + SASSERT(um.eval_sign_at(q.size(), q.c_ptr(), lowers[i]) == 0 || + um.eval_sign_at(q.size(), q.c_ptr(), uppers[i]) == 0 || + um.sign_variations_at(sseq, lowers[i]) - um.sign_variations_at(sseq, uppers[i]) == 1); + // Fourier sequence may also be used to check if the interval is isolating + TRACE("upolynomial", + tout << "lowers[i]: " << bqm.to_string(lowers[i]) << "\n"; + tout << "uppers[i]: " << bqm.to_string(uppers[i]) << "\n"; + tout << "fourier lower: " << um.sign_variations_at(fseq, lowers[i]) << "\n"; + tout << "fourier upper: " << um.sign_variations_at(fseq, uppers[i]) << "\n";); + unsigned fsv_lower = um.sign_variations_at(fseq, lowers[i]); + unsigned fsv_upper = um.sign_variations_at(fseq, uppers[i]); + SASSERT(um.eval_sign_at(q.size(), q.c_ptr(), lowers[i]) == 0 || + um.eval_sign_at(q.size(), q.c_ptr(), uppers[i]) == 0 || + // fsv_lower - fsv_upper is an upper bound for the number of roots in the interval + // fsv_upper - fsv_upper - num_roots is even + // Recall that num_roots == 1 in the interval. + (fsv_lower - fsv_upper >= 1 && (fsv_lower - fsv_upper - 1) % 2 == 0)); + + // Double checking using Descartes bounds for the interval + // Must use square free component. + unsigned dab = um.descartes_bound_a_b(q_sqf.size(), q_sqf.c_ptr(), bqm, lowers[i], uppers[i]); + TRACE("upolynomial", tout << "Descartes bound: " << dab << "\n";); + SASSERT(dab == 1); + } + } + std::cout << "\n"; +} + +static void tst_isolate_roots(polynomial_ref const & p, unsigned prec = 5) { + mpbq_manager bqm(p.m().m()); + scoped_mpbq_vector roots(bqm); + scoped_mpbq_vector lowers(bqm); + scoped_mpbq_vector uppers(bqm); + tst_isolate_roots(p, prec, bqm, roots, lowers, uppers); +} + +static void check_roots(mpbq_vector const & roots, mpbq_vector const & lowers, mpbq_vector const & uppers, unsigned expected_sz, rational const * expected_roots) { + SASSERT(expected_sz == roots.size() + lowers.size()); + svector visited; + visited.resize(expected_sz, false); + for (unsigned i = 0; i < expected_sz; i++) { + rational const & r = expected_roots[i]; + bool found = false; + for (unsigned j = 0; j < roots.size(); j++) { + if (to_rational(roots[j]) == r) { + SASSERT(!visited[j]); + SASSERT(!found); + found = true; + visited[j] = true; + } + } + for (unsigned j = 0; j < lowers.size(); j++) { + unsigned j_prime = j + roots.size(); + if (to_rational(lowers[j]) < r && r < to_rational(uppers[j])) { + SASSERT(!found); + SASSERT(!visited[j_prime]); + found = true; + visited[j_prime] = true; + } + } + SASSERT(found); + } +} + +static void tst_isolate_roots(polynomial_ref const & p, unsigned expected_sz, rational const * expected_roots, unsigned prec = 5) { + mpbq_manager bqm(p.m().m()); + scoped_mpbq_vector roots(bqm); + scoped_mpbq_vector lowers(bqm); + scoped_mpbq_vector uppers(bqm); + tst_isolate_roots(p, prec, bqm, roots, lowers, uppers); + check_roots(roots, lowers, uppers, expected_sz, expected_roots); +} + +static void tst_isolate_roots() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = (x-1)*(x-2); + { + rational ex[2] = { rational(1), rational(2) }; + tst_isolate_roots(p, 2, ex); + } + p = (x-1)*(x-1)*x*x*x; + { + rational ex[2] = { rational(1), rational(0) }; + tst_isolate_roots(p, 2, ex); + } + p = (x^5) - x - 1; + { + rational ex[1] = { rational(11673039, 10000000) }; // approximated root + tst_isolate_roots(p, 1, ex); + } + p = (x - 1)*(x + 1)*(x + 2)*(x + 3)*((x - 3)^2); + { + rational ex[5] = { rational(1), rational(-1), rational(-2), rational(-3), rational(3) }; + tst_isolate_roots(p, 5, ex); + } + p = (10000*x - 31)*(10000*x - 32); + { + rational ex[2] = { rational(31, 10000), rational(32, 10000) }; + tst_isolate_roots(p, 2, ex, 10); + } + p = (10000*x - 31)*(10000*x - 32)*(10000*x - 33); + { + rational ex[3] = { rational(31, 10000), rational(32, 10000), rational(33, 10000) }; + tst_isolate_roots(p, 3, ex, 10); + } + p = ((x^5) - x - 1)*((x^5) + x - 1)*(1000*x - 1167); + { + rational ex[3] = { rational(11673039, 10000000), // approximated + rational(75487766, 100000000), // approximated + rational(1167, 1000) }; + tst_isolate_roots(p, 3, ex, 10); + } + p = (x - 2)*(x - 4)*(x - 8)*(x - 16)*(x - 32)*(x - 64)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1)*(32*x - 1); + { + rational ex[11] = { rational(2), rational(4), rational(8), rational(16), rational(32), rational(64), + rational(1, 2), rational(1, 4), rational(1, 8), rational(1, 16), rational(1, 32) }; + tst_isolate_roots(p, 11, ex, 10); + } + p = ((x^5) - x - 1)*((x^5) + x - 1)*(1000*x - 1167)*((x^5) - x - 1)*((x^5) + x - 1)*(1000*x - 1167); + { + rational ex[3] = { rational(11673039, 10000000), // approximated + rational(75487766, 100000000), // approximated + rational(1167, 1000) }; + tst_isolate_roots(p, 3, ex, 10); + } + p = (x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7; + { + rational ex[3] = { rational(-413582, 100000), // approximated + rational(-170309, 100000), // approximated + rational(-109968, 100000), // approximated + }; + tst_isolate_roots(p, 3, ex, 10); + } + p = ((x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7)*(((x^5) - x - 1)^2)*(((x^3) - 2)^2); + { + rational ex[5] = { rational(-413582, 100000), // approximated + rational(-170309, 100000), // approximated + rational(-109968, 100000), // approximated + rational(11673039, 10000000), // approximated + rational(125992, 100000) // approximated + }; + tst_isolate_roots(p, 5, ex, 10); + } + p = (((x^5) - 1000000000)^3)*((3*x - 10000000)^2)*((10*x - 632)^2); + { + rational ex[3] = { rational(630957, 10000), // approximated + rational(10000000, 3), + rational(632, 10) + }; + tst_isolate_roots(p, 3, ex, 10); + } + +} + +static void tst_remove_one_half() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m), r(m); + p = 4*(x^3) - 12*(x^2) - x + 3; + r = 16*(x^2) - 40*x - 24; + upolynomial::manager um(nm); + upolynomial::scoped_numeral_vector _p(um), _q(um), _r(um); + um.to_numeral_vector(p, _p); + um.to_numeral_vector(r, _r); + SASSERT(um.has_one_half_root(_p.size(), _p.c_ptr())); + um.remove_one_half_root(_p.size(), _p.c_ptr(), _q); + SASSERT(!um.has_one_half_root(_q.size(), _q.c_ptr())); + std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n"; + std::cout << "_r: "; um.display(std::cout, _r); std::cout << "\n"; + std::cout << "_q: "; um.display(std::cout, _q); std::cout << "\n"; + SASSERT(um.eq(_q, _r)); + + p = (((x^5) - 1000000000)^3)*((3*x - 10000000)^2)*((10*x - 632)^2); + um.to_numeral_vector(p, _p); + SASSERT(!um.has_one_half_root(_p.size(), _p.c_ptr())); + + p = (x - 2)*(x - 4)*(x - 8)*(x - 16)*(x - 32)*(x - 64)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1)*(32*x - 1); + um.to_numeral_vector(p, _p); + SASSERT(um.has_one_half_root(_p.size(), _p.c_ptr())); +} + +template +static void tst_gcd(polynomial_ref const & p, polynomial_ref const & q, pmanager & um) { + typename pmanager::scoped_numeral_vector _p(um.m()), _q(um.m()), _r(um.m()); + um.to_numeral_vector(p, _p); + um.to_numeral_vector(q, _q); + std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n"; + std::cout << "_q: "; um.display(std::cout, _q); std::cout << std::endl; + um.gcd(_p.size(), _p.c_ptr(), _q.size(), _q.c_ptr(), _r); + std::cout << "gcd: "; um.display(std::cout, _r); std::cout << "\n"; + um.subresultant_gcd(_p.size(), _p.c_ptr(), _q.size(), _q.c_ptr(), _r); + std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n"; + std::cout << "_q: "; um.display(std::cout, _q); std::cout << "\n"; + std::cout << "subresultant_gcd: "; um.display(std::cout, _r); std::cout << "\n"; +} + +static void tst_gcd() { + std::cout << "\n\nTesting GCD\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + polynomial_ref q(m); + + upolynomial::manager um(nm); + + p = 13*((x - 3)^6)*((x - 5)^5)*((x - 11)^7); + q = derivative(p, 0); + tst_gcd(p, q, um); + + return; + + p = (x^8) + (x^6) - 3*(x^4) - 3*(x^3) + 8*(x^2) + 2*x - 5; + q = 3*(x^6) + 5*(x^4) - 4*(x^2) - 9*x + 21; + + tst_gcd(p, q, um); + + p = ((x - 1)^2)*(x - 3)*(x + 2)*((x - 5)^3); + q = (x + 1)*(x-1)*((x-3)^2)*(x + 3)*(x - 5); + tst_gcd(p, q, um); + std::cout << "expected: " << ((x - 1)*(x-3)*(x-5)) << "\n"; + +} + +static void tst_zp() { + std::cout << "\n\nTesting Z_p\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + polynomial_ref q(m); + p = (x^4) + 2*(x^3) + 2*(x^2) + x; + q = (x^3) + x + 1; + + // Computing GCD of p an q in Z[x] + std::cout << "GCD in Z[x]\n"; + upolynomial::manager um(nm); + tst_gcd(p, q, um); + + // Computing GCD of p an q in Z_3[x] + std::cout << "GCD in Z_3[x]\n"; + upolynomial::zp_manager um3(nm); + um3.set_zp(3); + tst_gcd(p, q, um3); +} + +static void tst_zp2() { + std::cout << "\n\nTesting Z_p\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref u(m); + polynomial_ref v(m); + v = (x^6) + 5*(x^5) + 9*(x^4) + 5*(x^2) + 5*x; + u = (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8; + + // Computing GCD of p an q in Z[x] + std::cout << "GCD in Z[x]\n"; + upolynomial::manager um(nm); + tst_gcd(u, v, um); + + // Computing GCD of p an q in Z_3[x] + std::cout << "GCD in Z_13[x]\n"; + upolynomial::zp_manager um13(nm); + um13.set_zp(13); + tst_gcd(u, v, um13); +} + +static void tst_ext_gcd() { + std::cout << "\nExtended GCD\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref a(m); + polynomial_ref b(m); + a = (x^6) + 5*(x^5) + 9*(x^4) + 5*(x^2) + 5*x; + b = (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8; + + // Computing GCD of p an q in Z_3[x] + std::cout << "GCD in Z_13[x]\n"; + upolynomial::zp_manager um(nm); + um.set_zp(13); + mpzzp_manager & z13 = um.m(); + upolynomial::zp_manager::scoped_numeral_vector A(z13), B(z13), U(z13), V(z13), D(z13); + um.to_numeral_vector(a, A); + um.to_numeral_vector(b, B); + um.ext_gcd(A.size(), A.c_ptr(), B.size(), B.c_ptr(), U, V, D); + std::cout << "A: "; um.display(std::cout, A); std::cout << "\n"; + std::cout << "B: "; um.display(std::cout, B); std::cout << "\n"; + std::cout << "U: "; um.display(std::cout, U); std::cout << "\n"; + std::cout << "V: "; um.display(std::cout, V); std::cout << "\n"; + std::cout << "D: "; um.display(std::cout, D); std::cout << "\n"; +} + +static void tst_ext_gcd_z7() { + std::cout << "\nExtended GCD in Z_7\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref a(m); + polynomial_ref b(m); + + a = (x^3) + 2; + b = 6*(x^2) + 6; + + // Computing GCD of a and b in Z_3[x] + // expecting: D = 1, U = 3*x + 6, V = 3*x^2 + 6*x + 4 + std::cout << "GCD in Z_7[x]\n"; + upolynomial::zp_manager um(nm); + um.set_zp(7); + mpzzp_manager & z7 = um.m(); + upolynomial::zp_manager::scoped_numeral_vector A(z7), B(z7), U(z7), V(z7), D(z7); + um.to_numeral_vector(a, A); + um.to_numeral_vector(b, B); + um.ext_gcd(A.size(), A.c_ptr(), B.size(), B.c_ptr(), U, V, D); + std::cout << "A: "; um.display(std::cout, A); std::cout << "\n"; + std::cout << "B: "; um.display(std::cout, B); std::cout << "\n"; + std::cout << "U: "; um.display(std::cout, U); std::cout << "\n"; + std::cout << "V: "; um.display(std::cout, V); std::cout << "\n"; + std::cout << "D: "; um.display(std::cout, D); std::cout << "\n"; +} + +static void tst_sturm() { + std::cout << "\nSturm Seq\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = 7*(x^10) + 3*(x^9) + (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8; + // p = ((x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7)*(((x^5) - x - 1)^2)*(((x^3) - 2)^2); + // p = ((x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7)*(((x^5) - x - 1))*(((x^3) - 2)); + + upolynomial::manager um(nm); + upolynomial::scoped_numeral_vector _p(um); + upolynomial::scoped_upolynomial_sequence seq2(um); + um.to_numeral_vector(p, _p); + um.sturm_seq(_p.size(), _p.c_ptr(), seq2); + std::cout << "upolynomial sturm seq...\n"; + um.display(std::cout, seq2); +} + + +static void tst_refinable(polynomial_ref const & p, mpbq_manager & bqm, mpbq & a, mpbq & b) { + upolynomial::manager um(p.m().m()); + upolynomial::scoped_numeral_vector _p(um); + um.to_numeral_vector(p, _p); + std::cout << "before (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n"; + bool r = um.isolating2refinable(_p.size(), _p.c_ptr(), bqm, a, b); + if (r) { + std::cout << "new (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n"; + int sign_a = um.eval_sign_at(_p.size(), _p.c_ptr(), a); + int sign_b = um.eval_sign_at(_p.size(), _p.c_ptr(), b); + SASSERT(sign_a != 0 && sign_b != 0 && sign_a == -sign_b); + } + else { + std::cout << "new root: " << bqm.to_string(a) << "\n"; + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), a) == 0); + } +} + +static void tst_refinable() { + std::cout << "\nRefinable intervals\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = (x - 1)*(4*x - 11)*(x - 3); + std::cout << "p: " << p << "\n"; + mpbq_manager bqm(nm); + mpbq a(1); + mpbq b(3); + tst_refinable(p, bqm, a, b); + bqm.set(a, 2); + bqm.set(b, 3); + tst_refinable(p, bqm, a, b); + bqm.set(a, 5, 1); + bqm.set(b, 3); + tst_refinable(p, bqm, a, b); + + p = (x - 1)*(5*x - 11)*(x - 3); + std::cout << "p: " << p << "\n"; + bqm.set(a, 1); + bqm.set(b, 3); + tst_refinable(p, bqm, a, b); + bqm.set(a, 2); + bqm.set(b, 3); + tst_refinable(p, bqm, a, b); + bqm.set(a, 3, 1); + bqm.set(b, 3); + tst_refinable(p, bqm, a, b); + bqm.set(a, 1); + bqm.set(b, 5, 1); + tst_refinable(p, bqm, a, b); + bqm.set(a, 3, 1); + bqm.set(b, 5, 1); + tst_refinable(p, bqm, a, b); + + p = (x - 1)*(x - 2)*(x - 3); + std::cout << "p: " << p << "\n"; + bqm.set(a, 1); + bqm.set(b, 3); + tst_refinable(p, bqm, a, b); + + bqm.del(a); bqm.del(b); +} + +static void tst_refine(polynomial_ref const & p, mpbq_manager & bqm, mpbq & a, mpbq & b, unsigned prec_k=100) { + upolynomial::manager um(p.m().m()); + upolynomial::scoped_numeral_vector _p(um); + um.to_numeral_vector(p, _p); + std::cout << "before (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n"; + bool r = um.refine(_p.size(), _p.c_ptr(), bqm, a, b, prec_k); + if (r) { + std::cout << "new (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n"; + std::cout << "as decimal: "; bqm.display_decimal(std::cout, a, prec_k); std::cout << "\n"; + } + else { + std::cout << "new root: " << bqm.to_string(a) << "\n"; + std::cout << "as decimal: "; bqm.display_decimal(std::cout, a, prec_k); std::cout << "\n"; + } +} + +static void tst_refine() { + std::cout << "\nRefining intervals\n"; + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = (x^5) - x - 1; + std::cout << "p: " << p << "\n"; + mpbq_manager bqm(nm); + scoped_mpbq a(bqm), b(bqm); + a = 1; + b = 2; + tst_refine(p, bqm, a, b, 20); + + p = (x^2) - 2; + std::cout << "p: " << p << "\n"; + a = 1; + b = 2; + tst_refine(p, bqm, a, b, 200); +} + +static void tst_translate_q() { + unsynch_mpq_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = (x-1)*(x-2)*(x-3)*(x-4); + upolynomial::manager um(nm); + upolynomial::scoped_numeral_vector _p(um), _q(um); + um.to_numeral_vector(p, _p); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(1)) == 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(2)) == 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(3)) == 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(4)) == 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(-1)) != 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(5)) != 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(-2)) != 0); + scoped_mpq c(nm); + nm.set(c, 1, 3); + scoped_mpq r1(nm); + r1 = 1; + r1 -= c; + scoped_mpq r2(nm); + r2 = 3; + r2 -= c; + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), r1) != 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), r2) != 0); + std::cout << "p: "; um.display(std::cout, _p); std::cout << "\n"; + um.translate_q(_p.size(), _p.c_ptr(), c, _q); + std::cout << "q: "; um.display(std::cout, _q); std::cout << "\n"; + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(1)) != 0); + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(2)) != 0); + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(3)) != 0); + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(4)) != 0); + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(-1)) != 0); + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(5)) != 0); + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(-2)) != 0); + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), r1) == 0); + SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), r2) == 0); + um.p_1_div_x(_p.size(), _p.c_ptr()); + std::cout << "p: "; um.display(std::cout, _p); std::cout << "\n"; + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(1)) == 0); + nm.set(c, 1, 2); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); + nm.set(c, 1, 3); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); + nm.set(c, 1, 4); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(2)) != 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(3)) != 0); + SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(4)) != 0); +} + +static void tst_convert_q2bq(unsynch_mpq_manager & m, polynomial_ref const & p, mpq const & a, mpq const & b) { + upolynomial::manager um(m); + upolynomial::scoped_numeral_vector _p(um); + um.to_numeral_vector(p, _p); + std::cout << "\np: "; + um.display(std::cout, _p); std::cout << "\n"; + std::cout << "before (" << m.to_string(a) << ", " << m.to_string(b) << ") ("; + m.display_decimal(std::cout, a, 10); std::cout << ", "; m.display_decimal(std::cout, b, 10); std::cout << ")\n"; + mpbq_manager bqm(m); + scoped_mpbq c(bqm); + scoped_mpbq d(bqm); + if (!um.convert_q2bq_interval(_p.size(), _p.c_ptr(), a, b, bqm, c, d)) { + std::cout << "found root: " << c << "\n"; + } + else { + std::cout << "after (" << c << ", " << d << ")" << " ("; + bqm.display_decimal(std::cout, c, 10); std::cout << ", "; bqm.display_decimal(std::cout, d, 10); std::cout << ")\n"; + } +} + +static void tst_convert_q2bq() { + unsynch_mpq_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = (x-1)*(x-2)*(x-3)*(x-4); + scoped_mpq a(nm), b(nm); + + nm.set(a, 1, 3); + nm.set(b, 7, 5); + tst_convert_q2bq(nm, p, a, b); + + nm.set(a, 1, 2); + nm.set(b, 7, 5); + tst_convert_q2bq(nm, p, a, b); + + nm.set(a, 3, 7); + nm.set(b, 3, 2); + tst_convert_q2bq(nm, p, a, b); + + nm.set(a, 0); + nm.set(b, 3, 2); + tst_convert_q2bq(nm, p, a, b); + + nm.set(a, 0); + nm.set(b, 23, 21); + tst_convert_q2bq(nm, p, a, b); + + nm.set(a, 7, 2); + nm.set(b, 5); + tst_convert_q2bq(nm, p, a, b); + + nm.set(a, 999, 1000); + nm.set(b, 1001, 1000); + tst_convert_q2bq(nm, p, a, b); + + nm.set(a, 9999, 10000); + nm.set(b, 10001, 10000); + tst_convert_q2bq(nm, p, a, b); + + nm.set(a, 39999, 10000); + nm.set(b, 40001, 10000); + tst_convert_q2bq(nm, p, a, b); +} + +static void tst_sturm2() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + polynomial_ref q(m); + + p = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225; + q = ((x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576)^2; + + upolynomial::manager um(nm); + upolynomial::scoped_numeral_vector _p(um), _q(um); + upolynomial::scoped_upolynomial_sequence seq2(um); + um.to_numeral_vector(p, _p); + um.to_numeral_vector(q, _q); + um.sturm_tarski_seq(_p.size(), _p.c_ptr(), _q.size(), _q.c_ptr(), seq2); + + std::cout << "upolynomial sturm seq...\n"; + um.display(std::cout, seq2); +} + +static void tst_isolate_roots2() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = (2*x - 1)*(x - 21)*(x + 12)*(x - 19)*(x + 11)*(x + 34)*(x - 9)*(x - 72)*(10000*x - 4999)*((x^5) - x - 1)*((x^2) - 2)*((x^2) - 3)*((x^7) - 3)*((x^101) - 3); + { + tst_isolate_roots(p, 10); + } +} + +static void tst_isolate_roots3() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x1(m), x2(m), x3(m), x4(m), x5(m), x6(m), x(m); + x = m.mk_polynomial(m.mk_var()); + x1 = m.mk_polynomial(m.mk_var()); + x2 = m.mk_polynomial(m.mk_var()); + x3 = m.mk_polynomial(m.mk_var()); + x4 = m.mk_polynomial(m.mk_var()); + x5 = m.mk_polynomial(m.mk_var()); + x6 = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p1(m); + polynomial_ref p2(m); + polynomial_ref p3(m); + polynomial_ref p4(m); + polynomial_ref p5(m); + polynomial_ref p6(m); + polynomial_ref q(m); + polynomial_ref r(m); + p1 = ((x1^2) - 2); + p2 = ((x2^2) - 3); + p3 = ((x3^2) - 5); + p4 = ((x4^2) - 7); + p5 = ((x5^2) - 11); + p6 = ((x6^2) - 13); + q = (x - x1 - x2 - x3 - x4 - x5 - x6); + r = resultant(resultant(resultant(resultant(resultant(resultant(q, p1, 1), p2, 2), p3, 3), p4, 4), p5, 5), p6, 6); + std::cout << "r: " << r << "\n"; + { + timeit timer(true, "isolate"); + tst_isolate_roots(r, 10); + } +} + +static void tst_gcd2() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = ((x^1000) - x + 1)^5; + + upolynomial::manager um(nm); + upolynomial::scoped_numeral_vector _p(um); + upolynomial::scoped_numeral_vector _p_sqf(um); + um.to_numeral_vector(p, _p); + { + timeit timer(true, "gcd"); + um.square_free(_p.size(), _p.c_ptr(), _p_sqf); + } + um.display(std::cout, _p_sqf.size(), _p_sqf.c_ptr()); std::cout << "\n"; +} + +static void tst_isolate_roots5() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + p = (x^70) - 6*(x^65) - (x^60) + 60*(x^55) - 54*(x^50) - 230*(x^45) + 274*(x^40) + 542*(x^35) - 615*(x^30) + - 1120*(x^25) + 1500*(x^20) - 160*(x^15) - 395*(x^10) + 76*(x^5) + 34; + { + tst_isolate_roots(p, 10); + } +} + +static void tst_exact_div(polynomial_ref const & p1, polynomial_ref const & p2, bool expected, polynomial_ref const & expected_q) { + upolynomial::manager um(p1.m().m()); + upolynomial::scoped_numeral_vector _p1(um), _p2(um), _q(um), _r(um); + um.to_numeral_vector(p1, _p1); + um.to_numeral_vector(p2, _p2); + if (expected) + um.to_numeral_vector(expected_q, _q); + std::cout << "------\n"; + std::cout << "p1: "; um.display(std::cout, _p1); std::cout << "\n"; + std::cout << "p2: "; um.display(std::cout, _p2); std::cout << std::endl; + bool res = um.exact_div(_p1.size(), _p1.c_ptr(), _p2.size(), _p2.c_ptr(), _r); + if (res) { + std::cout << "r: "; um.display(std::cout, _r); std::cout << "\n"; + } + if (expected) { + std::cout << "expected: "; um.display(std::cout, _q); std::cout << "\n"; + } + std::cout.flush(); + SASSERT(res == expected); + SASSERT(expected == um.divides(_p1.size(), _p1.c_ptr(), _p2.size(), _p2.c_ptr())); + SASSERT(!expected || um.eq(_r, _q)); +} + +static void tst_exact_div() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m); + x = m.mk_polynomial(m.mk_var()); + // create univariate polynomial using multivariate polynomial package + polynomial_ref p(m); + tst_exact_div((x - 1)*(x - 2)*(x - 3), (x-2)*(x-1), true, (x-3)); + tst_exact_div((x - 1)*(2*x - 4)*(x - 3), (x-2)*(x-1), true, (2*x-6)); + tst_exact_div((x - 1)*(2*x - 4)*(x - 3), (x-2)*(x-1)*(x-4), false, x); + tst_exact_div((x - 3), (x-1), false, x); + polynomial_ref z(m); + z = m.mk_const(rational(0)); + tst_exact_div(z, (x-2)*(x-1)*(x-4), true, z); + tst_exact_div((x-2)*(x-1)*(x-4), z, false, z); + tst_exact_div(z, z, false, z); + polynomial_ref two(m); + two = m.mk_const(rational(2)); + tst_exact_div((2*x - 2), (x-1), true, two); + tst_exact_div((2*x - 2), (4*x-4), false, two); + tst_exact_div((6*x - 4), two, true, (3*x - 2)); +} + +static void tst_fact(polynomial_ref const & p, unsigned num_distinct_factors, upolynomial::factor_params const & params = upolynomial::factor_params()) { + SASSERT(is_univariate(p)); + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + upolynomial::manager um(p.m().m()); + upolynomial::scoped_numeral_vector _p(um); + upolynomial::factors fs(um); + um.to_numeral_vector(p, _p); + um.factor(_p, fs, params); + std::cout << "factors:\n"; + std::cout << um.m().to_string(fs.get_constant()) << "\n"; + for (unsigned i = 0; i < fs.distinct_factors(); i++) { + std::cout << "*("; um.display(std::cout, fs[i]); std::cout << ")^" << fs.get_degree(i) << std::endl; + } + SASSERT(fs.distinct_factors() == num_distinct_factors); + upolynomial::scoped_numeral_vector _r(um); + fs.multiply(_r); + TRACE("upolynomial", tout << "_r: "; um.display(tout, _r); tout << "\n_p: "; um.display(tout, _p); tout << "\n";); + SASSERT(um.eq(_p, _r)); +} + +static void tst_fact() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m); + x0 = m.mk_polynomial(m.mk_var()); + tst_fact((x0^4) + (x0^2) - 20, 3); + tst_fact((x0^4) + (x0^2) - 20, 1, upolynomial::factor_params(5, 1, 1000)); + tst_fact((x0^4) + (x0^2) - 20, 3, upolynomial::factor_params(7, 1, 1000)); + tst_fact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 1, upolynomial::factor_params(3, 1, 20)); + tst_fact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 2, upolynomial::factor_params(3, 1, 72)); + tst_fact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 3, upolynomial::factor_params(3, 1, 80)); + tst_fact( (x0^10) - 10*(x0^8) + 38*(x0^6) - 2*(x0^5) - 100*(x0^4) - 40*(x0^3) + 121*(x0^2) - 38*x0 - 17, 1); + tst_fact( (x0^4) - 404*(x0^2) + 39204, 2); + tst_fact(((x0^5) - (x0^2) + 1)*((-1)*x0 + 1)*((x0^2) - 2*x0 + 3), 3); + tst_fact((x0^4) + (x0^2) - 20, 3); + tst_fact((-11)*((x0^5) - (x0^2) + 1)*((-1)*x0 + 1)*((x0^2) - 2*x0 + 3), 3); + tst_fact(x0 - 2*(x0^2) + 1, 2); + tst_fact(13*((x0 - 3)^6)*((x0 - 5)^5)*((x0 - 11)^7), 3); + tst_fact((x0+1)^30, 1); + tst_fact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 3); + tst_fact(((x0^4) - 8*(x0^2)), 2); + tst_fact((x0^5) - 2*(x0^3) + x0 - 1, 1); + tst_fact( (x0^25) - 4*(x0^21) - 5*(x0^20) + 6*(x0^17) + 11*(x0^16) + 10*(x0^15) - 4*(x0^13) - 7*(x0^12) - 9*(x0^11) - 10*(x0^10) + + (x0^9) + (x0^8) + (x0^7) + (x0^6) + 3*(x0^5) + x0 - 1, 2); + tst_fact( (x0^25) - 10*(x0^21) - 10*(x0^20) - 95*(x0^17) - 470*(x0^16) - 585*(x0^15) - 40*(x0^13) - 1280*(x0^12) - 4190*(x0^11) - 3830*(x0^10) + 400*(x0^9)+ 1760*(x0^8) + 760*(x0^7) - 2280*(x0^6) + 449*(x0^5) + 640*(x0^3) - 640*(x0^2) + 240*x0 - 32, 2); + tst_fact( x0^10, 1); + tst_fact( (x0^2) - 1, 2); + tst_fact( (-2)*(x0^2) + 2, 2); + polynomial_ref zero(m); + polynomial_ref three(m); + zero = m.mk_zero(); + three = m.mk_const(rational(3)); + tst_fact(zero, 0); + tst_fact(three, 0); + tst_fact(x0 + 1, 1); + tst_fact(x0 - 1, 1); + tst_fact((-1)*x0 - 1, 1); + tst_fact((-1)*x0 + 1, 1); + tst_fact( (x0^10) - 10*(x0^8) + 38*(x0^6) - 2*(x0^5) - 100*(x0^4) - 40*(x0^3) + 121*(x0^2) - 38*x0 - 17, 1); + tst_fact( (x0^50) - 10*(x0^40) + 38*(x0^30) - 2*(x0^25) - 100*(x0^20) - 40*(x0^15) + 121*(x0^10) - 38*(x0^5) - 17, 1); + + tst_fact( (((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^10) + + 10*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^9) + + 35*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^8) + + 40*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^7) + - 32*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^6) + - 82*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^5) + - 30*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^4) + - 140*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^3) + - 284*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^2) + - 168*((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0) + - 47, 1); + + tst_fact( (x0^4) - 404*(x0^2) + 39204, 2); + tst_fact( ((x0^5) - 15552)* + ((x0^20)- 15708*(x0^15) + rational("138771724")*(x0^10)- rational("432104148432")*(x0^5) + rational("614198284585616")), + 2); + tst_fact( (x0^25) - + rational("3125")*(x0^21) - + rational("15630")*(x0^20) + + rational("3888750")*(x0^17) + + rational("38684375")*(x0^16) + + rational("95765635")*(x0^15) - + rational("2489846500")*(x0^13) - + rational("37650481875")*(x0^12) - + rational("190548065625")*(x0^11) - + rational("323785250010")*(x0^10) + + rational("750249453025")*(x0^9) + + rational("14962295699875")*(x0^8) + + rational("111775113235000")*(x0^7) + + rational("370399286731250")*(x0^6) + + rational("362903064503129")*(x0^5) - + rational("2387239013984400")*(x0^4) - + rational("23872390139844000")*(x0^3) - + rational("119361950699220000")*(x0^2) - + rational("298404876748050000")*x0 - + rational("298500366308609376"), 2); + + tst_fact( rational("54")*(x0^24) - (x0^27) - 324*(x0^21) + rational("17496")*(x0^18) - 34992*(x0^15)+ rational("1889568")*(x0^12)- 1259712*(x0^9) + rational("68024448")*(x0^6), 3); + + tst_fact( ((x0^3)- 432)*(((x0^3)+54)^2)*((x0^6)+108)*((x0^6)+6912)*((x0^6)- 324*(x0^3)+37044), + 5); + + tst_fact( ((x0^6)- 6*(x0^4) - 864*(x0^3) + 12*(x0^2) - 5184*x0 + 186616)* + (((x0^6) - 6*(x0^4) + 108*(x0^3) + 12*(x0^2) + 648*x0 + 2908)^2)* + ((x0^12) - 12*(x0^10) + 60*(x0^8) + 56*(x0^6) + 6720*(x0^4) + 12768*(x0^2) + 13456)* + ((x0^12) - 12*(x0^10) + 60*(x0^8) + 13664*(x0^6) + 414960*(x0^4) + 829248*(x0^2) + 47886400)* + ((x0^12) - 12*(x0^10) - 648*(x0^9)+ 60*(x0^8) + 178904*(x0^6) + 15552*(x0^5) + 1593024*(x0^4) - 24045984*(x0^3) + + 5704800*(x0^2) - 143995968*x0 + 1372010896), + 5); +} + +static void tst_rem(polynomial_ref const & p, polynomial_ref const & q, polynomial_ref const & expected) { + SASSERT(is_univariate(p)); + SASSERT(is_univariate(q)); + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + std::cout << "q: " << q << std::endl; + upolynomial::manager um(p.m().m()); + upolynomial::scoped_numeral_vector _p(um), _q(um), _r(um); + um.to_numeral_vector(p, _p); + um.to_numeral_vector(q, _q); + um.rem(_p.size(), _p.c_ptr(), _q.size(), _q.c_ptr(), _r); + polynomial_ref r(p.m()); + r = p.m().to_polynomial(_r.size(), _r.c_ptr(), 0); + std::cout << "r: " << r << std::endl; + SASSERT(eq(expected, r)); +} + +static void tst_rem() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x0(m), zero(m), one(m); + x0 = m.mk_polynomial(m.mk_var()); + zero = m.mk_zero(); + one = m.mk_const(rational(1)); + tst_rem((x0^2) + x0, x0, zero); + tst_rem((x0^2) + x0 + 1, x0, one); + tst_rem((x0^2) + 2*x0 + 1, 2*x0 + 2, zero); +} + +static void tst_lower_bound(polynomial_ref const & p) { + SASSERT(is_univariate(p)); + std::cout << "---------------\n"; + std::cout << "p: " << p << std::endl; + upolynomial::manager um(p.m().m()); + upolynomial::scoped_numeral_vector _p(um); + um.to_numeral_vector(p, _p); + std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n"; + unsigned k = um.nonzero_root_lower_bound(_p.size(), _p.c_ptr()); + std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n"; + std::cout << "k: " << k << "\n"; +} + +static void tst_lower_bound() { + polynomial::numeral_manager nm; + polynomial::manager m(nm); + polynomial_ref x(m), zero(m), one(m); + x = m.mk_polynomial(m.mk_var()); + zero = m.mk_zero(); + one = m.mk_const(rational(1)); + tst_lower_bound((x^2) - 2); + tst_lower_bound((x^5)); + tst_lower_bound((x - 1)*(2*x - 1)*(4*x - 1)*(8*x - 1)); + tst_lower_bound((x - 1)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1)); + tst_lower_bound((x - 1)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1)*(x^3)); + tst_lower_bound((x^5) - x - 1); + tst_lower_bound((1000*x - 1)*(x - 1)); + tst_lower_bound((x + 1)*(2*x - 1)*(4*x + 1)*(8*x - 1)*(16*x + 1)); + tst_lower_bound((x + 1)*(2*x + 1)*(4*x + 1)*(8*x + 1)*(16*x + 1)); + tst_lower_bound((x^10) - 10*(x^8) + 38*(x^6) - 2*(x^5) - 100*(x^4) - 40*(x^3) + 121*(x^2) - 38*x - 17); + tst_lower_bound(((x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7)*(((x^5) - x - 1)^2)*(((x^3) - 2)^2)); + tst_lower_bound((((x^5) - 1000000000)^3)*((3*x - 10000000)^2)*((10*x - 632)^2)); +} + +void tst_upolynomial() { + set_verbosity_level(1000); + enable_trace("mpz_gcd"); + enable_trace("normalize_bug"); + enable_trace("factor_bug"); + enable_trace("factor"); + // enable_trace("mpzp_inv_bug"); + // enable_trace("mpz"); + tst_gcd(); + tst_lower_bound(); + tst_fact(); + tst_rem(); + tst_exact_div(); + tst_isolate_roots5(); + // tst_gcd2(); + // tst_isolate_roots4(); + // tst_isolate_roots3(); + // tst_isolate_roots2(); + // return; + tst_isolate_roots(); + tst_sturm2(); + tst_convert_q2bq(); + enable_trace("div_bug"); + enable_trace("mpbq_bug"); + tst_translate_q(); + tst_refine(); + tst_refinable(); + tst_sturm(); + tst_remove_one_half(); + tst_isolate_roots(); + tst1(); + tst_zp(); + tst_zp2(); + tst_ext_gcd(); + tst_ext_gcd_z7(); +} diff --git a/test/var_subst.cpp b/test/var_subst.cpp new file mode 100644 index 000000000..ec8078025 --- /dev/null +++ b/test/var_subst.cpp @@ -0,0 +1,124 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + var_subst.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-12. + +Revision History: + +--*/ +#include"var_subst.h" +#include"smtparser.h" +#include"ast_pp.h" +#include"arith_decl_plugin.h" +#include"bv_decl_plugin.h" +#include"array_decl_plugin.h" +#include"for_each_expr.h" + +namespace find_q { + struct proc { + quantifier * m_q; + proc():m_q(0) {} + void operator()(var * n) {} + void operator()(app * n) {} + void operator()(quantifier * n) { m_q = n; } + }; +}; + +quantifier * find_quantifier(expr * n) { + find_q::proc p; + for_each_expr(p, n); + return p.m_q; +} + +void tst_instantiate(ast_manager & m, expr * f) { + if (is_quantifier(f)) { + tst_instantiate(m, to_quantifier(f)->get_expr()); + return; + } + quantifier * q = find_quantifier(f); + if (q) { + expr_ref_vector cnsts(m); + for (unsigned i = 0; i < q->get_num_decls(); i++) + cnsts.push_back(m.mk_fresh_const("a", q->get_decl_sort(i))); + expr_ref r(m); + instantiate(m, q, cnsts.c_ptr(), r); + TRACE("var_subst", tout << "quantifier:\n" << mk_pp(q, m) << "\nresult:\n" << mk_pp(r, m) << "\n";); + } +} + +void tst_subst(ast_manager& m) { + func_decl_ref p(m); + sort_ref s(m); + obj_ref x(m), y(m), z(m), u(m), v(m); + expr_ref e1(m), e2(m), e3(m); + expr_ref t1(m), t2(m), t3(m); + s = m.mk_sort(symbol("S")); + sort* ss[2] = { s.get(), s.get() }; + symbol names[2] = { symbol("y"), symbol("x") }; + p = m.mk_func_decl(symbol("p"), 2, ss, m.mk_bool_sort()); + x = m.mk_var(0, s); + y = m.mk_var(1, s); + z = m.mk_var(2, s); + u = m.mk_var(3, s); + v = m.mk_var(4, s); + e1 = m.mk_and(m.mk_app(p, x.get(), y.get()), m.mk_app(p, z.get(), u.get())); + e2 = m.mk_forall(1, ss, names, e1); + t1 = m.mk_forall(1, ss, names, + m.mk_and(m.mk_app(p, x.get(), z.get()), m.mk_app(p, y.get(), u.get()))); + t2 = m.mk_forall(2, ss, names, + m.mk_and(m.mk_app(p, x.get(), y.get()), m.mk_app(p, u.get(), z.get()))); + + var_subst subst(m); + expr_ref_vector sub1(m); + sub1.push_back(x); + sub1.push_back(y); + // replace #1 -> #2, #2 -> #1 + subst(e2, 2, sub1.c_ptr(), e3); + std::cout << mk_pp(e2, m) << "\n"; + std::cout << mk_pp(e3, m) << "\n"; + std::cout << mk_pp(t1, m) << "\n"; + SASSERT(e3.get() == t1.get()); + + // replace #2 -> #3, #3 -> #2 + e2 = m.mk_forall(2, ss, names, e1); + subst(e2, 2, sub1.c_ptr(), e3); + std::cout << mk_pp(e2, m) << "\n"; + std::cout << mk_pp(e3, m) << "\n"; + std::cout << mk_pp(t2, m) << "\n"; + SASSERT(e3.get() == t2.get()); + +} + +void tst_var_subst() { + ast_manager m; + m.register_decl_plugins(); + 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); +} diff --git a/test/vector.cpp b/test/vector.cpp new file mode 100644 index 000000000..5ae62e150 --- /dev/null +++ b/test/vector.cpp @@ -0,0 +1,49 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_vector.cpp + +Abstract: + + Test my vector template. + +Author: + + Leonardo de Moura (leonardo) 2006-09-11. + +Revision History: + +--*/ +#include"vector.h" + +static void tst1() { + vector v1; + SASSERT(v1.empty()); + for (unsigned i = 0; i < 1000; i++) { + v1.push_back(i + 3); + SASSERT(v1[i] == i + 3); + SASSERT(v1.capacity() >= v1.size()); + SASSERT(!v1.empty()); + } + for (unsigned i = 0; i < 1000; i++) { + SASSERT(v1[i] == i + 3); + } + vector::iterator it = v1.begin(); + vector::iterator end = v1.end(); + for (int i = 0; it != end; ++it, ++i) { + SASSERT(*it == i + 3); + } + for (unsigned i = 0; i < 1000; i++) { + SASSERT(v1.back() == 1000 - i - 1 + 3); + SASSERT(v1.size() == 1000 - i); + v1.pop_back(); + } + SASSERT(v1.empty()); + SASSERT(v1.size() == 0); +} + +void tst_vector() { + tst1(); +} diff --git a/test/watch_list.cpp b/test/watch_list.cpp new file mode 100644 index 000000000..163edae0f --- /dev/null +++ b/test/watch_list.cpp @@ -0,0 +1,89 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + tst_watch_list.cpp + +Abstract: + + Test watch list data structure. + +Author: + + Leonardo de Moura (leonardo) 2006-10-02. + +Revision History: + +--*/ +#include"vector.h" +#include"sat_types.h" + +static void tst1() { + watch_list wl; + for(unsigned i = 0; i < 10; i++) + wl.insert_clause(reinterpret_cast(static_cast(i+1))); +} + +static void tst2() { + ptr_vector clause_list; + vector lit_list; + watch_list wl; + unsigned n = rand()%1000; + for (unsigned i = 0; i < n; i++) { + unsigned op = rand()%7; + if (op <= 1) { + clause * c = reinterpret_cast(static_cast(rand())); + wl.insert_clause(c); + clause_list.push_back(c); + } + else if (op <= 3) { + literal l = to_literal(rand()); + wl.insert_literal(l); + lit_list.push_back(l); + } + else if (op <= 4) { + if (!clause_list.empty()) { + int idx = rand() % (clause_list.size()); + clause * c = clause_list[idx]; + wl.remove_clause(c); + ptr_vector::iterator it = std::find(clause_list.begin(), clause_list.end(), c); + SASSERT(it); + clause_list.erase(it); + } + } + else if (op <= 5) { + ptr_vector::iterator it = clause_list.begin(); + ptr_vector::iterator end = clause_list.end(); + watch_list::clause_iterator it2 = wl.begin_clause(); + watch_list::clause_iterator end2 = wl.end_clause(); + for (; it != end; ++it, ++it2) { + SASSERT(it2 != end2); + SASSERT(*it == *it2); + } + } + else if (op <= 6) { + vector::iterator begin = lit_list.begin(); + vector::iterator it = lit_list.end(); + watch_list::literal_iterator it2 = wl.begin_literals(); + watch_list::literal_iterator end2 = wl.end_literals(); + while (it != begin) { + --it; + SASSERT(it2 != end2); + SASSERT(*it == *it2); + ++it2; + } + } + } +} + +static void tst3() { + for (unsigned i = 0; i < 1000; i++) + tst2(); +} + +void tst_watch_list() { + tst1(); + tst3(); +} + diff --git a/test_capi/README-external.txt b/test_capi/README-external.txt new file mode 100644 index 000000000..ede64e80a --- /dev/null +++ b/test_capi/README-external.txt @@ -0,0 +1,26 @@ +WARNING: this example still uses the old Z3 (version 3.x) C API. The current version is backward compatible. Please go to the examples/c++ for examples using the new API. + +This directory contains scripts to build the test application using +Microsoft C compiler, or gcc. + +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, +test_capi.exe can find z3.dll. + + +2) Using gcc + +Use 'build.sh' to build the test application using gcc. +The script 'exec.sh' adds the bin directory to the path. So, +test_capi.exe can find z3.dll. + +Remark: the scripts 'build.sh' and 'exec.sh' assumes you are in a +Cygwin or Mingw shell. + diff --git a/test_capi/README-linux.txt b/test_capi/README-linux.txt new file mode 100644 index 000000000..a0e3fc405 --- /dev/null +++ b/test_capi/README-linux.txt @@ -0,0 +1,8 @@ +WARNING: this example still uses the old Z3 (version 3.x) C API. The current version is backward compatible. Please go to the examples/c++ for examples using the new API. + +This directory contains scripts to build the test application using gcc. + +Use 'build.sh' to build the test application using gcc. +The script 'exec.sh' adds the lib directory to the path. So, +test_capi can find libz3.so. + diff --git a/test_capi/README-osx.txt b/test_capi/README-osx.txt new file mode 100644 index 000000000..fefe3cae9 --- /dev/null +++ b/test_capi/README-osx.txt @@ -0,0 +1,8 @@ +WARNING: this example still uses the old Z3 (version 3.x) C API. The current version is backward compatible. Please go to the examples/c++ for examples using the new API. + +This directory contains scripts to build the test application using gcc. + +Use 'build.sh' to build the test application using gcc. +The script 'exec.sh' adds the lib directory to the path. So, +test_capi can find libz3.dylib. + diff --git a/test_capi/build-external-linux.sh b/test_capi/build-external-linux.sh new file mode 100644 index 000000000..ca7b5c953 --- /dev/null +++ b/test_capi/build-external-linux.sh @@ -0,0 +1 @@ +gcc -fopenmp -o test_capi test_capi.c -I ../../include -L ../../lib -lz3 diff --git a/test_capi/build-external-osx.sh b/test_capi/build-external-osx.sh new file mode 100644 index 000000000..ca7b5c953 --- /dev/null +++ b/test_capi/build-external-osx.sh @@ -0,0 +1 @@ +gcc -fopenmp -o test_capi test_capi.c -I ../../include -L ../../lib -lz3 diff --git a/test_capi/build-external.cmd b/test_capi/build-external.cmd new file mode 100644 index 000000000..5ac5ca622 --- /dev/null +++ b/test_capi/build-external.cmd @@ -0,0 +1 @@ +cl /I ..\..\include ..\..\bin\z3.lib test_capi.c diff --git a/test_capi/build-external.sh b/test_capi/build-external.sh new file mode 100644 index 000000000..d7b1f6123 --- /dev/null +++ b/test_capi/build-external.sh @@ -0,0 +1 @@ +gcc -fopenmp -o test_capi.exe -I ../../include ../../bin/z3.dll test_capi.c diff --git a/test_capi/build-static-linux.sh b/test_capi/build-static-linux.sh new file mode 100644 index 000000000..1d7f2fecc --- /dev/null +++ b/test_capi/build-static-linux.sh @@ -0,0 +1,4 @@ +# Note: Z3 was built using C++, so libz3.a has C++ dependencies. +# You can use gcc to link the program, but you need tell it +# to link the C++ libraries +g++ -fopenmp -static -I../../include -L../../lib test_capi.c -lz3 -o test_capi diff --git a/test_capi/build-static-osx.sh b/test_capi/build-static-osx.sh new file mode 100644 index 000000000..4a2889e94 --- /dev/null +++ b/test_capi/build-static-osx.sh @@ -0,0 +1,4 @@ +# Note: Z3 was built using C++, so libz3.a has C++ dependencies. +# You can use gcc to link the program, but you need tell it +# to link the C++ libraries +g++ -fopenmp -I../../include test_capi.c ../../lib/libz3.a -o test_capi diff --git a/test_capi/exec-external-linux.sh b/test_capi/exec-external-linux.sh new file mode 100644 index 000000000..ced185c0f --- /dev/null +++ b/test_capi/exec-external-linux.sh @@ -0,0 +1,2 @@ +export LD_LIBRARY_PATH=../../lib:$LD_LIBRARY_PATH +./test_capi diff --git a/test_capi/exec-external-osx.sh b/test_capi/exec-external-osx.sh new file mode 100644 index 000000000..2fc2a0ac1 --- /dev/null +++ b/test_capi/exec-external-osx.sh @@ -0,0 +1,2 @@ +export DYLD_LIBRARY_PATH=../../lib:$DYLD_LIBRARY_PATH +./test_capi diff --git a/test_capi/exec-external.cmd b/test_capi/exec-external.cmd new file mode 100644 index 000000000..b6310d5ac --- /dev/null +++ b/test_capi/exec-external.cmd @@ -0,0 +1,5 @@ +@echo off +SETLOCAL +set PATH=..\..\bin;%PATH% +test_capi.exe +ENDLOCAL diff --git a/test_capi/exec-external.sh b/test_capi/exec-external.sh new file mode 100644 index 000000000..aa2ed0c7c --- /dev/null +++ b/test_capi/exec-external.sh @@ -0,0 +1,2 @@ +export PATH=../../bin:$PATH +./test_capi.exe diff --git a/test_capi/test_capi.c b/test_capi/test_capi.c new file mode 100644 index 000000000..70cdc2852 --- /dev/null +++ b/test_capi/test_capi.c @@ -0,0 +1,2695 @@ +#include +#include +#include +#include +#include +#include + +#define LOG_Z3_CALLS + +#ifdef LOG_Z3_CALLS +#define LOG_MSG(msg) Z3_append_log(msg) +#else +#define LOG_MSG(msg) ((void)0) +#endif + +/** + \defgroup capi_ex C API examples +*/ +/*@{*/ +/** + @name Auxiliary Functions +*/ +/*@{*/ + +/** + \brief exit gracefully in case of error. +*/ +void exitf(const char* message) +{ + fprintf(stderr,"BUG: %s.\n", message); + exit(1); +} + +/** + \brief exit if unreachable code was reached. +*/ +void unreachable() +{ + exitf("unreachable code was reached"); +} + +/** + \brief Simpler error handler. + */ +void error_handler(Z3_context c, Z3_error_code e) +{ + printf("Error code: %d\n", e); + exitf("incorrect use of Z3"); +} + +static jmp_buf g_catch_buffer; +/** + \brief Low tech exceptions. + + In high-level programming languages, an error handler can throw an exception. +*/ +void throw_z3_error(Z3_context c, Z3_error_code e) +{ + longjmp(g_catch_buffer, e); +} + +/** + \brief Create a logical context. + + Enable model construction. Other configuration parameters can be passed in the cfg variable. + + Also enable tracing to stderr and register custom error handler. +*/ +Z3_context mk_context_custom(Z3_config cfg, Z3_error_handler err) +{ + Z3_context ctx; + + Z3_set_param_value(cfg, "MODEL", "true"); + ctx = Z3_mk_context(cfg); + Z3_set_error_handler(ctx, err); + + return ctx; +} + +/** + \brief Create a logical context. + + Enable model construction only. + + Also enable tracing to stderr and register standard error handler. +*/ +Z3_context mk_context() +{ + Z3_config cfg; + Z3_context ctx; + cfg = Z3_mk_config(); + ctx = mk_context_custom(cfg, error_handler); + Z3_del_config(cfg); + return ctx; +} + +/** + \brief Create a logical context. + + Enable fine-grained proof construction. + Enable model construction. + + Also enable tracing to stderr and register standard error handler. +*/ +Z3_context mk_proof_context() { + Z3_config cfg = Z3_mk_config(); + Z3_context ctx; + Z3_set_param_value(cfg, "PROOF_MODE", "2"); + ctx = mk_context_custom(cfg, throw_z3_error); + Z3_del_config(cfg); + return ctx; +} + +/** + \brief Create a variable using the given name and type. +*/ +Z3_ast mk_var(Z3_context ctx, const char * name, Z3_sort ty) +{ + Z3_symbol s = Z3_mk_string_symbol(ctx, name); + return Z3_mk_const(ctx, s, ty); +} + +/** + \brief Create a boolean variable using the given name. +*/ +Z3_ast mk_bool_var(Z3_context ctx, const char * name) +{ + Z3_sort ty = Z3_mk_bool_sort(ctx); + return mk_var(ctx, name, ty); +} + +/** + \brief Create an integer variable using the given name. +*/ +Z3_ast mk_int_var(Z3_context ctx, const char * name) +{ + Z3_sort ty = Z3_mk_int_sort(ctx); + return mk_var(ctx, name, ty); +} + +/** + \brief Create a Z3 integer node using a C int. +*/ +Z3_ast mk_int(Z3_context ctx, int v) +{ + Z3_sort ty = Z3_mk_int_sort(ctx); + return Z3_mk_int(ctx, v, ty); +} + +/** + \brief Create a real variable using the given name. +*/ +Z3_ast mk_real_var(Z3_context ctx, const char * name) +{ + Z3_sort ty = Z3_mk_real_sort(ctx); + return mk_var(ctx, name, ty); +} + +/** + \brief Create the unary function application: (f x). +*/ +Z3_ast mk_unary_app(Z3_context ctx, Z3_func_decl f, Z3_ast x) +{ + Z3_ast args[1] = {x}; + return Z3_mk_app(ctx, f, 1, args); +} + +/** + \brief Create the binary function application: (f x y). +*/ +Z3_ast mk_binary_app(Z3_context ctx, Z3_func_decl f, Z3_ast x, Z3_ast y) +{ + Z3_ast args[2] = {x, y}; + return Z3_mk_app(ctx, f, 2, args); +} + +/** + \brief Check whether the logical context is satisfiable, and compare the result with the expected result. + If the context is satisfiable, then display the model. +*/ +void check(Z3_context ctx, Z3_lbool expected_result) +{ + Z3_model m = 0; + Z3_lbool result = Z3_check_and_get_model(ctx, &m); + switch (result) { + case Z3_L_FALSE: + printf("unsat\n"); + break; + case Z3_L_UNDEF: + printf("unknown\n"); + printf("potential model:\n%s\n", Z3_model_to_string(ctx, m)); + break; + case Z3_L_TRUE: + printf("sat\n%s\n", Z3_model_to_string(ctx, m)); + break; + } + if (m) { + Z3_del_model(ctx, m); + } + if (result != expected_result) { + exitf("unexpected result"); + } +} + +/** + \brief Prove that the constraints already asserted into the logical + context implies the given formula. The result of the proof is + displayed. + + Z3 is a satisfiability checker. So, one can prove \c f by showing + that (not f) is unsatisfiable. + + The context \c ctx is not modified by this function. +*/ +void prove(Z3_context ctx, Z3_ast f, Z3_bool is_valid) +{ + Z3_model m; + Z3_ast not_f; + + /* save the current state of the context */ + Z3_push(ctx); + + not_f = Z3_mk_not(ctx, f); + Z3_assert_cnstr(ctx, not_f); + + m = 0; + + switch (Z3_check_and_get_model(ctx, &m)) { + case Z3_L_FALSE: + /* proved */ + printf("valid\n"); + if (!is_valid) { + exitf("unexpected result"); + } + break; + case Z3_L_UNDEF: + /* Z3 failed to prove/disprove f. */ + printf("unknown\n"); + if (m != 0) { + /* m should be viewed as a potential counterexample. */ + printf("potential counterexample:\n%s\n", Z3_model_to_string(ctx, m)); + } + if (is_valid) { + exitf("unexpected result"); + } + break; + case Z3_L_TRUE: + /* disproved */ + printf("invalid\n"); + if (m) { + /* the model returned by Z3 is a counterexample */ + printf("counterexample:\n%s\n", Z3_model_to_string(ctx, m)); + } + if (is_valid) { + exitf("unexpected result"); + } + break; + } + + if (m) { + Z3_del_model(ctx, m); + } + + /* restore context */ + Z3_pop(ctx, 1); +} + +/** + \brief Assert the axiom: function f is injective in the i-th argument. + + The following axiom is asserted into the logical context: + \code + forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i + \endcode + + Where, \c finv is a fresh function declaration. +*/ +void assert_inj_axiom(Z3_context ctx, Z3_func_decl f, unsigned i) +{ + unsigned sz, j; + Z3_sort finv_domain, finv_range; + Z3_func_decl finv; + Z3_sort * types; /* types of the quantified variables */ + Z3_symbol * names; /* names of the quantified variables */ + Z3_ast * xs; /* arguments for the application f(x_0, ..., x_i, ..., x_{n-1}) */ + Z3_ast x_i, fxs, finv_fxs, eq; + Z3_pattern p; + Z3_ast q; + sz = Z3_get_domain_size(ctx, f); + + if (i >= sz) { + exitf("failed to create inj axiom"); + } + + /* declare the i-th inverse of f: finv */ + finv_domain = Z3_get_range(ctx, f); + finv_range = Z3_get_domain(ctx, f, i); + finv = Z3_mk_fresh_func_decl(ctx, "inv", 1, &finv_domain, finv_range); + + /* allocate temporary arrays */ + types = (Z3_sort *) malloc(sizeof(Z3_sort) * sz); + names = (Z3_symbol *) malloc(sizeof(Z3_symbol) * sz); + xs = (Z3_ast *) malloc(sizeof(Z3_ast) * sz); + + /* fill types, names and xs */ + for (j = 0; j < sz; j++) { types[j] = Z3_get_domain(ctx, f, j); }; + for (j = 0; j < sz; j++) { names[j] = Z3_mk_int_symbol(ctx, j); }; + for (j = 0; j < sz; j++) { xs[j] = Z3_mk_bound(ctx, j, types[j]); }; + + x_i = xs[i]; + + /* create f(x_0, ..., x_i, ..., x_{n-1}) */ + fxs = Z3_mk_app(ctx, f, sz, xs); + + /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ + finv_fxs = mk_unary_app(ctx, finv, fxs); + + /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ + eq = Z3_mk_eq(ctx, finv_fxs, x_i); + + /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ + p = Z3_mk_pattern(ctx, 1, &fxs); + printf("pattern: %s\n", Z3_pattern_to_string(ctx, p)); + printf("\n"); + + /* create & assert quantifier */ + q = Z3_mk_forall(ctx, + 0, /* using default weight */ + 1, /* number of patterns */ + &p, /* address of the "array" of patterns */ + sz, /* number of quantified variables */ + types, + names, + eq); + printf("assert axiom:\n%s\n", Z3_ast_to_string(ctx, q)); + Z3_assert_cnstr(ctx, q); + + /* free temporary arrays */ + free(types); + free(names); + free(xs); +} + +/** + \brief Assert the axiom: function f is commutative. + + This example uses the SMT-LIB parser to simplify the axiom construction. +*/ +void assert_comm_axiom(Z3_context ctx, Z3_func_decl f) +{ + Z3_sort t; + Z3_symbol f_name, t_name; + Z3_ast q; + + t = Z3_get_range(ctx, f); + + if (Z3_get_domain_size(ctx, f) != 2 || + Z3_get_domain(ctx, f, 0) != t || + Z3_get_domain(ctx, f, 1) != t) { + exitf("function must be binary, and argument types must be equal to return type"); + } + + /* Inside the parser, function f will be referenced using the symbol 'f'. */ + f_name = Z3_mk_string_symbol(ctx, "f"); + + /* Inside the parser, type t will be referenced using the symbol 'T'. */ + t_name = Z3_mk_string_symbol(ctx, "T"); + + + Z3_parse_smtlib_string(ctx, + "(benchmark comm :formula (forall (x T) (y T) (= (f x y) (f y x))))", + 1, &t_name, &t, + 1, &f_name, &f); + q = Z3_get_smtlib_formula(ctx, 0); + printf("assert axiom:\n%s\n", Z3_ast_to_string(ctx, q)); + Z3_assert_cnstr(ctx, q); +} + +/** + \brief Z3 does not support explicitly tuple updates. They can be easily implemented + as macros. The argument \c t must have tuple type. + A tuple update is a new tuple where field \c i has value \c new_val, and all + other fields have the value of the respective field of \c t. + + update(t, i, new_val) is equivalent to + mk_tuple(proj_0(t), ..., new_val, ..., proj_n(t)) +*/ +Z3_ast mk_tuple_update(Z3_context c, Z3_ast t, unsigned i, Z3_ast new_val) +{ + Z3_sort ty; + Z3_func_decl mk_tuple_decl; + unsigned num_fields, j; + Z3_ast * new_fields; + Z3_ast result; + + ty = Z3_get_sort(c, t); + + if (Z3_get_sort_kind(c, ty) != Z3_DATATYPE_SORT) { + exitf("argument must be a tuple"); + } + + num_fields = Z3_get_tuple_sort_num_fields(c, ty); + + if (i >= num_fields) { + exitf("invalid tuple update, index is too big"); + } + + new_fields = (Z3_ast*) malloc(sizeof(Z3_ast) * num_fields); + for (j = 0; j < num_fields; j++) { + if (i == j) { + /* use new_val at position i */ + new_fields[j] = new_val; + } + else { + /* use field j of t */ + Z3_func_decl proj_decl = Z3_get_tuple_sort_field_decl(c, ty, j); + new_fields[j] = mk_unary_app(c, proj_decl, t); + } + } + mk_tuple_decl = Z3_get_tuple_sort_mk_decl(c, ty); + result = Z3_mk_app(c, mk_tuple_decl, num_fields, new_fields); + free(new_fields); + return result; +} + +/** + \brief Display a symbol in the given output stream. +*/ +void display_symbol(Z3_context c, FILE * out, Z3_symbol s) +{ + switch (Z3_get_symbol_kind(c, s)) { + case Z3_INT_SYMBOL: + fprintf(out, "#%d", Z3_get_symbol_int(c, s)); + break; + case Z3_STRING_SYMBOL: + fprintf(out, "%s", Z3_get_symbol_string(c, s)); + break; + default: + unreachable(); + } +} + +/** + \brief Display the given type. +*/ +void display_sort(Z3_context c, FILE * out, Z3_sort ty) +{ + switch (Z3_get_sort_kind(c, ty)) { + case Z3_UNINTERPRETED_SORT: + display_symbol(c, out, Z3_get_sort_name(c, ty)); + break; + case Z3_BOOL_SORT: + fprintf(out, "bool"); + break; + case Z3_INT_SORT: + fprintf(out, "int"); + break; + case Z3_REAL_SORT: + fprintf(out, "real"); + break; + case Z3_BV_SORT: + fprintf(out, "bv%d", Z3_get_bv_sort_size(c, ty)); + break; + case Z3_ARRAY_SORT: + fprintf(out, "["); + display_sort(c, out, Z3_get_array_sort_domain(c, ty)); + fprintf(out, "->"); + display_sort(c, out, Z3_get_array_sort_range(c, ty)); + fprintf(out, "]"); + break; + case Z3_DATATYPE_SORT: + if (Z3_get_datatype_sort_num_constructors(c, ty) != 1) + { + fprintf(out, "%s", Z3_sort_to_string(c,ty)); + break; + } + { + unsigned num_fields = Z3_get_tuple_sort_num_fields(c, ty); + unsigned i; + fprintf(out, "("); + for (i = 0; i < num_fields; i++) { + Z3_func_decl field = Z3_get_tuple_sort_field_decl(c, ty, i); + if (i > 0) { + fprintf(out, ", "); + } + display_sort(c, out, Z3_get_range(c, field)); + } + fprintf(out, ")"); + break; + } + default: + fprintf(out, "unknown["); + display_symbol(c, out, Z3_get_sort_name(c, ty)); + fprintf(out, "]"); + break; + } +} + +/** + \brief Custom ast pretty printer. + + This function demonstrates how to use the API to navigate terms. +*/ +void display_ast(Z3_context c, FILE * out, Z3_ast v) +{ + switch (Z3_get_ast_kind(c, v)) { + case Z3_NUMERAL_AST: { + Z3_sort t; + fprintf(out, "%s", Z3_get_numeral_string(c, v)); + t = Z3_get_sort(c, v); + fprintf(out, ":"); + display_sort(c, out, t); + break; + } + case Z3_APP_AST: { + unsigned i; + Z3_app app = Z3_to_app(c, v); + unsigned num_fields = Z3_get_app_num_args(c, app); + Z3_func_decl d = Z3_get_app_decl(c, app); + fprintf(out, "%s", Z3_func_decl_to_string(c, d)); + if (num_fields > 0) { + fprintf(out, "["); + for (i = 0; i < num_fields; i++) { + if (i > 0) { + fprintf(out, ", "); + } + display_ast(c, out, Z3_get_app_arg(c, app, i)); + } + fprintf(out, "]"); + } + break; + } + case Z3_QUANTIFIER_AST: { + fprintf(out, "quantifier"); + ; + } + default: + fprintf(out, "#unknown"); + } +} + +/** + \brief Custom function interpretations pretty printer. +*/ +void display_function_interpretations(Z3_context c, FILE * out, Z3_model m) +{ + unsigned num_functions, i; + + fprintf(out, "function interpretations:\n"); + + num_functions = Z3_get_model_num_funcs(c, m); + for (i = 0; i < num_functions; i++) { + Z3_func_decl fdecl; + Z3_symbol name; + Z3_ast func_else; + unsigned num_entries, j; + + fdecl = Z3_get_model_func_decl(c, m, i); + name = Z3_get_decl_name(c, fdecl); + display_symbol(c, out, name); + fprintf(out, " = {"); + num_entries = Z3_get_model_func_num_entries(c, m, i); + for (j = 0; j < num_entries; j++) { + unsigned num_args, k; + if (j > 0) { + fprintf(out, ", "); + } + num_args = Z3_get_model_func_entry_num_args(c, m, i, j); + fprintf(out, "("); + for (k = 0; k < num_args; k++) { + if (k > 0) { + fprintf(out, ", "); + } + display_ast(c, out, Z3_get_model_func_entry_arg(c, m, i, j, k)); + } + fprintf(out, "|->"); + display_ast(c, out, Z3_get_model_func_entry_value(c, m, i, j)); + fprintf(out, ")"); + } + if (num_entries > 0) { + fprintf(out, ", "); + } + fprintf(out, "(else|->"); + func_else = Z3_get_model_func_else(c, m, i); + display_ast(c, out, func_else); + fprintf(out, ")}\n"); + } +} + +/** + \brief Custom model pretty printer. +*/ +void display_model(Z3_context c, FILE * out, Z3_model m) +{ + unsigned num_constants; + unsigned i; + + num_constants = Z3_get_model_num_constants(c, m); + for (i = 0; i < num_constants; i++) { + Z3_symbol name; + Z3_func_decl cnst = Z3_get_model_constant(c, m, i); + Z3_ast a, v; + Z3_bool ok; + name = Z3_get_decl_name(c, cnst); + display_symbol(c, out, name); + fprintf(out, " = "); + a = Z3_mk_app(c, cnst, 0, 0); + v = a; + ok = Z3_eval(c, m, a, &v); + display_ast(c, out, v); + fprintf(out, "\n"); + } + display_function_interpretations(c, out, m); +} + +/** + \brief Similar to #check, but uses #display_model instead of #Z3_model_to_string. +*/ +void check2(Z3_context ctx, Z3_lbool expected_result) +{ + Z3_model m = 0; + Z3_lbool result = Z3_check_and_get_model(ctx, &m); + switch (result) { + case Z3_L_FALSE: + printf("unsat\n"); + break; + case Z3_L_UNDEF: + printf("unknown\n"); + printf("potential model:\n"); + display_model(ctx, stdout, m); + break; + case Z3_L_TRUE: + printf("sat\n"); + display_model(ctx, stdout, m); + break; + } + if (m) { + Z3_del_model(ctx, m); + } + if (result != expected_result) { + exitf("unexpected result"); + } +} + +/** + \brief Display Z3 version in the standard output. +*/ +void display_version() +{ + unsigned major, minor, build, revision; + Z3_get_version(&major, &minor, &build, &revision); + printf("Z3 %d.%d.%d.%d\n", major, minor, build, revision); +} +/*@}*/ + +/** + @name Examples +*/ +/*@{*/ +/** + \brief "Hello world" example: create a Z3 logical context, and delete it. +*/ +void simple_example() +{ + Z3_context ctx; + LOG_MSG("simple_example"); + printf("\nsimple_example\n"); + + ctx = mk_context(); + + /* do something with the context */ + printf("CONTEXT:\n%sEND OF CONTEXT\n", Z3_context_to_string(ctx)); + + /* delete logical context */ + Z3_del_context(ctx); +} + +/** + Demonstration of how Z3 can be used to prove validity of + De Morgan's Duality Law: {e not(x and y) <-> (not x) or ( not y) } +*/ +void demorgan() +{ + Z3_config cfg; + Z3_context ctx; + Z3_sort bool_sort; + Z3_symbol symbol_x, symbol_y; + Z3_ast x, y, not_x, not_y, x_and_y, ls, rs, conjecture, negated_conjecture; + Z3_ast args[2]; + + printf("\nDeMorgan\n"); + LOG_MSG("DeMorgan"); + + cfg = Z3_mk_config(); + ctx = Z3_mk_context(cfg); + Z3_del_config(cfg); + bool_sort = Z3_mk_bool_sort(ctx); + symbol_x = Z3_mk_int_symbol(ctx, 0); + symbol_y = Z3_mk_int_symbol(ctx, 1); + x = Z3_mk_const(ctx, symbol_x, bool_sort); + y = Z3_mk_const(ctx, symbol_y, bool_sort); + + /* De Morgan - with a negation around */ + /* !(!(x && y) <-> (!x || !y)) */ + not_x = Z3_mk_not(ctx, x); + not_y = Z3_mk_not(ctx, y); + args[0] = x; + args[1] = y; + x_and_y = Z3_mk_and(ctx, 2, args); + ls = Z3_mk_not(ctx, x_and_y); + args[0] = not_x; + args[1] = not_y; + rs = Z3_mk_or(ctx, 2, args); + conjecture = Z3_mk_iff(ctx, ls, rs); + negated_conjecture = Z3_mk_not(ctx, conjecture); + + Z3_assert_cnstr(ctx, negated_conjecture); + switch (Z3_check(ctx)) { + case Z3_L_FALSE: + /* The negated conjecture was unsatisfiable, hence the conjecture is valid */ + printf("DeMorgan is valid\n"); + break; + case Z3_L_UNDEF: + /* Check returned undef */ + printf("Undef\n"); + break; + case Z3_L_TRUE: + /* The negated conjecture was satisfiable, hence the conjecture is not valid */ + printf("DeMorgan is not valid\n"); + break; + } + Z3_del_context(ctx); +} + +/** + \brief Find a model for x xor y. +*/ +void find_model_example1() +{ + Z3_context ctx; + Z3_ast x, y, x_xor_y; + + printf("\nfind_model_example1\n"); + LOG_MSG("find_model_example1"); + + ctx = mk_context(); + + x = mk_bool_var(ctx, "x"); + y = mk_bool_var(ctx, "y"); + x_xor_y = Z3_mk_xor(ctx, x, y); + + Z3_assert_cnstr(ctx, x_xor_y); + + printf("model for: x xor y\n"); + check(ctx, Z3_L_TRUE); + + Z3_del_context(ctx); +} + +/** + \brief Find a model for x < y + 1, x > 2. + Then, assert not(x = y), and find another model. +*/ +void find_model_example2() +{ + Z3_context ctx; + Z3_ast x, y, one, two, y_plus_one; + Z3_ast x_eq_y; + Z3_ast args[2]; + Z3_ast c1, c2, c3; + + printf("\nfind_model_example2\n"); + LOG_MSG("find_model_example2"); + + ctx = mk_context(); + x = mk_int_var(ctx, "x"); + y = mk_int_var(ctx, "y"); + one = mk_int(ctx, 1); + two = mk_int(ctx, 2); + + args[0] = y; + args[1] = one; + y_plus_one = Z3_mk_add(ctx, 2, args); + + c1 = Z3_mk_lt(ctx, x, y_plus_one); + c2 = Z3_mk_gt(ctx, x, two); + + Z3_assert_cnstr(ctx, c1); + Z3_assert_cnstr(ctx, c2); + + printf("model for: x < y + 1, x > 2\n"); + check(ctx, Z3_L_TRUE); + + /* assert not(x = y) */ + x_eq_y = Z3_mk_eq(ctx, x, y); + c3 = Z3_mk_not(ctx, x_eq_y); + Z3_assert_cnstr(ctx, c3); + + printf("model for: x < y + 1, x > 2, not(x = y)\n"); + check(ctx, Z3_L_TRUE); + + Z3_del_context(ctx); +} + +/** + \brief Prove x = y implies g(x) = g(y), and + disprove x = y implies g(g(x)) = g(y). + + This function demonstrates how to create uninterpreted types and + functions. +*/ +void prove_example1() +{ + Z3_context ctx; + Z3_symbol U_name, g_name, x_name, y_name; + Z3_sort U; + Z3_sort g_domain[1]; + Z3_func_decl g; + Z3_ast x, y, gx, ggx, gy; + Z3_ast eq, f; + + printf("\nprove_example1\n"); + LOG_MSG("prove_example1"); + + ctx = mk_context(); + + /* create uninterpreted type. */ + U_name = Z3_mk_string_symbol(ctx, "U"); + U = Z3_mk_uninterpreted_sort(ctx, U_name); + + /* declare function g */ + g_name = Z3_mk_string_symbol(ctx, "g"); + g_domain[0] = U; + g = Z3_mk_func_decl(ctx, g_name, 1, g_domain, U); + + /* create x and y */ + x_name = Z3_mk_string_symbol(ctx, "x"); + y_name = Z3_mk_string_symbol(ctx, "y"); + x = Z3_mk_const(ctx, x_name, U); + y = Z3_mk_const(ctx, y_name, U); + /* create g(x), g(y) */ + gx = mk_unary_app(ctx, g, x); + gy = mk_unary_app(ctx, g, y); + + /* assert x = y */ + eq = Z3_mk_eq(ctx, x, y); + Z3_assert_cnstr(ctx, eq); + + /* prove g(x) = g(y) */ + f = Z3_mk_eq(ctx, gx, gy); + printf("prove: x = y implies g(x) = g(y)\n"); + prove(ctx, f, Z3_TRUE); + + /* create g(g(x)) */ + ggx = mk_unary_app(ctx, g, gx); + + /* disprove g(g(x)) = g(y) */ + f = Z3_mk_eq(ctx, ggx, gy); + printf("disprove: x = y implies g(g(x)) = g(y)\n"); + prove(ctx, f, Z3_FALSE); + + Z3_del_context(ctx); +} + +/** + \brief Prove not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 . + Then, show that z < -1 is not implied. + + This example demonstrates how to combine uninterpreted functions and arithmetic. +*/ +void prove_example2() +{ + Z3_context ctx; + Z3_sort int_sort; + Z3_symbol g_name; + Z3_sort g_domain[1]; + Z3_func_decl g; + Z3_ast x, y, z, zero, minus_one, x_plus_z, gx, gy, gz, gx_gy, ggx_gy; + Z3_ast args[2]; + Z3_ast eq, c1, c2, c3, f; + + printf("\nprove_example2\n"); + LOG_MSG("prove_example2"); + + ctx = mk_context(); + + /* declare function g */ + int_sort = Z3_mk_int_sort(ctx); + g_name = Z3_mk_string_symbol(ctx, "g"); + g_domain[0] = int_sort; + g = Z3_mk_func_decl(ctx, g_name, 1, g_domain, int_sort); + + /* create x, y, and z */ + x = mk_int_var(ctx, "x"); + y = mk_int_var(ctx, "y"); + z = mk_int_var(ctx, "z"); + + /* create gx, gy, gz */ + gx = mk_unary_app(ctx, g, x); + gy = mk_unary_app(ctx, g, y); + gz = mk_unary_app(ctx, g, z); + + /* create zero */ + zero = mk_int(ctx, 0); + + /* assert not(g(g(x) - g(y)) = g(z)) */ + args[0] = gx; + args[1] = gy; + gx_gy = Z3_mk_sub(ctx, 2, args); + ggx_gy = mk_unary_app(ctx, g, gx_gy); + eq = Z3_mk_eq(ctx, ggx_gy, gz); + c1 = Z3_mk_not(ctx, eq); + Z3_assert_cnstr(ctx, c1); + + /* assert x + z <= y */ + args[0] = x; + args[1] = z; + x_plus_z = Z3_mk_add(ctx, 2, args); + c2 = Z3_mk_le(ctx, x_plus_z, y); + Z3_assert_cnstr(ctx, c2); + + /* assert y <= x */ + c3 = Z3_mk_le(ctx, y, x); + Z3_assert_cnstr(ctx, c3); + + /* prove z < 0 */ + f = Z3_mk_lt(ctx, z, zero); + printf("prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0\n"); + prove(ctx, f, Z3_TRUE); + + /* disprove z < -1 */ + minus_one = mk_int(ctx, -1); + f = Z3_mk_lt(ctx, z, minus_one); + printf("disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1\n"); + prove(ctx, f, Z3_FALSE); + + Z3_del_context(ctx); +} + +/** + \brief Show how push & pop can be used to create "backtracking" + points. + + This example also demonstrates how big numbers can be created in Z3. +*/ +void push_pop_example1() +{ + Z3_context ctx; + Z3_sort int_sort; + Z3_symbol x_sym, y_sym; + Z3_ast x, y, big_number, three; + Z3_ast c1, c2, c3; + + printf("\npush_pop_example1\n"); + LOG_MSG("push_pop_example1"); + + ctx = mk_context(); + + /* create a big number */ + int_sort = Z3_mk_int_sort(ctx); + big_number = Z3_mk_numeral(ctx, "1000000000000000000000000000000000000000000000000000000", int_sort); + + /* create number 3 */ + three = Z3_mk_numeral(ctx, "3", int_sort); + + /* create x */ + x_sym = Z3_mk_string_symbol(ctx, "x"); + x = Z3_mk_const(ctx, x_sym, int_sort); + + /* assert x >= "big number" */ + c1 = Z3_mk_ge(ctx, x, big_number); + printf("assert: x >= 'big number'\n"); + Z3_assert_cnstr(ctx, c1); + + /* create a backtracking point */ + printf("push\n"); + Z3_push(ctx); + + printf("number of scopes: %d\n", Z3_get_num_scopes(ctx)); + + /* assert x <= 3 */ + c2 = Z3_mk_le(ctx, x, three); + printf("assert: x <= 3\n"); + Z3_assert_cnstr(ctx, c2); + + /* context is inconsistent at this point */ + check2(ctx, Z3_L_FALSE); + + /* backtrack: the constraint x <= 3 will be removed, since it was + asserted after the last Z3_push. */ + printf("pop\n"); + Z3_pop(ctx, 1); + + printf("number of scopes: %d\n", Z3_get_num_scopes(ctx)); + + + /* the context is consistent again. */ + check2(ctx, Z3_L_TRUE); + + /* new constraints can be asserted... */ + + /* create y */ + y_sym = Z3_mk_string_symbol(ctx, "y"); + y = Z3_mk_const(ctx, y_sym, int_sort); + + /* assert y > x */ + c3 = Z3_mk_gt(ctx, y, x); + printf("assert: y > x\n"); + Z3_assert_cnstr(ctx, c3); + + /* the context is still consistent. */ + check2(ctx, Z3_L_TRUE); + + Z3_del_context(ctx); +} + +/** + \brief Prove that f(x, y) = f(w, v) implies y = v when + \c f is injective in the second argument. + + \sa assert_inj_axiom. +*/ +void quantifier_example1() +{ + Z3_config cfg; + Z3_context ctx; + Z3_sort int_sort; + Z3_symbol f_name; + Z3_sort f_domain[2]; + Z3_func_decl f; + Z3_ast x, y, w, v, fxy, fwv; + Z3_ast p1, p2, p3, not_p3; + + printf("\nquantifier_example1\n"); + LOG_MSG("quantifier_example1"); + + cfg = Z3_mk_config(); + /* If quantified formulas are asserted in a logical context, then + Z3 may return L_UNDEF. In this case, the model produced by Z3 should be viewed as a potential/candidate model. + */ + Z3_set_param_value(cfg, "MODEL", "true"); + /* + The current model finder for quantified formulas cannot handle injectivity. + So, we are limiting the number of iterations to avoid a long "wait". + */ + Z3_set_param_value(cfg, "MBQI_MAX_ITERATIONS", "10"); + ctx = mk_context_custom(cfg, error_handler); + Z3_del_config(cfg); + + /* declare function f */ + int_sort = Z3_mk_int_sort(ctx); + f_name = Z3_mk_string_symbol(ctx, "f"); + f_domain[0] = int_sort; + f_domain[1] = int_sort; + f = Z3_mk_func_decl(ctx, f_name, 2, f_domain, int_sort); + + /* assert that f is injective in the second argument. */ + assert_inj_axiom(ctx, f, 1); + + /* create x, y, v, w, fxy, fwv */ + x = mk_int_var(ctx, "x"); + y = mk_int_var(ctx, "y"); + v = mk_int_var(ctx, "v"); + w = mk_int_var(ctx, "w"); + fxy = mk_binary_app(ctx, f, x, y); + fwv = mk_binary_app(ctx, f, w, v); + + /* assert f(x, y) = f(w, v) */ + p1 = Z3_mk_eq(ctx, fxy, fwv); + Z3_assert_cnstr(ctx, p1); + + /* prove f(x, y) = f(w, v) implies y = v */ + p2 = Z3_mk_eq(ctx, y, v); + printf("prove: f(x, y) = f(w, v) implies y = v\n"); + prove(ctx, p2, Z3_TRUE); + + /* disprove f(x, y) = f(w, v) implies x = w */ + /* using check2 instead of prove */ + p3 = Z3_mk_eq(ctx, x, w); + not_p3 = Z3_mk_not(ctx, p3); + Z3_assert_cnstr(ctx, not_p3); + printf("disprove: f(x, y) = f(w, v) implies x = w\n"); + printf("that is: not(f(x, y) = f(w, v) implies x = w) is satisfiable\n"); + check2(ctx, Z3_L_UNDEF); + printf("reason for last failure: %d (7 = quantifiers)\n", + Z3_get_search_failure(ctx)); + if (Z3_get_search_failure(ctx) != Z3_QUANTIFIERS) { + exitf("unexpected result"); + } + + Z3_del_context(ctx); +} + +/** + \brief Prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)). + + This example demonstrates how to use the array theory. +*/ +void array_example1() +{ + Z3_context ctx; + Z3_sort int_sort, array_sort; + Z3_ast a1, a2, i1, v1, i2, v2, i3; + Z3_ast st1, st2, sel1, sel2; + Z3_ast antecedent, consequent; + Z3_ast ds[3]; + Z3_ast thm; + + printf("\narray_example1\n"); + LOG_MSG("array_example1"); + + ctx = mk_context(); + + int_sort = Z3_mk_int_sort(ctx); + array_sort = Z3_mk_array_sort(ctx, int_sort, int_sort); + + a1 = mk_var(ctx, "a1", array_sort); + a2 = mk_var(ctx, "a2", array_sort); + i1 = mk_var(ctx, "i1", int_sort); + i2 = mk_var(ctx, "i2", int_sort); + i3 = mk_var(ctx, "i3", int_sort); + v1 = mk_var(ctx, "v1", int_sort); + v2 = mk_var(ctx, "v2", int_sort); + + st1 = Z3_mk_store(ctx, a1, i1, v1); + st2 = Z3_mk_store(ctx, a2, i2, v2); + + sel1 = Z3_mk_select(ctx, a1, i3); + sel2 = Z3_mk_select(ctx, a2, i3); + + /* create antecedent */ + antecedent = Z3_mk_eq(ctx, st1, st2); + + /* create consequent: i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3) */ + ds[0] = Z3_mk_eq(ctx, i1, i3); + ds[1] = Z3_mk_eq(ctx, i2, i3); + ds[2] = Z3_mk_eq(ctx, sel1, sel2); + consequent = Z3_mk_or(ctx, 3, ds); + + /* prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) */ + thm = Z3_mk_implies(ctx, antecedent, consequent); + printf("prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))\n"); + printf("%s\n", Z3_ast_to_string(ctx, thm)); + prove(ctx, thm, Z3_TRUE); + + Z3_del_context(ctx); +} + +/** + \brief Show that distinct(a_0, ... , a_n) is + unsatisfiable when \c a_i's are arrays from boolean to + boolean and n > 4. + + This example also shows how to use the \c distinct construct. +*/ +void array_example2() +{ + Z3_context ctx; + Z3_sort bool_sort, array_sort; + Z3_ast a[5]; + Z3_ast d; + unsigned i, n; + + printf("\narray_example2\n"); + LOG_MSG("array_example2"); + + for (n = 2; n <= 5; n++) { + printf("n = %d\n", n); + ctx = mk_context(); + + bool_sort = Z3_mk_bool_sort(ctx); + array_sort = Z3_mk_array_sort(ctx, bool_sort, bool_sort); + + /* create arrays */ + for (i = 0; i < n; i++) { + Z3_symbol s = Z3_mk_int_symbol(ctx, i); + a[i] = Z3_mk_const(ctx, s, array_sort); + } + + /* assert distinct(a[0], ..., a[n]) */ + d = Z3_mk_distinct(ctx, n, a); + printf("%s\n", Z3_ast_to_string(ctx, d)); + Z3_assert_cnstr(ctx, d); + + /* context is satisfiable if n < 5 */ + check2(ctx, n < 5 ? Z3_L_TRUE : Z3_L_FALSE); + + Z3_del_context(ctx); + } +} + +/** + \brief Simple array type construction/deconstruction example. +*/ +void array_example3() +{ + Z3_context ctx; + Z3_sort bool_sort, int_sort, array_sort; + Z3_sort domain, range; + printf("\narray_example3\n"); + LOG_MSG("array_example3"); + + ctx = mk_context(); + + bool_sort = Z3_mk_bool_sort(ctx); + int_sort = Z3_mk_int_sort(ctx); + array_sort = Z3_mk_array_sort(ctx, int_sort, bool_sort); + + if (Z3_get_sort_kind(ctx, array_sort) != Z3_ARRAY_SORT) { + exitf("type must be an array type"); + } + + domain = Z3_get_array_sort_domain(ctx, array_sort); + range = Z3_get_array_sort_range(ctx, array_sort); + + printf("domain: "); + display_sort(ctx, stdout, domain); + printf("\n"); + printf("range: "); + display_sort(ctx, stdout, range); + printf("\n"); + + if (int_sort != domain || bool_sort != range) { + exitf("invalid array type"); + } + + Z3_del_context(ctx); +} + +/** + \brief Simple tuple type example. It creates a tuple that is a pair of real numbers. +*/ +void tuple_example1() +{ + Z3_context ctx; + Z3_sort real_sort, pair_sort; + Z3_symbol mk_tuple_name; + Z3_func_decl mk_tuple_decl; + Z3_symbol proj_names[2]; + Z3_sort proj_sorts[2]; + Z3_func_decl proj_decls[2]; + Z3_func_decl get_x_decl, get_y_decl; + + printf("\ntuple_example1\n"); + LOG_MSG("tuple_example1"); + + ctx = mk_context(); + + real_sort = Z3_mk_real_sort(ctx); + + /* Create pair (tuple) type */ + mk_tuple_name = Z3_mk_string_symbol(ctx, "mk_pair"); + proj_names[0] = Z3_mk_string_symbol(ctx, "get_x"); + proj_names[1] = Z3_mk_string_symbol(ctx, "get_y"); + proj_sorts[0] = real_sort; + proj_sorts[1] = real_sort; + /* Z3_mk_tuple_sort will set mk_tuple_decl and proj_decls */ + pair_sort = Z3_mk_tuple_sort(ctx, mk_tuple_name, 2, proj_names, proj_sorts, &mk_tuple_decl, proj_decls); + get_x_decl = proj_decls[0]; /* function that extracts the first element of a tuple. */ + get_y_decl = proj_decls[1]; /* function that extracts the second element of a tuple. */ + + printf("tuple_sort: "); + display_sort(ctx, stdout, pair_sort); + printf("\n"); + + { + /* prove that get_x(mk_pair(x,y)) == 1 implies x = 1*/ + Z3_ast app1, app2, x, y, one; + Z3_ast eq1, eq2, eq3, thm; + + x = mk_real_var(ctx, "x"); + y = mk_real_var(ctx, "y"); + app1 = mk_binary_app(ctx, mk_tuple_decl, x, y); + app2 = mk_unary_app(ctx, get_x_decl, app1); + one = Z3_mk_numeral(ctx, "1", real_sort); + eq1 = Z3_mk_eq(ctx, app2, one); + eq2 = Z3_mk_eq(ctx, x, one); + thm = Z3_mk_implies(ctx, eq1, eq2); + printf("prove: get_x(mk_pair(x, y)) = 1 implies x = 1\n"); + prove(ctx, thm, Z3_TRUE); + + /* disprove that get_x(mk_pair(x,y)) == 1 implies y = 1*/ + eq3 = Z3_mk_eq(ctx, y, one); + thm = Z3_mk_implies(ctx, eq1, eq3); + printf("disprove: get_x(mk_pair(x, y)) = 1 implies y = 1\n"); + prove(ctx, thm, Z3_FALSE); + } + + { + /* prove that get_x(p1) = get_x(p2) and get_y(p1) = get_y(p2) implies p1 = p2 */ + Z3_ast p1, p2, x1, x2, y1, y2; + Z3_ast antecedents[2]; + Z3_ast antecedent, consequent, thm; + + p1 = mk_var(ctx, "p1", pair_sort); + p2 = mk_var(ctx, "p2", pair_sort); + x1 = mk_unary_app(ctx, get_x_decl, p1); + y1 = mk_unary_app(ctx, get_y_decl, p1); + x2 = mk_unary_app(ctx, get_x_decl, p2); + y2 = mk_unary_app(ctx, get_y_decl, p2); + antecedents[0] = Z3_mk_eq(ctx, x1, x2); + antecedents[1] = Z3_mk_eq(ctx, y1, y2); + antecedent = Z3_mk_and(ctx, 2, antecedents); + consequent = Z3_mk_eq(ctx, p1, p2); + thm = Z3_mk_implies(ctx, antecedent, consequent); + printf("prove: get_x(p1) = get_x(p2) and get_y(p1) = get_y(p2) implies p1 = p2\n"); + prove(ctx, thm, Z3_TRUE); + + /* disprove that get_x(p1) = get_x(p2) implies p1 = p2 */ + thm = Z3_mk_implies(ctx, antecedents[0], consequent); + printf("disprove: get_x(p1) = get_x(p2) implies p1 = p2\n"); + prove(ctx, thm, Z3_FALSE); + } + + { + /* demonstrate how to use the mk_tuple_update function */ + /* prove that p2 = update(p1, 0, 10) implies get_x(p2) = 10 */ + Z3_ast p1, p2, one, ten, updt, x, y; + Z3_ast antecedent, consequent, thm; + + p1 = mk_var(ctx, "p1", pair_sort); + p2 = mk_var(ctx, "p2", pair_sort); + one = Z3_mk_numeral(ctx, "1", real_sort); + ten = Z3_mk_numeral(ctx, "10", real_sort); + updt = mk_tuple_update(ctx, p1, 0, ten); + antecedent = Z3_mk_eq(ctx, p2, updt); + x = mk_unary_app(ctx, get_x_decl, p2); + consequent = Z3_mk_eq(ctx, x, ten); + thm = Z3_mk_implies(ctx, antecedent, consequent); + printf("prove: p2 = update(p1, 0, 10) implies get_x(p2) = 10\n"); + prove(ctx, thm, Z3_TRUE); + + /* disprove that p2 = update(p1, 0, 10) implies get_y(p2) = 10 */ + y = mk_unary_app(ctx, get_y_decl, p2); + consequent = Z3_mk_eq(ctx, y, ten); + thm = Z3_mk_implies(ctx, antecedent, consequent); + printf("disprove: p2 = update(p1, 0, 10) implies get_y(p2) = 10\n"); + prove(ctx, thm, Z3_FALSE); + } + + Z3_del_context(ctx); +} + +/** + \brief Simple bit-vector example. This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers +*/ +void bitvector_example1() +{ + Z3_context ctx; + Z3_sort bv_sort; + Z3_ast x, zero, ten, x_minus_ten, c1, c2, thm; + + printf("\nbitvector_example1\n"); + LOG_MSG("bitvector_example1"); + + ctx = mk_context(); + + bv_sort = Z3_mk_bv_sort(ctx, 32); + + x = mk_var(ctx, "x", bv_sort); + zero = Z3_mk_numeral(ctx, "0", bv_sort); + ten = Z3_mk_numeral(ctx, "10", bv_sort); + x_minus_ten = Z3_mk_bvsub(ctx, x, ten); + /* bvsle is signed less than or equal to */ + c1 = Z3_mk_bvsle(ctx, x, ten); + c2 = Z3_mk_bvsle(ctx, x_minus_ten, zero); + thm = Z3_mk_iff(ctx, c1, c2); + printf("disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers\n"); + prove(ctx, thm, Z3_FALSE); + + Z3_del_context(ctx); +} + +/** + \brief Find x and y such that: x ^ y - 103 == x * y +*/ +void bitvector_example2() +{ + Z3_context ctx = mk_context(); + + /* construct x ^ y - 103 == x * y */ + Z3_sort bv_sort = Z3_mk_bv_sort(ctx, 32); + Z3_ast x = mk_var(ctx, "x", bv_sort); + Z3_ast y = mk_var(ctx, "y", bv_sort); + Z3_ast x_xor_y = Z3_mk_bvxor(ctx, x, y); + Z3_ast c103 = Z3_mk_numeral(ctx, "103", bv_sort); + Z3_ast lhs = Z3_mk_bvsub(ctx, x_xor_y, c103); + Z3_ast rhs = Z3_mk_bvmul(ctx, x, y); + Z3_ast ctr = Z3_mk_eq(ctx, lhs, rhs); + + printf("\nbitvector_example2\n"); + LOG_MSG("bitvector_example2"); + printf("find values of x and y, such that x ^ y - 103 == x * y\n"); + + /* add the constraint x ^ y - 103 == x * y<\tt> to the logical context */ + Z3_assert_cnstr(ctx, ctr); + + /* find a model (i.e., values for x an y that satisfy the constraint */ + check(ctx, Z3_L_TRUE); + + Z3_del_context(ctx); +} + +/** + \brief Demonstrate how to use #Z3_eval. +*/ +void eval_example1() +{ + Z3_context ctx; + Z3_ast x, y, two; + Z3_ast c1, c2; + Z3_model m; + + printf("\neval_example1\n"); + LOG_MSG("eval_example1"); + + ctx = mk_context(); + x = mk_int_var(ctx, "x"); + y = mk_int_var(ctx, "y"); + two = mk_int(ctx, 2); + + /* assert x < y */ + c1 = Z3_mk_lt(ctx, x, y); + Z3_assert_cnstr(ctx, c1); + + /* assert x > 2 */ + c2 = Z3_mk_gt(ctx, x, two); + Z3_assert_cnstr(ctx, c2); + + /* find model for the constraints above */ + if (Z3_check_and_get_model(ctx, &m) == Z3_L_TRUE) { + Z3_ast x_plus_y; + Z3_ast args[2] = {x, y}; + Z3_ast v; + printf("MODEL:\n%s", Z3_model_to_string(ctx, m)); + x_plus_y = Z3_mk_add(ctx, 2, args); + printf("\nevaluating x+y\n"); + if (Z3_eval(ctx, m, x_plus_y, &v)) { + printf("result = "); + display_ast(ctx, stdout, v); + printf("\n"); + } + else { + exitf("failed to evaluate: x+y"); + } + Z3_del_model(ctx, m); + } + else { + exitf("the constraints are satisfiable"); + } + + Z3_del_context(ctx); +} + +/** + \brief Several logical context can be used simultaneously. +*/ +void two_contexts_example1() +{ + Z3_context ctx1, ctx2; + Z3_ast x1, x2; + + printf("\ntwo_contexts_example1\n"); + LOG_MSG("two_contexts_example1"); + + /* using the same (default) configuration to initialized both logical contexts. */ + ctx1 = mk_context(); + ctx2 = mk_context(); + + x1 = Z3_mk_const(ctx1, Z3_mk_int_symbol(ctx1,0), Z3_mk_bool_sort(ctx1)); + x2 = Z3_mk_const(ctx2, Z3_mk_int_symbol(ctx2,0), Z3_mk_bool_sort(ctx2)); + + Z3_del_context(ctx1); + + /* ctx2 can still be used. */ + printf("%s\n", Z3_ast_to_string(ctx2, x2)); + + Z3_del_context(ctx2); +} + +/** + \brief Demonstrates how error codes can be read insted of registering an error handler. + */ +void error_code_example1() +{ + Z3_config cfg; + Z3_context ctx; + Z3_ast x; + Z3_model m; + Z3_ast v; + Z3_func_decl x_decl; + const char * str; + + printf("\nerror_code_example1\n"); + LOG_MSG("error_code_example11"); + + /* Do not register an error handler, as we want to use Z3_get_error_code manually */ + cfg = Z3_mk_config(); + ctx = mk_context_custom(cfg, NULL); + Z3_del_config(cfg); + + x = mk_bool_var(ctx, "x"); + x_decl = Z3_get_app_decl(ctx, Z3_to_app(ctx, x)); + Z3_assert_cnstr(ctx, x); + + if (Z3_check_and_get_model(ctx, &m) != Z3_L_TRUE) { + exitf("unexpected result"); + } + + if (!Z3_eval_func_decl(ctx, m, x_decl, &v)) { + exitf("did not obtain value for declaration.\n"); + } + if (Z3_get_error_code(ctx) == Z3_OK) { + printf("last call succeeded.\n"); + } + /* The following call will fail since the value of x is a boolean */ + str = Z3_get_numeral_string(ctx, v); + if (Z3_get_error_code(ctx) != Z3_OK) { + printf("last call failed.\n"); + } + Z3_del_model(ctx, m); + Z3_del_context(ctx); +} + +/** + \brief Demonstrates how error handlers can be used. +*/ +void error_code_example2() { + Z3_config cfg; + Z3_context ctx = NULL; + int r; + + printf("\nerror_code_example2\n"); + LOG_MSG("error_code_example2"); + + /* low tech try&catch */ + r = setjmp(g_catch_buffer); + if (r == 0) { + Z3_ast x, y, app; + + cfg = Z3_mk_config(); + ctx = mk_context_custom(cfg, throw_z3_error); + Z3_del_config(cfg); + + x = mk_int_var(ctx, "x"); + y = mk_bool_var(ctx, "y"); + printf("before Z3_mk_iff\n"); + /* the next call will produce an error */ + app = Z3_mk_iff(ctx, x, y); + unreachable(); + Z3_del_context(ctx); + } + else { + printf("Z3 error: %s.\n", Z3_get_error_msg((Z3_error_code)r)); + if (ctx != NULL) { + Z3_del_context(ctx); + } + } +} + +/** + \brief Demonstrates how to use the SMTLIB parser. + */ +void parser_example1() +{ + Z3_context ctx; + unsigned i, num_formulas; + + printf("\nparser_example1\n"); + LOG_MSG("parser_example1"); + + ctx = mk_context(); + + Z3_parse_smtlib_string(ctx, + "(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))", + 0, 0, 0, + 0, 0, 0); + num_formulas = Z3_get_smtlib_num_formulas(ctx); + for (i = 0; i < num_formulas; i++) { + Z3_ast f = Z3_get_smtlib_formula(ctx, i); + printf("formula %d: %s\n", i, Z3_ast_to_string(ctx, f)); + Z3_assert_cnstr(ctx, f); + } + + check(ctx, Z3_L_TRUE); + + Z3_del_context(ctx); +} + +/** + \brief Demonstrates how to initialize the parser symbol table. + */ +void parser_example2() +{ + Z3_context ctx; + Z3_ast x, y; + Z3_symbol names[2]; + Z3_func_decl decls[2]; + Z3_ast f; + + printf("\nparser_example2\n"); + LOG_MSG("parser_example2"); + + ctx = mk_context(); + + /* Z3_enable_arithmetic doesn't need to be invoked in this example + because it will be implicitly invoked by mk_int_var. + */ + + x = mk_int_var(ctx, "x"); + decls[0] = Z3_get_app_decl(ctx, Z3_to_app(ctx, x)); + y = mk_int_var(ctx, "y"); + decls[1] = Z3_get_app_decl(ctx, Z3_to_app(ctx, y)); + + names[0] = Z3_mk_string_symbol(ctx, "a"); + names[1] = Z3_mk_string_symbol(ctx, "b"); + + Z3_parse_smtlib_string(ctx, + "(benchmark tst :formula (> a b))", + 0, 0, 0, + /* 'x' and 'y' declarations are inserted as 'a' and 'b' into the parser symbol table. */ + 2, names, decls); + f = Z3_get_smtlib_formula(ctx, 0); + printf("formula: %s\n", Z3_ast_to_string(ctx, f)); + Z3_assert_cnstr(ctx, f); + check(ctx, Z3_L_TRUE); + + Z3_del_context(ctx); +} + +/** + \brief Demonstrates how to initialize the parser symbol table. + */ +void parser_example3() +{ + Z3_config cfg; + Z3_context ctx; + Z3_sort int_sort; + Z3_symbol g_name; + Z3_sort g_domain[2]; + Z3_func_decl g; + Z3_ast thm; + + printf("\nparser_example3\n"); + LOG_MSG("parser_example3"); + + cfg = Z3_mk_config(); + /* See quantifer_example1 */ + Z3_set_param_value(cfg, "MODEL", "true"); + ctx = mk_context_custom(cfg, error_handler); + Z3_del_config(cfg); + + /* declare function g */ + int_sort = Z3_mk_int_sort(ctx); + g_name = Z3_mk_string_symbol(ctx, "g"); + g_domain[0] = int_sort; + g_domain[1] = int_sort; + g = Z3_mk_func_decl(ctx, g_name, 2, g_domain, int_sort); + + assert_comm_axiom(ctx, g); + + Z3_parse_smtlib_string(ctx, + "(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (g x 0) (g 0 y)))))", + 0, 0, 0, + 1, &g_name, &g); + thm = Z3_get_smtlib_formula(ctx, 0); + printf("formula: %s\n", Z3_ast_to_string(ctx, thm)); + prove(ctx, thm, Z3_TRUE); + + Z3_del_context(ctx); +} + +/** + \brief Display the declarations, assumptions and formulas in a SMT-LIB string. +*/ +void parser_example4() +{ + Z3_context ctx; + unsigned i, num_decls, num_assumptions, num_formulas; + + printf("\nparser_example4\n"); + LOG_MSG("parser_example4"); + + ctx = mk_context(); + + Z3_parse_smtlib_string(ctx, + "(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))", + 0, 0, 0, + 0, 0, 0); + num_decls = Z3_get_smtlib_num_decls(ctx); + for (i = 0; i < num_decls; i++) { + Z3_func_decl d = Z3_get_smtlib_decl(ctx, i); + printf("declaration %d: %s\n", i, Z3_func_decl_to_string(ctx, d)); + } + num_assumptions = Z3_get_smtlib_num_assumptions(ctx); + for (i = 0; i < num_assumptions; i++) { + Z3_ast a = Z3_get_smtlib_assumption(ctx, i); + printf("assumption %d: %s\n", i, Z3_ast_to_string(ctx, a)); + } + num_formulas = Z3_get_smtlib_num_formulas(ctx); + for (i = 0; i < num_formulas; i++) { + Z3_ast f = Z3_get_smtlib_formula(ctx, i); + printf("formula %d: %s\n", i, Z3_ast_to_string(ctx, f)); + } + Z3_del_context(ctx); +} + +/** + \brief Demonstrates how to handle parser errors using Z3 error handling support. +*/ +void parser_example5() { + Z3_config cfg; + Z3_context ctx = NULL; + int r; + + printf("\nparser_example5\n"); + LOG_MSG("parser_example5"); + + r = setjmp(g_catch_buffer); + if (r == 0) { + cfg = Z3_mk_config(); + ctx = mk_context_custom(cfg, throw_z3_error); + Z3_del_config(cfg); + + Z3_parse_smtlib_string(ctx, + /* the following string has a parsing error: missing parenthesis */ + "(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))", + 0, 0, 0, + 0, 0, 0); + unreachable(); + Z3_del_context(ctx); + } + else { + printf("Z3 error: %s.\n", Z3_get_error_msg((Z3_error_code)r)); + if (ctx != NULL) { + printf("Error message: '%s'.\n",Z3_get_smtlib_error(ctx)); + Z3_del_context(ctx); + } + } +} + +/** + \brief Demonstrate different ways of creating rational numbers: decimal and fractional representations. +*/ +void numeral_example() { + Z3_context ctx; + Z3_ast n1, n2; + Z3_sort real_ty; + printf("\nnumeral_example\n"); + LOG_MSG("numeral_example"); + + ctx = mk_context(); + real_ty = Z3_mk_real_sort(ctx); + n1 = Z3_mk_numeral(ctx, "1/2", real_ty); + n2 = Z3_mk_numeral(ctx, "0.5", real_ty); + printf("Numerals n1:%s", Z3_ast_to_string(ctx, n1)); + printf(" n2:%s\n", Z3_ast_to_string(ctx, n2)); + prove(ctx, Z3_mk_eq(ctx, n1, n2), Z3_TRUE); + + n1 = Z3_mk_numeral(ctx, "-1/3", real_ty); + n2 = Z3_mk_numeral(ctx, "-0.33333333333333333333333333333333333333333333333333", real_ty); + printf("Numerals n1:%s", Z3_ast_to_string(ctx, n1)); + printf(" n2:%s\n", Z3_ast_to_string(ctx, n2)); + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, n1, n2)), Z3_TRUE); + Z3_del_context(ctx); +} + +/** + \brief Test ite-term (if-then-else terms). +*/ +void ite_example() +{ + Z3_context ctx; + Z3_ast f, one, zero, ite; + + printf("\nite_example\n"); + LOG_MSG("ite_example"); + + ctx = mk_context(); + + f = Z3_mk_false(ctx); + one = mk_int(ctx, 1); + zero = mk_int(ctx, 0); + ite = Z3_mk_ite(ctx, f, one, zero); + + printf("term: %s\n", Z3_ast_to_string(ctx, ite)); + + /* delete logical context */ + Z3_del_context(ctx); +} + +/** + \brief Create an enumeration data type. +*/ +void enum_example() { + Z3_context ctx = mk_context(); + Z3_sort fruit; + Z3_symbol name = Z3_mk_string_symbol(ctx, "fruit"); + Z3_symbol enum_names[3]; + Z3_func_decl enum_consts[3]; + Z3_func_decl enum_testers[3]; + Z3_ast apple, orange, banana, fruity; + Z3_ast ors[3]; + + printf("\nenum_example\n"); + LOG_MSG("enum_example"); + + enum_names[0] = Z3_mk_string_symbol(ctx,"apple"); + enum_names[1] = Z3_mk_string_symbol(ctx,"banana"); + enum_names[2] = Z3_mk_string_symbol(ctx,"orange"); + + fruit = Z3_mk_enumeration_sort(ctx, name, 3, enum_names, enum_consts, enum_testers); + + printf("%s\n", Z3_func_decl_to_string(ctx, enum_consts[0])); + printf("%s\n", Z3_func_decl_to_string(ctx, enum_consts[1])); + printf("%s\n", Z3_func_decl_to_string(ctx, enum_consts[2])); + + printf("%s\n", Z3_func_decl_to_string(ctx, enum_testers[0])); + printf("%s\n", Z3_func_decl_to_string(ctx, enum_testers[1])); + printf("%s\n", Z3_func_decl_to_string(ctx, enum_testers[2])); + + apple = Z3_mk_app(ctx, enum_consts[0], 0, 0); + banana = Z3_mk_app(ctx, enum_consts[1], 0, 0); + orange = Z3_mk_app(ctx, enum_consts[2], 0, 0); + + /* Apples are different from oranges */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, apple, orange)), Z3_TRUE); + + /* Apples pass the apple test */ + prove(ctx, Z3_mk_app(ctx, enum_testers[0], 1, &apple), Z3_TRUE); + + /* Oranges fail the apple test */ + prove(ctx, Z3_mk_app(ctx, enum_testers[0], 1, &orange), Z3_FALSE); + prove(ctx, Z3_mk_not(ctx, Z3_mk_app(ctx, enum_testers[0], 1, &orange)), Z3_TRUE); + + fruity = mk_var(ctx, "fruity", fruit); + + /* If something is fruity, then it is an apple, banana, or orange */ + ors[0] = Z3_mk_eq(ctx, fruity, apple); + ors[1] = Z3_mk_eq(ctx, fruity, banana); + ors[2] = Z3_mk_eq(ctx, fruity, orange); + + prove(ctx, Z3_mk_or(ctx, 3, ors), Z3_TRUE); + + /* delete logical context */ + Z3_del_context(ctx); +} + +/** + \brief Create a list datatype. +*/ +void list_example() { + Z3_context ctx = mk_context(); + Z3_sort int_ty, int_list; + Z3_func_decl nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl; + Z3_ast nil, l1, l2, x, y, u, v, fml, fml1; + Z3_ast ors[2]; + + + printf("\nlist_example\n"); + LOG_MSG("list_example"); + + int_ty = Z3_mk_int_sort(ctx); + + int_list = Z3_mk_list_sort(ctx, Z3_mk_string_symbol(ctx, "int_list"), int_ty, + &nil_decl, &is_nil_decl, &cons_decl, &is_cons_decl, &head_decl, &tail_decl); + + nil = Z3_mk_app(ctx, nil_decl, 0, 0); + l1 = mk_binary_app(ctx, cons_decl, mk_int(ctx, 1), nil); + l2 = mk_binary_app(ctx, cons_decl, mk_int(ctx, 2), nil); + + /* nil != cons(1, nil) */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, nil, l1)), Z3_TRUE); + + /* cons(2,nil) != cons(1, nil) */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, l1, l2)), Z3_TRUE); + + /* cons(x,nil) = cons(y, nil) => x = y */ + x = mk_var(ctx, "x", int_ty); + y = mk_var(ctx, "y", int_ty); + l1 = mk_binary_app(ctx, cons_decl, x, nil); + l2 = mk_binary_app(ctx, cons_decl, y, nil); + prove(ctx, Z3_mk_implies(ctx, Z3_mk_eq(ctx,l1,l2), Z3_mk_eq(ctx, x, y)), Z3_TRUE); + + /* cons(x,u) = cons(x, v) => u = v */ + u = mk_var(ctx, "u", int_list); + v = mk_var(ctx, "v", int_list); + l1 = mk_binary_app(ctx, cons_decl, x, u); + l2 = mk_binary_app(ctx, cons_decl, y, v); + prove(ctx, Z3_mk_implies(ctx, Z3_mk_eq(ctx,l1,l2), Z3_mk_eq(ctx, u, v)), Z3_TRUE); + prove(ctx, Z3_mk_implies(ctx, Z3_mk_eq(ctx,l1,l2), Z3_mk_eq(ctx, x, y)), Z3_TRUE); + + /* is_nil(u) or is_cons(u) */ + ors[0] = Z3_mk_app(ctx, is_nil_decl, 1, &u); + ors[1] = Z3_mk_app(ctx, is_cons_decl, 1, &u); + prove(ctx, Z3_mk_or(ctx, 2, ors), Z3_TRUE); + + /* occurs check u != cons(x,u) */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, u, l1)), Z3_TRUE); + + /* destructors: is_cons(u) => u = cons(head(u),tail(u)) */ + fml1 = Z3_mk_eq(ctx, u, mk_binary_app(ctx, cons_decl, mk_unary_app(ctx, head_decl, u), mk_unary_app(ctx, tail_decl, u))); + fml = Z3_mk_implies(ctx, Z3_mk_app(ctx, is_cons_decl, 1, &u), fml1); + printf("Formula %s\n", Z3_ast_to_string(ctx, fml)); + prove(ctx, fml, Z3_TRUE); + + prove(ctx, fml1, Z3_FALSE); + + /* delete logical context */ + Z3_del_context(ctx); +} + +/** + \brief Create a binary tree datatype. +*/ +void tree_example() { + Z3_context ctx = mk_context(); + Z3_sort cell; + Z3_func_decl nil_decl, is_nil_decl, cons_decl, is_cons_decl, car_decl, cdr_decl; + Z3_ast nil, l1, l2, x, y, u, v, fml, fml1; + Z3_symbol head_tail[2] = { Z3_mk_string_symbol(ctx, "car"), Z3_mk_string_symbol(ctx, "cdr") }; + Z3_sort sorts[2] = { 0, 0 }; + unsigned sort_refs[2] = { 0, 0 }; + Z3_constructor nil_con, cons_con; + Z3_constructor constructors[2]; + Z3_func_decl cons_accessors[2]; + Z3_ast ors[2]; + + printf("\ntree_example\n"); + LOG_MSG("tree_example"); + + nil_con = Z3_mk_constructor(ctx, Z3_mk_string_symbol(ctx, "nil"), Z3_mk_string_symbol(ctx, "is_nil"), 0, 0, 0, 0); + cons_con = Z3_mk_constructor(ctx, Z3_mk_string_symbol(ctx, "cons"), Z3_mk_string_symbol(ctx, "is_cons"), 2, head_tail, sorts, sort_refs); + constructors[0] = nil_con; + constructors[1] = cons_con; + + cell = Z3_mk_datatype(ctx, Z3_mk_string_symbol(ctx, "cell"), 2, constructors); + + Z3_query_constructor(ctx, nil_con, 0, &nil_decl, &is_nil_decl, 0); + Z3_query_constructor(ctx, cons_con, 2, &cons_decl, &is_cons_decl, cons_accessors); + car_decl = cons_accessors[0]; + cdr_decl = cons_accessors[1]; + + Z3_del_constructor(ctx,nil_con); + Z3_del_constructor(ctx,cons_con); + + + nil = Z3_mk_app(ctx, nil_decl, 0, 0); + l1 = mk_binary_app(ctx, cons_decl, nil, nil); + l2 = mk_binary_app(ctx, cons_decl, l1, nil); + + /* nil != cons(nil, nil) */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, nil, l1)), Z3_TRUE); + + /* cons(x,u) = cons(x, v) => u = v */ + u = mk_var(ctx, "u", cell); + v = mk_var(ctx, "v", cell); + x = mk_var(ctx, "x", cell); + y = mk_var(ctx, "y", cell); + l1 = mk_binary_app(ctx, cons_decl, x, u); + l2 = mk_binary_app(ctx, cons_decl, y, v); + prove(ctx, Z3_mk_implies(ctx, Z3_mk_eq(ctx,l1,l2), Z3_mk_eq(ctx, u, v)), Z3_TRUE); + prove(ctx, Z3_mk_implies(ctx, Z3_mk_eq(ctx,l1,l2), Z3_mk_eq(ctx, x, y)), Z3_TRUE); + + /* is_nil(u) or is_cons(u) */ + ors[0] = Z3_mk_app(ctx, is_nil_decl, 1, &u); + ors[1] = Z3_mk_app(ctx, is_cons_decl, 1, &u); + prove(ctx, Z3_mk_or(ctx, 2, ors), Z3_TRUE); + + /* occurs check u != cons(x,u) */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, u, l1)), Z3_TRUE); + + /* destructors: is_cons(u) => u = cons(car(u),cdr(u)) */ + fml1 = Z3_mk_eq(ctx, u, mk_binary_app(ctx, cons_decl, mk_unary_app(ctx, car_decl, u), mk_unary_app(ctx, cdr_decl, u))); + fml = Z3_mk_implies(ctx, Z3_mk_app(ctx, is_cons_decl, 1, &u), fml1); + printf("Formula %s\n", Z3_ast_to_string(ctx, fml)); + prove(ctx, fml, Z3_TRUE); + + prove(ctx, fml1, Z3_FALSE); + + /* delete logical context */ + Z3_del_context(ctx); + + +} + +/** + \brief Create a forest of trees. + + forest ::= nil | cons(tree, forest) + tree ::= nil | cons(forest, forest) +*/ + +void forest_example() { + Z3_context ctx = mk_context(); + Z3_sort tree, forest; + Z3_func_decl nil1_decl, is_nil1_decl, cons1_decl, is_cons1_decl, car1_decl, cdr1_decl; + Z3_func_decl nil2_decl, is_nil2_decl, cons2_decl, is_cons2_decl, car2_decl, cdr2_decl; + Z3_ast nil1, nil2, t1, t2, t3, t4, f1, f2, f3, l1, l2, x, y, u, v; + Z3_symbol head_tail[2] = { Z3_mk_string_symbol(ctx, "car"), Z3_mk_string_symbol(ctx, "cdr") }; + Z3_sort sorts[2] = { 0, 0 }; + unsigned sort_refs[2] = { 0, 0 }; + Z3_constructor nil1_con, cons1_con, nil2_con, cons2_con; + Z3_constructor constructors1[2], constructors2[2]; + Z3_func_decl cons_accessors[2]; + Z3_ast ors[2]; + Z3_constructor_list clist1, clist2; + Z3_constructor_list clists[2]; + Z3_symbol sort_names[2] = { Z3_mk_string_symbol(ctx, "forest"), Z3_mk_string_symbol(ctx, "tree") }; + + printf("\nforest_example\n"); + LOG_MSG("forest_example"); + + /* build a forest */ + nil1_con = Z3_mk_constructor(ctx, Z3_mk_string_symbol(ctx, "nil1"), Z3_mk_string_symbol(ctx, "is_nil1"), 0, 0, 0, 0); + sort_refs[0] = 1; /* the car of a forest is a tree */ + sort_refs[1] = 0; + cons1_con = Z3_mk_constructor(ctx, Z3_mk_string_symbol(ctx, "cons1"), Z3_mk_string_symbol(ctx, "is_cons1"), 2, head_tail, sorts, sort_refs); + constructors1[0] = nil1_con; + constructors1[1] = cons1_con; + + /* build a tree */ + nil2_con = Z3_mk_constructor(ctx, Z3_mk_string_symbol(ctx, "nil2"), Z3_mk_string_symbol(ctx, "is_nil2"),0, 0, 0, 0); + sort_refs[0] = 0; /* both branches of a tree are forests */ + sort_refs[1] = 0; + cons2_con = Z3_mk_constructor(ctx, Z3_mk_string_symbol(ctx, "cons2"), Z3_mk_string_symbol(ctx, "is_cons2"),2, head_tail, sorts, sort_refs); + constructors2[0] = nil2_con; + constructors2[1] = cons2_con; + + clist1 = Z3_mk_constructor_list(ctx, 2, constructors1); + clist2 = Z3_mk_constructor_list(ctx, 2, constructors2); + + clists[0] = clist1; + clists[1] = clist2; + + Z3_mk_datatypes(ctx, 2, sort_names, sorts, clists); + forest = sorts[0]; + tree = sorts[1]; + + Z3_query_constructor(ctx, nil1_con, 0, &nil1_decl, &is_nil1_decl, 0); + Z3_query_constructor(ctx, cons1_con, 2, &cons1_decl, &is_cons1_decl, cons_accessors); + car1_decl = cons_accessors[0]; + cdr1_decl = cons_accessors[1]; + + Z3_query_constructor(ctx, nil2_con, 0, &nil2_decl, &is_nil2_decl, 0); + Z3_query_constructor(ctx, cons2_con, 2, &cons2_decl, &is_cons2_decl, cons_accessors); + car2_decl = cons_accessors[0]; + cdr2_decl = cons_accessors[1]; + + Z3_del_constructor_list(ctx, clist1); + Z3_del_constructor_list(ctx, clist2); + Z3_del_constructor(ctx,nil1_con); + Z3_del_constructor(ctx,cons1_con); + Z3_del_constructor(ctx,nil2_con); + Z3_del_constructor(ctx,cons2_con); + + nil1 = Z3_mk_app(ctx, nil1_decl, 0, 0); + nil2 = Z3_mk_app(ctx, nil2_decl, 0, 0); + f1 = mk_binary_app(ctx, cons1_decl, nil2, nil1); + t1 = mk_binary_app(ctx, cons2_decl, nil1, nil1); + t2 = mk_binary_app(ctx, cons2_decl, f1, nil1); + t3 = mk_binary_app(ctx, cons2_decl, f1, f1); + t4 = mk_binary_app(ctx, cons2_decl, nil1, f1); + f2 = mk_binary_app(ctx, cons1_decl, t1, nil1); + f3 = mk_binary_app(ctx, cons1_decl, t1, f1); + + + /* nil != cons(nil,nil) */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, nil1, f1)), Z3_TRUE); + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, nil2, t1)), Z3_TRUE); + + + /* cons(x,u) = cons(x, v) => u = v */ + u = mk_var(ctx, "u", forest); + v = mk_var(ctx, "v", forest); + x = mk_var(ctx, "x", tree); + y = mk_var(ctx, "y", tree); + l1 = mk_binary_app(ctx, cons1_decl, x, u); + l2 = mk_binary_app(ctx, cons1_decl, y, v); + prove(ctx, Z3_mk_implies(ctx, Z3_mk_eq(ctx,l1,l2), Z3_mk_eq(ctx, u, v)), Z3_TRUE); + prove(ctx, Z3_mk_implies(ctx, Z3_mk_eq(ctx,l1,l2), Z3_mk_eq(ctx, x, y)), Z3_TRUE); + + /* is_nil(u) or is_cons(u) */ + ors[0] = Z3_mk_app(ctx, is_nil1_decl, 1, &u); + ors[1] = Z3_mk_app(ctx, is_cons1_decl, 1, &u); + prove(ctx, Z3_mk_or(ctx, 2, ors), Z3_TRUE); + + /* occurs check u != cons(x,u) */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, u, l1)), Z3_TRUE); + + /* delete logical context */ + Z3_del_context(ctx); +} + + + +/** + \brief Create a binary tree datatype of the form + BinTree ::= nil + | node(value : Int, left : BinTree, right : BinTree) +*/ +void binary_tree_example() { + Z3_context ctx = mk_context(); + Z3_sort cell; + Z3_func_decl + nil_decl, /* nil : BinTree (constructor) */ + is_nil_decl, /* is_nil : BinTree -> Bool (tester, return true if the given BinTree is a nil) */ + node_decl, /* node : Int, BinTree, BinTree -> BinTree (constructor) */ + is_node_decl, /* is_node : BinTree -> Bool (tester, return true if the given BinTree is a node) */ + value_decl, /* value : BinTree -> Int (accessor for nodes) */ + left_decl, /* left : BinTree -> BinTree (accessor for nodes, retrieves the left child of a node) */ + right_decl; /* right : BinTree -> BinTree (accessor for nodes, retrieves the right child of a node) */ + Z3_symbol node_accessor_names[3] = { Z3_mk_string_symbol(ctx, "value"), Z3_mk_string_symbol(ctx, "left"), Z3_mk_string_symbol(ctx, "right") }; + Z3_sort node_accessor_sorts[3] = { Z3_mk_int_sort(ctx), 0, 0 }; + unsigned node_accessor_sort_refs[3] = { 0, 0, 0 }; + Z3_constructor nil_con, node_con; + Z3_constructor constructors[2]; + Z3_func_decl node_accessors[3]; + + printf("\nbinary_tree_example\n"); + LOG_MSG("binary_tree_example"); + + /* nil_con and node_con are auxiliary datastructures used to create the new recursive datatype BinTree */ + nil_con = Z3_mk_constructor(ctx, Z3_mk_string_symbol(ctx, "nil"), Z3_mk_string_symbol(ctx, "is-nil"), 0, 0, 0, 0); + node_con = Z3_mk_constructor(ctx, Z3_mk_string_symbol(ctx, "node"), Z3_mk_string_symbol(ctx, "is-cons"), + 3, node_accessor_names, node_accessor_sorts, node_accessor_sort_refs); + constructors[0] = nil_con; + constructors[1] = node_con; + + /* create the new recursive datatype */ + cell = Z3_mk_datatype(ctx, Z3_mk_string_symbol(ctx, "BinTree"), 2, constructors); + + /* retrieve the new declarations: constructors (nil_decl, node_decl), testers (is_nil_decl, is_cons_del), and + accessors (value_decl, left_decl, right_decl */ + Z3_query_constructor(ctx, nil_con, 0, &nil_decl, &is_nil_decl, 0); + Z3_query_constructor(ctx, node_con, 3, &node_decl, &is_node_decl, node_accessors); + value_decl = node_accessors[0]; + left_decl = node_accessors[1]; + right_decl = node_accessors[2]; + + /* delete auxiliary/helper structures */ + Z3_del_constructor(ctx, nil_con); + Z3_del_constructor(ctx, node_con); + + /* small example using the recursive datatype BinTree */ + { + /* create nil */ + Z3_ast nil = Z3_mk_app(ctx, nil_decl, 0, 0); + /* create node1 ::= node(10, nil, nil) */ + Z3_ast args1[3] = { mk_int(ctx, 10), nil, nil }; + Z3_ast node1 = Z3_mk_app(ctx, node_decl, 3, args1); + /* create node2 ::= node(30, node1, nil) */ + Z3_ast args2[3] = { mk_int(ctx, 30), node1, nil }; + Z3_ast node2 = Z3_mk_app(ctx, node_decl, 3, args2); + /* create node3 ::= node(20, node2, node1); */ + Z3_ast args3[3] = { mk_int(ctx, 20), node2, node1 }; + Z3_ast node3 = Z3_mk_app(ctx, node_decl, 3, args3); + + /* prove that nil != node1 */ + prove(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, nil, node1)), Z3_TRUE); + + /* prove that nil = left(node1) */ + prove(ctx, Z3_mk_eq(ctx, nil, mk_unary_app(ctx, left_decl, node1)), Z3_TRUE); + + /* prove that node1 = right(node3) */ + prove(ctx, Z3_mk_eq(ctx, node1, mk_unary_app(ctx, right_decl, node3)), Z3_TRUE); + + /* prove that !is-nil(node2) */ + prove(ctx, Z3_mk_not(ctx, mk_unary_app(ctx, is_nil_decl, node2)), Z3_TRUE); + + /* prove that value(node2) >= 0 */ + prove(ctx, Z3_mk_ge(ctx, mk_unary_app(ctx, value_decl, node2), mk_int(ctx, 0)), Z3_TRUE); + } + + /* delete logical context */ + Z3_del_context(ctx); +} + +/** + \brief Prove a theorem and extract, and print the proof. + + This example illustrates the use of #Z3_check_assumptions. +*/ +void unsat_core_and_proof_example() { + Z3_context ctx = mk_proof_context(); + Z3_ast pa = mk_bool_var(ctx, "PredA"); + Z3_ast pb = mk_bool_var(ctx, "PredB"); + Z3_ast pc = mk_bool_var(ctx, "PredC"); + Z3_ast pd = mk_bool_var(ctx, "PredD"); + Z3_ast p1 = mk_bool_var(ctx, "P1"); + Z3_ast p2 = mk_bool_var(ctx, "P2"); + Z3_ast p3 = mk_bool_var(ctx, "P3"); + Z3_ast p4 = mk_bool_var(ctx, "P4"); + Z3_ast assumptions[4] = { Z3_mk_not(ctx, p1), Z3_mk_not(ctx, p2), Z3_mk_not(ctx, p3), Z3_mk_not(ctx, p4) }; + Z3_ast args1[3] = { pa, pb, pc }; + Z3_ast f1 = Z3_mk_and(ctx, 3, args1); + Z3_ast args2[3] = { pa, Z3_mk_not(ctx, pb), pc }; + Z3_ast f2 = Z3_mk_and(ctx, 3, args2); + Z3_ast args3[2] = { Z3_mk_not(ctx, pa), Z3_mk_not(ctx, pc) }; + Z3_ast f3 = Z3_mk_or(ctx, 2, args3); + Z3_ast f4 = pd; + Z3_ast g1[2] = { f1, p1 }; + Z3_ast g2[2] = { f2, p2 }; + Z3_ast g3[2] = { f3, p3 }; + Z3_ast g4[2] = { f4, p4 }; + Z3_ast core[4] = { 0, 0, 0, 0 }; + unsigned core_size = 4; + Z3_ast proof; + Z3_model m = 0; + Z3_lbool result; + unsigned i; + + printf("\nunsat_core_and_proof_example\n"); + LOG_MSG("unsat_core_and_proof_example"); + + Z3_assert_cnstr(ctx, Z3_mk_or(ctx, 2, g1)); + Z3_assert_cnstr(ctx, Z3_mk_or(ctx, 2, g2)); + Z3_assert_cnstr(ctx, Z3_mk_or(ctx, 2, g3)); + Z3_assert_cnstr(ctx, Z3_mk_or(ctx, 2, g4)); + + result = Z3_check_assumptions(ctx, 4, assumptions, &m, &proof, &core_size, core); + + switch (result) { + case Z3_L_FALSE: + printf("unsat\n"); + printf("proof: %s\n", Z3_ast_to_string(ctx, proof)); + + printf("\ncore:\n"); + for (i = 0; i < core_size; ++i) { + printf("%s\n", Z3_ast_to_string(ctx, core[i])); + } + printf("\n"); + break; + case Z3_L_UNDEF: + printf("unknown\n"); + printf("potential model:\n"); + display_model(ctx, stdout, m); + break; + case Z3_L_TRUE: + printf("sat\n"); + display_model(ctx, stdout, m); + break; + } + if (m) { + Z3_del_model(ctx, m); + } + + /* delete logical context */ + Z3_del_context(ctx); +} + +/** + \brief Extract classes of implied equalities. + + This example illustrates the use of #Z3_get_implied_equalities. +*/ +void get_implied_equalities_example() { + Z3_config cfg = Z3_mk_config(); + Z3_context ctx; + + printf("\nget_implied_equalities example\n"); + LOG_MSG("get_implied_equalities example"); + + Z3_set_param_value(cfg, "ARITH_PROCESS_ALL_EQS", "true"); + Z3_set_param_value(cfg, "ARITH_EQ_BOUNDS", "true"); + ctx = Z3_mk_context(cfg); + Z3_del_config(cfg); + { + Z3_sort int_ty = Z3_mk_int_sort(ctx); + Z3_ast a = mk_int_var(ctx,"a"); + Z3_ast b = mk_int_var(ctx,"b"); + Z3_ast c = mk_int_var(ctx,"c"); + Z3_ast d = mk_int_var(ctx,"d"); + Z3_func_decl f = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx,"f"), 1, &int_ty, int_ty); + Z3_ast fa = Z3_mk_app(ctx, f, 1, &a); + Z3_ast fb = Z3_mk_app(ctx, f, 1, &b); + Z3_ast fc = Z3_mk_app(ctx, f, 1, &c); + unsigned const num_terms = 7; + unsigned i; + Z3_ast terms[7] = { a, b, c, d, fa, fb, fc }; + unsigned class_ids[7] = { 0, 0, 0, 0, 0, 0, 0 }; + + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, a, b)); + Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, b, c)); + Z3_assert_cnstr(ctx, Z3_mk_le(ctx, fc, b)); + Z3_assert_cnstr(ctx, Z3_mk_le(ctx, b, fa)); + + Z3_get_implied_equalities(ctx, num_terms, terms, class_ids); + for (i = 0; i < num_terms; ++i) { + printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); + } + printf("asserting f(a) <= b\n"); + Z3_assert_cnstr(ctx, Z3_mk_le(ctx, fa, b)); + Z3_get_implied_equalities(ctx, num_terms, terms, class_ids); + for (i = 0; i < num_terms; ++i) { + printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); + } + } + /* delete logical context */ + Z3_del_context(ctx); +} + +#define MAX_RETRACTABLE_ASSERTIONS 1024 + +/** + \brief Very simple logical context wrapper with support for retractable constraints. + A retractable constraint can be "removed" without using push/pop. +*/ +typedef struct { + Z3_context m_context; + // IMPORTANT: the fields m_answer_literals, m_retracted and m_num_answer_literals must be saved/restored + // if push/pop operations are performed on m_context. + Z3_ast m_answer_literals[MAX_RETRACTABLE_ASSERTIONS]; + Z3_bool m_retracted[MAX_RETRACTABLE_ASSERTIONS]; // true if the assertion was retracted. + unsigned m_num_answer_literals; +} Z3_ext_context_struct; + +typedef Z3_ext_context_struct * Z3_ext_context; + +/** + \brief Create a logical context wrapper with support for retractable constraints. + */ +Z3_ext_context mk_ext_context() { + Z3_ext_context ctx = (Z3_ext_context) malloc(sizeof(Z3_ext_context_struct)); + ctx->m_context = mk_context(); + ctx->m_num_answer_literals = 0; + return ctx; +} + +/** + \brief Delete the given logical context wrapper. +*/ +void del_ext_context(Z3_ext_context ctx) { + Z3_del_context(ctx->m_context); + free(ctx); +} + +/** + \brief Create a retractable constraint. + + \return An id that can be used to retract/reassert the constraint. +*/ +unsigned assert_retractable_cnstr(Z3_ext_context ctx, Z3_ast c) { + unsigned result; + Z3_sort ty; + Z3_ast ans_lit; + Z3_ast args[2]; + if (ctx->m_num_answer_literals == MAX_RETRACTABLE_ASSERTIONS) { + exitf("maximum number of retractable constraints was exceeded."); + } + ty = Z3_mk_bool_sort(ctx->m_context); + ans_lit = Z3_mk_fresh_const(ctx->m_context, "k", ty); + result = ctx->m_num_answer_literals; + ctx->m_answer_literals[result] = ans_lit; + ctx->m_retracted[result] = Z3_FALSE; + ctx->m_num_answer_literals++; + // assert: c OR (not ans_lit) + args[0] = c; + args[1] = Z3_mk_not(ctx->m_context, ans_lit); + Z3_assert_cnstr(ctx->m_context, Z3_mk_or(ctx->m_context, 2, args)); + return result; +} + +/** + \brief Retract an constraint asserted using #assert_retractable_cnstr. +*/ +void retract_cnstr(Z3_ext_context ctx, unsigned id) { + if (id >= ctx->m_num_answer_literals) { + exitf("invalid constraint id."); + } + ctx->m_retracted[id] = Z3_TRUE; +} + +/** + \brief Reassert a constraint retracted using #retract_cnstr. +*/ +void reassert_cnstr(Z3_ext_context ctx, unsigned id) { + if (id >= ctx->m_num_answer_literals) { + exitf("invalid constraint id."); + } + ctx->m_retracted[id] = Z3_FALSE; +} + +/** + \brief Check whether the logical context wrapper with support for retractable assertions is feasible or not. +*/ +Z3_lbool ext_check(Z3_ext_context ctx) { + Z3_lbool result; + unsigned num_assumptions = 0; + Z3_ast assumptions[MAX_RETRACTABLE_ASSERTIONS]; + Z3_ast core[MAX_RETRACTABLE_ASSERTIONS]; + unsigned core_size; + Z3_ast dummy_proof = 0; // we don't care about the proof in this example. + Z3_model dummy_model = 0; // we don't care about the model in this example. + unsigned i; + for (i = 0; i < ctx->m_num_answer_literals; i++) { + if (ctx->m_retracted[i] == Z3_FALSE) { + // Since the answer literal was not retracted, we added it as an assumption. + // Recall that we assert (C \/ (not ans_lit)). Therefore, adding ans_lit as an assumption has the effect of "asserting" C. + // If the constraint was "retracted" (ctx->m_retracted[i] == Z3_true), then we don't really need to add (not ans_lit) as an assumption. + assumptions[num_assumptions] = ctx->m_answer_literals[i]; + num_assumptions ++; + } + } + result = Z3_check_assumptions(ctx->m_context, num_assumptions, assumptions, &dummy_model, &dummy_proof, &core_size, core); + if (result == Z3_L_FALSE) { + // Display the UNSAT core + printf("unsat core: "); + for (i = 0; i < core_size; i++) { + // In this example, we display the core based on the assertion ids. + unsigned j; + for (j = 0; j < ctx->m_num_answer_literals; j++) { + if (core[i] == ctx->m_answer_literals[j]) { + printf("%d ", j); + break; + } + } + if (j == ctx->m_num_answer_literals) { + exitf("bug in Z3, the core contains something that is not an assumption."); + } + } + printf("\n"); + } + + if (dummy_model) { + Z3_del_model(ctx->m_context, dummy_model); + } + + return result; +} + +/** + \brief Simple example using the functions: #mk_ext_context, #assert_retractable_cnstr, #retract_cnstr, #reassert_cnstr and #del_ext_context. +*/ +void incremental_example1() { + Z3_ext_context ext_ctx = mk_ext_context(); + Z3_context ctx = ext_ctx->m_context; + Z3_ast x, y, z, two, one; + unsigned c1, c2, c3, c4; + Z3_bool result; + + printf("\nincremental_example1\n"); + LOG_MSG("incremental_example1"); + + x = mk_int_var(ctx, "x"); + y = mk_int_var(ctx, "y"); + z = mk_int_var(ctx, "z"); + two = mk_int(ctx, 2); + one = mk_int(ctx, 1); + + /* assert x < y */ + c1 = assert_retractable_cnstr(ext_ctx, Z3_mk_lt(ctx, x, y)); + /* assert x = z */ + c2 = assert_retractable_cnstr(ext_ctx, Z3_mk_eq(ctx, x, z)); + /* assert x > 2 */ + c3 = assert_retractable_cnstr(ext_ctx, Z3_mk_gt(ctx, x, two)); + /* assert y < 1 */ + c4 = assert_retractable_cnstr(ext_ctx, Z3_mk_lt(ctx, y, one)); + + result = ext_check(ext_ctx); + if (result != Z3_L_FALSE) + exitf("bug in Z3"); + printf("unsat\n"); + + retract_cnstr(ext_ctx, c4); + result = ext_check(ext_ctx); + if (result != Z3_L_TRUE) + exitf("bug in Z3"); + printf("sat\n"); + + reassert_cnstr(ext_ctx, c4); + result = ext_check(ext_ctx); + if (result != Z3_L_FALSE) + exitf("bug in Z3"); + printf("unsat\n"); + + retract_cnstr(ext_ctx, c2); + result = ext_check(ext_ctx); + if (result != Z3_L_FALSE) + exitf("bug in Z3"); + printf("unsat\n"); + + retract_cnstr(ext_ctx, c3); + result = ext_check(ext_ctx); + if (result != Z3_L_TRUE) + exitf("bug in Z3"); + printf("sat\n"); + + del_ext_context(ext_ctx); +} + +/** + \brief Simple example showing how to use reference counters in Z3 + to manage memory efficiently. +*/ +void reference_counter_example() { + Z3_config cfg; + Z3_context ctx; + Z3_sort ty; + Z3_ast x, y, x_xor_y; + Z3_symbol sx, sy; + + printf("\nreference_counter_example\n"); + LOG_MSG("reference_counter_example"); + + cfg = Z3_mk_config(); + Z3_set_param_value(cfg, "MODEL", "true"); + // Create a Z3 context where the user is reponsible for managing + // Z3_ast reference counters. + ctx = Z3_mk_context_rc(cfg); + Z3_del_config(cfg); + + ty = Z3_mk_bool_sort(ctx); + Z3_inc_ref(ctx, Z3_sort_to_ast(ctx, ty)); // Z3_sort_to_ast(ty) is just syntax sugar for ((Z3_ast) ty) + sx = Z3_mk_string_symbol(ctx, "x"); + // Z3_symbol is not a Z3_ast. No reference counting is not needed. + x = Z3_mk_const(ctx, sx, ty); + Z3_inc_ref(ctx, x); + sy = Z3_mk_string_symbol(ctx, "y"); + y = Z3_mk_const(ctx, sy, ty); + Z3_inc_ref(ctx, y); + // ty is not needed anymore. + Z3_dec_ref(ctx, Z3_sort_to_ast(ctx, ty)); + x_xor_y = Z3_mk_xor(ctx, x, y); + Z3_inc_ref(ctx, x_xor_y); + // x and y are not needed anymore. + Z3_dec_ref(ctx, x); + Z3_dec_ref(ctx, y); + Z3_assert_cnstr(ctx, x_xor_y); + // x_or_y is not needed anymore. + Z3_dec_ref(ctx, x_xor_y); + + printf("model for: x xor y\n"); + check(ctx, Z3_L_TRUE); + + // Test push & pop + Z3_push(ctx); + Z3_pop(ctx, 1); + + Z3_del_context(ctx); +} + +/** + \brief Demonstrates how to use SMT2 parser. +*/ +void smt2parser_example() { + Z3_context ctx; + Z3_ast fs; + printf("\nsmt2parser_example\n"); + LOG_MSG("smt2parser_example"); + + ctx = mk_context(); + fs = Z3_parse_smtlib2_string(ctx, "(declare-fun a () (_ BitVec 8)) (assert (bvuge a #x10)) (assert (bvule a #xf0))", 0, 0, 0, 0, 0, 0); + printf("formulas: %s\n", Z3_ast_to_string(ctx, fs)); + Z3_del_context(ctx); +} + +/** + \brief Demonstrates how to use the function \c Z3_substitute to replace subexpressions in a Z3 AST. +*/ +void substitute_example() { + Z3_context ctx; + Z3_sort int_ty; + Z3_ast a, b; + Z3_func_decl f; + Z3_func_decl g; + Z3_ast fab, ga, ffabga, r; + + printf("\nsubstitute_example\n"); + LOG_MSG("substitute_example"); + + ctx = mk_context(); + int_ty = Z3_mk_int_sort(ctx); + a = mk_int_var(ctx,"a"); + b = mk_int_var(ctx,"b"); + { + Z3_sort f_domain[2] = { int_ty, int_ty }; + f = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx, "f"), 2, f_domain, int_ty); + } + g = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx, "g"), 1, &int_ty, int_ty); + { + Z3_ast args[2] = { a, b }; + fab = Z3_mk_app(ctx, f, 2, args); + } + ga = Z3_mk_app(ctx, g, 1, &a); + { + Z3_ast args[2] = { fab, ga }; + ffabga = Z3_mk_app(ctx, f, 2, args); + } + // Replace b -> 0, g(a) -> 1 in f(f(a, b), g(a)) + { + Z3_ast zero = Z3_mk_numeral(ctx, "0", int_ty); + Z3_ast one = Z3_mk_numeral(ctx, "1", int_ty); + Z3_ast from[2] = { b, ga }; + Z3_ast to[2] = { zero, one }; + r = Z3_substitute(ctx, ffabga, 2, from, to); + } + // Display r + printf("substitution result: %s\n", Z3_ast_to_string(ctx, r)); + Z3_del_context(ctx); +} + +/** + \brief Demonstrates how to use the function \c Z3_substitute_vars to replace (free) variables with expressions in a Z3 AST. +*/ +void substitute_vars_example() { + Z3_context ctx; + Z3_sort int_ty; + Z3_ast x0, x1; + Z3_ast a, b, gb; + Z3_func_decl f; + Z3_func_decl g; + Z3_ast f01, ff010, r; + + printf("\nsubstitute_vars_example\n"); + LOG_MSG("substitute_vars_example"); + + ctx = mk_context(); + int_ty = Z3_mk_int_sort(ctx); + x0 = Z3_mk_bound(ctx, 0, int_ty); + x1 = Z3_mk_bound(ctx, 1, int_ty); + { + Z3_sort f_domain[2] = { int_ty, int_ty }; + f = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx, "f"), 2, f_domain, int_ty); + } + g = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx, "g"), 1, &int_ty, int_ty); + { + Z3_ast args[2] = { x0, x1 }; + f01 = Z3_mk_app(ctx, f, 2, args); + } + { + Z3_ast args[2] = { f01, x0 }; + ff010 = Z3_mk_app(ctx, f, 2, args); + } + a = mk_int_var(ctx, "a"); + b = mk_int_var(ctx, "b"); + gb = Z3_mk_app(ctx, g, 1, &b); + // Replace x0 -> a, x1 -> g(b) in f(f(x0,x1),x0) + { + Z3_ast to[2] = { a, gb }; + r = Z3_substitute_vars(ctx, ff010, 2, to); + } + // Display r + printf("substitution result: %s\n", Z3_ast_to_string(ctx, r)); + Z3_del_context(ctx); +} + + +/*@}*/ +/*@}*/ + +int main() { +#ifdef LOG_Z3_CALLS + Z3_open_log("z3.log"); +#endif + display_version(); + simple_example(); + demorgan(); + find_model_example1(); + find_model_example2(); + prove_example1(); + prove_example2(); + push_pop_example1(); + quantifier_example1(); + array_example1(); + array_example2(); + array_example3(); + tuple_example1(); + bitvector_example1(); + bitvector_example2(); + eval_example1(); + two_contexts_example1(); + error_code_example1(); + error_code_example2(); + parser_example1(); + parser_example2(); + parser_example3(); + parser_example4(); + parser_example5(); + numeral_example(); + ite_example(); + list_example(); + tree_example(); + forest_example(); + binary_tree_example(); + enum_example(); + unsat_core_and_proof_example(); + get_implied_equalities_example(); + incremental_example1(); + reference_counter_example(); + smt2parser_example(); + substitute_example(); + substitute_vars_example(); + return 0; +} diff --git a/test_capi/test_capi.vcxproj b/test_capi/test_capi.vcxproj new file mode 100644 index 000000000..2c0959beb --- /dev/null +++ b/test_capi/test_capi.vcxproj @@ -0,0 +1,1246 @@ + + + + + commercial_64 + Win32 + + + commercial_64 + x64 + + + commercial + Win32 + + + commercial + x64 + + + debug_opt + Win32 + + + debug_opt + x64 + + + Debug + Win32 + + + Debug + x64 + + + external_64 + Win32 + + + external_64 + x64 + + + external_dbg + Win32 + + + external_dbg + x64 + + + external_parallel_x64 + Win32 + + + external_parallel_x64 + x64 + + + external_parallel + Win32 + + + external_parallel + x64 + + + mpi_debug + Win32 + + + mpi_debug + x64 + + + mpi_release + Win32 + + + mpi_release + x64 + + + parallel_debug + Win32 + + + parallel_debug + x64 + + + parallel_release + Win32 + + + parallel_release + x64 + + + ReleaseD + Win32 + + + ReleaseD + x64 + + + release_mt + Win32 + + + release_mt + x64 + + + release_static + Win32 + + + release_static + x64 + + + Release + Win32 + + + Release + x64 + + + smtcomp + Win32 + + + smtcomp + x64 + + + + {9E76526D-EDA2-4B88-9616-A8FC08F31071} + test_capi + Win32Proj + + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + + + Application + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + Unicode + true + + + Application + + + Application + + + Application + + + Application + + + 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)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + 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 + + + + + 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 + + + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_CONSOLE;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_CONSOLE;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX64 + + + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_CONSOLE;Z3DEBUG;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDLL + + + Level3 + EditAndContinue + + + true + Console + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_CONSOLE;Z3DEBUG;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + MachineX64 + + + + + ..\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 + + + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_CONSOLE;Z3DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + true + Console + 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 + + + + + Disabled + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_CONSOLE;Z3DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + true + Console + 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 + + + + + ..\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 + + + + + ..\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 + + + + + ..\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 + + + + + ..\lib;%(AdditionalIncludeDirectories) + WIN32;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + MachineX64 + + + + + + + + {0bf8cb94-61c7-4545-ae55-c58d858aa8b6} + false + + + {4a7e5a93-19d8-4382-8950-fb2edec7a76e} + false + + + + + + \ No newline at end of file diff --git a/test_capi/test_capi.vcxproj.user b/test_capi/test_capi.vcxproj.user new file mode 100644 index 000000000..ace9a86ac --- /dev/null +++ b/test_capi/test_capi.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test_managed/README-external.txt b/test_managed/README-external.txt new file mode 100644 index 000000000..8af1b4d90 --- /dev/null +++ b/test_managed/README-external.txt @@ -0,0 +1,6 @@ +Use 'build.cmd' to build the test application using Microsoft C# +compiler. + +Remark: The Microsoft C# compiler (csc) must be in your path, +or you can use the Visual Studio Command Prompt. + diff --git a/test_managed/build-external.bat b/test_managed/build-external.bat new file mode 100644 index 000000000..8539f1836 --- /dev/null +++ b/test_managed/build-external.bat @@ -0,0 +1,2 @@ +csc /reference:..\..\lib\Microsoft.Z3.dll /platform:x86 test_managed.cs +copy ..\..\lib\Microsoft.Z3.dll . \ No newline at end of file diff --git a/test_managed/build-external.cmd b/test_managed/build-external.cmd new file mode 100644 index 000000000..6f28e72a8 --- /dev/null +++ b/test_managed/build-external.cmd @@ -0,0 +1,3 @@ +csc /reference:..\..\bin\Microsoft.Z3.dll /platform:x86 test_managed.cs +@rem Copy DLL to allow test_managed.exe to find it. +copy ..\..\bin\Microsoft.Z3.dll \ No newline at end of file diff --git a/test_managed/build.bat b/test_managed/build.bat new file mode 100644 index 000000000..990b5e7f6 --- /dev/null +++ b/test_managed/build.bat @@ -0,0 +1,2 @@ +csc /reference:..\debug\Microsoft.Z3.dll /platform:x86 /debug:full test_managed.cs +copy ..\debug\Microsoft.Z3.dll . \ No newline at end of file diff --git a/test_managed/test_managed.cs b/test_managed/test_managed.cs new file mode 100644 index 000000000..ee9351b2e --- /dev/null +++ b/test_managed/test_managed.cs @@ -0,0 +1,1772 @@ + +/** + \defgroup mapi_ex Managed (.NET) API examples +*/ +/*@{*/ + +using Microsoft.Z3; +using System; +using System.Collections.Generic; +/// +/// \brief Class encapsulating Z3 tests. +/// + +class TestManaged +{ + /// + /// \brief local reference to the Z3 Api. + /// + Context z3; + Solver solver; + + + /*! \brief Create a logical context with model construction enabled. + */ + public void mk_context() + { + if (this.z3 != null) + { + this.z3.Dispose(); + } + Dictionary cfg = new Dictionary() { + { "MODEL", "true" }, + { "MBQI_MAX_ITERATIONS", "10" }, + { "PROOF_MODE", "2" } }; + this.z3 = new Context(cfg); + this.solver = z3.MkSolver(); + } + + + /*! \brief Create an integer type. + */ + public IntSort mk_int_type() + { + return z3.MkIntSort(); + } + + /*! \brief Create a bit-vector type. + */ + public BitVecSort mk_bv_type(uint num_bytes) + { + return z3.MkBitVecSort(num_bytes); + } + + /*! \brief Create a variable using the given name and type. + */ + public Expr mk_var(string name, Sort ty) + { + return z3.MkConst(name, ty); + } + + /*! \brief Create a boolean variable using the given name. + */ + public BoolExpr mk_bool_var(string name) + { + return (BoolExpr) mk_var(name, z3.MkBoolSort()); + } + + /*! \brief Create an integer variable using the given name. + */ + public IntExpr mk_int_var(string name) + { + return (IntExpr)mk_var(name, mk_int_type()); + } + + /*! \brief Create a bit-vector variable using the given name. + */ + public BitVecExpr mk_bv_var(string name, uint num_bytes) + { + return (BitVecExpr)mk_var(name, mk_bv_type(num_bytes)); + } + + /*! \brief Create a Z3 integer node using an int. + */ + IntExpr mk_int(int v) + { + return (IntExpr)z3.MkNumeral(v, mk_int_type()); + } + + /*! \brief Create a Z3 32-bit integer. + */ + BitVecExpr mk_bv32(UInt32 b) + { + return (BitVecExpr)z3.MkNumeral(String.Format("{0}", b), mk_bv_type(32)); + } + + /*! \brief Create the unary function application: (f x). + */ + Expr mk_unary_app(FuncDecl f, Expr x) + { + return f[x]; + } + + /*! \brief Create the binary function application: (f x y). + */ + Expr mk_binary_app(FuncDecl f, Expr x, Expr y) + { + return f[x, y]; + } + + void exitf(string message) + { + Console.WriteLine("{0}", message); + throw new Exception("Fatal Error"); + } + + /*! + \brief Check whether the logical context is satisfiable, + and compare the result with the expected result. + If the context is satisfiable, then display the model. + */ + public void check(Status expected_result, out Model model) + { + Status result = solver.Check(); + model = null; + Console.WriteLine("{0}", result); + switch (result) + { + case Status.UNSATISFIABLE: + break; + case Status.UNKNOWN: + break; + case Status.SATISFIABLE: + model = solver.Model; + Console.WriteLine("{0}", model.ToString()); + break; + } + if (result != expected_result) + { + Console.WriteLine("BUG: unexpected result"); + } + } + + /** + \brief Similar to #check, but uses #display_model instead of Z3's native display method. + */ + public void check2(Status expected_result) + { + Status result = solver.Check(); + Console.WriteLine("{0}", result); + switch (result) + { + case Status.UNSATISFIABLE: + case Status.UNKNOWN: + break; + case Status.SATISFIABLE: + display_model(Console.Out, solver.Model); + break; + } + if (result != expected_result) + { + Console.WriteLine("BUG: unexpected result"); + } + } + + + + /*! + \brief Prove that the constraints already asserted into the logical + context implies the given formula. The result of the proof is + displayed. + + Z3 is a satisfiability checker. So, one can prove \c f by showing + that (not f) is unsatisfiable. + + */ + public void prove(BoolExpr f) + { + /* save the current state of the context */ + solver.Push(); + + BoolExpr not_f = z3.MkNot(f); + solver.Assert(not_f); + Status result = solver.Check(); + + switch (result) + { + case Status.UNSATISFIABLE: + /* proved */ + Console.WriteLine("valid"); + Console.WriteLine("Proof: " + solver.Proof); + break; + case Status.UNKNOWN: + /* Z3 failed to prove/disprove f. */ + Console.WriteLine("unknown"); + break; + case Status.SATISFIABLE: + /* disproved */ + Console.WriteLine("invalid"); + display_model(Console.Out, solver.Model); + break; + } + + /* restore context */ + solver.Pop(); + } + + /*! + \brief Prove that the constraints already asserted into the logical + context implies the given formula. The result of the proof is + displayed. + + Z3 is a satisfiability checker. So, one can prove \c f by showing + that (not f) is unsatisfiable. + + */ + public void prove2(BoolExpr f, bool is_valid) + { + /* save the current state of the context */ + solver.Push(); + + BoolExpr not_f = z3.MkNot(f); + solver.Assert(not_f); + + switch (solver.Check()) + { + case Status.UNSATISFIABLE: + /* proved */ + Console.WriteLine("valid"); + if (!is_valid) + { + exitf("Did not expecte valid"); + } + break; + case Status.UNKNOWN: + /* Z3 failed to prove/disprove f. */ + Console.WriteLine("unknown"); + if (is_valid) + { + exitf("Expected valid"); + } + break; + case Status.SATISFIABLE: + /* disproved */ + Console.WriteLine("invalid"); + display_model(Console.Out, solver.Model); + if (is_valid) + { + exitf("Expected valid"); + } + break; + } + + /* restore context */ + solver.Pop(); + + } + + /** + \brief Custom model pretty printer. + */ + void display_model(System.IO.TextWriter w, Model model) + { + w.WriteLine("Custom model display:"); + FuncDecl[] consts = model.ConstDecls; + for (int i = 0; i < consts.Length; i++) + { + w.WriteLine("{0} |-> {1}", consts[i], model.Evaluate(consts[i].Apply())); + } + w.WriteLine("num consts: {0}", consts.Length); + FuncDecl[] funcs = model.FuncDecls; + foreach (FuncDecl f in funcs) + { + FuncInterp g = model.FuncInterp(f); + + w.WriteLine("function {0}:", f); + for (int j = 0; j < g.Entries.Length; ++j) + { + for (int k = 0; k < g.Entries[j].Args.Length; ++k) + { + w.Write(" {0} ", g.Entries[j].Args[k]); + } + w.WriteLine(" |-> {0}", g.Entries[j].Value); + } + w.WriteLine(" else |-> {0}", g.Else); + } + } + + /*! + \brief Assert the axiom: function f is injective in the i-th argument. + + The following axiom is asserted into the logical context: + \code + forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i + \endcode + + Where, \c finv is a fresh function declaration. + */ + public void assert_inj_axiom(FuncDecl f, int i) + { + Sort[] domain = f.Domain; + uint sz = f.DomainSize; + + if (i >= sz) + { + Console.WriteLine("failed to create inj axiom"); + return; + } + + /* declare the i-th inverse of f: finv */ + Sort finv_domain = f.Range; + Sort finv_range = domain[i]; + FuncDecl finv = z3.MkFuncDecl("f_fresh", finv_domain, finv_range); + + /* allocate temporary arrays */ + Expr[] xs = new Expr[sz]; + Symbol[] names = new Symbol[sz]; + Sort[] types = new Sort[sz]; + + /* fill types, names and xs */ + + for (uint j = 0; j < sz; j++) + { + types[j] = domain[j]; + names[j] = z3.MkSymbol(String.Format("x_{0}", j)); + xs[j] = z3.MkBound(j, types[j]); + } + Expr x_i = xs[i]; + + /* create f(x_0, ..., x_i, ..., x_{n-1}) */ + Expr fxs = f[xs]; + + /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ + Expr finv_fxs = mk_unary_app(finv, fxs); + + /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ + Expr eq = z3.MkEq(finv_fxs, x_i); + + /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ + Pattern p = z3.MkPattern(new Expr[] { fxs }); + Console.WriteLine("pattern {0}", p); + + /* create & assert quantifier */ + BoolExpr q = z3.MkForall( + types, /* types of quantified variables */ + names, /* names of quantified variables */ + eq, + 1, + new Pattern[] { p } /* patterns */); + + Console.WriteLine("assert axiom {0}", q); + solver.Assert(q); + + } + + /*! + \brief Assert the axiom: function f is injective in the i-th argument. + + The following axiom is asserted into the logical context: + \code + forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i + \endcode + + Where, \c finv is a fresh function declaration. + */ + public void assert_inj_axiom_abs(FuncDecl f, int i) + { + Sort[] domain = f.Domain; + uint sz = f.DomainSize; + + if (i >= sz) + { + Console.WriteLine("failed to create inj axiom"); + return; + } + + /* declare the i-th inverse of f: finv */ + Sort finv_domain = f.Range; + Sort finv_range = domain[i]; + FuncDecl finv = z3.MkFuncDecl("f_fresh", finv_domain, finv_range); + + /* allocate temporary arrays */ + Expr[] xs = new Expr[sz]; + + /* fill types, names and xs */ + + for (uint j = 0; j < sz; j++) + { + xs[j] = z3.MkConst(String.Format("x_{0}", j), domain[j]); + } + Expr x_i = xs[i]; + + /* create f(x_0, ..., x_i, ..., x_{n-1}) */ + Expr fxs = f[xs]; + + /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ + Expr finv_fxs = mk_unary_app(finv, fxs); + + /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ + Expr eq = z3.MkEq(finv_fxs, x_i); + + /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ + Pattern p = z3.MkPattern(new Expr[] { fxs }); + Console.WriteLine("pattern {0}", p); + + /* create & assert quantifier */ + Quantifier q = z3.MkForall( + xs, /* the list of bound variables */ + eq, + 1, + new Pattern[] { p } /* patterns */); + + Console.WriteLine("assert axiom {0}", q); + solver.Assert(q); + + } + + /** + \brief Assert the axiom: function f is commutative. + + This example uses the SMT-LIB parser to simplify the axiom construction. + */ + private void assert_comm_axiom(FuncDecl f) + { + Sort t = f.Range; + Sort[] dom = f.Domain; + + if (dom.Length != 2 || + !t.Equals(dom[0]) || + !t.Equals(dom[1])) + { + Console.WriteLine("{0} {1} {2} {3}", dom.Length, dom[0], dom[1], t); + exitf("function must be binary, and argument types must be equal to return type"); + } + string bench = string.Format("(benchmark comm :formula (forall (x {0}) (y {1}) (= ({2} x y) ({3} y x))))", + t.Name, t.Name, f.Name, f.Name); + z3.ParseSMTLIBString(bench, new Symbol[] { t.Name }, new Sort[] { t }, new Symbol[] { f.Name }, new FuncDecl[] { f }); + BoolExpr q = z3.SMTLIBFormulas[0]; + Console.WriteLine("assert axiom:\n{0}", q); + solver.Assert(q); + } + + + + /* @name Examples + */ + + /*! + \brief "Hello world" example: create a Z3 logical context, and delete it. + */ + public void simple_example() + { + Console.WriteLine("simple_example"); + Dictionary cfg = new Dictionary(); + Context z3 = new Context(cfg); + + /* do something with the context */ + + /* be kind to dispose manually and not wait for the GC. */ + z3.Dispose(); + } + + /*! + \brief Find a model for x xor y. + */ + public void find_model_example1() + { + Console.WriteLine("find_model_example1"); + + mk_context(); + + BoolExpr x = mk_bool_var("x"); + BoolExpr y = mk_bool_var("y"); + BoolExpr x_xor_y = z3.MkXor(x, y); + + solver.Assert(x_xor_y); + + Console.WriteLine("model for: x xor y"); + Model model = null; + check(Status.SATISFIABLE, out model); + Console.WriteLine("x = {0}, y = {1}", + model.Evaluate(x), + model.Evaluate(y)); + } + + /*! + \brief Find a model for x < y + 1, x > 2. + Then, assert not(x = y), and find another model. + */ + public void find_model_example2() + { + Console.WriteLine("find_model_example2"); + + mk_context(); + IntExpr x = mk_int_var("x"); + IntExpr y = mk_int_var("y"); + IntExpr one = mk_int(1); + IntExpr two = mk_int(2); + + ArithExpr y_plus_one = z3.MkAdd(y, one); + + BoolExpr c1 = z3.MkLt(x, y_plus_one); + BoolExpr c2 = z3.MkGt(x, two); + + solver.Assert(c1); + solver.Assert(c2); + + Console.WriteLine("model for: x < y + 1, x > 2"); + Model model = null; + check(Status.SATISFIABLE, out model); + Console.WriteLine("x = {0}, y = {1}", + (model.Evaluate(x)), + (model.Evaluate(y))); + + /* assert not(x = y) */ + BoolExpr x_eq_y = z3.MkEq(x, y); + BoolExpr c3 = z3.MkNot(x_eq_y); + solver.Assert(c3); + + Console.WriteLine("model for: x < y + 1, x > 2, not(x = y)"); + check(Status.SATISFIABLE, out model); + Console.WriteLine("x = {0}, y = {1}", + (model.Evaluate(x)), + (model.Evaluate(y))); + } + + /*! + \brief Prove x = y implies g(x) = g(y), and + disprove x = y implies g(g(x)) = g(y). + + This function demonstrates how to create uninterpreted types and + functions. + */ + public void prove_example1() + { + Console.WriteLine("prove_example1"); + + mk_context(); + + /* create uninterpreted type. */ + Sort U = z3.MkUninterpretedSort(z3.MkSymbol("U")); + + /* declare function g */ + FuncDecl g = z3.MkFuncDecl("g", U, U); + + /* create x and y */ + Expr x = z3.MkConst("x", U); + Expr y = z3.MkConst("y", U); + /* create g(x), g(y) */ + Expr gx = mk_unary_app(g, x); + Expr gy = mk_unary_app(g, y); + + /* assert x = y */ + BoolExpr eq = z3.MkEq(x, y); + + /* prove g(x) = g(y) */ + BoolExpr f = z3.MkEq(gx, gy); + Console.WriteLine("prove: x = y implies g(x) = g(y)"); + prove(z3.MkImplies(eq, f)); + + /* create g(g(x)) */ + Expr ggx = mk_unary_app(g, gx); + + /* disprove g(g(x)) = g(y) */ + f = z3.MkEq(ggx, gy); + Console.WriteLine("disprove: x = y implies g(g(x)) = g(y)"); + prove(z3.MkImplies(eq, f)); + + + /* Print the model using the custom model printer */ + solver.Assert(z3.MkNot(f)); + check2(Status.SATISFIABLE); + } + + + /*! \brief Prove not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 . + Then, show that z < -1 is not implied. + + This example demonstrates how to combine uninterpreted functions and arithmetic. + */ + public void prove_example2() + { + Console.WriteLine("prove_example2"); + + mk_context(); + + /* declare function g */ + Sort int_type = mk_int_type(); + + FuncDecl g = z3.MkFuncDecl("g", int_type, int_type); + + /* create x, y, and z */ + IntExpr x = mk_int_var("x"); + IntExpr y = mk_int_var("y"); + IntExpr z = mk_int_var("z"); + + /* create gx, gy, gz */ + Expr gx = mk_unary_app(g, x); + Expr gy = mk_unary_app(g, y); + Expr gz = mk_unary_app(g, z); + + /* create zero */ + IntExpr zero = mk_int(0); + + /* assert not(g(g(x) - g(y)) = g(z)) */ + ArithExpr gx_gy = z3.MkSub((IntExpr)gx, (IntExpr)gy); + Expr ggx_gy = mk_unary_app(g, gx_gy); + BoolExpr eq = z3.MkEq(ggx_gy, gz); + BoolExpr c1 = z3.MkNot(eq); + solver.Assert(c1); + + /* assert x + z <= y */ + ArithExpr x_plus_z = z3.MkAdd(x, z); + BoolExpr c2 = z3.MkLe(x_plus_z, y); + solver.Assert(c2); + + /* assert y <= x */ + BoolExpr c3 = z3.MkLe(y, x); + solver.Assert(c3); + + /* prove z < 0 */ + BoolExpr f = z3.MkLt(z, zero); + Console.WriteLine("prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0"); + prove(f); + + /* disprove z < -1 */ + IntExpr minus_one = mk_int(-1); + f = z3.MkLt(z, minus_one); + Console.WriteLine("disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1"); + prove(f); + } + + /*! \brief Show how push & pop can be used to create "backtracking" + points. + + This example also demonstrates how big numbers can be created in Z3. + */ + public void push_pop_example1() + { + Console.WriteLine("push_pop_example1"); + + mk_context(); + + /* create a big number */ + IntSort int_type = mk_int_type(); + IntExpr big_number = (IntExpr)z3.MkNumeral("1000000000000000000000000000000000000000000000000000000", int_type); + + /* create number 3 */ + IntExpr three = (IntExpr)z3.MkNumeral("3", int_type); + + /* create x */ + IntExpr x = mk_int_var("x"); + + + /* assert x >= "big number" */ + BoolExpr c1 = z3.MkGe(x, big_number); + Console.WriteLine("assert: x >= 'big number'"); + solver.Assert(c1); + + /* create a backtracking point */ + Console.WriteLine("push"); + solver.Push(); + + /* assert x <= 3 */ + BoolExpr c2 = z3.MkLe(x, three); + Console.WriteLine("assert: x <= 3"); + solver.Assert(c2); + + /* context is inconsistent at this point */ + Model model = null; + check(Status.UNSATISFIABLE, out model); + + /* backtrack: the constraint x <= 3 will be removed, since it was + asserted after the last z3.Push. */ + Console.WriteLine("pop"); + solver.Pop(1); + + /* the context is consistent again. */ + check2(Status.SATISFIABLE); + + /* new constraints can be asserted... */ + + /* create y */ + IntExpr y = mk_int_var("y"); + + /* assert y > x */ + BoolExpr c3 = z3.MkGt(y, x); + Console.WriteLine("assert: y > x"); + solver.Assert(c3); + + /* the context is still consistent. */ + check(Status.SATISFIABLE, out model); + } + + public void mk_quantifier() + { + Console.WriteLine("quantifier_example1"); + mk_context(); + Expr q1, q2; + FuncDecl f = z3.MkFuncDecl("f", z3.MkIntSort(), z3.MkIntSort()); + FuncDecl g = z3.MkFuncDecl("g", z3.MkIntSort(), z3.MkIntSort()); + + // Quantifier with Exprs as the bound variables. + { + Expr x = z3.MkConst("x", z3.MkIntSort()); + Expr y = z3.MkConst("y", z3.MkIntSort()); + Expr f_x = z3.MkApp(f,x); + Expr f_y = z3.MkApp(f,y); + Expr g_y = z3.MkApp(g,y); + Pattern[] pats = new Pattern[] { z3.MkPattern(new Expr[]{ f_x, g_y }) }; + Expr[] no_pats = new Expr[]{f_y}; + Expr[] bound = new Expr[2]{ x, y }; + Expr body = z3.MkAnd(z3.MkEq(f_x,f_y),z3.MkEq(f_y,g_y)); + + q1 = z3.MkForall(bound, body, 1, null, no_pats, z3.MkSymbol("q"), z3.MkSymbol("sk")); + + Console.WriteLine("{0}", q1); + } + // Quantifier with de-Brujin indices. + { + Expr x = z3.MkBound(1, z3.MkIntSort()); + Expr y = z3.MkBound(0, z3.MkIntSort()); + Expr f_x = z3.MkApp(f,x); + Expr f_y = z3.MkApp(f,y); + Expr g_y = z3.MkApp(g,y); + Pattern[] pats = new Pattern[] { z3.MkPattern(new Expr[]{ f_x, g_y }) }; + Expr[] no_pats = new Expr[]{f_y}; + Symbol[] names = new Symbol[] { z3.MkSymbol("x"), z3.MkSymbol("y") }; + Sort[] sorts = new Sort[] { z3.MkIntSort(), z3.MkIntSort() }; + Expr body = z3.MkAnd(z3.MkEq(f_x,f_y),z3.MkEq(f_y,g_y)); + + q2 = z3.MkForall( sorts, names, body, 1, + null, // pats, + no_pats, + z3.MkSymbol("q"), + z3.MkSymbol("sk") + ); + Console.WriteLine("{0}", q2); + } + Console.WriteLine("{0}", (q1.Equals(q2))); + + } + + /*! \brief Prove that f(x, y) = f(w, v) implies y = v when + \c f is injective in the second argument. + + \sa assert_inj_axiom. + */ + public void quantifier_example1() + { + Console.WriteLine("quantifier_example1"); + + Dictionary cfg = new Dictionary() { + { "MBQI", "false" }, + { "PROOF_MODE", "2" } }; + /* If quantified formulas are asserted in a logical context, then + the model produced by Z3 should be viewed as a potential model. + + */ + if (this.z3 != null) + { + this.z3.Dispose(); + } + this.z3 = new Context(cfg); + this.solver = z3.MkSolver(); + + /* declare function f */ + Sort int_type = mk_int_type(); + FuncDecl f = z3.MkFuncDecl("f", new Sort[] { int_type, int_type }, int_type); + + /* assert that f is injective in the second argument. */ + assert_inj_axiom(f, 1); + + /* create x, y, v, w, fxy, fwv */ + Expr x = mk_int_var("x"); + Expr y = mk_int_var("y"); + Expr v = mk_int_var("v"); + Expr w = mk_int_var("w"); + Expr fxy = mk_binary_app(f, x, y); + Expr fwv = mk_binary_app(f, w, v); + + /* assert f(x, y) = f(w, v) */ + BoolExpr p1 = z3.MkEq(fxy, fwv); + solver.Assert(p1); + + /* prove f(x, y) = f(w, v) implies y = v */ + BoolExpr p2 = z3.MkEq(y, v); + Console.WriteLine("prove: f(x, y) = f(w, v) implies y = v"); + prove(p2); + + /* disprove f(x, y) = f(w, v) implies x = w */ + BoolExpr p3 = z3.MkEq(x, w); + Console.WriteLine("disprove: f(x, y) = f(w, v) implies x = w"); + prove(p3); + } + + /*! \brief Prove that f(x, y) = f(w, v) implies y = v when + \c f is injective in the second argument. + + \sa assert_inj_axiom. + */ + public void quantifier_example1_abs() + { + Console.WriteLine("quantifier_example1_abs"); + + Dictionary cfg = new Dictionary() { { "MBQI", "false" }, { "PROOF_MODE", "2" } }; + + /* If quantified formulas are asserted in a logical context, then + the model produced by Z3 should be viewed as a potential model. + + */ + if (this.z3 != null) + { + this.z3.Dispose(); + } + this.z3 = new Context(cfg); + this.solver = z3.MkSolver(); + + /* declare function f */ + Sort int_type = mk_int_type(); + FuncDecl f = z3.MkFuncDecl("f", new Sort[] { int_type, int_type }, int_type); + + /* assert that f is injective in the second argument. */ + assert_inj_axiom_abs(f, 1); + + /* create x, y, v, w, fxy, fwv */ + Expr x = mk_int_var("x"); + Expr y = mk_int_var("y"); + Expr v = mk_int_var("v"); + Expr w = mk_int_var("w"); + Expr fxy = mk_binary_app(f, x, y); + Expr fwv = mk_binary_app(f, w, v); + + /* assert f(x, y) = f(w, v) */ + BoolExpr p1 = z3.MkEq(fxy, fwv); + solver.Assert(p1); + + /* prove f(x, y) = f(w, v) implies y = v */ + BoolExpr p2 = z3.MkEq(y, v); + Console.WriteLine("prove: f(x, y) = f(w, v) implies y = v"); + prove(p2); + + /* disprove f(x, y) = f(w, v) implies x = w */ + BoolExpr p3 = z3.MkEq(x, w); + Console.WriteLine("disprove: f(x, y) = f(w, v) implies x = w"); + prove(p3); + } + + + /*! \brief Prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)). + + This example demonstrates how to use the array theory. + */ + public void array_example1() + { + + Console.WriteLine("array_example1"); + + mk_context(); + + Sort int_type = mk_int_type(); + Sort array_type = z3.MkArraySort(int_type, int_type); + + ArrayExpr a1 = (ArrayExpr)mk_var("a1", array_type); + ArrayExpr a2 = (ArrayExpr)mk_var("a2", array_type); + Expr i1 = mk_var("i1", int_type); + Expr i2 = mk_var("i2", int_type); + Expr i3 = mk_var("i3", int_type); + Expr v1 = mk_var("v1", int_type); + Expr v2 = mk_var("v2", int_type); + + Expr st1 = z3.MkStore(a1, i1, v1); + Expr st2 = z3.MkStore(a2, i2, v2); + + Expr sel1 = z3.MkSelect(a1, i3); + Expr sel2 = z3.MkSelect(a2, i3); + + /* create antecedent */ + BoolExpr antecedent = z3.MkEq(st1, st2); + + /* create consequent: i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3) */ + BoolExpr consequent = z3.MkOr(new BoolExpr[] { z3.MkEq(i1, i3), z3.MkEq(i2, i3), z3.MkEq(sel1, sel2) }); + + /* prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) */ + BoolExpr thm = z3.MkImplies(antecedent, consequent); + Console.WriteLine("prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))"); + Console.WriteLine("{0}", (thm)); + prove(thm); + } + + /*! \brief Show that distinct(a_0, ... , a_n) is + unsatisfiable when \c a_i's are arrays from boolean to + boolean and n > 4. + + This example also shows how to use the \c distinct construct. + */ + public void array_example2() + { + Console.WriteLine("array_example2"); + + for (int n = 2; n <= 5; n++) + { + Console.WriteLine("n = {0}", n); + mk_context(); + + Sort bool_type = z3.MkBoolSort(); + Sort array_type = z3.MkArraySort(bool_type, bool_type); + Expr[] a = new Expr[n]; + + /* create arrays */ + for (int i = 0; i < n; i++) + { + a[i] = z3.MkConst(String.Format("array_{0}", i), array_type); + } + + /* assert distinct(a[0], ..., a[n]) */ + BoolExpr d = z3.MkDistinct(a); + Console.WriteLine("{0}", (d)); + solver.Assert(d); + + /* context is satisfiable if n < 5 */ + Model model = null; + check(n < 5 ? Status.SATISFIABLE : Status.UNSATISFIABLE, out model); + if (n < 5) + { + for (int i = 0; i < n; i++) + { + Console.WriteLine("{0} = {1}", + a[i], + model.Evaluate(a[i])); + } + } + } + } + + /*! \brief Tuples. + + Check that the projection of a tuple returns the corresponding element. + */ + public void tuple_example() + { + mk_context(); + Sort int_type = mk_int_type(); + TupleSort tuple = z3.MkTupleSort( + z3.MkSymbol("mk_tuple"), // name of tuple constructor + new Symbol[] { z3.MkSymbol("first"), z3.MkSymbol("second") }, // names of projection operators + new Sort[] { int_type, int_type } // types of projection operators + ); + FuncDecl first = tuple.FieldDecls[0]; // declarations are for projections + FuncDecl second = tuple.FieldDecls[1]; + Expr x = z3.MkConst("x", int_type); + Expr y = z3.MkConst("y", int_type); + Expr n1 = tuple.MkDecl[x, y]; + Expr n2 = first[n1]; + BoolExpr n3 = z3.MkEq(x, n2); + Console.WriteLine("Tuple example: {0}", n3); + prove(n3); + } + + /*! + \brief Simple bit-vector example. This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers + */ + public void bitvector_example1() + { + Console.WriteLine("\nbitvector_example1"); + + mk_context(); + + Sort bv_type = z3.MkBitVecSort(32); + BitVecExpr x = (BitVecExpr)mk_var("x", bv_type); + BitVecNum zero = (BitVecNum)z3.MkNumeral("0", bv_type); + BitVecNum ten = (BitVecNum)z3.MkNumeral("10", bv_type); + BitVecExpr x_minus_ten = z3.MkBVSub(x, ten); + /* bvsle is signed less than or equal to */ + BoolExpr c1 = z3.MkBVSLE(x, ten); + BoolExpr c2 = z3.MkBVSLE(x_minus_ten, zero); + BoolExpr thm = z3.MkIff(c1, c2); + Console.WriteLine("disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers"); + prove(thm); + } + + /*! + \brief Find x and y such that: x ^ y - 103 == x * y + */ + public void bitvector_example2() + { + mk_context(); + + /* construct x ^ y - 103 == x * y */ + Sort bv_type = z3.MkBitVecSort(32); + BitVecExpr x = (BitVecExpr)mk_var("x", bv_type); + BitVecExpr y = (BitVecExpr)mk_var("y", bv_type); + BitVecExpr x_xor_y = z3.MkBVXOR(x, y); + BitVecExpr c103 = (BitVecNum)z3.MkNumeral("103", bv_type); + BitVecExpr lhs = z3.MkBVSub(x_xor_y, c103); + BitVecExpr rhs = z3.MkBVMul(x, y); + BoolExpr ctr = z3.MkEq(lhs, rhs); + + Console.WriteLine("\nbitvector_example2"); + Console.WriteLine("find values of x and y, such that x ^ y - 103 == x * y"); + + /* add the constraint x ^ y - 103 == x * y<\tt> to the logical context */ + solver.Assert(ctr); + + /* find a model (i.e., values for x an y that satisfy the constraint */ + check2(Status.SATISFIABLE); + } + + + + /*! + \brief Demonstrates how to use the SMTLIB parser. + */ + public void parser_example1() + { + mk_context(); + + Console.WriteLine("\nparser_example1"); + + z3.ParseSMTLIBString("(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))"); + foreach (BoolExpr f in z3.SMTLIBFormulas) + { + Console.WriteLine("formula {0}", f); + solver.Assert(f); + } + check2(Status.SATISFIABLE); + } + + /*! + \brief Demonstrates how to initialize the parser symbol table. + */ + public void parser_example2() + { + mk_context(); + Console.WriteLine("\nparser_example2"); + + /* + Z3_enable_arithmetic doesn't need to be invoked in this example + because it will be implicitly invoked by mk_int_var. + */ + + Symbol[] declNames = { z3.MkSymbol("a"), z3.MkSymbol("b") }; + FuncDecl a = z3.MkConstDecl(declNames[0], z3.MkIntSort()); + FuncDecl b = z3.MkConstDecl(declNames[1], z3.MkIntSort()); + FuncDecl[] decls = new FuncDecl[] { a, b }; + + z3.ParseSMTLIBString("(benchmark tst :formula (> a b))", + null, null, declNames, decls); + BoolExpr f = z3.SMTLIBFormulas[0]; + Console.WriteLine("formula: {0}", f); + solver.Assert(f); + check2(Status.SATISFIABLE); + } + + /*! + \brief Demonstrates how to initialize the parser symbol table. + */ + public void parser_example3() + { + Console.WriteLine("\nparser_example3"); + + mk_context(); + + /* declare function g */ + Sort int_type = z3.MkIntSort(); + FuncDecl g = z3.MkFuncDecl("g", new Sort[] { int_type, int_type }, int_type); + + assert_comm_axiom(g); + + z3.ParseSMTLIBString("(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (gg x 0) (gg 0 y)))))", + null, null, + new Symbol[] { z3.MkSymbol("gg") }, + new FuncDecl[] { g }); + + BoolExpr thm = z3.SMTLIBFormulas[0]; + Console.WriteLine("formula: {0}", thm); + prove(thm); + } + + /*! + \brief Display the declarations, assumptions and formulas in a SMT-LIB string. + */ + public void parser_example4() + { + mk_context(); + + Console.WriteLine("\nparser_example4"); + + z3.ParseSMTLIBString + ("(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))"); + foreach (var decl in z3.SMTLIBDecls) + { + Console.WriteLine("Declaration: {0}", decl); + } + foreach (var f in z3.SMTLIBAssumptions) + { + Console.WriteLine("Assumption: {0}", f); + } + foreach (var f in z3.SMTLIBFormulas) + { + Console.WriteLine("Formula: {0}", f); + } + } + + /*! + \brief Demonstrates how to handle parser errors using Z3 error handling support. + */ + public void parser_example5() + { + Console.WriteLine("\nparser_example5"); + + try + { + z3.ParseSMTLIBString( + /* the following string has a parsing error: missing parenthesis */ + "(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))"); + } + catch (Z3Exception e) + { + Console.WriteLine("Z3 error: {0}", e); + } + } + + /*! + \brief Create an ite-Expr (if-then-else Exprs). + */ + public void ite_example() + { + Console.WriteLine("\nite_example"); + mk_context(); + + BoolExpr f = z3.MkFalse(); + Expr one = mk_int(1); + Expr zero = mk_int(0); + Expr ite = z3.MkITE(f, one, zero); + + Console.WriteLine("Expr: {0}", ite); + } + + /*! + \brief Create an enumeration data type. + */ + public void enum_example() + { + mk_context(); + Symbol name = z3.MkSymbol("fruit"); + + Console.WriteLine("\nenum_example"); + + EnumSort fruit = z3.MkEnumSort(z3.MkSymbol("fruit"), new Symbol[] { z3.MkSymbol("apple"), z3.MkSymbol("banana"), z3.MkSymbol("orange") }); + + Console.WriteLine("{0}", (fruit.Consts[0])); + Console.WriteLine("{0}", (fruit.Consts[1])); + Console.WriteLine("{0}", (fruit.Consts[2])); + + Console.WriteLine("{0}", (fruit.TesterDecls[0])); + Console.WriteLine("{0}", (fruit.TesterDecls[1])); + Console.WriteLine("{0}", (fruit.TesterDecls[2])); + + Expr apple = z3.MkConst(fruit.ConstDecls[0]); + Expr banana = z3.MkConst(fruit.ConstDecls[1]); + Expr orange = z3.MkConst(fruit.ConstDecls[2]); + + /* Apples are different from oranges */ + prove2(z3.MkNot(z3.MkEq(apple, orange)), true); + + /* Apples pass the apple test */ + prove2((BoolExpr)z3.MkApp(fruit.TesterDecls[0], apple), true); + + /* Oranges fail the apple test */ + prove2((BoolExpr)z3.MkApp(fruit.TesterDecls[0], orange), false); + prove2((BoolExpr)z3.MkNot((BoolExpr)z3.MkApp(fruit.TesterDecls[0], orange)), true); + + Expr fruity = mk_var("fruity", fruit); + + /* If something is fruity, then it is an apple, banana, or orange */ + + prove2(z3.MkOr(new BoolExpr[] { z3.MkEq(fruity, apple), z3.MkEq(fruity, banana), z3.MkEq(fruity, orange) }), true); + } + + + /*! + \brief Create a list datatype. + */ + public void list_example() + { + mk_context(); + + Sort int_ty; + ListSort int_list; + Expr nil, l1, l2, x, y, u, v; + BoolExpr fml, fml1; + + Console.WriteLine("\nlist_example"); + + int_ty = z3.MkIntSort(); + + int_list = z3.MkListSort(z3.MkSymbol("int_list"), int_ty); + + nil = z3.MkConst(int_list.NilDecl); + l1 = mk_binary_app(int_list.ConsDecl, mk_int(1), nil); + l2 = mk_binary_app(int_list.ConsDecl, mk_int(2), nil); + + /* nil != cons(1, nil) */ + prove2(z3.MkNot(z3.MkEq(nil, l1)), true); + + /* cons(2,nil) != cons(1, nil) */ + prove2(z3.MkNot(z3.MkEq(l1, l2)), true); + + /* cons(x,nil) = cons(y, nil) => x = y */ + x = mk_var("x", int_ty); + y = mk_var("y", int_ty); + l1 = mk_binary_app(int_list.ConsDecl, x, nil); + l2 = mk_binary_app(int_list.ConsDecl, y, nil); + prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(x, y)), true); + + /* cons(x,u) = cons(x, v) => u = v */ + u = mk_var("u", int_list); + v = mk_var("v", int_list); + l1 = mk_binary_app(int_list.ConsDecl, x, u); + l2 = mk_binary_app(int_list.ConsDecl, y, v); + prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(u, v)), true); + prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(x, y)), true); + + /* is_nil(u) or is_cons(u) */ + prove2(z3.MkOr((BoolExpr) z3.MkApp(int_list.IsNilDecl, u), + (BoolExpr)z3.MkApp(int_list.IsConsDecl, u)), true); + + /* occurs check u != cons(x,u) */ + prove2(z3.MkNot(z3.MkEq(u, l1)), true); + + /* destructors: is_cons(u) => u = cons(head(u),tail(u)) */ + fml1 = z3.MkEq(u, mk_binary_app(int_list.ConsDecl, mk_unary_app(int_list.HeadDecl, u), + mk_unary_app(int_list.TailDecl, u))); + fml = z3.MkImplies((BoolExpr) z3.MkApp(int_list.IsConsDecl, u), fml1); + Console.WriteLine("Formula {0}", fml); + + prove2(fml, true); + + prove2(fml1, false); + } + + + + /*! + \brief Create a binary tree datatype. + */ + public void tree_example() + { + mk_context(); + Sort cell; + FuncDecl nil_decl, is_nil_decl, cons_decl, is_cons_decl, car_decl, cdr_decl; + Expr nil, l1, l2, x, y, u, v; + BoolExpr fml, fml1; + string[] head_tail = new string[] {"car", "cdr" }; + Sort[] sorts = new Sort[] { null, null }; + uint[] sort_refs = new uint[] { 0, 0 }; + Constructor nil_con, cons_con; + + Console.WriteLine("\ntree_example"); + + nil_con = z3.MkConstructor("nil", "is_nil", null, null, null); + cons_con = z3.MkConstructor("cons", "is_cons", head_tail, sorts, sort_refs); + Constructor[] constructors = new Constructor[] { nil_con, cons_con }; + + cell = z3.MkDatatypeSort("cell", constructors); + + nil_decl = nil_con.ConstructorDecl; + is_nil_decl = nil_con.TesterDecl; + cons_decl = cons_con.ConstructorDecl; + is_cons_decl = cons_con.TesterDecl; + FuncDecl[] cons_accessors = cons_con.AccessorDecls; + car_decl = cons_accessors[0]; + cdr_decl = cons_accessors[1]; + + nil = z3.MkConst(nil_decl); + l1 = mk_binary_app(cons_decl, nil, nil); + l2 = mk_binary_app(cons_decl, l1, nil); + + /* nil != cons(nil, nil) */ + prove2(z3.MkNot(z3.MkEq(nil, l1)), true); + + /* cons(x,u) = cons(x, v) => u = v */ + u = mk_var("u", cell); + v = mk_var("v", cell); + x = mk_var("x", cell); + y = mk_var("y", cell); + l1 = mk_binary_app(cons_decl, x, u); + l2 = mk_binary_app(cons_decl, y, v); + prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(u, v)), true); + prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(x, y)), true); + + /* is_nil(u) or is_cons(u) */ + prove2(z3.MkOr((BoolExpr)z3.MkApp(is_nil_decl, u), (BoolExpr)z3.MkApp(is_cons_decl, u)), true); + + /* occurs check u != cons(x,u) */ + prove2(z3.MkNot(z3.MkEq(u, l1)), true); + + /* destructors: is_cons(u) => u = cons(car(u),cdr(u)) */ + fml1 = z3.MkEq(u, mk_binary_app(cons_decl, mk_unary_app(car_decl, u), mk_unary_app(cdr_decl, u))); + fml = z3.MkImplies((BoolExpr)z3.MkApp(is_cons_decl, u), fml1); + Console.WriteLine("Formula {0}", fml); + prove2(fml, true); + + prove2(fml1, false); + + } + + + /*! + \brief Create a forest of trees. + + forest ::= nil | cons(tree, forest) + tree ::= nil | cons(forest, forest) + */ + + public void forest_example() + { + mk_context(); + Sort tree, forest; + FuncDecl nil1_decl, is_nil1_decl, cons1_decl, is_cons1_decl, car1_decl, cdr1_decl; + FuncDecl nil2_decl, is_nil2_decl, cons2_decl, is_cons2_decl, car2_decl, cdr2_decl; + Expr nil1, nil2, t1, t2, t3, t4, f1, f2, f3, l1, l2, x, y, u, v; + + // + // Declare the names of the accessors for cons. + // Then declare the sorts of the accessors. + // For this example, all sorts refer to the new types 'forest' and 'tree' + // being declared, so we pass in null for both sorts1 and sorts2. + // On the other hand, the sort_refs arrays contain the indices of the + // two new sorts being declared. The first element in sort1_refs + // points to 'tree', which has index 1, the second element in sort1_refs array + // points to 'forest', which has index 0. + // + Symbol[] head_tail1 = new Symbol[] { z3.MkSymbol("head"), z3.MkSymbol("tail") }; + Sort[] sorts1 = new Sort[] { null, null }; + uint[] sort1_refs = new uint[] { 1, 0 }; // the first item points to a tree, the second to a forest + + Symbol[] head_tail2 = new Symbol[] { z3.MkSymbol("car"), z3.MkSymbol("cdr") }; + Sort[] sorts2 = new Sort[] { null, null }; + uint[] sort2_refs = new uint[] { 0, 0 }; // both items point to the forest datatype. + Constructor nil1_con, cons1_con, nil2_con, cons2_con; + Constructor[] constructors1 = new Constructor[2], constructors2 = new Constructor[2]; + Symbol[] sort_names = { z3.MkSymbol("forest"), z3.MkSymbol("tree") }; + + Console.WriteLine("\nforest_example"); + + /* build a forest */ + nil1_con = z3.MkConstructor(z3.MkSymbol("nil"), z3.MkSymbol("is_nil"), null, null, null); + cons1_con = z3.MkConstructor(z3.MkSymbol("cons1"), z3.MkSymbol("is_cons1"), head_tail1, sorts1, sort1_refs); + constructors1[0] = nil1_con; + constructors1[1] = cons1_con; + + /* build a tree */ + nil2_con = z3.MkConstructor(z3.MkSymbol("nil2"), z3.MkSymbol("is_nil2"), null, null, null); + cons2_con = z3.MkConstructor(z3.MkSymbol("cons2"), z3.MkSymbol("is_cons2"), head_tail2, sorts2, sort2_refs); + constructors2[0] = nil2_con; + constructors2[1] = cons2_con; + + + Constructor[][] clists = new Constructor[][] { constructors1, constructors2 }; + + Sort[] sorts = z3.MkDatatypeSorts(sort_names, clists); + forest = sorts[0]; + tree = sorts[1]; + + // + // Now that the datatype has been created. + // Query the constructors for the constructor + // functions, testers, and field accessors. + // + nil1_decl = nil1_con.ConstructorDecl; + is_nil1_decl = nil1_con.TesterDecl; + cons1_decl = cons1_con.ConstructorDecl; + is_cons1_decl = cons1_con.TesterDecl; + FuncDecl[] cons1_accessors = cons1_con.AccessorDecls; + car1_decl = cons1_accessors[0]; + cdr1_decl = cons1_accessors[1]; + + nil2_decl = nil2_con.ConstructorDecl; + is_nil2_decl = nil2_con.TesterDecl; + cons2_decl = cons2_con.ConstructorDecl; + is_cons2_decl = cons2_con.TesterDecl; + FuncDecl[] cons2_accessors = cons2_con.AccessorDecls; + car2_decl = cons2_accessors[0]; + cdr2_decl = cons2_accessors[1]; + + + nil1 = z3.MkConst(nil1_decl); + nil2 = z3.MkConst(nil2_decl); + f1 = mk_binary_app(cons1_decl, nil2, nil1); + t1 = mk_binary_app(cons2_decl, nil1, nil1); + t2 = mk_binary_app(cons2_decl, f1, nil1); + t3 = mk_binary_app(cons2_decl, f1, f1); + t4 = mk_binary_app(cons2_decl, nil1, f1); + f2 = mk_binary_app(cons1_decl, t1, nil1); + f3 = mk_binary_app(cons1_decl, t1, f1); + + + /* nil != cons(nil,nil) */ + prove2(z3.MkNot(z3.MkEq(nil1, f1)), true); + prove2(z3.MkNot(z3.MkEq(nil2, t1)), true); + + + /* cons(x,u) = cons(x, v) => u = v */ + u = mk_var("u", forest); + v = mk_var("v", forest); + x = mk_var("x", tree); + y = mk_var("y", tree); + l1 = mk_binary_app(cons1_decl, x, u); + l2 = mk_binary_app(cons1_decl, y, v); + prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(u, v)), true); + prove2(z3.MkImplies(z3.MkEq(l1, l2), z3.MkEq(x, y)), true); + + /* is_nil(u) or is_cons(u) */ + prove2(z3.MkOr((BoolExpr)z3.MkApp(is_nil1_decl, u), + (BoolExpr)z3.MkApp(is_cons1_decl, u)), true); + + /* occurs check u != cons(x,u) */ + prove2(z3.MkNot(z3.MkEq(u, l1)), true); + } + + + /*! + \brief Demonstrate how to use #Eval. + */ + public void eval_example1() + { + Console.WriteLine("\neval_example1"); + mk_context(); + IntExpr x = mk_int_var("x"); + IntExpr y = mk_int_var("y"); + IntExpr two = mk_int(2); + + /* assert x < y */ + solver.Assert(z3.MkLt(x, y)); + + /* assert x > 2 */ + solver.Assert(z3.MkGt(x, two)); + + /* find model for the constraints above */ + Model model = null; + if (Status.SATISFIABLE == solver.Check()) + { + model = solver.Model; + Console.WriteLine("{0}", model); + Console.WriteLine("\nevaluating x+y"); + Expr v = model.Evaluate(z3.MkAdd(x, y)); + if (v != null) + { + Console.WriteLine("result = {0}", (v)); + } + else + { + Console.WriteLine("Failed to evaluate: x+y"); + } + } + else + { + Console.WriteLine("BUG, the constraints are satisfiable."); + } + } + + /*! + \brief Demonstrate how to use #Eval on tuples. + */ + public void eval_example2() + { + Console.WriteLine("\neval_example2"); + mk_context(); + Sort int_type = mk_int_type(); + TupleSort tuple = z3.MkTupleSort( + z3.MkSymbol("mk_tuple"), // name of tuple constructor + new Symbol[] { z3.MkSymbol("first"), z3.MkSymbol("second") }, // names of projection operators + new Sort[] { int_type, int_type } // types of projection operators + ); + FuncDecl first = tuple.FieldDecls[0]; // declarations are for projections + FuncDecl second = tuple.FieldDecls[1]; + Expr tup1 = z3.MkConst("t1", tuple); + Expr tup2 = z3.MkConst("t2", tuple); + /* assert tup1 != tup2 */ + solver.Assert(z3.MkNot(z3.MkEq(tup1, tup2))); + /* assert first tup1 = first tup2 */ + solver.Assert(z3.MkEq(z3.MkApp(first, tup1), z3.MkApp(first, tup2))); + + /* find model for the constraints above */ + Model model = null; + if (Status.SATISFIABLE == solver.Check()) + { + model = solver.Model; + Console.WriteLine("{0}",model); + Console.WriteLine("evaluating tup1 {0}", (model.Evaluate(tup1))); + Console.WriteLine("evaluating tup2 {0}", (model.Evaluate(tup2))); + Console.WriteLine("evaluating second(tup2) {0}", + (model.Evaluate(z3.MkApp(second, tup2)))); + } + else + { + Console.WriteLine("BUG, the constraints are satisfiable."); + } + } + + /*! + \brief Demonstrate how to use #Push and #Pop to control + the size of models. + + Note: this test is specialized to 32-bit bitvectors. + */ + public void check_small(BitVecExpr[] to_minimize) + { + + Sort bv32 = mk_bv_type(32); + + int num_Exprs = to_minimize.Length; + UInt32[] upper = new UInt32[num_Exprs]; + UInt32[] lower = new UInt32[num_Exprs]; + BitVecExpr[] values = new BitVecExpr[num_Exprs]; + for (int i = 0; i < upper.Length; ++i) + { + upper[i] = UInt32.MaxValue; + lower[i] = 0; + } + bool some_work = true; + int last_index = -1; + UInt32 last_upper = 0; + while (some_work) + { + solver.Push(); + + bool check_is_sat = true; + while (check_is_sat && some_work) + { + // Assert all feasible bounds. + for (int i = 0; i < num_Exprs; ++i) + { + solver.Assert(z3.MkBVULE(to_minimize[i], mk_bv32(upper[i]))); + } + + check_is_sat = Status.SATISFIABLE == solver.Check(); + if (!check_is_sat) + { + if (last_index != -1) + { + lower[last_index] = last_upper + 1; + } + break; + } + Console.WriteLine("{0}",solver.Model); + + // narrow the bounds based on the current model. + for (int i = 0; i < num_Exprs; ++i) + { + Expr v = solver.Model.Evaluate(to_minimize[i]); + UInt64 ui = ((BitVecNum)v).UInt64; + if (ui < upper[i]) + { + upper[i] = (UInt32)ui; + } + Console.WriteLine("{0} {1} {2}", i, lower[i], upper[i]); + } + + // find a new bound to add + some_work = false; + last_index = 0; + for (int i = 0; i < num_Exprs; ++i) + { + if (lower[i] < upper[i]) + { + last_upper = (upper[i] + lower[i]) / 2; + last_index = i; + solver.Assert(z3.MkBVULE(to_minimize[i], mk_bv32(last_upper))); + some_work = true; + break; + } + } + } + solver.Pop(); + } + } + + /*! + \brief Reduced-size model generation example. + */ + public void find_small_model_example() + { + mk_context(); + BitVecExpr x = mk_bv_var("x", 32); + BitVecExpr y = mk_bv_var("y", 32); + BitVecExpr z = mk_bv_var("z", 32); + solver.Assert(z3.MkBVULE(x, z3.MkBVAdd(y, z))); + check_small(new BitVecExpr[] { x, y, z }); + } + + /*! + \brief Simplifier example. + */ + public void simplifier_example() + { + mk_context(); + IntExpr x = mk_int_var("x"); + IntExpr y = mk_int_var("y"); + IntExpr z = mk_int_var("z"); + IntExpr u = mk_int_var("u"); + + Expr t1 = z3.MkAdd(x, z3.MkSub(y, z3.MkAdd(x, z))); + Expr t2 = t1.Simplify(); + Console.WriteLine("{0} -> {1}", (t1), (t2)); + } + + /*! + \brief Extract unsatisfiable core example + */ + public void unsat_core_and_proof_example() + { + if (this.z3 != null) + { + this.z3.Dispose(); + } + Dictionary cfg = new Dictionary() { + { "PROOF_MODE", "2" } }; + this.z3 = new Context(cfg); + this.solver = z3.MkSolver(); + + BoolExpr pa = mk_bool_var("PredA"); + BoolExpr pb = mk_bool_var("PredB"); + BoolExpr pc = mk_bool_var("PredC"); + BoolExpr pd = mk_bool_var("PredD"); + BoolExpr p1 = mk_bool_var("P1"); + BoolExpr p2 = mk_bool_var("P2"); + BoolExpr p3 = mk_bool_var("P3"); + BoolExpr p4 = mk_bool_var("P4"); + BoolExpr[] assumptions = new BoolExpr[] { z3.MkNot(p1), z3.MkNot(p2), z3.MkNot(p3), z3.MkNot(p4) }; + BoolExpr f1 = z3.MkAnd(new BoolExpr[] { pa, pb, pc }); + BoolExpr f2 = z3.MkAnd(new BoolExpr[] { pa, z3.MkNot(pb), pc }); + BoolExpr f3 = z3.MkOr(z3.MkNot(pa), z3.MkNot(pc)); + BoolExpr f4 = pd; + + solver.Assert(z3.MkOr(f1, p1)); + solver.Assert(z3.MkOr(f2, p2)); + solver.Assert(z3.MkOr(f3, p3)); + solver.Assert(z3.MkOr(f4, p4)); + Status result = solver.Check(assumptions); + + if (result == Status.UNSATISFIABLE) + { + Console.WriteLine("unsat"); + Console.WriteLine("proof: {0}", solver.Proof); + foreach (Expr c in solver.UnsatCore) + { + Console.WriteLine("{0}", c); + } + } + } + + + // CMW: get_implied_equalities is deprecated. + + ///*! + // \brief Extract implied equalities. + //*/ +#if false + public void get_implied_equalities_example() { + if (this.z3 != null) + { + this.z3.Dispose(); + } + Config p = new Config(); + p.SetParam("ARITH_EQ_BOUNDS","true"); + this.z3 = new Context(p); + + Sort int_sort = z3.MkIntSort(); + Expr a = mk_int_var("a"); + Expr b = mk_int_var("b"); + Expr c = mk_int_var("c"); + Expr d = mk_int_var("d"); + FuncDecl f = z3.MkFuncDecl("f", int_sort, int_sort); + Expr fa = z3.MkApp(f,a); + Expr fb = z3.MkApp(f,b); + Expr fc = z3.MkApp(f,c); + Expr[] Exprs = new Expr[]{ a, b, c, d, fa, fb, fc }; + uint[] class_ids; + + solver.Assert(z3.MkEq(a, b)); + solver.Assert(z3.MkEq(b, c)); + solver.Assert(z3.MkLe((ArithExpr)fc, (ArithExpr)a)); + solver.Assert(z3.MkLe((ArithExpr)b, (ArithExpr)fb)); + int num_Exprs = Exprs.Length; + + z3.GetImpliedEqualities(Exprs, out class_ids); + for (int i = 0; i < num_Exprs; ++i) { + Console.WriteLine("Class {0} |-> {1}", Exprs[i], class_ids[i]); + } + } +#endif + + static void Main() + { + Log.Open("z3.log"); + TestManaged test = new TestManaged(); + Log.Append("mk_quantifier"); + test.mk_quantifier(); + Log.Append("simple_example"); + test.simple_example(); + Log.Append("find_model_example1"); + test.find_model_example1(); + Log.Append("find_model_example2"); + test.find_model_example2(); + Log.Append("prove_example1"); + test.prove_example1(); + Log.Append("prove_example2"); + test.prove_example2(); + Log.Append("push_pop_example1"); + test.push_pop_example1(); + Log.Append("quantifier_example1"); + test.quantifier_example1(); + Log.Append("quantifier_example1_abs"); + test.quantifier_example1_abs(); + Log.Append("array_example1"); + test.array_example1(); + Log.Append("array_example2"); + test.array_example2(); + Log.Append("tuple_example"); + test.tuple_example(); + Log.Append("bitvector_example1"); + test.bitvector_example1(); + Log.Append("bitvector_example2"); + test.bitvector_example2(); + Log.Append("parser_example1"); + test.parser_example1(); + Log.Append("parser_example2"); + test.parser_example2(); + Log.Append("parser_example3"); + test.parser_example3(); + Log.Append("parser_example4"); + test.parser_example4(); + Log.Append("parser_example5"); + test.parser_example5(); + Log.Append("ite_example"); + test.ite_example(); + Log.Append("enum_example"); + test.enum_example(); + Log.Append("list_example"); + test.list_example(); + Log.Append("tree_example"); + test.tree_example(); + Log.Append("forest_example"); + test.forest_example(); + Log.Append("eval_example1"); + test.eval_example1(); + Log.Append("eval_example2"); + test.eval_example2(); + Log.Append("find_small_model_example"); + test.find_small_model_example(); + Log.Append("simplifier_example"); + test.simplifier_example(); + Log.Append("unsat_core_and_proof_example"); + test.unsat_core_and_proof_example(); + + // CMW: these are deprecated. + //Log.Append("get_implied_equalities_example"); + //test.get_implied_equalities_example(); + + test.z3.Dispose(); + } +} + +/*@}*/ + + + + + + diff --git a/test_managed/test_managed.csproj b/test_managed/test_managed.csproj new file mode 100644 index 000000000..87061d7ae --- /dev/null +++ b/test_managed/test_managed.csproj @@ -0,0 +1,71 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {B408E4BF-338D-446D-8D28-0DAB9BE91182} + Exe + Properties + test_managed + test_managed + v4.0 + Client + 512 + + + x86 + true + full + false + ..\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + ..\Release\ + TRACE + prompt + 4 + + + x64 + ..\x64\Debug\ + + + x64 + ..\x64\Release\ + + + + + + + + + + + + + + + + + {EC3DB697-B734-42F7-9468-5B62821EEB5A} + Microsoft.Z3 + + + + + \ No newline at end of file diff --git a/update-version.sh b/update-version.sh new file mode 100644 index 000000000..151fad6b9 --- /dev/null +++ b/update-version.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# +# Update Z3 version +# + +if [ $# -ne 1 ]; then + echo "Usage: update-version.sh MAJOR.MINOR.BUILD.REVISION" +fi + +sd edit lib/version.h +sd edit release.cmd +sd edit shell/shell.rc +sd edit dll/dll.rc +sd edit shell/main.cpp +sd edit Z3Inspector/Properties/AssemblyInfo.cs +sd edit Microsoft.Z3/Properties/AssemblyInfo.cs +sd edit Microsoft.Z3V3/AssemblyInfo.cpp + +scripts/perl scripts/update-version.pl "$1" diff --git a/update_api.cmd b/update_api.cmd new file mode 100644 index 000000000..d6d498d1b --- /dev/null +++ b/update_api.cmd @@ -0,0 +1,30 @@ +sd edit dll\z3.def +sd edit dll\z3_dbg.def +cd dll +python mk_def.py +cd .. +sd edit Microsoft.Z3\native.cs +sd edit Microsoft.Z3\enumerations.cs +sd edit lib\api_log_macros.h +sd edit lib\api_log_macros.cpp +sd edit lib\api_commands.cpp +sd edit python\z3core.py +sd edit ml\z3.mli +sd edit ml\z3.ml +sd edit ml\z3_stubs.c +pushd lib +python api.py +popd +pushd Microsoft.Z3 +python mk_z3consts.py +popd +pushd python +sd edit z3consts.py +python mk_z3consts.py +sd edit z3tactics.py +python mk_z3tactics.py +popd +pushd ml +call build.cmd 32 +popd +sd revert -a ... \ No newline at end of file diff --git a/update_api.txt b/update_api.txt new file mode 100644 index 000000000..fe4dee8d6 --- /dev/null +++ b/update_api.txt @@ -0,0 +1,26 @@ +Instructions for updating external Z3 API +----------------------------------------- + +1) Add the new function to the file lib\z3_api.h +2) If the function requires logging, then add its definition to lib\api.py. +Each definition is a call to the API function in this python script. +This function has the following signature: +API(function name, return type, argument list) +The return type only needs to be specified if the function returns a Z3 object. +The file lib\api.py contains many examples. +3) Execute update_api.cmd +This script updates the .def files in the directory dll, and generates the API logging macros. + +If one only wants to generate the logging macros. Then it only needs to execute +cd lib +python api.py + +The script api.py generates the following files: +lib\z3_api_log.h: macros and function definitions for logging API invocations. +lib\z3_api_log.cpp +lib\z3_api_commands.cpp: bindings for z3_replayer.cpp (log interpreter) + + + + + diff --git a/z3-prover.sln b/z3-prover.sln new file mode 100644 index 000000000..48d2b1169 --- /dev/null +++ b/z3-prover.sln @@ -0,0 +1,1331 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{012E9D8D-46CF-4536-9F34-7260C08C1E3C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib", "lib\lib.vcxproj", "{4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shell", "shell\shell.vcxproj", "{BF547582-F16D-4BE5-B9AB-8B6A9364B447}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcxproj", "{21A10ECD-32E2-4F27-A03D-81D855A048CC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_capi", "test_capi\test_capi.vcxproj", "{9E76526D-EDA2-4B88-9616-A8FC08F31071}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dll", "dll\dll.vcxproj", "{0BF8CB94-61C7-4545-AE55-C58D858AA8B6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Z3V3", "Microsoft.Z3V3\Microsoft.Z3V3.vcxproj", "{F008F2C4-D652-4A58-8DEF-DB83E2355454}" + ProjectSection(ProjectDependencies) = postProject + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6} = {0BF8CB94-61C7-4545-AE55-C58D858AA8B6} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "maxsat", "maxsat\maxsat.vcxproj", "{7C154132-AAAB-4F60-B652-F8C51A63D244}" + ProjectSection(ProjectDependencies) = postProject + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E} = {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E} + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6} = {0BF8CB94-61C7-4545-AE55-C58D858AA8B6} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Z3", "Microsoft.Z3\Microsoft.Z3.csproj", "{EC3DB697-B734-42F7-9468-5B62821EEB5A}" + ProjectSection(ProjectDependencies) = postProject + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6} = {0BF8CB94-61C7-4545-AE55-C58D858AA8B6} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test_managed", "test_managed\test_managed.csproj", "{B408E4BF-338D-446D-8D28-0DAB9BE91182}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + commercial|Any CPU = commercial|Any CPU + commercial|Mixed Platforms = commercial|Mixed Platforms + commercial|Win32 = commercial|Win32 + commercial|x64 = commercial|x64 + commercial|x86 = commercial|x86 + debug_opt|Any CPU = debug_opt|Any CPU + debug_opt|Mixed Platforms = debug_opt|Mixed Platforms + debug_opt|Win32 = debug_opt|Win32 + debug_opt|x64 = debug_opt|x64 + debug_opt|x86 = debug_opt|x86 + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + external_64|Any CPU = external_64|Any CPU + external_64|Mixed Platforms = external_64|Mixed Platforms + external_64|Win32 = external_64|Win32 + external_64|x64 = external_64|x64 + external_64|x86 = external_64|x86 + external_dbg|Any CPU = external_dbg|Any CPU + external_dbg|Mixed Platforms = external_dbg|Mixed Platforms + external_dbg|Win32 = external_dbg|Win32 + external_dbg|x64 = external_dbg|x64 + external_dbg|x86 = external_dbg|x86 + external_parallel|Any CPU = external_parallel|Any CPU + external_parallel|Mixed Platforms = external_parallel|Mixed Platforms + external_parallel|Win32 = external_parallel|Win32 + external_parallel|x64 = external_parallel|x64 + external_parallel|x86 = external_parallel|x86 + external|Any CPU = external|Any CPU + external|Mixed Platforms = external|Mixed Platforms + external|Win32 = external|Win32 + external|x64 = external|x64 + external|x86 = external|x86 + mpi_debug|Any CPU = mpi_debug|Any CPU + mpi_debug|Mixed Platforms = mpi_debug|Mixed Platforms + mpi_debug|Win32 = mpi_debug|Win32 + mpi_debug|x64 = mpi_debug|x64 + mpi_debug|x86 = mpi_debug|x86 + mpi_release|Any CPU = mpi_release|Any CPU + mpi_release|Mixed Platforms = mpi_release|Mixed Platforms + mpi_release|Win32 = mpi_release|Win32 + mpi_release|x64 = mpi_release|x64 + mpi_release|x86 = mpi_release|x86 + parallel_debug|Any CPU = parallel_debug|Any CPU + parallel_debug|Mixed Platforms = parallel_debug|Mixed Platforms + parallel_debug|Win32 = parallel_debug|Win32 + parallel_debug|x64 = parallel_debug|x64 + parallel_debug|x86 = parallel_debug|x86 + parallel_release|Any CPU = parallel_release|Any CPU + parallel_release|Mixed Platforms = parallel_release|Mixed Platforms + parallel_release|Win32 = parallel_release|Win32 + parallel_release|x64 = parallel_release|x64 + parallel_release|x86 = parallel_release|x86 + Release_delaysign|Any CPU = Release_delaysign|Any CPU + Release_delaysign|Mixed Platforms = Release_delaysign|Mixed Platforms + Release_delaysign|Win32 = Release_delaysign|Win32 + Release_delaysign|x64 = Release_delaysign|x64 + Release_delaysign|x86 = Release_delaysign|x86 + release_mt|Any CPU = release_mt|Any CPU + release_mt|Mixed Platforms = release_mt|Mixed Platforms + release_mt|Win32 = release_mt|Win32 + release_mt|x64 = release_mt|x64 + release_mt|x86 = release_mt|x86 + release_static|Any CPU = release_static|Any CPU + release_static|Mixed Platforms = release_static|Mixed Platforms + release_static|Win32 = release_static|Win32 + release_static|x64 = release_static|x64 + release_static|x86 = release_static|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + ReleaseD|Any CPU = ReleaseD|Any CPU + ReleaseD|Mixed Platforms = ReleaseD|Mixed Platforms + ReleaseD|Win32 = ReleaseD|Win32 + ReleaseD|x64 = ReleaseD|x64 + ReleaseD|x86 = ReleaseD|x86 + ReleaseShellOnly|Any CPU = ReleaseShellOnly|Any CPU + ReleaseShellOnly|Mixed Platforms = ReleaseShellOnly|Mixed Platforms + ReleaseShellOnly|Win32 = ReleaseShellOnly|Win32 + ReleaseShellOnly|x64 = ReleaseShellOnly|x64 + ReleaseShellOnly|x86 = ReleaseShellOnly|x86 + Setup|Any CPU = Setup|Any CPU + Setup|Mixed Platforms = Setup|Mixed Platforms + Setup|Win32 = Setup|Win32 + Setup|x64 = Setup|x64 + Setup|x86 = Setup|x86 + Trace|Any CPU = Trace|Any CPU + Trace|Mixed Platforms = Trace|Mixed Platforms + Trace|Win32 = Trace|Win32 + Trace|x64 = Trace|x64 + Trace|x86 = Trace|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.commercial|Any CPU.ActiveCfg = commercial|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.commercial|Mixed Platforms.ActiveCfg = commercial|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.commercial|Mixed Platforms.Build.0 = commercial|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.commercial|Win32.ActiveCfg = commercial|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.commercial|Win32.Build.0 = commercial|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.commercial|x64.ActiveCfg = commercial|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.commercial|x64.Build.0 = commercial|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.commercial|x86.ActiveCfg = commercial|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.debug_opt|Any CPU.ActiveCfg = debug_opt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.debug_opt|Mixed Platforms.ActiveCfg = debug_opt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.debug_opt|Mixed Platforms.Build.0 = debug_opt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.debug_opt|Win32.ActiveCfg = debug_opt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.debug_opt|Win32.Build.0 = debug_opt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.debug_opt|x64.ActiveCfg = debug_opt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.debug_opt|x86.ActiveCfg = debug_opt|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|Any CPU.Build.0 = Debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|Win32.ActiveCfg = Debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|Win32.Build.0 = Debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|x64.ActiveCfg = Debug|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|x64.Build.0 = Debug|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Debug|x86.ActiveCfg = Debug|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_64|Any CPU.ActiveCfg = external_64|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_64|Mixed Platforms.ActiveCfg = external_64|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_64|Mixed Platforms.Build.0 = external_64|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_64|Win32.ActiveCfg = external_64|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_64|x64.ActiveCfg = external_64|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_64|x64.Build.0 = external_64|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_64|x86.ActiveCfg = external_64|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_dbg|Any CPU.ActiveCfg = external_dbg|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_dbg|Any CPU.Build.0 = external_dbg|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_dbg|Mixed Platforms.ActiveCfg = external_dbg|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_dbg|Mixed Platforms.Build.0 = external_dbg|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_dbg|Win32.ActiveCfg = external_dbg|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_dbg|Win32.Build.0 = external_dbg|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_dbg|x64.ActiveCfg = external_dbg|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_dbg|x86.ActiveCfg = external_dbg|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_parallel|Any CPU.ActiveCfg = external_parallel|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_parallel|Mixed Platforms.ActiveCfg = external_parallel|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_parallel|Mixed Platforms.Build.0 = external_parallel|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_parallel|Win32.ActiveCfg = external_parallel|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_parallel|Win32.Build.0 = external_parallel|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_parallel|x64.ActiveCfg = external_parallel|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_parallel|x64.Build.0 = external_parallel|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external_parallel|x86.ActiveCfg = external_parallel|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external|Any CPU.ActiveCfg = external|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external|Any CPU.Build.0 = external|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external|Mixed Platforms.ActiveCfg = external|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external|Mixed Platforms.Build.0 = external|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external|Win32.ActiveCfg = external|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external|Win32.Build.0 = external|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external|x64.ActiveCfg = external|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.external|x86.ActiveCfg = external|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_debug|Any CPU.ActiveCfg = mpi_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_debug|Mixed Platforms.ActiveCfg = mpi_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_debug|Mixed Platforms.Build.0 = mpi_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_debug|Win32.ActiveCfg = mpi_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_debug|Win32.Build.0 = mpi_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_debug|x64.ActiveCfg = mpi_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_debug|x86.ActiveCfg = mpi_debug|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_release|Any CPU.ActiveCfg = mpi_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_release|Mixed Platforms.ActiveCfg = mpi_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_release|Mixed Platforms.Build.0 = mpi_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_release|Win32.ActiveCfg = mpi_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_release|Win32.Build.0 = mpi_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_release|x64.ActiveCfg = mpi_release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_release|x64.Build.0 = mpi_release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.mpi_release|x86.ActiveCfg = mpi_release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_debug|Any CPU.ActiveCfg = parallel_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_debug|Mixed Platforms.ActiveCfg = parallel_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_debug|Mixed Platforms.Build.0 = parallel_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_debug|Win32.ActiveCfg = parallel_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_debug|Win32.Build.0 = parallel_debug|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_debug|x64.ActiveCfg = parallel_debug|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_debug|x64.Build.0 = parallel_debug|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_debug|x86.ActiveCfg = parallel_debug|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_release|Any CPU.ActiveCfg = parallel_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_release|Mixed Platforms.ActiveCfg = parallel_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_release|Mixed Platforms.Build.0 = parallel_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_release|Win32.ActiveCfg = parallel_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_release|Win32.Build.0 = parallel_release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_release|x64.ActiveCfg = parallel_release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_release|x64.Build.0 = parallel_release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.parallel_release|x86.ActiveCfg = parallel_release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release_delaysign|Any CPU.ActiveCfg = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release_delaysign|Mixed Platforms.ActiveCfg = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release_delaysign|Mixed Platforms.Build.0 = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release_delaysign|Win32.ActiveCfg = release_static|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release_delaysign|x64.ActiveCfg = Release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release_delaysign|x64.Build.0 = Release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release_delaysign|x86.ActiveCfg = release_static|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_mt|Any CPU.ActiveCfg = release_mt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_mt|Any CPU.Build.0 = release_mt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_mt|Mixed Platforms.ActiveCfg = release_mt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_mt|Mixed Platforms.Build.0 = release_mt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_mt|Win32.ActiveCfg = release_mt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_mt|Win32.Build.0 = release_mt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_mt|x64.ActiveCfg = release_mt|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_mt|x86.ActiveCfg = release_mt|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_static|Any CPU.ActiveCfg = release_static|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_static|Mixed Platforms.ActiveCfg = release_static|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_static|Mixed Platforms.Build.0 = release_static|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_static|Win32.ActiveCfg = release_static|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_static|Win32.Build.0 = release_static|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_static|x64.ActiveCfg = release_static|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_static|x64.Build.0 = release_static|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.release_static|x86.ActiveCfg = release_static|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|Any CPU.ActiveCfg = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|Any CPU.Build.0 = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|Mixed Platforms.Build.0 = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|Win32.ActiveCfg = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|Win32.Build.0 = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|x64.ActiveCfg = Release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|x64.Build.0 = Release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Release|x86.ActiveCfg = Release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseD|Any CPU.ActiveCfg = ReleaseD|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseD|Mixed Platforms.ActiveCfg = ReleaseD|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseD|Mixed Platforms.Build.0 = ReleaseD|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseD|Win32.ActiveCfg = ReleaseD|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseD|Win32.Build.0 = ReleaseD|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseD|x64.ActiveCfg = ReleaseD|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseD|x86.ActiveCfg = ReleaseD|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseShellOnly|Any CPU.ActiveCfg = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseShellOnly|Mixed Platforms.Build.0 = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseShellOnly|Win32.ActiveCfg = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseShellOnly|Win32.Build.0 = Release|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseShellOnly|x64.ActiveCfg = Release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseShellOnly|x64.Build.0 = Release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.ReleaseShellOnly|x86.ActiveCfg = Release|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Setup|Any CPU.ActiveCfg = smtcomp|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Setup|Mixed Platforms.ActiveCfg = smtcomp|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Setup|Mixed Platforms.Build.0 = smtcomp|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Setup|Win32.ActiveCfg = smtcomp|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Setup|x64.ActiveCfg = smtcomp|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Setup|x64.Build.0 = smtcomp|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Setup|x86.ActiveCfg = smtcomp|x64 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Trace|Any CPU.ActiveCfg = Trace|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Trace|Mixed Platforms.ActiveCfg = Trace|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Trace|Mixed Platforms.Build.0 = Trace|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Trace|Win32.ActiveCfg = Trace|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Trace|Win32.Build.0 = Trace|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Trace|x64.ActiveCfg = Trace|Win32 + {4A7E5A93-19D8-4382-8950-FB2EDEC7A76E}.Trace|x86.ActiveCfg = Trace|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.commercial|Any CPU.ActiveCfg = commercial|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.commercial|Mixed Platforms.ActiveCfg = commercial|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.commercial|Mixed Platforms.Build.0 = commercial|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.commercial|Win32.ActiveCfg = commercial|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.commercial|Win32.Build.0 = commercial|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.commercial|x64.ActiveCfg = commercial|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.commercial|x64.Build.0 = commercial|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.commercial|x86.ActiveCfg = commercial|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.debug_opt|Any CPU.ActiveCfg = debug_opt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.debug_opt|Mixed Platforms.ActiveCfg = debug_opt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.debug_opt|Mixed Platforms.Build.0 = debug_opt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.debug_opt|Win32.ActiveCfg = debug_opt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.debug_opt|Win32.Build.0 = debug_opt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.debug_opt|x64.ActiveCfg = debug_opt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.debug_opt|x86.ActiveCfg = debug_opt|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|Any CPU.Build.0 = Debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|Win32.ActiveCfg = Debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|Win32.Build.0 = Debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|x64.ActiveCfg = Debug|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|x64.Build.0 = Debug|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Debug|x86.ActiveCfg = Debug|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_64|Any CPU.ActiveCfg = external_64|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_64|Mixed Platforms.ActiveCfg = external_64|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_64|Mixed Platforms.Build.0 = external_64|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_64|Win32.ActiveCfg = external_64|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_64|x64.ActiveCfg = external_64|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_64|x64.Build.0 = external_64|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_64|x86.ActiveCfg = external_64|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_dbg|Any CPU.ActiveCfg = external_dbg|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_dbg|Mixed Platforms.ActiveCfg = external_dbg|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_dbg|Mixed Platforms.Build.0 = external_dbg|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_dbg|Win32.ActiveCfg = external_dbg|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_dbg|Win32.Build.0 = external_dbg|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_dbg|x64.ActiveCfg = external_dbg|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_dbg|x86.ActiveCfg = external_dbg|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_parallel|Any CPU.ActiveCfg = external_parallel|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_parallel|Mixed Platforms.ActiveCfg = external_parallel|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_parallel|Mixed Platforms.Build.0 = external_parallel|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_parallel|Win32.ActiveCfg = external_parallel|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_parallel|Win32.Build.0 = external_parallel|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_parallel|x64.ActiveCfg = external_parallel|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_parallel|x64.Build.0 = external_parallel|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external_parallel|x86.ActiveCfg = external_parallel|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external|Any CPU.ActiveCfg = external|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external|Any CPU.Build.0 = external|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external|Mixed Platforms.ActiveCfg = external|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external|Mixed Platforms.Build.0 = external|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external|Win32.ActiveCfg = external|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external|Win32.Build.0 = external|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external|x64.ActiveCfg = external|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.external|x86.ActiveCfg = external|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_debug|Any CPU.ActiveCfg = mpi_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_debug|Mixed Platforms.ActiveCfg = mpi_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_debug|Mixed Platforms.Build.0 = mpi_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_debug|Win32.ActiveCfg = mpi_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_debug|Win32.Build.0 = mpi_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_debug|x64.ActiveCfg = mpi_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_debug|x86.ActiveCfg = mpi_debug|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_release|Any CPU.ActiveCfg = mpi_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_release|Mixed Platforms.ActiveCfg = mpi_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_release|Mixed Platforms.Build.0 = mpi_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_release|Win32.ActiveCfg = mpi_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_release|Win32.Build.0 = mpi_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_release|x64.ActiveCfg = mpi_release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_release|x64.Build.0 = mpi_release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.mpi_release|x86.ActiveCfg = mpi_release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_debug|Any CPU.ActiveCfg = parallel_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_debug|Mixed Platforms.ActiveCfg = parallel_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_debug|Mixed Platforms.Build.0 = parallel_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_debug|Win32.ActiveCfg = parallel_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_debug|Win32.Build.0 = parallel_debug|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_debug|x64.ActiveCfg = parallel_debug|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_debug|x64.Build.0 = parallel_debug|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_debug|x86.ActiveCfg = parallel_debug|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_release|Any CPU.ActiveCfg = parallel_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_release|Mixed Platforms.ActiveCfg = parallel_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_release|Mixed Platforms.Build.0 = parallel_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_release|Win32.ActiveCfg = parallel_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_release|Win32.Build.0 = parallel_release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_release|x64.ActiveCfg = parallel_release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_release|x64.Build.0 = parallel_release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.parallel_release|x86.ActiveCfg = parallel_release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release_delaysign|Any CPU.ActiveCfg = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release_delaysign|Mixed Platforms.ActiveCfg = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release_delaysign|Mixed Platforms.Build.0 = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release_delaysign|Win32.ActiveCfg = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release_delaysign|x64.ActiveCfg = Release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release_delaysign|x64.Build.0 = Release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release_delaysign|x86.ActiveCfg = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_mt|Any CPU.ActiveCfg = release_mt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_mt|Any CPU.Build.0 = release_mt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_mt|Mixed Platforms.ActiveCfg = release_mt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_mt|Mixed Platforms.Build.0 = release_mt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_mt|Win32.ActiveCfg = release_mt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_mt|Win32.Build.0 = release_mt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_mt|x64.ActiveCfg = release_mt|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_mt|x86.ActiveCfg = release_mt|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_static|Any CPU.ActiveCfg = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_static|Mixed Platforms.ActiveCfg = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_static|Mixed Platforms.Build.0 = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_static|Win32.ActiveCfg = release_static|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_static|Win32.Build.0 = release_static|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_static|x64.ActiveCfg = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_static|x64.Build.0 = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.release_static|x86.ActiveCfg = release_static|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|Any CPU.ActiveCfg = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|Any CPU.Build.0 = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|Mixed Platforms.Build.0 = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|Win32.ActiveCfg = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|Win32.Build.0 = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|x64.ActiveCfg = Release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|x64.Build.0 = Release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Release|x86.ActiveCfg = Release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseD|Any CPU.ActiveCfg = ReleaseD|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseD|Mixed Platforms.ActiveCfg = ReleaseD|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseD|Mixed Platforms.Build.0 = ReleaseD|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseD|Win32.ActiveCfg = ReleaseD|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseD|Win32.Build.0 = ReleaseD|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseD|x64.ActiveCfg = ReleaseD|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseD|x86.ActiveCfg = ReleaseD|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseShellOnly|Any CPU.ActiveCfg = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseShellOnly|Mixed Platforms.Build.0 = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseShellOnly|Win32.ActiveCfg = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseShellOnly|Win32.Build.0 = Release|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseShellOnly|x64.ActiveCfg = Release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseShellOnly|x64.Build.0 = Release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.ReleaseShellOnly|x86.ActiveCfg = Release|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Setup|Any CPU.ActiveCfg = smtcomp|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Setup|Mixed Platforms.ActiveCfg = smtcomp|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Setup|Mixed Platforms.Build.0 = smtcomp|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Setup|Win32.ActiveCfg = smtcomp|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Setup|x64.ActiveCfg = smtcomp|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Setup|x64.Build.0 = smtcomp|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Setup|x86.ActiveCfg = smtcomp|x64 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Trace|Any CPU.ActiveCfg = Trace|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Trace|Mixed Platforms.ActiveCfg = Trace|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Trace|Mixed Platforms.Build.0 = Trace|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Trace|Win32.ActiveCfg = Trace|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Trace|Win32.Build.0 = Trace|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Trace|x64.ActiveCfg = Trace|Win32 + {BF547582-F16D-4BE5-B9AB-8B6A9364B447}.Trace|x86.ActiveCfg = Trace|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.commercial|Any CPU.ActiveCfg = commercial|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.commercial|Mixed Platforms.ActiveCfg = commercial|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.commercial|Win32.ActiveCfg = commercial|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.commercial|x64.ActiveCfg = commercial|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.commercial|x86.ActiveCfg = commercial|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.debug_opt|Any CPU.ActiveCfg = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.debug_opt|Mixed Platforms.ActiveCfg = debug_opt|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.debug_opt|Mixed Platforms.Build.0 = debug_opt|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.debug_opt|Win32.ActiveCfg = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.debug_opt|x64.ActiveCfg = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.debug_opt|x86.ActiveCfg = debug_opt|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|Any CPU.Build.0 = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|Win32.ActiveCfg = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|Win32.Build.0 = Debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|x64.ActiveCfg = Debug|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|x64.Build.0 = Debug|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Debug|x86.ActiveCfg = Debug|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_64|Any CPU.ActiveCfg = external_64|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_64|Mixed Platforms.ActiveCfg = external_64|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_64|Mixed Platforms.Build.0 = external_64|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_64|Win32.ActiveCfg = external_64|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_64|x64.ActiveCfg = external_64|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_64|x86.ActiveCfg = external_64|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_dbg|Any CPU.ActiveCfg = external_dbg|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_dbg|Mixed Platforms.ActiveCfg = external_dbg|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_dbg|Win32.ActiveCfg = external_dbg|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_dbg|x64.ActiveCfg = external_dbg|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_dbg|x86.ActiveCfg = external_dbg|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_parallel|Any CPU.ActiveCfg = external_parallel|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_parallel|Mixed Platforms.ActiveCfg = external_parallel|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_parallel|Mixed Platforms.Build.0 = external_parallel|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_parallel|Win32.ActiveCfg = external_parallel|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_parallel|x64.ActiveCfg = external_parallel|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external_parallel|x86.ActiveCfg = external_parallel|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external|Any CPU.ActiveCfg = external|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external|Mixed Platforms.ActiveCfg = external|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external|Win32.ActiveCfg = external|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external|x64.ActiveCfg = external|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.external|x86.ActiveCfg = external|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_debug|Any CPU.ActiveCfg = mpi_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_debug|Mixed Platforms.ActiveCfg = mpi_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_debug|Win32.ActiveCfg = mpi_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_debug|x64.ActiveCfg = mpi_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_debug|x86.ActiveCfg = mpi_debug|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_release|Any CPU.ActiveCfg = mpi_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_release|Mixed Platforms.ActiveCfg = mpi_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_release|Win32.ActiveCfg = mpi_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_release|x64.ActiveCfg = mpi_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.mpi_release|x86.ActiveCfg = mpi_release|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_debug|Any CPU.ActiveCfg = parallel_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_debug|Mixed Platforms.ActiveCfg = parallel_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_debug|Mixed Platforms.Build.0 = parallel_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_debug|Win32.ActiveCfg = parallel_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_debug|Win32.Build.0 = parallel_debug|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_debug|x64.ActiveCfg = parallel_debug|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_debug|x64.Build.0 = parallel_debug|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_debug|x86.ActiveCfg = parallel_debug|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_release|Any CPU.ActiveCfg = parallel_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_release|Mixed Platforms.ActiveCfg = parallel_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_release|Mixed Platforms.Build.0 = parallel_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_release|Win32.ActiveCfg = parallel_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_release|Win32.Build.0 = parallel_release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_release|x64.ActiveCfg = parallel_release|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_release|x64.Build.0 = parallel_release|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.parallel_release|x86.ActiveCfg = parallel_release|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release_delaysign|Any CPU.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release_delaysign|Mixed Platforms.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release_delaysign|Win32.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release_delaysign|x64.ActiveCfg = release_delaysign|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release_delaysign|x86.ActiveCfg = release_delaysign|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_mt|Any CPU.ActiveCfg = release_mt|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_mt|Mixed Platforms.ActiveCfg = release_mt|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_mt|Win32.ActiveCfg = release_mt|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_mt|x64.ActiveCfg = release_mt|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_mt|x86.ActiveCfg = release_mt|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_static|Any CPU.ActiveCfg = release_static|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_static|Mixed Platforms.ActiveCfg = release_static|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_static|Win32.ActiveCfg = release_static|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_static|x64.ActiveCfg = release_static|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.release_static|x86.ActiveCfg = release_static|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release|Any CPU.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release|Mixed Platforms.Build.0 = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release|Win32.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release|Win32.Build.0 = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release|x64.ActiveCfg = Release|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release|x64.Build.0 = Release|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Release|x86.ActiveCfg = Release|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseD|Any CPU.ActiveCfg = ReleaseD|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseD|Mixed Platforms.ActiveCfg = ReleaseD|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseD|Win32.ActiveCfg = ReleaseD|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseD|Win32.Build.0 = ReleaseD|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseD|x64.ActiveCfg = ReleaseD|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseD|x86.ActiveCfg = ReleaseD|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseShellOnly|Any CPU.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseShellOnly|Win32.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseShellOnly|Win32.Build.0 = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseShellOnly|x64.ActiveCfg = Release|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.ReleaseShellOnly|x86.ActiveCfg = Release|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Setup|Any CPU.ActiveCfg = smtcomp|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Setup|Mixed Platforms.ActiveCfg = smtcomp|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Setup|Mixed Platforms.Build.0 = smtcomp|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Setup|Win32.ActiveCfg = smtcomp|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Setup|x64.ActiveCfg = smtcomp|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Setup|x64.Build.0 = smtcomp|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Setup|x86.ActiveCfg = smtcomp|x64 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Trace|Any CPU.ActiveCfg = Trace|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Trace|Mixed Platforms.ActiveCfg = Trace|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Trace|Mixed Platforms.Build.0 = Trace|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Trace|Win32.ActiveCfg = Trace|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Trace|Win32.Build.0 = Trace|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Trace|x64.ActiveCfg = Trace|Win32 + {21A10ECD-32E2-4F27-A03D-81D855A048CC}.Trace|x86.ActiveCfg = Trace|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.commercial|Any CPU.ActiveCfg = commercial|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.commercial|Mixed Platforms.ActiveCfg = commercial|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.commercial|Win32.ActiveCfg = commercial|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.commercial|x64.ActiveCfg = commercial|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.commercial|x86.ActiveCfg = commercial|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.debug_opt|Any CPU.ActiveCfg = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.debug_opt|Mixed Platforms.ActiveCfg = debug_opt|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.debug_opt|Win32.ActiveCfg = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.debug_opt|Win32.Build.0 = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.debug_opt|x64.ActiveCfg = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.debug_opt|x86.ActiveCfg = debug_opt|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Debug|Win32.Build.0 = Debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Debug|x64.ActiveCfg = Debug|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Debug|x64.Build.0 = Debug|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Debug|x86.ActiveCfg = Debug|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_64|Any CPU.ActiveCfg = external_64|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_64|Mixed Platforms.ActiveCfg = external_64|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_64|Mixed Platforms.Build.0 = external_64|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_64|Win32.ActiveCfg = external_64|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_64|x64.ActiveCfg = external_64|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_64|x86.ActiveCfg = external_64|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_dbg|Any CPU.ActiveCfg = external_dbg|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_dbg|Mixed Platforms.ActiveCfg = external_dbg|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_dbg|Win32.ActiveCfg = external_dbg|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_dbg|Win32.Build.0 = external_dbg|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_dbg|x64.ActiveCfg = external_dbg|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_dbg|x86.ActiveCfg = external_dbg|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_parallel|Any CPU.ActiveCfg = external_parallel|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_parallel|Mixed Platforms.ActiveCfg = external_parallel|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_parallel|Mixed Platforms.Build.0 = external_parallel|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_parallel|Win32.ActiveCfg = external_parallel|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_parallel|x64.ActiveCfg = external_parallel|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external_parallel|x86.ActiveCfg = external_parallel|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external|Any CPU.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external|Mixed Platforms.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external|Win32.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external|x64.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.external|x86.ActiveCfg = external_parallel|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_debug|Any CPU.ActiveCfg = mpi_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_debug|Mixed Platforms.ActiveCfg = mpi_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_debug|Win32.ActiveCfg = mpi_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_debug|x64.ActiveCfg = mpi_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_debug|x86.ActiveCfg = mpi_debug|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_release|Any CPU.ActiveCfg = mpi_release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_release|Mixed Platforms.ActiveCfg = mpi_release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_release|Win32.ActiveCfg = mpi_release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_release|x64.ActiveCfg = mpi_release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.mpi_release|x86.ActiveCfg = mpi_release|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_debug|Any CPU.ActiveCfg = parallel_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_debug|Mixed Platforms.ActiveCfg = parallel_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_debug|Win32.ActiveCfg = parallel_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_debug|Win32.Build.0 = parallel_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_debug|x64.ActiveCfg = parallel_debug|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_debug|x86.ActiveCfg = parallel_debug|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_release|Any CPU.ActiveCfg = parallel_release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_release|Mixed Platforms.ActiveCfg = parallel_release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_release|Win32.ActiveCfg = parallel_release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_release|x64.ActiveCfg = parallel_release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.parallel_release|x86.ActiveCfg = parallel_release|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release_delaysign|Any CPU.ActiveCfg = release_static|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release_delaysign|Mixed Platforms.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release_delaysign|Win32.ActiveCfg = release_static|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release_delaysign|x64.ActiveCfg = release_static|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release_delaysign|x86.ActiveCfg = release_static|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_mt|Any CPU.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_mt|Mixed Platforms.ActiveCfg = release_mt|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_mt|Win32.ActiveCfg = release_mt|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_mt|x64.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_mt|x86.ActiveCfg = release_mt|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_static|Any CPU.ActiveCfg = release_static|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_static|Mixed Platforms.ActiveCfg = release_static|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_static|Win32.ActiveCfg = release_static|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_static|x64.ActiveCfg = release_static|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.release_static|x86.ActiveCfg = release_static|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release|Any CPU.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release|Mixed Platforms.Build.0 = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release|Win32.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release|Win32.Build.0 = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release|x64.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Release|x86.ActiveCfg = Release|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseD|Any CPU.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseD|Mixed Platforms.ActiveCfg = ReleaseD|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseD|Win32.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseD|Win32.Build.0 = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseD|x64.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseD|x86.ActiveCfg = ReleaseD|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseShellOnly|Any CPU.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseShellOnly|Win32.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseShellOnly|Win32.Build.0 = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseShellOnly|x64.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.ReleaseShellOnly|x86.ActiveCfg = Release|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Setup|Any CPU.ActiveCfg = smtcomp|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Setup|Mixed Platforms.ActiveCfg = smtcomp|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Setup|Mixed Platforms.Build.0 = smtcomp|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Setup|Win32.ActiveCfg = smtcomp|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Setup|x64.ActiveCfg = smtcomp|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Setup|x64.Build.0 = smtcomp|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Setup|x86.ActiveCfg = smtcomp|x64 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Trace|Any CPU.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Trace|Mixed Platforms.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Trace|Win32.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Trace|x64.ActiveCfg = Release|Win32 + {9E76526D-EDA2-4B88-9616-A8FC08F31071}.Trace|x86.ActiveCfg = commercial|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.commercial|Any CPU.ActiveCfg = commercial|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.commercial|Mixed Platforms.ActiveCfg = commercial|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.commercial|Mixed Platforms.Build.0 = commercial|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.commercial|Win32.ActiveCfg = commercial|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.commercial|Win32.Build.0 = commercial|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.commercial|x64.ActiveCfg = commercial|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.commercial|x64.Build.0 = commercial|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.commercial|x86.ActiveCfg = commercial|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.debug_opt|Any CPU.ActiveCfg = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.debug_opt|Mixed Platforms.ActiveCfg = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.debug_opt|Win32.ActiveCfg = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.debug_opt|Win32.Build.0 = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.debug_opt|x64.ActiveCfg = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.debug_opt|x86.ActiveCfg = Debug|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|Any CPU.Build.0 = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|Win32.ActiveCfg = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|Win32.Build.0 = Debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|x64.ActiveCfg = Debug|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|x64.Build.0 = Debug|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Debug|x86.ActiveCfg = Debug|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_64|Any CPU.ActiveCfg = external_64|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_64|Mixed Platforms.ActiveCfg = external_64|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_64|Mixed Platforms.Build.0 = external_64|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_64|Win32.ActiveCfg = external_64|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_64|x64.ActiveCfg = external_64|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_64|x64.Build.0 = external_64|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_64|x86.ActiveCfg = external_64|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_dbg|Any CPU.ActiveCfg = external_dbg|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_dbg|Any CPU.Build.0 = external_dbg|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_dbg|Mixed Platforms.ActiveCfg = external_dbg|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_dbg|Mixed Platforms.Build.0 = external_dbg|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_dbg|Win32.ActiveCfg = external_dbg|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_dbg|Win32.Build.0 = external_dbg|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_dbg|x64.ActiveCfg = external_dbg|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_dbg|x86.ActiveCfg = external_dbg|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_parallel|Any CPU.ActiveCfg = external_parallel|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_parallel|Mixed Platforms.ActiveCfg = external_parallel|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_parallel|Mixed Platforms.Build.0 = external_parallel|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_parallel|Win32.ActiveCfg = external_parallel|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_parallel|Win32.Build.0 = external_parallel|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_parallel|x64.ActiveCfg = external_parallel|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_parallel|x64.Build.0 = external_parallel|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external_parallel|x86.ActiveCfg = external_parallel|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external|Any CPU.ActiveCfg = external|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external|Any CPU.Build.0 = external|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external|Mixed Platforms.ActiveCfg = external|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external|Mixed Platforms.Build.0 = external|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external|Win32.ActiveCfg = external|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external|Win32.Build.0 = external|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external|x64.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.external|x86.ActiveCfg = external|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_debug|Any CPU.ActiveCfg = mpi_debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_debug|Mixed Platforms.ActiveCfg = mpi_debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_debug|Win32.ActiveCfg = mpi_debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_debug|x64.ActiveCfg = mpi_debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_debug|x86.ActiveCfg = mpi_debug|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_release|Any CPU.ActiveCfg = mpi_release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_release|Mixed Platforms.ActiveCfg = mpi_release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_release|Win32.ActiveCfg = mpi_release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_release|Win32.Build.0 = mpi_release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_release|x64.ActiveCfg = mpi_release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_release|x64.Build.0 = mpi_release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.mpi_release|x86.ActiveCfg = mpi_release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_debug|Any CPU.ActiveCfg = parallel_debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_debug|Mixed Platforms.ActiveCfg = parallel_debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_debug|Win32.ActiveCfg = parallel_debug|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_debug|x64.ActiveCfg = parallel_debug|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_debug|x64.Build.0 = parallel_debug|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_debug|x86.ActiveCfg = parallel_debug|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_release|Any CPU.ActiveCfg = parallel_release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_release|Mixed Platforms.ActiveCfg = parallel_release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_release|Win32.ActiveCfg = parallel_release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_release|Win32.Build.0 = parallel_release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_release|x64.ActiveCfg = parallel_release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_release|x64.Build.0 = parallel_release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.parallel_release|x86.ActiveCfg = parallel_release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release_delaysign|Any CPU.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release_delaysign|Mixed Platforms.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release_delaysign|Win32.ActiveCfg = release_static|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release_delaysign|x64.ActiveCfg = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release_delaysign|x64.Build.0 = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release_delaysign|x86.ActiveCfg = release_static|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_mt|Any CPU.ActiveCfg = release_mt|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_mt|Any CPU.Build.0 = release_mt|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_mt|Mixed Platforms.ActiveCfg = release_mt|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_mt|Mixed Platforms.Build.0 = release_mt|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_mt|Win32.ActiveCfg = release_mt|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_mt|Win32.Build.0 = release_mt|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_mt|x64.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_mt|x86.ActiveCfg = release_mt|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_static|Any CPU.ActiveCfg = release_static|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_static|Mixed Platforms.ActiveCfg = release_static|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_static|Mixed Platforms.Build.0 = release_static|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_static|Win32.ActiveCfg = release_static|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_static|Win32.Build.0 = release_static|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_static|x64.ActiveCfg = release_static|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_static|x64.Build.0 = release_static|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.release_static|x86.ActiveCfg = release_static|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|Any CPU.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|Any CPU.Build.0 = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|Mixed Platforms.Build.0 = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|Win32.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|Win32.Build.0 = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|x64.ActiveCfg = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|x64.Build.0 = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Release|x86.ActiveCfg = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseD|Any CPU.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseD|Mixed Platforms.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseD|Win32.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseD|Win32.Build.0 = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseD|x64.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseD|x86.ActiveCfg = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseShellOnly|Any CPU.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseShellOnly|Win32.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseShellOnly|x64.ActiveCfg = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseShellOnly|x64.Build.0 = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.ReleaseShellOnly|x86.ActiveCfg = Release|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Setup|Any CPU.ActiveCfg = smtcomp|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Setup|Mixed Platforms.ActiveCfg = smtcomp|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Setup|Mixed Platforms.Build.0 = smtcomp|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Setup|Win32.ActiveCfg = smtcomp|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Setup|x64.ActiveCfg = smtcomp|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Setup|x64.Build.0 = smtcomp|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Setup|x86.ActiveCfg = smtcomp|x64 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Trace|Any CPU.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Trace|Mixed Platforms.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Trace|Win32.ActiveCfg = trace|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Trace|Win32.Build.0 = trace|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Trace|x64.ActiveCfg = Release|Win32 + {0BF8CB94-61C7-4545-AE55-C58D858AA8B6}.Trace|x86.ActiveCfg = trace|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.commercial|Any CPU.ActiveCfg = commercial|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.commercial|Mixed Platforms.ActiveCfg = commercial|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.commercial|Mixed Platforms.Build.0 = commercial|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.commercial|Win32.ActiveCfg = commercial|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.commercial|Win32.Build.0 = commercial|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.commercial|x64.ActiveCfg = commercial|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.commercial|x64.Build.0 = commercial|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.commercial|x86.ActiveCfg = commercial|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.debug_opt|Any CPU.ActiveCfg = debug_opt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.debug_opt|Mixed Platforms.ActiveCfg = debug_opt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.debug_opt|Mixed Platforms.Build.0 = debug_opt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.debug_opt|Win32.ActiveCfg = debug_opt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.debug_opt|Win32.Build.0 = debug_opt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.debug_opt|x64.ActiveCfg = debug_opt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.debug_opt|x86.ActiveCfg = debug_opt|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|Any CPU.Build.0 = Debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|Win32.ActiveCfg = Debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|Win32.Build.0 = Debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|x64.ActiveCfg = Debug|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|x64.Build.0 = Debug|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Debug|x86.ActiveCfg = Debug|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_64|Any CPU.ActiveCfg = external_64|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_64|Mixed Platforms.ActiveCfg = external_64|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_64|Mixed Platforms.Build.0 = external_64|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_64|Win32.ActiveCfg = external_64|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_64|Win32.Build.0 = external_64|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_64|x64.ActiveCfg = external_64|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_64|x64.Build.0 = external_64|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_64|x86.ActiveCfg = external_64|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_dbg|Any CPU.ActiveCfg = external_dbg|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_dbg|Mixed Platforms.ActiveCfg = external_dbg|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_dbg|Mixed Platforms.Build.0 = external_dbg|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_dbg|Win32.ActiveCfg = external_dbg|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_dbg|Win32.Build.0 = external_dbg|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_dbg|x64.ActiveCfg = external_dbg|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_dbg|x86.ActiveCfg = external_dbg|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_parallel|Any CPU.ActiveCfg = external_parallel|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_parallel|Mixed Platforms.ActiveCfg = external_parallel|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_parallel|Mixed Platforms.Build.0 = external_parallel|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_parallel|Win32.ActiveCfg = external_parallel|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_parallel|Win32.Build.0 = external_parallel|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_parallel|x64.ActiveCfg = external_parallel|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_parallel|x64.Build.0 = external_parallel|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external_parallel|x86.ActiveCfg = external_parallel|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external|Any CPU.ActiveCfg = external|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external|Any CPU.Build.0 = external|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external|Mixed Platforms.ActiveCfg = external|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external|Mixed Platforms.Build.0 = external|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external|Win32.ActiveCfg = external|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external|Win32.Build.0 = external|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external|x64.ActiveCfg = external|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.external|x86.ActiveCfg = external|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_debug|Any CPU.ActiveCfg = mpi_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_debug|Mixed Platforms.ActiveCfg = mpi_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_debug|Mixed Platforms.Build.0 = mpi_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_debug|Win32.ActiveCfg = mpi_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_debug|Win32.Build.0 = mpi_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_debug|x64.ActiveCfg = mpi_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_debug|x86.ActiveCfg = mpi_debug|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_release|Any CPU.ActiveCfg = mpi_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_release|Mixed Platforms.ActiveCfg = mpi_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_release|Mixed Platforms.Build.0 = mpi_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_release|Win32.ActiveCfg = mpi_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_release|Win32.Build.0 = mpi_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_release|x64.ActiveCfg = mpi_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.mpi_release|x86.ActiveCfg = mpi_release|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_debug|Any CPU.ActiveCfg = parallel_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_debug|Mixed Platforms.ActiveCfg = parallel_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_debug|Mixed Platforms.Build.0 = parallel_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_debug|Win32.ActiveCfg = parallel_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_debug|Win32.Build.0 = parallel_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_debug|x64.ActiveCfg = parallel_debug|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_debug|x86.ActiveCfg = parallel_debug|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_release|Any CPU.ActiveCfg = parallel_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_release|Mixed Platforms.ActiveCfg = parallel_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_release|Mixed Platforms.Build.0 = parallel_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_release|Win32.ActiveCfg = parallel_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_release|Win32.Build.0 = parallel_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_release|x64.ActiveCfg = parallel_release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.parallel_release|x86.ActiveCfg = parallel_release|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release_delaysign|Any CPU.ActiveCfg = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release_delaysign|Mixed Platforms.ActiveCfg = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release_delaysign|Mixed Platforms.Build.0 = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release_delaysign|Win32.ActiveCfg = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release_delaysign|x64.ActiveCfg = Release_delaysign|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release_delaysign|x64.Build.0 = Release_delaysign|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release_delaysign|x86.ActiveCfg = Release_delaysign|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_mt|Any CPU.ActiveCfg = release_mt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_mt|Mixed Platforms.ActiveCfg = release_mt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_mt|Win32.ActiveCfg = release_mt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_mt|x64.ActiveCfg = release_mt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_mt|x64.Build.0 = release_mt|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_mt|x86.ActiveCfg = release_mt|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_static|Any CPU.ActiveCfg = release_static|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_static|Mixed Platforms.ActiveCfg = release_static|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_static|Mixed Platforms.Build.0 = release_static|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_static|Win32.ActiveCfg = release_static|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_static|Win32.Build.0 = release_static|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_static|x64.ActiveCfg = release_static|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.release_static|x86.ActiveCfg = release_static|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|Any CPU.ActiveCfg = Release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|Any CPU.Build.0 = Release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|Mixed Platforms.Build.0 = Release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|Win32.ActiveCfg = Release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|Win32.Build.0 = Release|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|x64.ActiveCfg = Release|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|x64.Build.0 = Release|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Release|x86.ActiveCfg = Release|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseD|Any CPU.ActiveCfg = ReleaseD|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseD|Mixed Platforms.ActiveCfg = ReleaseD|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseD|Mixed Platforms.Build.0 = ReleaseD|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseD|Win32.ActiveCfg = ReleaseD|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseD|Win32.Build.0 = ReleaseD|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseD|x64.ActiveCfg = ReleaseD|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseD|x86.ActiveCfg = ReleaseD|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseShellOnly|Any CPU.ActiveCfg = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseShellOnly|Mixed Platforms.Build.0 = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseShellOnly|Win32.ActiveCfg = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseShellOnly|Win32.Build.0 = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseShellOnly|x64.ActiveCfg = Release_delaysign|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.ReleaseShellOnly|x86.ActiveCfg = Release|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Setup|Any CPU.ActiveCfg = smtcomp|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Setup|Mixed Platforms.ActiveCfg = smtcomp|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Setup|Mixed Platforms.Build.0 = smtcomp|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Setup|Win32.ActiveCfg = smtcomp|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Setup|x64.ActiveCfg = smtcomp|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Setup|x64.Build.0 = smtcomp|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Setup|x86.ActiveCfg = smtcomp|x64 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Trace|Any CPU.ActiveCfg = Trace|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Trace|Mixed Platforms.ActiveCfg = Trace|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Trace|Win32.ActiveCfg = Trace|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Trace|Win32.Build.0 = Trace|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Trace|x64.ActiveCfg = Trace|Win32 + {F008F2C4-D652-4A58-8DEF-DB83E2355454}.Trace|x86.ActiveCfg = Trace|x64 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.commercial|Any CPU.ActiveCfg = commercial|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.commercial|Mixed Platforms.ActiveCfg = commercial|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.commercial|Win32.ActiveCfg = commercial|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.commercial|x64.ActiveCfg = commercial|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.commercial|x86.ActiveCfg = commercial|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.debug_opt|Any CPU.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.debug_opt|Mixed Platforms.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.debug_opt|Mixed Platforms.Build.0 = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.debug_opt|Win32.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.debug_opt|Win32.Build.0 = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.debug_opt|x64.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.debug_opt|x86.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Debug|Any CPU.Build.0 = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Debug|Win32.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Debug|Win32.Build.0 = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Debug|x64.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Debug|x86.ActiveCfg = Debug|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_64|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_64|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_64|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_64|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_64|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_64|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_64|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_dbg|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_dbg|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_dbg|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_dbg|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_dbg|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_dbg|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_parallel|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_parallel|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_parallel|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_parallel|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_parallel|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_parallel|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external_parallel|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.external|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_debug|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_debug|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_debug|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_debug|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_debug|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_debug|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_debug|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_release|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_release|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_release|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_release|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_release|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_release|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.mpi_release|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_debug|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_debug|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_debug|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_debug|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_debug|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_debug|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_debug|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_release|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_release|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_release|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_release|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_release|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_release|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.parallel_release|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release_delaysign|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release_delaysign|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release_delaysign|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release_delaysign|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release_delaysign|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release_delaysign|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_mt|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_mt|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_mt|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_mt|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_mt|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_static|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_static|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_static|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_static|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_static|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_static|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.release_static|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Release|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseD|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseD|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseD|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseD|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseD|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseD|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseD|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseShellOnly|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseShellOnly|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseShellOnly|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseShellOnly|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseShellOnly|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.ReleaseShellOnly|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Setup|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Setup|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Setup|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Setup|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Setup|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Setup|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Setup|x86.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Trace|Any CPU.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Trace|Mixed Platforms.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Trace|Mixed Platforms.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Trace|Win32.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Trace|Win32.Build.0 = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Trace|x64.ActiveCfg = Release|Win32 + {7C154132-AAAB-4F60-B652-F8C51A63D244}.Trace|x86.ActiveCfg = Release|Win32 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.commercial|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.commercial|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.commercial|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.commercial|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.commercial|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.commercial|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.commercial|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.debug_opt|Any CPU.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.debug_opt|Any CPU.Build.0 = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.debug_opt|Mixed Platforms.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.debug_opt|Mixed Platforms.Build.0 = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.debug_opt|Win32.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.debug_opt|x64.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.debug_opt|x86.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Win32.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Win32.Build.0 = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x64.ActiveCfg = Debug|x64 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x64.Build.0 = Debug|x64 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x86.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_64|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_64|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_64|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_64|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_64|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_64|x64.ActiveCfg = external_64|x64 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_64|x64.Build.0 = external_64|x64 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_64|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_dbg|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_dbg|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_dbg|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_dbg|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_dbg|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_dbg|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_dbg|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_parallel|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_parallel|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_parallel|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_parallel|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_parallel|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_parallel|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external_parallel|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external|Any CPU.ActiveCfg = external|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external|Any CPU.Build.0 = external|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external|Win32.ActiveCfg = external|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external|Win32.Build.0 = external|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.external|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_debug|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_debug|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_debug|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_debug|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_debug|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_debug|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_debug|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_release|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_release|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_release|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_release|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_release|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_release|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.mpi_release|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_debug|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_debug|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_debug|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_debug|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_debug|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_debug|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_debug|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_release|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_release|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_release|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_release|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_release|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_release|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.parallel_release|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release_delaysign|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release_delaysign|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release_delaysign|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release_delaysign|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release_delaysign|Win32.ActiveCfg = Release_delaysign|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release_delaysign|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release_delaysign|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_mt|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_mt|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_mt|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_mt|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_mt|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_mt|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_mt|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_static|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_static|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_static|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_static|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_static|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_static|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.release_static|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Win32.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x64.ActiveCfg = Release|x64 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x64.Build.0 = Release|x64 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseD|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseD|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseD|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseD|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseD|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseD|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseD|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseShellOnly|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseShellOnly|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseShellOnly|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseShellOnly|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseShellOnly|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.ReleaseShellOnly|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Setup|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Setup|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Setup|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Setup|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Setup|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Setup|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Setup|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Trace|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Trace|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Trace|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Trace|Mixed Platforms.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Trace|Win32.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Trace|x64.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Trace|x86.ActiveCfg = Release|Any CPU + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.commercial|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.commercial|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.commercial|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.commercial|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.commercial|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.commercial|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.commercial|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.debug_opt|Any CPU.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.debug_opt|Mixed Platforms.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.debug_opt|Mixed Platforms.Build.0 = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.debug_opt|Win32.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.debug_opt|x64.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.debug_opt|x86.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.debug_opt|x86.Build.0 = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Debug|Any CPU.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Debug|Win32.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Debug|x64.ActiveCfg = Debug|x64 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Debug|x64.Build.0 = Debug|x64 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Debug|x86.ActiveCfg = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Debug|x86.Build.0 = Debug|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_64|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_64|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_64|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_64|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_64|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_64|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_64|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_dbg|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_dbg|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_dbg|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_dbg|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_dbg|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_dbg|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_dbg|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_parallel|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_parallel|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_parallel|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_parallel|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_parallel|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_parallel|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external_parallel|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.external|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_debug|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_debug|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_debug|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_debug|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_debug|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_debug|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_debug|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_release|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_release|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_release|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_release|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_release|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_release|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.mpi_release|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_debug|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_debug|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_debug|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_debug|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_debug|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_debug|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_debug|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_release|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_release|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_release|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_release|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_release|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_release|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.parallel_release|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release_delaysign|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release_delaysign|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release_delaysign|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release_delaysign|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release_delaysign|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release_delaysign|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release_delaysign|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_mt|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_mt|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_mt|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_mt|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_mt|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_mt|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_mt|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_static|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_static|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_static|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_static|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_static|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_static|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.release_static|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release|x64.ActiveCfg = Release|x64 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release|x64.Build.0 = Release|x64 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Release|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseD|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseD|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseD|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseD|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseD|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseD|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseD|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseShellOnly|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseShellOnly|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseShellOnly|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseShellOnly|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseShellOnly|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseShellOnly|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.ReleaseShellOnly|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Setup|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Setup|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Setup|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Setup|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Setup|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Setup|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Setup|x86.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Trace|Any CPU.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Trace|Mixed Platforms.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Trace|Mixed Platforms.Build.0 = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Trace|Win32.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Trace|x64.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Trace|x86.ActiveCfg = Release|x86 + {B408E4BF-338D-446D-8D28-0DAB9BE91182}.Trace|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal