3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 05:18:44 +00:00

Merge remote-tracking branch 'upstream/master' into develop

This commit is contained in:
Murphy Berzish 2017-12-11 13:05:04 -05:00
commit 83bd103cd4
64 changed files with 1094 additions and 5223 deletions

View file

@ -33,8 +33,8 @@ endif()
# Project version
################################################################################
set(Z3_VERSION_MAJOR 4)
set(Z3_VERSION_MINOR 5)
set(Z3_VERSION_PATCH 1)
set(Z3_VERSION_MINOR 6)
set(Z3_VERSION_PATCH 0)
set(Z3_VERSION_TWEAK 0)
set(Z3_VERSION "${Z3_VERSION_MAJOR}.${Z3_VERSION_MINOR}.${Z3_VERSION_PATCH}.${Z3_VERSION_TWEAK}")
set(Z3_FULL_VERSION_STR "${Z3_VERSION}") # Note this might be modified

View file

@ -1,7 +1,11 @@
RELEASE NOTES
Version 4.5.x
Version 4.6.0
=============
- New requirements:
- C++11 capable compiler to build Z3.
- C++ API now requires C++11 or newer.
- New features (including):
- A new string solver from University of Waterloo
- A new linear real arithmetic solver

View file

@ -13,6 +13,22 @@ find_package(Z3
# use this option.
NO_DEFAULT_PATH
)
################################################################################
# Z3 C++ API bindings require C++11
################################################################################
if ("${CMAKE_VERSION}" VERSION_LESS "3.1")
# Legacy CMake support
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
message(FATAL_ERROR "Setting C++ version to C++11 not supported for \"${CMAKE_CXX_COMPILER_ID}\"")
endif()
else ()
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif ()
message(STATUS "Z3_FOUND: ${Z3_FOUND}")
message(STATUS "Found Z3 ${Z3_VERSION_STRING}")
message(STATUS "Z3_DIR: ${Z3_DIR}")

View file

