3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-14 01:46:15 +00:00

merge with unstable

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-04-30 10:40:03 -07:00
commit 9377779e58
54 changed files with 20581 additions and 20354 deletions

View file

@ -1,11 +1,52 @@
import os import os
import shutil import shutil
import re import re
import getopt
import pydoc import pydoc
import sys import sys
import subprocess import subprocess
import shutil import shutil
ML_ENABLED=False
BUILD_DIR='../build'
def norm_path(p):
# We use '/' on mk_project for convenience
return os.path.join(*(p.split('/')))
def display_help(exit_code):
print("mk_api_doc.py: Z3 documentation generator\n")
print("\nOptions:")
print(" -h, --help display this message.")
print(" -b <subdir>, --build=<subdir> subdirectory where Z3 is built (default: ../build).")
print(" --ml include ML/OCaml API documentation.")
def parse_options():
global ML_ENABLED, BUILD_DIR
try:
options, remainder = getopt.gnu_getopt(sys.argv[1:],
'b:h',
['build=', 'help', 'ml'])
except:
print("ERROR: Invalid command line option")
display_help(1)
for opt, arg in options:
if opt in ('-b', '--build'):
BUILD_DIR = norm_path(arg)
elif opt in ('h', '--help'):
display_help()
exit(1)
elif opt in ('--ml'):
ML_ENABLED=True
else:
print("ERROR: Invalid command line option: %s" % opt)
display_help(1)
def mk_dir(d): def mk_dir(d):
if not os.path.exists(d): if not os.path.exists(d):
os.makedirs(d) os.makedirs(d)
@ -22,9 +63,23 @@ def cleanup_API(inf, outf):
_outf.write(line) _outf.write(line)
try: try:
parse_options()
fi = open('website.dox', 'r')
fo = open('website-adj.dox', 'w')
for line in fi:
if (line != '[ML]\n'):
fo.write(line)
elif (ML_ENABLED):
fo.write(' - <a class="el" href="ml/index.html">ML/OCaml API</a>\n')
fi.close()
fo.close()
mk_dir('api/html') mk_dir('api/html')
mk_dir('tmp') mk_dir('tmp')
shutil.copyfile('website.dox', 'tmp/website.dox') shutil.copyfile('website-adj.dox', 'tmp/website.dox')
os.remove('website-adj.dox')
shutil.copyfile('../src/api/python/z3.py', 'tmp/z3py.py') shutil.copyfile('../src/api/python/z3.py', 'tmp/z3py.py')
cleanup_API('../src/api/z3_api.h', 'tmp/z3_api.h') cleanup_API('../src/api/z3_api.h', 'tmp/z3_api.h')
cleanup_API('../src/api/z3_algebraic.h', 'tmp/z3_algebraic.h') cleanup_API('../src/api/z3_algebraic.h', 'tmp/z3_algebraic.h')
@ -59,6 +114,14 @@ try:
pydoc.writedoc('z3') pydoc.writedoc('z3')
shutil.move('z3.html', 'api/html/z3.html') shutil.move('z3.html', 'api/html/z3.html')
print "Generated Python documentation." print "Generated Python documentation."
if ML_ENABLED:
mk_dir('api/html/ml')
if subprocess.call(['ocamldoc', '-html', '-d', 'api\html\ml', '-sort', '-hide', 'Z3', '-I', '%s/api/ml' % BUILD_DIR, '../src/api/ml/z3enums.mli', '../src/api/ml/z3.mli']) != 0:
print "ERROR: ocamldoc failed."
exit(1)
print "Generated ML/OCaml documentation."
print "Documentation was successfully generated at subdirectory './api/html'." print "Documentation was successfully generated at subdirectory './api/html'."
except: except:
print "ERROR: failed to generate documentation" print "ERROR: failed to generate documentation"

View file

