Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rs #3117

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Rs #3117

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions src/api/api_ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,68 @@ extern "C" {
MK_NARY(Z3_mk_and, mk_c(c)->get_basic_fid(), OP_AND, SKIP);
MK_NARY(Z3_mk_or, mk_c(c)->get_basic_fid(), OP_OR, SKIP);

Z3_sort Z3_API Z3_mk_refinement_sort(Z3_context c, Z3_ast f) {
Z3_TRY;
LOG_Z3_mk_refinement_sort(c, f);
sort* s = nullptr;
if (to_ast(f)->get_kind() == AST_FUNC_DECL) {
func_decl* g = to_func_decl(to_ast(f));
s = mk_c(c)->rsutil().mk_sort(g);
}
else {
CHECK_IS_EXPR(f, nullptr);
expr* e = to_expr(f);
s = mk_c(c)->rsutil().mk_sort(e);
}
mk_c(c)->save_ast_trail(s);
RETURN_Z3(of_sort(s));
Z3_CATCH_RETURN(nullptr);
}

Z3_sort Z3_API Z3_refine_sort_basis(Z3_context c, Z3_sort s) {
Z3_TRY;
LOG_Z3_refine_sort_basis(c, s);
sort* s0 = nullptr;
RESET_ERROR_CODE();
if (!mk_c(c)->rsutil().is_refine_sort(to_sort(s), s0)) {
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_sort(s0));
Z3_CATCH_RETURN(nullptr);
}

Z3_ast Z3_API Z3_refine_sort_predicate(Z3_context c, Z3_sort s) {
Z3_TRY;
LOG_Z3_refine_sort_predicate(c, s);
RESET_ERROR_CODE();
sort* s0 = nullptr;
expr* e = nullptr;
func_decl* f = nullptr;
if (mk_c(c)->rsutil().is_refine_sort(to_sort(s), s0, e)) {
RETURN_Z3(of_ast(e));
}
if (mk_c(c)->rsutil().is_refine_sort(to_sort(s), s0, f)) {
RETURN_Z3(of_ast(f));
}
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
Z3_CATCH_RETURN(nullptr);
}

MK_UNARY(Z3_mk_relax, mk_c(c)->rsutil().fid(), OP_RS_RELAX, SKIP);

Z3_ast Z3_API Z3_mk_restrict(Z3_context c, Z3_ast e, Z3_sort s) {
Z3_TRY;
LOG_Z3_mk_restrict(c, e, s);
RESET_ERROR_CODE();
CHECK_IS_EXPR(e, nullptr);
expr* result = mk_c(c)->rsutil().mk_restrict(to_expr(e), to_sort(s));
mk_c(c)->save_ast_trail(result);
RETURN_Z3(of_ast(result));
Z3_CATCH_RETURN(nullptr);
}

Z3_ast mk_ite_core(Z3_context c, Z3_ast t1, Z3_ast t2, Z3_ast t3) {
expr * result = mk_c(c)->m().mk_ite(to_expr(t1), to_expr(t2), to_expr(t3));
mk_c(c)->save_ast_trail(result);
Expand Down Expand Up @@ -714,6 +776,9 @@ extern "C" {
else if (fid == mk_c(c)->get_seq_fid() && k == RE_SORT) {
return Z3_RE_SORT;
}
else if (fid == mk_c(c)->rsutil().fid() && k == REFINE_SORT) {
return Z3_REFINE_SORT;
}
else {
return Z3_UNKNOWN_SORT;
}
Expand Down Expand Up @@ -1290,6 +1355,14 @@ extern "C" {
}
}

if (mk_c(c)->get_rs_fid() == _d->get_family_id()) {
switch (_d->get_decl_kind()) {
case OP_RS_RELAX: return Z3_OP_RELAX;
case OP_RS_RESTRICT: return Z3_OP_RESTRICT;
default: break;
}
}

return Z3_OP_UNINTERPRETED;
Z3_CATCH_RETURN(Z3_OP_UNINTERPRETED);
}
Expand Down
1 change: 1 addition & 0 deletions src/api/api_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ namespace api {
m_fpa_util(m()),
m_sutil(m()),
m_recfun(m()),
m_rs_util(m()),
m_last_result(m()),
m_ast_trail(m()),
m_pmanager(m_limit) {
Expand Down
4 changes: 4 additions & 0 deletions src/api/api_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Revision History:
#include "ast/fpa_decl_plugin.h"
#include "ast/recfun_decl_plugin.h"
#include "ast/special_relations_decl_plugin.h"
#include "ast/refinement_sort_decl_plugin.h"
#include "ast/rewriter/seq_rewriter.h"
#include "smt/params/smt_params.h"
#include "smt/smt_kernel.h"
Expand Down Expand Up @@ -89,6 +90,7 @@ namespace api {
fpa_util m_fpa_util;
seq_util m_sutil;
recfun::util m_recfun;
refinement_sort_util m_rs_util;

// Support for old solver API
smt_params m_fparams;
Expand Down Expand Up @@ -157,6 +159,7 @@ namespace api {
datatype_util& dtutil() { return m_dt_plugin->u(); }
seq_util& sutil() { return m_sutil; }
recfun::util& recfun() { return m_recfun; }
refinement_sort_util& rsutil() { return m_rs_util; }
family_id get_basic_fid() const { return m_basic_fid; }
family_id get_array_fid() const { return m_array_fid; }
family_id get_arith_fid() const { return m_arith_fid; }
Expand All @@ -166,6 +169,7 @@ namespace api {
family_id get_pb_fid() const { return m_pb_fid; }
family_id get_fpa_fid() const { return m_fpa_fid; }
family_id get_seq_fid() const { return m_seq_fid; }
family_id get_rs_fid() const { return m_rs_util.fid(); }
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
family_id get_special_relations_fid() const { return m_special_relations_fid; }

Expand Down
22 changes: 22 additions & 0 deletions src/api/python/z3/z3.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ def _to_sort_ref(s, ctx):
return ReSortRef(s, ctx)
elif k == Z3_SEQ_SORT:
return SeqSortRef(s, ctx)
elif k == Z3_REFINE_SORT:
return RefinementSortRef(s, ctx)
return SortRef(s, ctx)

def _sort(ctx, a):
Expand Down Expand Up @@ -10465,3 +10467,23 @@ def TransitiveClosure(f):
The transitive closure R+ is a new relation.
"""
return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)

# Refinement sorts

class RefinementSortRef(SortRef):
"""Refinement sort."""

def basis(self):
return _to_sort_ref(Z3_refine_sort_basis(self.ctx_ref(), self.ast), self.ctx)

def predicate(self):
return _to_expr_ref(Z3_refine_sort_predicate(self.ctx_ref(), self.ast), self.ctx)

def Relax(e):
return _to_expr_ref(Z3_mk_relax(e.ctx_ref(), e.as_ast()), e.ctx)

def Restrict(e, s):
return _to_expr_ref(Z3_mk_restrict(e.ctx_ref(), e.as_ast(), s.as_ast()), e.ctx)

def RefineSort(p):
return _to_sort_ref(Z3_mk_refinement_sort(p.ctx_ref(), p.as_ast()), p.ctx)
10 changes: 9 additions & 1 deletion src/api/python/z3/z3printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def _z3_assert(cond, msg):
Z3_OP_RE_INTERSECT : 'Intersect', Z3_OP_RE_COMPLEMENT : 'Complement',
Z3_OP_FPA_IS_NAN : 'fpIsNaN', Z3_OP_FPA_IS_INF : 'fpIsInf', Z3_OP_FPA_IS_ZERO : 'fpIsZero',
Z3_OP_FPA_IS_NORMAL : 'fpIsNormal', Z3_OP_FPA_IS_SUBNORMAL : 'fpIsSubnormal',
Z3_OP_FPA_IS_NEGATIVE : 'fpIsNegative', Z3_OP_FPA_IS_POSITIVE : 'fpIsPositive',
Z3_OP_FPA_IS_NEGATIVE : 'fpIsNegative', Z3_OP_FPA_IS_POSITIVE : 'fpIsPositive',
}

# List of infix operators
Expand Down Expand Up @@ -566,6 +566,14 @@ def pp_sort(self, s):
return seq1('FPSort', (to_format(s.ebits()), to_format(s.sbits())))
elif isinstance(s, z3.ReSortRef):
return seq1('ReSort', (self.pp_sort(s.basis()), ))
elif isinstance(s, z3.RefinementSortRef):
f1 = self.pp_sort(s.basis())
p = s.predicate()
if isinstance(p, z3.ExprRef):
s2 = self.pp_expr(p, 0, [])
else:
s2 = self.pp_fdecl(p, 0, [])
return seq1('RefineSort', [f1, to_format(s2)])
elif isinstance(s, z3.SeqSortRef):
if s.is_string():
return to_format("String")
Expand Down
52 changes: 52 additions & 0 deletions src/api/z3_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ typedef enum
Z3_ROUNDING_MODE_SORT,
Z3_SEQ_SORT,
Z3_RE_SORT,
Z3_REFINE_SORT,
Z3_UNKNOWN_SORT = 1000
} Z3_sort_kind;

Expand Down Expand Up @@ -998,6 +999,11 @@ typedef enum
3 = 011 = Z3_OP_FPA_RM_TOWARD_NEGATIVE,
4 = 100 = Z3_OP_FPA_RM_TOWARD_ZERO.

- Z3_OP_RELAX: takes a term of refinement sort s | p, and injects to sort s.

- Z3_OP_RESTRCIT: takes a term of sort s and projects to refinement sort s | p


- Z3_OP_INTERNAL: internal (often interpreted) symbol, but no additional
information is exposed. Tools may use the string representation of the
function declaration to obtain more information.
Expand Down Expand Up @@ -1302,6 +1308,10 @@ typedef enum {
Z3_OP_FPA_BVWRAP,
Z3_OP_FPA_BV2RM,

// injection and projection to refinement sorts
Z3_OP_RELAX = 0xc000,
Z3_OP_RESTRICT,

Z3_OP_INTERNAL,

Z3_OP_UNINTERPRETED
Expand Down Expand Up @@ -3771,6 +3781,48 @@ extern "C" {

/*@}*/

/** @name Refinement sort */
/*@{*/

/**
\brief creates refinement sort given lambda expression f (of sort Array(s, Bool))
or given function f with signature s -> Bool

def_API('Z3_mk_refinement_sort', SORT, (_in(CONTEXT), _in(AST)))
*/
Z3_sort Z3_API Z3_mk_refinement_sort(Z3_context c, Z3_ast f);


/**
\brief retrieve base sort from refinement sort

def_API('Z3_refine_sort_basis', SORT, (_in(CONTEXT), _in(SORT)))
*/
Z3_sort Z3_API Z3_refine_sort_basis(Z3_context c, Z3_sort s);

/**
\brief retrieve predicate from refinement sort

def_API('Z3_refine_sort_predicate', AST, (_in(CONTEXT), _in(SORT)))
*/
Z3_ast Z3_API Z3_refine_sort_predicate(Z3_context c, Z3_sort s);


/**
\brief takes term e of refinement sort s | p and produces injection into s.

def_API('Z3_mk_relax', AST, (_in(CONTEXT), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_relax(Z3_context c, Z3_ast e);

/**
\brief takes term e of refinement sort s | p and produces injection into s.

def_API('Z3_mk_restrict', AST, (_in(CONTEXT), _in(AST), _in(SORT)))
*/
Z3_ast Z3_API Z3_mk_restrict(Z3_context c, Z3_ast e, Z3_sort s);
/*@}*/

/** @name Quantifiers */
/*@{*/
/**
Expand Down
1 change: 1 addition & 0 deletions src/ast/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ z3_add_component(ast
pb_decl_plugin.cpp
pp.cpp
recfun_decl_plugin.cpp
refinement_sort_decl_plugin.cpp
reg_decl_plugins.cpp
seq_decl_plugin.cpp
shared_occs.cpp
Expand Down
4 changes: 4 additions & 0 deletions src/ast/reg_decl_plugins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Revision History:
#include "ast/pb_decl_plugin.h"
#include "ast/fpa_decl_plugin.h"
#include "ast/special_relations_decl_plugin.h"
#include "ast/refinement_sort_decl_plugin.h"

void reg_decl_plugins(ast_manager & m) {
if (!m.get_plugin(m.mk_family_id(symbol("arith")))) {
Expand Down Expand Up @@ -60,4 +61,7 @@ void reg_decl_plugins(ast_manager & m) {
if (!m.get_plugin(m.mk_family_id(symbol("special_relations")))) {
m.register_plugin(symbol("special_relations"), alloc(special_relations_decl_plugin));
}
if (!m.get_plugin(m.mk_family_id(symbol("refinement_sort")))) {
m.register_plugin(symbol("refinement_sort"), alloc(refinement_sort_decl_plugin));
}
}
4 changes: 4 additions & 0 deletions src/ast/static_features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static_features::static_features(ast_manager & m):
m_arrayutil(m),
m_fpautil(m),
m_sequtil(m),
m_rsutil(m),
m_bfid(m.get_basic_family_id()),
m_afid(m.mk_family_id("arith")),
m_lfid(m.mk_family_id("label")),
Expand Down Expand Up @@ -80,6 +81,7 @@ void static_features::reset() {
m_has_bv = false;
m_has_fpa = false;
m_has_sr = false;
m_has_rs = false;
m_has_str = false;
m_has_seq_non_str = false;
m_has_arrays = false;
Expand Down Expand Up @@ -279,6 +281,8 @@ void static_features::update_core(expr * e) {
m_has_fpa = true;
if (is_app(e) && to_app(e)->get_family_id() == m_srfid)
m_has_sr = true;
if (m_rsutil.is_refine_sort(e))
m_has_rs = true;
if (!m_has_arrays && m_arrayutil.is_array(e))
m_has_arrays = true;
if (!m_has_ext_arrays && m_arrayutil.is_array(e) &&
Expand Down
3 changes: 3 additions & 0 deletions src/ast/static_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ Revision History:
#include "ast/fpa_decl_plugin.h"
#include "ast/seq_decl_plugin.h"
#include "ast/special_relations_decl_plugin.h"
#include "ast/refinement_sort_decl_plugin.h"
#include "util/map.h"

struct static_features {
ast_manager & m;
arith_util m_autil;
bv_util m_bvutil;
refinement_sort_util m_rsutil;
array_util m_arrayutil;
fpa_util m_fpautil;
seq_util m_sequtil;
Expand Down Expand Up @@ -82,6 +84,7 @@ struct static_features {
bool m_has_bv; //
bool m_has_fpa; //
bool m_has_sr; // has special relations
bool m_has_rs; // has refinement sorts
bool m_has_str; // has String-typed terms
bool m_has_seq_non_str; // has non-String-typed Sequence terms
bool m_has_arrays; //
Expand Down
1 change: 1 addition & 0 deletions src/smt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ z3_add_component(smt
theory_opt.cpp
theory_pb.cpp
theory_recfun.cpp
theory_refinement_sort.cpp
theory_seq.cpp
theory_special_relations.cpp
theory_str.cpp
Expand Down
3 changes: 2 additions & 1 deletion src/smt/smt_internalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,8 @@ namespace smt {
\brief Internalize an uninterpreted function application or constant.
*/
void context::internalize_uninterpreted(app * n) {
SASSERT(!e_internalized(n));
if (e_internalized(n))
return;
// process args
for (expr * arg : *n) {
internalize_rec(arg, false);
Expand Down
7 changes: 7 additions & 0 deletions src/smt/smt_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Revision History:
#include "smt/theory_seq_empty.h"
#include "smt/theory_seq.h"
#include "smt/theory_special_relations.h"
#include "smt/theory_refinement_sort.h"
#include "smt/theory_pb.h"
#include "smt/theory_fpa.h"
#include "smt/theory_str.h"
Expand Down Expand Up @@ -942,6 +943,10 @@ namespace smt {
m_context.register_plugin(alloc(smt::theory_special_relations, m_manager));
}

void setup::setup_refinement_sort() {
m_context.register_plugin(alloc(smt::theory_refinement_sort, m_manager));
}

void setup::setup_unknown() {
static_features st(m_manager);
ptr_vector<expr> fmls;
Expand All @@ -958,6 +963,7 @@ namespace smt {
setup_card();
setup_fpa();
if (st.m_has_sr) setup_special_relations();
if (st.m_has_rs) setup_refinement_sort();
}

void setup::setup_unknown(static_features & st) {
Expand All @@ -975,6 +981,7 @@ namespace smt {
setup_fpa();
setup_recfuns();
if (st.m_has_sr) setup_special_relations();
if (st.m_has_rs) setup_refinement_sort();
return;
}

Expand Down
Loading