mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 10:25:18 +00:00
merge
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
13099b1590
|
@ -10,6 +10,12 @@ Z3 can be built using [Visual Studio][1], a [Makefile][2] or using [CMake][3]. I
|
|||
|
||||
See the [release notes](RELEASE_NOTES) for notes on various stable releases of Z3.
|
||||
|
||||
## Build status
|
||||
|
||||
| Windows x86 | Windows x64 | Ubuntu x64 | Ubuntu x86 | Debian x64 | OSX |
|
||||
| ----------- | ----------- | ---------- | ---------- | ---------- | --- |
|
||||
 |  |  |  |  | 
|
||||
|
||||
[1]: #building-z3-on-windows-using-visual-studio-command-prompt
|
||||
[2]: #building-z3-using-make-and-gccclang
|
||||
[3]: #building-z3-using-cmake
|
||||
|
|
|
@ -3,7 +3,6 @@ z3_add_component(polynomial
|
|||
algebraic_numbers.cpp
|
||||
polynomial_cache.cpp
|
||||
polynomial.cpp
|
||||
polynomial_factorization.cpp
|
||||
rpolynomial.cpp
|
||||
sexpr2upolynomial.cpp
|
||||
upolynomial.cpp
|
||||
|
|
|
@ -2,7 +2,6 @@ z3_add_component(sat
|
|||
SOURCES
|
||||
dimacs.cpp
|
||||
sat_asymm_branch.cpp
|
||||
sat_bceq.cpp
|
||||
sat_clause.cpp
|
||||
sat_clause_set.cpp
|
||||
sat_clause_use_list.cpp
|
||||
|
@ -16,7 +15,6 @@ z3_add_component(sat
|
|||
sat_probing.cpp
|
||||
sat_scc.cpp
|
||||
sat_simplifier.cpp
|
||||
sat_sls.cpp
|
||||
sat_solver.cpp
|
||||
sat_watched.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
|
|
|
@ -43,6 +43,7 @@ z3_add_component(smt
|
|||
smt_statistics.cpp
|
||||
smt_theory.cpp
|
||||
smt_value_sort.cpp
|
||||
smt2_extra_cmds.cpp
|
||||
theory_arith.cpp
|
||||
theory_array_base.cpp
|
||||
theory_array.cpp
|
||||
|
|
|
@ -82,7 +82,6 @@ add_executable(test-z3
|
|||
pdr.cpp
|
||||
permutation.cpp
|
||||
polynomial.cpp
|
||||
polynomial_factorization.cpp
|
||||
polynorm.cpp
|
||||
prime_generator.cpp
|
||||
proof_checker.cpp
|
||||
|
|
|
@ -818,6 +818,7 @@ namespace test_mapi
|
|||
BigIntCheck(ctx, ctx.MkReal("234234333/2"));
|
||||
|
||||
|
||||
#if !FRAMEWORK_LT_4
|
||||
string bn = "1234567890987654321";
|
||||
|
||||
if (ctx.MkInt(bn).BigInteger.ToString() != bn)
|
||||
|
@ -828,6 +829,7 @@ namespace test_mapi
|
|||
|
||||
if (ctx.MkBV(bn, 32).BigInteger.ToString() == bn)
|
||||
throw new TestFailedException();
|
||||
#endif
|
||||
|
||||
// Error handling test.
|
||||
try
|
||||
|
@ -1094,8 +1096,10 @@ namespace test_mapi
|
|||
|
||||
static void BigIntCheck(Context ctx, RatNum r)
|
||||
{
|
||||
#if !FRAMEWORK_LT_4
|
||||
Console.WriteLine("Num: " + r.BigIntNumerator);
|
||||
Console.WriteLine("Den: " + r.BigIntDenominator);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -22,6 +22,7 @@ def main(args):
|
|||
dest="java_package_name",
|
||||
default=None,
|
||||
help="Name to give the Java package (e.g. ``com.microsoft.z3``).")
|
||||
parser.add_argument("--ml-output-dir", dest="ml_output_dir", default=None)
|
||||
pargs = parser.parse_args(args)
|
||||
|
||||
if not mk_genfile_common.check_files_exist(pargs.api_files):
|
||||
|
@ -60,6 +61,15 @@ def main(args):
|
|||
logging.info('Generated "{}"'.format(generated_file))
|
||||
count += 1
|
||||
|
||||
if pargs.ml_output_dir:
|
||||
if not mk_genfile_common.check_dir_exists(pargs.ml_output_dir):
|
||||
return 1
|
||||
output = mk_genfile_common.mk_z3consts_ml_internal(
|
||||
pargs.api_files,
|
||||
pargs.ml_output_dir)
|
||||
logging.info('Generated "{}"'.format(output))
|
||||
count += 1
|
||||
|
||||
if count == 0:
|
||||
logging.info('No files generated. You need to specific an output directory'
|
||||
' for the relevant langauge bindings')
|
||||
|
|
|
@ -376,6 +376,180 @@ def mk_z3consts_java_internal(api_files, package_name, output_dir):
|
|||
api.close()
|
||||
return generated_enumeration_files
|
||||
|
||||
# Extract enumeration types from z3_api.h, and add ML definitions
|
||||
def mk_z3consts_ml_internal(api_files, output_dir):
|
||||
"""
|
||||
Generate ``z3enums.ml`` from the list of API header files
|
||||
in ``api_files`` and write the output file into
|
||||
the ``output_dir`` directory
|
||||
|
||||
Returns the path to the generated file.
|
||||
"""
|
||||
assert os.path.isdir(output_dir)
|
||||
assert isinstance(api_files, list)
|
||||
blank_pat = re.compile("^ *$")
|
||||
comment_pat = re.compile("^ *//.*$")
|
||||
typedef_pat = re.compile("typedef enum *")
|
||||
typedef2_pat = re.compile("typedef enum { *")
|
||||
openbrace_pat = re.compile("{ *")
|
||||
closebrace_pat = re.compile("}.*;")
|
||||
|
||||
|
||||
DeprecatedEnums = [ 'Z3_search_failure' ]
|
||||
if not os.path.exists(output_dir):
|
||||
os.mkdir(output_dir)
|
||||
|
||||
efile = open('%s.ml' % os.path.join(output_dir, "z3enums"), 'w')
|
||||
z3consts_output_path = efile.name
|
||||
efile.write('(* Automatically generated file *)\n\n')
|
||||
efile.write('(** The enumeration types of Z3. *)\n\n')
|
||||
for api_file in api_files:
|
||||
api = open(api_file, 'r')
|
||||
|
||||
SEARCHING = 0
|
||||
FOUND_ENUM = 1
|
||||
IN_ENUM = 2
|
||||
|
||||
mode = SEARCHING
|
||||
decls = {}
|
||||
idx = 0
|
||||
|
||||
linenum = 1
|
||||
for line in api:
|
||||
m1 = blank_pat.match(line)
|
||||
m2 = comment_pat.match(line)
|
||||
if m1 or m2:
|
||||
# skip blank lines and comments
|
||||
linenum = linenum + 1
|
||||
elif mode == SEARCHING:
|
||||
m = typedef_pat.match(line)
|
||||
if m:
|
||||
mode = FOUND_ENUM
|
||||
m = typedef2_pat.match(line)
|
||||
if m:
|
||||
mode = IN_ENUM
|
||||
decls = {}
|
||||
idx = 0
|
||||
elif mode == FOUND_ENUM:
|
||||
m = openbrace_pat.match(line)
|
||||
if m:
|
||||
mode = IN_ENUM
|
||||
decls = {}
|
||||
idx = 0
|
||||
else:
|
||||
assert False, "Invalid %s, line: %s" % (api_file, linenum)
|
||||
else:
|
||||
assert mode == IN_ENUM
|
||||
words = re.split('[^\-a-zA-Z0-9_]+', line)
|
||||
m = closebrace_pat.match(line)
|
||||
if m:
|
||||
name = words[1]
|
||||
if name not in DeprecatedEnums:
|
||||
sorted_decls = sorted(decls.items(), key=lambda pair: pair[1])
|
||||
efile.write('(** %s *)\n' % name[3:])
|
||||
efile.write('type %s =\n' % name[3:]) # strip Z3_
|
||||
for k, i in sorted_decls:
|
||||
efile.write(' | %s \n' % k[3:]) # strip Z3_
|
||||
efile.write('\n')
|
||||
efile.write('(** Convert %s to int*)\n' % name[3:])
|
||||
efile.write('let int_of_%s x : int =\n' % (name[3:])) # strip Z3_
|
||||
efile.write(' match x with\n')
|
||||
for k, i in sorted_decls:
|
||||
efile.write(' | %s -> %d\n' % (k[3:], i))
|
||||
efile.write('\n')
|
||||
efile.write('(** Convert int to %s*)\n' % name[3:])
|
||||
efile.write('let %s_of_int x : %s =\n' % (name[3:],name[3:])) # strip Z3_
|
||||
efile.write(' match x with\n')
|
||||
for k, i in sorted_decls:
|
||||
efile.write(' | %d -> %s\n' % (i, k[3:]))
|
||||
# use Z3.Exception?
|
||||
efile.write(' | _ -> raise (Failure "undefined enum value")\n\n')
|
||||
mode = SEARCHING
|
||||
else:
|
||||
if words[2] != '':
|
||||
if len(words[2]) > 1 and words[2][1] == 'x':
|
||||
idx = int(words[2], 16)
|
||||
else:
|
||||
idx = int(words[2])
|
||||
decls[words[1]] = idx
|
||||
idx = idx + 1
|
||||
linenum = linenum + 1
|
||||
api.close()
|
||||
efile.close()
|
||||
return z3consts_output_path
|
||||
# efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w')
|
||||
# efile.write('(* Automatically generated file *)\n\n')
|
||||
# efile.write('(** The enumeration types of Z3. *)\n\n')
|
||||
# for api_file in api_files:
|
||||
# api_file_c = ml.find_file(api_file, ml.name)
|
||||
# api_file = os.path.join(api_file_c.src_dir, api_file)
|
||||
|
||||
# api = open(api_file, 'r')
|
||||
|
||||
# SEARCHING = 0
|
||||
# FOUND_ENUM = 1
|
||||
# IN_ENUM = 2
|
||||
|
||||
# mode = SEARCHING
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
|
||||
# linenum = 1
|
||||
# for line in api:
|
||||
# m1 = blank_pat.match(line)
|
||||
# m2 = comment_pat.match(line)
|
||||
# if m1 or m2:
|
||||
# # skip blank lines and comments
|
||||
# linenum = linenum + 1
|
||||
# elif mode == SEARCHING:
|
||||
# m = typedef_pat.match(line)
|
||||
# if m:
|
||||
# mode = FOUND_ENUM
|
||||
# m = typedef2_pat.match(line)
|
||||
# if m:
|
||||
# mode = IN_ENUM
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
# elif mode == FOUND_ENUM:
|
||||
# m = openbrace_pat.match(line)
|
||||
# if m:
|
||||
# mode = IN_ENUM
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
# else:
|
||||
# assert False, "Invalid %s, line: %s" % (api_file, linenum)
|
||||
# else:
|
||||
# assert mode == IN_ENUM
|
||||
# words = re.split('[^\-a-zA-Z0-9_]+', line)
|
||||
# m = closebrace_pat.match(line)
|
||||
# if m:
|
||||
# name = words[1]
|
||||
# if name not in DeprecatedEnums:
|
||||
# efile.write('(** %s *)\n' % name[3:])
|
||||
# efile.write('type %s =\n' % name[3:]) # strip Z3_
|
||||
# for k, i in sorted(decls.items(), key=lambda pair: pair[1]):
|
||||
# efile.write(' | %s \n' % k[3:]) # strip Z3_
|
||||
# efile.write('\n')
|
||||
# efile.write('(** Convert %s to int*)\n' % name[3:])
|
||||
# efile.write('val int_of_%s : %s -> int\n' % (name[3:], name[3:])) # strip Z3_
|
||||
# efile.write('(** Convert int to %s*)\n' % name[3:])
|
||||
# efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_
|
||||
# efile.write('\n')
|
||||
# mode = SEARCHING
|
||||
# else:
|
||||
# if words[2] != '':
|
||||
# if len(words[2]) > 1 and words[2][1] == 'x':
|
||||
# idx = int(words[2], 16)
|
||||
# else:
|
||||
# idx = int(words[2])
|
||||
# decls[words[1]] = idx
|
||||
# idx = idx + 1
|
||||
# linenum = linenum + 1
|
||||
# api.close()
|
||||
# efile.close()
|
||||
# if VERBOSE:
|
||||
# print ('Generated "%s/z3enums.mli"' % ('%s' % gendir))
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Functions for generating a "module definition file" for MSVC
|
||||
|
|
|
@ -27,6 +27,7 @@ DOTNET_KEY_FILE=None
|
|||
JAVA_ENABLED=True
|
||||
GIT_HASH=False
|
||||
PYTHON_ENABLED=True
|
||||
MAKEJOBS=getenv("MAKEJOBS", '8')
|
||||
|
||||
def set_verbose(flag):
|
||||
global VERBOSE
|
||||
|
@ -139,7 +140,7 @@ class cd:
|
|||
def mk_z3():
|
||||
with cd(BUILD_DIR):
|
||||
try:
|
||||
return subprocess.call(['make', '-j', '8'])
|
||||
return subprocess.call(['make', '-j', MAKEJOBS])
|
||||
except:
|
||||
return 1
|
||||
|
||||
|
|
|
@ -2442,7 +2442,7 @@ def mk_config():
|
|||
CXXFLAGS = '%s -O3 -D _EXTERNAL_RELEASE -fomit-frame-pointer' % CXXFLAGS
|
||||
if is_CXX_clangpp():
|
||||
CXXFLAGS = '%s -Wno-unknown-pragmas -Wno-overloaded-virtual -Wno-unused-value' % CXXFLAGS
|
||||
sysname = os.uname()[0]
|
||||
sysname, _, _, _, machine = os.uname()
|
||||
if sysname == 'Darwin':
|
||||
SO_EXT = '.dylib'
|
||||
SLIBFLAGS = '-dynamiclib'
|
||||
|
@ -2493,7 +2493,9 @@ def mk_config():
|
|||
# and to make it create an import library.
|
||||
SLIBEXTRAFLAGS = '%s -static-libgcc -static-libstdc++ -Wl,--out-implib,libz3.dll.a' % SLIBEXTRAFLAGS
|
||||
LDFLAGS = '%s -static-libgcc -static-libstdc++' % LDFLAGS
|
||||
|
||||
if sysname == 'Linux' and machine.startswith('armv7') or machine.startswith('armv8'):
|
||||
CXXFLAGS = '%s -fpic' % CXXFLAGS
|
||||
|
||||
config.write('PREFIX=%s\n' % PREFIX)
|
||||
config.write('CC=%s\n' % CC)
|
||||
config.write('CXX=%s\n' % CXX)
|
||||
|
@ -2870,7 +2872,8 @@ def mk_bindings(api_files):
|
|||
dotnet_output_dir=dotnet_output_dir,
|
||||
java_output_dir=java_output_dir,
|
||||
java_package_name=java_package_name,
|
||||
ml_output_dir=ml_output_dir
|
||||
ml_output_dir=ml_output_dir,
|
||||
ml_src_dir=ml_output_dir
|
||||
)
|
||||
cp_z3py_to_build()
|
||||
if is_ml_enabled():
|
||||
|
@ -2924,172 +2927,17 @@ def mk_z3consts_java(api_files):
|
|||
|
||||
# Extract enumeration types from z3_api.h, and add ML definitions
|
||||
def mk_z3consts_ml(api_files):
|
||||
blank_pat = re.compile("^ *$")
|
||||
comment_pat = re.compile("^ *//.*$")
|
||||
typedef_pat = re.compile("typedef enum *")
|
||||
typedef2_pat = re.compile("typedef enum { *")
|
||||
openbrace_pat = re.compile("{ *")
|
||||
closebrace_pat = re.compile("}.*;")
|
||||
|
||||
ml = get_component(ML_COMPONENT)
|
||||
|
||||
DeprecatedEnums = [ 'Z3_search_failure' ]
|
||||
gendir = ml.src_dir
|
||||
if not os.path.exists(gendir):
|
||||
os.mkdir(gendir)
|
||||
|
||||
efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w')
|
||||
efile.write('(* Automatically generated file *)\n\n')
|
||||
efile.write('(** The enumeration types of Z3. *)\n\n')
|
||||
full_path_api_files = []
|
||||
for api_file in api_files:
|
||||
api_file_c = ml.find_file(api_file, ml.name)
|
||||
api_file = os.path.join(api_file_c.src_dir, api_file)
|
||||
|
||||
api = open(api_file, 'r')
|
||||
|
||||
SEARCHING = 0
|
||||
FOUND_ENUM = 1
|
||||
IN_ENUM = 2
|
||||
|
||||
mode = SEARCHING
|
||||
decls = {}
|
||||
idx = 0
|
||||
|
||||
linenum = 1
|
||||
for line in api:
|
||||
m1 = blank_pat.match(line)
|
||||
m2 = comment_pat.match(line)
|
||||
if m1 or m2:
|
||||
# skip blank lines and comments
|
||||
linenum = linenum + 1
|
||||
elif mode == SEARCHING:
|
||||
m = typedef_pat.match(line)
|
||||
if m:
|
||||
mode = FOUND_ENUM
|
||||
m = typedef2_pat.match(line)
|
||||
if m:
|
||||
mode = IN_ENUM
|
||||
decls = {}
|
||||
idx = 0
|
||||
elif mode == FOUND_ENUM:
|
||||
m = openbrace_pat.match(line)
|
||||
if m:
|
||||
mode = IN_ENUM
|
||||
decls = {}
|
||||
idx = 0
|
||||
else:
|
||||
assert False, "Invalid %s, line: %s" % (api_file, linenum)
|
||||
else:
|
||||
assert mode == IN_ENUM
|
||||
words = re.split('[^\-a-zA-Z0-9_]+', line)
|
||||
m = closebrace_pat.match(line)
|
||||
if m:
|
||||
name = words[1]
|
||||
if name not in DeprecatedEnums:
|
||||
efile.write('(** %s *)\n' % name[3:])
|
||||
efile.write('type %s =\n' % name[3:]) # strip Z3_
|
||||
for k, i in decls.items():
|
||||
efile.write(' | %s \n' % k[3:]) # strip Z3_
|
||||
efile.write('\n')
|
||||
efile.write('(** Convert %s to int*)\n' % name[3:])
|
||||
efile.write('let int_of_%s x : int =\n' % (name[3:])) # strip Z3_
|
||||
efile.write(' match x with\n')
|
||||
for k, i in decls.items():
|
||||
efile.write(' | %s -> %d\n' % (k[3:], i))
|
||||
efile.write('\n')
|
||||
efile.write('(** Convert int to %s*)\n' % name[3:])
|
||||
efile.write('let %s_of_int x : %s =\n' % (name[3:],name[3:])) # strip Z3_
|
||||
efile.write(' match x with\n')
|
||||
for k, i in decls.items():
|
||||
efile.write(' | %d -> %s\n' % (i, k[3:]))
|
||||
# use Z3.Exception?
|
||||
efile.write(' | _ -> raise (Failure "undefined enum value")\n\n')
|
||||
mode = SEARCHING
|
||||
else:
|
||||
if words[2] != '':
|
||||
if len(words[2]) > 1 and words[2][1] == 'x':
|
||||
idx = int(words[2], 16)
|
||||
else:
|
||||
idx = int(words[2])
|
||||
decls[words[1]] = idx
|
||||
idx = idx + 1
|
||||
linenum = linenum + 1
|
||||
api.close()
|
||||
efile.close()
|
||||
full_path_api_files.append(api_file)
|
||||
generated_file = mk_genfile_common.mk_z3consts_ml_internal(
|
||||
full_path_api_files,
|
||||
ml.src_dir)
|
||||
if VERBOSE:
|
||||
print ('Generated "%s/z3enums.ml"' % ('%s' % gendir))
|
||||
# efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w')
|
||||
# efile.write('(* Automatically generated file *)\n\n')
|
||||
# efile.write('(** The enumeration types of Z3. *)\n\n')
|
||||
# for api_file in api_files:
|
||||
# api_file_c = ml.find_file(api_file, ml.name)
|
||||
# api_file = os.path.join(api_file_c.src_dir, api_file)
|
||||
|
||||
# api = open(api_file, 'r')
|
||||
|
||||
# SEARCHING = 0
|
||||
# FOUND_ENUM = 1
|
||||
# IN_ENUM = 2
|
||||
|
||||
# mode = SEARCHING
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
|
||||
# linenum = 1
|
||||
# for line in api:
|
||||
# m1 = blank_pat.match(line)
|
||||
# m2 = comment_pat.match(line)
|
||||
# if m1 or m2:
|
||||
# # skip blank lines and comments
|
||||
# linenum = linenum + 1
|
||||
# elif mode == SEARCHING:
|
||||
# m = typedef_pat.match(line)
|
||||
# if m:
|
||||
# mode = FOUND_ENUM
|
||||
# m = typedef2_pat.match(line)
|
||||
# if m:
|
||||
# mode = IN_ENUM
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
# elif mode == FOUND_ENUM:
|
||||
# m = openbrace_pat.match(line)
|
||||
# if m:
|
||||
# mode = IN_ENUM
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
# else:
|
||||
# assert False, "Invalid %s, line: %s" % (api_file, linenum)
|
||||
# else:
|
||||
# assert mode == IN_ENUM
|
||||
# words = re.split('[^\-a-zA-Z0-9_]+', line)
|
||||
# m = closebrace_pat.match(line)
|
||||
# if m:
|
||||
# name = words[1]
|
||||
# if name not in DeprecatedEnums:
|
||||
# efile.write('(** %s *)\n' % name[3:])
|
||||
# efile.write('type %s =\n' % name[3:]) # strip Z3_
|
||||
# for k, i in decls.items():
|
||||
# efile.write(' | %s \n' % k[3:]) # strip Z3_
|
||||
# efile.write('\n')
|
||||
# efile.write('(** Convert %s to int*)\n' % name[3:])
|
||||
# efile.write('val int_of_%s : %s -> int\n' % (name[3:], name[3:])) # strip Z3_
|
||||
# efile.write('(** Convert int to %s*)\n' % name[3:])
|
||||
# efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_
|
||||
# efile.write('\n')
|
||||
# mode = SEARCHING
|
||||
# else:
|
||||
# if words[2] != '':
|
||||
# if len(words[2]) > 1 and words[2][1] == 'x':
|
||||
# idx = int(words[2], 16)
|
||||
# else:
|
||||
# idx = int(words[2])
|
||||
# decls[words[1]] = idx
|
||||
# idx = idx + 1
|
||||
# linenum = linenum + 1
|
||||
# api.close()
|
||||
# efile.close()
|
||||
# if VERBOSE:
|
||||
# print ('Generated "%s/z3enums.mli"' % ('%s' % gendir))
|
||||
print ('Generated "%s"' % generated_file)
|
||||
|
||||
def mk_gui_str(id):
|
||||
return '4D2F40D8-E5F9-473B-B548-%012d' % id
|
||||
|
|
|
@ -29,6 +29,9 @@ DOTNET_KEY_FILE=None
|
|||
JAVA_ENABLED=True
|
||||
GIT_HASH=False
|
||||
PYTHON_ENABLED=True
|
||||
X86ONLY=False
|
||||
X64ONLY=False
|
||||
MAKEJOBS=getenv("MAKEJOBS", "24")
|
||||
|
||||
def set_verbose(flag):
|
||||
global VERBOSE
|
||||
|
@ -63,11 +66,13 @@ def display_help():
|
|||
print(" --nojava do not include Java bindings in the binary distribution files.")
|
||||
print(" --nopython do not include Python bindings in the binary distribution files.")
|
||||
print(" --githash include git hash in the Zip file.")
|
||||
print(" --x86-only x86 dist only.")
|
||||
print(" --x64-only x64 dist only.")
|
||||
exit(0)
|
||||
|
||||
# Parse configuration option for mk_make script
|
||||
def parse_options():
|
||||
global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED, DOTNET_KEY_FILE, PYTHON_ENABLED
|
||||
global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED, DOTNET_KEY_FILE, PYTHON_ENABLED, X86ONLY, X64ONLY
|
||||
path = BUILD_DIR
|
||||
options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
|
||||
'help',
|
||||
|
@ -77,7 +82,9 @@ def parse_options():
|
|||
'nodotnet',
|
||||
'dotnet-key=',
|
||||
'githash',
|
||||
'nopython'
|
||||
'nopython',
|
||||
'x86-only',
|
||||
'x64-only'
|
||||
])
|
||||
for opt, arg in options:
|
||||
if opt in ('-b', '--build'):
|
||||
|
@ -100,6 +107,10 @@ def parse_options():
|
|||
JAVA_ENABLED = False
|
||||
elif opt == '--githash':
|
||||
GIT_HASH = True
|
||||
elif opt == '--x86-only' and not X64ONLY:
|
||||
X86ONLY = True
|
||||
elif opt == '--x64-only' and not X86ONLY:
|
||||
X64ONLY = True
|
||||
else:
|
||||
raise MKException("Invalid command line option '%s'" % opt)
|
||||
set_build_dir(path)
|
||||
|
@ -111,7 +122,8 @@ def check_build_dir(path):
|
|||
# Create a build directory using mk_make.py
|
||||
def mk_build_dir(path, x64):
|
||||
if not check_build_dir(path) or FORCE_MK:
|
||||
opts = ["python", os.path.join('scripts', 'mk_make.py'), "--parallel=24", "-b", path]
|
||||
parallel = '--parallel=' + MAKEJOBS
|
||||
opts = ["python", os.path.join('scripts', 'mk_make.py'), parallel, "-b", path]
|
||||
if DOTNET_ENABLED:
|
||||
opts.append('--dotnet')
|
||||
if not DOTNET_KEY_FILE is None:
|
||||
|
@ -160,7 +172,7 @@ def exec_cmds(cmds):
|
|||
return res
|
||||
|
||||
# Compile Z3 (if x64 == True, then it builds it in x64 mode).
|
||||
def mk_z3_core(x64):
|
||||
def mk_z3(x64):
|
||||
cmds = []
|
||||
if x64:
|
||||
cmds.append('call "%VCINSTALLDIR%vcvarsall.bat" amd64')
|
||||
|
@ -172,9 +184,9 @@ def mk_z3_core(x64):
|
|||
if exec_cmds(cmds) != 0:
|
||||
raise MKException("Failed to make z3, x64: %s" % x64)
|
||||
|
||||
def mk_z3():
|
||||
mk_z3_core(False)
|
||||
mk_z3_core(True)
|
||||
def mk_z3s():
|
||||
mk_z3(False)
|
||||
mk_z3(True)
|
||||
|
||||
def get_z3_name(x64):
|
||||
major, minor, build, revision = get_version()
|
||||
|
@ -187,7 +199,7 @@ def get_z3_name(x64):
|
|||
else:
|
||||
return 'z3-%s.%s.%s-%s-win' % (major, minor, build, platform)
|
||||
|
||||
def mk_dist_dir_core(x64):
|
||||
def mk_dist_dir(x64):
|
||||
if x64:
|
||||
platform = "x64"
|
||||
build_path = BUILD_X64_DIR
|
||||
|
@ -204,14 +216,14 @@ def mk_dist_dir_core(x64):
|
|||
if is_verbose():
|
||||
print("Generated %s distribution folder at '%s'" % (platform, dist_path))
|
||||
|
||||
def mk_dist_dir():
|
||||
mk_dist_dir_core(False)
|
||||
mk_dist_dir_core(True)
|
||||
def mk_dist_dirs():
|
||||
mk_dist_dir(False)
|
||||
mk_dist_dir(True)
|
||||
|
||||
def get_dist_path(x64):
|
||||
return get_z3_name(x64)
|
||||
|
||||
def mk_zip_core(x64):
|
||||
def mk_zip(x64):
|
||||
dist_path = get_dist_path(x64)
|
||||
old = os.getcwd()
|
||||
try:
|
||||
|
@ -228,9 +240,9 @@ def mk_zip_core(x64):
|
|||
os.chdir(old)
|
||||
|
||||
# Create a zip file for each platform
|
||||
def mk_zip():
|
||||
mk_zip_core(False)
|
||||
mk_zip_core(True)
|
||||
def mk_zips():
|
||||
mk_zip(False)
|
||||
mk_zip(True)
|
||||
|
||||
|
||||
VS_RUNTIME_PATS = [re.compile('vcomp.*\.dll'),
|
||||
|
@ -238,7 +250,7 @@ VS_RUNTIME_PATS = [re.compile('vcomp.*\.dll'),
|
|||
re.compile('msvcr.*\.dll')]
|
||||
|
||||
# Copy Visual Studio Runtime libraries
|
||||
def cp_vs_runtime_core(x64):
|
||||
def cp_vs_runtime(x64):
|
||||
if x64:
|
||||
platform = "x64"
|
||||
|
||||
|
@ -262,27 +274,49 @@ def cp_vs_runtime_core(x64):
|
|||
if is_verbose():
|
||||
print("Copied '%s' to '%s'" % (f, bin_dist_path))
|
||||
|
||||
def cp_vs_runtime():
|
||||
cp_vs_runtime_core(True)
|
||||
cp_vs_runtime_core(False)
|
||||
def cp_vs_runtimes():
|
||||
cp_vs_runtime(True)
|
||||
cp_vs_runtime(False)
|
||||
|
||||
def cp_license():
|
||||
shutil.copy("LICENSE.txt", os.path.join(DIST_DIR, get_dist_path(True)))
|
||||
shutil.copy("LICENSE.txt", os.path.join(DIST_DIR, get_dist_path(False)))
|
||||
def cp_license(x64):
|
||||
shutil.copy("LICENSE.txt", os.path.join(DIST_DIR, get_dist_path(x64)))
|
||||
|
||||
def cp_licenses():
|
||||
cp_license(True)
|
||||
cp_license(False)
|
||||
|
||||
# Entry point
|
||||
def main():
|
||||
if os.name != 'nt':
|
||||
raise MKException("This script is for Windows only")
|
||||
|
||||
parse_options()
|
||||
check_vc_cmd_prompt()
|
||||
mk_build_dirs()
|
||||
mk_z3()
|
||||
init_project_def()
|
||||
mk_dist_dir()
|
||||
cp_license()
|
||||
cp_vs_runtime()
|
||||
mk_zip()
|
||||
|
||||
if X86ONLY:
|
||||
mk_build_dir(BUILD_X86_DIR, False)
|
||||
mk_z3(False)
|
||||
init_project_def()
|
||||
mk_dist_dir(False)
|
||||
cp_license(False)
|
||||
cp_vs_runtime(False)
|
||||
mk_zip(False)
|
||||
elif X64ONLY:
|
||||
mk_build_dir(BUILD_X64_DIR, True)
|
||||
mk_z3(True)
|
||||
init_project_def()
|
||||
mk_dist_dir(True)
|
||||
cp_license(True)
|
||||
cp_vs_runtime(True)
|
||||
mk_zip(True)
|
||||
else:
|
||||
mk_build_dirs()
|
||||
mk_z3s()
|
||||
init_project_def()
|
||||
mk_dist_dirs()
|
||||
cp_licenses()
|
||||
cp_vs_runtimes()
|
||||
mk_zips()
|
||||
|
||||
main()
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ def mk_dotnet(dotnet):
|
|||
dotnet.write(' public delegate void Z3_error_handler(Z3_context c, Z3_error_code e);\n\n')
|
||||
dotnet.write(' public class LIB\n')
|
||||
dotnet.write(' {\n')
|
||||
dotnet.write(' const string Z3_DLL_NAME = \"libz3.dll\";\n'
|
||||
dotnet.write(' const string Z3_DLL_NAME = \"libz3\";\n'
|
||||
' \n')
|
||||
dotnet.write(' [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n')
|
||||
dotnet.write(' public extern static void Z3_set_error_handler(Z3_context a0, Z3_error_handler a1);\n\n')
|
||||
|
@ -1195,13 +1195,13 @@ def ml_alloc_and_store(t, lhs, rhs):
|
|||
alloc_str = '%s = caml_alloc_custom(&%s, sizeof(%s), 0, 1); ' % (lhs, pops, pts)
|
||||
return alloc_str + ml_set_wrap(t, lhs, rhs)
|
||||
|
||||
def mk_ml(ml_dir):
|
||||
def mk_ml(ml_src_dir, ml_output_dir):
|
||||
global Type2Str
|
||||
ml_nativef = os.path.join(ml_dir, 'z3native.ml')
|
||||
ml_nativef = os.path.join(ml_output_dir, 'z3native.ml')
|
||||
ml_native = open(ml_nativef, 'w')
|
||||
ml_native.write('(* Automatically generated file *)\n\n')
|
||||
|
||||
ml_pref = open(os.path.join(ml_dir, 'z3native.ml.pre'), 'r')
|
||||
ml_pref = open(os.path.join(ml_src_dir, 'z3native.ml.pre'), 'r')
|
||||
for s in ml_pref:
|
||||
ml_native.write(s);
|
||||
ml_pref.close()
|
||||
|
@ -1250,14 +1250,14 @@ def mk_ml(ml_dir):
|
|||
if mk_util.is_verbose():
|
||||
print ('Generated "%s"' % ml_nativef)
|
||||
|
||||
mk_z3native_stubs_c(ml_dir)
|
||||
mk_z3native_stubs_c(ml_src_dir, ml_output_dir)
|
||||
|
||||
def mk_z3native_stubs_c(ml_dir): # C interface
|
||||
ml_wrapperf = os.path.join(ml_dir, 'z3native_stubs.c')
|
||||
def mk_z3native_stubs_c(ml_src_dir, ml_output_dir): # C interface
|
||||
ml_wrapperf = os.path.join(ml_output_dir, 'z3native_stubs.c')
|
||||
ml_wrapper = open(ml_wrapperf, 'w')
|
||||
ml_wrapper.write('// Automatically generated file\n\n')
|
||||
|
||||
ml_pref = open(os.path.join(ml_dir, 'z3native_stubs.c.pre'), 'r')
|
||||
ml_pref = open(os.path.join(ml_src_dir, 'z3native_stubs.c.pre'), 'r')
|
||||
for s in ml_pref:
|
||||
ml_wrapper.write(s);
|
||||
ml_pref.close()
|
||||
|
@ -1574,6 +1574,7 @@ def write_log_h_preamble(log_h):
|
|||
log_h.write('#define _Z3_UNUSED\n')
|
||||
log_h.write('#endif\n')
|
||||
#
|
||||
log_h.write('#include<iostream>\n')
|
||||
log_h.write('extern std::ostream * g_z3_log;\n')
|
||||
log_h.write('extern bool g_z3_log_enabled;\n')
|
||||
log_h.write('class z3_log_ctx { bool m_prev; public: z3_log_ctx():m_prev(g_z3_log_enabled) { g_z3_log_enabled = false; } ~z3_log_ctx() { g_z3_log_enabled = m_prev; } bool enabled() const { return m_prev; } };\n')
|
||||
|
@ -1666,7 +1667,8 @@ def generate_files(api_files,
|
|||
dotnet_output_dir=None,
|
||||
java_output_dir=None,
|
||||
java_package_name=None,
|
||||
ml_output_dir=None):
|
||||
ml_output_dir=None,
|
||||
ml_src_dir=None):
|
||||
"""
|
||||
Scan the api files in ``api_files`` and emit the relevant API files into
|
||||
the output directories specified. If an output directory is set to ``None``
|
||||
|
@ -1741,7 +1743,8 @@ def generate_files(api_files,
|
|||
mk_java(java_output_dir, java_package_name)
|
||||
|
||||
if ml_output_dir:
|
||||
mk_ml(ml_output_dir)
|
||||
assert not ml_src_dir is None
|
||||
mk_ml(ml_src_dir, ml_output_dir)
|
||||
|
||||
def main(args):
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
@ -1768,6 +1771,10 @@ def main(args):
|
|||
dest="java_package_name",
|
||||
default=None,
|
||||
help="Name to give the Java package (e.g. ``com.microsoft.z3``).")
|
||||
parser.add_argument("--ml-src-dir",
|
||||
dest="ml_src_dir",
|
||||
default=None,
|
||||
help="Directory containing OCaml source files. If not specified no files are emitted")
|
||||
parser.add_argument("--ml-output-dir",
|
||||
dest="ml_output_dir",
|
||||
default=None,
|
||||
|
@ -1779,6 +1786,11 @@ def main(args):
|
|||
logging.error('--java-package-name must be specified')
|
||||
return 1
|
||||
|
||||
if pargs.ml_output_dir:
|
||||
if pargs.ml_src_dir is None:
|
||||
logging.error('--ml-src-dir must be specified')
|
||||
return 1
|
||||
|
||||
for api_file in pargs.api_files:
|
||||
if not os.path.exists(api_file):
|
||||
logging.error('"{}" does not exist'.format(api_file))
|
||||
|
@ -1790,7 +1802,8 @@ def main(args):
|
|||
dotnet_output_dir=pargs.dotnet_output_dir,
|
||||
java_output_dir=pargs.java_output_dir,
|
||||
java_package_name=pargs.java_package_name,
|
||||
ml_output_dir=pargs.ml_output_dir)
|
||||
ml_output_dir=pargs.ml_output_dir,
|
||||
ml_src_dir=pargs.ml_src_dir)
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -7,7 +7,7 @@ Module Name:
|
|||
|
||||
Abstract:
|
||||
|
||||
Additional APIs for handling Z3 algebraic numbers encoded as
|
||||
Additional APIs for handling Z3 algebraic numbers encoded as
|
||||
Z3_ASTs
|
||||
|
||||
Author:
|
||||
|
@ -15,9 +15,8 @@ Author:
|
|||
Leonardo de Moura (leonardo) 2012-12-07
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -74,9 +73,9 @@ extern "C" {
|
|||
|
||||
bool Z3_algebraic_is_value_core(Z3_context c, Z3_ast a) {
|
||||
api::context * _c = mk_c(c);
|
||||
return
|
||||
is_expr(a) &&
|
||||
(_c->autil().is_numeral(to_expr(a)) ||
|
||||
return
|
||||
is_expr(a) &&
|
||||
(_c->autil().is_numeral(to_expr(a)) ||
|
||||
_c->autil().is_irrational_algebraic_numeral(to_expr(a)));
|
||||
}
|
||||
|
||||
|
@ -162,9 +161,9 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_algebraic_add(Z3_context c, Z3_ast a, Z3_ast b) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_algebraic_add(c, a, b);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
BIN_OP(+,add);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -172,9 +171,9 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_algebraic_sub(Z3_context c, Z3_ast a, Z3_ast b) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_algebraic_sub(c, a, b);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
BIN_OP(-,sub);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -182,9 +181,9 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_algebraic_mul(Z3_context c, Z3_ast a, Z3_ast b) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_algebraic_mul(c, a, b);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
BIN_OP(*,mul);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -219,8 +218,8 @@ extern "C" {
|
|||
algebraic_numbers::manager & _am = am(c);
|
||||
scoped_anum _r(_am);
|
||||
if (is_rational(c, a)) {
|
||||
scoped_anum av(_am);
|
||||
_am.set(av, get_rational(c, a).to_mpq());
|
||||
scoped_anum av(_am);
|
||||
_am.set(av, get_rational(c, a).to_mpq());
|
||||
_am.root(av, k, _r);
|
||||
}
|
||||
else {
|
||||
|
@ -241,8 +240,8 @@ extern "C" {
|
|||
algebraic_numbers::manager & _am = am(c);
|
||||
scoped_anum _r(_am);
|
||||
if (is_rational(c, a)) {
|
||||
scoped_anum av(_am);
|
||||
_am.set(av, get_rational(c, a).to_mpq());
|
||||
scoped_anum av(_am);
|
||||
_am.set(av, get_rational(c, a).to_mpq());
|
||||
_am.power(av, k, _r);
|
||||
}
|
||||
else {
|
||||
|
@ -328,7 +327,7 @@ extern "C" {
|
|||
scoped_anum tmp(_am);
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (is_rational(c, a[i])) {
|
||||
_am.set(tmp, get_rational(c, a[i]).to_mpq());
|
||||
_am.set(tmp, get_rational(c, a[i]).to_mpq());
|
||||
as.push_back(tmp);
|
||||
}
|
||||
else if (is_irrational(c, a[i])) {
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -37,7 +36,7 @@ extern "C" {
|
|||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_sort Z3_API Z3_mk_real_sort(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_real_sort(c);
|
||||
|
@ -50,7 +49,7 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_mk_real(Z3_context c, int num, int den) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_real(c, num, den);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
if (den == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
|
@ -60,7 +59,7 @@ extern "C" {
|
|||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
MK_ARITH_OP(Z3_mk_add, OP_ADD);
|
||||
MK_ARITH_OP(Z3_mk_mul, OP_MUL);
|
||||
MK_BINARY_ARITH_OP(Z3_mk_power, OP_POWER);
|
||||
|
@ -70,17 +69,17 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_mk_div(Z3_context c, Z3_ast n1, Z3_ast n2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_div(c, n1, n2);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
decl_kind k = OP_IDIV;
|
||||
sort* ty = mk_c(c)->m().get_sort(to_expr(n1));
|
||||
sort* real_ty = mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), REAL_SORT);
|
||||
if (ty == real_ty) {
|
||||
k = OP_DIV;
|
||||
}
|
||||
expr * args[2] = { to_expr(n1), to_expr(n2) };
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_arith_fid(), k, 0, 0, 2, args);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
expr * args[2] = { to_expr(n1), to_expr(n2) };
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_arith_fid(), k, 0, 0, 2, args);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -142,7 +141,7 @@ extern "C" {
|
|||
rational l;
|
||||
mk_c(c)->autil().am().get_lower(val, l, precision);
|
||||
expr * r = mk_c(c)->autil().mk_numeral(l, false);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -160,7 +159,7 @@ extern "C" {
|
|||
rational l;
|
||||
mk_c(c)->autil().am().get_upper(val, l, precision);
|
||||
expr * r = mk_c(c)->autil().mk_numeral(l, false);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -176,7 +175,7 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
expr * r = mk_c(c)->autil().mk_numeral(numerator(val), true);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -192,7 +191,7 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
expr * r = mk_c(c)->autil().mk_numeral(denominator(val), true);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -27,7 +26,7 @@ extern "C" {
|
|||
Z3_sort Z3_API Z3_mk_array_sort(Z3_context c, Z3_sort domain, Z3_sort range) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_array_sort(c, domain, range);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
parameter params[2] = { parameter(to_sort(domain)), parameter(to_sort(range)) };
|
||||
sort * ty = mk_c(c)->m().mk_sort(mk_c(c)->get_array_fid(), ARRAY_SORT, 2, params);
|
||||
mk_c(c)->save_ast_trail(ty);
|
||||
|
@ -57,7 +56,7 @@ extern "C" {
|
|||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_store(c, a, i, v);
|
||||
|
@ -82,7 +81,7 @@ extern "C" {
|
|||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const* args) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_map(c, f, n, args);
|
||||
|
@ -94,7 +93,7 @@ extern "C" {
|
|||
ast_manager & m = mk_c(c)->m();
|
||||
func_decl* _f = to_func_decl(f);
|
||||
expr* const* _args = to_exprs(args);
|
||||
|
||||
|
||||
ptr_vector<sort> domain;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
domain.push_back(m.get_sort(_args[i]));
|
||||
|
@ -111,7 +110,7 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_mk_const_array(Z3_context c, Z3_sort domain, Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_const_array(c, domain, v);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _v = to_expr(v);
|
||||
sort * _range = m.get_sort(_v);
|
||||
|
@ -123,14 +122,14 @@ extern "C" {
|
|||
app * r = m.mk_app(cd, 1, &_v);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_array_default(Z3_context c, Z3_ast array) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_array_default(c, array);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _a = to_expr(array);
|
||||
|
||||
|
@ -138,12 +137,12 @@ extern "C" {
|
|||
app * r = m.mk_app(f, 1, &_a);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast mk_app_array_core(Z3_context c, Z3_sort domain, Z3_ast v) {
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _v = to_expr(v);
|
||||
sort * _range = m.get_sort(_v);
|
||||
|
@ -178,7 +177,7 @@ extern "C" {
|
|||
LOG_Z3_mk_full_set(c, domain);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast r = mk_app_array_core(c, domain, Z3_mk_true(c));
|
||||
RETURN_Z3(r);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -205,8 +204,8 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_get_array_sort_domain(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT) {
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(0).get_ast());
|
||||
RETURN_Z3(r);
|
||||
|
@ -215,13 +214,13 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_sort Z3_API Z3_get_array_sort_range(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_array_sort_range(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT) {
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(1).get_ast());
|
||||
RETURN_Z3(r);
|
||||
|
|
|
@ -1063,9 +1063,10 @@ extern "C" {
|
|||
case OP_BV2INT: return Z3_OP_BV2INT;
|
||||
case OP_CARRY: return Z3_OP_CARRY;
|
||||
case OP_XOR3: return Z3_OP_XOR3;
|
||||
case OP_BIT2BOOL: return Z3_OP_BIT2BOOL;
|
||||
case OP_BSMUL_NO_OVFL: return Z3_OP_BSMUL_NO_OVFL;
|
||||
case OP_BUMUL_NO_OVFL: return Z3_OP_BUMUL_NO_OVFL;
|
||||
case OP_BSMUL_NO_UDFL: return Z3_OP_BSMUL_NO_UDFL;
|
||||
case OP_BSMUL_NO_UDFL: return Z3_OP_BSMUL_NO_UDFL;
|
||||
case OP_BSDIV_I: return Z3_OP_BSDIV_I;
|
||||
case OP_BUDIV_I: return Z3_OP_BUDIV_I;
|
||||
case OP_BSREM_I: return Z3_OP_BSREM_I;
|
||||
|
@ -1210,7 +1211,9 @@ extern "C" {
|
|||
switch(_d->get_decl_kind()) {
|
||||
case OP_PB_LE: return Z3_OP_PB_LE;
|
||||
case OP_PB_GE: return Z3_OP_PB_GE;
|
||||
case OP_PB_EQ: return Z3_OP_PB_EQ;
|
||||
case OP_AT_MOST_K: return Z3_OP_PB_AT_MOST;
|
||||
case OP_AT_LEAST_K: return Z3_OP_PB_AT_LEAST;
|
||||
default: return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -27,7 +26,7 @@ extern "C" {
|
|||
Z3_sort Z3_API Z3_mk_bv_sort(Z3_context c, unsigned sz) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bv_sort(c, sz);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
if (sz == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
}
|
||||
|
@ -39,7 +38,7 @@ extern "C" {
|
|||
|
||||
#define MK_BV_UNARY(NAME, OP) MK_UNARY(NAME, mk_c(c)->get_bv_fid(), OP, SKIP)
|
||||
#define MK_BV_BINARY(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_bv_fid(), OP, SKIP)
|
||||
|
||||
|
||||
MK_BV_UNARY(Z3_mk_bvnot, OP_BNOT);
|
||||
MK_BV_UNARY(Z3_mk_bvredand, OP_BREDAND);
|
||||
MK_BV_UNARY(Z3_mk_bvredor, OP_BREDOR);
|
||||
|
@ -75,11 +74,11 @@ extern "C" {
|
|||
expr * _n = to_expr(n);
|
||||
parameter params[2] = { parameter(high), parameter(low) };
|
||||
expr * a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_EXTRACT, 2, params, 1, &_n);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
return of_ast(a);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_extract(Z3_context c, unsigned high, unsigned low, Z3_ast n) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_extract(c, high, low, n);
|
||||
|
@ -88,7 +87,7 @@ extern "C" {
|
|||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
#define MK_BV_PUNARY(NAME, OP) \
|
||||
Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
||||
Z3_TRY; \
|
||||
|
@ -113,7 +112,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_ast Z3_API Z3_mk_bv2int(Z3_context c, Z3_ast n, Z3_bool is_signed) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bv2int(c, n, is_signed);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort int_s = Z3_mk_int_sort(c);
|
||||
if (is_signed) {
|
||||
Z3_ast r = Z3_mk_bv2int(c, n, false);
|
||||
|
@ -125,7 +124,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_inc_ref(c, bound);
|
||||
Z3_ast zero = Z3_mk_int(c, 0, s);
|
||||
Z3_inc_ref(c, zero);
|
||||
Z3_ast pred = Z3_mk_bvslt(c, n, zero);
|
||||
Z3_ast pred = Z3_mk_bvslt(c, n, zero);
|
||||
Z3_inc_ref(c, pred);
|
||||
// if n <_sigend 0 then r - s^sz else r
|
||||
Z3_ast args[2] = { r, bound };
|
||||
|
@ -140,19 +139,19 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
RETURN_Z3(res);
|
||||
}
|
||||
else {
|
||||
expr * _n = to_expr(n);
|
||||
parameter p(to_sort(int_s));
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_BV2INT, 1, &p, 1, &_n);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
expr * _n = to_expr(n);
|
||||
parameter p(to_sort(int_s));
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_BV2INT, 1, &p, 1, &_n);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Create a bit-vector of sort \s with 1 in the most significant bit position.
|
||||
|
||||
|
||||
The sort \s must be a bit-vector sort.
|
||||
|
||||
This function is a shorthand for <tt>shl(1, N-1)</tt>
|
||||
|
@ -343,7 +342,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
return Z3_mk_not(c, eq);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
// only for signed machine integers
|
||||
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2) {
|
||||
Z3_TRY;
|
||||
|
@ -369,7 +368,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
return result;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bvsub(Z3_context c, Z3_ast n1, Z3_ast n2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bvsub(c, n1, n2);
|
||||
|
@ -389,7 +388,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
unsigned Z3_API Z3_get_bv_sort_size(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_bv_sort_size(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_bv_fid() && to_sort(t)->get_decl_kind() == BV_SORT) {
|
||||
return to_sort(t)->get_parameter(0).get_int();
|
||||
|
@ -398,5 +397,5 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
return 0;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -290,8 +290,8 @@ extern "C" {
|
|||
r = to_fixedpoint_ref(d)->ctx().query(to_expr(q));
|
||||
}
|
||||
catch (z3_exception& ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
r = l_undef;
|
||||
mk_c(c)->handle_exception(ex);
|
||||
}
|
||||
to_fixedpoint_ref(d)->ctx().cleanup();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -24,16 +23,16 @@ Revision History:
|
|||
|
||||
extern "C" {
|
||||
|
||||
Z3_sort Z3_API Z3_mk_tuple_sort(Z3_context c,
|
||||
Z3_sort Z3_API Z3_mk_tuple_sort(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned num_fields,
|
||||
unsigned num_fields,
|
||||
Z3_symbol const field_names[],
|
||||
Z3_sort const field_sorts[],
|
||||
Z3_func_decl * mk_tuple_decl,
|
||||
Z3_func_decl proj_decls[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_tuple_sort(c, name, num_fields, field_names, field_sorts, mk_tuple_decl, proj_decls);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->reset_last_result();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
|
@ -43,14 +42,14 @@ extern "C" {
|
|||
std::string recognizer_s("is_");
|
||||
recognizer_s += to_symbol(name).str();
|
||||
symbol recognizer(recognizer_s.c_str());
|
||||
|
||||
|
||||
ptr_vector<accessor_decl> acc;
|
||||
for (unsigned i = 0; i < num_fields; ++i) {
|
||||
acc.push_back(mk_accessor_decl(to_symbol(field_names[i]), type_ref(to_sort(field_sorts[i]))));
|
||||
}
|
||||
|
||||
constructor_decl* constrs[1] = { mk_constructor_decl(to_symbol(name), recognizer, acc.size(), acc.c_ptr()) };
|
||||
|
||||
|
||||
{
|
||||
datatype_decl * dt = mk_datatype_decl(to_symbol(name), 1, constrs);
|
||||
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, tuples);
|
||||
|
@ -63,7 +62,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
// create tuple type
|
||||
SASSERT(tuples.size() == 1);
|
||||
SASSERT(tuples.size() == 1);
|
||||
tuple = tuples[0].get();
|
||||
mk_c(c)->save_multiple_ast_trail(tuple);
|
||||
|
||||
|
@ -72,9 +71,9 @@ extern "C" {
|
|||
SASSERT(!dt_util.is_recursive(tuple));
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple);
|
||||
func_decl* decl = (*decls)[0];
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
*mk_tuple_decl = of_func_decl(decl);
|
||||
|
||||
|
||||
// Create projections
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors(decl);
|
||||
if (!accs) {
|
||||
|
@ -90,8 +89,8 @@ extern "C" {
|
|||
RETURN_Z3_mk_tuple_sort(of_sort(tuple));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c,
|
||||
|
||||
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned n,
|
||||
Z3_symbol const enum_names[],
|
||||
|
@ -106,7 +105,7 @@ extern "C" {
|
|||
|
||||
sort_ref_vector sorts(m);
|
||||
sort* e;
|
||||
|
||||
|
||||
ptr_vector<constructor_decl> constrs;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
symbol e_name(to_symbol(enum_names[i]));
|
||||
|
@ -128,9 +127,9 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create enum type.
|
||||
SASSERT(sorts.size() == 1);
|
||||
SASSERT(sorts.size() == 1);
|
||||
e = sorts[0].get();
|
||||
mk_c(c)->save_multiple_ast_trail(e);
|
||||
|
||||
|
@ -141,10 +140,10 @@ extern "C" {
|
|||
SASSERT(decls && decls->size() == n);
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
func_decl* decl = (*decls)[i];
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
enum_consts[i] = of_func_decl(decl);
|
||||
decl = dt_util.get_constructor_recognizer(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
enum_testers[i] = of_func_decl(decl);
|
||||
}
|
||||
|
||||
|
@ -168,11 +167,11 @@ extern "C" {
|
|||
ast_manager& m = mk_c(c)->m();
|
||||
mk_c(c)->reset_last_result();
|
||||
datatype_util data_util(m);
|
||||
accessor_decl* head_tail[2] = {
|
||||
accessor_decl* head_tail[2] = {
|
||||
mk_accessor_decl(symbol("head"), type_ref(to_sort(elem_sort))),
|
||||
mk_accessor_decl(symbol("tail"), type_ref(0))
|
||||
};
|
||||
constructor_decl* constrs[2] = {
|
||||
constructor_decl* constrs[2] = {
|
||||
mk_constructor_decl(symbol("nil"), symbol("is_nil"), 0, 0),
|
||||
// Leo: SMT 2.0 document uses 'insert' instead of cons
|
||||
mk_constructor_decl(symbol("cons"), symbol("is_cons"), 2, head_tail)
|
||||
|
@ -197,22 +196,22 @@ extern "C" {
|
|||
func_decl* f;
|
||||
if (nil_decl) {
|
||||
f = cnstrs[0];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*nil_decl = of_func_decl(f);
|
||||
}
|
||||
if (is_nil_decl) {
|
||||
f = data_util.get_constructor_recognizer(cnstrs[0]);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*is_nil_decl = of_func_decl(f);
|
||||
}
|
||||
if (cons_decl) {
|
||||
f = cnstrs[1];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*cons_decl = of_func_decl(f);
|
||||
}
|
||||
if (is_cons_decl) {
|
||||
f = data_util.get_constructor_recognizer(cnstrs[1]);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*is_cons_decl = of_func_decl(f);
|
||||
}
|
||||
if (head_decl) {
|
||||
|
@ -220,7 +219,7 @@ extern "C" {
|
|||
SASSERT(acc);
|
||||
SASSERT(acc->size() == 2);
|
||||
f = (*acc)[0];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*head_decl = of_func_decl(f);
|
||||
}
|
||||
if (tail_decl) {
|
||||
|
@ -228,7 +227,7 @@ extern "C" {
|
|||
SASSERT(acc);
|
||||
SASSERT(acc->size() == 2);
|
||||
f = (*acc)[1];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*tail_decl = of_func_decl(f);
|
||||
}
|
||||
RETURN_Z3_mk_list_sort(of_sort(s));
|
||||
|
@ -255,7 +254,7 @@ extern "C" {
|
|||
) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_constructor(c, name, tester, num_fields, field_names, sorts, sort_refs);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
constructor* cnstr = alloc(constructor, m);
|
||||
cnstr->m_name = to_symbol(name);
|
||||
|
@ -291,7 +290,7 @@ extern "C" {
|
|||
if (!f) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (constructor_decl) {
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*constructor_decl = of_func_decl(f);
|
||||
|
@ -301,15 +300,15 @@ extern "C" {
|
|||
mk_c(c)->save_multiple_ast_trail(f2);
|
||||
*tester = of_func_decl(f2);
|
||||
}
|
||||
|
||||
|
||||
ptr_vector<func_decl> const* accs = data_util.get_constructor_accessors(f);
|
||||
if (!accs && num_fields > 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
for (unsigned i = 0; i < num_fields; ++i) {
|
||||
func_decl* f2 = (*accs)[i];
|
||||
mk_c(c)->save_multiple_ast_trail(f2);
|
||||
mk_c(c)->save_multiple_ast_trail(f2);
|
||||
accessors[i] = of_func_decl(f2);
|
||||
}
|
||||
RETURN_Z3_query_constructor;
|
||||
|
@ -324,7 +323,7 @@ extern "C" {
|
|||
Z3_CATCH;
|
||||
}
|
||||
|
||||
static datatype_decl* mk_datatype_decl(Z3_context c,
|
||||
static datatype_decl* mk_datatype_decl(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned num_constructors,
|
||||
Z3_constructor constructors[]) {
|
||||
|
@ -342,7 +341,7 @@ extern "C" {
|
|||
}
|
||||
constrs.push_back(mk_constructor_decl(cn->m_name, cn->m_tester, acc.size(), acc.c_ptr()));
|
||||
}
|
||||
return mk_datatype_decl(to_symbol(name), num_constructors, constrs.c_ptr());
|
||||
return mk_datatype_decl(to_symbol(name), num_constructors, constrs.c_ptr());
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_datatype(Z3_context c,
|
||||
|
@ -352,9 +351,9 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_datatype(c, name, num_constructors, constructors);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
datatype_util data_util(m);
|
||||
|
||||
|
||||
sort_ref_vector sorts(m);
|
||||
{
|
||||
datatype_decl * data = mk_datatype_decl(c, name, num_constructors, constructors);
|
||||
|
@ -370,7 +369,7 @@ extern "C" {
|
|||
|
||||
mk_c(c)->save_ast_trail(s);
|
||||
ptr_vector<func_decl> const* cnstrs = data_util.get_datatype_constructors(s);
|
||||
|
||||
|
||||
for (unsigned i = 0; i < num_constructors; ++i) {
|
||||
constructor* cn = reinterpret_cast<constructor*>(constructors[i]);
|
||||
cn->m_constructor = (*cnstrs)[i];
|
||||
|
@ -411,7 +410,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_datatypes(c, num_sorts, sort_names, sorts, constructor_lists);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
mk_c(c)->reset_last_result();
|
||||
datatype_util data_util(m);
|
||||
|
||||
|
@ -423,7 +422,7 @@ extern "C" {
|
|||
sort_ref_vector _sorts(m);
|
||||
bool ok = mk_c(c)->get_dt_plugin()->mk_datatypes(datas.size(), datas.c_ptr(), _sorts);
|
||||
del_datatype_decls(datas.size(), datas.c_ptr());
|
||||
|
||||
|
||||
if (!ok) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
|
@ -437,8 +436,8 @@ extern "C" {
|
|||
constructor_list* cl = reinterpret_cast<constructor_list*>(constructor_lists[i]);
|
||||
ptr_vector<func_decl> const* cnstrs = data_util.get_datatype_constructors(s);
|
||||
for (unsigned j = 0; j < cl->size(); ++j) {
|
||||
constructor* cn = (*cl)[j];
|
||||
cn->m_constructor = (*cnstrs)[j];
|
||||
constructor* cn = (*cl)[j];
|
||||
cn->m_constructor = (*cnstrs)[j];
|
||||
}
|
||||
}
|
||||
RETURN_Z3_mk_datatypes;
|
||||
|
@ -452,15 +451,15 @@ extern "C" {
|
|||
CHECK_VALID_AST(t, 0);
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (!decls) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
return decls->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
|
@ -468,7 +467,7 @@ extern "C" {
|
|||
|
||||
Z3_func_decl get_datatype_sort_constructor_core(Z3_context c, Z3_sort t, unsigned idx) {
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
|
@ -497,10 +496,10 @@ extern "C" {
|
|||
Z3_func_decl Z3_API Z3_get_datatype_sort_recognizer(Z3_context c, Z3_sort t, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_datatype_sort_recognizer(c, t, idx);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
|
@ -520,13 +519,13 @@ extern "C" {
|
|||
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(Z3_context c, Z3_sort t, unsigned idx_c, unsigned idx_a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_datatype_sort_constructor_accessor(c, t, idx_c, idx_a);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (!decls || idx_c >= decls->size()) {
|
||||
|
@ -536,24 +535,24 @@ extern "C" {
|
|||
func_decl* decl = (*decls)[idx_c];
|
||||
if (decl->get_arity() <= idx_a) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors(decl);
|
||||
SASSERT(accs && accs->size() == decl->get_arity());
|
||||
if (!accs || accs->size() <= idx_a) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
decl = (*accs)[idx_a];
|
||||
mk_c(c)->save_ast_trail(decl);
|
||||
RETURN_Z3(of_func_decl(decl));
|
||||
RETURN_Z3(of_func_decl(decl));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_tuple_sort_mk_decl(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_mk_decl(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
|
@ -564,34 +563,34 @@ extern "C" {
|
|||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
unsigned Z3_API Z3_get_tuple_sort_num_fields(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_num_fields(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple);
|
||||
if (!decls || decls->size() != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors((*decls)[0]);
|
||||
if (!accs) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
return accs->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_tuple_sort_field_decl(Z3_context c, Z3_sort t, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_field_decl(c, t, i);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
|
@ -619,14 +618,14 @@ extern "C" {
|
|||
}
|
||||
|
||||
Z3_ast Z3_datatype_update_field(
|
||||
Z3_context c, Z3_func_decl f, Z3_ast t, Z3_ast v) {
|
||||
Z3_context c, Z3_func_decl f, Z3_ast t, Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_datatype_update_field(c, f, t, v);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
func_decl* _f = to_func_decl(f);
|
||||
expr* _t = to_expr(t);
|
||||
expr* _v = to_expr(v);
|
||||
expr* _v = to_expr(v);
|
||||
expr* args[2] = { _t, _v };
|
||||
sort* domain[2] = { m.get_sort(_t), m.get_sort(_v) };
|
||||
parameter param(_f);
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include<sstream>
|
||||
#include<vector>
|
||||
#include"z3.h"
|
||||
|
@ -375,7 +374,7 @@ extern "C" {
|
|||
for(int i = 0; i < num_theory; i++)
|
||||
fmlas[i] = Z3_mk_implies(ctx,Z3_mk_true(ctx),fmlas[i]);
|
||||
std::copy(cnsts,cnsts+num,fmlas.begin()+num_theory);
|
||||
Z3_string smt = Z3_benchmark_to_smtlib_string(ctx,"none","AUFLIA","unknown","",num_fmlas-1,&fmlas[0],fmlas[num_fmlas-1]);
|
||||
Z3_string smt = Z3_benchmark_to_smtlib_string(ctx,"none","AUFLIA","unknown","",num_fmlas-1,&fmlas[0],fmlas[num_fmlas-1]);
|
||||
std::ofstream f(filename);
|
||||
if(num_theory)
|
||||
f << ";! THEORY=" << num_theory << "\n";
|
||||
|
@ -469,7 +468,7 @@ extern "C" {
|
|||
}
|
||||
f.close();
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
|
||||
|
||||
if(!parents){
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -23,8 +22,8 @@ Revision History:
|
|||
#include"pb_decl_plugin.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], unsigned k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_atmost(c, num_args, args, k);
|
||||
|
@ -38,8 +37,21 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atleast(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], unsigned k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_atmost(c, num_args, args, k);
|
||||
RESET_ERROR_CODE();
|
||||
parameter param(k);
|
||||
pb_util util(mk_c(c)->m());
|
||||
ast* a = util.mk_at_least_k(num_args, to_exprs(args), k);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
|
||||
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int _coeffs[],
|
||||
int k) {
|
||||
Z3_TRY;
|
||||
|
@ -57,7 +69,25 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pbeq(Z3_context c, unsigned num_args,
|
||||
Z3_ast Z3_API Z3_mk_pbge(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int _coeffs[],
|
||||
int k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_pble(c, num_args, args, _coeffs, k);
|
||||
RESET_ERROR_CODE();
|
||||
pb_util util(mk_c(c)->m());
|
||||
vector<rational> coeffs;
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
coeffs.push_back(rational(_coeffs[i]));
|
||||
}
|
||||
ast* a = util.mk_ge(num_args, coeffs.c_ptr(), to_exprs(args), rational(k));
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pbeq(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int _coeffs[],
|
||||
int k) {
|
||||
Z3_TRY;
|
||||
|
|
|
@ -14,9 +14,8 @@ Author:
|
|||
Leonardo de Moura (leonardo) 2012-12-08
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -35,7 +34,7 @@ namespace api {
|
|||
|
||||
pmanager::~pmanager() {
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -26,17 +25,17 @@ Revision History:
|
|||
extern "C" {
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body)
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body)
|
||||
{
|
||||
return Z3_mk_quantifier_ex(
|
||||
c,
|
||||
is_forall,
|
||||
c,
|
||||
is_forall,
|
||||
weight,
|
||||
0,
|
||||
0,
|
||||
|
@ -50,15 +49,15 @@ extern "C" {
|
|||
}
|
||||
|
||||
Z3_ast mk_quantifier_ex_core(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
Z3_symbol skolem_id,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
|
@ -86,9 +85,9 @@ extern "C" {
|
|||
expr_ref result(mk_c(c)->m());
|
||||
if (num_decls > 0) {
|
||||
result = mk_c(c)->m().mk_quantifier(
|
||||
(0 != is_forall),
|
||||
names.size(), ts, names.c_ptr(), to_expr(body),
|
||||
weight,
|
||||
(0 != is_forall),
|
||||
names.size(), ts, names.c_ptr(), to_expr(body),
|
||||
weight,
|
||||
to_symbol(quantifier_id),
|
||||
to_symbol(skolem_id),
|
||||
num_patterns, ps,
|
||||
|
@ -104,44 +103,44 @@ extern "C" {
|
|||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_ex(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
Z3_symbol skolem_id,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body)
|
||||
{
|
||||
LOG_Z3_mk_quantifier_ex(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
LOG_Z3_mk_quantifier_ex(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
num_no_patterns, no_patterns, num_decls, sorts, decl_names, body);
|
||||
Z3_ast r = mk_quantifier_ex_core(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
Z3_ast r = mk_quantifier_ex_core(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
num_no_patterns, no_patterns, num_decls, sorts, decl_names, body);
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_forall(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
|
||||
Z3_ast Z3_API Z3_mk_forall(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier(c, 1, weight, num_patterns, patterns, num_decls, types, decl_names, body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_exists(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
|
||||
Z3_ast Z3_API Z3_mk_exists(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier(c, 0, weight, num_patterns, patterns, num_decls, types, decl_names, body);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c,
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
|
@ -166,7 +165,7 @@ extern "C" {
|
|||
}
|
||||
if (num_bound == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
RETURN_Z3(0);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
for (unsigned i = 0; i < num_bound; ++i) {
|
||||
app* a = to_app(bound[i]);
|
||||
|
@ -191,7 +190,7 @@ extern "C" {
|
|||
app* pat = to_pattern(patterns[i]);
|
||||
SASSERT(mk_c(c)->m().is_pattern(pat));
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
pinned.push_back(result.get());
|
||||
SASSERT(mk_c(c)->m().is_pattern(result.get()));
|
||||
_patterns.push_back(of_pattern(result.get()));
|
||||
|
@ -205,25 +204,25 @@ extern "C" {
|
|||
}
|
||||
app* pat = to_app(to_expr(no_patterns[i]));
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
pinned.push_back(result.get());
|
||||
_no_patterns.push_back(of_ast(result.get()));
|
||||
}
|
||||
expr_ref abs_body(mk_c(c)->m());
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), to_expr(body), abs_body);
|
||||
|
||||
Z3_ast result = mk_quantifier_ex_core(c, is_forall, weight,
|
||||
Z3_ast result = mk_quantifier_ex_core(c, is_forall, weight,
|
||||
quantifier_id,
|
||||
skolem_id,
|
||||
num_patterns, _patterns.c_ptr(),
|
||||
num_patterns, _patterns.c_ptr(),
|
||||
num_no_patterns, _no_patterns.c_ptr(),
|
||||
names.size(), types.c_ptr(), names.c_ptr(),
|
||||
names.size(), types.c_ptr(), names.c_ptr(),
|
||||
of_ast(abs_body.get()));
|
||||
RETURN_Z3(result);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const(Z3_context c,
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const(Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
|
@ -231,14 +230,14 @@ extern "C" {
|
|||
unsigned num_patterns,
|
||||
Z3_pattern const patterns[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier_const_ex(c, is_forall, weight, 0, 0,
|
||||
num_bound, bound,
|
||||
return Z3_mk_quantifier_const_ex(c, is_forall, weight, 0, 0,
|
||||
num_bound, bound,
|
||||
num_patterns, patterns,
|
||||
0, 0,
|
||||
body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_forall_const(Z3_context c,
|
||||
Z3_ast Z3_API Z3_mk_forall_const(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
Z3_app const bound[],
|
||||
|
@ -248,7 +247,7 @@ extern "C" {
|
|||
return Z3_mk_quantifier_const(c, true, weight, num_bound, bound, num_patterns, patterns, body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_exists_const(Z3_context c,
|
||||
Z3_ast Z3_API Z3_mk_exists_const(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
Z3_app const bound[],
|
||||
|
@ -257,7 +256,7 @@ extern "C" {
|
|||
Z3_ast body) {
|
||||
return Z3_mk_quantifier_const(c, false, weight, num_bound, bound, num_patterns, patterns, body);
|
||||
}
|
||||
|
||||
|
||||
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_pattern(c, num_patterns, terms);
|
||||
|
@ -273,7 +272,7 @@ extern "C" {
|
|||
RETURN_Z3(of_pattern(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bound(Z3_context c, unsigned index, Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bound(c, index, ty);
|
||||
|
@ -436,7 +435,7 @@ extern "C" {
|
|||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -450,7 +449,7 @@ extern "C" {
|
|||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -471,13 +470,13 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_pattern_to_ast(Z3_context c, Z3_pattern p) {
|
||||
Z3_ast Z3_API Z3_pattern_to_ast(Z3_context c, Z3_pattern p) {
|
||||
RESET_ERROR_CODE();
|
||||
return (Z3_ast)(p);
|
||||
}
|
||||
return (Z3_ast)(p);
|
||||
}
|
||||
|
||||
Z3_API char const * Z3_pattern_to_string(Z3_context c, Z3_pattern p) {
|
||||
return Z3_ast_to_string(c, reinterpret_cast<Z3_ast>(p));
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -16,7 +16,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -28,7 +27,7 @@ extern "C" {
|
|||
Z3_sort Z3_API Z3_mk_seq_sort(Z3_context c, Z3_sort domain) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_seq_sort(c, domain);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * ty = mk_c(c)->sutil().str.mk_seq(to_sort(domain));
|
||||
mk_c(c)->save_ast_trail(ty);
|
||||
RETURN_Z3(of_sort(ty));
|
||||
|
@ -38,7 +37,7 @@ extern "C" {
|
|||
Z3_sort Z3_API Z3_mk_re_sort(Z3_context c, Z3_sort domain) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_re_sort(c, domain);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * ty = mk_c(c)->sutil().re.mk_re(to_sort(domain));
|
||||
mk_c(c)->save_ast_trail(ty);
|
||||
RETURN_Z3(of_sort(ty));
|
||||
|
@ -48,14 +47,14 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_mk_string(Z3_context c, Z3_string str) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_string(c, str);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
zstring s(str, zstring::ascii);
|
||||
app* a = mk_c(c)->sutil().str.mk_string(s);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_sort Z3_API Z3_mk_string_sort(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_string_sort(c);
|
||||
|
@ -71,8 +70,8 @@ extern "C" {
|
|||
LOG_Z3_is_seq_sort(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
bool result = mk_c(c)->sutil().is_seq(to_sort(s));
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_re_sort(Z3_context c, Z3_sort s) {
|
||||
|
@ -80,8 +79,8 @@ extern "C" {
|
|||
LOG_Z3_is_re_sort(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
bool result = mk_c(c)->sutil().is_re(to_sort(s));
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_string_sort(Z3_context c, Z3_sort s) {
|
||||
|
@ -89,8 +88,8 @@ extern "C" {
|
|||
LOG_Z3_is_string_sort(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
bool result = mk_c(c)->sutil().is_string(to_sort(s));
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_string(Z3_context c, Z3_ast s) {
|
||||
|
@ -98,7 +97,7 @@ extern "C" {
|
|||
LOG_Z3_is_string(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
bool result = mk_c(c)->sutil().str.is_string(to_expr(s));
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
|
@ -125,7 +124,7 @@ extern "C" {
|
|||
mk_c(c)->save_ast_trail(a); \
|
||||
RETURN_Z3(of_ast(a)); \
|
||||
Z3_CATCH_RETURN(0); \
|
||||
}
|
||||
}
|
||||
|
||||
MK_SORTED(Z3_mk_seq_empty, mk_c(c)->sutil().str.mk_empty);
|
||||
|
||||
|
@ -143,13 +142,13 @@ extern "C" {
|
|||
MK_BINARY(Z3_mk_seq_in_re, mk_c(c)->get_seq_fid(), OP_SEQ_IN_RE, SKIP);
|
||||
|
||||
Z3_ast Z3_API Z3_mk_re_loop(Z3_context c, Z3_ast r, unsigned lo, unsigned hi) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_re_loop(c, r, lo, hi);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_re_loop(c, r, lo, hi);
|
||||
RESET_ERROR_CODE();
|
||||
app* a = hi == 0 ? mk_c(c)->sutil().re.mk_loop(to_expr(r), lo) : mk_c(c)->sutil().re.mk_loop(to_expr(r), lo, hi);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
MK_UNARY(Z3_mk_re_plus, mk_c(c)->get_seq_fid(), OP_RE_PLUS, SKIP);
|
||||
|
|
|
@ -132,16 +132,19 @@ namespace z3 {
|
|||
\brief A Context manages all other Z3 objects, global configuration options, etc.
|
||||
*/
|
||||
class context {
|
||||
bool m_enable_exceptions;
|
||||
Z3_context m_ctx;
|
||||
static void error_handler(Z3_context /*c*/, Z3_error_code /*e*/) { /* do nothing */ }
|
||||
void init(config & c) {
|
||||
m_ctx = Z3_mk_context_rc(c);
|
||||
m_enable_exceptions = true;
|
||||
Z3_set_error_handler(m_ctx, error_handler);
|
||||
Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT);
|
||||
}
|
||||
|
||||
void init_interp(config & c) {
|
||||
m_ctx = Z3_mk_interpolation_context(c);
|
||||
m_enable_exceptions = true;
|
||||
Z3_set_error_handler(m_ctx, error_handler);
|
||||
Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT);
|
||||
}
|
||||
|
@ -159,12 +162,24 @@ namespace z3 {
|
|||
/**
|
||||
\brief Auxiliary method used to check for API usage errors.
|
||||
*/
|
||||
void check_error() const {
|
||||
Z3_error_code check_error() const {
|
||||
Z3_error_code e = Z3_get_error_code(m_ctx);
|
||||
if (e != Z3_OK)
|
||||
if (e != Z3_OK && enable_exceptions())
|
||||
throw exception(Z3_get_error_msg(m_ctx, e));
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief The C++ API uses by defaults exceptions on errors.
|
||||
For applications that don't work well with exceptions (there should be only few)
|
||||
you have the ability to turn off exceptions. The tradeoffs are that applications
|
||||
have to very careful about using check_error() after calls that may result in an errornous
|
||||
state.
|
||||
*/
|
||||
void set_enable_exceptions(bool f) { m_enable_exceptions = f; }
|
||||
|
||||
bool enable_exceptions() const { return m_enable_exceptions; }
|
||||
|
||||
/**
|
||||
\brief Update global parameter \c param with string \c value.
|
||||
*/
|
||||
|
@ -330,7 +345,7 @@ namespace z3 {
|
|||
object(context & c):m_ctx(&c) {}
|
||||
object(object const & s):m_ctx(s.m_ctx) {}
|
||||
context & ctx() const { return *m_ctx; }
|
||||
void check_error() const { m_ctx->check_error(); }
|
||||
Z3_error_code check_error() const { return m_ctx->check_error(); }
|
||||
friend void check_context(object const & a, object const & b);
|
||||
};
|
||||
inline void check_context(object const & a, object const & b) { assert(a.m_ctx == b.m_ctx); }
|
||||
|
@ -672,12 +687,18 @@ namespace z3 {
|
|||
/**
|
||||
\brief Return int value of numeral, throw if result cannot fit in
|
||||
machine int
|
||||
|
||||
It only makes sense to use this function if the caller can ensure that
|
||||
the result is an integer or if exceptions are enabled.
|
||||
If exceptions are disabled, then use the the is_numeral_i function.
|
||||
|
||||
\pre is_numeral()
|
||||
*/
|
||||
int get_numeral_int() const {
|
||||
int result;
|
||||
int result = 0;
|
||||
if (!is_numeral_i(result)) {
|
||||
assert(ctx().enable_exceptions());
|
||||
if (!ctx().enable_exceptions()) return 0;
|
||||
throw exception("numeral does not fit in machine int");
|
||||
}
|
||||
return result;
|
||||
|
@ -686,13 +707,18 @@ namespace z3 {
|
|||
/**
|
||||
\brief Return uint value of numeral, throw if result cannot fit in
|
||||
machine uint
|
||||
|
||||
|
||||
It only makes sense to use this function if the caller can ensure that
|
||||
the result is an integer or if exceptions are enabled.
|
||||
If exceptions are disabled, then use the the is_numeral_u function.
|
||||
\pre is_numeral()
|
||||
*/
|
||||
unsigned get_numeral_uint() const {
|
||||
assert(is_numeral());
|
||||
unsigned result;
|
||||
unsigned result = 0;
|
||||
if (!is_numeral_u(result)) {
|
||||
assert(ctx().enable_exceptions());
|
||||
if (!ctx().enable_exceptions()) return 0;
|
||||
throw exception("numeral does not fit in machine uint");
|
||||
}
|
||||
return result;
|
||||
|
@ -706,8 +732,10 @@ namespace z3 {
|
|||
*/
|
||||
__int64 get_numeral_int64() const {
|
||||
assert(is_numeral());
|
||||
__int64 result;
|
||||
__int64 result = 0;
|
||||
if (!is_numeral_i64(result)) {
|
||||
assert(ctx().enable_exceptions());
|
||||
if (!ctx().enable_exceptions()) return 0;
|
||||
throw exception("numeral does not fit in machine __int64");
|
||||
}
|
||||
return result;
|
||||
|
@ -721,8 +749,10 @@ namespace z3 {
|
|||
*/
|
||||
__uint64 get_numeral_uint64() const {
|
||||
assert(is_numeral());
|
||||
__uint64 result;
|
||||
__uint64 result = 0;
|
||||
if (!is_numeral_u64(result)) {
|
||||
assert(ctx().enable_exceptions());
|
||||
if (!ctx().enable_exceptions()) return 0;
|
||||
throw exception("numeral does not fit in machine __uint64");
|
||||
}
|
||||
return result;
|
||||
|
@ -1615,7 +1645,7 @@ namespace z3 {
|
|||
Z3_ast r = 0;
|
||||
Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r);
|
||||
check_error();
|
||||
if (status == Z3_FALSE)
|
||||
if (status == Z3_FALSE && ctx().enable_exceptions())
|
||||
throw exception("failed to evaluate expression");
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
|
|
|
@ -2692,6 +2692,18 @@ namespace Microsoft.Z3
|
|||
AST.ArrayToNative(args), k));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an at-least-k constraint.
|
||||
/// </summary>
|
||||
public BoolExpr MkAtLeast(BoolExpr[] args, uint k)
|
||||
{
|
||||
Contract.Requires(args != null);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch<BoolExpr>(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_atleast(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args), k));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a pseudo-Boolean less-or-equal constraint.
|
||||
/// </summary>
|
||||
|
@ -2707,6 +2719,20 @@ namespace Microsoft.Z3
|
|||
coeffs, k));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a pseudo-Boolean greater-or-equal constraint.
|
||||
/// </summary>
|
||||
public BoolExpr MkPBGe(int[] coeffs, BoolExpr[] args, int k)
|
||||
{
|
||||
Contract.Requires(args != null);
|
||||
Contract.Requires(coeffs != null);
|
||||
Contract.Requires(args.Length == coeffs.Length);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch<BoolExpr>(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_pbge(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args),
|
||||
coeffs, k));
|
||||
}
|
||||
/// <summary>
|
||||
/// Create a pseudo-Boolean equal constraint.
|
||||
/// </summary>
|
||||
|
|
|
@ -18,6 +18,7 @@ Notes:
|
|||
--*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
|
@ -126,6 +127,14 @@ namespace Microsoft.Z3
|
|||
Assert(constraints);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alias for Assert.
|
||||
/// </summary>
|
||||
public void Add(IEnumerable<BoolExpr> constraints)
|
||||
{
|
||||
Assert(constraints.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert multiple constraints into the solver, and track them (in the unsat) core
|
||||
/// using the Boolean constants in ps.
|
||||
|
|
|
@ -44,15 +44,21 @@ namespace System.Diagnostics.Contracts
|
|||
|
||||
public static class Contract
|
||||
{
|
||||
[Conditional("false")]
|
||||
public static void Ensures(bool b) { }
|
||||
[Conditional("false")]
|
||||
public static void Requires(bool b) { }
|
||||
[Conditional("false")]
|
||||
public static void Assume(bool b, string msg) { }
|
||||
[Conditional("false")]
|
||||
public static void Assert(bool b) { }
|
||||
public static bool ForAll(bool b) { return true; }
|
||||
public static bool ForAll(Object c, Func<Object, bool> p) { return true; }
|
||||
public static bool ForAll(int from, int to, Predicate<int> p) { return true; }
|
||||
[Conditional("false")]
|
||||
public static void Invariant(bool b) { }
|
||||
public static T[] Result<T>() { return new T[1]; }
|
||||
[Conditional("false")]
|
||||
public static void EndContractBlock() { }
|
||||
public static T ValueAtReturn<T>(out T v) { T[] t = new T[1]; v = t[0]; return v; }
|
||||
}
|
||||
|
|
6
src/api/dotnet/dotnet35/Example/App.config
Normal file
6
src/api/dotnet/dotnet35/Example/App.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
78
src/api/dotnet/dotnet35/Example/Example.csproj
Normal file
78
src/api/dotnet/dotnet35/Example/Example.csproj
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Example</RootNamespace>
|
||||
<AssemblyName>Example</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;FRAMEWORK_LT_4</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;FRAMEWORK_LT_4</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;FRAMEWORK_LT_4</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;FRAMEWORK_LT_4</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\..\..\examples\dotnet\Program.cs">
|
||||
<Link>Program.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Z3.NET35.csproj">
|
||||
<Project>{ec3db697-b734-42f7-9468-5b62821eeb5a}</Project>
|
||||
<Name>Microsoft.Z3.NET35</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
36
src/api/dotnet/dotnet35/Example/Properties/AssemblyInfo.cs
Normal file
36
src/api/dotnet/dotnet35/Example/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Example")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Example")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("2a8e577b-7b6d-4ca9-832a-ca2eec314812")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
347
src/api/dotnet/dotnet35/Microsoft.Z3.NET35.csproj
Normal file
347
src/api/dotnet/dotnet35/Microsoft.Z3.NET35.csproj
Normal file
|
@ -0,0 +1,347 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{EC3DB697-B734-42F7-9468-5B62821EEB5A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.Z3</RootNamespace>
|
||||
<AssemblyName>Microsoft.Z3</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;FRAMEWORK_LT_4</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>Debug\Microsoft.Z3.XML</DocumentationFile>
|
||||
<CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
|
||||
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
|
||||
<CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
|
||||
<CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
|
||||
<CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
|
||||
<CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
|
||||
<CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
|
||||
<CodeContractsBoundsObligations>True</CodeContractsBoundsObligations>
|
||||
<CodeContractsArithmeticObligations>True</CodeContractsArithmeticObligations>
|
||||
<CodeContractsEnumObligations>False</CodeContractsEnumObligations>
|
||||
<CodeContractsPointerObligations>False</CodeContractsPointerObligations>
|
||||
<CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
|
||||
<CodeContractsInferRequires>True</CodeContractsInferRequires>
|
||||
<CodeContractsInferEnsures>False</CodeContractsInferEnsures>
|
||||
<CodeContractsInferObjectInvariants>False</CodeContractsInferObjectInvariants>
|
||||
<CodeContractsSuggestAssumptions>False</CodeContractsSuggestAssumptions>
|
||||
<CodeContractsSuggestRequires>True</CodeContractsSuggestRequires>
|
||||
<CodeContractsSuggestEnsures>False</CodeContractsSuggestEnsures>
|
||||
<CodeContractsSuggestObjectInvariants>False</CodeContractsSuggestObjectInvariants>
|
||||
<CodeContractsDisjunctiveRequires>True</CodeContractsDisjunctiveRequires>
|
||||
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
|
||||
<CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
|
||||
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
|
||||
<CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
|
||||
<CodeContractsCustomRewriterAssembly />
|
||||
<CodeContractsCustomRewriterClass />
|
||||
<CodeContractsLibPaths />
|
||||
<CodeContractsExtraRewriteOptions />
|
||||
<CodeContractsExtraAnalysisOptions />
|
||||
<CodeContractsBaseLineFile />
|
||||
<CodeContractsCacheAnalysisResults>True</CodeContractsCacheAnalysisResults>
|
||||
<CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
|
||||
<CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
|
||||
<CodeContractsAnalysisWarningLevel>2</CodeContractsAnalysisWarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>Release\</OutputPath>
|
||||
<DefineConstants>FRAMEWORK_LT_4</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>Release\Microsoft.Z3.xml</DocumentationFile>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<DelaySign>false</DelaySign>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;FRAMEWORK_LT_4</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>Debug\Microsoft.Z3.XML</DocumentationFile>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>FRAMEWORK_LT_4</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>Release\Microsoft.Z3.xml</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Code.Contract.1.0.0\lib\net35\Microsoft.Contracts.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\AlgebraicNum.cs">
|
||||
<Link>AlgebraicNum.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ApplyResult.cs">
|
||||
<Link>ApplyResult.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ArithExpr.cs">
|
||||
<Link>ArithExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ArithSort.cs">
|
||||
<Link>ArithSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ArrayExpr.cs">
|
||||
<Link>ArrayExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ArraySort.cs">
|
||||
<Link>ArraySort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\AST.cs">
|
||||
<Link>AST.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ASTMap.cs">
|
||||
<Link>ASTMap.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ASTVector.cs">
|
||||
<Link>ASTVector.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\BitVecExpr.cs">
|
||||
<Link>BitVecExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\BitVecNum.cs">
|
||||
<Link>BitVecNum.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\BitVecSort.cs">
|
||||
<Link>BitVecSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\BoolExpr.cs">
|
||||
<Link>BoolExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\BoolSort.cs">
|
||||
<Link>BoolSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Constructor.cs">
|
||||
<Link>Constructor.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ConstructorList.cs">
|
||||
<Link>ConstructorList.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Context.cs">
|
||||
<Link>Context.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DatatypeExpr.cs">
|
||||
<Link>DatatypeExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DatatypeSort.cs">
|
||||
<Link>DatatypeSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Deprecated.cs">
|
||||
<Link>Deprecated.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Enumerations.cs">
|
||||
<Link>Enumerations.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\EnumSort.cs">
|
||||
<Link>EnumSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Expr.cs">
|
||||
<Link>Expr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FiniteDomainExpr.cs">
|
||||
<Link>FiniteDomainExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FiniteDomainNum.cs">
|
||||
<Link>FiniteDomainNum.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FiniteDomainSort.cs">
|
||||
<Link>FiniteDomainSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Fixedpoint.cs">
|
||||
<Link>Fixedpoint.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FPExpr.cs">
|
||||
<Link>FPExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FPNum.cs">
|
||||
<Link>FPNum.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FPRMExpr.cs">
|
||||
<Link>FPRMExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FPRMNum.cs">
|
||||
<Link>FPRMNum.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FPRMSort.cs">
|
||||
<Link>FPRMSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FPSort.cs">
|
||||
<Link>FPSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FuncDecl.cs">
|
||||
<Link>FuncDecl.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FuncInterp.cs">
|
||||
<Link>FuncInterp.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Global.cs">
|
||||
<Link>Global.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Goal.cs">
|
||||
<Link>Goal.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\IDecRefQueue.cs">
|
||||
<Link>IDecRefQueue.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\InterpolationContext.cs">
|
||||
<Link>InterpolationContext.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\IntExpr.cs">
|
||||
<Link>IntExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\IntNum.cs">
|
||||
<Link>IntNum.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\IntSort.cs">
|
||||
<Link>IntSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\IntSymbol.cs">
|
||||
<Link>IntSymbol.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ListSort.cs">
|
||||
<Link>ListSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Log.cs">
|
||||
<Link>Log.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Model.cs">
|
||||
<Link>Model.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Native.cs">
|
||||
<Link>Native.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Optimize.cs">
|
||||
<Link>Optimize.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ParamDescrs.cs">
|
||||
<Link>ParamDescrs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Params.cs">
|
||||
<Link>Params.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Pattern.cs">
|
||||
<Link>Pattern.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Probe.cs">
|
||||
<Link>Probe.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Quantifier.cs">
|
||||
<Link>Quantifier.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\RatNum.cs">
|
||||
<Link>RatNum.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\RealExpr.cs">
|
||||
<Link>RealExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\RealSort.cs">
|
||||
<Link>RealSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ReExpr.cs">
|
||||
<Link>ReExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\RelationSort.cs">
|
||||
<Link>RelationSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ReSort.cs">
|
||||
<Link>ReSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\SeqExpr.cs">
|
||||
<Link>SeqExpr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\SeqSort.cs">
|
||||
<Link>SeqSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\SetSort.cs">
|
||||
<Link>SetSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Solver.cs">
|
||||
<Link>Solver.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Sort.cs">
|
||||
<Link>Sort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Statistics.cs">
|
||||
<Link>Statistics.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Status.cs">
|
||||
<Link>Status.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\StringSymbol.cs">
|
||||
<Link>StringSymbol.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Symbol.cs">
|
||||
<Link>Symbol.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tactic.cs">
|
||||
<Link>Tactic.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\TupleSort.cs">
|
||||
<Link>TupleSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\UninterpretedSort.cs">
|
||||
<Link>UninterpretedSort.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Version.cs">
|
||||
<Link>Version.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Z3Exception.cs">
|
||||
<Link>Z3Exception.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Z3Object.cs">
|
||||
<Link>Z3Object.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WCFMetadata Include="Service References\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
48
src/api/dotnet/dotnet35/Microsoft.Z3.NET35.sln
Normal file
48
src/api/dotnet/dotnet35/Microsoft.Z3.NET35.sln
Normal file
|
@ -0,0 +1,48 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Z3.NET35", "Microsoft.Z3.NET35.csproj", "{EC3DB697-B734-42F7-9468-5B62821EEB5A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example", "Example\Example.csproj", "{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x64.ActiveCfg = Release|x64
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x64.Build.0 = Release|x64
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x86.Build.0 = Release|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x64.ActiveCfg = Release|x64
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x64.Build.0 = Release|x64
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
38
src/api/dotnet/dotnet35/Properties/AssemblyInfo.cs
Normal file
38
src/api/dotnet/dotnet35/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Z3 .NET Interface")]
|
||||
[assembly: AssemblyDescription(".NET Interface to the Z3 Theorem Prover")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("Z3")]
|
||||
[assembly: AssemblyCopyright("Copyright (C) 2006-2015 Microsoft Corporation")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4853ed71-2078-40f4-8117-bc46646bce0e")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("4.2.0.0")]
|
||||
[assembly: AssemblyVersion("4.5.1.6031")]
|
||||
[assembly: AssemblyFileVersion("4.5.1.6031")]
|
38
src/api/dotnet/dotnet35/Properties/AssemblyInfo.cs.in
Normal file
38
src/api/dotnet/dotnet35/Properties/AssemblyInfo.cs.in
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Z3 .NET Interface")]
|
||||
[assembly: AssemblyDescription(".NET Interface to the Z3 Theorem Prover")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("Z3")]
|
||||
[assembly: AssemblyCopyright("Copyright (C) 2006-2015 Microsoft Corporation")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4853ed71-2078-40f4-8117-bc46646bce0e")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("4.2.0.0")]
|
||||
[assembly: AssemblyVersion("@VER_MAJOR@.@VER_MINOR@.@VER_BUILD@.@VER_REVISION@")]
|
||||
[assembly: AssemblyFileVersion("@VER_MAJOR@.@VER_MINOR@.@VER_BUILD@.@VER_REVISION@")]
|
|
@ -6,4 +6,5 @@ In the project properties of Microsoft.Z3.csproj:
|
|||
- Under 'Application': Change Target framework to .NET Framework 3.5
|
||||
- Under 'Build': Add FRAMEWORK_LT_4 to the condidional compilation symbols
|
||||
- Remove the reference to System.Numerics
|
||||
- Install the NuGet Package "Microsoft Code Contracts for Net3.5"
|
||||
- Install the NuGet Package "Microsoft Code Contracts for Net3.5":
|
||||
In the Package Manager Console enter Install-Package Code.Contract
|
4
src/api/dotnet/dotnet35/packages.config
Normal file
4
src/api/dotnet/dotnet35/packages.config
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Code.Contract" version="1.0.0" targetFramework="net35" />
|
||||
</packages>
|
|
@ -7648,11 +7648,6 @@ def AtLeast(*args):
|
|||
>>> a, b, c = Bools('a b c')
|
||||
>>> f = AtLeast(a, b, c, 2)
|
||||
"""
|
||||
def mk_not(a):
|
||||
if is_not(a):
|
||||
return a.arg(0)
|
||||
else:
|
||||
return Not(a)
|
||||
args = _get_args(args)
|
||||
if __debug__:
|
||||
_z3_assert(len(args) > 1, "Non empty list of arguments expected")
|
||||
|
@ -7660,10 +7655,25 @@ def AtLeast(*args):
|
|||
if __debug__:
|
||||
_z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
|
||||
args1 = _coerce_expr_list(args[:-1], ctx)
|
||||
args1 = [ mk_not(a) for a in args1 ]
|
||||
k = len(args1) - args[-1]
|
||||
k = args[-1]
|
||||
_args, sz = _to_ast_array(args1)
|
||||
return BoolRef(Z3_mk_atmost(ctx.ref(), sz, _args, k), ctx)
|
||||
return BoolRef(Z3_mk_atleast(ctx.ref(), sz, _args, k), ctx)
|
||||
|
||||
|
||||
def _pb_args_coeffs(args):
|
||||
args = _get_args(args)
|
||||
args, coeffs = zip(*args)
|
||||
if __debug__:
|
||||
_z3_assert(len(args) > 0, "Non empty list of arguments expected")
|
||||
ctx = _ctx_from_ast_arg_list(args)
|
||||
if __debug__:
|
||||
_z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
|
||||
args = _coerce_expr_list(args, ctx)
|
||||
_args, sz = _to_ast_array(args)
|
||||
_coeffs = (ctypes.c_int * len(coeffs))()
|
||||
for i in range(len(coeffs)):
|
||||
_coeffs[i] = coeffs[i]
|
||||
return ctx, sz, _args, _coeffs
|
||||
|
||||
def PbLe(args, k):
|
||||
"""Create a Pseudo-Boolean inequality k constraint.
|
||||
|
@ -7671,38 +7681,25 @@ def PbLe(args, k):
|
|||
>>> a, b, c = Bools('a b c')
|
||||
>>> f = PbLe(((a,1),(b,3),(c,2)), 3)
|
||||
"""
|
||||
args = _get_args(args)
|
||||
args, coeffs = zip(*args)
|
||||
if __debug__:
|
||||
_z3_assert(len(args) > 0, "Non empty list of arguments expected")
|
||||
ctx = _ctx_from_ast_arg_list(args)
|
||||
if __debug__:
|
||||
_z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
|
||||
args = _coerce_expr_list(args, ctx)
|
||||
_args, sz = _to_ast_array(args)
|
||||
_coeffs = (ctypes.c_int * len(coeffs))()
|
||||
for i in range(len(coeffs)):
|
||||
_coeffs[i] = coeffs[i]
|
||||
ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
|
||||
return BoolRef(Z3_mk_pble(ctx.ref(), sz, _args, _coeffs, k), ctx)
|
||||
|
||||
def PbGe(args, k):
|
||||
"""Create a Pseudo-Boolean inequality k constraint.
|
||||
|
||||
>>> a, b, c = Bools('a b c')
|
||||
>>> f = PbGe(((a,1),(b,3),(c,2)), 3)
|
||||
"""
|
||||
ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
|
||||
return BoolRef(Z3_mk_pbge(ctx.ref(), sz, _args, _coeffs, k), ctx)
|
||||
|
||||
def PbEq(args, k):
|
||||
"""Create a Pseudo-Boolean inequality k constraint.
|
||||
|
||||
>>> a, b, c = Bools('a b c')
|
||||
>>> f = PbEq(((a,1),(b,3),(c,2)), 3)
|
||||
"""
|
||||
args = _get_args(args)
|
||||
args, coeffs = zip(*args)
|
||||
if __debug__:
|
||||
_z3_assert(len(args) > 0, "Non empty list of arguments expected")
|
||||
ctx = _ctx_from_ast_arg_list(args)
|
||||
if __debug__:
|
||||
_z3_assert(ctx is not None, "At least one of the arguments must be a Z3 expression")
|
||||
args = _coerce_expr_list(args, ctx)
|
||||
_args, sz = _to_ast_array(args)
|
||||
_coeffs = (ctypes.c_int * len(coeffs))()
|
||||
for i in range(len(coeffs)):
|
||||
_coeffs[i] = coeffs[i]
|
||||
ctx, sz, _args, _coeffs = _pb_args_coeffs(args)
|
||||
return BoolRef(Z3_mk_pbeq(ctx.ref(), sz, _args, _coeffs, k), ctx)
|
||||
|
||||
|
||||
|
|
|
@ -855,6 +855,9 @@ typedef enum
|
|||
- Z3_OP_PB_AT_MOST: Cardinality constraint.
|
||||
E.g., x + y + z <= 2
|
||||
|
||||
- Z3_OP_PB_AT_LEAST: Cardinality constraint.
|
||||
E.g., x + y + z >= 2
|
||||
|
||||
- Z3_OP_PB_LE: Generalized Pseudo-Boolean cardinality constraint.
|
||||
Example 2*x + 3*y <= 4
|
||||
|
||||
|
@ -1060,6 +1063,7 @@ typedef enum {
|
|||
Z3_OP_EXT_ROTATE_LEFT,
|
||||
Z3_OP_EXT_ROTATE_RIGHT,
|
||||
|
||||
Z3_OP_BIT2BOOL,
|
||||
Z3_OP_INT2BV,
|
||||
Z3_OP_BV2INT,
|
||||
Z3_OP_CARRY,
|
||||
|
@ -1173,6 +1177,7 @@ typedef enum {
|
|||
|
||||
// Pseudo Booleans
|
||||
Z3_OP_PB_AT_MOST=0x900,
|
||||
Z3_OP_PB_AT_LEAST,
|
||||
Z3_OP_PB_LE,
|
||||
Z3_OP_PB_GE,
|
||||
Z3_OP_PB_EQ,
|
||||
|
@ -1948,7 +1953,7 @@ extern "C" {
|
|||
The datatype may be recursive. Return the datatype sort.
|
||||
|
||||
\param c logical context.
|
||||
\param name name of datatype.
|
||||
\param name name of datatype.
|
||||
\param num_constructors number of constructors passed in.
|
||||
\param constructors array of constructor containers.
|
||||
|
||||
|
@ -3083,7 +3088,7 @@ extern "C" {
|
|||
|
||||
\param c logical context.
|
||||
\param numeral A string representing the numeral value in decimal notation. The string may be of the form \code{[num]*[.[num]*][E[+|-][num]+]}.
|
||||
If the given sort is a real, then the numeral can be a rational, that is, a string of the form \ccode{[num]* / [num]*}.
|
||||
If the given sort is a real, then the numeral can be a rational, that is, a string of the form \ccode{[num]* / [num]*}.
|
||||
\param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, finite-domain, or bit-vectors of arbitrary size.
|
||||
|
||||
\sa Z3_mk_int
|
||||
|
@ -3388,7 +3393,7 @@ extern "C" {
|
|||
\c lo number of times, and with an unbounded upper bound.
|
||||
|
||||
def_API('Z3_mk_re_loop', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in(UINT)))
|
||||
*/
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_re_loop(Z3_context c, Z3_ast r, unsigned lo, unsigned hi);
|
||||
|
||||
/**
|
||||
|
@ -3425,7 +3430,7 @@ extern "C" {
|
|||
def_API('Z3_mk_re_full' ,AST ,(_in(CONTEXT), _in(SORT)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_re_full(Z3_context c, Z3_sort re);
|
||||
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
@ -3961,10 +3966,19 @@ extern "C" {
|
|||
|
||||
def_API('Z3_mk_atmost', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in(UINT)))
|
||||
*/
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], unsigned k);
|
||||
|
||||
/**
|
||||
\brief Pseudo-Boolean relations.
|
||||
|
||||
Encode p1 + p2 + ... + pn >= k
|
||||
|
||||
def_API('Z3_mk_atleast', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in(UINT)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_atleast(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], unsigned k);
|
||||
|
||||
/**
|
||||
\brief Pseudo-Boolean relations.
|
||||
|
||||
|
@ -3972,11 +3986,21 @@ extern "C" {
|
|||
|
||||
def_API('Z3_mk_pble', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in_array(1,INT), _in(INT)))
|
||||
*/
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int coeffs[],
|
||||
int k);
|
||||
|
||||
/**
|
||||
\brief Pseudo-Boolean relations.
|
||||
|
||||
Encode k1*p1 + k2*p2 + ... + kn*pn >= k
|
||||
|
||||
def_API('Z3_mk_pbge', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in_array(1,INT), _in(INT)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_pbge(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int coeffs[],
|
||||
int k);
|
||||
|
||||
/**
|
||||
\brief Pseudo-Boolean relations.
|
||||
|
||||
|
@ -3984,7 +4008,6 @@ extern "C" {
|
|||
|
||||
def_API('Z3_mk_pbeq', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in_array(1,INT), _in(INT)))
|
||||
*/
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pbeq(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int coeffs[],
|
||||
int k);
|
||||
|
@ -5199,7 +5222,7 @@ extern "C" {
|
|||
/*@}*/
|
||||
|
||||
/**
|
||||
\brief Return a string describing the given error code.
|
||||
\brief Return a string describing the given error code.
|
||||
Retained function name for backwards compatibility within v4.1
|
||||
*/
|
||||
Z3_string Z3_API Z3_get_error_msg_ex(Z3_context c, Z3_error_code err);
|
||||
|
@ -5972,11 +5995,11 @@ extern "C" {
|
|||
|
||||
/**
|
||||
\brief retrieve consequences from solver that determine values of the supplied function symbols.
|
||||
|
||||
|
||||
def_API('Z3_solver_get_consequences', INT, (_in(CONTEXT), _in(SOLVER), _in(AST_VECTOR), _in(AST_VECTOR), _in(AST_VECTOR)))
|
||||
*/
|
||||
|
||||
Z3_lbool Z3_API Z3_solver_get_consequences(Z3_context c,
|
||||
Z3_lbool Z3_API Z3_solver_get_consequences(Z3_context c,
|
||||
Z3_solver s,
|
||||
Z3_ast_vector assumptions,
|
||||
Z3_ast_vector variables,
|
||||
|
|
|
@ -106,7 +106,7 @@ bool macro_manager::insert(func_decl * f, quantifier * m, proof * pr) {
|
|||
if (!m_deps.insert(f, s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// add macro
|
||||
m_decl2macro.insert(f, m);
|
||||
m_decls.push_back(f);
|
||||
|
@ -117,8 +117,8 @@ bool macro_manager::insert(func_decl * f, quantifier * m, proof * pr) {
|
|||
}
|
||||
|
||||
TRACE("macro_insert", tout << "A macro was successfully created for: " << f->get_name() << "\n";);
|
||||
|
||||
// Nothing's forbidden anymore; if something's bad, we detected it earlier.
|
||||
|
||||
// Nothing's forbidden anymore; if something's bad, we detected it earlier.
|
||||
// mark_forbidden(m->get_expr());
|
||||
return true;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ namespace macro_manager_ns {
|
|||
\brief Mark all func_decls used in exprs as forbidden.
|
||||
*/
|
||||
void macro_manager::mark_forbidden(unsigned n, expr * const * exprs) {
|
||||
expr_mark visited;
|
||||
expr_mark visited;
|
||||
macro_manager_ns::proc p(m_forbidden_set, m_forbidden);
|
||||
for (unsigned i = 0; i < n; i++)
|
||||
for_each_expr(p, visited, exprs[i]);
|
||||
|
@ -187,9 +187,9 @@ func_decl * macro_manager::get_macro_interpretation(unsigned i, expr_ref & inter
|
|||
app * head;
|
||||
expr * def;
|
||||
get_head_def(q, f, head, def);
|
||||
TRACE("macro_bug",
|
||||
TRACE("macro_bug",
|
||||
tout << f->get_name() << "\n" << mk_pp(head, m_manager) << "\n" << mk_pp(q, m_manager) << "\n";);
|
||||
m_util.mk_macro_interpretation(head, def, interp);
|
||||
m_util.mk_macro_interpretation(head, q->get_num_decls(), def, interp);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ void macro_manager::macro_expander::reduce1_quantifier(quantifier * q) {
|
|||
erase_patterns = true;
|
||||
}
|
||||
for (unsigned i = 0; !erase_patterns && i < q->get_num_no_patterns(); i++) {
|
||||
if (q->get_no_pattern(i) != new_q->get_no_pattern(i))
|
||||
if (q->get_no_pattern(i) != new_q->get_no_pattern(i))
|
||||
erase_patterns = true;
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ bool macro_manager::macro_expander::get_subst(expr * _n, expr_ref & r, proof_ref
|
|||
return false;
|
||||
app * n = to_app(_n);
|
||||
quantifier * q = 0;
|
||||
func_decl * d = n->get_decl();
|
||||
func_decl * d = n->get_decl();
|
||||
TRACE("macro_manager_bug", tout << "trying to expand:\n" << mk_pp(n, m) << "\nd:\n" << d->get_name() << "\n";);
|
||||
if (m_macro_manager.m_decl2macro.find(d, q)) {
|
||||
TRACE("macro_manager", tout << "expanding: " << mk_pp(n, m) << "\n";);
|
||||
|
@ -308,7 +308,7 @@ void macro_manager::expand_macros(expr * n, proof * pr, expr_ref & r, proof_ref
|
|||
if (r.get() == old_n.get())
|
||||
return;
|
||||
old_n = r;
|
||||
old_pr = new_pr;
|
||||
old_pr = new_pr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -405,7 +405,7 @@ bool macro_util::is_quasi_macro_head(expr * n, unsigned num_decls) const {
|
|||
\brief Convert a quasi-macro head into a macro head, and store the conditions under
|
||||
which it is valid in cond.
|
||||
*/
|
||||
void macro_util::quasi_macro_head_to_macro_head(app * qhead, unsigned num_decls, app_ref & head, expr_ref & cond) const {
|
||||
void macro_util::quasi_macro_head_to_macro_head(app * qhead, unsigned & num_decls, app_ref & head, expr_ref & cond) const {
|
||||
unsigned num_args = qhead->get_num_args();
|
||||
sbuffer<bool> found_vars;
|
||||
found_vars.resize(num_decls, false);
|
||||
|
@ -431,6 +431,7 @@ void macro_util::quasi_macro_head_to_macro_head(app * qhead, unsigned num_decls,
|
|||
}
|
||||
get_basic_simp()->mk_and(new_conds.size(), new_conds.c_ptr(), cond);
|
||||
head = m_manager.mk_app(qhead->get_decl(), new_args.size(), new_args.c_ptr());
|
||||
num_decls = next_var_idx;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -440,10 +441,10 @@ void macro_util::quasi_macro_head_to_macro_head(app * qhead, unsigned num_decls,
|
|||
|
||||
See normalize_expr
|
||||
*/
|
||||
void macro_util::mk_macro_interpretation(app * head, expr * def, expr_ref & interp) const {
|
||||
void macro_util::mk_macro_interpretation(app * head, unsigned num_decls, expr * def, expr_ref & interp) const {
|
||||
SASSERT(is_macro_head(head, head->get_num_args()));
|
||||
SASSERT(!occurs(head->get_decl(), def));
|
||||
normalize_expr(head, def, interp);
|
||||
normalize_expr(head, num_decls, def, interp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -456,40 +457,31 @@ void macro_util::mk_macro_interpretation(app * head, expr * def, expr_ref & inte
|
|||
f(x_1, x_2) --> f(x_0, x_1)
|
||||
f(x_3, x_2) --> f(x_0, x_1)
|
||||
*/
|
||||
void macro_util::normalize_expr(app * head, expr * t, expr_ref & norm_t) const {
|
||||
expr_ref_buffer var_mapping(m_manager);
|
||||
void macro_util::normalize_expr(app * head, unsigned num_decls, expr * t, expr_ref & norm_t) const {
|
||||
expr_ref_buffer var_mapping(m_manager);
|
||||
var_mapping.resize(num_decls);
|
||||
bool changed = false;
|
||||
unsigned num_args = head->get_num_args();
|
||||
unsigned max_var_idx = 0;
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
var const * v = to_var(head->get_arg(i));
|
||||
if (v->get_idx() > max_var_idx)
|
||||
max_var_idx = v->get_idx();
|
||||
}
|
||||
TRACE("normalize_expr_bug",
|
||||
TRACE("macro_util",
|
||||
tout << "head: " << mk_pp(head, m_manager) << "\n";
|
||||
tout << "applying substitution to:\n" << mk_bounded_pp(t, m_manager) << "\n";);
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
var * v = to_var(head->get_arg(i));
|
||||
if (v->get_idx() != i) {
|
||||
unsigned vi = v->get_idx();
|
||||
SASSERT(vi < num_decls);
|
||||
if (vi != i) {
|
||||
changed = true;
|
||||
var_ref new_var(m_manager.mk_var(i, v->get_sort()), m_manager);
|
||||
var_mapping.setx(max_var_idx - v->get_idx(), new_var);
|
||||
var_mapping.setx(num_decls - vi - 1, new_var);
|
||||
}
|
||||
else
|
||||
var_mapping.setx(max_var_idx - i, v);
|
||||
var_mapping.setx(num_decls - i - 1, v);
|
||||
}
|
||||
|
||||
for (unsigned i = num_args; i <= max_var_idx; i++)
|
||||
// CMW: Won't be used, but dictates a larger binding size,
|
||||
// so that the indexes between here and in the rewriter match.
|
||||
// It's possible that we don't see the true max idx of all vars here.
|
||||
var_mapping.setx(max_var_idx - i, 0);
|
||||
|
||||
if (changed) {
|
||||
// REMARK: t may have nested quantifiers... So, I must use the std order for variable substitution.
|
||||
var_subst subst(m_manager, true);
|
||||
TRACE("macro_util_bug",
|
||||
TRACE("macro_util",
|
||||
tout << "head: " << mk_pp(head, m_manager) << "\n";
|
||||
tout << "applying substitution to:\n" << mk_ll_pp(t, m_manager) << "\nsubstitution:\n";
|
||||
for (unsigned i = 0; i < var_mapping.size(); i++) {
|
||||
|
@ -573,7 +565,7 @@ bool is_hint_atom(expr * lhs, expr * rhs) {
|
|||
return !occurs(to_app(lhs)->get_decl(), rhs) && vars_of_is_subset(rhs, vars);
|
||||
}
|
||||
|
||||
void hint_to_macro_head(ast_manager & m, app * head, unsigned num_decls, app_ref & new_head) {
|
||||
void hint_to_macro_head(ast_manager & m, app * head, unsigned & num_decls, app_ref & new_head) {
|
||||
unsigned num_args = head->get_num_args();
|
||||
ptr_buffer<expr> new_args;
|
||||
sbuffer<bool> found_vars;
|
||||
|
@ -595,6 +587,7 @@ void hint_to_macro_head(ast_manager & m, app * head, unsigned num_decls, app_ref
|
|||
new_args.push_back(new_var);
|
||||
}
|
||||
new_head = m.mk_app(head->get_decl(), new_args.size(), new_args.c_ptr());
|
||||
num_decls = next_var_idx;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -604,12 +597,12 @@ void hint_to_macro_head(ast_manager & m, app * head, unsigned num_decls, app_ref
|
|||
is_hint_head(head, vars) must also return true
|
||||
*/
|
||||
bool macro_util::is_poly_hint(expr * n, app * head, expr * exception) {
|
||||
TRACE("macro_util_hint", tout << "is_poly_hint n:\n" << mk_pp(n, m_manager) << "\nhead:\n" << mk_pp(head, m_manager) << "\nexception:\n";
|
||||
TRACE("macro_util", tout << "is_poly_hint n:\n" << mk_pp(n, m_manager) << "\nhead:\n" << mk_pp(head, m_manager) << "\nexception:\n";
|
||||
if (exception) tout << mk_pp(exception, m_manager); else tout << "<null>";
|
||||
tout << "\n";);
|
||||
ptr_buffer<var> vars;
|
||||
if (!is_hint_head(head, vars)) {
|
||||
TRACE("macro_util_hint", tout << "failed because head is not hint head\n";);
|
||||
TRACE("macro_util", tout << "failed because head is not hint head\n";);
|
||||
return false;
|
||||
}
|
||||
func_decl * f = head->get_decl();
|
||||
|
@ -626,11 +619,11 @@ bool macro_util::is_poly_hint(expr * n, app * head, expr * exception) {
|
|||
for (unsigned i = 0; i < num_args; i++) {
|
||||
expr * arg = args[i];
|
||||
if (arg != exception && (occurs(f, arg) || !vars_of_is_subset(arg, vars))) {
|
||||
TRACE("macro_util_hint", tout << "failed because of:\n" << mk_pp(arg, m_manager) << "\n";);
|
||||
TRACE("macro_util", tout << "failed because of:\n" << mk_pp(arg, m_manager) << "\n";);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
TRACE("macro_util_hint", tout << "succeeded\n";);
|
||||
TRACE("macro_util", tout << "succeeded\n";);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@ -671,12 +664,12 @@ void macro_util::macro_candidates::insert(func_decl * f, expr * def, expr * cond
|
|||
//
|
||||
// -----------------------------
|
||||
|
||||
void macro_util::insert_macro(app * head, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint, macro_candidates & r) {
|
||||
void macro_util::insert_macro(app * head, unsigned num_decls, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint, macro_candidates & r) {
|
||||
expr_ref norm_def(m_manager);
|
||||
expr_ref norm_cond(m_manager);
|
||||
normalize_expr(head, def, norm_def);
|
||||
normalize_expr(head, num_decls, def, norm_def);
|
||||
if (cond != 0)
|
||||
normalize_expr(head, cond, norm_cond);
|
||||
normalize_expr(head, num_decls, cond, norm_cond);
|
||||
else if (!hint)
|
||||
norm_cond = m_manager.mk_true();
|
||||
SASSERT(!hint || norm_cond.get() == 0);
|
||||
|
@ -698,11 +691,14 @@ void macro_util::insert_quasi_macro(app * head, unsigned num_decls, expr * def,
|
|||
}
|
||||
else {
|
||||
hint_to_macro_head(m_manager, head, num_decls, new_head);
|
||||
TRACE("macro_util",
|
||||
tout << "hint macro head: " << mk_ismt2_pp(new_head, m_manager) << std::endl;
|
||||
tout << "hint macro def: " << mk_ismt2_pp(def, m_manager) << std::endl; );
|
||||
}
|
||||
insert_macro(new_head, def, new_cond, ineq, satisfy_atom, hint, r);
|
||||
insert_macro(new_head, num_decls, def, new_cond, ineq, satisfy_atom, hint, r);
|
||||
}
|
||||
else {
|
||||
insert_macro(head, def, cond, ineq, satisfy_atom, hint, r);
|
||||
insert_macro(head, num_decls, def, cond, ineq, satisfy_atom, hint, r);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -831,7 +827,7 @@ void macro_util::collect_arith_macro_candidates(expr * lhs, expr * rhs, expr * a
|
|||
}
|
||||
|
||||
void macro_util::collect_arith_macro_candidates(expr * atom, unsigned num_decls, macro_candidates & r) {
|
||||
TRACE("macro_util_hint", tout << "collect_arith_macro_candidates:\n" << mk_pp(atom, m_manager) << "\n";);
|
||||
TRACE("macro_util", tout << "collect_arith_macro_candidates:\n" << mk_pp(atom, m_manager) << "\n";);
|
||||
if (!m_manager.is_eq(atom) && !is_le_ge(atom))
|
||||
return;
|
||||
expr * lhs = to_app(atom)->get_arg(0);
|
||||
|
@ -879,6 +875,9 @@ void macro_util::collect_arith_macro_candidates(expr * atom, unsigned num_decls,
|
|||
*/
|
||||
void macro_util::collect_macro_candidates_core(expr * atom, unsigned num_decls, macro_candidates & r) {
|
||||
expr* lhs, *rhs;
|
||||
|
||||
TRACE("macro_util", tout << "Candidate check for: " << mk_ismt2_pp(atom, m_manager) << std::endl;);
|
||||
|
||||
if (m_manager.is_eq(atom, lhs, rhs) || m_manager.is_iff(atom, lhs, rhs)) {
|
||||
if (is_quasi_macro_head(lhs, num_decls) &&
|
||||
!is_forbidden(to_app(lhs)->get_decl()) &&
|
||||
|
|
|
@ -74,9 +74,9 @@ private:
|
|||
void collect_arith_macros(expr * n, unsigned num_decls, unsigned max_macros, bool allow_cond_macros,
|
||||
macro_candidates & r);
|
||||
|
||||
void normalize_expr(app * head, expr * t, expr_ref & norm_t) const;
|
||||
void insert_macro(app * head, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint, macro_candidates & r);
|
||||
void insert_quasi_macro(app * head, unsigned num_decls, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint,
|
||||
void normalize_expr(app * head, unsigned num_decls, expr * t, expr_ref & norm_t) const;
|
||||
void insert_macro(app * head, unsigned num_decls, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint, macro_candidates & r);
|
||||
void insert_quasi_macro(app * head, unsigned num_decls, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint,
|
||||
macro_candidates & r);
|
||||
|
||||
expr * m_curr_clause; // auxiliary var used in collect_macro_candidates.
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
bool is_left_simple_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def) const;
|
||||
bool is_right_simple_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def) const;
|
||||
bool is_simple_macro(expr * n, unsigned num_decls, app_ref& head, expr_ref & def) const {
|
||||
return is_left_simple_macro(n, num_decls, head, def) || is_right_simple_macro(n, num_decls, head, def);
|
||||
return is_left_simple_macro(n, num_decls, head, def) || is_right_simple_macro(n, num_decls, head, def);
|
||||
}
|
||||
|
||||
bool is_arith_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def, bool & inv) const;
|
||||
|
@ -113,20 +113,20 @@ public:
|
|||
bool inv;
|
||||
return is_arith_macro(n, num_decls, head, def, inv);
|
||||
}
|
||||
|
||||
|
||||
bool is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, app_ref & t);
|
||||
bool is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t, expr_ref & def);
|
||||
|
||||
bool is_quasi_macro_head(expr * n, unsigned num_decls) const;
|
||||
void quasi_macro_head_to_macro_head(app * qhead, unsigned num_decls, app_ref & head, expr_ref & cond) const;
|
||||
void quasi_macro_head_to_macro_head(app * qhead, unsigned & num_decls, app_ref & head, expr_ref & cond) const;
|
||||
|
||||
void mk_macro_interpretation(app * head, expr * def, expr_ref & interp) const;
|
||||
void mk_macro_interpretation(app * head, unsigned num_decls, expr * def, expr_ref & interp) const;
|
||||
|
||||
void collect_macro_candidates(expr * atom, unsigned num_decls, macro_candidates & r);
|
||||
void collect_macro_candidates(quantifier * q, macro_candidates & r);
|
||||
|
||||
//
|
||||
// Auxiliary goodness that allows us to manipulate BV and Arith polynomials.
|
||||
// Auxiliary goodness that allows us to manipulate BV and Arith polynomials.
|
||||
//
|
||||
bool is_bv(expr * n) const;
|
||||
bool is_bv_sort(sort * s) const;
|
||||
|
|
|
@ -59,9 +59,12 @@ br_status bool_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * co
|
|||
mk_implies(args[0], args[1], result);
|
||||
return BR_DONE;
|
||||
case OP_XOR:
|
||||
SASSERT(num_args == 2);
|
||||
mk_xor(args[0], args[1], result);
|
||||
return BR_DONE;
|
||||
switch (num_args) {
|
||||
case 0: return BR_FAILED;
|
||||
case 1: result = args[0]; return BR_DONE;
|
||||
case 2: mk_xor(args[0], args[1], result); return BR_DONE;
|
||||
default: UNREACHABLE(); return BR_FAILED;
|
||||
}
|
||||
default:
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ Notes:
|
|||
#include"scoped_ptr_vector.h"
|
||||
#include"cooperate.h"
|
||||
#include"upolynomial_factorization.h"
|
||||
#include"polynomial_factorization.h"
|
||||
#include"polynomial_primes.h"
|
||||
#include"permutation.h"
|
||||
#include"algebraic_numbers.h"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,65 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
polynomial_factorization.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Methods for factoring polynomials.
|
||||
|
||||
Author:
|
||||
|
||||
Dejan (t-dejanj) 2011-11-29
|
||||
|
||||
Notes:
|
||||
|
||||
[1] Elwyn Ralph Berlekamp. Factoring Polynomials over Finite Fields. Bell System Technical Journal,
|
||||
46(8-10):1853-1859, 1967.
|
||||
[2] Donald Ervin Knuth. The Art of Computer Programming, volume 2: Seminumerical Algorithms. Addison Wesley, third
|
||||
edition, 1997.
|
||||
[3] Henri Cohen. A Course in Computational Algebraic Number Theory. Springer Verlag, 1993.
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if 0
|
||||
// Disabled for reorg
|
||||
#include "polynomial.h"
|
||||
#include "upolynomial.h"
|
||||
#include "bit_vector.h"
|
||||
#include "z3_exception.h"
|
||||
|
||||
namespace polynomial {
|
||||
|
||||
/**
|
||||
\brief Something to throw when we are in trouble.
|
||||
*/
|
||||
class factorization_exception : public default_exception {
|
||||
public:
|
||||
factorization_exception(char const * msg) : default_exception(msg) {}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Factor the polynomial f from Z[x1, ..., x_n]. Returns the index of the last factor that is completely
|
||||
factored. I.e., if the method returns m, then f_1, ..., f_m are true irreducible factors, and the rest might
|
||||
be further reducible.
|
||||
*/
|
||||
unsigned factor(polynomial_ref & f, factors & factors);
|
||||
|
||||
/**
|
||||
\brief Factor the square-free primitive polynomial f from Z[x1, ..., x_n]. Returns true if the factorization
|
||||
was sucesseful, i.e. it was completed and the result is complete. Otherwise the quarantee is that the all but
|
||||
the last factor are irreducible.
|
||||
*/
|
||||
bool factor_square_free_primitive(polynomial_ref const & f, factors & factors);
|
||||
}
|
||||
|
||||
inline std::ostream & operator<<(std::ostream & out, polynomial::factors & factors) {
|
||||
factors.display(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -575,7 +575,7 @@ namespace pdr {
|
|||
// Predicates that are variable representatives. Other predicates at
|
||||
// positions the variables occur are made equivalent with these.
|
||||
expr_ref_vector conj(m);
|
||||
app_ref_vector& var_reprs = *(alloc(app_ref_vector, m));
|
||||
app_ref_vector var_reprs(m);
|
||||
ptr_vector<app> aux_vars;
|
||||
|
||||
unsigned ut_size = rule.get_uninterpreted_tail_size();
|
||||
|
@ -584,8 +584,9 @@ namespace pdr {
|
|||
init_atom(pts, rule.get_head(), var_reprs, conj, UINT_MAX);
|
||||
for (unsigned i = 0; i < ut_size; ++i) {
|
||||
if (rule.is_neg_tail(i)) {
|
||||
dealloc(&var_reprs);
|
||||
throw default_exception("PDR does not support negated predicates in rule tails");
|
||||
char const* msg = "PDR does not supported negated predicates in rule tails";
|
||||
IF_VERBOSE(0, verbose_stream() << msg << "\n";);
|
||||
throw default_exception(msg);
|
||||
}
|
||||
init_atom(pts, rule.get_tail(i), var_reprs, conj, i);
|
||||
}
|
||||
|
@ -600,14 +601,14 @@ namespace pdr {
|
|||
flatten_and(tail);
|
||||
for (unsigned i = 0; i < tail.size(); ++i) {
|
||||
expr_ref tmp(m);
|
||||
var_subst(m, false)(tail[i].get(), var_reprs.size(), (expr*const*)var_reprs.c_ptr(), tmp);
|
||||
var_subst vs(m, false);
|
||||
vs(tail[i].get(), var_reprs.size(), (expr*const*)var_reprs.c_ptr(), tmp);
|
||||
conj.push_back(tmp);
|
||||
TRACE("pdr", tout << mk_pp(tail[i].get(), m) << "\n" << mk_pp(tmp, m) << "\n";);
|
||||
if (!is_ground(tmp)) {
|
||||
std::stringstream msg;
|
||||
msg << "PDR cannot solve non-ground tails: " << tmp;
|
||||
IF_VERBOSE(0, verbose_stream() << msg.str() << "\n";);
|
||||
dealloc(&var_reprs);
|
||||
throw default_exception(msg.str());
|
||||
}
|
||||
}
|
||||
|
@ -631,7 +632,7 @@ namespace pdr {
|
|||
m_rule2transition.insert(&rule, fml.get());
|
||||
rules.push_back(&rule);
|
||||
}
|
||||
m_rule2inst.insert(&rule, &var_reprs);
|
||||
m_rule2inst.insert(&rule, alloc(app_ref_vector, var_reprs));
|
||||
m_rule2vars.insert(&rule, aux_vars);
|
||||
TRACE("pdr",
|
||||
tout << rule.get_decl()->get_name() << "\n";
|
||||
|
@ -1468,13 +1469,20 @@ namespace pdr {
|
|||
reset();
|
||||
}
|
||||
|
||||
void context::reset() {
|
||||
TRACE("pdr", tout << "\n";);
|
||||
decl2rel::iterator it = m_rels.begin(), end = m_rels.end();
|
||||
void context::reset(decl2rel& rels) {
|
||||
decl2rel::iterator it = rels.begin(), end = rels.end();
|
||||
for (; it != end; ++it) {
|
||||
dealloc(it->m_value);
|
||||
}
|
||||
m_rels.reset();
|
||||
rels.reset();
|
||||
}
|
||||
|
||||
void context::reset(bool full) {
|
||||
TRACE("pdr", tout << "reset\n";);
|
||||
reset(m_rels);
|
||||
if (full) {
|
||||
reset(m_rels_tmp);
|
||||
}
|
||||
m_search.reset();
|
||||
m_query = 0;
|
||||
m_last_result = l_undef;
|
||||
|
@ -1496,6 +1504,7 @@ namespace pdr {
|
|||
e->get_data().m_value->add_rule(pred_rules[i]);
|
||||
}
|
||||
}
|
||||
TRACE("pdr", tout << "adding rules\n";);
|
||||
datalog::rule_set::iterator rit = rules.begin(), rend = rules.end();
|
||||
for (; rit != rend; ++rit) {
|
||||
datalog::rule* r = *rit;
|
||||
|
@ -1510,6 +1519,7 @@ namespace pdr {
|
|||
}
|
||||
}
|
||||
// Initialize use list dependencies
|
||||
TRACE("pdr", tout << "initialize use list dependencies\n";);
|
||||
decl2rel::iterator it = rels.begin(), end = rels.end();
|
||||
for (; it != end; ++it) {
|
||||
func_decl* pred = it->m_key;
|
||||
|
@ -1523,9 +1533,11 @@ namespace pdr {
|
|||
}
|
||||
}
|
||||
|
||||
TRACE("pdr", tout << "initialize predicate transformers\n";);
|
||||
// Initialize the predicate transformers.
|
||||
it = rels.begin(), end = rels.end();
|
||||
for (; it != end; ++it) {
|
||||
SASSERT(it->m_value);
|
||||
pred_transformer& rel = *it->m_value;
|
||||
rel.initialize(rels);
|
||||
TRACE("pdr", rel.display(tout); );
|
||||
|
@ -1533,21 +1545,24 @@ namespace pdr {
|
|||
}
|
||||
|
||||
void context::update_rules(datalog::rule_set& rules) {
|
||||
decl2rel rels;
|
||||
TRACE("pdr", tout << "update rules\n";);
|
||||
reset(m_rels_tmp);
|
||||
init_core_generalizers(rules);
|
||||
init_rules(rules, rels);
|
||||
decl2rel::iterator it = rels.begin(), end = rels.end();
|
||||
init_rules(rules, m_rels_tmp);
|
||||
decl2rel::iterator it = m_rels_tmp.begin(), end = m_rels_tmp.end();
|
||||
for (; it != end; ++it) {
|
||||
pred_transformer* pt = 0;
|
||||
if (m_rels.find(it->m_key, pt)) {
|
||||
it->m_value->inherit_properties(*pt);
|
||||
}
|
||||
}
|
||||
reset();
|
||||
it = rels.begin(), end = rels.end();
|
||||
reset(false);
|
||||
it = m_rels_tmp.begin(), end = m_rels_tmp.end();
|
||||
for (; it != end; ++it) {
|
||||
m_rels.insert(it->m_key, it->m_value);
|
||||
}
|
||||
m_rels_tmp.reset();
|
||||
TRACE("pdr", tout << "done update rules\n";);
|
||||
}
|
||||
|
||||
unsigned context::get_num_levels(func_decl* p) {
|
||||
|
@ -1875,6 +1890,7 @@ namespace pdr {
|
|||
}
|
||||
|
||||
lbool context::solve() {
|
||||
TRACE("pdr", tout << "solve\n";);
|
||||
m_last_result = l_undef;
|
||||
try {
|
||||
solve_impl();
|
||||
|
@ -2090,6 +2106,7 @@ namespace pdr {
|
|||
}
|
||||
case l_undef: {
|
||||
TRACE("pdr", tout << "unknown state: " << mk_pp(m_pm.mk_and(cube), m) << "\n";);
|
||||
IF_VERBOSE(1, verbose_stream() << "unknown state\n";);
|
||||
throw unknown_exception();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -328,6 +328,7 @@ namespace pdr {
|
|||
datalog::context* m_context;
|
||||
manager m_pm;
|
||||
decl2rel m_rels; // Map from relation predicate to fp-operator.
|
||||
decl2rel m_rels_tmp;
|
||||
func_decl_ref m_query_pred;
|
||||
pred_transformer* m_query;
|
||||
mutable model_search m_search;
|
||||
|
@ -370,6 +371,8 @@ namespace pdr {
|
|||
|
||||
void reset_core_generalizers();
|
||||
|
||||
void reset(decl2rel& rels);
|
||||
|
||||
void validate();
|
||||
void validate_proof();
|
||||
void validate_search();
|
||||
|
@ -410,8 +413,7 @@ namespace pdr {
|
|||
|
||||
lbool solve();
|
||||
|
||||
|
||||
void reset();
|
||||
void reset(bool full = true);
|
||||
|
||||
void set_query(func_decl* q) { m_query_pred = q; }
|
||||
|
||||
|
|
|
@ -19,12 +19,8 @@ Revision History:
|
|||
|
||||
#include "dl_context.h"
|
||||
#include "dl_mk_coi_filter.h"
|
||||
#include "dl_mk_interp_tail_simplifier.h"
|
||||
#include "dl_mk_subsumption_checker.h"
|
||||
#include "dl_mk_rule_inliner.h"
|
||||
#include "dl_rule.h"
|
||||
#include "dl_rule_transformer.h"
|
||||
#include "smt2parser.h"
|
||||
#include "pdr_context.h"
|
||||
#include "pdr_dl_interface.h"
|
||||
#include "dl_rule_set.h"
|
||||
|
@ -164,7 +160,7 @@ lbool dl_interface::query(expr * query) {
|
|||
m_context->set_proof_converter(m_ctx.get_proof_converter());
|
||||
m_context->set_model_converter(m_ctx.get_model_converter());
|
||||
m_context->set_query(query_pred);
|
||||
m_context->set_axioms(bg_assertion);
|
||||
m_context->set_axioms(bg_assertion);
|
||||
m_context->update_rules(m_pdr_rules);
|
||||
|
||||
if (m_pdr_rules.get_rules().empty()) {
|
||||
|
|
|
@ -93,7 +93,7 @@ private:
|
|||
mss m_mss;
|
||||
expr_ref_vector m_trail;
|
||||
strategy_t m_st;
|
||||
rational m_max_upper;
|
||||
rational m_max_upper;
|
||||
model_ref m_csmodel;
|
||||
unsigned m_correction_set_size;
|
||||
bool m_found_feasible_optimum;
|
||||
|
@ -109,6 +109,7 @@ private:
|
|||
bool m_pivot_on_cs; // prefer smaller correction set to core.
|
||||
bool m_dump_benchmarks; // display benchmarks (into wcnf format)
|
||||
|
||||
|
||||
std::string m_trace_id;
|
||||
typedef ptr_vector<expr> exprs;
|
||||
|
||||
|
@ -150,9 +151,7 @@ public:
|
|||
return
|
||||
is_uninterp_const(l) ||
|
||||
(m.is_not(l, l) && is_uninterp_const(l));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void add_soft(expr* e, rational const& w) {
|
||||
TRACE("opt", tout << mk_pp(e, m) << " |-> " << w << "\n";);
|
||||
|
@ -290,7 +289,7 @@ public:
|
|||
index = next_index(asms, index);
|
||||
}
|
||||
first = false;
|
||||
IF_VERBOSE(3, verbose_stream() << "weight: " << get_weight(asms[0].get()) << " " << get_weight(asms[index-1].get()) << " num soft: " << index << "\n";);
|
||||
// IF_VERBOSE(3, verbose_stream() << "weight: " << get_weight(asms[0].get()) << " " << get_weight(asms[index-1].get()) << " num soft: " << index << "\n";);
|
||||
m_last_index = index;
|
||||
is_sat = check_sat(index, asms.c_ptr());
|
||||
}
|
||||
|
@ -302,17 +301,7 @@ public:
|
|||
}
|
||||
|
||||
lbool check_sat(unsigned sz, expr* const* asms) {
|
||||
if (m_st == s_primal_dual && m_c.sat_enabled()) {
|
||||
rational max_weight = m_upper;
|
||||
vector<rational> weights;
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
weights.push_back(get_weight(asms[i]));
|
||||
}
|
||||
return inc_sat_check_sat(s(), sz, asms, weights.c_ptr(), max_weight);
|
||||
}
|
||||
else {
|
||||
return s().check_sat(sz, asms);
|
||||
}
|
||||
return s().check_sat(sz, asms);
|
||||
}
|
||||
|
||||
void found_optimum() {
|
||||
|
@ -500,7 +489,7 @@ public:
|
|||
TRACE("opt", display_vec(tout << "minimized core: ", core););
|
||||
IF_VERBOSE(10, display_vec(verbose_stream() << "core: ", core););
|
||||
max_resolve(core, w);
|
||||
fml = mk_not(m, mk_and(m, m_B.size(), m_B.c_ptr()));
|
||||
fml = mk_not(m, mk_and(m, core.size(), core.c_ptr()));
|
||||
s().assert_expr(fml);
|
||||
m_lower += w;
|
||||
if (m_st == s_primal_dual) {
|
||||
|
@ -540,7 +529,10 @@ public:
|
|||
}
|
||||
|
||||
lbool minimize_core(exprs& core) {
|
||||
if (m_c.sat_enabled() || core.empty()) {
|
||||
if (core.empty()) {
|
||||
return l_true;
|
||||
}
|
||||
if (m_c.sat_enabled()) {
|
||||
return l_true;
|
||||
}
|
||||
m_mus.reset();
|
||||
|
@ -617,8 +609,8 @@ public:
|
|||
// Soundness of this rule can be established using MaxRes
|
||||
//
|
||||
for (unsigned i = 1; i < core.size(); ++i) {
|
||||
expr* b_i = m_B[i-1].get();
|
||||
expr* b_i1 = m_B[i].get();
|
||||
expr* b_i = core[i-1];
|
||||
expr* b_i1 = core[i];
|
||||
if (i == 1) {
|
||||
d = to_app(b_i);
|
||||
}
|
||||
|
@ -668,8 +660,8 @@ public:
|
|||
// d_i => d_{i-1} or b_{i-1}
|
||||
//
|
||||
for (unsigned i = 1; i < cs.size(); ++i) {
|
||||
expr* b_i = m_B[i-1].get();
|
||||
expr* b_i1 = m_B[i].get();
|
||||
expr* b_i = cs[i - 1];
|
||||
expr* b_i1 = cs[i];
|
||||
cls = m.mk_or(b_i, d);
|
||||
if (i > 2) {
|
||||
d = mk_fresh_bool("d");
|
||||
|
@ -690,10 +682,11 @@ public:
|
|||
s().assert_expr(fml);
|
||||
m_defs.push_back(fml);
|
||||
new_assumption(asum, w);
|
||||
|
||||
fml = m.mk_and(b_i1, cls);
|
||||
update_model(asum, fml);
|
||||
}
|
||||
fml = m.mk_or(m_B.size(), m_B.c_ptr());
|
||||
fml = m.mk_or(cs.size(), cs.c_ptr());
|
||||
s().assert_expr(fml);
|
||||
}
|
||||
|
||||
|
@ -749,7 +742,7 @@ public:
|
|||
nsoft.push_back(mk_not(m, m_soft[i]));
|
||||
}
|
||||
fml = u.mk_lt(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper);
|
||||
s().assert_expr(fml);
|
||||
s().assert_expr(fml);
|
||||
}
|
||||
|
||||
bool is_true(model* mdl, expr* e) {
|
||||
|
@ -767,10 +760,9 @@ public:
|
|||
}
|
||||
|
||||
bool is_true(expr_ref_vector const& es) {
|
||||
for (unsigned i = 0; i < es.size(); ++i) {
|
||||
if (!is_true(es[i])) return false;
|
||||
}
|
||||
return true;
|
||||
unsigned i = 0;
|
||||
for (; i < es.size() && is_true(es[i]); ++i) { }
|
||||
return i == es.size();
|
||||
}
|
||||
|
||||
void remove_soft(exprs const& core, expr_ref_vector& asms) {
|
||||
|
@ -790,7 +782,6 @@ public:
|
|||
virtual void updt_params(params_ref& p) {
|
||||
maxsmt_solver_base::updt_params(p);
|
||||
opt_params _p(p);
|
||||
|
||||
m_hill_climb = _p.maxres_hill_climb();
|
||||
m_add_upper_bound_block = _p.maxres_add_upper_bound_block();
|
||||
m_max_num_cores = _p.maxres_max_num_cores();
|
||||
|
@ -868,7 +859,6 @@ public:
|
|||
IF_VERBOSE(0, verbose_stream() << "assignment is infeasible\n";);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
opt::maxsmt_solver_base* opt::mk_maxres(
|
||||
|
|
|
@ -55,15 +55,18 @@ namespace opt {
|
|||
|
||||
void maxsmt_solver_base::commit_assignment() {
|
||||
expr_ref tmp(m);
|
||||
rational k(0);
|
||||
rational k(0), cost(0);
|
||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||
if (get_assignment(i)) {
|
||||
k += m_weights[i];
|
||||
}
|
||||
else {
|
||||
cost += m_weights[i];
|
||||
}
|
||||
}
|
||||
pb_util pb(m);
|
||||
tmp = pb.mk_ge(m_weights.size(), m_weights.c_ptr(), m_soft.c_ptr(), k);
|
||||
TRACE("opt", tout << tmp << "\n";);
|
||||
TRACE("opt", tout << "cost: " << cost << "\n" << tmp << "\n";);
|
||||
s().assert_expr(tmp);
|
||||
}
|
||||
|
||||
|
@ -140,7 +143,9 @@ namespace opt {
|
|||
m_wth = s.ensure_wmax_theory();
|
||||
}
|
||||
maxsmt_solver_base::scoped_ensure_theory::~scoped_ensure_theory() {
|
||||
//m_wth->reset_local();
|
||||
if (m_wth) {
|
||||
m_wth->reset_local();
|
||||
}
|
||||
}
|
||||
smt::theory_wmaxsat& maxsmt_solver_base::scoped_ensure_theory::operator()() { return *m_wth; }
|
||||
|
||||
|
@ -226,7 +231,9 @@ namespace opt {
|
|||
m_msolver = 0;
|
||||
symbol const& maxsat_engine = m_c.maxsat_engine();
|
||||
IF_VERBOSE(1, verbose_stream() << "(maxsmt)\n";);
|
||||
TRACE("opt", tout << "maxsmt\n";);
|
||||
TRACE("opt", tout << "maxsmt\n";
|
||||
s().display(tout); tout << "\n";
|
||||
);
|
||||
if (m_soft_constraints.empty() || maxsat_engine == symbol("maxres") || maxsat_engine == symbol::null) {
|
||||
m_msolver = mk_maxres(m_c, m_index, m_weights, m_soft_constraints);
|
||||
}
|
||||
|
|
|
@ -327,12 +327,7 @@ namespace opt {
|
|||
SASSERT(idx < get_num_assertions());
|
||||
return m_context.get_formulas()[idx];
|
||||
}
|
||||
|
||||
std::ostream& opt_solver::display(std::ostream & out) const {
|
||||
m_context.display(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
smt::theory_var opt_solver::add_objective(app* term) {
|
||||
smt::theory_var v = get_optimizer().add_objective(term);
|
||||
m_objective_vars.push_back(v);
|
||||
|
|
|
@ -104,7 +104,6 @@ namespace opt {
|
|||
virtual void set_progress_callback(progress_callback * callback);
|
||||
virtual unsigned get_num_assertions() const;
|
||||
virtual expr * get_assertion(unsigned idx) const;
|
||||
virtual std::ostream& display(std::ostream & out) const;
|
||||
virtual ast_manager& get_manager() const { return m; }
|
||||
virtual lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes);
|
||||
virtual lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores);
|
||||
|
|
|
@ -20,9 +20,49 @@ Notes:
|
|||
#include "smt_literal.h"
|
||||
#include "ast_pp.h"
|
||||
#include "th_rewriter.h"
|
||||
#include "sat_sls.h"
|
||||
#include "sat_types.h"
|
||||
|
||||
namespace smt {
|
||||
|
||||
class index_set {
|
||||
|
||||
unsigned_vector m_elems;
|
||||
unsigned_vector m_index;
|
||||
public:
|
||||
unsigned num_elems() const { return m_elems.size(); }
|
||||
unsigned operator[](unsigned idx) const { return m_elems[idx]; }
|
||||
void reset() { m_elems.reset(); m_index.reset(); }
|
||||
bool empty() const { return m_elems.empty(); }
|
||||
|
||||
bool contains(unsigned idx) const {
|
||||
return
|
||||
(idx < m_index.size()) &&
|
||||
(m_index[idx] < m_elems.size()) &&
|
||||
(m_elems[m_index[idx]] == idx);
|
||||
}
|
||||
|
||||
void insert(unsigned idx) {
|
||||
m_index.reserve(idx+1);
|
||||
if (!contains(idx)) {
|
||||
m_index[idx] = m_elems.size();
|
||||
m_elems.push_back(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void remove(unsigned idx) {
|
||||
if (!contains(idx)) return;
|
||||
unsigned pos = m_index[idx];
|
||||
m_elems[pos] = m_elems.back();
|
||||
m_index[m_elems[pos]] = pos;
|
||||
m_elems.pop_back();
|
||||
}
|
||||
|
||||
unsigned choose(random_gen& rnd) const {
|
||||
SASSERT(!empty());
|
||||
return m_elems[rnd(num_elems())];
|
||||
}
|
||||
};
|
||||
|
||||
struct pb_sls::imp {
|
||||
|
||||
struct clause {
|
||||
|
@ -73,8 +113,8 @@ namespace smt {
|
|||
expr_ref_vector m_trail;
|
||||
obj_map<expr, unsigned> m_decl2var; // map declarations to Boolean variables.
|
||||
ptr_vector<expr> m_var2decl; // reverse map
|
||||
sat::index_set m_hard_false; // list of hard clauses that are false.
|
||||
sat::index_set m_soft_false; // list of soft clauses that are false.
|
||||
index_set m_hard_false; // list of hard clauses that are false.
|
||||
index_set m_soft_false; // list of soft clauses that are false.
|
||||
unsigned m_max_flips; // maximal number of flips
|
||||
unsigned m_non_greedy_percent; // percent of moves to do non-greedy style
|
||||
random_gen m_rng;
|
||||
|
|
|
@ -62,20 +62,22 @@ namespace opt {
|
|||
}
|
||||
m_upper = m_lower;
|
||||
bool was_sat = false;
|
||||
expr_ref_vector disj(m), asms(m);
|
||||
expr_ref_vector asms(m);
|
||||
vector<expr_ref_vector> cores;
|
||||
|
||||
obj_map<expr, rational>::iterator it = soft.begin(), end = soft.end();
|
||||
for (; it != end; ++it) {
|
||||
expr* c = assert_weighted(wth(), it->m_key, it->m_value);
|
||||
if (!is_true(it->m_key)) {
|
||||
disj.push_back(m.mk_not(c));
|
||||
m_upper += it->m_value;
|
||||
}
|
||||
}
|
||||
wth().init_min_cost(m_upper - m_lower);
|
||||
s().assert_expr(mk_or(disj));
|
||||
trace_bounds("wmax");
|
||||
|
||||
TRACE("opt",
|
||||
s().display(tout); tout << "\n";
|
||||
tout << "lower: " << m_lower << " upper: " << m_upper << "\n";);
|
||||
while (!m.canceled() && m_lower < m_upper) {
|
||||
//mk_assumptions(asms);
|
||||
//is_sat = s().preferred_sat(asms, cores);
|
||||
|
@ -84,6 +86,7 @@ namespace opt {
|
|||
is_sat = l_undef;
|
||||
}
|
||||
if (is_sat == l_false) {
|
||||
TRACE("opt", tout << "Unsat\n";);
|
||||
break;
|
||||
}
|
||||
if (is_sat == l_true) {
|
||||
|
|
|
@ -109,7 +109,6 @@ namespace smt2 {
|
|||
typedef std::pair<symbol, expr*> named_expr;
|
||||
named_expr m_last_named_expr;
|
||||
|
||||
|
||||
ast_manager & m() const { return m_ctx.m(); }
|
||||
pdecl_manager & pm() const { return m_ctx.pm(); }
|
||||
sexpr_manager & sm() const { return m_ctx.sm(); }
|
||||
|
@ -117,7 +116,7 @@ namespace smt2 {
|
|||
bool m_ignore_user_patterns;
|
||||
bool m_ignore_bad_patterns;
|
||||
bool m_display_error_for_vs;
|
||||
|
||||
|
||||
bool ignore_user_patterns() const { return m_ignore_user_patterns; }
|
||||
bool ignore_bad_patterns() const { return m_ignore_bad_patterns; }
|
||||
bool use_vs_format() const { return m_display_error_for_vs; }
|
||||
|
@ -129,7 +128,7 @@ namespace smt2 {
|
|||
m_decl(d), m_spos(spos) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef psort_frame sort_frame;
|
||||
|
||||
enum expr_frame_kind { EF_APP, EF_LET, EF_LET_DECL, EF_QUANT, EF_ATTR_EXPR, EF_PATTERN };
|
||||
|
@ -138,17 +137,17 @@ namespace smt2 {
|
|||
expr_frame_kind m_kind;
|
||||
expr_frame(expr_frame_kind k):m_kind(k) {}
|
||||
};
|
||||
|
||||
|
||||
struct app_frame : public expr_frame {
|
||||
symbol m_f;
|
||||
unsigned m_expr_spos;
|
||||
unsigned m_param_spos;
|
||||
bool m_as_sort;
|
||||
app_frame(symbol const & f, unsigned expr_spos, unsigned param_spos, bool as_sort):
|
||||
expr_frame(EF_APP),
|
||||
m_f(f),
|
||||
m_expr_spos(expr_spos),
|
||||
m_param_spos(param_spos),
|
||||
expr_frame(EF_APP),
|
||||
m_f(f),
|
||||
m_expr_spos(expr_spos),
|
||||
m_param_spos(param_spos),
|
||||
m_as_sort(as_sort) {}
|
||||
};
|
||||
|
||||
|
@ -163,8 +162,8 @@ namespace smt2 {
|
|||
unsigned m_sort_spos;
|
||||
unsigned m_expr_spos;
|
||||
quant_frame(bool forall, unsigned pat_spos, unsigned nopat_spos, unsigned sym_spos, unsigned sort_spos, unsigned expr_spos):
|
||||
expr_frame(EF_QUANT), m_forall(forall), m_weight(1),
|
||||
m_pat_spos(pat_spos), m_nopat_spos(nopat_spos),
|
||||
expr_frame(EF_QUANT), m_forall(forall), m_weight(1),
|
||||
m_pat_spos(pat_spos), m_nopat_spos(nopat_spos),
|
||||
m_sym_spos(sym_spos), m_sort_spos(sort_spos),
|
||||
m_expr_spos(expr_spos) {}
|
||||
};
|
||||
|
@ -175,7 +174,7 @@ namespace smt2 {
|
|||
unsigned m_expr_spos;
|
||||
let_frame(unsigned sym_spos, unsigned expr_spos):expr_frame(EF_LET), m_in_decls(true), m_sym_spos(sym_spos), m_expr_spos(expr_spos) {}
|
||||
};
|
||||
|
||||
|
||||
struct let_decl_frame : public expr_frame {
|
||||
let_decl_frame():expr_frame(EF_LET_DECL) {}
|
||||
};
|
||||
|
@ -186,9 +185,9 @@ namespace smt2 {
|
|||
unsigned m_expr_spos;
|
||||
symbol m_last_symbol;
|
||||
attr_expr_frame(expr_frame * prev, unsigned sym_spos, unsigned expr_spos):
|
||||
expr_frame(EF_ATTR_EXPR),
|
||||
m_prev(prev),
|
||||
m_sym_spos(sym_spos),
|
||||
expr_frame(EF_ATTR_EXPR),
|
||||
m_prev(prev),
|
||||
m_sym_spos(sym_spos),
|
||||
m_expr_spos(expr_spos) {}
|
||||
};
|
||||
|
||||
|
@ -228,12 +227,12 @@ namespace smt2 {
|
|||
m_expr_stack = alloc(expr_ref_vector, m());
|
||||
return *(m_expr_stack.get());
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static unsigned size(scoped_ptr<T> & v) {
|
||||
return v.get() == 0 ? 0 : v->size();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static void shrink(scoped_ptr<T> & v, unsigned old_sz) {
|
||||
if (v.get() == 0) {
|
||||
|
@ -255,7 +254,7 @@ namespace smt2 {
|
|||
m_nopattern_stack = alloc(expr_ref_vector, m());
|
||||
return *(m_nopattern_stack.get());
|
||||
}
|
||||
|
||||
|
||||
svector<symbol> & symbol_stack() {
|
||||
return m_symbol_stack;
|
||||
}
|
||||
|
@ -328,7 +327,7 @@ namespace smt2 {
|
|||
bool sync_after_error() {
|
||||
while (true) {
|
||||
try {
|
||||
while (curr_is_rparen())
|
||||
while (curr_is_rparen())
|
||||
next();
|
||||
if (m_num_open_paren < 0)
|
||||
m_num_open_paren = 0;
|
||||
|
@ -337,7 +336,7 @@ namespace smt2 {
|
|||
SASSERT(m_num_open_paren >= 0);
|
||||
while (m_num_open_paren > 0 || !curr_is_lparen()) {
|
||||
TRACE("sync", tout << "sync(): curr: " << curr() << "\n";
|
||||
tout << "m_num_open_paren: " << m_num_open_paren << ", line: " << m_scanner.get_line() << ", pos: "
|
||||
tout << "m_num_open_paren: " << m_num_open_paren << ", line: " << m_scanner.get_line() << ", pos: "
|
||||
<< m_scanner.get_pos() << "\n";);
|
||||
if (curr() == scanner::EOF_TOKEN) {
|
||||
return false;
|
||||
|
@ -365,7 +364,7 @@ namespace smt2 {
|
|||
}
|
||||
throw parser_exception(msg);
|
||||
}
|
||||
|
||||
|
||||
symbol const & curr_id() const { return m_scanner.get_id(); }
|
||||
rational curr_numeral() const { return m_scanner.get_number(); }
|
||||
|
||||
|
@ -402,15 +401,20 @@ namespace smt2 {
|
|||
void check_int_or_float(char const * msg) { if (!curr_is_int() && !curr_is_float()) throw parser_exception(msg); }
|
||||
void check_float(char const * msg) { if (!curr_is_float()) throw parser_exception(msg); }
|
||||
|
||||
char const * m_current_file;
|
||||
void set_current_file(char const * s) { m_current_file = s; }
|
||||
|
||||
void error(unsigned line, unsigned pos, char const * msg) {
|
||||
m_ctx.set_cancel(false);
|
||||
if (use_vs_format()) {
|
||||
m_ctx.diagnostic_stream() << "Z3(" << line << ", " << pos << "): ERROR: " << msg;
|
||||
if (msg[strlen(msg)-1] != '\n')
|
||||
m_ctx.diagnostic_stream() << std::endl;
|
||||
m_ctx.diagnostic_stream() << std::endl;
|
||||
}
|
||||
else {
|
||||
m_ctx.regular_stream() << "(error \"line " << line << " column " << pos << ": " << escaped(msg, true) << "\")" << std::endl;
|
||||
m_ctx.regular_stream() << "(error \"";
|
||||
if (m_current_file) m_ctx.regular_stream() << m_current_file << ": ";
|
||||
m_ctx.regular_stream()<< "line " << line << " column " << pos << ": " << escaped(msg, true) << "\")" << std::endl;
|
||||
}
|
||||
if (m_ctx.exit_on_error()) {
|
||||
exit(1);
|
||||
|
@ -431,7 +435,7 @@ namespace smt2 {
|
|||
m_ctx.regular_stream() << "(error : " << escaped(msg, true) << "\")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void unknown_sort(symbol id, char const* context = "") {
|
||||
std::string msg = context;
|
||||
if (context[0]) msg += ": ";
|
||||
|
@ -444,10 +448,10 @@ namespace smt2 {
|
|||
unsigned num_parens = 0;
|
||||
do {
|
||||
switch (curr()) {
|
||||
case scanner::LEFT_PAREN:
|
||||
num_parens++;
|
||||
case scanner::LEFT_PAREN:
|
||||
num_parens++;
|
||||
break;
|
||||
case scanner::RIGHT_PAREN:
|
||||
case scanner::RIGHT_PAREN:
|
||||
if (num_parens == 0)
|
||||
throw parser_exception("invalid s-expression, unexpected ')'");
|
||||
num_parens--;
|
||||
|
@ -565,7 +569,7 @@ namespace smt2 {
|
|||
else {
|
||||
if (ignore_unknow_sort)
|
||||
return 0;
|
||||
unknown_sort(id);
|
||||
unknown_sort(id);
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
@ -579,7 +583,7 @@ namespace smt2 {
|
|||
check_identifier("invalid indexed sort, symbol expected");
|
||||
symbol id = curr_id();
|
||||
psort_decl * d = m_ctx.find_psort_decl(id);
|
||||
if (d == 0)
|
||||
if (d == 0)
|
||||
unknown_sort(id);
|
||||
next();
|
||||
sbuffer<unsigned> args;
|
||||
|
@ -604,13 +608,13 @@ namespace smt2 {
|
|||
SASSERT(curr_is_identifier());
|
||||
symbol id = curr_id();
|
||||
psort_decl * d = m_ctx.find_psort_decl(id);
|
||||
if (d == 0)
|
||||
if (d == 0)
|
||||
unknown_sort(id);
|
||||
next();
|
||||
void * mem = m_stack.allocate(sizeof(psort_frame));
|
||||
new (mem) psort_frame(*this, d, psort_stack().size());
|
||||
}
|
||||
|
||||
|
||||
void pop_psort_app_frame() {
|
||||
SASSERT(curr_is_rparen());
|
||||
psort_frame * fr = static_cast<psort_frame*>(m_stack.top());
|
||||
|
@ -647,7 +651,7 @@ namespace smt2 {
|
|||
else {
|
||||
check_lparen_next("invalid sort, symbol, '_' or '(' expected");
|
||||
if (!curr_is_identifier())
|
||||
throw parser_exception("invalid sort, symbol or '_' expected");
|
||||
throw parser_exception("invalid sort, symbol or '_' expected");
|
||||
if (curr_id_is_underscore()) {
|
||||
psort_stack().push_back(pm().mk_psort_cnst(parse_indexed_sort()));
|
||||
}
|
||||
|
@ -665,13 +669,13 @@ namespace smt2 {
|
|||
SASSERT(curr_is_identifier());
|
||||
symbol id = curr_id();
|
||||
psort_decl * d = m_ctx.find_psort_decl(id);
|
||||
if (d == 0)
|
||||
if (d == 0)
|
||||
unknown_sort(id);
|
||||
next();
|
||||
void * mem = m_stack.allocate(sizeof(sort_frame));
|
||||
new (mem) sort_frame(*this, d, sort_stack().size());
|
||||
}
|
||||
|
||||
|
||||
void pop_sort_app_frame() {
|
||||
SASSERT(curr_is_rparen());
|
||||
sort_frame * fr = static_cast<sort_frame*>(m_stack.top());
|
||||
|
@ -710,8 +714,8 @@ namespace smt2 {
|
|||
}
|
||||
else {
|
||||
check_lparen_next("invalid sort, symbol, '_' or '(' expected");
|
||||
if (!curr_is_identifier())
|
||||
throw parser_exception(std::string(context) + " invalid sort, symbol or '_' expected");
|
||||
if (!curr_is_identifier())
|
||||
throw parser_exception(std::string(context) + " invalid sort, symbol or '_' expected");
|
||||
if (curr_id_is_underscore()) {
|
||||
sort_stack().push_back(parse_indexed_sort());
|
||||
}
|
||||
|
@ -726,7 +730,7 @@ namespace smt2 {
|
|||
}
|
||||
|
||||
unsigned parse_sorts(char const* context) {
|
||||
unsigned sz = 0;
|
||||
unsigned sz = 0;
|
||||
check_lparen_next(context);
|
||||
while (!curr_is_rparen()) {
|
||||
parse_sort(context);
|
||||
|
@ -949,7 +953,7 @@ namespace smt2 {
|
|||
}
|
||||
|
||||
// parse expression state
|
||||
enum pe_state {
|
||||
enum pe_state {
|
||||
PES_EXPR, // expecting <expr>
|
||||
PES_DECL, // expecting (<id> <expr>)
|
||||
PES_PATTERN,
|
||||
|
@ -1015,7 +1019,7 @@ namespace smt2 {
|
|||
else {
|
||||
// just consume pattern
|
||||
next();
|
||||
consume_sexpr();
|
||||
consume_sexpr();
|
||||
}
|
||||
}
|
||||
else if (id == m_nopattern) {
|
||||
|
@ -1036,7 +1040,7 @@ namespace smt2 {
|
|||
str << "unknown attribute " << id;
|
||||
warning_msg("%s", str.str().c_str());
|
||||
next();
|
||||
// just consume the
|
||||
// just consume the
|
||||
consume_sexpr();
|
||||
}
|
||||
if (curr_is_rparen())
|
||||
|
@ -1051,13 +1055,13 @@ namespace smt2 {
|
|||
switch (fr->m_kind) {
|
||||
case EF_LET:
|
||||
return static_cast<let_frame*>(fr)->m_in_decls ? PES_DECL : PES_EXPR;
|
||||
case EF_ATTR_EXPR:
|
||||
case EF_ATTR_EXPR:
|
||||
return consume_attributes(static_cast<attr_expr_frame*>(fr));
|
||||
default:
|
||||
return PES_EXPR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void parse_numeral(bool is_int) {
|
||||
SASSERT(!is_int || curr_is_int());
|
||||
SASSERT(is_int || curr_is_float());
|
||||
|
@ -1095,7 +1099,7 @@ namespace smt2 {
|
|||
expr_stack().push_back(0); // empty pattern
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (curr_is_lparen()) {
|
||||
// multi-pattern
|
||||
void * mem = m_stack.allocate(sizeof(pattern_frame));
|
||||
|
@ -1185,9 +1189,9 @@ namespace smt2 {
|
|||
SASSERT(curr_id_is_forall() || curr_id_is_exists());
|
||||
SASSERT(!is_forall || curr_id_is_forall());
|
||||
SASSERT(is_forall || curr_id_is_exists());
|
||||
next();
|
||||
next();
|
||||
void * mem = m_stack.allocate(sizeof(quant_frame));
|
||||
new (mem) quant_frame(is_forall, pattern_stack().size(), nopattern_stack().size(), symbol_stack().size(),
|
||||
new (mem) quant_frame(is_forall, pattern_stack().size(), nopattern_stack().size(), symbol_stack().size(),
|
||||
sort_stack().size(), expr_stack().size());
|
||||
m_num_expr_frames++;
|
||||
unsigned num_vars = parse_sorted_vars();
|
||||
|
@ -1229,11 +1233,11 @@ namespace smt2 {
|
|||
next();
|
||||
return r;
|
||||
}
|
||||
check_lparen_next("invalid (indexed) identifier, '(_' or symbol expected");
|
||||
check_lparen_next("invalid (indexed) identifier, '(_' or symbol expected");
|
||||
return parse_indexed_identifier_core();
|
||||
}
|
||||
|
||||
// parse:
|
||||
// parse:
|
||||
// 'as' <identifier> <sort> ')'
|
||||
// '_' <identifier> <num>+ ')'
|
||||
// 'as' <identifier '(' '_' <identifier> (<num>|<func-decl-ref>)+ ')' <sort> ')'
|
||||
|
@ -1255,7 +1259,7 @@ namespace smt2 {
|
|||
}
|
||||
}
|
||||
|
||||
// parse:
|
||||
// parse:
|
||||
// <identifier>
|
||||
// '(' 'as' <identifier> <sort> ')'
|
||||
// '(' '_' <identifier> <num>+ ')'
|
||||
|
@ -1281,8 +1285,8 @@ namespace smt2 {
|
|||
throw parser_exception(msg.c_str());
|
||||
}
|
||||
|
||||
rational m_last_bv_numeral; // for bv, bvbin, bvhex
|
||||
|
||||
rational m_last_bv_numeral; // for bv, bvbin, bvhex
|
||||
|
||||
// return true if *s == [0-9]+
|
||||
bool is_bv_decimal(char const * s) {
|
||||
TRACE("is_bv_num", tout << "is_bv_decimal: " << s << "\n";);
|
||||
|
@ -1321,7 +1325,7 @@ namespace smt2 {
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// return true if *s == hex[0-9,a-f,A-F]+
|
||||
bool is_bv_hex(char const * s) {
|
||||
SASSERT(*s == 'h');
|
||||
|
@ -1329,7 +1333,7 @@ namespace smt2 {
|
|||
if (*s != 'e') return false;
|
||||
++s;
|
||||
if (*s != 'x') return false;
|
||||
++s;
|
||||
++s;
|
||||
rational & n = m_last_bv_numeral;
|
||||
unsigned i = 0;
|
||||
n = rational(0);
|
||||
|
@ -1340,7 +1344,7 @@ namespace smt2 {
|
|||
}
|
||||
else if ('a' <= *s && *s <= 'f') {
|
||||
n *= rational(16);
|
||||
n += rational(10 + (*s - 'a'));
|
||||
n += rational(10 + (*s - 'a'));
|
||||
}
|
||||
else if ('A' <= *s && *s <= 'F') {
|
||||
n *= rational(16);
|
||||
|
@ -1357,11 +1361,11 @@ namespace smt2 {
|
|||
}
|
||||
}
|
||||
|
||||
// Return true if
|
||||
// Return true if
|
||||
// n == bv[0-9]+ OR
|
||||
// n == bvhex[0-9,a-f,A-F]+ OR
|
||||
// n == bvbin[0-1]+
|
||||
// It store the bit-vector value in m_last_bv_numeral
|
||||
// n == bvbin[0-1]+
|
||||
// It store the bit-vector value in m_last_bv_numeral
|
||||
bool is_bv_num(symbol const & n) {
|
||||
char const * s = n.bare_str();
|
||||
if (*s != 'b') return false;
|
||||
|
@ -1405,7 +1409,7 @@ namespace smt2 {
|
|||
}
|
||||
next();
|
||||
}
|
||||
|
||||
|
||||
// if has_as == true, then the sort of t must be equal to sort_stack().pop_back()
|
||||
// if that is the case, pop the top of sort_stack()
|
||||
void check_qualifier(expr * t, bool has_as) {
|
||||
|
@ -1543,7 +1547,7 @@ namespace smt2 {
|
|||
unsigned num_args = expr_stack().size() - fr->m_expr_spos;
|
||||
unsigned num_indices = m_param_stack.size() - fr->m_param_spos;
|
||||
expr_ref t_ref(m());
|
||||
m_ctx.mk_app(fr->m_f,
|
||||
m_ctx.mk_app(fr->m_f,
|
||||
num_args,
|
||||
expr_stack().c_ptr() + fr->m_expr_spos,
|
||||
num_indices,
|
||||
|
@ -1627,7 +1631,7 @@ namespace smt2 {
|
|||
fr->m_qid = symbol(m_scanner.get_line());
|
||||
if (!m().is_bool(expr_stack().back()))
|
||||
throw parser_exception("quantifier body must be a Boolean expression");
|
||||
quantifier * new_q = m().mk_quantifier(fr->m_forall,
|
||||
quantifier * new_q = m().mk_quantifier(fr->m_forall,
|
||||
num_decls,
|
||||
sort_stack().c_ptr() + fr->m_sort_spos,
|
||||
symbol_stack().c_ptr() + fr->m_sym_spos,
|
||||
|
@ -1688,7 +1692,7 @@ namespace smt2 {
|
|||
case EF_APP:
|
||||
pop_app_frame(static_cast<app_frame*>(fr));
|
||||
break;
|
||||
case EF_LET:
|
||||
case EF_LET:
|
||||
pop_let_frame(static_cast<let_frame*>(fr));
|
||||
break;
|
||||
case EF_LET_DECL:
|
||||
|
@ -1714,7 +1718,7 @@ namespace smt2 {
|
|||
void parse_expr() {
|
||||
m_num_expr_frames = 0;
|
||||
do {
|
||||
TRACE("parse_expr", tout << "curr(): " << curr() << ", m_num_expr_frames: " << m_num_expr_frames
|
||||
TRACE("parse_expr", tout << "curr(): " << curr() << ", m_num_expr_frames: " << m_num_expr_frames
|
||||
<< ", expr_stack().size(): " << expr_stack().size() << "\n";);
|
||||
if (curr_is_rparen()) {
|
||||
if (m_num_expr_frames == 0)
|
||||
|
@ -1798,7 +1802,7 @@ namespace smt2 {
|
|||
SASSERT(curr_is_identifier());
|
||||
SASSERT(curr_id() == m_declare_sort);
|
||||
next();
|
||||
|
||||
|
||||
check_identifier("invalid sort declaration, symbol expected");
|
||||
symbol id = curr_id();
|
||||
if (m_ctx.find_psort_decl(id) != 0)
|
||||
|
@ -1812,7 +1816,7 @@ namespace smt2 {
|
|||
check_int("invalid sort declaration, arity (<numeral>) or ')' expected");
|
||||
rational n = curr_numeral();
|
||||
if (!n.is_unsigned())
|
||||
throw parser_exception("invalid sort declaration, arity is too big to fit in an unsigned machine integer");
|
||||
throw parser_exception("invalid sort declaration, arity is too big to fit in an unsigned machine integer");
|
||||
psort_decl * decl = pm().mk_psort_user_decl(n.get_unsigned(), id, 0);
|
||||
m_ctx.insert(decl);
|
||||
next();
|
||||
|
@ -1872,12 +1876,12 @@ namespace smt2 {
|
|||
}
|
||||
|
||||
void parse_define_fun_rec() {
|
||||
// ( define-fun-rec hfun_defi )
|
||||
// ( define-fun-rec hfun_defi )
|
||||
SASSERT(curr_is_identifier());
|
||||
SASSERT(curr_id() == m_define_fun_rec);
|
||||
SASSERT(m_num_bindings == 0);
|
||||
next();
|
||||
|
||||
|
||||
expr_ref_vector binding(m());
|
||||
svector<symbol> ids;
|
||||
func_decl_ref f(m());
|
||||
|
@ -1890,7 +1894,7 @@ namespace smt2 {
|
|||
}
|
||||
|
||||
void parse_define_funs_rec() {
|
||||
// ( define-funs-rec ( hfun_decin+1 ) ( htermin+1 ) )
|
||||
// ( define-funs-rec ( hfun_decin+1 ) ( htermin+1 ) )
|
||||
SASSERT(curr_is_identifier());
|
||||
SASSERT(curr_id() == m_define_funs_rec);
|
||||
SASSERT(m_num_bindings == 0);
|
||||
|
@ -1920,14 +1924,14 @@ namespace smt2 {
|
|||
|
||||
check_lparen("invalid recursive function definition, '(' expected");
|
||||
next();
|
||||
|
||||
|
||||
parse_rec_fun_decl(f, binding, id);
|
||||
decls.push_back(f);
|
||||
bindings.push_back(binding);
|
||||
ids.push_back(id);
|
||||
|
||||
check_rparen("invalid recursive function definition, ')' expected");
|
||||
next();
|
||||
next();
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
@ -1950,7 +1954,7 @@ namespace smt2 {
|
|||
sort_stack().shrink(sort_spos);
|
||||
expr_stack().shrink(expr_spos);
|
||||
m_env.end_scope();
|
||||
m_num_bindings = 0;
|
||||
m_num_bindings = 0;
|
||||
}
|
||||
|
||||
void parse_rec_fun_bodies(func_decl_ref_vector const& decls, vector<expr_ref_vector> const& bindings, vector<svector<symbol> >const & ids) {
|
||||
|
@ -1963,10 +1967,10 @@ namespace smt2 {
|
|||
}
|
||||
|
||||
if (i != decls.size()) {
|
||||
throw parser_exception("the number of declarations does not match number of supplied definitions");
|
||||
throw parser_exception("the number of declarations does not match number of supplied definitions");
|
||||
}
|
||||
check_rparen("invalid recursive function definition, ')' expected");
|
||||
next();
|
||||
next();
|
||||
}
|
||||
|
||||
void parse_rec_fun_body(func_decl* f, expr_ref_vector const& bindings, svector<symbol> const& ids) {
|
||||
|
@ -1980,19 +1984,19 @@ namespace smt2 {
|
|||
for (unsigned i = 0; i < num_vars; ++i) {
|
||||
m_env.insert(ids[i], local(bindings[i], num_vars));
|
||||
}
|
||||
parse_expr();
|
||||
parse_expr();
|
||||
body = expr_stack().back();
|
||||
expr_stack().pop_back();
|
||||
symbol_stack().shrink(sym_spos);
|
||||
m_env.end_scope();
|
||||
m_num_bindings = 0;
|
||||
m_num_bindings = 0;
|
||||
if (m().get_sort(body) != f->get_range()) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "invalid function definition, sort mismatch. Expcected "
|
||||
<< mk_pp(f->get_range(), m()) << " but function body has sort "
|
||||
<< mk_pp(f->get_range(), m()) << " but function body has sort "
|
||||
<< mk_pp(m().get_sort(body), m());
|
||||
throw parser_exception(buffer.str().c_str());
|
||||
}
|
||||
}
|
||||
m_ctx.insert_rec_fun(f, bindings, ids, body);
|
||||
}
|
||||
|
||||
|
@ -2185,7 +2189,7 @@ namespace smt2 {
|
|||
unsigned spos = expr_stack().size();
|
||||
check_lparen_next("invalid check-sat-assuming command, '(', expected");
|
||||
parse_assumptions();
|
||||
check_rparen_next("invalid check-sat-assuming command, ')', expected");
|
||||
check_rparen_next("invalid check-sat-assuming command, ')', expected");
|
||||
m_ctx.check_sat(expr_stack().size() - spos, expr_stack().c_ptr() + spos);
|
||||
next();
|
||||
expr_stack().shrink(spos);
|
||||
|
@ -2201,7 +2205,7 @@ namespace smt2 {
|
|||
m_scanner.start_caching();
|
||||
m_cache_end = 0;
|
||||
m_cached_strings.resize(0);
|
||||
|
||||
|
||||
check_lparen_next("invalid get-value command, '(' expected");
|
||||
while (!curr_is_rparen()) {
|
||||
parse_expr();
|
||||
|
@ -2241,7 +2245,7 @@ namespace smt2 {
|
|||
SASSERT(curr_id() == m_reset);
|
||||
next();
|
||||
check_rparen("invalid reset command, ')' expected");
|
||||
m_ctx.reset();
|
||||
m_ctx.reset();
|
||||
reset();
|
||||
m_ctx.print_success();
|
||||
next();
|
||||
|
@ -2323,7 +2327,7 @@ namespace smt2 {
|
|||
}
|
||||
next();
|
||||
}
|
||||
|
||||
|
||||
void parse_next_cmd_arg() {
|
||||
SASSERT(m_curr_cmd != 0);
|
||||
cmd_arg_kind k = m_curr_cmd->next_arg_kind(m_ctx);
|
||||
|
@ -2332,7 +2336,7 @@ namespace smt2 {
|
|||
check_int("invalid command argument, unsigned integer expected");
|
||||
rational n = curr_numeral();
|
||||
if (!n.is_unsigned())
|
||||
throw parser_exception("invalid command argument, numeral is too big to fit in an unsigned machine integer");
|
||||
throw parser_exception("invalid command argument, numeral is too big to fit in an unsigned machine integer");
|
||||
m_curr_cmd->set_next_arg(m_ctx, n.get_unsigned());
|
||||
next();
|
||||
break;
|
||||
|
@ -2445,7 +2449,7 @@ namespace smt2 {
|
|||
m_curr_cmd = m_ctx.find_cmd(s);
|
||||
if (m_curr_cmd == 0) {
|
||||
parse_unknown_cmd();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
next();
|
||||
unsigned arity = m_curr_cmd->get_arity();
|
||||
|
@ -2475,14 +2479,14 @@ namespace smt2 {
|
|||
return;
|
||||
}
|
||||
else {
|
||||
if (arity != VAR_ARITY && i == arity)
|
||||
if (arity != VAR_ARITY && i == arity)
|
||||
throw parser_exception("invalid command, too many arguments");
|
||||
parse_next_cmd_arg();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void parse_cmd() {
|
||||
SASSERT(curr_is_lparen());
|
||||
int line = m_scanner.get_line();
|
||||
|
@ -2531,7 +2535,7 @@ namespace smt2 {
|
|||
return;
|
||||
}
|
||||
if (s == m_declare_datatypes) {
|
||||
parse_declare_datatypes();
|
||||
parse_declare_datatypes();
|
||||
return;
|
||||
}
|
||||
if (s == m_get_value) {
|
||||
|
@ -2558,8 +2562,8 @@ namespace smt2 {
|
|||
}
|
||||
|
||||
public:
|
||||
parser(cmd_context & ctx, std::istream & is, bool interactive, params_ref const & p):
|
||||
m_ctx(ctx),
|
||||
parser(cmd_context & ctx, std::istream & is, bool interactive, params_ref const & p, char const * filename=0):
|
||||
m_ctx(ctx),
|
||||
m_params(p),
|
||||
m_scanner(ctx, is, interactive),
|
||||
m_curr(scanner::NULL_TOKEN),
|
||||
|
@ -2597,14 +2601,15 @@ namespace smt2 {
|
|||
m_check_sat_assuming("check-sat-assuming"),
|
||||
m_define_fun_rec("define-fun-rec"),
|
||||
m_define_funs_rec("define-funs-rec"),
|
||||
m_underscore("_"),
|
||||
m_num_open_paren(0) {
|
||||
m_underscore("_"),
|
||||
m_num_open_paren(0),
|
||||
m_current_file(filename) {
|
||||
// the following assertion does not hold if ctx was already attached to an AST manager before the parser object is created.
|
||||
// SASSERT(!m_ctx.has_manager());
|
||||
|
||||
|
||||
updt_params();
|
||||
}
|
||||
|
||||
|
||||
~parser() {
|
||||
reset_stack();
|
||||
}
|
||||
|
@ -2615,7 +2620,7 @@ namespace smt2 {
|
|||
m_ignore_bad_patterns = p.ignore_bad_patterns();
|
||||
m_display_error_for_vs = p.error_for_visual_studio();
|
||||
}
|
||||
|
||||
|
||||
void reset() {
|
||||
reset_stack();
|
||||
m_num_bindings = 0;
|
||||
|
@ -2630,7 +2635,7 @@ namespace smt2 {
|
|||
m_env .reset();
|
||||
m_sort_id2param_idx .reset();
|
||||
m_dt_name2idx .reset();
|
||||
|
||||
|
||||
m_bv_util = 0;
|
||||
m_arith_util = 0;
|
||||
m_seq_util = 0;
|
||||
|
@ -2680,9 +2685,9 @@ namespace smt2 {
|
|||
return !found_errors;
|
||||
}
|
||||
catch (parser_exception & ex) {
|
||||
if (ex.has_pos())
|
||||
if (ex.has_pos())
|
||||
error(ex.line(), ex.pos(), ex.msg());
|
||||
else
|
||||
else
|
||||
error(ex.msg());
|
||||
}
|
||||
catch (ast_exception & ex) {
|
||||
|
@ -2705,8 +2710,8 @@ namespace smt2 {
|
|||
};
|
||||
};
|
||||
|
||||
bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive, params_ref const & ps) {
|
||||
smt2::parser p(ctx, is, interactive, ps);
|
||||
bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive, params_ref const & ps, char const * filename) {
|
||||
smt2::parser p(ctx, is, interactive, ps, filename);
|
||||
return p();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,6 @@ Revision History:
|
|||
|
||||
#include"cmd_context.h"
|
||||
|
||||
bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive = false, params_ref const & p = params_ref());
|
||||
bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive = false, params_ref const & p = params_ref(), char const * filename = 0);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,530 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sat_bceq.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Find equivalent literals based on blocked clause decomposition.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2014-09-27.
|
||||
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"sat_bceq.h"
|
||||
#include"sat_solver.h"
|
||||
#include"trace.h"
|
||||
#include"bit_vector.h"
|
||||
#include"map.h"
|
||||
#include"sat_elim_eqs.h"
|
||||
|
||||
namespace sat {
|
||||
|
||||
void bceq::use_list::init(unsigned num_vars) {
|
||||
m_clauses.reset();
|
||||
m_clauses.resize(2*num_vars);
|
||||
}
|
||||
|
||||
void bceq::use_list::insert(clause& c) {
|
||||
unsigned sz = c.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
m_clauses[c[i].index()].push_back(&c);
|
||||
}
|
||||
}
|
||||
|
||||
void bceq::use_list::erase(clause& c) {
|
||||
unsigned sz = c.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
m_clauses[c[i].index()].erase(&c);
|
||||
}
|
||||
}
|
||||
|
||||
ptr_vector<clause>& bceq::use_list::get(literal lit) {
|
||||
return m_clauses[lit.index()];
|
||||
}
|
||||
|
||||
bceq::bceq(solver & s):
|
||||
m_solver(s) {
|
||||
}
|
||||
|
||||
void bceq::register_clause(clause* cls) {
|
||||
m_clauses.setx(cls->id(), cls, 0);
|
||||
}
|
||||
|
||||
void bceq::unregister_clause(clause* cls) {
|
||||
m_clauses.setx(cls->id(), 0, 0);
|
||||
}
|
||||
|
||||
void bceq::init() {
|
||||
m_clauses.reset();
|
||||
m_bin_clauses.reset();
|
||||
m_L.reset();
|
||||
m_R.reset();
|
||||
m_L_blits.reset();
|
||||
m_R_blits.reset();
|
||||
m_bce_use_list.reset();
|
||||
clause * const* it = m_solver.begin_clauses();
|
||||
clause * const* end = m_solver.end_clauses();
|
||||
for (; it != end; ++it) {
|
||||
clause* cls = *it;
|
||||
if (!cls->was_removed()) {
|
||||
m_use_list->insert(*cls);
|
||||
register_clause(cls);
|
||||
}
|
||||
}
|
||||
bin_clauses bc;
|
||||
m_solver.collect_bin_clauses(bc, false); // exclude roots.
|
||||
literal lits[2];
|
||||
for (unsigned i = 0; i < bc.size(); ++i) {
|
||||
lits[0] = bc[i].first;
|
||||
lits[1] = bc[i].second;
|
||||
clause* cls = m_solver.m_cls_allocator.mk_clause(2, lits, false);
|
||||
m_use_list->insert(*cls);
|
||||
m_bin_clauses.push_back(cls);
|
||||
register_clause(cls);
|
||||
}
|
||||
TRACE("sat",
|
||||
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||
clause const* cls = m_clauses[i];
|
||||
if (cls) tout << *cls << "\n";
|
||||
});
|
||||
}
|
||||
|
||||
void bceq::pure_decompose() {
|
||||
// while F != empty
|
||||
// pick a clause and variable x in clause.
|
||||
// get use list U1 of x and U2 of ~x
|
||||
// assume |U1| >= |U2|
|
||||
// add U1 to clause set.
|
||||
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||
clause* cls = m_clauses[i];
|
||||
if (cls) {
|
||||
SASSERT(i == cls->id());
|
||||
pure_decompose((*cls)[0]);
|
||||
SASSERT(!m_clauses[i]);
|
||||
}
|
||||
}
|
||||
m_L.reverse();
|
||||
m_L_blits.reverse();
|
||||
}
|
||||
|
||||
void bceq::pure_decompose(literal lit) {
|
||||
clause_use_list& pos = m_use_list->get(lit);
|
||||
clause_use_list& neg = m_use_list->get(~lit);
|
||||
unsigned sz1 = m_L.size();
|
||||
unsigned sz2 = m_R.size();
|
||||
pure_decompose(pos, m_L);
|
||||
pure_decompose(neg, m_R);
|
||||
unsigned delta1 = m_L.size() - sz1;
|
||||
unsigned delta2 = m_R.size() - sz2;
|
||||
if (delta1 < delta2) {
|
||||
m_L_blits.resize(sz1+delta2, ~lit);
|
||||
m_R_blits.resize(sz2+delta1, lit);
|
||||
for (unsigned i = 0; i < delta1; ++i) {
|
||||
std::swap(m_L[sz1 + i], m_R[sz2 + i]);
|
||||
}
|
||||
for (unsigned i = delta1; i < delta2; ++i) {
|
||||
m_L.push_back(m_R[sz2 + i]);
|
||||
}
|
||||
m_R.resize(sz2 + delta1);
|
||||
std::swap(delta1, delta2);
|
||||
}
|
||||
else {
|
||||
m_L_blits.resize(sz1+delta1, lit);
|
||||
m_R_blits.resize(sz2+delta2, ~lit);
|
||||
}
|
||||
TRACE("bceq", tout << lit << " " << "pos: " << delta1 << " " << "neg: " << delta2 << "\n";);
|
||||
}
|
||||
|
||||
void bceq::pure_decompose(clause_use_list& uses, svector<clause*>& clauses) {
|
||||
unsigned sz = uses.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
clause& cls = *uses[i];
|
||||
if (!cls.was_removed() && m_clauses[cls.id()]) {
|
||||
clauses.push_back(&cls);
|
||||
m_clauses[cls.id()] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bceq::post_decompose() {
|
||||
m_marked.reset();
|
||||
m_marked.resize(2*m_solver.num_vars(), false);
|
||||
use_list ul;
|
||||
use_list* save = m_use_list;
|
||||
m_use_list = &ul;
|
||||
ul.init(m_solver.num_vars());
|
||||
for (unsigned i = 0; i < m_L.size(); ++i) {
|
||||
ul.insert(*m_L[i]);
|
||||
}
|
||||
|
||||
// cheap pass: add clauses from R in order
|
||||
// such that they are blocked with respect to
|
||||
// predecessors.
|
||||
m_removed.reset();
|
||||
for (unsigned i = 0; i < m_R.size(); ++i) {
|
||||
literal lit = find_blocked(*m_R[i]);
|
||||
if (lit != null_literal) {
|
||||
m_L.push_back(m_R[i]);
|
||||
m_L_blits.push_back(lit);
|
||||
ul.insert(*m_R[i]);
|
||||
m_R[i] = m_R.back();
|
||||
m_R_blits[i] = m_R_blits.back();
|
||||
m_R.pop_back();
|
||||
m_R_blits.pop_back();
|
||||
--i;
|
||||
}
|
||||
}
|
||||
// expensive pass: add clauses from R as long
|
||||
// as BCE produces the empty set of clauses.
|
||||
m_bce_use_list.init(m_solver.num_vars());
|
||||
for (unsigned i = 0; i < m_L.size(); ++i) {
|
||||
m_bce_use_list.insert(*m_L[i]);
|
||||
}
|
||||
for (unsigned i = 0; i < m_R.size(); ++i) {
|
||||
if (bce(*m_R[i])) {
|
||||
m_R[i] = m_R.back();
|
||||
m_R_blits[i] = m_R_blits.back();
|
||||
m_R.pop_back();
|
||||
m_R_blits.pop_back();
|
||||
--i;
|
||||
}
|
||||
}
|
||||
m_use_list = save;
|
||||
}
|
||||
|
||||
|
||||
// Note: replay blocked clause elimination:
|
||||
// Suppose C u { c1 } is blocked.
|
||||
// annotate each clause by blocking literal.
|
||||
// for new clause c2, check if C u { c2 } is blocked.
|
||||
// For each c in C record which literal it is blocked.
|
||||
// (Order the clauses in C by block ordering)
|
||||
// l | c is blocked,
|
||||
// -> c2 contains ~l => check if c c2 is blocked
|
||||
//
|
||||
bool bceq::bce(clause& cls0) {
|
||||
IF_VERBOSE(1, verbose_stream() << "bce " << m_L.size() << " " << m_R.size() << " " << cls0 << "\n";);
|
||||
unsigned_vector& live_clauses = m_live_clauses;
|
||||
live_clauses.reset();
|
||||
m_use_list = &m_bce_use_list;
|
||||
m_bce_use_list.insert(cls0);
|
||||
svector<clause*>& clauses = m_L;
|
||||
literal_vector& blits = m_L_blits;
|
||||
clauses.push_back(&cls0);
|
||||
blits.push_back(null_literal);
|
||||
bool removed = false;
|
||||
m_removed.reset();
|
||||
for (unsigned i = 0; i < clauses.size(); ++i) {
|
||||
clause& cls1 = *clauses[i];
|
||||
literal lit = find_blocked(cls1);
|
||||
if (lit == null_literal) {
|
||||
live_clauses.push_back(i);
|
||||
}
|
||||
else {
|
||||
m_removed.setx(cls1.id(), true, false);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
while (removed) {
|
||||
removed = false;
|
||||
//std::cout << live_clauses.size() << " ";
|
||||
for (unsigned i = 0; i < live_clauses.size(); ++i) {
|
||||
clause& cls1 = *clauses[live_clauses[i]];
|
||||
literal lit = find_blocked(cls1);
|
||||
if (lit != null_literal) {
|
||||
m_removed.setx(cls1.id(), true, false);
|
||||
removed = true;
|
||||
live_clauses[i] = live_clauses.back();
|
||||
live_clauses.pop_back();
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
//std::cout << "\n";
|
||||
m_bce_use_list.erase(cls0);
|
||||
clauses.pop_back();
|
||||
blits.pop_back();
|
||||
return live_clauses.empty();
|
||||
}
|
||||
|
||||
literal bceq::find_blocked(clause const& cls) {
|
||||
TRACE("bceq", tout << cls << "\n";);
|
||||
|
||||
unsigned sz = cls.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
m_marked[(~cls[i]).index()] = true;
|
||||
}
|
||||
literal result = null_literal;
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
literal lit = cls[i];
|
||||
if (is_blocked(lit)) {
|
||||
TRACE("bceq", tout << "is blocked " << lit << " : " << cls << "\n";);
|
||||
result = lit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
m_marked[(~cls[i]).index()] = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool bceq::is_blocked(literal lit) const {
|
||||
clause_use_list& uses = m_use_list->get(~lit);
|
||||
unsigned sz = uses.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
clause const& cls = *uses[i];
|
||||
unsigned sz = cls.size();
|
||||
bool is_axiom = m_removed.get(cls.id(), false);
|
||||
for (unsigned i = 0; !is_axiom && i < sz; ++i) {
|
||||
is_axiom = m_marked[cls[i].index()] && cls[i] != ~lit;
|
||||
}
|
||||
|
||||
TRACE("bceq", tout << "resolvent " << lit << " : " << cls << " " << (is_axiom?"axiom":"non-axiom") << "\n";);
|
||||
if (!is_axiom) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void bceq::init_rbits() {
|
||||
m_rbits.reset();
|
||||
for (unsigned i = 0; i < m_solver.num_vars(); ++i) {
|
||||
uint64 lo = m_rand() + (m_rand() << 16);
|
||||
uint64 hi = m_rand() + (m_rand() << 16);
|
||||
m_rbits.push_back(lo + (hi << 32ULL));
|
||||
}
|
||||
}
|
||||
|
||||
void bceq::init_reconstruction_stack() {
|
||||
m_rstack.reset();
|
||||
m_bstack.reset();
|
||||
// decomposition already creates a blocked stack in the proper order.
|
||||
m_rstack.append(m_L);
|
||||
m_bstack.append(m_L_blits);
|
||||
}
|
||||
|
||||
uint64 bceq::eval_clause(clause const& cls) const {
|
||||
uint64 b = 0;
|
||||
unsigned sz = cls.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
literal lit = cls[i];
|
||||
uint64 val = m_rbits[lit.var()];
|
||||
if (lit.sign()) {
|
||||
val = ~val;
|
||||
}
|
||||
b |= val;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void bceq::sat_sweep() {
|
||||
init_rbits();
|
||||
init_reconstruction_stack();
|
||||
for (unsigned i = 0; i < m_rstack.size(); ++i) {
|
||||
clause const& cls = *m_rstack[i];
|
||||
literal block_lit = m_bstack[i];
|
||||
uint64 b = eval_clause(cls);
|
||||
// v = 0, b = 0 -> v := 1
|
||||
// v = 0, b = 1 -> v := 0
|
||||
// v = 1, b = 0 -> v := 0
|
||||
// v = 1, b = 1 -> v := 1
|
||||
m_rbits[block_lit.var()] ^= ~b;
|
||||
|
||||
}
|
||||
DEBUG_CODE(verify_sweep(););
|
||||
}
|
||||
|
||||
void bceq::verify_sweep() {
|
||||
DEBUG_CODE(
|
||||
for (unsigned i = 0; i < m_L.size(); ++i) {
|
||||
uint64 b = eval_clause(*m_L[i]);
|
||||
SASSERT((~b) == 0);
|
||||
});
|
||||
}
|
||||
|
||||
struct u64_hash { unsigned operator()(uint64 u) const { return (unsigned)u; } };
|
||||
|
||||
struct u64_eq { bool operator()(uint64 u1, uint64 u2) const { return u1 == u2; } };
|
||||
|
||||
void bceq::extract_partition() {
|
||||
unsigned num_vars = m_solver.num_vars();
|
||||
map<uint64, unsigned, u64_hash, u64_eq> table;
|
||||
union_find<> union_find(m_union_find_ctx);
|
||||
for (unsigned i = 0; i < num_vars; ++i) {
|
||||
m_s->mk_var(true, true);
|
||||
union_find.mk_var();
|
||||
}
|
||||
for (unsigned i = 0; i < m_L.size(); ++i) {
|
||||
m_s->mk_clause(m_L[i]->size(), m_L[i]->begin());
|
||||
}
|
||||
for (unsigned i = 0; i < num_vars; ++i) {
|
||||
uint64 val = m_rbits[i];
|
||||
unsigned index;
|
||||
if (table.find(val, index)) {
|
||||
union_find.merge(i, index);
|
||||
}
|
||||
else if (table.find(~val, index)) {
|
||||
union_find.merge(i, index);
|
||||
}
|
||||
else {
|
||||
table.insert(val, i);
|
||||
}
|
||||
}
|
||||
TRACE("sat", union_find.display(tout););
|
||||
|
||||
//
|
||||
// Preliminary version:
|
||||
// A more appropriate is to walk each pair,
|
||||
// and refine partition based on SAT results.
|
||||
//
|
||||
for (unsigned i = 0; i < num_vars; ++i) {
|
||||
if (!union_find.is_root(i)) continue;
|
||||
unsigned v = union_find.next(i);
|
||||
unsigned last_v = UINT_MAX;
|
||||
if (!m_solver.was_eliminated(i)) {
|
||||
last_v = i;
|
||||
}
|
||||
while (v != i) {
|
||||
if (!m_solver.was_eliminated(v)) {
|
||||
if (last_v != UINT_MAX) {
|
||||
if (check_equality(v, last_v)) {
|
||||
// last_v was eliminated.
|
||||
|
||||
}
|
||||
else {
|
||||
// TBD: refine partition.
|
||||
}
|
||||
}
|
||||
last_v = v;
|
||||
}
|
||||
v = union_find.next(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bceq::check_equality(unsigned v1, unsigned v2) {
|
||||
TRACE("sat", tout << "check: " << v1 << " = " << v2 << "\n";);
|
||||
uint64 val1 = m_rbits[v1];
|
||||
uint64 val2 = m_rbits[v2];
|
||||
literal l1 = literal(v1, false);
|
||||
literal l2 = literal(v2, false);
|
||||
if (val1 != val2) {
|
||||
SASSERT(val1 == ~val2);
|
||||
l2.neg();
|
||||
}
|
||||
if (is_already_equiv(l1, l2)) {
|
||||
TRACE("sat", tout << "Already equivalent: " << l1 << " " << l2 << "\n";);
|
||||
return false;
|
||||
}
|
||||
|
||||
literal lits[2];
|
||||
lits[0] = l1;
|
||||
lits[1] = ~l2;
|
||||
lbool is_sat = m_s->check(2, lits);
|
||||
if (is_sat == l_false) {
|
||||
lits[0] = ~l1;
|
||||
lits[1] = l2;
|
||||
is_sat = m_s->check(2, lits);
|
||||
}
|
||||
if (is_sat == l_false) {
|
||||
TRACE("sat", tout << "Found equivalent: " << l1 << " " << l2 << "\n";);
|
||||
assert_equality(l1, l2);
|
||||
}
|
||||
else {
|
||||
TRACE("sat", tout << "Not equivalent: " << l1 << " " << l2 << "\n";);
|
||||
// TBD: if is_sat == l_true, then refine partition.
|
||||
}
|
||||
return is_sat == l_false;
|
||||
}
|
||||
|
||||
bool bceq::is_already_equiv(literal l1, literal l2) {
|
||||
watch_list const& w1 = m_solver.get_wlist(l1);
|
||||
bool found = false;
|
||||
for (unsigned i = 0; !found && i < w1.size(); ++i) {
|
||||
watched const& w = w1[i];
|
||||
found = w.is_binary_clause() && w.get_literal() == ~l2;
|
||||
}
|
||||
if (!found) return false;
|
||||
found = false;
|
||||
watch_list const& w2 = m_solver.get_wlist(~l1);
|
||||
for (unsigned i = 0; !found && i < w2.size(); ++i) {
|
||||
watched const& w = w2[i];
|
||||
found = w.is_binary_clause() && w.get_literal() == l2;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void bceq::assert_equality(literal l1, literal l2) {
|
||||
if (l2.sign()) {
|
||||
l1.neg();
|
||||
l2.neg();
|
||||
}
|
||||
literal_vector roots;
|
||||
bool_var_vector vars;
|
||||
for (unsigned i = 0; i < m_solver.num_vars(); ++i) {
|
||||
roots.push_back(literal(i, false));
|
||||
}
|
||||
roots[l2.var()] = l1;
|
||||
vars.push_back(l2.var());
|
||||
elim_eqs elim(m_solver);
|
||||
IF_VERBOSE(1,
|
||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
||||
verbose_stream() << "var: " << vars[i] << " root: " << roots[vars[i]] << "\n";
|
||||
});
|
||||
elim(roots, vars);
|
||||
}
|
||||
|
||||
void bceq::cleanup() {
|
||||
m_solver.del_clauses(m_bin_clauses.begin(), m_bin_clauses.end());
|
||||
m_bin_clauses.reset();
|
||||
}
|
||||
|
||||
|
||||
void bceq::operator()() {
|
||||
if (!m_solver.m_config.m_bcd) return;
|
||||
flet<bool> _disable_bcd(m_solver.m_config.m_bcd, false);
|
||||
flet<bool> _disable_min(m_solver.m_config.m_core_minimize, false);
|
||||
flet<bool> _disable_opt(m_solver.m_config.m_optimize_model, false);
|
||||
flet<unsigned> _bound_maxc(m_solver.m_config.m_max_conflicts, 1500);
|
||||
|
||||
use_list ul;
|
||||
solver s(m_solver.m_params, m_solver.rlimit(), 0);
|
||||
s.m_config.m_bcd = false;
|
||||
s.m_config.m_core_minimize = false;
|
||||
s.m_config.m_optimize_model = false;
|
||||
s.m_config.m_max_conflicts = 1500;
|
||||
m_use_list = &ul;
|
||||
m_s = &s;
|
||||
ul.init(m_solver.num_vars());
|
||||
init();
|
||||
pure_decompose();
|
||||
post_decompose();
|
||||
IF_VERBOSE(1, verbose_stream() << "Decomposed set " << m_L.size() << " rest: " << m_R.size() << "\n";);
|
||||
|
||||
TRACE("sat",
|
||||
tout << "Decomposed set " << m_L.size() << "\n";
|
||||
for (unsigned i = 0; i < m_L.size(); ++i) {
|
||||
clause const* cls = m_L[i];
|
||||
if (cls) tout << *cls << "\n";
|
||||
}
|
||||
tout << "remainder " << m_R.size() << "\n";
|
||||
for (unsigned i = 0; i < m_R.size(); ++i) {
|
||||
clause const* cls = m_R[i];
|
||||
if (cls) tout << *cls << "\n";
|
||||
}
|
||||
);
|
||||
sat_sweep();
|
||||
extract_partition();
|
||||
cleanup();
|
||||
}
|
||||
};
|
|
@ -1,89 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sat_bceq.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Find equivalent literals based on blocked clause decomposition.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2014-09-27.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef SAT_BCEQ_H_
|
||||
#define SAT_BCEQ_H_
|
||||
|
||||
#include"sat_types.h"
|
||||
#include"union_find.h"
|
||||
|
||||
|
||||
namespace sat {
|
||||
class solver;
|
||||
|
||||
class bceq {
|
||||
typedef ptr_vector<clause> clause_use_list;
|
||||
class use_list {
|
||||
vector<ptr_vector<clause> > m_clauses;
|
||||
public:
|
||||
use_list() {}
|
||||
void init(unsigned num_vars);
|
||||
void reset() { m_clauses.reset(); }
|
||||
void erase(clause& c);
|
||||
void insert(clause& c);
|
||||
ptr_vector<clause>& get(literal lit);
|
||||
};
|
||||
typedef std::pair<literal, literal> bin_clause;
|
||||
typedef svector<bin_clause> bin_clauses;
|
||||
solver & m_solver;
|
||||
use_list* m_use_list;
|
||||
use_list m_bce_use_list;
|
||||
solver* m_s;
|
||||
random_gen m_rand;
|
||||
svector<clause*> m_clauses;
|
||||
svector<clause*> m_L;
|
||||
svector<clause*> m_R;
|
||||
literal_vector m_L_blits;
|
||||
literal_vector m_R_blits;
|
||||
svector<clause*> m_bin_clauses;
|
||||
svector<uint64> m_rbits;
|
||||
svector<clause*> m_rstack; // stack of blocked clauses
|
||||
literal_vector m_bstack; // stack of blocking literals
|
||||
svector<bool> m_marked;
|
||||
svector<bool> m_removed; // set of clauses removed (not considered in clause set during BCE)
|
||||
union_find_default_ctx m_union_find_ctx;
|
||||
unsigned_vector m_live_clauses;
|
||||
|
||||
void init();
|
||||
void register_clause(clause* cls);
|
||||
void unregister_clause(clause* cls);
|
||||
void pure_decompose();
|
||||
void pure_decompose(literal lit);
|
||||
void pure_decompose(ptr_vector<clause>& uses, svector<clause*>& clauses);
|
||||
void post_decompose();
|
||||
literal find_blocked(clause const& cls);
|
||||
bool bce(clause& cls);
|
||||
bool is_blocked(literal lit) const;
|
||||
void init_rbits();
|
||||
void init_reconstruction_stack();
|
||||
void sat_sweep();
|
||||
void cleanup();
|
||||
uint64 eval_clause(clause const& cls) const;
|
||||
void verify_sweep();
|
||||
void extract_partition();
|
||||
bool check_equality(unsigned v1, unsigned v2);
|
||||
bool is_already_equiv(literal l1, literal l2);
|
||||
void assert_equality(literal l1, literal l2);
|
||||
public:
|
||||
bceq(solver & s);
|
||||
void operator()();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -23,10 +23,10 @@ Revision History:
|
|||
namespace sat {
|
||||
|
||||
config::config(params_ref const & p):
|
||||
m_restart_max(0),
|
||||
m_always_true("always_true"),
|
||||
m_always_false("always_false"),
|
||||
m_caching("caching"),
|
||||
m_restart_max(0),
|
||||
m_random("random"),
|
||||
m_geometric("geometric"),
|
||||
m_luby("luby"),
|
||||
|
@ -111,8 +111,6 @@ namespace sat {
|
|||
m_minimize_lemmas = p.minimize_lemmas();
|
||||
m_core_minimize = p.core_minimize();
|
||||
m_core_minimize_partial = p.core_minimize_partial();
|
||||
m_optimize_model = p.optimize_model();
|
||||
m_bcd = p.bcd();
|
||||
m_dyn_sub_res = p.dyn_sub_res();
|
||||
}
|
||||
|
||||
|
|
|
@ -72,8 +72,6 @@ namespace sat {
|
|||
bool m_dyn_sub_res;
|
||||
bool m_core_minimize;
|
||||
bool m_core_minimize_partial;
|
||||
bool m_optimize_model;
|
||||
bool m_bcd;
|
||||
|
||||
|
||||
symbol m_always_true;
|
||||
|
|
|
@ -20,11 +20,10 @@ Notes:
|
|||
|
||||
#include "sat_solver.h"
|
||||
#include "sat_mus.h"
|
||||
#include "sat_sls.h"
|
||||
|
||||
namespace sat {
|
||||
|
||||
mus::mus(solver& s):s(s), m_is_active(false), m_best_value(0), m_restart(0), m_max_restarts(0) {}
|
||||
mus::mus(solver& s):s(s), m_is_active(false),m_restart(0), m_max_restarts(0) {}
|
||||
|
||||
mus::~mus() {}
|
||||
|
||||
|
@ -32,7 +31,6 @@ namespace sat {
|
|||
m_core.reset();
|
||||
m_mus.reset();
|
||||
m_model.reset();
|
||||
m_best_value = 0;
|
||||
m_max_restarts = (s.m_stats.m_restart - m_restart) + 10;
|
||||
m_restart = s.m_stats.m_restart;
|
||||
}
|
||||
|
@ -45,21 +43,13 @@ namespace sat {
|
|||
}
|
||||
|
||||
void mus::update_model() {
|
||||
double new_value = s.m_wsls.evaluate_model(s.m_model);
|
||||
if (m_model.empty()) {
|
||||
m_model.append(s.m_model);
|
||||
m_best_value = new_value;
|
||||
}
|
||||
else if (m_best_value > new_value) {
|
||||
m_model.reset();
|
||||
m_model.append(s.m_model);
|
||||
m_best_value = new_value;
|
||||
}
|
||||
}
|
||||
|
||||
lbool mus::operator()() {
|
||||
flet<bool> _disable_min(s.m_config.m_core_minimize, false);
|
||||
flet<bool> _disable_opt(s.m_config.m_optimize_model, false);
|
||||
flet<bool> _is_active(m_is_active, true);
|
||||
IF_VERBOSE(3, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
|
||||
reset();
|
||||
|
@ -120,9 +110,6 @@ namespace sat {
|
|||
SASSERT(value_at(lit, s.get_model()) == l_false);
|
||||
mus.push_back(lit);
|
||||
update_model();
|
||||
if (!core.empty()) {
|
||||
// mr(); // TBD: measure
|
||||
}
|
||||
break;
|
||||
}
|
||||
case l_false:
|
||||
|
@ -262,27 +249,5 @@ namespace sat {
|
|||
IF_VERBOSE(3, verbose_stream() << "core verification: " << is_sat << " " << core << "\n";);
|
||||
}
|
||||
|
||||
void mus::mr() {
|
||||
sls sls(s);
|
||||
literal_vector tabu;
|
||||
tabu.append(m_mus);
|
||||
tabu.append(m_core);
|
||||
bool reuse_model = false;
|
||||
for (unsigned i = m_mus.size(); i < tabu.size(); ++i) {
|
||||
tabu[i] = ~tabu[i];
|
||||
lbool is_sat = sls(tabu.size(), tabu.c_ptr(), reuse_model);
|
||||
tabu[i] = ~tabu[i];
|
||||
if (is_sat == l_true) {
|
||||
m_mus.push_back(tabu[i]);
|
||||
m_core.erase(tabu[i]);
|
||||
IF_VERBOSE(3, verbose_stream() << "in core " << tabu[i] << "\n";);
|
||||
reuse_model = true;
|
||||
}
|
||||
else {
|
||||
IF_VERBOSE(3, verbose_stream() << "NOT in core " << tabu[i] << "\n";);
|
||||
reuse_model = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace sat {
|
|||
literal_vector m_mus;
|
||||
bool m_is_active;
|
||||
model m_model; // model obtained during minimal unsat core
|
||||
double m_best_value;
|
||||
unsigned m_restart;
|
||||
unsigned m_max_restarts;
|
||||
|
||||
|
@ -41,7 +40,6 @@ namespace sat {
|
|||
lbool mus1();
|
||||
lbool mus2();
|
||||
lbool qx(literal_set& assignment, literal_set& support, bool has_support);
|
||||
void mr();
|
||||
void reset();
|
||||
void set_core();
|
||||
void update_model();
|
||||
|
|
|
@ -7,7 +7,7 @@ def_module_params('sat',
|
|||
('phase.caching.off', UINT, 100, 'phase caching off period (in number of conflicts)'),
|
||||
('restart', SYMBOL, 'luby', 'restart strategy: luby or geometric'),
|
||||
('restart.initial', UINT, 100, 'initial restart (number of conflicts)'),
|
||||
('restart.max', UINT, 0, 'maximal number of restarts. Ignored if set to 0'),
|
||||
('restart.max', UINT, UINT_MAX, 'maximal number of restarts.'),
|
||||
('restart.factor', DOUBLE, 1.5, 'restart increment factor for geometric strategy'),
|
||||
('random_freq', DOUBLE, 0.01, 'frequency of random case splits'),
|
||||
('random_seed', UINT, 0, 'random seed'),
|
||||
|
@ -22,6 +22,4 @@ def_module_params('sat',
|
|||
('dyn_sub_res', BOOL, True, 'dynamic subsumption resolution for minimizing learned clauses'),
|
||||
('core.minimize', BOOL, False, 'minimize computed core'),
|
||||
('core.minimize_partial', BOOL, False, 'apply partial (cheap) core minimization'),
|
||||
('optimize_model', BOOL, False, 'enable optimization of soft constraints'),
|
||||
('bcd', BOOL, False, 'enable blocked clause decomposition for equality extraction'),
|
||||
('dimacs.core', BOOL, False, 'extract core from DIMACS benchmarks')))
|
||||
|
|
|
@ -1,686 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sat_sls.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
SLS for clauses in SAT solver
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2014-12-8
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
|
||||
#include "sat_sls.h"
|
||||
#include "sat_solver.h"
|
||||
|
||||
namespace sat {
|
||||
|
||||
bool index_set::contains(unsigned idx) const {
|
||||
return
|
||||
(idx < m_index.size()) &&
|
||||
(m_index[idx] < m_elems.size()) &&
|
||||
(m_elems[m_index[idx]] == idx);
|
||||
}
|
||||
|
||||
void index_set::insert(unsigned idx) {
|
||||
m_index.reserve(idx+1);
|
||||
if (!contains(idx)) {
|
||||
m_index[idx] = m_elems.size();
|
||||
m_elems.push_back(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void index_set::remove(unsigned idx) {
|
||||
if (!contains(idx)) return;
|
||||
unsigned pos = m_index[idx];
|
||||
m_elems[pos] = m_elems.back();
|
||||
m_index[m_elems[pos]] = pos;
|
||||
m_elems.pop_back();
|
||||
}
|
||||
|
||||
unsigned index_set::choose(random_gen& rnd) const {
|
||||
SASSERT(!empty());
|
||||
return m_elems[rnd(num_elems())];
|
||||
}
|
||||
|
||||
sls::sls(solver& s): s(s) {
|
||||
m_prob_choose_min_var = 43;
|
||||
m_clause_generation = 0;
|
||||
}
|
||||
|
||||
sls::~sls() {
|
||||
for (unsigned i = 0; i < m_bin_clauses.size(); ++i) {
|
||||
m_alloc.del_clause(m_bin_clauses[i]);
|
||||
}
|
||||
}
|
||||
|
||||
lbool sls::operator()(unsigned sz, literal const* tabu, bool reuse_model) {
|
||||
init(sz, tabu, reuse_model);
|
||||
unsigned i;
|
||||
for (i = 0; !m_false.empty() && !s.canceled() && i < m_max_tries; ++i) {
|
||||
flip();
|
||||
}
|
||||
IF_VERBOSE(2, verbose_stream() << "tries " << i << "\n";);
|
||||
if (m_false.empty()) {
|
||||
SASSERT(s.check_model(m_model));
|
||||
return l_true;
|
||||
}
|
||||
return l_undef;
|
||||
}
|
||||
|
||||
void sls::init(unsigned sz, literal const* tabu, bool reuse_model) {
|
||||
bool same_generation = (m_clause_generation == s.m_stats.m_non_learned_generation);
|
||||
if (!same_generation) {
|
||||
init_clauses();
|
||||
init_use();
|
||||
IF_VERBOSE(0, verbose_stream() << s.m_stats.m_non_learned_generation << " " << m_clause_generation << "\n";);
|
||||
}
|
||||
if (!reuse_model) {
|
||||
init_model();
|
||||
}
|
||||
init_tabu(sz, tabu);
|
||||
m_clause_generation = s.m_stats.m_non_learned_generation;
|
||||
|
||||
m_max_tries = 10*(s.num_vars() + m_clauses.size());
|
||||
|
||||
}
|
||||
|
||||
void sls::init_clauses() {
|
||||
for (unsigned i = 0; i < m_bin_clauses.size(); ++i) {
|
||||
m_alloc.del_clause(m_bin_clauses[i]);
|
||||
}
|
||||
m_bin_clauses.reset();
|
||||
m_clauses.reset();
|
||||
clause * const * it = s.begin_clauses();
|
||||
clause * const * end = s.end_clauses();
|
||||
for (; it != end; ++it) {
|
||||
m_clauses.push_back(*it);
|
||||
}
|
||||
svector<solver::bin_clause> bincs;
|
||||
s.collect_bin_clauses(bincs, false);
|
||||
literal lits[2];
|
||||
for (unsigned i = 0; i < bincs.size(); ++i) {
|
||||
lits[0] = bincs[i].first;
|
||||
lits[1] = bincs[i].second;
|
||||
clause* cl = m_alloc.mk_clause(2, lits, false);
|
||||
m_clauses.push_back(cl);
|
||||
m_bin_clauses.push_back(cl);
|
||||
}
|
||||
}
|
||||
|
||||
void sls::init_model() {
|
||||
m_num_true.reset();
|
||||
m_model.reset();
|
||||
m_model.append(s.get_model());
|
||||
unsigned sz = m_clauses.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
clause const& c = *m_clauses[i];
|
||||
unsigned n = 0;
|
||||
unsigned csz = c.size();
|
||||
for (unsigned j = 0; j < csz; ++j) {
|
||||
lbool val = value_at(c[j], m_model);
|
||||
switch (val) {
|
||||
case l_true:
|
||||
++n;
|
||||
break;
|
||||
case l_undef:
|
||||
++n;
|
||||
m_model[c[j].var()] = c[j].sign()?l_false:l_true;
|
||||
SASSERT(value_at(c[j], m_model) == l_true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_num_true.push_back(n);
|
||||
if (n == 0) {
|
||||
m_false.insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sls::init_tabu(unsigned sz, literal const* tabu) {
|
||||
// our main use is where m_model satisfies all the hard constraints.
|
||||
// SASSERT(s.check_model(m_model));
|
||||
// SASSERT(m_false.empty());
|
||||
// ASSERT: m_num_true is correct count.
|
||||
m_tabu.reset();
|
||||
m_tabu.resize(s.num_vars(), false);
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
literal lit = tabu[i];
|
||||
if (s.m_level[lit.var()] == 0) continue;
|
||||
if (value_at(lit, m_model) == l_false) {
|
||||
flip(lit);
|
||||
}
|
||||
m_tabu[lit.var()] = true;
|
||||
}
|
||||
for (unsigned i = 0; i < s.m_trail.size(); ++i) {
|
||||
literal lit = s.m_trail[i];
|
||||
if (s.m_level[lit.var()] > 0) break;
|
||||
if (value_at(lit, m_model) != l_true) {
|
||||
flip(lit);
|
||||
}
|
||||
m_tabu[lit.var()] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void sls::init_use() {
|
||||
m_use_list.reset();
|
||||
m_use_list.resize(s.num_vars()*2);
|
||||
unsigned sz = m_clauses.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
clause const& c = *m_clauses[i];
|
||||
unsigned csz = c.size();
|
||||
for (unsigned j = 0; j < csz; ++j) {
|
||||
m_use_list[c[j].index()].push_back(i);
|
||||
}
|
||||
}
|
||||
DEBUG_CODE(check_use_list(););
|
||||
}
|
||||
|
||||
unsigned_vector const& sls::get_use(literal lit) {
|
||||
SASSERT(lit.index() < m_use_list.size());
|
||||
return m_use_list[lit.index()];
|
||||
}
|
||||
|
||||
unsigned sls::get_break_count(literal lit, unsigned min_break) {
|
||||
SASSERT(value_at(lit, m_model) == l_false);
|
||||
unsigned result = 0;
|
||||
unsigned_vector const& uses = get_use(~lit);
|
||||
unsigned sz = uses.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
if (m_num_true[uses[i]] == 1) {
|
||||
++result;
|
||||
if (result > min_break) return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool sls::pick_flip(literal& lit) {
|
||||
unsigned clause_idx = m_false.choose(m_rand);
|
||||
clause const& c = *m_clauses[clause_idx];
|
||||
SASSERT(!c.satisfied_by(m_model));
|
||||
unsigned min_break = UINT_MAX;
|
||||
unsigned sz = c.size();
|
||||
m_min_vars.reset();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
lit = c[i];
|
||||
if (m_tabu[lit.var()]) continue;
|
||||
unsigned break_count = get_break_count(lit, min_break);
|
||||
if (break_count < min_break) {
|
||||
min_break = break_count;
|
||||
m_min_vars.reset();
|
||||
m_min_vars.push_back(lit);
|
||||
}
|
||||
else if (break_count == min_break) {
|
||||
m_min_vars.push_back(lit);
|
||||
}
|
||||
}
|
||||
if (min_break == 0 || (!m_min_vars.empty() && m_rand(100) >= m_prob_choose_min_var)) {
|
||||
lit = m_min_vars[m_rand(m_min_vars.size())];
|
||||
return true;
|
||||
}
|
||||
else if (min_break == UINT_MAX) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
lit = c[m_rand(c.size())];
|
||||
return !m_tabu[lit.var()];
|
||||
}
|
||||
}
|
||||
|
||||
void sls::flip() {
|
||||
literal lit;
|
||||
if (pick_flip(lit)) {
|
||||
flip(lit);
|
||||
}
|
||||
}
|
||||
|
||||
void sls::flip(literal lit) {
|
||||
//IF_VERBOSE(0, verbose_stream() << lit << " ";);
|
||||
SASSERT(value_at(lit, m_model) == l_false);
|
||||
SASSERT(!m_tabu[lit.var()]);
|
||||
m_model[lit.var()] = lit.sign()?l_false:l_true;
|
||||
SASSERT(value_at(lit, m_model) == l_true);
|
||||
unsigned_vector const& use1 = get_use(lit);
|
||||
unsigned sz = use1.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
unsigned cl = use1[i];
|
||||
m_num_true[cl]++;
|
||||
SASSERT(m_num_true[cl] <= m_clauses[cl]->size());
|
||||
if (m_num_true[cl] == 1) m_false.remove(cl);
|
||||
}
|
||||
unsigned_vector const& use2 = get_use(~lit);
|
||||
sz = use2.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
unsigned cl = use2[i];
|
||||
SASSERT(m_num_true[cl] > 0);
|
||||
m_num_true[cl]--;
|
||||
if (m_num_true[cl] == 0) m_false.insert(cl);
|
||||
}
|
||||
}
|
||||
|
||||
void sls::check_invariant() {
|
||||
DEBUG_CODE(
|
||||
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||
clause const& c = *m_clauses[i];
|
||||
bool is_sat = c.satisfied_by(m_model);
|
||||
SASSERT(is_sat != m_false.contains(i));
|
||||
SASSERT(is_sat == (m_num_true[i] > 0));
|
||||
});
|
||||
}
|
||||
|
||||
void sls::check_use_list() {
|
||||
DEBUG_CODE(
|
||||
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||
clause const& c = *m_clauses[i];
|
||||
for (unsigned j = 0; j < c.size(); ++j) {
|
||||
unsigned idx = c[j].index();
|
||||
SASSERT(m_use_list[idx].contains(i));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < m_use_list.size(); ++i) {
|
||||
literal lit = to_literal(i);
|
||||
for (unsigned j = 0; j < m_use_list[i].size(); ++j) {
|
||||
clause const& c = *m_clauses[m_use_list[i][j]];
|
||||
bool found = false;
|
||||
for (unsigned k = 0; !found && k < c.size(); ++k) {
|
||||
found = c[k] == lit;
|
||||
}
|
||||
SASSERT(found);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void sls::display(std::ostream& out) const {
|
||||
out << "Model\n";
|
||||
for (bool_var v = 0; v < m_model.size(); ++v) {
|
||||
out << v << ": " << m_model[v] << "\n";
|
||||
}
|
||||
out << "Clauses\n";
|
||||
unsigned sz = m_false.num_elems();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
out << *m_clauses[m_false[i]] << "\n";
|
||||
}
|
||||
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||
if (m_false.contains(i)) continue;
|
||||
clause const& c = *m_clauses[i];
|
||||
out << c << " " << m_num_true[i] << "\n";
|
||||
}
|
||||
bool has_tabu = false;
|
||||
for (unsigned i = 0; !has_tabu && i < m_tabu.size(); ++i) {
|
||||
has_tabu = m_tabu[i];
|
||||
}
|
||||
if (has_tabu) {
|
||||
out << "Tabu: ";
|
||||
for (unsigned i = 0; i < m_tabu.size(); ++i) {
|
||||
if (m_tabu[i]) {
|
||||
literal lit(i, false);
|
||||
if (value_at(lit, m_model) == l_false) lit.neg();
|
||||
out << lit << " ";
|
||||
}
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wsls::wsls(solver& s):
|
||||
sls(s)
|
||||
{
|
||||
m_smoothing_probability = 1; // 1/1000
|
||||
}
|
||||
|
||||
wsls::~wsls() {}
|
||||
|
||||
void wsls::set_soft(unsigned sz, literal const* lits, double const* weights) {
|
||||
m_soft.reset();
|
||||
m_weights.reset();
|
||||
m_soft.append(sz, lits);
|
||||
m_weights.append(sz, weights);
|
||||
}
|
||||
|
||||
void wsls::opt(unsigned sz, literal const* tabu, bool reuse_model) {
|
||||
init(sz, tabu, reuse_model);
|
||||
|
||||
//
|
||||
// Initialize m_clause_weights, m_hscore, m_sscore.
|
||||
//
|
||||
m_best_value = m_false.empty()?evaluate_model(m_model):-1.0;
|
||||
m_best_model.reset();
|
||||
m_clause_weights.reset();
|
||||
m_hscore.reset();
|
||||
m_sscore.reset();
|
||||
m_H.reset();
|
||||
m_S.reset();
|
||||
m_best_model.append(s.get_model());
|
||||
m_clause_weights.resize(m_clauses.size(), 1);
|
||||
m_sscore.resize(s.num_vars(), 0.0);
|
||||
m_hscore.resize(s.num_vars(), 0);
|
||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||
literal lit = m_soft[i];
|
||||
m_sscore[lit.var()] = m_weights[i];
|
||||
if (value_at(lit, m_model) == l_true) {
|
||||
m_sscore[lit.var()] = -m_sscore[lit.var()];
|
||||
}
|
||||
}
|
||||
for (bool_var i = 0; i < s.num_vars(); ++i) {
|
||||
m_hscore[i] = compute_hscore(i);
|
||||
refresh_scores(i);
|
||||
}
|
||||
DEBUG_CODE(check_invariant(););
|
||||
unsigned i = 0;
|
||||
for (; !s.canceled() && m_best_value > 0 && i < m_max_tries; ++i) {
|
||||
wflip();
|
||||
if (m_false.empty()) {
|
||||
double val = evaluate_model(m_model);
|
||||
if (val < m_best_value || m_best_value < 0.0) {
|
||||
m_best_value = val;
|
||||
m_best_model.reset();
|
||||
m_best_model.append(m_model);
|
||||
s.set_model(m_best_model);
|
||||
IF_VERBOSE(1, verbose_stream() << "new value: " << val << " @ " << i << "\n";);
|
||||
if (i*2 > m_max_tries) {
|
||||
m_max_tries *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("sat", display(tout););
|
||||
IF_VERBOSE(0, verbose_stream() << "tries " << i << "\n";);
|
||||
}
|
||||
|
||||
void wsls::wflip() {
|
||||
literal lit;
|
||||
if (pick_wflip(lit)) {
|
||||
// IF_VERBOSE(0, verbose_stream() << lit << " ";);
|
||||
wflip(lit);
|
||||
}
|
||||
}
|
||||
|
||||
bool wsls::pick_wflip(literal & lit) {
|
||||
unsigned idx;
|
||||
if (!m_H.empty()) {
|
||||
idx = m_H.choose(m_rand);
|
||||
lit = literal(idx, false);
|
||||
if (value_at(lit, m_model) == l_true) lit.neg();
|
||||
SASSERT(value_at(lit, m_model) == l_false);
|
||||
TRACE("sat", tout << "flip H(" << m_H.num_elems() << ") " << lit << "\n";);
|
||||
}
|
||||
else if (!m_S.empty()) {
|
||||
double score = 0.0;
|
||||
m_min_vars.reset();
|
||||
for (unsigned i = 0; i < m_S.num_elems(); ++i) {
|
||||
unsigned v = m_S[i];
|
||||
SASSERT(m_sscore[v] > 0.0);
|
||||
if (m_sscore[v] > score) {
|
||||
m_min_vars.reset();
|
||||
m_min_vars.push_back(literal(v, false));
|
||||
score = m_sscore[v];
|
||||
}
|
||||
else if (m_sscore[v] == score) {
|
||||
m_min_vars.push_back(literal(v, false));
|
||||
}
|
||||
}
|
||||
lit = m_min_vars[m_rand(m_min_vars.size())]; // pick with largest sscore.
|
||||
SASSERT(value_at(lit, m_model) == l_false);
|
||||
TRACE("sat", tout << "flip S(" << m_min_vars.size() << "," << score << ") " << lit << "\n";);
|
||||
}
|
||||
else {
|
||||
update_hard_weights();
|
||||
if (!m_false.empty()) {
|
||||
unsigned cls_idx = m_false.choose(m_rand);
|
||||
clause const& c = *m_clauses[cls_idx];
|
||||
lit = c[m_rand(c.size())];
|
||||
TRACE("sat", tout << "flip hard(" << m_false.num_elems() << "," << c.size() << ") " << lit << "\n";);
|
||||
}
|
||||
else {
|
||||
m_min_vars.reset();
|
||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||
lit = m_soft[i];
|
||||
if (value_at(lit, m_model) == l_false) {
|
||||
m_min_vars.push_back(lit);
|
||||
}
|
||||
}
|
||||
if (m_min_vars.empty()) {
|
||||
SASSERT(m_best_value == 0.0);
|
||||
UNREACHABLE(); // we should have exited the main loop before.
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
lit = m_min_vars[m_rand(m_min_vars.size())];
|
||||
}
|
||||
TRACE("sat", tout << "flip soft(" << m_min_vars.size() << ", " << m_sscore[lit.var()] << ") " << lit << "\n";);
|
||||
|
||||
}
|
||||
SASSERT(value_at(lit, m_model) == l_false);
|
||||
}
|
||||
return !m_tabu[lit.var()];
|
||||
}
|
||||
|
||||
void wsls::wflip(literal lit) {
|
||||
flip(lit);
|
||||
unsigned v = lit.var();
|
||||
m_sscore[v] = -m_sscore[v];
|
||||
m_hscore[v] = compute_hscore(v);
|
||||
refresh_scores(v);
|
||||
recompute_hscores(lit);
|
||||
}
|
||||
|
||||
void wsls::update_hard_weights() {
|
||||
unsigned csz = m_clauses.size();
|
||||
if (m_smoothing_probability >= m_rand(1000)) {
|
||||
for (unsigned i = 0; i < csz; ++i) {
|
||||
if (m_clause_weights[i] > 1 && !m_false.contains(i)) {
|
||||
--m_clause_weights[i];
|
||||
if (m_num_true[i] == 1) {
|
||||
clause const& c = *m_clauses[i];
|
||||
unsigned sz = c.size();
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
if (value_at(c[j], m_model) == l_true) {
|
||||
++m_hscore[c[j].var()];
|
||||
refresh_scores(c[j].var());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (unsigned i = 0; i < csz; ++i) {
|
||||
if (m_false.contains(i)) {
|
||||
++m_clause_weights[i];
|
||||
clause const& c = *m_clauses[i];
|
||||
unsigned sz = c.size();
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
++m_hscore[c[j].var()];
|
||||
refresh_scores(c[j].var());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DEBUG_CODE(check_invariant(););
|
||||
}
|
||||
|
||||
double wsls::evaluate_model(model& mdl) {
|
||||
SASSERT(m_false.empty());
|
||||
double result = 0.0;
|
||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||
literal lit = m_soft[i];
|
||||
if (value_at(lit, mdl) != l_true) {
|
||||
result += m_weights[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int wsls::compute_hscore(bool_var v) {
|
||||
literal lit(v, false);
|
||||
if (value_at(lit, m_model) == l_false) {
|
||||
lit.neg();
|
||||
}
|
||||
SASSERT(value_at(lit, m_model) == l_true);
|
||||
int hs = 0;
|
||||
unsigned_vector const& use1 = get_use(~lit);
|
||||
unsigned sz = use1.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
unsigned cl = use1[i];
|
||||
if (m_num_true[cl] == 0) {
|
||||
SASSERT(m_false.contains(cl));
|
||||
hs += m_clause_weights[cl];
|
||||
}
|
||||
else {
|
||||
SASSERT(!m_false.contains(cl));
|
||||
}
|
||||
}
|
||||
unsigned_vector const& use2 = get_use(lit);
|
||||
sz = use2.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
unsigned cl = use2[i];
|
||||
if (m_num_true[cl] == 1) {
|
||||
SASSERT(!m_false.contains(cl));
|
||||
hs -= m_clause_weights[cl];
|
||||
}
|
||||
}
|
||||
return hs;
|
||||
}
|
||||
|
||||
void wsls::recompute_hscores(literal lit) {
|
||||
SASSERT(value_at(lit, m_model) == l_true);
|
||||
TRACE("sat", tout << lit.var() << " := " << m_hscore[lit.var()] << "\n";);
|
||||
unsigned_vector const& use1 = get_use(lit);
|
||||
unsigned sz = use1.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
unsigned cl = use1[i];
|
||||
TRACE("sat", tout << *m_clauses[cl] << " " << m_num_true[cl] << "\n";);
|
||||
SASSERT(m_num_true[cl] > 0);
|
||||
if (m_num_true[cl] == 1) {
|
||||
// num_true 0 -> 1
|
||||
// other literals don't have upside any more.
|
||||
// subtract one from all other literals
|
||||
adjust_all_values(lit, cl, -static_cast<int>(m_clause_weights[cl]));
|
||||
}
|
||||
else if (m_num_true[cl] == 2) {
|
||||
// num_true 1 -> 2, previous critical literal is no longer critical
|
||||
adjust_pivot_value(lit, cl, +m_clause_weights[cl]);
|
||||
}
|
||||
}
|
||||
unsigned_vector const& use2 = get_use(~lit);
|
||||
sz = use2.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
unsigned cl = use2[i];
|
||||
TRACE("sat", tout << *m_clauses[cl] << " " << m_num_true[cl] << "\n";);
|
||||
if (m_num_true[cl] == 0) {
|
||||
// num_true 1 -> 0
|
||||
// all variables became critical.
|
||||
adjust_all_values(~lit, cl, +m_clause_weights[cl]);
|
||||
}
|
||||
else if (m_num_true[cl] == 1) {
|
||||
adjust_pivot_value(~lit, cl, -static_cast<int>(m_clause_weights[cl]));
|
||||
}
|
||||
// else n+1 -> n >= 2
|
||||
}
|
||||
}
|
||||
|
||||
void wsls::adjust_all_values(literal lit, unsigned cl, int delta) {
|
||||
clause const& c = *m_clauses[cl];
|
||||
unsigned sz = c.size();
|
||||
TRACE("sat", tout << lit << " " << c << " delta: " << delta << " nt: " << m_num_true[cl] << "\n";);
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
literal lit2 = c[i];
|
||||
if (lit2 != lit) {
|
||||
TRACE("sat", tout << lit2.var() << " := " << m_hscore[lit2.var()] << "\n";);
|
||||
m_hscore[lit2.var()] += delta;
|
||||
TRACE("sat", tout << lit2.var() << " := " << m_hscore[lit2.var()] << "\n";);
|
||||
refresh_scores(lit2.var());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wsls::adjust_pivot_value(literal lit, unsigned cl, int delta) {
|
||||
clause const& c = *m_clauses[cl];
|
||||
unsigned csz = c.size();
|
||||
for (unsigned j = 0; j < csz; ++j) {
|
||||
literal lit2 = c[j];
|
||||
if (lit2 != lit && value_at(lit2, m_model) == l_true) {
|
||||
TRACE("sat", tout << lit2.var() << " := " << m_hscore[lit2.var()] << "\n";);
|
||||
m_hscore[lit2.var()] += delta;
|
||||
TRACE("sat", tout << lit2.var() << " := " << m_hscore[lit2.var()] << "\n";);
|
||||
refresh_scores(lit2.var());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wsls::refresh_scores(bool_var v) {
|
||||
if (m_hscore[v] > 0 && !m_tabu[v] && m_sscore[v] == 0) {
|
||||
m_H.insert(v);
|
||||
}
|
||||
else {
|
||||
m_H.remove(v);
|
||||
}
|
||||
if (m_sscore[v] > 0) {
|
||||
if (m_hscore[v] == 0 && !m_tabu[v]) {
|
||||
m_S.insert(v);
|
||||
}
|
||||
else {
|
||||
m_S.remove(v);
|
||||
}
|
||||
}
|
||||
else if (m_sscore[v] < 0) {
|
||||
m_S.remove(v);
|
||||
}
|
||||
}
|
||||
|
||||
void wsls::check_invariant() {
|
||||
sls::check_invariant();
|
||||
// The hscore is the reward for flipping the truth value of variable v.
|
||||
// hscore(v) = Sum weight(c) for num_true(c) = 0 and v in c
|
||||
// - Sum weight(c) for num_true(c) = 1 and (v in c, M(v) or !v in c and !M(v))
|
||||
DEBUG_CODE(
|
||||
for (unsigned v = 0; v < s.num_vars(); ++v) {
|
||||
int hs = compute_hscore(v);
|
||||
CTRACE("sat", hs != m_hscore[v], display(tout << v << " - computed: " << hs << " - assigned: " << m_hscore[v] << "\n"););
|
||||
SASSERT(m_hscore[v] == hs);
|
||||
}
|
||||
|
||||
// The score(v) is the reward on soft clauses for flipping v.
|
||||
for (unsigned j = 0; j < m_soft.size(); ++j) {
|
||||
unsigned v = m_soft[j].var();
|
||||
double ss = (l_true == value_at(m_soft[j], m_model))?(-m_weights[j]):m_weights[j];
|
||||
SASSERT(m_sscore[v] == ss);
|
||||
}
|
||||
|
||||
// m_H are values such that m_hscore > 0 and sscore = 0.
|
||||
for (bool_var v = 0; v < m_hscore.size(); ++v) {
|
||||
SASSERT((m_hscore[v] > 0 && !m_tabu[v] && m_sscore[v] == 0) == m_H.contains(v));
|
||||
}
|
||||
|
||||
// m_S are values such that hscore = 0, sscore > 0
|
||||
for (bool_var v = 0; v < m_sscore.size(); ++v) {
|
||||
SASSERT((m_hscore[v] == 0 && m_sscore[v] > 0 && !m_tabu[v]) == m_S.contains(v));
|
||||
});
|
||||
}
|
||||
|
||||
void wsls::display(std::ostream& out) const {
|
||||
sls::display(out);
|
||||
out << "Best model\n";
|
||||
for (bool_var v = 0; v < m_best_model.size(); ++v) {
|
||||
out << v << ": " << m_best_model[v] << " h: " << m_hscore[v];
|
||||
if (m_sscore[v] != 0.0) out << " s: " << m_sscore[v];
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sat_sls.h
|
||||
|
||||
Abstract:
|
||||
|
||||
SLS for clauses in SAT solver
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2014-12-8
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef SAT_SLS_H_
|
||||
#define SAT_SLS_H_
|
||||
|
||||
#include "util.h"
|
||||
#include "sat_simplifier.h"
|
||||
|
||||
namespace sat {
|
||||
|
||||
class index_set {
|
||||
unsigned_vector m_elems;
|
||||
unsigned_vector m_index;
|
||||
public:
|
||||
unsigned num_elems() const { return m_elems.size(); }
|
||||
unsigned operator[](unsigned idx) const { return m_elems[idx]; }
|
||||
void reset() { m_elems.reset(); m_index.reset(); }
|
||||
bool empty() const { return m_elems.empty(); }
|
||||
bool contains(unsigned idx) const;
|
||||
void insert(unsigned idx);
|
||||
void remove(unsigned idx);
|
||||
unsigned choose(random_gen& rnd) const;
|
||||
};
|
||||
|
||||
class sls {
|
||||
protected:
|
||||
solver& s;
|
||||
random_gen m_rand;
|
||||
unsigned m_max_tries;
|
||||
unsigned m_prob_choose_min_var; // number between 0 and 99.
|
||||
unsigned m_clause_generation;
|
||||
ptr_vector<clause const> m_clauses; // vector of all clauses.
|
||||
index_set m_false; // clauses currently false
|
||||
vector<unsigned_vector> m_use_list; // use lists for literals
|
||||
unsigned_vector m_num_true; // per clause, count of # true literals
|
||||
svector<literal> m_min_vars; // literals with smallest break count
|
||||
model m_model; // current model
|
||||
clause_allocator m_alloc; // clause allocator
|
||||
clause_vector m_bin_clauses; // binary clauses
|
||||
svector<bool> m_tabu; // variables that cannot be swapped
|
||||
public:
|
||||
sls(solver& s);
|
||||
virtual ~sls();
|
||||
lbool operator()(unsigned sz, literal const* tabu, bool reuse_model);
|
||||
void set_max_tries(unsigned mx) { m_max_tries = mx; }
|
||||
virtual void display(std::ostream& out) const;
|
||||
protected:
|
||||
void init(unsigned sz, literal const* tabu, bool reuse_model);
|
||||
void init_tabu(unsigned sz, literal const* tabu);
|
||||
void init_model();
|
||||
void init_use();
|
||||
void init_clauses();
|
||||
unsigned_vector const& get_use(literal lit);
|
||||
void flip(literal lit);
|
||||
virtual void check_invariant();
|
||||
void check_use_list();
|
||||
private:
|
||||
bool pick_flip(literal& lit);
|
||||
void flip();
|
||||
unsigned get_break_count(literal lit, unsigned min_break);
|
||||
};
|
||||
|
||||
/**
|
||||
\brief sls with weighted soft clauses.
|
||||
*/
|
||||
class wsls : public sls {
|
||||
unsigned_vector m_clause_weights;
|
||||
svector<int> m_hscore;
|
||||
svector<double> m_sscore;
|
||||
literal_vector m_soft;
|
||||
svector<double> m_weights;
|
||||
double m_best_value;
|
||||
model m_best_model;
|
||||
index_set m_H, m_S;
|
||||
unsigned m_smoothing_probability;
|
||||
public:
|
||||
wsls(solver& s);
|
||||
virtual ~wsls();
|
||||
void set_soft(unsigned sz, literal const* lits, double const* weights);
|
||||
bool has_soft() const { return !m_soft.empty(); }
|
||||
void opt(unsigned sz, literal const* tabu, bool reuse_model);
|
||||
virtual void display(std::ostream& out) const;
|
||||
double evaluate_model(model& mdl);
|
||||
private:
|
||||
void wflip();
|
||||
void wflip(literal lit);
|
||||
void update_hard_weights();
|
||||
bool pick_wflip(literal & lit);
|
||||
virtual void check_invariant();
|
||||
void refresh_scores(bool_var v);
|
||||
int compute_hscore(bool_var v);
|
||||
void recompute_hscores(literal lit);
|
||||
void adjust_all_values(literal lit, unsigned cl, int delta);
|
||||
void adjust_pivot_value(literal lit, unsigned cl, int delta);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -20,7 +20,6 @@ Revision History:
|
|||
#include"sat_integrity_checker.h"
|
||||
#include"luby.h"
|
||||
#include"trace.h"
|
||||
#include"sat_bceq.h"
|
||||
#include"max_cliques.h"
|
||||
|
||||
// define to update glue during propagation
|
||||
|
@ -42,7 +41,6 @@ namespace sat {
|
|||
m_asymm_branch(*this, p),
|
||||
m_probing(*this, p),
|
||||
m_mus(*this),
|
||||
m_wsls(*this),
|
||||
m_inconsistent(false),
|
||||
m_num_frozen(0),
|
||||
m_activity_inc(128),
|
||||
|
@ -55,7 +53,6 @@ namespace sat {
|
|||
m_conflicts = 0;
|
||||
m_next_simplify = 0;
|
||||
m_num_checkpoints = 0;
|
||||
m_initializing_preferred = false;
|
||||
}
|
||||
|
||||
solver::~solver() {
|
||||
|
@ -123,6 +120,7 @@ namespace sat {
|
|||
// -----------------------
|
||||
|
||||
bool_var solver::mk_var(bool ext, bool dvar) {
|
||||
m_model_is_current = false;
|
||||
m_stats.m_mk_var++;
|
||||
bool_var v = m_level.size();
|
||||
m_watches.push_back(watch_list());
|
||||
|
@ -148,6 +146,7 @@ namespace sat {
|
|||
}
|
||||
|
||||
void solver::mk_clause(unsigned num_lits, literal * lits) {
|
||||
m_model_is_current = false;
|
||||
DEBUG_CODE({
|
||||
for (unsigned i = 0; i < num_lits; i++)
|
||||
SASSERT(m_eliminated[lits[i].var()] == false);
|
||||
|
@ -212,7 +211,7 @@ namespace sat {
|
|||
if (propagate_bin_clause(l1, l2)) {
|
||||
if (scope_lvl() == 0)
|
||||
return;
|
||||
if (!learned)
|
||||
if (!learned)
|
||||
m_clauses_to_reinit.push_back(clause_wrapper(l1, l2));
|
||||
}
|
||||
m_stats.m_mk_bin_clause++;
|
||||
|
@ -235,19 +234,18 @@ namespace sat {
|
|||
}
|
||||
|
||||
void solver::push_reinit_stack(clause & c) {
|
||||
TRACE("sat_reinit", tout << "adding to reinit stack: " << c << "\n";);
|
||||
m_clauses_to_reinit.push_back(clause_wrapper(c));
|
||||
c.set_reinit_stack(true);
|
||||
c.set_reinit_stack(true);
|
||||
}
|
||||
|
||||
|
||||
clause * solver::mk_ter_clause(literal * lits, bool learned) {
|
||||
m_stats.m_mk_ter_clause++;
|
||||
clause * r = m_cls_allocator.mk_clause(3, lits, learned);
|
||||
bool reinit;
|
||||
attach_ter_clause(*r, reinit);
|
||||
if (!learned && reinit) {
|
||||
TRACE("sat_reinit", tout << "adding to reinit stack: " << *r << "\n";);
|
||||
push_reinit_stack(*r);
|
||||
}
|
||||
bool reinit = attach_ter_clause(*r);
|
||||
if (reinit && !learned) push_reinit_stack(*r);
|
||||
|
||||
if (learned)
|
||||
m_learned.push_back(r);
|
||||
else
|
||||
|
@ -255,8 +253,8 @@ namespace sat {
|
|||
return r;
|
||||
}
|
||||
|
||||
void solver::attach_ter_clause(clause & c, bool & reinit) {
|
||||
reinit = false;
|
||||
bool solver::attach_ter_clause(clause & c) {
|
||||
bool reinit = false;
|
||||
m_watches[(~c[0]).index()].push_back(watched(c[1], c[2]));
|
||||
m_watches[(~c[1]).index()].push_back(watched(c[0], c[2]));
|
||||
m_watches[(~c[2]).index()].push_back(watched(c[0], c[1]));
|
||||
|
@ -277,18 +275,15 @@ namespace sat {
|
|||
reinit = true;
|
||||
}
|
||||
}
|
||||
return reinit;
|
||||
}
|
||||
|
||||
clause * solver::mk_nary_clause(unsigned num_lits, literal * lits, bool learned) {
|
||||
m_stats.m_mk_clause++;
|
||||
clause * r = m_cls_allocator.mk_clause(num_lits, lits, learned);
|
||||
SASSERT(!learned || r->is_learned());
|
||||
bool reinit;
|
||||
attach_nary_clause(*r, reinit);
|
||||
if (!learned && reinit) {
|
||||
TRACE("sat_reinit", tout << "adding to reinit stack: " << *r << "\n";);
|
||||
push_reinit_stack(*r);
|
||||
}
|
||||
bool reinit = attach_nary_clause(*r);
|
||||
if (reinit && !learned) push_reinit_stack(*r);
|
||||
if (learned)
|
||||
m_learned.push_back(r);
|
||||
else
|
||||
|
@ -296,8 +291,8 @@ namespace sat {
|
|||
return r;
|
||||
}
|
||||
|
||||
void solver::attach_nary_clause(clause & c, bool & reinit) {
|
||||
reinit = false;
|
||||
bool solver::attach_nary_clause(clause & c) {
|
||||
bool reinit = false;
|
||||
clause_offset cls_off = m_cls_allocator.get_offset(&c);
|
||||
if (scope_lvl() > 0) {
|
||||
if (c.is_learned()) {
|
||||
|
@ -326,15 +321,16 @@ namespace sat {
|
|||
literal block_lit = c[some_idx];
|
||||
m_watches[(~c[0]).index()].push_back(watched(block_lit, cls_off));
|
||||
m_watches[(~c[1]).index()].push_back(watched(block_lit, cls_off));
|
||||
return reinit;
|
||||
}
|
||||
|
||||
void solver::attach_clause(clause & c, bool & reinit) {
|
||||
SASSERT(c.size() > 2);
|
||||
reinit = false;
|
||||
if (c.size() == 3)
|
||||
attach_ter_clause(c, reinit);
|
||||
reinit = attach_ter_clause(c);
|
||||
else
|
||||
attach_nary_clause(c, reinit);
|
||||
reinit = attach_nary_clause(c);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -711,7 +707,7 @@ namespace sat {
|
|||
// Search
|
||||
//
|
||||
// -----------------------
|
||||
lbool solver::check(unsigned num_lits, literal const* lits, double const* weights, double max_weight) {
|
||||
lbool solver::check(unsigned num_lits, literal const* lits) {
|
||||
pop_to_base_level();
|
||||
IF_VERBOSE(2, verbose_stream() << "(sat.sat-solver)\n";);
|
||||
SASSERT(scope_lvl() == 0);
|
||||
|
@ -726,7 +722,7 @@ namespace sat {
|
|||
init_search();
|
||||
propagate(false);
|
||||
if (inconsistent()) return l_false;
|
||||
init_assumptions(num_lits, lits, weights, max_weight);
|
||||
init_assumptions(num_lits, lits);
|
||||
propagate(false);
|
||||
if (check_inconsistent()) return l_false;
|
||||
cleanup();
|
||||
|
@ -766,7 +762,7 @@ namespace sat {
|
|||
if (check_inconsistent()) return l_false;
|
||||
gc();
|
||||
|
||||
if (m_config.m_restart_max != 0 && m_config.m_restart_max <= m_restarts) {
|
||||
if (m_config.m_restart_max <= m_restarts) {
|
||||
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat \"abort: max-restarts\")\n";);
|
||||
return l_undef;
|
||||
}
|
||||
|
@ -912,12 +908,11 @@ namespace sat {
|
|||
}
|
||||
}
|
||||
|
||||
void solver::init_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight) {
|
||||
void solver::init_assumptions(unsigned num_lits, literal const* lits) {
|
||||
if (num_lits == 0 && m_user_scope_literals.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
retry_init_assumptions:
|
||||
reset_assumptions();
|
||||
push();
|
||||
|
||||
|
@ -941,16 +936,6 @@ namespace sat {
|
|||
assign(nlit, justification());
|
||||
}
|
||||
|
||||
if (weights && !inconsistent()) {
|
||||
if (m_config.m_optimize_model) {
|
||||
m_wsls.set_soft(num_lits, lits, weights);
|
||||
}
|
||||
if (!init_weighted_assumptions(num_lits, lits, weights, max_weight)) {
|
||||
goto retry_init_assumptions;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; !inconsistent() && i < num_lits; ++i) {
|
||||
literal lit = lits[i];
|
||||
SASSERT(is_external(lit.var()));
|
||||
|
@ -960,109 +945,6 @@ namespace sat {
|
|||
}
|
||||
|
||||
|
||||
bool solver::init_weighted_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight) {
|
||||
flet<bool> _min1(m_config.m_core_minimize, false);
|
||||
m_weight = 0;
|
||||
m_blocker.reset();
|
||||
svector<lbool> values;
|
||||
unsigned num_cores = 0;
|
||||
for (unsigned i = 0; !inconsistent() && i < num_lits; ++i) {
|
||||
literal lit = lits[i];
|
||||
SASSERT(is_external(lit.var()));
|
||||
TRACE("sat", tout << "propagate: " << lit << " " << value(lit) << "\n";);
|
||||
SASSERT(m_scope_lvl == 1);
|
||||
add_assumption(lit);
|
||||
switch(value(lit)) {
|
||||
case l_undef:
|
||||
values.push_back(l_true);
|
||||
assign(lit, justification());
|
||||
if (num_cores*2 >= num_lits) {
|
||||
break;
|
||||
}
|
||||
propagate(false);
|
||||
if (inconsistent()) {
|
||||
flet<bool> _init(m_initializing_preferred, true);
|
||||
while (inconsistent()) {
|
||||
if (!resolve_conflict()) {
|
||||
return true;
|
||||
}
|
||||
propagate(true);
|
||||
}
|
||||
if (m_scope_lvl == 0) {
|
||||
return false;
|
||||
}
|
||||
// backjump to last consistent assumption:
|
||||
unsigned j;
|
||||
m_weight = 0;
|
||||
m_blocker.reset();
|
||||
for (j = 0; j < i && value(lits[j]) == values[j]; ++j) {
|
||||
if (values[j] == l_false) {
|
||||
m_weight += weights[j];
|
||||
m_blocker.push_back(lits[j]);
|
||||
}
|
||||
}
|
||||
SASSERT(value(lits[j]) != values[j]);
|
||||
SASSERT(j <= i);
|
||||
SASSERT(j == 0 || value(lits[j-1]) == values[j-1]);
|
||||
for (unsigned k = i; k >= j; --k) {
|
||||
if (is_assumption(lits[k])) {
|
||||
pop_assumption();
|
||||
}
|
||||
}
|
||||
values.resize(j);
|
||||
TRACE("sat", tout << "backjump " << (i - j + 1) << " steps " << num_cores << "\n";);
|
||||
i = j - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case l_false:
|
||||
++num_cores;
|
||||
values.push_back(l_false);
|
||||
SASSERT(!inconsistent());
|
||||
set_conflict(justification(), ~lit);
|
||||
m_conflict_lvl = scope_lvl();
|
||||
resolve_conflict_for_unsat_core();
|
||||
IF_VERBOSE(3, verbose_stream() << "(sat.core: " << m_core << ")\n";);
|
||||
update_min_core();
|
||||
SASSERT(m_min_core_valid);
|
||||
m_weight += weights[i];
|
||||
if (m_weight <= max_weight) {
|
||||
m_blocker.push_back(lit);
|
||||
}
|
||||
TRACE("sat", tout << "core: " << m_core << "\nassumptions: " << m_assumptions << "\n";);
|
||||
SASSERT(m_core.size() <= m_assumptions.size());
|
||||
SASSERT(m_assumptions.size() <= i+1);
|
||||
if (m_core.size() <= 3) {
|
||||
m_inconsistent = true;
|
||||
TRACE("opt", tout << "found small core: " << m_core << "\n";);
|
||||
IF_VERBOSE(11, verbose_stream() << "(sat.core: " << m_core << ")\n";);
|
||||
return true;
|
||||
}
|
||||
pop_assumption();
|
||||
m_inconsistent = false;
|
||||
break;
|
||||
case l_true:
|
||||
values.push_back(l_true);
|
||||
SASSERT(m_justification[lit.var()].get_kind() != justification::NONE || lvl(lit) == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
TRACE("sat", tout << "initialized\n";);
|
||||
IF_VERBOSE(11, verbose_stream() << "(sat.blocker: " << m_blocker << "\nCore: " << m_min_core << ")\n";);
|
||||
if (m_weight >= max_weight) {
|
||||
// block the current correction set candidate.
|
||||
++m_stats.m_blocked_corr_sets;
|
||||
TRACE("opt", tout << "blocking soft correction set: " << m_blocker << "\n";);
|
||||
IF_VERBOSE(11, verbose_stream() << "blocking " << m_blocker << "\n";);
|
||||
pop_to_base_level();
|
||||
mk_clause_core(m_blocker);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void solver::update_min_core() {
|
||||
if (!m_min_core_valid || m_core.size() < m_min_core.size()) {
|
||||
m_min_core.reset();
|
||||
|
@ -1112,6 +994,13 @@ namespace sat {
|
|||
for (unsigned i = 0; !inconsistent() && i < m_assumptions.size(); ++i) {
|
||||
assign(m_assumptions[i], justification());
|
||||
}
|
||||
TRACE("sat",
|
||||
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
|
||||
index_set s;
|
||||
if (m_antecedents.find(m_assumptions[i].var(), s)) {
|
||||
tout << m_assumptions[i] << ": "; display_index_set(tout, s) << "\n";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1139,11 +1028,6 @@ namespace sat {
|
|||
m_min_core_valid = false;
|
||||
m_min_core.reset();
|
||||
TRACE("sat", display(tout););
|
||||
|
||||
if (m_config.m_bcd) {
|
||||
bceq bc(*this);
|
||||
bc();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1235,9 +1119,6 @@ namespace sat {
|
|||
m_model[v] = value(v);
|
||||
}
|
||||
TRACE("sat_mc_bug", m_mc.display(tout););
|
||||
if (m_config.m_optimize_model) {
|
||||
m_wsls.opt(0, 0, false);
|
||||
}
|
||||
m_mc(m_model);
|
||||
TRACE("sat", for (bool_var v = 0; v < num; v++) tout << v << ": " << m_model[v] << "\n";);
|
||||
|
||||
|
@ -1664,10 +1545,6 @@ namespace sat {
|
|||
if (m_not_l == literal()) tout << "null literal\n";
|
||||
else tout << m_not_l << "\n";);
|
||||
|
||||
if (m_initializing_preferred) {
|
||||
SASSERT(m_conflict_lvl <= 1);
|
||||
return resolve_conflict_for_init();
|
||||
}
|
||||
if (m_conflict_lvl <= 1 && tracking_assumptions()) {
|
||||
resolve_conflict_for_unsat_core();
|
||||
return false;
|
||||
|
@ -3118,7 +2995,14 @@ namespace sat {
|
|||
|
||||
lbool solver::get_consequences(literal_vector const& asms, bool_var_vector const& vars, vector<literal_vector>& conseq) {
|
||||
literal_vector lits;
|
||||
lbool is_sat = check(asms.size(), asms.c_ptr());
|
||||
lbool is_sat = l_true;
|
||||
|
||||
if (m_config.m_restart_max != UINT_MAX && !m_model_is_current) {
|
||||
return get_bounded_consequences(asms, vars, conseq);
|
||||
}
|
||||
if (!m_model_is_current) {
|
||||
is_sat = check(asms.size(), asms.c_ptr());
|
||||
}
|
||||
if (is_sat != l_true) {
|
||||
return is_sat;
|
||||
}
|
||||
|
@ -3136,9 +3020,94 @@ namespace sat {
|
|||
return is_sat;
|
||||
}
|
||||
|
||||
lbool solver::get_consequences(literal_vector const& asms, literal_vector const& lits, vector<literal_vector>& conseq) {
|
||||
void solver::fixup_consequence_core() {
|
||||
index_set s;
|
||||
TRACE("sat", tout << m_core << "\n";);
|
||||
for (unsigned i = 0; i < m_core.size(); ++i) {
|
||||
TRACE("sat", tout << m_core[i] << ": "; display_index_set(tout, m_antecedents.find(m_core[i].var())) << "\n";);
|
||||
s |= m_antecedents.find(m_core[i].var());
|
||||
}
|
||||
m_core.reset();
|
||||
index_set::iterator it = s.begin(), end = s.end();
|
||||
for (; it != end; ++it) {
|
||||
m_core.push_back(to_literal(*it));
|
||||
}
|
||||
TRACE("sat", tout << m_core << "\n";);
|
||||
}
|
||||
|
||||
|
||||
lbool solver::get_bounded_consequences(literal_vector const& asms, bool_var_vector const& vars, vector<literal_vector>& conseq) {
|
||||
bool_var_set unfixed_vars;
|
||||
unsigned num_units = 0, num_iterations = 0;
|
||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
||||
unfixed_vars.insert(vars[i]);
|
||||
}
|
||||
TRACE("sat", tout << asms << "\n";);
|
||||
m_antecedents.reset();
|
||||
literal_set vars(lits), assumptions(asms);
|
||||
pop_to_base_level();
|
||||
if (inconsistent()) return l_false;
|
||||
init_search();
|
||||
propagate(false);
|
||||
if (inconsistent()) return l_false;
|
||||
if (asms.empty()) {
|
||||
bool_var v = mk_var(true, false);
|
||||
literal lit(v, false);
|
||||
init_assumptions(1, &lit);
|
||||
}
|
||||
else {
|
||||
init_assumptions(asms.size(), asms.c_ptr());
|
||||
}
|
||||
propagate(false);
|
||||
if (check_inconsistent()) return l_false;
|
||||
|
||||
extract_fixed_consequences(num_units, asms, unfixed_vars, conseq);
|
||||
|
||||
simplify_problem();
|
||||
if (check_inconsistent()) {
|
||||
fixup_consequence_core();
|
||||
return l_false;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
++num_iterations;
|
||||
SASSERT(!inconsistent());
|
||||
|
||||
lbool r = bounded_search();
|
||||
if (r != l_undef) {
|
||||
fixup_consequence_core();
|
||||
return r;
|
||||
}
|
||||
|
||||
extract_fixed_consequences(num_units, asms, unfixed_vars, conseq);
|
||||
|
||||
if (m_conflicts > m_config.m_max_conflicts) {
|
||||
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat \"abort: max-conflicts = " << m_conflicts << "\")\n";);
|
||||
return l_undef;
|
||||
}
|
||||
|
||||
restart();
|
||||
simplify_problem();
|
||||
if (check_inconsistent()) {
|
||||
fixup_consequence_core();
|
||||
return l_false;
|
||||
}
|
||||
gc();
|
||||
|
||||
if (m_config.m_restart_max <= num_iterations) {
|
||||
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat \"abort: max-restarts\")\n";);
|
||||
return l_undef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lbool solver::get_consequences(literal_vector const& asms, literal_vector const& lits, vector<literal_vector>& conseq) {
|
||||
TRACE("sat", tout << asms << "\n";);
|
||||
m_antecedents.reset();
|
||||
literal_set unfixed_lits(lits), assumptions(asms);
|
||||
bool_var_set unfixed_vars;
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
unfixed_vars.insert(lits[i].var());
|
||||
}
|
||||
|
||||
pop_to_base_level();
|
||||
if (inconsistent()) return l_false;
|
||||
|
@ -3148,20 +3117,24 @@ namespace sat {
|
|||
if (asms.empty()) {
|
||||
bool_var v = mk_var(true, false);
|
||||
literal lit(v, false);
|
||||
init_assumptions(1, &lit, 0, 0);
|
||||
init_assumptions(1, &lit);
|
||||
}
|
||||
else {
|
||||
init_assumptions(asms.size(), asms.c_ptr(), 0, 0);
|
||||
init_assumptions(asms.size(), asms.c_ptr());
|
||||
}
|
||||
propagate(false);
|
||||
if (check_inconsistent()) return l_false;
|
||||
|
||||
unsigned num_units = 0, num_iterations = 0;
|
||||
extract_fixed_consequences(num_units, assumptions, vars, conseq);
|
||||
while (!vars.empty()) {
|
||||
extract_fixed_consequences(num_units, assumptions, unfixed_vars, conseq);
|
||||
update_unfixed_literals(unfixed_lits, unfixed_vars);
|
||||
while (!unfixed_lits.empty()) {
|
||||
if (scope_lvl() > 1) {
|
||||
pop(scope_lvl() - 1);
|
||||
}
|
||||
++num_iterations;
|
||||
checkpoint();
|
||||
literal_set::iterator it = vars.begin(), end = vars.end();
|
||||
literal_set::iterator it = unfixed_lits.begin(), end = unfixed_lits.end();
|
||||
unsigned num_resolves = 0;
|
||||
lbool is_sat = l_true;
|
||||
for (; it != end; ++it) {
|
||||
|
@ -3202,53 +3175,84 @@ namespace sat {
|
|||
m_inconsistent = false;
|
||||
}
|
||||
if (is_sat == l_true) {
|
||||
delete_unfixed(vars);
|
||||
delete_unfixed(unfixed_lits, unfixed_vars);
|
||||
}
|
||||
extract_fixed_consequences(num_units, assumptions, vars, conseq);
|
||||
extract_fixed_consequences(num_units, assumptions, unfixed_vars, conseq);
|
||||
update_unfixed_literals(unfixed_lits, unfixed_vars);
|
||||
IF_VERBOSE(1, verbose_stream() << "(sat.get-consequences"
|
||||
<< " iterations: " << num_iterations
|
||||
<< " variables: " << vars.size()
|
||||
<< " variables: " << unfixed_lits.size()
|
||||
<< " fixed: " << conseq.size()
|
||||
<< " unfixed: " << lits.size() - conseq.size() - vars.size()
|
||||
<< " unfixed: " << lits.size() - conseq.size() - unfixed_lits.size()
|
||||
<< ")\n";);
|
||||
|
||||
if (!unfixed_lits.empty() && m_config.m_restart_max <= num_iterations) {
|
||||
return l_undef;
|
||||
}
|
||||
}
|
||||
return l_true;
|
||||
}
|
||||
|
||||
void solver::delete_unfixed(literal_set& unfixed) {
|
||||
void solver::delete_unfixed(literal_set& unfixed_lits, bool_var_set& unfixed_vars) {
|
||||
literal_set to_keep;
|
||||
literal_set::iterator it = unfixed.begin(), end = unfixed.end();
|
||||
literal_set::iterator it = unfixed_lits.begin(), end = unfixed_lits.end();
|
||||
for (; it != end; ++it) {
|
||||
literal lit = *it;
|
||||
if (value(lit) == l_true) {
|
||||
to_keep.insert(lit);
|
||||
}
|
||||
else {
|
||||
unfixed_vars.remove(lit.var());
|
||||
}
|
||||
}
|
||||
unfixed = to_keep;
|
||||
unfixed_lits = to_keep;
|
||||
}
|
||||
|
||||
void solver::extract_fixed_consequences(unsigned& start, literal_set const& assumptions, literal_set& unfixed, vector<literal_vector>& conseq) {
|
||||
if (scope_lvl() > 1) {
|
||||
pop(scope_lvl() - 1);
|
||||
void solver::update_unfixed_literals(literal_set& unfixed_lits, bool_var_set& unfixed_vars) {
|
||||
literal_vector to_delete;
|
||||
literal_set::iterator it = unfixed_lits.begin(), end = unfixed_lits.end();
|
||||
for (; it != end; ++it) {
|
||||
literal lit = *it;
|
||||
if (!unfixed_vars.contains(lit.var())) {
|
||||
to_delete.push_back(lit);
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < to_delete.size(); ++i) {
|
||||
unfixed_lits.remove(to_delete[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void solver::extract_fixed_consequences(unsigned& start, literal_set const& assumptions, bool_var_set& unfixed, vector<literal_vector>& conseq) {
|
||||
SASSERT(!inconsistent());
|
||||
unsigned sz = m_trail.size();
|
||||
for (unsigned i = start; i < sz; ++i) {
|
||||
extract_fixed_consequences(m_trail[i], assumptions, unfixed, conseq);
|
||||
for (unsigned i = start; i < sz && lvl(m_trail[i]) <= 1; ++i) {
|
||||
if (!extract_fixed_consequences(m_trail[i], assumptions, unfixed, conseq)) {
|
||||
for (i = 0; i < sz && lvl(m_trail[i]) <= 1; ++i) {
|
||||
VERIFY(extract_fixed_consequences(m_trail[i], assumptions, unfixed, conseq));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
start = sz;
|
||||
}
|
||||
|
||||
void solver::extract_assumptions(literal lit, index_set& s) {
|
||||
bool solver::check_domain(literal lit, literal lit2) {
|
||||
return m_antecedents.contains(lit2.var());
|
||||
}
|
||||
|
||||
bool solver::extract_assumptions(literal lit, index_set& s) {
|
||||
justification js = m_justification[lit.var()];
|
||||
switch (js.get_kind()) {
|
||||
case justification::NONE:
|
||||
break;
|
||||
case justification::BINARY:
|
||||
if (!check_domain(lit, js.get_literal())) return false;
|
||||
s |= m_antecedents.find(js.get_literal().var());
|
||||
break;
|
||||
case justification::TERNARY:
|
||||
if (!check_domain(lit, js.get_literal1())) return false;
|
||||
if (!check_domain(lit, js.get_literal2())) return false;
|
||||
s |= m_antecedents.find(js.get_literal1().var());
|
||||
s |= m_antecedents.find(js.get_literal2().var());
|
||||
break;
|
||||
|
@ -3256,6 +3260,7 @@ namespace sat {
|
|||
clause & c = *(m_cls_allocator.get_clause(js.get_clause_offset()));
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
if (c[i] != lit) {
|
||||
if (!check_domain(lit, c[i])) return false;
|
||||
s |= m_antecedents.find(c[i].var());
|
||||
}
|
||||
}
|
||||
|
@ -3266,6 +3271,7 @@ namespace sat {
|
|||
literal_vector::iterator it = m_ext_antecedents.begin();
|
||||
literal_vector::iterator end = m_ext_antecedents.end();
|
||||
for (; it != end; ++it) {
|
||||
if (!check_domain(lit, *it)) return false;
|
||||
s |= m_antecedents.find(it->var());
|
||||
}
|
||||
break;
|
||||
|
@ -3274,28 +3280,46 @@ namespace sat {
|
|||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
TRACE("sat", display_index_set(tout << lit << ": " , s) << "\n";);
|
||||
return true;
|
||||
}
|
||||
|
||||
void solver::extract_fixed_consequences(literal lit, literal_set const& assumptions, literal_set& unfixed, vector<literal_vector>& conseq) {
|
||||
std::ostream& solver::display_index_set(std::ostream& out, index_set const& s) const {
|
||||
index_set::iterator it = s.begin();
|
||||
index_set::iterator end = s.end();
|
||||
for (; it != end; ++it) {
|
||||
out << to_literal(*it) << " ";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
bool solver::extract_fixed_consequences(literal lit, literal_set const& assumptions, bool_var_set& unfixed, vector<literal_vector>& conseq) {
|
||||
index_set s;
|
||||
if (m_antecedents.contains(lit.var())) {
|
||||
return true;
|
||||
}
|
||||
if (assumptions.contains(lit)) {
|
||||
s.insert(lit.index());
|
||||
}
|
||||
else {
|
||||
if (!extract_assumptions(lit, s)) {
|
||||
return false;
|
||||
}
|
||||
add_assumption(lit);
|
||||
extract_assumptions(lit, s);
|
||||
}
|
||||
m_antecedents.insert(lit.var(), s);
|
||||
if (unfixed.contains(lit)) {
|
||||
if (unfixed.contains(lit.var())) {
|
||||
literal_vector cons;
|
||||
cons.push_back(lit);
|
||||
index_set::iterator it = s.begin(), end = s.end();
|
||||
for (; it != end; ++it) {
|
||||
cons.push_back(to_literal(*it));
|
||||
}
|
||||
unfixed.remove(lit);
|
||||
unfixed.remove(lit.var());
|
||||
conseq.push_back(cons);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void solver::asymmetric_branching() {
|
||||
|
|
|
@ -33,7 +33,6 @@ Revision History:
|
|||
#include"sat_iff3_finder.h"
|
||||
#include"sat_probing.h"
|
||||
#include"sat_mus.h"
|
||||
#include"sat_sls.h"
|
||||
#include"params.h"
|
||||
#include"statistics.h"
|
||||
#include"stopwatch.h"
|
||||
|
@ -86,7 +85,6 @@ namespace sat {
|
|||
asymm_branch m_asymm_branch;
|
||||
probing m_probing;
|
||||
mus m_mus; // MUS for minimal core extraction
|
||||
wsls m_wsls; // SLS facility for MaxSAT use
|
||||
bool m_inconsistent;
|
||||
// A conflict is usually a single justification. That is, a justification
|
||||
// for false. If m_not_l is not null_literal, then m_conflict is a
|
||||
|
@ -141,9 +139,6 @@ namespace sat {
|
|||
friend class probing;
|
||||
friend class iff3_finder;
|
||||
friend class mus;
|
||||
friend class sls;
|
||||
friend class wsls;
|
||||
friend class bceq;
|
||||
friend struct mk_stat;
|
||||
public:
|
||||
solver(params_ref const & p, reslimit& l, extension * ext);
|
||||
|
@ -189,11 +184,9 @@ namespace sat {
|
|||
void mk_bin_clause(literal l1, literal l2, bool learned);
|
||||
bool propagate_bin_clause(literal l1, literal l2);
|
||||
clause * mk_ter_clause(literal * lits, bool learned);
|
||||
void attach_ter_clause(clause & c, bool & reinit);
|
||||
void attach_ter_clause(clause & c) { bool reinit; attach_ter_clause(c, reinit); }
|
||||
bool attach_ter_clause(clause & c);
|
||||
clause * mk_nary_clause(unsigned num_lits, literal * lits, bool learned);
|
||||
void attach_nary_clause(clause & c, bool & reinit);
|
||||
void attach_nary_clause(clause & c) { bool reinit; attach_nary_clause(c, reinit); }
|
||||
bool attach_nary_clause(clause & c);
|
||||
void attach_clause(clause & c, bool & reinit);
|
||||
void attach_clause(clause & c) { bool reinit; attach_clause(c, reinit); }
|
||||
unsigned select_watch_lit(clause const & cls, unsigned starting_at) const;
|
||||
|
@ -280,10 +273,7 @@ namespace sat {
|
|||
//
|
||||
// -----------------------
|
||||
public:
|
||||
lbool check(unsigned num_lits = 0, literal const* lits = 0) {
|
||||
return check(num_lits, lits, 0, 0);
|
||||
}
|
||||
lbool check(unsigned num_lits, literal const* lits, double const* weights, double max_weight);
|
||||
lbool check(unsigned num_lits = 0, literal const* lits = 0);
|
||||
|
||||
model const & get_model() const { return m_model; }
|
||||
bool model_is_current() const { return m_model_is_current; }
|
||||
|
@ -311,11 +301,7 @@ namespace sat {
|
|||
|
||||
literal_vector m_min_core;
|
||||
bool m_min_core_valid;
|
||||
literal_vector m_blocker;
|
||||
double m_weight;
|
||||
bool m_initializing_preferred;
|
||||
void init_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight);
|
||||
bool init_weighted_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight);
|
||||
void init_assumptions(unsigned num_lits, literal const* lits);
|
||||
void reassert_min_core();
|
||||
void update_min_core();
|
||||
void resolve_weighted();
|
||||
|
@ -453,15 +439,25 @@ namespace sat {
|
|||
u_map<index_set> m_antecedents;
|
||||
vector<literal_vector> m_binary_clause_graph;
|
||||
|
||||
void extract_assumptions(literal lit, index_set& s);
|
||||
bool extract_assumptions(literal lit, index_set& s);
|
||||
|
||||
bool check_domain(literal lit, literal lit2);
|
||||
|
||||
std::ostream& display_index_set(std::ostream& out, index_set const& s) const;
|
||||
|
||||
lbool get_consequences(literal_vector const& assms, literal_vector const& lits, vector<literal_vector>& conseq);
|
||||
|
||||
void delete_unfixed(literal_set& unfixed);
|
||||
lbool get_bounded_consequences(literal_vector const& assms, bool_var_vector const& vars, vector<literal_vector>& conseq);
|
||||
|
||||
void extract_fixed_consequences(unsigned& start, literal_set const& assumptions, literal_set& unfixed, vector<literal_vector>& conseq);
|
||||
void delete_unfixed(literal_set& unfixed_lits, bool_var_set& unfixed_vars);
|
||||
|
||||
void extract_fixed_consequences(literal lit, literal_set const& assumptions, literal_set& unfixed, vector<literal_vector>& conseq);
|
||||
void extract_fixed_consequences(unsigned& start, literal_set const& assumptions, bool_var_set& unfixed, vector<literal_vector>& conseq);
|
||||
|
||||
bool extract_fixed_consequences(literal lit, literal_set const& assumptions, bool_var_set& unfixed, vector<literal_vector>& conseq);
|
||||
|
||||
void update_unfixed_literals(literal_set& unfixed_lits, bool_var_set& unfixed_vars);
|
||||
|
||||
void fixup_consequence_core();
|
||||
|
||||
// -----------------------
|
||||
//
|
||||
|
|
|
@ -105,13 +105,8 @@ public:
|
|||
|
||||
virtual void set_progress_callback(progress_callback * callback) {}
|
||||
|
||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) {
|
||||
return check_sat(num_assumptions, assumptions, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
void display_weighted(std::ostream& out, unsigned sz, expr * const * assumptions, unsigned const* weights) {
|
||||
m_weights.reset();
|
||||
if (weights != 0) {
|
||||
for (unsigned i = 0; i < sz; ++i) m_weights.push_back(weights[i]);
|
||||
}
|
||||
|
@ -131,15 +126,11 @@ public:
|
|||
for (unsigned i = 0; i < m_asms.size(); ++i) {
|
||||
nweights.push_back((unsigned) m_weights[i]);
|
||||
}
|
||||
m_weights.reset();
|
||||
m_solver.display_wcnf(out, m_asms.size(), m_asms.c_ptr(), nweights.c_ptr());
|
||||
}
|
||||
|
||||
lbool check_sat(unsigned sz, expr * const * assumptions, double const* weights, double max_weight) {
|
||||
m_weights.reset();
|
||||
if (weights != 0) {
|
||||
m_weights.append(sz, weights);
|
||||
}
|
||||
SASSERT(m_weights.empty() == (m_weights.c_ptr() == 0));
|
||||
virtual lbool check_sat(unsigned sz, expr * const * assumptions) {
|
||||
m_solver.pop_to_base_level();
|
||||
dep2asm_t dep2asm;
|
||||
m_model = 0;
|
||||
|
@ -148,10 +139,10 @@ public:
|
|||
r = internalize_assumptions(sz, assumptions, dep2asm);
|
||||
if (r != l_true) return r;
|
||||
|
||||
r = m_solver.check(m_asms.size(), m_asms.c_ptr(), m_weights.c_ptr(), max_weight);
|
||||
r = m_solver.check(m_asms.size(), m_asms.c_ptr());
|
||||
switch (r) {
|
||||
case l_true:
|
||||
if (sz > 0 && !weights) {
|
||||
if (sz > 0) {
|
||||
check_assumptions(dep2asm);
|
||||
}
|
||||
break;
|
||||
|
@ -252,12 +243,17 @@ public:
|
|||
m_solver.pop_to_base_level();
|
||||
lbool r = internalize_formulas();
|
||||
if (r != l_true) return r;
|
||||
r = internalize_vars(vars, bvars);
|
||||
if (r != l_true) return r;
|
||||
r = internalize_assumptions(assumptions.size(), assumptions.c_ptr(), dep2asm);
|
||||
if (r != l_true) return r;
|
||||
r = internalize_vars(vars, bvars);
|
||||
|
||||
r = m_solver.get_consequences(m_asms, bvars, lconseq);
|
||||
if (r != l_true) return r;
|
||||
if (r == l_false) {
|
||||
if (!m_asms.empty()) {
|
||||
extract_core(dep2asm);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// build map from bound variables to
|
||||
// the consequences that cover them.
|
||||
|
@ -670,18 +666,6 @@ solver* mk_inc_sat_solver(ast_manager& m, params_ref const& p) {
|
|||
}
|
||||
|
||||
|
||||
lbool inc_sat_check_sat(solver& _s, unsigned sz, expr*const* soft, rational const* _weights, rational const& max_weight) {
|
||||
inc_sat_solver& s = dynamic_cast<inc_sat_solver&>(_s);
|
||||
vector<double> weights;
|
||||
for (unsigned i = 0; _weights && i < sz; ++i) {
|
||||
weights.push_back(_weights[i].get_double());
|
||||
}
|
||||
params_ref p;
|
||||
p.set_bool("minimize_core", false);
|
||||
s.updt_params(p);
|
||||
return s.check_sat(sz, soft, weights.c_ptr(), max_weight.get_double());
|
||||
}
|
||||
|
||||
void inc_sat_display(std::ostream& out, solver& _s, unsigned sz, expr*const* soft, rational const* _weights) {
|
||||
inc_sat_solver& s = dynamic_cast<inc_sat_solver&>(_s);
|
||||
vector<unsigned> weights;
|
||||
|
|
|
@ -24,7 +24,6 @@ Notes:
|
|||
|
||||
solver* mk_inc_sat_solver(ast_manager& m, params_ref const& p);
|
||||
|
||||
lbool inc_sat_check_sat(solver& s, unsigned sz, expr*const* soft, rational const* weights, rational const& max_weight);
|
||||
|
||||
void inc_sat_display(std::ostream& out, solver& s, unsigned sz, expr*const* soft, rational const* _weights);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ Revision History:
|
|||
#include"opt_cmds.h"
|
||||
#include"polynomial_cmds.h"
|
||||
#include"subpaving_cmds.h"
|
||||
#include"smt2_extra_cmds.h"
|
||||
#include"smt_strategic_solver.h"
|
||||
#include"smt_solver.h"
|
||||
|
||||
|
@ -113,6 +114,7 @@ unsigned read_smtlib2_commands(char const * file_name) {
|
|||
install_polynomial_cmds(ctx);
|
||||
install_subpaving_cmds(ctx);
|
||||
install_opt_cmds(ctx);
|
||||
install_smt2_extra_cmds(ctx);
|
||||
|
||||
g_cmd_context = &ctx;
|
||||
signal(SIGINT, on_ctrl_c);
|
||||
|
|
|
@ -184,13 +184,13 @@ void asserted_formulas::get_assertions(ptr_vector<expr> & result) {
|
|||
}
|
||||
|
||||
void asserted_formulas::push_scope() {
|
||||
SASSERT(inconsistent() || m_asserted_qhead == m_asserted_formulas.size());
|
||||
SASSERT(inconsistent() || m_asserted_qhead == m_asserted_formulas.size() || m_manager.canceled());
|
||||
TRACE("asserted_formulas_scopes", tout << "push:\n"; display(tout););
|
||||
m_scopes.push_back(scope());
|
||||
m_macro_manager.push_scope();
|
||||
scope & s = m_scopes.back();
|
||||
s.m_asserted_formulas_lim = m_asserted_formulas.size();
|
||||
SASSERT(inconsistent() || s.m_asserted_formulas_lim == m_asserted_qhead);
|
||||
SASSERT(inconsistent() || s.m_asserted_formulas_lim == m_asserted_qhead || m_manager.canceled());
|
||||
s.m_inconsistent_old = m_inconsistent;
|
||||
m_defined_names.push();
|
||||
m_bv_sharing.push_scope();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
def_module_params(module_name='smt',
|
||||
def_module_params(module_name='smt',
|
||||
class_name='smt_params_helper',
|
||||
description='smt solver based on lazy smt',
|
||||
export=True,
|
||||
|
@ -17,7 +17,7 @@ def_module_params(module_name='smt',
|
|||
('pull_nested_quantifiers', BOOL, False, 'pull nested quantifiers'),
|
||||
('refine_inj_axioms', BOOL, True, 'refine injectivity axioms'),
|
||||
('timeout', UINT, UINT_MAX, 'timeout (in milliseconds) (UINT_MAX and 0 mean no timeout)'),
|
||||
('rlimit', UINT, 0, 'resource limit (0 means no limit)'),
|
||||
('rlimit', UINT, 0, 'resource limit (0 means no limit)'),
|
||||
('max_conflicts', UINT, UINT_MAX, 'maximum number of conflicts before giving up.'),
|
||||
('mbqi', BOOL, True, 'model based quantifier instantiation (MBQI)'),
|
||||
('mbqi.max_cexs', UINT, 1, 'initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation'),
|
||||
|
@ -62,5 +62,6 @@ def_module_params(module_name='smt',
|
|||
('dack.gc_inv_decay', DOUBLE, 0.8, 'Dynamic ackermannization garbage collection decay'),
|
||||
('dack.threshold', UINT, 10, ' number of times the congruence rule must be used before Leibniz\'s axiom is expanded'),
|
||||
('core.validate', BOOL, False, 'validate unsat core produced by SMT context'),
|
||||
('core.minimize', BOOL, False, 'minimize unsat core produced by SMT context')
|
||||
('core.minimize', BOOL, False, 'minimize unsat core produced by SMT context'),
|
||||
('core.extend_patterns', BOOL, False, 'extend unsat core with literals that trigger (potential) quantifier instances')
|
||||
))
|
||||
|
|
47
src/smt/smt2_extra_cmds.cpp
Normal file
47
src/smt/smt2_extra_cmds.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smt2_extra_cmds.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Additional SMT-specific commands.
|
||||
|
||||
Author:
|
||||
|
||||
Christoph (cwinter) 2017-01-16
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"cmd_context.h"
|
||||
#include"smt2parser.h"
|
||||
#include"smt2_extra_cmds.h"
|
||||
|
||||
class include_cmd : public cmd {
|
||||
char const * m_filename;
|
||||
public:
|
||||
include_cmd() : cmd("include"), m_filename(0) {}
|
||||
virtual char const * get_usage() const { return "<string>"; }
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "include a file"; }
|
||||
virtual unsigned get_arity() const { return 1; }
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { return CPK_STRING; }
|
||||
virtual void set_next_arg(cmd_context & ctx, char const * val) { m_filename = val; }
|
||||
virtual void failure_cleanup(cmd_context & ctx) {}
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
std::ifstream is(m_filename);
|
||||
if (is.bad() || is.fail())
|
||||
throw cmd_exception(std::string("failed to open file '") + m_filename + "'");
|
||||
parse_smt2_commands(ctx, is, false, params_ref(), m_filename);
|
||||
is.close();
|
||||
}
|
||||
virtual void prepare(cmd_context & ctx) { reset(ctx); }
|
||||
virtual void reset(cmd_context & ctx) { m_filename = 0; }
|
||||
virtual void finalize(cmd_context & ctx) { reset(ctx); }
|
||||
};
|
||||
|
||||
void install_smt2_extra_cmds(cmd_context & ctx) {
|
||||
ctx.insert(alloc(include_cmd));
|
||||
}
|
26
src/smt/smt2_extra_cmds.h
Normal file
26
src/smt/smt2_extra_cmds.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smt2_extra_cmds.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Additional SMT-specific commands.
|
||||
|
||||
Author:
|
||||
|
||||
Christoph (cwinter) 2017-01-16
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef SMT2_EXTRA_CMDS_H_
|
||||
#define SMT2_EXTRA_CMDS_H_
|
||||
|
||||
class cmd_context;
|
||||
|
||||
void install_smt2_extra_cmds(cmd_context & ctx);
|
||||
|
||||
#endif /* SMT2_EXTRA_CMDS_H_ */
|
|
@ -24,7 +24,9 @@ Revision History:
|
|||
namespace smt {
|
||||
|
||||
struct bool_var_data {
|
||||
private:
|
||||
b_justification m_justification;
|
||||
public:
|
||||
unsigned m_scope_lvl:24; //!< scope level of when the variable was assigned.
|
||||
unsigned m_mark:1;
|
||||
unsigned m_assumption:1;
|
||||
|
@ -45,6 +47,14 @@ namespace smt {
|
|||
public:
|
||||
|
||||
unsigned get_intern_level() const { return m_iscope_lvl; }
|
||||
|
||||
b_justification justification() const { return m_justification; }
|
||||
|
||||
void set_axiom() { m_justification = b_justification::mk_axiom(); }
|
||||
|
||||
void set_null_justification() { m_justification = null_b_justification; }
|
||||
|
||||
void set_justification(b_justification const& j) { m_justification = j; }
|
||||
|
||||
bool is_atom() const { return m_atom; }
|
||||
|
||||
|
|
|
@ -496,13 +496,15 @@ namespace smt {
|
|||
|
||||
unsigned idx = skip_literals_above_conflict_level();
|
||||
|
||||
TRACE("conflict", m_ctx.display_literal_verbose(tout, not_l); m_ctx.display(tout << " ", conflict););
|
||||
|
||||
// save space for first uip
|
||||
m_lemma.push_back(null_literal);
|
||||
m_lemma_atoms.push_back(0);
|
||||
|
||||
unsigned num_marks = 0;
|
||||
if (not_l != null_literal) {
|
||||
TRACE("conflict", tout << "not_l: "; m_ctx.display_literal(tout, not_l); tout << "\n";);
|
||||
TRACE("conflict", tout << "not_l: "; m_ctx.display_literal_verbose(tout, not_l); tout << "\n";);
|
||||
process_antecedent(not_l, num_marks);
|
||||
}
|
||||
|
||||
|
@ -514,7 +516,7 @@ namespace smt {
|
|||
get_manager().trace_stream() << "\n";
|
||||
}
|
||||
|
||||
TRACE("conflict", tout << "processing consequent: "; m_ctx.display_literal(tout, consequent); tout << "\n";
|
||||
TRACE("conflict", tout << "processing consequent: "; m_ctx.display_literal_verbose(tout, consequent); tout << "\n";
|
||||
tout << "num_marks: " << num_marks << ", js kind: " << js.get_kind() << "\n";);
|
||||
SASSERT(js != null_b_justification);
|
||||
switch (js.get_kind()) {
|
||||
|
@ -1076,6 +1078,7 @@ namespace smt {
|
|||
return true;
|
||||
SASSERT(js.get_kind() != b_justification::BIN_CLAUSE);
|
||||
CTRACE("visit_b_justification_bug", js.get_kind() == b_justification::AXIOM, tout << "l: " << l << "\n"; m_ctx.display(tout););
|
||||
|
||||
if (js.get_kind() == b_justification::AXIOM)
|
||||
return true;
|
||||
SASSERT(js.get_kind() != b_justification::AXIOM);
|
||||
|
@ -1089,14 +1092,17 @@ namespace smt {
|
|||
i = 1;
|
||||
}
|
||||
else {
|
||||
SASSERT(cls->get_literal(1) == l);
|
||||
if (get_proof(~cls->get_literal(0)) == 0)
|
||||
visited = false;
|
||||
i = 2;
|
||||
}
|
||||
}
|
||||
for (; i < num_lits; i++)
|
||||
for (; i < num_lits; i++) {
|
||||
SASSERT(cls->get_literal(i) != l);
|
||||
if (get_proof(~cls->get_literal(i)) == 0)
|
||||
visited = false;
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
else
|
||||
|
@ -1251,14 +1257,19 @@ namespace smt {
|
|||
}
|
||||
tout << "\n";);
|
||||
init_mk_proof();
|
||||
literal consequent = false_literal;
|
||||
if (not_l != null_literal)
|
||||
consequent = ~not_l;
|
||||
visit_b_justification(consequent, conflict);
|
||||
if (not_l != null_literal)
|
||||
literal consequent;
|
||||
if (not_l == null_literal) {
|
||||
consequent = false_literal;
|
||||
}
|
||||
else {
|
||||
consequent = ~not_l;
|
||||
m_todo_pr.push_back(tp_elem(not_l));
|
||||
}
|
||||
visit_b_justification(consequent, conflict);
|
||||
|
||||
while (!m_todo_pr.empty()) {
|
||||
tp_elem & elem = m_todo_pr.back();
|
||||
|
||||
switch (elem.m_kind) {
|
||||
case tp_elem::EQUALITY: {
|
||||
enode * lhs = elem.m_lhs;
|
||||
|
|
|
@ -261,10 +261,11 @@ namespace smt {
|
|||
m_assignment[false_literal.index()] = l_false;
|
||||
if (m_manager.proofs_enabled()) {
|
||||
proof * pr = m_manager.mk_true_proof();
|
||||
m_bdata[true_bool_var].m_justification = b_justification(mk_justification(justification_proof_wrapper(*this, pr)));
|
||||
|
||||
set_justification(true_bool_var, m_bdata[true_bool_var], b_justification(mk_justification(justification_proof_wrapper(*this, pr))));
|
||||
}
|
||||
else {
|
||||
m_bdata[true_bool_var].m_justification = b_justification::mk_axiom();
|
||||
m_bdata[true_bool_var].set_axiom();
|
||||
}
|
||||
m_true_enode = mk_enode(t, true, true, false);
|
||||
// internalizer is marking enodes as interpreted whenever the associated ast is a value and a constant.
|
||||
|
@ -292,6 +293,12 @@ namespace smt {
|
|||
std::swap(lhs, rhs);
|
||||
return m_manager.mk_eq(lhs, rhs);
|
||||
}
|
||||
|
||||
void context::set_justification(bool_var v, bool_var_data& d, b_justification const& j) {
|
||||
SASSERT(validate_justification(v, d, j));
|
||||
d.set_justification(j);
|
||||
}
|
||||
|
||||
|
||||
void context::assign_core(literal l, b_justification j, bool decision) {
|
||||
TRACE("assign_core", tout << (decision?"decision: ":"propagating: ") << l << " ";
|
||||
|
@ -302,7 +309,7 @@ namespace smt {
|
|||
m_assignment[l.index()] = l_true;
|
||||
m_assignment[(~l).index()] = l_false;
|
||||
bool_var_data & d = get_bdata(l.var());
|
||||
d.m_justification = j;
|
||||
set_justification(l.var(), d, j);
|
||||
d.m_scope_lvl = m_scope_lvl;
|
||||
if (m_fparams.m_restart_adaptive && d.m_phase_available) {
|
||||
m_agility *= m_fparams.m_agility_factor;
|
||||
|
@ -1406,7 +1413,8 @@ namespace smt {
|
|||
else {
|
||||
TRACE("add_diseq", display_eq_detail(tout, bool_var2enode(v)););
|
||||
if (!add_diseq(get_enode(lhs), get_enode(rhs)) && !inconsistent()) {
|
||||
set_conflict(b_justification(mk_justification(eq_propagation_justification(get_enode(lhs), get_enode(rhs)))), ~l);
|
||||
literal n_eq = literal(l.var(), true);
|
||||
set_conflict(b_justification(mk_justification(eq_propagation_justification(get_enode(lhs), get_enode(rhs)))), n_eq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1787,6 +1795,7 @@ namespace smt {
|
|||
|
||||
void context::set_conflict(b_justification js, literal not_l) {
|
||||
if (!inconsistent()) {
|
||||
TRACE("set_conflict", display_literal_verbose(tout, not_l); display(tout, js); );
|
||||
m_conflict = js;
|
||||
m_not_l = not_l;
|
||||
}
|
||||
|
@ -2042,7 +2051,7 @@ namespace smt {
|
|||
m_assignment[(~l).index()] = l_undef;
|
||||
bool_var v = l.var();
|
||||
bool_var_data & d = get_bdata(v);
|
||||
d.m_justification = null_b_justification;
|
||||
d.set_null_justification();
|
||||
m_case_split_queue->unassign_var_eh(v);
|
||||
}
|
||||
|
||||
|
@ -2593,10 +2602,10 @@ namespace smt {
|
|||
cls->set_justification(0);
|
||||
m_justifications.push_back(js);
|
||||
}
|
||||
m_bdata[v0].m_justification = b_justification(js);
|
||||
set_justification(v0, m_bdata[v0], b_justification(js));
|
||||
}
|
||||
else
|
||||
m_bdata[v0].m_justification = b_justification::mk_axiom();
|
||||
m_bdata[v0].set_axiom();
|
||||
}
|
||||
}
|
||||
del_clause(cls);
|
||||
|
|
|
@ -50,9 +50,9 @@ Revision History:
|
|||
#include"statistics.h"
|
||||
#include"progress_callback.h"
|
||||
|
||||
// there is a significant space overhead with allocating 1000+ contexts in
|
||||
// there is a significant space overhead with allocating 1000+ contexts in
|
||||
// the case that each context only references a few expressions.
|
||||
// Using a map instead of a vector for the literals can compress space
|
||||
// Using a map instead of a vector for the literals can compress space
|
||||
// consumption.
|
||||
#ifdef SPARSE_MAP
|
||||
#define USE_BOOL_VAR_VECTOR 0
|
||||
|
@ -98,7 +98,7 @@ namespace smt {
|
|||
// Remark: boolean expressions can also be internalized as
|
||||
// enodes. Examples: boolean expression nested in an
|
||||
// uninterpreted function.
|
||||
expr_ref_vector m_e_internalized_stack; // stack of the expressions already internalized as enodes.
|
||||
expr_ref_vector m_e_internalized_stack; // stack of the expressions already internalized as enodes.
|
||||
|
||||
ptr_vector<justification> m_justifications;
|
||||
|
||||
|
@ -116,7 +116,7 @@ namespace smt {
|
|||
plugin_manager<theory> m_theories; // mapping from theory_id -> theory
|
||||
ptr_vector<theory> m_theory_set; // set of theories for fast traversal
|
||||
vector<enode_vector> m_decl2enodes; // decl -> enode (for decls with arity > 0)
|
||||
cg_table m_cg_table;
|
||||
cg_table m_cg_table;
|
||||
dyn_ack_manager m_dyn_ack_manager;
|
||||
struct new_eq {
|
||||
enode * m_lhs;
|
||||
|
@ -140,7 +140,7 @@ namespace smt {
|
|||
svector<new_th_eq> m_propagated_th_eqs;
|
||||
svector<new_th_eq> m_propagated_th_diseqs;
|
||||
svector<enode_pair> m_diseq_vector;
|
||||
#endif
|
||||
#endif
|
||||
enode * m_is_diseq_tmp; // auxiliary enode used to find congruent equality atoms.
|
||||
|
||||
tmp_enode m_tmp_enode;
|
||||
|
@ -161,8 +161,8 @@ namespace smt {
|
|||
vector<watch_list> m_watches; //!< per literal
|
||||
vector<clause_set> m_lit_occs; //!< index for backward subsumption
|
||||
svector<bool_var_data> m_bdata; //!< mapping bool_var -> data
|
||||
svector<double> m_activity;
|
||||
clause_vector m_aux_clauses;
|
||||
svector<double> m_activity;
|
||||
clause_vector m_aux_clauses;
|
||||
clause_vector m_lemmas;
|
||||
vector<clause_vector> m_clauses_to_reinit;
|
||||
expr_ref_vector m_units_to_reassert;
|
||||
|
@ -176,7 +176,7 @@ namespace smt {
|
|||
bool m_phase_cache_on;
|
||||
unsigned m_phase_counter; //!< auxiliary variable used to decide when to turn on/off phase caching
|
||||
bool m_phase_default; //!< default phase when using phase caching
|
||||
|
||||
|
||||
// A conflict is usually a single justification. That is, a justification
|
||||
// for false. If m_not_l is not null_literal, then m_conflict is a
|
||||
// justification for l, and the conflict is union of m_no_l and m_conflict;
|
||||
|
@ -220,10 +220,10 @@ namespace smt {
|
|||
// Unsat core extraction
|
||||
//
|
||||
// -----------------------------------
|
||||
typedef u_map<expr *> literal2assumption;
|
||||
typedef u_map<expr *> literal2assumption;
|
||||
literal_vector m_assumptions;
|
||||
literal2assumption m_literal2assumption; // maps an expression associated with a literal to the original assumption
|
||||
expr_ref_vector m_unsat_core;
|
||||
expr_ref_vector m_unsat_core;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
|
@ -261,7 +261,7 @@ namespace smt {
|
|||
SASSERT(e_internalized(n));
|
||||
return m_app2enode[n->get_id()];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Similar to get_enode, but returns 0 if n is to e_internalized.
|
||||
*/
|
||||
|
@ -323,7 +323,7 @@ namespace smt {
|
|||
literal enode2literal(enode const * n) const {
|
||||
SASSERT(n->is_bool());
|
||||
return n == m_false_enode ? false_literal : literal(enode2bool_var(n));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned get_num_bool_vars() const {
|
||||
return m_b_internalized_stack.size();
|
||||
|
@ -336,7 +336,7 @@ namespace smt {
|
|||
bool_var_data const & get_bdata(bool_var v) const {
|
||||
return m_bdata[v];
|
||||
}
|
||||
|
||||
|
||||
lbool get_lit_assignment(unsigned lit_idx) const {
|
||||
return static_cast<lbool>(m_assignment[lit_idx]);
|
||||
}
|
||||
|
@ -349,8 +349,8 @@ namespace smt {
|
|||
return get_assignment(literal(v));
|
||||
}
|
||||
|
||||
literal_vector const & assigned_literals() const {
|
||||
return m_assigned_literals;
|
||||
literal_vector const & assigned_literals() const {
|
||||
return m_assigned_literals;
|
||||
}
|
||||
|
||||
lbool get_assignment(expr * n) const;
|
||||
|
@ -363,9 +363,11 @@ namespace smt {
|
|||
void get_assignments(expr_ref_vector& assignments);
|
||||
|
||||
b_justification get_justification(bool_var v) const {
|
||||
return get_bdata(v).m_justification;
|
||||
return get_bdata(v).justification();
|
||||
}
|
||||
|
||||
void set_justification(bool_var v, bool_var_data& d, b_justification const& j);
|
||||
|
||||
bool has_th_justification(bool_var v, theory_id th_id) const {
|
||||
b_justification js = get_justification(v);
|
||||
return js.get_kind() == b_justification::JUSTIFICATION && js.get_justification()->get_from_theory() == th_id;
|
||||
|
@ -423,7 +425,7 @@ namespace smt {
|
|||
unsigned get_assign_level(literal l) const {
|
||||
return get_assign_level(l.var());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Return the scope level when v was internalized.
|
||||
*/
|
||||
|
@ -434,7 +436,7 @@ namespace smt {
|
|||
theory * get_theory(theory_id th_id) const {
|
||||
return m_theories.get_plugin(th_id);
|
||||
}
|
||||
|
||||
|
||||
ptr_vector<theory>::const_iterator begin_theories() const {
|
||||
return m_theories.begin();
|
||||
}
|
||||
|
@ -448,7 +450,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
unsigned get_base_level() const {
|
||||
return m_base_lvl;
|
||||
return m_base_lvl;
|
||||
}
|
||||
|
||||
bool at_base_level() const {
|
||||
|
@ -468,11 +470,11 @@ namespace smt {
|
|||
}
|
||||
|
||||
expr * bool_var2expr(bool_var v) const {
|
||||
return m_bool_var2expr[v];
|
||||
return m_bool_var2expr[v];
|
||||
}
|
||||
|
||||
|
||||
void literal2expr(literal l, expr_ref & result) const {
|
||||
if (l == true_literal)
|
||||
if (l == true_literal)
|
||||
result = m_manager.mk_true();
|
||||
else if (l == false_literal)
|
||||
result = m_manager.mk_false();
|
||||
|
@ -499,7 +501,7 @@ namespace smt {
|
|||
unsigned id = decl->get_decl_id();
|
||||
return id < m_decl2enodes.size() ? m_decl2enodes[id].begin() : 0;
|
||||
}
|
||||
|
||||
|
||||
enode_vector::const_iterator end_enodes_of(func_decl const * decl) const {
|
||||
unsigned id = decl->get_decl_id();
|
||||
return id < m_decl2enodes.size() ? m_decl2enodes[id].end() : 0;
|
||||
|
@ -589,7 +591,7 @@ namespace smt {
|
|||
void push_scope();
|
||||
|
||||
unsigned pop_scope_core(unsigned num_scopes);
|
||||
|
||||
|
||||
void pop_scope(unsigned num_scopes);
|
||||
|
||||
void undo_trail_stack(unsigned old_size);
|
||||
|
@ -615,13 +617,13 @@ namespace smt {
|
|||
bool is_empty_clause(clause const * c) const;
|
||||
|
||||
void cache_generation(unsigned new_scope_lvl);
|
||||
|
||||
|
||||
void cache_generation(clause const * cls, unsigned new_scope_lvl);
|
||||
|
||||
void cache_generation(unsigned num_lits, literal const * lits, unsigned new_scope_lvl);
|
||||
|
||||
void cache_generation(expr * n, unsigned new_scope_lvl);
|
||||
|
||||
|
||||
void reset_cache_generation();
|
||||
|
||||
void reinit_clauses(unsigned num_scopes, unsigned num_bool_vars);
|
||||
|
@ -630,14 +632,14 @@ namespace smt {
|
|||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Internalization
|
||||
// Internalization
|
||||
//
|
||||
// -----------------------------------
|
||||
public:
|
||||
bool b_internalized(expr const * n) const {
|
||||
return get_bool_var_of_id_option(n->get_id()) != null_bool_var;
|
||||
}
|
||||
|
||||
|
||||
bool lit_internalized(expr const * n) const {
|
||||
return m_manager.is_false(n) || (m_manager.is_not(n) ? b_internalized(to_app(n)->get_arg(0)) : b_internalized(n));
|
||||
}
|
||||
|
@ -646,7 +648,7 @@ namespace smt {
|
|||
return m_app2enode.get(n->get_id(), 0) != 0;
|
||||
}
|
||||
|
||||
unsigned get_num_b_internalized() const {
|
||||
unsigned get_num_b_internalized() const {
|
||||
return m_b_internalized_stack.size();
|
||||
}
|
||||
|
||||
|
@ -654,7 +656,7 @@ namespace smt {
|
|||
return m_b_internalized_stack.get(idx);
|
||||
}
|
||||
|
||||
unsigned get_num_e_internalized() const {
|
||||
unsigned get_num_e_internalized() const {
|
||||
return m_e_internalized_stack.size();
|
||||
}
|
||||
|
||||
|
@ -691,9 +693,9 @@ namespace smt {
|
|||
void ts_visit_child(expr * n, bool gate_ctx, svector<int> & tcolors, svector<int> & fcolors, svector<expr_bool_pair> & todo, bool & visited);
|
||||
|
||||
bool ts_visit_children(expr * n, bool gate_ctx, svector<int> & tcolors, svector<int> & fcolors, svector<expr_bool_pair> & todo);
|
||||
|
||||
|
||||
void top_sort_expr(expr * n, svector<expr_bool_pair> & sorted_exprs);
|
||||
|
||||
|
||||
void assert_default(expr * n, proof * pr);
|
||||
|
||||
void assert_distinct(app * n, proof * pr);
|
||||
|
@ -721,7 +723,7 @@ namespace smt {
|
|||
void internalize_term(app * n);
|
||||
|
||||
void internalize_ite_term(app * n);
|
||||
|
||||
|
||||
bool internalize_theory_term(app * n);
|
||||
|
||||
void internalize_uninterpreted(app * n);
|
||||
|
@ -752,7 +754,7 @@ namespace smt {
|
|||
bool simplify_aux_lemma_literals(unsigned & num_lits, literal * lits);
|
||||
|
||||
void mark_for_reinit(clause * cls, unsigned scope_lvl, bool reinternalize_atoms);
|
||||
|
||||
|
||||
unsigned get_max_iscope_lvl(unsigned num_lits, literal const * lits) const;
|
||||
|
||||
bool use_binary_clause_opt(literal l1, literal l2, bool lemma) const;
|
||||
|
@ -784,7 +786,7 @@ namespace smt {
|
|||
void add_and_rel_watches(app * n);
|
||||
|
||||
void add_or_rel_watches(app * n);
|
||||
|
||||
|
||||
void add_ite_rel_watches(app * n);
|
||||
|
||||
void mk_not_cnstr(app * n);
|
||||
|
@ -796,7 +798,7 @@ namespace smt {
|
|||
void mk_iff_cnstr(app * n);
|
||||
|
||||
void mk_ite_cnstr(app * n);
|
||||
|
||||
|
||||
bool lit_occs_enabled() const { return m_fparams.m_phase_selection==PS_OCCURRENCE; }
|
||||
|
||||
void add_lit_occs(clause * cls);
|
||||
|
@ -819,7 +821,7 @@ namespace smt {
|
|||
|
||||
|
||||
bool_var mk_bool_var(expr * n);
|
||||
|
||||
|
||||
enode * mk_enode(app * n, bool suppress_args, bool merge_tf, bool cgc_enabled);
|
||||
|
||||
void attach_th_var(enode * n, theory * th, theory_var v);
|
||||
|
@ -828,7 +830,7 @@ namespace smt {
|
|||
justification * mk_justification(Justification const & j) {
|
||||
justification * js = new (m_region) Justification(j);
|
||||
SASSERT(js->in_region());
|
||||
if (js->has_del_eh())
|
||||
if (js->has_del_eh())
|
||||
m_justifications.push_back(js);
|
||||
return js;
|
||||
}
|
||||
|
@ -849,10 +851,10 @@ namespace smt {
|
|||
unsigned m_num_conflicts_since_lemma_gc;
|
||||
unsigned m_restart_threshold;
|
||||
unsigned m_restart_outer_threshold;
|
||||
unsigned m_luby_idx;
|
||||
unsigned m_luby_idx;
|
||||
double m_agility;
|
||||
unsigned m_lemma_gc_threshold;
|
||||
|
||||
|
||||
void assign_core(literal l, b_justification j, bool decision = false);
|
||||
void trace_assign(literal l, b_justification j, bool decision) const;
|
||||
|
||||
|
@ -878,7 +880,7 @@ namespace smt {
|
|||
|
||||
friend class set_true_first_trail;
|
||||
void set_true_first_flag(bool_var v);
|
||||
|
||||
|
||||
bool try_true_first(bool_var v) const { return get_bdata(v).try_true_first(); }
|
||||
|
||||
bool assume_eq(enode * lhs, enode * rhs);
|
||||
|
@ -899,13 +901,13 @@ namespace smt {
|
|||
d.m_phase = phase;
|
||||
}
|
||||
|
||||
void force_phase(literal l) {
|
||||
void force_phase(literal l) {
|
||||
force_phase(l.var(), !l.sign());
|
||||
}
|
||||
|
||||
bool contains_instance(quantifier * q, unsigned num_bindings, enode * const * bindings);
|
||||
|
||||
bool add_instance(quantifier * q, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation,
|
||||
bool add_instance(quantifier * q, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation,
|
||||
unsigned min_top_generation, unsigned max_top_generation, ptr_vector<enode> & used_enodes);
|
||||
|
||||
void set_global_generation(unsigned generation) { m_generation = generation; }
|
||||
|
@ -958,7 +960,7 @@ namespace smt {
|
|||
|
||||
void assign_quantifier(quantifier * q);
|
||||
|
||||
void set_conflict(b_justification js, literal not_l);
|
||||
void set_conflict(b_justification js, literal not_l);
|
||||
|
||||
void set_conflict(b_justification js) {
|
||||
set_conflict(js, null_literal);
|
||||
|
@ -997,12 +999,12 @@ namespace smt {
|
|||
#define INV_ACTIVITY_LIMIT 1e-100
|
||||
|
||||
void rescale_bool_var_activity();
|
||||
|
||||
|
||||
public:
|
||||
void inc_bvar_activity(bool_var v) {
|
||||
double & act = m_activity[v];
|
||||
act += m_bvar_inc;
|
||||
if (act > ACTIVITY_LIMIT)
|
||||
if (act > ACTIVITY_LIMIT)
|
||||
rescale_bool_var_activity();
|
||||
m_case_split_queue->activity_increased_eh(v);
|
||||
}
|
||||
|
@ -1031,7 +1033,7 @@ namespace smt {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool can_delete(clause * cls) const {
|
||||
if (cls->in_reinit_stack())
|
||||
return false;
|
||||
|
@ -1053,7 +1055,7 @@ namespace smt {
|
|||
bool validate_assumptions(unsigned num_assumptions, expr * const * assumptions);
|
||||
|
||||
void init_assumptions(unsigned num_assumptions, expr * const * assumptions);
|
||||
|
||||
|
||||
void reset_assumptions();
|
||||
|
||||
void mk_unsat_core();
|
||||
|
@ -1073,9 +1075,9 @@ namespace smt {
|
|||
void tick(unsigned & counter) const;
|
||||
|
||||
lbool bounded_search();
|
||||
|
||||
|
||||
final_check_status final_check();
|
||||
|
||||
|
||||
void check_proof(proof * pr);
|
||||
|
||||
void forget_phase_of_vars_in_current_level();
|
||||
|
@ -1102,7 +1104,7 @@ namespace smt {
|
|||
|
||||
public:
|
||||
// event handler for relevancy_propagator class
|
||||
void relevant_eh(expr * n);
|
||||
void relevant_eh(expr * n);
|
||||
|
||||
bool is_relevant(expr * n) const {
|
||||
return !relevancy() || is_relevant_core(n);
|
||||
|
@ -1126,9 +1128,9 @@ namespace smt {
|
|||
void mark_as_relevant(enode * n) { mark_as_relevant(n->get_owner()); }
|
||||
|
||||
void mark_as_relevant(bool_var v) { mark_as_relevant(bool_var2expr(v)); }
|
||||
|
||||
|
||||
void mark_as_relevant(literal l) { mark_as_relevant(l.var()); }
|
||||
|
||||
|
||||
template<typename Eh>
|
||||
relevancy_eh * mk_relevancy_eh(Eh const & eh) {
|
||||
return m_relevancy_propagator->mk_relevancy_eh(eh);
|
||||
|
@ -1149,9 +1151,9 @@ namespace smt {
|
|||
void propagate_th_eqs();
|
||||
|
||||
void propagate_th_diseqs();
|
||||
|
||||
|
||||
bool can_theories_propagate() const;
|
||||
|
||||
|
||||
bool propagate();
|
||||
|
||||
public:
|
||||
|
@ -1167,7 +1169,7 @@ namespace smt {
|
|||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Pretty Printing
|
||||
// Pretty Printing
|
||||
//
|
||||
// -----------------------------------
|
||||
protected:
|
||||
|
@ -1215,7 +1217,7 @@ namespace smt {
|
|||
void display_binary_clauses(std::ostream & out) const;
|
||||
|
||||
void display_assignment(std::ostream & out) const;
|
||||
|
||||
|
||||
void display_eqc(std::ostream & out) const;
|
||||
|
||||
void display_app_enode_map(std::ostream & out) const;
|
||||
|
@ -1235,15 +1237,15 @@ namespace smt {
|
|||
void display_lemma_as_smt_problem(std::ostream & out, unsigned num_antecedents, literal const * antecedents, literal consequent = false_literal, symbol const& logic = symbol::null) const;
|
||||
|
||||
void display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents, literal consequent = false_literal, symbol const& logic = symbol::null) const;
|
||||
void display_lemma_as_smt_problem(std::ostream & out, unsigned num_antecedents, literal const * antecedents,
|
||||
unsigned num_antecedent_eqs, enode_pair const * antecedent_eqs,
|
||||
void display_lemma_as_smt_problem(std::ostream & out, unsigned num_antecedents, literal const * antecedents,
|
||||
unsigned num_antecedent_eqs, enode_pair const * antecedent_eqs,
|
||||
literal consequent = false_literal, symbol const& logic = symbol::null) const;
|
||||
|
||||
void display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents,
|
||||
unsigned num_antecedent_eqs, enode_pair const * antecedent_eqs,
|
||||
void display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents,
|
||||
unsigned num_antecedent_eqs, enode_pair const * antecedent_eqs,
|
||||
literal consequent = false_literal, symbol const& logic = symbol::null) const;
|
||||
|
||||
void display_assignment_as_smtlib2(std::ostream& out, symbol const& logic = symbol::null) const;
|
||||
void display_assignment_as_smtlib2(std::ostream& out, symbol const& logic = symbol::null) const;
|
||||
|
||||
void display_normalized_enodes(std::ostream & out) const;
|
||||
|
||||
|
@ -1289,13 +1291,13 @@ namespace smt {
|
|||
bool check_invariant() const;
|
||||
|
||||
bool check_eqc_bool_assignment() const;
|
||||
|
||||
|
||||
bool check_missing_clause_propagation(clause_vector const & v) const;
|
||||
|
||||
bool check_missing_bin_clause_propagation() const;
|
||||
|
||||
bool check_missing_eq_propagation() const;
|
||||
|
||||
|
||||
bool check_missing_congruence() const;
|
||||
|
||||
bool check_missing_bool_enode_propagation() const;
|
||||
|
@ -1357,7 +1359,7 @@ namespace smt {
|
|||
static literal translate_literal(
|
||||
literal lit, context& src_ctx, context& dst_ctx,
|
||||
vector<bool_var> b2v, ast_translation& tr);
|
||||
|
||||
|
||||
/*
|
||||
\brief Utilities for consequence finding.
|
||||
*/
|
||||
|
@ -1366,7 +1368,7 @@ namespace smt {
|
|||
u_map<index_set> m_antecedents;
|
||||
void extract_fixed_consequences(literal lit, obj_map<expr, expr*>& var2val, index_set const& assumptions, expr_ref_vector& conseq);
|
||||
void extract_fixed_consequences(unsigned& idx, obj_map<expr, expr*>& var2val, index_set const& assumptions, expr_ref_vector& conseq);
|
||||
|
||||
|
||||
void display_consequence_progress(std::ostream& out, unsigned it, unsigned nv, unsigned fixed, unsigned unfixed, unsigned eq);
|
||||
|
||||
unsigned delete_unfixed(obj_map<expr, expr*>& var2val, expr_ref_vector& unfixed);
|
||||
|
@ -1378,9 +1380,11 @@ namespace smt {
|
|||
|
||||
literal mk_diseq(expr* v, expr* val);
|
||||
|
||||
void validate_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars,
|
||||
void validate_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars,
|
||||
expr_ref_vector const& conseq, expr_ref_vector const& unfixed);
|
||||
|
||||
bool validate_justification(bool_var v, bool_var_data const& d, b_justification const& j);
|
||||
|
||||
void justify(literal lit, index_set& s);
|
||||
|
||||
void extract_cores(expr_ref_vector const& asms, vector<expr_ref_vector>& cores, unsigned& min_core_size);
|
||||
|
@ -1426,18 +1430,18 @@ namespace smt {
|
|||
|
||||
void pop(unsigned num_scopes);
|
||||
|
||||
lbool check(unsigned num_assumptions = 0, expr * const * assumptions = 0, bool reset_cancel = true);
|
||||
lbool check(unsigned num_assumptions = 0, expr * const * assumptions = 0, bool reset_cancel = true);
|
||||
|
||||
lbool get_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars, expr_ref_vector& conseq, expr_ref_vector& unfixed);
|
||||
|
||||
lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes);
|
||||
|
||||
lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores);
|
||||
|
||||
|
||||
lbool setup_and_check(bool reset_cancel = true);
|
||||
|
||||
|
||||
// return 'true' if assertions are inconsistent.
|
||||
bool reduce_assertions();
|
||||
bool reduce_assertions();
|
||||
|
||||
bool resource_limits_exceeded();
|
||||
|
||||
|
@ -1462,15 +1466,15 @@ namespace smt {
|
|||
}
|
||||
|
||||
bool already_internalized() const { return m_e_internalized_stack.size() > 2 || m_b_internalized_stack.size() > 1; }
|
||||
|
||||
|
||||
unsigned get_unsat_core_size() const {
|
||||
return m_unsat_core.size();
|
||||
}
|
||||
|
||||
|
||||
expr * get_unsat_core_expr(unsigned idx) const {
|
||||
return m_unsat_core.get(idx);
|
||||
}
|
||||
|
||||
|
||||
void get_model(model_ref & m) const;
|
||||
|
||||
bool update_model(bool refinalize);
|
||||
|
@ -1478,17 +1482,17 @@ namespace smt {
|
|||
void get_proto_model(proto_model_ref & m) const;
|
||||
|
||||
bool validate_model();
|
||||
|
||||
|
||||
unsigned get_num_asserted_formulas() const { return m_asserted_formulas.get_num_formulas(); }
|
||||
|
||||
unsigned get_asserted_formulas_last_level() const { return m_asserted_formulas.get_formulas_last_level(); }
|
||||
|
||||
expr * get_asserted_formula(unsigned idx) const { return m_asserted_formulas.get_formula(idx); }
|
||||
|
||||
|
||||
proof * get_asserted_formula_proof(unsigned idx) const { return m_asserted_formulas.get_formula_proof(idx); }
|
||||
|
||||
|
||||
expr * const * get_asserted_formulas() const { return m_asserted_formulas.get_formulas(); }
|
||||
|
||||
|
||||
proof * const * get_asserted_formula_proofs() const { return m_asserted_formulas.get_formula_proofs(); }
|
||||
|
||||
void get_assumptions_core(ptr_vector<expr> & result);
|
||||
|
@ -1500,7 +1504,7 @@ namespace smt {
|
|||
void display_unsat_core(std::ostream & out) const;
|
||||
|
||||
void collect_statistics(::statistics & st) const;
|
||||
|
||||
|
||||
void display_statistics(std::ostream & out) const;
|
||||
void display_istatistics(std::ostream & out) const;
|
||||
|
||||
|
|
|
@ -402,6 +402,20 @@ namespace smt {
|
|||
|
||||
#endif
|
||||
|
||||
bool context::validate_justification(bool_var v, bool_var_data const& d, b_justification const& j) {
|
||||
if (j.get_kind() == b_justification::CLAUSE && v != true_bool_var) {
|
||||
clause* cls = j.get_clause();
|
||||
unsigned num_lits = cls->get_num_literals();
|
||||
literal l = cls->get_literal(0);
|
||||
if (l.var() != v) {
|
||||
l = cls->get_literal(1);
|
||||
}
|
||||
SASSERT(l.var() == v);
|
||||
SASSERT(m_assignment[l.index()] == l_true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool context::validate_model() {
|
||||
if (!m_proto_model) {
|
||||
return true;
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace smt {
|
|||
out << "true";
|
||||
else if (*this == false_literal)
|
||||
out << "false";
|
||||
else if (*this == null_literal)
|
||||
out << "null";
|
||||
else if (sign())
|
||||
out << "(not " << mk_pp(bool_var2expr_map[var()], m) << ")";
|
||||
else
|
||||
|
|
|
@ -22,42 +22,62 @@ Notes:
|
|||
#include"smt_params.h"
|
||||
#include"smt_params_helper.hpp"
|
||||
#include"mus.h"
|
||||
|
||||
#include"for_each_expr.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"func_decl_dependencies.h"
|
||||
#include"dec_ref_util.h"
|
||||
|
||||
namespace smt {
|
||||
|
||||
class solver : public solver_na2as {
|
||||
smt_params m_smt_params;
|
||||
params_ref m_params;
|
||||
smt::kernel m_context;
|
||||
progress_callback * m_callback;
|
||||
symbol m_logic;
|
||||
bool m_minimizing_core;
|
||||
smt_params m_smt_params;
|
||||
params_ref m_params;
|
||||
smt::kernel m_context;
|
||||
progress_callback * m_callback;
|
||||
symbol m_logic;
|
||||
bool m_minimizing_core;
|
||||
bool m_core_extend_patterns;
|
||||
obj_map<expr, expr*> m_name2assertion;
|
||||
|
||||
public:
|
||||
solver(ast_manager & m, params_ref const & p, symbol const & l):
|
||||
solver(ast_manager & m, params_ref const & p, symbol const & l) :
|
||||
solver_na2as(m),
|
||||
m_smt_params(p),
|
||||
m_params(p),
|
||||
m_context(m, m_smt_params),
|
||||
m_minimizing_core(false) {
|
||||
m_minimizing_core(false),
|
||||
m_core_extend_patterns(false) {
|
||||
m_logic = l;
|
||||
if (m_logic != symbol::null)
|
||||
m_context.set_logic(m_logic);
|
||||
smt_params_helper smth(p);
|
||||
m_core_extend_patterns = smth.core_extend_patterns();
|
||||
}
|
||||
|
||||
virtual solver* translate(ast_manager& m, params_ref const& p) {
|
||||
solver* result = alloc(solver, m, p, m_logic);
|
||||
virtual solver * translate(ast_manager & m, params_ref const & p) {
|
||||
solver * result = alloc(solver, m, p, m_logic);
|
||||
smt::kernel::copy(m_context, result->m_context);
|
||||
|
||||
ast_translation translator(get_manager(), m);
|
||||
obj_map<expr, expr*>::iterator it = m_name2assertion.begin();
|
||||
obj_map<expr, expr*>::iterator end = m_name2assertion.end();
|
||||
for (; it != end; it++)
|
||||
result->m_name2assertion.insert(translator(it->m_key),
|
||||
translator(it->m_value));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
virtual ~solver() {
|
||||
dec_ref_values(get_manager(), m_name2assertion);
|
||||
}
|
||||
|
||||
virtual void updt_params(params_ref const & p) {
|
||||
m_smt_params.updt_params(p);
|
||||
m_params.copy(p);
|
||||
m_context.updt_params(p);
|
||||
smt_params_helper smth(p);
|
||||
m_core_extend_patterns = smth.core_extend_patterns();
|
||||
}
|
||||
|
||||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
|
@ -81,11 +101,32 @@ namespace smt {
|
|||
m_context.assert_expr(t);
|
||||
}
|
||||
|
||||
virtual void assert_expr(expr * t, expr * a) {
|
||||
solver_na2as::assert_expr(t, a);
|
||||
SASSERT(!m_name2assertion.contains(a));
|
||||
get_manager().inc_ref(t);
|
||||
m_name2assertion.insert(a, t);
|
||||
}
|
||||
|
||||
virtual void push_core() {
|
||||
m_context.push();
|
||||
}
|
||||
|
||||
virtual void pop_core(unsigned n) {
|
||||
unsigned cur_sz = m_assumptions.size();
|
||||
if (n > 0 && cur_sz > 0) {
|
||||
unsigned lvl = m_scopes.size();
|
||||
SASSERT(n <= lvl);
|
||||
unsigned new_lvl = lvl - n;
|
||||
unsigned old_sz = m_scopes[new_lvl];
|
||||
for (unsigned i = cur_sz - 1; i >= old_sz; i--) {
|
||||
expr * key = m_assumptions[i].get();
|
||||
SASSERT(m_name2assertion.contains(key));
|
||||
expr * value = m_name2assertion.find(key);
|
||||
m.dec_ref(value);
|
||||
m_name2assertion.erase(key);
|
||||
}
|
||||
}
|
||||
m_context.pop(n);
|
||||
}
|
||||
|
||||
|
@ -97,7 +138,7 @@ namespace smt {
|
|||
struct scoped_minimize_core {
|
||||
solver& s;
|
||||
expr_ref_vector m_assumptions;
|
||||
scoped_minimize_core(solver& s): s(s), m_assumptions(s.m_assumptions) {
|
||||
scoped_minimize_core(solver& s) : s(s), m_assumptions(s.m_assumptions) {
|
||||
s.m_minimizing_core = true;
|
||||
s.m_assumptions.reset();
|
||||
}
|
||||
|
@ -114,17 +155,19 @@ namespace smt {
|
|||
r.push_back(m_context.get_unsat_core_expr(i));
|
||||
}
|
||||
|
||||
if (m_minimizing_core || smt_params_helper(m_params).core_minimize() == false) {
|
||||
return;
|
||||
}
|
||||
scoped_minimize_core scm(*this);
|
||||
mus mus(*this);
|
||||
mus.add_soft(r.size(), r.c_ptr());
|
||||
ptr_vector<expr> r2;
|
||||
if (l_true == mus.get_mus(r2)) {
|
||||
r.reset();
|
||||
r.append(r2);
|
||||
if (m_minimizing_core && smt_params_helper(m_params).core_minimize()) {
|
||||
scoped_minimize_core scm(*this);
|
||||
mus mus(*this);
|
||||
mus.add_soft(r.size(), r.c_ptr());
|
||||
ptr_vector<expr> r2;
|
||||
if (l_true == mus.get_mus(r2)) {
|
||||
r.reset();
|
||||
r.append(r2);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_core_extend_patterns)
|
||||
add_pattern_literals_to_core(r);
|
||||
}
|
||||
|
||||
virtual void get_model(model_ref & m) {
|
||||
|
@ -149,7 +192,7 @@ namespace smt {
|
|||
r.append(tmp.size(), tmp.c_ptr());
|
||||
}
|
||||
|
||||
virtual ast_manager& get_manager() const { return m_context.m(); }
|
||||
virtual ast_manager & get_manager() const { return m_context.m(); }
|
||||
|
||||
virtual void set_progress_callback(progress_callback * callback) {
|
||||
m_callback = callback;
|
||||
|
@ -159,12 +202,115 @@ namespace smt {
|
|||
virtual unsigned get_num_assertions() const {
|
||||
return m_context.size();
|
||||
}
|
||||
|
||||
|
||||
virtual expr * get_assertion(unsigned idx) const {
|
||||
SASSERT(idx < get_num_assertions());
|
||||
return m_context.get_formulas()[idx];
|
||||
}
|
||||
}
|
||||
|
||||
struct collect_fds_proc {
|
||||
ast_manager & m;
|
||||
func_decl_set & m_fds;
|
||||
collect_fds_proc(ast_manager & m, func_decl_set & fds) :
|
||||
m(m), m_fds(fds) {
|
||||
}
|
||||
void operator()(var * n) {}
|
||||
void operator()(app * n) {
|
||||
func_decl * fd = n->get_decl();
|
||||
if (fd->get_family_id() == null_family_id)
|
||||
m_fds.insert_if_not_there(fd);
|
||||
}
|
||||
void operator()(quantifier * n) {}
|
||||
};
|
||||
|
||||
struct collect_pattern_fds_proc {
|
||||
ast_manager & m;
|
||||
expr_fast_mark1 m_visited;
|
||||
func_decl_set & m_fds;
|
||||
collect_pattern_fds_proc(ast_manager & m, func_decl_set & fds) :
|
||||
m(m), m_fds(fds) {
|
||||
m_visited.reset();
|
||||
}
|
||||
void operator()(var * n) {}
|
||||
void operator()(app * n) {}
|
||||
void operator()(quantifier * n) {
|
||||
collect_fds_proc p(m, m_fds);
|
||||
|
||||
unsigned sz = n->get_num_patterns();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
quick_for_each_expr(p, m_visited, n->get_pattern(i));
|
||||
|
||||
sz = n->get_num_no_patterns();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
quick_for_each_expr(p, m_visited, n->get_no_pattern(i));
|
||||
}
|
||||
};
|
||||
|
||||
void collect_pattern_func_decls(expr_ref & e, func_decl_set & fds) {
|
||||
collect_pattern_fds_proc p(get_manager(), fds);
|
||||
expr_mark visited;
|
||||
for_each_expr(p, visited, e);
|
||||
}
|
||||
|
||||
void compute_assrtn_fds(ptr_vector<expr> & core, vector<func_decl_set> & assrtn_fds) {
|
||||
assrtn_fds.resize(m_name2assertion.size());
|
||||
obj_map<expr, expr*>::iterator ait = m_name2assertion.begin();
|
||||
obj_map<expr, expr*>::iterator aend = m_name2assertion.end();
|
||||
for (unsigned i = 0; ait != aend; ait++, i++) {
|
||||
if (core.contains(ait->m_key))
|
||||
continue;
|
||||
collect_fds_proc p(m, assrtn_fds[i]);
|
||||
expr_fast_mark1 visited;
|
||||
quick_for_each_expr(p, visited, ait->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
bool fds_intersect(func_decl_set & pattern_fds, func_decl_set & assrtn_fds) {
|
||||
func_decl_set::iterator it = pattern_fds.begin();
|
||||
func_decl_set::iterator end = pattern_fds.end();
|
||||
for (; it != end; it++) {
|
||||
func_decl * fd = *it;
|
||||
if (assrtn_fds.contains(fd))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void add_pattern_literals_to_core(ptr_vector<expr> & core) {
|
||||
ast_manager & m = get_manager();
|
||||
expr_ref_vector new_core_literals(m);
|
||||
|
||||
func_decl_set pattern_fds;
|
||||
vector<func_decl_set> assrtn_fds;
|
||||
|
||||
do {
|
||||
new_core_literals.reset();
|
||||
|
||||
unsigned sz = core.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr_ref name(core[i], m);
|
||||
SASSERT(m_name2assertion.contains(name));
|
||||
expr_ref assrtn(m_name2assertion.find(name), m);
|
||||
collect_pattern_func_decls(assrtn, pattern_fds);
|
||||
}
|
||||
|
||||
if (!pattern_fds.empty()) {
|
||||
if (assrtn_fds.empty())
|
||||
compute_assrtn_fds(core, assrtn_fds);
|
||||
|
||||
obj_map<expr, expr*>::iterator ait = m_name2assertion.begin();
|
||||
obj_map<expr, expr*>::iterator aend = m_name2assertion.end();
|
||||
for (unsigned i = 0; ait != aend; ait++, i++) {
|
||||
if (!core.contains(ait->m_key) &&
|
||||
fds_intersect(pattern_fds, assrtn_fds[i]))
|
||||
new_core_literals.push_back(ait->m_key);
|
||||
}
|
||||
}
|
||||
|
||||
core.append(new_core_literals.size(), new_core_literals.c_ptr());
|
||||
}
|
||||
while (!new_core_literals.empty());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ namespace smt {
|
|||
|
||||
final_check_status theory_wmaxsat::final_check_eh() {
|
||||
if (m_normalize) normalize();
|
||||
// std::cout << "cost: " << m_zcost << " min cost: " << m_zmin_cost << "\n";
|
||||
TRACE("opt", tout << "cost: " << m_zcost << " min cost: " << m_zmin_cost << "\n";);
|
||||
return FC_DONE;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,6 @@ int main(int argc, char ** argv) {
|
|||
TST(polynomial);
|
||||
TST(upolynomial);
|
||||
TST(algebraic);
|
||||
TST(polynomial_factorization);
|
||||
TST(prime_generator);
|
||||
TST(permutation);
|
||||
TST(nlsat);
|
||||
|
|
|
@ -18,7 +18,6 @@ Notes:
|
|||
--*/
|
||||
#if !defined(__clang__)
|
||||
#include"polynomial.h"
|
||||
#include"polynomial_factorization.h"
|
||||
#include"polynomial_var2value.h"
|
||||
#include"polynomial_cache.h"
|
||||
#include"linear_eq_solver.h"
|
||||
|
|
|
@ -1,746 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
polynomial_factorization.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Testing of factorization.
|
||||
|
||||
Author:
|
||||
|
||||
Dejan (t-dejanj) 2011-11-29
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"upolynomial_factorization_int.h"
|
||||
#include"timeit.h"
|
||||
#include"polynomial.h"
|
||||
#include"rlimit.h"
|
||||
#if 0
|
||||
#include"polynomial_factorization.h"
|
||||
#endif
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// some prime numbers
|
||||
unsigned primes[] = {
|
||||
2, 3, 5, 7, 11, 13, 17, 19, 23, 29
|
||||
};
|
||||
|
||||
// [i,l]: how many factors the Knuth example has over p_i, when i = 0 it's Z, p_1 = 2, for l=0 distinct, for l = 1 total
|
||||
unsigned knuth_factors[2][11] = {
|
||||
// x^8 + x^6 + 10*x^4 + 10*x^3 + 8*x^2 + 2*x + 8
|
||||
{2, 2, 3, 3, 2, 3, 1, 4, 3, 1, 1},
|
||||
{8, 2, 3, 3, 2, 3, 1, 4, 3, 1, 1},
|
||||
};
|
||||
|
||||
// [k,l,i]: how many factors the S_k has over p_i, when i = 0 it's Z, p_1 = 2, for l=0 distinct, for l = 1 total
|
||||
unsigned swinnerton_dyer_factors[5][2][11] = {
|
||||
// S1 = (x^2) - 2
|
||||
{
|
||||
// 2, 3, 5, 7,11,13,17,19,23,29, Z
|
||||
{1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1},
|
||||
{2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1}
|
||||
},
|
||||
// S2 = (x^4) - 10*(x^2) + 1
|
||||
{
|
||||
{1, 1, 2, 2, 2, 2, 2, 2, 4, 2, 1},
|
||||
{4, 2, 2, 2, 2, 2, 2, 2, 4, 2, 1}
|
||||
},
|
||||
// S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576
|
||||
{
|
||||
{1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 1},
|
||||
{8, 6, 4, 4, 4, 4, 4, 4, 4, 4, 1}
|
||||
},
|
||||
// S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225
|
||||
{
|
||||
{1, 4, 3, 4, 8, 8, 8, 8, 8, 8, 1},
|
||||
{16, 12, 10, 8, 8, 8, 8, 8, 8, 8, 1}
|
||||
},
|
||||
// SA = S1*S2*S3*S4
|
||||
{
|
||||
//p = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, Z
|
||||
{ 2, 6, 3, 6, 15, 11, 16, 15, 18, 15, 1},
|
||||
{30, 21, 17, 16, 15, 15, 16, 15, 18, 15, 1}
|
||||
}
|
||||
};
|
||||
|
||||
int random_polynomial[20][2][11] = {
|
||||
{
|
||||
// 3*x^10 + 2*x^9 + 4*x^8 + 4*x^7 + 4*x^6 + x^5 + 3*x^2 + 3*x
|
||||
{ 4, 3, 4, 4, 3, 4, 4, 4, 3, 4, 2 },
|
||||
{ 7, 7, 4, 4, 3, 4, 4, 4, 3, 4, 2 },
|
||||
},
|
||||
{
|
||||
// 4*x^9 + 4*x^8 + x^7 + x^6 + 2*x^5 + 3*x^4 + 4*x^2 + 4*x
|
||||
{ 2, 2, 3, 3, 4, 2, 5, 3, 4, 2, 2 },
|
||||
{ 5, 2, 3, 3, 4, 2, 5, 3, 5, 2, 2 },
|
||||
},
|
||||
{
|
||||
// 3*x^10 + 4*x^9 + 3*x^8 + x^6 + 4*x^5 + 4*x^4 + x^2
|
||||
{ 3, 2, 4, 4, 5, 3, 4, 2, 4, 5, 2 },
|
||||
{ 6, 3, 5, 5, 6, 4, 5, 3, 5, 7, 3 },
|
||||
},
|
||||
{
|
||||
// x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^4 + 3*x^3 + x^2 + 4*x
|
||||
{ 3, 4, 4, 3, 3, 3, 4, 4, 5, 3, 2 },
|
||||
{ 8, 4, 4, 3, 3, 3, 4, 4, 5, 3, 2 },
|
||||
},
|
||||
{
|
||||
// x^9 + 2*x^8 + 3*x^7 + x^6 + 2*x^5 + 4*x^4 + 3*x^2
|
||||
{ 3, 3, 3, 3, 4, 4, 4, 3, 3, 4, 2 },
|
||||
{ 5, 6, 4, 5, 5, 6, 5, 4, 4, 5, 3 },
|
||||
},
|
||||
{
|
||||
// x^10 + x^9 + 4*x^7 + x^6 + 3*x^5 + x^4 + x^3 + x
|
||||
{ 3, 2, 3, 3, 3, 5, 3, 2, 4, 4, 2 },
|
||||
{ 3, 2, 3, 3, 3, 5, 3, 2, 4, 4, 2 },
|
||||
},
|
||||
{
|
||||
// 4*x^10 + 4*x^9 + x^8 + 2*x^7 + 3*x^6 + 4*x^5 + 3*x^4 + x^3 + 2*x^2 + 4*x
|
||||
{ 3, 3, 2, 5, 3, 4, 2, 4, 5, 5, 2 },
|
||||
{ 5, 3, 2, 5, 3, 4, 2, 4, 5, 5, 2 },
|
||||
},
|
||||
{
|
||||
// 3*x^10 + 4*x^9 + 3*x^8 + x^7 + x^6 + 2*x^5 + x^4 + 2*x^3 + 2*x^2 + x
|
||||
{ 3, 4, 6, 4, 4, 4, 4, 6, 6, 4, 3 },
|
||||
{ 4, 4, 7, 4, 4, 4, 4, 6, 6, 4, 3 },
|
||||
},
|
||||
{
|
||||
// 4*x^10 + x^9 + x^7 + 2*x^5 + 3*x^3 + x^2 + 4*x
|
||||
{ 3, 3, 3, 4, 4, 5, 4, 5, 2, 4, 2 },
|
||||
{ 4, 4, 3, 4, 4, 5, 4, 5, 2, 4, 2 },
|
||||
},
|
||||
{
|
||||
// x^10 + 3*x^9 + 3*x^8 + x^7 + 3*x^6 + 3*x^5 + 3*x^4 + x^2 + 3*x
|
||||
{ 2, 3, 4, 4, 3, 3, 4, 3, 3, 4, 2 },
|
||||
{ 2, 4, 5, 4, 3, 3, 4, 3, 3, 4, 2 },
|
||||
},
|
||||
{
|
||||
// x^10 + x^9 + 2*x^8 + x^7 + 4*x^6 + 2*x^5 + 3*x^4 + 4*x^3 + x^2 + 2*x
|
||||
{ 3, 4, 4, 3, 3, 3, 3, 4, 5, 3, 2 },
|
||||
{ 4, 4, 4, 3, 3, 3, 3, 4, 5, 3, 2 },
|
||||
},
|
||||
{
|
||||
// 3*x^9 + x^8 + 3*x^7 + 3*x^6 + x^5 + 2*x^4 + 4*x^3 + 4*x^2 + 3*x
|
||||
{ 4, 3, 3, 3, 5, 3, 6, 4, 2, 2, 2 },
|
||||
{ 6, 4, 3, 3, 5, 3, 6, 4, 2, 2, 2 },
|
||||
},
|
||||
{
|
||||
// 2*x^10 + 3*x^9 + 2*x^8 + 4*x^7 + x^6 + 3*x^5 + 2*x^3 + 3*x^2 + 2*x + 2
|
||||
{ 3, 3, 3, 5, 4, 5, 6, 7, 4, 6, 3 },
|
||||
{ 8, 4, 3, 7, 4, 5, 6, 7, 4, 7, 3 },
|
||||
},
|
||||
{
|
||||
// 3*x^10 + x^9 + 4*x^8 + 2*x^7 + x^6 + 4*x^5 + x^4 + 3*x^3 + x + 2
|
||||
{ 3, 3, 3, 2, 6, 4, 4, 4, 3, 3, 2 },
|
||||
{ 3, 3, 3, 2, 6, 5, 4, 5, 3, 3, 2 },
|
||||
},
|
||||
{
|
||||
// 4*x^10 + 2*x^9 + x^8 + x^6 + x^5 + 3*x^4 + 4*x^3 + x^2 + x
|
||||
{ 3, 4, 2, 4, 4, 4, 4, 2, 3, 3, 2 },
|
||||
{ 6, 4, 2, 4, 4, 4, 4, 2, 3, 3, 2 },
|
||||
},
|
||||
{
|
||||
// 4*x^10 + 2*x^7 + 4*x^6 + 2*x^3 + x
|
||||
{ 1, 3, 3, 3, 4, 4, 4, 3, 3, 2, 2 },
|
||||
{ 1, 3, 3, 3, 4, 4, 4, 3, 3, 2, 2 },
|
||||
},
|
||||
{
|
||||
// 4*x^10 + x^9 + x^8 + 4*x^7 + 4*x^4 + 2*x^2 + x + 4
|
||||
{ 3, 4, 2, 5, 3, 6, 3, 6, 3, 3, 2 },
|
||||
{ 3, 6, 2, 5, 3, 6, 3, 6, 3, 3, 2 },
|
||||
},
|
||||
{
|
||||
// 3*x^10 + 2*x^8 + x^7 + x^6 + 3*x^4 + 3*x^3 + 4*x^2 + 3*x
|
||||
{ 4, 3, 4, 3, 3, 3, 2, 4, 4, 3, 2 },
|
||||
{ 5, 4, 4, 3, 3, 3, 2, 4, 4, 3, 2 },
|
||||
},
|
||||
{
|
||||
// x^10 + 2*x^9 + 2*x^6 + 4*x^3 + 4*x^2
|
||||
{ 1, 2, 2, 3, 3, 4, 3, 3, 3, 3, 2 },
|
||||
{ 10, 3, 3, 4, 4, 6, 4, 4, 4, 4, 3 },
|
||||
},
|
||||
{
|
||||
// x^10 + 2*x^9 + 2*x^8 + 4*x^7 + 4*x^6 + x^5 + x^3 + x^2 + 3*x
|
||||
{ 2, 4, 2, 3, 3, 3, 5, 5, 6, 2, 2 },
|
||||
{ 2, 5, 2, 3, 3, 3, 5, 5, 6, 2, 2 },
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
static void tst_square_free_finite_1() {
|
||||
polynomial::numeral_manager nm;
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
// example from Knuth, p. 442
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
// polynomials \prod_{i < p} (x - i)^i
|
||||
for (unsigned prime_i = 0; prime_i < 5; ++ prime_i)
|
||||
{
|
||||
int p = primes[prime_i];
|
||||
|
||||
// make the polynomial
|
||||
polynomial_ref f(pm);
|
||||
f = x - 1;
|
||||
for (int i = 2; i < p; ++ i) {
|
||||
f = f*((x + (-i))^i);
|
||||
}
|
||||
cout << "Factoring " << f << " into square-free over Z_" << p << endl;
|
||||
|
||||
// convert to univariate over Z_p
|
||||
upolynomial::zp_manager upm(nm);
|
||||
upm.set_zp(p);
|
||||
upolynomial::numeral_vector f_u;
|
||||
upm.to_numeral_vector(f, f_u);
|
||||
|
||||
cout << "Input: "; upm.display(cout, f_u); cout << endl;
|
||||
|
||||
// factor it
|
||||
upolynomial::zp_factors f_factors(upm);
|
||||
cout << "Start: " << f_factors << endl;
|
||||
|
||||
upolynomial::zp_square_free_factor(upm, f_u, f_factors);
|
||||
|
||||
upolynomial::numeral_vector mult;
|
||||
f_factors.multiply(mult);
|
||||
cout << "Multiplied: "; upm.display(cout, mult); cout << endl;
|
||||
|
||||
SASSERT(upm.eq(mult, f_u));
|
||||
|
||||
// remove the temps
|
||||
upm.reset(f_u);
|
||||
upm.reset(mult);
|
||||
}
|
||||
}
|
||||
|
||||
static void tst_factor_finite_1() {
|
||||
|
||||
polynomial::numeral_manager nm;
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
// example from Knuth, p. 442
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
polynomial_ref K(pm);
|
||||
K = (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8;
|
||||
|
||||
// factor them for all the prime numbers
|
||||
for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i)
|
||||
{
|
||||
// make the Z_p
|
||||
unsigned prime = primes[prime_i];
|
||||
upolynomial::zp_manager upm(nm);
|
||||
upm.set_zp(prime);
|
||||
|
||||
// make the polynomial in Z_p
|
||||
upolynomial::numeral_vector K_u;
|
||||
upm.to_numeral_vector(K, K_u);
|
||||
|
||||
cout << "Factoring " << K << "("; upm.display(cout, K_u); cout << ") in Z_" << prime << endl;
|
||||
cout << "Expecting " << knuth_factors[0][prime_i] << " distinct factors, " << knuth_factors[1][prime_i] << " total" << endl;
|
||||
|
||||
// factor it
|
||||
upolynomial::zp_factors factors(upm);
|
||||
/* bool factorized = */ upolynomial::zp_factor(upm, K_u, factors);
|
||||
|
||||
// check the result
|
||||
unsigned distinct = factors.distinct_factors();
|
||||
unsigned total = factors.total_factors();
|
||||
|
||||
cout << "Got " << factors << endl;
|
||||
cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl;
|
||||
|
||||
SASSERT(knuth_factors[0][prime_i] == distinct);
|
||||
SASSERT(knuth_factors[1][prime_i] == total);
|
||||
|
||||
upolynomial::numeral_vector multiplied;
|
||||
factors.multiply(multiplied);
|
||||
SASSERT(upm.eq(K_u, multiplied));
|
||||
upm.reset(multiplied);
|
||||
|
||||
// remove the temp
|
||||
upm.reset(K_u);
|
||||
}
|
||||
}
|
||||
|
||||
static void tst_factor_finite_2() {
|
||||
|
||||
polynomial::numeral_manager nm;
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
// Swinnerton-Dyer polynomials (irreducible, modular factors of degree at most 2)
|
||||
polynomial_ref S1 = (x^2) - 2;
|
||||
polynomial_ref S2 = (x^4) - 10*(x^2) + 1;
|
||||
polynomial_ref S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576;
|
||||
polynomial_ref S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225;
|
||||
|
||||
vector<polynomial_ref> S;
|
||||
S.push_back(S1);
|
||||
S.push_back(S2);
|
||||
S.push_back(S3);
|
||||
S.push_back(S4);
|
||||
S.push_back(S1*S2*S3*S4);
|
||||
|
||||
// factor all the S_i them for all the prime numbers
|
||||
for (unsigned S_i = 0; S_i < S.size(); ++ S_i) {
|
||||
for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) {
|
||||
unsigned prime = primes[prime_i];
|
||||
|
||||
upolynomial::zp_manager upm(nm);
|
||||
upm.set_zp(prime);
|
||||
|
||||
upolynomial::numeral_vector S_i_u;
|
||||
upm.to_numeral_vector(S[S_i], S_i_u);
|
||||
|
||||
cout << "Factoring "; upm.display(cout, S_i_u); cout << " over Z_" << prime << endl;
|
||||
cout << "Expecting " << swinnerton_dyer_factors[S_i][0][prime_i] << " distinct factors, " << swinnerton_dyer_factors[S_i][1][prime_i] << " total" << endl;
|
||||
|
||||
upolynomial::zp_factors factors(upm);
|
||||
upolynomial::zp_factor(upm, S_i_u, factors);
|
||||
|
||||
// check the result
|
||||
unsigned distinct = factors.distinct_factors();
|
||||
unsigned total = factors.total_factors();
|
||||
|
||||
cout << "Got " << factors << endl;
|
||||
cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl;
|
||||
|
||||
SASSERT(swinnerton_dyer_factors[S_i][0][prime_i] == distinct);
|
||||
SASSERT(swinnerton_dyer_factors[S_i][1][prime_i] == total);
|
||||
|
||||
upolynomial::numeral_vector multiplied;
|
||||
factors.multiply(multiplied);
|
||||
SASSERT(upm.eq(S_i_u, multiplied));
|
||||
upm.reset(multiplied);
|
||||
|
||||
// remove the temp
|
||||
upm.reset(S_i_u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void tst_factor_finite_3() {
|
||||
|
||||
polynomial::numeral_manager nm;
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
// random polynomials
|
||||
vector<polynomial_ref> random_p;
|
||||
random_p.push_back( 3*(x^10) + 2*(x^9) + 4*(x^8) + 4*(x^7) + 4*(x^6) + 1*(x^5) + 3*(x^2) + 3*x + 0 );
|
||||
random_p.push_back( 4*(x^9) + 4*(x^8) + 1*(x^7) + 1*(x^6) + 2*(x^5) + 3*(x^4) + 4*(x^2) + 4*x + 0 );
|
||||
random_p.push_back( 3*(x^10) + 4*(x^9) + 3*(x^8) + 1*(x^6) + 4*(x^5) + 4*(x^4) + 1*(x^2) + 0 );
|
||||
random_p.push_back( 1*(x^10) + 4*(x^9) + 1*(x^8) + 3*(x^7) + 3*(x^4) + 3*(x^3) + 1*(x^2) + 4*x + 0 );
|
||||
random_p.push_back( 1*(x^9) + 2*(x^8) + 3*(x^7) + 1*(x^6) + 2*(x^5) + 4*(x^4) + 3*(x^2) + 0 );
|
||||
random_p.push_back( 1*(x^10) + 1*(x^9) + 4*(x^7) + 1*(x^6) + 3*(x^5) + 1*(x^4) + 1*(x^3) + 1*x + 0 );
|
||||
random_p.push_back( 4*(x^10) + 4*(x^9) + 1*(x^8) + 2*(x^7) + 3*(x^6) + 4*(x^5) + 3*(x^4) + 1*(x^3) + 2*(x^2) + 4*x + 0 );
|
||||
random_p.push_back( 3*(x^10) + 4*(x^9) + 3*(x^8) + 1*(x^7) + 1*(x^6) + 2*(x^5) + 1*(x^4) + 2*(x^3) + 2*(x^2) + 1*x + 0 );
|
||||
random_p.push_back( 4*(x^10) + 1*(x^9) + 1*(x^7) + 2*(x^5) + 3*(x^3) + 1*(x^2) + 4*x + 0 );
|
||||
random_p.push_back( 1*(x^10) + 3*(x^9) + 3*(x^8) + 1*(x^7) + 3*(x^6) + 3*(x^5) + 3*(x^4) + 1*(x^2) + 3*x + 0 );
|
||||
random_p.push_back( 1*(x^10) + 1*(x^9) + 2*(x^8) + 1*(x^7) + 4*(x^6) + 2*(x^5) + 3*(x^4) + 4*(x^3) + 1*(x^2) + 2*x + 0 );
|
||||
random_p.push_back( 3*(x^9) + 1*(x^8) + 3*(x^7) + 3*(x^6) + 1*(x^5) + 2*(x^4) + 4*(x^3) + 4*(x^2) + 3*x + 0 );
|
||||
random_p.push_back( 2*(x^10) + 3*(x^9) + 2*(x^8) + 4*(x^7) + 1*(x^6) + 3*(x^5) + 2*(x^3) + 3*(x^2) + 2*x + 2 );
|
||||
random_p.push_back( 3*(x^10) + 1*(x^9) + 4*(x^8) + 2*(x^7) + 1*(x^6) + 4*(x^5) + 1*(x^4) + 3*(x^3) + 1*x + 2 );
|
||||
random_p.push_back( 4*(x^10) + 2*(x^9) + 1*(x^8) + 1*(x^6) + 1*(x^5) + 3*(x^4) + 4*(x^3) + 1*(x^2) + 1*x + 0 );
|
||||
random_p.push_back( 4*(x^10) + 2*(x^7) + 4*(x^6) + 2*(x^3) + 1*x + 0 );
|
||||
random_p.push_back( 4*(x^10) + 1*(x^9) + 1*(x^8) + 4*(x^7) + 4*(x^4) + 2*(x^2) + 1*x + 4 );
|
||||
random_p.push_back( 3*(x^10) + 2*(x^8) + 1*(x^7) + 1*(x^6) + 3*(x^4) + 3*(x^3) + 4*(x^2) + 3*x + 0 );
|
||||
random_p.push_back( 1*(x^10) + 2*(x^9) + 2*(x^6) + 4*(x^3) + 4*(x^2) + 0 );
|
||||
random_p.push_back( 1*(x^10) + 2*(x^9) + 2*(x^8) + 4*(x^7) + 4*(x^6) + 1*(x^5) + 1*(x^3) + 1*(x^2) + 3*x + 0 );
|
||||
|
||||
// factor all the randoms them for all the prime numbers
|
||||
for (unsigned random_i = 0; random_i < random_p.size(); ++ random_i) {
|
||||
for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) {
|
||||
unsigned prime = primes[prime_i];
|
||||
|
||||
upolynomial::zp_manager upm(nm);
|
||||
upm.set_zp(prime);
|
||||
|
||||
upolynomial::numeral_vector poly;
|
||||
upm.to_numeral_vector(random_p[random_i], poly);
|
||||
|
||||
cout << "Factoring "; upm.display(cout, poly); cout << " over Z_" << prime << endl;
|
||||
cout << "Expecting " << swinnerton_dyer_factors[random_i][0][prime_i] << " distinct factors, " << random_polynomial[random_i][1][prime_i] << " total" << endl;
|
||||
|
||||
upolynomial::zp_factors factors(upm);
|
||||
upolynomial::zp_factor(upm, poly, factors);
|
||||
|
||||
// check the result
|
||||
unsigned distinct = factors.distinct_factors();
|
||||
unsigned total = factors.total_factors();
|
||||
|
||||
cout << "Got " << factors << endl;
|
||||
cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl;
|
||||
|
||||
// SASSERT(random_polynomial[random_i][0][prime_i] == distinct);
|
||||
// SASSERT(random_polynomial[random_i][1][prime_i] == total);
|
||||
|
||||
upolynomial::numeral_vector multiplied;
|
||||
factors.multiply(multiplied);
|
||||
bool equal = upm.eq(poly, multiplied);
|
||||
cout << (equal ? "equal" : "not equal") << endl;
|
||||
SASSERT(equal);
|
||||
upm.reset(multiplied);
|
||||
|
||||
// remove the temp
|
||||
upm.reset(poly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void tst_factor_enumeration() {
|
||||
polynomial::numeral_manager nm;
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
vector<polynomial_ref> factors;
|
||||
for (int i = 0; i < 5; ++ i) {
|
||||
polynomial_ref factor(pm);
|
||||
factor = x + i;
|
||||
factors.push_back(factor);
|
||||
}
|
||||
|
||||
upolynomial::manager upm(nm);
|
||||
|
||||
upolynomial::zp_manager upm_13(nm);
|
||||
upm_13.set_zp(13);
|
||||
upolynomial::zp_factors factors_13(upm_13);
|
||||
|
||||
upolynomial::numeral constant;
|
||||
nm.set(constant, 10);
|
||||
factors_13.set_constant(constant);
|
||||
|
||||
for (unsigned i = 0; i < 5; ++ i) {
|
||||
upolynomial::numeral_vector ufactor;
|
||||
upm_13.to_numeral_vector(factors[i], ufactor);
|
||||
factors_13.push_back(ufactor, 1);
|
||||
upm.reset(ufactor);
|
||||
}
|
||||
|
||||
cout << "All: " << factors_13 << endl;
|
||||
|
||||
upolynomial::factorization_degree_set degrees(factors_13);
|
||||
degrees.display(cout); cout << endl;
|
||||
|
||||
scoped_mpz_vector left(nm), right(nm);
|
||||
upolynomial::ufactorization_combination_iterator it(factors_13, degrees);
|
||||
unsigned i = 0;
|
||||
it.display(cout);
|
||||
bool remove = false;
|
||||
while (it.next(remove)) {
|
||||
it.left(left);
|
||||
it.right(right);
|
||||
cout << "Left " << i << ": "; upm.display(cout, left); cout << endl;
|
||||
cout << "Right " << i << ": "; upm.display(cout, right); cout << endl;
|
||||
i ++;
|
||||
if (i % 3 == 0) {
|
||||
remove = true;
|
||||
} else {
|
||||
remove = false;
|
||||
}
|
||||
it.display(cout);
|
||||
}
|
||||
// SASSERT(i == 15);
|
||||
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < 5; ++ i) {
|
||||
factors_13.set_degree(i, factors_13.get_degree(i) + i);
|
||||
}
|
||||
cout << "Different: " << factors_13 << " of degree " << factors_13.get_degree() << endl;
|
||||
upolynomial::factorization_degree_set degrees1(factors_13);
|
||||
degrees1.display(cout); cout << endl; // [0, ..., 15]
|
||||
|
||||
polynomial_ref tmp1 = (x^3) + 1;
|
||||
polynomial_ref tmp2 = (x^5) + 2;
|
||||
polynomial_ref tmp3 = (x^7) + 3;
|
||||
upolynomial::numeral_vector up1, up2, up3;
|
||||
upm_13.to_numeral_vector(tmp1, up1);
|
||||
upm_13.to_numeral_vector(tmp2, up2);
|
||||
upm_13.to_numeral_vector(tmp3, up3);
|
||||
upolynomial::zp_factors tmp(upm_13);
|
||||
tmp.push_back(up1, 1);
|
||||
tmp.push_back(up2, 1);
|
||||
tmp.push_back(up3, 1);
|
||||
upm_13.reset(up1);
|
||||
upm_13.reset(up2);
|
||||
upm_13.reset(up3);
|
||||
|
||||
cout << "Different: " << tmp << " of degree " << tmp.get_degree() << endl;
|
||||
upolynomial::factorization_degree_set degrees2(tmp);
|
||||
degrees2.display(cout); cout << endl;
|
||||
|
||||
tmp1 = (x^2) + 1;
|
||||
tmp2 = (x^10) + 2;
|
||||
tmp3 = x + 3;
|
||||
upm_13.to_numeral_vector(tmp1, up1);
|
||||
upm_13.to_numeral_vector(tmp2, up2);
|
||||
upm_13.to_numeral_vector(tmp3, up3);
|
||||
tmp.clear();
|
||||
tmp.push_back(up1, 2);
|
||||
tmp.push_back(up2, 1);
|
||||
tmp.push_back(up3, 1);
|
||||
cout << "Different: " << tmp << " of degree " << tmp.get_degree() << endl;
|
||||
upm_13.reset(up1);
|
||||
upm_13.reset(up2);
|
||||
upm_13.reset(up3);
|
||||
upolynomial::factorization_degree_set degrees3(tmp);
|
||||
degrees3.display(cout); cout << endl;
|
||||
degrees1.intersect(degrees3);
|
||||
degrees1.display(cout); cout << endl;
|
||||
}
|
||||
|
||||
static void tst_factor_square_free_univariate_1(unsigned max_length) {
|
||||
|
||||
polynomial::numeral_manager nm;
|
||||
upolynomial::numeral test;
|
||||
upolynomial::numeral p;
|
||||
nm.set(test, -9);
|
||||
nm.set(p, 5);
|
||||
nm.mod(test, p, test);
|
||||
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
cout << "R.<x> = QQ['x']" << endl;
|
||||
|
||||
// let's start with \prod (p_i x^{p_{i+1} - p_{i+1})
|
||||
unsigned n_primes = sizeof(primes)/sizeof(unsigned);
|
||||
max_length = std::min(max_length, n_primes);
|
||||
for(unsigned length = 1; length < max_length; ++ length) {
|
||||
|
||||
// starting from prime_i going for length
|
||||
for(unsigned start_i = 0; start_i < n_primes; ++ start_i) {
|
||||
|
||||
polynomial_ref f(pm);
|
||||
|
||||
bool first = true;
|
||||
for (unsigned prime_i = 0; prime_i < length; ++ prime_i) {
|
||||
int p1 = primes[(start_i + prime_i) % n_primes];
|
||||
int p2 = primes[(start_i + prime_i + 1) % n_primes];
|
||||
if (first) {
|
||||
f = (p1*(x^p2) - p2);
|
||||
first = false;
|
||||
} else {
|
||||
f = f*(p1*(x^p2) - p2);
|
||||
}
|
||||
}
|
||||
|
||||
upolynomial::manager upm(nm);
|
||||
scoped_mpz_vector f_u(nm);
|
||||
upm.to_numeral_vector(f, f_u);
|
||||
|
||||
cout << "factoring "; upm.display(cout, f_u); cout << endl;
|
||||
cout << "expecting " << length << " factors ";
|
||||
upolynomial::factors factors(upm);
|
||||
/* bool ok = */ upolynomial::factor_square_free(upm, f_u, factors);
|
||||
cout << "got " << factors << endl;
|
||||
|
||||
SASSERT(factors.distinct_factors() == length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void tst_factor_square_free_univariate_2() {
|
||||
polynomial::numeral_manager nm;
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
// Swinnerton-Dyer polynomials (irreducible, modular factors of degree at most 2)
|
||||
polynomial_ref S1 = (x^2) - 2;
|
||||
polynomial_ref S2 = (x^4) - 10*(x^2) + 1;
|
||||
polynomial_ref S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576;
|
||||
polynomial_ref S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225;
|
||||
|
||||
vector<polynomial_ref> S;
|
||||
S.push_back(S1);
|
||||
S.push_back(S2);
|
||||
S.push_back(S3);
|
||||
S.push_back(S4);
|
||||
|
||||
upolynomial::manager upm(nm);
|
||||
|
||||
// factor all the S_i them for all the prime numbers
|
||||
for (unsigned S_i = 0; S_i < S.size(); ++ S_i) {
|
||||
upolynomial::numeral_vector S_i_u;
|
||||
upm.to_numeral_vector(S[S_i], S_i_u);
|
||||
|
||||
cout << "Factoring "; upm.display(cout, S_i_u); cout << " over Z " << endl;
|
||||
upolynomial::factors factors(upm);
|
||||
upolynomial::factor_square_free(upm, S_i_u, factors);
|
||||
|
||||
// check the result
|
||||
cout << "Got " << factors << endl;
|
||||
|
||||
// remove the temp
|
||||
upm.reset(S_i_u);
|
||||
}
|
||||
}
|
||||
|
||||
static void tst_factor_square_free_univariate_3() {
|
||||
polynomial::numeral_manager nm;
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
polynomial_ref deg70 = (x^70) - 6*(x^65) - (x^60) + 60*(x^55) - 54*(x^50) - 230*(x^45) + 274*(x^40) + 542*(x^35) - 615*(x^30) - 1120*(x^25) + 1500*(x^20) - 160*(x^15) - 395*(x^10) + 76*(x^5) + 34;
|
||||
|
||||
upolynomial::manager upm(nm);
|
||||
upolynomial::numeral_vector deg70_u;
|
||||
|
||||
upm.to_numeral_vector(deg70, deg70_u);
|
||||
|
||||
cout << "Factoring "; upm.display(cout, deg70_u); cout << " over Z " << endl;
|
||||
upolynomial::factors factors(upm);
|
||||
upolynomial::factor_square_free(upm, deg70_u, factors);
|
||||
|
||||
cout << "Got " << factors << endl;
|
||||
|
||||
upm.reset(deg70_u);
|
||||
}
|
||||
#endif
|
||||
|
||||
void tst_factor_swinnerton_dyer_big(unsigned max) {
|
||||
polynomial::numeral_manager nm;
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
vector<polynomial_ref> roots;
|
||||
vector<polynomial::var> vars;
|
||||
|
||||
unsigned n = std::min(max, static_cast<unsigned>(sizeof(primes)/sizeof(unsigned)));
|
||||
for(unsigned prime_i = 0; prime_i < n; ++ prime_i) {
|
||||
|
||||
int prime = primes[prime_i];
|
||||
|
||||
cout << "Computing Swinnerton-Dyer[" << prime_i + 1 << "]" << endl;
|
||||
|
||||
polynomial_ref y(pm);
|
||||
vars.push_back(pm.mk_var());
|
||||
y = pm.mk_polynomial(vars.back());
|
||||
|
||||
polynomial_ref p(pm);
|
||||
p = (y^2) - prime;
|
||||
roots.push_back(p);
|
||||
|
||||
polynomial_ref computation = x;
|
||||
for (unsigned i = 0; i < roots.size(); ++ i) {
|
||||
polynomial_ref var(pm);
|
||||
var = pm.mk_polynomial(vars[i]);
|
||||
computation = computation - var;
|
||||
}
|
||||
|
||||
{
|
||||
timeit timer(true, "computing swinnerton-dyer");
|
||||
|
||||
for (unsigned i = 0; i < roots.size(); ++ i) {
|
||||
polynomial_ref tmp(pm);
|
||||
pm.resultant(computation, roots[i], vars[i], tmp);
|
||||
computation = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "Computed Swinnerton-Dyer[" << prime_i + 1 << "], degree = " << pm.total_degree(computation) << ", size = " << pm.size(computation) << endl;
|
||||
|
||||
cout << "Starting factoring " << endl;
|
||||
|
||||
{
|
||||
timeit timer(true, "factoring swinnerton-dyer");
|
||||
|
||||
reslimit rl;
|
||||
upolynomial::manager upm(rl, nm);
|
||||
scoped_mpz_vector sd_u(nm);
|
||||
upm.to_numeral_vector(computation, sd_u);
|
||||
upolynomial::factors factors(upm);
|
||||
upolynomial::factor_square_free(upm, sd_u, factors);
|
||||
cout << "Got " << factors.distinct_factors() << " factors" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void tst_factor_square_free_multivariate_1(unsigned max_n) {
|
||||
#if 0
|
||||
polynomial::numeral_manager nm;
|
||||
upolynomial::numeral test;
|
||||
upolynomial::numeral p;
|
||||
nm.set(test, -9);
|
||||
nm.set(p, 5);
|
||||
nm.mod(test, p, test);
|
||||
|
||||
reslimit rl; polynomial::manager pm(rl, nm);
|
||||
|
||||
polynomial_ref x(pm);
|
||||
x = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
polynomial_ref y(pm);
|
||||
y = pm.mk_polynomial(pm.mk_var());
|
||||
|
||||
// lets start simple x^n - y^n
|
||||
for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) {
|
||||
unsigned prime = primes[prime_i];
|
||||
|
||||
if (prime > max_n) {
|
||||
break;
|
||||
}
|
||||
|
||||
polynomial_ref f = (x^prime) - (y^prime);
|
||||
cout << "factoring: " << f << endl;
|
||||
|
||||
// factor
|
||||
polynomial::factors factors(pm);
|
||||
polynomial::factor_square_free_primitive(f, factors);
|
||||
|
||||
cout << "got: " << factors << endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void tst_polynomial_factorization() {
|
||||
|
||||
enable_trace("polynomial::factorization");
|
||||
// enable_trace("polynomial::factorization::bughunt");
|
||||
enable_trace("polynomial::factorization::multivariate");
|
||||
// enable_trace("upolynomial");
|
||||
|
||||
// Z_p square-free factorization tests
|
||||
// tst_square_free_finite_1();
|
||||
|
||||
// Z_p factorization tests
|
||||
// tst_factor_finite_1();
|
||||
// tst_factor_finite_2();
|
||||
// tst_factor_finite_3();
|
||||
|
||||
// Z factorization
|
||||
// tst_factor_enumeration();
|
||||
// tst_factor_square_free_univariate_1(3);
|
||||
// tst_factor_square_free_univariate_2();
|
||||
// tst_factor_square_free_univariate_3();
|
||||
// tst_factor_swinnerton_dyer_big(3);
|
||||
|
||||
// Multivariate factorization
|
||||
tst_factor_square_free_multivariate_1(3);
|
||||
}
|
Loading…
Reference in a new issue