@ -4,9 +4,9 @@
Z3 is a high-performance theorem prover being developed at <a class="el" Z3 is a high-performance theorem prover being developed at <a class="el"
href="http://research.microsoft.com">Microsoft Research</a>. href="http://research.microsoft.com">Microsoft Research</a>.
<b>The Z3 website moved to <a class="el" href="http://z3.codeplex.com">z3.codeplex.com</a>.</b> <b>The Z3 website moved to <a class="el" href="http://github.com/z3prover">http://github.com/z3prover.</a>.</b>
The old Z3 website can be found <a class="el" href="http://research.microsoft.com/en-us/um/redmond/projects/z3/old/index.html">here</a>. The old Z3 websites can be found <a class="el" href="http://research.microsoft.com/en-us/um/redmond/projects/z3/old/index.html">here</a> and <a href="http://z3.codeplex.com">here</a>.
This website hosts the automatically generated documentation for the Z3 APIs. This website hosts the automatically generated documentation for the Z3 APIs.
@ -14,6 +14,7 @@
- \ref cppapi - \ref cppapi
- <a class="el" href="class_microsoft_1_1_z3_1_1_context.html">.NET API</a> - <a class="el" href="class_microsoft_1_1_z3_1_1_context.html">.NET API</a>
- <a class="el" href="namespacecom_1_1microsoft_1_1z3.html">Java API</a> - <a class="el" href="namespacecom_1_1microsoft_1_1z3.html">Java API</a>
- <a class="el" href="namespacez3py.html">Python API</a> (also available in <a class="el" href="z3.html">pydoc format</a>). - <a class="el" href="namespacez3py.html">Python API</a> (also available in <a class="el" href="z3.html">pydoc format</a>)
[ML]
- Try Z3 online at <a href="http://rise4fun.com/z3">RiSE4Fun</a>. - Try Z3 online at <a href="http://rise4fun.com/z3">RiSE4Fun</a>.
*/ */

View file

@ -47,16 +47,16 @@ def set_build_dir(path):
mk_dir(BUILD_X64_DIR) mk_dir(BUILD_X64_DIR)
def display_help(): def display_help():
print "mk_win_dist.py: Z3 Windows distribution generator\n" print("mk_win_dist.py: Z3 Windows distribution generator\n")
print "This script generates the zip files containing executables, dlls, header files for Windows." print("This script generates the zip files containing executables, dlls, header files for Windows.")
print "It must be executed from the Z3 root directory." print("It must be executed from the Z3 root directory.")
print "\nOptions:" print("\nOptions:")
print " -h, --help display this message." print(" -h, --help display this message.")
print " -s, --silent do not print verbose messages." print(" -s, --silent do not print verbose messages.")
print " -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist)." print(" -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist).")
print " -f, --force force script to regenerate Makefiles." print(" -f, --force force script to regenerate Makefiles.")
print " --nojava do not include Java bindings in the binary distribution files." print(" --nojava do not include Java bindings in the binary distribution files.")
print " --githash include git hash in the Zip file." print(" --githash include git hash in the Zip file.")
exit(0) exit(0)
# Parse configuration option for mk_make script # Parse configuration option for mk_make script
@ -180,7 +180,7 @@ def mk_dist_dir_core(x64):
mk_util.JAVA_ENABLED = JAVA_ENABLED mk_util.JAVA_ENABLED = JAVA_ENABLED
mk_win_dist(build_path, dist_path) mk_win_dist(build_path, dist_path)
if is_verbose(): if is_verbose():
print "Generated %s distribution folder at '%s'" % (platform, dist_path) print("Generated %s distribution folder at '%s'") % (platform, dist_path)
def mk_dist_dir(): def mk_dist_dir():
mk_dist_dir_core(False) mk_dist_dir_core(False)
@ -208,7 +208,7 @@ def mk_zip_core(x64):
ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED) ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED)
os.path.walk(dist_path, mk_zip_visitor, '*') os.path.walk(dist_path, mk_zip_visitor, '*')
if is_verbose(): if is_verbose():
print "Generated '%s'" % zfname print("Generated '%s'") % zfname
except: except:
pass pass
ZIPOUT = None ZIPOUT = None
@ -253,7 +253,7 @@ def cp_vs_runtime_core(x64):
for f in VS_RUNTIME_FILES: for f in VS_RUNTIME_FILES:
shutil.copy(f, bin_dist_path) shutil.copy(f, bin_dist_path)
if is_verbose(): if is_verbose():
print "Copied '%s' to '%s'" % (f, bin_dist_path) print("Copied '%s' to '%s'") % (f, bin_dist_path)
def cp_vs_runtime(): def cp_vs_runtime():
cp_vs_runtime_core(True) cp_vs_runtime_core(True)

View file

