mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
add option to validate result of PDR. Add PDR tactic. Add fixedpoint parsing
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
68ae5d434c
commit
50385e7e29
32 changed files with 836 additions and 393 deletions
|
@ -26,6 +26,9 @@ Revision History:
|
|||
#include"datalog_parser.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"scoped_timer.h"
|
||||
#include"dl_cmds.h"
|
||||
#include"cmd_context.h"
|
||||
#include"smt2parser.h"
|
||||
|
||||
namespace api {
|
||||
|
||||
|
@ -124,55 +127,6 @@ namespace api {
|
|||
return str.str();
|
||||
}
|
||||
|
||||
void fixedpoint_context::simplify_rules(
|
||||
unsigned num_rules, expr* const* rules,
|
||||
unsigned num_outputs, func_decl* const* outputs, expr_ref_vector& result) {
|
||||
ast_manager& m = m_context.get_manager();
|
||||
|
||||
datalog::context ctx(m, m_context.get_fparams());
|
||||
for (unsigned i = 0; i < num_rules; ++i) {
|
||||
expr* rule = rules[i], *body, *head;
|
||||
while (true) {
|
||||
if (is_quantifier(rule)) {
|
||||
rule = to_quantifier(rule)->get_expr();
|
||||
}
|
||||
else if (m.is_implies(rule, body, head)) {
|
||||
rule = head;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_app(rule)) {
|
||||
func_decl* r = to_app(rule)->get_decl();
|
||||
if (!ctx.is_predicate(r)) {
|
||||
ctx.register_predicate(r);
|
||||
if (num_outputs == 0) {
|
||||
ctx.set_output_predicate(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < num_outputs; ++i) {
|
||||
ctx.set_output_predicate(outputs[i]);
|
||||
}
|
||||
for (unsigned i = 0; i < num_rules; ++i) {
|
||||
expr* rule = rules[i];
|
||||
ctx.add_rule(rule, symbol::null);
|
||||
}
|
||||
model_converter_ref mc; // not exposed.
|
||||
proof_converter_ref pc; // not exposed.
|
||||
ctx.apply_default_transformation(mc, pc);
|
||||
datalog::rule_set const& new_rules = ctx.get_rules();
|
||||
datalog::rule_set::iterator it = new_rules.begin(), end = new_rules.end();
|
||||
for (; it != end; ++it) {
|
||||
datalog::rule* r = *it;
|
||||
expr_ref fml(m);
|
||||
r->to_formula(fml);
|
||||
result.push_back(fml);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
@ -384,6 +338,62 @@ extern "C" {
|
|||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_fixedpoint_from_stream(
|
||||
Z3_context c,
|
||||
Z3_fixedpoint d,
|
||||
std::istream& s) {
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
dl_collected_cmds coll(m);
|
||||
cmd_context ctx(&mk_c(c)->fparams(), false, &m);
|
||||
install_dl_collect_cmds(coll, ctx);
|
||||
ctx.set_ignore_check(true);
|
||||
if (!parse_smt2_commands(ctx, s)) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
|
||||
mk_c(c)->save_object(v);
|
||||
for (unsigned i = 0; i < coll.m_queries.size(); ++i) {
|
||||
v->m_ast_vector.push_back(coll.m_queries[i].get());
|
||||
}
|
||||
for (unsigned i = 0; i < coll.m_rels.size(); ++i) {
|
||||
to_fixedpoint_ref(d)->ctx().register_predicate(coll.m_rels[i].get());
|
||||
}
|
||||
for (unsigned i = 0; i < coll.m_rules.size(); ++i) {
|
||||
to_fixedpoint_ref(d)->add_rule(coll.m_rules[i].get(), coll.m_names[i]);
|
||||
}
|
||||
return of_ast_vector(v);
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_from_string(
|
||||
Z3_context c,
|
||||
Z3_fixedpoint d,
|
||||
Z3_string s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_from_string(c, d, s);
|
||||
std::string str(s);
|
||||
std::istringstream is(str);
|
||||
RETURN_Z3(Z3_fixedpoint_from_stream(c, d, is));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_from_file(
|
||||
Z3_context c,
|
||||
Z3_fixedpoint d,
|
||||
Z3_string s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_from_file(c, d, s);
|
||||
std::ifstream is(s);
|
||||
if (!is) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
RETURN_Z3(Z3_fixedpoint_from_stream(c, d, is));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_stats Z3_API Z3_fixedpoint_get_statistics(Z3_context c,Z3_fixedpoint d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_statistics(c, d);
|
||||
|
@ -419,6 +429,27 @@ extern "C" {
|
|||
Z3_CATCH;
|
||||
}
|
||||
|
||||
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_get_rules(
|
||||
Z3_context c,
|
||||
Z3_fixedpoint d)
|
||||
{
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_rules(c, d);
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
|
||||
mk_c(c)->save_object(v);
|
||||
datalog::rule_set const& rules = to_fixedpoint_ref(d)->ctx().get_rules();
|
||||
datalog::rule_set::iterator it = rules.begin(), end = rules.end();
|
||||
for (; it != end; ++it) {
|
||||
expr_ref fml(m);
|
||||
(*it)->to_formula(fml);
|
||||
v->m_ast_vector.push_back(fml);
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_set_reduce_assign_callback(
|
||||
Z3_context c, Z3_fixedpoint d, Z3_fixedpoint_reduce_assign_callback_fptr f) {
|
||||
Z3_TRY;
|
||||
|
@ -435,31 +466,6 @@ extern "C" {
|
|||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_simplify_rules(
|
||||
Z3_context c,
|
||||
Z3_fixedpoint d,
|
||||
unsigned num_rules,
|
||||
Z3_ast _rules[],
|
||||
unsigned num_outputs,
|
||||
Z3_func_decl _outputs[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_simplify_rules(c, d, num_rules, _rules, num_outputs, _outputs);
|
||||
RESET_ERROR_CODE();
|
||||
expr** rules = (expr**)_rules;
|
||||
func_decl** outputs = (func_decl**)_outputs;
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
expr_ref_vector result(m);
|
||||
to_fixedpoint_ref(d)->simplify_rules(num_rules, rules, num_outputs, outputs, result);
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
for (unsigned i = 0; i < result.size(); ++i) {
|
||||
v->m_ast_vector.push_back(result[i].get());
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0)
|
||||
}
|
||||
|
||||
|
||||
void Z3_API Z3_fixedpoint_init(Z3_context c,Z3_fixedpoint d, void* state) {
|
||||
Z3_TRY;
|
||||
// not logged
|
||||
|
|
|
@ -62,9 +62,6 @@ namespace api {
|
|||
void collect_param_descrs(param_descrs & p) { m_context.collect_params(p); }
|
||||
void updt_params(params_ref const& p) { m_context.updt_params(p); }
|
||||
|
||||
void simplify_rules(
|
||||
unsigned num_rules, expr* const* rules,
|
||||
unsigned num_outputs, func_decl* const* outputs, expr_ref_vector& result);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -261,6 +261,23 @@ namespace Microsoft.Z3
|
|||
AST.ArrayLength(queries), AST.ArrayToNative(queries));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve set of rules added to fixedpoint context.
|
||||
/// </summary>
|
||||
public BoolExpr[] Rules {
|
||||
get
|
||||
{
|
||||
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
|
||||
|
||||
ASTVector v = new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject));
|
||||
uint n = v.Size;
|
||||
BoolExpr[] res = new BoolExpr[n];
|
||||
for (uint i = 0; i < n; i++)
|
||||
res[i] = new BoolExpr(Context, v[i].NativeObject);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Internal
|
||||
internal Fixedpoint(Context ctx, IntPtr obj)
|
||||
|
|
|
@ -6102,7 +6102,6 @@ class Fixedpoint(Z3PPObject):
|
|||
"""Add property to predicate for the level'th unfolding. -1 is treated as infinity (infinity)"""
|
||||
Z3_fixedpoint_add_cover(self.ctx.ref(), self.fixedpoint, level, predicate.ast, property.ast)
|
||||
|
||||
|
||||
def register_relation(self, *relations):
|
||||
"""Register relation as recursive"""
|
||||
relations = _get_args(relations)
|
||||
|
@ -6119,16 +6118,35 @@ class Fixedpoint(Z3PPObject):
|
|||
args[i] = representations[i]
|
||||
Z3_fixedpoint_set_predicate_representation(self.ctx.ref(), self.fixedpoint, f.ast, sz, args)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
def get_rules(self):
|
||||
"""retrieve rules that have been added to fixedpoint context"""
|
||||
return AstVector(Z3_fixedpoint_get_rules(self.ctx.ref(), self.fixedpoint), self.ctx)
|
||||
|
||||
def __repr__(self):
|
||||
"""Return a formatted string with all added rules and constraints."""
|
||||
return self.sexpr()
|
||||
|
||||
def sexpr(self):
|
||||
"""Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
|
||||
|
||||
"""Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
|
||||
"""
|
||||
return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
|
||||
return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, 0, (Ast * 0)())
|
||||
|
||||
def to_string(self, queries):
|
||||
"""Return a formatted string (in Lisp-like format) with all added constraints.
|
||||
We say the string is in s-expression format.
|
||||
Include also queries.
|
||||
"""
|
||||
args, len = _to_ast_array(queries)
|
||||
return Z3_fixedpoint_to_string(self.ctx.ref(), self.fixedpoint, len, args)
|
||||
|
||||
def statistics(self):
|
||||
"""Return statistics for the last `query()`.
|
||||
"""
|
||||
|
|
|
@ -5688,19 +5688,13 @@ END_MLAPI_EXCLUDE
|
|||
__in_ecount(num_relations) Z3_symbol const relation_kinds[]);
|
||||
|
||||
/**
|
||||
\brief Simplify rules into a set of new rules that are returned.
|
||||
The simplification routines apply inlining, quantifier elimination, and other
|
||||
algebraic simplifications.
|
||||
\brief Retrieve set of rules from fixedpoint context.
|
||||
|
||||
def_API('Z3_fixedpoint_simplify_rules', AST_VECTOR, (_in(CONTEXT), _in(FIXEDPOINT), _in(UINT), _in_array(2,AST), _in(UINT), _in_array(4,FUNC_DECL)))
|
||||
*/
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_simplify_rules(
|
||||
def_API('Z3_fixedpoint_get_rules', AST_VECTOR, (_in(CONTEXT),_in(FIXEDPOINT)))
|
||||
*/
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_get_rules(
|
||||
__in Z3_context c,
|
||||
__in Z3_fixedpoint f,
|
||||
__in unsigned num_rules,
|
||||
__in_ecount(num_rules) Z3_ast rules[],
|
||||
__in unsigned num_outputs,
|
||||
__in_ecount(num_outputs) Z3_func_decl outputs[]);
|
||||
__in Z3_fixedpoint f);
|
||||
|
||||
/**
|
||||
\brief Set parameters on fixedpoint context.
|
||||
|
@ -5738,6 +5732,38 @@ END_MLAPI_EXCLUDE
|
|||
__in unsigned num_queries,
|
||||
__in_ecount(num_queries) Z3_ast queries[]);
|
||||
|
||||
/**
|
||||
\brief Parse an SMT-LIB2 string with fixedpoint rules.
|
||||
Add the rules to the current fixedpoint context.
|
||||
Return the set of queries in the file.
|
||||
|
||||
\param c - context.
|
||||
\param f - fixedpoint context.
|
||||
\param s - string containing SMT2 specification.
|
||||
|
||||
def_API('Z3_fixedpoint_from_string', AST_VECTOR, (_in(CONTEXT), _in(FIXEDPOINT), _in(STRING)))
|
||||
*/
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_from_string(
|
||||
__in Z3_context c,
|
||||
__in Z3_fixedpoint f,
|
||||
__in Z3_string s);
|
||||
|
||||
/**
|
||||
\brief Parse an SMT-LIB2 file with fixedpoint rules.
|
||||
Add the rules to the current fixedpoint context.
|
||||
Return the set of queries in the file.
|
||||
|
||||
\param c - context.
|
||||
\param f - fixedpoint context.
|
||||
\param s - string containing SMT2 specification.
|
||||
|
||||
def_API('Z3_fixedpoint_from_file', AST_VECTOR, (_in(CONTEXT), _in(FIXEDPOINT), _in(STRING)))
|
||||
*/
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_from_file(
|
||||
__in Z3_context c,
|
||||
__in Z3_fixedpoint f,
|
||||
__in Z3_string s);
|
||||
|
||||
/**
|
||||
\brief Create a backtracking point.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue