", line)
tgt.write(line);
elif (not in_class and (s.startswith("{") or s.startswith("}"))) or s.startswith("[") or s.startswith("#"):
- # print "Skipping: " + s;
+ # tgt.write("// Skipping: " + s)
pass
elif line == "}\n":
pass
else:
# indent = line.find(s)
+ # tgt.write("// LINE: " + line)
if line.find(": base") != -1:
- line = re.sub(": base\((?P[\w,.\(\) ]*)\)", "{ super(\g
);", line)
- if line.find("; {") != -1:
- line = line.replace("; {", ";")
+ line = re.sub(": base\((?P
[^\{]*)\)", "{ super(\g
);", line)
+ line = line[4:]
+ obraces = line.count("{")
+ cbraces = line.count("}")
+ mbraces = obraces - cbraces
+ # tgt.write("// obraces = " + str(obraces) + "\n")
+ if obraces == 1:
+ skip_brace = 1
else:
- skip_brace = 1
- if s.startswith("public"):
+ for i in range(0, mbraces):
+ line = line.replace("\n", "}\n")
+ if (s.find("public") != -1 or s.find("protected") != -1 or s.find("internal") != -1) and s.find("(") != -1:
line = re.sub(" = [\w.]+(?P[,;\)])", "\g", line)
a = type_replace(line)
+ a = enum_replace(a)
a = re.sub("(?P[\(, ])params ", "\g", a)
a = a.replace("base.", "super.")
a = re.sub("Contract.\w+\([\s\S]*\);", "", a)
a = rename_native(a)
a = re.sub("~\w+\(\)", "protected void finalize()", a)
+
+ if missing_foreach_brace == 1:
+ # a = a.replace("\n", " // checked " + str(foreach_opened_brace) + "\n")
+ if foreach_opened_brace == 0 and a.find("{") != -1:
+ foreach_opened_brace = 1
+ elif foreach_opened_brace == 0 and a.find("}") == -1:
+ a = a.replace("\n", "}}\n")
+ foreach_opened_brace = 0
+ missing_foreach_brace = 0
+ elif foreach_opened_brace == 1 and a.find("}") != -1:
+ a = a.replace("\n", "}}\n")
+ foreach_opened_brace = 0
+ missing_foreach_brace = 0
+
+# if a.find("foreach") != -1:
+# missing_foreach_brace = 1
+# a = re.sub("foreach\s*\((?P[\w <>,]+)\s+(?P\w+)\s+in\s+(?P\w+)\)",
+ # "{ Iterator fe_i = \g.iterator(); while (fe_i.hasNext()) { \g \g = (long)fe_i.next(); ",
+# a)
a = re.sub("foreach\s*\((?P[\w <>,]+)\s+(?P\w+)\s+in\s+(?P\w+)\)",
- "for (\g.Iterator \g = \g.iterator(); \g.hasNext(); )", a)
+ "for (\g \g: \g)",
+ a)
+ if a.find("long o: m_queue") != -1:
+ a = a.replace("long", "Long")
a = a.replace("readonly ", "")
a = a.replace("const ", "final ")
- a = a.replace("ToString", "toString")
+ a = a.replace("String ToString", "String toString")
+ a = a.replace(".ToString", ".toString")
a = a.replace("internal ", "")
a = a.replace("new static", "static")
a = a.replace("new public", "public")
a = a.replace("override ", "")
a = a.replace("virtual ", "")
a = a.replace("o as AST", "(AST) o")
+ a = a.replace("o as Sort", "(Sort) o")
a = a.replace("other as AST", "(AST) other")
a = a.replace("o as FuncDecl", "(FuncDecl) o")
+ a = a.replace("IntPtr obj", "long obj")
+ a = a.replace("IntPtr o", "long o")
+ a = a.replace("new long()", "0")
+ a = a.replace("long.Zero", "0")
+ a = a.replace("object o", "Object o")
+ a = a.replace("object other", "Object other")
a = a.replace("IntPtr res = IntPtr.Zero;", "Native.IntPtr res = new Native.IntPtr();")
a = a.replace("out res", "res")
+ a = a.replace("GC.ReRegisterForFinalize(m_ctx);", "")
+ a = a.replace("GC.SuppressFinalize(this);", "")
+ a = a.replace(".Length", ".length")
+ a = a.replace("m_queue.Count", "m_queue.size()")
+ a = a.replace("m_queue.Add", "m_queue.add")
+ a = a.replace("m_queue.Clear", "m_queue.clear")
+ a = a.replace("for (long ", "for (int ")
+ a = a.replace("ReferenceEquals(Context, ctx)", "Context() == ctx")
+ a = a.replace("BigInteger.Parse", "new BigInteger")
+ if had_ulong_res == 0 and a.find("ulong res = 0") != -1:
+ a = a.replace("ulong res = 0;", "LongPtr res = new LongPtr();")
+ elif had_ulong_res == 1:
+ a = a.replace("ref res)", "res)")
+ if a.find("return res;") != -1:
+ a = a.replace("return res;", "return res.value;")
+ had_ulong_res = 0
a = a.replace("lock (", "synchronized (")
if in_static_class:
a = a.replace("static", "")
a = re.sub("ref (?P\w+)", "\g", a)
subst_getters(a, getters)
+ a = re.sub("NativeObject = (?P.*);", "setNativeObject(\g);", a)
+ a = replace_generals(a)
tgt.write(a)
-
tgt.close()
mk_java_bindings()
diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile
new file mode 100644
index 000000000..55f89fe1c
--- /dev/null
+++ b/src/api/ml/Makefile
@@ -0,0 +1,14 @@
+# to set ARGS, invoke as e.g.: $ make ARGS='-DUNSAFE_ERRORS -DLEAK_CONTEXTS'
+ARGS=
+
+
+default: z3.ml z3.mli z3_stubs.c
+
+
+%.ml %.mli %_stubs.c: ../%_api.h %.0.idl x3.ml x3V3.ml x3V3.mli \
+ error_handling.idl mlx_get_app_args.idl mlx_get_array_sort.idl mlx_get_datatype_sort.idl mlx_get_domains.idl mlx_get_error_msg.idl mlx_get_pattern_terms.idl mlx_get_tuple_sort.idl mlx_mk_context_x.idl mlx_mk_datatypes.idl mlx_mk_numeral.idl mlx_mk_sort.idl mlx_mk_symbol.idl mlx_model.idl mlx_numeral_refine.idl mlx_parse_smtlib.idl mlx_sort_refine.idl mlx_statistics.idl mlx_symbol_refine.idl mlx_term_refine.idl \
+ generate_mlapi.sh add_error_checking.V3.sed add_error_checking.sed preprocess.sed postprocess.sed reverse.sed
+ ./generate_mlapi.sh $(ARGS)
+
+clean:
+ rm -f z3.ml z3.mli z3_stubs.c
diff --git a/src/api/ml/Makefile.build b/src/api/ml/Makefile.build
new file mode 100644
index 000000000..27c798bbf
--- /dev/null
+++ b/src/api/ml/Makefile.build
@@ -0,0 +1,69 @@
+# Makefile to compile OCaml interface to Z3
+#
+# Parameters: ARGS and DEPS environment variables
+# ARGS is passed through to the Makefile that generates the OCaml interface
+# DEPS is a sequence of files that are deleted when the OCaml interface changes
+
+SRC_ML=../../../src/api/ml
+ifeq (${OS}, Windows_NT)
+# the BLD_ML path ends up stored in z3.cm{,x}a, so it must be in windows format
+BLD_ML=$(shell cygpath -m $(CURDIR))
+CFLAGS=-ccopt -wd4090 -ccopt -I$(SRC_ML)/..
+XCDBG=-g $(CFLAGS)
+XCOPT=-ccopt -Ox -ccopt -Oy- $(CFLAGS)
+# ole32 is needed by camlidl (COM support)
+XLIB=-cclib ole32.lib
+AR=lib /nologo /LIBPATH:../../build ../../z3.lib /out:
+O=obj
+A=lib
+else
+BLD_ML=$(CURDIR)
+CFLAGS=-ccopt -Wno-discard-qual -ccopt -Wno-unused-variable -ccopt -I$(SRC_ML)/..
+XCDBG=-g -ccopt -g $(CFLAGS)
+XCOPT=-ccopt -O3 -ccopt -fomit-frame-pointer $(CFLAGS)
+XLIB=
+AR=ar rcs # note trailing space is significant
+O=o
+A=a
+endif
+
+
+all: z3.cma z3.cmxa ocamlz3
+
+
+# keep these files to avoid repeatedly rebuilding them
+.PRECIOUS: $(SRC_ML)/z3.ml $(SRC_ML)/z3.mli $(SRC_ML)/z3_stubs.c z3.ml z3.mli z3_stubs.c z3_theory_stubs.c
+
+# regenerate OCaml API if needed
+$(SRC_ML)/%.mli $(SRC_ML)/%.ml $(SRC_ML)/%_stubs.c: $(SRC_ML)/Makefile
+ make -C $(SRC_ML) z3.mli z3.ml z3_stubs.c
+
+# copy OCaml API from src to build directories
+%.mli %.ml %_stubs.c %_theory_stubs.c: $(SRC_ML)/%.mli $(SRC_ML)/%.ml $(SRC_ML)/%_stubs.c Makefile
+ cp $(SRC_ML)/z3.mli $(SRC_ML)/z3.ml $(SRC_ML)/z3_stubs.c $(SRC_ML)/z3_theory_stubs.c .
+
+# OCaml library module for native code clients
+%.cmxa %.cmi lib%stubs.a %.a: %.mli %.ml %_stubs.c %_theory_stubs.c Makefile
+ rm -f $(DEPS)
+ ocamlopt.opt -c $(XCOPT) z3.mli z3.ml z3_stubs.c z3_theory_stubs.c
+ $(AR)libz3stubs.$(A) z3.$(O) z3_stubs.$(O) z3_theory_stubs.$(O)
+ ocamlopt.opt -a -cclib -L$(BLD_ML)/../.. $(XLIB) -cclib -lcamlidl -cclib -lz3 -cclib -lz3stubs z3.cmx -o z3.cmxa
+ rm -f z3_theory_stubs.$(O) z3_stubs.$(O) z3.$(O) z3.cmx
+
+# OCaml library module for byte code clients
+%.cma %.cmi lib%stubs_dbg.a: %.mli %.ml %_stubs.c %_theory_stubs.c Makefile
+ rm -f $(DEPS)
+ ocamlc.opt -c $(XCDBG) z3.mli z3.ml z3_stubs.c z3_theory_stubs.c
+ $(AR)libz3stubs_dbg.$(A) z3_stubs.$(O) z3_theory_stubs.$(O)
+ ocamlc.opt -custom -a $(CXDBG) -cclib -L$(BLD_ML)/../.. $(XLIB) -cclib -lcamlidl -cclib -lz3 -cclib -lz3stubs_dbg z3.cmo -o z3.cma
+ rm -f z3_theory_stubs.$(O) z3_stubs.$(O) z3.cmo
+
+
+# OCaml custom toplevel system pre-linked with Z3
+ocamlz3: z3.cma Makefile
+ ocamlmktop -o ocamlz3 z3.cma -cclib -L.
+
+
+clean: Makefile
+ make -C $(SRC_ML) clean
+ rm -rf Makefile libz3stubs.$(A) libz3stubs_dbg.$(A) ocamlz3 ocamlz3.dSYM z3.$(O) z3.$(A) z3.cma z3.cmi z3.cmo z3.cmx z3.cmxa z3.ml z3.mli z3_stubs.$(O) z3_stubs.c z3_theory_stubs.$(O) z3_theory_stubs.c
diff --git a/src/api/ml/add_error_checking.V3.sed b/src/api/ml/add_error_checking.V3.sed
index 170ca2d6b..7df291520 100644
--- a/src/api/ml/add_error_checking.V3.sed
+++ b/src/api/ml/add_error_checking.V3.sed
@@ -1,2 +1,2 @@
# Customize error handling for contexts created in ML:
-s/Z3_API Z3_mk_context\(_rc\|\)(\(.*\))/Z3_API Z3_mk_context\1(\2) quote(dealloc,\"Z3_set_error_handler(_res, caml_z3_error_handler);\")/g
+s/Z3_API Z3_mk_context(\(.*\))/Z3_API Z3_mk_context(\1) quote(dealloc,\"Z3_set_error_handler(_res, (void*)caml_z3_error_handler);\")/g
diff --git a/src/api/ml/add_error_checking.sed b/src/api/ml/add_error_checking.sed
index ede3275e1..71c06b9e4 100644
--- a/src/api/ml/add_error_checking.sed
+++ b/src/api/ml/add_error_checking.sed
@@ -3,14 +3,19 @@
# Add error checking epilogue for all Z3_API functions that accept two Z3_contexts
:begincc
-# add epilogue for two Z3_context parameters
-s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\")\7/g
-
-# if a match was found, done with all Z3_contexts and Z3_theorys
+# add epilogue for two Z3_context parameters and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt
+s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\");/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3);\");/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\")/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3);\")/g
t endt
# if complete prototype, done with two Z3_contexts
-/Z3_API .*(.*)\(;\|\)[ ]*$/b endcc
+/Z3_API .*(.*);[ ]*$/b endcc
+/Z3_API .*(.*)[ ]*$/b endcc
# if incomplete prototype
/Z3_API .*(.*/{
@@ -18,10 +23,14 @@ t endt
# read another line
N
- # add epilogue for two Z3_context parameters
- s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")\7/g
-
- # if a match was found, done with all Z3_contexts and Z3_theorys
+ # add epilogue for two Z3_context parameters and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt
+ s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\");/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\");/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")/g
t endt
# else keep looking for two Z3_contexts
@@ -31,14 +40,19 @@ t endt
# Add error checking epilogue for all Z3_API functions that accept one Z3_context
:beginc
-# add epilogue for one Z3_context parameter
-s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")\5/g
-
-# if a match was found, done with all Z3_contexts and Z3_theorys
+# add epilogue for one Z3_context parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt
+s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\");/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\");/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\)[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\")/g
t endt
# if complete prototype, done with all Z3_contexts
-/Z3_API .*(.*)\(;\|\)[ ]*$/b endc
+/Z3_API .*(.*);[ ]*$/b endc
+/Z3_API .*(.*)[ ]*$/b endc
# if incomplete prototype
/Z3_API .*(.*/{
@@ -46,10 +60,14 @@ t endt
# read another line
N
- # add epilogue for one Z3_context parameter
- s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")\5/g
-
- # if a match was found, done with all Z3_contexts and Z3_theorys
+ # add epilogue for one Z3_context parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt
+ s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\");/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\");/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\")/g
t endt
# else keep looking for one Z3_context
@@ -60,24 +78,33 @@ t endt
# Add error checking epilogue for all Z3_API functions that accept a Z3_theory
:begint
-# add epilogue for one Z3_theory parameter
-s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")\5/g
-
-# if a match was found, done with all Z3_contexts and Z3_theorys
+# add epilogue for one Z3_theory parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt
+s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g
+t endt
+s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g
t endt
# if complete prototype, done with all Z3_theorys
-/Z3_API .*(.*)\(;\|\)[ ]*$/b endt
+/Z3_API .*(.*);[ ]*$/b endt
+/Z3_API .*(.*)[ ]*$/b endt
/Z3_API .*(.*/{
# read another line
N
- # add epilogue for one Z3_theory parameter
- s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")\5/g
-
- # if a match was found, done with all Z3_theorys
+ # add epilogue for one Z3_theory parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt
+ s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g
+ t endt
+ s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g
t endt
# else keep looking for one Z3_theory
diff --git a/src/api/ml/error_handling.idl b/src/api/ml/error_handling.idl
index cc49a91e4..5a2ec9915 100644
--- a/src/api/ml/error_handling.idl
+++ b/src/api/ml/error_handling.idl
@@ -53,6 +53,12 @@ Author:
#endif
+// The V3 API uses a single handler irregardless of UNSAFE_ERRORS
+quote(c,"
+/* All contexts share the same handler */
+static value caml_z3_error_handler = 0;
+");
+
#ifdef SAFE_ERRORS
quote(mlmli,"
@@ -64,7 +70,7 @@ quote(mlmli,"
exception Error of context * error_code
");
quote(ml,"
-/* Register dynamically-generated exception tag for use from C */
+(* Register dynamically-generated exception tag for use from C *)
let _ = Callback.register_exception \"Z3.Error\" (Error (Obj.magic None, OK))
");
@@ -108,7 +114,7 @@ quote(mlmli,"
exception Error of context * error_code
");
quote(ml,"
-/* Register dynamically-generated exception tag for use from C */
+(* Register dynamically-generated exception tag for use from C *)
let _ = Callback.register_exception \"Z3.Error\" (Error (Obj.magic None, OK))
");
@@ -116,9 +122,6 @@ quote(c,"
/* Error checking routine that does nothing */
void check_error_code(Z3_context c) {}
-/* All contexts share the same handler */
-static value caml_error_handler = 0;
-
static void error_handler_static (Z3_context c, Z3_error_code e)
{
static struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
@@ -126,8 +129,8 @@ static void error_handler_static (Z3_context c, Z3_error_code e)
value ctx_err[2];
ctx_err[0] = c2ml_Z3_context(&c);
ctx_err[1] = camlidl_c2ml_z3_Z3_error_code(&e, &_ctxs);
- if (caml_error_handler) {
- caml_callback2(caml_error_handler, ctx_err[0], ctx_err[1]);
+ if (caml_z3_error_handler) {
+ caml_callback2(caml_z3_error_handler, ctx_err[0], ctx_err[1]);
} else {
/* if no handler set, raise OCaml Error exception */
exn_tag = caml_named_value(\"Z3.Error\");
@@ -141,7 +144,7 @@ static void error_handler_static (Z3_context c, Z3_error_code e)
void ml2c_Z3_error_handler (value ml_handler, void* c_handler)
{
- caml_error_handler = ml_handler;
+ caml_z3_error_handler = ml_handler;
c_handler = (void*)error_handler_static;
}
diff --git a/src/api/ml/generate_mlapi.sh b/src/api/ml/generate_mlapi.sh
new file mode 100755
index 000000000..dd8692833
--- /dev/null
+++ b/src/api/ml/generate_mlapi.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+# Script to generate the Z3 OCaml API
+#
+# Assumes that environment variables are set to provide access to the following commands: camlidl, gcc, grep, sed
+#
+# This script uses 'gcc -E' as the C preprocessor, other C preprocessors may work but have not been tested.
+#
+# Invoke with "-DUNSAFE_ERRORS" to build version that does not support recoverable errors, but avoids some error-checking overhead.
+# Invoke with "-DLEAK_CONTEXTS" to build version that leaks Z3_context objects, but avoids some garbage-collection overhead.
+
+
+# add calls to error checking routine
+# convert from doxygen to ocamldoc markup and other syntactic munging
+# ../z3_api.h -> z3V3_api.idl
+sed -f add_error_checking.V3.sed -f preprocess.sed ../z3_api.h > z3V3_api.idl
+
+# z3.idl (z3V3_api.idl x3V3.mli x3V3.ml) -> z3V3_stubs.c, z3V3.mli, z3V3.ml
+gcc -E -w -P -CC -xc -DCAMLIDL -DMLAPIV3 $@ z3.0.idl > z3V3.idl
+camlidl -nocpp z3V3.idl
+
+# reverse.sed to reverse order of substitution of enums to avoid matching prefixes such as enum_1 of enum_10
+grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_]*$" z3V3.mli | sed -e "s|and z3_\([a-zA-Z0-9_]*\) = \([a-zA-Z0-9_]*\)|s/\2/\1/g|g" -f reverse.sed > /tmp/renameV3.sed
+grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_ ]* option$" z3V3.mli | sed -e "s|and \(z3_[a-zA-Z0-9_]*\) = \([a-zA-Z0-9_ ]*\)|s/\1/\2/g|g" >> /tmp/renameV3.sed
+
+# rename.sed to substitute out type equations for enums and options, then postprocess
+cp -f z3V3.mli z3V3.ml /tmp
+sed -f /tmp/renameV3.sed -f postprocess.sed /tmp/z3V3.mli > z3V3.mli
+sed -f /tmp/renameV3.sed -f postprocess.sed /tmp/z3V3.ml > z3V3.ml
+
+# ../z3_api.h -> z3_api.idl
+sed -f add_error_checking.sed -f preprocess.sed ../z3_api.h > z3_api.idl
+
+# z3.idl (z3_api.idl x3.ml) -> z3_stubs.c, z3.mli, z3.ml
+gcc -E -w -P -CC -xc -I. -DCAMLIDL $@ z3.0.idl > z3.idl
+camlidl -nocpp z3.idl
+
+# reverse.sed to reverse order of substitution of enums to avoid matching prefixes such as enum_1 of enum_10
+grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_]*$" z3.mli | sed -e "s|and z3_\([a-zA-Z0-9_]*\) = \([a-zA-Z0-9_]*\)|s/\2/\1/g|g" -f reverse.sed > /tmp/rename.sed
+grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_ ]* option$" z3.mli | sed -e "s|and \(z3_[a-zA-Z0-9_]*\) = \([a-zA-Z0-9_ ]*\)|s/\1/\2/g|g" >> /tmp/rename.sed
+
+# rename.sed to substitute out type equations for enums and options, then postprocess
+cp z3.mli z3.ml /tmp
+sed -f /tmp/rename.sed -f postprocess.sed /tmp/z3.mli > z3.mli
+sed -f /tmp/rename.sed -f postprocess.sed /tmp/z3.ml > z3.ml
+
+
+# append Z3.V3 module onto Z3 module
+cat z3V3.mli >> z3.mli
+cat z3V3.ml >> z3.ml
+sed "1,22d" z3V3_stubs.c >> z3_stubs.c
+
+rm -f z3V3_api.idl z3V3.idl z3V3.ml z3V3.mli z3V3_stubs.c z3_api.idl z3.idl
diff --git a/src/api/ml/postprocess.sed b/src/api/ml/postprocess.sed
new file mode 100644
index 000000000..f25f70cb7
--- /dev/null
+++ b/src/api/ml/postprocess.sed
@@ -0,0 +1,8 @@
+# remove 'z3_' and 'Z3_' prefixes on names
+
+s/{\!Z3\./{\!/g
+s/\([^_]\)[zZ]3_/\1/g
+
+# remove cyclic definitions introduced by substituting type equations
+
+s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g
diff --git a/src/api/ml/build.sed b/src/api/ml/preprocess.sed
similarity index 92%
rename from src/api/ml/build.sed
rename to src/api/ml/preprocess.sed
index e4434a5a1..c7d1fc804 100644
--- a/src/api/ml/build.sed
+++ b/src/api/ml/preprocess.sed
@@ -1,7 +1,7 @@
# attempt to clean up the mess with 'unsigned'
-s/__in unsigned __/__in __/g
-s/__out unsigned __/__out __/g
-s/__out_opt unsigned __/__out_opt __/g
+s/ unsigned/ unsigned int/g
+s/unsigned int long/unsigned long/g
+s/unsigned int __/unsigned __/g
# '@name ' -> 'Section: '
@@ -43,7 +43,7 @@ s/\\ / /g
s/\\c \([^ .,:]*\)/[\1]/g
# '#Z3_' -> 'Z3.'
-s/#Z3_\([^ \n\.\t,)]*\)/{!Z3.\1}/g
+s/#Z3_\([^ \.,) ]*\)/{!Z3.\1}/g
# '/*@}*/' -> ''
s/\/\*@{\*\///g
diff --git a/src/api/ml/reverse.sed b/src/api/ml/reverse.sed
new file mode 100644
index 000000000..31ac563d2
--- /dev/null
+++ b/src/api/ml/reverse.sed
@@ -0,0 +1,3 @@
+# output lines of input in reverse order
+
+1!G;h;$!d
diff --git a/src/api/ml/z3.idl b/src/api/ml/z3.0.idl
similarity index 97%
rename from src/api/ml/z3.idl
rename to src/api/ml/z3.0.idl
index 2450e387d..3773a28e3 100644
--- a/src/api/ml/z3.idl
+++ b/src/api/ml/z3.0.idl
@@ -91,16 +91,6 @@ quote(c,"#define xstr(s) str(s)");
quote(c,"#define str(s) #s");
-// CamlIDL (1.05) has a bug where it does not accept [unsigned] as a type,
-// only as a specifier, so unsigned is defined to be unsigned int.
-#define unsigned unsigned int
-
-
-// Suppress "warning C4090: 'function' : different 'const' qualifiers" as
-// CamlIDL does not seem to get this right.
-quote(c,"#pragma warning(disable:4090)");
-
-
#ifndef MLAPIV3
#define DEFINE_TYPE(T) typedef [abstract] void* T
diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli
index 9f58ba06a..905716035 100644
--- a/src/api/ml/z3.mli
+++ b/src/api/ml/z3.mli
@@ -4886,7 +4886,8 @@ external fixedpoint_add_rule : context -> fixedpoint -> ast -> symbol -> unit
of sorts in the domain of [r]. Each sort in the domain should be an integral
(bit-vector, Boolean or or finite domain sort).
- The call has the same effect as adding a rule where
is applied to the arguments.
+ The call has the same effect as adding a rule where
+ is applied to the arguments.
def_API('fixedpoint_add_fact', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(FUNC_DECL), _in(UINT), _in_array(3, UINT)))
*)
diff --git a/src/api/python/z3.py b/src/api/python/z3.py
index a71db82c5..6517de221 100644
--- a/src/api/python/z3.py
+++ b/src/api/python/z3.py
@@ -23,8 +23,11 @@ Small example:
>>> s.add(y == x + 1)
>>> s.check()
sat
->>> s.model()
-[y = 2, x = 1]
+>>> m = s.model()
+>>> m[x]
+1
+>>> m[y]
+2
Z3 exceptions:
@@ -169,28 +172,6 @@ class Context:
"""
Z3_interrupt(self.ref())
- def set(self, *args, **kws):
- """Set global configuration options.
-
- Z3 command line options can be set using this method.
- The option names can be specified in different ways:
-
- >>> ctx = Context()
- >>> ctx.set('WELL_SORTED_CHECK', True)
- >>> ctx.set(':well-sorted-check', True)
- >>> ctx.set(well_sorted_check=True)
- """
- if __debug__:
- _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
- for key, value in kws.iteritems():
- Z3_update_param_value(self.ctx, str(key).upper(), _to_param_value(value))
- prev = None
- for a in args:
- if prev == None:
- prev = a
- else:
- Z3_update_param_value(self.ctx, str(prev), _to_param_value(a))
- prev = None
# Global Z3 context
_main_ctx = None
@@ -220,16 +201,48 @@ def _get_ctx(ctx):
else:
return ctx
-def set_option(*args, **kws):
- """Update parameters of the global context `main_ctx()`, and global configuration options of Z3Py. See `Context.set()`.
-
- >>> set_option(precision=10)
+def set_param(*args, **kws):
+ """Set Z3 global (or module) parameters.
+
+ >>> set_param(precision=10)
"""
+ if __debug__:
+ _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.")
new_kws = {}
for k, v in kws.iteritems():
if not set_pp_option(k, v):
new_kws[k] = v
- main_ctx().set(*args, **new_kws)
+ for key, value in new_kws.iteritems():
+ Z3_global_param_set(str(key).upper(), _to_param_value(value))
+ prev = None
+ for a in args:
+ if prev == None:
+ prev = a
+ else:
+ Z3_global_param_set(str(prev), _to_param_value(a))
+ prev = None
+
+def reset_params():
+ """Reset all global (or module) parameters.
+ """
+ Z3_global_param_reset_all()
+
+def set_option(*args, **kws):
+ """Alias for 'set_param' for backward compatibility.
+ """
+ return set_param(*args, **kws)
+
+def get_param(name):
+ """Return the value of a Z3 global (or module) parameter
+
+ >>> get_param('nlsat.reorder')
+ 'true'
+ """
+ ptr = (ctypes.c_char_p * 1)()
+ if Z3_global_param_get(str(name), ptr):
+ r = str(ptr[0])
+ return r
+ raise Z3Exception("failed to retrieve value for '%s'" % name)
#########################################
#
@@ -632,10 +645,10 @@ class FuncDeclRef(AstRef):
>>> f(x, x)
f(x, ToReal(x))
"""
- args = _get_args(args)
+ args = _get_args(args)
num = len(args)
if __debug__:
- _z3_assert(num == self.arity(), "Incorrect number of arguments")
+ _z3_assert(num == self.arity(), "Incorrect number of arguments to %s" % self)
_args = (Ast * num)()
saved = []
for i in range(num):
@@ -1718,10 +1731,11 @@ def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
>>> q = Exists([x, y], f(x, y) >= x, skid="foo")
>>> q
Exists([x, y], f(x, y) >= x)
- >>> Tactic('nnf')(q)
- [[f(x!foo!1, y!foo!0) >= x!foo!1]]
- >>> Tactic('nnf')(q).as_expr()
- f(x!foo!3, y!foo!2) >= x!foo!3
+ >>> is_quantifier(q)
+ True
+ >>> r = Tactic('nnf')(q).as_expr()
+ >>> is_quantifier(r)
+ False
"""
return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
@@ -1735,7 +1749,7 @@ class ArithSortRef(SortRef):
"""Real and Integer sorts."""
def is_real(self):
- """Return `True` if `self` is the integer sort.
+ """Return `True` if `self` is of the sort Real.
>>> x = Real('x')
>>> x.is_real()
@@ -1749,7 +1763,7 @@ class ArithSortRef(SortRef):
return self.kind() == Z3_REAL_SORT
def is_int(self):
- """Return `True` if `self` is the real sort.
+ """Return `True` if `self` is of the sort Integer.
>>> x = Int('x')
>>> x.is_int()
@@ -4384,8 +4398,8 @@ def args2params(arguments, keywords, ctx=None):
"""Convert python arguments into a Z3_params object.
A ':' is added to the keywords, and '_' is replaced with '-'
- >>> args2params([':model', True, ':relevancy', 2], {'elim_and' : True})
- (params :model 1 :relevancy 2 :elim-and 1)
+ >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True})
+ (params model 1 relevancy 2 elim_and 1)
"""
if __debug__:
_z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.")
@@ -4398,7 +4412,6 @@ def args2params(arguments, keywords, ctx=None):
r.set(prev, a)
prev = None
for k, v in keywords.iteritems():
- k = ':' + k.replace('_', '-')
r.set(k, v)
return r
@@ -5774,8 +5787,15 @@ class Solver(Z3PPObject):
>>> s.assert_and_track(x < 0, p3)
>>> print s.check()
unsat
- >>> print s.unsat_core()
- [p3, p1]
+ >>> c = s.unsat_core()
+ >>> len(c)
+ 2
+ >>> Bool('p1') in c
+ True
+ >>> Bool('p2') in c
+ False
+ >>> p3 in c
+ True
"""
if isinstance(p, str):
p = Bool(p, self.ctx)
@@ -6972,9 +6992,9 @@ def solve(*args, **keywords):
configure it using the options in `keywords`, adds the constraints
in `args`, and invokes check.
- >>> a, b = Ints('a b')
- >>> solve(a + b == 3, Or(a == 0, a == 1), a != 0)
- [b = 2, a = 1]
+ >>> a = Int('a')
+ >>> solve(a > 0, a < 2)
+ [a = 1]
"""
s = Solver()
s.set(**keywords)
diff --git a/src/api/z3_api.h b/src/api/z3_api.h
index 9570af43b..49d59e125 100644
--- a/src/api/z3_api.h
+++ b/src/api/z3_api.h
@@ -1233,25 +1233,99 @@ extern "C" {
#endif // CAMLIDL
#ifdef CorML3
+ /**
+ @name Configuration
+ */
+
+ /*@{*/
+ /**
+ \brief Set a global (or module) parameter.
+ This setting is shared by all Z3 contexts.
+
+ When a Z3 module is initialized it will use the value of these parameters
+ when Z3_params objects are not provided.
+
+ The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'.
+ The character '.' is a delimiter (more later).
+
+ The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'.
+ Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION".
+
+ This function can be used to set parameters for a specific Z3 module.
+ This can be done by using ..
+ For example:
+ Z3_global_param_set('pp.decimal', 'true')
+ will set the parameter "decimal" in the module "pp" to true.
+
+ def_API('Z3_global_param_set', VOID, (_in(STRING), _in(STRING)))
+ */
+ void Z3_API Z3_global_param_set(__in Z3_string param_id, __in Z3_string param_value);
+
+
+ /**
+ \brief Restore the value of all global (and module) parameters.
+ This command will not affect already created objects (such as tactics and solvers).
+
+ \sa Z3_global_param_set
+
+ def_API('Z3_global_param_reset_all', VOID, ())
+ */
+ void Z3_API Z3_global_param_reset_all();
+
+ /**
+ \brief Get a global (or module) parameter.
+
+ Returns \mlonly \c None \endmlonly \conly \c Z3_FALSE
+ if the parameter value does not exist.
+
+ \sa Z3_global_param_set
+
+ The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value.
+
+ \remark This function cannot be invoked simultaneously from different threads without synchronization.
+ The result string stored in param_value is stored in shared location.
+
+ def_API('Z3_global_param_get', BOOL, (_in(STRING), _out(STRING)))
+ */
+ Z3_bool_opt Z3_API Z3_global_param_get(__in Z3_string param_id, __out_opt Z3_string_ptr param_value);
+
+ /*@}*/
+
/**
@name Create configuration
*/
/*@{*/
/**
- \brief Create a configuration.
+ \brief Create a configuration object for the Z3 context object.
Configurations are created in order to assign parameters prior to creating
- contexts for Z3 interaction. For example, if the users wishes to use model
+ contexts for Z3 interaction. For example, if the users wishes to use proof
generation, then call:
- \ccode{Z3_set_param_value(cfg\, "MODEL"\, "true")}
+ \ccode{Z3_set_param_value(cfg\, "proof"\, "true")}
\mlonly \remark Consider using {!mk_context_x} instead of using
explicit configuration objects. The function {!mk_context_x}
receives an array of string pairs. This array represents the
configuration options. \endmlonly
+ \remark In previous versions of Z3, the \c Z3_config was used to store
+ global and module configurations. Now, we should use \c Z3_global_param_set.
+
+ The following parameters can be set:
+
+ - proof (Boolean) Enable proof generation
+ - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting
+ - trace (Boolean) Tracing support for VCC
+ - trace_file_name (String) Trace out file for VCC traces
+ - timeout (unsigned) default timeout (in milliseconds) used for solvers
+ - well_sorted_check type checker
+ - auto_config use heuristics to automatically select solver and configure it
+ - model model generation for solvers, this parameter can be overwritten when creating a solver
+ - model_validate validate models produced by solvers
+ - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver
+
\sa Z3_set_param_value
\sa Z3_del_config
@@ -1271,18 +1345,14 @@ extern "C" {
/**
\brief Set a configuration parameter.
- The list of all configuration parameters can be obtained using the Z3 executable:
-
- \verbatim
- z3.exe -ini?
- \endverbatim
+ The following parameters can be set for
\sa Z3_mk_config
def_API('Z3_set_param_value', VOID, (_in(CONFIG), _in(STRING), _in(STRING)))
*/
void Z3_API Z3_set_param_value(__in Z3_config c, __in Z3_string param_id, __in Z3_string param_value);
-
+
/*@}*/
#endif
@@ -1367,33 +1437,18 @@ extern "C" {
#endif
/**
- \brief Update a mutable configuration parameter.
+ \brief Set a value of a context 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.
-
- \conly \sa Z3_set_param_value
- \mlonly \sa Z3_mk_context \endmlonly
+ \sa Z3_global_param_set
def_API('Z3_update_param_value', VOID, (_in(CONTEXT), _in(STRING), _in(STRING)))
*/
void Z3_API Z3_update_param_value(__in Z3_context c, __in Z3_string param_id, __in Z3_string param_value);
/**
- \brief Get a configuration parameter.
+ \brief Return the value of a context parameter.
- Returns \mlonly \c None \endmlonly \conly \c Z3_FALSE
- if the parameter value does not exist.
-
- \conly \sa Z3_mk_config
- \conly \sa Z3_set_param_value
- \mlonly \sa Z3_mk_context \endmlonly
+ \sa Z3_global_param_get
def_API('Z3_get_param_value', BOOL, (_in(CONTEXT), _in(STRING), _out(STRING)))
*/
@@ -1663,7 +1718,7 @@ extern "C" {
use the APIs for creating numerals and pass a numeric
constant together with the sort returned by this call.
- \sa Z3_get_finite_domain_sort_size.
+ \sa Z3_get_finite_domain_sort_size
def_API('Z3_mk_finite_domain_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT64)))
*/
diff --git a/src/api/z3_replayer.cpp b/src/api/z3_replayer.cpp
index b41ef876c..079516145 100644
--- a/src/api/z3_replayer.cpp
+++ b/src/api/z3_replayer.cpp
@@ -232,8 +232,11 @@ struct z3_replayer::imp {
}
void read_ptr() {
- if (!(('0' <= curr() && curr() <= '9') || ('A' <= curr() && curr() <= 'F') || ('a' <= curr() && curr() <= 'f')))
+ if (!(('0' <= curr() && curr() <= '9') || ('A' <= curr() && curr() <= 'F') || ('a' <= curr() && curr() <= 'f'))) {
+ TRACE("invalid_ptr", tout << "curr: " << curr() << "\n";);
throw z3_replayer_exception("invalid ptr");
+ }
+ unsigned pos = 0;
m_ptr = 0;
while (true) {
char c = curr();
@@ -246,10 +249,13 @@ struct z3_replayer::imp {
else if ('A' <= c && c <= 'F') {
m_ptr = m_ptr * 16 + 10 + (c - 'A');
}
+ else if (pos == 1 && (c == 'x' || c == 'X')) {
+ // support for 0x.... notation
+ }
else {
return;
}
- next();
+ next(); pos++;
}
}
diff --git a/src/ast/array_decl_plugin.h b/src/ast/array_decl_plugin.h
index bd1e123e3..68c473560 100644
--- a/src/ast/array_decl_plugin.h
+++ b/src/ast/array_decl_plugin.h
@@ -144,7 +144,21 @@ public:
bool is_map(expr* n) const { return is_app_of(n, m_fid, OP_ARRAY_MAP); }
bool is_as_array(expr * n) const { return is_app_of(n, m_fid, OP_AS_ARRAY); }
bool is_as_array_tree(expr * n);
+ bool is_select(func_decl* f) const { return is_decl_of(f, m_fid, OP_SELECT); }
+ bool is_store(func_decl* f) const { return is_decl_of(f, m_fid, OP_STORE); }
+ bool is_const(func_decl* f) const { return is_decl_of(f, m_fid, OP_CONST_ARRAY); }
+ bool is_map(func_decl* f) const { return is_decl_of(f, m_fid, OP_ARRAY_MAP); }
+ bool is_as_array(func_decl* f) const { return is_decl_of(f, m_fid, OP_AS_ARRAY); }
func_decl * get_as_array_func_decl(app * n) const { SASSERT(is_as_array(n)); return to_func_decl(n->get_decl()->get_parameter(0).get_ast()); }
+
+ app * mk_store(unsigned num_args, expr * const * args) {
+ return m_manager.mk_app(m_fid, OP_STORE, 0, 0, num_args, args);
+ }
+
+ app * mk_select(unsigned num_args, expr * const * args) {
+ return m_manager.mk_app(m_fid, OP_SELECT, 0, 0, num_args, args);
+ }
+
app * mk_map(func_decl * f, unsigned num_args, expr * const * args) {
parameter p(f);
return m_manager.mk_app(m_fid, OP_ARRAY_MAP, 1, &p, num_args, args);
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 3c98dca33..ae82dcadf 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -1196,13 +1196,36 @@ decl_plugin * user_sort_plugin::mk_fresh() {
//
// -----------------------------------
-ast_manager::ast_manager(proof_gen_mode m, std::ostream *trace_stream, bool is_format_manager):
+ast_manager::ast_manager(proof_gen_mode m, char const * trace_file, bool is_format_manager):
m_alloc("ast_manager"),
m_expr_array_manager(*this, m_alloc),
m_expr_dependency_manager(*this, m_alloc),
m_expr_dependency_array_manager(*this, m_alloc),
m_proof_mode(m),
- m_trace_stream(trace_stream) {
+ m_trace_stream(0),
+ m_trace_stream_owner(false) {
+
+ if (trace_file) {
+ m_trace_stream = alloc(std::fstream, trace_file, std::ios_base::out);
+ m_trace_stream_owner = true;
+ }
+
+ if (!is_format_manager)
+ m_format_manager = alloc(ast_manager, PGM_DISABLED, m_trace_stream, true);
+ else
+ m_format_manager = 0;
+ init();
+}
+
+ast_manager::ast_manager(proof_gen_mode m, std::fstream * trace_stream, bool is_format_manager):
+ m_alloc("ast_manager"),
+ m_expr_array_manager(*this, m_alloc),
+ m_expr_dependency_manager(*this, m_alloc),
+ m_expr_dependency_array_manager(*this, m_alloc),
+ m_proof_mode(m),
+ m_trace_stream(trace_stream),
+ m_trace_stream_owner(false) {
+
if (!is_format_manager)
m_format_manager = alloc(ast_manager, PGM_DISABLED, trace_stream, true);
else
@@ -1216,9 +1239,10 @@ ast_manager::ast_manager(ast_manager const & src, bool disable_proofs):
m_expr_dependency_manager(*this, m_alloc),
m_expr_dependency_array_manager(*this, m_alloc),
m_proof_mode(disable_proofs ? PGM_DISABLED : src.m_proof_mode),
- m_trace_stream(src.m_trace_stream) {
+ m_trace_stream(src.m_trace_stream),
+ m_trace_stream_owner(false) {
SASSERT(!src.is_format_manager());
- m_format_manager = 0;
+ m_format_manager = alloc(ast_manager, PGM_DISABLED, m_trace_stream, true);
init();
copy_families_plugins(src);
}
@@ -1256,6 +1280,7 @@ void ast_manager::init() {
ast_manager::~ast_manager() {
SASSERT(is_format_manager() || !m_family_manager.has_family(symbol("format")));
+
dec_ref(m_bool_sort);
dec_ref(m_proof_sort);
dec_ref(m_true);
@@ -1294,6 +1319,13 @@ ast_manager::~ast_manager() {
#endif
if (m_format_manager != 0)
dealloc(m_format_manager);
+ if (m_trace_stream_owner) {
+ std::fstream & tmp = * m_trace_stream;
+ tmp << "[eof]\n";
+ tmp.close();
+ dealloc(m_trace_stream);
+ m_trace_stream = 0;
+ }
}
void ast_manager::compact_memory() {
@@ -1873,8 +1905,8 @@ app * ast_manager::mk_app_core(func_decl * decl, unsigned num_args, expr * const
new_node = new (mem) app(decl, num_args, args);
r = register_node(new_node);
}
-#ifndef SMTCOMP
- if (m_trace_stream != NULL && r == new_node) {
+
+ if (m_trace_stream && r == new_node) {
*m_trace_stream << "[mk-app] #" << r->get_id() << " ";
if (r->get_num_args() == 0 && r->get_decl()->get_name() == "int") {
ast_ll_pp(*m_trace_stream, *this, r);
@@ -1887,7 +1919,7 @@ app * ast_manager::mk_app_core(func_decl * decl, unsigned num_args, expr * const
*m_trace_stream << "\n";
}
}
-#endif
+
return r;
}
@@ -2064,8 +2096,7 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort *
num_no_patterns, no_patterns);
quantifier * r = register_node(new_node);
-#ifndef SMTCOMP
- if (m_trace_stream != NULL && r == new_node) {
+ if (m_trace_stream && r == new_node) {
*m_trace_stream << "[mk-quant] #" << r->get_id() << " " << qid;
for (unsigned i = 0; i < num_patterns; ++i) {
*m_trace_stream << " #" << patterns[i]->get_id();
@@ -2073,7 +2104,7 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort *
*m_trace_stream << " #" << body->get_id() << "\n";
}
-#endif
+
return r;
}
@@ -2637,12 +2668,13 @@ proof * ast_manager::mk_unit_resolution(unsigned num_proofs, proof * const * pro
ptr_buffer args;
args.append(num_proofs, (expr**) proofs);
expr * fact;
- expr const * f1 = get_fact(proofs[0]);
- expr const * f2 = get_fact(proofs[1]);
+ expr * f1 = get_fact(proofs[0]);
+ expr * f2 = get_fact(proofs[1]);
if (num_proofs == 2 && is_complement(f1, f2)) {
fact = mk_false();
}
else {
+ CTRACE("mk_unit_resolution_bug", !is_or(f1), tout << mk_pp(f1, *this) << " " << mk_pp(f2, *this) << "\n";);
SASSERT(is_or(f1));
ptr_buffer new_lits;
app const * cls = to_app(f1);
diff --git a/src/ast/ast.h b/src/ast/ast.h
index 8453598f2..2a0872721 100644
--- a/src/ast/ast.h
+++ b/src/ast/ast.h
@@ -1350,7 +1350,8 @@ protected:
unsigned m_fresh_id;
bool m_debug_ref_count;
u_map m_debug_free_indices;
- std::ostream* m_trace_stream;
+ std::fstream* m_trace_stream;
+ bool m_trace_stream_owner;
#ifdef Z3DEBUG
bool slow_not_contains(ast const * n);
#endif
@@ -1361,10 +1362,14 @@ protected:
bool coercion_needed(func_decl * decl, unsigned num_args, expr * const * args);
public:
- ast_manager(proof_gen_mode = PGM_DISABLED, std::ostream * trace_stream = NULL, bool is_format_manager = false);
+ ast_manager(proof_gen_mode = PGM_DISABLED, char const * trace_file = 0, bool is_format_manager = false);
+ ast_manager(proof_gen_mode, std::fstream * trace_stream, bool is_format_manager = false);
ast_manager(ast_manager const & src, bool disable_proofs = false);
~ast_manager();
+ bool has_trace_stream() const { return m_trace_stream != 0; }
+ std::ostream & trace_stream() { SASSERT(has_trace_stream()); return *m_trace_stream; }
+
void enable_int_real_coercions(bool f) { m_int_real_coercions = f; }
bool int_real_coercions() const { return m_int_real_coercions; }
diff --git a/src/ast/ast_pp.h b/src/ast/ast_pp.h
index d99fb7670..7e7bdfc4e 100644
--- a/src/ast/ast_pp.h
+++ b/src/ast/ast_pp.h
@@ -24,7 +24,7 @@ Revision History:
#include"ast_smt2_pp.h"
struct mk_pp : public mk_ismt2_pp {
- mk_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0):
+ mk_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0):
mk_ismt2_pp(t, m, p, indent, num_vars, var_prefix) {
}
mk_pp(ast * t, ast_manager & m, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0):
diff --git a/src/ast/ast_printer.cpp b/src/ast/ast_printer.cpp
index 33ddcb709..8d6ed91f7 100644
--- a/src/ast/ast_printer.cpp
+++ b/src/ast/ast_printer.cpp
@@ -33,14 +33,14 @@ public:
virtual void display(std::ostream & out, func_decl * f, unsigned indent = 0) const {
out << f->get_name();
}
- virtual void pp(sort * s, format_ns::format_ref & r) const { mk_smt2_format(s, env(), get_pp_default_params(), r); }
- virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), get_pp_default_params(), r); }
+ virtual void pp(sort * s, format_ns::format_ref & r) const { mk_smt2_format(s, env(), params_ref(), r); }
+ virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), params_ref(), r); }
virtual void pp(expr * n, format_ns::format_ref & r) const {
sbuffer buf;
- mk_smt2_format(n, env(), get_pp_default_params(), 0, 0, r, buf);
+ mk_smt2_format(n, env(), params_ref(), 0, 0, r, buf);
}
virtual void pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer & var_names) const {
- mk_smt2_format(n, env(), get_pp_default_params(), num_vars, var_prefix, r, var_names);
+ mk_smt2_format(n, env(), params_ref(), num_vars, var_prefix, r, var_names);
}
virtual void display(std::ostream & out, expr * n, unsigned indent, unsigned num_vars, char const * var_prefix, sbuffer & var_names) const {
NOT_IMPLEMENTED_YET();
diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp
index dcc7a1a0d..afe301ddf 100644
--- a/src/ast/ast_smt2_pp.cpp
+++ b/src/ast/ast_smt2_pp.cpp
@@ -24,6 +24,7 @@ Revision History:
#include"ast_ll_pp.h"
#include"ast_pp.h"
#include"algebraic_numbers.h"
+#include"pp_params.hpp"
using namespace format_ns;
#define ALIAS_PREFIX "a"
@@ -376,7 +377,6 @@ typedef app_ref_vector format_ref_vector;
class smt2_printer {
ast_manager & m_manager;
- pp_params const & m_params;
smt2_pp_environment & m_env;
shared_occs m_soccs;
@@ -421,6 +421,16 @@ class smt2_printer {
string_buffer<> m_next_name_buffer;
+ // Config
+ bool m_pp_decimal;
+ unsigned m_pp_decimal_precision;
+ bool m_pp_bv_lits;
+ bool m_pp_bv_neg;
+ unsigned m_pp_max_depth;
+ unsigned m_pp_min_alias_size;
+ bool m_pp_flat_assoc;
+
+
symbol next_name(char const * prefix, unsigned & idx) {
while (true) {
m_next_name_buffer.reset();
@@ -508,10 +518,10 @@ class smt2_printer {
void pp_const(app * c) {
format * f;
if (m_env.get_autil().is_numeral(c) || m_env.get_autil().is_irrational_algebraic_numeral(c)) {
- f = m_env.pp_arith_literal(c, m_params.m_pp_decimal, m_params.m_pp_decimal_precision);
+ f = m_env.pp_arith_literal(c, m_pp_decimal, m_pp_decimal_precision);
}
else if (m_env.get_bvutil().is_numeral(c)) {
- f = m_env.pp_bv_literal(c, m_params.m_pp_bv_lits, m_params.m_pp_bv_neg);
+ f = m_env.pp_bv_literal(c, m_pp_bv_lits, m_pp_bv_neg);
}
else if (m_env.get_futil().is_value(c)) {
f = m_env.pp_float_literal(c);
@@ -584,8 +594,8 @@ class smt2_printer {
m_format_stack.shrink(fr.m_spos);
m_info_stack.shrink(fr.m_spos);
if (fr.m_use_alias && m_root != t &&
- ((f_info.m_depth >= m_params.m_pp_max_depth) ||
- ((f_info.m_weight >= m_params.m_pp_min_alias_size || is_quantifier(t)) && m_soccs.is_shared(t)))) {
+ ((f_info.m_depth >= m_pp_max_depth) ||
+ ((f_info.m_weight >= m_pp_min_alias_size || is_quantifier(t)) && m_soccs.is_shared(t)))) {
symbol a = next_alias();
TRACE("smt2_pp", tout << "a: " << a << " depth: " << f_info.m_depth << ", weight: " << f_info.m_weight
<< ", lvl: " << f_info.m_lvl << " t: #" << t->get_id() << "\n" << mk_ll_pp(t, m())
@@ -602,7 +612,7 @@ class smt2_printer {
}
bool flat_assoc(app * t, frame const & fr) {
- if (!m_params.m_pp_flat_assoc)
+ if (!m_pp_flat_assoc)
return false;
func_decl * f = t->get_decl();
if (f->is_associative() && m_frame_stack.size() >= 2 && !m_soccs.is_shared(t)) {
@@ -943,9 +953,8 @@ class smt2_printer {
}
public:
- smt2_printer(smt2_pp_environment & env, pp_params const & params):
+ smt2_printer(smt2_pp_environment & env, params_ref const & params):
m_manager(env.get_manager()),
- m_params(params),
m_env(env),
m_soccs(m_manager),
m_root(0),
@@ -953,6 +962,15 @@ public:
m_next_alias_idx(1),
m_format_stack(fm()) {
init_expr2alias_stack();
+
+ pp_params p(params);
+ m_pp_decimal = p.decimal();
+ m_pp_decimal_precision = p.decimal_precision();
+ m_pp_bv_lits = p.bv_literals();
+ m_pp_bv_neg = p.bv_neg();
+ m_pp_max_depth = p.max_depth();
+ m_pp_min_alias_size = p.min_alias_size();
+ m_pp_flat_assoc = p.flat_assoc();
}
~smt2_printer() {
@@ -1003,24 +1021,24 @@ public:
};
-void mk_smt2_format(expr * n, smt2_pp_environment & env, pp_params const & p,
+void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p,
unsigned num_vars, char const * var_prefix,
format_ref & r, sbuffer & var_names) {
smt2_printer pr(env, p);
pr(n, num_vars, var_prefix, r, var_names);
}
-void mk_smt2_format(sort * s, smt2_pp_environment & env, pp_params const & p, format_ref & r) {
+void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, format_ref & r) {
smt2_printer pr(env, p);
pr(s, r);
}
-void mk_smt2_format(func_decl * f, smt2_pp_environment & env, pp_params const & p, format_ref & r) {
+void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ref & r) {
smt2_printer pr(env, p);
pr(f, r);
}
-std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, pp_params const & p, unsigned indent,
+std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p, unsigned indent,
unsigned num_vars, char const * var_prefix) {
ast_manager & m = env.get_manager();
format_ref r(fm(m));
@@ -1032,7 +1050,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & e
return out;
}
-std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, pp_params const & p, unsigned indent) {
+std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p, unsigned indent) {
ast_manager & m = env.get_manager();
format_ref r(fm(m));
sbuffer var_names;
@@ -1043,7 +1061,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & e
return out;
}
-std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, pp_params const & p, unsigned indent) {
+std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p, unsigned indent) {
ast_manager & m = env.get_manager();
format_ref r(fm(m));
sbuffer var_names;
@@ -1054,7 +1072,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environmen
return out;
}
-mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent, unsigned num_vars, char const * var_prefix):
+mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent, unsigned num_vars, char const * var_prefix):
m_ast(t),
m_manager(m),
m_params(p),
@@ -1066,7 +1084,7 @@ mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned
mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, unsigned indent, unsigned num_vars, char const * var_prefix):
m_ast(t),
m_manager(m),
- m_params(get_pp_default_params()),
+ m_params(m_empty),
m_indent(indent),
m_num_vars(num_vars),
m_var_prefix(var_prefix) {
diff --git a/src/ast/ast_smt2_pp.h b/src/ast/ast_smt2_pp.h
index 048dd8d67..aa84d6e03 100644
--- a/src/ast/ast_smt2_pp.h
+++ b/src/ast/ast_smt2_pp.h
@@ -23,7 +23,7 @@ Revision History:
#define _AST_SMT2_PP_H_
#include"format.h"
-#include"pp_params.h"
+#include"params.h"
#include"arith_decl_plugin.h"
#include"bv_decl_plugin.h"
#include"array_decl_plugin.h"
@@ -82,28 +82,29 @@ public:
virtual bool uses(symbol const & s) const { return false; }
};
-void mk_smt2_format(expr * n, smt2_pp_environment & env, pp_params const & p,
+void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p,
unsigned num_vars, char const * var_prefix,
format_ns::format_ref & r, sbuffer & var_names);
-void mk_smt2_format(sort * s, smt2_pp_environment & env, pp_params const & p, format_ns::format_ref & r);
-void mk_smt2_format(func_decl * f, smt2_pp_environment & env, pp_params const & p, format_ns::format_ref & r);
+void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r);
+void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r);
-std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0,
+std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0,
unsigned num_vars = 0, char const * var_prefix = 0);
-std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0);
-std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0);
+std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0);
+std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0);
/**
\brief Internal wrapper (for debugging purposes only)
*/
struct mk_ismt2_pp {
- ast * m_ast;
- ast_manager & m_manager;
- pp_params const & m_params;
- unsigned m_indent;
- unsigned m_num_vars;
- char const * m_var_prefix;
- mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0);
+ ast * m_ast;
+ ast_manager & m_manager;
+ params_ref m_empty;
+ params_ref const & m_params;
+ unsigned m_indent;
+ unsigned m_num_vars;
+ char const * m_var_prefix;
+ mk_ismt2_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0);
mk_ismt2_pp(ast * t, ast_manager & m, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0);
};
diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp
index 713727f05..78a1caf68 100644
--- a/src/ast/ast_smt_pp.cpp
+++ b/src/ast/ast_smt_pp.cpp
@@ -67,8 +67,13 @@ symbol smt_renaming::fix_symbol(symbol s, int k) {
buffer << s << k;
return symbol(buffer.str().c_str());
}
-
- buffer << mk_smt2_quoted_symbol(s);
+
+ if (is_smt2_quoted_symbol(s)) {
+ buffer << mk_smt2_quoted_symbol(s);
+ }
+ else {
+ buffer << s;
+ }
if (k > 0) {
buffer << k;
}
@@ -949,6 +954,10 @@ public:
mark.mark(s, true);
}
+ void operator()(sort* s) {
+ ast_mark mark;
+ pp_sort_decl(mark, s);
+ }
void operator()(func_decl* d) {
if (m_is_smt2) {
@@ -962,7 +971,6 @@ public:
m_out << ") ";
visit_sort(d->get_range());
m_out << ")";
- newline();
}
else {
m_out << "(";
@@ -1021,6 +1029,22 @@ void ast_smt_pp::display_expr_smt2(std::ostream& strm, expr* n, unsigned indent,
p(n);
}
+void ast_smt_pp::display_ast_smt2(std::ostream& strm, ast* a, unsigned indent, unsigned num_var_names, char const* const* var_names) {
+ ptr_vector ql;
+ smt_renaming rn;
+ smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, indent, num_var_names, var_names);
+ if (is_expr(a)) {
+ p(to_expr(a));
+ }
+ else if (is_func_decl(a)) {
+ p(to_func_decl(a));
+ }
+ else {
+ SASSERT(is_sort(a));
+ p(to_sort(a));
+ }
+}
+
void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
ptr_vector ql;
@@ -1071,6 +1095,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
if (!(*m_is_declared)(d)) {
smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0);
p(d);
+ strm << "\n";
}
}
@@ -1079,6 +1104,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
if (!(*m_is_declared)(d)) {
smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0);
p(d);
+ strm << "\n";
}
}
diff --git a/src/ast/ast_smt_pp.h b/src/ast/ast_smt_pp.h
index 36d4ced2e..97527759a 100644
--- a/src/ast/ast_smt_pp.h
+++ b/src/ast/ast_smt_pp.h
@@ -79,22 +79,23 @@ public:
void display_smt2(std::ostream& strm, expr* n);
void display_expr(std::ostream& strm, expr* n);
void display_expr_smt2(std::ostream& strm, expr* n, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0);
+ void display_ast_smt2(std::ostream& strm, ast* n, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0);
};
struct mk_smt_pp {
- expr * m_expr;
+ ast* m_ast;
ast_manager& m_manager;
unsigned m_indent;
unsigned m_num_var_names;
char const* const* m_var_names;
- mk_smt_pp(expr* e, ast_manager & m, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0) :
- m_expr(e), m_manager(m), m_indent(indent), m_num_var_names(num_var_names), m_var_names(var_names) {}
+ mk_smt_pp(ast* e, ast_manager & m, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0) :
+ m_ast(e), m_manager(m), m_indent(indent), m_num_var_names(num_var_names), m_var_names(var_names) {}
};
inline std::ostream& operator<<(std::ostream& out, const mk_smt_pp & p) {
ast_smt_pp pp(p.m_manager);
- pp.display_expr_smt2(out, p.m_expr, p.m_indent, p.m_num_var_names, p.m_var_names);
+ pp.display_ast_smt2(out, p.m_ast, p.m_indent, p.m_num_var_names, p.m_var_names);
return out;
}
diff --git a/src/ast/dl_decl_plugin.cpp b/src/ast/dl_decl_plugin.cpp
index 76f34f316..5b73f944a 100644
--- a/src/ast/dl_decl_plugin.cpp
+++ b/src/ast/dl_decl_plugin.cpp
@@ -44,8 +44,7 @@ namespace datalog {
m_num_sym("N"),
m_lt_sym("<"),
m_le_sym("<="),
- m_rule_sym("R"),
- m_hyper_resolve_sym("hyper-res")
+ m_rule_sym("R")
{
}
diff --git a/src/ast/dl_decl_plugin.h b/src/ast/dl_decl_plugin.h
index 6e824b639..32e3c6da9 100644
--- a/src/ast/dl_decl_plugin.h
+++ b/src/ast/dl_decl_plugin.h
@@ -69,7 +69,6 @@ namespace datalog {
symbol m_lt_sym;
symbol m_le_sym;
symbol m_rule_sym;
- symbol m_hyper_resolve_sym;
bool check_bounds(char const* msg, unsigned low, unsigned up, unsigned val) const;
bool check_domain(unsigned low, unsigned up, unsigned val) const;
@@ -93,7 +92,6 @@ namespace datalog {
func_decl * mk_compare(decl_kind k, symbol const& sym, sort*const* domain);
func_decl * mk_clone(sort* r);
func_decl * mk_rule(unsigned arity);
- func_decl * mk_hyper_res(unsigned num_params, parameter const* params, unsigned arity, sort *const* domain);
sort * mk_finite_sort(unsigned num_params, parameter const* params);
sort * mk_relation_sort(unsigned num_params, parameter const* params);
diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp
index 7cf8f32bd..dbe7d5232 100644
--- a/src/ast/float_decl_plugin.cpp
+++ b/src/ast/float_decl_plugin.cpp
@@ -348,13 +348,13 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
// When the bv_decl_plugin is installed, then we know how to convert 3 bit-vectors into a float!
sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1);
symbol name("asFloat");
- return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
- }
+ return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
+ }
else {
// .. Otherwise we only know how to convert rationals/reals.
if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
m_manager->raise_exception("expecting two integer parameters to asFloat");
- if (arity != 2 && arity != 3)
+ if (arity != 2 && arity != 3)
m_manager->raise_exception("invalid number of arguments to asFloat operator");
if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
m_manager->raise_exception("sort mismatch");
@@ -373,6 +373,23 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
}
}
+func_decl * float_decl_plugin::mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters,
+ unsigned arity, sort * const * domain, sort * range) {
+ if (!m_bv_plugin)
+ m_manager->raise_exception("asIEEEBV unsupported; use a logic with BV support");
+ if (arity != 1)
+ m_manager->raise_exception("invalid number of arguments to asIEEEBV");
+ if (!is_float_sort(domain[0]))
+ m_manager->raise_exception("sort mismatch");
+
+ // When the bv_decl_plugin is installed, then we know how to convert a float to an IEEE bit-vector.
+ unsigned float_sz = domain[0]->get_parameter(0).get_int() + domain[0]->get_parameter(1).get_int();
+ parameter ps[] = { parameter(float_sz) };
+ sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps);
+ symbol name("asIEEEBV");
+ return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters));
+}
+
func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range) {
switch (k) {
@@ -420,6 +437,8 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
return mk_rm_unary_decl(k, num_parameters, parameters, arity, domain, range);
case OP_FLOAT_FUSED_MA:
return mk_fused_ma(k, num_parameters, parameters, arity, domain, range);
+ case OP_TO_IEEE_BV:
+ return mk_to_ieee_bv(k, num_parameters, parameters, arity, domain, range);
default:
m_manager->raise_exception("unsupported floating point operator");
return 0;
@@ -462,7 +481,10 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co
op_names.push_back(builtin_name("min", OP_FLOAT_MIN));
op_names.push_back(builtin_name("max", OP_FLOAT_MAX));
- op_names.push_back(builtin_name("asFloat", OP_TO_FLOAT));
+ op_names.push_back(builtin_name("asFloat", OP_TO_FLOAT));
+
+ if (m_bv_plugin)
+ op_names.push_back(builtin_name("asIEEEBV", OP_TO_IEEE_BV));
}
void float_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) {
diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h
index 416275306..c4503349b 100644
--- a/src/ast/float_decl_plugin.h
+++ b/src/ast/float_decl_plugin.h
@@ -67,6 +67,7 @@ enum float_op_kind {
OP_FLOAT_IS_SIGN_MINUS,
OP_TO_FLOAT,
+ OP_TO_IEEE_BV,
LAST_FLOAT_OP
};
@@ -118,6 +119,8 @@ class float_decl_plugin : public decl_plugin {
unsigned arity, sort * const * domain, sort * range);
func_decl * mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range);
+ func_decl * mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters,
+ unsigned arity, sort * const * domain, sort * range);
virtual void set_manager(ast_manager * m, family_id id);
unsigned mk_id(mpf const & v);
@@ -159,7 +162,7 @@ class float_util {
ast_manager & m_manager;
float_decl_plugin * m_plugin;
family_id m_fid;
- arith_util m_a_util;
+ arith_util m_a_util;
public:
float_util(ast_manager & m);
~float_util();
@@ -209,7 +212,7 @@ public:
bool is_to_float(expr * n) { return is_app_of(n, m_fid, OP_TO_FLOAT); }
- app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_TO_FLOAT, arg1, arg2); }
+ app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_TO_FLOAT, arg1, arg2); }
app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_ADD, arg1, arg2, arg3); }
app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); }
app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); }
@@ -238,6 +241,8 @@ public:
app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_SIGN_MINUS, arg1); }
bool is_uminus(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_UMINUS); }
+
+ app * mk_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_TO_IEEE_BV, arg1); }
};
#endif
diff --git a/src/ast/normal_forms/cnf.cpp b/src/ast/normal_forms/cnf.cpp
deleted file mode 100644
index d454c7f00..000000000
--- a/src/ast/normal_forms/cnf.cpp
+++ /dev/null
@@ -1,524 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- cnf.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-23.
-
-Revision History:
-
---*/
-#include"cnf.h"
-#include"var_subst.h"
-#include"ast_util.h"
-#include"ast_pp.h"
-#include"ast_ll_pp.h"
-
-unsigned cnf_entry::hash() const {
- unsigned a = m_node->get_id();
- unsigned b = m_polarity;
- unsigned c = m_in_q;
- mix(a,b,c);
- return c;
-}
-
-bool cnf_entry::operator==(cnf_entry const & k) const {
- return m_node == k.m_node && m_polarity == k.m_polarity && m_in_q == k.m_in_q;
-}
-
-cnf_cache::cnf_cache(ast_manager & m):
- m_manager(m) {
-}
-
-void cnf_cache::insert(cnf_entry const & k, expr * r, proof * pr) {
- SASSERT(!m_cache.contains(k));
- m_manager.inc_ref(r);
- m_manager.inc_ref(pr);
- m_cache.insert(k, expr_proof_pair(r, pr));
-}
-
-void cnf_cache::reset() {
- cache::iterator it = m_cache.begin();
- cache::iterator end = m_cache.end();
- for (; it != end; ++it) {
- expr_proof_pair & pair = (*it).m_value;
- m_manager.dec_ref(pair.first);
- m_manager.dec_ref(pair.second);
- }
- m_cache.reset();
-}
-
-void cnf::cache_result(expr * e, bool in_q, expr * r, proof * pr) {
- SASSERT(r);
- TRACE("cnf", tout << "caching result for: " << e->get_id() << " " << r->get_id() << "\n";);
- m_cache.insert(cnf_entry(e, true, in_q), r, pr);
-}
-
-void cnf::visit(expr * n, bool in_q, bool & visited) {
- if (!is_cached(n, in_q)) {
- m_todo.push_back(std::make_pair(n, in_q));
- visited = false;
- }
-}
-
-bool cnf::visit_children(expr * n, bool in_q) {
- bool visited = true;
- switch(n->get_kind()) {
- case AST_APP:
- if (m_manager.is_or(n) || m_manager.is_and(n) || m_manager.is_label(n)) {
- unsigned j = to_app(n)->get_num_args();
- while (j > 0) {
- --j;
- visit(to_app(n)->get_arg(j), in_q, visited);
- }
- }
- break;
- case AST_QUANTIFIER:
- visit(to_quantifier(n)->get_expr(), true, visited);
- break;
- default:
- break;
- }
- return visited;
-}
-
-void cnf::reduce1(expr * n, bool in_q) {
- switch(n->get_kind()) {
- case AST_APP:
- if (m_manager.is_or(n))
- reduce1_or(to_app(n), in_q);
- else if (m_manager.is_and(n))
- reduce1_and(to_app(n), in_q);
- else if (m_manager.is_label(n))
- reduce1_label(to_app(n), in_q);
- else
- cache_result(n, in_q, n, 0);
- break;
- case AST_QUANTIFIER:
- reduce1_quantifier(to_quantifier(n), in_q);
- break;
- default:
- cache_result(n, in_q, n, 0);
- break;
- }
-}
-
-void cnf::get_args(app * n, bool in_q, ptr_buffer & new_args, ptr_buffer & new_arg_prs) {
- unsigned num = n->get_num_args();
- for (unsigned i = 0; i < num; i++) {
- expr * new_arg = 0;
- proof * new_arg_pr = 0;
- get_cached(n->get_arg(i), in_q, new_arg, new_arg_pr);
- SASSERT(new_arg);
- new_args.push_back(new_arg);
- if (new_arg_pr)
- new_arg_prs.push_back(new_arg_pr);
- }
-}
-
-void cnf::flat_args(func_decl * d, ptr_buffer const & args, ptr_buffer & flat_args) {
- ptr_buffer::const_iterator it = args.begin();
- ptr_buffer::const_iterator end = args.end();
- for (; it != end; ++it) {
- expr * arg = *it;
- if (is_app_of(arg, d))
- flat_args.append(to_app(arg)->get_num_args(), to_app(arg)->get_args());
- else
- flat_args.push_back(arg);
- }
-}
-
-/**
- \brief Return the approximated size of distributing OR over AND on
- (OR args[0] .... args[sz-1])
-*/
-approx_nat cnf::approx_result_size_for_disj(ptr_buffer const & args) {
- approx_nat r(1);
- ptr_buffer::const_iterator it = args.begin();
- ptr_buffer::const_iterator end = args.end();
- for (; it != end; ++it) {
- expr * arg = *it;
- if (m_manager.is_and(arg))
- r *= to_app(arg)->get_num_args();
- }
- return r;
-}
-
-/**
- \brief Return true if it is too expensive to process the disjunction of args
-*/
-inline bool cnf::is_too_expensive(approx_nat approx_result_size, ptr_buffer const & args) {
- // (OR A (AND B C)) is always considered cheap.
- if (args.size() == 2 && (!m_manager.is_and(args[0]) || !m_manager.is_and(args[1])))
- return false;
- return !(approx_result_size < m_params.m_cnf_factor);
-}
-
-/**
- \brief Create a (positive) name for the expressions of the form (AND ...) in args.
- Store the result in new_args.
-*/
-void cnf::name_args(ptr_buffer const & args, expr_ref_buffer & new_args, proof_ref_buffer & new_arg_prs) {
- ptr_buffer::const_iterator it = args.begin();
- ptr_buffer::const_iterator end = args.end();
- for (; it != end; ++it) {
- expr * arg = *it;
- if (m_manager.is_and(arg)) {
- expr_ref new_def(m_manager);
- proof_ref new_def_pr(m_manager);
- app_ref new_arg(m_manager);
- proof_ref new_arg_pr(m_manager);
-
- if (m_defined_names.mk_pos_name(to_app(arg), new_def, new_def_pr, new_arg, new_arg_pr)) {
- m_todo_defs.push_back(new_def);
- if (m_manager.proofs_enabled())
- m_todo_proofs.push_back(new_def_pr);
- }
- new_args.push_back(new_arg);
-
- if (m_manager.fine_grain_proofs())
- new_arg_prs.push_back(new_arg_pr);
- else
- m_coarse_proofs.push_back(new_arg_pr);
- }
- else
- new_args.push_back(arg);
- }
-}
-
-void cnf::distribute(app * n, app * & r, proof * & pr) {
- SASSERT(m_manager.is_or(n));
- buffer sz;
- buffer it;
- ptr_buffer new_args;
- unsigned num = n->get_num_args();
- for (unsigned i = 0; i < num; i++) {
- expr * arg = n->get_arg(i);
- it.push_back(0);
- if (m_manager.is_and(arg))
- sz.push_back(to_app(arg)->get_num_args());
- else
- sz.push_back(1);
- }
-
- do {
- ptr_buffer lits;
- for (unsigned i = 0; i < num; i++) {
- expr * arg = n->get_arg(i);
- if (m_manager.is_and(arg)) {
- SASSERT(it[i] < to_app(arg)->get_num_args());
- lits.push_back(to_app(arg)->get_arg(it[i]));
- }
- else {
- SASSERT(it[i] == 0);
- lits.push_back(arg);
- }
- }
- app * n = m_manager.mk_or(lits.size(), lits.c_ptr());
- new_args.push_back(n);
- }
- while (product_iterator_next(sz.size(), sz.c_ptr(), it.c_ptr()));
- SASSERT(!new_args.empty());
- if (new_args.size() == 1)
- r = to_app(new_args[0]);
- else
- r = m_manager.mk_and(new_args.size(), new_args.c_ptr());
- pr = 0;
- if (m_manager.fine_grain_proofs() && r != n)
- pr = m_manager.mk_iff_oeq(m_manager.mk_distributivity(n, r));
-}
-
-void cnf::push_quant(quantifier * q, expr * & r, proof * & pr) {
- SASSERT(is_forall(q));
- expr * e = q->get_expr();
- pr = 0;
- if (m_manager.is_and(e)) {
- expr_ref_buffer new_args(m_manager);
- unsigned num = to_app(e)->get_num_args();
- for (unsigned i = 0; i < num; i++) {
- quantifier_ref aux(m_manager);
- aux = m_manager.update_quantifier(q, 0, 0, 0, 0, to_app(e)->get_arg(i));
- expr_ref new_arg(m_manager);
- elim_unused_vars(m_manager, aux, new_arg);
- new_args.push_back(new_arg);
- }
- r = m_manager.mk_and(new_args.size(), new_args.c_ptr());
- if (m_manager.fine_grain_proofs())
- pr = m_manager.mk_iff_oeq(m_manager.mk_push_quant(q, r));
- }
- else {
- r = q;
- }
-}
-
-void cnf::reduce1_or(app * n, bool in_q) {
- ptr_buffer new_args;
- ptr_buffer new_arg_prs;
- get_args(n, in_q, new_args, new_arg_prs);
- expr * r;
- proof * pr = 0;
- if (in_q || m_params.m_cnf_mode == CNF_OPPORTUNISTIC || m_params.m_cnf_mode == CNF_FULL) {
- ptr_buffer f_args;
- flat_args(n->get_decl(), new_args, f_args);
- TRACE("cnf_or", for (unsigned i = 0; i < f_args.size(); i++) tout << mk_pp(f_args[i], m_manager) << "\n";);
- approx_nat result_size = approx_result_size_for_disj(f_args);
- TRACE("cnf_or", tout << mk_pp(n, m_manager) << "\napprox. result: " << result_size << "\n";);
- if (m_params.m_cnf_mode != CNF_OPPORTUNISTIC || result_size < m_params.m_cnf_factor) {
- expr_ref_buffer cheap_args(m_manager);
- proof_ref_buffer cheap_args_pr(m_manager);
- if (is_too_expensive(result_size, f_args)) {
- name_args(f_args, cheap_args, cheap_args_pr);
- }
- else {
- cheap_args.append(f_args.size(), f_args.c_ptr());
- }
-
- app_ref r1(m_manager);
- r1 = m_manager.mk_or(cheap_args.size(), cheap_args.c_ptr());
-
- // Proof gen support ---------------------------
- // r1 is (OR cheap_args) it is only built if proofs are enabled.
- // p1 is a proof for (= n r1)
- proof * p1 = 0;
- if (m_manager.fine_grain_proofs()) {
- proof * prs[3];
- app * r[2];
- r[0] = m_manager.mk_or(new_args.size(), new_args.c_ptr());
- prs[0] = n == r[0] ? 0 : m_manager.mk_oeq_congruence(n, r[0], new_arg_prs.size(), new_arg_prs.c_ptr());
- r[1] = m_manager.mk_or(f_args.size(), f_args.c_ptr());
- prs[1] = r[0] == r[1] ? 0 : m_manager.mk_iff_oeq(m_manager.mk_rewrite(r[0], r[1]));
- prs[2] = r[1] == r1 ? 0 : m_manager.mk_oeq_congruence(r[1], r1, cheap_args_pr.size(), cheap_args_pr.c_ptr());
- p1 = m_manager.mk_transitivity(3, prs);
- }
- // --------------------------------------------
-
- expr_ref r2(m_manager);
- proof_ref p2(m_manager);
- m_pull.pull_quant2(r1, r2, p2);
-
- if (is_quantifier(r2)) {
- expr * e = to_quantifier(r2)->get_expr();
- SASSERT(m_manager.is_or(e));
- app * d_r;
- proof * d_pr;
- distribute(to_app(e), d_r, d_pr);
- quantifier_ref r3(m_manager);
- r3 = m_manager.update_quantifier(to_quantifier(r2), d_r);
- proof * push_pr;
- push_quant(r3, r, push_pr);
- if (m_manager.fine_grain_proofs()) {
- // p1 is a proof of n == r1
- // p2 is a proof of r1 == r2
- p2 = p2 == 0 ? 0 : m_manager.mk_iff_oeq(p2);
- proof * p3 = r2 == r3 ? 0 : m_manager.mk_oeq_quant_intro(to_quantifier(r2), r3, d_pr);
- CTRACE("cnf_or", p1, tout << "p1:\n" << mk_pp(m_manager.get_fact(p1), m_manager) << "\n";);
- CTRACE("cnf_or", p2, tout << "p2:\n" << mk_pp(m_manager.get_fact(p2), m_manager) << "\n";);
- CTRACE("cnf_or", p3, tout << "p3:\n" << mk_pp(m_manager.get_fact(p3), m_manager) << "\n";);
- TRACE("cnf_or", tout << "r2 == r3: " << (r2 == r3) << "\n"
- << mk_pp(r2, m_manager) << "\n" << mk_pp(r3, m_manager) << "\n";);
- pr = m_manager.mk_transitivity(p1, p2, p3, push_pr);
- }
- cache_result(n, in_q, r, pr);
- }
- else {
- SASSERT(p2 == 0);
- SASSERT(r1 == r2);
- SASSERT(m_manager.is_or(r2));
- app * r3;
- distribute(to_app(r2), r3, pr);
- r = r3;
- pr = m_manager.mk_transitivity(p1, pr);
- cache_result(n, in_q, r, pr);
- }
- return;
- }
- }
-
- r = m_manager.mk_or(new_args.size(), new_args.c_ptr());
- if (m_manager.fine_grain_proofs() && n != r)
- pr = m_manager.mk_oeq_congruence(n, to_app(r), new_arg_prs.size(), new_arg_prs.c_ptr());
- cache_result(n, in_q, r, pr);
-}
-
-void cnf::reduce1_and(app * n, bool in_q) {
- ptr_buffer new_args;
- ptr_buffer new_arg_prs;
- get_args(n, in_q, new_args, new_arg_prs);
- app * r;
- proof * pr = 0;
- if (in_q || m_params.m_cnf_mode == CNF_OPPORTUNISTIC || m_params.m_cnf_mode == CNF_FULL) {
- ptr_buffer f_args;
- flat_args(n->get_decl(), new_args, f_args);
- r = m_manager.mk_and(f_args.size(), f_args.c_ptr());
- if (m_manager.fine_grain_proofs() && n != r) {
- app * r0 = m_manager.mk_and(new_args.size(), new_args.c_ptr());
- proof * p0 = r0 == n ? 0 : m_manager.mk_oeq_congruence(n, r0, new_arg_prs.size(), new_arg_prs.c_ptr());
- proof * p1 = r0 == r ? 0 : m_manager.mk_iff_oeq(m_manager.mk_rewrite(r0, r));
- pr = m_manager.mk_transitivity(p0, p1);
- }
- }
- else {
- r = m_manager.mk_and(new_args.size(), new_args.c_ptr());
- if (m_manager.fine_grain_proofs() && n != r)
- pr = m_manager.mk_oeq_congruence(n, r, new_arg_prs.size(), new_arg_prs.c_ptr());
- }
- cache_result(n, in_q, r, pr);
-}
-
-void cnf::reduce1_label(app * n, bool in_q) {
- expr * r;
- proof * pr = 0;
- expr * new_arg;
- proof * new_arg_pr;
- get_cached(n->get_arg(0), true, new_arg, new_arg_pr);
- if (in_q || m_params.m_cnf_mode == CNF_FULL) {
- // TODO: in the current implementation, labels are removed during CNF translation.
- // This is satisfactory for Boogie, since it does not use labels inside quantifiers,
- // and we only need CNF_QUANT for Superposition Calculus.
- r = new_arg;
- if (m_manager.fine_grain_proofs()) {
- proof * p0 = m_manager.mk_iff_oeq(m_manager.mk_rewrite(n, n->get_arg(0)));
- pr = m_manager.mk_transitivity(p0, new_arg_pr);
- }
- }
- else {
- r = m_manager.mk_app(n->get_decl(), new_arg);
- if (m_manager.fine_grain_proofs() && n != r)
- pr = m_manager.mk_oeq_congruence(n, to_app(r), 1, &new_arg_pr);
- }
- cache_result(n, in_q, r, pr);
-}
-
-void cnf::reduce1_quantifier(quantifier * q, bool in_q) {
- expr * new_expr;
- proof * new_expr_pr;
- get_cached(q->get_expr(), true, new_expr, new_expr_pr);
- expr_ref r(m_manager);
- proof_ref pr(m_manager);
- if (m_manager.is_and(new_expr) && q->is_forall()) {
- quantifier_ref q1(m_manager);
- q1 = m_manager.update_quantifier(q, new_expr);
- expr_ref q2(m_manager);
- proof_ref p2(m_manager);
- m_pull.pull_quant2(q1, q2, p2);
- expr * q3;
- proof * p3;
- push_quant(to_quantifier(q2), q3, p3);
- r = q3;
- if (m_manager.fine_grain_proofs()) {
- proof * p1 = q == q1 ? 0 : m_manager.mk_oeq_quant_intro(q, q1, new_expr_pr);
- p2 = p2 == 0 ? 0 : m_manager.mk_iff_oeq(p2);
- pr = m_manager.mk_transitivity(p1, p2, p3);
- }
- }
- else if ((m_manager.is_or(new_expr) || is_forall(new_expr)) && q->is_forall()) {
- quantifier_ref q1(m_manager);
- q1 = m_manager.update_quantifier(q, new_expr);
- m_pull.pull_quant2(q1, r, pr);
- if (m_manager.fine_grain_proofs()) {
- pr = pr == 0 ? 0 : m_manager.mk_iff_oeq(pr);
- proof * p1 = q == q1 ? 0 : m_manager.mk_oeq_quant_intro(q, q1, new_expr_pr);
- pr = m_manager.mk_transitivity(p1, pr);
- }
- }
- else {
- r = m_manager.update_quantifier(q, new_expr);
- if (m_manager.fine_grain_proofs() && r != q)
- pr = q == r ? 0 : m_manager.mk_oeq_quant_intro(q, to_quantifier(r), new_expr_pr);
- }
-
- cache_result(q, in_q, r, pr);
- TRACE("cnf_quant", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";);
-}
-
-cnf::cnf(ast_manager & m, defined_names & n, cnf_params & params):
- m_params(params),
- m_manager(m),
- m_defined_names(n),
- m_pull(m),
- m_cache(m),
- m_todo_defs(m),
- m_todo_proofs(m),
- m_coarse_proofs(m) {
-}
-
-cnf::~cnf() {
-}
-
-void cnf::reduce(expr * n, expr_ref & r, proof_ref & pr) {
- m_coarse_proofs.reset();
- m_todo.reset();
- m_todo.push_back(expr_bool_pair(n, false));
- while (!m_todo.empty()) {
- expr_bool_pair pair = m_todo.back();
- expr * n = pair.first;
- bool in_q = pair.second;
- if (is_cached(n, in_q)) {
- m_todo.pop_back();
- }
- else if (visit_children(n, in_q)) {
- m_todo.pop_back();
- reduce1(n, in_q);
- }
- }
- expr * r2;
- proof * pr2;
- get_cached(n, false, r2, pr2);
- r = r2;
- switch (m_manager.proof_mode()) {
- case PGM_DISABLED:
- pr = m_manager.mk_undef_proof();
- break;
- case PGM_COARSE:
- remove_duplicates(m_coarse_proofs);
- pr = n == r2 ? m_manager.mk_reflexivity(n) : m_manager.mk_cnf_star(n, r2, m_coarse_proofs.size(), m_coarse_proofs.c_ptr());
- break;
- case PGM_FINE:
- pr = pr2 == 0 ? m_manager.mk_reflexivity(n) : pr2;
- break;
- }
-}
-
-void cnf::operator()(expr * n, expr_ref_vector & new_defs, proof_ref_vector & new_def_proofs, expr_ref & r, proof_ref & pr) {
- if (m_params.m_cnf_mode == CNF_DISABLED) {
- r = n;
- pr = m_manager.mk_reflexivity(n);
- return;
- }
-
- reset();
- reduce(n, r, pr);
- for (unsigned i = 0; i < m_todo_defs.size(); i++) {
- expr_ref dr(m_manager);
- proof_ref dpr(m_manager);
- reduce(m_todo_defs.get(i), dr, dpr);
- m_result_defs.push_back(dr);
- if (m_manager.proofs_enabled()) {
- proof * new_pr = m_manager.mk_modus_ponens(m_todo_proofs.get(i), dpr);
- m_result_def_proofs.push_back(new_pr);
- }
- else
- m_result_def_proofs.push_back(m_manager.mk_undef_proof());
- }
- std::reverse(m_result_defs.begin(), m_result_defs.end());
- new_defs.append(m_result_defs.size(), m_result_defs.c_ptr());
- std::reverse(m_result_def_proofs.begin(), m_result_def_proofs.end());
- new_def_proofs.append(m_result_def_proofs.size(), m_result_def_proofs.c_ptr());
-}
-
-void cnf::reset() {
- m_cache.reset();
- m_todo.reset();
- m_todo_defs.reset();
- m_todo_proofs.reset();
- m_result_defs.reset();
- m_result_def_proofs.reset();
-}
diff --git a/src/ast/normal_forms/cnf.h b/src/ast/normal_forms/cnf.h
deleted file mode 100644
index 60c2d2410..000000000
--- a/src/ast/normal_forms/cnf.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- cnf.h
-
-Abstract:
-
- CNF translation
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-17.
-
-Revision History:
-
---*/
-#ifndef _CNF_H_
-#define _CNF_H_
-
-#include"cnf_params.h"
-#include"pull_quant.h"
-#include"nnf.h"
-#include"approx_nat.h"
-
-/**
- \brief Entry into the todo list of the CNF translator. It is also used as the key in the CNF cache.
-*/
-struct cnf_entry {
- expr * m_node;
- bool m_polarity:1;
- bool m_in_q:1;
- cnf_entry():m_node(0), m_polarity(false), m_in_q(false) {}
- cnf_entry(expr * n, bool p, bool in_q):m_node(n), m_polarity(p), m_in_q(in_q) {}
- unsigned hash() const;
- bool operator==(cnf_entry const & k) const;
-};
-
-/**
- \brief Cache for CNF transformation. It is a mapping from (expr, polarity, in_q) -> (expr, proof)
-*/
-class cnf_cache {
-public:
- typedef std::pair expr_proof_pair;
-
- typedef map, default_eq > cache;
-
- ast_manager & m_manager;
- cache m_cache;
-
-public:
- cnf_cache(ast_manager & m);
- ~cnf_cache() { reset(); }
- void insert(cnf_entry const & k, expr * r, proof * pr);
- bool contains(cnf_entry const & k) const { return m_cache.contains(k); }
- void get(cnf_entry const & k, expr * & r, proof * & pr) const { expr_proof_pair tmp; m_cache.find(k, tmp); r = tmp.first; pr = tmp.second; }
- void reset();
-};
-
-/**
- \brief Functor for converting expressions into CNF. The functor can
- optionally process subformulas nested in quantifiers. New names may be
- introduced for subformulas that are too expensive to be put into CNF.
-
- NNF translation must be applied before converting to CNF.
-
- - To use CNF_QUANT, we must use at least NNF_QUANT
- - To use CNF_OPPORTUNISTIC, we must use at least NNF_QUANT
- - To use CNF_FULL, we must use NNF_FULL
-*/
-class cnf {
- typedef std::pair expr_bool_pair;
- cnf_params & m_params;
- ast_manager & m_manager;
- defined_names & m_defined_names;
- pull_quant m_pull;
- cnf_cache m_cache;
- svector m_todo;
- expr_ref_vector m_todo_defs;
- proof_ref_vector m_todo_proofs;
- ptr_vector m_result_defs;
- ptr_vector m_result_def_proofs;
- proof_ref_vector m_coarse_proofs;
-
- void cache_result(expr * e, bool in_q, expr * r, proof * pr);
- void get_cached(expr * n, bool in_q, expr * & r, proof * & pr) const { m_cache.get(cnf_entry(n, true, in_q), r, pr); }
- bool is_cached(expr * n, bool in_q) const { return m_cache.contains(cnf_entry(n, true, in_q)); }
-
- void visit(expr * n, bool in_q, bool & visited);
- bool visit_children(expr * n, bool in_q);
-
- void get_args(app * n, bool in_q, ptr_buffer & new_args, ptr_buffer & new_arg_prs);
- void flat_args(func_decl * d, ptr_buffer const & args, ptr_buffer & flat_args);
- approx_nat approx_result_size_for_disj(ptr_buffer const & args);
- bool is_too_expensive(approx_nat approx_result_size, ptr_buffer const & args);
- void name_args(ptr_buffer const & args, expr_ref_buffer & new_args, proof_ref_buffer & new_arg_prs);
- void distribute(app * arg, app * & r, proof * & pr);
- void push_quant(quantifier * q, expr * & r, proof * & pr);
- void reduce1(expr * n, bool in_q);
- void reduce1_or(app * n, bool in_q);
- void reduce1_and(app * n, bool in_q);
- void reduce1_label(app * n, bool in_q);
- void reduce1_quantifier(quantifier * q, bool in_q);
-
- void reduce(expr * n, expr_ref & r, proof_ref & pr);
-public:
- cnf(ast_manager & m, defined_names & n, cnf_params & params);
- ~cnf();
- void operator()(expr * n, // [IN] expression that should be put into CNF
- expr_ref_vector & new_defs, // [OUT] new definitions
- proof_ref_vector & new_def_proofs, // [OUT] proofs of the new definitions
- expr_ref & r, // [OUT] resultant expression
- proof_ref & p // [OUT] proof for (~ n r)
- );
-
- void reset();
-};
-
-#endif /* _CNF_H_ */
-
diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp
index 8f46139f7..c3ea69e77 100644
--- a/src/ast/normal_forms/nnf.cpp
+++ b/src/ast/normal_forms/nnf.cpp
@@ -18,6 +18,7 @@ Notes:
--*/
#include"nnf.h"
+#include"nnf_params.hpp"
#include"warning.h"
#include"used_vars.h"
#include"well_sorted.h"
@@ -29,6 +30,40 @@ Notes:
#include"ast_smt2_pp.h"
+/**
+ \brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and
+ the most expensive is NNF_FULL.
+*/
+enum nnf_mode {
+ NNF_SKOLEM, /* A subformula is put into NNF only if it contains
+ quantifiers or labels. The result of the
+ transformation will be in skolem normal form.
+ If a formula is too expensive to be put into NNF,
+ then nested quantifiers and labels are renamed.
+
+ This mode is sufficient when using E-matching.
+ */
+ NNF_QUANT, /* A subformula is put into NNF if it contains
+ quantifiers, labels, or is in the scope of a
+ quantifier. The result of the transformation will be
+ in skolem normal form, and the body of quantifiers
+ will be in NNF. If a ground formula is too expensive to
+ be put into NNF, then nested quantifiers and labels
+ are renamed.
+
+ This mode is sufficient when using Superposition
+ Calculus.
+
+ Remark: If the problem does not contain quantifiers,
+ then NNF_QUANT is identical to NNF_SKOLEM.
+ */
+ NNF_OPPORTUNISTIC, /* Similar to NNF_QUANT, but a subformula is
+ also put into NNF, if it is
+ cheap. Otherwise, the nested quantifiers and
+ labels are renamed. */
+ NNF_FULL /* Everything is put into NNF. */
+};
+
class skolemizer {
typedef act_cache cache;
@@ -112,20 +147,16 @@ class skolemizer {
}
public:
- skolemizer(ast_manager & m, params_ref const & p):
+ skolemizer(ast_manager & m):
m_manager(m),
m_sk_hack("sk_hack"),
+ m_sk_hack_enabled(false),
m_cache(m),
m_cache_pr(m) {
- updt_params(p);
}
- void updt_params(params_ref const & p) {
- m_sk_hack_enabled = p.get_bool(":nnf-sk-hack", false);
- }
-
- static void get_param_descrs(param_descrs & r) {
- r.insert(":nnf-sk-hack", CPK_BOOL, "(default: false) hack for VCC");
+ void set_sk_hack(bool f) {
+ m_sk_hack_enabled = f;
}
ast_manager & m() const { return m_manager; }
@@ -219,8 +250,6 @@ struct nnf::imp {
name_exprs * m_name_nested_formulas;
name_exprs * m_name_quant;
- symbol m_skolem;
-
volatile bool m_cancel;
unsigned long long m_max_memory; // in bytes
@@ -230,10 +259,9 @@ struct nnf::imp {
m_todo_defs(m),
m_todo_proofs(m),
m_result_pr_stack(m),
- m_skolemizer(m, p),
- m_skolem("skolem"),
+ m_skolemizer(m),
m_cancel(false) {
- updt_local_params(p);
+ updt_params(p);
for (unsigned i = 0; i < 4; i++) {
m_cache[i] = alloc(act_cache, m);
if (m.proofs_enabled())
@@ -257,14 +285,10 @@ struct nnf::imp {
del_name_exprs(m_name_quant);
}
- void updt_params(params_ref const & p) {
- updt_local_params(p);
- m_skolemizer.updt_params(p);
- }
-
- void updt_local_params(params_ref const & p) {
- symbol mode_sym = p.get_sym(":nnf-mode", m_skolem);
- if (mode_sym == m_skolem)
+ void updt_params(params_ref const & _p) {
+ nnf_params p(_p);
+ symbol mode_sym = p.mode();
+ if (mode_sym == "skolem")
m_mode = NNF_SKOLEM;
else if (mode_sym == "full")
m_mode = NNF_FULL;
@@ -272,23 +296,17 @@ struct nnf::imp {
m_mode = NNF_QUANT;
else
throw nnf_params_exception("invalid NNF mode");
+
+ TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << _p << "\n";);
- TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << p << "\n";);
-
- m_ignore_labels = p.get_bool(":nnf-ignore-labels", false);
- m_skolemize = p.get_bool(":skolemize", true);
- m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
+ m_ignore_labels = p.ignore_labels();
+ m_skolemize = p.skolemize();
+ m_max_memory = megabytes_to_bytes(p.max_memory());
+ m_skolemizer.set_sk_hack(p.sk_hack());
}
static void get_param_descrs(param_descrs & r) {
- insert_max_memory(r);
- r.insert(":nnf-mode", CPK_SYMBOL,
- "(default: skolem) NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full");
- r.insert(":nnf-ignore-labels", CPK_BOOL,
- "(default: false) remove/ignore labels in the input formula, this option is ignored if proofs are enabled");
- r.insert(":skolemize", CPK_BOOL,
- "(default: true) skolemize (existential force) quantifiers");
- skolemizer::get_param_descrs(r);
+ nnf_params::collect_param_descrs(r);
}
void reset() {
@@ -880,21 +898,6 @@ nnf::nnf(ast_manager & m, defined_names & n, params_ref const & p) {
m_imp = alloc(imp, m, n, p);
}
-nnf::nnf(ast_manager & m, defined_names & n, nnf_params & np) {
- params_ref p;
- if (np.m_nnf_mode == NNF_FULL)
- p.set_sym(":nnf-mode", symbol("full"));
- else if (np.m_nnf_mode == NNF_QUANT)
- p.set_sym(":nnf-mode", symbol("quantifiers"));
-
- if (np.m_nnf_ignore_labels)
- p.set_bool(":nnf-ignore-labels", true);
-
- if (np.m_nnf_sk_hack)
- p.set_bool(":nnf-sk-hack", true);
- m_imp = alloc(imp, m, n, p);
-}
-
nnf::~nnf() {
dealloc(m_imp);
}
diff --git a/src/ast/normal_forms/nnf.h b/src/ast/normal_forms/nnf.h
index 685083ff7..e8296e933 100644
--- a/src/ast/normal_forms/nnf.h
+++ b/src/ast/normal_forms/nnf.h
@@ -21,7 +21,6 @@ Notes:
#define _NNF_H_
#include"ast.h"
-#include"nnf_params.h"
#include"params.h"
#include"defined_names.h"
@@ -30,7 +29,6 @@ class nnf {
imp * m_imp;
public:
nnf(ast_manager & m, defined_names & n, params_ref const & p = params_ref());
- nnf(ast_manager & m, defined_names & n, nnf_params & params); // for backward compatibility
~nnf();
void operator()(expr * n, // [IN] expression that should be put into NNF
@@ -41,6 +39,9 @@ public:
);
void updt_params(params_ref const & p);
+ /*
+ REG_MODULE_PARAMS('nnf', 'nnf::get_param_descrs')
+ */
static void get_param_descrs(param_descrs & r);
void cancel() { set_cancel(true); }
diff --git a/src/ast/normal_forms/nnf_params.pyg b/src/ast/normal_forms/nnf_params.pyg
new file mode 100644
index 000000000..aac8fbb86
--- /dev/null
+++ b/src/ast/normal_forms/nnf_params.pyg
@@ -0,0 +1,9 @@
+def_module_params('nnf',
+ description='negation normal form',
+ export=True,
+ params=(max_memory_param(),
+ ('sk_hack', BOOL, False, 'hack for VCC'),
+ ('mode', SYMBOL, 'skolem',
+ 'NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full'),
+ ('ignore_labels', BOOL, False, 'remove/ignore labels in the input formula, this option is ignored if proofs are enabled'),
+ ('skolemize', BOOL, True, 'skolemize (existential force) quantifiers')))
diff --git a/src/ast/pattern/expr_pattern_match.cpp b/src/ast/pattern/expr_pattern_match.cpp
index 25be8dbf0..86cad58f8 100644
--- a/src/ast/pattern/expr_pattern_match.cpp
+++ b/src/ast/pattern/expr_pattern_match.cpp
@@ -36,7 +36,6 @@ Notes:
#include"ast_pp.h"
#include"cmd_context.h"
#include"smt2parser.h"
-#include"front_end_params.h"
expr_pattern_match::expr_pattern_match(ast_manager & manager):
m_manager(manager), m_precompiled(manager) {
@@ -388,8 +387,7 @@ expr_pattern_match::initialize(char const * spec_string) {
m_instrs.push_back(instr(BACKTRACK));
std::istringstream is(spec_string);
- front_end_params p;
- cmd_context ctx(&p, true, &m_manager);
+ cmd_context ctx(true, &m_manager);
VERIFY(parse_smt2_commands(ctx, is));
ptr_vector::const_iterator it = ctx.begin_assertions();
diff --git a/src/ast/pattern/expr_pattern_match.h b/src/ast/pattern/expr_pattern_match.h
index 45295e627..555d6a67e 100644
--- a/src/ast/pattern/expr_pattern_match.h
+++ b/src/ast/pattern/expr_pattern_match.h
@@ -22,7 +22,6 @@ Notes:
#include"ast.h"
#include"map.h"
-#include"front_end_params.h"
class expr_pattern_match {
diff --git a/src/ast/pattern/pattern_inference_params.cpp b/src/ast/pattern/pattern_inference_params.cpp
new file mode 100644
index 000000000..8adbdb9f1
--- /dev/null
+++ b/src/ast/pattern/pattern_inference_params.cpp
@@ -0,0 +1,32 @@
+/*++
+Copyright (c) 2012 Microsoft Corporation
+
+Module Name:
+
+ pattern_inference_params.h
+
+Abstract:
+
+
+
+Author:
+
+ Leonardo de Moura (leonardo) 2012-12-02.
+
+Revision History:
+
+--*/
+#include"pattern_inference_params.h"
+#include"pattern_inference_params_helper.hpp"
+
+void pattern_inference_params::updt_params(params_ref const & _p) {
+ pattern_inference_params_helper p(_p);
+ m_pi_max_multi_patterns = p.max_multi_patterns();
+ m_pi_block_loop_patterns = p.block_loop_patterns();
+ m_pi_arith = static_cast(p.arith());
+ m_pi_use_database = p.use_database();
+ m_pi_arith_weight = p.arith_weight();
+ m_pi_non_nested_arith_weight = p.non_nested_arith_weight();
+ m_pi_pull_quantifiers = p.pull_quantifiers();
+ m_pi_warnings = p.warnings();
+}
diff --git a/src/front_end_params/pattern_inference_params.h b/src/ast/pattern/pattern_inference_params.h
similarity index 74%
rename from src/front_end_params/pattern_inference_params.h
rename to src/ast/pattern/pattern_inference_params.h
index 79d7b4d87..dc9f0cb9b 100644
--- a/src/front_end_params/pattern_inference_params.h
+++ b/src/ast/pattern/pattern_inference_params.h
@@ -19,7 +19,7 @@ Revision History:
#ifndef _PATTERN_INFERENCE_PARAMS_H_
#define _PATTERN_INFERENCE_PARAMS_H_
-#include"ini_file.h"
+#include"params.h"
enum arith_pattern_inference_kind {
AP_NO, // do not infer patterns with arithmetic terms
@@ -39,20 +39,13 @@ struct pattern_inference_params {
bool m_pi_avoid_skolems;
bool m_pi_warnings;
- pattern_inference_params():
- m_pi_max_multi_patterns(0),
- m_pi_block_loop_patterns(true),
- m_pi_arith(AP_CONSERVATIVE),
- m_pi_use_database(false),
- m_pi_arith_weight(5),
- m_pi_non_nested_arith_weight(10),
- m_pi_pull_quantifiers(true),
+ pattern_inference_params(params_ref const & p = params_ref()):
m_pi_nopat_weight(-1),
- m_pi_avoid_skolems(true),
- m_pi_warnings(false) {
+ m_pi_avoid_skolems(true) {
+ updt_params(p);
}
- void register_params(ini_params & p);
+ void updt_params(params_ref const & _p);
};
#endif /* _PATTERN_INFERENCE_PARAMS_H_ */
diff --git a/src/ast/pattern/pattern_inference_params_helper.pyg b/src/ast/pattern/pattern_inference_params_helper.pyg
new file mode 100644
index 000000000..5d64e8e52
--- /dev/null
+++ b/src/ast/pattern/pattern_inference_params_helper.pyg
@@ -0,0 +1,12 @@
+def_module_params(class_name='pattern_inference_params_helper',
+ module_name='pi',
+ description='pattern inference (heuristics) for universal formulas (without annotation)',
+ export=True,
+ params=(('max_multi_patterns', UINT, 0, 'when patterns are not provided, the prover uses a heuristic to infer them, this option sets the threshold on the number of extra multi-patterns that can be created; by default, the prover creates at most one multi-pattern when there is no unary pattern'),
+ ('block_loop_patterns', BOOL, True, 'block looping patterns during pattern inference'),
+ ('arith', UINT, 1, '0 - do not infer patterns with arithmetic terms, 1 - use patterns with arithmetic terms if there is no other pattern, 2 - always use patterns with arithmetic terms'),
+ ('use_database', BOOL, True, 'use pattern database'),
+ ('arith_weight', UINT, 5, 'default weight for quantifiers where the only available pattern has nested arithmetic terms'),
+ ('non_nested_arith_weight', UINT, 10, 'default weight for quantifiers where the only available pattern has non nested arithmetic terms'),
+ ('pull_quantifiers', BOOL, True, 'pull nested quantifiers, if no pattern was found'),
+ ('warnings', BOOL, False, 'enable/disable warning messages in the pattern inference module')))
diff --git a/src/ast/pp.cpp b/src/ast/pp.cpp
index 43f19e166..13247127d 100644
--- a/src/ast/pp.cpp
+++ b/src/ast/pp.cpp
@@ -17,22 +17,9 @@ Revision History:
--*/
#include"pp.h"
+#include"pp_params.hpp"
using namespace format_ns;
-pp_params g_pp_params;
-
-void set_pp_default_params(pp_params const & p) {
- g_pp_params = p;
-}
-
-void register_pp_params(ini_params & p) {
- g_pp_params.register_params(p);
-}
-
-pp_params const & get_pp_default_params() {
- return g_pp_params;
-}
-
static std::pair space_upto_line_break(ast_manager & m, format * f) {
unsigned r;
SASSERT(f->get_family_id() == fm(m).get_family_id("format"));
@@ -69,7 +56,15 @@ inline bool fits(ast_manager & m, format * f, unsigned space_left) {
return s <= space_left;
}
-void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
+void pp(std::ostream & out, format * f, ast_manager & m, params_ref const & _p) {
+ pp_params p(_p);
+ unsigned max_width = p.max_width();
+ unsigned max_ribbon = p.max_ribbon();
+ unsigned max_num_lines = p.max_num_lines();
+ unsigned max_indent = p.max_indent();
+ bool bounded = p.bounded();
+ bool single_line = p.single_line();
+
unsigned pos = 0;
unsigned ribbon_pos = 0;
unsigned line = 0;
@@ -80,7 +75,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
todo.push_back(std::make_pair(f, 0));
app_ref space(mk_string(m, " "), fm(m));
while (!todo.empty()) {
- if (line >= p.m_pp_max_num_lines)
+ if (line >= max_num_lines)
return;
std::pair pair = todo.back();
format * f = pair.first;
@@ -89,10 +84,10 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
SASSERT(f->get_family_id() == fm(m).get_family_id("format"));
switch (f->get_decl_kind()) {
case OP_STRING:
- if (p.m_pp_bounded && pos > p.m_pp_max_width)
+ if (bounded && pos > max_width)
break;
len = static_cast(strlen(f->get_decl()->get_parameter(0).get_symbol().bare_str()));
- if (p.m_pp_bounded && pos + len > p.m_pp_max_width) {
+ if (bounded && pos + len > max_width) {
out << "...";
break;
}
@@ -103,7 +98,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
case OP_INDENT:
todo.push_back(std::make_pair(to_app(f->get_arg(0)),
std::min(indent + f->get_decl()->get_parameter(0).get_int(),
- p.m_pp_max_indent)));
+ max_indent)));
break;
case OP_COMPOSE:
i = f->get_num_args();
@@ -113,7 +108,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
}
break;
case OP_CHOICE:
- space_left = std::min(p.m_pp_max_width - pos, p.m_pp_max_ribbon - pos);
+ space_left = std::min(max_width - pos, max_ribbon - pos);
if (space_left > 0 && fits(m, to_app(f->get_arg(0)), space_left))
todo.push_back(std::make_pair(to_app(f->get_arg(0)), indent));
else
@@ -121,14 +116,14 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
break;
case OP_LINE_BREAK:
case OP_LINE_BREAK_EXT:
- if (p.m_pp_single_line) {
+ if (single_line) {
todo.push_back(std::make_pair(space, indent));
break;
}
pos = indent;
ribbon_pos = 0;
line++;
- if (line < p.m_pp_max_num_lines) {
+ if (line < max_num_lines) {
out << "\n";
for (unsigned i = 0; i < indent; i++)
out << " ";
@@ -142,7 +137,3 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) {
}
}
-void pp(std::ostream & out, format_ns::format * f, ast_manager & m) {
- pp(out, f, m, g_pp_params);
-}
-
diff --git a/src/ast/pp.h b/src/ast/pp.h
index 43c1de7b7..f567afa4a 100644
--- a/src/ast/pp.h
+++ b/src/ast/pp.h
@@ -20,15 +20,9 @@ Revision History:
#define _PP_H_
#include"format.h"
-#include"pp_params.h"
+#include"params.h"
-void set_pp_default_params(pp_params const & p);
-void register_pp_params(ini_params & p);
-
-pp_params const & get_pp_default_params();
-
-void pp(std::ostream & out, format_ns::format * f, ast_manager & m, pp_params const & p);
-void pp(std::ostream & out, format_ns::format * f, ast_manager & m);
+void pp(std::ostream & out, format_ns::format * f, ast_manager & m, params_ref const & p = params_ref());
#endif /* _PP_H_ */
diff --git a/src/ast/pp_params.cpp b/src/ast/pp_params.cpp
deleted file mode 100644
index 0cf3e455d..000000000
--- a/src/ast/pp_params.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- pp_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-20.
-
-Revision History:
-
---*/
-
-#include"pp_params.h"
-
-pp_params::pp_params():
- m_pp_max_indent(UINT_MAX),
- m_pp_max_num_lines(UINT_MAX),
- m_pp_max_width(80),
- m_pp_max_ribbon(80),
- m_pp_max_depth(5),
- m_pp_min_alias_size(10),
- m_pp_decimal(false),
- m_pp_decimal_precision(10),
- m_pp_bv_lits(true),
- m_pp_bv_neg(false),
- m_pp_flat_assoc(true),
- m_pp_fixed_indent(false),
- m_pp_single_line(false),
- m_pp_bounded(false),
- m_pp_simplify_implies(false) {
-}
-
-void pp_params::register_params(ini_params & p) {
- p.register_unsigned_param("PP_MAX_INDENT", m_pp_max_indent, "max. indentation in pretty printer", true);
- p.register_unsigned_param("PP_MAX_NUM_LINES", m_pp_max_num_lines, "max. number of lines to be displayed in pretty printer", true);
- p.register_unsigned_param("PP_MAX_WIDTH", m_pp_max_width, "max. width in pretty printer", true);
- p.register_unsigned_param("PP_MAX_RIBBON", m_pp_max_ribbon, "max. ribbon (width - indentation) in pretty printer", true);
- p.register_unsigned_param("PP_MAX_DEPTH", m_pp_max_depth, "max. term depth (when pretty printing SMT2 terms/formulas)", true);
- p.register_unsigned_param("PP_MIN_ALIAS_SIZE", m_pp_min_alias_size, "min. size for creating an alias for a shared term (when pretty printing SMT2 terms/formulas)", true);
- p.register_bool_param("PP_DECIMAL", m_pp_decimal, "pretty print real numbers using decimal notation (the output may be truncated). Z3 adds a '?' if the value is not precise", true);
- p.register_unsigned_param("PP_DECIMAL_PRECISION", m_pp_decimal_precision, "maximum number of decimal places to be used when PP_DECIMAL=true", true);
- p.register_bool_param("PP_BV_LITERALS", m_pp_bv_lits, "use Bit-Vector literals (e.g, #x0F and #b0101) during pretty printing", true);
- p.register_bool_param("PP_BV_NEG", m_pp_bv_neg, "use bvneg when displaying Bit-Vector literals where the most significant bit is 1", true);
- p.register_bool_param("PP_FLAT_ASSOC", m_pp_flat_assoc, "flat associative operators (when pretty printing SMT2 terms/formulas)", true);
- p.register_bool_param("PP_FIXED_INDENT", m_pp_fixed_indent, "use a fixed indentation for applications", true);
- p.register_bool_param("PP_SINGLE_LINE", m_pp_single_line, "ignore line breaks when true", true);
- p.register_bool_param("PP_BOUNDED", m_pp_bounded, "ignore characters exceeding max widht", true);
- p.register_bool_param("PP_SIMPLIFY_IMPLIES", m_pp_simplify_implies, "simplify nested implications for pretty printing", true);
-}
-
diff --git a/src/ast/pp_params.h b/src/ast/pp_params.h
deleted file mode 100644
index 970f97968..000000000
--- a/src/ast/pp_params.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- pp_params.h
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-20.
-
-Revision History:
-
---*/
-#ifndef _PP_PARAMS_H_
-#define _PP_PARAMS_H_
-
-#include"ini_file.h"
-
-struct pp_params {
- unsigned m_pp_max_indent; // max. indentation
- unsigned m_pp_max_num_lines; // max. num. lines
- unsigned m_pp_max_width; // max. width
- unsigned m_pp_max_ribbon; // max. ribbon: width - indentation
- unsigned m_pp_max_depth;
- unsigned m_pp_min_alias_size;
- bool m_pp_decimal; // display reals using decimals
- unsigned m_pp_decimal_precision; // max. number of decimal places
- bool m_pp_bv_lits;
- bool m_pp_bv_neg; // use bvneg to display bit-vector literals which the most significant bit is 1
- bool m_pp_flat_assoc;
- bool m_pp_fixed_indent;
- bool m_pp_single_line; // ignore line breaks if true
- bool m_pp_bounded; // ignore characters exceeding max width.
- bool m_pp_simplify_implies; // simplify nested implications during pretty printing
-
- pp_params();
- void register_params(ini_params & p);
-};
-
-#endif /* _PP_PARAMS_H_ */
-
diff --git a/src/ast/pp_params.pyg b/src/ast/pp_params.pyg
new file mode 100644
index 000000000..75b2baddd
--- /dev/null
+++ b/src/ast/pp_params.pyg
@@ -0,0 +1,18 @@
+def_module_params('pp',
+ export=True,
+ description='pretty printer',
+ params=(('max_indent', UINT, UINT_MAX, 'max. indentation in pretty printer'),
+ ('max_num_lines', UINT, UINT_MAX, 'max. number of lines to be displayed in pretty printer'),
+ ('max_width', UINT, 80, 'max. width in pretty printer'),
+ ('max_ribbon', UINT, 80, 'max. ribbon (width - indentation) in pretty printer'),
+ ('max_depth', UINT, 5, 'max. term depth (when pretty printing SMT2 terms/formulas)'),
+ ('min_alias_size', UINT, 10, 'min. size for creating an alias for a shared term (when pretty printing SMT2 terms/formulas)'),
+ ('decimal', BOOL, False, 'pretty print real numbers using decimal notation (the output may be truncated). Z3 adds a ? if the value is not precise'),
+ ('decimal_precision', UINT, 10, 'maximum number of decimal places to be used when pp.decimal=true'),
+ ('bv_literals', BOOL, True, 'use Bit-Vector literals (e.g, #x0F and #b0101) during pretty printing'),
+ ('bv_neg', BOOL, False, 'use bvneg when displaying Bit-Vector literals where the most significant bit is 1'),
+ ('flat_assoc', BOOL, True, 'flat associative operators (when pretty printing SMT2 terms/formulas)'),
+ ('fixed_indent', BOOL, False, 'use a fixed indentation for applications'),
+ ('single_line', BOOL, False, 'ignore line breaks when true'),
+ ('bounded', BOOL, False, 'ignore characters exceeding max widht'),
+ ('simplify_implies', BOOL, True, 'simplify nested implications for pretty printing')))
diff --git a/src/ast/proof_checker/proof_checker.cpp b/src/ast/proof_checker/proof_checker.cpp
index 8a064a315..240504048 100644
--- a/src/ast/proof_checker/proof_checker.cpp
+++ b/src/ast/proof_checker/proof_checker.cpp
@@ -4,7 +4,6 @@
// include "spc_decl_plugin.h"
#include "ast_smt_pp.h"
#include "arith_decl_plugin.h"
-#include "front_end_params.h"
#include "th_rewriter.h"
#include "var_subst.h"
diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp
index 3efc14abe..a5dfda6e7 100644
--- a/src/ast/rewriter/arith_rewriter.cpp
+++ b/src/ast/rewriter/arith_rewriter.cpp
@@ -17,23 +17,25 @@ Notes:
--*/
#include"arith_rewriter.h"
+#include"arith_rewriter_params.hpp"
#include"poly_rewriter_def.h"
#include"algebraic_numbers.h"
#include"ast_pp.h"
-void arith_rewriter::updt_local_params(params_ref const & p) {
- m_arith_lhs = p.get_bool(":arith-lhs", false);
- m_gcd_rounding = p.get_bool(":gcd-rounding", false);
- m_eq2ineq = p.get_bool(":eq2ineq", false);
- m_elim_to_real = p.get_bool(":elim-to-real", false);
- m_push_to_real = p.get_bool(":push-to-real", true);
- m_anum_simp = p.get_bool(":algebraic-number-evaluator", true);
- m_max_degree = p.get_uint(":max-degree", 64);
- m_expand_power = p.get_bool(":expand-power", false);
- m_mul2power = p.get_bool(":mul-to-power", false);
- m_elim_rem = p.get_bool(":elim-rem", false);
- m_expand_tan = p.get_bool(":expand-tan", false);
- set_sort_sums(p.get_bool(":sort-sums", false)); // set here to avoid collision with bvadd
+void arith_rewriter::updt_local_params(params_ref const & _p) {
+ arith_rewriter_params p(_p);
+ m_arith_lhs = p.arith_lhs();
+ m_gcd_rounding = p.gcd_rounding();
+ m_eq2ineq = p.eq2ineq();
+ m_elim_to_real = p.elim_to_real();
+ m_push_to_real = p.push_to_real();
+ m_anum_simp = p.algebraic_number_evaluator();
+ m_max_degree = p.max_degree();
+ m_expand_power = p.expand_power();
+ m_mul2power = p.mul_to_power();
+ m_elim_rem = p.elim_rem();
+ m_expand_tan = p.expand_tan();
+ set_sort_sums(p.sort_sums());
}
void arith_rewriter::updt_params(params_ref const & p) {
@@ -43,18 +45,7 @@ void arith_rewriter::updt_params(params_ref const & p) {
void arith_rewriter::get_param_descrs(param_descrs & r) {
poly_rewriter::get_param_descrs(r);
- r.insert(":algebraic-number-evaluator", CPK_BOOL, "(default: true) simplify/evaluate expressions containing (algebraic) irrational numbers.");
- r.insert(":mul-to-power", CPK_BOOL, "(default: false) collpase (* t ... t) into (^ t k), it is ignored if :expand-power is true.");
- r.insert(":expand-power", CPK_BOOL, "(default: false) expand (^ t k) into (* t ... t) if 1 < k <= :max-degree.");
- r.insert(":expand-tan", CPK_BOOL, "(default: false) replace (tan x) with (/ (sin x) (cos x)).");
- r.insert(":max-degree", CPK_UINT, "(default: 64) max degree of algebraic numbers (and power operators) processed by simplifier.");
- r.insert(":eq2ineq", CPK_BOOL, "(default: false) split arithmetic equalities into two inequalities.");
- r.insert(":sort-sums", CPK_BOOL, "(default: false) sort the arguments of + application.");
- r.insert(":gcd-rounding", CPK_BOOL, "(default: false) use gcd rounding on integer arithmetic atoms.");
- r.insert(":arith-lhs", CPK_BOOL, "(default: false) all monomials are moved to the left-hand-side, and the right-hand-side is just a constant.");
- r.insert(":elim-to-real", CPK_BOOL, "(default: false) eliminate to_real from arithmetic predicates that contain only integers.");
- r.insert(":push-to-real", CPK_BOOL, "(default: true) distribute to_real over * and +.");
- r.insert(":elim-rem", CPK_BOOL, "(default: false) replace (rem x y) with (ite (>= y 0) (mod x y) (- (mod x y))).");
+ arith_rewriter_params::collect_param_descrs(r);
}
br_status arith_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
diff --git a/src/ast/rewriter/arith_rewriter_params.pyg b/src/ast/rewriter/arith_rewriter_params.pyg
new file mode 100644
index 000000000..8a41d838d
--- /dev/null
+++ b/src/ast/rewriter/arith_rewriter_params.pyg
@@ -0,0 +1,15 @@
+def_module_params(module_name='rewriter',
+ class_name='arith_rewriter_params',
+ export=True,
+ params=(("algebraic_number_evaluator", BOOL, True, "simplify/evaluate expressions containing (algebraic) irrational numbers."),
+ ("mul_to_power", BOOL, False, "collpase (* t ... t) into (^ t k), it is ignored if expand_power is true."),
+ ("expand_power", BOOL, False, "expand (^ t k) into (* t ... t) if 1 < k <= max_degree."),
+ ("expand_tan", BOOL, False, "replace (tan x) with (/ (sin x) (cos x))."),
+ ("max_degree", UINT, 64, "max degree of algebraic numbers (and power operators) processed by simplifier."),
+ ("eq2ineq", BOOL, False, "split arithmetic equalities into two inequalities."),
+ ("sort_sums", BOOL, False, "sort the arguments of + application."),
+ ("gcd_rounding", BOOL, False, "use gcd rounding on integer arithmetic atoms."),
+ ("arith_lhs", BOOL, False, "all monomials are moved to the left-hand-side, and the right-hand-side is just a constant."),
+ ("elim_to_real", BOOL, False, "eliminate to_real from arithmetic predicates that contain only integers."),
+ ("push_to_real", BOOL, True, "distribute to_real over * and +."),
+ ("elim_rem", BOOL, False, "replace (rem x y) with (ite (>= y 0) (mod x y) (- (mod x y))).")))
diff --git a/src/ast/rewriter/array_rewriter.cpp b/src/ast/rewriter/array_rewriter.cpp
index 268f4dca0..9dbbeb231 100644
--- a/src/ast/rewriter/array_rewriter.cpp
+++ b/src/ast/rewriter/array_rewriter.cpp
@@ -17,17 +17,18 @@ Notes:
--*/
#include"array_rewriter.h"
+#include"array_rewriter_params.hpp"
#include"ast_lt.h"
#include"ast_pp.h"
-void array_rewriter::updt_params(params_ref const & p) {
- m_sort_store = p.get_bool(":sort-store", false);
- m_expand_select_store = p.get_bool(":expand-select-store", false);
+void array_rewriter::updt_params(params_ref const & _p) {
+ array_rewriter_params p(_p);
+ m_sort_store = p.sort_store();
+ m_expand_select_store = p.expand_select_store();
}
void array_rewriter::get_param_descrs(param_descrs & r) {
- r.insert(":expand-select-store", CPK_BOOL, "(default: false) replace a (select (store ...) ...) term by an if-then-else term.");
- r.insert(":sort-store", CPK_BOOL, "(default: false) sort nested stores when the indices are known to be different.");
+ array_rewriter_params::collect_param_descrs(r);
}
br_status array_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
diff --git a/src/ast/rewriter/array_rewriter_params.pyg b/src/ast/rewriter/array_rewriter_params.pyg
new file mode 100644
index 000000000..2e3ae9f6a
--- /dev/null
+++ b/src/ast/rewriter/array_rewriter_params.pyg
@@ -0,0 +1,5 @@
+def_module_params(module_name='rewriter',
+ class_name='array_rewriter_params',
+ export=True,
+ params=(("expand_select_store", BOOL, False, "replace a (select (store ...) ...) term by an if-then-else term"),
+ ("sort_store", BOOL, False, "sort nested stores when the indices are known to be different")))
diff --git a/src/front_end_params/bit_blaster_params.h b/src/ast/rewriter/bit_blaster/bit_blaster_params.h
similarity index 80%
rename from src/front_end_params/bit_blaster_params.h
rename to src/ast/rewriter/bit_blaster/bit_blaster_params.h
index 8196774ca..653c8fc74 100644
--- a/src/front_end_params/bit_blaster_params.h
+++ b/src/ast/rewriter/bit_blaster/bit_blaster_params.h
@@ -19,8 +19,6 @@ Revision History:
#ifndef _BIT_BLASTER_PARAMS_H_
#define _BIT_BLASTER_PARAMS_H_
-#include"ini_file.h"
-
struct bit_blaster_params {
bool m_bb_ext_gates;
bool m_bb_quantifiers;
@@ -28,10 +26,12 @@ struct bit_blaster_params {
m_bb_ext_gates(false),
m_bb_quantifiers(false) {
}
+#if 0
void register_params(ini_params & p) {
- p.register_bool_param("BB_EXT_GATES", m_bb_ext_gates, "use extended gates during bit-blasting");
- p.register_bool_param("BB_QUANTIFIERS", m_bb_quantifiers, "convert bit-vectors to Booleans in quantifiers");
+ p.register_bool_param("bb_ext_gates", m_bb_ext_gates, "use extended gates during bit-blasting");
+ p.register_bool_param("bb_quantifiers", m_bb_quantifiers, "convert bit-vectors to Booleans in quantifiers");
}
+#endif
};
#endif /* _BIT_BLASTER_PARAMS_H_ */
diff --git a/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp b/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp
index c64ea56d0..1fd83e91f 100644
--- a/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp
+++ b/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp
@@ -125,12 +125,12 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
}
void updt_params(params_ref const & p) {
- m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
- m_max_steps = p.get_uint(":max-steps", UINT_MAX);
- m_blast_add = p.get_bool(":blast-add", true);
- m_blast_mul = p.get_bool(":blast-mul", true);
- m_blast_full = p.get_bool(":blast-full", false);
- m_blast_quant = p.get_bool(":blast-quant", false);
+ m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
+ m_max_steps = p.get_uint("max_steps", UINT_MAX);
+ m_blast_add = p.get_bool("blast_add", true);
+ m_blast_mul = p.get_bool("blast_mul", true);
+ m_blast_full = p.get_bool("blast_full", false);
+ m_blast_quant = p.get_bool("blast_quant", false);
m_blaster.set_max_memory(m_max_memory);
}
diff --git a/src/ast/rewriter/bool_rewriter.cpp b/src/ast/rewriter/bool_rewriter.cpp
index b7fe296c4..4fcaf02fe 100644
--- a/src/ast/rewriter/bool_rewriter.cpp
+++ b/src/ast/rewriter/bool_rewriter.cpp
@@ -17,24 +17,21 @@ Notes:
--*/
#include"bool_rewriter.h"
+#include"bool_rewriter_params.hpp"
#include"rewriter_def.h"
-void bool_rewriter::updt_params(params_ref const & p) {
- m_flat = p.get_bool(":flat", true);
- m_elim_and = p.get_bool(":elim-and", false);
- m_local_ctx = p.get_bool(":local-ctx", false);
- m_local_ctx_limit = p.get_uint(":local-ctx-limit", UINT_MAX);
- m_blast_distinct = p.get_bool(":blast-distinct", false);
- m_ite_extra_rules = p.get_bool(":ite-extra-rules", false);
+void bool_rewriter::updt_params(params_ref const & _p) {
+ bool_rewriter_params p(_p);
+ m_flat = p.flat();
+ m_elim_and = p.elim_and();
+ m_local_ctx = p.local_ctx();
+ m_local_ctx_limit = p.local_ctx_limit();
+ m_blast_distinct = p.blast_distinct();
+ m_ite_extra_rules = p.ite_extra_rules();
}
void bool_rewriter::get_param_descrs(param_descrs & r) {
- r.insert(":ite-extra-rules", CPK_BOOL, "(default: false) extra ite simplifications, these additional simplifications may reduce size locally but increase globally.");
- r.insert(":flat", CPK_BOOL, "(default: true) create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor.");
- r.insert(":elim-and", CPK_BOOL, "(default: false) conjunctions are rewritten using negation and disjunctions.");
- r.insert(":local-ctx", CPK_BOOL, "(default: false) perform local (i.e., cheap) context simplifications.");
- r.insert(":local-ctx-limit", CPK_UINT, "(default: inf) limit for applying local context simplifier.");
- r.insert(":blast-distinct", CPK_BOOL, "(default: false) expand a distinct predicate into a quadratic number of disequalities.");
+ bool_rewriter_params::collect_param_descrs(r);
}
br_status bool_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
diff --git a/src/ast/rewriter/bool_rewriter_params.pyg b/src/ast/rewriter/bool_rewriter_params.pyg
new file mode 100644
index 000000000..a5bcf6f5d
--- /dev/null
+++ b/src/ast/rewriter/bool_rewriter_params.pyg
@@ -0,0 +1,9 @@
+def_module_params(module_name='rewriter',
+ class_name='bool_rewriter_params',
+ export=True,
+ params=(("ite_extra_rules", BOOL, False, "extra ite simplifications, these additional simplifications may reduce size locally but increase globally"),
+ ("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor"),
+ ("elim_and", BOOL, False, "conjunctions are rewritten using negation and disjunctions"),
+ ("local_ctx", BOOL, False, "perform local (i.e., cheap) context simplifications"),
+ ("local_ctx_limit", UINT, UINT_MAX, "limit for applying local context simplifier"),
+ ("blast_distinct", BOOL, False, "expand a distinct predicate into a quadratic number of disequalities")))
diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp
index adef6a5b0..5fd562676 100644
--- a/src/ast/rewriter/bv_rewriter.cpp
+++ b/src/ast/rewriter/bv_rewriter.cpp
@@ -17,6 +17,7 @@ Notes:
--*/
#include"bv_rewriter.h"
+#include"bv_rewriter_params.hpp"
#include"poly_rewriter_def.h"
#include"ast_smt2_pp.h"
@@ -53,15 +54,16 @@ app * mk_extract_proc::operator()(unsigned high, unsigned low, expr * arg) {
return r;
}
-void bv_rewriter::updt_local_params(params_ref const & p) {
- m_hi_div0 = p.get_bool(":hi-div0", true);
- m_elim_sign_ext = p.get_bool(":elim-sign-ext", true);
- m_mul2concat = p.get_bool(":mul2concat", false);
- m_bit2bool = p.get_bool(":bit2bool", true);
- m_blast_eq_value = p.get_bool(":blast-eq-value", false);
- m_mkbv2num = p.get_bool(":mkbv2num", false);
- m_split_concat_eq = p.get_bool(":split-concat-eq", false);
- m_udiv2mul = p.get_bool(":udiv2mul", false);
+void bv_rewriter::updt_local_params(params_ref const & _p) {
+ bv_rewriter_params p(_p);
+ m_hi_div0 = p.hi_div0();
+ m_elim_sign_ext = p.elim_sign_ext();
+ m_mul2concat = p.mul2concat();
+ m_bit2bool = p.bit2bool();
+ m_blast_eq_value = p.blast_eq_value();
+ m_split_concat_eq = p.split_concat_eq();
+ m_udiv2mul = p.udiv2mul();
+ m_mkbv2num = _p.get_bool("mkbv2num", false);
}
void bv_rewriter::updt_params(params_ref const & p) {
@@ -71,15 +73,9 @@ void bv_rewriter::updt_params(params_ref const & p) {
void bv_rewriter::get_param_descrs(param_descrs & r) {
poly_rewriter::get_param_descrs(r);
- r.insert(":udiv2mul", CPK_BOOL, "(default: false) convert constant udiv to mul.");
- r.insert(":split-concat-eq", CPK_BOOL, "(default: false) split equalities of the form (= (concat t1 t2) t3).");
- r.insert(":bit2bool", CPK_BOOL, "(default: true) try to convert bit-vector terms of size 1 into Boolean terms.");
- r.insert(":blast-eq-value", CPK_BOOL, "(default: false) blast (some) Bit-vector equalities into bits.");
- r.insert(":elim-sign-ext", CPK_BOOL, "(default: true) expand sign-ext operator using concat and extract.");
- r.insert(":hi-div0", CPK_BOOL, "(default: true) use the 'hardware interpretation' for division by zero (for bit-vector terms).");
- r.insert(":mul2concat", CPK_BOOL, "(default: false) replace multiplication by a power of two into a concatenation.");
+ bv_rewriter_params::collect_param_descrs(r);
#ifndef _EXTERNAL_RELEASE
- r.insert(":mkbv2num", CPK_BOOL, "(default: false) convert (mkbv [true/false]*) into a numeral");
+ r.insert("mkbv2num", CPK_BOOL, "(default: false) convert (mkbv [true/false]*) into a numeral");
#endif
}
diff --git a/src/ast/rewriter/bv_rewriter_params.pyg b/src/ast/rewriter/bv_rewriter_params.pyg
new file mode 100644
index 000000000..780d8e724
--- /dev/null
+++ b/src/ast/rewriter/bv_rewriter_params.pyg
@@ -0,0 +1,10 @@
+def_module_params(module_name='rewriter',
+ class_name='bv_rewriter_params',
+ export=True,
+ params=(("udiv2mul", BOOL, False, "convert constant udiv to mul"),
+ ("split_concat_eq", BOOL, False, "split equalities of the form (= (concat t1 t2) t3)"),
+ ("bit2bool", BOOL, True, "try to convert bit-vector terms of size 1 into Boolean terms"),
+ ("blast_eq_value", BOOL, False, "blast (some) Bit-vector equalities into bits"),
+ ("elim_sign_ext", BOOL, True, "expand sign-ext operator using concat and extract"),
+ ("hi_div0", BOOL, True, "use the 'hardware interpretation' for division by zero (for bit-vector terms)"),
+ ("mul2concat", BOOL, False, "replace multiplication by a power of two into a concatenation")))
diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp
index ad0709423..9678af216 100644
--- a/src/ast/rewriter/float_rewriter.cpp
+++ b/src/ast/rewriter/float_rewriter.cpp
@@ -59,6 +59,7 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c
case OP_FLOAT_IS_NZERO: SASSERT(num_args == 1); st = mk_is_nzero(args[0], result); break;
case OP_FLOAT_IS_PZERO: SASSERT(num_args == 1); st = mk_is_pzero(args[0], result); break;
case OP_FLOAT_IS_SIGN_MINUS: SASSERT(num_args == 1); st = mk_is_sign_minus(args[0], result); break;
+ case OP_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break;
}
return st;
}
@@ -439,3 +440,7 @@ br_status float_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result
return BR_FAILED;
}
+
+br_status float_rewriter::mk_to_ieee_bv(expr * arg1, expr_ref & result) {
+ return BR_FAILED;
+}
\ No newline at end of file
diff --git a/src/ast/rewriter/float_rewriter.h b/src/ast/rewriter/float_rewriter.h
index e4258895d..7c86a5bc3 100644
--- a/src/ast/rewriter/float_rewriter.h
+++ b/src/ast/rewriter/float_rewriter.h
@@ -67,6 +67,8 @@ public:
br_status mk_is_nzero(expr * arg1, expr_ref & result);
br_status mk_is_pzero(expr * arg1, expr_ref & result);
br_status mk_is_sign_minus(expr * arg1, expr_ref & result);
+
+ br_status mk_to_ieee_bv(expr * arg1, expr_ref & result);
};
#endif
diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h
index e942b453a..290144c75 100644
--- a/src/ast/rewriter/poly_rewriter_def.h
+++ b/src/ast/rewriter/poly_rewriter_def.h
@@ -17,6 +17,7 @@ Notes:
--*/
#include"poly_rewriter.h"
+#include"poly_rewriter_params.hpp"
#include"ast_lt.h"
#include"ast_ll_pp.h"
#include"ast_smt2_pp.h"
@@ -26,20 +27,18 @@ char const * poly_rewriter::g_ste_blowup_msg = "sum of monomials blowup"
template
-void poly_rewriter::updt_params(params_ref const & p) {
- m_flat = p.get_bool(":flat", true);
- m_som = p.get_bool(":som", false);
- m_hoist_mul = p.get_bool(":hoist-mul", false);
- m_hoist_cmul = p.get_bool(":hoist-cmul", false);
- m_som_blowup = p.get_uint(":som-blowup", UINT_MAX);
+void poly_rewriter::updt_params(params_ref const & _p) {
+ poly_rewriter_params p(_p);
+ m_flat = p.flat();
+ m_som = p.som();
+ m_hoist_mul = p.hoist_mul();
+ m_hoist_cmul = p.hoist_cmul();
+ m_som_blowup = p.som_blowup();
}
template
void poly_rewriter::get_param_descrs(param_descrs & r) {
- r.insert(":som", CPK_BOOL, "(default: false) put polynomials in som-of-monomials form.");
- r.insert(":som-blowup", CPK_UINT, "(default: infty) maximum number of monomials generated when putting a polynomial in sum-of-monomials normal form");
- r.insert(":hoist-mul", CPK_BOOL, "(default: false) hoist multiplication over summation to minimize number of multiplications");
- r.insert(":hoist-cmul", CPK_BOOL, "(default: false) hoist constant multiplication over summation to minimize number of multiplications");
+ poly_rewriter_params::collect_param_descrs(r);
}
template
diff --git a/src/ast/rewriter/poly_rewriter_params.pyg b/src/ast/rewriter/poly_rewriter_params.pyg
new file mode 100644
index 000000000..18d1e1dba
--- /dev/null
+++ b/src/ast/rewriter/poly_rewriter_params.pyg
@@ -0,0 +1,8 @@
+def_module_params(module_name='rewriter',
+ class_name='poly_rewriter_params',
+ export=True,
+ params=(("som", BOOL, False, "put polynomials in som-of-monomials form"),
+ ("som_blowup", UINT, UINT_MAX, "maximum number of monomials generated when putting a polynomial in sum-of-monomials normal form"),
+ ("hoist_mul", BOOL, False, "hoist multiplication over summation to minimize number of multiplications"),
+ ("hoist_cmul", BOOL, False, "hoist constant multiplication over summation to minimize number of multiplications"),
+ ("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor")))
diff --git a/src/ast/rewriter/rewriter_params.pyg b/src/ast/rewriter/rewriter_params.pyg
new file mode 100644
index 000000000..3a8ed5d5e
--- /dev/null
+++ b/src/ast/rewriter/rewriter_params.pyg
@@ -0,0 +1,11 @@
+def_module_params('rewriter',
+ description='new formula simplification module used in the tactic framework, and new solvers',
+ export=True,
+ params=(max_memory_param(),
+ max_steps_param(),
+ ("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor"),
+ ("push_ite_arith", BOOL, False, "push if-then-else over arithmetic terms."),
+ ("push_ite_bv", BOOL, False, "push if-then-else over bit-vector terms."),
+ ("pull_cheap_ite", BOOL, False, "pull if-then-else terms when cheap."),
+ ("cache_all", BOOL, False, "cache all intermediate results.")))
+
diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp
index ee55d53e7..29034d396 100644
--- a/src/ast/rewriter/th_rewriter.cpp
+++ b/src/ast/rewriter/th_rewriter.cpp
@@ -17,6 +17,7 @@ Notes:
--*/
#include"th_rewriter.h"
+#include"rewriter_params.hpp"
#include"bool_rewriter.h"
#include"arith_rewriter.h"
#include"bv_rewriter.h"
@@ -56,14 +57,15 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
ast_manager & m() const { return m_b_rw.m(); }
- void updt_local_params(params_ref const & p) {
- m_flat = p.get_bool(":flat", true);
- m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
- m_max_steps = p.get_uint(":max-steps", UINT_MAX);
- m_pull_cheap_ite = p.get_bool(":pull-cheap-ite", false);
- m_cache_all = p.get_bool(":cache-all", false);
- m_push_ite_arith = p.get_bool(":push-ite-arith", false);
- m_push_ite_bv = p.get_bool(":push-ite-bv", false);
+ void updt_local_params(params_ref const & _p) {
+ rewriter_params p(_p);
+ m_flat = p.flat();
+ m_max_memory = megabytes_to_bytes(p.max_memory());
+ m_max_steps = p.max_steps();
+ m_pull_cheap_ite = p.pull_cheap_ite();
+ m_cache_all = p.cache_all();
+ m_push_ite_arith = p.push_ite_arith();
+ m_push_ite_bv = p.push_ite_bv();
}
void updt_params(params_ref const & p) {
@@ -481,10 +483,13 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
f = to_app(t1)->get_decl();
return unify_core(to_app(t1), t2, new_t1, new_t2, c, first);
}
- else {
+ else if (is_arith_bv_app(t2)) {
f = to_app(t2)->get_decl();
return unify_core(to_app(t2), t1, new_t2, new_t1, c, first);
}
+ else {
+ return false;
+ }
}
// Apply transformations of the form
@@ -693,12 +698,7 @@ void th_rewriter::get_param_descrs(param_descrs & r) {
arith_rewriter::get_param_descrs(r);
bv_rewriter::get_param_descrs(r);
array_rewriter::get_param_descrs(r);
- insert_max_memory(r);
- insert_max_steps(r);
- r.insert(":push-ite-arith", CPK_BOOL, "(default: false) push if-then-else over arithmetic terms.");
- r.insert(":push-ite-bv", CPK_BOOL, "(default: false) push if-then-else over bit-vector terms.");
- r.insert(":pull-cheap-ite", CPK_BOOL, "(default: false) pull if-then-else terms when cheap.");
- r.insert(":cache-all", CPK_BOOL, "(default: false) cache all intermediate results.");
+ rewriter_params::collect_param_descrs(r);
}
th_rewriter::~th_rewriter() {
diff --git a/src/ast/rewriter/th_rewriter.h b/src/ast/rewriter/th_rewriter.h
index 1b77c42c7..b25558dd9 100644
--- a/src/ast/rewriter/th_rewriter.h
+++ b/src/ast/rewriter/th_rewriter.h
@@ -37,7 +37,6 @@ public:
void updt_params(params_ref const & p);
static void get_param_descrs(param_descrs & r);
-
unsigned get_cache_size() const;
unsigned get_num_steps() const;
diff --git a/src/ast/simplifier/arith_simplifier_params.cpp b/src/ast/simplifier/arith_simplifier_params.cpp
new file mode 100644
index 000000000..a3fabe02f
--- /dev/null
+++ b/src/ast/simplifier/arith_simplifier_params.cpp
@@ -0,0 +1,26 @@
+/*++
+Copyright (c) 2006 Microsoft Corporation
+
+Module Name:
+
+ arith_simplifier_params.cpp
+
+Abstract:
+
+
+
+Author:
+
+ Leonardo de Moura (leonardo) 2012-12-02.
+
+Revision History:
+
+--*/
+#include"arith_simplifier_params.h"
+#include"arith_simplifier_params_helper.hpp"
+
+void arith_simplifier_params::updt_params(params_ref const & _p) {
+ arith_simplifier_params_helper p(_p);
+ m_arith_expand_eqs = p.arith_expand_eqs();
+ m_arith_process_all_eqs = p.arith_process_all_eqs();
+}
diff --git a/src/front_end_params/arith_simplifier_params.h b/src/ast/simplifier/arith_simplifier_params.h
similarity index 65%
rename from src/front_end_params/arith_simplifier_params.h
rename to src/ast/simplifier/arith_simplifier_params.h
index 3e44b5a6e..109f73307 100644
--- a/src/front_end_params/arith_simplifier_params.h
+++ b/src/ast/simplifier/arith_simplifier_params.h
@@ -19,18 +19,17 @@ Revision History:
#ifndef _ARITH_SIMPLIFIER_PARAMS_H_
#define _ARITH_SIMPLIFIER_PARAMS_H_
-#include"ini_file.h"
+#include"params.h"
-struct arith_simplifier_params {
+struct arith_simplifier_params {
bool m_arith_expand_eqs;
bool m_arith_process_all_eqs;
- arith_simplifier_params():
- m_arith_expand_eqs(false),
- m_arith_process_all_eqs(false) {
+ arith_simplifier_params(params_ref const & p = params_ref()) {
+ updt_params(p);
}
-
- void register_params(ini_params & p);
+
+ void updt_params(params_ref const & _p);
};
#endif /* _ARITH_SIMPLIFIER_PARAMS_H_ */
diff --git a/src/ast/simplifier/arith_simplifier_params_helper.pyg b/src/ast/simplifier/arith_simplifier_params_helper.pyg
new file mode 100644
index 000000000..49a7cf3d2
--- /dev/null
+++ b/src/ast/simplifier/arith_simplifier_params_helper.pyg
@@ -0,0 +1,7 @@
+def_module_params(class_name='arith_simplifier_params_helper',
+ module_name="old_simplify", # Parameters will be in the old_simplify module
+ description="old simplification (stack) still used in the smt module",
+ export=True,
+ params=(
+ ('arith.expand_eqs', BOOL, False, 'expand equalities into two inequalities'),
+ ('arith.process_all_eqs', BOOL, False, 'put all equations in the form (= t c), where c is a numeral')))
diff --git a/src/ast/simplifier/array_simplifier_params.cpp b/src/ast/simplifier/array_simplifier_params.cpp
new file mode 100644
index 000000000..bffff44d9
--- /dev/null
+++ b/src/ast/simplifier/array_simplifier_params.cpp
@@ -0,0 +1,26 @@
+/*++
+Copyright (c) 2012 Microsoft Corporation
+
+Module Name:
+
+ array_simplifier_params.cpp
+
+Abstract:
+
+ This file was created during code reorg.
+
+Author:
+
+ Leonardo de Moura (leonardo) 2012-12-02.
+
+Revision History:
+
+--*/
+#include"array_simplifier_params.h"
+#include"array_simplifier_params_helper.hpp"
+
+void array_simplifier_params::updt_params(params_ref const & _p) {
+ array_simplifier_params_helper p(_p);
+ m_array_canonize_simplify = p.array_canonize();
+ m_array_simplify = p.array_simplify();
+}
diff --git a/src/ast/simplifier/array_simplifier_params.h b/src/ast/simplifier/array_simplifier_params.h
new file mode 100644
index 000000000..2f6fa720b
--- /dev/null
+++ b/src/ast/simplifier/array_simplifier_params.h
@@ -0,0 +1,36 @@
+/*++
+Copyright (c) 2012 Microsoft Corporation
+
+Module Name:
+
+ array_simplifier_params.h
+
+Abstract:
+
+ This file was created during code reorg.
+
+Author:
+
+ Leonardo de Moura (leonardo) 2012-12-02.
+
+Revision History:
+
+--*/
+#ifndef _ARRAY_SIMPLIFIER_PARAMS_H_
+#define _ARRAY_SIMPLIFIER_PARAMS_H_
+
+#include"params.h"
+
+struct array_simplifier_params {
+ bool m_array_canonize_simplify;
+ bool m_array_simplify; // temporary hack for disabling array simplifier plugin.
+
+ array_simplifier_params(params_ref const & p = params_ref()) {
+ updt_params(p);
+ }
+
+ void updt_params(params_ref const & _p);
+};
+
+#endif /* _ARITH_SIMPLIFIER_PARAMS_H_ */
+
diff --git a/src/ast/simplifier/array_simplifier_params_helper.pyg b/src/ast/simplifier/array_simplifier_params_helper.pyg
new file mode 100644
index 000000000..93c184c23
--- /dev/null
+++ b/src/ast/simplifier/array_simplifier_params_helper.pyg
@@ -0,0 +1,6 @@
+def_module_params(class_name='array_simplifier_params_helper',
+ module_name="old_simplify", # Parameters will be in the old_simplify module
+ export=True,
+ params=(
+ ('array.canonize', BOOL, False, 'normalize array terms into normal form during simplification'),
+ ('array.simplify', BOOL, True, 'enable/disable array simplifications')))
diff --git a/src/ast/simplifier/array_simplifier_plugin.cpp b/src/ast/simplifier/array_simplifier_plugin.cpp
index 8654db275..75c3cdbce 100644
--- a/src/ast/simplifier/array_simplifier_plugin.cpp
+++ b/src/ast/simplifier/array_simplifier_plugin.cpp
@@ -33,7 +33,7 @@ array_simplifier_plugin::array_simplifier_plugin(
ast_manager & m,
basic_simplifier_plugin& s,
simplifier& simp,
- theory_array_params const& p) :
+ array_simplifier_params const& p) :
simplifier_plugin(symbol("array"),m),
m_util(m),
m_simp(s),
diff --git a/src/ast/simplifier/array_simplifier_plugin.h b/src/ast/simplifier/array_simplifier_plugin.h
index fffa18c3f..572da9a17 100644
--- a/src/ast/simplifier/array_simplifier_plugin.h
+++ b/src/ast/simplifier/array_simplifier_plugin.h
@@ -24,7 +24,7 @@ Revision History:
#include"array_decl_plugin.h"
#include"simplifier_plugin.h"
#include"basic_simplifier_plugin.h"
-#include"theory_array_params.h"
+#include"array_simplifier_params.h"
#include"simplifier.h"
#include"obj_hashtable.h"
#include"lbool.h"
@@ -71,7 +71,7 @@ class array_simplifier_plugin : public simplifier_plugin {
array_util m_util;
basic_simplifier_plugin& m_simp;
simplifier& m_simplifier;
- theory_array_params const& m_params;
+ array_simplifier_params const& m_params;
select_cache m_select_cache;
ptr_vector m_tmp;
ptr_vector m_tmp2;
@@ -100,7 +100,7 @@ class array_simplifier_plugin : public simplifier_plugin {
public:
- array_simplifier_plugin(ast_manager & m, basic_simplifier_plugin& s, simplifier& simp, theory_array_params const& p);
+ array_simplifier_plugin(ast_manager & m, basic_simplifier_plugin& s, simplifier& simp, array_simplifier_params const& p);
virtual ~array_simplifier_plugin();
virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result);
diff --git a/src/ast/simplifier/bv_simplifier_params.cpp b/src/ast/simplifier/bv_simplifier_params.cpp
new file mode 100644
index 000000000..aa9dcfc2d
--- /dev/null
+++ b/src/ast/simplifier/bv_simplifier_params.cpp
@@ -0,0 +1,26 @@
+/*++
+Copyright (c) 2006 Microsoft Corporation
+
+Module Name:
+
+ bv_simplifier_params.cpp
+
+Abstract:
+
+
+
+Author:
+
+ Leonardo de Moura (leonardo) 2012-12-02.
+
+Revision History:
+
+--*/
+#include"bv_simplifier_params.h"
+#include"bv_simplifier_params_helper.hpp"
+
+void bv_simplifier_params::updt_params(params_ref const & _p) {
+ bv_simplifier_params_helper p(_p);
+ m_hi_div0 = p.bv_hi_div0();
+ m_bv2int_distribute = p.bv_bv2int_distribute();
+}
diff --git a/src/front_end_params/bv_simplifier_params.h b/src/ast/simplifier/bv_simplifier_params.h
similarity index 53%
rename from src/front_end_params/bv_simplifier_params.h
rename to src/ast/simplifier/bv_simplifier_params.h
index a6ff749c4..5f5832235 100644
--- a/src/front_end_params/bv_simplifier_params.h
+++ b/src/ast/simplifier/bv_simplifier_params.h
@@ -19,20 +19,17 @@ Revision History:
#ifndef _BV_SIMPLIFIER_PARAMS_H_
#define _BV_SIMPLIFIER_PARAMS_H_
-#include"ini_file.h"
+#include"params.h"
struct bv_simplifier_params {
bool m_hi_div0; //!< if true, uses the hardware interpretation for div0, mod0, ... if false, div0, mod0, ... are considered uninterpreted.
bool m_bv2int_distribute; //!< if true allows downward propagation of bv2int.
- bv_simplifier_params():
- m_hi_div0(true),
- m_bv2int_distribute(true) {
- }
- void register_params(ini_params & p) {
- p.register_bool_param("HI_DIV0", m_hi_div0, "if true, then Z3 uses the usual hardware interpretation for division (rem, mod) by zero. Otherwise, these operations are considered uninterpreted.");
- p.register_bool_param("BV2INT_DISTRIBUTE", m_bv2int_distribute, "if true, then int2bv is distributed over arithmetical operators.");
+ bv_simplifier_params(params_ref const & p = params_ref()) {
+ updt_params(p);
}
+
+ void updt_params(params_ref const & _p);
};
#endif /* _BV_SIMPLIFIER_PARAMS_H_ */
diff --git a/src/ast/simplifier/bv_simplifier_params_helper.pyg b/src/ast/simplifier/bv_simplifier_params_helper.pyg
new file mode 100644
index 000000000..24bc86150
--- /dev/null
+++ b/src/ast/simplifier/bv_simplifier_params_helper.pyg
@@ -0,0 +1,6 @@
+def_module_params(class_name='bv_simplifier_params_helper',
+ module_name="old_simplify", # Parameters will be in the old_simplify module
+ export=True,
+ params=(
+ ('bv.hi_div0', BOOL, True, 'if true, then Z3 uses the usual hardware interpretation for division (rem, mod) by zero; otherwise, these operations are considered uninterpreted'),
+ ('bv.bv2int_distribute', BOOL, True, 'if true, then int2bv is distributed over arithmetical operators')))
diff --git a/src/ast/substitution/substitution_tree.cpp b/src/ast/substitution/substitution_tree.cpp
index 81b2f7be6..037d51e32 100644
--- a/src/ast/substitution/substitution_tree.cpp
+++ b/src/ast/substitution/substitution_tree.cpp
@@ -607,8 +607,8 @@ void substitution_tree::display(std::ostream & out, node * n, unsigned delta) co
out << " ";
display(out, n->m_subst);
if (n->m_leaf) {
- pp_params p;
- p.m_pp_single_line = true;
+ params_ref p;
+ p.set_bool("single_line", true);
out << " ==> ";
out << mk_pp(n->m_expr, m_manager, p);
out << "\n";
diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp
index 4c24b5ae6..8f65485ae 100644
--- a/src/cmd_context/basic_cmds.cpp
+++ b/src/cmd_context/basic_cmds.cpp
@@ -27,7 +27,9 @@ Notes:
#include"cmd_util.h"
#include"simplify_cmd.h"
#include"eval_cmd.h"
-#include"front_end_params.h"
+#include"gparams.h"
+#include"model_params.hpp"
+#include"env_params.h"
class help_cmd : public cmd {
svector m_cmds;
@@ -103,9 +105,10 @@ ATOMIC_CMD(get_model_cmd, "get-model", "retrieve model for the last check-sat co
throw cmd_exception("model is not available");
model_ref m;
ctx.get_check_sat_result()->get_model(m);
- if (ctx.params().m_model_v1_pp || ctx.params().m_model_v2_pp) {
+ model_params p;
+ if (p.v1() || p.v2()) {
std::ostringstream buffer;
- model_v2_pp(buffer, *m, ctx.params().m_model_partial);
+ model_v2_pp(buffer, *m, p.partial());
ctx.regular_stream() << "\"" << escaped(buffer.str().c_str(), true) << "\"" << std::endl;
} else {
ctx.regular_stream() << "(model " << std::endl;
@@ -156,7 +159,7 @@ public:
};
ATOMIC_CMD(get_proof_cmd, "get-proof", "retrieve proof", {
- if (ctx.params().m_proof_mode == PGM_DISABLED)
+ if (!ctx.produce_proofs())
throw cmd_exception("proof construction is not enabled, use command (set-option :produce-proofs true)");
if (!ctx.has_manager() ||
ctx.cs_state() != cmd_context::css_unsat)
@@ -219,25 +222,6 @@ UNARY_CMD(pp_cmd, "display", "", "display the given term.", CPK_EXPR, expr
UNARY_CMD(echo_cmd, "echo", "", "display the given string", CPK_STRING, char const *, ctx.regular_stream() << arg << std::endl;);
-/**
- \brief Convert a keyword into an internal Z3 option name
-*/
-std::string smt_keyword2opt_name(symbol const & opt) {
- std::string r;
- SASSERT(opt.bare_str()[0] == ':');
- r = opt.bare_str() + 1;
- unsigned sz = static_cast(r.size());
- for (unsigned i = 0; i < sz; i++) {
- char curr = r[i];
- if ('a' <= curr && curr <= 'z')
- r[i] = 'A' + (curr - 'a');
- else if (curr == '-')
- r[i] = '_';
- }
- TRACE("smt2_opt_name", tout << opt << " -> '" << r << "'\n";);
- return r;
-}
-
class set_get_option_cmd : public cmd {
protected:
symbol m_true;
@@ -259,7 +243,6 @@ protected:
symbol m_numeral_as_real;
symbol m_error_behavior;
symbol m_int_real_coercions;
- ini_params m_ini;
bool is_builtin_option(symbol const & s) const {
return
@@ -270,7 +253,7 @@ protected:
}
public:
- set_get_option_cmd(char const * name, front_end_params & params):
+ set_get_option_cmd(char const * name):
cmd(name),
m_true("true"),
m_false("false"),
@@ -289,10 +272,7 @@ public:
m_global_decls(":global-decls"),
m_numeral_as_real(":numeral-as-real"),
m_error_behavior(":error-behavior"),
- m_int_real_coercions(":int-real-coercions"),
- m_ini(false) {
- params.register_params(m_ini);
- register_pp_params(m_ini);
+ m_int_real_coercions(":int-real-coercions") {
}
virtual ~set_get_option_cmd() {}
@@ -324,22 +304,13 @@ class set_option_cmd : public set_get_option_cmd {
}
void set_param(cmd_context & ctx, char const * value) {
- m_ini.freeze(ctx.has_manager());
- std::string internal_opt = smt_keyword2opt_name(m_option);
try {
- std::string old_value;
- if (!m_ini.get_param_value(internal_opt.c_str(), old_value)) {
- m_unsupported = true;
- return;
- }
- m_ini.set_param_value(internal_opt.c_str(), value);
+ gparams::set(m_option, value);
+ env_params::updt_params();
+ ctx.global_params_updated();
}
- catch (set_get_param_exception ex) {
- std::string msg = "error setting '";
- msg += m_option.str();
- msg += "', ";
- msg += ex.get_msg();
- throw cmd_exception(msg);
+ catch (gparams::exception ex) {
+ throw cmd_exception(ex.msg());
}
}
@@ -406,8 +377,8 @@ class set_option_cmd : public set_get_option_cmd {
}
public:
- set_option_cmd(front_end_params & params):
- set_get_option_cmd("set-option", params),
+ set_option_cmd():
+ set_get_option_cmd("set-option"),
m_unsupported(false) {
}
@@ -485,8 +456,8 @@ class get_option_cmd : public set_get_option_cmd {
}
public:
- get_option_cmd(front_end_params & params):
- set_get_option_cmd("get-option", params) {
+ get_option_cmd():
+ set_get_option_cmd("get-option") {
}
virtual char const * get_usage() const { return ""; }
virtual char const * get_descr(cmd_context & ctx) const { return "get configuration option."; }
@@ -507,13 +478,13 @@ public:
print_bool(ctx, ctx.interactive_mode());
}
else if (opt == m_produce_proofs) {
- print_bool(ctx, ctx.params().m_proof_mode != PGM_DISABLED);
+ print_bool(ctx, ctx.produce_proofs());
}
else if (opt == m_produce_unsat_cores) {
print_bool(ctx, ctx.produce_unsat_cores());
}
else if (opt == m_produce_models) {
- print_bool(ctx, ctx.params().m_model);
+ print_bool(ctx, ctx.produce_models());
}
else if (opt == m_produce_assignments) {
print_bool(ctx, ctx.produce_assignments());
@@ -545,12 +516,10 @@ public:
print_bool(ctx, ctx.m().int_real_coercions());
}
else {
- std::string iopt = smt_keyword2opt_name(opt);
- std::string r;
- if (m_ini.get_param_value(iopt.c_str(), r)) {
- ctx.regular_stream() << r << std::endl;
+ try {
+ ctx.regular_stream() << gparams::get_value(opt) << std::endl;
}
- else {
+ catch (gparams::exception ex) {
ctx.print_unsupported(opt);
}
}
@@ -744,8 +713,8 @@ void install_basic_cmds(cmd_context & ctx) {
ctx.insert(alloc(get_assertions_cmd));
ctx.insert(alloc(get_proof_cmd));
ctx.insert(alloc(get_unsat_core_cmd));
- ctx.insert(alloc(set_option_cmd, ctx.params()));
- ctx.insert(alloc(get_option_cmd, ctx.params()));
+ ctx.insert(alloc(set_option_cmd));
+ ctx.insert(alloc(get_option_cmd));
ctx.insert(alloc(get_info_cmd));
ctx.insert(alloc(set_info_cmd));
ctx.insert(alloc(builtin_cmd, "assert", "", "assert term."));
diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp
index afcac48ac..0380e91ea 100644
--- a/src/cmd_context/cmd_context.cpp
+++ b/src/cmd_context/cmd_context.cpp
@@ -16,7 +16,6 @@ Notes:
--*/
#include
-#include"front_end_params.h"
#include"tptr.h"
#include"cmd_context.h"
#include"func_decl_dependencies.h"
@@ -300,10 +299,8 @@ public:
}
};
-cmd_context::cmd_context(front_end_params * params, bool main_ctx, ast_manager * m, symbol const & l):
+cmd_context::cmd_context(bool main_ctx, ast_manager * m, symbol const & l):
m_main_ctx(main_ctx),
- m_params(params == 0 ? alloc(front_end_params) : params),
- m_params_owner(params == 0),
m_logic(l),
m_interactive_mode(false),
m_global_decls(false), // :global-decls is false by default.
@@ -343,39 +340,54 @@ cmd_context::~cmd_context() {
finalize_probes();
m_solver = 0;
m_check_sat_result = 0;
- if (m_params_owner) {
- dealloc(m_params);
+}
+
+void cmd_context::global_params_updated() {
+ m_params.updt_params();
+ if (m_solver) {
+ params_ref p;
+ if (!m_params.m_auto_config)
+ p.set_bool("auto_config", false);
+ m_solver->updt_params(p);
}
}
void cmd_context::set_produce_models(bool f) {
- params().m_model = f;
if (m_solver)
m_solver->set_produce_models(f);
+ m_params.m_model = f;
}
void cmd_context::set_produce_unsat_cores(bool f) {
// can only be set before initialization
SASSERT(!has_manager());
- m_produce_unsat_cores = f;
+ m_params.m_unsat_core = f;
}
void cmd_context::set_produce_proofs(bool f) {
// can only be set before initialization
SASSERT(!has_manager());
- params().m_proof_mode = f ? PGM_FINE : PGM_DISABLED;
-}
-
-bool cmd_context::is_smtlib2_compliant() const {
- return params().m_smtlib2_compliant;
+ m_params.m_proof = f;
}
bool cmd_context::produce_models() const {
- return params().m_model;
+ return m_params.m_model;
}
bool cmd_context::produce_proofs() const {
- return params().m_proof_mode != PGM_DISABLED;
+ return m_params.m_proof;
+}
+
+bool cmd_context::produce_unsat_cores() const {
+ return m_params.m_unsat_core;
+}
+
+bool cmd_context::well_sorted_check_enabled() const {
+ return m_params.m_well_sorted_check;
+}
+
+bool cmd_context::validate_model_enabled() const {
+ return m_params.m_model_validate;
}
cmd_context::check_sat_state cmd_context::cs_state() const {
@@ -460,6 +472,7 @@ bool cmd_context::logic_has_arith_core(symbol const & s) const {
s == "LIA" ||
s == "LRA" ||
s == "QF_FPA" ||
+ s == "QF_FPABV" ||
s == "HORN";
}
@@ -478,6 +491,7 @@ bool cmd_context::logic_has_bv_core(symbol const & s) const {
s == "QF_ABV" ||
s == "QF_AUFBV" ||
s == "QF_BVRE" ||
+ s == "QF_FPABV" ||
s == "HORN";
}
@@ -502,7 +516,7 @@ bool cmd_context::logic_has_seq() const {
}
bool cmd_context::logic_has_floats() const {
- return !has_logic() || m_logic == "QF_FPA";
+ return !has_logic() || m_logic == "QF_FPA" || m_logic == "QF_FPABV";
}
bool cmd_context::logic_has_array_core(symbol const & s) const {
@@ -568,10 +582,7 @@ void cmd_context::init_manager_core(bool new_manager) {
insert(pm().mk_plist_decl());
}
if (m_solver) {
- m_solver->set_produce_unsat_cores(m_produce_unsat_cores);
- m_solver->set_produce_models(params().m_model);
- m_solver->set_produce_proofs(params().m_proof_mode == PGM_FINE);
- m_solver->init(m(), m_logic);
+ init_solver_options(m_solver.get());
}
m_check_logic.set_logic(m(), m_logic);
}
@@ -580,11 +591,14 @@ void cmd_context::init_manager() {
SASSERT(m_manager == 0);
SASSERT(m_pmanager == 0);
m_check_sat_result = 0;
- m_manager = alloc(ast_manager, params().m_proof_mode, params().m_trace_stream);
+ m_manager = alloc(ast_manager,
+ produce_proofs() ? PGM_FINE : PGM_DISABLED,
+ m_params.m_trace ? m_params.m_trace_file_name.c_str() : 0);
m_pmanager = alloc(pdecl_manager, *m_manager);
init_manager_core(true);
- if (params().m_smtlib2_compliant)
- m_manager->enable_int_real_coercions(false);
+ // PARAM-TODO
+ // if (params().m_smtlib2_compliant)
+ // m_manager->enable_int_real_coercions(false);
}
void cmd_context::init_external_manager() {
@@ -599,7 +613,7 @@ bool cmd_context::supported_logic(symbol const & s) const {
logic_has_arith_core(s) || logic_has_bv_core(s) ||
logic_has_array_core(s) || logic_has_seq_core(s) ||
logic_has_horn(s) ||
- s == "QF_FPA";
+ s == "QF_FPA" || s == "QF_FPABV";
}
void cmd_context::set_logic(symbol const & s) {
@@ -843,7 +857,7 @@ object_ref * cmd_context::find_object_ref(symbol const & s) const {
return r;
}
-#define CHECK_SORT(T) if (params().m_well_sorted_check) m().check_sorts_core(T)
+#define CHECK_SORT(T) if (well_sorted_check_enabled()) m().check_sorts_core(T)
void cmd_context::mk_const(symbol const & s, expr_ref & result) const {
mk_app(s, 0, 0, 0, 0, 0, result);
@@ -883,13 +897,13 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg
return;
}
SASSERT(num_args > 0);
- TRACE("macro_bug", tout << "m_well_sorted_check: " << params().m_well_sorted_check << "\n";
+ TRACE("macro_bug", tout << "well_sorted_check_enabled(): " << well_sorted_check_enabled() << "\n";
tout << "s: " << s << "\n";
tout << "body:\n" << mk_ismt2_pp(_m.second, m()) << "\n";
tout << "args:\n"; for (unsigned i = 0; i < num_args; i++) tout << mk_ismt2_pp(args[i], m()) << "\n" << mk_pp(m().get_sort(args[i]), m()) << "\n";);
var_subst subst(m());
subst(_m.second, num_args, args, result);
- if (params().m_well_sorted_check && !is_well_sorted(m(), result))
+ if (well_sorted_check_enabled() && !is_well_sorted(m(), result))
throw cmd_exception("invalid macro application, sort mismatch ", s);
return;
}
@@ -918,7 +932,7 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg
func_decl * f = fs.find(m(), num_args, args, range);
if (f == 0)
throw cmd_exception("unknown constant ", s);
- if (params().m_well_sorted_check)
+ if (well_sorted_check_enabled())
m().check_sort(f, num_args, args);
result = m().mk_app(f, num_args, args);
return;
@@ -1139,7 +1153,7 @@ void cmd_context::assert_expr(expr * t) {
m_check_sat_result = 0;
m().inc_ref(t);
m_assertions.push_back(t);
- if (m_produce_unsat_cores)
+ if (produce_unsat_cores())
m_assertion_names.push_back(0);
if (m_solver)
m_solver->assert_expr(t);
@@ -1148,7 +1162,7 @@ void cmd_context::assert_expr(expr * t) {
void cmd_context::assert_expr(symbol const & name, expr * t) {
if (!m_check_logic(t))
throw cmd_exception(m_check_logic.get_last_error());
- if (!m_produce_unsat_cores || name == symbol::null) {
+ if (!produce_unsat_cores() || name == symbol::null) {
assert_expr(t);
return;
}
@@ -1254,7 +1268,7 @@ void cmd_context::restore_assertions(unsigned old_sz) {
SASSERT(old_sz <= m_assertions.size());
SASSERT(!m_interactive_mode || m_assertions.size() == m_assertion_strings.size());
restore(m(), m_assertions, old_sz);
- if (m_produce_unsat_cores)
+ if (produce_unsat_cores())
restore(m(), m_assertion_names, old_sz);
if (m_interactive_mode)
m_assertion_strings.shrink(old_sz);
@@ -1283,18 +1297,12 @@ void cmd_context::pop(unsigned n) {
void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions) {
if (m_ignore_check)
return;
- IF_VERBOSE(100, verbose_stream() << "check-sat..." << std::endl;);
+ IF_VERBOSE(100, verbose_stream() << "(started \"check-sat\")" << std::endl;);
TRACE("before_check_sat", dump_assertions(tout););
- if (params().m_ignore_checksat) {
- m_check_sat_result = 0;
- regular_stream() << "unknown" << std::endl;
- return;
- }
if (!has_manager())
init_manager();
if (m_solver) {
m_check_sat_result = m_solver.get(); // solver itself stores the result.
- m_solver->set_front_end_params(params());
m_solver->set_progress_callback(this);
scoped_watch sw(*this);
cancel_eh eh(*m_solver);
@@ -1392,7 +1400,7 @@ struct contains_array_op_proc {
\brief Check if the current model satisfies the quantifier free formulas.
*/
void cmd_context::validate_model() {
- if (!params().m_model_validate)
+ if (!validate_model_enabled())
return;
if (!is_model_available())
return;
@@ -1400,9 +1408,9 @@ void cmd_context::validate_model() {
get_check_sat_result()->get_model(md);
SASSERT(md.get() != 0);
params_ref p;
- p.set_uint(":max-degree", UINT_MAX); // evaluate algebraic numbers of any degree.
- p.set_uint(":sort-store", true);
- p.set_bool(":model-completion", true);
+ p.set_uint("max_degree", UINT_MAX); // evaluate algebraic numbers of any degree.
+ p.set_uint("sort_store", true);
+ p.set_bool("model_completion", true);
model_evaluator evaluator(*(md.get()), p);
contains_array_op_proc contains_array(m());
{
@@ -1435,15 +1443,23 @@ void cmd_context::validate_model() {
}
}
+void cmd_context::init_solver_options(solver * s) {
+ m_solver->set_produce_unsat_cores(produce_unsat_cores());
+ m_solver->set_produce_models(produce_models());
+ m_solver->set_produce_proofs(produce_proofs());
+ m_solver->init(m(), m_logic);
+ if (!m_params.m_auto_config) {
+ params_ref p;
+ p.set_bool("auto_config", false);
+ m_solver->updt_params(p);
+ }
+}
+
void cmd_context::set_solver(solver * s) {
m_check_sat_result = 0;
m_solver = s;
- m_solver->set_front_end_params(params());
if (has_manager() && s != 0) {
- m_solver->set_produce_unsat_cores(m_produce_unsat_cores);
- m_solver->set_produce_models(params().m_model);
- m_solver->set_produce_proofs(params().m_proof_mode == PGM_FINE);
- m_solver->init(m(), m_logic);
+ init_solver_options(s);
// assert formulas and create scopes in the new solver.
unsigned lim = 0;
svector::iterator it = m_scopes.begin();
@@ -1497,7 +1513,7 @@ void cmd_context::display_assertions() {
}
bool cmd_context::is_model_available() const {
- if (params().m_model &&
+ if (produce_models() &&
has_manager() &&
(cs_state() == css_sat || cs_state() == css_unknown)) {
model_ref md;
@@ -1520,8 +1536,7 @@ cmd_context::pp_env & cmd_context::get_pp_env() const {
}
void cmd_context::pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer & var_names) const {
- mk_smt2_format(n, get_pp_env(), get_pp_default_params(),
- num_vars, var_prefix, r, var_names);
+ mk_smt2_format(n, get_pp_env(), params_ref(), num_vars, var_prefix, r, var_names);
}
void cmd_context::pp(expr * n, format_ns::format_ref & r) const {
@@ -1530,7 +1545,7 @@ void cmd_context::pp(expr * n, format_ns::format_ref & r) const {
}
void cmd_context::pp(func_decl * f, format_ns::format_ref & r) const {
- mk_smt2_format(f, get_pp_env(), get_pp_default_params(), r);
+ mk_smt2_format(f, get_pp_env(), params_ref(), r);
}
void cmd_context::display(std::ostream & out, sort * s, unsigned indent) const {
@@ -1538,7 +1553,7 @@ void cmd_context::display(std::ostream & out, sort * s, unsigned indent) const {
f = pp(s);
if (indent > 0)
f = format_ns::mk_indent(m(), indent, f);
- ::pp(out, f.get(), m(), get_pp_default_params());
+ ::pp(out, f.get(), m());
}
void cmd_context::display(std::ostream & out, expr * n, unsigned indent, unsigned num_vars, char const * var_prefix, sbuffer & var_names) const {
@@ -1546,7 +1561,7 @@ void cmd_context::display(std::ostream & out, expr * n, unsigned indent, unsigne
pp(n, num_vars, var_prefix, f, var_names);
if (indent > 0)
f = format_ns::mk_indent(m(), indent, f);
- ::pp(out, f.get(), m(), get_pp_default_params());
+ ::pp(out, f.get(), m());
}
void cmd_context::display(std::ostream & out, expr * n, unsigned indent) const {
@@ -1559,7 +1574,7 @@ void cmd_context::display(std::ostream & out, func_decl * d, unsigned indent) co
pp(d, f);
if (indent > 0)
f = format_ns::mk_indent(m(), indent, f);
- ::pp(out, f.get(), m(), get_pp_default_params());
+ ::pp(out, f.get(), m());
}
void cmd_context::dump_assertions(std::ostream & out) const {
diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h
index 5f83e0224..2edc87ca6 100644
--- a/src/cmd_context/cmd_context.h
+++ b/src/cmd_context/cmd_context.h
@@ -36,8 +36,7 @@ Notes:
#include"check_logic.h"
#include"progress_callback.h"
#include"scoped_ptr_vector.h"
-
-struct front_end_params;
+#include"context_params.h"
class func_decls {
func_decl * m_decls;
@@ -132,9 +131,8 @@ public:
};
protected:
+ context_params m_params;
bool m_main_ctx;
- front_end_params * m_params;
- bool m_params_owner;
symbol m_logic;
bool m_interactive_mode;
bool m_global_decls;
@@ -245,10 +243,13 @@ protected:
void print_unsupported_msg() { regular_stream() << "unsupported" << std::endl; }
void print_unsupported_info(symbol const& s) { if (s != symbol::null) diagnostic_stream() << "; " << s << std::endl;}
+ void init_solver_options(solver * s);
+
public:
- cmd_context(front_end_params * params = 0, bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null);
+ cmd_context(bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null);
~cmd_context();
- bool is_smtlib2_compliant() const;
+ context_params & params() { return m_params; }
+ void global_params_updated(); // this method should be invoked when global (and module) params are updated.
void set_logic(symbol const & s);
bool has_logic() const { return m_logic != symbol::null; }
symbol const & get_logic() const { return m_logic; }
@@ -270,7 +271,9 @@ public:
void set_random_seed(unsigned s) { m_random_seed = s; }
bool produce_models() const;
bool produce_proofs() const;
- bool produce_unsat_cores() const { return m_produce_unsat_cores; }
+ bool produce_unsat_cores() const;
+ bool well_sorted_check_enabled() const;
+ bool validate_model_enabled() const;
void set_produce_models(bool flag);
void set_produce_unsat_cores(bool flag);
void set_produce_proofs(bool flag);
@@ -285,7 +288,6 @@ public:
virtual ast_manager & get_ast_manager() { return m(); }
pdecl_manager & pm() const { if (!m_pmanager) const_cast(this)->init_manager(); return *m_pmanager; }
sexpr_manager & sm() const { if (!m_sexpr_manager) const_cast(this)->m_sexpr_manager = alloc(sexpr_manager); return *m_sexpr_manager; }
- front_end_params & params() const { return *m_params; }
void set_solver(solver * s);
solver * get_solver() const { return m_solver.get(); }
diff --git a/src/cmd_context/context_params.cpp b/src/cmd_context/context_params.cpp
new file mode 100644
index 000000000..495f73b75
--- /dev/null
+++ b/src/cmd_context/context_params.cpp
@@ -0,0 +1,114 @@
+/*++
+Copyright (c) 2011 Microsoft Corporation
+
+Module Name:
+
+ context_params.cpp
+
+Abstract:
+
+ Goodies for managing context parameters in the cmd_context and
+ api_context
+
+Author:
+
+ Leonardo (leonardo) 2012-12-01
+
+Notes:
+
+--*/
+#include"context_params.h"
+#include"gparams.h"
+#include"params.h"
+
+context_params::context_params() {
+ updt_params();
+}
+
+void context_params::set_bool(bool & opt, char const * param, char const * value) {
+ if (strcmp(value, "true") == 0) {
+ opt = true;
+ }
+ else if (strcmp(value, "false") == 0) {
+ opt = false;
+ }
+ else {
+ throw default_exception("invalid value '%s' for Boolean parameter '%s'", value, param);
+ }
+}
+
+void context_params::set(char const * param, char const * value) {
+ std::string p = param;
+ unsigned n = p.size();
+ for (unsigned i = 0; i < n; i++) {
+ if (p[i] >= 'A' && p[i] <= 'Z')
+ p[i] = p[i] - 'A' + 'a';
+ else if (p[i] == '-')
+ p[i] = '_';
+ }
+ if (p == "timeout") {
+ long val = strtol(value, 0, 10);
+ m_timeout = static_cast(val);
+ }
+ else if (p == "type_check" || p == "well_sorted_check") {
+ set_bool(m_well_sorted_check, param, value);
+ }
+ else if (p == "auto_config") {
+ set_bool(m_auto_config, param, value);
+ }
+ else if (p == "proof") {
+ set_bool(m_proof, param, value);
+ }
+ else if (p == "model") {
+ set_bool(m_model, param, value);
+ }
+ else if (p == "model_validate") {
+ set_bool(m_model_validate, param, value);
+ }
+ else if (p == "trace") {
+ set_bool(m_trace, param, value);
+ }
+ else if (p == "trace_file_name") {
+ m_trace_file_name = value;
+ }
+ else if (p == "unsat_core") {
+ set_bool(m_unsat_core, param, value);
+ }
+ else if (p == "debug_ref_count") {
+ set_bool(m_debug_ref_count, param, value);
+ }
+ else {
+ throw default_exception("unknown parameter '%s'", p.c_str());
+ }
+}
+
+void context_params::updt_params() {
+ updt_params(gparams::get());
+}
+
+void context_params::updt_params(params_ref const & p) {
+ m_timeout = p.get_uint("timeout", UINT_MAX);
+ m_well_sorted_check = p.get_bool("type_check", p.get_bool("well_sorted_check", true));
+ m_auto_config = p.get_bool("auto_config", true);
+ m_proof = p.get_bool("proof", false);
+ m_model = p.get_bool("model", true);
+ m_model_validate = p.get_bool("model_validate", false);
+ m_trace = p.get_bool("trace", false);
+ m_trace_file_name = p.get_str("trace_file_name", "z3.log");
+ m_unsat_core = p.get_bool("unsat_core", false);
+ m_debug_ref_count = p.get_bool("debug_ref_count", false);
+}
+
+void context_params::collect_param_descrs(param_descrs & d) {
+ d.insert("timeout", CPK_UINT, "default timeout (in milliseconds) used for solvers", "4294967295");
+ d.insert("well_sorted_check", CPK_BOOL, "type checker", "true");
+ d.insert("type_check", CPK_BOOL, "type checker (alias for well_sorted_check)", "true");
+ d.insert("auto_config", CPK_BOOL, "use heuristics to automatically select solver and configure it", "true");
+ d.insert("proof", CPK_BOOL, "proof generation, it must be enabled when the Z3 context is created", "false");
+ d.insert("model", CPK_BOOL, "model generation for solvers, this parameter can be overwritten when creating a solver", "true");
+ d.insert("model_validate", CPK_BOOL, "validate models produced by solvers", "false");
+ d.insert("trace", CPK_BOOL, "trace generation for VCC", "false");
+ d.insert("trace_file_name", CPK_STRING, "trace out file name (see option 'trace')", "z3.log");
+ d.insert("unsat_core", CPK_BOOL, "unsat-core generation for solvers, this parameter can be overwritten when creating a solver, not every solver in Z3 supports unsat core generation", "false");
+ d.insert("debug_ref_count", CPK_BOOL, "debug support for AST reference counting", "false");
+}
diff --git a/src/cmd_context/context_params.h b/src/cmd_context/context_params.h
new file mode 100644
index 000000000..6b42b5b50
--- /dev/null
+++ b/src/cmd_context/context_params.h
@@ -0,0 +1,51 @@
+/*++
+Copyright (c) 2011 Microsoft Corporation
+
+Module Name:
+
+ context_params.h
+
+Abstract:
+
+ Goodies for managing context parameters in the cmd_context and
+ api_context
+
+Author:
+
+ Leonardo (leonardo) 2012-12-01
+
+Notes:
+
+--*/
+#ifndef _CONTEXT_PARAMS_H_
+#define _CONTEXT_PARAMS_H_
+
+#include"params.h"
+
+class context_params {
+ void set_bool(bool & opt, char const * param, char const * value);
+
+public:
+ bool m_auto_config;
+ bool m_proof;
+ bool m_debug_ref_count;
+ bool m_trace;
+ std::string m_trace_file_name;
+ bool m_well_sorted_check;
+ bool m_model;
+ bool m_model_validate;
+ bool m_unsat_core;
+ unsigned m_timeout;
+
+ context_params();
+ void set(char const * param, char const * value);
+ void updt_params();
+ void updt_params(params_ref const & p);
+ static void collect_param_descrs(param_descrs & d);
+ /*
+ REG_PARAMS('context_params::collect_param_descrs')
+ */
+};
+
+
+#endif
diff --git a/src/cmd_context/eval_cmd.cpp b/src/cmd_context/eval_cmd.cpp
index fe9c738a2..7ebe2f54f 100644
--- a/src/cmd_context/eval_cmd.cpp
+++ b/src/cmd_context/eval_cmd.cpp
@@ -62,7 +62,7 @@ public:
SASSERT(last_result);
last_result->get_model(md);
expr_ref r(ctx.m());
- unsigned timeout = m_params.get_uint(":timeout", UINT_MAX);
+ unsigned timeout = m_params.get_uint("timeout", UINT_MAX);
model_evaluator ev(*(md.get()), m_params);
cancel_eh eh(ev);
{
diff --git a/src/cmd_context/extra_cmds/dbg_cmds.cpp b/src/cmd_context/extra_cmds/dbg_cmds.cpp
index b7b4f058d..509b5ff2e 100644
--- a/src/cmd_context/extra_cmds/dbg_cmds.cpp
+++ b/src/cmd_context/extra_cmds/dbg_cmds.cpp
@@ -141,8 +141,8 @@ public:
UNARY_CMD(bool_rewriter_cmd, "dbg-bool-rewriter", "", "apply the Boolean rewriter to the given term", CPK_EXPR, expr *, {
expr_ref t(ctx.m());
params_ref p;
- p.set_bool(":flat", false);
- SASSERT(p.get_bool(":flat", true) == false);
+ p.set_bool("flat", false);
+ SASSERT(p.get_bool("flat", true) == false);
bool_rewriter_star r(ctx.m(), p);
r(arg, t);
ctx.display(ctx.regular_stream(), t);
@@ -153,7 +153,7 @@ UNARY_CMD(bool_frewriter_cmd, "dbg-bool-flat-rewriter", "", "apply the Boo
expr_ref t(ctx.m());
{
params_ref p;
- p.set_bool(":flat", true);
+ p.set_bool("flat", true);
bool_rewriter_star r(ctx.m(), p);
r(arg, t);
}
@@ -165,8 +165,8 @@ UNARY_CMD(elim_and_cmd, "dbg-elim-and", "", "apply the Boolean rewriter (e
expr_ref t(ctx.m());
{
params_ref p;
- p.set_bool(":flat", true);
- p.set_bool(":elim-and", true);
+ p.set_bool("flat", true);
+ p.set_bool("elim_and", true);
bool_rewriter_star r(ctx.m(), p);
r(arg, t);
}
@@ -208,15 +208,15 @@ UNARY_CMD(some_value_cmd, "dbg-some-value", "", "retrieve some value of th
void tst_params(cmd_context & ctx) {
params_ref p1;
params_ref p2;
- p1.set_uint(":val", 100);
+ p1.set_uint("val", 100);
p2 = p1;
- SASSERT(p2.get_uint(":val", 0) == 100);
- p2.set_uint(":val", 200);
- SASSERT(p2.get_uint(":val", 0) == 200);
- SASSERT(p1.get_uint(":val", 0) == 100);
+ SASSERT(p2.get_uint("val", 0) == 100);
+ p2.set_uint("val", 200);
+ SASSERT(p2.get_uint("val", 0) == 200);
+ SASSERT(p1.get_uint("val", 0) == 100);
p2 = p1;
- SASSERT(p2.get_uint(":val", 0) == 100);
- SASSERT(p1.get_uint(":val", 0) == 100);
+ SASSERT(p2.get_uint("val", 0) == 100);
+ SASSERT(p1.get_uint("val", 0) == 100);
ctx.regular_stream() << "worked" << std::endl;
}
diff --git a/src/cmd_context/extra_cmds/polynomial_cmds.cpp b/src/cmd_context/extra_cmds/polynomial_cmds.cpp
index 7b37b750e..e68789dac 100644
--- a/src/cmd_context/extra_cmds/polynomial_cmds.cpp
+++ b/src/cmd_context/extra_cmds/polynomial_cmds.cpp
@@ -26,10 +26,10 @@ Notes:
#include"parametric_cmd.h"
#include"mpq.h"
#include"algebraic_numbers.h"
-#include"pp.h"
-#include"pp_params.h"
#include"polynomial_var2value.h"
#include"expr2var.h"
+#include"pp.h"
+#include"pp_params.hpp"
static void to_poly(cmd_context & ctx, expr * t) {
polynomial::numeral_manager nm;
@@ -145,9 +145,11 @@ class poly_isolate_roots_cmd : public cmd {
scoped_anum_vector rs(m_am);
m_am.isolate_roots(m_p, m_x2v, rs);
ctx.regular_stream() << "(roots";
+ pp_params params;
+ bool pp_decimal = params.decimal();
for (unsigned i = 0; i < rs.size(); i++) {
ctx.regular_stream() << std::endl;
- if (!get_pp_default_params().m_pp_decimal)
+ if (!pp_decimal)
m_am.display_root_smt2(ctx.regular_stream(), rs[i]);
else
m_am.display_decimal(ctx.regular_stream(), rs[i]);
diff --git a/src/cmd_context/extra_cmds/subpaving_cmds.cpp b/src/cmd_context/extra_cmds/subpaving_cmds.cpp
index 9b84ddf68..632f558dc 100644
--- a/src/cmd_context/extra_cmds/subpaving_cmds.cpp
+++ b/src/cmd_context/extra_cmds/subpaving_cmds.cpp
@@ -31,7 +31,7 @@ static void to_subpaving(cmd_context & ctx, expr * t) {
expr2var e2v(m);
expr2subpaving e2s(m, *s, &e2v);
params_ref p;
- p.set_bool(":mul-to-power", true);
+ p.set_bool("mul_to_power", true);
th_rewriter simp(m, p);
expr_ref t_s(m);
simp(t, t_s);
diff --git a/src/cmd_context/parametric_cmd.cpp b/src/cmd_context/parametric_cmd.cpp
index bc06d3ee6..c229bc29c 100644
--- a/src/cmd_context/parametric_cmd.cpp
+++ b/src/cmd_context/parametric_cmd.cpp
@@ -16,6 +16,7 @@ Notes:
--*/
#include
+#include"cmd_context.h"
#include"parametric_cmd.h"
char const * parametric_cmd::get_descr(cmd_context & ctx) const {
@@ -37,13 +38,15 @@ cmd_arg_kind parametric_cmd::next_arg_kind(cmd_context & ctx) const {
void parametric_cmd::set_next_arg(cmd_context & ctx, symbol const & s) {
if (m_last == symbol::null) {
- m_last = s;
+ m_last = symbol(norm_param_name(s).c_str());
if (pdescrs(ctx).get_kind(m_last.bare_str()) == CPK_INVALID)
throw cmd_exception("invalid keyword argument");
return;
}
- m_params.set_sym(m_last.bare_str(), s);
- m_last = symbol::null;
+ else {
+ m_params.set_sym(m_last.bare_str(), s);
+ m_last = symbol::null;
+ }
}
param_descrs const & parametric_cmd::pdescrs(cmd_context & ctx) const {
diff --git a/src/cmd_context/simplify_cmd.cpp b/src/cmd_context/simplify_cmd.cpp
index 089eb353b..3a1828a51 100644
--- a/src/cmd_context/simplify_cmd.cpp
+++ b/src/cmd_context/simplify_cmd.cpp
@@ -40,9 +40,9 @@ public:
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
th_rewriter::get_param_descrs(p);
insert_timeout(p);
- p.insert(":print", CPK_BOOL, "(default: true) print the simplified term.");
- p.insert(":print-proofs", CPK_BOOL, "(default: false) print a proof showing the original term is equal to the resultant one.");
- p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics.");
+ p.insert("print", CPK_BOOL, "(default: true) print the simplified term.");
+ p.insert("print_proofs", CPK_BOOL, "(default: false) print a proof showing the original term is equal to the resultant one.");
+ p.insert("print_statistics", CPK_BOOL, "(default: false) print statistics.");
}
virtual ~simplify_cmd() {
@@ -67,12 +67,12 @@ public:
throw cmd_exception("invalid simplify command, argument expected");
expr_ref r(ctx.m());
proof_ref pr(ctx.m());
- if (m_params.get_bool(":som", false))
- m_params.set_bool(":flat", true);
+ if (m_params.get_bool("som", false))
+ m_params.set_bool("flat", true);
th_rewriter s(ctx.m(), m_params);
unsigned cache_sz;
unsigned num_steps = 0;
- unsigned timeout = m_params.get_uint(":timeout", UINT_MAX);
+ unsigned timeout = m_params.get_uint("timeout", UINT_MAX);
bool failed = false;
cancel_eh eh(s);
{
@@ -94,17 +94,17 @@ public:
num_steps = s.get_num_steps();
s.cleanup();
}
- if (m_params.get_bool(":print", true)) {
+ if (m_params.get_bool("print", true)) {
ctx.display(ctx.regular_stream(), r);
ctx.regular_stream() << std::endl;
}
- if (!failed && m_params.get_bool(":print-proofs", false)) {
+ if (!failed && m_params.get_bool("print_proofs", false)) {
ast_smt_pp pp(ctx.m());
pp.set_logic(ctx.get_logic().str().c_str());
pp.display_expr_smt2(ctx.regular_stream(), pr.get());
ctx.regular_stream() << std::endl;
}
- if (m_params.get_bool(":print-statistics", false)) {
+ if (m_params.get_bool("print_statistics", false)) {
shared_occs s1(ctx.m());
if (!failed)
s1(r);
diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp
index 32adb5f47..ca87406c7 100644
--- a/src/cmd_context/tactic_cmds.cpp
+++ b/src/cmd_context/tactic_cmds.cpp
@@ -24,7 +24,6 @@ Notes:
#include"scoped_ctrl_c.h"
#include"cancel_eh.h"
#include"model_smt2_pp.h"
-#include"params2front_end_params.h"
#include"ast_smt2_pp.h"
#include"tactic.h"
#include"tactical.h"
@@ -153,7 +152,7 @@ public:
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
insert_timeout(p);
insert_max_memory(p);
- p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics.");
+ p.insert("print_statistics", CPK_BOOL, "(default: false) print statistics.");
}
void display_statistics(cmd_context & ctx, tactic * t) {
@@ -180,19 +179,17 @@ public:
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
exec_given_tactic_cmd::init_pdescrs(ctx, p);
- p.insert(":print-unsat-core", CPK_BOOL, "(default: false) print unsatisfiable core.");
- p.insert(":print-proof", CPK_BOOL, "(default: false) print proof.");
- p.insert(":print-model", CPK_BOOL, "(default: false) print model.");
+ p.insert("print_unsat_core", CPK_BOOL, "(default: false) print unsatisfiable core.");
+ p.insert("print_proof", CPK_BOOL, "(default: false) print proof.");
+ p.insert("print_model", CPK_BOOL, "(default: false) print model.");
}
virtual void execute(cmd_context & ctx) {
params_ref p = ps();
- front_end_params2params(ctx.params(), p);
tactic_ref tref = using_params(sexpr2tactic(ctx, m_tactic), p);
- tref->set_front_end_params(ctx.params());
tref->set_logic(ctx.get_logic());
ast_manager & m = ctx.m();
- unsigned timeout = p.get_uint(":timeout", UINT_MAX);
+ unsigned timeout = p.get_uint("timeout", UINT_MAX);
goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores());
assert_exprs_from(ctx, *g);
TRACE("check_sat_using", g->display(tout););
@@ -241,7 +238,7 @@ public:
ptr_vector core_elems;
m.linearize(core, core_elems);
result->m_core.append(core_elems.size(), core_elems.c_ptr());
- if (p.get_bool(":print-unsat-core", false)) {
+ if (p.get_bool("print_unsat_core", false)) {
ctx.regular_stream() << "(unsat-core";
ptr_vector::const_iterator it = core_elems.begin();
ptr_vector::const_iterator end = core_elems.end();
@@ -255,7 +252,7 @@ public:
if (ctx.produce_models() && md) {
result->m_model = md;
- if (p.get_bool(":print-model", false)) {
+ if (p.get_bool("print_model", false)) {
ctx.regular_stream() << "(model " << std::endl;
model_smt2_pp(ctx.regular_stream(), ctx, *md, 2);
ctx.regular_stream() << ")" << std::endl;
@@ -266,12 +263,12 @@ public:
if (ctx.produce_proofs() && pr) {
result->m_proof = pr;
- if (p.get_bool(":print-proof", false)) {
+ if (p.get_bool("print_proof", false)) {
ctx.regular_stream() << mk_ismt2_pp(pr, m) << "\n";
}
}
- if (p.get_bool(":print-statistics", false))
+ if (p.get_bool("print_statistics", false))
display_statistics(ctx, tref.get());
}
};
@@ -285,21 +282,20 @@ public:
virtual char const * get_main_descr() const { return "apply the given tactic to the current context, and print the resultant set of goals."; }
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
- p.insert(":print", CPK_BOOL, "(default: true) print resultant goals.");
+ p.insert("print", CPK_BOOL, "(default: true) print resultant goals.");
#ifndef _EXTERNAL_RELEASE
- p.insert(":print-proof", CPK_BOOL, "(default: false) print proof associated with each assertion.");
+ p.insert("print_proof", CPK_BOOL, "(default: false) print proof associated with each assertion.");
#endif
- p.insert(":print-model-converter", CPK_BOOL, "(default: false) print model converter.");
- p.insert(":print-benchmark", CPK_BOOL, "(default: false) display resultant goals as a SMT2 benchmark.");
+ p.insert("print_model_converter", CPK_BOOL, "(default: false) print model converter.");
+ p.insert("print_benchmark", CPK_BOOL, "(default: false) display resultant goals as a SMT2 benchmark.");
#ifndef _EXTERNAL_RELEASE
- p.insert(":print-dependencies", CPK_BOOL, "(default: false) print dependencies when displaying the resultant set of goals.");
+ p.insert("print_dependencies", CPK_BOOL, "(default: false) print dependencies when displaying the resultant set of goals.");
#endif
exec_given_tactic_cmd::init_pdescrs(ctx, p);
}
virtual void execute(cmd_context & ctx) {
params_ref p = ps();
- front_end_params2params(ctx.params(), p);
tactic_ref tref = using_params(sexpr2tactic(ctx, m_tactic), p);
{
tactic & t = *(tref.get());
@@ -307,7 +303,7 @@ public:
goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores());
assert_exprs_from(ctx, *g);
- unsigned timeout = p.get_uint(":timeout", UINT_MAX);
+ unsigned timeout = p.get_uint("timeout", UINT_MAX);
goal_ref_buffer result_goals;
model_converter_ref mc;
@@ -330,8 +326,8 @@ public:
}
}
- if (!failed && p.get_bool(":print", true)) {
- bool print_dependencies = p.get_bool(":print-dependencies", false);
+ if (!failed && p.get_bool("print", true)) {
+ bool print_dependencies = p.get_bool("print_dependencies", false);
ctx.regular_stream() << "(goals\n";
unsigned sz = result_goals.size();
for (unsigned i = 0; i < sz; i++) {
@@ -344,12 +340,12 @@ public:
}
#ifndef _EXTERNAL_RELEASE
- if (!failed && ctx.produce_proofs() && p.get_bool(":print-proof", false)) {
+ if (!failed && ctx.produce_proofs() && p.get_bool("print_proof", false)) {
// TODO
}
#endif
- if (!failed && p.get_bool(":print-benchmark", false)) {
+ if (!failed && p.get_bool("print_benchmark", false)) {
unsigned num_goals = result_goals.size();
SASSERT(num_goals > 0);
if (num_goals == 1) {
@@ -381,10 +377,10 @@ public:
}
}
- if (!failed && mc && p.get_bool(":print-model-converter", false))
+ if (!failed && mc && p.get_bool("print_model_converter", false))
mc->display(ctx.regular_stream());
- if (p.get_bool(":print-statistics", false))
+ if (p.get_bool("print_statistics", false))
display_statistics(ctx, tref.get());
}
}
@@ -501,7 +497,7 @@ static tactic * mk_using_params(cmd_context & ctx, sexpr * n) {
throw cmd_exception("invalid using-params combinator, keyword expected", c->get_line(), c->get_pos());
if (i == num_children)
throw cmd_exception("invalid using-params combinator, parameter value expected", c->get_line(), c->get_pos());
- symbol param_name = c->get_symbol();
+ symbol param_name = symbol(norm_param_name(c->get_symbol()).c_str());
c = n->get_child(i);
i++;
switch (descrs.get_kind(param_name)) {
diff --git a/src/front_end_params/arith_simplifier_params.cpp b/src/front_end_params/arith_simplifier_params.cpp
deleted file mode 100644
index 0c2f5c710..000000000
--- a/src/front_end_params/arith_simplifier_params.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- arith_simplifier_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-05-09.
-
-Revision History:
-
---*/
-
-#include"arith_simplifier_params.h"
-
-void arith_simplifier_params::register_params(ini_params & p) {
- p.register_bool_param("ARITH_EXPAND_EQS", m_arith_expand_eqs);
- p.register_bool_param("ARITH_PROCESS_ALL_EQS", m_arith_process_all_eqs);
-}
-
diff --git a/src/front_end_params/cnf_params.cpp b/src/front_end_params/cnf_params.cpp
deleted file mode 100644
index 57d02e8db..000000000
--- a/src/front_end_params/cnf_params.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- cnf_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-23.
-
-Revision History:
-
---*/
-
-#include"cnf_params.h"
-
-void cnf_params::register_params(ini_params & p) {
- p.register_unsigned_param("CNF_FACTOR", m_cnf_factor, "the maximum number of clauses that can be created when converting a subformula");
- p.register_int_param("CNF_MODE", 0, 3, reinterpret_cast(m_cnf_mode), "CNF translation mode: 0 - disabled, 1 - quantifiers in CNF, 2 - 0 + opportunistic, 3 - full");
-}
-
diff --git a/src/front_end_params/cnf_params.h b/src/front_end_params/cnf_params.h
deleted file mode 100644
index f694e1716..000000000
--- a/src/front_end_params/cnf_params.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- cnf_params.h
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-23.
-
-Revision History:
-
---*/
-#ifndef _CNF_PARAMS_H_
-#define _CNF_PARAMS_H_
-
-#include"ini_file.h"
-
-/**
- \brief CNF translation mode. The cheapest mode is CNF_QUANT, and
- the most expensive is CNF_FULL.
-*/
-enum cnf_mode {
- CNF_DISABLED, /* CNF translator is disabled.
- This mode is sufficient when using E-matching.
- */
- CNF_QUANT, /* A subformula is put into CNF if it is inside of a
- quantifier.
-
- This mode is sufficient when using Superposition
- Calculus.
- */
- CNF_OPPORTUNISTIC, /* a subformula is also put in CNF if it is cheap. */
- CNF_FULL /* Everything is put into CNF, new names are introduced
- if it is too expensive. */
-};
-
-struct cnf_params {
- cnf_mode m_cnf_mode;
- unsigned m_cnf_factor;
- cnf_params():
- m_cnf_mode(CNF_DISABLED),
- m_cnf_factor(4) {
- }
-
- void register_params(ini_params & p);
-};
-
-
-#endif /* _CNF_PARAMS_H_ */
-
diff --git a/src/front_end_params/front_end_params.cpp b/src/front_end_params/front_end_params.cpp
deleted file mode 100644
index 7aea7e7ee..000000000
--- a/src/front_end_params/front_end_params.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- front_end_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2007-05-10.
-
-Revision History:
-
---*/
-#include"front_end_params.h"
-
-void front_end_params::register_params(ini_params & p) {
- p.register_param_vector(m_param_vector.get());
- preprocessor_params::register_params(p);
- smt_params::register_params(p);
- parser_params::register_params(p);
- arith_simplifier_params::register_params(p);
- model_params::register_params(p);
- p.register_bool_param("AT_LABELS_CEX", m_at_labels_cex,
- "only use labels that contain '@' when building multiple counterexamples");
- p.register_bool_param("CHECK_AT_LABELS", m_check_at_labels,
- "check that labels containing '@' are used correctly to only produce unique counter examples");
- p.register_bool_param("DEFAULT_QID", m_default_qid, "create a default quantifier id based on its position, the id is used to report profiling information (see QI_PROFILE)");
-
- p.register_bool_param("TYPE_CHECK", m_well_sorted_check, "enable/disable type checker");
- p.register_bool_param("WELL_SORTED_CHECK", m_well_sorted_check, "enable/disable type checker");
- p.register_bool_param("INTERACTIVE", m_interactive, "enable interactive mode using Simplify input format");
- p.register_unsigned_param("SOFT_TIMEOUT", m_soft_timeout, "set approximate timeout for each solver query (milliseconds), the value 0 represents no timeout", true);
- p.register_double_param("INSTRUCTION_MAX", m_instr_out, "set the (approximate) maximal number of instructions per invocation of check", true);
- p.register_bool_param("AUTO_CONFIG", m_auto_config, "use heuristics to set Z3 configuration parameters, it is only available for the SMT-LIB input format");
- p.register_int_param("PROOF_MODE", 0, 2, reinterpret_cast(m_proof_mode), "select proof generation mode: 0 - disabled, 1 - coarse grain, 2 - fine grain");
- p.register_bool_param("TRACE", m_trace, "enable tracing for the Axiom Profiler tool");
- p.register_string_param("TRACE_FILE_NAME", m_trace_file_name, "tracing file name");
- p.register_bool_param("ASYNC_COMMANDS", m_async_commands, "enable/disable support for asynchronous commands in the Simplify front-end.");
- p.register_bool_param("DISPLAY_CONFIG", m_display_config, "display configuration used by Z3");
-
-#ifdef _WINDOWS
- // The non-windows memory manager does not have access to memory sizes.
- p.register_unsigned_param("MEMORY_HIGH_WATERMARK", m_memory_high_watermark,
- "set high watermark for memory consumption (in megabytes)");
- p.register_unsigned_param("MEMORY_MAX_SIZE", m_memory_max_size,
- "set hard upper limit for memory consumption (in megabytes)");
-#endif
-
-#ifndef _EXTERNAL_RELEASE
- // external users should not have access to it.
- p.register_bool_param("PREPROCESS", m_preprocess);
-#endif
-
- p.register_bool_param("USER_THEORY_PREPROCESS_AXIOMS",
- m_user_theory_preprocess_axioms,
- "Apply full pre-processing to user theory axioms",
- true);
-
- p.register_bool_param("USER_THEORY_PERSIST_AXIOMS",
- m_user_theory_persist_axioms,
- "Persist user axioms to the base level",
- true);
-
- p.register_bool_param("SMTLIB2_COMPLIANT", m_smtlib2_compliant);
-
- p.register_bool_param("IGNORE_BAD_PATTERNS", m_ignore_bad_patterns);
-
- PRIVATE_PARAMS({
- p.register_bool_param("IGNORE_CHECKSAT", m_ignore_checksat);
- p.register_bool_param("DEBUG_REF_COUNT", m_debug_ref_count);
- p.register_bool_param("IGNORE_USER_PATTERNS", m_ignore_user_patterns);
- p.register_bool_param("INCREMENTAL_CORE_ASSERT", m_incremental_core_assert);
- DEBUG_CODE(p.register_int_param("COPY_PARAMS", m_copy_params););
- });
-
- // temporary hack until strategic_solver is ported to new tactic framework
- PRIVATE_PARAMS({
- p.register_bool_param("NLSAT", m_nlsat);
- });
-}
-
-void front_end_params::open_trace_file() {
- if (m_trace) {
- m_trace_stream = alloc(std::fstream, m_trace_file_name.c_str(), std::ios_base::out);
- }
-}
-
-void front_end_params::close_trace_file() {
- if (m_trace_stream != NULL) {
- std::fstream &tmp = *m_trace_stream;
- m_trace_stream = NULL;
- tmp << "[eof]\n";
- tmp.close();
- // do not delete it, this might be called from a Ctrl-C signal handler
- // and there might be someone writing to it
- }
-}
diff --git a/src/front_end_params/front_end_params.h b/src/front_end_params/front_end_params.h
deleted file mode 100644
index 7a9b4e8e8..000000000
--- a/src/front_end_params/front_end_params.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- front_end_params.h
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2007-05-10.
-
-Revision History:
-
---*/
-#ifndef _FRONT_END_PARAMS_H_
-#define _FRONT_END_PARAMS_H_
-
-#include"ini_file.h"
-#include"ast.h"
-#include"preprocessor_params.h"
-#include"smt_params.h"
-#include"pp_params.h"
-#include"parser_params.h"
-#include"arith_simplifier_params.h"
-#include"model_params.h"
-
-struct front_end_params : public preprocessor_params, public smt_params, public parser_params,
- public arith_simplifier_params, public model_params
- {
- ref m_param_vector;
- bool m_at_labels_cex; // only use labels which contains the @ symbol when building multiple counterexamples.
- bool m_check_at_labels; // check that @ labels are inserted to generate unique counter-examples.
- bool m_default_qid;
- bool m_interactive;
- bool m_well_sorted_check;
- bool m_ignore_bad_patterns;
- bool m_ignore_user_patterns;
- bool m_incremental_core_assert; // assert conditions to the core incrementally
- unsigned m_soft_timeout;
- double m_instr_out;
- unsigned m_memory_high_watermark;
- unsigned m_memory_max_size;
- proof_gen_mode m_proof_mode;
- bool m_auto_config;
- bool m_smtlib2_compliant;
-#ifdef Z3DEBUG
- int m_copy_params; // used for testing copy params... Invoke method copy_params(m_copy_params) in main.cpp when diff -1.
-#endif
- bool m_preprocess; // temporary hack for disabling all preprocessing..
- bool m_ignore_checksat; // abort before checksat... for internal debugging
- bool m_debug_ref_count;
- bool m_trace;
- std::string m_trace_file_name;
- std::fstream* m_trace_stream;
- bool m_async_commands;
- bool m_display_config;
- bool m_user_theory_preprocess_axioms;
- bool m_user_theory_persist_axioms;
- bool m_nlsat; // temporary hack until strategic_solver is ported to new tactic framework
-
- front_end_params():
- m_param_vector(alloc(param_vector, this)),
- m_at_labels_cex(false),
- m_check_at_labels(false),
- m_default_qid(false),
- m_interactive(false),
- m_well_sorted_check(true),
- m_ignore_bad_patterns(true),
- m_ignore_user_patterns(false),
- m_incremental_core_assert(true),
- m_soft_timeout(0),
- m_instr_out(0.0),
- m_memory_high_watermark(0),
- m_memory_max_size(0),
- m_proof_mode(PGM_DISABLED),
-#if defined(SMTCOMP) || defined(_EXTERNAL_RELEASE)
- m_auto_config(true),
-#else
- m_auto_config(false),
-#endif
-#if 0
- m_smtlib2_compliant(true),
-#else
- m_smtlib2_compliant(false),
-#endif
-#ifdef Z3DEBUG
- m_copy_params(-1),
-#endif
- m_preprocess(true), // temporary hack for disabling all preprocessing..
- m_ignore_checksat(false),
- m_debug_ref_count(false),
- m_trace(false),
- m_trace_file_name("z3.log"),
- m_trace_stream(NULL),
- m_async_commands(true),
- m_display_config(false),
- m_user_theory_preprocess_axioms(false),
- m_user_theory_persist_axioms(false),
- m_nlsat(false) {
- }
-
- void register_params(ini_params & p);
-
- void open_trace_file();
-
- void close_trace_file();
-
- void copy_params(unsigned idx) {
- m_param_vector->copy_params(this, idx);
- }
-
- bool has_auto_config(unsigned idx) { return m_auto_config; }
-
-private:
-
- front_end_params& operator=(front_end_params const& other);
-};
-
-#endif /* _FRONT_END_PARAMS_H_ */
-
diff --git a/src/front_end_params/model_params.cpp b/src/front_end_params/model_params.cpp
deleted file mode 100644
index df6420b7a..000000000
--- a/src/front_end_params/model_params.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- model_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2007-08-23.
-
-Revision History:
-
---*/
-
-#include"model_params.h"
-
-void model_params::register_params(ini_params & p) {
- p.register_bool_param("MODEL_PARTIAL", m_model_partial, "enable/disable partial function interpretations", true);
- p.register_bool_param("MODEL_V1", m_model_v1_pp,
- "use Z3 version 1.x pretty printer", true);
- p.register_bool_param("MODEL_V2", m_model_v2_pp,
- "use Z3 version 2.x (x <= 16) pretty printer", true);
- p.register_bool_param("MODEL_COMPACT", m_model_compact,
- "try to compact function graph (i.e., function interpretations that are lookup tables", true);
- p.register_bool_param("MODEL_COMPLETION", m_model_completion,
- "assigns an interptetation to symbols that do not have one in the current model, when evaluating expressions in the current model", true);
-
-}
-
-
diff --git a/src/front_end_params/model_params.h b/src/front_end_params/model_params.h
deleted file mode 100644
index 2718d4e5f..000000000
--- a/src/front_end_params/model_params.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- model_params.h
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2007-08-23.
-
-Revision History:
-
---*/
-#ifndef _MODEL_PARAMS_H_
-#define _MODEL_PARAMS_H_
-
-#include"ini_file.h"
-
-struct model_params {
- bool m_model_partial;
- bool m_model_compact;
- bool m_model_v1_pp;
- bool m_model_v2_pp;
- bool m_model_completion;
-
- model_params():
- m_model_partial(false),
- m_model_compact(false),
- m_model_v1_pp(false),
- m_model_v2_pp(false),
- m_model_completion(false) {
- }
-
- void register_params(ini_params & p);
-};
-
-#endif /* _MODEL_PARAMS_H_ */
-
diff --git a/src/front_end_params/nnf_params.cpp b/src/front_end_params/nnf_params.cpp
deleted file mode 100644
index 044ca155e..000000000
--- a/src/front_end_params/nnf_params.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- nnf_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-14.
-
-Revision History:
-
---*/
-#include"nnf_params.h"
-
-void nnf_params::register_params(ini_params & p) {
- p.register_unsigned_param("NNF_FACTOR", m_nnf_factor, "the maximum growth factor during NNF translation (auxiliary definitions are introduced if the threshold is reached)");
- p.register_int_param("NNF_MODE", 0, 3, reinterpret_cast(m_nnf_mode), "NNF translation mode: 0 - skolem normal form, 1 - 0 + quantifiers in NNF, 2 - 1 + opportunistic, 3 - full");
- p.register_bool_param("NNF_IGNORE_LABELS", m_nnf_ignore_labels, "remove/ignore labels in the input formula, this option is ignored if proofs are enabled");
- p.register_bool_param("NNF_SK_HACK", m_nnf_sk_hack, "hack for VCC");
-}
diff --git a/src/front_end_params/nnf_params.h b/src/front_end_params/nnf_params.h
deleted file mode 100644
index f759a93ac..000000000
--- a/src/front_end_params/nnf_params.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- nnf_params.h
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-14.
-
-Revision History:
-
---*/
-#ifndef _NNF_PARAMS_H_
-#define _NNF_PARAMS_H_
-
-#include"ini_file.h"
-
-/**
- \brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and
- the most expensive is NNF_FULL.
-*/
-enum nnf_mode {
- NNF_SKOLEM, /* A subformula is put into NNF only if it contains
- quantifiers or labels. The result of the
- transformation will be in skolem normal form.
- If a formula is too expensive to be put into NNF,
- then nested quantifiers and labels are renamed.
-
- This mode is sufficient when using E-matching.
- */
- NNF_QUANT, /* A subformula is put into NNF if it contains
- quantifiers, labels, or is in the scope of a
- quantifier. The result of the transformation will be
- in skolem normal form, and the body of quantifiers
- will be in NNF. If a ground formula is too expensive to
- be put into NNF, then nested quantifiers and labels
- are renamed.
-
- This mode is sufficient when using Superposition
- Calculus.
-
- Remark: If the problem does not contain quantifiers,
- then NNF_QUANT is identical to NNF_SKOLEM.
- */
- NNF_OPPORTUNISTIC, /* Similar to NNF_QUANT, but a subformula is
- also put into NNF, if it is
- cheap. Otherwise, the nested quantifiers and
- labels are renamed. */
- NNF_FULL /* Everything is put into NNF. */
-};
-
-struct nnf_params {
- nnf_mode m_nnf_mode;
- unsigned m_nnf_factor;
- bool m_nnf_ignore_labels;
- bool m_nnf_sk_hack;
- nnf_params():
- m_nnf_mode(NNF_SKOLEM),
- m_nnf_factor(4),
- m_nnf_ignore_labels(false),
- m_nnf_sk_hack(false) {
- }
-
- void register_params(ini_params & p);
-};
-
-#endif /* _NNF_PARAMS_H_ */
-
diff --git a/src/front_end_params/params2front_end_params.cpp b/src/front_end_params/params2front_end_params.cpp
deleted file mode 100644
index a2bae371c..000000000
--- a/src/front_end_params/params2front_end_params.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*++
-Copyright (c) 2011 Microsoft Corporation
-
-Module Name:
-
- params2front_end_params.h
-
-Abstract:
-
- Backward compatibility utilities for parameter setting
-
-Author:
-
- Leonardo de Moura (leonardo) 2011-05-19.
-
-Revision History:
-
---*/
-#include"front_end_params.h"
-#include"params.h"
-
-/**
- Update front_end_params using s.
- Only the most frequently used options are updated.
-
- This function is mainly used to allow smt::context to be used in
- the new strategy framework.
-*/
-void params2front_end_params(params_ref const & s, front_end_params & t) {
- t.m_relevancy_lvl = s.get_uint(":relevancy", t.m_relevancy_lvl);
- TRACE("qi_cost", s.display(tout); tout << "\n";);
- t.m_qi_cost = s.get_str(":qi-cost", t.m_qi_cost.c_str());
- t.m_mbqi = s.get_bool(":mbqi", t.m_mbqi);
- t.m_mbqi_max_iterations = s.get_uint(":mbqi-max-iterations", t.m_mbqi_max_iterations);
- t.m_random_seed = s.get_uint(":random-seed", t.m_random_seed);
- t.m_model = s.get_bool(":produce-models", t.m_model);
- if (s.get_bool(":produce-proofs", false))
- t.m_proof_mode = PGM_FINE;
- t.m_well_sorted_check = s.get_bool(":check-sorts", t.m_well_sorted_check);
- t.m_qi_eager_threshold = s.get_double(":qi-eager-threshold", t.m_qi_eager_threshold);
- t.m_qi_lazy_threshold = s.get_double(":qi-lazy-threshold", t.m_qi_lazy_threshold);
- t.m_preprocess = s.get_bool(":preprocess", t.m_preprocess);
- t.m_hi_div0 = s.get_bool(":hi-div0", t.m_hi_div0);
- t.m_auto_config = s.get_bool(":auto-config", t.m_auto_config);
- t.m_array_simplify = s.get_bool(":array-old-simplifier", t.m_array_simplify);
- t.m_arith_branch_cut_ratio = s.get_uint(":arith-branch-cut-ratio", t.m_arith_branch_cut_ratio);
- t.m_arith_expand_eqs = s.get_bool(":arith-expand-eqs", t.m_arith_expand_eqs);
-
- if (s.get_bool(":arith-greatest-error-pivot", false))
- t.m_arith_pivot_strategy = ARITH_PIVOT_GREATEST_ERROR;
- else if (s.get_bool(":arith-least-error-pivot", false))
- t.m_arith_pivot_strategy = ARITH_PIVOT_LEAST_ERROR;
-}
-
-/**
- \brief Copy parameters (from s) that affect the semantics of Z3 (e.g., HI_DIV0).
- It also copies the model construction parameter. Thus, model construction
- can be enabled at the command line.
-*/
-void front_end_params2params(front_end_params const & s, params_ref & t) {
- if (s.m_model)
- t.set_bool(":produce-models", true);
- if (!s.m_hi_div0)
- t.set_bool(":hi-div0", false);
-}
-
-/**
- \brief Bridge for using params_ref with smt::context.
-*/
-void solver_front_end_params_descrs(param_descrs & r) {
- r.insert(":hi-div0", CPK_BOOL, "(default: true) if true, then Z3 uses the usual hardware interpretation for division (rem, mod) by zero. Otherwise, these operations are considered uninterpreted");
- r.insert(":relevancy", CPK_UINT, "relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant");
- r.insert(":mbqi", CPK_BOOL, "model based quantifier instantiation (MBQI)");
- r.insert(":mbqi-max-iterations", CPK_UINT, "maximum number of rounds of MBQI");
- r.insert(":random-seed", CPK_UINT, "random seed for smt solver");
- r.insert(":qi-eager-threshold", CPK_DOUBLE, "threshold for eager quantifier instantiation");
- r.insert(":qi-lazy-threshold", CPK_DOUBLE, "threshold for lazy quantifier instantiation");
- r.insert(":auto_config", CPK_BOOL, "use heuristics to automatically configure smt solver");
- r.insert(":arith-branch-cut-ratio", CPK_UINT, "branch&bound / gomory cut ratio");
-}
diff --git a/src/front_end_params/params2front_end_params.h b/src/front_end_params/params2front_end_params.h
deleted file mode 100644
index 936928d4a..000000000
--- a/src/front_end_params/params2front_end_params.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*++
-Copyright (c) 2011 Microsoft Corporation
-
-Module Name:
-
- params2front_end_params.h
-
-Abstract:
-
- Backward compatibility utilities for parameter setting
-
-Author:
-
- Leonardo de Moura (leonardo) 2011-05-19.
-
-Revision History:
-
---*/
-#ifndef _PARAMS2FRONT_END_PARAMS_H_
-#define _PARAMS2FRONT_END_PARAMS_H_
-
-class params_ref;
-struct front_end_params;
-
-void params2front_end_params(params_ref const & s, front_end_params & t);
-
-void front_end_params2params(front_end_params const & s, params_ref & t);
-
-void solver_front_end_params_descrs(param_descrs & r);
-
-#endif
diff --git a/src/front_end_params/parser_params.cpp b/src/front_end_params/parser_params.cpp
deleted file mode 100644
index 000885fa5..000000000
--- a/src/front_end_params/parser_params.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "parser_params.h"
-
-parser_params::parser_params() :
- m_dump_goal_as_smt(false),
- m_display_error_for_vs(false) {
-}
-
-void parser_params::register_params(ini_params & p) {
- p.register_bool_param("DUMP_GOAL_AS_SMT", m_dump_goal_as_smt, "write goal back to output in SMT format");
- p.register_bool_param("DISPLAY_ERROR_FOR_VISUAL_STUDIO", m_display_error_for_vs, "display error messages in Visual Studio format");
-}
-
-
-
diff --git a/src/front_end_params/parser_params.h b/src/front_end_params/parser_params.h
deleted file mode 100644
index eaab4fd81..000000000
--- a/src/front_end_params/parser_params.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*++
-Copyright (c) 2008 Microsoft Corporation
-
-Module Name:
-
- parser_params.h
-
-Abstract:
-
-
-
-Author:
-
- Nikolaj Bjorner (nbjorner) 2008-04-21.
-
-Revision History:
-
---*/
-#ifndef _PARSER_PARAMS_H_
-#define _PARSER_PARAMS_H_
-
-#include"ini_file.h"
-
-struct parser_params {
- bool m_dump_goal_as_smt; // re-print goal as SMT benchmark.
- bool m_display_error_for_vs; // print error in vs format.
-
- parser_params();
- void register_params(ini_params & p);
-};
-
-#endif /* _PARSER_PARAMS_H_ */
-
diff --git a/src/front_end_params/pattern_inference_params.cpp b/src/front_end_params/pattern_inference_params.cpp
deleted file mode 100644
index 176fdd8c2..000000000
--- a/src/front_end_params/pattern_inference_params.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- pattern_inference_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-03-24.
-
-Revision History:
-
---*/
-#include"pattern_inference_params.h"
-
-void pattern_inference_params::register_params(ini_params & p) {
- p.register_unsigned_param("PI_MAX_MULTI_PATTERNS", m_pi_max_multi_patterns,
- "when patterns are not provided, the prover uses a heuristic to infer them. This option sets the threshold on the number of extra multi-patterns that can be created. By default, the prover creates at most one multi-pattern when there is no unary pattern");
- p.register_bool_param("PI_BLOCK_LOOP_PATTERNS", m_pi_block_loop_patterns,
- "block looping patterns during pattern inference");
- p.register_int_param("PI_ARITH", 0, 2, reinterpret_cast(m_pi_arith),
- "0 - do not infer patterns with arithmetic terms, 1 - use patterns with arithmetic terms if there is no other pattern, 2 - always use patterns with arithmetic terms.");
- p.register_bool_param("PI_USE_DATABASE", m_pi_use_database);
- p.register_unsigned_param("PI_ARITH_WEIGHT", m_pi_arith_weight, "default weight for quantifiers where the only available pattern has nested arithmetic terms.");
- p.register_unsigned_param("PI_NON_NESTED_ARITH_WEIGHT", m_pi_non_nested_arith_weight, "default weight for quantifiers where the only available pattern has non nested arithmetic terms.");
- p.register_bool_param("PI_PULL_QUANTIFIERS", m_pi_pull_quantifiers, "pull nested quantifiers, if no pattern was found.");
- p.register_int_param("PI_NOPAT_WEIGHT", m_pi_nopat_weight, "set weight of quantifiers without patterns, if negative the weight is not changed.");
- p.register_bool_param("PI_AVOID_SKOLEMS", m_pi_avoid_skolems);
- p.register_bool_param("PI_WARNINGS", m_pi_warnings, "enable/disable warning messages in the pattern inference module.");
-}
-
-
diff --git a/src/front_end_params/preprocessor_params.h b/src/front_end_params/preprocessor_params.h
deleted file mode 100644
index 4b32feb60..000000000
--- a/src/front_end_params/preprocessor_params.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- preprocessor_params.h
-
-Abstract:
-
- Preprocess AST before adding them to the logical context
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-01-17.
-
-Revision History:
-
---*/
-#ifndef _PREPROCESSOR_PARAMS_H_
-#define _PREPROCESSOR_PARAMS_H_
-
-#include"nnf_params.h"
-#include"cnf_params.h"
-#include"pattern_inference_params.h"
-#include"bit_blaster_params.h"
-#include"bv_simplifier_params.h"
-
-enum lift_ite_kind {
- LI_NONE,
- LI_CONSERVATIVE,
- LI_FULL
-};
-
-struct preprocessor_params : public nnf_params, public cnf_params, public pattern_inference_params,
- public bit_blaster_params, public bv_simplifier_params {
- lift_ite_kind m_lift_ite;
- lift_ite_kind m_ng_lift_ite; // lift ite for non ground terms
- bool m_pull_cheap_ite_trees;
- bool m_pull_nested_quantifiers;
- bool m_eliminate_term_ite;
- bool m_eliminate_and; // represent (and a b) as (not (or (not a) (not b)))
- bool m_macro_finder;
- bool m_propagate_values;
- bool m_propagate_booleans;
- bool m_refine_inj_axiom;
- bool m_eliminate_bounds;
- bool m_simplify_bit2int;
- bool m_nnf_cnf;
- bool m_distribute_forall;
- bool m_reduce_args;
- bool m_quasi_macros;
- bool m_restricted_quasi_macros;
- bool m_max_bv_sharing;
- bool m_pre_simplifier;
- bool m_nlquant_elim;
-
-public:
- preprocessor_params():
- m_lift_ite(LI_NONE),
- m_ng_lift_ite(LI_NONE),
- m_pull_cheap_ite_trees(false),
- m_pull_nested_quantifiers(false),
- m_eliminate_term_ite(false),
- m_eliminate_and(true),
- m_macro_finder(false),
- m_propagate_values(true),
- m_propagate_booleans(false), // TODO << check peformance
- m_refine_inj_axiom(true),
- m_eliminate_bounds(false),
- m_simplify_bit2int(false),
- m_nnf_cnf(true),
- m_distribute_forall(false),
- m_reduce_args(false),
- m_quasi_macros(false),
- m_restricted_quasi_macros(false),
- m_max_bv_sharing(true),
- m_pre_simplifier(true),
- m_nlquant_elim(false) {
- }
-
- void register_params(ini_params & p) {
- nnf_params::register_params(p);
- cnf_params::register_params(p);
- pattern_inference_params::register_params(p);
- bit_blaster_params::register_params(p);
- bv_simplifier_params::register_params(p);
- p.register_int_param("LIFT_ITE", 0, 2, reinterpret_cast(m_lift_ite), "ite term lifting: 0 - no lifting, 1 - conservative, 2 - full");
- p.register_int_param("NG_LIFT_ITE", 0, 2, reinterpret_cast(m_ng_lift_ite), "ite (non-ground) term lifting: 0 - no lifting, 1 - conservative, 2 - full");
- p.register_bool_param("ELIM_TERM_ITE", m_eliminate_term_ite, "eliminate term if-then-else in the preprocessor");
- p.register_bool_param("ELIM_AND", m_eliminate_and, "represent (and a b) as (not (or (not a) (not b)))");
- p.register_bool_param("MACRO_FINDER", m_macro_finder, "try to find universally quantified formulas that can be viewed as macros");
- p.register_bool_param("PROPAGATE_VALUES", m_propagate_values, "propagate values during preprocessing step");
- p.register_bool_param("PROPAGATE_BOOLEANS", m_propagate_booleans, "propagate boolean values during preprocessing step");
- p.register_bool_param("PULL_CHEAP_ITE_TREES", m_pull_cheap_ite_trees);
- p.register_bool_param("PULL_NESTED_QUANTIFIERS", m_pull_nested_quantifiers, "eliminate nested quantifiers by moving nested quantified variables to the outermost quantifier, it is unnecessary if the formula is converted into CNF");
- p.register_bool_param("REFINE_INJ_AXIOM", m_refine_inj_axiom);
- p.register_bool_param("ELIM_BOUNDS", m_eliminate_bounds, "cheap Fourier-Motzkin");
-
- p.register_bool_param("BIT2INT", m_simplify_bit2int, "hoist bit2int conversions over arithmetical expressions");
- p.register_bool_param("DISTRIBUTE_FORALL", m_distribute_forall);
- p.register_bool_param("REDUCE_ARGS", m_reduce_args);
- p.register_bool_param("QUASI_MACROS", m_quasi_macros);
- p.register_bool_param("RESTRICTED_QUASI_MACROS", m_restricted_quasi_macros);
- p.register_bool_param("BV_MAX_SHARING", m_max_bv_sharing);
- p.register_bool_param("PRE_SIMPLIFIER", m_pre_simplifier);
- }
-};
-
-#endif /* _PREPROCESSOR_PARAMS_H_ */
diff --git a/src/front_end_params/smt_params.cpp b/src/front_end_params/smt_params.cpp
deleted file mode 100644
index 0c4a0c844..000000000
--- a/src/front_end_params/smt_params.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- smt_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-02-20.
-
-Revision History:
-
---*/
-#include"smt_params.h"
-#include"trace.h"
-
-void smt_params::register_params(ini_params & p) {
- dyn_ack_params::register_params(p);
- qi_params::register_params(p);
- theory_arith_params::register_params(p);
- theory_array_params::register_params(p);
- theory_bv_params::register_params(p);
- theory_datatype_params::register_params(p);
-
- p.register_bool_param("CHECK_PROOF", m_check_proof);
- p.register_bool_param("DISPLAY_PROOF", m_display_proof);
- p.register_bool_param("DISPLAY_DOT_PROOF", m_display_dot_proof);
- p.register_bool_param("DISPLAY_UNSAT_CORE", m_display_unsat_core);
- p.register_bool_param("INTERNALIZER_NNF", m_internalizer_nnf);
- p.register_bool_param("EQ_PROPAGATION", m_eq_propagation);
- p.register_bool_param("BIN_CLAUSES", m_binary_clause_opt);
- p.register_unsigned_param("RELEVANCY", m_relevancy_lvl, "relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant", true);
- p.register_bool_param("RELEVANCY_LEMMA", m_relevancy_lemma, "true if lemmas are used to propagate relevancy");
- p.register_unsigned_param("RANDOM_SEED", m_random_seed, "random seed for Z3");
- p.register_percentage_param("RANDOM_CASE_SPLIT_FREQ", m_random_var_freq, "frequency of random case splits");
- p.register_int_param("PHASE_SELECTION", 0, 6, reinterpret_cast(m_phase_selection), "phase selection heuristic: 0 - always false, 1 - always true, 2 - phase caching, 3 - phase caching conservative, 4 - phase caching conservative 2, 5 - random, 6 - number of occurrences");
- p.register_bool_param("MINIMIZE_LEMMAS", m_minimize_lemmas, "enable/disable lemma minimization algorithm");
- p.register_unsigned_param("MAX_CONFLICTS", m_max_conflicts, "maximum number of conflicts");
-
- p.register_unsigned_param("RECENT_LEMMA_THRESHOLD", m_recent_lemmas_size);
- p.register_unsigned_param("TICK", m_tick);
-
- PRIVATE_PARAMS({
- p.register_bool_param("THEORY_RESOLVE", m_theory_resolve, "Apply theory resolution to produce auxiliary conflict clauses", true);
- });
-
- p.register_int_param("RESTART_STRATEGY", 0, 4, reinterpret_cast(m_restart_strategy), "0 - geometric, 1 - inner-outer-geometric, 2 - luby, 3 - fixed, 4 - arithmetic");
- p.register_unsigned_param("RESTART_INITIAL", m_restart_initial,
- "inital restart frequency in number of conflicts, it is also the unit for the luby sequence");
- p.register_double_param("RESTART_FACTOR", m_restart_factor, "when using geometric (or inner-outer-geometric) progression of restarts, it specifies the constant used to multiply the currect restart threshold");
- p.register_bool_param("RESTART_ADAPTIVE", m_restart_adaptive, "disable restarts based on the search 'agility'");
- p.register_percentage_param("RESTART_AGILITY_THRESHOLD", m_restart_agility_threshold);
-
- p.register_int_param("LEMMA_GC_STRATEGY", 0, 2, reinterpret_cast(m_lemma_gc_strategy), "0 - fixed, 1 - geometric, 2 - at every restart");
- p.register_bool_param("LEMMA_GC_HALF", m_lemma_gc_half, "true for simple gc algorithm (delete approx. half of the clauses)");
- p.register_unsigned_param("LEMMA_GC_INITIAL", m_lemma_gc_initial, "lemma initial gc frequency (in number of conflicts), used by fixed or geometric strategies");
- p.register_double_param("LEMMA_GC_FACTOR", m_lemma_gc_factor, "used by geometric strategy");
- p.register_unsigned_param("LEMMA_GC_NEW_OLD_RATIO", m_new_old_ratio);
- p.register_unsigned_param("LEMMA_GC_NEW_CLAUSE_ACTIVITY", m_new_clause_activity);
- p.register_unsigned_param("LEMMA_GC_OLD_CLAUSE_ACTIVITY", m_old_clause_activity);
- p.register_unsigned_param("LEMMA_GC_NEW_CLAUSE_RELEVANCY", m_new_clause_relevancy);
- p.register_unsigned_param("LEMMA_GC_OLD_CLAUSE_RELEVANCY", m_old_clause_activity);
-
- p.register_bool_param("SIMPLIFY_CLAUSES", m_simplify_clauses);
-
- p.register_int_param("RANDOM_INITIAL_ACTIVITY", 0, 2, reinterpret_cast(m_random_initial_activity));
-
- PRIVATE_PARAMS({
-
- p.register_double_param("INV_DECAY", m_inv_decay);
- p.register_unsigned_param("PHASE_CACHING_ON_DURATION", m_phase_caching_on);
- p.register_unsigned_param("PHASE_CACHING_OFF_DURATION", m_phase_caching_off);
- });
-
- p.register_bool_param("SMTLIB_DUMP_LEMMAS", m_smtlib_dump_lemmas);
- p.register_string_param("SMTLIB_LOGIC", m_smtlib_logic, "Name used for the :logic field when generating SMT-LIB benchmarks");
- p.register_bool_param("DISPLAY_FEATURES", m_display_features);
-
- p.register_bool_param("NEW_CORE2TH_EQ", m_new_core2th_eq);
- p.register_bool_param("EMATCHING", m_ematching, "E-Matching based quantifier instantiation");
-
- p.register_bool_param("PROFILE_RES_SUB", m_profile_res_sub);
-#ifndef _EXTERNAL_RELEASE
- p.register_bool_param("DISPLAY_BOOL_VAR2EXPR", m_display_bool_var2expr);
- p.register_bool_param("DISPLAY_LL_BOOL_VAR2EXPR", m_display_ll_bool_var2expr);
- p.register_bool_param("ABORT_AFTER_PREPROC", m_abort_after_preproc, "abort after preprocessing step, this flag is only useful for debugging purposes");
- p.register_bool_param("DISPLAY_INSTALLED_THEORIES", m_display_installed_theories, "display theories installed at smt::context", true);
-#endif
- p.register_int_param("CASE_SPLIT", 0, 5, reinterpret_cast(m_case_split_strategy), "0 - case split based on variable activity, 1 - similar to 0, but delay case splits created during the search, 2 - similar to 0, but cache the relevancy, 3 - case split based on relevancy (structural splitting), 4 - case split on relevancy and activity, 5 - case split on relevancy and current goal");
- p.register_unsigned_param("REL_CASE_SPLIT_ORDER", 0, 2, m_rel_case_split_order, "structural (relevancy) splitting order: 0 - left-to-right (default), 1 - random, 2 - right-to-left");
- p.register_bool_param("LOOKAHEAD_DISEQ", m_lookahead_diseq);
-
- p.register_bool_param("DELAY_UNITS", m_delay_units);
- p.register_unsigned_param("DELAY_UNITS_THRESHOLD", m_delay_units_threshold);
-
- p.register_bool_param("MODEL", m_model, "enable/disable model construction", true);
- p.register_bool_param("MODEL_VALIDATE", m_model_validate, "validate the model", true);
- p.register_bool_param("MODEL_ON_TIMEOUT", m_model_on_timeout, "after hitting soft-timeout or memory high watermark, generate a candidate model", true);
- p.register_bool_param("MODEL_ON_FINAL_CHECK", m_model_on_final_check, "display candidate model (in the standard output) whenever Z3 hits a final check", true);
-
- p.register_unsigned_param("PROGRESS_SAMPLING_FREQ", m_progress_sampling_freq, "frequency for progress output in miliseconds");
-}
-
diff --git a/src/front_end_params/theory_arith_params.cpp b/src/front_end_params/theory_arith_params.cpp
deleted file mode 100644
index 2d77b6e73..000000000
--- a/src/front_end_params/theory_arith_params.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- theory_arith_params.cpp
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-05-06.
-
-Revision History:
-
---*/
-
-#include"theory_arith_params.h"
-
-void theory_arith_params::register_params(ini_params & p) {
-#ifdef _EXTERNAL_RELEASE
- p.register_int_param("ARITH_SOLVER", 0, 3, reinterpret_cast(m_arith_mode), "select arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination");
-#else
- p.register_int_param("ARITH_SOLVER", 0, 4, reinterpret_cast(m_arith_mode), "select arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination, 4 - model guided arith_solver");
-#endif
- p.register_bool_param("ARITH_FORCE_SIMPLEX", m_arith_auto_config_simplex, "force Z3 to use simplex solver.");
- p.register_unsigned_param("ARITH_BLANDS_RULE_THRESHOLD", m_arith_blands_rule_threshold);
- p.register_bool_param("ARITH_PROPAGATE_EQS", m_arith_propagate_eqs);
- p.register_int_param("ARITH_PROPAGATION_MODE", 0, 2, reinterpret_cast(m_arith_bound_prop));
- p.register_bool_param("ARITH_STRONGER_LEMMAS", m_arith_stronger_lemmas);
- p.register_bool_param("ARITH_SKIP_BIG_COEFFS", m_arith_skip_rows_with_big_coeffs);
- p.register_unsigned_param("ARITH_MAX_LEMMA_SIZE", m_arith_max_lemma_size);
- p.register_unsigned_param("ARITH_SMALL_LEMMA_SIZE", m_arith_small_lemma_size);
- p.register_bool_param("ARITH_REFLECT", m_arith_reflect);
- p.register_bool_param("ARITH_IGNORE_INT", m_arith_ignore_int);
- p.register_unsigned_param("ARITH_LAZY_PIVOTING", m_arith_lazy_pivoting_lvl);
- p.register_unsigned_param("ARITH_RANDOM_SEED", m_arith_random_seed);
- p.register_bool_param("ARITH_RANDOM_INITIAL_VALUE", m_arith_random_initial_value);
- p.register_int_param("ARITH_RANDOM_LOWER", m_arith_random_lower);
- p.register_int_param("ARITH_RANDOM_UPPER", m_arith_random_upper);
- p.register_bool_param("ARITH_ADAPTIVE", m_arith_adaptive);
- p.register_double_param("ARITH_ADAPTIVE_ASSERTION_THRESHOLD", m_arith_adaptive_assertion_threshold, "Delay arithmetic atoms if the num-arith-conflicts/total-conflicts < threshold");
- p.register_double_param("ARITH_ADAPTIVE_PROPAGATION_THRESHOLD", m_arith_adaptive_propagation_threshold, "Disable arithmetic theory propagation if the num-arith-conflicts/total-conflicts < threshold");
- p.register_bool_param("ARITH_DUMP_LEMMAS", m_arith_dump_lemmas);
- p.register_bool_param("ARITH_EAGER_EQ_AXIOMS", m_arith_eager_eq_axioms);
- p.register_unsigned_param("ARITH_BRANCH_CUT_RATIO", m_arith_branch_cut_ratio);
-
- p.register_bool_param("ARITH_ADD_BINARY_BOUNDS", m_arith_add_binary_bounds);
- p.register_unsigned_param("ARITH_PROP_STRATEGY", 0, 1, reinterpret_cast(m_arith_propagation_strategy), "Propagation strategy: 0 - use agility measures based on ration of theory conflicts, 1 - propagate proportional to ratio of theory conflicts (default)");
-
- p.register_bool_param("ARITH_EQ_BOUNDS", m_arith_eq_bounds);
- p.register_bool_param("ARITH_LAZY_ADAPTER", m_arith_lazy_adapter);
- p.register_bool_param("ARITH_GCD_TEST", m_arith_gcd_test);
- p.register_bool_param("ARITH_EAGER_GCD", m_arith_eager_gcd);
- p.register_bool_param("ARITH_ADAPTIVE_GCD", m_arith_adaptive_gcd);
- p.register_unsigned_param("ARITH_PROPAGATION_THRESHOLD", m_arith_propagation_threshold);
-
- p.register_bool_param("NL_ARITH", m_nl_arith, "enable/disable non linear arithmetic support. This option is ignored when ARITH_SOLVER != 2.");
- p.register_bool_param("NL_ARITH_GB", m_nl_arith_gb, "enable/disable Grobner Basis computation. This option is ignored when NL_ARITH=false");
- p.register_bool_param("NL_ARITH_GB_EQS", m_nl_arith_gb_eqs, "enable/disable equations in the Grobner Basis to be copied to the Simplex tableau.");
- p.register_bool_param("NL_ARITH_GB_PERTURBATE", m_nl_arith_gb_perturbate, "enable/disable perturbation of the variable order in GB when searching for new polynomials.");
- p.register_unsigned_param("NL_ARITH_GB_THRESHOLD", m_nl_arith_gb_threshold, "Grobner basis computation can be very expensive. This is a threshold on the number of new equalities that can be generated.");
- p.register_bool_param("NL_ARITH_BRANCHING", m_nl_arith_branching, "enable/disable branching on integer variables in non linear clusters");
- p.register_unsigned_param("NL_ARITH_ROUNDS", m_nl_arith_rounds, "threshold for number of (nested) final checks for non linear arithmetic.");
- p.register_unsigned_param("NL_ARITH_MAX_DEGREE", m_nl_arith_max_degree, "max degree for internalizing new monomials.");
- PRIVATE_PARAMS({
- p.register_bool_param("ARITH_FIXNUM", m_arith_fixnum);
- p.register_bool_param("ARITH_INT_ONLY", m_arith_int_only);
- p.register_bool_param("ARITH_ENUM_CONST_MOD", m_arith_enum_const_mod, "Create axioms for the finite set of equalities for (mod x k) where k is a positive numeral constant");
- p.register_bool_param("ARITH_INT_EQ_BRANCHING", m_arith_int_eq_branching, "Determine branch predicates based on integer equation solving");
- });
- p.register_bool_param("ARITH_EUCLIDEAN_SOLVER", m_arith_euclidean_solver, "");
-}
-
diff --git a/src/front_end_params/theory_bv_params.h b/src/front_end_params/theory_bv_params.h
deleted file mode 100644
index 38e1e263f..000000000
--- a/src/front_end_params/theory_bv_params.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*++
-Copyright (c) 2006 Microsoft Corporation
-
-Module Name:
-
- theory_bv_params.h
-
-Abstract:
-
-
-
-Author:
-
- Leonardo de Moura (leonardo) 2008-06-06.
-
-Revision History:
-
---*/
-#ifndef _THEORY_BV_PARAMS_H_
-#define _THEORY_BV_PARAMS_H_
-
-#include"ini_file.h"
-
-enum bv_solver_id {
- BS_NO_BV,
- BS_BLASTER
-};
-
-struct theory_bv_params {
- bv_solver_id m_bv_mode;
- bool m_bv_reflect;
- bool m_bv_lazy_le;
- bool m_bv_cc;
- unsigned m_bv_blast_max_size;
- bool m_bv_enable_int2bv2int;
- theory_bv_params():
- m_bv_mode(BS_BLASTER),
- m_bv_reflect(true),
- m_bv_lazy_le(false),
- m_bv_cc(false),
- m_bv_blast_max_size(INT_MAX),
- m_bv_enable_int2bv2int(false) {}
- void register_params(ini_params & p) {
- p.register_int_param("BV_SOLVER", 0, 2, reinterpret_cast(m_bv_mode), "0 - no bv, 1 - simple");
- p.register_unsigned_param("BV_BLAST_MAX_SIZE", m_bv_blast_max_size, "Maximal size for bit-vectors to blast");
- p.register_bool_param("BV_REFLECT", m_bv_reflect);
- p.register_bool_param("BV_LAZY_LE", m_bv_lazy_le);
- p.register_bool_param("BV_CC", m_bv_cc, "enable congruence closure for BV operators");
- p.register_bool_param("BV_ENABLE_INT2BV_PROPAGATION", m_bv_enable_int2bv2int,
- "enable full (potentially expensive) propagation for int2bv and bv2int");
- }
-};
-
-#endif /* _THEORY_BV_PARAMS_H_ */
-
diff --git a/src/math/polynomial/algebraic.pyg b/src/math/polynomial/algebraic.pyg
new file mode 100644
index 000000000..92a2f10df
--- /dev/null
+++ b/src/math/polynomial/algebraic.pyg
@@ -0,0 +1,10 @@
+def_module_params('algebraic',
+ description='real algebraic number package',
+ export=True,
+ params=(('zero_accuracy', UINT, 0, 'one of the most time-consuming operations in the real algebraic number module is determining the sign of a polynomial evaluated at a sample point with non-rational algebraic number values. Let k be the value of this option. If k is 0, Z3 uses precise computation. Otherwise, the result of a polynomial evaluation is considered to be 0 if Z3 can show it is inside the interval (-1/2^k, 1/2^k)'),
+ ('min_mag', UINT, 16, 'Z3 represents algebraic numbers using a (square-free) polynomial p and an isolating interval (which contains one and only one root of p). This interval may be refined during the computations. This parameter specifies whether to cache the value of a refined interval or not. It says the minimal size of an interval for caching purposes is 1/2^16'),
+ ('factor', BOOL, True, 'use polynomial factorization to simplify polynomials representing algebraic numbers'),
+ ('factor_max_prime', UINT, 31, 'parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step'),
+ ('factor_num_primes', UINT, 1, 'parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)\'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching'),
+ ('factor_search_size', UINT, 5000, 'parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space')))
+
diff --git a/src/math/polynomial/algebraic_numbers.cpp b/src/math/polynomial/algebraic_numbers.cpp
index f7de4054c..90ad6ea9d 100644
--- a/src/math/polynomial/algebraic_numbers.cpp
+++ b/src/math/polynomial/algebraic_numbers.cpp
@@ -25,6 +25,7 @@ Notes:
#include"scoped_ptr_vector.h"
#include"mpbqi.h"
#include"timeit.h"
+#include"algebraic_params.hpp"
namespace algebraic_numbers {
@@ -57,12 +58,7 @@ namespace algebraic_numbers {
typedef upolynomial::factors factors;
void manager::get_param_descrs(param_descrs & r) {
- r.insert(":algebraic-zero-accuracy", CPK_UINT, "(default: 0) one of the most time-consuming operations in the real algebraic number module is determining the sign of a polynomial evaluated at a sample point with non-rational algebraic number values. Let k be the value of this option. If k is 0, Z3 uses precise computation. Otherwise, the result of a polynomial evaluation is considered to be 0 if Z3 can show it is inside the interval (-1/2^k, 1/2^k).");
- r.insert(":algebraic-min-mag", CPK_UINT, "(default: 16) Z3 represents algebraic numbers using a (square-free) polynomial p and an isolating interval (which contains one and only one root of p). This interval may be refined during the computations. This parameter specifies whether to cache the value of a refined interval or not. It says the minimal size of an interval for caching purposes is 1/2^16");
- r.insert(":algebraic-factor", CPK_BOOL, "(default: true) use polynomial factorization to simplify polynomials representing algebraic numbers.");
- r.insert(":algebraic-factor-max-prime", CPK_UINT, "(default: 31), parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step.");
- r.insert(":algebraic-factor-num-primes", CPK_UINT, "(default: 1), parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching.");
- r.insert(":algebraic-factor-search-size", CPK_UINT, "(default: 5000), parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space.");
+ algebraic_params::collect_param_descrs(r);
}
struct manager::imp {
@@ -156,13 +152,14 @@ namespace algebraic_numbers {
#endif
}
- void updt_params(params_ref const & p) {
- m_min_magnitude = -static_cast(p.get_uint(":algebraic-min-mag", 16));
- m_factor = p.get_bool(":algebraic-factor", true); // use polynomial factorization
- m_factor_params.m_max_p = p.get_uint(":algebraic-factor-max-prime", 31);
- m_factor_params.m_p_trials = p.get_uint(":algebraic-factor-num-primes", 1);
- m_factor_params.m_max_search_size = p.get_uint(":algebraic-factor-max-search-size", 5000);
- m_zero_accuracy = -static_cast(p.get_uint(":algebraic-zero-accuracy", 0));
+ void updt_params(params_ref const & _p) {
+ algebraic_params p(_p);
+ m_min_magnitude = -static_cast(p.min_mag());
+ m_factor = p.factor();
+ m_factor_params.m_max_p = p.factor_max_prime();
+ m_factor_params.m_p_trials = p.factor_num_primes();
+ m_factor_params.m_max_search_size = p.factor_search_size();
+ m_zero_accuracy = -static_cast(p.zero_accuracy());
}
unsynch_mpq_manager & qm() {
diff --git a/src/math/polynomial/polynomial.cpp b/src/math/polynomial/polynomial.cpp
index 1b5c7965f..4e14c5661 100644
--- a/src/math/polynomial/polynomial.cpp
+++ b/src/math/polynomial/polynomial.cpp
@@ -50,15 +50,15 @@ namespace polynomial {
}
void factor_params::updt_params(params_ref const & p) {
- m_max_p = p.get_uint(":factor-max-prime", UINT_MAX);
- m_p_trials = p.get_uint(":factor-num-primes", 1);
- m_max_search_size = p.get_uint(":factor-max-search-size", UINT_MAX);
+ m_max_p = p.get_uint("max_prime", UINT_MAX);
+ m_p_trials = p.get_uint("num_primes", 1);
+ m_max_search_size = p.get_uint("max_search_size", UINT_MAX);
}
void factor_params::get_param_descrs(param_descrs & r) {
- r.insert(":factor-max-search-size", CPK_UINT, "(default: infty) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space.");
- r.insert(":factor-max-prime", CPK_UINT, "(default: infty) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step.");
- r.insert(":factor-num-primes", CPK_UINT, "(default: 1) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching.");
+ r.insert("max_search_size", CPK_UINT, "(default: infty) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space.");
+ r.insert("max_prime", CPK_UINT, "(default: infty) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step.");
+ r.insert("num_primes", CPK_UINT, "(default: 1) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching.");
}
typedef ptr_vector monomial_vector;
diff --git a/src/math/polynomial/polynomial.h b/src/math/polynomial/polynomial.h
index f6370e5fa..7cefe6f56 100644
--- a/src/math/polynomial/polynomial.h
+++ b/src/math/polynomial/polynomial.h
@@ -90,6 +90,9 @@ namespace polynomial {
factor_params();
factor_params(unsigned max_p, unsigned p_trials, unsigned max_search_size);
void updt_params(params_ref const & p);
+ /*
+ REG_MODULE_PARAMS('factor', polynomial::factor_params::get_param_descrs')
+ */
static void get_param_descrs(param_descrs & r);
};
diff --git a/src/math/subpaving/subpaving_t_def.h b/src/math/subpaving/subpaving_t_def.h
index 7c80de75c..c215ddf98 100644
--- a/src/math/subpaving/subpaving_t_def.h
+++ b/src/math/subpaving/subpaving_t_def.h
@@ -474,7 +474,7 @@ void context_t::del(interval & a) {
template
void context_t::updt_params(params_ref const & p) {
- unsigned epsilon = p.get_uint(":epsilon", 20);
+ unsigned epsilon = p.get_uint("epsilon", 20);
if (epsilon != 0) {
nm().set(m_epsilon, static_cast(epsilon));
nm().inv(m_epsilon);
@@ -485,18 +485,18 @@ void context_t::updt_params(params_ref const & p) {
m_zero_epsilon = true;
}
- unsigned max_power = p.get_uint(":max-bound", 10);
+ unsigned max_power = p.get_uint("max_bound", 10);
nm().set(m_max_bound, 10);
nm().power(m_max_bound, max_power, m_max_bound);
nm().set(m_minus_max_bound, m_max_bound);
nm().neg(m_minus_max_bound);
- m_max_depth = p.get_uint(":max-depth", 128);
- m_max_nodes = p.get_uint(":max-nodes", 8192);
+ m_max_depth = p.get_uint("max_depth", 128);
+ m_max_nodes = p.get_uint("max_nodes", 8192);
- m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
+ m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
- unsigned prec = p.get_uint(":nth-root-precision", 8192);
+ unsigned prec = p.get_uint("nth_root_precision", 8192);
if (prec == 0)
prec = 1;
nm().set(m_nth_root_prec, static_cast(prec));
@@ -505,20 +505,20 @@ void context_t::updt_params(params_ref const & p) {
template
void context_t::collect_param_descrs(param_descrs & d) {
- d.insert(":max-nodes", CPK_UINT, "(default: 8192) maximum number of nodes in the subpaving tree.");
- d.insert(":max-depth", CPK_UINT, "(default: 128) maximum depth of the subpaving tree.");
- d.insert(":epsilon", CPK_UINT, "(default: 20) value k s.t. a new lower (upper) bound for x is propagated only new-lower(x) > lower(k) + 1/k * max(min(upper(x) - lower(x), |lower|), 1) (new-upper(x) < upper(x) - 1/k * max(min(upper(x) - lower(x), |lower|), 1)). If k = 0, then this restriction is ignored.");
- d.insert(":max-bound", CPK_UINT, "(default 10) value k s.t. a new upper (lower) bound for x is propagated only if upper(x) > -10^k or lower(x) = -oo (lower(x) < 10^k or upper(x) = oo)");
- d.insert(":nth-root-precision", CPK_UINT, "(default 8192) value k s.t. 1/k is the precision for computing the nth root in the subpaving module.");
+ d.insert("max_nodes", CPK_UINT, "(default: 8192) maximum number of nodes in the subpaving tree.");
+ d.insert("max_depth", CPK_UINT, "(default: 128) maximum depth of the subpaving tree.");
+ d.insert("epsilon", CPK_UINT, "(default: 20) value k s.t. a new lower (upper) bound for x is propagated only new-lower(x) > lower(k) + 1/k * max(min(upper(x) - lower(x), |lower|), 1) (new-upper(x) < upper(x) - 1/k * max(min(upper(x) - lower(x), |lower|), 1)). If k = 0, then this restriction is ignored.");
+ d.insert("max_bound", CPK_UINT, "(default 10) value k s.t. a new upper (lower) bound for x is propagated only if upper(x) > -10^k or lower(x) = -oo (lower(x) < 10^k or upper(x) = oo)");
+ d.insert("nth_root_precision", CPK_UINT, "(default 8192) value k s.t. 1/k is the precision for computing the nth root in the subpaving module.");
}
template
void context_t::display_params(std::ostream & out) const {
- out << ":max-nodes " << m_max_nodes << "\n";
- out << ":max-depth " << m_max_depth << "\n";
- out << ":epsilon " << nm().to_rational_string(m_epsilon) << "\n";
- out << ":max-bound " << nm().to_rational_string(m_max_bound) << "\n";
- out << ":max-memory " << m_max_memory << "\n";
+ out << "max_nodes " << m_max_nodes << "\n";
+ out << "max_depth " << m_max_depth << "\n";
+ out << "epsilon " << nm().to_rational_string(m_epsilon) << "\n";
+ out << "max_bound " << nm().to_rational_string(m_max_bound) << "\n";
+ out << "max_memory " << m_max_memory << "\n";
}
template
diff --git a/src/math/subpaving/tactic/subpaving_tactic.cpp b/src/math/subpaving/tactic/subpaving_tactic.cpp
index 7bbff4b0b..d03bacebb 100644
--- a/src/math/subpaving/tactic/subpaving_tactic.cpp
+++ b/src/math/subpaving/tactic/subpaving_tactic.cpp
@@ -81,14 +81,14 @@ class subpaving_tactic : public tactic {
void collect_param_descrs(param_descrs & r) {
m_ctx->collect_param_descrs(r);
// #ifndef _EXTERNAL_RELEASE
- r.insert(":numeral", CPK_SYMBOL, "(default: mpq) options: mpq, mpf, hwf, mpff, mpfx.");
- r.insert(":print-nodes", CPK_BOOL, "(default: false) display subpaving tree leaves.");
+ r.insert("numeral", CPK_SYMBOL, "(default: mpq) options: mpq, mpf, hwf, mpff, mpfx.");
+ r.insert("print_nodes", CPK_BOOL, "(default: false) display subpaving tree leaves.");
// #endif
}
void updt_params(params_ref const & p) {
- m_display = p.get_bool(":print-nodes", false);
- symbol engine = p.get_sym(":numeral", symbol("mpq"));
+ m_display = p.get_bool("print_nodes", false);
+ symbol engine = p.get_sym("numeral", symbol("mpq"));
engine_kind new_kind;
if (engine == "mpq")
new_kind = MPQ;
@@ -293,16 +293,16 @@ tactic * mk_subpaving_tactic_core(ast_manager & m, params_ref const & p) {
tactic * mk_subpaving_tactic(ast_manager & m, params_ref const & p) {
params_ref simp_p = p;
- simp_p.set_bool(":arith-lhs", true);
- simp_p.set_bool(":expand-power", true);
- simp_p.set_uint(":max-power", UINT_MAX);
- simp_p.set_bool(":som", true);
- simp_p.set_bool(":eq2ineq", true);
- simp_p.set_bool(":elim-and", true);
- simp_p.set_bool(":blast-distinct", true);
+ simp_p.set_bool("arith_lhs", true);
+ simp_p.set_bool("expand_power", true);
+ simp_p.set_uint("max_power", UINT_MAX);
+ simp_p.set_bool("som", true);
+ simp_p.set_bool("eq2ineq", true);
+ simp_p.set_bool("elim_and", true);
+ simp_p.set_bool("blast_distinct", true);
params_ref simp2_p = p;
- simp2_p.set_bool(":mul-to-power", true);
+ simp2_p.set_bool("mul_to_power", true);
return and_then(using_params(mk_simplify_tactic(m, p),
simp_p),
diff --git a/src/model/model_evaluator.cpp b/src/model/model_evaluator.cpp
index bccade304..beed0061e 100644
--- a/src/model/model_evaluator.cpp
+++ b/src/model/model_evaluator.cpp
@@ -60,10 +60,10 @@ struct evaluator_cfg : public default_rewriter_cfg {
}
void updt_params(params_ref const & p) {
- m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
- m_max_steps = p.get_uint(":max-steps", UINT_MAX);
- m_model_completion = p.get_bool(":model-completion", false);
- m_cache = p.get_bool(":cache", true);
+ m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
+ m_max_steps = p.get_uint("max_steps", UINT_MAX);
+ m_model_completion = p.get_bool("model_completion", false);
+ m_cache = p.get_bool("cache", true);
}
ast_manager & m() const { return m_model.get_manager(); }
@@ -147,7 +147,7 @@ struct evaluator_cfg : public default_rewriter_cfg {
return m_a_rw.mk_app_core(f, num, args, result);
if (fid == m_bv_rw.get_fid())
return m_bv_rw.mk_app_core(f, num, args, result);
- if (fid == m_ar_rw.get_fid())
+ if (fid == m_ar_rw.get_fid())
return m_ar_rw.mk_app_core(f, num, args, result);
if (fid == m_dt_rw.get_fid())
return m_dt_rw.mk_app_core(f, num, args, result);
@@ -232,8 +232,8 @@ void model_evaluator::updt_params(params_ref const & p) {
void model_evaluator::get_param_descrs(param_descrs & r) {
insert_max_memory(r);
insert_max_steps(r);
- r.insert(":model-completion", CPK_BOOL, "(default: false) assigns an interpretation to symbols that are not intepreted by the model.");
- r.insert(":cache", CPK_BOOL, "(default: true) cache intermediate results.");
+ r.insert("model_completion", CPK_BOOL, "(default: false) assigns an interpretation to symbols that are not intepreted by the model.");
+ r.insert("cache", CPK_BOOL, "(default: true) cache intermediate results.");
}
void model_evaluator::set_model_completion(bool f) {
diff --git a/src/model/model_params.pyg b/src/model/model_params.pyg
new file mode 100644
index 000000000..977538163
--- /dev/null
+++ b/src/model/model_params.pyg
@@ -0,0 +1,8 @@
+def_module_params('model',
+ export=True,
+ params=(('partial', BOOL, False, 'enable/disable partial function interpretations'),
+ ('v1', BOOL, False, 'use Z3 version 1.x pretty printer'),
+ ('v2', BOOL, False, 'use Z3 version 2.x (x <= 16) pretty printer'),
+ ('compact', BOOL, False, 'try to compact function graph (i.e., function interpretations that are lookup tables)'),
+ ('completion', BOOL, False, 'assigns an interptetation to symbols that do not have one in the current model, when evaluating expressions in the current model')))
+
diff --git a/src/model/model_pp.cpp b/src/model/model_pp.cpp
index a8e8a0880..b968c7184 100644
--- a/src/model/model_pp.cpp
+++ b/src/model/model_pp.cpp
@@ -85,8 +85,7 @@ static void display_functions(std::ostream & out, model_core const & md) {
if (fi->is_partial())
out << " #unspecified";
else {
- pp_params const & params = get_pp_default_params();
- out << " " << mk_ismt2_pp(fi->get_else(), m, params, 5, arity, "x");
+ out << " " << mk_ismt2_pp(fi->get_else(), m, params_ref(), 5, arity, "x");
}
for (unsigned j = 0; j < num_entries; j++)
out << ")";
diff --git a/src/model/model_smt2_pp.cpp b/src/model/model_smt2_pp.cpp
index 1a639b5f1..929668638 100644
--- a/src/model/model_smt2_pp.cpp
+++ b/src/model/model_smt2_pp.cpp
@@ -128,7 +128,7 @@ static void pp_uninterp_sorts(std::ostream & out, ast_printer_context & ctx, mod
format_ref f_card(fm(m));
f_card = mk_indent(m, indent, mk_seq1(m, f_args, f_args+2, f2f(), "forall"));
pp_indent(out, indent);
- pp(out, f_card, m, get_pp_default_params());
+ pp(out, f_card, m);
out << "\n";
pp_indent(out, indent);
out << ";; -----------\n";
@@ -284,7 +284,7 @@ static void pp_funs(std::ostream & out, ast_printer_context & ctx, model_core co
body.get(),
mk_string(m, ")")))));
pp_indent(out, indent);
- pp(out, def.get(), m, get_pp_default_params());
+ pp(out, def.get(), m);
out << "\n";
}
}
diff --git a/src/muz_qe/datalog_parser.cpp b/src/muz_qe/datalog_parser.cpp
index f527bb25a..cfe283410 100644
--- a/src/muz_qe/datalog_parser.cpp
+++ b/src/muz_qe/datalog_parser.cpp
@@ -1160,9 +1160,9 @@ class wpa_parser_impl : public wpa_parser, dparser {
public:
wpa_parser_impl(context & ctx)
: dparser(ctx, ctx.get_manager()),
- m_bool_sort(ctx.get_manager()),
- m_short_sort(ctx.get_manager()),
- m_use_map_names(ctx.get_params().get_bool(":use-map-names", true)) {
+ m_bool_sort(ctx.get_manager()),
+ m_short_sort(ctx.get_manager()),
+ m_use_map_names(ctx.get_params().use_map_names()) {
}
~wpa_parser_impl() {
reset_dealloc_values(m_sort_contents);
@@ -1326,9 +1326,6 @@ private:
throw default_exception("tuple file %s for undeclared predicate %s",
m_current_file.c_str(), predicate_name.bare_str());
}
- if(!m_context.can_add_table_fact(pred)) {
- NOT_IMPLEMENTED_YET();
- }
unsigned pred_arity = pred->get_arity();
sort * const * arg_sorts = pred->get_domain();
diff --git a/src/muz_qe/dl_bmc_engine.cpp b/src/muz_qe/dl_bmc_engine.cpp
index 02791bc6f..27161320e 100644
--- a/src/muz_qe/dl_bmc_engine.cpp
+++ b/src/muz_qe/dl_bmc_engine.cpp
@@ -57,7 +57,6 @@ namespace datalog {
m_ctx.ensure_opened();
m_rules.reset();
- m_ctx.get_rmanager().reset_relations();
datalog::rule_manager& rule_manager = m_ctx.get_rule_manager();
datalog::rule_set old_rules(m_ctx.get_rules());
datalog::rule_ref_vector query_rules(rule_manager);
@@ -71,7 +70,7 @@ namespace datalog {
m_ctx.set_output_predicate(m_query_pred);
m_ctx.apply_default_transformation(mc, m_pc);
- if (m_ctx.get_params().get_bool(":slice", true)) {
+ if (m_ctx.get_params().slice()) {
datalog::rule_transformer transformer(m_ctx);
datalog::mk_slice* slice = alloc(datalog::mk_slice, m_ctx);
transformer.register_plugin(slice);
@@ -1100,9 +1099,6 @@ namespace datalog {
m_solver.reset_statistics();
}
- void bmc::collect_params(param_descrs& p) {
- }
-
expr_ref bmc::get_answer() {
return m_answer;
}
diff --git a/src/muz_qe/dl_bmc_engine.h b/src/muz_qe/dl_bmc_engine.h
index 5de54f843..5b6e433cd 100644
--- a/src/muz_qe/dl_bmc_engine.h
+++ b/src/muz_qe/dl_bmc_engine.h
@@ -24,6 +24,7 @@ Revision History:
#include "statistics.h"
#include "smt_kernel.h"
#include "bv_decl_plugin.h"
+#include "smt_params.h"
namespace datalog {
@@ -32,7 +33,7 @@ namespace datalog {
class bmc {
context& m_ctx;
ast_manager& m;
- front_end_params m_fparams;
+ smt_params m_fparams;
smt::kernel m_solver;
obj_map m_pred2sort;
obj_map m_sort2pred;
@@ -130,8 +131,6 @@ namespace datalog {
void reset_statistics();
expr_ref get_answer();
-
- static void collect_params(param_descrs& p);
};
};
diff --git a/src/muz_qe/dl_cmds.cpp b/src/muz_qe/dl_cmds.cpp
index e19b9fef8..bf9c24203 100644
--- a/src/muz_qe/dl_cmds.cpp
+++ b/src/muz_qe/dl_cmds.cpp
@@ -32,7 +32,10 @@ Notes:
#include
-class dl_context {
+struct dl_context {
+ smt_params m_fparams;
+ params_ref m_params_ref;
+ fixedpoint_params m_params;
cmd_context & m_cmd;
dl_collected_cmds* m_collected_cmds;
unsigned m_ref_count;
@@ -40,8 +43,13 @@ class dl_context {
scoped_ptr m_context;
trail_stack m_trail;
-public:
+ fixedpoint_params const& get_params() {
+ init();
+ return m_context->get_params();
+ }
+
dl_context(cmd_context & ctx, dl_collected_cmds* collected_cmds):
+ m_params(m_params_ref),
m_cmd(ctx),
m_collected_cmds(collected_cmds),
m_ref_count(0),
@@ -62,7 +70,7 @@ public:
void init() {
ast_manager& m = m_cmd.m();
if (!m_context) {
- m_context = alloc(datalog::context, m, m_cmd.params());
+ m_context = alloc(datalog::context, m, m_fparams, m_params_ref);
}
if (!m_decl_plugin) {
symbol name("datalog_relation");
@@ -210,7 +218,7 @@ public:
datalog::context& dlctx = m_dl_ctx->dlctx();
set_background(ctx);
dlctx.updt_params(m_params);
- unsigned timeout = m_params.get_uint(":timeout", UINT_MAX);
+ unsigned timeout = m_dl_ctx->get_params().timeout();
cancel_eh eh(dlctx);
lbool status = l_undef;
{
@@ -265,10 +273,6 @@ public:
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
m_dl_ctx->dlctx().collect_params(p);
- insert_timeout(p);
- p.insert(":print-answer", CPK_BOOL, "(default: false) print answer instance(s) to query.");
- p.insert(":print-certificate", CPK_BOOL, "(default: false) print certificate for reachability or non-reachability.");
- p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics.");
}
@@ -283,7 +287,7 @@ private:
}
void print_answer(cmd_context& ctx) {
- if (m_params.get_bool(":print-answer", false)) {
+ if (m_dl_ctx->get_params().print_answer()) {
datalog::context& dlctx = m_dl_ctx->dlctx();
ast_manager& m = ctx.m();
expr_ref query_result(dlctx.get_answer_as_formula(), m);
@@ -298,7 +302,7 @@ private:
}
void print_statistics(cmd_context& ctx) {
- if (m_params.get_bool(":print-statistics", false)) {
+ if (m_dl_ctx->get_params().print_statistics()) {
statistics st;
datalog::context& dlctx = m_dl_ctx->dlctx();
unsigned long long max_mem = memory::get_max_used_memory();
@@ -312,7 +316,7 @@ private:
}
void print_certificate(cmd_context& ctx) {
- if (m_params.get_bool(":print-certificate", false)) {
+ if (m_dl_ctx->get_params().print_certificate()) {
datalog::context& dlctx = m_dl_ctx->dlctx();
if (!dlctx.display_certificate(ctx.regular_stream())) {
throw cmd_exception("certificates are not supported for the selected engine");
@@ -472,8 +476,10 @@ static void install_dl_cmds_aux(cmd_context& ctx, dl_collected_cmds* collected_c
ctx.insert(alloc(dl_query_cmd, dl_ctx));
ctx.insert(alloc(dl_declare_rel_cmd, dl_ctx));
ctx.insert(alloc(dl_declare_var_cmd, dl_ctx));
- PRIVATE_PARAMS(ctx.insert(alloc(dl_push_cmd, dl_ctx));); // not exposed to keep command-extensions simple.
- PRIVATE_PARAMS(ctx.insert(alloc(dl_pop_cmd, dl_ctx)););
+#ifndef _EXTERNAL_RELEASE
+ ctx.insert(alloc(dl_push_cmd, dl_ctx)); // not exposed to keep command-extensions simple.
+ ctx.insert(alloc(dl_pop_cmd, dl_ctx));
+#endif
}
void install_dl_cmds(cmd_context & ctx) {
diff --git a/src/muz_qe/dl_compiler.cpp b/src/muz_qe/dl_compiler.cpp
index 99c7b86f5..d403b5b5c 100644
--- a/src/muz_qe/dl_compiler.cpp
+++ b/src/muz_qe/dl_compiler.cpp
@@ -42,7 +42,7 @@ namespace datalog {
return;
}
relation_signature sig;
- m_context.get_rmanager().from_predicate(pred, sig);
+ m_context.get_rel_context().get_rmanager().from_predicate(pred, sig);
reg_idx reg = get_fresh_register(sig);
e->get_data().m_value=reg;
@@ -563,7 +563,7 @@ namespace datalog {
}
SASSERT(is_app(e));
relation_sort arg_sort;
- m_context.get_rmanager().from_predicate(neg_pred, i, arg_sort);
+ m_context.get_rel_context().get_rmanager().from_predicate(neg_pred, i, arg_sort);
reg_idx new_reg;
make_add_constant_column(head_pred, filtered_res, arg_sort, to_app(e), new_reg, acc);
@@ -1096,7 +1096,7 @@ namespace datalog {
func_decl_set::iterator fdit = preds.begin();
func_decl_set::iterator fdend = preds.end();
for(; fdit!=fdend; ++fdit) {
- if(!m_context.get_rmanager().is_saturated(*fdit)) {
+ if(!m_context.get_rel_context().get_rmanager().is_saturated(*fdit)) {
return false;
}
}
@@ -1181,7 +1181,7 @@ namespace datalog {
acc.set_observer(0);
- TRACE("dl", execution_code.display(m_context, tout););
+ TRACE("dl", execution_code.display(m_context.get_rel_context(), tout););
}
diff --git a/src/muz_qe/dl_context.cpp b/src/muz_qe/dl_context.cpp
index 91e396671..7a46228ce 100644
--- a/src/muz_qe/dl_context.cpp
+++ b/src/muz_qe/dl_context.cpp
@@ -24,18 +24,12 @@ Revision History:
#include"arith_decl_plugin.h"
#include"bv_decl_plugin.h"
#include"dl_table.h"
-#include"dl_sparse_table.h"
#include"dl_table_relation.h"
-#include"dl_bound_relation.h"
-#include"dl_interval_relation.h"
-#include"dl_finite_product_relation.h"
-#include"dl_product_relation.h"
#include"dl_rule_transformer.h"
#include"dl_mk_coi_filter.h"
#include"dl_mk_explanations.h"
#include"dl_mk_filter_rules.h"
#include"dl_mk_interp_tail_simplifier.h"
-#include"dl_mk_magic_sets.h"
#include"dl_mk_rule_inliner.h"
#include"dl_mk_simple_joins.h"
#include"dl_mk_similarity_compressor.h"
@@ -44,16 +38,13 @@ Revision History:
#include"dl_compiler.h"
#include"dl_instruction.h"
#include"dl_context.h"
-#include"dl_smt_relation.h"
-#ifndef _EXTERNAL_RELEASE
-#include"dl_skip_table.h"
-#endif
#include"for_each_expr.h"
#include"ast_smt_pp.h"
#include"ast_smt2_pp.h"
#include"expr_functors.h"
#include"dl_mk_partial_equiv.h"
#include"dl_mk_bit_blast.h"
+#include"dl_mk_array_blast.h"
#include"datatype_decl_plugin.h"
#include"expr_abstract.h"
@@ -189,7 +180,6 @@ namespace datalog {
virtual ~restore_rules() {}
virtual void undo(context& ctx) {
- ctx.reset_tables();
ctx.replace_rules(*m_old_rules);
reset();
}
@@ -209,7 +199,6 @@ namespace datalog {
m_trail.push_scope();
m_trail.push(restore_rules(m_rule_set));
m_trail.push(restore_vec_size_trail(m_background));
- m_trail.push(restore_vec_size_trail(m_table_facts));
}
void context::pop() {
@@ -225,14 +214,14 @@ namespace datalog {
//
// -----------------------------------
- context::context(ast_manager & m, front_end_params& fp, params_ref const& pa):
+ context::context(ast_manager & m, smt_params& fp, params_ref const& pa):
m(m),
m_fparams(fp),
- m_params(pa),
+ m_params_ref(pa),
+ m_params(m_params_ref),
m_decl_util(m),
m_rewriter(m),
m_var_subst(m),
- m_rmanager(*this),
m_rule_manager(*this),
m_trail(*this),
m_pinned(m),
@@ -242,26 +231,11 @@ namespace datalog {
m_background(m),
m_closed(false),
m_saturation_was_run(false),
- m_last_result_relation(0),
m_last_answer(m),
m_engine(LAST_ENGINE),
m_cancel(false) {
//register plugins for builtin tables
- get_rmanager().register_plugin(alloc(sparse_table_plugin, get_rmanager()));
- get_rmanager().register_plugin(alloc(hashtable_table_plugin, get_rmanager()));
- get_rmanager().register_plugin(alloc(bitvector_table_plugin, get_rmanager()));
- get_rmanager().register_plugin(alloc(equivalence_table_plugin, get_rmanager()));
-
-#ifndef _EXTERNAL_RELEASE
- get_rmanager().register_plugin(alloc(skip_table_plugin, get_rmanager()));
-#endif
-
- //register plugins for builtin relations
- get_rmanager().register_plugin(alloc(smt_relation_plugin, get_rmanager()));
-
- get_rmanager().register_plugin(alloc(bound_relation_plugin, get_rmanager()));
- get_rmanager().register_plugin(alloc(interval_relation_plugin, get_rmanager()));
}
context::~context() {
@@ -272,14 +246,12 @@ namespace datalog {
m_trail.reset();
m_rule_set.reset();
m_argument_var_names.reset();
- m_output_preds.reset();
m_preds.reset();
m_preds_by_name.reset();
reset_dealloc_values(m_sorts);
- if (m_last_result_relation) {
- m_last_result_relation->deallocate();
- m_last_result_relation = 0;
- }
+ m_pdr = 0;
+ m_bmc = 0;
+ m_rel = 0;
}
bool context::is_fact(app * head) const {
@@ -337,7 +309,7 @@ namespace datalog {
expr_ref context::bind_variables(expr* fml, bool is_forall) {
expr_ref result(m);
- app_ref_vector const& vars = m_vars;
+ app_ref_vector const & vars = m_vars;
if (vars.empty()) {
result = fml;
}
@@ -352,9 +324,19 @@ namespace datalog {
svector names;
for (unsigned i = 0; i < sorts.size(); ++i) {
if (!sorts[i]) {
- sorts[i] = vars[i]->get_decl()->get_range();
+ if (i < vars.size()) {
+ sorts[i] = vars[i]->get_decl()->get_range();
+ }
+ else {
+ sorts[i] = m.mk_bool_sort();
+ }
+ }
+ if (i < vars.size()) {
+ names.push_back(vars[i]->get_decl()->get_name());
+ }
+ else {
+ names.push_back(symbol(i));
}
- names.push_back(vars[i]->get_decl()->get_name());
}
quantifier_ref q(m);
sorts.reverse();
@@ -445,59 +427,13 @@ namespace datalog {
return e->get_data().m_value[arg_index];
}
- relation_plugin & context::get_ordinary_relation_plugin(symbol relation_name) {
- relation_plugin * plugin = get_rmanager().get_relation_plugin(relation_name);
- if (!plugin) {
- std::stringstream sstm;
- sstm << "relation plugin " << relation_name << " does not exist";
- throw default_exception(sstm.str());
- }
- if (plugin->is_product_relation()) {
- throw default_exception("cannot request product relation directly");
- }
- if (plugin->is_sieve_relation()) {
- throw default_exception("cannot request sieve relation directly");
- }
- if (plugin->is_finite_product_relation()) {
- throw default_exception("cannot request finite product relation directly");
- }
- return *plugin;
- }
void context::set_predicate_representation(func_decl * pred, unsigned relation_name_cnt,
symbol const * relation_names) {
- relation_manager & rmgr = get_rmanager();
-
- family_id target_kind = null_family_id;
- switch (relation_name_cnt) {
- case 0:
- return;
- case 1:
- target_kind = get_ordinary_relation_plugin(relation_names[0]).get_kind();
- break;
- default: {
- svector rel_kinds; // kinds of plugins that are not table plugins
- family_id rel_kind; // the aggregate kind of non-table plugins
- for (unsigned i = 0; i < relation_name_cnt; i++) {
- relation_plugin & p = get_ordinary_relation_plugin(relation_names[i]);
- rel_kinds.push_back(p.get_kind());
- }
- if (rel_kinds.size() == 1) {
- rel_kind = rel_kinds[0];
- }
- else {
- relation_signature rel_sig;
- //rmgr.from_predicate(pred, rel_sig);
- product_relation_plugin & prod_plugin = product_relation_plugin::get_plugin(rmgr);
- rel_kind = prod_plugin.get_relation_kind(rel_sig, rel_kinds);
- }
- target_kind = rel_kind;
- break;
- }
+ if (relation_name_cnt > 0) {
+ ensure_rel();
+ m_rel->set_predicate_representation(pred, relation_name_cnt, relation_names);
}
-
- SASSERT(target_kind != null_family_id);
- get_rmanager().set_predicate_kind(pred, target_kind);
}
func_decl * context::mk_fresh_head_predicate(symbol const & prefix, symbol const & suffix,
@@ -507,19 +443,25 @@ namespace datalog {
register_predicate(new_pred);
- if (orig_pred) {
- family_id target_kind = get_rmanager().get_requested_predicate_kind(orig_pred);
- if (target_kind != null_family_id) {
- get_rmanager().set_predicate_kind(new_pred, target_kind);
- }
+ if (m_rel.get()) {
+ m_rel->inherit_predicate_kind(new_pred, orig_pred);
}
return new_pred;
}
void context::set_output_predicate(func_decl * pred) {
- if (!m_output_preds.contains(pred)) {
- m_output_preds.insert(pred);
- }
+ ensure_rel();
+ m_rel->set_output_predicate(pred);
+ }
+
+ bool context::is_output_predicate(func_decl * pred) {
+ ensure_rel();
+ return m_rel->is_output_predicate(pred);
+ }
+
+ const decl_set & context::get_output_predicates() {
+ ensure_rel();
+ return m_rel->get_output_predicates();
}
void context::add_rule(expr* rl, symbol const& name) {
@@ -552,7 +494,6 @@ namespace datalog {
throw default_exception(strm.str());
}
rule_ref r(rules[0].get(), rm);
- get_rmanager().reset_saturated_marks();
rule_ref_vector const& rls = m_rule_set.get_rules();
rule* old_rule = 0;
for (unsigned i = 0; i < rls.size(); ++i) {
@@ -785,7 +726,6 @@ namespace datalog {
}
void context::add_rule(rule_ref& r) {
- get_rmanager().reset_saturated_marks();
m_rule_set.add_rule(r);
}
@@ -799,12 +739,10 @@ namespace datalog {
void context::add_fact(func_decl * pred, const relation_fact & fact) {
if (get_engine() == DATALOG_ENGINE) {
- get_rmanager().reset_saturated_marks();
- get_relation(pred).add_fact(fact);
- m_table_facts.push_back(std::make_pair(pred, fact));
+ ensure_rel();
+ m_rel->add_fact(pred, fact);
}
else {
- ast_manager& m = get_manager();
expr_ref rule(m.mk_app(pred, fact.size(), (expr*const*)fact.c_ptr()), m);
add_rule(rule, symbol::null);
}
@@ -822,26 +760,18 @@ namespace datalog {
add_fact(head->get_decl(), fact);
}
- bool context::can_add_table_fact(func_decl * pred) {
- return get_relation(pred).from_table();
- }
-
void context::add_table_fact(func_decl * pred, const table_fact & fact) {
- relation_base & rel0 = get_relation(pred);
- if (get_engine() != DATALOG_ENGINE ||
- !can_add_table_fact(pred) ||
- !rel0.from_table()) {
+ if (get_engine() == DATALOG_ENGINE) {
+ ensure_rel();
+ m_rel->add_fact(pred, fact);
+ }
+ else {
relation_fact rfact(m);
for (unsigned i = 0; i < fact.size(); ++i) {
rfact.push_back(m_decl_util.mk_numeral(fact[i], pred->get_domain()[i]));
}
add_fact(pred, rfact);
}
- else {
- get_rmanager().reset_saturated_marks();
- table_relation & rel = static_cast(rel0);
- rel.add_table_fact(fact);
- }
}
void context::add_table_fact(func_decl * pred, unsigned num_args, unsigned args[]) {
@@ -944,181 +874,28 @@ namespace datalog {
transf.register_plugin(alloc(datalog::mk_subsumption_checker, *this, 34880));
transf.register_plugin(alloc(datalog::mk_bit_blast, *this, 35000));
+ transf.register_plugin(alloc(datalog::mk_array_blast, *this, 36000));
transform_rules(transf, mc, pc);
}
void context::collect_params(param_descrs& p) {
- p.insert(":engine", CPK_SYMBOL, "(default: automatically configured) select 'datalog', PDR 'pdr' engine.");
- p.insert(":bit-blast", CPK_BOOL, "(default: false) bit-blast bit-vectors (for PDR engine).");
- p.insert(":default-table", CPK_SYMBOL, "default table implementation: 'sparse' (default), 'hashtable', 'bitvector', 'interval'");
- p.insert(":default-relation", CPK_SYMBOL, "default relation implementation: 'external_relation', 'pentagon'");
-
- p.insert(":generate-explanations", CPK_BOOL, "if true, signature of relations will be extended to contain explanations for facts");
- p.insert(":explanations-on-relation-level", CPK_BOOL, "if true, explanations are generated as history of each relation, "
- "rather than per fact (:generate-explanations must be set to true for this option to have any effect)");
-
- p.insert(":magic-sets-for-queries", CPK_BOOL, "magic set transformation will be used for queries");
- p.insert(":unbound-compressor", CPK_BOOL, "auxiliary relations will be introduced to avoid unbound variables in rule heads");
- p.insert(":similarity-compressor", CPK_BOOL, "rules that differ only in values of constants will be merged into a single rule");
- p.insert(":similarity-compressor-threshold", CPK_UINT, "if :dl-similiaryt-compressor is on, this value determines how many "
- "similar rules there must be in order for them to be merged");
-
- p.insert(":all-or-nothing-deltas", CPK_BOOL, "compile rules so that it is enough for the delta relation in union and widening "
- "operations to determine only whether the updated relation was modified or not");
- p.insert(":compile-with-widening", CPK_BOOL, "widening will be used to compile recursive rules");
- p.insert(":eager-emptiness-checking", CPK_BOOL, "emptiness of affected relations will be checked after each instruction, "
- "so that we may ommit unnecessary instructions");
- p.insert(":default-table-checked", CPK_BOOL,
- "if true, the detault table will be :default-table inside a wrapper that checks that "
- "its results are the same as of :default-table-checker table");
-
-
- p.insert(":initial-restart-timeout", CPK_UINT, "length of saturation run before the first restart (in ms); zero means no restarts");
- p.insert(":restart-timeout-quotient", CPK_UINT, "restart timeout will be multiplied by this number after each restart");
- p.insert(":use-map-names", CPK_BOOL, "use names from map files when displaying tuples");
-
- p.insert(":output-profile", CPK_BOOL, "determines whether profile informations should be output when outputting Datalog rules or instructions");
- p.insert(":output-tuples", CPK_BOOL, "determines whether tuples for output predicates should be output");
- p.insert(":profile-timeout-milliseconds", CPK_UINT, "instructions and rules that took less than the threshold will not be printed when printed the instruction/rule list");
-
- p.insert(":print-with-fixedpoint-extensions", CPK_BOOL, "(default true) use SMT-LIB2 fixedpoint extensions, instead of pure SMT2, when printing rules");
-
- PRIVATE_PARAMS(
- p.insert(":dbg-fpr-nonempty-relation-signature", CPK_BOOL,
- "if true, finite_product_relation will attempt to avoid creating inner relation with empty signature "
- "by putting in half of the table columns, if it would have been empty otherwise");
-
- p.insert(":smt-relation-ground-recursive", CPK_BOOL, "Ensure recursive relation is ground in union");
- );
-
- p.insert(":fix-unbound-vars", CPK_BOOL, "fix unbound variables in tail");
- p.insert(":default-table-checker", CPK_SYMBOL, "see :default-table-checked");
- p.insert(":inline-linear", CPK_BOOL, "(default true) try linear inlining method");
- p.insert(":inline-eager", CPK_BOOL, "(default true) try eager inlining of rules");
- PRIVATE_PARAMS(p.insert(":inline-linear-branch", CPK_BOOL, "try linear inlining method with potential expansion"););
-
- pdr::dl_interface::collect_params(p);
- bmc::collect_params(p);
+ fixedpoint_params::collect_param_descrs(p);
insert_timeout(p);
}
void context::updt_params(params_ref const& p) {
- m_params.copy(p);
- if (m_pdr.get()) m_pdr->updt_params();
-
+ m_params_ref.copy(p);
+ if (m_pdr.get()) m_pdr->updt_params();
}
- void context::collect_predicates(decl_set & res) {
- unsigned rule_cnt = m_rule_set.get_num_rules();
- for (unsigned rindex=0; rindexget_head()->get_decl());
- unsigned tail_len = r->get_uninterpreted_tail_size();
- for (unsigned tindex=0; tindexget_tail(tindex)->get_decl());
- }
- }
- decl_set::iterator oit = m_output_preds.begin();
- decl_set::iterator oend = m_output_preds.end();
- for (; oit!=oend; ++oit) {
- res.insert(*oit);
- }
- get_rmanager().collect_predicates(res);
+ void context::collect_predicates(decl_set& res) {
+ ensure_rel();
+ m_rel->collect_predicates(res);
}
-
- void context::restrict_predicates( const decl_set & res ) {
- set_intersection(m_output_preds, res);
- get_rmanager().restrict_predicates(res);
- }
-
- lbool context::dl_saturate() {
- if (!m_closed) {
- close();
- }
- bool time_limit = soft_timeout()!=0;
- unsigned remaining_time_limit = soft_timeout();
- unsigned restart_time = initial_restart_timeout();
-
- rule_set original_rules(get_rules());
- decl_set original_predicates;
- collect_predicates(original_predicates);
-
- instruction_block rules_code;
- instruction_block termination_code;
- execution_context ex_ctx(*this);
- lbool result;
-
- TRACE("dl", display(tout););
-
- while (true) {
- model_converter_ref mc; // Ignored in Datalog mode
- proof_converter_ref pc; // Ignored in Datalog mode
- transform_rules(mc, pc);
- compiler::compile(*this, get_rules(), rules_code, termination_code);
-
- TRACE("dl", rules_code.display(*this, tout); );
-
- bool timeout_after_this_round = time_limit && (restart_time==0 || remaining_time_limit<=restart_time);
-
- if (time_limit || restart_time!=0) {
- unsigned timeout = time_limit ? (restart_time!=0) ?
- std::min(remaining_time_limit, restart_time)
- : remaining_time_limit : restart_time;
- ex_ctx.set_timelimit(timeout);
- }
-
- bool early_termination = !rules_code.perform(ex_ctx);
- ex_ctx.reset_timelimit();
- VERIFY( termination_code.perform(ex_ctx) );
-
- rules_code.process_all_costs();
-
- IF_VERBOSE(10, ex_ctx.report_big_relations(1000, verbose_stream()););
-
- if (!early_termination) {
- m_last_status = OK;
- result = l_true;
- break;
- }
-
- if (memory::above_high_watermark()) {
- m_last_status = MEMOUT;
- result = l_undef;
- break;
- }
- if (timeout_after_this_round || m_cancel) {
- m_last_status = TIMEOUT;
- result = l_undef;
- break;
- }
- SASSERT(restart_time!=0);
- if (time_limit) {
- SASSERT(remaining_time_limit>restart_time);
- remaining_time_limit-=restart_time;
- }
- uint64 new_restart_time = static_cast(restart_time)*initial_restart_timeout();
- if (new_restart_time>UINT_MAX) {
- restart_time=UINT_MAX;
- }
- else {
- restart_time=static_cast(new_restart_time);
- }
-
- rules_code.reset();
- termination_code.reset();
- ex_ctx.reset();
- reopen();
- restrict_predicates(original_predicates);
- replace_rules(original_rules);
- close();
- }
- reopen();
- restrict_predicates(original_predicates);
- replace_rules(original_rules);
- close();
- TRACE("dl", ex_ctx.report_big_relations(100, tout););
- return result;
+ void context::restrict_predicates(decl_set const& res) {
+ ensure_rel();
+ m_rel->restrict_predicates(res);
}
expr_ref context::get_background_assertion() {
@@ -1141,19 +918,21 @@ namespace datalog {
m_cancel = true;
if (m_pdr.get()) m_pdr->cancel();
if (m_bmc.get()) m_bmc->cancel();
+ if (m_rel.get()) m_rel->cancel();
}
void context::cleanup() {
m_cancel = false;
if (m_pdr.get()) m_pdr->cleanup();
if (m_bmc.get()) m_bmc->cleanup();
+ if (m_rel.get()) m_rel->cleanup();
}
class context::engine_type_proc {
- ast_manager& m;
- arith_util a;
+ ast_manager& m;
+ arith_util a;
datatype_util dt;
- DL_ENGINE m_engine;
+ DL_ENGINE m_engine;
public:
engine_type_proc(ast_manager& m): m(m), a(m), dt(m), m_engine(DATALOG_ENGINE) {}
@@ -1176,7 +955,7 @@ namespace datalog {
};
void context::configure_engine() {
- symbol e = m_params.get_sym(":engine", symbol());
+ symbol e = m_params.engine();
if (e == symbol("datalog")) {
m_engine = DATALOG_ENGINE;
@@ -1220,7 +999,7 @@ namespace datalog {
switch(get_engine()) {
case DATALOG_ENGINE:
- return dl_query(query);
+ return rel_query(query);
case PDR_ENGINE:
case QPDR_ENGINE:
return pdr_query(query);
@@ -1229,18 +1008,14 @@ namespace datalog {
return bmc_query(query);
default:
UNREACHABLE();
- return dl_query(query);
+ return rel_query(query);
}
}
void context::new_query() {
flush_add_rules();
- if (m_last_result_relation) {
- m_last_result_relation->deallocate();
- m_last_result_relation = 0;
- }
m_last_status = OK;
- m_last_answer = get_manager().mk_true();
+ m_last_answer = 0;
}
model_ref context::get_model() {
@@ -1273,7 +1048,6 @@ namespace datalog {
lbool context::pdr_query(expr* query) {
ensure_pdr();
- m_last_answer = 0;
return m_pdr->query(query);
}
@@ -1285,218 +1059,25 @@ namespace datalog {
lbool context::bmc_query(expr* query) {
ensure_bmc();
- m_last_answer = 0;
return m_bmc->query(query);
}
-#define BEGIN_QUERY() \
- rule_set original_rules(get_rules()); \
- decl_set original_preds; \
- collect_predicates(original_preds); \
- bool was_closed = m_closed; \
- if (m_closed) { \
- reopen(); \
- } \
-
-#define END_QUERY() \
- reopen(); \
- replace_rules(original_rules); \
- restrict_predicates(original_preds); \
- \
- if (was_closed) { \
- close(); \
- } \
-
- lbool context::dl_query(unsigned num_rels, func_decl * const* rels) {
- BEGIN_QUERY();
- for (unsigned i = 0; i < num_rels; ++i) {
- set_output_predicate(rels[i]);
+ void context::ensure_rel() {
+ if (!m_rel.get()) {
+ m_rel = alloc(rel_context, *this);
}
- close();
- reset_negated_tables();
- lbool res = dl_saturate();
+ }
- switch(res) {
- case l_true: {
- expr_ref_vector ans(m);
- expr_ref e(m);
- bool some_non_empty = num_rels == 0;
- for (unsigned i = 0; i < num_rels; ++i) {
- relation_base& rel = get_relation(rels[i]);
- if (!rel.empty()) {
- some_non_empty = true;
- }
- rel.to_formula(e);
- ans.push_back(e);
- }
- SASSERT(!m_last_result_relation);
- if (some_non_empty) {
- m_last_answer = m.mk_and(ans.size(), ans.c_ptr());
- }
- else {
- m_last_answer = m.mk_false();
- res = l_false;
- }
- break;
- }
- case l_false:
- m_last_answer = m.mk_false();
- break;
- case l_undef:
- break;
- }
- END_QUERY();
- return res;
+ lbool context::rel_query(unsigned num_rels, func_decl * const* rels) {
+ ensure_rel();
+ return m_rel->query(num_rels, rels);
}
- lbool context::dl_query(expr* query) {
- BEGIN_QUERY();
- rule_manager& rm = get_rule_manager();
- rule_ref qrule(rm);
- rule_ref_vector qrules(rm);
- func_decl_ref query_pred(get_manager());
- try {
- rm.mk_query(query, query_pred, qrules, qrule);
- }
- catch(default_exception& exn) {
- close();
- m_last_status = INPUT_ERROR;
- throw exn;
- }
- try {
- add_rules(qrules);
- }
- catch (default_exception& exn) {
- close();
- m_last_status = INPUT_ERROR;
- throw exn;
- }
-
- set_output_predicate(qrule->get_head()->get_decl());
- close();
- reset_negated_tables();
-
- if (generate_explanations()) {
- model_converter_ref mc; // ignored in Datalog mode
- proof_converter_ref pc; // ignored in Datalog mode
- rule_transformer transformer(*this);
- //expl_plugin is deallocated when transformer goes out of scope
- mk_explanations * expl_plugin =
- alloc(mk_explanations, *this, explanations_on_relation_level());
- transformer.register_plugin(expl_plugin);
- transform_rules(transformer, mc, pc);
-
- //we will retrieve the predicate with explanations instead of the original query predicate
- query_pred = expl_plugin->get_e_decl(query_pred);
- const rule_vector & query_rules = get_rules().get_predicate_rules(query_pred);
- SASSERT(query_rules.size()==1);
- qrule = query_rules.back();
- }
-
- if (magic_sets_for_queries()) {
- model_converter_ref mc; // Ignored in Datalog mode
- proof_converter_ref pc; // Ignored in Datalog mode
- rule_transformer transformer(*this);
- transformer.register_plugin(alloc(mk_magic_sets, *this, qrule.get()));
- transform_rules(transformer, mc, pc);
- }
-
- lbool res = dl_saturate();
-
- if (res != l_undef) {
- m_last_result_relation = get_relation(query_pred).clone();
- if (m_last_result_relation->empty()) {
- res = l_false;
- m_last_answer = m.mk_false();
- }
- else {
- m_last_result_relation->to_formula(m_last_answer);
- }
- }
-
- END_QUERY();
- return res;
+ lbool context::rel_query(expr* query) {
+ ensure_rel();
+ return m_rel->query(query);
}
- void context::reset_tables() {
- get_rmanager().reset_saturated_marks();
- rule_set::decl2rules::iterator it = m_rule_set.begin_grouped_rules();
- rule_set::decl2rules::iterator end = m_rule_set.end_grouped_rules();
- for (; it != end; ++it) {
- func_decl* p = it->m_key;
- relation_base & rel = get_relation(p);
- rel.reset();
- }
- for (unsigned i = 0; i < m_table_facts.size(); ++i) {
- func_decl* pred = m_table_facts[i].first;
- relation_fact const& fact = m_table_facts[i].second;
- get_relation(pred).add_fact(fact);
- }
- }
-
- void context::reset_negated_tables() {
- rule_set::pred_set_vector const & pred_sets = m_rule_set.get_strats();
- bool non_empty = false;
- for (unsigned i = 1; i < pred_sets.size(); ++i) {
- func_decl_set::iterator it = pred_sets[i]->begin(), end = pred_sets[i]->end();
- for (; it != end; ++it) {
- func_decl* pred = *it;
- relation_base & rel = get_relation(pred);
- if (!rel.empty()) {
- non_empty = true;
- break;
- }
- }
- }
- if (!non_empty) {
- return;
- }
- // collect predicates that depend on negation.
- func_decl_set depends_on_negation;
- for (unsigned i = 1; i < pred_sets.size(); ++i) {
- bool change = true;
- while (change) {
- change = false;
- func_decl_set::iterator it = pred_sets[i]->begin(), end = pred_sets[i]->end();
- for (; it != end; ++it) {
- func_decl* pred = *it;
- if (depends_on_negation.contains(pred)) {
- continue;
- }
- rule_vector const& rules = m_rule_set.get_predicate_rules(pred);
- bool inserted = false;
- for (unsigned j = 0; !inserted && j < rules.size(); ++j) {
- rule* r = rules[j];
- unsigned psz = r->get_positive_tail_size();
- unsigned tsz = r->get_uninterpreted_tail_size();
- if (psz < tsz) {
- depends_on_negation.insert(pred);
- change = true;
- inserted = true;
- }
- for (unsigned k = 0; !inserted && k < tsz; ++k) {
- func_decl* tail_decl = r->get_tail(k)->get_decl();
- if (depends_on_negation.contains(tail_decl)) {
- depends_on_negation.insert(pred);
- change = true;
- inserted = true;
- }
- }
- }
- }
- }
- }
- func_decl_set::iterator it = depends_on_negation.begin(), end = depends_on_negation.end();
- for (; it != end; ++it) {
- func_decl* pred = *it;
- relation_base & rel = get_relation(pred);
-
- if (!rel.empty()) {
- TRACE("dl", tout << "Resetting: " << mk_ismt2_pp(pred, m) << "\n";);
- rel.reset();
- }
- }
- }
expr* context::get_answer_as_formula() {
if (m_last_answer) {
@@ -1513,6 +1094,10 @@ namespace datalog {
ensure_bmc();
m_last_answer = m_bmc->get_answer();
return m_last_answer.get();
+ case DATALOG_ENGINE:
+ ensure_rel();
+ m_last_answer = m_rel->get_last_answer();
+ return m_last_answer.get();
default:
UNREACHABLE();
}
@@ -1573,8 +1158,8 @@ namespace datalog {
execution_result context::get_status() { return m_last_status; }
bool context::result_contains_fact(relation_fact const& f) {
- SASSERT(m_last_result_relation);
- return m_last_result_relation->contains_fact(f);
+ ensure_rel();
+ return m_rel->result_contains_fact(f);
}
// TBD: algebraic data-types declarations will not be printed.
@@ -1612,6 +1197,23 @@ namespace datalog {
void context::get_rules_as_formulas(expr_ref_vector& rules, svector& names) {
expr_ref fml(m);
+ datalog::rule_manager& rm = get_rule_manager();
+ datalog::rule_ref_vector rule_refs(rm);
+
+ // ensure that rules are all using bound variables.
+ for (unsigned i = 0; i < m_rule_fmls.size(); ++i) {
+ ptr_vector sorts;
+ get_free_vars(m_rule_fmls[i].get(), sorts);
+ if (!sorts.empty()) {
+ rm.mk_rule(m_rule_fmls[i].get(), rule_refs, m_rule_names[i]);
+ m_rule_fmls[i] = m_rule_fmls.back();
+ m_rule_names[i] = m_rule_names.back();
+ m_rule_fmls.pop_back();
+ m_rule_names.pop_back();
+ --i;
+ }
+ }
+ add_rules(rule_refs);
rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end();
for (; it != end; ++it) {
(*it)->to_formula(fml);
@@ -1637,12 +1239,15 @@ namespace datalog {
expr_ref fml(m);
expr_ref_vector rules(m);
svector names;
- bool use_fixedpoint_extensions = m_params.get_bool(":print-with-fixedpoint-extensions", true);
+ bool use_fixedpoint_extensions = m_params.print_with_fixedpoint_extensions();
+ bool print_low_level = m_params.print_low_level_smt2();
+ bool do_declare_vars = m_params.print_with_variable_declarations();
+
+#define PP(_e_) if (print_low_level) out << mk_smt_pp(_e_, m); else ast_smt2_pp(out, _e_, env);
get_rules_as_formulas(rules, names);
smt2_pp_environment_dbg env(m);
- pp_params params;
mk_fresh_name fresh_names;
collect_free_funcs(num_axioms, axioms, visited, visitor, fresh_names);
collect_free_funcs(rules.size(), rules.c_ptr(), visited, visitor, fresh_names);
@@ -1672,19 +1277,19 @@ namespace datalog {
obj_hashtable& sorts = visitor.sorts();
obj_hashtable::iterator sit = sorts.begin(), send = sorts.end();
for (; sit != send; ++sit) {
- ast_smt2_pp(out, *sit, env, params);
+ PP(*sit);
}
for (; it != end; ++it) {
func_decl* f = *it;
- ast_smt2_pp(out, f, env, params);
+ PP(f);
out << "\n";
}
it = rels.begin(); end = rels.end();
for (; it != end; ++it) {
func_decl* f = *it;
out << "(declare-rel " << f->get_name() << " (";
- for (unsigned i = 0; i < f->get_arity(); ++i) {
- ast_smt2_pp(out, f->get_domain(i), env, params);
+ for (unsigned i = 0; i < f->get_arity(); ++i) {
+ ast_smt2_pp(out, f->get_domain(i), env);
if (i + 1 < f->get_arity()) {
out << " ";
}
@@ -1692,7 +1297,7 @@ namespace datalog {
out << "))\n";
}
- if (use_fixedpoint_extensions) {
+ if (use_fixedpoint_extensions && do_declare_vars) {
declare_vars(rules, fresh_names, out);
}
@@ -1702,7 +1307,7 @@ namespace datalog {
for (unsigned i = 0; i < num_axioms; ++i) {
out << "(assert ";
- ast_smt2_pp(out, axioms[i], env, params);
+ PP(axioms[i]);
out << ")\n";
}
for (unsigned i = 0; i < rules.size(); ++i) {
@@ -1712,27 +1317,29 @@ namespace datalog {
if (symbol::null != nm) {
out << "(! ";
}
- if (use_fixedpoint_extensions) {
- ast_smt2_pp(out, r, env, params);
- }
- else {
- out << mk_smt_pp(r, m);
- }
+ PP(r);
if (symbol::null != nm) {
+ out << " :named ";
while (fresh_names.contains(nm)) {
std::ostringstream s;
s << nm << "!";
nm = symbol(s.str().c_str());
}
fresh_names.add(nm);
- out << " :named " << nm << ")";
+ if (is_smt2_quoted_symbol(nm)) {
+ out << mk_smt2_quoted_symbol(nm);
+ }
+ else {
+ out << nm;
+ }
+ out << ")";
}
out << ")\n";
}
if (use_fixedpoint_extensions) {
for (unsigned i = 0; i < num_queries; ++i) {
out << "(query ";
- ast_smt2_pp(out, queries[i], env, params);
+ PP(queries[i]);
out << ")\n";
}
}
@@ -1742,7 +1349,7 @@ namespace datalog {
out << "(assert ";
expr_ref q(m);
q = m.mk_not(queries[i]);
- ast_smt2_pp(out, q, env, params);
+ PP(q);
out << ")\n";
out << "(check-sat)\n";
if (num_queries > 1) out << "(pop)\n";
@@ -1759,7 +1366,6 @@ namespace datalog {
//
smt2_pp_environment_dbg env(m);
var_subst vsubst(m, false);
- pp_params param;
expr_ref_vector fresh_vars(m), subst(m);
expr_ref res(m);
@@ -1802,7 +1408,7 @@ namespace datalog {
symbol name = fresh_names.next();
fresh_vars.push_back(m.mk_const(name, s));
out << "(declare-var " << name << " ";
- ast_smt2_pp(out, s, env, param);
+ ast_smt2_pp(out, s, env);
out << ")\n";
}
subst.push_back(fresh_vars[vars[max_var]].get());
diff --git a/src/muz_qe/dl_context.h b/src/muz_qe/dl_context.h
index 229bbc474..f84050e68 100644
--- a/src/muz_qe/dl_context.h
+++ b/src/muz_qe/dl_context.h
@@ -24,7 +24,6 @@ Revision History:
#undef max
#endif
#include"arith_decl_plugin.h"
-#include"front_end_params.h"
#include"map.h"
#include"th_rewriter.h"
#include"str_hashtable.h"
@@ -36,14 +35,15 @@ Revision History:
#include"dl_rule_set.h"
#include"pdr_dl_interface.h"
#include"dl_bmc_engine.h"
+#include"rel_context.h"
#include"lbool.h"
#include"statistics.h"
#include"params.h"
#include"trail.h"
-#include"dl_external_relation.h"
#include"model_converter.h"
#include"proof_converter.h"
#include"model2expr.h"
+#include"smt_params.h"
namespace datalog {
@@ -75,15 +75,14 @@ namespace datalog {
typedef map sym2decl;
typedef obj_map