@ -2559,7 +2559,7 @@ namespace Microsoft.Z3
/// Create a bit-vector numeral. /// Create a bit-vector numeral.
/// </summary> /// </summary>
/// <param name="v">value of the numeral.</param> /// <param name="v">value of the numeral.</param>
/// /// <param name="size">the size of the bit-vector</param> /// <param name="size">the size of the bit-vector</param>
public BitVecNum MkBV(long v, uint size) public BitVecNum MkBV(long v, uint size)
{ {
Contract.Ensures(Contract.Result<BitVecNum>() != null); Contract.Ensures(Contract.Result<BitVecNum>() != null);

View file

@ -3212,7 +3212,7 @@ public class Context extends IDisposable
* @param rm rounding mode term * @param rm rounding mode term
* @param t1 floating-point term * @param t1 floating-point term
* @param t2 floating-point term * @param t2 floating-point term
* @param t3">floating-point term * @param t3 floating-point term
* Remarks: * Remarks:
* The result is round((t1 * t2) + t3) * The result is round((t1 * t2) + t3)
* @throws Z3Exception * @throws Z3Exception
@ -3247,7 +3247,7 @@ public class Context extends IDisposable
/** /**
* Floating-point roundToIntegral. Rounds a floating-point number to * Floating-point roundToIntegral. Rounds a floating-point number to
* the closest integer, again represented as a floating-point number. * the closest integer, again represented as a floating-point number.
* @param rm">term of RoundingMode sort * @param rm term of RoundingMode sort
* @param t floating-point term * @param t floating-point term
* @throws Z3Exception * @throws Z3Exception
**/ **/
@ -3425,7 +3425,7 @@ public class Context extends IDisposable
/** /**
* Conversion of a single IEEE 754-2008 bit-vector into a floating-point number. * Conversion of a single IEEE 754-2008 bit-vector into a floating-point number.
* @param bv">bit-vector value (of size m). * @param bv bit-vector value (of size m).
* @param s FloatingPoint sort (ebits+sbits == m) * @param s FloatingPoint sort (ebits+sbits == m)
* Remarks: * Remarks:
* Produces a term that represents the conversion of a bit-vector term bv to a * Produces a term that represents the conversion of a bit-vector term bv to a

View file

@ -8580,29 +8580,83 @@ def fpToFPUnsigned(rm, x, s):
return FPRef(Z3_mk_fpa_to_fp_unsigned(rm.ctx_ref(), rm.ast, x.ast, s.ast), rm.ctx) return FPRef(Z3_mk_fpa_to_fp_unsigned(rm.ctx_ref(), rm.ast, x.ast, s.ast), rm.ctx)
def fpToSBV(rm, x, s): def fpToSBV(rm, x, s):
"""Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.""" """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.
>>> x = FP('x', FPSort(8, 24))
>>> y = fpToSBV(RTZ(), x, BitVecSort(32))
>>> print is_fp(x)
True
>>> print is_bv(y)
True
>>> print is_fp(y)
False
>>> print is_bv(x)
False
"""
if __debug__: if __debug__:
_z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
_z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression") _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
_z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort") _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
return FPRef(Z3_mk_fpa_to_sbv(rm.ctx_ref(), rm.ast, x.ast, s.size()), rm.ctx) return BitVecRef(Z3_mk_fpa_to_sbv(rm.ctx_ref(), rm.ast, x.ast, s.size()), rm.ctx)
def fpToUBV(rm, x, s): def fpToUBV(rm, x, s):
"""Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.""" """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.
>>> x = FP('x', FPSort(8, 24))
>>> y = fpToUBV(RTZ(), x, BitVecSort(32))
>>> print is_fp(x)
True
>>> print is_bv(y)
True
>>> print is_fp(y)
False
>>> print is_bv(x)
False
"""
if __debug__: if __debug__:
_z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression")
_z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression") _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression")
_z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort") _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort")
return FPRef(Z3_mk_fpa_to_ubv(rm.ctx_ref(), rm.ast, x.ast, s.size()), rm.ctx) return BitVecRef(Z3_mk_fpa_to_ubv(rm.ctx_ref(), rm.ast, x.ast, s.size()), rm.ctx)
def fpToReal(x): def fpToReal(x):
"""Create a Z3 floating-point conversion expression, from floating-point expression to real.""" """Create a Z3 floating-point conversion expression, from floating-point expression to real.
>>> x = FP('x', FPSort(8, 24))
>>> y = fpToReal(x)
>>> print is_fp(x)
True
>>> print is_real(y)
True
>>> print is_fp(y)
False
>>> print is_real(x)
False
"""
if __debug__: if __debug__:
_z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression") _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
return FPRef(Z3_mk_fpa_to_real(x.ctx_ref(), x.ast), x.ctx) return ArithRef(Z3_mk_fpa_to_real(x.ctx_ref(), x.ast), x.ctx)
def fpToIEEEBV(x): def fpToIEEEBV(x):
"""Create a Z3 floating-point conversion expression, from floating-point expression to IEEE bit-vector.""" """\brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
The size of the resulting bit-vector is automatically determined.
Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion
knows only one NaN and it will always produce the same bit-vector represenatation of
that NaN.
>>> x = FP('x', FPSort(8, 24))
>>> y = fpToIEEEBV(x)
>>> print is_fp(x)
True
>>> print is_bv(y)
True
>>> print is_fp(y)
False
>>> print is_bv(x)
False
"""
if __debug__: if __debug__:
_z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression") _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
return FPRef(Z3_mk_fpa_to_ieee_bv(x.ctx_ref(), x.ast), x.ctx) return BitVecRef(Z3_mk_fpa_to_ieee_bv(x.ctx_ref(), x.ast), x.ctx)

View file

@ -1043,6 +1043,13 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
case OP_DISTINCT: { case OP_DISTINCT: {
func_decl_info info(m_family_id, OP_DISTINCT); func_decl_info info(m_family_id, OP_DISTINCT);
info.set_pairwise(); info.set_pairwise();
for (unsigned i = 1; i < arity; i++) {
if (domain[i] != domain[0]) {
std::ostringstream buffer;
buffer << "Sort mismatch between first argument and argument " << (i+1);
throw ast_exception(buffer.str().c_str());
}
}
return m_manager->mk_func_decl(symbol("distinct"), arity, domain, m_bool_sort, info); return m_manager->mk_func_decl(symbol("distinct"), arity, domain, m_bool_sort, info);
} }
default: default:
@ -2340,6 +2347,10 @@ quantifier * ast_manager::update_quantifier(quantifier * q, bool is_forall, unsi
num_patterns == 0 ? q->get_no_patterns() : 0); num_patterns == 0 ? q->get_no_patterns() : 0);
} }
app * ast_manager::mk_distinct(unsigned num_args, expr * const * args) {
return mk_app(m_basic_family_id, OP_DISTINCT, num_args, args);
}
app * ast_manager::mk_distinct_expanded(unsigned num_args, expr * const * args) { app * ast_manager::mk_distinct_expanded(unsigned num_args, expr * const * args) {
if (num_args < 2) if (num_args < 2)
return mk_true(); return mk_true();

View file

@ -2000,7 +2000,7 @@ public:
app * mk_and(expr * arg1, expr * arg2, expr * arg3) { return mk_app(m_basic_family_id, OP_AND, arg1, arg2, arg3); } app * mk_and(expr * arg1, expr * arg2, expr * arg3) { return mk_app(m_basic_family_id, OP_AND, arg1, arg2, arg3); }
app * mk_implies(expr * arg1, expr * arg2) { return mk_app(m_basic_family_id, OP_IMPLIES, arg1, arg2); } app * mk_implies(expr * arg1, expr * arg2) { return mk_app(m_basic_family_id, OP_IMPLIES, arg1, arg2); }
app * mk_not(expr * n) { return mk_app(m_basic_family_id, OP_NOT, n); } app * mk_not(expr * n) { return mk_app(m_basic_family_id, OP_NOT, n); }
app * mk_distinct(unsigned num_args, expr * const * args) { return mk_app(m_basic_family_id, OP_DISTINCT, num_args, args); } app * mk_distinct(unsigned num_args, expr * const * args);
app * mk_distinct_expanded(unsigned num_args, expr * const * args); app * mk_distinct_expanded(unsigned num_args, expr * const * args);
app * mk_true() { return m_true; } app * mk_true() { return m_true; }
app * mk_false() { return m_false; } app * mk_false() { return m_false; }

View file

@ -2096,9 +2096,14 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
bool is_int; bool is_int;
m_util.au().is_numeral(x, q, is_int); m_util.au().is_numeral(x, q, is_int);
if (q.is_zero())
return mk_pzero(f, result);
else {
scoped_mpf v(m_mpf_manager); scoped_mpf v(m_mpf_manager);
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq()); m_util.fm().set(v, ebits, sbits, rm, q.to_mpq());
expr_ref sgn(m), s(m), e(m), unbiased_exp(m); expr_ref sgn(m), s(m), e(m), unbiased_exp(m);
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1); sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1);
s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1); s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1);
@ -2107,11 +2112,15 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
mk_fp(sgn, e, s, result); mk_fp(sgn, e, s, result);
} }
}
else if (m_util.au().is_numeral(x)) { else if (m_util.au().is_numeral(x)) {
rational q; rational q;
bool is_int; bool is_int;
m_util.au().is_numeral(x, q, is_int); m_util.au().is_numeral(x, q, is_int);
if (m_util.au().is_zero(x))
mk_pzero(f, result);
else {
expr_ref rm_nta(m), rm_nte(m), rm_tp(m), rm_tn(m), rm_tz(m); expr_ref rm_nta(m), rm_nte(m), rm_tp(m), rm_tn(m), rm_tz(m);
mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_nta); mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_nta);
mk_is_rm(rm, BV_RM_TIES_TO_EVEN, rm_nte); mk_is_rm(rm, BV_RM_TIES_TO_EVEN, rm_nte);
@ -2165,6 +2174,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
mk_ite(rm_nte, v2, result, result); mk_ite(rm_nte, v2, result, result);
mk_ite(rm_nta, v1, result, result); mk_ite(rm_nta, v1, result, result);
} }
}
else { else {
bv_util & bu = m_bv_util; bv_util & bu = m_bv_util;
arith_util & au = m_arith_util; arith_util & au = m_arith_util;
@ -2183,6 +2193,10 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
expr_ref rme(rm, m); expr_ref rme(rm, m);
round(s, rme, sgn, sig, exp, result); round(s, rme, sgn, sig, exp, result);
expr_ref c0(m);
mk_is_zero(x, c0);
mk_ite(c0, x, result, result);
expr * e = m.mk_eq(m_util.mk_to_real(result), x); expr * e = m.mk_eq(m_util.mk_to_real(result), x);
m_extra_assertions.push_back(e); m_extra_assertions.push_back(e);
} }
@ -2209,6 +2223,9 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con
SASSERT(e.is_int64()); SASSERT(e.is_int64());
SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1)); SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1));
if (q.is_zero())
return mk_pzero(f, result);
else {
scoped_mpf nte(m_mpf_manager), nta(m_mpf_manager), tp(m_mpf_manager), tn(m_mpf_manager), tz(m_mpf_manager); scoped_mpf nte(m_mpf_manager), nta(m_mpf_manager), tp(m_mpf_manager), tn(m_mpf_manager), tz(m_mpf_manager);
m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator()); m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator());
m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator()); m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator());
@ -2241,6 +2258,8 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con
mk_ite(c3, bv_nta, result, result); mk_ite(c3, bv_nta, result, result);
mk_ite(c4, bv_nte, result, result); mk_ite(c4, bv_nte, result, result);
} }
}
void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
TRACE("fpa2bv_to_real", for (unsigned i = 0; i < num; i++) TRACE("fpa2bv_to_real", for (unsigned i = 0; i < num; i++)
tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;);
@ -2367,10 +2386,9 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const
mk_pinf(f, pinf); mk_pinf(f, pinf);
// Special case: x == 0 -> p/n zero // Special case: x == 0 -> p/n zero
expr_ref c1(m), v1(m), rm_is_to_neg(m); expr_ref c1(m), v1(m);
c1 = is_zero; c1 = is_zero;
mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); v1 = pzero;
mk_ite(rm_is_to_neg, nzero, pzero, v1);
// Special case: x != 0 // Special case: x != 0
expr_ref is_neg_bit(m), exp_too_large(m), sig_4(m), exp_2(m); expr_ref is_neg_bit(m), exp_too_large(m), sig_4(m), exp_2(m);
@ -2508,10 +2526,9 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con
mk_pinf(f, pinf); mk_pinf(f, pinf);
// Special case: x == 0 -> p/n zero // Special case: x == 0 -> p/n zero
expr_ref c1(m), v1(m), rm_is_to_neg(m); expr_ref c1(m), v1(m);
c1 = is_zero; c1 = is_zero;
mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); v1 = pzero;
mk_ite(rm_is_to_neg, nzero, pzero, v1);
// Special case: x != 0 // Special case: x != 0
expr_ref exp_too_large(m), sig_4(m), exp_2(m); expr_ref exp_too_large(m), sig_4(m), exp_2(m);

View file

@ -879,13 +879,21 @@ void fpa_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbol
} }
expr * fpa_decl_plugin::get_some_value(sort * s) { expr * fpa_decl_plugin::get_some_value(sort * s) {
SASSERT(s->is_sort_of(m_family_id, FLOATING_POINT_SORT)); if (s->is_sort_of(m_family_id, FLOATING_POINT_SORT)) {
mpf tmp; mpf tmp;
m_fm.mk_nan(s->get_parameter(0).get_int(), s->get_parameter(1).get_int(), tmp); m_fm.mk_nan(s->get_parameter(0).get_int(), s->get_parameter(1).get_int(), tmp);
expr * res = this->mk_numeral(tmp); expr * res = mk_numeral(tmp);
m_fm.del(tmp); m_fm.del(tmp);
return res; return res;
} }
else if (s->is_sort_of(m_family_id, ROUNDING_MODE_SORT)) {
func_decl * f = mk_rm_const_decl(OP_FPA_RM_TOWARD_ZERO, 0, 0, 0, 0, s);
return m_manager->mk_const(f);
}
UNREACHABLE();
return 0;
}
bool fpa_decl_plugin::is_value(app * e) const { bool fpa_decl_plugin::is_value(app * e) const {
if (e->get_family_id() != m_family_id) if (e->get_family_id() != m_family_id)

View file

@ -902,6 +902,7 @@ template<typename Cfg>
void bit_blaster_tpl<Cfg>::mk_shl(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits) { void bit_blaster_tpl<Cfg>::mk_shl(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits) {
numeral k; numeral k;
if (is_numeral(sz, b_bits, k)) { if (is_numeral(sz, b_bits, k)) {
if (k > numeral(sz)) k = numeral(sz);
unsigned n = static_cast<unsigned>(k.get_int64()); unsigned n = static_cast<unsigned>(k.get_int64());
if (n >= sz) n = sz; if (n >= sz) n = sz;
unsigned pos; unsigned pos;
@ -947,6 +948,7 @@ template<typename Cfg>
void bit_blaster_tpl<Cfg>::mk_lshr(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits) { void bit_blaster_tpl<Cfg>::mk_lshr(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits) {
numeral k; numeral k;
if (is_numeral(sz, b_bits, k)) { if (is_numeral(sz, b_bits, k)) {
if (k > numeral(sz)) k = numeral(sz);
unsigned n = static_cast<unsigned>(k.get_int64()); unsigned n = static_cast<unsigned>(k.get_int64());
unsigned pos = 0; unsigned pos = 0;
for (unsigned i = n; i < sz; pos++, i++) for (unsigned i = n; i < sz; pos++, i++)
@ -989,6 +991,7 @@ template<typename Cfg>
void bit_blaster_tpl<Cfg>::mk_ashr(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits) { void bit_blaster_tpl<Cfg>::mk_ashr(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits) {
numeral k; numeral k;
if (is_numeral(sz, b_bits, k)) { if (is_numeral(sz, b_bits, k)) {
if (k > numeral(sz)) k = numeral(sz);
unsigned n = static_cast<unsigned>(k.get_int64()); unsigned n = static_cast<unsigned>(k.get_int64());
unsigned pos = 0; unsigned pos = 0;
for (unsigned i = n; i < sz; pos++, i++) for (unsigned i = n; i < sz; pos++, i++)

View file

@ -3117,6 +3117,7 @@ done:
} }
if(node->Annotation.IsEmpty() || eq(node->Annotation.Formula,prev_annot) || (repeated_case_count > 0 && !axioms_added) || (repeated_case_count >= 10)){ if(node->Annotation.IsEmpty() || eq(node->Annotation.Formula,prev_annot) || (repeated_case_count > 0 && !axioms_added) || (repeated_case_count >= 10)){
//looks_bad:
if(!axioms_added){ if(!axioms_added){
// add the axioms in the off chance they are useful // add the axioms in the off chance they are useful
const std::vector<expr> &theory = ls->get_axioms(); const std::vector<expr> &theory = ls->get_axioms();

View file

@ -44,6 +44,7 @@ namespace hash_space {
template <typename T> class hash {}; template <typename T> class hash {};
template <> template <>
class hash<int> { class hash<int> {
public: public:
@ -56,7 +57,7 @@ namespace hash_space {
class hash<std::string> { class hash<std::string> {
public: public:
size_t operator()(const std::string &s) const { size_t operator()(const std::string &s) const {
return string_hash(s.c_str(), static_cast<unsigned>(s.size()), 0); return string_hash(s.c_str(), s.size(), 0);
} }
}; };
@ -111,7 +112,7 @@ namespace hash_space {
4294967291ul 4294967291ul
}; };
inline size_t next_prime(size_t n) { inline unsigned long next_prime(unsigned long n) {
const unsigned long* to = primes + (int)num_primes; const unsigned long* to = primes + (int)num_primes;
for(const unsigned long* p = primes; p < to; p++) for(const unsigned long* p = primes; p < to; p++)
if(*p >= n) return *p; if(*p >= n) return *p;
@ -378,7 +379,7 @@ namespace hash_space {
void resize(size_t new_size) { void resize(size_t new_size) {
const size_t old_n = buckets.size(); const size_t old_n = buckets.size();
if (new_size <= old_n) return; if (new_size <= old_n) return;
const size_t n = next_prime(static_cast<unsigned>(new_size)); const size_t n = next_prime(new_size);
if (n <= old_n) return; if (n <= old_n) return;
Table tmp(n, (Entry*)(0)); Table tmp(n, (Entry*)(0));
for (size_t i = 0; i < old_n; ++i) { for (size_t i = 0; i < old_n; ++i) {

View file

@ -398,10 +398,27 @@ public:
s.assert_expr(to_expr(cnsts[i].raw())); s.assert_expr(to_expr(cnsts[i].raw()));
} }
void get_proof_assumptions(z3pf proof, std::vector<ast> &cnsts, hash_set<ast> &memo){
if(memo.find(proof) != memo.end())return;
memo.insert(proof);
pfrule dk = pr(proof);
if(dk == PR_ASSERTED)
cnsts.push_back(conc(proof));
else {
unsigned nprems = num_prems(proof);
for(unsigned i = 0; i < nprems; i++){
z3pf arg = prem(proof,i);
get_proof_assumptions(arg,cnsts,memo);
}
}
}
iz3interp(ast_manager &_m_manager) iz3interp(ast_manager &_m_manager)
: iz3base(_m_manager) {} : iz3base(_m_manager) {}
}; };
void iz3interpolate(ast_manager &_m_manager, void iz3interpolate(ast_manager &_m_manager,
ast *proof, ast *proof,
const ptr_vector<ast> &cnsts, const ptr_vector<ast> &cnsts,
@ -475,6 +492,13 @@ void iz3interpolate(ast_manager &_m_manager,
_cnsts[i] = itp.cook(cnsts[i]); _cnsts[i] = itp.cook(cnsts[i]);
iz3mgr::ast _proof = itp.cook(proof); iz3mgr::ast _proof = itp.cook(proof);
iz3mgr::ast _tree = itp.cook(tree); iz3mgr::ast _tree = itp.cook(tree);
// if consts isn't provided, we can reconstruct it
if(_cnsts.empty()){
hash_set<iz3mgr::ast> memo;
itp.get_proof_assumptions(_proof,_cnsts,memo);
}
itp.proof_to_interpolant(_proof,_cnsts,_tree,_interps,options); itp.proof_to_interpolant(_proof,_cnsts,_tree,_interps,options);
interps.resize(_interps.size()); interps.resize(_interps.size());
for(unsigned i = 0; i < interps.size(); i++) for(unsigned i = 0; i < interps.size(); i++)

View file

@ -67,7 +67,11 @@ void iz3interpolate(ast_manager &_m_manager,
interpolation_options_struct * options = 0); interpolation_options_struct * options = 0);
/* Compute an interpolant from a proof. This version uses the ast /* Compute an interpolant from a proof. This version uses the ast
representation, for compatibility with the new API. */ representation, for compatibility with the new API. Here, cnsts is
a vector of all the assertions in the proof. This can be
over-approximated by the set of all assertions in the
solver. However, if it is empty it will be reconstructed from the
proof, so it can be considered a hint. */
void iz3interpolate(ast_manager &_m_manager, void iz3interpolate(ast_manager &_m_manager,
ast *proof, ast *proof,

View file

@ -4761,6 +4761,25 @@ namespace polynomial {
} }
} }
// muladd may throw if the cancel flag is set.
// So we wrap the degree2pos set and reset
// in a scoped class to ensure the state is clean
// on exit.
struct scoped_degree2pos {
imp& pm;
polynomial const* p;
scoped_degree2pos(imp& pm, polynomial const* p):
pm(pm),
p(p)
{
pm.save_degree2pos(p);
}
~scoped_degree2pos() {
pm.reset_degree2pos(p);
}
};
/** /**
\brief Given an univariate polynomial p(x) and a polynomial q(y_1, ..., y_n), \brief Given an univariate polynomial p(x) and a polynomial q(y_1, ..., y_n),
return a polynomial r(y_1, ..., y_n) = p(q(y_1, ..., y_n)). return a polynomial r(y_1, ..., y_n) = p(q(y_1, ..., y_n)).
@ -4773,7 +4792,7 @@ namespace polynomial {
} }
var x = max_var(p); var x = max_var(p);
unsigned d = degree(p, x); unsigned d = degree(p, x);
save_degree2pos(p); scoped_degree2pos _sd2pos(*this, p);
scoped_numeral a(m()); scoped_numeral a(m());
m_manager.set(a, p->a(m_degree2pos[d])); m_manager.set(a, p->a(m_degree2pos[d]));
r = mk_const(a); r = mk_const(a);
@ -4785,7 +4804,6 @@ namespace polynomial {
m_manager.reset(a); m_manager.reset(a);
r = muladd(q, r, a); r = muladd(q, r, a);
} }
reset_degree2pos(p);
} }
polynomial * mk_x_minus_y(var x, var y) { polynomial * mk_x_minus_y(var x, var y) {

View file

@ -63,7 +63,7 @@ def_module_params('fixedpoint',
('duality.recursion_bound', UINT, UINT_MAX, ('duality.recursion_bound', UINT, UINT_MAX,
'Recursion bound for stratified inlining'), 'Recursion bound for stratified inlining'),
('duality.profile', BOOL, False, 'profile run time'), ('duality.profile', BOOL, False, 'profile run time'),
('duality.mbqi', BOOL, True, 'use model-based quantifier instantion'), ('duality.mbqi', BOOL, True, 'use model-based quantifier instantiation'),
('duality.batch_expand', BOOL, False, 'use batch expansion'), ('duality.batch_expand', BOOL, False, 'use batch expansion'),
('duality.conjecture_file', STRING, '', 'save conjectures to file'), ('duality.conjecture_file', STRING, '', 'save conjectures to file'),
('pdr.bfs_model_search', BOOL, True, ('pdr.bfs_model_search', BOOL, True,

View file

@ -282,7 +282,7 @@ class fix_dl_var_tactic : public tactic {
expr_ref new_curr(m); expr_ref new_curr(m);
proof_ref new_pr(m); proof_ref new_pr(m);
unsigned size = g->size(); unsigned size = g->size();
for (unsigned idx = 0; idx < size; idx++) { for (unsigned idx = 0; !g->inconsistent() && idx < size; idx++) {
expr * curr = g->form(idx); expr * curr = g->form(idx);
m_rw(curr, new_curr, new_pr); m_rw(curr, new_curr, new_pr);
if (produce_proofs) { if (produce_proofs) {

View file

@ -447,9 +447,28 @@ void test_bvneg() {
Z3_del_context(ctx); Z3_del_context(ctx);
} }
static bool cb_called = false;
static void my_cb(Z3_context, Z3_error_code) {
cb_called = true;
}
static void test_mk_distinct() {
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_set_error_handler(ctx, my_cb);
Z3_sort bv8 = Z3_mk_bv_sort(ctx, 8);
Z3_sort bv32 = Z3_mk_bv_sort(ctx, 32);
Z3_ast args[] = { Z3_mk_int64(ctx, 0, bv8), Z3_mk_int64(ctx, 0, bv32) };
Z3_ast d = Z3_mk_distinct(ctx, 2, args);
SASSERT(cb_called);
}
void tst_api() { void tst_api() {
test_apps(); test_apps();
test_bvneg(); test_bvneg();
test_mk_distinct();
// bv_invariant(); // bv_invariant();
} }
#else #else

View file

@ -1475,6 +1475,9 @@ void mpf_manager::mk_ninf(unsigned ebits, unsigned sbits, mpf & o) {
void mpf_manager::unpack(mpf & o, bool normalize) { void mpf_manager::unpack(mpf & o, bool normalize) {
// Insert the hidden bit or adjust the exponent of denormal numbers. // Insert the hidden bit or adjust the exponent of denormal numbers.
if (is_zero(o))
return;
if (is_normal(o)) if (is_normal(o))
m_mpz_manager.add(o.significand, m_powers2(o.sbits-1), o.significand); m_mpz_manager.add(o.significand, m_powers2(o.sbits-1), o.significand);
else { else {