mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 10:25:18 +00:00
Merge branch 'unstable' of https://git01.codeplex.com/z3 into fpa-api
This commit is contained in:
commit
3e5a702073
3
.gitattributes
vendored
3
.gitattributes
vendored
|
@ -1 +1,4 @@
|
|||
# Set default behaviour, in case users don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
src/api/dotnet/Properties/AssemblyInfo.cs text eol=crlf
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -55,6 +55,8 @@ src/api/api_log_macros.cpp
|
|||
src/api/dll/api_dll.def
|
||||
src/api/dotnet/Enumerations.cs
|
||||
src/api/dotnet/Native.cs
|
||||
src/api/dotnet/Properties/AssemblyInfo.cs
|
||||
src/api/dotnet/Microsoft.Z3.xml
|
||||
src/api/python/z3consts.py
|
||||
src/api/python/z3core.py
|
||||
src/ast/pattern/database.h
|
||||
|
|
|
@ -54,6 +54,7 @@ CPP_COMPONENT='cpp'
|
|||
IS_WINDOWS=False
|
||||
IS_LINUX=False
|
||||
IS_OSX=False
|
||||
IS_FREEBSD=False
|
||||
VERBOSE=True
|
||||
DEBUG_MODE=False
|
||||
SHOW_CPPS = True
|
||||
|
@ -98,6 +99,9 @@ def is_windows():
|
|||
def is_linux():
|
||||
return IS_LINUX
|
||||
|
||||
def is_freebsd():
|
||||
return IS_FREEBSD
|
||||
|
||||
def is_osx():
|
||||
return IS_OSX
|
||||
|
||||
|
@ -426,6 +430,8 @@ elif os.name == 'posix':
|
|||
IS_OSX=True
|
||||
elif os.uname()[0] == 'Linux':
|
||||
IS_LINUX=True
|
||||
elif os.uname()[0] == 'FreeBSD':
|
||||
IS_FREEBSD=True
|
||||
|
||||
def display_help(exit_code):
|
||||
print("mk_make.py: Z3 Makefile generator\n")
|
||||
|
@ -639,7 +645,7 @@ def is_CXX_gpp():
|
|||
return is_compiler(CXX, 'g++')
|
||||
|
||||
def is_clang_in_gpp_form(cc):
|
||||
version_string = subprocess.check_output([cc, '--version'])
|
||||
version_string = check_output([cc, '--version'])
|
||||
return str(version_string).find('clang') != -1
|
||||
|
||||
def is_CXX_clangpp():
|
||||
|
@ -1181,6 +1187,8 @@ class JavaDLLComponent(Component):
|
|||
t = t.replace('PLATFORM', 'darwin')
|
||||
elif IS_LINUX:
|
||||
t = t.replace('PLATFORM', 'linux')
|
||||
elif IS_FREEBSD:
|
||||
t = t.replace('PLATFORM', 'freebsd')
|
||||
else:
|
||||
t = t.replace('PLATFORM', 'win32')
|
||||
out.write(t)
|
||||
|
|
|
@ -144,7 +144,7 @@ def mk_z3_core(x64):
|
|||
cmds.append('call "%VCINSTALLDIR%vcvarsall.bat" amd64')
|
||||
cmds.append('cd %s' % BUILD_X64_DIR)
|
||||
else:
|
||||
cmds.append('"call %VCINSTALLDIR%vcvarsall.bat" x86')
|
||||
cmds.append('call "%VCINSTALLDIR%vcvarsall.bat" x86')
|
||||
cmds.append('cd %s' % BUILD_X86_DIR)
|
||||
cmds.append('nmake')
|
||||
if exec_cmds(cmds) != 0:
|
||||
|
|
|
@ -117,6 +117,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_sort int_s = Z3_mk_int_sort(c);
|
||||
if (is_signed) {
|
||||
Z3_ast r = Z3_mk_bv2int(c, n, false);
|
||||
Z3_inc_ref(c, r);
|
||||
Z3_sort s = Z3_get_sort(c, n);
|
||||
unsigned sz = Z3_get_bv_sort_size(c, s);
|
||||
rational max_bound = power(rational(2), sz);
|
||||
|
@ -135,6 +136,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_dec_ref(c, pred);
|
||||
Z3_dec_ref(c, sub);
|
||||
Z3_dec_ref(c, zero);
|
||||
Z3_dec_ref(c, r);
|
||||
RETURN_Z3(res);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -39,11 +39,8 @@ Revision History:
|
|||
#include"iz3pp.h"
|
||||
#include"iz3checker.h"
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
// WARNING: don't make a hash_map with this if the range type
|
||||
// has a destructor: you'll get an address dependency!!!
|
||||
namespace stl_ext {
|
||||
|
@ -55,7 +52,6 @@ namespace stl_ext {
|
|||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef interpolation_options_struct *Z3_interpolation_options;
|
||||
|
||||
|
|
|
@ -652,6 +652,8 @@ namespace z3 {
|
|||
return expr(c.ctx(), r);
|
||||
}
|
||||
|
||||
friend expr distinct(expr_vector const& args);
|
||||
|
||||
friend expr operator==(expr const & a, expr const & b) {
|
||||
check_context(a, b);
|
||||
Z3_ast r = Z3_mk_eq(a.ctx(), a, b);
|
||||
|
@ -1065,6 +1067,16 @@ namespace z3 {
|
|||
array<Z3_app> vars(xs);
|
||||
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, vars.size(), vars.ptr(), 0, 0, b); b.check_error(); return expr(b.ctx(), r);
|
||||
}
|
||||
|
||||
|
||||
inline expr distinct(expr_vector const& args) {
|
||||
assert(args.size() > 0);
|
||||
context& ctx = args[0].ctx();
|
||||
array<Z3_ast> _args(args);
|
||||
Z3_ast r = Z3_mk_distinct(ctx, _args.size(), _args.ptr());
|
||||
ctx.check_error();
|
||||
return expr(ctx, r);
|
||||
}
|
||||
|
||||
class func_entry : public object {
|
||||
Z3_func_entry m_entry;
|
||||
|
|
|
@ -302,11 +302,11 @@ namespace Microsoft.Z3
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new finite domain sort.
|
||||
/// <param name="name">The name used to identify the sort</param>
|
||||
/// <param size="size">The size of the sort</param>
|
||||
/// <returns>The result is a sort</returns>
|
||||
/// Create a new finite domain sort.
|
||||
/// <returns>The result is a sort</returns>
|
||||
/// </summary>
|
||||
/// <param name="name">The name used to identify the sort</param>
|
||||
/// <param name="size">The size of the sort</param>
|
||||
public FiniteDomainSort MkFiniteDomainSort(Symbol name, ulong size)
|
||||
{
|
||||
Contract.Requires(name != null);
|
||||
|
@ -317,13 +317,13 @@ namespace Microsoft.Z3
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new finite domain sort.
|
||||
/// <param name="name">The name used to identify the sort</param>
|
||||
/// <param size="size">The size of the sort</param>
|
||||
/// <returns>The result is a sort</returns>
|
||||
/// Elements of the sort are created using <seealso cref="MkNumeral"/>,
|
||||
/// and the elements range from 0 to <tt>size-1</tt>.
|
||||
/// Create a new finite domain sort.
|
||||
/// <returns>The result is a sort</returns>
|
||||
/// Elements of the sort are created using <seealso cref="MkNumeral(ulong, Sort)"/>,
|
||||
/// and the elements range from 0 to <tt>size-1</tt>.
|
||||
/// </summary>
|
||||
/// <param name="name">The name used to identify the sort</param>
|
||||
/// <param name="size">The size of the sort</param>
|
||||
public FiniteDomainSort MkFiniteDomainSort(string name, ulong size)
|
||||
{
|
||||
Contract.Ensures(Contract.Result<FiniteDomainSort>() != null);
|
||||
|
@ -916,6 +916,8 @@ namespace Microsoft.Z3
|
|||
CheckContextMatch(t);
|
||||
return new BoolExpr(this, Native.Z3_mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Arithmetic
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(args, a => a != null));
|
||||
|
||||
Context.CheckContextMatch(args);
|
||||
if (args.Length != NumArgs)
|
||||
if (IsApp && args.Length != NumArgs)
|
||||
throw new Z3Exception("Number of arguments does not match");
|
||||
NativeObject = Native.Z3_update_term(Context.nCtx, NativeObject, (uint)args.Length, Expr.ArrayToNative(args));
|
||||
}
|
||||
|
@ -269,57 +269,58 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Indicates whether the term is the constant true.
|
||||
/// </summary>
|
||||
public bool IsTrue { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TRUE; } }
|
||||
public bool IsTrue { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TRUE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is the constant false.
|
||||
/// </summary>
|
||||
public bool IsFalse { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FALSE; } }
|
||||
public bool IsFalse { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FALSE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an equality predicate.
|
||||
/// </summary>
|
||||
public bool IsEq { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EQ; } }
|
||||
public bool IsEq { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct).
|
||||
/// </summary>
|
||||
public bool IsDistinct { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_DISTINCT; } }
|
||||
public bool IsDistinct { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_DISTINCT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a ternary if-then-else term
|
||||
/// </summary>
|
||||
public bool IsITE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ITE; } }
|
||||
public bool IsITE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ITE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an n-ary conjunction
|
||||
/// </summary>
|
||||
public bool IsAnd { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_AND; } }
|
||||
public bool IsAnd { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_AND; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an n-ary disjunction
|
||||
/// </summary>
|
||||
public bool IsOr { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_OR; } }
|
||||
public bool IsOr { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_OR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an if-and-only-if (Boolean equivalence, binary)
|
||||
/// </summary>
|
||||
public bool IsIff { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IFF; } }
|
||||
public bool IsIff { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IFF; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an exclusive or
|
||||
/// </summary>
|
||||
public bool IsXor { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_XOR; } }
|
||||
public bool IsXor { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_XOR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a negation
|
||||
/// </summary>
|
||||
public bool IsNot { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_NOT; } }
|
||||
public bool IsNot { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_NOT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an implication
|
||||
/// </summary>
|
||||
public bool IsImplies { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IMPLIES; } }
|
||||
public bool IsImplies { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IMPLIES; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Arithmetic Terms
|
||||
|
@ -346,82 +347,82 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Indicates whether the term is an arithmetic numeral.
|
||||
/// </summary>
|
||||
public bool IsArithmeticNumeral { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ANUM; } }
|
||||
public bool IsArithmeticNumeral { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ANUM; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a less-than-or-equal
|
||||
/// </summary>
|
||||
public bool IsLE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LE; } }
|
||||
public bool IsLE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a greater-than-or-equal
|
||||
/// </summary>
|
||||
public bool IsGE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_GE; } }
|
||||
public bool IsGE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_GE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a less-than
|
||||
/// </summary>
|
||||
public bool IsLT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LT; } }
|
||||
public bool IsLT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a greater-than
|
||||
/// </summary>
|
||||
public bool IsGT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_GT; } }
|
||||
public bool IsGT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_GT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is addition (binary)
|
||||
/// </summary>
|
||||
public bool IsAdd { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ADD; } }
|
||||
public bool IsAdd { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ADD; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is subtraction (binary)
|
||||
/// </summary>
|
||||
public bool IsSub { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SUB; } }
|
||||
public bool IsSub { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SUB; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a unary minus
|
||||
/// </summary>
|
||||
public bool IsUMinus { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UMINUS; } }
|
||||
public bool IsUMinus { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UMINUS; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is multiplication (binary)
|
||||
/// </summary>
|
||||
public bool IsMul { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_MUL; } }
|
||||
public bool IsMul { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_MUL; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is division (binary)
|
||||
/// </summary>
|
||||
public bool IsDiv { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_DIV; } }
|
||||
public bool IsDiv { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_DIV; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is integer division (binary)
|
||||
/// </summary>
|
||||
public bool IsIDiv { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IDIV; } }
|
||||
public bool IsIDiv { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IDIV; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is remainder (binary)
|
||||
/// </summary>
|
||||
public bool IsRemainder { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_REM; } }
|
||||
public bool IsRemainder { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_REM; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is modulus (binary)
|
||||
/// </summary>
|
||||
public bool IsModulus { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_MOD; } }
|
||||
public bool IsModulus { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_MOD; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a coercion of integer to real (unary)
|
||||
/// </summary>
|
||||
public bool IsIntToReal { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TO_REAL; } }
|
||||
public bool IsIntToReal { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TO_REAL; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a coercion of real to integer (unary)
|
||||
/// </summary>
|
||||
public bool IsRealToInt { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TO_INT; } }
|
||||
public bool IsRealToInt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TO_INT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a check that tests whether a real is integral (unary)
|
||||
/// </summary>
|
||||
public bool IsRealIsInt { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IS_INT; } }
|
||||
public bool IsRealIsInt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IS_INT; } }
|
||||
#endregion
|
||||
|
||||
#region Array Terms
|
||||
|
@ -443,64 +444,64 @@ namespace Microsoft.Z3
|
|||
/// </summary>
|
||||
/// <remarks>It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j).
|
||||
/// Array store takes at least 3 arguments. </remarks>
|
||||
public bool IsStore { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_STORE; } }
|
||||
public bool IsStore { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_STORE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an array select.
|
||||
/// </summary>
|
||||
public bool IsSelect { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SELECT; } }
|
||||
public bool IsSelect { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SELECT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a constant array.
|
||||
/// </summary>
|
||||
/// <remarks>For example, select(const(v),i) = v holds for every v and i. The function is unary.</remarks>
|
||||
public bool IsConstantArray { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CONST_ARRAY; } }
|
||||
public bool IsConstantArray { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CONST_ARRAY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a default array.
|
||||
/// </summary>
|
||||
/// <remarks>For example default(const(v)) = v. The function is unary.</remarks>
|
||||
public bool IsDefaultArray { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ARRAY_DEFAULT; } }
|
||||
public bool IsDefaultArray { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ARRAY_DEFAULT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an array map.
|
||||
/// </summary>
|
||||
/// <remarks>It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i.</remarks>
|
||||
public bool IsArrayMap { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ARRAY_MAP; } }
|
||||
public bool IsArrayMap { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ARRAY_MAP; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an as-array term.
|
||||
/// </summary>
|
||||
/// <remarks>An as-array term is n array value that behaves as the function graph of the
|
||||
/// function passed as parameter.</remarks>
|
||||
public bool IsAsArray { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_AS_ARRAY; } }
|
||||
public bool IsAsArray { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_AS_ARRAY; } }
|
||||
#endregion
|
||||
|
||||
#region Set Terms
|
||||
/// <summary>
|
||||
/// Indicates whether the term is set union
|
||||
/// </summary>
|
||||
public bool IsSetUnion { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_UNION; } }
|
||||
public bool IsSetUnion { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_UNION; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is set intersection
|
||||
/// </summary>
|
||||
public bool IsSetIntersect { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_INTERSECT; } }
|
||||
public bool IsSetIntersect { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_INTERSECT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is set difference
|
||||
/// </summary>
|
||||
public bool IsSetDifference { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_DIFFERENCE; } }
|
||||
public bool IsSetDifference { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_DIFFERENCE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is set complement
|
||||
/// </summary>
|
||||
public bool IsSetComplement { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_COMPLEMENT; } }
|
||||
public bool IsSetComplement { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_COMPLEMENT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is set subset
|
||||
/// </summary>
|
||||
public bool IsSetSubset { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_SUBSET; } }
|
||||
public bool IsSetSubset { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_SUBSET; } }
|
||||
#endregion
|
||||
|
||||
#region Bit-vector terms
|
||||
|
@ -515,266 +516,266 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector numeral
|
||||
/// </summary>
|
||||
public bool IsBVNumeral { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNUM; } }
|
||||
public bool IsBVNumeral { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNUM; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a one-bit bit-vector with value one
|
||||
/// </summary>
|
||||
public bool IsBVBitOne { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BIT1; } }
|
||||
public bool IsBVBitOne { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BIT1; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a one-bit bit-vector with value zero
|
||||
/// </summary>
|
||||
public bool IsBVBitZero { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BIT0; } }
|
||||
public bool IsBVBitZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BIT0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector unary minus
|
||||
/// </summary>
|
||||
public bool IsBVUMinus { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNEG; } }
|
||||
public bool IsBVUMinus { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNEG; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector addition (binary)
|
||||
/// </summary>
|
||||
public bool IsBVAdd { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BADD; } }
|
||||
public bool IsBVAdd { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BADD; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector subtraction (binary)
|
||||
/// </summary>
|
||||
public bool IsBVSub { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSUB; } }
|
||||
public bool IsBVSub { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSUB; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector multiplication (binary)
|
||||
/// </summary>
|
||||
public bool IsBVMul { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BMUL; } }
|
||||
public bool IsBVMul { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BMUL; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector signed division (binary)
|
||||
/// </summary>
|
||||
public bool IsBVSDiv { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSDIV; } }
|
||||
public bool IsBVSDiv { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSDIV; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector unsigned division (binary)
|
||||
/// </summary>
|
||||
public bool IsBVUDiv { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUDIV; } }
|
||||
public bool IsBVUDiv { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUDIV; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector signed remainder (binary)
|
||||
/// </summary>
|
||||
public bool IsBVSRem { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSREM; } }
|
||||
public bool IsBVSRem { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSREM; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector unsigned remainder (binary)
|
||||
/// </summary>
|
||||
public bool IsBVURem { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUREM; } }
|
||||
public bool IsBVURem { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUREM; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector signed modulus
|
||||
/// </summary>
|
||||
public bool IsBVSMod { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSMOD; } }
|
||||
public bool IsBVSMod { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSMOD; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector signed division by zero
|
||||
/// </summary>
|
||||
internal bool IsBVSDiv0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSDIV0; } }
|
||||
internal bool IsBVSDiv0 { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSDIV0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector unsigned division by zero
|
||||
/// </summary>
|
||||
internal bool IsBVUDiv0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUDIV0; } }
|
||||
internal bool IsBVUDiv0 { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUDIV0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector signed remainder by zero
|
||||
/// </summary>
|
||||
internal bool IsBVSRem0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSREM0; } }
|
||||
internal bool IsBVSRem0 { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSREM0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector unsigned remainder by zero
|
||||
/// </summary>
|
||||
internal bool IsBVURem0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUREM0; } }
|
||||
internal bool IsBVURem0 { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUREM0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector signed modulus by zero
|
||||
/// </summary>
|
||||
internal bool IsBVSMod0 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSMOD0; } }
|
||||
internal bool IsBVSMod0 { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSMOD0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an unsigned bit-vector less-than-or-equal
|
||||
/// </summary>
|
||||
public bool IsBVULE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ULEQ; } }
|
||||
public bool IsBVULE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ULEQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a signed bit-vector less-than-or-equal
|
||||
/// </summary>
|
||||
public bool IsBVSLE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SLEQ; } }
|
||||
public bool IsBVSLE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SLEQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an unsigned bit-vector greater-than-or-equal
|
||||
/// </summary>
|
||||
public bool IsBVUGE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UGEQ; } }
|
||||
public bool IsBVUGE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UGEQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a signed bit-vector greater-than-or-equal
|
||||
/// </summary>
|
||||
public bool IsBVSGE { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SGEQ; } }
|
||||
public bool IsBVSGE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SGEQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an unsigned bit-vector less-than
|
||||
/// </summary>
|
||||
public bool IsBVULT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ULT; } }
|
||||
public bool IsBVULT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ULT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a signed bit-vector less-than
|
||||
/// </summary>
|
||||
public bool IsBVSLT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SLT; } }
|
||||
public bool IsBVSLT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SLT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an unsigned bit-vector greater-than
|
||||
/// </summary>
|
||||
public bool IsBVUGT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UGT; } }
|
||||
public bool IsBVUGT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UGT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a signed bit-vector greater-than
|
||||
/// </summary>
|
||||
public bool IsBVSGT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SGT; } }
|
||||
public bool IsBVSGT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SGT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-wise AND
|
||||
/// </summary>
|
||||
public bool IsBVAND { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BAND; } }
|
||||
public bool IsBVAND { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BAND; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-wise OR
|
||||
/// </summary>
|
||||
public bool IsBVOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BOR; } }
|
||||
public bool IsBVOR { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BOR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-wise NOT
|
||||
/// </summary>
|
||||
public bool IsBVNOT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNOT; } }
|
||||
public bool IsBVNOT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNOT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-wise XOR
|
||||
/// </summary>
|
||||
public bool IsBVXOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BXOR; } }
|
||||
public bool IsBVXOR { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BXOR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-wise NAND
|
||||
/// </summary>
|
||||
public bool IsBVNAND { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNAND; } }
|
||||
public bool IsBVNAND { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNAND; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-wise NOR
|
||||
/// </summary>
|
||||
public bool IsBVNOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNOR; } }
|
||||
public bool IsBVNOR { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNOR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-wise XNOR
|
||||
/// </summary>
|
||||
public bool IsBVXNOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BXNOR; } }
|
||||
public bool IsBVXNOR { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BXNOR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector concatenation (binary)
|
||||
/// </summary>
|
||||
public bool IsBVConcat { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CONCAT; } }
|
||||
public bool IsBVConcat { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CONCAT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector sign extension
|
||||
/// </summary>
|
||||
public bool IsBVSignExtension { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SIGN_EXT; } }
|
||||
public bool IsBVSignExtension { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SIGN_EXT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector zero extension
|
||||
/// </summary>
|
||||
public bool IsBVZeroExtension { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ZERO_EXT; } }
|
||||
public bool IsBVZeroExtension { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ZERO_EXT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector extraction
|
||||
/// </summary>
|
||||
public bool IsBVExtract { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXTRACT; } }
|
||||
public bool IsBVExtract { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXTRACT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector repetition
|
||||
/// </summary>
|
||||
public bool IsBVRepeat { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_REPEAT; } }
|
||||
public bool IsBVRepeat { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_REPEAT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector reduce OR
|
||||
/// </summary>
|
||||
public bool IsBVReduceOR { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BREDOR; } }
|
||||
public bool IsBVReduceOR { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BREDOR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector reduce AND
|
||||
/// </summary>
|
||||
public bool IsBVReduceAND { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BREDAND; } }
|
||||
public bool IsBVReduceAND { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BREDAND; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector comparison
|
||||
/// </summary>
|
||||
public bool IsBVComp { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BCOMP; } }
|
||||
public bool IsBVComp { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BCOMP; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector shift left
|
||||
/// </summary>
|
||||
public bool IsBVShiftLeft { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSHL; } }
|
||||
public bool IsBVShiftLeft { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSHL; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector logical shift right
|
||||
/// </summary>
|
||||
public bool IsBVShiftRightLogical { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BLSHR; } }
|
||||
public bool IsBVShiftRightLogical { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BLSHR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector arithmetic shift left
|
||||
/// </summary>
|
||||
public bool IsBVShiftRightArithmetic { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BASHR; } }
|
||||
public bool IsBVShiftRightArithmetic { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BASHR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector rotate left
|
||||
/// </summary>
|
||||
public bool IsBVRotateLeft { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ROTATE_LEFT; } }
|
||||
public bool IsBVRotateLeft { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ROTATE_LEFT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector rotate right
|
||||
/// </summary>
|
||||
public bool IsBVRotateRight { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ROTATE_RIGHT; } }
|
||||
public bool IsBVRotateRight { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ROTATE_RIGHT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector rotate left (extended)
|
||||
/// </summary>
|
||||
/// <remarks>Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one.</remarks>
|
||||
public bool IsBVRotateLeftExtended { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXT_ROTATE_LEFT; } }
|
||||
public bool IsBVRotateLeftExtended { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXT_ROTATE_LEFT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector rotate right (extended)
|
||||
/// </summary>
|
||||
/// <remarks>Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one.</remarks>
|
||||
public bool IsBVRotateRightExtended { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXT_ROTATE_RIGHT; } }
|
||||
public bool IsBVRotateRightExtended { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXT_ROTATE_RIGHT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a coercion from integer to bit-vector
|
||||
/// </summary>
|
||||
/// <remarks>This function is not supported by the decision procedures. Only the most
|
||||
/// rudimentary simplification rules are applied to this function.</remarks>
|
||||
public bool IsIntToBV { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_INT2BV; } }
|
||||
public bool IsIntToBV { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_INT2BV; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a coercion from bit-vector to integer
|
||||
/// </summary>
|
||||
/// <remarks>This function is not supported by the decision procedures. Only the most
|
||||
/// rudimentary simplification rules are applied to this function.</remarks>
|
||||
public bool IsBVToInt { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BV2INT; } }
|
||||
public bool IsBVToInt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BV2INT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector carry
|
||||
/// </summary>
|
||||
/// <remarks>Compute the carry bit in a full-adder. The meaning is given by the
|
||||
/// equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3)))</remarks>
|
||||
public bool IsBVCarry { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CARRY; } }
|
||||
public bool IsBVCarry { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CARRY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a bit-vector ternary XOR
|
||||
/// </summary>
|
||||
/// <remarks>The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3)</remarks>
|
||||
public bool IsBVXOR3 { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_XOR3; } }
|
||||
public bool IsBVXOR3 { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_XOR3; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -783,13 +784,13 @@ namespace Microsoft.Z3
|
|||
/// Indicates whether the term is a label (used by the Boogie Verification condition generator).
|
||||
/// </summary>
|
||||
/// <remarks>The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula.</remarks>
|
||||
public bool IsLabel { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LABEL; } }
|
||||
public bool IsLabel { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LABEL; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a label literal (used by the Boogie Verification condition generator).
|
||||
/// </summary>
|
||||
/// <remarks>A label literal has a set of string parameters. It takes no arguments.</remarks>
|
||||
public bool IsLabelLit { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LABEL_LIT; } }
|
||||
public bool IsLabelLit { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LABEL_LIT; } }
|
||||
#endregion
|
||||
|
||||
#region Proof Terms
|
||||
|
@ -798,22 +799,22 @@ namespace Microsoft.Z3
|
|||
/// </summary>
|
||||
/// <remarks>This binary predicate is used in proof terms.
|
||||
/// It captures equisatisfiability and equivalence modulo renamings.</remarks>
|
||||
public bool IsOEQ { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_OEQ; } }
|
||||
public bool IsOEQ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_OEQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a Proof for the expression 'true'.
|
||||
/// </summary>
|
||||
public bool IsProofTrue { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRUE; } }
|
||||
public bool IsProofTrue { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRUE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for a fact asserted by the user.
|
||||
/// </summary>
|
||||
public bool IsProofAsserted { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_ASSERTED; } }
|
||||
public bool IsProofAsserted { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_ASSERTED; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user.
|
||||
/// </summary>
|
||||
public bool IsProofGoal { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_GOAL; } }
|
||||
public bool IsProofGoal { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_GOAL; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is proof via modus ponens
|
||||
|
@ -824,7 +825,7 @@ namespace Microsoft.Z3
|
|||
/// T2: (implies p q)
|
||||
/// [mp T1 T2]: q
|
||||
/// The second antecedents may also be a proof for (iff p q).</remarks>
|
||||
public bool IsProofModusPonens { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS; } }
|
||||
public bool IsProofModusPonens { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for (R t t), where R is a reflexive relation.
|
||||
|
@ -833,7 +834,7 @@ namespace Microsoft.Z3
|
|||
/// The only reflexive relations that are used are
|
||||
/// equivalence modulo namings, equality and equivalence.
|
||||
/// That is, R is either '~', '=' or 'iff'.</remarks>
|
||||
public bool IsProofReflexivity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REFLEXIVITY; } }
|
||||
public bool IsProofReflexivity { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REFLEXIVITY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is proof by symmetricity of a relation
|
||||
|
@ -844,7 +845,7 @@ namespace Microsoft.Z3
|
|||
/// [symmetry T1]: (R s t)
|
||||
/// T1 is the antecedent of this proof object.
|
||||
/// </remarks>
|
||||
public bool IsProofSymmetry { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_SYMMETRY; } }
|
||||
public bool IsProofSymmetry { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_SYMMETRY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by transitivity of a relation
|
||||
|
@ -856,7 +857,7 @@ namespace Microsoft.Z3
|
|||
/// T2: (R s u)
|
||||
/// [trans T1 T2]: (R t u)
|
||||
/// </remarks>
|
||||
public bool IsProofTransitivity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY; } }
|
||||
public bool IsProofTransitivity { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by condensed transitivity of a relation
|
||||
|
@ -877,7 +878,7 @@ namespace Microsoft.Z3
|
|||
/// if there is a path from s to t, if we view every
|
||||
/// antecedent (R a b) as an edge between a and b.
|
||||
/// </remarks>
|
||||
public bool IsProofTransitivityStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY_STAR; } }
|
||||
public bool IsProofTransitivityStar { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY_STAR; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -891,7 +892,7 @@ namespace Microsoft.Z3
|
|||
/// Remark: if t_i == s_i, then the antecedent Ti is suppressed.
|
||||
/// That is, reflexivity proofs are supressed to save space.
|
||||
/// </remarks>
|
||||
public bool IsProofMonotonicity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MONOTONICITY; } }
|
||||
public bool IsProofMonotonicity { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MONOTONICITY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a quant-intro proof
|
||||
|
@ -901,7 +902,7 @@ namespace Microsoft.Z3
|
|||
/// T1: (~ p q)
|
||||
/// [quant-intro T1]: (~ (forall (x) p) (forall (x) q))
|
||||
/// </remarks>
|
||||
public bool IsProofQuantIntro { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_QUANT_INTRO; } }
|
||||
public bool IsProofQuantIntro { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_QUANT_INTRO; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a distributivity proof object.
|
||||
|
@ -919,7 +920,7 @@ namespace Microsoft.Z3
|
|||
/// Remark. This rule is used by the CNF conversion pass and
|
||||
/// instantiated by f = or, and g = and.
|
||||
/// </remarks>
|
||||
public bool IsProofDistributivity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DISTRIBUTIVITY; } }
|
||||
public bool IsProofDistributivity { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DISTRIBUTIVITY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by elimination of AND
|
||||
|
@ -929,7 +930,7 @@ namespace Microsoft.Z3
|
|||
/// T1: (and l_1 ... l_n)
|
||||
/// [and-elim T1]: l_i
|
||||
/// </remarks>
|
||||
public bool IsProofAndElimination { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_AND_ELIM; } }
|
||||
public bool IsProofAndElimination { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_AND_ELIM; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by eliminiation of not-or
|
||||
|
@ -939,7 +940,7 @@ namespace Microsoft.Z3
|
|||
/// T1: (not (or l_1 ... l_n))
|
||||
/// [not-or-elim T1]: (not l_i)
|
||||
/// </remarks>
|
||||
public bool IsProofOrElimination { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NOT_OR_ELIM; } }
|
||||
public bool IsProofOrElimination { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NOT_OR_ELIM; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by rewriting
|
||||
|
@ -958,7 +959,7 @@ namespace Microsoft.Z3
|
|||
/// (= (+ x 1 2) (+ 3 x))
|
||||
/// (iff (or x false) x)
|
||||
/// </remarks>
|
||||
public bool IsProofRewrite { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REWRITE; } }
|
||||
public bool IsProofRewrite { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REWRITE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by rewriting
|
||||
|
@ -974,7 +975,7 @@ namespace Microsoft.Z3
|
|||
/// - When converting bit-vectors to Booleans (BIT2BOOL=true)
|
||||
/// - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true)
|
||||
/// </remarks>
|
||||
public bool IsProofRewriteStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REWRITE_STAR; } }
|
||||
public bool IsProofRewriteStar { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REWRITE_STAR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for pulling quantifiers out.
|
||||
|
@ -982,7 +983,7 @@ namespace Microsoft.Z3
|
|||
/// <remarks>
|
||||
/// A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents.
|
||||
/// </remarks>
|
||||
public bool IsProofPullQuant { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PULL_QUANT; } }
|
||||
public bool IsProofPullQuant { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PULL_QUANT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for pulling quantifiers out.
|
||||
|
@ -992,7 +993,7 @@ namespace Microsoft.Z3
|
|||
/// This proof object is only used if the parameter PROOF_MODE is 1.
|
||||
/// This proof object has no antecedents
|
||||
/// </remarks>
|
||||
public bool IsProofPullQuantStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PULL_QUANT_STAR; } }
|
||||
public bool IsProofPullQuantStar { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PULL_QUANT_STAR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for pushing quantifiers in.
|
||||
|
@ -1005,7 +1006,7 @@ namespace Microsoft.Z3
|
|||
/// (forall (x_1 ... x_m) p_n[x_1 ... x_m])))
|
||||
/// This proof object has no antecedents
|
||||
/// </remarks>
|
||||
public bool IsProofPushQuant { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PUSH_QUANT; } }
|
||||
public bool IsProofPushQuant { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PUSH_QUANT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for elimination of unused variables.
|
||||
|
@ -1017,7 +1018,7 @@ namespace Microsoft.Z3
|
|||
/// It is used to justify the elimination of unused variables.
|
||||
/// This proof object has no antecedents.
|
||||
/// </remarks>
|
||||
public bool IsProofElimUnusedVars { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_ELIM_UNUSED_VARS; } }
|
||||
public bool IsProofElimUnusedVars { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_ELIM_UNUSED_VARS; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for destructive equality resolution
|
||||
|
@ -1031,7 +1032,7 @@ namespace Microsoft.Z3
|
|||
///
|
||||
/// Several variables can be eliminated simultaneously.
|
||||
/// </remarks>
|
||||
public bool IsProofDER { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DER; } }
|
||||
public bool IsProofDER { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DER; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for quantifier instantiation
|
||||
|
@ -1039,13 +1040,13 @@ namespace Microsoft.Z3
|
|||
/// <remarks>
|
||||
/// A proof of (or (not (forall (x) (P x))) (P a))
|
||||
/// </remarks>
|
||||
public bool IsProofQuantInst { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_QUANT_INST; } }
|
||||
public bool IsProofQuantInst { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_QUANT_INST; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a hypthesis marker.
|
||||
/// </summary>
|
||||
/// <remarks>Mark a hypothesis in a natural deduction style proof.</remarks>
|
||||
public bool IsProofHypothesis { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_HYPOTHESIS; } }
|
||||
public bool IsProofHypothesis { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_HYPOTHESIS; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by lemma
|
||||
|
@ -1058,7 +1059,7 @@ namespace Microsoft.Z3
|
|||
/// It converts the proof in a proof for (or (not l_1) ... (not l_n)),
|
||||
/// when T1 contains the hypotheses: l_1, ..., l_n.
|
||||
/// </remarks>
|
||||
public bool IsProofLemma { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_LEMMA; } }
|
||||
public bool IsProofLemma { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_LEMMA; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by unit resolution
|
||||
|
@ -1070,7 +1071,7 @@ namespace Microsoft.Z3
|
|||
/// T(n+1): (not l_n)
|
||||
/// [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m')
|
||||
/// </remarks>
|
||||
public bool IsProofUnitResolution { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_UNIT_RESOLUTION; } }
|
||||
public bool IsProofUnitResolution { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_UNIT_RESOLUTION; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by iff-true
|
||||
|
@ -1079,7 +1080,7 @@ namespace Microsoft.Z3
|
|||
/// T1: p
|
||||
/// [iff-true T1]: (iff p true)
|
||||
/// </remarks>
|
||||
public bool IsProofIFFTrue { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_TRUE; } }
|
||||
public bool IsProofIFFTrue { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_TRUE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by iff-false
|
||||
|
@ -1088,7 +1089,7 @@ namespace Microsoft.Z3
|
|||
/// T1: (not p)
|
||||
/// [iff-false T1]: (iff p false)
|
||||
/// </remarks>
|
||||
public bool IsProofIFFFalse { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_FALSE; } }
|
||||
public bool IsProofIFFFalse { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_FALSE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by commutativity
|
||||
|
@ -1101,7 +1102,7 @@ namespace Microsoft.Z3
|
|||
/// This proof object has no antecedents.
|
||||
/// Remark: if f is bool, then = is iff.
|
||||
/// </remarks>
|
||||
public bool IsProofCommutativity { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_COMMUTATIVITY; } }
|
||||
public bool IsProofCommutativity { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_COMMUTATIVITY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for Tseitin-like axioms
|
||||
|
@ -1137,7 +1138,7 @@ namespace Microsoft.Z3
|
|||
/// unfolding the Boolean connectives in the axioms a small
|
||||
/// bounded number of steps (=3).
|
||||
/// </remarks>
|
||||
public bool IsProofDefAxiom { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DEF_AXIOM; } }
|
||||
public bool IsProofDefAxiom { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DEF_AXIOM; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for introduction of a name
|
||||
|
@ -1160,7 +1161,7 @@ namespace Microsoft.Z3
|
|||
/// Otherwise:
|
||||
/// [def-intro]: (= n e)
|
||||
/// </remarks>
|
||||
public bool IsProofDefIntro { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DEF_INTRO; } }
|
||||
public bool IsProofDefIntro { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DEF_INTRO; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for application of a definition
|
||||
|
@ -1170,7 +1171,7 @@ namespace Microsoft.Z3
|
|||
/// F is 'equivalent' to n, given that T1 is a proof that
|
||||
/// n is a name for F.
|
||||
/// </remarks>
|
||||
public bool IsProofApplyDef { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_APPLY_DEF; } }
|
||||
public bool IsProofApplyDef { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_APPLY_DEF; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof iff-oeq
|
||||
|
@ -1179,7 +1180,7 @@ namespace Microsoft.Z3
|
|||
/// T1: (iff p q)
|
||||
/// [iff~ T1]: (~ p q)
|
||||
/// </remarks>
|
||||
public bool IsProofIFFOEQ { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_OEQ; } }
|
||||
public bool IsProofIFFOEQ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_OEQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for a positive NNF step
|
||||
|
@ -1207,7 +1208,7 @@ namespace Microsoft.Z3
|
|||
/// NNF_NEG furthermore handles the case where negation is pushed
|
||||
/// over Boolean connectives 'and' and 'or'.
|
||||
/// </remarks>
|
||||
public bool IsProofNNFPos { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_POS; } }
|
||||
public bool IsProofNNFPos { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_POS; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for a negative NNF step
|
||||
|
@ -1232,7 +1233,7 @@ namespace Microsoft.Z3
|
|||
/// [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2))
|
||||
/// (and (or r_1 r_2) (or r_1' r_2')))
|
||||
/// </remarks>
|
||||
public bool IsProofNNFNeg { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_NEG; } }
|
||||
public bool IsProofNNFNeg { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_NEG; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form.
|
||||
|
@ -1244,7 +1245,7 @@ namespace Microsoft.Z3
|
|||
///
|
||||
/// This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO.
|
||||
/// </remarks>
|
||||
public bool IsProofNNFStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_STAR; } }
|
||||
public bool IsProofNNFStar { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_STAR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form.
|
||||
|
@ -1254,7 +1255,7 @@ namespace Microsoft.Z3
|
|||
/// This proof object is only used if the parameter PROOF_MODE is 1.
|
||||
/// This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO.
|
||||
/// </remarks>
|
||||
public bool IsProofCNFStar { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_CNF_STAR; } }
|
||||
public bool IsProofCNFStar { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_CNF_STAR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for a Skolemization step
|
||||
|
@ -1267,7 +1268,7 @@ namespace Microsoft.Z3
|
|||
///
|
||||
/// This proof object has no antecedents.
|
||||
/// </remarks>
|
||||
public bool IsProofSkolemize { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_SKOLEMIZE; } }
|
||||
public bool IsProofSkolemize { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_SKOLEMIZE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof by modus ponens for equi-satisfiability.
|
||||
|
@ -1278,7 +1279,7 @@ namespace Microsoft.Z3
|
|||
/// T2: (~ p q)
|
||||
/// [mp~ T1 T2]: q
|
||||
/// </remarks>
|
||||
public bool IsProofModusPonensOEQ { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS_OEQ; } }
|
||||
public bool IsProofModusPonensOEQ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS_OEQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a proof for theory lemma
|
||||
|
@ -1297,7 +1298,7 @@ namespace Microsoft.Z3
|
|||
/// (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1)))
|
||||
/// - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test.
|
||||
/// </remarks>
|
||||
public bool IsProofTheoryLemma { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TH_LEMMA; } }
|
||||
public bool IsProofTheoryLemma { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TH_LEMMA; } }
|
||||
#endregion
|
||||
|
||||
#region Relational Terms
|
||||
|
@ -1322,40 +1323,40 @@ namespace Microsoft.Z3
|
|||
/// The function takes <c>n+1</c> arguments, where the first argument is the relation and the remaining <c>n</c> elements
|
||||
/// correspond to the <c>n</c> columns of the relation.
|
||||
/// </remarks>
|
||||
public bool IsRelationStore { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_STORE; } }
|
||||
public bool IsRelationStore { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_STORE; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an empty relation
|
||||
/// </summary>
|
||||
public bool IsEmptyRelation { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_EMPTY; } }
|
||||
public bool IsEmptyRelation { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_EMPTY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a test for the emptiness of a relation
|
||||
/// </summary>
|
||||
public bool IsIsEmptyRelation { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_IS_EMPTY; } }
|
||||
public bool IsIsEmptyRelation { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_IS_EMPTY; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a relational join
|
||||
/// </summary>
|
||||
public bool IsRelationalJoin { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_JOIN; } }
|
||||
public bool IsRelationalJoin { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_JOIN; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is the union or convex hull of two relations.
|
||||
/// </summary>
|
||||
/// <remarks>The function takes two arguments.</remarks>
|
||||
public bool IsRelationUnion { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_UNION; } }
|
||||
public bool IsRelationUnion { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_UNION; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is the widening of two relations
|
||||
/// </summary>
|
||||
/// <remarks>The function takes two arguments.</remarks>
|
||||
public bool IsRelationWiden { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_WIDEN; } }
|
||||
public bool IsRelationWiden { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_WIDEN; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a projection of columns (provided as numbers in the parameters).
|
||||
/// </summary>
|
||||
/// <remarks>The function takes one argument.</remarks>
|
||||
public bool IsRelationProject { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_PROJECT; } }
|
||||
public bool IsRelationProject { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_PROJECT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a relation filter
|
||||
|
@ -1367,7 +1368,7 @@ namespace Microsoft.Z3
|
|||
/// corresponding to the columns of the relation.
|
||||
/// So the first column in the relation has index 0.
|
||||
/// </remarks>
|
||||
public bool IsRelationFilter { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_FILTER; } }
|
||||
public bool IsRelationFilter { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_FILTER; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is an intersection of a relation with the negation of another.
|
||||
|
@ -1383,7 +1384,7 @@ namespace Microsoft.Z3
|
|||
/// target are elements in x in pos, such that there is no y in neg that agrees with
|
||||
/// x on the columns c1, d1, .., cN, dN.
|
||||
/// </remarks>
|
||||
public bool IsRelationNegationFilter { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_NEGATION_FILTER; } }
|
||||
public bool IsRelationNegationFilter { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_NEGATION_FILTER; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is the renaming of a column in a relation
|
||||
|
@ -1392,12 +1393,12 @@ namespace Microsoft.Z3
|
|||
/// The function takes one argument.
|
||||
/// The parameters contain the renaming as a cycle.
|
||||
/// </remarks>
|
||||
public bool IsRelationRename { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_RENAME; } }
|
||||
public bool IsRelationRename { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_RENAME; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is the complement of a relation
|
||||
/// </summary>
|
||||
public bool IsRelationComplement { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_COMPLEMENT; } }
|
||||
public bool IsRelationComplement { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_COMPLEMENT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a relational select
|
||||
|
@ -1407,7 +1408,7 @@ namespace Microsoft.Z3
|
|||
/// The function takes <c>n+1</c> arguments, where the first argument is a relation,
|
||||
/// and the remaining <c>n</c> arguments correspond to a record.
|
||||
/// </remarks>
|
||||
public bool IsRelationSelect { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_SELECT; } }
|
||||
public bool IsRelationSelect { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_SELECT; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the term is a relational clone (copy)
|
||||
|
@ -1419,7 +1420,7 @@ namespace Microsoft.Z3
|
|||
/// for terms of kind <seealso cref="IsRelationUnion"/>
|
||||
/// to perform destructive updates to the first argument.
|
||||
/// </remarks>
|
||||
public bool IsRelationClone { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_CLONE; } }
|
||||
public bool IsRelationClone { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_CLONE; } }
|
||||
#endregion
|
||||
|
||||
#region Finite domain terms
|
||||
|
@ -1438,7 +1439,7 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Indicates whether the term is a less than predicate over a finite domain.
|
||||
/// </summary>
|
||||
public bool IsFiniteDomainLT { get { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FD_LT; } }
|
||||
public bool IsFiniteDomainLT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FD_LT; } }
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace Microsoft.Z3
|
|||
/// The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'.
|
||||
/// Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION".
|
||||
/// This function can be used to set parameters for a specific Z3 module.
|
||||
/// This can be done by using <module-name>.<parameter-name>.
|
||||
/// This can be done by using [module-name].[parameter-name].
|
||||
/// For example:
|
||||
/// Z3_global_param_set('pp.decimal', 'true')
|
||||
/// will set the parameter "decimal" in the module "pp" to true.
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DocumentationFile>..\Debug\Microsoft.Z3.XML</DocumentationFile>
|
||||
<CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
|
||||
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
|
||||
<CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
|
||||
|
@ -140,6 +139,7 @@
|
|||
<CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
|
||||
<CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
|
||||
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
|
||||
<DocumentationFile>..\x64\Debug\Microsoft.Z3.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>..\x64\external_64\</OutputPath>
|
||||
|
@ -193,7 +193,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'external|x64'">
|
||||
<OutputPath>..\x64\external\</OutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>..\external\Microsoft.Z3.xml</DocumentationFile>
|
||||
<DocumentationFile>..\x64\external\Microsoft.Z3.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
|
@ -220,7 +220,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_delaysign|AnyCPU'">
|
||||
<OutputPath>..\Release_delaysign\</OutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>..\Release_delaysign\Microsoft.Z3.xml</DocumentationFile>
|
||||
<DocumentationFile>..\Release_delaysign\Microsoft.Z3.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
@ -238,7 +238,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_delaysign|x64'">
|
||||
<OutputPath>bin\x64\Release_delaysign\</OutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>..\x64\external_64\Microsoft.Z3.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\x64\Release_delaysign\Microsoft.Z3.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
|
@ -266,11 +266,12 @@
|
|||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
|
||||
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
|
||||
<DocumentationFile>bin\x86\Debug\Microsoft.Z3.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>..\external\Microsoft.Z3.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\x86\Release\Microsoft.Z3.xml</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
|
@ -285,7 +286,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'external|x86'">
|
||||
<OutputPath>bin\x86\external\</OutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>..\external\Microsoft.Z3.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\x86\external\Microsoft.Z3.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
|
@ -303,7 +304,7 @@
|
|||
<OutputPath>bin\x86\Release_delaysign\</OutputPath>
|
||||
<DefineConstants>DELAYSIGN</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>..\Release_delaysign\Microsoft.Z3.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\x86\Release_delaysign\Microsoft.Z3.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
|
|
|
@ -132,7 +132,8 @@ namespace Microsoft.Z3
|
|||
/// <remarks>
|
||||
/// This API is an alternative to <see cref="Check"/> 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"/> and the Boolean literals
|
||||
/// of the Boolean variables provided using <see cref="AssertAndTrack(BoolExpr[],BoolExpr[])"/>
|
||||
/// and the Boolean literals
|
||||
/// provided using <see cref="Check"/> with assumptions.
|
||||
/// </remarks>
|
||||
public void AssertAndTrack(BoolExpr[] constraints, BoolExpr[] ps)
|
||||
|
@ -156,7 +157,8 @@ namespace Microsoft.Z3
|
|||
/// <remarks>
|
||||
/// This API is an alternative to <see cref="Check"/> 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"/> and the Boolean literals
|
||||
/// of the Boolean variables provided using <see cref="AssertAndTrack(BoolExpr[],BoolExpr[])"/>
|
||||
/// and the Boolean literals
|
||||
/// provided using <see cref="Check"/> with assumptions.
|
||||
/// </remarks>
|
||||
public void AssertAndTrack(BoolExpr constraint, BoolExpr p)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -386,7 +386,7 @@ def seq3(args, lp='(', rp=')'):
|
|||
else:
|
||||
return group(indent(len(lp), compose(to_format(lp), seq(args), to_format(rp))))
|
||||
|
||||
class StopPPException:
|
||||
class StopPPException(Exception):
|
||||
def __str__(self):
|
||||
return 'pp-interrupted'
|
||||
|
||||
|
|
|
@ -472,6 +472,25 @@ class smt2_printer {
|
|||
ast_manager & m() const { return m_manager; }
|
||||
ast_manager & fm() const { return format_ns::fm(m()); }
|
||||
|
||||
std::string ensure_quote(symbol const& s) {
|
||||
std::string str;
|
||||
if (is_smt2_quoted_symbol(s))
|
||||
str = mk_smt2_quoted_symbol(s);
|
||||
else
|
||||
str = s.str();
|
||||
return str;
|
||||
}
|
||||
|
||||
symbol ensure_quote_sym(symbol const& s) {
|
||||
if (is_smt2_quoted_symbol(s)) {
|
||||
std::string str;
|
||||
str = mk_smt2_quoted_symbol(s);
|
||||
return symbol(str.c_str());
|
||||
}
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
||||
void pp_var(var * v) {
|
||||
format * f;
|
||||
if (v->get_idx() < m_var_names.size()) {
|
||||
|
@ -501,11 +520,7 @@ class smt2_printer {
|
|||
}
|
||||
|
||||
format * pp_simple_attribute(char const * attr, symbol const & s) {
|
||||
std::string str;
|
||||
if (is_smt2_quoted_symbol(s))
|
||||
str = mk_smt2_quoted_symbol(s);
|
||||
else
|
||||
str = s.str();
|
||||
std::string str = ensure_quote(s);
|
||||
return mk_compose(m(), mk_string(m(), attr), mk_string(m(), str.c_str()));
|
||||
}
|
||||
|
||||
|
@ -773,7 +788,7 @@ class smt2_printer {
|
|||
void register_var_names(quantifier * q) {
|
||||
unsigned num_decls = q->get_num_decls();
|
||||
for (unsigned i = 0; i < num_decls; i++) {
|
||||
symbol name = q->get_decl_name(i);
|
||||
symbol name = ensure_quote_sym(q->get_decl_name(i));
|
||||
if (name.is_numerical()) {
|
||||
unsigned idx = 1;
|
||||
name = next_name("x", idx);
|
||||
|
@ -997,6 +1012,7 @@ public:
|
|||
unsigned idx = 1;
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
symbol name = next_name(var_prefix, idx);
|
||||
name = ensure_quote_sym(name);
|
||||
var_names.push_back(name);
|
||||
m_var_names_set.insert(name);
|
||||
m_var_names.push_back(name);
|
||||
|
|
|
@ -753,12 +753,7 @@ br_status arith_rewriter::mk_rem_core(expr * arg1, expr * arg2, expr_ref & resul
|
|||
}
|
||||
else if (m_util.is_numeral(arg2, v2, is_int) && is_int && !v2.is_zero()) {
|
||||
if (is_add(arg1) || is_mul(arg1)) {
|
||||
ptr_buffer<expr> new_args;
|
||||
unsigned num_args = to_app(arg1)->get_num_args();
|
||||
for (unsigned i = 0; i < num_args; i++)
|
||||
new_args.push_back(m_util.mk_rem(to_app(arg1)->get_arg(i), arg2));
|
||||
result = m().mk_app(to_app(arg1)->get_decl(), new_args.size(), new_args.c_ptr());
|
||||
return BR_REWRITE2;
|
||||
return BR_FAILED;
|
||||
}
|
||||
else {
|
||||
if (v2.is_neg()) {
|
||||
|
|
|
@ -310,6 +310,8 @@ struct check_logic::imp {
|
|||
return false;
|
||||
non_numeral = arg;
|
||||
}
|
||||
if (non_numeral == 0)
|
||||
return true;
|
||||
if (is_diff_var(non_numeral))
|
||||
return true;
|
||||
if (!m_a_util.is_add(non_numeral) && !m_a_util.is_sub(non_numeral))
|
||||
|
|
|
@ -515,6 +515,25 @@ bool pdatatype_decl::has_missing_refs(symbol & missing) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool pdatatype_decl::has_duplicate_accessors(symbol & duplicated) const {
|
||||
hashtable<symbol, symbol_hash_proc, symbol_eq_proc> names;
|
||||
ptr_vector<pconstructor_decl>::const_iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::const_iterator end = m_constructors.end();
|
||||
for (; it != end; ++it) {
|
||||
ptr_vector<paccessor_decl> const& acc = (*it)->m_accessors;
|
||||
for (unsigned i = 0; i < acc.size(); ++i) {
|
||||
symbol const& name = acc[i]->get_name();
|
||||
if (names.contains(name)) {
|
||||
duplicated = name;
|
||||
return true;
|
||||
}
|
||||
names.insert(name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool pdatatype_decl::fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing) {
|
||||
ptr_vector<pconstructor_decl>::iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::iterator end = m_constructors.end();
|
||||
|
|
|
@ -169,6 +169,7 @@ public:
|
|||
class paccessor_decl : public pdecl {
|
||||
friend class pdecl_manager;
|
||||
friend class pconstructor_decl;
|
||||
friend class pdatatype_decl;
|
||||
symbol m_name;
|
||||
ptype m_type;
|
||||
paccessor_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, ptype const & r);
|
||||
|
@ -222,6 +223,7 @@ public:
|
|||
sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s);
|
||||
virtual void display(std::ostream & out) const;
|
||||
bool has_missing_refs(symbol & missing) const;
|
||||
bool has_duplicate_accessors(symbol & repeated) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,169 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3hash.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Wrapper for stl hash tables
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
// pull in the headers for has_map and hash_set
|
||||
// these live in non-standard places
|
||||
|
||||
#ifndef IZ3_HASH_H
|
||||
#define IZ3_HASH_H
|
||||
|
||||
//#define USE_UNORDERED_MAP
|
||||
#ifdef USE_UNORDERED_MAP
|
||||
|
||||
#define stl_ext std
|
||||
#define hash_space std
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#define hash_map unordered_map
|
||||
#define hash_set unordered_set
|
||||
|
||||
#else
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#undef __DEPRECATED
|
||||
#define stl_ext __gnu_cxx
|
||||
#define hash_space stl_ext
|
||||
#include <ext/hash_map>
|
||||
#include <ext/hash_set>
|
||||
#else
|
||||
#ifdef WIN32
|
||||
#define stl_ext stdext
|
||||
#define hash_space std
|
||||
#include <hash_map>
|
||||
#include <hash_set>
|
||||
#else
|
||||
#define stl_ext std
|
||||
#define hash_space std
|
||||
#include <hash_map>
|
||||
#include <hash_set>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
// stupid STL doesn't include hash function for class string
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
namespace stl_ext {
|
||||
template <>
|
||||
class hash<std::string> {
|
||||
stl_ext::hash<char *> H;
|
||||
public:
|
||||
size_t operator()(const std::string &s) const {
|
||||
return H(s.c_str());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace hash_space {
|
||||
template <>
|
||||
class hash<std::pair<int,int> > {
|
||||
public:
|
||||
size_t operator()(const std::pair<int,int> &p) const {
|
||||
return p.first + p.second;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
template <> inline
|
||||
size_t stdext::hash_value<std::pair<int,int> >(const std::pair<int,int>& p)
|
||||
{ // hash _Keyval to size_t value one-to-one
|
||||
return p.first + p.second;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace hash_space {
|
||||
template <class T>
|
||||
class hash<std::pair<T *, T *> > {
|
||||
public:
|
||||
size_t operator()(const std::pair<T *,T *> &p) const {
|
||||
return (size_t)p.first + (size_t)p.second;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#if 0
|
||||
template <class T> inline
|
||||
size_t stdext::hash_value<std::pair<T *, T *> >(const std::pair<T *, T *>& p)
|
||||
{ // hash _Keyval to size_t value one-to-one
|
||||
return (size_t)p.first + (size_t)p.second;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class less<std::pair<int,int> > {
|
||||
public:
|
||||
bool operator()(const pair<int,int> &x, const pair<int,int> &y) const {
|
||||
return x.first < y.first || x.first == y.first && x.second < y.second;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <class T>
|
||||
class less<std::pair<T *,T *> > {
|
||||
public:
|
||||
bool operator()(const pair<T *,T *> &x, const pair<T *,T *> &y) const {
|
||||
return (size_t)x.first < (size_t)y.first || (size_t)x.first == (size_t)y.first && (size_t)x.second < (size_t)y.second;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
namespace stl_ext {
|
||||
template <class T>
|
||||
class hash<T *> {
|
||||
public:
|
||||
size_t operator()(const T *p) const {
|
||||
return (size_t) p;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
|
||||
|
||||
|
||||
template <class K, class T>
|
||||
class hash_map : public stl_ext::hash_map<K,T,stl_ext::hash_compare<K,std::less<K> > > {};
|
||||
|
||||
template <class K>
|
||||
class hash_set : public stl_ext::hash_set<K,stl_ext::hash_compare<K,std::less<K> > > {};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,134 +1,134 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
duality_profiling.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
collection performance information for duality
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
#endif
|
||||
|
||||
#include "duality_wrapper.h"
|
||||
#include "iz3profiling.h"
|
||||
|
||||
namespace Duality {
|
||||
|
||||
void show_time(){
|
||||
output_time(std::cout,current_time());
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
typedef std::map<const char*, struct node> nmap;
|
||||
|
||||
struct node {
|
||||
std::string name;
|
||||
clock_t time;
|
||||
clock_t start_time;
|
||||
nmap sub;
|
||||
struct node *parent;
|
||||
|
||||
node();
|
||||
} top;
|
||||
|
||||
node::node(){
|
||||
time = 0;
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
struct node *current;
|
||||
|
||||
struct init {
|
||||
init(){
|
||||
top.name = "TOTAL";
|
||||
current = ⊤
|
||||
}
|
||||
} initializer;
|
||||
|
||||
struct time_entry {
|
||||
clock_t t;
|
||||
time_entry(){t = 0;};
|
||||
void add(clock_t incr){t += incr;}
|
||||
};
|
||||
|
||||
struct ltstr
|
||||
{
|
||||
bool operator()(const char* s1, const char* s2) const
|
||||
{
|
||||
return strcmp(s1, s2) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<const char*, time_entry, ltstr> tmap;
|
||||
|
||||
static std::ostream *pfs;
|
||||
|
||||
void print_node(node &top, int indent, tmap &totals){
|
||||
for(int i = 0; i < indent; i++) (*pfs) << " ";
|
||||
(*pfs) << top.name;
|
||||
int dots = 70 - 2 * indent - top.name.size();
|
||||
for(int i = 0; i <dots; i++) (*pfs) << ".";
|
||||
output_time(*pfs, top.time);
|
||||
(*pfs) << std::endl;
|
||||
if(indent != 0)totals[top.name.c_str()].add(top.time);
|
||||
for(nmap::iterator it = top.sub.begin(); it != top.sub.end(); it++)
|
||||
print_node(it->second,indent+1,totals);
|
||||
}
|
||||
|
||||
void print_profile(std::ostream &os) {
|
||||
pfs = &os;
|
||||
top.time = 0;
|
||||
for(nmap::iterator it = top.sub.begin(); it != top.sub.end(); it++)
|
||||
top.time += it->second.time;
|
||||
tmap totals;
|
||||
print_node(top,0,totals);
|
||||
(*pfs) << "TOTALS:" << std::endl;
|
||||
for(tmap::iterator it = totals.begin(); it != totals.end(); it++){
|
||||
(*pfs) << (it->first) << " ";
|
||||
output_time(*pfs, it->second.t);
|
||||
(*pfs) << std::endl;
|
||||
}
|
||||
profiling::print(os); // print the interpolation stats
|
||||
}
|
||||
|
||||
void timer_start(const char *name){
|
||||
node &child = current->sub[name];
|
||||
if(child.name.empty()){ // a new node
|
||||
child.parent = current;
|
||||
child.name = name;
|
||||
}
|
||||
child.start_time = current_time();
|
||||
current = &child;
|
||||
}
|
||||
|
||||
void timer_stop(const char *name){
|
||||
if(current->name != name || !current->parent){
|
||||
std::cerr << "imbalanced timer_start and timer_stop";
|
||||
exit(1);
|
||||
}
|
||||
current->time += (current_time() - current->start_time);
|
||||
current = current->parent;
|
||||
}
|
||||
}
|
||||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
duality_profiling.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
collection performance information for duality
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
#endif
|
||||
|
||||
#include "duality_wrapper.h"
|
||||
#include "iz3profiling.h"
|
||||
|
||||
namespace Duality {
|
||||
|
||||
void show_time(){
|
||||
output_time(std::cout,current_time());
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
typedef std::map<const char*, struct node> nmap;
|
||||
|
||||
struct node {
|
||||
std::string name;
|
||||
clock_t time;
|
||||
clock_t start_time;
|
||||
nmap sub;
|
||||
struct node *parent;
|
||||
|
||||
node();
|
||||
} top;
|
||||
|
||||
node::node(){
|
||||
time = 0;
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
struct node *current;
|
||||
|
||||
struct init {
|
||||
init(){
|
||||
top.name = "TOTAL";
|
||||
current = ⊤
|
||||
}
|
||||
} initializer;
|
||||
|
||||
struct time_entry {
|
||||
clock_t t;
|
||||
time_entry(){t = 0;};
|
||||
void add(clock_t incr){t += incr;}
|
||||
};
|
||||
|
||||
struct ltstr
|
||||
{
|
||||
bool operator()(const char* s1, const char* s2) const
|
||||
{
|
||||
return strcmp(s1, s2) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<const char*, time_entry, ltstr> tmap;
|
||||
|
||||
static std::ostream *pfs;
|
||||
|
||||
void print_node(node &top, int indent, tmap &totals){
|
||||
for(int i = 0; i < indent; i++) (*pfs) << " ";
|
||||
(*pfs) << top.name;
|
||||
int dots = 70 - 2 * indent - top.name.size();
|
||||
for(int i = 0; i <dots; i++) (*pfs) << ".";
|
||||
output_time(*pfs, top.time);
|
||||
(*pfs) << std::endl;
|
||||
if(indent != 0)totals[top.name.c_str()].add(top.time);
|
||||
for(nmap::iterator it = top.sub.begin(); it != top.sub.end(); it++)
|
||||
print_node(it->second,indent+1,totals);
|
||||
}
|
||||
|
||||
void print_profile(std::ostream &os) {
|
||||
pfs = &os;
|
||||
top.time = 0;
|
||||
for(nmap::iterator it = top.sub.begin(); it != top.sub.end(); it++)
|
||||
top.time += it->second.time;
|
||||
tmap totals;
|
||||
print_node(top,0,totals);
|
||||
(*pfs) << "TOTALS:" << std::endl;
|
||||
for(tmap::iterator it = totals.begin(); it != totals.end(); it++){
|
||||
(*pfs) << (it->first) << " ";
|
||||
output_time(*pfs, it->second.t);
|
||||
(*pfs) << std::endl;
|
||||
}
|
||||
profiling::print(os); // print the interpolation stats
|
||||
}
|
||||
|
||||
void timer_start(const char *name){
|
||||
node &child = current->sub[name];
|
||||
if(child.name.empty()){ // a new node
|
||||
child.parent = current;
|
||||
child.name = name;
|
||||
}
|
||||
child.start_time = current_time();
|
||||
current = &child;
|
||||
}
|
||||
|
||||
void timer_stop(const char *name){
|
||||
if(current->name != name || !current->parent){
|
||||
std::cerr << "imbalanced timer_start and timer_stop";
|
||||
exit(1);
|
||||
}
|
||||
current->time += (current_time() - current->start_time);
|
||||
current = current->parent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
duality_profiling.h
|
||||
|
||||
Abstract:
|
||||
|
||||
collection performance information for duality
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef DUALITYPROFILING_H
|
||||
#define DUALITYPROFILING_H
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace Duality {
|
||||
/** Start a timer with given name */
|
||||
void timer_start(const char *);
|
||||
/** Stop a timer with given name */
|
||||
void timer_stop(const char *);
|
||||
/** Print out timings */
|
||||
void print_profile(std::ostream &s);
|
||||
/** Show the current time. */
|
||||
void show_time();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
duality_profiling.h
|
||||
|
||||
Abstract:
|
||||
|
||||
collection performance information for duality
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef DUALITYPROFILING_H
|
||||
#define DUALITYPROFILING_H
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace Duality {
|
||||
/** Start a timer with given name */
|
||||
void timer_start(const char *);
|
||||
/** Stop a timer with given name */
|
||||
void timer_stop(const char *);
|
||||
/** Print out timings */
|
||||
void print_profile(std::ostream &s);
|
||||
/** Show the current time. */
|
||||
void show_time();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
@ -37,16 +37,18 @@ Revision History:
|
|||
|
||||
namespace Duality {
|
||||
|
||||
solver::solver(Duality::context& c, bool extensional, bool models) : object(c), the_model(c) {
|
||||
solver::solver(Duality::context& c, bool _extensional, bool models) : object(c), the_model(c) {
|
||||
params_ref p;
|
||||
p.set_bool("proof", true); // this is currently useless
|
||||
if(models)
|
||||
p.set_bool("model", true);
|
||||
p.set_bool("unsat_core", true);
|
||||
p.set_bool("mbqi",true);
|
||||
bool mbqi = c.get_config().get().get_bool("mbqi",true);
|
||||
p.set_bool("mbqi",mbqi); // just to test
|
||||
p.set_str("mbqi.id","itp"); // use mbqi for quantifiers in interpolants
|
||||
p.set_uint("mbqi.max_iterations",1); // use mbqi for quantifiers in interpolants
|
||||
if(true || extensional)
|
||||
extensional = mbqi && (true || _extensional);
|
||||
if(extensional)
|
||||
p.set_bool("array.extensional",true);
|
||||
scoped_ptr<solver_factory> sf = mk_smt_solver_factory();
|
||||
m_solver = (*sf)(m(), p, true, true, true, ::symbol::null);
|
||||
|
@ -338,6 +340,12 @@ expr context::make_quant(decl_kind op, const std::vector<sort> &_sorts, const st
|
|||
params p;
|
||||
return simplify(p);
|
||||
}
|
||||
|
||||
expr context::make_var(int idx, const sort &s){
|
||||
::sort * a = to_sort(s.raw());
|
||||
return cook(m().mk_var(idx,a));
|
||||
}
|
||||
|
||||
|
||||
expr expr::qe_lite() const {
|
||||
::qe_lite qe(m());
|
||||
|
@ -372,6 +380,12 @@ expr context::make_quant(decl_kind op, const std::vector<sort> &_sorts, const st
|
|||
return q.ctx().cook(q.m().update_quantifier(thing, is_forall, num_patterns, &_patterns[0], to_expr(b.raw())));
|
||||
}
|
||||
|
||||
expr clone_quantifier(decl_kind dk, const expr &q, const expr &b){
|
||||
quantifier *thing = to_quantifier(q.raw());
|
||||
bool is_forall = dk == Forall;
|
||||
return q.ctx().cook(q.m().update_quantifier(thing, is_forall, to_expr(b.raw())));
|
||||
}
|
||||
|
||||
void expr::get_patterns(std::vector<expr> &pats) const {
|
||||
quantifier *thing = to_quantifier(raw());
|
||||
unsigned num_patterns = thing->get_num_patterns();
|
||||
|
@ -656,6 +670,18 @@ expr context::make_quant(decl_kind op, const std::vector<sort> &_sorts, const st
|
|||
pp.display_smt2(std::cout, m_solver->get_assertion(n-1));
|
||||
}
|
||||
|
||||
void solver::print(const char *filename) {
|
||||
std::ofstream f(filename);
|
||||
unsigned n = m_solver->get_num_assertions();
|
||||
if(!n)
|
||||
return;
|
||||
ast_smt_pp pp(m());
|
||||
for (unsigned i = 0; i < n-1; ++i)
|
||||
pp.add_assumption(m_solver->get_assertion(i));
|
||||
pp.display_smt2(f, m_solver->get_assertion(n-1));
|
||||
}
|
||||
|
||||
|
||||
void solver::show_assertion_ids() {
|
||||
#if 0
|
||||
unsigned n = m_solver->get_num_assertions();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,7 +23,7 @@ Revision History:
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#define FOCI2_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define FOCI2_EXPORT __attribute__ ((visibility ("default")))
|
||||
|
|
|
@ -18,7 +18,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
@ -34,9 +34,7 @@ Revision History:
|
|||
#include "../smt/smt_solver.h"
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
|
||||
iz3base::range &iz3base::ast_range(ast t){
|
||||
|
|
|
@ -1,195 +1,195 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3base.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Base class for interpolators. Includes an AST manager and a scoping
|
||||
object as bases.
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef IZ3BASE_H
|
||||
#define IZ3BASE_H
|
||||
|
||||
#include "iz3mgr.h"
|
||||
#include "iz3scopes.h"
|
||||
|
||||
namespace hash_space {
|
||||
template <>
|
||||
class hash<func_decl *> {
|
||||
public:
|
||||
size_t operator()(func_decl * const &s) const {
|
||||
return (size_t) s;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* Base class for interpolators. Includes an AST manager and a scoping
|
||||
object as bases. */
|
||||
|
||||
class iz3base : public iz3mgr, public scopes {
|
||||
|
||||
public:
|
||||
|
||||
/** Get the range in which an expression occurs. This is the
|
||||
smallest subtree containing all occurrences of the
|
||||
expression. */
|
||||
range &ast_range(ast);
|
||||
|
||||
/** Get the scope of an expression. This is the set of tree nodes in
|
||||
which all of the expression's symbols are in scope. */
|
||||
range &ast_scope(ast);
|
||||
|
||||
/** Get the range of a symbol. This is the smallest subtree containing
|
||||
all occurrences of the symbol. */
|
||||
range &sym_range(symb);
|
||||
|
||||
/** Is an expression local (in scope in some frame)? */
|
||||
|
||||
bool is_local(ast node){
|
||||
return !range_is_empty(ast_scope(node));
|
||||
}
|
||||
|
||||
/** Simplify an expression */
|
||||
|
||||
ast simplify(ast);
|
||||
|
||||
/** Constructor */
|
||||
|
||||
iz3base(ast_manager &_m_manager,
|
||||
const std::vector<ast> &_cnsts,
|
||||
const std::vector<int> &_parents,
|
||||
const std::vector<ast> &_theory)
|
||||
: iz3mgr(_m_manager), scopes(_parents) {
|
||||
initialize(_cnsts,_parents,_theory);
|
||||
weak = false;
|
||||
}
|
||||
|
||||
iz3base(const iz3mgr& other,
|
||||
const std::vector<ast> &_cnsts,
|
||||
const std::vector<int> &_parents,
|
||||
const std::vector<ast> &_theory)
|
||||
: iz3mgr(other), scopes(_parents) {
|
||||
initialize(_cnsts,_parents,_theory);
|
||||
weak = false;
|
||||
}
|
||||
|
||||
iz3base(const iz3mgr& other,
|
||||
const std::vector<std::vector<ast> > &_cnsts,
|
||||
const std::vector<int> &_parents,
|
||||
const std::vector<ast> &_theory)
|
||||
: iz3mgr(other), scopes(_parents) {
|
||||
initialize(_cnsts,_parents,_theory);
|
||||
weak = false;
|
||||
}
|
||||
|
||||
iz3base(const iz3mgr& other)
|
||||
: iz3mgr(other), scopes() {
|
||||
weak = false;
|
||||
}
|
||||
|
||||
/* Set our options */
|
||||
void set_option(const std::string &name, const std::string &value){
|
||||
if(name == "weak" && value == "1") weak = true;
|
||||
}
|
||||
|
||||
/* Are we doing weak interpolants? */
|
||||
bool weak_mode(){return weak;}
|
||||
|
||||
/** Print interpolation problem to an SMTLIB format file */
|
||||
void print(const std::string &filename);
|
||||
|
||||
/** Check correctness of a solutino to this problem. */
|
||||
void check_interp(const std::vector<ast> &itps, std::vector<ast> &theory);
|
||||
|
||||
/** For convenience -- is this formula SAT? */
|
||||
bool is_sat(const std::vector<ast> &consts, ast &_proof);
|
||||
|
||||
/** Interpolator for clauses, to be implemented */
|
||||
virtual void interpolate_clause(std::vector<ast> &lits, std::vector<ast> &itps){
|
||||
throw "no interpolator";
|
||||
}
|
||||
|
||||
ast get_proof_check_assump(range &rng){
|
||||
std::vector<ast> cs(theory);
|
||||
cs.push_back(cnsts[rng.hi]);
|
||||
return make(And,cs);
|
||||
}
|
||||
|
||||
int frame_of_assertion(const ast &ass){
|
||||
stl_ext::hash_map<ast,int>::iterator it = frame_map.find(ass);
|
||||
if(it == frame_map.end())
|
||||
throw "unknown assertion";
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
void to_parents_vec_representation(const std::vector<ast> &_cnsts,
|
||||
const ast &tree,
|
||||
std::vector<ast> &cnsts,
|
||||
std::vector<int> &parents,
|
||||
std::vector<ast> &theory,
|
||||
std::vector<int> &pos_map,
|
||||
bool merge = false
|
||||
);
|
||||
|
||||
protected:
|
||||
std::vector<ast> cnsts;
|
||||
std::vector<ast> theory;
|
||||
|
||||
private:
|
||||
|
||||
struct ranges {
|
||||
range rng;
|
||||
range scp;
|
||||
bool scope_computed;
|
||||
ranges(){scope_computed = false;}
|
||||
};
|
||||
|
||||
stl_ext::hash_map<symb,range> sym_range_hash;
|
||||
stl_ext::hash_map<ast,ranges> ast_ranges_hash;
|
||||
stl_ext::hash_map<ast,ast> simplify_memo;
|
||||
stl_ext::hash_map<ast,int> frame_map; // map assertions to frames
|
||||
|
||||
int frames; // number of frames
|
||||
|
||||
protected:
|
||||
void add_frame_range(int frame, ast t);
|
||||
|
||||
private:
|
||||
void initialize(const std::vector<ast> &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
|
||||
|
||||
void initialize(const std::vector<std::vector<ast> > &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
|
||||
|
||||
bool is_literal(ast n);
|
||||
void gather_conjuncts_rec(ast n, std::vector<ast> &conjuncts, stl_ext::hash_set<ast> &memo);
|
||||
void gather_conjuncts(ast n, std::vector<ast> &conjuncts);
|
||||
ast simplify_and(std::vector<ast> &conjuncts);
|
||||
ast simplify_with_lit_rec(ast n, ast lit, stl_ext::hash_map<ast,ast> &memo, int depth);
|
||||
ast simplify_with_lit(ast n, ast lit);
|
||||
void find_children(const stl_ext::hash_set<ast> &cnsts_set,
|
||||
const ast &tree,
|
||||
std::vector<ast> &cnsts,
|
||||
std::vector<int> &parents,
|
||||
std::vector<ast> &conjuncts,
|
||||
std::vector<int> &children,
|
||||
std::vector<int> &pos_map,
|
||||
bool merge
|
||||
);
|
||||
bool weak;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3base.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Base class for interpolators. Includes an AST manager and a scoping
|
||||
object as bases.
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef IZ3BASE_H
|
||||
#define IZ3BASE_H
|
||||
|
||||
#include "iz3mgr.h"
|
||||
#include "iz3scopes.h"
|
||||
|
||||
namespace hash_space {
|
||||
template <>
|
||||
class hash<func_decl *> {
|
||||
public:
|
||||
size_t operator()(func_decl * const &s) const {
|
||||
return (size_t) s;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* Base class for interpolators. Includes an AST manager and a scoping
|
||||
object as bases. */
|
||||
|
||||
class iz3base : public iz3mgr, public scopes {
|
||||
|
||||
public:
|
||||
|
||||
/** Get the range in which an expression occurs. This is the
|
||||
smallest subtree containing all occurrences of the
|
||||
expression. */
|
||||
range &ast_range(ast);
|
||||
|
||||
/** Get the scope of an expression. This is the set of tree nodes in
|
||||
which all of the expression's symbols are in scope. */
|
||||
range &ast_scope(ast);
|
||||
|
||||
/** Get the range of a symbol. This is the smallest subtree containing
|
||||
all occurrences of the symbol. */
|
||||
range &sym_range(symb);
|
||||
|
||||
/** Is an expression local (in scope in some frame)? */
|
||||
|
||||
bool is_local(ast node){
|
||||
return !range_is_empty(ast_scope(node));
|
||||
}
|
||||
|
||||
/** Simplify an expression */
|
||||
|
||||
ast simplify(ast);
|
||||
|
||||
/** Constructor */
|
||||
|
||||
iz3base(ast_manager &_m_manager,
|
||||
const std::vector<ast> &_cnsts,
|
||||
const std::vector<int> &_parents,
|
||||
const std::vector<ast> &_theory)
|
||||
: iz3mgr(_m_manager), scopes(_parents) {
|
||||
initialize(_cnsts,_parents,_theory);
|
||||
weak = false;
|
||||
}
|
||||
|
||||
iz3base(const iz3mgr& other,
|
||||
const std::vector<ast> &_cnsts,
|
||||
const std::vector<int> &_parents,
|
||||
const std::vector<ast> &_theory)
|
||||
: iz3mgr(other), scopes(_parents) {
|
||||
initialize(_cnsts,_parents,_theory);
|
||||
weak = false;
|
||||
}
|
||||
|
||||
iz3base(const iz3mgr& other,
|
||||
const std::vector<std::vector<ast> > &_cnsts,
|
||||
const std::vector<int> &_parents,
|
||||
const std::vector<ast> &_theory)
|
||||
: iz3mgr(other), scopes(_parents) {
|
||||
initialize(_cnsts,_parents,_theory);
|
||||
weak = false;
|
||||
}
|
||||
|
||||
iz3base(const iz3mgr& other)
|
||||
: iz3mgr(other), scopes() {
|
||||
weak = false;
|
||||
}
|
||||
|
||||
/* Set our options */
|
||||
void set_option(const std::string &name, const std::string &value){
|
||||
if(name == "weak" && value == "1") weak = true;
|
||||
}
|
||||
|
||||
/* Are we doing weak interpolants? */
|
||||
bool weak_mode(){return weak;}
|
||||
|
||||
/** Print interpolation problem to an SMTLIB format file */
|
||||
void print(const std::string &filename);
|
||||
|
||||
/** Check correctness of a solutino to this problem. */
|
||||
void check_interp(const std::vector<ast> &itps, std::vector<ast> &theory);
|
||||
|
||||
/** For convenience -- is this formula SAT? */
|
||||
bool is_sat(const std::vector<ast> &consts, ast &_proof);
|
||||
|
||||
/** Interpolator for clauses, to be implemented */
|
||||
virtual void interpolate_clause(std::vector<ast> &lits, std::vector<ast> &itps){
|
||||
throw "no interpolator";
|
||||
}
|
||||
|
||||
ast get_proof_check_assump(range &rng){
|
||||
std::vector<ast> cs(theory);
|
||||
cs.push_back(cnsts[rng.hi]);
|
||||
return make(And,cs);
|
||||
}
|
||||
|
||||
int frame_of_assertion(const ast &ass){
|
||||
stl_ext::hash_map<ast,int>::iterator it = frame_map.find(ass);
|
||||
if(it == frame_map.end())
|
||||
throw "unknown assertion";
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
void to_parents_vec_representation(const std::vector<ast> &_cnsts,
|
||||
const ast &tree,
|
||||
std::vector<ast> &cnsts,
|
||||
std::vector<int> &parents,
|
||||
std::vector<ast> &theory,
|
||||
std::vector<int> &pos_map,
|
||||
bool merge = false
|
||||
);
|
||||
|
||||
protected:
|
||||
std::vector<ast> cnsts;
|
||||
std::vector<ast> theory;
|
||||
|
||||
private:
|
||||
|
||||
struct ranges {
|
||||
range rng;
|
||||
range scp;
|
||||
bool scope_computed;
|
||||
ranges(){scope_computed = false;}
|
||||
};
|
||||
|
||||
stl_ext::hash_map<symb,range> sym_range_hash;
|
||||
stl_ext::hash_map<ast,ranges> ast_ranges_hash;
|
||||
stl_ext::hash_map<ast,ast> simplify_memo;
|
||||
stl_ext::hash_map<ast,int> frame_map; // map assertions to frames
|
||||
|
||||
int frames; // number of frames
|
||||
|
||||
protected:
|
||||
void add_frame_range(int frame, ast t);
|
||||
|
||||
private:
|
||||
void initialize(const std::vector<ast> &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
|
||||
|
||||
void initialize(const std::vector<std::vector<ast> > &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
|
||||
|
||||
bool is_literal(ast n);
|
||||
void gather_conjuncts_rec(ast n, std::vector<ast> &conjuncts, stl_ext::hash_set<ast> &memo);
|
||||
void gather_conjuncts(ast n, std::vector<ast> &conjuncts);
|
||||
ast simplify_and(std::vector<ast> &conjuncts);
|
||||
ast simplify_with_lit_rec(ast n, ast lit, stl_ext::hash_map<ast,ast> &memo, int depth);
|
||||
ast simplify_with_lit(ast n, ast lit);
|
||||
void find_children(const stl_ext::hash_set<ast> &cnsts_set,
|
||||
const ast &tree,
|
||||
std::vector<ast> &cnsts,
|
||||
std::vector<int> &parents,
|
||||
std::vector<ast> &conjuncts,
|
||||
std::vector<int> &children,
|
||||
std::vector<int> &pos_map,
|
||||
bool merge
|
||||
);
|
||||
bool weak;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
@ -36,9 +36,7 @@ Revision History:
|
|||
#include <iterator>
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
struct iz3checker : iz3base {
|
||||
|
||||
|
|
|
@ -25,9 +25,7 @@ Revision History:
|
|||
#include "foci2.h"
|
||||
#include "iz3foci.h"
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
class iz3foci_impl : public iz3secondary {
|
||||
|
||||
|
|
547
src/interp/iz3hash.h
Executable file → Normal file
547
src/interp/iz3hash.h
Executable file → Normal file
|
@ -7,7 +7,16 @@ Module Name:
|
|||
|
||||
Abstract:
|
||||
|
||||
Wrapper for stl hash tables
|
||||
Simple implementation of bucket-list hash tables conforming to SGI
|
||||
hash_map and hash_set interfaces. Just enough members are
|
||||
implemented to support iz3 and duality.
|
||||
|
||||
iz3 and duality need this package because they assume that insert
|
||||
preserves iterators and references to elements, which is not true
|
||||
of the hashtable packages in util.
|
||||
|
||||
This package lives in namespace hash_space. Specializations of
|
||||
class "hash" should be made in this namespace.
|
||||
|
||||
Author:
|
||||
|
||||
|
@ -17,66 +26,36 @@ Revision History:
|
|||
|
||||
--*/
|
||||
|
||||
// pull in the headers for has_map and hash_set
|
||||
// these live in non-standard places
|
||||
|
||||
#ifndef IZ3_HASH_H
|
||||
#define IZ3_HASH_H
|
||||
|
||||
//#define USE_UNORDERED_MAP
|
||||
#ifdef USE_UNORDERED_MAP
|
||||
|
||||
#define stl_ext std
|
||||
#define hash_space std
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#define hash_map unordered_map
|
||||
#define hash_set unordered_set
|
||||
|
||||
#else
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#undef __DEPRECATED
|
||||
#define stl_ext __gnu_cxx
|
||||
#define hash_space stl_ext
|
||||
#include <ext/hash_map>
|
||||
#include <ext/hash_set>
|
||||
#else
|
||||
#ifdef _WINDOWS
|
||||
#define stl_ext stdext
|
||||
#define hash_space std
|
||||
#include <hash_map>
|
||||
#include <hash_set>
|
||||
#else
|
||||
#define stl_ext std
|
||||
#define hash_space std
|
||||
#include <hash_map>
|
||||
#include <hash_set>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include "hash.h"
|
||||
|
||||
// stupid STL doesn't include hash function for class string
|
||||
|
||||
#ifndef _WINDOWS
|
||||
|
||||
namespace stl_ext {
|
||||
template <>
|
||||
class hash<std::string> {
|
||||
stl_ext::hash<const char *> H;
|
||||
public:
|
||||
size_t operator()(const std::string &s) const {
|
||||
return H(s.c_str());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#define stl_ext hash_space
|
||||
|
||||
namespace hash_space {
|
||||
|
||||
template <typename T> class hash {};
|
||||
|
||||
template <>
|
||||
class hash<int> {
|
||||
public:
|
||||
size_t operator()(const int &s) const {
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class hash<std::string> {
|
||||
public:
|
||||
size_t operator()(const std::string &s) const {
|
||||
return string_hash(s.c_str(), s.size(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class hash<std::pair<int,int> > {
|
||||
public:
|
||||
|
@ -84,17 +63,7 @@ namespace hash_space {
|
|||
return p.first + p.second;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
template <> inline
|
||||
size_t stdext::hash_value<std::pair<int,int> >(const std::pair<int,int>& p)
|
||||
{ // hash _Keyval to size_t value one-to-one
|
||||
return p.first + p.second;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace hash_space {
|
||||
template <class T>
|
||||
class hash<std::pair<T *, T *> > {
|
||||
public:
|
||||
|
@ -102,70 +71,404 @@ namespace hash_space {
|
|||
return (size_t)p.first + (size_t)p.second;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#if 0
|
||||
template <class T> inline
|
||||
size_t stdext::hash_value<std::pair<T *, T *> >(const std::pair<T *, T *>& p)
|
||||
{ // hash _Keyval to size_t value one-to-one
|
||||
return (size_t)p.first + (size_t)p.second;
|
||||
}
|
||||
#endif
|
||||
enum { num_primes = 29 };
|
||||
|
||||
#ifdef _WINDOWS
|
||||
static const unsigned long primes[num_primes] =
|
||||
{
|
||||
7ul,
|
||||
53ul,
|
||||
97ul,
|
||||
193ul,
|
||||
389ul,
|
||||
769ul,
|
||||
1543ul,
|
||||
3079ul,
|
||||
6151ul,
|
||||
12289ul,
|
||||
24593ul,
|
||||
49157ul,
|
||||
98317ul,
|
||||
196613ul,
|
||||
393241ul,
|
||||
786433ul,
|
||||
1572869ul,
|
||||
3145739ul,
|
||||
6291469ul,
|
||||
12582917ul,
|
||||
25165843ul,
|
||||
50331653ul,
|
||||
100663319ul,
|
||||
201326611ul,
|
||||
402653189ul,
|
||||
805306457ul,
|
||||
1610612741ul,
|
||||
3221225473ul,
|
||||
4294967291ul
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class less<std::pair<int,int> > {
|
||||
public:
|
||||
bool operator()(const pair<int,int> &x, const pair<int,int> &y) const {
|
||||
return x.first < y.first || x.first == y.first && x.second < y.second;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <class T>
|
||||
class less<std::pair<T *,T *> > {
|
||||
public:
|
||||
bool operator()(const pair<T *,T *> &x, const pair<T *,T *> &y) const {
|
||||
return (size_t)x.first < (size_t)y.first || (size_t)x.first == (size_t)y.first && (size_t)x.second < (size_t)y.second;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
inline unsigned long next_prime(unsigned long n) {
|
||||
const unsigned long* to = primes + (int)num_primes;
|
||||
for(const unsigned long* p = primes; p < to; p++)
|
||||
if(*p >= n) return *p;
|
||||
return primes[num_primes-1];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _WINDOWS
|
||||
|
||||
#if 0
|
||||
namespace stl_ext {
|
||||
template <class T>
|
||||
class hash<T *> {
|
||||
template<class Value, class Key, class HashFun, class GetKey, class KeyEqFun>
|
||||
class hashtable
|
||||
{
|
||||
public:
|
||||
size_t operator()(const T *p) const {
|
||||
return (size_t) p;
|
||||
|
||||
typedef Value &reference;
|
||||
typedef const Value &const_reference;
|
||||
|
||||
struct Entry
|
||||
{
|
||||
Entry* next;
|
||||
Value val;
|
||||
|
||||
Entry(const Value &_val) : val(_val) {next = 0;}
|
||||
};
|
||||
|
||||
|
||||
struct iterator
|
||||
{
|
||||
Entry* ent;
|
||||
hashtable* tab;
|
||||
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef Value value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef Value& reference;
|
||||
typedef Value* pointer;
|
||||
|
||||
iterator(Entry* _ent, hashtable* _tab) : ent(_ent), tab(_tab) { }
|
||||
|
||||
iterator() { }
|
||||
|
||||
Value &operator*() const { return ent->val; }
|
||||
|
||||
Value *operator->() const { return &(operator*()); }
|
||||
|
||||
iterator &operator++() {
|
||||
Entry *old = ent;
|
||||
ent = ent->next;
|
||||
if (!ent) {
|
||||
size_t bucket = tab->get_bucket(old->val);
|
||||
while (!ent && ++bucket < tab->buckets.size())
|
||||
ent = tab->buckets[bucket];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator++(int) {
|
||||
iterator tmp = *this;
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const iterator& it) const {
|
||||
return ent == it.ent;
|
||||
}
|
||||
|
||||
bool operator!=(const iterator& it) const {
|
||||
return ent != it.ent;
|
||||
}
|
||||
};
|
||||
|
||||
struct const_iterator
|
||||
{
|
||||
const Entry* ent;
|
||||
const hashtable* tab;
|
||||
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef Value value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef const Value& reference;
|
||||
typedef const Value* pointer;
|
||||
|
||||
const_iterator(const Entry* _ent, const hashtable* _tab) : ent(_ent), tab(_tab) { }
|
||||
|
||||
const_iterator() { }
|
||||
|
||||
const Value &operator*() const { return ent->val; }
|
||||
|
||||
const Value *operator->() const { return &(operator*()); }
|
||||
|
||||
const_iterator &operator++() {
|
||||
Entry *old = ent;
|
||||
ent = ent->next;
|
||||
if (!ent) {
|
||||
size_t bucket = tab->get_bucket(old->val);
|
||||
while (!ent && ++bucket < tab->buckets.size())
|
||||
ent = tab->buckets[bucket];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator operator++(int) {
|
||||
const_iterator tmp = *this;
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const const_iterator& it) const {
|
||||
return ent == it.ent;
|
||||
}
|
||||
|
||||
bool operator!=(const const_iterator& it) const {
|
||||
return ent != it.ent;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
typedef std::vector<Entry*> Table;
|
||||
|
||||
Table buckets;
|
||||
size_t entries;
|
||||
HashFun hash_fun ;
|
||||
GetKey get_key;
|
||||
KeyEqFun key_eq_fun;
|
||||
|
||||
public:
|
||||
|
||||
hashtable(size_t init_size) : buckets(init_size,(Entry *)0) {
|
||||
entries = 0;
|
||||
}
|
||||
|
||||
hashtable(const hashtable& other) {
|
||||
dup(other);
|
||||
}
|
||||
|
||||
hashtable& operator= (const hashtable& other) {
|
||||
if (&other != this)
|
||||
dup(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~hashtable() {
|
||||
clear();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return entries;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
void swap(hashtable& other) {
|
||||
buckets.swap(other.buckets);
|
||||
std::swap(entries, other.entries);
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
for (size_t i = 0; i < buckets.size(); ++i)
|
||||
if (buckets[i])
|
||||
return iterator(buckets[i], this);
|
||||
return end();
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(0, this);
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
for (size_t i = 0; i < buckets.size(); ++i)
|
||||
if (buckets[i])
|
||||
return const_iterator(buckets[i], this);
|
||||
return end();
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(0, this);
|
||||
}
|
||||
|
||||
size_t get_bucket(const Value& val, size_t n) const {
|
||||
return hash_fun(get_key(val)) % n;
|
||||
}
|
||||
|
||||
size_t get_key_bucket(const Key& key) const {
|
||||
return hash_fun(key) % buckets.size();
|
||||
}
|
||||
|
||||
size_t get_bucket(const Value& val) const {
|
||||
return get_bucket(val,buckets.size());
|
||||
}
|
||||
|
||||
Entry *lookup(const Value& val, bool ins = false)
|
||||
{
|
||||
resize(entries + 1);
|
||||
|
||||
size_t n = get_bucket(val);
|
||||
Entry* from = buckets[n];
|
||||
|
||||
for (Entry* ent = from; ent; ent = ent->next)
|
||||
if (key_eq_fun(get_key(ent->val), get_key(val)))
|
||||
return ent;
|
||||
|
||||
if(!ins) return 0;
|
||||
|
||||
Entry* tmp = new Entry(val);
|
||||
tmp->next = from;
|
||||
buckets[n] = tmp;
|
||||
++entries;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Entry *lookup_key(const Key& key) const
|
||||
{
|
||||
size_t n = get_key_bucket(key);
|
||||
Entry* from = buckets[n];
|
||||
|
||||
for (Entry* ent = from; ent; ent = ent->next)
|
||||
if (key_eq_fun(get_key(ent->val), key))
|
||||
return ent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const_iterator find(const Key& key) const {
|
||||
return const_iterator(lookup_key(key),this);
|
||||
}
|
||||
|
||||
iterator find(const Key& key) {
|
||||
return iterator(lookup_key(key),this);
|
||||
}
|
||||
|
||||
std::pair<iterator,bool> insert(const Value& val){
|
||||
size_t old_entries = entries;
|
||||
Entry *ent = lookup(val,true);
|
||||
return std::pair<iterator,bool>(iterator(ent,this),entries > old_entries);
|
||||
}
|
||||
|
||||
iterator insert(const iterator &it, const Value& val){
|
||||
Entry *ent = lookup(val,true);
|
||||
return iterator(ent,this);
|
||||
}
|
||||
|
||||
size_t erase(const Key& key)
|
||||
{
|
||||
Entry** p = &(buckets[get_key_bucket(key)]);
|
||||
size_t count = 0;
|
||||
while(*p){
|
||||
Entry *q = *p;
|
||||
if (key_eq_fun(get_key(q->val), key)) {
|
||||
++count;
|
||||
*p = q->next;
|
||||
delete q;
|
||||
}
|
||||
else
|
||||
p = &(q->next);
|
||||
}
|
||||
entries -= count;
|
||||
return count;
|
||||
}
|
||||
|
||||
void resize(size_t new_size) {
|
||||
const size_t old_n = buckets.size();
|
||||
if (new_size <= old_n) return;
|
||||
const size_t n = next_prime(new_size);
|
||||
if (n <= old_n) return;
|
||||
Table tmp(n, (Entry*)(0));
|
||||
for (size_t i = 0; i < old_n; ++i) {
|
||||
Entry* ent = buckets[i];
|
||||
while (ent) {
|
||||
size_t new_bucket = get_bucket(ent->val, n);
|
||||
buckets[i] = ent->next;
|
||||
ent->next = tmp[new_bucket];
|
||||
tmp[new_bucket] = ent;
|
||||
ent = buckets[i];
|
||||
}
|
||||
}
|
||||
buckets.swap(tmp);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (size_t i = 0; i < buckets.size(); ++i) {
|
||||
for (Entry* ent = buckets[i]; ent != 0;) {
|
||||
Entry* next = ent->next;
|
||||
delete ent;
|
||||
ent = next;
|
||||
}
|
||||
buckets[i] = 0;
|
||||
}
|
||||
entries = 0;
|
||||
}
|
||||
|
||||
void dup(const hashtable& other)
|
||||
{
|
||||
buckets.resize(other.buckets.size());
|
||||
for (size_t i = 0; i < other.buckets.size(); ++i) {
|
||||
Entry** to = &buckets[i];
|
||||
for (Entry* from = other.buckets[i]; from; from = from->next)
|
||||
to = &((*to = new Entry(from->val))->next);
|
||||
}
|
||||
entries = other.entries;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class equal {
|
||||
public:
|
||||
bool operator()(const T& x, const T &y) const {
|
||||
return x == y;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class identity {
|
||||
public:
|
||||
const T &operator()(const T &x) const {
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
class proj1 {
|
||||
public:
|
||||
const T &operator()(const std::pair<T,U> &x) const {
|
||||
return x.first;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Element, class HashFun = hash<Element>,
|
||||
class EqFun = equal<Element> >
|
||||
class hash_set
|
||||
: public hashtable<Element,Element,HashFun,identity<Element>,EqFun> {
|
||||
|
||||
public:
|
||||
|
||||
typedef Element value_type;
|
||||
|
||||
hash_set()
|
||||
: hashtable<Element,Element,HashFun,identity<Element>,EqFun>(7) {}
|
||||
};
|
||||
|
||||
template <typename Key, typename Value, class HashFun = hash<Key>,
|
||||
class EqFun = equal<Key> >
|
||||
class hash_map
|
||||
: public hashtable<std::pair<Key,Value>,Key,HashFun,proj1<Key,Value>,EqFun> {
|
||||
|
||||
public:
|
||||
|
||||
hash_map()
|
||||
: hashtable<std::pair<Key,Value>,Key,HashFun,proj1<Key,Value>,EqFun>(7) {}
|
||||
|
||||
Value &operator[](const Key& key) {
|
||||
std::pair<Key,Value> kvp(key,Value());
|
||||
return
|
||||
hashtable<std::pair<Key,Value>,Key,HashFun,proj1<Key,Value>,EqFun>::
|
||||
lookup(kvp,true)->val.second;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
|
||||
|
||||
|
||||
template <class K, class T>
|
||||
class hash_map : public stl_ext::hash_map<K,T,stl_ext::hash_compare<K,std::less<K> > > {};
|
||||
|
||||
template <class K>
|
||||
class hash_set : public stl_ext::hash_set<K,stl_ext::hash_compare<K,std::less<K> > > {};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,7 @@ Revision History:
|
|||
|
||||
/* Copyright 2011 Microsoft Research. */
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
@ -43,9 +43,7 @@ Revision History:
|
|||
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -64,7 +62,7 @@ struct frame_reducer : public iz3mgr {
|
|||
: iz3mgr(other) {}
|
||||
|
||||
void get_proof_assumptions_rec(z3pf proof, hash_set<ast> &memo, std::vector<bool> &used_frames){
|
||||
if(memo.count(proof))return;
|
||||
if(memo.find(proof) != memo.end())return;
|
||||
memo.insert(proof);
|
||||
pfrule dk = pr(proof);
|
||||
if(dk == PR_ASSERTED){
|
||||
|
|
|
@ -18,7 +18,7 @@ Revision History:
|
|||
--*/
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
@ -38,9 +38,7 @@ Revision History:
|
|||
#include "params.h"
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
|
||||
std::ostream &operator <<(std::ostream &s, const iz3mgr::ast &a){
|
||||
|
|
|
@ -126,14 +126,6 @@ namespace hash_space {
|
|||
};
|
||||
}
|
||||
|
||||
// to make ast_r hashable in windows
|
||||
#ifdef _WINDOWS
|
||||
template <> inline
|
||||
size_t stdext::hash_value<ast_r >(const ast_r& s)
|
||||
{
|
||||
return s.raw()->get_id();
|
||||
}
|
||||
#endif
|
||||
|
||||
// to make ast_r usable in ordered collections
|
||||
namespace std {
|
||||
|
|
|
@ -36,11 +36,8 @@ Revision History:
|
|||
#include"expr_abstract.h"
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
// We promise not to use this for hash_map with range destructor
|
||||
namespace stl_ext {
|
||||
template <>
|
||||
|
@ -51,7 +48,6 @@ namespace stl_ext {
|
|||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// TBD: algebraic data-types declarations will not be printed.
|
||||
|
|
|
@ -17,7 +17,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
|
|
@ -18,7 +18,7 @@ Revision History:
|
|||
--*/
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
|
|
@ -17,7 +17,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
@ -26,9 +26,7 @@ Revision History:
|
|||
|
||||
#include "iz3proof_itp.h"
|
||||
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
// #define INVARIANT_CHECKING
|
||||
|
||||
|
@ -369,11 +367,17 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
}
|
||||
default:
|
||||
{
|
||||
symb s = sym(itp2);
|
||||
if(s == sforall || s == sexists)
|
||||
res = make(s,arg(itp2,0),resolve_arith_rec2(memo, pivot1, conj1, arg(itp2,1)));
|
||||
else
|
||||
opr o = op(itp2);
|
||||
if(o == Uninterpreted){
|
||||
symb s = sym(itp2);
|
||||
if(s == sforall || s == sexists)
|
||||
res = make(s,arg(itp2,0),resolve_arith_rec2(memo, pivot1, conj1, arg(itp2,1)));
|
||||
else
|
||||
res = itp2;
|
||||
}
|
||||
else {
|
||||
res = itp2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -405,11 +409,17 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
}
|
||||
default:
|
||||
{
|
||||
symb s = sym(itp1);
|
||||
if(s == sforall || s == sexists)
|
||||
res = make(s,arg(itp1,0),resolve_arith_rec1(memo, neg_pivot_lit, arg(itp1,1), itp2));
|
||||
else
|
||||
opr o = op(itp1);
|
||||
if(o == Uninterpreted){
|
||||
symb s = sym(itp1);
|
||||
if(s == sforall || s == sexists)
|
||||
res = make(s,arg(itp1,0),resolve_arith_rec1(memo, neg_pivot_lit, arg(itp1,1), itp2));
|
||||
else
|
||||
res = itp1;
|
||||
}
|
||||
else {
|
||||
res = itp1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -464,18 +474,20 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
std::pair<hash_map<ast,ast>::iterator,bool> bar = subst_memo.insert(foo);
|
||||
ast &res = bar.first->second;
|
||||
if(bar.second){
|
||||
symb g = sym(e);
|
||||
if(g == rotate_sum){
|
||||
if(var == get_placeholder(arg(e,0))){
|
||||
res = e;
|
||||
if(op(e) == Uninterpreted){
|
||||
symb g = sym(e);
|
||||
if(g == rotate_sum){
|
||||
if(var == get_placeholder(arg(e,0))){
|
||||
res = e;
|
||||
}
|
||||
else
|
||||
res = make(rotate_sum,arg(e,0),subst_term_and_simp_rec(var,t,arg(e,1)));
|
||||
return res;
|
||||
}
|
||||
if(g == concat){
|
||||
res = e;
|
||||
return res;
|
||||
}
|
||||
else
|
||||
res = make(rotate_sum,arg(e,0),subst_term_and_simp_rec(var,t,arg(e,1)));
|
||||
return res;
|
||||
}
|
||||
if(g == concat){
|
||||
res = e;
|
||||
return res;
|
||||
}
|
||||
int nargs = num_args(e);
|
||||
std::vector<ast> args(nargs);
|
||||
|
@ -538,8 +550,9 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
else if(g == symm) res = simplify_symm(args);
|
||||
else if(g == modpon) res = simplify_modpon(args);
|
||||
else if(g == sum) res = simplify_sum(args);
|
||||
#if 0
|
||||
else if(g == exmid) res = simplify_exmid(args);
|
||||
else if(g == cong) res = simplify_cong(args);
|
||||
#if 0
|
||||
else if(g == modpon) res = simplify_modpon(args);
|
||||
else if(g == leq2eq) res = simplify_leq2eq(args);
|
||||
else if(g == eq2leq) res = simplify_eq2leq(args);
|
||||
|
@ -680,7 +693,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
ast dummy1, dummy2;
|
||||
sum_cond_ineq(in1,coeff2,in2,dummy1,dummy2);
|
||||
n1 = merge_normal_chains(n1,n2, Aproves, Bproves);
|
||||
ineq = make_normal(in1,n1);
|
||||
ineq = is_true(n1) ? in1 : make_normal(in1,n1);
|
||||
}
|
||||
|
||||
bool is_ineq(const ast &ineq){
|
||||
|
@ -729,29 +742,31 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
ast x = arg(equality,0);
|
||||
ast y = arg(equality,1);
|
||||
ast Aproves1 = mk_true(), Bproves1 = mk_true();
|
||||
ast xleqy = round_ineq(ineq_from_chain(arg(pf,1),Aproves1,Bproves1));
|
||||
ast yleqx = round_ineq(ineq_from_chain(arg(pf,2),Aproves1,Bproves1));
|
||||
ast pf1 = destruct_cond_ineq(arg(pf,1), Aproves1, Bproves1);
|
||||
ast pf2 = destruct_cond_ineq(arg(pf,2), Aproves1, Bproves1);
|
||||
ast xleqy = round_ineq(ineq_from_chain(pf1,Aproves1,Bproves1));
|
||||
ast yleqx = round_ineq(ineq_from_chain(pf2,Aproves1,Bproves1));
|
||||
ast ineq1 = make(Leq,make_int("0"),make_int("0"));
|
||||
sum_cond_ineq(ineq1,make_int("-1"),xleqy,Aproves1,Bproves1);
|
||||
sum_cond_ineq(ineq1,make_int("-1"),yleqx,Aproves1,Bproves1);
|
||||
Bproves1 = my_and(Bproves1,z3_simplify(ineq1));
|
||||
ast Acond = my_implies(Aproves1,my_and(Bproves1,z3_simplify(ineq1)));
|
||||
ast Aproves2 = mk_true(), Bproves2 = mk_true();
|
||||
ast ineq2 = make(Leq,make_int("0"),make_int("0"));
|
||||
sum_cond_ineq(ineq2,make_int("1"),xleqy,Aproves2,Bproves2);
|
||||
sum_cond_ineq(ineq2,make_int("1"),yleqx,Aproves2,Bproves2);
|
||||
Bproves2 = z3_simplify(ineq2);
|
||||
if(!is_true(Aproves1) || !is_true(Aproves2))
|
||||
throw "help!";
|
||||
ast Bcond = my_implies(Bproves1,my_and(Aproves1,z3_simplify(ineq2)));
|
||||
// if(!is_true(Aproves1) || !is_true(Bproves1))
|
||||
// std::cout << "foo!\n";;
|
||||
if(get_term_type(x) == LitA){
|
||||
ast iter = z3_simplify(make(Plus,x,get_ineq_rhs(xleqy)));
|
||||
ast rewrite1 = make_rewrite(LitA,top_pos,Bproves1,make(Equal,x,iter));
|
||||
ast rewrite2 = make_rewrite(LitB,top_pos,Bproves2,make(Equal,iter,y));
|
||||
ast rewrite1 = make_rewrite(LitA,top_pos,Acond,make(Equal,x,iter));
|
||||
ast rewrite2 = make_rewrite(LitB,top_pos,Bcond,make(Equal,iter,y));
|
||||
return chain_cons(chain_cons(mk_true(),rewrite1),rewrite2);
|
||||
}
|
||||
if(get_term_type(y) == LitA){
|
||||
ast iter = z3_simplify(make(Plus,y,get_ineq_rhs(yleqx)));
|
||||
ast rewrite2 = make_rewrite(LitA,top_pos,Bproves1,make(Equal,iter,y));
|
||||
ast rewrite1 = make_rewrite(LitB,top_pos,Bproves2,make(Equal,x,iter));
|
||||
ast rewrite2 = make_rewrite(LitA,top_pos,Acond,make(Equal,iter,y));
|
||||
ast rewrite1 = make_rewrite(LitB,top_pos,Bcond,make(Equal,x,iter));
|
||||
return chain_cons(chain_cons(mk_true(),rewrite1),rewrite2);
|
||||
}
|
||||
throw cannot_simplify();
|
||||
|
@ -760,6 +775,8 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
}
|
||||
|
||||
ast round_ineq(const ast &ineq){
|
||||
if(sym(ineq) == normal)
|
||||
return make_normal(round_ineq(arg(ineq,0)),arg(ineq,1));
|
||||
if(!is_ineq(ineq))
|
||||
throw cannot_simplify();
|
||||
ast res = simplify_ineq(ineq);
|
||||
|
@ -790,12 +807,17 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
return simplify_sum(args);
|
||||
}
|
||||
|
||||
|
||||
ast simplify_rotate_eq2leq(const ast &pl, const ast &neg_equality, const ast &pf){
|
||||
if(pl == arg(pf,1)){
|
||||
ast cond = mk_true();
|
||||
ast equa = sep_cond(arg(pf,0),cond);
|
||||
if(is_equivrel_chain(equa)){
|
||||
ast lhs,rhs; eq_from_ineq(arg(neg_equality,0),lhs,rhs); // get inequality we need to prove
|
||||
if(!rewrites_from_to(equa,lhs,rhs)){
|
||||
lhs = arg(arg(neg_equality,0),0); // the equality proved is ambiguous, sadly
|
||||
rhs = arg(arg(neg_equality,0),1);
|
||||
}
|
||||
LitType lhst = get_term_type(lhs), rhst = get_term_type(rhs);
|
||||
if(lhst != LitMixed && rhst != LitMixed)
|
||||
return unmixed_eq2ineq(lhs, rhs, op(arg(neg_equality,0)), equa, cond);
|
||||
|
@ -920,6 +942,8 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
return chain;
|
||||
}
|
||||
|
||||
struct subterm_normals_failed {};
|
||||
|
||||
void get_subterm_normals(const ast &ineq1, const ast &ineq2, const ast &chain, ast &normals,
|
||||
const ast &pos, hash_set<ast> &memo, ast &Aproves, ast &Bproves){
|
||||
opr o1 = op(ineq1);
|
||||
|
@ -933,14 +957,77 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
get_subterm_normals(arg(ineq1,i), arg(ineq2,i), chain, normals, new_pos, memo, Aproves, Bproves);
|
||||
}
|
||||
}
|
||||
else if(get_term_type(ineq2) == LitMixed && memo.find(ineq2) == memo.end()){
|
||||
memo.insert(ineq2);
|
||||
ast sub_chain = extract_rewrites(chain,pos);
|
||||
if(is_true(sub_chain))
|
||||
throw "bad inequality rewriting";
|
||||
ast new_normal = make_normal_step(ineq2,ineq1,reverse_chain(sub_chain));
|
||||
normals = merge_normal_chains(normals,cons_normal(new_normal,mk_true()), Aproves, Bproves);
|
||||
else if(get_term_type(ineq2) == LitMixed){
|
||||
if(memo.find(ineq2) == memo.end()){
|
||||
memo.insert(ineq2);
|
||||
ast sub_chain = extract_rewrites(chain,pos);
|
||||
if(is_true(sub_chain))
|
||||
throw "bad inequality rewriting";
|
||||
ast new_normal = make_normal_step(ineq2,ineq1,reverse_chain(sub_chain));
|
||||
normals = merge_normal_chains(normals,cons_normal(new_normal,mk_true()), Aproves, Bproves);
|
||||
}
|
||||
}
|
||||
else if(!(ineq1 == ineq2))
|
||||
throw subterm_normals_failed();
|
||||
}
|
||||
|
||||
ast rewrites_to_normals(const ast &ineq1, const ast &chain, ast &normals, ast &Aproves, ast &Bproves, ast &Aineqs){
|
||||
if(is_true(chain))
|
||||
return ineq1;
|
||||
ast last = chain_last(chain);
|
||||
ast rest = chain_rest(chain);
|
||||
ast new_ineq1 = rewrites_to_normals(ineq1, rest, normals, Aproves, Bproves, Aineqs);
|
||||
ast p1 = rewrite_pos(last);
|
||||
ast term1;
|
||||
ast coeff = arith_rewrite_coeff(new_ineq1,p1,term1);
|
||||
ast res = subst_in_pos(new_ineq1,rewrite_pos(last),rewrite_rhs(last));
|
||||
ast rpos;
|
||||
pos_diff(p1,rewrite_pos(last),rpos);
|
||||
ast term2 = subst_in_pos(term1,rpos,rewrite_rhs(last));
|
||||
if(get_term_type(term1) != LitMixed && get_term_type(term2) != LitMixed){
|
||||
if(is_rewrite_side(LitA,last))
|
||||
linear_comb(Aineqs,coeff,make(Leq,make_int(rational(0)),make(Sub,term2,term1)));
|
||||
}
|
||||
else {
|
||||
ast pf = extract_rewrites(make(concat,mk_true(),rest),p1);
|
||||
ast new_normal = fix_normal(term1,term2,pf);
|
||||
normals = merge_normal_chains(normals,cons_normal(new_normal,mk_true()), Aproves, Bproves);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ast arith_rewrite_coeff(const ast &ineq, ast &p1, ast &term){
|
||||
ast coeff = make_int(rational(1));
|
||||
if(p1 == top_pos){
|
||||
term = ineq;
|
||||
return coeff;
|
||||
}
|
||||
int argpos = pos_arg(p1);
|
||||
opr o = op(ineq);
|
||||
switch(o){
|
||||
case Leq:
|
||||
case Lt:
|
||||
coeff = argpos ? make_int(rational(1)) : make_int(rational(-1));
|
||||
break;
|
||||
case Geq:
|
||||
case Gt:
|
||||
coeff = argpos ? make_int(rational(-1)) : make_int(rational(1));
|
||||
break;
|
||||
case Not:
|
||||
case Plus:
|
||||
break;
|
||||
case Times:
|
||||
coeff = arg(ineq,0);
|
||||
break;
|
||||
default:
|
||||
p1 = top_pos;
|
||||
term = ineq;
|
||||
return coeff;
|
||||
}
|
||||
p1 = arg(p1,1);
|
||||
ast res = arith_rewrite_coeff(arg(ineq,argpos),p1,term);
|
||||
p1 = pos_add(argpos,p1);
|
||||
return coeff == make_int(rational(1)) ? res : make(Times,coeff,res);
|
||||
}
|
||||
|
||||
ast rewrite_chain_to_normal_ineq(const ast &chain, ast &Aproves, ast &Bproves){
|
||||
|
@ -950,20 +1037,25 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
ast ineq2 = apply_rewrite_chain(ineq1,tail);
|
||||
ast nc = mk_true();
|
||||
hash_set<ast> memo;
|
||||
get_subterm_normals(ineq1,ineq2,tail,nc,top_pos,memo, Aproves, Bproves);
|
||||
ast itp;
|
||||
ast itp = make(Leq,make_int(rational(0)),make_int(rational(0)));
|
||||
ast Aproves_save = Aproves, Bproves_save = Bproves; try {
|
||||
get_subterm_normals(ineq1,ineq2,tail,nc,top_pos,memo, Aproves, Bproves);
|
||||
}
|
||||
catch (const subterm_normals_failed &){ Aproves = Aproves_save; Bproves = Bproves_save; nc = mk_true();
|
||||
rewrites_to_normals(ineq1, tail, nc, Aproves, Bproves, itp);
|
||||
}
|
||||
if(is_rewrite_side(LitA,head)){
|
||||
itp = make(Leq,make_int("0"),make_int("0"));
|
||||
linear_comb(itp,make_int("1"),ineq1); // make sure it is normal form
|
||||
//itp = ineq1;
|
||||
ast mc = z3_simplify(chain_side_proves(LitB,pref));
|
||||
Bproves = my_and(Bproves,mc);
|
||||
}
|
||||
else {
|
||||
itp = make(Leq,make_int(rational(0)),make_int(rational(0)));
|
||||
ast mc = z3_simplify(chain_side_proves(LitA,pref));
|
||||
Aproves = my_and(Aproves,mc);
|
||||
}
|
||||
if(is_true(nc))
|
||||
return itp;
|
||||
return make_normal(itp,nc);
|
||||
}
|
||||
|
||||
|
@ -1010,6 +1102,31 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
}
|
||||
|
||||
|
||||
ast simplify_exmid(const std::vector<ast> &args){
|
||||
if(is_equivrel(args[0])){
|
||||
ast Aproves = mk_true(), Bproves = mk_true();
|
||||
ast chain = destruct_cond_ineq(args[1],Aproves,Bproves);
|
||||
ast Q2 = destruct_cond_ineq(args[2],Aproves,Bproves);
|
||||
ast interp = contra_chain(Q2,chain);
|
||||
return my_and(Aproves,my_implies(Bproves,interp));
|
||||
}
|
||||
throw "bad exmid";
|
||||
}
|
||||
|
||||
ast simplify_cong(const std::vector<ast> &args){
|
||||
ast Aproves = mk_true(), Bproves = mk_true();
|
||||
ast chain = destruct_cond_ineq(args[0],Aproves,Bproves);
|
||||
rational pos;
|
||||
if(is_numeral(args[1],pos)){
|
||||
int ipos = pos.get_unsigned();
|
||||
chain = chain_pos_add(ipos,chain);
|
||||
ast Q2 = destruct_cond_ineq(args[2],Aproves,Bproves);
|
||||
ast interp = contra_chain(Q2,chain);
|
||||
return my_and(Aproves,my_implies(Bproves,interp));
|
||||
}
|
||||
throw "bad cong";
|
||||
}
|
||||
|
||||
bool is_equivrel(const ast &p){
|
||||
opr o = op(p);
|
||||
return o == Equal || o == Iff;
|
||||
|
@ -1294,6 +1411,8 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
if(pos == top_pos && op(equality) == Iff && !is_true(arg(equality,0)))
|
||||
throw "bad rewrite";
|
||||
#endif
|
||||
if(!is_equivrel(equality))
|
||||
throw "bad rewrite";
|
||||
return make(t == LitA ? rewrite_A : rewrite_B, pos, cond, equality);
|
||||
}
|
||||
|
||||
|
@ -1556,9 +1675,20 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
return head;
|
||||
}
|
||||
|
||||
// split a rewrite chain into head and tail at last non-mixed term
|
||||
bool has_mixed_summands(const ast &e){
|
||||
if(op(e) == Plus){
|
||||
int nargs = num_args(e);
|
||||
for(int i = 0; i < nargs; i++)
|
||||
if(has_mixed_summands(arg(e,i)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return get_term_type(e) == LitMixed;
|
||||
}
|
||||
|
||||
// split a rewrite chain into head and tail at last sum with no mixed sumands
|
||||
ast get_right_movers(const ast &chain, const ast &rhs, ast &tail, ast &mid){
|
||||
if(is_true(chain) || get_term_type(rhs) != LitMixed){
|
||||
if(is_true(chain) || !has_mixed_summands(rhs)){
|
||||
mid = rhs;
|
||||
tail = mk_true();
|
||||
return chain;
|
||||
|
@ -1571,11 +1701,11 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
return res;
|
||||
}
|
||||
|
||||
// split a rewrite chain into head and tail at first non-mixed term
|
||||
// split a rewrite chain into head and tail at first sum with no mixed sumands
|
||||
ast get_left_movers(const ast &chain, const ast &lhs, ast &tail, ast &mid){
|
||||
if(is_true(chain)){
|
||||
mid = lhs;
|
||||
if(get_term_type(lhs) != LitMixed){
|
||||
if(!has_mixed_summands(lhs)){
|
||||
tail = mk_true();
|
||||
return chain;
|
||||
}
|
||||
|
@ -1675,10 +1805,21 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
}
|
||||
|
||||
|
||||
bool rewrites_from_to(const ast &chain, const ast &lhs, const ast &rhs){
|
||||
if(is_true(chain))
|
||||
return lhs == rhs;
|
||||
ast last = chain_last(chain);
|
||||
ast rest = chain_rest(chain);
|
||||
ast mid = subst_in_pos(rhs,rewrite_pos(last),rewrite_lhs(last));
|
||||
return rewrites_from_to(rest,lhs,mid);
|
||||
}
|
||||
|
||||
struct bad_ineq_inference {};
|
||||
|
||||
ast chain_ineqs(opr comp_op, LitType t, const ast &chain, const ast &lhs, const ast &rhs){
|
||||
if(is_true(chain)){
|
||||
if(lhs != rhs)
|
||||
throw "bad ineq inference";
|
||||
throw bad_ineq_inference();
|
||||
return make(Leq,make_int(rational(0)),make_int(rational(0)));
|
||||
}
|
||||
ast last = chain_last(chain);
|
||||
|
@ -1689,7 +1830,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
ast diff;
|
||||
if(comp_op == Leq) diff = make(Sub,rhs,mid);
|
||||
else diff = make(Sub,mid,rhs);
|
||||
ast foo = z3_simplify(make(Leq,make_int("0"),diff));
|
||||
ast foo = make(Leq,make_int("0"),z3_simplify(diff));
|
||||
if(is_true(cond))
|
||||
cond = foo;
|
||||
else {
|
||||
|
@ -2541,11 +2682,18 @@ class iz3proof_itp_impl : public iz3proof_itp {
|
|||
pf = make_refl(e); // proof that e = e
|
||||
|
||||
prover::range erng = pv->ast_scope(e);
|
||||
#if 0
|
||||
if(!(erng.lo > erng.hi) && pv->ranges_intersect(pv->ast_scope(e),rng)){
|
||||
return e; // this term occurs in range, so it's O.K.
|
||||
}
|
||||
#endif
|
||||
|
||||
hash_map<ast,ast>::iterator it = localization_map.find(e);
|
||||
|
||||
if(it != localization_map.end() && is_bool_type(get_type(e))
|
||||
&& !pv->ranges_intersect(pv->ast_scope(it->second),rng))
|
||||
it = localization_map.end(); // prevent quantifiers over booleans
|
||||
|
||||
if(it != localization_map.end()){
|
||||
pf = localization_pf_map[e];
|
||||
e = it->second;
|
||||
|
|
|
@ -1,321 +1,321 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3scopes.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Calculations with scopes, for both sequence and tree interpolation.
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "iz3scopes.h"
|
||||
|
||||
|
||||
/** computes the least common ancestor of two nodes in the tree, or SHRT_MAX if none */
|
||||
int scopes::tree_lca(int n1, int n2){
|
||||
if(!tree_mode())
|
||||
return std::max(n1,n2);
|
||||
if(n1 == SHRT_MIN) return n2;
|
||||
if(n2 == SHRT_MIN) return n1;
|
||||
if(n1 == SHRT_MAX || n2 == SHRT_MAX) return SHRT_MAX;
|
||||
while(n1 != n2){
|
||||
if(n1 == SHRT_MAX || n2 == SHRT_MAX) return SHRT_MAX;
|
||||
assert(n1 >= 0 && n2 >= 0 && n1 < (int)parents.size() && n2 < (int)parents.size());
|
||||
if(n1 < n2) n1 = parents[n1];
|
||||
else n2 = parents[n2];
|
||||
}
|
||||
return n1;
|
||||
}
|
||||
|
||||
/** computes the greatest common descendant two nodes in the tree, or SHRT_MIN if none */
|
||||
int scopes::tree_gcd(int n1, int n2){
|
||||
if(!tree_mode())
|
||||
return std::min(n1,n2);
|
||||
int foo = tree_lca(n1,n2);
|
||||
if(foo == n1) return n2;
|
||||
if(foo == n2) return n1;
|
||||
return SHRT_MIN;
|
||||
}
|
||||
|
||||
#ifndef FULL_TREE
|
||||
|
||||
/** test whether a tree node is contained in a range */
|
||||
bool scopes::in_range(int n, const range &rng){
|
||||
return tree_lca(rng.lo,n) == n && tree_gcd(rng.hi,n) == n;
|
||||
}
|
||||
|
||||
/** test whether two ranges of tree nodes intersect */
|
||||
bool scopes::ranges_intersect(const range &rng1, const range &rng2){
|
||||
return tree_lca(rng1.lo,rng2.hi) == rng2.hi && tree_lca(rng1.hi,rng2.lo) == rng1.hi;
|
||||
}
|
||||
|
||||
|
||||
bool scopes::range_contained(const range &rng1, const range &rng2){
|
||||
return tree_lca(rng2.lo,rng1.lo) == rng1.lo
|
||||
&& tree_lca(rng1.hi,rng2.hi) == rng2.hi;
|
||||
}
|
||||
|
||||
scopes::range scopes::range_lub(const range &rng1, const range &rng2){
|
||||
range res;
|
||||
res.lo = tree_gcd(rng1.lo,rng2.lo);
|
||||
res.hi = tree_lca(rng1.hi,rng2.hi);
|
||||
return res;
|
||||
}
|
||||
|
||||
scopes::range scopes::range_glb(const range &rng1, const range &rng2){
|
||||
range res;
|
||||
res.lo = tree_lca(rng1.lo,rng2.lo);
|
||||
res.hi = tree_gcd(rng1.hi,rng2.hi);
|
||||
return res;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class hash<scopes::range_lo > {
|
||||
public:
|
||||
size_t operator()(const scopes::range_lo &p) const {
|
||||
return p.lo + (size_t)p.next;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <> inline
|
||||
size_t stdext::hash_value<scopes::range_lo >(const scopes::range_lo& p)
|
||||
{
|
||||
std::hash<scopes::range_lo> h;
|
||||
return h(p);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class less<scopes::range_lo > {
|
||||
public:
|
||||
bool operator()(const scopes::range_lo &x, const scopes::range_lo &y) const {
|
||||
return x.lo < y.lo || x.lo == y.lo && (size_t)x.next < (size_t)y.next;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
struct range_op {
|
||||
scopes::range_lo *x, *y;
|
||||
int hi;
|
||||
range_op(scopes::range_lo *_x, scopes::range_lo *_y, int _hi){
|
||||
x = _x; y = _y; hi = _hi;
|
||||
}
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class hash<range_op > {
|
||||
public:
|
||||
size_t operator()(const range_op &p) const {
|
||||
return (size_t) p.x + (size_t)p.y + p.hi;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <> inline
|
||||
size_t stdext::hash_value<range_op >(const range_op& p)
|
||||
{
|
||||
std::hash<range_op> h;
|
||||
return h(p);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class less<range_op > {
|
||||
public:
|
||||
bool operator()(const range_op &x, const range_op &y) const {
|
||||
return (size_t)x.x < (size_t)y.x || x.x == y.x &&
|
||||
((size_t)x.y < (size_t)y.y || x.y == y.y && x.hi < y.hi);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct range_tables {
|
||||
hash_map<scopes::range_lo, scopes::range_lo *> unique;
|
||||
hash_map<range_op,scopes::range_lo *> lub;
|
||||
hash_map<range_op,scopes::range_lo *> glb;
|
||||
};
|
||||
|
||||
|
||||
scopes::range_lo *scopes::find_range_lo(int lo, range_lo *next){
|
||||
range_lo foo(lo,next);
|
||||
std::pair<range_lo,range_lo *> baz(foo,(range_lo *)0);
|
||||
std::pair<hash_map<range_lo,scopes::range_lo *>::iterator,bool> bar = rt->unique.insert(baz);
|
||||
if(bar.second)
|
||||
bar.first->second = new range_lo(lo,next);
|
||||
return bar.first->second;
|
||||
//std::pair<hash_set<scopes::range_lo>::iterator,bool> bar = rt->unique.insert(foo);
|
||||
// const range_lo *baz = &*(bar.first);
|
||||
// return (range_lo *)baz; // exit const hell
|
||||
}
|
||||
|
||||
scopes::range_lo *scopes::range_lub_lo(range_lo *rng1, range_lo *rng2){
|
||||
if(!rng1) return rng2;
|
||||
if(!rng2) return rng1;
|
||||
if(rng1->lo > rng2->lo)
|
||||
std::swap(rng1,rng2);
|
||||
std::pair<range_op,range_lo *> foo(range_op(rng1,rng2,0),(range_lo *)0);
|
||||
std::pair<hash_map<range_op,scopes::range_lo *>::iterator,bool> bar = rt->lub.insert(foo);
|
||||
range_lo *&res = bar.first->second;
|
||||
if(!bar.second) return res;
|
||||
if(!(rng1->next && rng1->next->lo <= rng2->lo)){
|
||||
for(int lo = rng1->lo; lo <= rng2->lo; lo = parents[lo])
|
||||
if(lo == rng2->lo)
|
||||
{rng2 = rng2->next; break;}
|
||||
}
|
||||
range_lo *baz = range_lub_lo(rng1->next,rng2);
|
||||
res = find_range_lo(rng1->lo,baz);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
scopes::range_lo *scopes::range_glb_lo(range_lo *rng1, range_lo *rng2, int hi){
|
||||
if(!rng1) return rng1;
|
||||
if(!rng2) return rng2;
|
||||
if(rng1->lo > rng2->lo)
|
||||
std::swap(rng1,rng2);
|
||||
std::pair<range_op,range_lo *> cand(range_op(rng1,rng2,hi),(range_lo *)0);
|
||||
std::pair<hash_map<range_op,scopes::range_lo *>::iterator,bool> bar = rt->glb.insert(cand);
|
||||
range_lo *&res = bar.first->second;
|
||||
if(!bar.second) return res;
|
||||
range_lo *foo;
|
||||
if(!(rng1->next && rng1->next->lo <= rng2->lo)){
|
||||
int lim = hi;
|
||||
if(rng1->next) lim = std::min(lim,rng1->next->lo);
|
||||
int a = rng1->lo, b = rng2->lo;
|
||||
while(a != b && b <= lim){
|
||||
a = parents[a];
|
||||
if(a > b)std::swap(a,b);
|
||||
}
|
||||
if(a == b && b <= lim){
|
||||
foo = range_glb_lo(rng1->next,rng2->next,hi);
|
||||
foo = find_range_lo(b,foo);
|
||||
}
|
||||
else
|
||||
foo = range_glb_lo(rng2,rng1->next,hi);
|
||||
}
|
||||
else foo = range_glb_lo(rng1->next,rng2,hi);
|
||||
res = foo;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** computes the lub (smallest containing subtree) of two ranges */
|
||||
scopes::range scopes::range_lub(const range &rng1, const range &rng2){
|
||||
int hi = tree_lca(rng1.hi,rng2.hi);
|
||||
if(hi == SHRT_MAX) return range_full();
|
||||
range_lo *lo = range_lub_lo(rng1.lo,rng2.lo);
|
||||
return range(hi,lo);
|
||||
}
|
||||
|
||||
/** computes the glb (intersection) of two ranges */
|
||||
scopes::range scopes::range_glb(const range &rng1, const range &rng2){
|
||||
if(rng1.hi == SHRT_MAX) return rng2;
|
||||
if(rng2.hi == SHRT_MAX) return rng1;
|
||||
int hi = tree_gcd(rng1.hi,rng2.hi);
|
||||
range_lo *lo = hi == SHRT_MIN ? 0 : range_glb_lo(rng1.lo,rng2.lo,hi);
|
||||
if(!lo) hi = SHRT_MIN;
|
||||
return range(hi,lo);
|
||||
}
|
||||
|
||||
/** is this range empty? */
|
||||
bool scopes::range_is_empty(const range &rng){
|
||||
return rng.hi == SHRT_MIN;
|
||||
}
|
||||
|
||||
/** return an empty range */
|
||||
scopes::range scopes::range_empty(){
|
||||
return range(SHRT_MIN,0);
|
||||
}
|
||||
|
||||
/** return a full range */
|
||||
scopes::range scopes::range_full(){
|
||||
return range(SHRT_MAX,0);
|
||||
}
|
||||
|
||||
/** return the maximal element of a range */
|
||||
int scopes::range_max(const range &rng){
|
||||
return rng.hi;
|
||||
}
|
||||
|
||||
/** return a minimal (not necessarily unique) element of a range */
|
||||
int scopes::range_min(const range &rng){
|
||||
if(rng.hi == SHRT_MAX) return SHRT_MIN;
|
||||
return rng.lo ? rng.lo->lo : SHRT_MAX;
|
||||
}
|
||||
|
||||
|
||||
/** return range consisting of downward closure of a point */
|
||||
scopes::range scopes::range_downward(int _hi){
|
||||
std::vector<bool> descendants(parents.size());
|
||||
for(int i = descendants.size() - 1; i >= 0 ; i--)
|
||||
descendants[i] = i == _hi || parents[i] < parents.size() && descendants[parents[i]];
|
||||
for(unsigned i = 0; i < descendants.size() - 1; i++)
|
||||
if(parents[i] < parents.size())
|
||||
descendants[parents[i]] = false;
|
||||
range_lo *foo = 0;
|
||||
for(int i = descendants.size() - 1; i >= 0; --i)
|
||||
if(descendants[i]) foo = find_range_lo(i,foo);
|
||||
return range(_hi,foo);
|
||||
}
|
||||
|
||||
/** add an element to a range */
|
||||
void scopes::range_add(int i, range &n){
|
||||
range foo = range(i, find_range_lo(i,0));
|
||||
n = range_lub(foo,n);
|
||||
}
|
||||
|
||||
/** Choose an element of rng1 that is near to rng2 */
|
||||
int scopes::range_near(const range &rng1, const range &rng2){
|
||||
|
||||
int frame;
|
||||
int thing = tree_lca(rng1.hi,rng2.hi);
|
||||
if(thing != rng1.hi) return rng1.hi;
|
||||
range line = range(rng1.hi,find_range_lo(rng2.hi,(range_lo *)0));
|
||||
line = range_glb(line,rng1);
|
||||
return range_min(line);
|
||||
}
|
||||
|
||||
|
||||
/** test whether a tree node is contained in a range */
|
||||
bool scopes::in_range(int n, const range &rng){
|
||||
range r = range_empty();
|
||||
range_add(n,r);
|
||||
r = range_glb(rng,r);
|
||||
return !range_is_empty(r);
|
||||
}
|
||||
|
||||
/** test whether two ranges of tree nodes intersect */
|
||||
bool scopes::ranges_intersect(const range &rng1, const range &rng2){
|
||||
range r = range_glb(rng1,rng2);
|
||||
return !range_is_empty(r);
|
||||
}
|
||||
|
||||
|
||||
bool scopes::range_contained(const range &rng1, const range &rng2){
|
||||
range r = range_glb(rng1,rng2);
|
||||
return r.hi == rng1.hi && r.lo == rng1.lo;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3scopes.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Calculations with scopes, for both sequence and tree interpolation.
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "iz3scopes.h"
|
||||
|
||||
|
||||
/** computes the least common ancestor of two nodes in the tree, or SHRT_MAX if none */
|
||||
int scopes::tree_lca(int n1, int n2){
|
||||
if(!tree_mode())
|
||||
return std::max(n1,n2);
|
||||
if(n1 == SHRT_MIN) return n2;
|
||||
if(n2 == SHRT_MIN) return n1;
|
||||
if(n1 == SHRT_MAX || n2 == SHRT_MAX) return SHRT_MAX;
|
||||
while(n1 != n2){
|
||||
if(n1 == SHRT_MAX || n2 == SHRT_MAX) return SHRT_MAX;
|
||||
assert(n1 >= 0 && n2 >= 0 && n1 < (int)parents.size() && n2 < (int)parents.size());
|
||||
if(n1 < n2) n1 = parents[n1];
|
||||
else n2 = parents[n2];
|
||||
}
|
||||
return n1;
|
||||
}
|
||||
|
||||
/** computes the greatest common descendant two nodes in the tree, or SHRT_MIN if none */
|
||||
int scopes::tree_gcd(int n1, int n2){
|
||||
if(!tree_mode())
|
||||
return std::min(n1,n2);
|
||||
int foo = tree_lca(n1,n2);
|
||||
if(foo == n1) return n2;
|
||||
if(foo == n2) return n1;
|
||||
return SHRT_MIN;
|
||||
}
|
||||
|
||||
#ifndef FULL_TREE
|
||||
|
||||
/** test whether a tree node is contained in a range */
|
||||
bool scopes::in_range(int n, const range &rng){
|
||||
return tree_lca(rng.lo,n) == n && tree_gcd(rng.hi,n) == n;
|
||||
}
|
||||
|
||||
/** test whether two ranges of tree nodes intersect */
|
||||
bool scopes::ranges_intersect(const range &rng1, const range &rng2){
|
||||
return tree_lca(rng1.lo,rng2.hi) == rng2.hi && tree_lca(rng1.hi,rng2.lo) == rng1.hi;
|
||||
}
|
||||
|
||||
|
||||
bool scopes::range_contained(const range &rng1, const range &rng2){
|
||||
return tree_lca(rng2.lo,rng1.lo) == rng1.lo
|
||||
&& tree_lca(rng1.hi,rng2.hi) == rng2.hi;
|
||||
}
|
||||
|
||||
scopes::range scopes::range_lub(const range &rng1, const range &rng2){
|
||||
range res;
|
||||
res.lo = tree_gcd(rng1.lo,rng2.lo);
|
||||
res.hi = tree_lca(rng1.hi,rng2.hi);
|
||||
return res;
|
||||
}
|
||||
|
||||
scopes::range scopes::range_glb(const range &rng1, const range &rng2){
|
||||
range res;
|
||||
res.lo = tree_lca(rng1.lo,rng2.lo);
|
||||
res.hi = tree_gcd(rng1.hi,rng2.hi);
|
||||
return res;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class hash<scopes::range_lo > {
|
||||
public:
|
||||
size_t operator()(const scopes::range_lo &p) const {
|
||||
return p.lo + (size_t)p.next;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <> inline
|
||||
size_t stdext::hash_value<scopes::range_lo >(const scopes::range_lo& p)
|
||||
{
|
||||
std::hash<scopes::range_lo> h;
|
||||
return h(p);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class less<scopes::range_lo > {
|
||||
public:
|
||||
bool operator()(const scopes::range_lo &x, const scopes::range_lo &y) const {
|
||||
return x.lo < y.lo || x.lo == y.lo && (size_t)x.next < (size_t)y.next;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
struct range_op {
|
||||
scopes::range_lo *x, *y;
|
||||
int hi;
|
||||
range_op(scopes::range_lo *_x, scopes::range_lo *_y, int _hi){
|
||||
x = _x; y = _y; hi = _hi;
|
||||
}
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class hash<range_op > {
|
||||
public:
|
||||
size_t operator()(const range_op &p) const {
|
||||
return (size_t) p.x + (size_t)p.y + p.hi;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <> inline
|
||||
size_t stdext::hash_value<range_op >(const range_op& p)
|
||||
{
|
||||
std::hash<range_op> h;
|
||||
return h(p);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class less<range_op > {
|
||||
public:
|
||||
bool operator()(const range_op &x, const range_op &y) const {
|
||||
return (size_t)x.x < (size_t)y.x || x.x == y.x &&
|
||||
((size_t)x.y < (size_t)y.y || x.y == y.y && x.hi < y.hi);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct range_tables {
|
||||
hash_map<scopes::range_lo, scopes::range_lo *> unique;
|
||||
hash_map<range_op,scopes::range_lo *> lub;
|
||||
hash_map<range_op,scopes::range_lo *> glb;
|
||||
};
|
||||
|
||||
|
||||
scopes::range_lo *scopes::find_range_lo(int lo, range_lo *next){
|
||||
range_lo foo(lo,next);
|
||||
std::pair<range_lo,range_lo *> baz(foo,(range_lo *)0);
|
||||
std::pair<hash_map<range_lo,scopes::range_lo *>::iterator,bool> bar = rt->unique.insert(baz);
|
||||
if(bar.second)
|
||||
bar.first->second = new range_lo(lo,next);
|
||||
return bar.first->second;
|
||||
//std::pair<hash_set<scopes::range_lo>::iterator,bool> bar = rt->unique.insert(foo);
|
||||
// const range_lo *baz = &*(bar.first);
|
||||
// return (range_lo *)baz; // exit const hell
|
||||
}
|
||||
|
||||
scopes::range_lo *scopes::range_lub_lo(range_lo *rng1, range_lo *rng2){
|
||||
if(!rng1) return rng2;
|
||||
if(!rng2) return rng1;
|
||||
if(rng1->lo > rng2->lo)
|
||||
std::swap(rng1,rng2);
|
||||
std::pair<range_op,range_lo *> foo(range_op(rng1,rng2,0),(range_lo *)0);
|
||||
std::pair<hash_map<range_op,scopes::range_lo *>::iterator,bool> bar = rt->lub.insert(foo);
|
||||
range_lo *&res = bar.first->second;
|
||||
if(!bar.second) return res;
|
||||
if(!(rng1->next && rng1->next->lo <= rng2->lo)){
|
||||
for(int lo = rng1->lo; lo <= rng2->lo; lo = parents[lo])
|
||||
if(lo == rng2->lo)
|
||||
{rng2 = rng2->next; break;}
|
||||
}
|
||||
range_lo *baz = range_lub_lo(rng1->next,rng2);
|
||||
res = find_range_lo(rng1->lo,baz);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
scopes::range_lo *scopes::range_glb_lo(range_lo *rng1, range_lo *rng2, int hi){
|
||||
if(!rng1) return rng1;
|
||||
if(!rng2) return rng2;
|
||||
if(rng1->lo > rng2->lo)
|
||||
std::swap(rng1,rng2);
|
||||
std::pair<range_op,range_lo *> cand(range_op(rng1,rng2,hi),(range_lo *)0);
|
||||
std::pair<hash_map<range_op,scopes::range_lo *>::iterator,bool> bar = rt->glb.insert(cand);
|
||||
range_lo *&res = bar.first->second;
|
||||
if(!bar.second) return res;
|
||||
range_lo *foo;
|
||||
if(!(rng1->next && rng1->next->lo <= rng2->lo)){
|
||||
int lim = hi;
|
||||
if(rng1->next) lim = std::min(lim,rng1->next->lo);
|
||||
int a = rng1->lo, b = rng2->lo;
|
||||
while(a != b && b <= lim){
|
||||
a = parents[a];
|
||||
if(a > b)std::swap(a,b);
|
||||
}
|
||||
if(a == b && b <= lim){
|
||||
foo = range_glb_lo(rng1->next,rng2->next,hi);
|
||||
foo = find_range_lo(b,foo);
|
||||
}
|
||||
else
|
||||
foo = range_glb_lo(rng2,rng1->next,hi);
|
||||
}
|
||||
else foo = range_glb_lo(rng1->next,rng2,hi);
|
||||
res = foo;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** computes the lub (smallest containing subtree) of two ranges */
|
||||
scopes::range scopes::range_lub(const range &rng1, const range &rng2){
|
||||
int hi = tree_lca(rng1.hi,rng2.hi);
|
||||
if(hi == SHRT_MAX) return range_full();
|
||||
range_lo *lo = range_lub_lo(rng1.lo,rng2.lo);
|
||||
return range(hi,lo);
|
||||
}
|
||||
|
||||
/** computes the glb (intersection) of two ranges */
|
||||
scopes::range scopes::range_glb(const range &rng1, const range &rng2){
|
||||
if(rng1.hi == SHRT_MAX) return rng2;
|
||||
if(rng2.hi == SHRT_MAX) return rng1;
|
||||
int hi = tree_gcd(rng1.hi,rng2.hi);
|
||||
range_lo *lo = hi == SHRT_MIN ? 0 : range_glb_lo(rng1.lo,rng2.lo,hi);
|
||||
if(!lo) hi = SHRT_MIN;
|
||||
return range(hi,lo);
|
||||
}
|
||||
|
||||
/** is this range empty? */
|
||||
bool scopes::range_is_empty(const range &rng){
|
||||
return rng.hi == SHRT_MIN;
|
||||
}
|
||||
|
||||
/** return an empty range */
|
||||
scopes::range scopes::range_empty(){
|
||||
return range(SHRT_MIN,0);
|
||||
}
|
||||
|
||||
/** return a full range */
|
||||
scopes::range scopes::range_full(){
|
||||
return range(SHRT_MAX,0);
|
||||
}
|
||||
|
||||
/** return the maximal element of a range */
|
||||
int scopes::range_max(const range &rng){
|
||||
return rng.hi;
|
||||
}
|
||||
|
||||
/** return a minimal (not necessarily unique) element of a range */
|
||||
int scopes::range_min(const range &rng){
|
||||
if(rng.hi == SHRT_MAX) return SHRT_MIN;
|
||||
return rng.lo ? rng.lo->lo : SHRT_MAX;
|
||||
}
|
||||
|
||||
|
||||
/** return range consisting of downward closure of a point */
|
||||
scopes::range scopes::range_downward(int _hi){
|
||||
std::vector<bool> descendants(parents.size());
|
||||
for(int i = descendants.size() - 1; i >= 0 ; i--)
|
||||
descendants[i] = i == _hi || parents[i] < parents.size() && descendants[parents[i]];
|
||||
for(unsigned i = 0; i < descendants.size() - 1; i++)
|
||||
if(parents[i] < parents.size())
|
||||
descendants[parents[i]] = false;
|
||||
range_lo *foo = 0;
|
||||
for(int i = descendants.size() - 1; i >= 0; --i)
|
||||
if(descendants[i]) foo = find_range_lo(i,foo);
|
||||
return range(_hi,foo);
|
||||
}
|
||||
|
||||
/** add an element to a range */
|
||||
void scopes::range_add(int i, range &n){
|
||||
range foo = range(i, find_range_lo(i,0));
|
||||
n = range_lub(foo,n);
|
||||
}
|
||||
|
||||
/** Choose an element of rng1 that is near to rng2 */
|
||||
int scopes::range_near(const range &rng1, const range &rng2){
|
||||
|
||||
int frame;
|
||||
int thing = tree_lca(rng1.hi,rng2.hi);
|
||||
if(thing != rng1.hi) return rng1.hi;
|
||||
range line = range(rng1.hi,find_range_lo(rng2.hi,(range_lo *)0));
|
||||
line = range_glb(line,rng1);
|
||||
return range_min(line);
|
||||
}
|
||||
|
||||
|
||||
/** test whether a tree node is contained in a range */
|
||||
bool scopes::in_range(int n, const range &rng){
|
||||
range r = range_empty();
|
||||
range_add(n,r);
|
||||
r = range_glb(rng,r);
|
||||
return !range_is_empty(r);
|
||||
}
|
||||
|
||||
/** test whether two ranges of tree nodes intersect */
|
||||
bool scopes::ranges_intersect(const range &rng1, const range &rng2){
|
||||
range r = range_glb(rng1,rng2);
|
||||
return !range_is_empty(r);
|
||||
}
|
||||
|
||||
|
||||
bool scopes::range_contained(const range &rng1, const range &rng2){
|
||||
range r = range_glb(rng1,rng2);
|
||||
return r.hi == rng1.hi && r.lo == rng1.lo;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,197 +1,197 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3scopes.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Calculations with scopes, for both sequence and tree interpolation.
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef IZ3SOPES_H
|
||||
#define IZ3SOPES_H
|
||||
|
||||
#include <vector>
|
||||
#include <limits.h>
|
||||
|
||||
class scopes {
|
||||
|
||||
public:
|
||||
/** Construct from parents vector. */
|
||||
scopes(const std::vector<int> &_parents){
|
||||
parents = _parents;
|
||||
}
|
||||
|
||||
scopes(){
|
||||
}
|
||||
|
||||
void initialize(const std::vector<int> &_parents){
|
||||
parents = _parents;
|
||||
}
|
||||
|
||||
/** The parents vector defining the tree structure */
|
||||
std::vector<int> parents;
|
||||
|
||||
// #define FULL_TREE
|
||||
#ifndef FULL_TREE
|
||||
struct range {
|
||||
range(){
|
||||
lo = SHRT_MAX;
|
||||
hi = SHRT_MIN;
|
||||
}
|
||||
short lo, hi;
|
||||
};
|
||||
|
||||
/** computes the lub (smallest containing subtree) of two ranges */
|
||||
range range_lub(const range &rng1, const range &rng2);
|
||||
|
||||
/** computes the glb (intersection) of two ranges */
|
||||
range range_glb(const range &rng1, const range &rng2);
|
||||
|
||||
/** is this range empty? */
|
||||
bool range_is_empty(const range &rng){
|
||||
return rng.hi < rng.lo;
|
||||
}
|
||||
|
||||
/** return an empty range */
|
||||
range range_empty(){
|
||||
range res;
|
||||
res.lo = SHRT_MAX;
|
||||
res.hi = SHRT_MIN;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** return an empty range */
|
||||
range range_full(){
|
||||
range res;
|
||||
res.lo = SHRT_MIN;
|
||||
res.hi = SHRT_MAX;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** return the maximal element of a range */
|
||||
int range_max(const range &rng){
|
||||
return rng.hi;
|
||||
}
|
||||
|
||||
/** return a minimal (not necessarily unique) element of a range */
|
||||
int range_min(const range &rng){
|
||||
return rng.lo;
|
||||
}
|
||||
|
||||
/** return range consisting of downward closure of a point */
|
||||
range range_downward(int _hi){
|
||||
range foo;
|
||||
foo.lo = SHRT_MIN;
|
||||
foo.hi = _hi;
|
||||
return foo;
|
||||
}
|
||||
|
||||
void range_add(int i, range &n){
|
||||
#if 0
|
||||
if(i < n.lo) n.lo = i;
|
||||
if(i > n.hi) n.hi = i;
|
||||
#else
|
||||
range rng; rng.lo = i; rng.hi = i;
|
||||
n = range_lub(rng,n);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Choose an element of rng1 that is near to rng2 */
|
||||
int range_near(const range &rng1, const range &rng2){
|
||||
int frame;
|
||||
int thing = tree_lca(rng1.lo,rng2.hi);
|
||||
if(thing == rng1.lo) frame = rng1.lo;
|
||||
else frame = tree_gcd(thing,rng1.hi);
|
||||
return frame;
|
||||
}
|
||||
#else
|
||||
|
||||
struct range_lo {
|
||||
int lo;
|
||||
range_lo *next;
|
||||
range_lo(int _lo, range_lo *_next){
|
||||
lo = _lo;
|
||||
next = _next;
|
||||
}
|
||||
};
|
||||
|
||||
struct range {
|
||||
int hi;
|
||||
range_lo *lo;
|
||||
range(int _hi, range_lo *_lo){
|
||||
hi = _hi;
|
||||
lo = _lo;
|
||||
}
|
||||
range(){
|
||||
hi = SHRT_MIN;
|
||||
lo = 0;
|
||||
}
|
||||
};
|
||||
|
||||
range_tables *rt;
|
||||
|
||||
/** computes the lub (smallest containing subtree) of two ranges */
|
||||
range range_lub(const range &rng1, const range &rng2);
|
||||
|
||||
/** computes the glb (intersection) of two ranges */
|
||||
range range_glb(const range &rng1, const range &rng2);
|
||||
|
||||
/** is this range empty? */
|
||||
bool range_is_empty(const range &rng);
|
||||
|
||||
/** return an empty range */
|
||||
range range_empty();
|
||||
|
||||
/** return a full range */
|
||||
range range_full();
|
||||
|
||||
/** return the maximal element of a range */
|
||||
int range_max(const range &rng);
|
||||
|
||||
/** return a minimal (not necessarily unique) element of a range */
|
||||
int range_min(const range &rng);
|
||||
|
||||
/** return range consisting of downward closure of a point */
|
||||
range range_downward(int _hi);
|
||||
|
||||
/** add an element to a range */
|
||||
void range_add(int i, range &n);
|
||||
|
||||
/** Choose an element of rng1 that is near to rng2 */
|
||||
int range_near(const range &rng1, const range &rng2);
|
||||
|
||||
range_lo *find_range_lo(int lo, range_lo *next);
|
||||
range_lo *range_lub_lo(range_lo *rng1, range_lo *rng2);
|
||||
range_lo *range_glb_lo(range_lo *rng1, range_lo *rng2, int lim);
|
||||
|
||||
#endif
|
||||
|
||||
/** test whether a tree node is contained in a range */
|
||||
bool in_range(int n, const range &rng);
|
||||
|
||||
/** test whether two ranges of tree nodes intersect */
|
||||
bool ranges_intersect(const range &rng1, const range &rng2);
|
||||
|
||||
/** test whether range rng1 contained in range rng2 */
|
||||
bool range_contained(const range &rng1, const range &rng2);
|
||||
|
||||
private:
|
||||
int tree_lca(int n1, int n2);
|
||||
int tree_gcd(int n1, int n2);
|
||||
bool tree_mode(){return parents.size() != 0;}
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
iz3scopes.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Calculations with scopes, for both sequence and tree interpolation.
|
||||
|
||||
Author:
|
||||
|
||||
Ken McMillan (kenmcmil)
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef IZ3SOPES_H
|
||||
#define IZ3SOPES_H
|
||||
|
||||
#include <vector>
|
||||
#include <limits.h>
|
||||
|
||||
class scopes {
|
||||
|
||||
public:
|
||||
/** Construct from parents vector. */
|
||||
scopes(const std::vector<int> &_parents){
|
||||
parents = _parents;
|
||||
}
|
||||
|
||||
scopes(){
|
||||
}
|
||||
|
||||
void initialize(const std::vector<int> &_parents){
|
||||
parents = _parents;
|
||||
}
|
||||
|
||||
/** The parents vector defining the tree structure */
|
||||
std::vector<int> parents;
|
||||
|
||||
// #define FULL_TREE
|
||||
#ifndef FULL_TREE
|
||||
struct range {
|
||||
range(){
|
||||
lo = SHRT_MAX;
|
||||
hi = SHRT_MIN;
|
||||
}
|
||||
short lo, hi;
|
||||
};
|
||||
|
||||
/** computes the lub (smallest containing subtree) of two ranges */
|
||||
range range_lub(const range &rng1, const range &rng2);
|
||||
|
||||
/** computes the glb (intersection) of two ranges */
|
||||
range range_glb(const range &rng1, const range &rng2);
|
||||
|
||||
/** is this range empty? */
|
||||
bool range_is_empty(const range &rng){
|
||||
return rng.hi < rng.lo;
|
||||
}
|
||||
|
||||
/** return an empty range */
|
||||
range range_empty(){
|
||||
range res;
|
||||
res.lo = SHRT_MAX;
|
||||
res.hi = SHRT_MIN;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** return an empty range */
|
||||
range range_full(){
|
||||
range res;
|
||||
res.lo = SHRT_MIN;
|
||||
res.hi = SHRT_MAX;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** return the maximal element of a range */
|
||||
int range_max(const range &rng){
|
||||
return rng.hi;
|
||||
}
|
||||
|
||||
/** return a minimal (not necessarily unique) element of a range */
|
||||
int range_min(const range &rng){
|
||||
return rng.lo;
|
||||
}
|
||||
|
||||
/** return range consisting of downward closure of a point */
|
||||
range range_downward(int _hi){
|
||||
range foo;
|
||||
foo.lo = SHRT_MIN;
|
||||
foo.hi = _hi;
|
||||
return foo;
|
||||
}
|
||||
|
||||
void range_add(int i, range &n){
|
||||
#if 0
|
||||
if(i < n.lo) n.lo = i;
|
||||
if(i > n.hi) n.hi = i;
|
||||
#else
|
||||
range rng; rng.lo = i; rng.hi = i;
|
||||
n = range_lub(rng,n);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Choose an element of rng1 that is near to rng2 */
|
||||
int range_near(const range &rng1, const range &rng2){
|
||||
int frame;
|
||||
int thing = tree_lca(rng1.lo,rng2.hi);
|
||||
if(thing == rng1.lo) frame = rng1.lo;
|
||||
else frame = tree_gcd(thing,rng1.hi);
|
||||
return frame;
|
||||
}
|
||||
#else
|
||||
|
||||
struct range_lo {
|
||||
int lo;
|
||||
range_lo *next;
|
||||
range_lo(int _lo, range_lo *_next){
|
||||
lo = _lo;
|
||||
next = _next;
|
||||
}
|
||||
};
|
||||
|
||||
struct range {
|
||||
int hi;
|
||||
range_lo *lo;
|
||||
range(int _hi, range_lo *_lo){
|
||||
hi = _hi;
|
||||
lo = _lo;
|
||||
}
|
||||
range(){
|
||||
hi = SHRT_MIN;
|
||||
lo = 0;
|
||||
}
|
||||
};
|
||||
|
||||
range_tables *rt;
|
||||
|
||||
/** computes the lub (smallest containing subtree) of two ranges */
|
||||
range range_lub(const range &rng1, const range &rng2);
|
||||
|
||||
/** computes the glb (intersection) of two ranges */
|
||||
range range_glb(const range &rng1, const range &rng2);
|
||||
|
||||
/** is this range empty? */
|
||||
bool range_is_empty(const range &rng);
|
||||
|
||||
/** return an empty range */
|
||||
range range_empty();
|
||||
|
||||
/** return a full range */
|
||||
range range_full();
|
||||
|
||||
/** return the maximal element of a range */
|
||||
int range_max(const range &rng);
|
||||
|
||||
/** return a minimal (not necessarily unique) element of a range */
|
||||
int range_min(const range &rng);
|
||||
|
||||
/** return range consisting of downward closure of a point */
|
||||
range range_downward(int _hi);
|
||||
|
||||
/** add an element to a range */
|
||||
void range_add(int i, range &n);
|
||||
|
||||
/** Choose an element of rng1 that is near to rng2 */
|
||||
int range_near(const range &rng1, const range &rng2);
|
||||
|
||||
range_lo *find_range_lo(int lo, range_lo *next);
|
||||
range_lo *range_lub_lo(range_lo *rng1, range_lo *rng2);
|
||||
range_lo *range_glb_lo(range_lo *rng1, range_lo *rng2, int lim);
|
||||
|
||||
#endif
|
||||
|
||||
/** test whether a tree node is contained in a range */
|
||||
bool in_range(int n, const range &rng);
|
||||
|
||||
/** test whether two ranges of tree nodes intersect */
|
||||
bool ranges_intersect(const range &rng1, const range &rng2);
|
||||
|
||||
/** test whether range rng1 contained in range rng2 */
|
||||
bool range_contained(const range &rng1, const range &rng2);
|
||||
|
||||
private:
|
||||
int tree_lca(int n1, int n2);
|
||||
int tree_gcd(int n1, int n2);
|
||||
bool tree_mode(){return parents.size() != 0;}
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
@ -39,9 +39,7 @@ Revision History:
|
|||
#include <set>
|
||||
|
||||
//using std::vector;
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -466,7 +464,7 @@ public:
|
|||
for(int i = 0; i < 2; i++){ // try the second equality both ways
|
||||
if(match_op(eq_ops_r[0],Select,sel_ops,2))
|
||||
if(match_op(sel_ops[0],Store,sto_ops,3))
|
||||
if(match_op(eq_ops_r[1],Select,sel_ops2,2))
|
||||
if(match_op(eq_ops_r[1],Select,sel_ops2,2))
|
||||
for(int j = 0; j < 2; j++){ // try the first equality both ways
|
||||
if(eq_ops_l[0] == sto_ops[1]
|
||||
&& eq_ops_l[1] == sel_ops[1]
|
||||
|
@ -484,8 +482,8 @@ public:
|
|||
// int frame = range_min(ast_scope(res)); TODO
|
||||
// antes.push_back(std::pair<ast,int>(res,frame));
|
||||
return;
|
||||
}
|
||||
std::swap(eq_ops_l[0],eq_ops_l[1]);
|
||||
}
|
||||
std::swap(eq_ops_l[0],eq_ops_l[1]);
|
||||
}
|
||||
std::swap(eq_ops_r[0],eq_ops_r[1]);
|
||||
}
|
||||
|
@ -1592,6 +1590,27 @@ public:
|
|||
return res;
|
||||
}
|
||||
|
||||
/* This idiom takes ~P and Q=P, yielding ~Q. It uses a "rewrite"
|
||||
(Q=false) = ~Q. We eliminate the rewrite by using symmetry,
|
||||
congruence and modus ponens. */
|
||||
|
||||
if(dk == PR_MODUS_PONENS && pr(prem(proof,1)) == PR_REWRITE && pr(prem(proof,0)) == PR_TRANSITIVITY && pr(prem(prem(proof,0),1)) == PR_IFF_FALSE){
|
||||
if(op(con) == Not && arg(con,0) == arg(conc(prem(proof,0)),0)){
|
||||
Iproof::node ante1 = translate_main(prem(prem(proof,0),0),false);
|
||||
Iproof::node ante2 = translate_main(prem(prem(prem(proof,0),1),0),false);
|
||||
ast ante1_con = conc(prem(prem(proof,0),0));
|
||||
ast eq0 = arg(ante1_con,0);
|
||||
ast eq1 = arg(ante1_con,1);
|
||||
ast symm_con = make(Iff,eq1,eq0);
|
||||
Iproof::node ante1s = iproof->make_symmetry(symm_con,ante1_con,ante1);
|
||||
ast cong_con = make(Iff,make(Not,eq1),make(Not,eq0));
|
||||
Iproof::node ante1sc = iproof->make_congruence(symm_con,cong_con,ante1s);
|
||||
res = iproof->make_mp(cong_con,ante2,ante1sc);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// translate all the premises
|
||||
std::vector<Iproof::node> args(nprems);
|
||||
for(unsigned i = 0; i < nprems; i++)
|
||||
|
@ -1751,6 +1770,13 @@ public:
|
|||
res = args[0];
|
||||
break;
|
||||
}
|
||||
case PR_IFF_FALSE: { // turns ~p into p <-> false, noop for us
|
||||
if(is_local(con))
|
||||
res = args[0];
|
||||
else
|
||||
throw unsupported();
|
||||
break;
|
||||
}
|
||||
case PR_COMMUTATIVITY: {
|
||||
ast comm_equiv = make(op(con),arg(con,0),arg(con,0));
|
||||
ast pf = iproof->make_reflexivity(comm_equiv);
|
||||
|
@ -1758,6 +1784,7 @@ public:
|
|||
break;
|
||||
}
|
||||
default:
|
||||
pfgoto(proof);
|
||||
assert(0 && "translate_main: unsupported proof rule");
|
||||
throw unsupported();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ Revision History:
|
|||
--*/
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WINDOWS
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4267)
|
||||
|
@ -42,11 +42,7 @@ Revision History:
|
|||
#include <set>
|
||||
|
||||
//using std::vector;
|
||||
#ifndef WIN32
|
||||
using namespace stl_ext;
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
/* This can introduce an address dependency if the range type of hash_map has
|
||||
a destructor. Since the code in this file is not used and only here for
|
||||
|
@ -62,9 +58,6 @@ namespace stl_ext {
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static int lemma_count = 0;
|
||||
#if 0
|
||||
static int nll_lemma_count = 0;
|
||||
|
@ -96,38 +89,12 @@ namespace hash_space {
|
|||
};
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
template <> inline
|
||||
size_t stdext::hash_value<Z3_resolvent >(const Z3_resolvent& p)
|
||||
{
|
||||
std::hash<Z3_resolvent> h;
|
||||
return h(p);
|
||||
}
|
||||
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class less<Z3_resolvent > {
|
||||
public:
|
||||
bool operator()(const Z3_resolvent &x, const Z3_resolvent &y) const {
|
||||
size_t ixproof = (size_t) x.proof.raw();
|
||||
size_t iyproof = (size_t) y.proof.raw();
|
||||
if(ixproof < iyproof) return true;
|
||||
if(ixproof > iyproof) return false;
|
||||
return x.pivot < y.pivot;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool operator==(const Z3_resolvent &x, const Z3_resolvent &y) {
|
||||
return x.proof == y.proof && x.pivot == y.pivot;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
typedef std::vector<Z3_resolvent *> ResolventAppSet;
|
||||
|
||||
|
@ -151,36 +118,6 @@ namespace hash_space {
|
|||
};
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
template <> inline
|
||||
size_t stdext::hash_value<non_local_lits >(const non_local_lits& p)
|
||||
{
|
||||
std::hash<non_local_lits> h;
|
||||
return h(p);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
class less<non_local_lits > {
|
||||
public:
|
||||
bool operator()(const non_local_lits &x, const non_local_lits &y) const {
|
||||
ResolventAppSet::const_iterator itx = x.proofs.begin();
|
||||
ResolventAppSet::const_iterator ity = y.proofs.begin();
|
||||
while(true){
|
||||
if(ity == y.proofs.end()) return false;
|
||||
if(itx == x.proofs.end()) return true;
|
||||
size_t xi = (size_t) *itx;
|
||||
size_t yi = (size_t) *ity;
|
||||
if(xi < yi) return true;
|
||||
if(xi > yi) return false;
|
||||
++itx; ++ity;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool operator==(const non_local_lits &x, const non_local_lits &y) {
|
||||
ResolventAppSet::const_iterator itx = x.proofs.begin();
|
||||
|
@ -194,8 +131,6 @@ bool operator==(const non_local_lits &x, const non_local_lits &y) {
|
|||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* This translator goes directly from Z3 proofs to interpolatable
|
||||
proofs without an intermediate representation as an iz3proof. */
|
||||
|
||||
|
@ -549,7 +484,7 @@ public:
|
|||
for(int i = 0; i < 2; i++){ // try the second equality both ways
|
||||
if(match_op(eq_ops_r[0],Select,sel_ops,2))
|
||||
if(match_op(sel_ops[0],Store,sto_ops,3))
|
||||
if(match_op(eq_ops_r[1],Select,sel_ops2,2))
|
||||
if(match_op(eq_ops_r[1],Select,sel_ops2,2))
|
||||
for(int j = 0; j < 2; j++){ // try the first equality both ways
|
||||
if(eq_ops_l[0] == sto_ops[1]
|
||||
&& eq_ops_l[1] == sel_ops[1]
|
||||
|
@ -567,8 +502,8 @@ public:
|
|||
int frame = range_min(ast_scope(res));
|
||||
antes.push_back(std::pair<ast,int>(res,frame));
|
||||
return;
|
||||
}
|
||||
std::swap(eq_ops_l[0],eq_ops_l[1]);
|
||||
}
|
||||
std::swap(eq_ops_l[0],eq_ops_l[1]);
|
||||
}
|
||||
std::swap(eq_ops_r[0],eq_ops_r[1]);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ def_module_params('fixedpoint',
|
|||
('stratified_inlining', BOOL, False, 'DUALITY: Use stratified inlining'),
|
||||
('recursion_bound', UINT, UINT_MAX, 'DUALITY: Recursion bound for stratified inlining'),
|
||||
('profile', BOOL, False, 'DUALITY: profile run time'),
|
||||
('mbqi', BOOL, True, 'DUALITY: use model-based quantifier instantion'),
|
||||
('batch_expand', BOOL, False, 'DUALITY: use batch expansion'),
|
||||
('dump_aig', SYMBOL, '', 'Dump clauses in AIG text format (AAG) to the given file name'),
|
||||
))
|
||||
|
||||
|
|
|
@ -1465,6 +1465,10 @@ namespace datalog {
|
|||
if (m_rules.get_num_rules() == 0) {
|
||||
return l_false;
|
||||
}
|
||||
if (m_rules.get_predicate_rules(m_query_pred).empty()) {
|
||||
return l_false;
|
||||
}
|
||||
|
||||
|
||||
if (is_linear()) {
|
||||
if (m_ctx.get_engine() == QBMC_ENGINE) {
|
||||
|
|
|
@ -64,20 +64,22 @@ namespace Duality {
|
|||
std::vector<expr> clauses;
|
||||
std::vector<std::vector<RPFP::label_struct> > clause_labels;
|
||||
hash_map<RPFP::Edge *,int> map; // edges to clauses
|
||||
Solver *old_rs;
|
||||
Solver::Counterexample cex;
|
||||
|
||||
duality_data(ast_manager &_m) : ctx(_m,config(params_ref())) {
|
||||
ls = 0;
|
||||
rpfp = 0;
|
||||
status = StatusNull;
|
||||
old_rs = 0;
|
||||
}
|
||||
~duality_data(){
|
||||
if(old_rs)
|
||||
dealloc(old_rs);
|
||||
if(rpfp)
|
||||
dealloc(rpfp);
|
||||
if(ls)
|
||||
dealloc(ls);
|
||||
if(cex.tree)
|
||||
delete cex.tree;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -132,15 +134,18 @@ lbool dl_interface::query(::expr * query) {
|
|||
m_ctx.ensure_opened();
|
||||
|
||||
// if there is old data, get the cex and dispose (later)
|
||||
Solver::Counterexample old_cex;
|
||||
duality_data *old_data = _d;
|
||||
if(old_data)
|
||||
old_cex = old_data->cex;
|
||||
Solver *old_rs = 0;
|
||||
if(old_data){
|
||||
old_rs = old_data->old_rs;
|
||||
old_rs->GetCounterexample().swap(old_data->cex);
|
||||
}
|
||||
|
||||
scoped_proof generate_proofs_please(m_ctx.get_manager());
|
||||
|
||||
// make a new problem and solver
|
||||
_d = alloc(duality_data,m_ctx.get_manager());
|
||||
_d->ctx.set("mbqi",m_ctx.get_params().mbqi());
|
||||
_d->ls = alloc(RPFP::iZ3LogicSolver,_d->ctx);
|
||||
_d->rpfp = alloc(RPFP,_d->ls);
|
||||
|
||||
|
@ -195,8 +200,9 @@ lbool dl_interface::query(::expr * query) {
|
|||
|
||||
Solver *rs = Solver::Create("duality", _d->rpfp);
|
||||
|
||||
rs->LearnFrom(old_cex); // new solver gets hints from old cex
|
||||
|
||||
if(old_rs)
|
||||
rs->LearnFrom(old_rs); // new solver gets hints from old solver
|
||||
|
||||
// set its options
|
||||
IF_VERBOSE(1, rs->SetOption("report","1"););
|
||||
rs->SetOption("full_expand",m_ctx.get_params().full_expand() ? "1" : "0");
|
||||
|
@ -204,6 +210,7 @@ lbool dl_interface::query(::expr * query) {
|
|||
rs->SetOption("feasible_edges",m_ctx.get_params().feasible_edges() ? "1" : "0");
|
||||
rs->SetOption("use_underapprox",m_ctx.get_params().use_underapprox() ? "1" : "0");
|
||||
rs->SetOption("stratified_inlining",m_ctx.get_params().stratified_inlining() ? "1" : "0");
|
||||
rs->SetOption("batch_expand",m_ctx.get_params().batch_expand() ? "1" : "0");
|
||||
unsigned rb = m_ctx.get_params().recursion_bound();
|
||||
if(rb != UINT_MAX){
|
||||
std::ostringstream os; os << rb;
|
||||
|
@ -229,15 +236,14 @@ lbool dl_interface::query(::expr * query) {
|
|||
|
||||
// save the result and counterexample if there is one
|
||||
_d->status = ans ? StatusModel : StatusRefutation;
|
||||
_d->cex = rs->GetCounterexample();
|
||||
_d->cex.swap(rs->GetCounterexample()); // take ownership of cex
|
||||
_d->old_rs = rs; // save this for later hints
|
||||
|
||||
if(old_data){
|
||||
old_data->cex.tree = 0; // we own it now
|
||||
dealloc(old_data);
|
||||
dealloc(old_data); // this deallocates the old solver if there is one
|
||||
}
|
||||
|
||||
|
||||
dealloc(rs);
|
||||
// dealloc(rs); this is now owned by data
|
||||
|
||||
// true means the RPFP problem is SAT, so the query is UNSAT
|
||||
return ans ? l_false : l_true;
|
||||
|
@ -265,18 +271,16 @@ void dl_interface::reset_statistics() {
|
|||
|
||||
static hash_set<func_decl> *local_func_decls;
|
||||
|
||||
static void print_proof(dl_interface *d, std::ostream& out, Solver::Counterexample &cex) {
|
||||
static void print_proof(dl_interface *d, std::ostream& out, RPFP *tree, RPFP::Node *root) {
|
||||
context &ctx = d->dd()->ctx;
|
||||
RPFP::Node &node = *cex.root;
|
||||
RPFP::Node &node = *root;
|
||||
RPFP::Edge &edge = *node.Outgoing;
|
||||
|
||||
// first, prove the children (that are actually used)
|
||||
|
||||
for(unsigned i = 0; i < edge.Children.size(); i++){
|
||||
if(!cex.tree->Empty(edge.Children[i])){
|
||||
Solver::Counterexample foo = cex;
|
||||
foo.root = edge.Children[i];
|
||||
print_proof(d,out,foo);
|
||||
if(!tree->Empty(edge.Children[i])){
|
||||
print_proof(d,out,tree,edge.Children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,7 +289,7 @@ static void print_proof(dl_interface *d, std::ostream& out, Solver::Counterexamp
|
|||
out << "(step s!" << node.number;
|
||||
out << " (" << node.Name.name();
|
||||
for(unsigned i = 0; i < edge.F.IndParams.size(); i++)
|
||||
out << " " << cex.tree->Eval(&edge,edge.F.IndParams[i]);
|
||||
out << " " << tree->Eval(&edge,edge.F.IndParams[i]);
|
||||
out << ")\n";
|
||||
|
||||
// print the rule number
|
||||
|
@ -307,8 +311,8 @@ static void print_proof(dl_interface *d, std::ostream& out, Solver::Counterexamp
|
|||
sort the_sort = t.get_quantifier_bound_sort(j);
|
||||
symbol name = t.get_quantifier_bound_name(j);
|
||||
expr skolem = ctx.constant(symbol(ctx,name),sort(ctx,the_sort));
|
||||
out << " (= " << skolem << " " << cex.tree->Eval(&edge,skolem) << ")\n";
|
||||
expr local_skolem = cex.tree->Localize(&edge,skolem);
|
||||
out << " (= " << skolem << " " << tree->Eval(&edge,skolem) << ")\n";
|
||||
expr local_skolem = tree->Localize(&edge,skolem);
|
||||
(*local_func_decls).insert(local_skolem.decl());
|
||||
}
|
||||
}
|
||||
|
@ -316,7 +320,7 @@ static void print_proof(dl_interface *d, std::ostream& out, Solver::Counterexamp
|
|||
|
||||
out << " (labels";
|
||||
std::vector<symbol> labels;
|
||||
cex.tree->GetLabels(&edge,labels);
|
||||
tree->GetLabels(&edge,labels);
|
||||
for(unsigned j = 0; j < labels.size(); j++){
|
||||
out << " " << labels[j];
|
||||
}
|
||||
|
@ -328,7 +332,7 @@ static void print_proof(dl_interface *d, std::ostream& out, Solver::Counterexamp
|
|||
|
||||
out << " (ref ";
|
||||
for(unsigned i = 0; i < edge.Children.size(); i++){
|
||||
if(!cex.tree->Empty(edge.Children[i]))
|
||||
if(!tree->Empty(edge.Children[i]))
|
||||
out << " s!" << edge.Children[i]->number;
|
||||
else
|
||||
out << " true";
|
||||
|
@ -353,11 +357,11 @@ void dl_interface::display_certificate_non_const(std::ostream& out) {
|
|||
// negation of the query is the last clause -- prove it
|
||||
hash_set<func_decl> locals;
|
||||
local_func_decls = &locals;
|
||||
print_proof(this,out,_d->cex);
|
||||
print_proof(this,out,_d->cex.get_tree(),_d->cex.get_root());
|
||||
out << ")\n";
|
||||
out << "(model \n\"";
|
||||
::model mod(m_ctx.get_manager());
|
||||
model orig_model = _d->cex.tree->dualModel;
|
||||
model orig_model = _d->cex.get_tree()->dualModel;
|
||||
for(unsigned i = 0; i < orig_model.num_consts(); i++){
|
||||
func_decl cnst = orig_model.get_const_decl(i);
|
||||
if(locals.find(cnst) == locals.end()){
|
||||
|
@ -428,10 +432,10 @@ model_ref dl_interface::get_model() {
|
|||
return md;
|
||||
}
|
||||
|
||||
static proof_ref extract_proof(dl_interface *d, Solver::Counterexample &cex) {
|
||||
static proof_ref extract_proof(dl_interface *d, RPFP *tree, RPFP::Node *root) {
|
||||
context &ctx = d->dd()->ctx;
|
||||
ast_manager &mgr = ctx.m();
|
||||
RPFP::Node &node = *cex.root;
|
||||
RPFP::Node &node = *root;
|
||||
RPFP::Edge &edge = *node.Outgoing;
|
||||
RPFP::Edge *orig_edge = edge.map;
|
||||
|
||||
|
@ -453,21 +457,19 @@ static proof_ref extract_proof(dl_interface *d, Solver::Counterexample &cex) {
|
|||
sort the_sort = t.get_quantifier_bound_sort(j);
|
||||
symbol name = t.get_quantifier_bound_name(j);
|
||||
expr skolem = ctx.constant(symbol(ctx,name),sort(ctx,the_sort));
|
||||
expr val = cex.tree->Eval(&edge,skolem);
|
||||
expr val = tree->Eval(&edge,skolem);
|
||||
expr_ref thing(ctx.uncook(val),mgr);
|
||||
substs[0].push_back(thing);
|
||||
expr local_skolem = cex.tree->Localize(&edge,skolem);
|
||||
expr local_skolem = tree->Localize(&edge,skolem);
|
||||
(*local_func_decls).insert(local_skolem.decl());
|
||||
}
|
||||
}
|
||||
|
||||
svector<std::pair<unsigned, unsigned> > pos;
|
||||
for(unsigned i = 0; i < edge.Children.size(); i++){
|
||||
if(!cex.tree->Empty(edge.Children[i])){
|
||||
if(!tree->Empty(edge.Children[i])){
|
||||
pos.push_back(std::pair<unsigned,unsigned>(i+1,0));
|
||||
Solver::Counterexample foo = cex;
|
||||
foo.root = edge.Children[i];
|
||||
proof_ref prem = extract_proof(d,foo);
|
||||
proof_ref prem = extract_proof(d,tree,edge.Children[i]);
|
||||
prems.push_back(prem);
|
||||
substs.push_back(expr_ref_vector(mgr));
|
||||
}
|
||||
|
@ -476,7 +478,7 @@ static proof_ref extract_proof(dl_interface *d, Solver::Counterexample &cex) {
|
|||
func_decl f = node.Name;
|
||||
std::vector<expr> args;
|
||||
for(unsigned i = 0; i < edge.F.IndParams.size(); i++)
|
||||
args.push_back(cex.tree->Eval(&edge,edge.F.IndParams[i]));
|
||||
args.push_back(tree->Eval(&edge,edge.F.IndParams[i]));
|
||||
expr conc = f(args);
|
||||
|
||||
|
||||
|
@ -493,7 +495,7 @@ proof_ref dl_interface::get_proof() {
|
|||
if(_d->status == StatusRefutation){
|
||||
hash_set<func_decl> locals;
|
||||
local_func_decls = &locals;
|
||||
return extract_proof(this,_d->cex);
|
||||
return extract_proof(this,_d->cex.get_tree(),_d->cex.get_root());
|
||||
}
|
||||
else
|
||||
return proof_ref(m_ctx.get_manager());
|
||||
|
|
|
@ -850,6 +850,13 @@ namespace smt2 {
|
|||
for (unsigned i = 0; i < sz; i++) {
|
||||
pdatatype_decl * d = new_dt_decls[i];
|
||||
SASSERT(d != 0);
|
||||
symbol duplicated;
|
||||
if (d->has_duplicate_accessors(duplicated)) {
|
||||
std::string err_msg = "invalid datatype declaration, repeated accessor identifier '";
|
||||
err_msg += duplicated.str();
|
||||
err_msg += "'";
|
||||
throw parser_exception(err_msg, line, pos);
|
||||
}
|
||||
m_ctx.insert(d);
|
||||
if (d->get_num_params() == 0) {
|
||||
// if datatype is not parametric... then force instantiation to register accessor, recognizers and constructors...
|
||||
|
@ -2070,6 +2077,7 @@ namespace smt2 {
|
|||
|
||||
void parse_option_value() {
|
||||
switch (curr()) {
|
||||
case scanner::BV_TOKEN:
|
||||
case scanner::INT_TOKEN:
|
||||
case scanner::FLOAT_TOKEN:
|
||||
m_curr_cmd->set_next_arg(m_ctx, m_scanner.get_number());
|
||||
|
|
|
@ -87,7 +87,7 @@ void display_usage() {
|
|||
std::cout << "\nResources:\n";
|
||||
// timeout and memout are now available on Linux and OSX too.
|
||||
std::cout << " -T:timeout set the timeout (in seconds).\n";
|
||||
std::cout << " -t:timeout set the soft timeout (in seconds). It only kills the current query.\n";
|
||||
std::cout << " -t:timeout set the soft timeout (in milli seconds). It only kills the current query.\n";
|
||||
std::cout << " -memory:Megabytes set a limit for virtual memory consumption.\n";
|
||||
//
|
||||
std::cout << "\nOutput:\n";
|
||||
|
|
|
@ -27,8 +27,7 @@ enum arith_solver_id {
|
|||
AS_DIFF_LOGIC,
|
||||
AS_ARITH,
|
||||
AS_DENSE_DIFF_LOGIC,
|
||||
AS_UTVPI,
|
||||
AS_HORN
|
||||
AS_UTVPI
|
||||
};
|
||||
|
||||
enum bound_prop_mode {
|
||||
|
|
|
@ -439,12 +439,12 @@ namespace smt {
|
|||
virtual bool model_based() const { return m_fparams->m_mbqi; }
|
||||
|
||||
virtual bool mbqi_enabled(quantifier *q) const {
|
||||
if(!m_fparams->m_mbqi_id) return true;
|
||||
const symbol &s = q->get_qid();
|
||||
unsigned len = strlen(m_fparams->m_mbqi_id);
|
||||
if(s == symbol::null || s.is_numerical())
|
||||
return len == 0;
|
||||
return strncmp(s.bare_str(),m_fparams->m_mbqi_id,len) == 0;
|
||||
if(!m_fparams->m_mbqi_id) return true;
|
||||
const symbol &s = q->get_qid();
|
||||
size_t len = strlen(m_fparams->m_mbqi_id);
|
||||
if(s == symbol::null || s.is_numerical())
|
||||
return len == 0;
|
||||
return strncmp(s.bare_str(),m_fparams->m_mbqi_id,len) == 0;
|
||||
}
|
||||
|
||||
/* Quantifier id's must begin with the prefix specified by
|
||||
|
|
|
@ -22,7 +22,6 @@ Revision History:
|
|||
#include"theory_arith.h"
|
||||
#include"theory_dense_diff_logic.h"
|
||||
#include"theory_diff_logic.h"
|
||||
#include"theory_horn_ineq.h"
|
||||
#include"theory_utvpi.h"
|
||||
#include"theory_array.h"
|
||||
#include"theory_array_full.h"
|
||||
|
@ -725,12 +724,6 @@ namespace smt {
|
|||
m_context.register_plugin(alloc(smt::theory_dense_mi, m_manager, m_params));
|
||||
}
|
||||
break;
|
||||
case AS_HORN:
|
||||
if (m_params.m_arith_int_only)
|
||||
m_context.register_plugin(alloc(smt::theory_ihi, m_manager));
|
||||
else
|
||||
m_context.register_plugin(alloc(smt::theory_rhi, m_manager));
|
||||
break;
|
||||
case AS_UTVPI:
|
||||
if (m_params.m_arith_int_only)
|
||||
m_context.register_plugin(alloc(smt::theory_iutvpi, m_manager));
|
||||
|
|
|
@ -139,22 +139,32 @@ protected:
|
|||
SASSERT(g.is_well_sorted());
|
||||
}
|
||||
|
||||
struct expr_pos {
|
||||
unsigned m_parent;
|
||||
unsigned m_self;
|
||||
unsigned m_idx;
|
||||
expr* m_expr;
|
||||
expr_pos(unsigned p, unsigned s, unsigned i, expr* e):
|
||||
m_parent(p), m_self(s), m_idx(i), m_expr(e)
|
||||
{}
|
||||
expr_pos():
|
||||
m_parent(0), m_self(0), m_idx(0), m_expr(0)
|
||||
{}
|
||||
};
|
||||
|
||||
void reduce(expr_ref& result){
|
||||
SASSERT(m.is_bool(result));
|
||||
ptr_vector<expr> todo;
|
||||
ptr_vector<expr> names;
|
||||
svector<bool> is_checked;
|
||||
svector<unsigned> parent_ids, self_ids;
|
||||
svector<expr_pos> todo;
|
||||
expr_ref_vector fresh_vars(m), trail(m);
|
||||
expr_ref res(m), tmp(m);
|
||||
obj_map<expr,std::pair<unsigned, expr*> > cache;
|
||||
unsigned id = 1;
|
||||
obj_map<expr, expr_pos> cache;
|
||||
unsigned id = 1, child_id = 0;
|
||||
expr_ref n2(m), fml(m);
|
||||
unsigned path_id = 0, self_pos = 0;
|
||||
unsigned parent_pos = 0, self_pos = 0, self_idx = 0;
|
||||
app * a;
|
||||
unsigned sz;
|
||||
std::pair<unsigned,expr*> path_r;
|
||||
ptr_vector<expr> found;
|
||||
expr_pos path_r;
|
||||
expr_ref_vector args(m);
|
||||
expr_ref n = mk_fresh(id, m.mk_bool_sort());
|
||||
trail.push_back(n);
|
||||
|
@ -163,26 +173,25 @@ protected:
|
|||
tmp = m.mk_not(m.mk_iff(fml, n));
|
||||
m_solver.assert_expr(tmp);
|
||||
|
||||
todo.push_back(fml);
|
||||
todo.push_back(expr_pos(0,0,0,fml));
|
||||
names.push_back(n);
|
||||
is_checked.push_back(false);
|
||||
parent_ids.push_back(0);
|
||||
self_ids.push_back(0);
|
||||
m_solver.push();
|
||||
|
||||
while (!todo.empty() && !m_cancel) {
|
||||
expr_ref res(m);
|
||||
args.reset();
|
||||
expr* e = todo.back();
|
||||
unsigned pos = parent_ids.back();
|
||||
expr* e = todo.back().m_expr;
|
||||
self_pos = todo.back().m_self;
|
||||
parent_pos = todo.back().m_parent;
|
||||
self_idx = todo.back().m_idx;
|
||||
n = names.back();
|
||||
bool checked = is_checked.back();
|
||||
|
||||
if (cache.contains(e)) {
|
||||
goto done;
|
||||
}
|
||||
if (m.is_bool(e) && !checked && simplify_bool(n, res)) {
|
||||
TRACE("ctx_solver_simplify_tactic", tout << "simplified: " << mk_pp(e, m) << " |-> " << mk_pp(res, m) << "\n";);
|
||||
if (m.is_bool(e) && simplify_bool(n, res)) {
|
||||
TRACE("ctx_solver_simplify_tactic",
|
||||
tout << "simplified: " << mk_pp(e, m) << " |-> " << mk_pp(res, m) << "\n";);
|
||||
goto done;
|
||||
}
|
||||
if (!is_app(e)) {
|
||||
|
@ -191,49 +200,31 @@ protected:
|
|||
}
|
||||
|
||||
a = to_app(e);
|
||||
if (!is_checked.back()) {
|
||||
self_ids.back() = ++path_id;
|
||||
is_checked.back() = true;
|
||||
}
|
||||
self_pos = self_ids.back();
|
||||
sz = a->get_num_args();
|
||||
|
||||
sz = a->get_num_args();
|
||||
n2 = 0;
|
||||
|
||||
found.reset(); // arguments already simplified.
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
expr* arg = a->get_arg(i);
|
||||
if (cache.find(arg, path_r) && !found.contains(arg)) {
|
||||
if (cache.find(arg, path_r)) {
|
||||
//
|
||||
// This is a single traversal version of the context
|
||||
// simplifier. It simplifies only the first occurrence of
|
||||
// a sub-term with respect to the context.
|
||||
//
|
||||
|
||||
found.push_back(arg);
|
||||
if (path_r.first == self_pos) {
|
||||
TRACE("ctx_solver_simplify_tactic", tout << "cached " << mk_pp(arg, m) << " |-> " << mk_pp(path_r.second, m) << "\n";);
|
||||
args.push_back(path_r.second);
|
||||
}
|
||||
else if (m.is_bool(arg)) {
|
||||
res = local_simplify(a, n, id, i);
|
||||
TRACE("ctx_solver_simplify_tactic",
|
||||
tout << "Already cached: " << path_r.first << " " << mk_pp(arg, m) << " |-> " << mk_pp(res, m) << "\n";);
|
||||
args.push_back(res);
|
||||
if (path_r.m_parent == self_pos && path_r.m_idx == i) {
|
||||
args.push_back(path_r.m_expr);
|
||||
}
|
||||
else {
|
||||
args.push_back(arg);
|
||||
}
|
||||
}
|
||||
else if (!n2 && !found.contains(arg)) {
|
||||
else if (!n2) {
|
||||
n2 = mk_fresh(id, m.get_sort(arg));
|
||||
trail.push_back(n2);
|
||||
todo.push_back(arg);
|
||||
parent_ids.push_back(self_pos);
|
||||
self_ids.push_back(0);
|
||||
todo.push_back(expr_pos(self_pos, child_id++, i, arg));
|
||||
names.push_back(n2);
|
||||
args.push_back(n2);
|
||||
is_checked.push_back(false);
|
||||
}
|
||||
else {
|
||||
args.push_back(arg);
|
||||
|
@ -251,22 +242,16 @@ protected:
|
|||
|
||||
done:
|
||||
if (res) {
|
||||
cache.insert(e, std::make_pair(pos, res));
|
||||
}
|
||||
|
||||
TRACE("ctx_solver_simplify_tactic",
|
||||
tout << mk_pp(e, m) << " checked: " << checked << " cached: " << mk_pp(res?res.get():e, m) << "\n";);
|
||||
cache.insert(e, expr_pos(parent_pos, self_pos, self_idx, res));
|
||||
}
|
||||
|
||||
todo.pop_back();
|
||||
parent_ids.pop_back();
|
||||
self_ids.pop_back();
|
||||
names.pop_back();
|
||||
is_checked.pop_back();
|
||||
m_solver.pop(1);
|
||||
}
|
||||
if (!m_cancel) {
|
||||
VERIFY(cache.find(fml, path_r));
|
||||
result = path_r.second;
|
||||
result = path_r.m_expr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,32 +291,6 @@ protected:
|
|||
}
|
||||
return expr_ref(m.mk_app(fn, m_arith.mk_numeral(rational(id++), true)), m);
|
||||
}
|
||||
|
||||
|
||||
expr_ref local_simplify(app* a, expr* n, unsigned& id, unsigned index) {
|
||||
SASSERT(index < a->get_num_args());
|
||||
SASSERT(m.is_bool(a->get_arg(index)));
|
||||
expr_ref n2(m), result(m), tmp(m);
|
||||
n2 = mk_fresh(id, m.get_sort(a->get_arg(index)));
|
||||
ptr_buffer<expr> args;
|
||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
||||
if (i == index) {
|
||||
args.push_back(n2);
|
||||
}
|
||||
else {
|
||||
args.push_back(a->get_arg(i));
|
||||
}
|
||||
}
|
||||
m_mk_app(a->get_decl(), args.size(), args.c_ptr(), result);
|
||||
m_solver.push();
|
||||
tmp = m.mk_eq(result, n);
|
||||
m_solver.assert_expr(tmp);
|
||||
if (!simplify_bool(n2, result)) {
|
||||
result = a->get_arg(index);
|
||||
}
|
||||
m_solver.pop(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1,236 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
theory_horn_ineq.h
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2013-04-18
|
||||
|
||||
Revision History:
|
||||
|
||||
The implementaton is derived from theory_diff_logic.
|
||||
|
||||
--*/
|
||||
#include "theory_horn_ineq.h"
|
||||
#include "theory_horn_ineq_def.h"
|
||||
|
||||
namespace smt {
|
||||
|
||||
template class theory_horn_ineq<ihi_ext>;
|
||||
template class theory_horn_ineq<rhi_ext>;
|
||||
|
||||
// similar to test_diff_logic:
|
||||
|
||||
horn_ineq_tester::horn_ineq_tester(ast_manager& m): m(m), a(m) {}
|
||||
|
||||
bool horn_ineq_tester::operator()(expr* e) {
|
||||
m_todo.reset();
|
||||
m_pols.reset();
|
||||
pos_mark.reset();
|
||||
neg_mark.reset();
|
||||
m_todo.push_back(e);
|
||||
m_pols.push_back(l_true);
|
||||
while (!m_todo.empty()) {
|
||||
expr* e = m_todo.back();
|
||||
lbool p = m_pols.back();
|
||||
m_todo.pop_back();
|
||||
m_pols.pop_back();
|
||||
switch (p) {
|
||||
case l_true:
|
||||
if (pos_mark.is_marked(e)) {
|
||||
continue;
|
||||
}
|
||||
pos_mark.mark(e, true);
|
||||
break;
|
||||
case l_false:
|
||||
if (neg_mark.is_marked(e)) {
|
||||
continue;
|
||||
}
|
||||
neg_mark.mark(e, true);
|
||||
break;
|
||||
case l_undef:
|
||||
if (pos_mark.is_marked(e) && neg_mark.is_marked(e)) {
|
||||
continue;
|
||||
}
|
||||
pos_mark.mark(e, true);
|
||||
neg_mark.mark(e, true);
|
||||
break;
|
||||
}
|
||||
if (!test_expr(p, e)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
vector<std::pair<expr*,rational> > const& horn_ineq_tester::get_linearization() const {
|
||||
return m_terms;
|
||||
}
|
||||
|
||||
bool horn_ineq_tester::test_expr(lbool p, expr* e) {
|
||||
expr* e1, *e2, *e3;
|
||||
if (is_var(e)) {
|
||||
return true;
|
||||
}
|
||||
if (!is_app(e)) {
|
||||
return false;
|
||||
}
|
||||
app* ap = to_app(e);
|
||||
if (m.is_and(ap) || m.is_or(ap)) {
|
||||
for (unsigned i = 0; i < ap->get_num_args(); ++i) {
|
||||
m_todo.push_back(ap->get_arg(i));
|
||||
m_pols.push_back(p);
|
||||
}
|
||||
}
|
||||
else if (m.is_not(e, e1)) {
|
||||
m_todo.push_back(e);
|
||||
m_pols.push_back(~p);
|
||||
}
|
||||
else if (m.is_ite(e, e1, e2, e3)) {
|
||||
m_todo.push_back(e1);
|
||||
m_pols.push_back(l_undef);
|
||||
m_todo.push_back(e2);
|
||||
m_pols.push_back(p);
|
||||
m_todo.push_back(e3);
|
||||
m_pols.push_back(p);
|
||||
}
|
||||
else if (m.is_iff(e, e1, e2)) {
|
||||
m_todo.push_back(e1);
|
||||
m_pols.push_back(l_undef);
|
||||
m_todo.push_back(e2);
|
||||
m_pols.push_back(l_undef);
|
||||
m_todo.push_back(e2);
|
||||
}
|
||||
else if (m.is_implies(e, e1, e2)) {
|
||||
m_todo.push_back(e1);
|
||||
m_pols.push_back(~p);
|
||||
m_todo.push_back(e2);
|
||||
m_pols.push_back(p);
|
||||
}
|
||||
else if (m.is_eq(e, e1, e2)) {
|
||||
return linearize(e1, e2) == diff;
|
||||
}
|
||||
else if (m.is_true(e) || m.is_false(e)) {
|
||||
// no-op
|
||||
}
|
||||
else if (a.is_le(e, e1, e2) || a.is_ge(e, e2, e1) ||
|
||||
a.is_lt(e, e1, e2) || a.is_gt(e, e2, e1)) {
|
||||
if (p == l_false) {
|
||||
std::swap(e2, e1);
|
||||
}
|
||||
classify_t cl = linearize(e1, e2);
|
||||
switch(p) {
|
||||
case l_undef:
|
||||
return cl == diff;
|
||||
case l_true:
|
||||
case l_false:
|
||||
return cl == horn || cl == diff;
|
||||
}
|
||||
}
|
||||
else if (!is_uninterp_const(e)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool horn_ineq_tester::operator()(unsigned num_fmls, expr* const* fmls) {
|
||||
for (unsigned i = 0; i < num_fmls; ++i) {
|
||||
if (!(*this)(fmls[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
horn_ineq_tester::classify_t horn_ineq_tester::linearize(expr* e) {
|
||||
m_terms.reset();
|
||||
m_terms.push_back(std::make_pair(e, rational(1)));
|
||||
return linearize();
|
||||
}
|
||||
|
||||
horn_ineq_tester::classify_t horn_ineq_tester::linearize(expr* e1, expr* e2) {
|
||||
m_terms.reset();
|
||||
m_terms.push_back(std::make_pair(e1, rational(1)));
|
||||
m_terms.push_back(std::make_pair(e2, rational(-1)));
|
||||
return linearize();
|
||||
}
|
||||
|
||||
horn_ineq_tester::classify_t horn_ineq_tester::linearize() {
|
||||
|
||||
m_weight.reset();
|
||||
m_coeff_map.reset();
|
||||
|
||||
while (!m_terms.empty()) {
|
||||
expr* e1, *e2;
|
||||
rational num;
|
||||
rational mul = m_terms.back().second;
|
||||
expr* e = m_terms.back().first;
|
||||
m_terms.pop_back();
|
||||
if (a.is_add(e)) {
|
||||
for (unsigned i = 0; i < to_app(e)->get_num_args(); ++i) {
|
||||
m_terms.push_back(std::make_pair(to_app(e)->get_arg(i), mul));
|
||||
}
|
||||
}
|
||||
else if (a.is_mul(e, e1, e2) && a.is_numeral(e1, num)) {
|
||||
m_terms.push_back(std::make_pair(e2, mul*num));
|
||||
}
|
||||
else if (a.is_mul(e, e2, e1) && a.is_numeral(e1, num)) {
|
||||
m_terms.push_back(std::make_pair(e2, mul*num));
|
||||
}
|
||||
else if (a.is_sub(e, e1, e2)) {
|
||||
m_terms.push_back(std::make_pair(e1, mul));
|
||||
m_terms.push_back(std::make_pair(e2, -mul));
|
||||
}
|
||||
else if (a.is_uminus(e, e1)) {
|
||||
m_terms.push_back(std::make_pair(e1, -mul));
|
||||
}
|
||||
else if (a.is_numeral(e, num)) {
|
||||
m_weight += num*mul;
|
||||
}
|
||||
else if (a.is_to_real(e, e1)) {
|
||||
m_terms.push_back(std::make_pair(e1, mul));
|
||||
}
|
||||
else if (!is_uninterp_const(e)) {
|
||||
return non_horn;
|
||||
}
|
||||
else {
|
||||
m_coeff_map.insert_if_not_there2(e, rational(0))->get_data().m_value += mul;
|
||||
}
|
||||
}
|
||||
unsigned num_negative = 0;
|
||||
unsigned num_positive = 0;
|
||||
bool is_unit_pos = true, is_unit_neg = true;
|
||||
obj_map<expr, rational>::iterator it = m_coeff_map.begin();
|
||||
obj_map<expr, rational>::iterator end = m_coeff_map.end();
|
||||
for (; it != end; ++it) {
|
||||
rational r = it->m_value;
|
||||
if (r.is_zero()) {
|
||||
continue;
|
||||
}
|
||||
m_terms.push_back(std::make_pair(it->m_key, r));
|
||||
if (r.is_pos()) {
|
||||
is_unit_pos = is_unit_pos && r.is_one();
|
||||
num_positive++;
|
||||
}
|
||||
else {
|
||||
is_unit_neg = is_unit_neg && r.is_minus_one();
|
||||
num_negative++;
|
||||
}
|
||||
}
|
||||
if (num_negative <= 1 && is_unit_pos && is_unit_neg && num_positive <= 1) {
|
||||
return diff;
|
||||
}
|
||||
if (num_positive <= 1 && is_unit_pos) {
|
||||
return horn;
|
||||
}
|
||||
if (num_negative <= 1 && is_unit_neg) {
|
||||
return co_horn;
|
||||
}
|
||||
return non_horn;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,328 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
theory_horn_ineq.h
|
||||
|
||||
Abstract:
|
||||
|
||||
A*x <= weight + D*x, coefficients to A and D are non-negative,
|
||||
D is a diagonal matrix.
|
||||
Coefficients to weight may have both signs.
|
||||
|
||||
Label variables by weight.
|
||||
Select inequality that is not satisfied.
|
||||
Set delta(LHS) := 0
|
||||
Set delta(RHS(x)) := weight(x) - b
|
||||
Propagate weight increment through inequalities.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2013-04-18
|
||||
|
||||
Revision History:
|
||||
|
||||
The implementaton is derived from theory_diff_logic.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _THEORY_HORN_INEQ_H_
|
||||
#define _THEORY_HORN_INEQ_H_
|
||||
|
||||
#include"rational.h"
|
||||
#include"inf_rational.h"
|
||||
#include"inf_int_rational.h"
|
||||
#include"inf_eps_rational.h"
|
||||
#include"smt_theory.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"smt_justification.h"
|
||||
#include"map.h"
|
||||
#include"smt_params.h"
|
||||
#include"arith_eq_adapter.h"
|
||||
#include"smt_model_generator.h"
|
||||
#include"numeral_factory.h"
|
||||
#include"smt_clause.h"
|
||||
|
||||
namespace smt {
|
||||
|
||||
class horn_ineq_tester {
|
||||
ast_manager& m;
|
||||
arith_util a;
|
||||
ptr_vector<expr> m_todo;
|
||||
svector<lbool> m_pols;
|
||||
ast_mark pos_mark, neg_mark;
|
||||
obj_map<expr, rational> m_coeff_map;
|
||||
rational m_weight;
|
||||
vector<std::pair<expr*, rational> > m_terms;
|
||||
|
||||
public:
|
||||
enum classify_t {
|
||||
co_horn,
|
||||
horn,
|
||||
diff,
|
||||
non_horn
|
||||
};
|
||||
horn_ineq_tester(ast_manager& m);
|
||||
|
||||
// test if formula is in the Horn inequality fragment:
|
||||
bool operator()(expr* fml);
|
||||
bool operator()(unsigned num_fmls, expr* const* fmls);
|
||||
|
||||
// linearize inequality/equality
|
||||
classify_t linearize(expr* e);
|
||||
classify_t linearize(expr* e1, expr* e2);
|
||||
|
||||
// retrieve linearization
|
||||
vector<std::pair<expr*,rational> > const& get_linearization() const;
|
||||
rational const& get_weight() const { return m_weight; }
|
||||
private:
|
||||
bool test_expr(lbool p, expr* e);
|
||||
classify_t linearize();
|
||||
};
|
||||
|
||||
template<typename Ext>
|
||||
class theory_horn_ineq : public theory, private Ext {
|
||||
|
||||
typedef typename Ext::numeral numeral;
|
||||
typedef typename Ext::inf_numeral inf_numeral;
|
||||
typedef literal explanation;
|
||||
typedef theory_var th_var;
|
||||
typedef svector<th_var> th_var_vector;
|
||||
typedef unsigned clause_id;
|
||||
typedef vector<std::pair<th_var, rational> > coeffs;
|
||||
|
||||
class clause;
|
||||
class graph;
|
||||
class assignment_trail;
|
||||
class parent_trail;
|
||||
|
||||
class atom {
|
||||
protected:
|
||||
bool_var m_bvar;
|
||||
bool m_true;
|
||||
int m_pos;
|
||||
int m_neg;
|
||||
public:
|
||||
atom(bool_var bv, int pos, int neg) :
|
||||
m_bvar(bv), m_true(false),
|
||||
m_pos(pos), m_neg(neg) {}
|
||||
~atom() {}
|
||||
bool_var get_bool_var() const { return m_bvar; }
|
||||
bool is_true() const { return m_true; }
|
||||
void assign_eh(bool is_true) { m_true = is_true; }
|
||||
int get_asserted_edge() const { return this->m_true?m_pos:m_neg; }
|
||||
int get_pos() const { return m_pos; }
|
||||
int get_neg() const { return m_neg; }
|
||||
std::ostream& display(theory_horn_ineq const& th, std::ostream& out) const;
|
||||
};
|
||||
typedef svector<atom> atoms;
|
||||
|
||||
struct scope {
|
||||
unsigned m_atoms_lim;
|
||||
unsigned m_asserted_atoms_lim;
|
||||
unsigned m_asserted_qhead_old;
|
||||
};
|
||||
|
||||
struct stats {
|
||||
unsigned m_num_conflicts;
|
||||
unsigned m_num_assertions;
|
||||
unsigned m_num_core2th_eqs;
|
||||
unsigned m_num_core2th_diseqs;
|
||||
|
||||
void reset() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
stats() {
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
stats m_stats;
|
||||
smt_params m_params;
|
||||
arith_util a;
|
||||
arith_eq_adapter m_arith_eq_adapter;
|
||||
th_var m_zero_int; // cache the variable representing the zero variable.
|
||||
th_var m_zero_real; // cache the variable representing the zero variable.
|
||||
|
||||
graph* m_graph;
|
||||
atoms m_atoms;
|
||||
unsigned_vector m_asserted_atoms; // set of asserted atoms
|
||||
unsigned m_asserted_qhead;
|
||||
u_map<unsigned> m_bool_var2atom;
|
||||
svector<scope> m_scopes;
|
||||
|
||||
double m_agility;
|
||||
bool m_lia;
|
||||
bool m_lra;
|
||||
bool m_non_horn_ineq_exprs;
|
||||
|
||||
horn_ineq_tester m_test;
|
||||
|
||||
|
||||
arith_factory * m_factory;
|
||||
rational m_delta;
|
||||
rational m_lambda;
|
||||
|
||||
|
||||
// Set a conflict due to a negative cycle.
|
||||
void set_neg_cycle_conflict();
|
||||
|
||||
// Create a new theory variable.
|
||||
virtual th_var mk_var(enode* n);
|
||||
|
||||
virtual th_var mk_var(expr* n);
|
||||
|
||||
void compute_delta();
|
||||
|
||||
void found_non_horn_ineq_expr(expr * n);
|
||||
|
||||
bool is_interpreted(app* n) const {
|
||||
return n->get_family_id() == get_family_id();
|
||||
}
|
||||
|
||||
public:
|
||||
theory_horn_ineq(ast_manager& m);
|
||||
|
||||
virtual ~theory_horn_ineq();
|
||||
|
||||
virtual theory * mk_fresh(context * new_ctx) { return alloc(theory_horn_ineq, get_manager()); }
|
||||
|
||||
virtual char const * get_name() const { return "horn-inequality-logic"; }
|
||||
|
||||
/**
|
||||
\brief See comment in theory::mk_eq_atom
|
||||
*/
|
||||
virtual app * mk_eq_atom(expr * lhs, expr * rhs) { return a.mk_eq(lhs, rhs); }
|
||||
|
||||
virtual void init(context * ctx);
|
||||
|
||||
virtual bool internalize_atom(app * atom, bool gate_ctx);
|
||||
|
||||
virtual bool internalize_term(app * term);
|
||||
|
||||
virtual void internalize_eq_eh(app * atom, bool_var v);
|
||||
|
||||
virtual void assign_eh(bool_var v, bool is_true);
|
||||
|
||||
virtual void new_eq_eh(th_var v1, th_var v2) {
|
||||
m_arith_eq_adapter.new_eq_eh(v1, v2);
|
||||
}
|
||||
|
||||
virtual bool use_diseqs() const { return true; }
|
||||
|
||||
virtual void new_diseq_eh(th_var v1, th_var v2) {
|
||||
m_arith_eq_adapter.new_diseq_eh(v1, v2);
|
||||
}
|
||||
|
||||
virtual void push_scope_eh();
|
||||
|
||||
virtual void pop_scope_eh(unsigned num_scopes);
|
||||
|
||||
virtual void restart_eh() {
|
||||
m_arith_eq_adapter.restart_eh();
|
||||
}
|
||||
|
||||
virtual void relevant_eh(app* e) {}
|
||||
|
||||
virtual void init_search_eh() {
|
||||
m_arith_eq_adapter.init_search_eh();
|
||||
}
|
||||
|
||||
virtual final_check_status final_check_eh();
|
||||
|
||||
virtual bool is_shared(th_var v) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool can_propagate() {
|
||||
SASSERT(m_asserted_qhead <= m_asserted_atoms.size());
|
||||
return m_asserted_qhead != m_asserted_atoms.size();
|
||||
}
|
||||
|
||||
virtual void propagate();
|
||||
|
||||
virtual justification * why_is_diseq(th_var v1, th_var v2) {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void reset_eh();
|
||||
|
||||
virtual void init_model(model_generator & m);
|
||||
|
||||
virtual model_value_proc * mk_value(enode * n, model_generator & mg);
|
||||
|
||||
virtual bool validate_eq_in_model(th_var v1, th_var v2, bool is_true) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & out) const;
|
||||
|
||||
virtual void collect_statistics(::statistics & st) const;
|
||||
|
||||
private:
|
||||
|
||||
virtual void new_eq_eh(th_var v1, th_var v2, justification& j) {
|
||||
m_stats.m_num_core2th_eqs++;
|
||||
new_eq_or_diseq(true, v1, v2, j);
|
||||
}
|
||||
|
||||
virtual void new_diseq_eh(th_var v1, th_var v2, justification& j) {
|
||||
m_stats.m_num_core2th_diseqs++;
|
||||
new_eq_or_diseq(false, v1, v2, j);
|
||||
}
|
||||
|
||||
void negate(coeffs& coeffs, rational& weight);
|
||||
numeral mk_weight(bool is_real, bool is_strict, rational const& w) const;
|
||||
void mk_coeffs(vector<std::pair<expr*,rational> >const& terms, coeffs& coeffs, rational& w);
|
||||
|
||||
void del_atoms(unsigned old_size);
|
||||
|
||||
void propagate_core();
|
||||
|
||||
bool propagate_atom(atom const& a);
|
||||
|
||||
th_var mk_term(app* n);
|
||||
|
||||
th_var mk_num(app* n, rational const& r);
|
||||
|
||||
bool is_consistent() const;
|
||||
|
||||
th_var expand(bool pos, th_var v, rational & k);
|
||||
|
||||
void new_eq_or_diseq(bool is_eq, th_var v1, th_var v2, justification& eq_just);
|
||||
|
||||
th_var get_zero(sort* s) const { return a.is_int(s)?m_zero_int:m_zero_real; }
|
||||
|
||||
th_var get_zero(expr* e) const { return get_zero(get_manager().get_sort(e)); }
|
||||
|
||||
void inc_conflicts();
|
||||
|
||||
};
|
||||
|
||||
struct rhi_ext {
|
||||
typedef inf_rational inf_numeral;
|
||||
typedef inf_eps_rational<inf_rational> numeral;
|
||||
numeral m_epsilon;
|
||||
numeral m_minus_infty;
|
||||
rhi_ext() : m_epsilon(inf_rational(rational(), true)), m_minus_infty(rational(-1),inf_rational()) {}
|
||||
};
|
||||
|
||||
struct ihi_ext {
|
||||
typedef rational inf_numeral;
|
||||
typedef inf_eps_rational<rational> numeral;
|
||||
numeral m_epsilon;
|
||||
numeral m_minus_infty;
|
||||
ihi_ext() : m_epsilon(rational(1)), m_minus_infty(rational(-1),rational(0)) {}
|
||||
};
|
||||
|
||||
typedef theory_horn_ineq<rhi_ext> theory_rhi;
|
||||
typedef theory_horn_ineq<ihi_ext> theory_ihi;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* _THEORY_HORN_INEQ_H_ */
|
File diff suppressed because it is too large
Load diff
|
@ -25,6 +25,7 @@ Notes:
|
|||
#include"bv_decl_plugin.h"
|
||||
#include"expr_replacer.h"
|
||||
#include"extension_model_converter.h"
|
||||
#include"filter_model_converter.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
|
||||
class bv_size_reduction_tactic : public tactic {
|
||||
|
@ -60,6 +61,7 @@ struct bv_size_reduction_tactic::imp {
|
|||
obj_map<app, numeral> m_unsigned_lowers;
|
||||
obj_map<app, numeral> m_unsigned_uppers;
|
||||
ref<bv_size_reduction_mc> m_mc;
|
||||
ref<filter_model_converter> m_fmc;
|
||||
scoped_ptr<expr_replacer> m_replacer;
|
||||
bool m_produce_models;
|
||||
volatile bool m_cancel;
|
||||
|
@ -121,21 +123,41 @@ struct bv_size_reduction_tactic::imp {
|
|||
negated = true;
|
||||
f = to_app(f)->get_arg(0);
|
||||
}
|
||||
|
||||
|
||||
if (m_util.is_bv_sle(f, lhs, rhs)) {
|
||||
bv_sz = m_util.get_bv_size(lhs);
|
||||
if (is_uninterp_const(lhs) && m_util.is_numeral(rhs, val, bv_sz)) {
|
||||
TRACE("bv_size_reduction", tout << (negated?"not ":"") << mk_ismt2_pp(f, m) << std::endl; );
|
||||
// v <= k
|
||||
if (negated) update_signed_lower(to_app(lhs), val+numeral(1));
|
||||
val = m_util.norm(val, bv_sz, true);
|
||||
if (negated) {
|
||||
val += numeral(1);
|
||||
if (m_util.norm(val, bv_sz, true) != val) {
|
||||
// bound is infeasible.
|
||||
}
|
||||
else {
|
||||
update_signed_lower(to_app(lhs), val);
|
||||
}
|
||||
}
|
||||
else update_signed_upper(to_app(lhs), val);
|
||||
}
|
||||
else if (is_uninterp_const(rhs) && m_util.is_numeral(lhs, val, bv_sz)) {
|
||||
TRACE("bv_size_reduction", tout << (negated?"not ":"") << mk_ismt2_pp(f, m) << std::endl; );
|
||||
// k <= v
|
||||
if (negated) update_signed_upper(to_app(rhs), val-numeral(1));
|
||||
val = m_util.norm(val, bv_sz, true);
|
||||
if (negated) {
|
||||
val -= numeral(1);
|
||||
if (m_util.norm(val, bv_sz, true) != val) {
|
||||
// bound is infeasible.
|
||||
}
|
||||
else {
|
||||
update_signed_upper(to_app(lhs), val);
|
||||
}
|
||||
}
|
||||
else update_signed_lower(to_app(rhs), val);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
else if (m_util.is_bv_ule(f, lhs, rhs)) {
|
||||
if (is_uninterp_const(lhs) && m_util.is_numeral(rhs, val, bv_sz)) {
|
||||
|
@ -196,6 +218,7 @@ struct bv_size_reduction_tactic::imp {
|
|||
numeral u = m_util.norm(entry->get_data().m_value, bv_sz, true);
|
||||
TRACE("bv_size_reduction", tout << l << " <= " << v->get_decl()->get_name() << " <= " << u << "\n";);
|
||||
expr * new_def = 0;
|
||||
app * new_const = 0;
|
||||
if (l > u) {
|
||||
g.assert_expr(m.mk_false());
|
||||
return;
|
||||
|
@ -208,15 +231,19 @@ struct bv_size_reduction_tactic::imp {
|
|||
if (l.is_neg()) {
|
||||
unsigned i_nb = (u - l).get_num_bits();
|
||||
unsigned v_nb = m_util.get_bv_size(v);
|
||||
if (i_nb < v_nb)
|
||||
new_def = m_util.mk_sign_extend(v_nb - i_nb, m.mk_fresh_const(0, m_util.mk_sort(i_nb)));
|
||||
if (i_nb < v_nb) {
|
||||
new_const = m.mk_fresh_const(0, m_util.mk_sort(i_nb));
|
||||
new_def = m_util.mk_sign_extend(v_nb - i_nb, new_const);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 0 <= l <= v <= u
|
||||
unsigned u_nb = u.get_num_bits();
|
||||
unsigned v_nb = m_util.get_bv_size(v);
|
||||
if (u_nb < v_nb)
|
||||
new_def = m_util.mk_concat(m_util.mk_numeral(numeral(0), v_nb - u_nb), m.mk_fresh_const(0, m_util.mk_sort(u_nb)));
|
||||
if (u_nb < v_nb) {
|
||||
new_const = m.mk_fresh_const(0, m_util.mk_sort(u_nb));
|
||||
new_def = m_util.mk_concat(m_util.mk_numeral(numeral(0), v_nb - u_nb), new_const);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,6 +253,10 @@ struct bv_size_reduction_tactic::imp {
|
|||
if (!m_mc)
|
||||
m_mc = alloc(bv_size_reduction_mc, m);
|
||||
m_mc->insert(v->get_decl(), new_def);
|
||||
if (!m_fmc && new_const)
|
||||
m_fmc = alloc(filter_model_converter, m);
|
||||
if (new_const)
|
||||
m_fmc->insert(new_const->get_decl());
|
||||
}
|
||||
num_reduced++;
|
||||
}
|
||||
|
@ -264,6 +295,7 @@ struct bv_size_reduction_tactic::imp {
|
|||
|
||||
TRACE("bv_size_reduction", tout << l << " <= " << v->get_decl()->get_name() << " <= " << u << "\n";);
|
||||
expr * new_def = 0;
|
||||
app * new_const = 0;
|
||||
if (l > u) {
|
||||
g.assert_expr(m.mk_false());
|
||||
return;
|
||||
|
@ -275,8 +307,10 @@ struct bv_size_reduction_tactic::imp {
|
|||
// 0 <= l <= v <= u
|
||||
unsigned u_nb = u.get_num_bits();
|
||||
unsigned v_nb = m_util.get_bv_size(v);
|
||||
if (u_nb < v_nb)
|
||||
new_def = m_util.mk_concat(m_util.mk_numeral(numeral(0), v_nb - u_nb), m.mk_fresh_const(0, m_util.mk_sort(u_nb)));
|
||||
if (u_nb < v_nb) {
|
||||
new_def = m_util.mk_concat(m_util.mk_numeral(numeral(0), v_nb - u_nb), new_const);
|
||||
new_const = m.mk_fresh_const(0, m_util.mk_sort(u_nb));
|
||||
}
|
||||
}
|
||||
|
||||
if (new_def) {
|
||||
|
@ -285,6 +319,10 @@ struct bv_size_reduction_tactic::imp {
|
|||
if (!m_mc)
|
||||
m_mc = alloc(bv_size_reduction_mc, m);
|
||||
m_mc->insert(v->get_decl(), new_def);
|
||||
if (!m_fmc && new_const)
|
||||
m_fmc = alloc(filter_model_converter, m);
|
||||
if (new_const)
|
||||
m_fmc->insert(new_const->get_decl());
|
||||
}
|
||||
num_reduced++;
|
||||
TRACE("bv_size_reduction", tout << "New definition = " << mk_ismt2_pp(new_def, m) << "\n";);
|
||||
|
@ -309,7 +347,11 @@ struct bv_size_reduction_tactic::imp {
|
|||
g.update(i, new_f);
|
||||
}
|
||||
mc = m_mc.get();
|
||||
if (m_fmc) {
|
||||
mc = concat(m_fmc.get(), mc.get());
|
||||
}
|
||||
m_mc = 0;
|
||||
m_fmc = 0;
|
||||
}
|
||||
report_tactic_progress(":bv-reduced", num_reduced);
|
||||
TRACE("after_bv_size_reduction", g.display(tout); if (m_mc) m_mc->display(tout););
|
||||
|
|
|
@ -872,8 +872,19 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args,
|
|||
sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, m_bv_util.mk_extract(extra_bits-2, 0, quotient));
|
||||
res_sig = m_bv_util.mk_concat(m_bv_util.mk_extract(extra_bits+sbits+1, extra_bits-1, quotient), sticky);
|
||||
|
||||
SASSERT(m_bv_util.get_bv_size(res_sig) == (sbits + 4));
|
||||
SASSERT(m_bv_util.get_bv_size(res_sig) == (sbits + 4));
|
||||
|
||||
expr_ref res_sig_lz(m);
|
||||
mk_leading_zeros(res_sig, sbits + 4, res_sig_lz);
|
||||
dbg_decouple("fpa2bv_div_res_sig_lz", res_sig_lz);
|
||||
expr_ref res_sig_shift_amount(m);
|
||||
res_sig_shift_amount = m_bv_util.mk_bv_sub(res_sig_lz, m_bv_util.mk_numeral(1, sbits + 4));
|
||||
dbg_decouple("fpa2bv_div_res_sig_shift_amount", res_sig_shift_amount);
|
||||
expr_ref shift_cond(m);
|
||||
shift_cond = m_bv_util.mk_ule(res_sig_lz, m_bv_util.mk_numeral(1, sbits + 4));
|
||||
m_simp.mk_ite(shift_cond, res_sig, m_bv_util.mk_bv_shl(res_sig, res_sig_shift_amount), res_sig);
|
||||
m_simp.mk_ite(shift_cond, res_exp, m_bv_util.mk_bv_sub(res_exp, m_bv_util.mk_extract(ebits+1, 0, res_sig_shift_amount)), res_exp);
|
||||
|
||||
round(f->get_range(), rm, res_sgn, res_sig, res_exp, v8);
|
||||
|
||||
// And finally, we tie them together.
|
||||
|
|
|
@ -331,22 +331,13 @@ public:
|
|||
return target;
|
||||
}
|
||||
|
||||
friend inline rational gcd(rational const & r1, rational const & r2) {
|
||||
rational result;
|
||||
m().gcd(r1.m_val, r2.m_val, result.m_val);
|
||||
return result;
|
||||
}
|
||||
friend inline rational gcd(rational const & r1, rational const & r2);
|
||||
|
||||
//
|
||||
// extended Euclid:
|
||||
// r1*a + r2*b = gcd
|
||||
//
|
||||
friend inline rational gcd(rational const & r1, rational const & r2, rational & a, rational & b) {
|
||||
rational result;
|
||||
m().gcd(r1.m_val, r2.m_val, a.m_val, b.m_val, result.m_val);
|
||||
return result;
|
||||
}
|
||||
|
||||
friend inline rational gcd(rational const & r1, rational const & r2, rational & a, rational & b);
|
||||
|
||||
friend inline rational lcm(rational const & r1, rational const & r2) {
|
||||
rational result;
|
||||
|
@ -378,11 +369,7 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
friend inline rational abs(rational const & r) {
|
||||
rational result(r);
|
||||
m().abs(result.m_val);
|
||||
return result;
|
||||
}
|
||||
friend inline rational abs(rational const & r);
|
||||
|
||||
rational to_rational() const { return *this; }
|
||||
|
||||
|
@ -446,5 +433,24 @@ inline rational power(rational const & r, unsigned p) {
|
|||
return r.expt(p);
|
||||
}
|
||||
|
||||
inline rational abs(rational const & r) {
|
||||
rational result(r);
|
||||
rational::m().abs(result.m_val);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline rational gcd(rational const & r1, rational const & r2) {
|
||||
rational result;
|
||||
rational::m().gcd(r1.m_val, r2.m_val, result.m_val);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline rational gcd(rational const & r1, rational const & r2, rational & a, rational & b) {
|
||||
rational result;
|
||||
rational::m().gcd(r1.m_val, r2.m_val, a.m_val, b.m_val, result.m_val);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _RATIONAL_H_ */
|
||||
|
||||
|
|
Loading…
Reference in a new issue