@ -1138,8 +1138,11 @@ static void parse_example() {
decls.push_back(c.function("a", 0, 0, B));
expr a = c.parse_string("(assert a)", sorts, decls);
std::cout << a << "\n";
// expr b = c.parse_string("(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))");
}
int main() {
try {

View file

@ -395,11 +395,10 @@ void assert_comm_axiom(Z3_context ctx, Z3_solver s, Z3_func_decl f)
t_name = Z3_mk_string_symbol(ctx, "T");
Z3_parse_smtlib_string(ctx,
"(benchmark comm :formula (forall (x T) (y T) (= (f x y) (f y x))))",
q = Z3_parse_smtlib2_string(ctx,
"(assert (forall ((x T) (y T)) (= (f x y) (f y x))))",
1, &t_name, &t,
1, &f_name, &f);
q = Z3_get_smtlib_formula(ctx, 0);
printf("assert axiom:\n%s\n", Z3_ast_to_string(ctx, q));
Z3_solver_assert(ctx, s, q);
}
@ -1632,35 +1631,6 @@ void error_code_example2() {
}
}
/**
\brief Demonstrates how to use the SMTLIB parser.
*/
void parser_example1()
{
Z3_context ctx = mk_context();
Z3_solver s = mk_solver(ctx);
unsigned i, num_formulas;
printf("\nparser_example1\n");
LOG_MSG("parser_example1");
Z3_parse_smtlib_string(ctx,
"(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))",
0, 0, 0,
0, 0, 0);
num_formulas = Z3_get_smtlib_num_formulas(ctx);
for (i = 0; i < num_formulas; i++) {
Z3_ast f = Z3_get_smtlib_formula(ctx, i);
printf("formula %d: %s\n", i, Z3_ast_to_string(ctx, f));
Z3_solver_assert(ctx, s, f);
}
check(ctx, s, Z3_L_TRUE);
del_solver(ctx, s);
Z3_del_context(ctx);
}
/**
\brief Demonstrates how to initialize the parser symbol table.
@ -1690,12 +1660,11 @@ void parser_example2()
names[0] = Z3_mk_string_symbol(ctx, "a");
names[1] = Z3_mk_string_symbol(ctx, "b");
Z3_parse_smtlib_string(ctx,
"(benchmark tst :formula (> a b))",
f = Z3_parse_smtlib2_string(ctx,
"(assert (> a b))",
0, 0, 0,
/* 'x' and 'y' declarations are inserted as 'a' and 'b' into the parser symbol table. */
2, names, decls);
f = Z3_get_smtlib_formula(ctx, 0);
printf("formula: %s\n", Z3_ast_to_string(ctx, f));
Z3_solver_assert(ctx, s, f);
check(ctx, s, Z3_L_TRUE);
@ -1737,11 +1706,10 @@ void parser_example3()
assert_comm_axiom(ctx, s, g);
Z3_parse_smtlib_string(ctx,
"(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (g x 0) (g 0 y)))))",
thm = Z3_parse_smtlib2_string(ctx,
"(assert (forall ((x Int) (y Int)) (=> (= x y) (= (g x 0) (g 0 y)))))",
0, 0, 0,
1, &g_name, &g);
thm = Z3_get_smtlib_formula(ctx, 0);
printf("formula: %s\n", Z3_ast_to_string(ctx, thm));
prove(ctx, s, thm, Z3_TRUE);
@ -1749,41 +1717,6 @@ void parser_example3()
Z3_del_context(ctx);
}
/**
\brief Display the declarations, assumptions and formulas in a SMT-LIB string.
*/
void parser_example4()
{
Z3_context ctx;
unsigned i, num_decls, num_assumptions, num_formulas;
printf("\nparser_example4\n");
LOG_MSG("parser_example4");
ctx = mk_context();
Z3_parse_smtlib_string(ctx,
"(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))",
0, 0, 0,
0, 0, 0);
num_decls = Z3_get_smtlib_num_decls(ctx);
for (i = 0; i < num_decls; i++) {
Z3_func_decl d = Z3_get_smtlib_decl(ctx, i);
printf("declaration %d: %s\n", i, Z3_func_decl_to_string(ctx, d));
}
num_assumptions = Z3_get_smtlib_num_assumptions(ctx);
for (i = 0; i < num_assumptions; i++) {
Z3_ast a = Z3_get_smtlib_assumption(ctx, i);
printf("assumption %d: %s\n", i, Z3_ast_to_string(ctx, a));
}
num_formulas = Z3_get_smtlib_num_formulas(ctx);
for (i = 0; i < num_formulas; i++) {
Z3_ast f = Z3_get_smtlib_formula(ctx, i);
printf("formula %d: %s\n", i, Z3_ast_to_string(ctx, f));
}
Z3_del_context(ctx);
}
/**
\brief Demonstrates how to handle parser errors using Z3 error handling support.
*/
@ -1802,9 +1735,9 @@ void parser_example5() {
s = mk_solver(ctx);
Z3_del_config(cfg);
Z3_parse_smtlib_string(ctx,
Z3_parse_smtlib2_string(ctx,
/* the following string has a parsing error: missing parenthesis */
"(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))",
"(declare-const x Int) declare-const y Int) (assert (and (> x y) (> x 0)))",
0, 0, 0,
0, 0, 0);
e = Z3_get_error_code(ctx);
@ -1817,7 +1750,7 @@ void parser_example5() {
err:
printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, e));
if (ctx != NULL) {
printf("Error message: '%s'.\n",Z3_get_smtlib_error(ctx));
printf("Error message: '%s'.\n",Z3_get_parser_error(ctx));
del_solver(ctx, s);
Z3_del_context(ctx);
}
@ -3065,10 +2998,8 @@ int main() {
two_contexts_example1();
error_code_example1();
error_code_example2();
parser_example1();
parser_example2();
parser_example3();
parser_example4();
parser_example5();
numeral_example();
ite_example();

View file

@ -173,10 +173,9 @@ namespace test_mapi
throw new Exception("function must be binary, and argument types must be equal to return type");
}
string bench = string.Format("(benchmark comm :formula (forall (x {0}) (y {1}) (= ({2} x y) ({3} y x))))",
string bench = string.Format("(assert (forall ((x {0}) (y {1})) (= ({2} x y) ({3} y x))))",
t.Name, t.Name, f.Name, f.Name);
ctx.ParseSMTLIBString(bench, new Symbol[] { t.Name }, new Sort[] { t }, new Symbol[] { f.Name }, new FuncDecl[] { f });
return ctx.SMTLIBFormulas[0];
return ctx.ParseSMTLIB2String(bench, new Symbol[] { t.Name }, new Sort[] { t }, new Symbol[] { f.Name }, new FuncDecl[] { f });
}
/// <summary>
@ -965,21 +964,6 @@ namespace test_mapi
}
}
/// <summary>
/// Shows how to read an SMT1 file.
/// </summary>
static void SMT1FileTest(string filename)
{
Console.Write("SMT File test ");
using (Context ctx = new Context(new Dictionary<string, string>() { { "MODEL", "true" } }))
{
ctx.ParseSMTLIBFile(filename);
BoolExpr a = ctx.MkAnd(ctx.SMTLIBFormulas);
Console.WriteLine("read formula: " + a);
}
}
/// <summary>
/// Shows how to read an SMT2 file.
@ -1399,11 +1383,10 @@ namespace test_mapi
{
Console.WriteLine("ParserExample1");
ctx.ParseSMTLIBString("(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))");
foreach (BoolExpr f in ctx.SMTLIBFormulas)
Console.WriteLine("formula {0}", f);
var fml = ctx.ParseSMTLIB2String("(declare-const x Int) (declare-const y Int) (assert (> x y)) (assert (> x 0))");
Console.WriteLine("formula {0}", fml);
Model m = Check(ctx, ctx.MkAnd(ctx.SMTLIBFormulas), Status.SATISFIABLE);
Model m = Check(ctx, fml, Status.SATISFIABLE);
}
/// <summary>
@ -1412,15 +1395,11 @@ namespace test_mapi
public static void ParserExample2(Context ctx)
{
Console.WriteLine("ParserExample2");
Symbol[] declNames = { ctx.MkSymbol("a"), ctx.MkSymbol("b") };
FuncDecl a = ctx.MkConstDecl(declNames[0], ctx.MkIntSort());
FuncDecl b = ctx.MkConstDecl(declNames[1], ctx.MkIntSort());
FuncDecl[] decls = new FuncDecl[] { a, b };
ctx.ParseSMTLIBString("(benchmark tst :formula (> a b))",
null, null, declNames, decls);
BoolExpr f = ctx.SMTLIBFormulas[0];
BoolExpr f = ctx.ParseSMTLIB2String("(assert (> a b))", null, null, declNames, decls);
Console.WriteLine("formula: {0}", f);
Check(ctx, f, Status.SATISFIABLE);
}
@ -1438,39 +1417,15 @@ namespace test_mapi
BoolExpr ca = CommAxiom(ctx, g);
ctx.ParseSMTLIBString("(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (gg x 0) (gg 0 y)))))",
BoolExpr thm = ctx.ParseSMTLIB2String("(assert (forall ((x Int) (y Int)) (=> (= x y) (= (gg x 0) (gg 0 y)))))",
null, null,
new Symbol[] { ctx.MkSymbol("gg") },
new FuncDecl[] { g });
BoolExpr thm = ctx.SMTLIBFormulas[0];
Console.WriteLine("formula: {0}", thm);
Prove(ctx, thm, false, ca);
}
/// <summary>
/// Display the declarations, assumptions and formulas in a SMT-LIB string.
/// </summary>
public static void ParserExample4(Context ctx)
{
Console.WriteLine("ParserExample4");
ctx.ParseSMTLIBString
("(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))");
foreach (var decl in ctx.SMTLIBDecls)
{
Console.WriteLine("Declaration: {0}", decl);
}
foreach (var f in ctx.SMTLIBAssumptions)
{
Console.WriteLine("Assumption: {0}", f);
}
foreach (var f in ctx.SMTLIBFormulas)
{
Console.WriteLine("Formula: {0}", f);
}
}
/// <summary>
/// Demonstrates how to handle parser errors using Z3 error handling support.
/// </summary>
@ -1481,9 +1436,9 @@ namespace test_mapi
try
{
ctx.ParseSMTLIBString(
ctx.ParseSMTLIB2String(
/* the following string has a parsing error: missing parenthesis */
"(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))");
"(declare-const x Int (declare-const y Int)) (assert (> x y))");
}
catch (Z3Exception e)
{
@ -1990,7 +1945,7 @@ namespace test_mapi
BoolExpr p2 = ctx.MkBoolConst("P2");
BoolExpr p3 = ctx.MkBoolConst("P3");
BoolExpr p4 = ctx.MkBoolConst("P4");
BoolExpr[] assumptions = new BoolExpr[] { ctx.MkNot(p1), ctx.MkNot(p2), ctx.MkNot(p3), ctx.MkNot(p4) };
Expr[] assumptions = new Expr[] { ctx.MkNot(p1), ctx.MkNot(p2), ctx.MkNot(p3), ctx.MkNot(p4) };
BoolExpr f1 = ctx.MkAnd(new BoolExpr[] { pa, pb, pc });
BoolExpr f2 = ctx.MkAnd(new BoolExpr[] { pa, ctx.MkNot(pb), pc });
BoolExpr f3 = ctx.MkOr(ctx.MkNot(pa), ctx.MkNot(pc));
@ -2213,7 +2168,6 @@ namespace test_mapi
BitvectorExample2(ctx);
ParserExample1(ctx);
ParserExample2(ctx);
ParserExample4(ctx);
ParserExample5(ctx);
ITEExample(ctx);
EvalExample1(ctx);

View file

@ -170,10 +170,9 @@ class JavaExample
String bench = "(benchmark comm :formula (forall (x " + t.getName()
+ ") (y " + t.getName() + ") (= (" + f.getName() + " x y) ("
+ f.getName() + " y x))))";
ctx.parseSMTLIBString(bench, new Symbol[] { t.getName() },
return ctx.parseSMTLIB2String(bench, new Symbol[] { t.getName() },
new Sort[] { t }, new Symbol[] { f.getName() },
new FuncDecl[] { f });
return ctx.getSMTLIBFormulas()[0];
}
// / "Hello world" example: create a Z3 logical context, and delete it.
@ -1028,21 +1027,6 @@ class JavaExample
}
}
// / Shows how to read an SMT1 file.
void smt1FileTest(String filename)
{
System.out.print("SMT File test ");
{
HashMap<String, String> cfg = new HashMap<String, String>();
Context ctx = new Context(cfg);
ctx.parseSMTLIBFile(filename, null, null, null, null);
BoolExpr a = ctx.mkAnd(ctx.getSMTLIBFormulas());
System.out.println("read formula: " + a);
}
}
// / Shows how to read an SMT2 file.
@ -1459,15 +1443,13 @@ class JavaExample
System.out.println("ParserExample1");
Log.append("ParserExample1");
ctx.parseSMTLIBString(
"(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))",
BoolExpr f = ctx.parseSMTLIB2String(
"(declare-const x Int) (declare-const y Int) (assert (and (> x y) (> x 0)))",
null, null, null, null);
for (BoolExpr f : ctx.getSMTLIBFormulas())
System.out.println("formula " + f);
System.out.println("formula " + f);
@SuppressWarnings("unused")
Model m = check(ctx, ctx.mkAnd(ctx.getSMTLIBFormulas()),
Status.SATISFIABLE);
Model m = check(ctx, f, Status.SATISFIABLE);
}
// / Demonstrates how to initialize the parser symbol table.
@ -1482,9 +1464,8 @@ class JavaExample
FuncDecl b = ctx.mkConstDecl(declNames[1], ctx.mkIntSort());
FuncDecl[] decls = new FuncDecl[] { a, b };
ctx.parseSMTLIBString("(benchmark tst :formula (> a b))", null, null,
BoolExpr f = ctx.parseSMTLIB2String("(assert (> a b))", null, null,
declNames, decls);
BoolExpr f = ctx.getSMTLIBFormulas()[0];
System.out.println("formula: " + f);
check(ctx, f, Status.SATISFIABLE);
}
@ -1502,39 +1483,14 @@ class JavaExample
BoolExpr ca = commAxiom(ctx, g);
ctx.parseSMTLIBString(
"(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (gg x 0) (gg 0 y)))))",
BoolExpr thm = ctx.parseSMTLIB2String(
"(assert (forall ((x Int) (y Int)) (=> (= x y) (= (gg x 0) (gg 0 y)))))",
null, null, new Symbol[] { ctx.mkSymbol("gg") },
new FuncDecl[] { g });
BoolExpr thm = ctx.getSMTLIBFormulas()[0];
System.out.println("formula: " + thm);
prove(ctx, thm, false, ca);
}
// / Display the declarations, assumptions and formulas in a SMT-LIB string.
public void parserExample4(Context ctx)
{
System.out.println("ParserExample4");
Log.append("ParserExample4");
ctx.parseSMTLIBString(
"(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))",
null, null, null, null);
for (FuncDecl decl : ctx.getSMTLIBDecls())
{
System.out.println("Declaration: " + decl);
}
for (BoolExpr f : ctx.getSMTLIBAssumptions())
{
System.out.println("Assumption: " + f);
}
for (BoolExpr f : ctx.getSMTLIBFormulas())
{
System.out.println("Formula: " + f);
}
}
// / Demonstrates how to handle parser errors using Z3 error handling
// support.
@ -1546,12 +1502,12 @@ class JavaExample
try
{
ctx.parseSMTLIBString(
ctx.parseSMTLIB2String(
/*
* the following string has a parsing error: missing
* parenthesis
*/
"(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))",
"(declare-const x Int (declare-const y Int)) (assert (> x y))",
null, null, null, null);
} catch (Z3Exception e)
{
@ -2341,7 +2297,6 @@ class JavaExample
p.bitvectorExample2(ctx);
p.parserExample1(ctx);
p.parserExample2(ctx);
p.parserExample4(ctx);
p.parserExample5(ctx);
p.iteExample(ctx);
p.evalExample1(ctx);

View file

@ -1,11 +1,11 @@
(benchmark ex
:logic AUFLIA
:extrafuns ((x Int) (y Int) (z Int))
:assumption (> x 0)
:assumption (<= x -1)
:assumption (or (> x 0) (< y 1))
:assumption (> y 2)
:assumption (> y 3)
:assumption (<= y -1)
:formula (= z (+ x y)))
(declare-const x Int)
(declare-const y Int)
(declare-const z Int)
(assert-soft (> x 0))
(assert-soft (<= x -1))
(assert-soft (or (> x 0) (< y 1)))
(assert-soft (> y 2))
(assert-soft (> y 3))
(assert-soft (<= y -1))
(assert (= z (+ x y)))

View file

@ -116,41 +116,6 @@ Z3_ast mk_binary_and(Z3_context ctx, Z3_ast in_1, Z3_ast in_2)
}
/**
\brief Get hard constraints from a SMT-LIB file. We assume hard constraints
are formulas preceeded with the keyword :formula.
Return an array containing all formulas read by the last Z3_parse_smtlib_file invocation.
It will store the number of formulas in num_cnstrs.
*/
Z3_ast * get_hard_constraints(Z3_context ctx, unsigned * num_cnstrs)
{
Z3_ast * result;
unsigned i;
*num_cnstrs = Z3_get_smtlib_num_formulas(ctx);
result = (Z3_ast *) malloc(sizeof(Z3_ast) * (*num_cnstrs));
for (i = 0; i < *num_cnstrs; i++) {
result[i] = Z3_get_smtlib_formula(ctx, i);
}
return result;
}
/**
\brief Get soft constraints from a SMT-LIB file. We assume soft constraints
are formulas preceeded with the keyword :assumption.
Return an array containing all assumptions read by the last Z3_parse_smtlib_file invocation.
It will store the number of formulas in num_cnstrs.
*/
Z3_ast * get_soft_constraints(Z3_context ctx, unsigned * num_cnstrs)
{
Z3_ast * result;
unsigned i;
*num_cnstrs = Z3_get_smtlib_num_assumptions(ctx);
result = (Z3_ast *) malloc(sizeof(Z3_ast) * (*num_cnstrs));
for (i = 0; i < *num_cnstrs; i++) {
result[i] = Z3_get_smtlib_assumption(ctx, i);
}
return result;
}
/**
\brief Free the given array of cnstrs that was allocated using get_hard_constraints or get_soft_constraints.
@ -610,14 +575,37 @@ int smtlib_maxsat(char * file_name, int approach)
{
Z3_context ctx;
Z3_solver s;
unsigned i;
Z3_optimize opt;
unsigned num_hard_cnstrs, num_soft_cnstrs;
Z3_ast * hard_cnstrs, * soft_cnstrs;
Z3_ast_vector hard, objs;
Z3_app soft;
unsigned result = 0;
ctx = mk_context();
s = mk_solver(ctx);
Z3_parse_smtlib_file(ctx, file_name, 0, 0, 0, 0, 0, 0);
hard_cnstrs = get_hard_constraints(ctx, &num_hard_cnstrs);
soft_cnstrs = get_soft_constraints(ctx, &num_soft_cnstrs);
opt = Z3_mk_optimize(ctx);
Z3_optimize_inc_ref(ctx, opt);
Z3_optimize_from_file(ctx, opt, file_name);
hard = Z3_optimize_get_assertions(ctx, opt);
Z3_ast_vector_inc_ref(ctx, hard);
num_hard_cnstrs = Z3_ast_vector_size(ctx, hard);
hard_cnstrs = (Z3_ast *) malloc(sizeof(Z3_ast) * (num_hard_cnstrs));
for (i = 0; i < num_hard_cnstrs; i++) {
hard_cnstrs[i] = Z3_ast_vector_get(ctx, hard, i);
}
objs = Z3_optimize_get_objectives(ctx, opt);
Z3_ast_vector_inc_ref(ctx, objs);
// soft constraints are stored in a single objective which is a sum
// of if-then-else expressions.
soft = Z3_to_app(ctx, Z3_ast_vector_get(ctx, objs, 0));
num_soft_cnstrs = Z3_get_app_num_args(ctx, soft);
soft_cnstrs = (Z3_ast *) malloc(sizeof(Z3_ast) * (num_soft_cnstrs));
for (i = 0; i < num_soft_cnstrs; ++i) {
soft_cnstrs[i] = Z3_get_app_arg(ctx, Z3_to_app(ctx, Z3_get_app_arg(ctx, soft, i)), 0);
}
switch (approach) {
case NAIVE_MAXSAT:
result = naive_maxsat(ctx, s, num_hard_cnstrs, hard_cnstrs, num_soft_cnstrs, soft_cnstrs);
@ -633,6 +621,7 @@ int smtlib_maxsat(char * file_name, int approach)
free_cnstr_array(hard_cnstrs);
free_cnstr_array(soft_cnstrs);
Z3_solver_dec_ref(ctx, s);
Z3_optimize_dec_ref(ctx, opt);
return result;
}

View file

@ -9,7 +9,7 @@ from mk_util import *
# Z3 Project definition
def init_project_def():
set_version(4, 5, 1, 0)
set_version(4, 6, 0, 0)
add_lib('util', [])
add_lib('lp', ['util'], 'util/lp')
add_lib('polynomial', ['util'], 'math/polynomial')
@ -75,10 +75,9 @@ def init_project_def():
add_lib('smtlogic_tactics', ['ackermannization', 'sat_solver', 'arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt_tactic', 'aig_tactic', 'fp', 'muz','qe','nlsat_smt_tactic'], 'tactic/smtlogics')
add_lib('fpa_tactics', ['fpa', 'core_tactics', 'bv_tactics', 'sat_tactic', 'smt_tactic', 'arith_tactics', 'smtlogic_tactics'], 'tactic/fpa')
add_lib('portfolio', ['smtlogic_tactics', 'sat_solver', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio')
add_lib('smtparser', ['portfolio'], 'parsers/smt')
add_lib('opt', ['smt', 'smtlogic_tactics', 'sls_tactic', 'sat_solver'], 'opt')
API_files = ['z3_api.h', 'z3_ast_containers.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_fixedpoint.h', 'z3_optimization.h', 'z3_interp.h', 'z3_fpa.h', 'z3_spacer.h']
add_lib('api', ['portfolio', 'smtparser', 'realclosure', 'interp', 'opt'],
add_lib('api', ['portfolio', 'realclosure', 'interp', 'opt'],
includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files)
add_exe('shell', ['api', 'sat', 'extra_cmds','opt'], exe_name='z3')
add_exe('test', ['api', 'fuzzing', 'simplex'], exe_name='test-z3', install=False)

View file

@ -98,7 +98,6 @@ add_subdirectory(sat/sat_solver)
add_subdirectory(tactic/smtlogics)
add_subdirectory(tactic/fpa)
add_subdirectory(tactic/portfolio)
add_subdirectory(parsers/smt)
add_subdirectory(opt)
add_subdirectory(api)
add_subdirectory(api/dll)

View file

@ -71,5 +71,4 @@ z3_add_component(api
opt
portfolio
realclosure
smtparser
)

View file

@ -832,30 +832,9 @@ extern "C" {
case Z3_PRINT_LOW_LEVEL:
buffer << mk_ll_pp(to_ast(a), mk_c(c)->m());
break;
case Z3_PRINT_SMTLIB_COMPLIANT: {
ast_smt_pp pp(mk_c(c)->m());
pp_params params;
pp.set_simplify_implies(params.simplify_implies());
ast* a1 = to_ast(a);
pp.set_logic(mk_c(c)->fparams().m_logic);
if (!is_expr(a1)) {
buffer << mk_pp(a1, mk_c(c)->m());
break;
}
if (mk_c(c)->get_print_mode() == Z3_PRINT_SMTLIB_COMPLIANT) {
pp.display_expr(buffer, to_expr(a1));
break;
}
if (mk_c(c)->get_print_mode() == Z3_PRINT_SMTLIB2_COMPLIANT) {
pp.display_expr_smt2(buffer, to_expr(a1));
break;
}
break;
}
case Z3_PRINT_SMTLIB2_COMPLIANT: {
case Z3_PRINT_SMTLIB2_COMPLIANT:
buffer << mk_ismt2_pp(to_ast(a), mk_c(c)->m());
break;
}
default:
UNREACHABLE();
}
@ -893,12 +872,7 @@ extern "C" {
for (unsigned i = 0; i < num_assumptions; ++i) {
pp.add_assumption(to_expr(assumptions[i]));
}
if (mk_c(c)->get_print_mode() == Z3_PRINT_SMTLIB2_COMPLIANT) {
pp.display_smt2(buffer, to_expr(formula));
}
else {
pp.display(buffer, to_expr(formula));
}
pp.display_smt2(buffer, to_expr(formula));
return mk_c(c)->mk_external_string(buffer.str());
Z3_CATCH_RETURN("");
}

View file

@ -19,7 +19,6 @@ Revision History:
--*/
#include<typeinfo>
#include "api/api_context.h"
#include "parsers/smt/smtparser.h"
#include "util/version.h"
#include "ast/ast_pp.h"
#include "ast/ast_ll_pp.h"
@ -89,8 +88,6 @@ namespace api {
m_print_mode = Z3_PRINT_SMTLIB_FULL;
m_searching = false;
m_smtlib_parser = 0;
m_smtlib_parser_has_decls = false;
m_interruptable = 0;
m_error_handler = &default_error_handler;
@ -111,13 +108,13 @@ namespace api {
context::~context() {
reset_parser();
m_last_obj = 0;
u_map<api::object*>::iterator it = m_allocated_objects.begin();
while (it != m_allocated_objects.end()) {
DEBUG_CODE(warning_msg("Uncollected memory: %d: %s", it->m_key, typeid(*it->m_value).name()););
api::object* val = it->m_value;
DEBUG_CODE(warning_msg("Uncollected memory: %d: %s", it->m_key, typeid(*val).name()););
m_allocated_objects.remove(it->m_key);
dealloc(it->m_value);
dealloc(val);
it = m_allocated_objects.begin();
}
}
@ -304,39 +301,6 @@ namespace api {
}
}
// ------------------------
//
// Parser interface for backward compatibility
//
// ------------------------
void context::reset_parser() {
if (m_smtlib_parser) {
dealloc(m_smtlib_parser);
m_smtlib_parser = 0;
m_smtlib_parser_has_decls = false;
m_smtlib_parser_decls.reset();
m_smtlib_parser_sorts.reset();
}
SASSERT(!m_smtlib_parser_has_decls);
}
void context::extract_smtlib_parser_decls() {
if (m_smtlib_parser) {
if (!m_smtlib_parser_has_decls) {
smtlib::symtable * table = m_smtlib_parser->get_benchmark()->get_symtable();
table->get_func_decls(m_smtlib_parser_decls);
table->get_sorts(m_smtlib_parser_sorts);
m_smtlib_parser_has_decls = true;
}
}
else {
m_smtlib_parser_decls.reset();
m_smtlib_parser_sorts.reset();
}
}
// ------------------------
//
// RCF manager

View file

@ -220,19 +220,11 @@ namespace api {
// ------------------------
//
// Parser interface for backward compatibility
// Parser interface
//
// ------------------------
// TODO: move to a "parser" object visible to the external world.
std::string m_smtlib_error_buffer;
smtlib::parser * m_smtlib_parser;
bool m_smtlib_parser_has_decls;
ptr_vector<func_decl> m_smtlib_parser_decls;
ptr_vector<sort> m_smtlib_parser_sorts;
void reset_parser();
void extract_smtlib_parser_decls();
std::string m_parser_error_buffer;
};

View file

@ -510,31 +510,15 @@ extern "C" {
read_error.clear();
try {
std::string foo(filename);
if (foo.size() >= 5 && foo.substr(foo.size() - 5) == ".smt2"){
Z3_ast assrts = Z3_parse_smtlib2_file(ctx, filename, 0, 0, 0, 0, 0, 0);
Z3_app app = Z3_to_app(ctx, assrts);
int nconjs = Z3_get_app_num_args(ctx, app);
assertions.resize(nconjs);
for (int k = 0; k < nconjs; k++)
assertions[k] = Z3_get_app_arg(ctx, app, k);
}
else {
Z3_parse_smtlib_file(ctx, filename, 0, 0, 0, 0, 0, 0);
int numa = Z3_get_smtlib_num_assumptions(ctx);
int numf = Z3_get_smtlib_num_formulas(ctx);
int num = numa + numf;
assertions.resize(num);
for (int j = 0; j < num; j++){
if (j < numa)
assertions[j] = Z3_get_smtlib_assumption(ctx, j);
else
assertions[j] = Z3_get_smtlib_formula(ctx, j - numa);
}
}
Z3_ast assrts = Z3_parse_smtlib2_file(ctx, filename, 0, 0, 0, 0, 0, 0);
Z3_app app = Z3_to_app(ctx, assrts);
int nconjs = Z3_get_app_num_args(ctx, app);
assertions.resize(nconjs);
for (int k = 0; k < nconjs; k++)
assertions[k] = Z3_get_app_arg(ctx, app, k);
}
catch (...) {
read_error << "SMTLIB parse error: " << Z3_get_smtlib_error(ctx);
read_error << "SMTLIB parse error: " << Z3_get_parser_error(ctx);
read_msg = read_error.str();
*error = read_msg.c_str();
return false;

View file

@ -16,17 +16,19 @@ Revision History:
--*/
#include<iostream>
#include "util/cancel_eh.h"
#include "util/file_path.h"
#include "util/scoped_timer.h"
#include "parsers/smt2/smt2parser.h"
#include "opt/opt_context.h"
#include "opt/opt_cmds.h"
#include "opt/opt_parse.h"
#include "api/z3.h"
#include "api/api_log_macros.h"
#include "api/api_stats.h"
#include "api/api_context.h"
#include "api/api_util.h"
#include "api/api_model.h"
#include "opt/opt_context.h"
#include "opt/opt_cmds.h"
#include "util/cancel_eh.h"
#include "util/scoped_timer.h"
#include "parsers/smt2/smt2parser.h"
#include "api/api_ast_vector.h"
extern "C" {
@ -281,16 +283,40 @@ extern "C" {
static void Z3_optimize_from_stream(
Z3_context c,
Z3_optimize opt,
std::istream& s) {
ast_manager& m = mk_c(c)->m();
std::istream& s,
char const* ext) {
ast_manager& m = mk_c(c)->m();
if (ext && std::string("opb") == ext) {
unsigned_vector h;
parse_opb(*to_optimize_ptr(opt), s, h);
return;
}
if (ext && std::string("wcnf") == ext) {
unsigned_vector h;
parse_wcnf(*to_optimize_ptr(opt), s, h);
return;
}
scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &m);
install_opt_cmds(*ctx.get(), to_optimize_ptr(opt));
std::stringstream errstrm;
ctx->set_regular_stream(errstrm);
ctx->set_ignore_check(true);
if (!parse_smt2_commands(*ctx.get(), s)) {
try {
if (!parse_smt2_commands(*ctx.get(), s)) {
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
return;
}
}
catch (z3_exception& e) {
errstrm << e.msg();
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
return;
}
}
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
ptr_vector<expr>::const_iterator end = ctx->end_assertions();
for (; it != end; ++it) {
@ -298,6 +324,8 @@ extern "C" {
}
}
void Z3_API Z3_optimize_from_string(
Z3_context c,
Z3_optimize d,
@ -306,7 +334,7 @@ extern "C" {
//LOG_Z3_optimize_from_string(c, d, s);
std::string str(s);
std::istringstream is(str);
Z3_optimize_from_stream(c, d, is);
Z3_optimize_from_stream(c, d, is, nullptr);
Z3_CATCH;
}
@ -322,7 +350,7 @@ extern "C" {
strm << "Could not open file " << s;
throw default_exception(strm.str());
}
Z3_optimize_from_stream(c, d, is);
Z3_optimize_from_stream(c, d, is, get_extension(s));
Z3_CATCH;
}
@ -335,8 +363,8 @@ extern "C" {
mk_c(c)->save_object(v);
expr_ref_vector hard(mk_c(c)->m());
to_optimize_ptr(o)->get_hard_constraints(hard);
for (unsigned i = 0; i < hard.size(); i++) {
v->m_ast_vector.push_back(hard[i].get());
for (expr* h : hard) {
v->m_ast_vector.push_back(h);
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(0);

View file

@ -22,232 +22,16 @@ Revision History:
#include "api/api_util.h"
#include "cmd_context/cmd_context.h"
#include "parsers/smt2/smt2parser.h"
#include "parsers/smt/smtparser.h"
#include "solver/solver_na2as.h"
extern "C" {
void init_smtlib_parser(Z3_context c,
unsigned num_sorts,
Z3_symbol const sort_names[],
Z3_sort const types[],
unsigned num_decls,
Z3_symbol const decl_names[],
Z3_func_decl const decls[]) {
mk_c(c)->reset_parser();
mk_c(c)->m_smtlib_parser = smtlib::parser::create(mk_c(c)->m());
mk_c(c)->m_smtlib_parser->initialize_smtlib();
smtlib::symtable * table = mk_c(c)->m_smtlib_parser->get_benchmark()->get_symtable();
for (unsigned i = 0; i < num_sorts; i++) {
table->insert(to_symbol(sort_names[i]), to_sort(types[i]));
}
for (unsigned i = 0; i < num_decls; i++) {
table->insert(to_symbol(decl_names[i]), to_func_decl(decls[i]));
}
}
void Z3_API Z3_parse_smtlib_string(Z3_context c,
const char * str,
unsigned num_sorts,
Z3_symbol const sort_names[],
Z3_sort const sorts[],
unsigned num_decls,
Z3_symbol const decl_names[],
Z3_func_decl const decls[]) {
Z3_TRY;
LOG_Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
scoped_ptr<std::ostringstream> outs = alloc(std::ostringstream);
bool ok = false;
RESET_ERROR_CODE();
init_smtlib_parser(c, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
mk_c(c)->m_smtlib_parser->set_error_stream(*outs);
try {
ok = mk_c(c)->m_smtlib_parser->parse_string(str);
}
catch (...) {
ok = false;
}
mk_c(c)->m_smtlib_error_buffer = outs->str();
outs = nullptr;
if (!ok) {
mk_c(c)->reset_parser();
SET_ERROR_CODE(Z3_PARSER_ERROR);
}
Z3_CATCH;
}
void Z3_API Z3_parse_smtlib_file(Z3_context c,
const char * file_name,
unsigned num_sorts,
Z3_symbol const sort_names[],
Z3_sort const types[],
unsigned num_decls,
Z3_symbol const decl_names[],
Z3_func_decl const decls[]) {
Z3_string Z3_API Z3_get_parser_error(Z3_context c) {
Z3_TRY;
LOG_Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, types, num_decls, decl_names, decls);
bool ok = false;
RESET_ERROR_CODE();
scoped_ptr<std::ostringstream> outs = alloc(std::ostringstream);
init_smtlib_parser(c, num_sorts, sort_names, types, num_decls, decl_names, decls);
mk_c(c)->m_smtlib_parser->set_error_stream(*outs);
try {
ok = mk_c(c)->m_smtlib_parser->parse_file(file_name);
}
catch(...) {
ok = false;
}
mk_c(c)->m_smtlib_error_buffer = outs->str();
outs = nullptr;
if (!ok) {
mk_c(c)->reset_parser();
SET_ERROR_CODE(Z3_PARSER_ERROR);
}
Z3_CATCH;
}
unsigned Z3_API Z3_get_smtlib_num_formulas(Z3_context c) {
Z3_TRY;
LOG_Z3_get_smtlib_num_formulas(c);
RESET_ERROR_CODE();
if (mk_c(c)->m_smtlib_parser) {
return mk_c(c)->m_smtlib_parser->get_benchmark()->get_num_formulas();
}
SET_ERROR_CODE(Z3_NO_PARSER);
return 0;
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_get_smtlib_formula(Z3_context c, unsigned i) {
Z3_TRY;
LOG_Z3_get_smtlib_formula(c, i);
RESET_ERROR_CODE();
if (mk_c(c)->m_smtlib_parser) {
if (i < mk_c(c)->m_smtlib_parser->get_benchmark()->get_num_formulas()) {
ast * f = mk_c(c)->m_smtlib_parser->get_benchmark()->begin_formulas()[i];
mk_c(c)->save_ast_trail(f);
RETURN_Z3(of_ast(f));
}
else {
SET_ERROR_CODE(Z3_IOB);
}
}
else {
SET_ERROR_CODE(Z3_NO_PARSER);
}
RETURN_Z3(0);
Z3_CATCH_RETURN(0);
}
unsigned Z3_API Z3_get_smtlib_num_assumptions(Z3_context c) {
Z3_TRY;
LOG_Z3_get_smtlib_num_assumptions(c);
RESET_ERROR_CODE();
if (mk_c(c)->m_smtlib_parser) {
return mk_c(c)->m_smtlib_parser->get_benchmark()->get_num_axioms();
}
SET_ERROR_CODE(Z3_NO_PARSER);
return 0;
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_get_smtlib_assumption(Z3_context c, unsigned i) {
Z3_TRY;
LOG_Z3_get_smtlib_assumption(c, i);
RESET_ERROR_CODE();
if (mk_c(c)->m_smtlib_parser) {
if (i < mk_c(c)->m_smtlib_parser->get_benchmark()->get_num_axioms()) {
ast * a = mk_c(c)->m_smtlib_parser->get_benchmark()->begin_axioms()[i];
mk_c(c)->save_ast_trail(a);
RETURN_Z3(of_ast(a));
}
else {
SET_ERROR_CODE(Z3_IOB);
}
}
else {
SET_ERROR_CODE(Z3_NO_PARSER);
}
RETURN_Z3(0);
Z3_CATCH_RETURN(0);
}
unsigned Z3_API Z3_get_smtlib_num_decls(Z3_context c) {
Z3_TRY;
LOG_Z3_get_smtlib_num_decls(c);
RESET_ERROR_CODE();
if (mk_c(c)->m_smtlib_parser) {
mk_c(c)->extract_smtlib_parser_decls();
return mk_c(c)->m_smtlib_parser_decls.size();
}
SET_ERROR_CODE(Z3_NO_PARSER);
return 0;
Z3_CATCH_RETURN(0);
}
Z3_func_decl Z3_API Z3_get_smtlib_decl(Z3_context c, unsigned i) {
Z3_TRY;
LOG_Z3_get_smtlib_decl(c, i);
LOG_Z3_get_parser_error(c);
RESET_ERROR_CODE();
mk_c(c)->extract_smtlib_parser_decls();
if (mk_c(c)->m_smtlib_parser) {
if (i < mk_c(c)->m_smtlib_parser_decls.size()) {
func_decl * d = mk_c(c)->m_smtlib_parser_decls[i];
mk_c(c)->save_ast_trail(d);
RETURN_Z3(of_func_decl(d));
}
else {
SET_ERROR_CODE(Z3_IOB);
}
}
else {
SET_ERROR_CODE(Z3_NO_PARSER);
}
RETURN_Z3(0);
Z3_CATCH_RETURN(0);
}
unsigned Z3_API Z3_get_smtlib_num_sorts(Z3_context c) {
Z3_TRY;
LOG_Z3_get_smtlib_num_sorts(c);
RESET_ERROR_CODE();
if (mk_c(c)->m_smtlib_parser) {
mk_c(c)->extract_smtlib_parser_decls();
return mk_c(c)->m_smtlib_parser_sorts.size();
}
SET_ERROR_CODE(Z3_NO_PARSER);
return 0;
Z3_CATCH_RETURN(0);
}
Z3_sort Z3_API Z3_get_smtlib_sort(Z3_context c, unsigned i) {
Z3_TRY;
LOG_Z3_get_smtlib_sort(c, i);
RESET_ERROR_CODE();
if (mk_c(c)->m_smtlib_parser) {
mk_c(c)->extract_smtlib_parser_decls();
if (i < mk_c(c)->m_smtlib_parser_sorts.size()) {
sort* s = mk_c(c)->m_smtlib_parser_sorts[i];
mk_c(c)->save_ast_trail(s);
RETURN_Z3(of_sort(s));
}
else {
SET_ERROR_CODE(Z3_IOB);
}
}
else {
SET_ERROR_CODE(Z3_NO_PARSER);
}
RETURN_Z3(0);
Z3_CATCH_RETURN(0);
}
Z3_string Z3_API Z3_get_smtlib_error(Z3_context c) {
Z3_TRY;
LOG_Z3_get_smtlib_error(c);
RESET_ERROR_CODE();
return mk_c(c)->m_smtlib_error_buffer.c_str();
return mk_c(c)->m_parser_error_buffer.c_str();
Z3_CATCH_RETURN("");
}
@ -268,10 +52,26 @@ extern "C" {
ctx->insert(to_symbol(decl_names[i]), to_func_decl(decls[i]));
}
for (unsigned i = 0; i < num_sorts; ++i) {
psort* ps = ctx->pm().mk_psort_cnst(to_sort(sorts[i]));
ctx->insert(ctx->pm().mk_psort_user_decl(0, to_symbol(sort_names[i]), ps));
sort* srt = to_sort(sorts[i]);
symbol name(to_symbol(sort_names[i]));
if (!ctx->find_psort_decl(name)) {
psort* ps = ctx->pm().mk_psort_cnst(srt);
ctx->insert(ctx->pm().mk_psort_user_decl(0, name, ps));
}
}
if (!parse_smt2_commands(*ctx.get(), is)) {
std::stringstream errstrm;
ctx->set_regular_stream(errstrm);
try {
if (!parse_smt2_commands(*ctx.get(), is)) {
ctx = nullptr;
mk_c(c)->m_parser_error_buffer = errstrm.str();
SET_ERROR_CODE(Z3_PARSER_ERROR);
return of_ast(mk_c(c)->m().mk_true());
}
}
catch (z3_exception& e) {
errstrm << e.msg();
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
return of_ast(mk_c(c)->m().mk_true());

View file

@ -28,11 +28,17 @@ Revision History:
#include "solver/tactic2solver.h"
#include "util/scoped_ctrl_c.h"
#include "util/cancel_eh.h"
#include "util/file_path.h"
#include "util/scoped_timer.h"
#include "tactic/portfolio/smt_strategic_solver.h"
#include "smt/smt_solver.h"
#include "smt/smt_implied_equalities.h"
#include "solver/smt_logics.h"
#include "cmd_context/cmd_context.h"
#include "parsers/smt2/smt2parser.h"
#include "sat/dimacs.h"
#include "sat/sat_solver.h"
#include "sat/tactic/goal2sat.h"
extern "C" {
@ -121,6 +127,63 @@ extern "C" {
Z3_CATCH_RETURN(0);
}
void solver_from_stream(Z3_context c, Z3_solver s, std::istream& is) {
scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &(mk_c(c)->m()));
ctx->set_ignore_check(true);
if (!parse_smt2_commands(*ctx.get(), is)) {
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
return;
}
bool initialized = to_solver(s)->m_solver.get() != 0;
if (!initialized)
init_solver(c, s);
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
ptr_vector<expr>::const_iterator end = ctx->end_assertions();
for (; it != end; ++it) {
to_solver_ref(s)->assert_expr(*it);
}
// to_solver_ref(s)->set_model_converter(ctx->get_model_converter());
}
void Z3_API Z3_solver_from_string(Z3_context c, Z3_solver s, Z3_string c_str) {
Z3_TRY;
LOG_Z3_solver_from_string(c, s, c_str);
std::string str(c_str);
std::istringstream is(str);
solver_from_stream(c, s, is);
Z3_CATCH;
}
void Z3_API Z3_solver_from_file(Z3_context c, Z3_solver s, Z3_string file_name) {
Z3_TRY;
LOG_Z3_solver_from_file(c, s, file_name);
char const* ext = get_extension(file_name);
std::ifstream is(file_name);
if (!is) {
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR);
}
else if (ext && std::string("dimacs") == ext) {
ast_manager& m = to_solver_ref(s)->get_manager();
sat::solver solver(to_solver_ref(s)->get_params(), m.limit(), nullptr);
parse_dimacs(is, solver);
sat2goal s2g;
model_converter_ref mc;
atom2bool_var a2b(m);
goal g(m);
s2g(solver, a2b, to_solver_ref(s)->get_params(), g, mc);
for (unsigned i = 0; i < g.size(); ++i) {
to_solver_ref(s)->assert_expr(g.form(i));
}
}
else {
solver_from_stream(c, s, is);
}
Z3_CATCH;
}
Z3_string Z3_API Z3_solver_get_help(Z3_context c, Z3_solver s) {
Z3_TRY;
LOG_Z3_solver_get_help(c, s);

View file

@ -174,6 +174,15 @@ namespace z3 {
return e;
}
void check_parser_error() const {
Z3_error_code e = Z3_get_error_code(*this);
if (e != Z3_OK && enable_exceptions()) {
Z3_string s = Z3_get_parser_error(*this);
if (s && *s) Z3_THROW(exception(s));
}
check_error();
}
/**
\brief The C++ API uses by defaults exceptions on errors.
For applications that don't work well with exceptions (there should be only few)
@ -1527,6 +1536,38 @@ namespace z3 {
m_vector = s.m_vector;
return *this;
}
/*
Disabled pending C++98 build upgrade
bool contains(T const& x) const {
for (T y : *this) if (eq(x, y)) return true;
return false;
}
*/
class iterator {
ast_vector_tpl const* m_vector;
unsigned m_index;
public:
iterator(ast_vector_tpl const* v, unsigned i): m_vector(v), m_index(i) {}
iterator(iterator& other): m_vector(other.m_vector), m_index(other.m_index) {}
iterator operator=(iterator const& other) { m_vector = other.m_vector; m_index = other.m_index; return *this; }
bool operator==(iterator const& other) {
return other.m_index == m_index;
};
bool operator!=(iterator const& other) {
return other.m_index != m_index;
};
iterator& operator++() {
++m_index;
return *this;
}
iterator operator++(int) { iterator tmp = *this; ++m_index; return tmp; }
T * operator->() const { return &(operator*()); }
T operator*() const { return (*m_vector)[m_index]; }
};
iterator begin() const { return iterator(this, 0); }
iterator end() const { return iterator(this, size()); }
friend std::ostream & operator<<(std::ostream & out, ast_vector_tpl const & v) { out << Z3_ast_vector_to_string(v.ctx(), v); return out; }
};
@ -1902,6 +1943,11 @@ namespace z3 {
return *this;
}
void set(params const & p) { Z3_solver_set_params(ctx(), m_solver, p); check_error(); }
void set(char const * k, bool v) { params p(ctx()); p.set(k, v); set(p); }
void set(char const * k, unsigned v) { params p(ctx()); p.set(k, v); set(p); }
void set(char const * k, double v) { params p(ctx()); p.set(k, v); set(p); }
void set(char const * k, symbol const & v) { params p(ctx()); p.set(k, v); set(p); }
void set(char const * k, char const* v) { params p(ctx()); p.set(k, v); set(p); }
void push() { Z3_solver_push(ctx(), m_solver); check_error(); }
void pop(unsigned n = 1) { Z3_solver_pop(ctx(), m_solver, n); check_error(); }
void reset() { Z3_solver_reset(ctx(), m_solver); check_error(); }
@ -1914,6 +1960,11 @@ namespace z3 {
void add(expr const & e, char const * p) {
add(e, ctx().bool_const(p));
}
// fails for some compilers:
// void add(expr_vector const& v) { check_context(*this, v); for (expr e : v) add(e); }
void from_file(char const* file) { Z3_solver_from_file(ctx(), m_solver, file); ctx().check_parser_error(); }
void from_string(char const* s) { Z3_solver_from_string(ctx(), m_solver, s); ctx().check_parser_error(); }
check_result check() { Z3_lbool r = Z3_solver_check(ctx(), m_solver); check_error(); return to_check_result(r); }
check_result check(unsigned n, expr * const assumptions) {
array<Z3_ast> _assumptions(n);
@ -1994,6 +2045,8 @@ namespace z3 {
return *this;
}
void add(expr const & f) { check_context(*this, f); Z3_goal_assert(ctx(), m_goal, f); check_error(); }
// fails for some compilers:
// void add(expr_vector const& v) { check_context(*this, v); for (expr e : v) add(e); }
unsigned size() const { return Z3_goal_size(ctx(), m_goal); }
expr operator[](int i) const { assert(0 <= i); Z3_ast r = Z3_goal_formula(ctx(), m_goal, i); check_error(); return expr(ctx(), r); }
Z3_goal_prec precision() const { return Z3_goal_precision(ctx(), m_goal); }
@ -2774,13 +2827,12 @@ namespace z3 {
inline expr context::parse_string(char const* s) {
Z3_ast r = Z3_parse_smtlib2_string(*this, s, 0, 0, 0, 0, 0, 0);
check_error();
return expr(*this, r);
check_parser_error();
return expr(*this, r);
}
inline expr context::parse_file(char const* s) {
Z3_ast r = Z3_parse_smtlib2_file(*this, s, 0, 0, 0, 0, 0, 0);
check_error();
check_parser_error();
return expr(*this, r);
}
@ -2796,7 +2848,7 @@ namespace z3 {
decl_names[i] = decls[i].name();
}
Z3_ast r = Z3_parse_smtlib2_string(*this, s, sorts.size(), sort_names.ptr(), sorts1.ptr(), decls.size(), decl_names.ptr(), decls1.ptr());
check_error();
check_parser_error();
return expr(*this, r);
}
@ -2812,7 +2864,7 @@ namespace z3 {
decl_names[i] = decls[i].name();
}
Z3_ast r = Z3_parse_smtlib2_file(*this, s, sorts.size(), sort_names.ptr(), sorts1.ptr(), decls.size(), decl_names.ptr(), decls1.ptr());
check_error();
check_parser_error();
return expr(*this, r);
}

View file

@ -3320,160 +3320,10 @@ namespace Microsoft.Z3
#endregion
#region SMT Files & Strings
/// <summary>
/// Convert a benchmark into an SMT-LIB formatted string.
/// </summary>
/// <param name="name">Name of the benchmark. The argument is optional.</param>
/// <param name="logic">The benchmark logic. </param>
/// <param name="status">The status string (sat, unsat, or unknown)</param>
/// <param name="attributes">Other attributes, such as source, difficulty or category.</param>
/// <param name="assumptions">Auxiliary assumptions.</param>
/// <param name="formula">Formula to be checked for consistency in conjunction with assumptions.</param>
/// <returns>A string representation of the benchmark.</returns>
public string BenchmarkToSMTString(string name, string logic, string status, string attributes,
BoolExpr[] assumptions, BoolExpr formula)
{
Contract.Requires(assumptions != null);
Contract.Requires(formula != null);
Contract.Ensures(Contract.Result<string>() != null);
return Native.Z3_benchmark_to_smtlib_string(nCtx, name, logic, status, attributes,
(uint)assumptions.Length, AST.ArrayToNative(assumptions),
formula.NativeObject);
}
/// <summary>
/// Parse the given string using the SMT-LIB parser.
/// </summary>
/// <remarks>
/// The symbol table of the parser can be initialized using the given sorts and declarations.
/// The symbols in the arrays <paramref name="sortNames"/> and <paramref name="declNames"/>
/// don't need to match the names of the sorts and declarations in the arrays <paramref name="sorts"/>
/// and <paramref name="decls"/>. This is a useful feature since we can use arbitrary names to
/// reference sorts and declarations.
/// </remarks>
public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null)
{
uint csn = Symbol.ArrayLength(sortNames);
uint cs = Sort.ArrayLength(sorts);
uint cdn = Symbol.ArrayLength(declNames);
uint cd = AST.ArrayLength(decls);
if (csn != cs || cdn != cd)
throw new Z3Exception("Argument size mismatch");
Native.Z3_parse_smtlib_string(nCtx, str,
AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts),
AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls));
}
/// <summary>
/// Parse the given file using the SMT-LIB parser.
/// </summary>
/// <seealso cref="ParseSMTLIBString"/>
public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null)
{
uint csn = Symbol.ArrayLength(sortNames);
uint cs = Sort.ArrayLength(sorts);
uint cdn = Symbol.ArrayLength(declNames);
uint cd = AST.ArrayLength(decls);
if (csn != cs || cdn != cd)
throw new Z3Exception("Argument size mismatch");
Native.Z3_parse_smtlib_file(nCtx, fileName,
AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts),
AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls));
}
/// <summary>
/// The number of SMTLIB formulas parsed by the last call to <c>ParseSMTLIBString</c> or <c>ParseSMTLIBFile</c>.
/// </summary>
public uint NumSMTLIBFormulas { get { return Native.Z3_get_smtlib_num_formulas(nCtx); } }
/// <summary>
/// The formulas parsed by the last call to <c>ParseSMTLIBString</c> or <c>ParseSMTLIBFile</c>.
/// </summary>
public BoolExpr[] SMTLIBFormulas
{
get
{
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
uint n = NumSMTLIBFormulas;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (BoolExpr)Expr.Create(this, Native.Z3_get_smtlib_formula(nCtx, i));
return res;
}
}
/// <summary>
/// The number of SMTLIB assumptions parsed by the last call to <c>ParseSMTLIBString</c> or <c>ParseSMTLIBFile</c>.
/// </summary>
public uint NumSMTLIBAssumptions { get { return Native.Z3_get_smtlib_num_assumptions(nCtx); } }
/// <summary>
/// The assumptions parsed by the last call to <c>ParseSMTLIBString</c> or <c>ParseSMTLIBFile</c>.
/// </summary>
public BoolExpr[] SMTLIBAssumptions
{
get
{
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
uint n = NumSMTLIBAssumptions;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (BoolExpr)Expr.Create(this, Native.Z3_get_smtlib_assumption(nCtx, i));
return res;
}
}
/// <summary>
/// The number of SMTLIB declarations parsed by the last call to <c>ParseSMTLIBString</c> or <c>ParseSMTLIBFile</c>.
/// </summary>
public uint NumSMTLIBDecls { get { return Native.Z3_get_smtlib_num_decls(nCtx); } }
/// <summary>
/// The declarations parsed by the last call to <c>ParseSMTLIBString</c> or <c>ParseSMTLIBFile</c>.
/// </summary>
public FuncDecl[] SMTLIBDecls
{
get
{
Contract.Ensures(Contract.Result<FuncDecl[]>() != null);
uint n = NumSMTLIBDecls;
FuncDecl[] res = new FuncDecl[n];
for (uint i = 0; i < n; i++)
res[i] = new FuncDecl(this, Native.Z3_get_smtlib_decl(nCtx, i));
return res;
}
}
/// <summary>
/// The number of SMTLIB sorts parsed by the last call to <c>ParseSMTLIBString</c> or <c>ParseSMTLIBFile</c>.
/// </summary>
public uint NumSMTLIBSorts { get { return Native.Z3_get_smtlib_num_sorts(nCtx); } }
/// <summary>
/// The declarations parsed by the last call to <c>ParseSMTLIBString</c> or <c>ParseSMTLIBFile</c>.
/// </summary>
public Sort[] SMTLIBSorts
{
get
{
Contract.Ensures(Contract.Result<Sort[]>() != null);
uint n = NumSMTLIBSorts;
Sort[] res = new Sort[n];
for (uint i = 0; i < n; i++)
res[i] = Sort.Create(this, Native.Z3_get_smtlib_sort(nCtx, i));
return res;
}
}
/// <summary>
/// Parse the given string using the SMT-LIB2 parser.
/// </summary>
/// <seealso cref="ParseSMTLIBString"/>
/// <returns>A conjunction of assertions in the scope (up to push/pop) at the end of the string.</returns>
public BoolExpr ParseSMTLIB2String(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null)
{

View file

@ -31,98 +31,108 @@ namespace Microsoft.Z3
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(Symbol name, bool value)
public Params Add(Symbol name, bool value)
{
Contract.Requires(name != null);
Native.Z3_params_set_bool(Context.nCtx, NativeObject, name.NativeObject, (value) ? 1 : 0);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(Symbol name, uint value)
public Params Add(Symbol name, uint value)
{
Contract.Requires(name != null);
Native.Z3_params_set_uint(Context.nCtx, NativeObject, name.NativeObject, value);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(Symbol name, double value)
public Params Add(Symbol name, double value)
{
Contract.Requires(name != null);
Contract.Requires(name != null);
Native.Z3_params_set_double(Context.nCtx, NativeObject, name.NativeObject, value);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(Symbol name, string value)
public Params Add(Symbol name, string value)
{
Contract.Requires(value != null);
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, Context.MkSymbol(value).NativeObject);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(Symbol name, Symbol value)
public Params Add(Symbol name, Symbol value)
{
Contract.Requires(name != null);
Contract.Requires(value != null);
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, value.NativeObject);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(string name, bool value)
public Params Add(string name, bool value)
{
Native.Z3_params_set_bool(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, (value) ? 1 : 0);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(string name, uint value)
public Params Add(string name, uint value)
{
Native.Z3_params_set_uint(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(string name, double value)
public Params Add(string name, double value)
{
Native.Z3_params_set_double(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(string name, Symbol value)
public Params Add(string name, Symbol value)
{
Contract.Requires(value != null);
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value.NativeObject);
return this;
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
public void Add(string name, string value)
public Params Add(string name, string value)
{
Contract.Requires(name != null);
Contract.Requires(value != null);
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, Context.MkSymbol(value).NativeObject);
return this;
}
/// <summary>

View file

@ -57,6 +57,49 @@ namespace Microsoft.Z3
}
}
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(string name, bool value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(string name, uint value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(string name, double value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(string name, string value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(string name, Symbol value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(Symbol name, bool value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(Symbol name, uint value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(Symbol name, double value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(Symbol name, string value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Sets parameter on the solver
/// </summary>
public void Set(Symbol name, Symbol value) { Parameters = Context.MkParams().Add(name, value); }
/// <summary>
/// Retrieves parameter descriptions for solver.
/// </summary>
@ -140,11 +183,11 @@ namespace Microsoft.Z3
/// using the Boolean constants in ps.
/// </summary>
/// <remarks>
/// This API is an alternative to <see cref="Check"/> with assumptions for extracting unsat cores.
/// This API is an alternative to <see cref="Check(Expr[])"/> with assumptions for extracting unsat cores.
/// Both APIs can be used in the same solver. The unsat core will contain a combination
/// of the Boolean variables provided using <see cref="AssertAndTrack(BoolExpr[],BoolExpr[])"/>
/// and the Boolean literals
/// provided using <see cref="Check"/> with assumptions.
/// provided using <see cref="Check(Expr[])"/> with assumptions.
/// </remarks>
public void AssertAndTrack(BoolExpr[] constraints, BoolExpr[] ps)
{
@ -165,11 +208,11 @@ namespace Microsoft.Z3
/// using the Boolean constant p.
/// </summary>
/// <remarks>
/// This API is an alternative to <see cref="Check"/> with assumptions for extracting unsat cores.
/// This API is an alternative to <see cref="Check(Expr[])"/> with assumptions for extracting unsat cores.
/// Both APIs can be used in the same solver. The unsat core will contain a combination
/// of the Boolean variables provided using <see cref="AssertAndTrack(BoolExpr[],BoolExpr[])"/>
/// and the Boolean literals
/// provided using <see cref="Check"/> with assumptions.
/// provided using <see cref="Check(Expr[])"/> with assumptions.
/// </remarks>
public void AssertAndTrack(BoolExpr constraint, BoolExpr p)
{
@ -181,6 +224,22 @@ namespace Microsoft.Z3
Native.Z3_solver_assert_and_track(Context.nCtx, NativeObject, constraint.NativeObject, p.NativeObject);
}
/// <summary>
/// Load solver assertions from a file.
/// </summary>
public void FromFile(string file)
{
Native.Z3_solver_from_file(Context.nCtx, NativeObject, file);
}
/// <summary>
/// Load solver assertions from a string.
/// </summary>
public void FromString(string str)
{
Native.Z3_solver_from_string(Context.nCtx, NativeObject, str);
}
/// <summary>
/// The number of assertions in the solver.
/// </summary>
@ -225,6 +284,25 @@ namespace Microsoft.Z3
return lboolToStatus(r);
}
/// <summary>
/// Checks whether the assertions in the solver are consistent or not.
/// </summary>
/// <remarks>
/// <seealso cref="Model"/>
/// <seealso cref="UnsatCore"/>
/// <seealso cref="Proof"/>
/// </remarks>
public Status Check(IEnumerable<BoolExpr> assumptions)
{
Z3_lbool r;
BoolExpr[] asms = assumptions.ToArray();
if (asms.Length == 0)
r = (Z3_lbool)Native.Z3_solver_check(Context.nCtx, NativeObject);
else
r = (Z3_lbool)Native.Z3_solver_check_assumptions(Context.nCtx, NativeObject, (uint)asms.Length, AST.ArrayToNative(asms));
return lboolToStatus(r);
}
/// <summary>
/// Retrieve fixed assignments to the set of variables in the form of consequences.
/// Each consequence is an implication of the form

View file

@ -2540,147 +2540,8 @@ public class Context implements AutoCloseable {
AST.arrayToNative(assumptions), formula.getNativeObject());
}
/**
* Parse the given string using the SMT-LIB parser.
* Remarks: The symbol
* table of the parser can be initialized using the given sorts and
* declarations. The symbols in the arrays {@code sortNames} and
* {@code declNames} don't need to match the names of the sorts
* and declarations in the arrays {@code sorts} and {@code decls}. This is a useful feature since we can use arbitrary names
* to reference sorts and declarations.
**/
public void parseSMTLIBString(String str, Symbol[] sortNames, Sort[] sorts,
Symbol[] declNames, FuncDecl[] decls)
{
int csn = Symbol.arrayLength(sortNames);
int cs = Sort.arrayLength(sorts);
int cdn = Symbol.arrayLength(declNames);
int cd = AST.arrayLength(decls);
if (csn != cs || cdn != cd)
throw new Z3Exception("Argument size mismatch");
Native.parseSmtlibString(nCtx(), str, AST.arrayLength(sorts),
Symbol.arrayToNative(sortNames), AST.arrayToNative(sorts),
AST.arrayLength(decls), Symbol.arrayToNative(declNames),
AST.arrayToNative(decls));
}
/**
* Parse the given file using the SMT-LIB parser.
* @see #parseSMTLIBString
**/
public void parseSMTLIBFile(String fileName, Symbol[] sortNames,
Sort[] sorts, Symbol[] declNames, FuncDecl[] decls)
{
int csn = Symbol.arrayLength(sortNames);
int cs = Sort.arrayLength(sorts);
int cdn = Symbol.arrayLength(declNames);
int cd = AST.arrayLength(decls);
if (csn != cs || cdn != cd)
throw new Z3Exception("Argument size mismatch");
Native.parseSmtlibFile(nCtx(), fileName, AST.arrayLength(sorts),
Symbol.arrayToNative(sortNames), AST.arrayToNative(sorts),
AST.arrayLength(decls), Symbol.arrayToNative(declNames),
AST.arrayToNative(decls));
}
/**
* The number of SMTLIB formulas parsed by the last call to
* {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}.
**/
public int getNumSMTLIBFormulas()
{
return Native.getSmtlibNumFormulas(nCtx());
}
/**
* The formulas parsed by the last call to {@code ParseSMTLIBString} or
* {@code ParseSMTLIBFile}.
**/
public BoolExpr[] getSMTLIBFormulas()
{
int n = getNumSMTLIBFormulas();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = (BoolExpr) Expr.create(this,
Native.getSmtlibFormula(nCtx(), i));
return res;
}
/**
* The number of SMTLIB assumptions parsed by the last call to
* {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}.
**/
public int getNumSMTLIBAssumptions()
{
return Native.getSmtlibNumAssumptions(nCtx());
}
/**
* The assumptions parsed by the last call to {@code ParseSMTLIBString}
* or {@code ParseSMTLIBFile}.
**/
public BoolExpr[] getSMTLIBAssumptions()
{
int n = getNumSMTLIBAssumptions();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = (BoolExpr) Expr.create(this,
Native.getSmtlibAssumption(nCtx(), i));
return res;
}
/**
* The number of SMTLIB declarations parsed by the last call to
* {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}.
**/
public int getNumSMTLIBDecls()
{
return Native.getSmtlibNumDecls(nCtx());
}
/**
* The declarations parsed by the last call to
* {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}.
**/
public FuncDecl[] getSMTLIBDecls()
{
int n = getNumSMTLIBDecls();
FuncDecl[] res = new FuncDecl[n];
for (int i = 0; i < n; i++)
res[i] = new FuncDecl(this, Native.getSmtlibDecl(nCtx(), i));
return res;
}
/**
* The number of SMTLIB sorts parsed by the last call to
* {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}.
**/
public int getNumSMTLIBSorts()
{
return Native.getSmtlibNumSorts(nCtx());
}
/**
* The declarations parsed by the last call to
* {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}.
**/
public Sort[] getSMTLIBSorts()
{
int n = getNumSMTLIBSorts();
Sort[] res = new Sort[n];
for (int i = 0; i < n; i++)
res[i] = Sort.create(this, Native.getSmtlibSort(nCtx(), i));
return res;
}
/**
* Parse the given string using the SMT-LIB2 parser.
* @see #parseSMTLIBString
*
* @return A conjunction of assertions in the scope (up to push/pop) at the
* end of the string.

View file

@ -1,3 +1,4 @@
/**
Copyright (c) 2012-2014 Microsoft Corporation
@ -120,6 +121,23 @@ public class Solver extends Z3Object {
}
}
/**
* Load solver assertions from a file.
*/
public void fromFile(String file)
{
Native.solverFromFile(getContext().nCtx(), getNativeObject(), file);
}
/**
* Load solver assertions from a string.
*/
public void fromString(String str)
{
Native.solverFromString(getContext().nCtx(), getNativeObject(), str);
}
/**
* Assert multiple constraints into the solver, and track them (in the
* unsat) core

View file

@ -1975,56 +1975,6 @@ struct
(List.length assumptions) assumptions
formula
let parse_smtlib_string (ctx:context) (str:string) (sort_names:Symbol.symbol list) (sorts:Sort.sort list) (decl_names:Symbol.symbol list) (decls:func_decl list) =
let csn = List.length sort_names in
let cs = List.length sorts in
let cdn = List.length decl_names in
let cd = List.length decls in
if (csn <> cs || cdn <> cd) then
raise (Error "Argument size mismatch")
else
Z3native.parse_smtlib_string ctx str
cs sort_names sorts cd decl_names decls
let parse_smtlib_file (ctx:context) (file_name:string) (sort_names:Symbol.symbol list) (sorts:Sort.sort list) (decl_names:Symbol.symbol list) (decls:func_decl list) =
let csn = (List.length sort_names) in
let cs = (List.length sorts) in
let cdn = (List.length decl_names) in
let cd = (List.length decls) in
if (csn <> cs || cdn <> cd) then
raise (Error "Argument size mismatch")
else
Z3native.parse_smtlib_file ctx file_name
cs sort_names sorts cd decl_names decls
let get_num_smtlib_formulas (ctx:context) = Z3native.get_smtlib_num_formulas ctx
let get_smtlib_formulas (ctx:context) =
let n = get_num_smtlib_formulas ctx in
let f i = Z3native.get_smtlib_formula ctx i in
mk_list f n
let get_num_smtlib_assumptions (ctx:context) = Z3native.get_smtlib_num_assumptions ctx
let get_smtlib_assumptions (ctx:context) =
let n = get_num_smtlib_assumptions ctx in
let f i = Z3native.get_smtlib_assumption ctx i in
mk_list f n
let get_num_smtlib_decls (ctx:context) = Z3native.get_smtlib_num_decls ctx
let get_smtlib_decls (ctx:context) =
let n = get_num_smtlib_decls ctx in
let f i = Z3native.get_smtlib_decl ctx i in
mk_list f n
let get_num_smtlib_sorts (ctx:context) = Z3native.get_smtlib_num_sorts ctx
let get_smtlib_sorts (ctx:context) =
let n = get_num_smtlib_sorts ctx in
let f i = Z3native.get_smtlib_sort ctx i in
mk_list f n
let parse_smtlib2_string (ctx:context) (str:string) (sort_names:Symbol.symbol list) (sorts:Sort.sort list) (decl_names:Symbol.symbol list) (decls:func_decl list) =
let csn = List.length sort_names in
let cs = List.length sorts in

View file

@ -3441,43 +3441,6 @@ sig
@return A string representation of the benchmark. *)
val benchmark_to_smtstring : context -> string -> string -> string -> string -> Expr.expr list -> Expr.expr -> string
(** Parse the given string using the SMT-LIB parser.
The symbol table of the parser can be initialized using the given sorts and declarations.
The symbols in the arrays in the third and fifth argument
don't need to match the names of the sorts and declarations in the arrays in the fourth
and sixth argument. This is a useful feature since we can use arbitrary names to
reference sorts and declarations. *)
val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit
(** Parse the given file using the SMT-LIB parser.
{!parse_smtlib_string} *)
val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit
(** The number of SMTLIB formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *)
val get_num_smtlib_formulas : context -> int
(** The formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *)
val get_smtlib_formulas : context -> Expr.expr list
(** The number of SMTLIB assumptions parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *)
val get_num_smtlib_assumptions : context -> int
(** The assumptions parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *)
val get_smtlib_assumptions : context -> Expr.expr list
(** The number of SMTLIB declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *)
val get_num_smtlib_decls : context -> int
(** The declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *)
val get_smtlib_decls : context -> FuncDecl.func_decl list
(** The number of SMTLIB sorts parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *)
val get_num_smtlib_sorts : context -> int
(** The sort declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *)
val get_smtlib_sorts : context -> Sort.sort list
(** Parse the given string using the SMT-LIB2 parser.
{!parse_smtlib_string}

View file

@ -6324,6 +6324,20 @@ class Solver(Z3PPObject):
sz = len(consequences)
consequences = [ consequences[i] for i in range(sz) ]
return CheckSatResult(r), consequences
def from_file(self, filename):
"""Parse assertions from a file"""
try:
Z3_solver_from_file(self.ctx.ref(), self.solver, filename)
except Z3Exception as e:
_handle_parse_error(e, self.ctx)
def from_string(self, s):
"""Parse assertions from a string"""
try:
Z3_solver_from_string(self.ctx.ref(), self.solver, s)
except Z3Exception as e:
_handle_parse_error(e, self.ctx)
def proof(self):
"""Return a proof for the last `check()`. Proof construction must be enabled."""
@ -6668,11 +6682,17 @@ class Fixedpoint(Z3PPObject):
def parse_string(self, s):
"""Parse rules and queries from a string"""
return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
try:
return AstVector(Z3_fixedpoint_from_string(self.ctx.ref(), self.fixedpoint, s), self.ctx)
except Z3Exception as e:
_handle_parse_error(e, self.ctx)
def parse_file(self, f):
"""Parse rules and queries from a file"""
return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
try:
return AstVector(Z3_fixedpoint_from_file(self.ctx.ref(), self.fixedpoint, f), self.ctx)
except Z3Exception as e:
_handle_parse_error(e, self.ctx)
def get_rules(self):
"""retrieve rules that have been added to fixedpoint context"""
@ -6995,15 +7015,21 @@ class Optimize(Z3PPObject):
def upper_values(self, obj):
if not isinstance(obj, OptimizeObjective):
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
return obj.upper_values()
return obj.upper_values()
def from_file(self, filename):
"""Parse assertions and objectives from a file"""
Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
try:
Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
except Z3Exception as e:
_handle_parse_error(e, self.ctx)
def from_string(self, s):
"""Parse assertions and objectives from a string"""
Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
try:
Z3_optimize_from_string(self.ctx.ref(), self.optimize, s)
except Z3Exception as e:
_handle_parse_error(e, self.ctx)
def assertions(self):
"""Return an AST vector containing all added constraints."""
@ -8071,6 +8097,12 @@ def _dict2darray(decls, ctx):
i = i + 1
return sz, _names, _decls
def _handle_parse_error(ex, ctx):
msg = Z3_get_parser_error(ctx.ref())
if msg != "":
raise Z3Exception(msg)
raise ex
def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
"""Parse a string in SMT 2.0 format using the given sorts and decls.
@ -8089,7 +8121,10 @@ def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
ctx = _get_ctx(ctx)
ssz, snames, ssorts = _dict2sarray(sorts, ctx)
dsz, dnames, ddecls = _dict2darray(decls, ctx)
return _to_expr_ref(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
try:
return _to_expr_ref(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
except Z3Exception as e:
_handle_parse_error(e, ctx)
def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
"""Parse a file in SMT 2.0 format using the given sorts and decls.
@ -8099,7 +8134,10 @@ def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
ctx = _get_ctx(ctx)
ssz, snames, ssorts = _dict2sarray(sorts, ctx)
dsz, dnames, ddecls = _dict2darray(decls, ctx)
return _to_expr_ref(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
try:
return _to_expr_ref(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
except Z3Exception as e:
_handle_parse_error(e, ctx)
def Interpolant(a,ctx=None):
"""Create an interpolation operator.

View file

@ -1314,13 +1314,11 @@ typedef enum {
- Z3_PRINT_SMTLIB_FULL: Print AST nodes in SMTLIB verbose format.
- Z3_PRINT_LOW_LEVEL: Print AST nodes using a low-level format.
- Z3_PRINT_SMTLIB_COMPLIANT: Print AST nodes in SMTLIB 1.x compliant format.
- Z3_PRINT_SMTLIB2_COMPLIANT: Print AST nodes in SMTLIB 2.x compliant format.
*/
typedef enum {
Z3_PRINT_SMTLIB_FULL,
Z3_PRINT_LOW_LEVEL,
Z3_PRINT_SMTLIB_COMPLIANT,
Z3_PRINT_SMTLIB2_COMPLIANT
} Z3_ast_print_mode;
@ -4301,7 +4299,7 @@ extern "C" {
/**
\brief Return the i-th argument of the given application.
\pre i < Z3_get_num_args(c, a)
\pre i < Z3_get_app_num_args(c, a)
def_API('Z3_get_app_arg', AST, (_in(CONTEXT), _in(APP), _in(UINT)))
*/
@ -5116,7 +5114,7 @@ extern "C" {
To print shared common subexpressions only once,
use the Z3_PRINT_LOW_LEVEL mode.
To print in way that conforms to SMT-LIB standards and uses let
expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT.
expressions to share common sub-expressions use Z3_PRINT_SMTLIB2_COMPLIANT.
\sa Z3_ast_to_string
\sa Z3_pattern_to_string
@ -5228,115 +5226,13 @@ extern "C" {
Z3_symbol const decl_names[],
Z3_func_decl const decls[]);
/**
\brief Parse the given string using the SMT-LIB parser.
The symbol table of the parser can be initialized using the given sorts and declarations.
The symbols in the arrays \c sort_names and \c decl_names don't need to match the names
of the sorts and declarations in the arrays \c sorts and \c decls. This is an useful feature
since we can use arbitrary names to reference sorts and declarations defined using the C API.
The formulas, assumptions and declarations defined in \c str can be extracted using the functions:
#Z3_get_smtlib_num_formulas, #Z3_get_smtlib_formula, #Z3_get_smtlib_num_assumptions, #Z3_get_smtlib_assumption,
#Z3_get_smtlib_num_decls, and #Z3_get_smtlib_decl.
def_API('Z3_parse_smtlib_string', VOID, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL)))
*/
void Z3_API Z3_parse_smtlib_string(Z3_context c,
Z3_string str,
unsigned num_sorts,
Z3_symbol const sort_names[],
Z3_sort const sorts[],
unsigned num_decls,
Z3_symbol const decl_names[],
Z3_func_decl const decls[]
);
/**
\brief Similar to #Z3_parse_smtlib_string, but reads the benchmark from a file.
def_API('Z3_parse_smtlib_file', VOID, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL)))
*/
void Z3_API Z3_parse_smtlib_file(Z3_context c,
Z3_string file_name,
unsigned num_sorts,
Z3_symbol const sort_names[],
Z3_sort const sorts[],
unsigned num_decls,
Z3_symbol const decl_names[],
Z3_func_decl const decls[]
);
/**
\brief Return the number of SMTLIB formulas parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.
def_API('Z3_get_smtlib_num_formulas', UINT, (_in(CONTEXT), ))
*/
unsigned Z3_API Z3_get_smtlib_num_formulas(Z3_context c);
/**
\brief Return the i-th formula parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.
\pre i < Z3_get_smtlib_num_formulas(c)
def_API('Z3_get_smtlib_formula', AST, (_in(CONTEXT), _in(UINT)))
*/
Z3_ast Z3_API Z3_get_smtlib_formula(Z3_context c, unsigned i);
/**
\brief Return the number of SMTLIB assumptions parsed by #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.
def_API('Z3_get_smtlib_num_assumptions', UINT, (_in(CONTEXT), ))
*/
unsigned Z3_API Z3_get_smtlib_num_assumptions(Z3_context c);
/**
\brief Return the i-th assumption parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.
\pre i < Z3_get_smtlib_num_assumptions(c)
def_API('Z3_get_smtlib_assumption', AST, (_in(CONTEXT), _in(UINT)))
*/
Z3_ast Z3_API Z3_get_smtlib_assumption(Z3_context c, unsigned i);
/**
\brief Return the number of declarations parsed by #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.
def_API('Z3_get_smtlib_num_decls', UINT, (_in(CONTEXT), ))
*/
unsigned Z3_API Z3_get_smtlib_num_decls(Z3_context c);
/**
\brief Return the i-th declaration parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.
\pre i < Z3_get_smtlib_num_decls(c)
def_API('Z3_get_smtlib_decl', FUNC_DECL, (_in(CONTEXT), _in(UINT)))
*/
Z3_func_decl Z3_API Z3_get_smtlib_decl(Z3_context c, unsigned i);
/**
\brief Return the number of sorts parsed by #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.
def_API('Z3_get_smtlib_num_sorts', UINT, (_in(CONTEXT), ))
*/
unsigned Z3_API Z3_get_smtlib_num_sorts(Z3_context c);
/**
\brief Return the i-th sort parsed by the last call to #Z3_parse_smtlib_string or #Z3_parse_smtlib_file.
\pre i < Z3_get_smtlib_num_sorts(c)
def_API('Z3_get_smtlib_sort', SORT, (_in(CONTEXT), _in(UINT)))
*/
Z3_sort Z3_API Z3_get_smtlib_sort(Z3_context c, unsigned i);
/**
\brief Retrieve that last error message information generated from parsing.
def_API('Z3_get_smtlib_error', STRING, (_in(CONTEXT), ))
def_API('Z3_get_parser_error', STRING, (_in(CONTEXT), ))
*/
Z3_string Z3_API Z3_get_smtlib_error(Z3_context c);
Z3_string Z3_API Z3_get_parser_error(Z3_context c);
/*@}*/
/** @name Error Handling */
@ -6142,6 +6038,20 @@ extern "C" {
*/
Z3_ast_vector Z3_API Z3_solver_get_assertions(Z3_context c, Z3_solver s);
/**
\brief load solver assertions from a file.
def_API('Z3_solver_from_file', VOID, (_in(CONTEXT), _in(SOLVER), _in(STRING)))
*/
void Z3_API Z3_solver_from_file(Z3_context c, Z3_solver s, Z3_string file_name);
/**
\brief load solver assertions from a string.
def_API('Z3_solver_from_string', VOID, (_in(CONTEXT), _in(SOLVER), _in(STRING)))
*/
void Z3_API Z3_solver_from_string(Z3_context c, Z3_solver s, Z3_string file_name);
/**
\brief Check whether the assertions in a given solver are consistent or not.

View file

@ -1289,7 +1289,7 @@ decl_kind user_sort_plugin::register_name(symbol s) {
decl_plugin * user_sort_plugin::mk_fresh() {
user_sort_plugin * p = alloc(user_sort_plugin);
for (symbol const& s : m_sort_names)
for (symbol const& s : m_sort_names)
p->register_name(s);
return p;
}
@ -1415,7 +1415,7 @@ ast_manager::~ast_manager() {
p->finalize();
}
for (decl_plugin* p : m_plugins) {
if (p)
if (p)
dealloc(p);
}
m_plugins.reset();
@ -1454,13 +1454,13 @@ ast_manager::~ast_manager() {
mark_array_ref(mark, to_quantifier(n)->get_num_patterns(), to_quantifier(n)->get_patterns());
mark_array_ref(mark, to_quantifier(n)->get_num_no_patterns(), to_quantifier(n)->get_no_patterns());
break;
}
}
}
}
for (ast * n : m_ast_table) {
if (!mark.is_marked(n)) {
roots.push_back(n);
}
}
}
SASSERT(!roots.empty());
for (unsigned i = 0; i < roots.size(); ++i) {
ast* a = roots[i];
@ -1683,7 +1683,7 @@ ast * ast_manager::register_node_core(ast * n) {
bool contains = m_ast_table.contains(n);
CASSERT("nondet_bug", contains || slow_not_contains(n));
#endif
ast * r = m_ast_table.insert_if_not_there(n);
SASSERT(r->m_hash == h);
if (r != n) {
@ -2358,8 +2358,9 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort *
unsigned num_patterns, expr * const * patterns,
unsigned num_no_patterns, expr * const * no_patterns) {
SASSERT(body);
SASSERT(num_patterns == 0 || num_no_patterns == 0);
SASSERT(num_decls > 0);
if (num_patterns != 0 && num_no_patterns != 0)
throw ast_exception("simultaneous patterns and no-patterns not supported");
DEBUG_CODE({
for (unsigned i = 0; i < num_patterns; ++i) {
TRACE("ast", tout << i << " " << mk_pp(patterns[i], *this) << "\n";);
@ -2763,7 +2764,7 @@ proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs
}
proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs, expr * n1, expr * n2) {
if (num_proofs == 0)
if (num_proofs == 0)
return nullptr;
if (num_proofs == 1)
return proofs[0];

View file

@ -340,8 +340,7 @@ class smt_printer {
}
void pp_arg(expr *arg, app *parent)
{
void pp_arg(expr *arg, app *parent) {
pp_marked_expr(arg);
}
@ -417,7 +416,7 @@ class smt_printer {
else if (m_simplify_implies && m_manager.is_implies(decl) && m_manager.is_implies(n->get_arg(1))) {
expr *curr = n;
expr *arg;
m_out << "(implies (and";
m_out << "(=> (and";
while (m_manager.is_implies(curr)) {
arg = to_app(curr)->get_arg(0);
@ -476,9 +475,8 @@ class smt_printer {
}
}
void print_no_lets(expr *e)
{
smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, true, m_simplify_implies, true, m_indent, m_num_var_names, m_var_names);
void print_no_lets(expr *e) {
smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, true, m_simplify_implies, m_indent, m_num_var_names, m_var_names);
p(e);
}
@ -511,7 +509,7 @@ class smt_printer {
m_out << "(! ";
}
{
smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, false, true, m_simplify_implies, m_indent, m_num_var_names, m_var_names);
smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, false, m_simplify_implies, m_indent, m_num_var_names, m_var_names);
p(q->get_expr());
}
@ -704,7 +702,7 @@ class smt_printer {
public:
smt_printer(std::ostream& out, ast_manager& m, ptr_vector<quantifier>& ql, smt_renaming& rn,
symbol logic, bool no_lets, bool is_smt2, bool simplify_implies, unsigned indent, unsigned num_var_names = 0, char const* const* var_names = 0) :
symbol logic, bool no_lets, bool simplify_implies, unsigned indent, unsigned num_var_names = 0, char const* const* var_names = 0) :
m_out(out),
m_manager(m),
m_qlists(ql),
@ -894,25 +892,17 @@ ast_smt_pp::ast_smt_pp(ast_manager& m):
m_simplify_implies(true)
{}
void ast_smt_pp::display_expr(std::ostream& strm, expr* n) {
ptr_vector<quantifier> ql;
smt_renaming rn;
smt_printer p(strm, m_manager, ql, rn, m_logic, false, false, m_simplify_implies, 0);
p(n);
}
void ast_smt_pp::display_expr_smt2(std::ostream& strm, expr* n, unsigned indent, unsigned num_var_names, char const* const* var_names) {
ptr_vector<quantifier> 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);
smt_printer p(strm, m_manager, ql, rn, m_logic, false, m_simplify_implies, indent, num_var_names, var_names);
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<quantifier> 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);
smt_printer p(strm, m_manager, ql, rn, m_logic, false, m_simplify_implies, indent, num_var_names, var_names);
if (is_expr(a)) {
p(to_expr(a));
}
@ -1021,92 +1011,3 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) {
p(n);
}
}
void ast_smt_pp::display(std::ostream& strm, expr* n) {
ptr_vector<quantifier> ql;
decl_collector decls(m_manager);
smt_renaming rn;
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
decls.visit(m_assumptions[i].get());
}
for (unsigned i = 0; i < m_assumptions_star.size(); ++i) {
decls.visit(m_assumptions_star[i].get());
}
decls.visit(n);
strm << "(benchmark ";
if (m_benchmark_name != symbol::null) {
strm << m_benchmark_name << "\n";
}
else {
strm << "unnamed\n";
}
if (m_source_info != symbol::null && m_source_info != symbol("")) {
strm << ":source { " << m_source_info << " }\n";
}
strm << ":status " << m_status << "\n";
if (m_category != symbol::null && m_category != symbol("")) {
strm << ":category { " << m_category << " }\n";
}
if (m_logic != symbol::null && m_logic != symbol("")) {
strm << ":logic " << m_logic << "\n";
}
if (m_attributes.size() > 0) {
strm << m_attributes.c_str();
}
ast_mark sort_mark;
for (unsigned i = 0; i < decls.get_num_sorts(); ++i) {
sort* s = decls.get_sorts()[i];
if (!(*m_is_declared)(s)) {
smt_printer p(strm, m_manager, ql, rn, m_logic, true, false, m_simplify_implies, 0);
p.pp_sort_decl(sort_mark, s);
}
}
for (unsigned i = 0; i < decls.get_num_decls(); ++i) {
func_decl* d = decls.get_func_decls()[i];
if (!(*m_is_declared)(d)) {
strm << ":extrafuns (";
smt_printer p(strm, m_manager, ql, rn, m_logic, true, false, m_simplify_implies, 0);
p(d);
strm << ")\n";
}
}
for (unsigned i = 0; i < decls.get_num_preds(); ++i) {
func_decl* d = decls.get_pred_decls()[i];
if (!(*m_is_declared)(d)) {
strm << ":extrapreds (";
smt_printer p(strm, m_manager, ql, rn, m_logic, true, false, m_simplify_implies, 0);
p.visit_pred(d);
strm << ")\n";
}
}
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
expr * e = m_assumptions[i].get();
strm << ":assumption\n";
smt_printer p(strm, m_manager, ql, rn, m_logic, false, false, m_simplify_implies, 0);
p(e);
strm << "\n";
}
for (unsigned i = 0; i < m_assumptions_star.size(); ++i) {
strm << ":assumption-core\n";
smt_printer p(strm, m_manager, ql, rn, m_logic, false, false, m_simplify_implies, 0);
p(m_assumptions_star[i].get());
strm << "\n";
}
{
strm << ":formula\n";
smt_printer p(strm, m_manager, ql, rn, m_logic, false, false, m_simplify_implies, 0);
p(n);
strm << "\n";
}
strm << ")\n";
}

View file

@ -75,9 +75,7 @@ public:
void set_is_declared(is_declared* id) { m_is_declared = id; }
void display(std::ostream& strm, expr* n);
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);

View file

@ -1284,7 +1284,7 @@ void proof_checker::dump_proof(unsigned num_antecedents, expr * const * antecede
pp.add_assumption(antecedents[i]);
expr_ref n(m);
n = m.mk_not(consequent);
pp.display(out, n);
pp.display_smt2(out, n);
out.close();
m_proof_lemma_id++;
}

View file

@ -111,16 +111,6 @@ void static_features::flush_cache() {
m_expr2formula_depth.reset();
}
#if 0
bool static_features::is_non_linear(expr * e) const {
if (!is_arith_expr(e))
return false;
if (is_numeral(e))
return true;
if (m_autil.is_add(e))
return true; // the non
}
#endif
bool static_features::is_diff_term(expr const * e, rational & r) const {
// lhs can be 'x' or '(+ k x)'
@ -301,10 +291,12 @@ void static_features::update_core(expr * e) {
m_num_interpreted_constants++;
}
if (fid == m_afid) {
// std::cout << mk_pp(e, m_manager) << "\n";
switch (to_app(e)->get_decl_kind()) {
case OP_MUL:
if (!is_numeral(to_app(e)->get_arg(0)))
if (!is_numeral(to_app(e)->get_arg(0)) || to_app(e)->get_num_args() > 2) {
m_num_non_linear++;
}
break;
case OP_DIV:
case OP_IDIV:

View file

@ -339,6 +339,13 @@ void ast_object_ref::finalize(cmd_context & ctx) {
ctx.m().dec_ref(m_ast);
}
void stream_ref::set(std::ostream& out) {
reset();
m_owner = false;
m_name = "caller-owned";
m_stream = &out;
}
void stream_ref::set(char const * name) {
if (!name) {
throw cmd_exception("invalid stream name");

View file

@ -128,6 +128,7 @@ public:
stream_ref(std::string n, std::ostream & d):m_default_name(n), m_default(d), m_name(n), m_stream(&d), m_owner(false) {}
~stream_ref() { reset(); }
void set(char const * name);
void set(std::ostream& strm);
void reset();
std::ostream & operator*() { return *m_stream; }
char const * name() const { return m_name.c_str(); }
@ -404,6 +405,7 @@ public:
void reset_object_refs();
void reset_user_tactics();
void set_regular_stream(char const * name) { m_regular.set(name); }
void set_regular_stream(std::ostream& out) { m_regular.set(out); }
void set_diagnostic_stream(char const * name);
virtual std::ostream & regular_stream() { return *m_regular; }
virtual std::ostream & diagnostic_stream() { return *m_diagnostic; }

View file

@ -852,7 +852,7 @@ pdecl_manager::pdecl_manager(ast_manager & m):
pdecl_manager::~pdecl_manager() {
dec_ref(m_list);
reset_sort_info();
SASSERT(m_sort2psort.empty());
SASSERT(m_sort2psort.empty());
SASSERT(m_table.empty());
}

View file

@ -6,6 +6,7 @@ z3_add_component(opt
opt_cmds.cpp
opt_context.cpp
opt_pareto.cpp
opt_parse.cpp
optsmt.cpp
opt_solver.cpp
pb_sls.cpp

View file

@ -345,12 +345,24 @@ namespace opt {
fix_model(mdl);
}
bool context::contains_quantifiers() const {
for (expr* f : m_hard_constraints) {
if (has_quantifiers(f)) return true;
}
return false;
}
lbool context::execute_min_max(unsigned index, bool committed, bool scoped, bool is_max) {
if (scoped) get_solver().push();
lbool result = m_optsmt.lex(index, is_max);
if (result == l_true) m_optsmt.get_model(m_model, m_labels);
if (scoped) get_solver().pop(1);
if (result == l_true && committed) m_optsmt.commit_assignment(index);
if (result == l_true && m_optsmt.is_unbounded(index, is_max) && contains_quantifiers()) {
throw default_exception("unbounded objectives on quantified constraints is not supported");
result = l_undef;
}
return result;
}
@ -646,8 +658,7 @@ namespace opt {
expr_fast_mark1 visited;
is_bv proc(m);
try {
for (unsigned i = 0; i < m_objectives.size(); ++i) {
objective & obj = m_objectives[i];
for (objective& obj : m_objectives) {
if (obj.m_type != O_MAXSMT) return false;
maxsmt& ms = *m_maxsmts.find(obj.m_id);
for (unsigned j = 0; j < ms.size(); ++j) {
@ -658,8 +669,8 @@ namespace opt {
for (unsigned i = 0; i < sz; i++) {
quick_for_each_expr(proc, visited, get_solver().get_assertion(i));
}
for (unsigned i = 0; i < m_hard_constraints.size(); ++i) {
quick_for_each_expr(proc, visited, m_hard_constraints[i].get());
for (expr* f : m_hard_constraints) {
quick_for_each_expr(proc, visited, f);
}
}
catch (is_bv::found) {

View file

@ -233,13 +233,14 @@ namespace opt {
private:
lbool execute(objective const& obj, bool committed, bool scoped);
lbool execute_min_max(unsigned index, bool committed, bool scoped, bool is_max);
lbool execute_min_max(unsigned index, bool committed, bool scoped, bool is_max);
lbool execute_maxsat(symbol const& s, bool committed, bool scoped);
lbool execute_lex();
lbool execute_box();
lbool execute_pareto();
lbool adjust_unknown(lbool r);
bool scoped_lex();
bool contains_quantifiers() const;
expr_ref to_expr(inf_eps const& n);
void to_exprs(inf_eps const& n, expr_ref_vector& es);

317
src/opt/opt_parse.cpp Normal file
View file

@ -0,0 +1,317 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
opt_parse.cpp
Abstract:
Parse utilities for optimization.
Author:
Nikolaj Bjorner (nbjorner) 2017-11-19
Revision History:
--*/
#include "opt/opt_context.h"
#include "opt/opt_parse.h"
class opt_stream_buffer {
std::istream & m_stream;
int m_val;
unsigned m_line;
public:
opt_stream_buffer(std::istream & s):
m_stream(s),
m_line(0) {
m_val = m_stream.get();
}
int operator *() const { return m_val;}
void operator ++() { m_val = m_stream.get(); }
int ch() const { return m_val; }
void next() { m_val = m_stream.get(); }
bool eof() const { return ch() == EOF; }
unsigned line() const { return m_line; }
void skip_whitespace();
void skip_space();
void skip_line();
bool parse_token(char const* token);
int parse_int();
unsigned parse_unsigned();
};
void opt_stream_buffer::skip_whitespace() {
while ((ch() >= 9 && ch() <= 13) || ch() == 32) {
if (ch() == 10) ++m_line;
next();
}
}
void opt_stream_buffer::skip_space() {
while (ch() != 10 && ((ch() >= 9 && ch() <= 13) || ch() == 32)) {
next();
}
}
void opt_stream_buffer::skip_line() {
while(true) {
if (eof()) {
return;
}
if (ch() == '\n') {
++m_line;
next();
return;
}
next();
}
}
bool opt_stream_buffer::parse_token(char const* token) {
skip_whitespace();
char const* t = token;
while (ch() == *t) {
next();
++t;
}
return 0 == *t;
}
unsigned opt_stream_buffer::parse_unsigned() {
skip_space();
if (ch() == '\n') {
return UINT_MAX;
}
unsigned val = 0;
while (ch() >= '0' && ch() <= '9') {
val = val*10 + (ch() - '0');
next();
}
return val;
}
int opt_stream_buffer::parse_int() {
int val = 0;
bool neg = false;
skip_whitespace();
if (ch() == '-') {
neg = true;
next();
}
else if (ch() == '+') {
next();
}
if (ch() < '0' || ch() > '9') {
std::cerr << "(error line " << line() << " \"unexpected char: " << ((char)ch()) << "\" )\n";
exit(3);
}
while (ch() >= '0' && ch() <= '9') {
val = val*10 + (ch() - '0');
next();
}
return neg ? -val : val;
}
class wcnf {
opt::context& opt;
ast_manager& m;
opt_stream_buffer& in;
unsigned_vector& m_handles;
app_ref read_clause(unsigned& weight) {
int parsed_lit;
int var;
weight = in.parse_unsigned();
app_ref result(m), p(m);
expr_ref_vector ors(m);
while (true) {
parsed_lit = in.parse_int();
if (parsed_lit == 0)
break;
var = abs(parsed_lit);
p = m.mk_const(symbol(var), m.mk_bool_sort());
if (parsed_lit < 0) p = m.mk_not(p);
ors.push_back(p);
}
result = to_app(mk_or(m, ors.size(), ors.c_ptr()));
return result;
}
void parse_spec(unsigned& num_vars, unsigned& num_clauses, unsigned& max_weight) {
in.parse_token("wcnf");
num_vars = in.parse_unsigned();
num_clauses = in.parse_unsigned();
max_weight = in.parse_unsigned();
}
public:
wcnf(opt::context& opt, opt_stream_buffer& in, unsigned_vector& h): opt(opt), m(opt.get_manager()), in(in), m_handles(h) {
opt.set_clausal(true);
}
void parse() {
unsigned num_vars = 0, num_clauses = 0, max_weight = 0;
while (true) {
in.skip_whitespace();
if (in.eof()) {
break;
}
else if (*in == 'c') {
in.skip_line();
}
else if (*in == 'p') {
++in;
parse_spec(num_vars, num_clauses, max_weight);
}
else {
unsigned weight = 0;
app_ref cls = read_clause(weight);
if (weight >= max_weight) {
opt.add_hard_constraint(cls);
}
else {
unsigned id = opt.add_soft_constraint(cls, rational(weight), symbol::null);
if (m_handles.empty()) {
m_handles.push_back(id);
}
}
}
}
}
};
class opb {
opt::context& opt;
ast_manager& m;
opt_stream_buffer& in;
unsigned_vector& m_handles;
arith_util arith;
app_ref parse_id() {
bool negated = in.parse_token("~");
if (!in.parse_token("x")) {
std::cerr << "(error line " << in.line() << " \"unexpected char: " << ((char)in.ch()) << "\" expected \"x\")\n";
exit(3);
}
app_ref p(m);
int id = in.parse_int();
p = m.mk_const(symbol(id), m.mk_bool_sort());
if (negated) p = m.mk_not(p);
in.skip_whitespace();
return p;
}
app_ref parse_ids() {
app_ref result = parse_id();
while (*in == '~' || *in == 'x') {
result = m.mk_and(result, parse_id());
}
return result;
}
rational parse_coeff_r() {
in.skip_whitespace();
svector<char> num;
bool pos = true;
if (*in == '-') pos = false, ++in;
if (*in == '+') ++in;
if (!pos) num.push_back('-');
in.skip_whitespace();
while ('0' <= *in && *in <='9') num.push_back(*in), ++in;
num.push_back(0);
return rational(num.c_ptr());
}
app_ref parse_coeff() {
return app_ref(arith.mk_numeral(parse_coeff_r(), true), m);
}
app_ref parse_term() {
app_ref c = parse_coeff();
app_ref e = parse_ids();
return app_ref(m.mk_ite(e, c, arith.mk_numeral(rational(0), true)), m);
}
void parse_objective(bool is_min) {
app_ref t = parse_term();
while (!in.parse_token(";") && !in.eof()) {
if (is_min) {
t = arith.mk_add(t, parse_term());
}
else {
t = arith.mk_sub(t, parse_term());
}
}
m_handles.push_back(opt.add_objective(t, false));
}
void parse_constraint() {
app_ref t = parse_term();
while (!in.eof()) {
if (in.parse_token(">=")) {
t = arith.mk_ge(t, parse_coeff());
in.parse_token(";");
break;
}
if (in.parse_token("=")) {
t = m.mk_eq(t, parse_coeff());
in.parse_token(";");
break;
}
if (in.parse_token("<=")) {
t = arith.mk_le(t, parse_coeff());
in.parse_token(";");
break;
}
t = arith.mk_add(t, parse_term());
}
opt.add_hard_constraint(t);
}
public:
opb(opt::context& opt, opt_stream_buffer& in, unsigned_vector& h):
opt(opt), m(opt.get_manager()),
in(in), m_handles(h), arith(m) {}
void parse() {
while (true) {
in.skip_whitespace();
if (in.eof()) {
break;
}
else if (*in == '*') {
in.skip_line();
}
else if (in.parse_token("min:")) {
parse_objective(true);
}
else if (in.parse_token("max:")) {
parse_objective(false);
}
else {
parse_constraint();
}
}
}
};
void parse_wcnf(opt::context& opt, std::istream& is, unsigned_vector& h) {
opt_stream_buffer _is(is);
wcnf w(opt, _is, h);
w.parse();
}
void parse_opb(opt::context& opt, std::istream& is, unsigned_vector& h) {
opt_stream_buffer _is(is);
opb opb(opt, _is, h);
opb.parse();
}

28
src/opt/opt_parse.h Normal file
View file

@ -0,0 +1,28 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
opt_parse.h
Abstract:
Parse utilities for optimization.
Author:
Nikolaj Bjorner (nbjorner) 2017-11-19
Revision History:
--*/
#ifndef OPT_PARSE_H_
#define OPT_PARSE_H_
void parse_wcnf(opt::context& opt, std::istream& is, unsigned_vector& h);
void parse_opb(opt::context& opt, std::istream& is, unsigned_vector& h);
#endif /* OPT_PARSE_H_ */

View file

@ -161,6 +161,14 @@ namespace opt {
return l_true;
}
bool optsmt::is_unbounded(unsigned obj_index, bool is_maximize) {
if (is_maximize) {
return !m_upper[obj_index].is_finite();
}
else {
return !m_lower[obj_index].is_finite();
}
}
lbool optsmt::geometric_lex(unsigned obj_index, bool is_maximize) {
arith_util arith(m);

View file

@ -49,6 +49,8 @@ namespace opt {
lbool lex(unsigned obj_index, bool is_maximize);
bool is_unbounded(unsigned obj_index, bool is_maximize);
unsigned add(app* t);
void updt_params(params_ref& p);

View file

@ -1,8 +0,0 @@
z3_add_component(smtparser
SOURCES
smtlib.cpp
smtlib_solver.cpp
smtparser.cpp
COMPONENT_DEPENDENCIES
portfolio
)

View file

@ -1,258 +0,0 @@
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#include "parsers/smt/smtlib.h"
#include "ast/ast_pp.h"
#include "ast/ast_smt2_pp.h"
#ifdef _WINDOWS
#ifdef ARRAYSIZE
#undef ARRAYSIZE
#endif
#include <windows.h>
#include <strsafe.h>
#endif
#include <iostream>
using namespace smtlib;
// --------------------------------------------------------------------------
// symtable
symtable::~symtable() {
reset();
}
void symtable::reset() {
svector<ptr_vector<func_decl>*> range;
m_ids.get_range(range);
for (unsigned i = 0; i < range.size(); ++i) {
ptr_vector<func_decl> const & v = *range[i];
for (unsigned j = 0; j < v.size(); ++j) {
m_manager.dec_ref(v[j]);
}
dealloc(range[i]);
}
m_ids.reset();
ptr_vector<sort> sorts;
m_sorts1.get_range(sorts);
for (unsigned i = 0; i < sorts.size(); ++i) {
m_manager.dec_ref(sorts[i]);
}
m_sorts1.reset();
ptr_vector<sort_builder> sort_builders;
m_sorts.get_range(sort_builders);
for (unsigned i = 0; i < sort_builders.size(); ++i) {
dealloc(sort_builders[i]);
}
m_sorts.reset();
}
void symtable::insert(symbol s, func_decl * d) {
ptr_vector<func_decl>* decls = 0;
m_manager.inc_ref(d);
if (!m_ids.find(s, decls)) {
SASSERT(!decls);
decls = alloc(ptr_vector<func_decl>);
decls->push_back(d);
m_ids.insert(s, decls);
}
else {
SASSERT(decls);
if ((*decls)[0] != d) {
decls->push_back(d);
}
else {
m_manager.dec_ref(d);
}
}
}
bool symtable::find1(symbol s, func_decl*& d) {
ptr_vector<func_decl>* decls = 0;
if (!m_ids.find(s, decls)) {
SASSERT(!decls);
return false;
}
SASSERT(decls && !decls->empty());
d = (*decls)[0];
return true;
}
bool symtable::find_overload(symbol s, ptr_vector<sort> const & dom, func_decl * & d) {
ptr_vector<func_decl>* decls = 0;
d = 0;
if (!m_ids.find(s, decls)) {
SASSERT(!decls);
return false;
}
SASSERT(decls);
for (unsigned i = 0; i < decls->size(); ++i) {
func_decl* decl = (*decls)[i];
if (decl->is_associative() && decl->get_arity() > 0) {
for (unsigned j = 0; j < dom.size(); ++j) {
if (dom[j] != decl->get_domain(0)) {
goto try_next;
}
}
d = decl;
return true;
}
if (decl->get_arity() != dom.size()) {
goto try_next;
}
for (unsigned j = 0; j < decl->get_arity(); ++j) {
if (decl->get_domain(j) != dom[j]) {
goto try_next;
}
}
d = decl;
return true;
try_next:
if (decl->get_family_id() == m_manager.get_basic_family_id() && decl->get_decl_kind() == OP_DISTINCT) {
// we skip type checking for 'distinct'
d = decl;
return true;
}
}
return false;
}
// Store in result the func_decl that are not attached to any family id.
// That is, the uninterpreted constants and function declarations.
void symtable::get_func_decls(ptr_vector<func_decl> & result) const {
svector<ptr_vector<func_decl>*> tmp;
m_ids.get_range(tmp);
svector<ptr_vector<func_decl>*>::const_iterator it = tmp.begin();
svector<ptr_vector<func_decl>*>::const_iterator end = tmp.end();
for (; it != end; ++it) {
ptr_vector<func_decl> * curr = *it;
if (curr) {
ptr_vector<func_decl>::const_iterator it2 = curr->begin();
ptr_vector<func_decl>::const_iterator end2 = curr->end();
for (; it2 != end2; ++it2) {
func_decl * d = *it2;
if (d && d->get_family_id() == null_family_id) {
result.push_back(d);
}
}
}
}
}
void symtable::insert(symbol s, sort_builder* sb) {
m_sorts.insert(s, sb);
}
bool symtable::lookup(symbol s, sort_builder*& sb) {
return m_sorts.find(s, sb);
}
void symtable::push_sort(symbol name, sort* srt) {
m_sorts.begin_scope();
sort_builder* sb = alloc(basic_sort_builder,srt);
m_sorts.insert(name, sb);
m_sorts_trail.push_back(sb);
}
void symtable::pop_sorts(unsigned num_sorts) {
while (num_sorts > 0) {
dealloc(m_sorts_trail.back());
m_sorts_trail.pop_back();
m_sorts.end_scope();
}
}
void symtable::get_sorts(ptr_vector<sort>& result) const {
vector<sort*,false> tmp;
m_sorts1.get_range(tmp);
for (unsigned i = 0; i < tmp.size(); ++i) {
if (tmp[i]->get_family_id() == null_family_id) {
result.push_back(tmp[i]);
}
}
}
// --------------------------------------------------------------------------
// theory
func_decl * theory::declare_func(symbol const & id, sort_ref_buffer & domain, sort * range,
bool is_assoc, bool is_comm, bool is_inj) {
func_decl * decl = m_ast_manager.mk_func_decl(id, domain.size(), domain.c_ptr(), range,
is_assoc, is_comm, is_inj);
m_symtable.insert(id, decl);
m_asts.push_back(decl);
return decl;
}
sort * theory::declare_sort(symbol const & id) {
sort * decl = m_ast_manager.mk_uninterpreted_sort(id);
m_symtable.insert(id, decl);
m_asts.push_back(decl);
return decl;
}
bool theory::get_func_decl(symbol id, func_decl * & decl) {
return m_symtable.find1(id, decl);
}
bool theory::get_sort(symbol id, sort* & s) {
return m_symtable.find(id, s);
}
bool theory::get_const(symbol id, expr * & term) {
func_decl* decl = 0;
if (!get_func_decl(id,decl)) {
return false;
}
if (decl->get_arity() != 0) {
return false;
}
term = m_ast_manager.mk_const(decl);
m_asts.push_back(term);
return true;
}
void benchmark::display_as_smt2(std::ostream & out) const {
if (m_logic != symbol::null)
out << "(set-logic " << m_logic << ")\n";
out << "(set-info :smt-lib-version 2.0)\n";
out << "(set-info :status ";
switch (m_status) {
case SAT: out << "sat"; break;
case UNSAT: out << "unsat"; break;
default: out << "unknown"; break;
}
out << ")\n";
#if 0
ast_manager & m = m_ast_manager;
ptr_vector<func_decl> decls;
m_symtable.get_func_decls(decls);
ptr_vector<func_decl>::const_iterator it = decls.begin();
ptr_vector<func_decl>::const_iterator end = decls.end();
for (; it != end; ++it) {
func_decl * f = *it;
out << "(declare-fun " << f->get_name() << " (";
for (unsigned i = 0; i < f->get_arity(); i++) {
if (i > 0) out << " ";
out << mk_ismt2_pp(f->get_domain(i), m);
}
out << ") " << mk_ismt2_pp(f->get_range(), m);
out << ")\n";
}
#endif
}

View file

@ -1,232 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smtlib.h
Abstract:
SMT library utilities
Author:
Nikolaj Bjorner (nbjorner) 2006-09-29
Revision History:
--*/
#ifndef SMTLIB_H_
#define SMTLIB_H_
#include "ast/ast.h"
#include "util/symbol_table.h"
#include "util/map.h"
#include "ast/arith_decl_plugin.h"
namespace smtlib {
class sort_builder {
public:
virtual ~sort_builder() {}
virtual bool apply(unsigned num_params, parameter const* params, sort_ref& result) = 0;
virtual char const* error_message() { return ""; }
};
class basic_sort_builder : public sort_builder {
sort* m_sort;
public:
basic_sort_builder(sort* s) : m_sort(s) {}
virtual bool apply(unsigned np, parameter const*, sort_ref& result) {
result = m_sort;
return m_sort && np != 0;
}
};
class symtable {
ast_manager& m_manager;
symbol_table<sort*> m_sorts1;
symbol_table<sort_builder*> m_sorts;
ptr_vector<sort_builder> m_sorts_trail;
symbol_table<ptr_vector<func_decl>* > m_ids;
public:
symtable(ast_manager& m): m_manager(m) {}
~symtable();
void reset();
void insert(symbol s, func_decl * d);
bool find(symbol s, ptr_vector<func_decl> * & decls) {
return m_ids.find(s, decls);
}
bool find1(symbol s, func_decl * & d);
bool find_overload(symbol s, ptr_vector<sort> const & dom, func_decl * & d);
void insert(symbol s, sort * d) {
sort * d2;
if (m_sorts1.find(s, d2)) {
m_manager.dec_ref(d2);
}
m_manager.inc_ref(d);
m_sorts1.insert(s, d);
}
bool find(symbol s, sort * & d) {
return m_sorts1.find(s, d);
}
void insert(symbol s, sort_builder* sb);
bool lookup(symbol s, sort_builder*& sb);
void push_sort(symbol s, sort*);
void pop_sorts(unsigned num_sorts);
void get_func_decls(ptr_vector<func_decl> & result) const;
void get_sorts(ptr_vector<sort>& result) const;
};
class theory {
public:
typedef ptr_vector<expr>::const_iterator expr_iterator;
theory(ast_manager & ast_manager, symbol const& name):
m_name(name),
m_ast_manager(ast_manager),
m_symtable(ast_manager),
m_asts(ast_manager)
{}
virtual ~theory() {}
symtable * get_symtable() { return &m_symtable; }
void insert(sort * s) { m_symtable.insert(s->get_name(), s); }
void insert(func_decl * c) { m_symtable.insert(c->get_name(), c); }
func_decl * declare_func(symbol const & id, sort_ref_buffer & domain, sort * range,
bool is_assoc, bool is_comm, bool is_inj);
sort * declare_sort(symbol const & id);
void add_axiom(expr * axiom) {
m_asts.push_back(axiom);
m_axioms.push_back(axiom);
}
expr_iterator begin_axioms() const {
return m_axioms.begin();
}
unsigned get_num_axioms() const {
return m_axioms.size();
}
expr * const * get_axioms() const {
return m_axioms.c_ptr();
}
expr_iterator end_axioms() const {
return m_axioms.end();
}
void add_assumption(expr * axiom) {
m_asts.push_back(axiom);
m_assumptions.push_back(axiom);
}
unsigned get_num_assumptions() const {
return m_assumptions.size();
}
expr * const * get_assumptions() const {
return m_assumptions.c_ptr();
}
bool get_func_decl(symbol, func_decl*&);
bool get_sort(symbol, sort*&);
bool get_const(symbol, expr*&);
void set_name(symbol const& name) { m_name = name; }
symbol const get_name() const { return m_name; }
protected:
symbol m_name;
ast_manager& m_ast_manager;
ptr_vector<expr> m_axioms;
ptr_vector<expr> m_assumptions;
symtable m_symtable;
ast_ref_vector m_asts;
private:
theory& operator=(theory const&);
theory(theory const&);
};
class benchmark : public theory {
public:
enum status {
UNKNOWN,
SAT,
UNSAT
};
benchmark(ast_manager & ast_manager, symbol const & name) :
theory(ast_manager, name),
m_status(UNKNOWN) {}
virtual ~benchmark() {}
status get_status() const { return m_status; }
void set_status(status status) { m_status = status; }
symbol get_logic() const {
if (m_logic == symbol::null) {
return symbol("ALL");
}
return m_logic;
}
void set_logic(symbol const & s) { m_logic = s; }
unsigned get_num_formulas() const {
return m_formulas.size();
}
expr_iterator begin_formulas() const {
return m_formulas.begin();
}
expr_iterator end_formulas() const {
return m_formulas.end();
}
void add_formula(expr * formula) {
m_asts.push_back(formula);
m_formulas.push_back(formula);
}
void display_as_smt2(std::ostream & out) const;
private:
status m_status;
symbol m_logic;
ptr_vector<expr> m_formulas;
};
};
#endif

View file

@ -1,119 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smtlib_solver.cpp
Abstract:
SMT based solver.
Author:
Nikolaj Bjorner (nbjorner) 2006-11-3.
Revision History:
--*/
#include "parsers/smt/smtparser.h"
#include "parsers/smt/smtlib_solver.h"
#include "util/warning.h"
#include "ast/ast_pp.h"
#include "ast/ast_ll_pp.h"
#include "ast/well_sorted.h"
#include "model/model.h"
#include "model/model_v2_pp.h"
#include "solver/solver.h"
#include "tactic/portfolio/smt_strategic_solver.h"
#include "cmd_context/cmd_context.h"
#include "model/model_params.hpp"
#include "parsers/util/parser_params.hpp"
namespace smtlib {
solver::solver():
m_ast_manager(m_params.m_proof ? PGM_ENABLED : PGM_DISABLED,
m_params.m_trace ? m_params.m_trace_file_name.c_str() : 0),
m_ctx(0),
m_error_code(0) {
parser_params ps;
m_parser = parser::create(m_ast_manager, ps.ignore_user_patterns());
m_parser->initialize_smtlib();
}
solver::~solver() {
if (m_ctx)
dealloc(m_ctx);
}
bool solver::solve_smt(char const * benchmark_file) {
IF_VERBOSE(100, verbose_stream() << "parsing...\n";);
if (!m_parser->parse_file(benchmark_file)) {
if (benchmark_file) {
warning_msg("could not parse file '%s'.", benchmark_file);
}
else {
warning_msg("could not parse input stream.");
}
m_error_code = ERR_PARSER;
return false;
}
benchmark * benchmark = m_parser->get_benchmark();
solve_benchmark(*benchmark);
return true;
}
bool solver::solve_smt_string(char const * benchmark_string) {
if (!m_parser->parse_string(benchmark_string)) {
warning_msg("could not parse string '%s'.", benchmark_string);
return false;
}
benchmark * benchmark = m_parser->get_benchmark();
solve_benchmark(*benchmark);
return true;
}
void solver::display_statistics() {
if (m_ctx)
m_ctx->display_statistics();
}
void solver::solve_benchmark(benchmark & benchmark) {
if (benchmark.get_num_formulas() == 0) {
// Hack: it seems SMT-LIB allow benchmarks without any :formula
benchmark.add_formula(m_ast_manager.mk_true());
}
m_ctx = alloc(cmd_context, true, &m_ast_manager, benchmark.get_logic());
m_ctx->set_solver_factory(mk_smt_strategic_solver_factory());
theory::expr_iterator fit = benchmark.begin_formulas();
theory::expr_iterator fend = benchmark.end_formulas();
for (; fit != fend; ++fit)
solve_formula(benchmark, *fit);
}
void solver::solve_formula(benchmark const & benchmark, expr * f) {
IF_VERBOSE(100, verbose_stream() << "starting...\n";);
m_ctx->reset();
for (unsigned i = 0; i < benchmark.get_num_axioms(); i++)
m_ctx->assert_expr(benchmark.get_axioms()[i]);
m_ctx->assert_expr(f);
m_ctx->check_sat(benchmark.get_num_assumptions(), benchmark.get_assumptions());
check_sat_result * r = m_ctx->get_check_sat_result();
if (r != 0) {
proof * pr = r->get_proof();
if (pr != 0 && m_params.m_proof)
std::cout << mk_ll_pp(pr, m_ast_manager, false, false);
model_ref md;
if (r->status() != l_false) r->get_model(md);
if (md.get() != 0 && m_params.m_model) {
model_params p;
model_v2_pp(std::cout, *(md.get()), p.partial());
}
}
else {
m_error_code = ERR_UNKNOWN_RESULT;
}
}
};

View file

@ -1,48 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smtlib_solver.h
Abstract:
SMT based solver.
Author:
Nikolaj Bjorner (nbjorner) 2006-11-3.
Revision History:
--*/
#ifndef SMTLIB_SOLVER_H_
#define SMTLIB_SOLVER_H_
#include "parsers/smt/smtparser.h"
#include "cmd_context/context_params.h"
#include "util/lbool.h"
class cmd_context;
namespace smtlib {
class solver {
context_params m_params;
ast_manager m_ast_manager;
cmd_context * m_ctx;
scoped_ptr<parser> m_parser;
unsigned m_error_code;
public:
solver();
~solver();
bool solve_smt(char const * benchmark_file);
bool solve_smt_string(char const * benchmark_string);
void display_statistics();
unsigned get_error_code() const { return m_error_code; }
private:
void solve_benchmark(benchmark & benchmark);
void solve_formula(benchmark const & benchmark, expr * f);
};
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,48 +0,0 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smtparser.h
Abstract:
SMT parsing utilities
Author:
Nikolaj Bjorner (nbjorner) 2006-09-25
Revision History:
--*/
#ifndef SMT_PARSER_H_
#define SMT_PARSER_H_
#include<iostream>
#include "ast/ast.h"
#include "util/vector.h"
#include "parsers/smt/smtlib.h"
namespace smtlib {
class parser {
public:
static parser * create(ast_manager & ast_manager, bool ignore_user_patterns = false);
virtual ~parser() {}
virtual void add_builtin_op(char const *, family_id fid, decl_kind kind) = 0;
virtual void add_builtin_type(char const *, family_id fid, decl_kind kind) = 0;
virtual void initialize_smtlib() = 0;
virtual void set_error_stream(std::ostream& strm) = 0;
virtual bool parse_file(char const * path) = 0;
virtual bool parse_string(char const * string) = 0;
virtual benchmark * get_benchmark() = 0;
};
};
#endif

View file

@ -867,7 +867,7 @@ namespace smt2 {
throw parser_exception("invalid datatype declaration, too many data-type bodies defined");
}
symbol dt_name = m_dt_names[i];
parse_datatype_dec(new_ct_decls);
parse_datatype_dec(nullptr, new_ct_decls);
d = pm().mk_pdatatype_decl(m_dt_name2arity.find(dt_name), dt_name, new_ct_decls.size(), new_ct_decls.c_ptr());
}
else {
@ -942,7 +942,7 @@ namespace smt2 {
pdatatype_decl_ref d(pm());
pconstructor_decl_ref_buffer new_ct_decls(pm());
parse_datatype_dec(new_ct_decls);
parse_datatype_dec(&dt_name, new_ct_decls);
d = pm().mk_pdatatype_decl(m_sort_id2param_idx.size(), dt_name, new_ct_decls.size(), new_ct_decls.c_ptr());
check_missing(d, line, pos);
@ -956,12 +956,16 @@ namespace smt2 {
// datatype_dec ::= ( constructor_dec+ ) | ( par ( symbol+ ) ( constructor_dec+ ) )
void parse_datatype_dec(pconstructor_decl_ref_buffer & ct_decls) {
void parse_datatype_dec(symbol* dt_name, pconstructor_decl_ref_buffer & ct_decls) {
check_lparen_next("invalid datatype declaration, '(' expected");
if (curr_id() == m_par) {
next();
parse_sort_decl_params();
check_lparen_next("invalid constructor declaration after par, '(' expected");
unsigned sz = m_sort_id2param_idx.size();
if (sz > 0 && dt_name) {
m_ctx.insert(pm().mk_psort_dt_decl(sz, *dt_name));
}
parse_constructor_decls(ct_decls);
check_rparen_next("invalid datatype declaration, ')' expected");
}

View file

@ -886,174 +886,6 @@ namespace qe {
tactic * translate(ast_manager & m) {
return alloc(nlqsat, m, m_mode, m_params);
}
#if 0
/**
Algorithm:
I := true
while there is M, such that M |= ~B & I:
find P, such that M => P => exists y . ~B & I
; forall y B => ~P
C := core of P with respect to A
; A => ~ C => ~ P
I := I & ~C
Alternative Algorithm:
R := false
while there is M, such that M |= A & ~R:
find I, such that M => I => forall y . B
R := R | I
*/
lbool interpolate(expr* a, expr* b, expr_ref& result) {
SASSERT(m_mode == interp_t);
reset();
app_ref enableA(m), enableB(m);
expr_ref A(m), B(m), fml(m);
expr_ref_vector fmls(m), answer(m);
// varsB are private to B.
nlsat::var_vector vars;
uint_set fvars;
private_vars(a, b, vars, fvars);
enableA = m.mk_const(symbol("#A"), m.mk_bool_sort());
enableB = m.mk_not(enableA);
A = m.mk_implies(enableA, a);
B = m.mk_implies(enableB, m.mk_not(b));
fml = m.mk_and(A, B);
hoist(fml);
nlsat::literal _enableB = nlsat::literal(m_a2b.to_var(enableB), false);
nlsat::literal _enableA = ~_enableB;
while (true) {
m_mode = qsat_t;
// enable B
m_assumptions.reset();
m_assumptions.push_back(_enableB);
lbool is_sat = check_sat();
switch (is_sat) {
case l_undef:
return l_undef;
case l_true:
break;
case l_false:
result = mk_and(answer);
return l_true;
}
// disable B, enable A
m_assumptions.reset();
m_assumptions.push_back(_enableA);
// add blocking clause to solver.
nlsat::scoped_literal_vector core(m_solver);
m_mode = elim_t;
mbp(vars, fvars, core);
// minimize core.
nlsat::literal_vector _core(core.size(), core.c_ptr());
_core.push_back(_enableA);
is_sat = m_solver.check(_core); // TBD: only for quantifier-free A. Generalize output of elim_t to be a core.
switch (is_sat) {
case l_undef:
return l_undef;
case l_true:
UNREACHABLE();
case l_false:
core.reset();
core.append(_core.size(), _core.c_ptr());
break;
}
negate_clause(core);
// keep polarity of enableA, such that clause is only
// used when checking satisfiability of B.
for (unsigned i = 0; i < core.size(); ++i) {
if (core[i].var() == _enableA.var()) core.set(i, ~core[i]);
}
add_clause(core); // Invariant is added as assumption for B.
answer.push_back(clause2fml(core)); // TBD: remove answer literal.
}
}
/**
\brief extract variables that are private to a (not used in b).
vars cover the real variables, and fvars cover the Boolean variables.
TBD: We want fvars to be the complement such that returned core contains
Shared boolean variables, but not the ones private to B.
*/
void private_vars(expr* a, expr* b, nlsat::var_vector& vars, uint_set& fvars) {
app_ref_vector varsA(m), varsB(m);
obj_hashtable<expr> varsAS;
pred_abs abs(m);
abs.get_free_vars(a, varsA);
abs.get_free_vars(b, varsB);
insert_set(varsAS, varsA);
for (unsigned i = 0; i < varsB.size(); ++i) {
if (varsAS.contains(varsB[i].get())) {
varsB[i] = varsB.back();
varsB.pop_back();
--i;
}
}
for (unsigned j = 0; j < varsB.size(); ++j) {
app* v = varsB[j].get();
if (m_a2b.is_var(v)) {
fvars.insert(m_a2b.to_var(v));
}
else if (m_t2x.is_var(v)) {
vars.push_back(m_t2x.to_var(v));
}
}
}
lbool maximize(app* _x, expr* _fml, scoped_anum& result, bool& unbounded) {
expr_ref fml(_fml, m);
reset();
hoist(fml);
nlsat::literal_vector lits;
lbool is_sat = l_true;
nlsat::var x = m_t2x.to_var(_x);
m_mode = qsat_t;
while (is_sat == l_true) {
is_sat = check_sat();
if (is_sat == l_true) {
// m_asms is minimized set of literals that satisfy formula.
nlsat::explain& ex = m_solver.get_explain();
polynomial::manager& pm = m_solver.pm();
anum_manager& am = m_solver.am();
ex.maximize(x, m_asms.size(), m_asms.c_ptr(), result, unbounded);
if (unbounded) {
break;
}
// TBD: assert the new bound on x using the result.
bool is_even = false;
polynomial::polynomial_ref pr(pm);
pr = pm.mk_polynomial(x);
rational r;
am.get_upper(result, r);
// result is algebraic numeral, but polynomials are not defined over extension field.
polynomial::polynomial* p = pr;
nlsat::bool_var b = m_solver.mk_ineq_atom(nlsat::atom::GT, 1, &p, &is_even);
nlsat::literal bound(b, false);
m_solver.mk_clause(1, &bound);
}
}
return is_sat;
}
#endif
};
};

View file

@ -35,9 +35,10 @@ Revision History:
#include "util/error_codes.h"
#include "util/gparams.h"
#include "util/env_params.h"
#include "util/file_path.h"
#include "shell/lp_frontend.h"
typedef enum { IN_UNSPECIFIED, IN_SMTLIB, IN_SMTLIB_2, IN_DATALOG, IN_DIMACS, IN_WCNF, IN_OPB, IN_Z3_LOG, IN_MPS } input_kind;
typedef enum { IN_UNSPECIFIED, IN_SMTLIB_2, IN_DATALOG, IN_DIMACS, IN_WCNF, IN_OPB, IN_Z3_LOG, IN_MPS } input_kind;
std::string g_aux_input_file;
char const * g_input_file = 0;
@ -169,9 +170,6 @@ void parse_cmd_line_args(int argc, char ** argv) {
std::cout << "\n";
exit(0);
}
else if (strcmp(opt_name, "smt") == 0) {
g_input_kind = IN_SMTLIB;
}
else if (strcmp(opt_name, "smt2") == 0) {
g_input_kind = IN_SMTLIB_2;
}
@ -289,19 +287,6 @@ void parse_cmd_line_args(int argc, char ** argv) {
}
}
char const * get_extension(char const * file_name) {
if (file_name == 0)
return 0;
char const * last_dot = 0;
for (;;) {
char const * tmp = strchr(file_name, '.');
if (tmp == 0) {
return last_dot;
}
last_dot = tmp + 1;
file_name = last_dot;
}
}
int STD_CALL main(int argc, char ** argv) {
try{
@ -340,9 +325,6 @@ int STD_CALL main(int argc, char ** argv) {
else if (strcmp(ext, "smt2") == 0) {
g_input_kind = IN_SMTLIB_2;
}
else if (strcmp(ext, "smt") == 0) {
g_input_kind = IN_SMTLIB;
}
else if (strcmp(ext, "mps") == 0 || strcmp(ext, "sif") == 0 ||
strcmp(ext, "MPS") == 0 || strcmp(ext, "SIF") == 0) {
g_input_kind = IN_MPS;
@ -350,9 +332,6 @@ int STD_CALL main(int argc, char ** argv) {
}
}
switch (g_input_kind) {
case IN_SMTLIB:
return_value = read_smtlib_file(g_input_file);
break;
case IN_SMTLIB_2:
memory::exit_when_out_of_memory(true, "(error \"out of memory\")");
return_value = read_smtlib2_commands(g_input_file);

View file

@ -13,6 +13,7 @@ Copyright (c) 2015 Microsoft Corporation
#include "util/gparams.h"
#include "util/timeout.h"
#include "ast/reg_decl_plugins.h"
#include "opt/opt_parse.h"
extern bool g_display_statistics;
static bool g_first_interrupt = true;
@ -20,262 +21,6 @@ static opt::context* g_opt = 0;
static double g_start_time = 0;
static unsigned_vector g_handles;
class opt_stream_buffer {
std::istream & m_stream;
int m_val;
unsigned m_line;
public:
opt_stream_buffer(std::istream & s):
m_stream(s),
m_line(0) {
m_val = m_stream.get();
}
int operator *() const { return m_val;}
void operator ++() { m_val = m_stream.get(); }
int ch() const { return m_val; }
void next() { m_val = m_stream.get(); }
bool eof() const { return ch() == EOF; }
unsigned line() const { return m_line; }
void skip_whitespace() {
while ((ch() >= 9 && ch() <= 13) || ch() == 32) {
if (ch() == 10) ++m_line;
next();
}
}
void skip_space() {
while (ch() != 10 && ((ch() >= 9 && ch() <= 13) || ch() == 32)) {
next();
}
}
void skip_line() {
while(true) {
if (eof()) {
return;
}
if (ch() == '\n') {
++m_line;
next();
return;
}
next();
}
}
bool parse_token(char const* token) {
skip_whitespace();
char const* t = token;
while (ch() == *t) {
next();
++t;
}
return 0 == *t;
}
int parse_int() {
int val = 0;
bool neg = false;
skip_whitespace();
if (ch() == '-') {
neg = true;
next();
}
else if (ch() == '+') {
next();
}
if (ch() < '0' || ch() > '9') {
std::cerr << "(error line " << line() << " \"unexpected char: " << ((char)ch()) << "\" )\n";
exit(3);
}
while (ch() >= '0' && ch() <= '9') {
val = val*10 + (ch() - '0');
next();
}
return neg ? -val : val;
}
unsigned parse_unsigned() {
skip_space();
if (ch() == '\n') {
return UINT_MAX;
}
unsigned val = 0;
while (ch() >= '0' && ch() <= '9') {
val = val*10 + (ch() - '0');
next();
}
return val;
}
};
class wcnf {
opt::context& opt;
ast_manager& m;
opt_stream_buffer& in;
app_ref read_clause(unsigned& weight) {
int parsed_lit;
int var;
weight = in.parse_unsigned();
app_ref result(m), p(m);
expr_ref_vector ors(m);
while (true) {
parsed_lit = in.parse_int();
if (parsed_lit == 0)
break;
var = abs(parsed_lit);
p = m.mk_const(symbol(var), m.mk_bool_sort());
if (parsed_lit < 0) p = m.mk_not(p);
ors.push_back(p);
}
result = to_app(mk_or(m, ors.size(), ors.c_ptr()));
return result;
}
void parse_spec(unsigned& num_vars, unsigned& num_clauses, unsigned& max_weight) {
in.parse_token("wcnf");
num_vars = in.parse_unsigned();
num_clauses = in.parse_unsigned();
max_weight = in.parse_unsigned();
}
public:
wcnf(opt::context& opt, opt_stream_buffer& in): opt(opt), m(opt.get_manager()), in(in) {
opt.set_clausal(true);
}
void parse() {
unsigned num_vars = 0, num_clauses = 0, max_weight = 0;
while (true) {
in.skip_whitespace();
if (in.eof()) {
break;
}
else if (*in == 'c') {
in.skip_line();
}
else if (*in == 'p') {
++in;
parse_spec(num_vars, num_clauses, max_weight);
}
else {
unsigned weight = 0;
app_ref cls = read_clause(weight);
if (weight >= max_weight) {
opt.add_hard_constraint(cls);
}
else {
unsigned id = opt.add_soft_constraint(cls, rational(weight), symbol::null);
if (g_handles.empty()) {
g_handles.push_back(id);
}
}
}
}
}
};
class opb {
opt::context& opt;
ast_manager& m;
opt_stream_buffer& in;
arith_util arith;
app_ref parse_id() {
bool negated = in.parse_token("~");
if (!in.parse_token("x")) {
std::cerr << "(error line " << in.line() << " \"unexpected char: " << ((char)in.ch()) << "\")\n";
exit(3);
}
app_ref p(m);
int id = in.parse_int();
p = m.mk_const(symbol(id), m.mk_bool_sort());
if (negated) p = m.mk_not(p);
in.skip_whitespace();
return p;
}
app_ref parse_ids() {
app_ref result = parse_id();
while (*in == '~' || *in == 'x') {
result = m.mk_and(result, parse_id());
}
return result;
}
rational parse_coeff_r() {
in.skip_whitespace();
svector<char> num;
bool pos = true;
if (*in == '-') pos = false, ++in;
if (*in == '+') ++in;
if (!pos) num.push_back('-');
in.skip_whitespace();
while ('0' <= *in && *in <='9') num.push_back(*in), ++in;
num.push_back(0);
return rational(num.c_ptr());
}
app_ref parse_coeff() {
return app_ref(arith.mk_numeral(parse_coeff_r(), true), m);
}
app_ref parse_term() {
app_ref c = parse_coeff();
app_ref e = parse_ids();
return app_ref(m.mk_ite(e, c, arith.mk_numeral(rational(0), true)), m);
}
void parse_objective() {
app_ref t = parse_term();
while (!in.parse_token(";") && !in.eof()) {
t = arith.mk_add(t, parse_term());
}
g_handles.push_back(opt.add_objective(t, false));
}
void parse_constraint() {
app_ref t = parse_term();
while (!in.eof()) {
if (in.parse_token(">=")) {
t = arith.mk_ge(t, parse_coeff());
in.parse_token(";");
break;
}
if (in.parse_token("=")) {
t = m.mk_eq(t, parse_coeff());
in.parse_token(";");
break;
}
t = arith.mk_add(t, parse_term());
}
opt.add_hard_constraint(t);
}
public:
opb(opt::context& opt, opt_stream_buffer& in):
opt(opt), m(opt.get_manager()),
in(in), arith(m) {}
void parse() {
while (true) {
in.skip_whitespace();
if (in.eof()) {
break;
}
else if (*in == '*') {
in.skip_line();
}
else if (in.parse_token("min:")) {
parse_objective();
}
else {
parse_constraint();
}
}
}
};
static void display_results() {
@ -335,14 +80,11 @@ static unsigned parse_opt(std::istream& in, bool is_wcnf) {
g_opt = &opt;
params_ref p = gparams::get_module("opt");
opt.updt_params(p);
opt_stream_buffer _in(in);
if (is_wcnf) {
wcnf wcnf(opt, _in);
wcnf.parse();
parse_wcnf(opt, in, g_handles);
}
else {
opb opb(opt, _in);
opb.parse();
parse_opb(opt, in, g_handles);
}
try {
lbool r = opt.optimize();

View file

@ -21,7 +21,6 @@ Revision History:
#include<iostream>
#include<time.h>
#include<signal.h>
#include "parsers/smt/smtlib_solver.h"
#include "util/timeout.h"
#include "parsers/smt2/smt2parser.h"
#include "muz/fp/dl_cmds.h"
@ -35,20 +34,14 @@ Revision History:
extern bool g_display_statistics;
static clock_t g_start_time;
static smtlib::solver* g_solver = 0;
static cmd_context * g_cmd_context = 0;
static void display_statistics() {
clock_t end_time = clock();
if ((g_solver || g_cmd_context) && g_display_statistics) {
if (g_cmd_context && g_display_statistics) {
std::cout.flush();
std::cerr.flush();
if (g_solver) {
g_solver->display_statistics();
memory::display_max_usage(std::cout);
std::cout << "time: " << ((static_cast<double>(end_time) - static_cast<double>(g_start_time)) / CLOCKS_PER_SEC) << " secs\n";
}
else if (g_cmd_context) {
if (g_cmd_context) {
g_cmd_context->set_regular_stream("stdout");
g_cmd_context->display_statistics(true, ((static_cast<double>(end_time) - static_cast<double>(g_start_time)) / CLOCKS_PER_SEC));
}
@ -72,33 +65,6 @@ static void STD_CALL on_ctrl_c(int) {
raise(SIGINT);
}
unsigned read_smtlib_file(char const * benchmark_file) {
g_start_time = clock();
register_on_timeout_proc(on_timeout);
signal(SIGINT, on_ctrl_c);
smtlib::solver solver;
g_solver = &solver;
bool ok = true;
ok = solver.solve_smt(benchmark_file);
if (!ok) {
if (benchmark_file) {
std::cerr << "ERROR: solving '" << benchmark_file << "'.\n";
}
else {
std::cerr << "ERROR: solving input stream.\n";
}
}
#pragma omp critical (g_display_stats)
{
display_statistics();
register_on_timeout_proc(0);
g_solver = 0;
}
return solver.get_error_code();
}
unsigned read_smtlib2_commands(char const * file_name) {
g_start_time = clock();

View file

@ -968,7 +968,7 @@ namespace smt {
if (st.num_theories() == 2 && st.has_uf() && is_arith(st)) {
if (!st.m_has_real)
setup_QF_UFLIA(st);
else if (!st.m_has_int)
else if (!st.m_has_int && st.m_num_non_linear == 0)
setup_QF_UFLRA();
else
setup_unknown();

View file

@ -526,7 +526,7 @@ namespace smt {
}
}
}
pp.display(out, m.mk_true());
pp.display_smt2(out, m.mk_true());
}
template<typename Ext>

View file

@ -397,15 +397,13 @@ bool theory_seq::branch_binary_variable(eq const& e) {
expr_ref Y1(mk_skolem(symbol("seq.left"), x, y), m);
expr_ref Y2(mk_skolem(symbol("seq.right"), x, y), m);
ys.push_back(Y1);
expr_ref ysY1(m_util.str.mk_concat(ys.size(), ys.c_ptr()), m);
expr_ref xsE(m_util.str.mk_concat(xs.size(), xs.c_ptr()), m);
expr_ref Y1Y2(m_util.str.mk_concat(Y1, Y2), m);
literal_vector lits;
lits.push_back(~lit);
expr_ref ysY1(mk_concat(ys));
expr_ref xsE(mk_concat(xs));
expr_ref Y1Y2(mk_concat(Y1, Y2));
dependency* dep = e.dep();
propagate_eq(dep, lits, x, ysY1, true);
propagate_eq(dep, lits, y, Y1Y2, true);
propagate_eq(dep, lits, Y2, xsE, true);
propagate_eq(dep, ~lit, x, ysY1);
propagate_eq(dep, ~lit, y, Y1Y2);
propagate_eq(dep, ~lit, Y2, xsE);
}
else {
ctx.mark_as_relevant(lit);
@ -471,9 +469,7 @@ void theory_seq::branch_unit_variable(dependency* dep, expr* X, expr_ref_vector
literal lit = mk_eq(m_autil.mk_int(lX), m_util.str.mk_length(X), false);
if (l_true == ctx.get_assignment(lit)) {
expr_ref R(m_util.str.mk_concat(lX, units.c_ptr()), m);
literal_vector lits;
lits.push_back(lit);
propagate_eq(dep, lits, X, R, true);
propagate_eq(dep, lit, X, R);
TRACE("seq", tout << "propagate " << mk_pp(X, m) << " " << R << "\n";);
}
else {
@ -506,11 +502,10 @@ bool theory_seq::branch_variable_mb() {
for (unsigned j = 0; j < len2.size(); ++j) l2 += len2[j];
if (l1 != l2) {
TRACE("seq", tout << "lengths are not compatible\n";);
expr_ref l = mk_concat(e.ls().size(), e.ls().c_ptr());
expr_ref r = mk_concat(e.rs().size(), e.rs().c_ptr());
expr_ref l = mk_concat(e.ls());
expr_ref r = mk_concat(e.rs());
expr_ref lnl(m_util.str.mk_length(l), m), lnr(m_util.str.mk_length(r), m);
literal_vector lits;
propagate_eq(e.dep(), lits, lnl, lnr, false);
propagate_eq(e.dep(), lnl, lnr, false);
change = true;
continue;
}
@ -626,8 +621,8 @@ bool theory_seq::split_lengths(dependency* dep,
SASSERT(is_var(Y));
expr_ref Y1(mk_skolem(symbol("seq.left"), X, b, Y), m);
expr_ref Y2(mk_skolem(symbol("seq.right"), X, b, Y), m);
expr_ref bY1(m_util.str.mk_concat(b, Y1), m);
expr_ref Y1Y2(m_util.str.mk_concat(Y1, Y2), m);
expr_ref bY1 = mk_concat(b, Y1);
expr_ref Y1Y2 = mk_concat(Y1, Y2);
propagate_eq(dep, lits, X, bY1, true);
propagate_eq(dep, lits, Y, Y1Y2, true);
}
@ -1317,6 +1312,18 @@ void theory_seq::propagate_eq(dependency* dep, enode* n1, enode* n2) {
enforce_length_coherence(n1, n2);
}
void theory_seq::propagate_eq(dependency* dep, expr* e1, expr* e2, bool add_eq) {
literal_vector lits;
propagate_eq(dep, lits, e1, e2, add_eq);
}
void theory_seq::propagate_eq(dependency* dep, literal lit, expr* e1, expr* e2, bool add_to_eqs) {
literal_vector lits;
lits.push_back(lit);
propagate_eq(dep, lits, e1, e2, add_to_eqs);
}
void theory_seq::enforce_length_coherence(enode* n1, enode* n2) {
expr* o1 = n1->get_owner();
expr* o2 = n2->get_owner();
@ -1662,19 +1669,18 @@ bool theory_seq::reduce_length(unsigned i, unsigned j, bool front, expr_ref_vect
}
SASSERT(0 < l1 && l1 < ls.size());
SASSERT(0 < r1 && r1 < rs.size());
expr_ref l(m_util.str.mk_concat(l1, ls1), m);
expr_ref r(m_util.str.mk_concat(r1, rs1), m);
expr_ref l = mk_concat(l1, ls1);
expr_ref r = mk_concat(r1, rs1);
expr_ref lenl(m_util.str.mk_length(l), m);
expr_ref lenr(m_util.str.mk_length(r), m);
literal lit = mk_eq(lenl, lenr, false);
if (ctx.get_assignment(lit) == l_true) {
literal_vector lits;
expr_ref_vector lhs(m), rhs(m);
lhs.append(l2, ls2);
rhs.append(r2, rs2);
deps = mk_join(deps, lit);
m_eqs.push_back(eq(m_eq_id++, lhs, rhs, deps));
propagate_eq(deps, lits, l, r, true);
propagate_eq(deps, l, r, true);
TRACE("seq", tout << "propagate eq\nlhs: " << lhs << "\nrhs: " << rhs << "\n";);
return true;
}
@ -3661,7 +3667,6 @@ void theory_seq::add_extract_axiom(expr* e) {
literal ls_le_i = mk_simplified_literal(m_autil.mk_le(mk_sub(i, ls), zero));
literal li_ge_ls = mk_simplified_literal(m_autil.mk_ge(ls_minus_i_l, zero));
literal l_ge_zero = mk_simplified_literal(m_autil.mk_ge(l, zero));
literal l_le_zero = mk_simplified_literal(m_autil.mk_le(l, zero));
literal ls_le_0 = mk_simplified_literal(m_autil.mk_le(ls, zero));
add_axiom(~i_ge_0, ~ls_le_i, mk_seq_eq(xey, s));

View file

@ -410,6 +410,8 @@ namespace smt {
expr_ref mk_empty(sort* s) { return expr_ref(m_util.str.mk_empty(s), m); }
expr_ref mk_concat(unsigned n, expr*const* es) { return expr_ref(m_util.str.mk_concat(n, es), m); }
expr_ref mk_concat(expr_ref_vector const& es, sort* s) { if (es.empty()) return mk_empty(s); return mk_concat(es.size(), es.c_ptr()); }
expr_ref mk_concat(expr_ref_vector const& es) { SASSERT(!es.empty()); return mk_concat(es.size(), es.c_ptr()); }
expr_ref mk_concat(ptr_vector<expr> const& es) { SASSERT(!es.empty()); return mk_concat(es.size(), es.c_ptr()); }
expr_ref mk_concat(expr* e1, expr* e2) { return expr_ref(m_util.str.mk_concat(e1, e2), m); }
expr_ref mk_concat(expr* e1, expr* e2, expr* e3) { return expr_ref(m_util.str.mk_concat(e1, e2, e3), m); }
bool solve_nqs(unsigned i);
@ -436,7 +438,9 @@ namespace smt {
void propagate_lit(dependency* dep, unsigned n, literal const* lits, literal lit);
void propagate_eq(dependency* dep, enode* n1, enode* n2);
void propagate_eq(literal lit, expr* e1, expr* e2, bool add_to_eqs);
void propagate_eq(dependency* dep, literal_vector const& lits, expr* e1, expr* e2, bool add_to_eqs);
void propagate_eq(dependency* dep, literal_vector const& lits, expr* e1, expr* e2, bool add_to_eqs = true);
void propagate_eq(dependency* dep, expr* e1, expr* e2, bool add_to_eqs = true);
void propagate_eq(dependency* dep, literal lit, expr* e1, expr* e2, bool add_to_eqs = true);
void set_conflict(dependency* dep, literal_vector const& lits = literal_vector());
u_map<unsigned> m_branch_start;

View file

@ -40,10 +40,10 @@ void tst_expr_arith(unsigned num_files) {
pp.set_logic(symbol("QF_AUFLIA"));
std::ostringstream buffer;
buffer << "random_arith_" << i << ".smt";
buffer << "random_arith_" << i << ".smt2";
std::cout << buffer.str() << "\n";
std::ofstream file(buffer.str().c_str());
pp.display(file, e.get());
pp.display_smt2(file, e.get());
file.close();
}
@ -83,10 +83,10 @@ void tst_expr_rand(unsigned num_files) {
pp.set_logic(symbol("QF_AUFBV"));
std::ostringstream buffer;
buffer << "random_bv_" << i << ".smt";
buffer << "random_bv_" << i << ".smt2";
std::cout << buffer.str() << "\n";
std::ofstream file(buffer.str().c_str());
pp.display(file, e.get());
pp.display_smt2(file, e.get());
file.close();
}

View file

@ -8,8 +8,6 @@ Copyright (c) 2015 Microsoft Corporation
#include "smt/params/smt_params.h"
#include "qe/qe.h"
#include "ast/ast_pp.h"
#include "parsers/smt/smtlib.h"
#include "parsers/smt/smtparser.h"
#include "util/lbool.h"
#include <sstream>
#include "ast/reg_decl_plugins.h"
@ -54,6 +52,9 @@ static void test_qe(ast_manager& m, lbool expected_outcome, expr* fml, char cons
static void test_formula(lbool expected_outcome, char const* fml) {
ast_manager m;
reg_decl_plugins(m);
// No-op requires SMTLIB2
#if 0
scoped_ptr<smtlib::parser> parser = smtlib::parser::create(m);
parser->initialize_smtlib();
@ -73,8 +74,10 @@ static void test_formula(lbool expected_outcome, char const* fml) {
for (; it != end; ++it) {
test_qe(m, expected_outcome, *it, 0);
}
#endif
}
void tst_quant_elim() {
disable_debug("heap");

39
src/util/file_path.h Normal file
View file

@ -0,0 +1,39 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
file_path.h
Abstract:
File path functions.
Author:
Nikolaj Bjorner (nbjorner) 2017-11-19
Revision History:
--*/
#ifndef FILE_PATH_H_
#define FILE_PATH_H_
#include <cstring>
inline char const * get_extension(char const * file_name) {
if (file_name == 0)
return 0;
char const * last_dot = 0;
for (;;) {
char const * tmp = strchr(file_name, '.');
if (tmp == 0) {
return last_dot;
}
last_dot = tmp + 1;
file_name = last_dot;
}
}
#endif /* FILE_PATH_H_ */

View file

@ -0,0 +1,117 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
obj_ref_hashtable.h
Abstract:
corresponding obj_map with reference count managment.
Author:
Nikolaj Bjorner (nbjorner) 2017-12-8
Revision History:
--*/
#ifndef OBJ_REF_HASHTABLE_H_
#define OBJ_REF_HASHTABLE_H_
#include "util/obj_hashtable.h"
template<typename M, typename Key, typename Value>
class obj_ref_map {
M& m;
obj_map<Key, Value> m_table;
public:
typedef typename obj_map<Key, Value> iterator;
typedef Key key;
typedef Value value;
typedef typename obj_map<Key, Value>::key_data key_data;
typedef typename obj_map<Key, Value>::obj_map_entry obj_map_entry;
obj_ref_map(M& m):m(m) {}
~obj_ref_map() { reset(); }
void reset() {
for (auto& kv : m_table) {
m.dec_ref(kv.m_key);
}
m_table.reset();
}
void finalize() {
reset();
m_table.finalize();
}
bool empty() const { return m_table.empty(); }
unsigned size() const { return m_table.size(); }
unsigned capacity() const { return m_table.capacity(); }
iterator begin() const { return m_table.begin(); }
iterator end() const { return m_table.end(); }
void insert(Key * const k, Value const & v) {
if (!m_table.contains(k)) m.inc_ref(k);
m_table.insert(k, v);
}
void insert(Key * const k, Value && v) {
if (!m_table.contains(k)) m.inc_ref(k);
m_table.insert(k, v);
}
key_data const & insert_if_not_there(Key * k, Value const & v) {
if (!m_table.contains(k)) m.inc_ref(k);
return m_table.insert_if_not_there(k, v);
}
obj_map_entry * insert_if_not_there2(Key * k, Value const & v) {
if (!m_table.contains(k)) m.inc_ref(k);
return m_table.insert_if_not_there2(k, v);
}
obj_map_entry * find_core(Key * k) const { return m_table.find_core(k); }
bool find(Key * const k, Value & v) const { return m_table.find(k, v); }
value const & find(key * k) const { return m_table.find(k); }
value & find(key * k) { return m_table.find(k); }
value const & operator[](key * k) const { return find(k); }
value & operator[](key * k) { return find(k); }
iterator find_iterator(Key * k) const { return m_table.find_iterator(k); }
bool contains(Key * k) const { return m_table.contains(k); }
void remove(Key * k) {
if (m_table.contains(k)) {
m_table.remove(k);
m.dec_ref(k);
}
}
void erase(Key * k) { remove(k); }
unsigned long long get_num_collision() const { return m_table.get_num_collision(); }
void swap(obj_ref_map & other) {
m_table.swap(other.m_table);
}
};
#endif /* OBJ_REF_HASHTABLE_H_ */