mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 04:28:17 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3
This commit is contained in:
commit
dedc130e98
|
@ -53,8 +53,8 @@ make
|
|||
sudo make install
|
||||
```
|
||||
|
||||
Note by default ``gcc`` is used as the C++ compiler if it is available. If you
|
||||
would prefer to use Clang change the ``mk_make.py`` line to
|
||||
Note by default ``g++`` is used as the C++ compiler if it is available. If you
|
||||
would prefer to use Clang change the ``mk_make.py`` invocation to:
|
||||
|
||||
```bash
|
||||
CXX=clang++ CC=clang python scripts/mk_make.py
|
||||
|
|
7
contrib/qprofdiff/Makefile
Normal file
7
contrib/qprofdiff/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
qprofdiff: main.cpp
|
||||
$(CXX) $(CXXFLAGS) main.cpp -o qprofdiff
|
||||
|
||||
all: qprofdiff
|
||||
|
||||
clean:
|
||||
rm -f qprofdiff
|
284
contrib/qprofdiff/main.cpp
Normal file
284
contrib/qprofdiff/main.cpp
Normal file
|
@ -0,0 +1,284 @@
|
|||
/*++
|
||||
Copyright (c) 2017 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
main.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Main file for qprofdiff.
|
||||
|
||||
Author:
|
||||
|
||||
Christoph M. Wintersteiger (cwinter)
|
||||
|
||||
Revision History:
|
||||
--*/
|
||||
#include<errno.h>
|
||||
#include<limits.h>
|
||||
|
||||
#include<string>
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<map>
|
||||
#include<vector>
|
||||
#include<set>
|
||||
#include<algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
set<string> options;
|
||||
|
||||
// Profile format:
|
||||
// [quantifier_instances] qname : num_instances : max_generation : max_cost_s
|
||||
const string prefix = "[quantifier_instances]";
|
||||
unsigned prefix_len = prefix.length();
|
||||
typedef struct { unsigned num_instances, max_generation, max_cost; } map_entry;
|
||||
|
||||
string trim(string str) {
|
||||
size_t linx = str.find_first_not_of(' ');
|
||||
size_t rinx = str.find_last_not_of(' ');
|
||||
return str.substr(linx, rinx-linx+1);
|
||||
}
|
||||
|
||||
int parse(string const & filename, map<string, map_entry> & data) {
|
||||
ifstream fs(filename.c_str());
|
||||
|
||||
if (!fs.is_open()) {
|
||||
cout << "Can't open file '" << filename << "'" << endl;
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
string qid;
|
||||
string tokens[4];
|
||||
unsigned cur_token = 0;
|
||||
|
||||
while (!fs.eof()) {
|
||||
string line;
|
||||
getline(fs, line);
|
||||
|
||||
if (line.substr(0, prefix_len) == prefix) {
|
||||
line = trim(line.substr(prefix_len));
|
||||
size_t from = 0, ti = 0;
|
||||
for (size_t inx = line.find(':', from);
|
||||
inx != string::npos;
|
||||
inx = line.find(':', from)) {
|
||||
tokens[ti] = trim(line.substr(from, inx-from));
|
||||
from = inx+1;
|
||||
ti++;
|
||||
}
|
||||
if (from != line.length() && ti < 4)
|
||||
tokens[ti] = trim(line.substr(from));
|
||||
|
||||
qid = tokens[0];
|
||||
|
||||
if (data.find(qid) == data.end()) {
|
||||
map_entry & entry = data[qid];
|
||||
entry.num_instances = entry.max_generation = entry.max_cost = 0;
|
||||
}
|
||||
|
||||
map_entry & entry = data[qid];
|
||||
entry.num_instances = atoi(tokens[1].c_str());
|
||||
entry.max_generation = (unsigned)atoi(tokens[2].c_str());
|
||||
entry.max_cost = (unsigned)atoi(tokens[3].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
fs.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void display_data(map<string, map_entry> & data) {
|
||||
for (map<string, map_entry>::iterator it = data.begin();
|
||||
it != data.end();
|
||||
it++)
|
||||
cout << it->first << ": " << it->second.num_instances <<
|
||||
", " << it->second.max_generation <<
|
||||
", " << it->second.max_cost << endl;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
int d_num_instances, d_max_generation, d_max_cost;
|
||||
bool left_only, right_only;
|
||||
} diff_entry;
|
||||
|
||||
typedef struct { string qid; diff_entry e; } diff_item;
|
||||
|
||||
#define DIFF_LT(X) bool diff_item_lt_ ## X (diff_item const & l, diff_item const & r) { \
|
||||
int l_lt_r = l.e.d_ ## X < r.e.d_ ## X; \
|
||||
int l_eq_r = l.e.d_ ## X == r.e.d_ ## X; \
|
||||
return \
|
||||
l.e.left_only ? (r.e.left_only ? ((l_eq_r) ? l.qid < r.qid : l_lt_r) : false) : \
|
||||
l.e.right_only ? (r.e.right_only ? ((l_eq_r) ? l.qid < r.qid : l_lt_r) : true) : \
|
||||
r.e.right_only ? false : \
|
||||
r.e.left_only ? true : \
|
||||
l_lt_r; \
|
||||
}
|
||||
|
||||
DIFF_LT(num_instances)
|
||||
DIFF_LT(max_generation)
|
||||
DIFF_LT(max_cost)
|
||||
|
||||
int indicate(diff_entry const & e, bool suppress_unchanged) {
|
||||
if (e.left_only) {
|
||||
cout << "< ";
|
||||
return INT_MIN;
|
||||
}
|
||||
else if (e.right_only) {
|
||||
cout << "> ";
|
||||
return INT_MAX;
|
||||
}
|
||||
else {
|
||||
int const & delta =
|
||||
(options.find("-si") != options.end()) ? e.d_num_instances :
|
||||
(options.find("-sg") != options.end()) ? e.d_max_generation :
|
||||
(options.find("-sc") != options.end()) ? e.d_max_cost :
|
||||
e.d_num_instances;
|
||||
|
||||
if (delta < 0)
|
||||
cout << "+ ";
|
||||
else if (delta > 0)
|
||||
cout << "- ";
|
||||
else if (delta == 0 && !suppress_unchanged)
|
||||
cout << "= ";
|
||||
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
|
||||
void diff(map<string, map_entry> & left, map<string, map_entry> & right) {
|
||||
map<string, diff_entry> diff_data;
|
||||
|
||||
for (map<string, map_entry>::const_iterator lit = left.begin();
|
||||
lit != left.end();
|
||||
lit++) {
|
||||
string const & qid = lit->first;
|
||||
map_entry const & lentry = lit->second;
|
||||
|
||||
map<string, map_entry>::const_iterator rit = right.find(qid);
|
||||
if (rit != right.end()) {
|
||||
map_entry const & rentry = rit->second;
|
||||
diff_entry & de = diff_data[qid];
|
||||
|
||||
de.left_only = de.right_only = false;
|
||||
de.d_num_instances = lentry.num_instances - rentry.num_instances;
|
||||
de.d_max_generation = lentry.max_generation - rentry.max_generation;
|
||||
de.d_max_cost = lentry.max_cost - rentry.max_cost;
|
||||
}
|
||||
else {
|
||||
diff_entry & de = diff_data[qid];
|
||||
de.left_only = true;
|
||||
de.right_only = false;
|
||||
de.d_num_instances = lentry.num_instances;
|
||||
de.d_max_generation = lentry.max_generation;
|
||||
de.d_max_cost = lentry.max_cost;
|
||||
}
|
||||
}
|
||||
|
||||
for (map<string, map_entry>::const_iterator rit = right.begin();
|
||||
rit != right.end();
|
||||
rit++) {
|
||||
string const & qid = rit->first;
|
||||
map_entry const & rentry = rit->second;
|
||||
|
||||
map<string, map_entry>::const_iterator lit = left.find(qid);
|
||||
if (lit == left.end()) {
|
||||
diff_entry & de = diff_data[qid];
|
||||
de.left_only = false;
|
||||
de.right_only = true;
|
||||
de.d_num_instances = -(int)rentry.num_instances;
|
||||
de.d_max_generation = -(int)rentry.max_generation;
|
||||
de.d_max_cost = -(int)rentry.max_cost;
|
||||
}
|
||||
}
|
||||
|
||||
vector<diff_item> flat_data;
|
||||
for (map<string, diff_entry>::const_iterator it = diff_data.begin();
|
||||
it != diff_data.end();
|
||||
it++) {
|
||||
flat_data.push_back(diff_item());
|
||||
flat_data.back().qid = it->first;
|
||||
flat_data.back().e = it->second;
|
||||
}
|
||||
|
||||
stable_sort(flat_data.begin(), flat_data.end(),
|
||||
options.find("-si") != options.end() ? diff_item_lt_num_instances:
|
||||
options.find("-sg") != options.end() ? diff_item_lt_max_generation :
|
||||
options.find("-sc") != options.end() ? diff_item_lt_max_cost :
|
||||
diff_item_lt_num_instances);
|
||||
|
||||
bool suppress_unchanged = options.find("-n") != options.end();
|
||||
|
||||
for (vector<diff_item>::const_iterator it = flat_data.begin();
|
||||
it != flat_data.end();
|
||||
it++) {
|
||||
diff_item const & d = *it;
|
||||
string const & qid = d.qid;
|
||||
diff_entry const & e = d.e;
|
||||
|
||||
int delta = indicate(e, suppress_unchanged);
|
||||
|
||||
if (!(delta == 0 && suppress_unchanged))
|
||||
cout << qid << " (" <<
|
||||
(e.d_num_instances > 0 ? "" : "+") << -e.d_num_instances << " inst., " <<
|
||||
(e.d_max_generation > 0 ? "" : "+") << -e.d_max_generation << " max. gen., " <<
|
||||
(e.d_max_cost > 0 ? "" : "+") << -e.d_max_cost << " max. cost)" <<
|
||||
endl;
|
||||
}
|
||||
}
|
||||
|
||||
void display_usage() {
|
||||
cout << "Usage: qprofdiff [options] <filename> <filename>" << endl;
|
||||
cout << "Options:" << endl;
|
||||
cout << " -n Suppress unchanged items" << endl;
|
||||
cout << " -si Sort by difference in number of instances" << endl;
|
||||
cout << " -sg Sort by difference in max. generation" << endl;
|
||||
cout << " -sc Sort by difference in max. cost" << endl;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
char * filename1 = 0;
|
||||
char * filename2 = 0;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
int len = string(argv[i]).length();
|
||||
if (len > 1 && argv[i][0] == '-') {
|
||||
options.insert(string(argv[i]));
|
||||
}
|
||||
else if (filename1 == 0)
|
||||
filename1 = argv[i];
|
||||
else if (filename2 == 0)
|
||||
filename2 = argv[i];
|
||||
else {
|
||||
cout << "Invalid argument: " << argv[i] << endl << endl;
|
||||
display_usage();
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (filename1 == 0 || filename2 == 0) {
|
||||
cout << "Two filenames required." << endl << endl;
|
||||
display_usage();
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
||||
cout << "Comparing " << filename1 << " to " << filename2 << endl;
|
||||
|
||||
map<string, map_entry> data1, data2;
|
||||
|
||||
int r = parse(filename1, data1);
|
||||
if (r != 0) return r;
|
||||
r = parse(filename2, data2);
|
||||
if (r != 0) return r;
|
||||
|
||||
// display_data(data1);
|
||||
// display_data(data2);
|
||||
|
||||
diff(data1, data2);
|
||||
|
||||
return 0;
|
||||
}
|
3
contrib/qprofdiff/maintainers.txt
Normal file
3
contrib/qprofdiff/maintainers.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Maintainers
|
||||
|
||||
- Christoph M. Wintersteiger (@wintersteiger, cwinter@microsoft.com)
|
137
contrib/qprofdiff/qprofdiff.vcxproj
Normal file
137
contrib/qprofdiff/qprofdiff.vcxproj
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{96E7E3EF-4162-474D-BD32-C702632AAF2B}</ProjectGuid>
|
||||
<RootNamespace>qprofdiff</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\src\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>
|
||||
</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(LibraryPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\src\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\src\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\src\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
22
contrib/qprofdiff/qprofdiff.vcxproj.filters
Normal file
22
contrib/qprofdiff/qprofdiff.vcxproj.filters
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -128,7 +128,7 @@ extern "C" {
|
|||
lbool r = l_undef;
|
||||
cancel_eh<reslimit> eh(mk_c(c)->m().limit());
|
||||
unsigned timeout = to_optimize_ptr(o)->get_params().get_uint("timeout", mk_c(c)->get_timeout());
|
||||
unsigned rlimit = mk_c(c)->get_rlimit();
|
||||
unsigned rlimit = to_optimize_ptr(o)->get_params().get_uint("rlimit", mk_c(c)->get_rlimit());
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_timer timer(timeout, &eh);
|
||||
|
|
|
@ -2244,7 +2244,7 @@ namespace z3 {
|
|||
void from_file(char const* s) { Z3_fixedpoint_from_file(ctx(), m_fp, s); check_error(); }
|
||||
void add_rule(expr& rule, symbol const& name) { Z3_fixedpoint_add_rule(ctx(), m_fp, rule, name); check_error(); }
|
||||
void add_fact(func_decl& f, unsigned * args) { Z3_fixedpoint_add_fact(ctx(), m_fp, f, f.arity(), args); check_error(); }
|
||||
check_result query(expr& q) { Z3_lbool r = Z3_fixedpoint_query(ctx(), m_fp, q); check_error(); to_check_result(r); }
|
||||
check_result query(expr& q) { Z3_lbool r = Z3_fixedpoint_query(ctx(), m_fp, q); check_error(); return to_check_result(r); }
|
||||
check_result query(func_decl_vector& relations) {
|
||||
array<Z3_func_decl> rs(relations);
|
||||
Z3_lbool r = Z3_fixedpoint_query_relations(ctx(), m_fp, rs.size(), rs.ptr());
|
||||
|
|
|
@ -1890,43 +1890,43 @@ public class Context implements AutoCloseable {
|
|||
/**
|
||||
* Create the empty sequence.
|
||||
*/
|
||||
public SeqExpr MkEmptySeq(Sort s)
|
||||
public SeqExpr mkEmptySeq(Sort s)
|
||||
{
|
||||
checkContextMatch(s);
|
||||
return new SeqExpr(this, Native.mkSeqEmpty(nCtx(), s.getNativeObject()));
|
||||
return (SeqExpr) Expr.create(this, Native.mkSeqEmpty(nCtx(), s.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the singleton sequence.
|
||||
*/
|
||||
public SeqExpr MkUnit(Expr elem)
|
||||
public SeqExpr mkUnit(Expr elem)
|
||||
{
|
||||
checkContextMatch(elem);
|
||||
return new SeqExpr(this, Native.mkSeqUnit(nCtx(), elem.getNativeObject()));
|
||||
return (SeqExpr) Expr.create(this, Native.mkSeqUnit(nCtx(), elem.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a string constant.
|
||||
*/
|
||||
public SeqExpr MkString(String s)
|
||||
public SeqExpr mkString(String s)
|
||||
{
|
||||
return new SeqExpr(this, Native.mkString(nCtx(), s));
|
||||
return (SeqExpr) Expr.create(this, Native.mkString(nCtx(), s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatentate sequences.
|
||||
*/
|
||||
public SeqExpr MkConcat(SeqExpr... t)
|
||||
public SeqExpr mkConcat(SeqExpr... t)
|
||||
{
|
||||
checkContextMatch(t);
|
||||
return new SeqExpr(this, Native.mkSeqConcat(nCtx(), t.length, AST.arrayToNative(t)));
|
||||
return (SeqExpr) Expr.create(this, Native.mkSeqConcat(nCtx(), t.length, AST.arrayToNative(t)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the length of a given sequence.
|
||||
*/
|
||||
public IntExpr MkLength(SeqExpr s)
|
||||
public IntExpr mkLength(SeqExpr s)
|
||||
{
|
||||
checkContextMatch(s);
|
||||
return (IntExpr) Expr.create(this, Native.mkSeqLength(nCtx(), s.getNativeObject()));
|
||||
|
@ -1935,128 +1935,219 @@ public class Context implements AutoCloseable {
|
|||
/**
|
||||
* Check for sequence prefix.
|
||||
*/
|
||||
public BoolExpr MkPrefixOf(SeqExpr s1, SeqExpr s2)
|
||||
public BoolExpr mkPrefixOf(SeqExpr s1, SeqExpr s2)
|
||||
{
|
||||
checkContextMatch(s1, s2);
|
||||
return new BoolExpr(this, Native.mkSeqPrefix(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
|
||||
return (BoolExpr) Expr.create(this, Native.mkSeqPrefix(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for sequence suffix.
|
||||
*/
|
||||
public BoolExpr MkSuffixOf(SeqExpr s1, SeqExpr s2)
|
||||
public BoolExpr mkSuffixOf(SeqExpr s1, SeqExpr s2)
|
||||
{
|
||||
checkContextMatch(s1, s2);
|
||||
return new BoolExpr(this, Native.mkSeqSuffix(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
|
||||
return (BoolExpr)Expr.create(this, Native.mkSeqSuffix(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for sequence containment of s2 in s1.
|
||||
*/
|
||||
public BoolExpr MkContains(SeqExpr s1, SeqExpr s2)
|
||||
public BoolExpr mkContains(SeqExpr s1, SeqExpr s2)
|
||||
{
|
||||
checkContextMatch(s1, s2);
|
||||
return new BoolExpr(this, Native.mkSeqContains(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
|
||||
return (BoolExpr) Expr.create(this, Native.mkSeqContains(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve sequence of length one at index.
|
||||
*/
|
||||
public SeqExpr MkAt(SeqExpr s, IntExpr index)
|
||||
public SeqExpr mkAt(SeqExpr s, IntExpr index)
|
||||
{
|
||||
checkContextMatch(s, index);
|
||||
return new SeqExpr(this, Native.mkSeqAt(nCtx(), s.getNativeObject(), index.getNativeObject()));
|
||||
return (SeqExpr) Expr.create(this, Native.mkSeqAt(nCtx(), s.getNativeObject(), index.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract subsequence.
|
||||
*/
|
||||
public SeqExpr MkExtract(SeqExpr s, IntExpr offset, IntExpr length)
|
||||
public SeqExpr mkExtract(SeqExpr s, IntExpr offset, IntExpr length)
|
||||
{
|
||||
checkContextMatch(s, offset, length);
|
||||
return new SeqExpr(this, Native.mkSeqExtract(nCtx(), s.getNativeObject(), offset.getNativeObject(), length.getNativeObject()));
|
||||
return (SeqExpr) Expr.create(this, Native.mkSeqExtract(nCtx(), s.getNativeObject(), offset.getNativeObject(), length.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract index of sub-string starting at offset.
|
||||
*/
|
||||
public IntExpr MkIndexOf(SeqExpr s, SeqExpr substr, ArithExpr offset)
|
||||
public IntExpr mkIndexOf(SeqExpr s, SeqExpr substr, ArithExpr offset)
|
||||
{
|
||||
checkContextMatch(s, substr, offset);
|
||||
return new IntExpr(this, Native.mkSeqIndex(nCtx(), s.getNativeObject(), substr.getNativeObject(), offset.getNativeObject()));
|
||||
return (IntExpr)Expr.create(this, Native.mkSeqIndex(nCtx(), s.getNativeObject(), substr.getNativeObject(), offset.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the first occurrence of src by dst in s.
|
||||
*/
|
||||
public SeqExpr MkReplace(SeqExpr s, SeqExpr src, SeqExpr dst)
|
||||
public SeqExpr mkReplace(SeqExpr s, SeqExpr src, SeqExpr dst)
|
||||
{
|
||||
checkContextMatch(s, src, dst);
|
||||
return new SeqExpr(this, Native.mkSeqReplace(nCtx(), s.getNativeObject(), src.getNativeObject(), dst.getNativeObject()));
|
||||
return (SeqExpr) Expr.create(this, Native.mkSeqReplace(nCtx(), s.getNativeObject(), src.getNativeObject(), dst.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a regular expression that accepts sequence s.
|
||||
*/
|
||||
public ReExpr MkToRe(SeqExpr s)
|
||||
public ReExpr mkToRe(SeqExpr s)
|
||||
{
|
||||
checkContextMatch(s);
|
||||
return new ReExpr(this, Native.mkSeqToRe(nCtx(), s.getNativeObject()));
|
||||
return (ReExpr) Expr.create(this, Native.mkSeqToRe(nCtx(), s.getNativeObject()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check for regular expression membership.
|
||||
*/
|
||||
public BoolExpr MkInRe(SeqExpr s, ReExpr re)
|
||||
public BoolExpr mkInRe(SeqExpr s, ReExpr re)
|
||||
{
|
||||
checkContextMatch(s, re);
|
||||
return new BoolExpr(this, Native.mkSeqInRe(nCtx(), s.getNativeObject(), re.getNativeObject()));
|
||||
return (BoolExpr) Expr.create(this, Native.mkSeqInRe(nCtx(), s.getNativeObject(), re.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the Kleene star of a regular expression.
|
||||
*/
|
||||
public ReExpr MkStar(ReExpr re)
|
||||
public ReExpr mkStar(ReExpr re)
|
||||
{
|
||||
checkContextMatch(re);
|
||||
return new ReExpr(this, Native.mkReStar(nCtx(), re.getNativeObject()));
|
||||
return (ReExpr) Expr.create(this, Native.mkReStar(nCtx(), re.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the lower and upper-bounded Kleene star of a regular expression.
|
||||
*/
|
||||
public ReExpr mkLoop(ReExpr re, int lo, int hi)
|
||||
{
|
||||
return (ReExpr) Expr.create(this, Native.mkReLoop(nCtx(), re.getNativeObject(), lo, hi));
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the lower-bounded Kleene star of a regular expression.
|
||||
*/
|
||||
public ReExpr mkLoop(ReExpr re, int lo)
|
||||
{
|
||||
return (ReExpr) Expr.create(this, Native.mkReLoop(nCtx(), re.getNativeObject(), lo, 0));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Take the Kleene plus of a regular expression.
|
||||
*/
|
||||
public ReExpr MPlus(ReExpr re)
|
||||
public ReExpr mkPlus(ReExpr re)
|
||||
{
|
||||
checkContextMatch(re);
|
||||
return new ReExpr(this, Native.mkRePlus(nCtx(), re.getNativeObject()));
|
||||
return (ReExpr) Expr.create(this, Native.mkRePlus(nCtx(), re.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the optional regular expression.
|
||||
*/
|
||||
public ReExpr MOption(ReExpr re)
|
||||
public ReExpr mkOption(ReExpr re)
|
||||
{
|
||||
checkContextMatch(re);
|
||||
return new ReExpr(this, Native.mkReOption(nCtx(), re.getNativeObject()));
|
||||
return (ReExpr) Expr.create(this, Native.mkReOption(nCtx(), re.getNativeObject()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the complement regular expression.
|
||||
*/
|
||||
public ReExpr mkComplement(ReExpr re)
|
||||
{
|
||||
checkContextMatch(re);
|
||||
return (ReExpr) Expr.create(this, Native.mkReComplement(nCtx(), re.getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the concatenation of regular languages.
|
||||
*/
|
||||
public ReExpr MkConcat(ReExpr... t)
|
||||
public ReExpr mkConcat(ReExpr... t)
|
||||
{
|
||||
checkContextMatch(t);
|
||||
return new ReExpr(this, Native.mkReConcat(nCtx(), t.length, AST.arrayToNative(t)));
|
||||
return (ReExpr) Expr.create(this, Native.mkReConcat(nCtx(), t.length, AST.arrayToNative(t)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the union of regular languages.
|
||||
*/
|
||||
public ReExpr MkUnion(ReExpr... t)
|
||||
public ReExpr mkUnion(ReExpr... t)
|
||||
{
|
||||
checkContextMatch(t);
|
||||
return new ReExpr(this, Native.mkReUnion(nCtx(), t.length, AST.arrayToNative(t)));
|
||||
return (ReExpr) Expr.create(this, Native.mkReUnion(nCtx(), t.length, AST.arrayToNative(t)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the intersection of regular languages.
|
||||
*/
|
||||
public ReExpr mkIntersect(ReExpr... t)
|
||||
{
|
||||
checkContextMatch(t);
|
||||
return (ReExpr) Expr.create(this, Native.mkReIntersect(nCtx(), t.length, AST.arrayToNative(t)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a range expression.
|
||||
*/
|
||||
public ReExpr MkRange(SeqExpr lo, SeqExpr hi)
|
||||
{
|
||||
checkContextMatch(lo, hi);
|
||||
return (ReExpr) Expr.create(this, Native.mkReRange(nCtx(), lo.getNativeObject(), hi.getNativeObject()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an at-most-k constraint.
|
||||
*/
|
||||
public BoolExpr mkAtMost(BoolExpr[] args, int k)
|
||||
{
|
||||
checkContextMatch(args);
|
||||
return (BoolExpr) Expr.create(this, Native.mkAtmost(nCtx(), args.length, AST.arrayToNative(args), k));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an at-least-k constraint.
|
||||
*/
|
||||
public BoolExpr mkAtLeast(BoolExpr[] args, int k)
|
||||
{
|
||||
checkContextMatch(args);
|
||||
return (BoolExpr) Expr.create(this, Native.mkAtleast(nCtx(), args.length, AST.arrayToNative(args), k));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pseudo-Boolean less-or-equal constraint.
|
||||
*/
|
||||
public BoolExpr mkPBLe(int[] coeffs, BoolExpr[] args, int k)
|
||||
{
|
||||
checkContextMatch(args);
|
||||
return (BoolExpr) Expr.create(this, Native.mkPble(nCtx(), args.length, AST.arrayToNative(args), coeffs, k));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pseudo-Boolean greater-or-equal constraint.
|
||||
*/
|
||||
public BoolExpr mkPBGe(int[] coeffs, BoolExpr[] args, int k)
|
||||
{
|
||||
checkContextMatch(args);
|
||||
return (BoolExpr) Expr.create(this, Native.mkPbge(nCtx(), args.length, AST.arrayToNative(args), coeffs, k));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pseudo-Boolean equal constraint.
|
||||
*/
|
||||
public BoolExpr mkPBEq(int[] coeffs, BoolExpr[] args, int k)
|
||||
{
|
||||
checkContextMatch(args);
|
||||
return (BoolExpr) Expr.create(this, Native.mkPbeq(nCtx(), args.length, AST.arrayToNative(args), coeffs, k));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ void defined_names::impl::bound_vars(sort_ref_buffer const & sorts, buffer<symbo
|
|||
1, symbol::null, symbol::null,
|
||||
1, patterns);
|
||||
TRACE("mk_definition_bug", tout << "before elim_unused_vars:\n" << mk_ismt2_pp(q, m_manager) << "\n";);
|
||||
elim_unused_vars(m_manager, q, result);
|
||||
elim_unused_vars(m_manager, q, params_ref(), result);
|
||||
TRACE("mk_definition_bug", tout << "after elim_unused_vars:\n" << mk_ismt2_pp(result, m_manager) << "\n";);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ bool arith_rewriter::is_bound(expr * arg1, expr * arg2, op_kind kind, expr_ref &
|
|||
}
|
||||
}
|
||||
expr* t1, *t2;
|
||||
bool is_int;
|
||||
bool is_int = false;
|
||||
if (m_util.is_mod(arg2)) {
|
||||
std::swap(arg1, arg2);
|
||||
switch (kind) {
|
||||
|
|
|
@ -138,7 +138,7 @@ void der::operator()(quantifier * q, expr_ref & r, proof_ref & pr) {
|
|||
// Eliminate variables that have become unused
|
||||
if (reduced && is_forall(r)) {
|
||||
quantifier * q = to_quantifier(r);
|
||||
elim_unused_vars(m_manager, q, r);
|
||||
elim_unused_vars(m_manager, q, params_ref(), r);
|
||||
if (m_manager.proofs_enabled()) {
|
||||
proof * p1 = m_manager.mk_elim_unused_vars(q, r);
|
||||
pr = m_manager.mk_transitivity(pr, p1);
|
||||
|
|
|
@ -8,5 +8,6 @@ def_module_params('rewriter',
|
|||
("push_ite_bv", BOOL, False, "push if-then-else over bit-vector terms."),
|
||||
("pull_cheap_ite", BOOL, False, "pull if-then-else terms when cheap."),
|
||||
("bv_ineq_consistency_test_max", UINT, 0, "max size of conjunctions on which to perform consistency test based on inequalities on bitvectors."),
|
||||
("cache_all", BOOL, False, "cache all intermediate results.")))
|
||||
("cache_all", BOOL, False, "cache all intermediate results."),
|
||||
("ignore_patterns_on_ground_qbody", BOOL, True, "ignores patterns on quantifiers that don't mention their bound variables.")))
|
||||
|
||||
|
|
|
@ -60,7 +60,12 @@ expr_ref sym_expr::accept(expr* e) {
|
|||
}
|
||||
|
||||
std::ostream& sym_expr::display(std::ostream& out) const {
|
||||
return out << m_t;
|
||||
switch (m_ty) {
|
||||
case t_char: return out << m_t;
|
||||
case t_range: return out << m_t << ":" << m_s;
|
||||
case t_pred: return out << m_t;
|
||||
}
|
||||
return out << "expression type not recognized";
|
||||
}
|
||||
|
||||
struct display_expr1 {
|
||||
|
@ -237,6 +242,7 @@ eautomaton* re2automaton::re2aut(expr* e) {
|
|||
unsigned nb = s1.num_bits();
|
||||
expr_ref _start(bv.mk_numeral(start, nb), m);
|
||||
expr_ref _stop(bv.mk_numeral(stop, nb), m);
|
||||
TRACE("seq", tout << "Range: " << start << " " << stop << "\n";);
|
||||
a = alloc(eautomaton, sm, sym_expr::mk_range(_start, _stop));
|
||||
return a.detach();
|
||||
}
|
||||
|
@ -646,6 +652,29 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) {
|
|||
result = m().mk_true();
|
||||
return BR_DONE;
|
||||
}
|
||||
bool all_units = true;
|
||||
for (unsigned i = 0; i < bs.size(); ++i) {
|
||||
all_units = m_util.str.is_unit(bs[i].get());
|
||||
}
|
||||
for (unsigned i = 0; i < as.size(); ++i) {
|
||||
all_units = m_util.str.is_unit(as[i].get());
|
||||
}
|
||||
if (all_units) {
|
||||
if (as.size() < bs.size()) {
|
||||
result = m().mk_false();
|
||||
return BR_DONE;
|
||||
}
|
||||
expr_ref_vector ors(m());
|
||||
for (unsigned i = 0; i < as.size() - bs.size() + 1; ++i) {
|
||||
expr_ref_vector ands(m());
|
||||
for (unsigned j = 0; j < bs.size(); ++j) {
|
||||
ands.push_back(m().mk_eq(as[i + j].get(), bs[j].get()));
|
||||
}
|
||||
ors.push_back(::mk_and(ands));
|
||||
}
|
||||
result = ::mk_or(ors);
|
||||
return BR_REWRITE_FULL;
|
||||
}
|
||||
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
@ -1435,6 +1464,7 @@ bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_
|
|||
zstring s;
|
||||
bool lchange = false;
|
||||
SASSERT(lhs.empty());
|
||||
TRACE("seq", tout << ls << "\n"; tout << rs << "\n";);
|
||||
// solve from back
|
||||
while (true) {
|
||||
while (!rs.empty() && m_util.str.is_empty(rs.back())) {
|
||||
|
@ -1552,9 +1582,11 @@ bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_
|
|||
head2 < rs.size() &&
|
||||
m_util.str.is_string(ls[head1].get(), s1) &&
|
||||
m_util.str.is_string(rs[head2].get(), s2)) {
|
||||
TRACE("seq", tout << s1 << " - " << s2 << " " << s1.length() << " " << s2.length() << "\n";);
|
||||
unsigned l = std::min(s1.length(), s2.length());
|
||||
for (unsigned i = 0; i < l; ++i) {
|
||||
if (s1[i] != s2[i]) {
|
||||
TRACE("seq", tout << "different at position " << i << " " << s1[i] << " " << s2[i] << "\n";);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
bool m_cache_all;
|
||||
bool m_push_ite_arith;
|
||||
bool m_push_ite_bv;
|
||||
bool m_ignore_patterns_on_ground_qbody;
|
||||
|
||||
// substitution support
|
||||
expr_dependency_ref m_used_dependencies; // set of dependencies of used substitutions
|
||||
|
@ -70,6 +71,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
m_cache_all = p.cache_all();
|
||||
m_push_ite_arith = p.push_ite_arith();
|
||||
m_push_ite_bv = p.push_ite_bv();
|
||||
m_ignore_patterns_on_ground_qbody = p.ignore_patterns_on_ground_qbody();
|
||||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
|
@ -649,7 +651,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
SASSERT(is_well_sorted(m(), q1));
|
||||
}
|
||||
|
||||
elim_unused_vars(m(), q1, result);
|
||||
elim_unused_vars(m(), q1, params_ref(), result);
|
||||
|
||||
TRACE("reduce_quantifier", tout << "after elim_unused_vars:\n" << mk_ismt2_pp(result, m()) << "\n";);
|
||||
|
||||
|
|
|
@ -39,10 +39,16 @@ void var_subst::operator()(expr * n, unsigned num_args, expr * const * args, exp
|
|||
tout << mk_ismt2_pp(result, m_reducer.m()) << "\n";);
|
||||
}
|
||||
|
||||
unused_vars_eliminator::unused_vars_eliminator(ast_manager & m, params_ref const & params) :
|
||||
m(m), m_subst(m), m_params(params)
|
||||
{
|
||||
m_ignore_patterns_on_ground_qbody = m_params.get_bool("ignore_patterns_on_ground_qbody", true);
|
||||
}
|
||||
|
||||
void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
||||
SASSERT(is_well_sorted(m, q));
|
||||
if (is_ground(q->get_expr())) {
|
||||
// ignore patterns if the body is a ground formula.
|
||||
if (m_ignore_patterns_on_ground_qbody && is_ground(q->get_expr())) {
|
||||
// Ignore patterns if the body is a ground formula.
|
||||
result = q->get_expr();
|
||||
return;
|
||||
}
|
||||
|
@ -146,8 +152,8 @@ void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
|||
SASSERT(is_well_sorted(m, result));
|
||||
}
|
||||
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
|
||||
unused_vars_eliminator el(m);
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params, expr_ref & result) {
|
||||
unused_vars_eliminator el(m, params);
|
||||
el(q, result);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Notes:
|
|||
|
||||
#include"rewriter.h"
|
||||
#include"used_vars.h"
|
||||
#include"params.h"
|
||||
|
||||
/**
|
||||
\brief Alias for var_shifter class.
|
||||
|
@ -58,12 +59,14 @@ class unused_vars_eliminator {
|
|||
ast_manager & m;
|
||||
var_subst m_subst;
|
||||
used_vars m_used;
|
||||
params_ref m_params;
|
||||
bool m_ignore_patterns_on_ground_qbody;
|
||||
public:
|
||||
unused_vars_eliminator(ast_manager& m): m(m), m_subst(m) {}
|
||||
unused_vars_eliminator(ast_manager & m, params_ref const & params);
|
||||
void operator()(quantifier* q, expr_ref& r);
|
||||
};
|
||||
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & r);
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params, expr_ref & r);
|
||||
|
||||
/**
|
||||
\brief Instantiate quantifier q using the given exprs.
|
||||
|
|
|
@ -126,13 +126,14 @@ static bool is_escape_char(char const *& s, unsigned& result) {
|
|||
zstring::zstring(encoding enc): m_encoding(enc) {}
|
||||
|
||||
zstring::zstring(char const* s, encoding enc): m_encoding(enc) {
|
||||
unsigned mask = 0xFF; // TBD for UTF
|
||||
while (*s) {
|
||||
unsigned ch;
|
||||
if (is_escape_char(s, ch)) {
|
||||
m_buffer.push_back(ch);
|
||||
m_buffer.push_back(ch & mask);
|
||||
}
|
||||
else {
|
||||
m_buffer.push_back(*s);
|
||||
m_buffer.push_back(*s & mask);
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -304,6 +304,7 @@ public:
|
|||
|
||||
app* mk_to_re(expr* s) { return m.mk_app(m_fid, OP_SEQ_TO_RE, 1, &s); }
|
||||
app* mk_in_re(expr* s, expr* r) { return m.mk_app(m_fid, OP_SEQ_IN_RE, s, r); }
|
||||
app* mk_range(expr* s1, expr* s2) { return m.mk_app(m_fid, OP_RE_RANGE, s1, s2); }
|
||||
app* mk_concat(expr* r1, expr* r2) { return m.mk_app(m_fid, OP_RE_CONCAT, r1, r2); }
|
||||
app* mk_union(expr* r1, expr* r2) { return m.mk_app(m_fid, OP_RE_UNION, r1, r2); }
|
||||
app* mk_inter(expr* r1, expr* r2) { return m.mk_app(m_fid, OP_RE_INTERSECT, r1, r2); }
|
||||
|
|
|
@ -126,7 +126,7 @@ void distribute_forall::reduce1_quantifier(quantifier * q) {
|
|||
quantifier_ref tmp_q(m_manager);
|
||||
tmp_q = m_manager.update_quantifier(q, not_arg);
|
||||
expr_ref new_q(m_manager);
|
||||
elim_unused_vars(m_manager, tmp_q, new_q);
|
||||
elim_unused_vars(m_manager, tmp_q, params_ref(), new_q);
|
||||
new_args.push_back(new_q);
|
||||
}
|
||||
expr_ref result(m_manager);
|
||||
|
|
|
@ -188,7 +188,7 @@ void elim_bounds::operator()(quantifier * q, expr_ref & r) {
|
|||
}
|
||||
quantifier_ref new_q(m_manager);
|
||||
new_q = m_manager.update_quantifier(q, new_body);
|
||||
elim_unused_vars(m_manager, new_q, r);
|
||||
elim_unused_vars(m_manager, new_q, params_ref(), r);
|
||||
TRACE("elim_bounds", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";);
|
||||
}
|
||||
|
||||
|
|
|
@ -852,7 +852,7 @@ void simplifier::reduce1_quantifier(quantifier * q) {
|
|||
}
|
||||
|
||||
expr_ref r(m);
|
||||
elim_unused_vars(m, q1, r);
|
||||
elim_unused_vars(m, q1, params_ref(), r);
|
||||
|
||||
proof * pr = 0;
|
||||
if (m.fine_grain_proofs()) {
|
||||
|
|
|
@ -29,6 +29,7 @@ Notes:
|
|||
#include"bound_manager.h"
|
||||
#include"used_vars.h"
|
||||
#include"var_subst.h"
|
||||
#include"gparams.h"
|
||||
|
||||
#ifndef _EXTERNAL_RELEASE
|
||||
|
||||
|
@ -271,7 +272,7 @@ UNARY_CMD(elim_unused_vars_cmd, "dbg-elim-unused-vars", "<expr>", "eliminate unu
|
|||
return;
|
||||
}
|
||||
expr_ref r(ctx.m());
|
||||
elim_unused_vars(ctx.m(), to_quantifier(arg), r);
|
||||
elim_unused_vars(ctx.m(), to_quantifier(arg), gparams::get(), r);
|
||||
SASSERT(!is_quantifier(r) || !to_quantifier(r)->may_have_unused_vars());
|
||||
ctx.display(ctx.regular_stream(), r);
|
||||
ctx.regular_stream() << std::endl;
|
||||
|
|
|
@ -348,7 +348,7 @@ namespace Duality {
|
|||
|
||||
|
||||
expr expr::qe_lite() const {
|
||||
::qe_lite qe(m());
|
||||
::qe_lite qe(m(), params_ref());
|
||||
expr_ref result(to_expr(raw()),m());
|
||||
proof_ref pf(m());
|
||||
qe(result,pf);
|
||||
|
@ -356,7 +356,7 @@ namespace Duality {
|
|||
}
|
||||
|
||||
expr expr::qe_lite(const std::set<int> &idxs, bool index_of_bound) const {
|
||||
::qe_lite qe(m());
|
||||
::qe_lite qe(m(), params_ref());
|
||||
expr_ref result(to_expr(raw()),m());
|
||||
proof_ref pf(m());
|
||||
uint_set uis;
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace datalog {
|
|||
m_head(m),
|
||||
m_args(m),
|
||||
m_hnf(m),
|
||||
m_qe(m),
|
||||
m_qe(m, params_ref()),
|
||||
m_rwr(m),
|
||||
m_ufproc(m) {}
|
||||
|
||||
|
|
|
@ -2241,7 +2241,7 @@ namespace pdr {
|
|||
vars.append(aux_vars.size(), aux_vars.c_ptr());
|
||||
|
||||
scoped_ptr<expr_replacer> rep;
|
||||
qe_lite qe(m);
|
||||
qe_lite qe(m, m_params.p);
|
||||
expr_ref phi1 = m_pm.mk_and(Phi);
|
||||
qe(vars, phi1);
|
||||
TRACE("pdr", tout << "Eliminated\n" << mk_pp(phi1, m) << "\n";);
|
||||
|
|
|
@ -520,7 +520,7 @@ namespace tb {
|
|||
m_matcher(m),
|
||||
m_refs(m),
|
||||
m_subst(m),
|
||||
m_qe(m),
|
||||
m_qe(m, params_ref()),
|
||||
m_rw(m),
|
||||
m_solver(m, m_fparams) {}
|
||||
|
||||
|
@ -1067,7 +1067,7 @@ namespace tb {
|
|||
}
|
||||
|
||||
bool unify(clause const& tgt, unsigned idx, clause const& src, bool compute_subst, ref<clause>& result) {
|
||||
qe_lite qe(m);
|
||||
qe_lite qe(m, params_ref());
|
||||
reset();
|
||||
SASSERT(tgt.get_predicate(idx)->get_decl() == src.get_decl());
|
||||
unsigned var_cnt = std::max(tgt.get_num_vars(), src.get_num_vars());
|
||||
|
|
|
@ -5,6 +5,8 @@ def_module_params('opt',
|
|||
('maxsat_engine', SYMBOL, 'maxres', "select engine for maxsat: 'core_maxsat', 'wmax', 'maxres', 'pd-maxres'"),
|
||||
('priority', SYMBOL, 'lex', "select how to priortize objectives: 'lex' (lexicographic), 'pareto', or 'box'"),
|
||||
('dump_benchmarks', BOOL, False, 'dump benchmarks for profiling'),
|
||||
('timeout', UINT, UINT_MAX, 'timeout (in milliseconds) (UINT_MAX and 0 mean no timeout)'),
|
||||
('rlimit', UINT, 0, 'resource limit (0 means no limit)'),
|
||||
('print_model', BOOL, False, 'display model for satisfiable constraints'),
|
||||
('enable_sls', BOOL, False, 'enable SLS tuning during weighted maxsast'),
|
||||
('enable_sat', BOOL, True, 'enable the new SAT core for propositional constraints'),
|
||||
|
|
|
@ -91,6 +91,7 @@ namespace eq {
|
|||
expr_ref_vector m_subst_map;
|
||||
expr_ref_buffer m_new_args;
|
||||
th_rewriter m_rewriter;
|
||||
params_ref m_params;
|
||||
|
||||
void der_sort_vars(ptr_vector<var> & vars, ptr_vector<expr> & definitions, unsigned_vector & order) {
|
||||
order.reset();
|
||||
|
@ -563,7 +564,8 @@ namespace eq {
|
|||
void elim_unused_vars(expr_ref& r, proof_ref &pr) {
|
||||
if (is_quantifier(r)) {
|
||||
quantifier * q = to_quantifier(r);
|
||||
::elim_unused_vars(m, q, r);
|
||||
|
||||
::elim_unused_vars(m, q, m_params, r);
|
||||
if (m.proofs_enabled()) {
|
||||
proof * p1 = m.mk_elim_unused_vars(q, r);
|
||||
pr = m.mk_transitivity(pr, p1);
|
||||
|
@ -744,7 +746,7 @@ namespace eq {
|
|||
}
|
||||
|
||||
public:
|
||||
der(ast_manager & m):
|
||||
der(ast_manager & m, params_ref const & p):
|
||||
m(m),
|
||||
a(m),
|
||||
dt(m),
|
||||
|
@ -753,7 +755,8 @@ namespace eq {
|
|||
m_new_exprs(m),
|
||||
m_subst_map(m),
|
||||
m_new_args(m),
|
||||
m_rewriter(m) {}
|
||||
m_rewriter(m),
|
||||
m_params(p) {}
|
||||
|
||||
void set_is_variable_proc(is_variable_proc& proc) { m_is_variable = &proc;}
|
||||
|
||||
|
@ -2346,9 +2349,9 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
impl(ast_manager& m):
|
||||
impl(ast_manager & m, params_ref const & p):
|
||||
m(m),
|
||||
m_der(m),
|
||||
m_der(m, p),
|
||||
m_fm(m),
|
||||
m_array_der(m),
|
||||
m_elim_star(*this),
|
||||
|
@ -2438,8 +2441,8 @@ public:
|
|||
|
||||
};
|
||||
|
||||
qe_lite::qe_lite(ast_manager& m) {
|
||||
m_impl = alloc(impl, m);
|
||||
qe_lite::qe_lite(ast_manager & m, params_ref const & p) {
|
||||
m_impl = alloc(impl, m, p);
|
||||
}
|
||||
|
||||
qe_lite::~qe_lite() {
|
||||
|
@ -2471,7 +2474,7 @@ class qe_lite_tactic : public tactic {
|
|||
|
||||
imp(ast_manager& m, params_ref const & p):
|
||||
m(m),
|
||||
m_qe(m)
|
||||
m_qe(m, p)
|
||||
{}
|
||||
|
||||
void checkpoint() {
|
||||
|
|
|
@ -31,7 +31,7 @@ class qe_lite {
|
|||
class impl;
|
||||
impl * m_impl;
|
||||
public:
|
||||
qe_lite(ast_manager& m);
|
||||
qe_lite(ast_manager & m, params_ref const & p);
|
||||
|
||||
~qe_lite();
|
||||
|
||||
|
|
|
@ -154,6 +154,8 @@ namespace sat {
|
|||
if (!m_subsumption && !m_elim_blocked_clauses && !m_resolution)
|
||||
return;
|
||||
|
||||
// solver::scoped_disable_checkpoint _scoped_disable_checkpoint(s);
|
||||
|
||||
initialize();
|
||||
|
||||
CASSERT("sat_solver", s.check_invariant());
|
||||
|
@ -167,7 +169,6 @@ namespace sat {
|
|||
CASSERT("sat_solver", s.check_invariant());
|
||||
m_need_cleanup = false;
|
||||
m_use_list.init(s.num_vars());
|
||||
init_visited();
|
||||
m_learned_in_use_lists = false;
|
||||
if (learned) {
|
||||
register_clauses(s.m_learned);
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace sat {
|
|||
|
||||
solver::solver(params_ref const & p, reslimit& l, extension * ext):
|
||||
m_rlimit(l),
|
||||
m_checkpoint_enabled(true),
|
||||
m_config(p),
|
||||
m_ext(ext),
|
||||
m_par(0),
|
||||
|
|
|
@ -72,6 +72,7 @@ namespace sat {
|
|||
struct abort_solver {};
|
||||
protected:
|
||||
reslimit& m_rlimit;
|
||||
bool m_checkpoint_enabled;
|
||||
config m_config;
|
||||
stats m_stats;
|
||||
extension * m_ext;
|
||||
|
@ -214,6 +215,16 @@ namespace sat {
|
|||
}
|
||||
}
|
||||
};
|
||||
class scoped_disable_checkpoint {
|
||||
solver& s;
|
||||
public:
|
||||
scoped_disable_checkpoint(solver& s): s(s) {
|
||||
s.m_checkpoint_enabled = false;
|
||||
}
|
||||
~scoped_disable_checkpoint() {
|
||||
s.m_checkpoint_enabled = true;
|
||||
}
|
||||
};
|
||||
unsigned select_watch_lit(clause const & cls, unsigned starting_at) const;
|
||||
unsigned select_learned_watch_lit(clause const & cls) const;
|
||||
bool simplify_clause(unsigned & num_lits, literal * lits) const;
|
||||
|
@ -257,6 +268,7 @@ namespace sat {
|
|||
lbool status(clause const & c) const;
|
||||
clause_offset get_offset(clause const & c) const { return m_cls_allocator.get_offset(&c); }
|
||||
void checkpoint() {
|
||||
if (!m_checkpoint_enabled) return;
|
||||
if (!m_rlimit.inc()) {
|
||||
m_mc.reset();
|
||||
m_model_is_current = false;
|
||||
|
|
|
@ -64,5 +64,6 @@ def_module_params(module_name='smt',
|
|||
('core.validate', BOOL, False, 'validate 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'),
|
||||
('core.extend_patterns.max_distance', UINT, UINT_MAX, 'limits the distance of a pattern-extended unsat core')
|
||||
('core.extend_patterns.max_distance', UINT, UINT_MAX, 'limits the distance of a pattern-extended unsat core'),
|
||||
('core.extend_nonlocal_patterns', BOOL, False, 'extend unsat cores with literals that have quantifiers with patterns that contain symbols which are not in the quantifier\'s body')
|
||||
))
|
||||
|
|
|
@ -3072,11 +3072,11 @@ namespace smt {
|
|||
m_assumptions.reset();
|
||||
}
|
||||
|
||||
void context::mk_unsat_core() {
|
||||
lbool context::mk_unsat_core() {
|
||||
SASSERT(inconsistent());
|
||||
if (!tracking_assumptions()) {
|
||||
SASSERT(m_assumptions.empty());
|
||||
return;
|
||||
return l_false;
|
||||
}
|
||||
uint_set already_found_assumptions;
|
||||
literal_vector::const_iterator it = m_conflict_resolution->begin_unsat_core();
|
||||
|
@ -3102,6 +3102,16 @@ namespace smt {
|
|||
tout << mk_pp(m_unsat_core.get(i), m_manager) << "\n";
|
||||
});
|
||||
validate_unsat_core();
|
||||
// theory validation of unsat core
|
||||
ptr_vector<theory>::iterator th_it = m_theory_set.begin();
|
||||
ptr_vector<theory>::iterator th_end = m_theory_set.end();
|
||||
for (; th_it != th_end; ++th_it) {
|
||||
lbool theory_result = (*th_it)->validate_unsat_core(m_unsat_core);
|
||||
if (theory_result == l_undef) {
|
||||
return l_undef;
|
||||
}
|
||||
}
|
||||
return l_false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3144,6 +3154,14 @@ namespace smt {
|
|||
SASSERT(m_scope_lvl == 0);
|
||||
SASSERT(!m_setup.already_configured());
|
||||
setup_context(m_fparams.m_auto_config);
|
||||
|
||||
expr_ref_vector theory_assumptions(m_manager);
|
||||
add_theory_assumptions(theory_assumptions);
|
||||
if (!theory_assumptions.empty()) {
|
||||
TRACE("search", tout << "Adding theory assumptions to context" << std::endl;);
|
||||
return check(theory_assumptions.size(), theory_assumptions.c_ptr(), reset_cancel, true);
|
||||
}
|
||||
|
||||
internalize_assertions();
|
||||
lbool r = l_undef;
|
||||
if (m_asserted_formulas.inconsistent()) {
|
||||
|
@ -3205,7 +3223,15 @@ namespace smt {
|
|||
(*it)->setup();
|
||||
}
|
||||
|
||||
lbool context::check(unsigned num_assumptions, expr * const * assumptions, bool reset_cancel) {
|
||||
void context::add_theory_assumptions(expr_ref_vector & theory_assumptions) {
|
||||
ptr_vector<theory>::iterator it = m_theory_set.begin();
|
||||
ptr_vector<theory>::iterator end = m_theory_set.end();
|
||||
for (; it != end; ++it) {
|
||||
(*it)->add_theory_assumptions(theory_assumptions);
|
||||
}
|
||||
}
|
||||
|
||||
lbool context::check(unsigned ext_num_assumptions, expr * const * ext_assumptions, bool reset_cancel, bool already_did_theory_assumptions) {
|
||||
m_stats.m_num_checks++;
|
||||
TRACE("check_bug", tout << "STARTING check(num_assumptions, assumptions)\n";
|
||||
tout << "inconsistent: " << inconsistent() << ", m_unsat_core.empty(): " << m_unsat_core.empty() << "\n";
|
||||
|
@ -3216,6 +3242,15 @@ namespace smt {
|
|||
m_unsat_core.reset();
|
||||
if (!check_preamble(reset_cancel))
|
||||
return l_undef;
|
||||
|
||||
expr_ref_vector all_assumptions(m_manager, ext_num_assumptions, ext_assumptions);
|
||||
if (!already_did_theory_assumptions) {
|
||||
add_theory_assumptions(all_assumptions);
|
||||
}
|
||||
|
||||
unsigned num_assumptions = all_assumptions.size();
|
||||
expr * const * assumptions = all_assumptions.c_ptr();
|
||||
|
||||
if (!validate_assumptions(num_assumptions, assumptions))
|
||||
return l_undef;
|
||||
TRACE("check_bug", tout << "inconsistent: " << inconsistent() << ", m_unsat_core.empty(): " << m_unsat_core.empty() << "\n";);
|
||||
|
@ -3239,13 +3274,21 @@ namespace smt {
|
|||
TRACE("after_internalization", display(tout););
|
||||
if (inconsistent()) {
|
||||
VERIFY(!resolve_conflict()); // build the proof
|
||||
mk_unsat_core();
|
||||
lbool result = mk_unsat_core();
|
||||
if (result == l_undef) {
|
||||
r = l_undef;
|
||||
} else {
|
||||
r = l_false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
r = search();
|
||||
if (r == l_false)
|
||||
mk_unsat_core();
|
||||
if (r == l_false) {
|
||||
lbool result = mk_unsat_core();
|
||||
if (result == l_undef) {
|
||||
r = l_undef;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1059,7 +1059,9 @@ namespace smt {
|
|||
|
||||
void reset_assumptions();
|
||||
|
||||
void mk_unsat_core();
|
||||
void add_theory_assumptions(expr_ref_vector & theory_assumptions);
|
||||
|
||||
lbool mk_unsat_core();
|
||||
|
||||
void validate_unsat_core();
|
||||
|
||||
|
@ -1444,7 +1446,7 @@ 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, bool already_did_theory_assumptions = false);
|
||||
|
||||
lbool get_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars, expr_ref_vector& conseq, expr_ref_vector& unfixed);
|
||||
|
||||
|
|
|
@ -433,6 +433,9 @@ namespace smt {
|
|||
if (!is_ground(n)) {
|
||||
continue;
|
||||
}
|
||||
if (is_quantifier(n) && m.is_rec_fun_def(to_quantifier(n))) {
|
||||
continue;
|
||||
}
|
||||
switch (get_assignment(*it)) {
|
||||
case l_undef:
|
||||
break;
|
||||
|
|
|
@ -246,6 +246,7 @@ namespace smt {
|
|||
|
||||
simple_justification::simple_justification(region & r, unsigned num_lits, literal const * lits):
|
||||
m_num_literals(num_lits) {
|
||||
if (num_lits != 0) {
|
||||
m_literals = new (r) literal[num_lits];
|
||||
memcpy(m_literals, lits, sizeof(literal) * num_lits);
|
||||
#ifdef Z3DEBUG
|
||||
|
@ -254,6 +255,7 @@ namespace smt {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void simple_justification::get_antecedents(conflict_resolution & cr) {
|
||||
for (unsigned i = 0; i < m_num_literals; i++)
|
||||
|
|
|
@ -316,7 +316,7 @@ namespace smt {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool model_checker::check_rec_fun(quantifier* q) {
|
||||
bool model_checker::check_rec_fun(quantifier* q, bool strict_rec_fun) {
|
||||
TRACE("model_checker", tout << mk_pp(q, m) << "\n";);
|
||||
SASSERT(q->get_num_patterns() == 2); // first pattern is the function, second is the body.
|
||||
expr* fn = to_app(q->get_pattern(0))->get_arg(0);
|
||||
|
@ -340,7 +340,7 @@ namespace smt {
|
|||
}
|
||||
sub(q->get_expr(), num_decls, args.c_ptr(), tmp);
|
||||
m_curr_model->eval(tmp, result, true);
|
||||
if (m.is_false(result)) {
|
||||
if (strict_rec_fun ? !m.is_true(result) : m.is_false(result)) {
|
||||
add_instance(q, args, 0);
|
||||
return false;
|
||||
}
|
||||
|
@ -365,10 +365,10 @@ namespace smt {
|
|||
|
||||
bool model_checker::check(proto_model * md, obj_map<enode, app *> const & root2value) {
|
||||
SASSERT(md != 0);
|
||||
|
||||
m_root2value = &root2value;
|
||||
ptr_vector<quantifier>::const_iterator it = m_qm->begin_quantifiers();
|
||||
ptr_vector<quantifier>::const_iterator end = m_qm->end_quantifiers();
|
||||
if (it == end)
|
||||
|
||||
if (m_qm->num_quantifiers() == 0)
|
||||
return true;
|
||||
|
||||
if (m_iteration_idx >= m_params.m_mbqi_max_iterations) {
|
||||
|
@ -393,6 +393,36 @@ namespace smt {
|
|||
bool found_relevant = false;
|
||||
unsigned num_failures = 0;
|
||||
|
||||
check_quantifiers(false, found_relevant, num_failures);
|
||||
|
||||
|
||||
if (found_relevant)
|
||||
m_iteration_idx++;
|
||||
|
||||
TRACE("model_checker", tout << "model after check:\n"; model_pp(tout, *md););
|
||||
TRACE("model_checker", tout << "model checker result: " << (num_failures == 0) << "\n";);
|
||||
m_max_cexs += m_params.m_mbqi_max_cexs;
|
||||
|
||||
if (num_failures == 0 && !m_context->validate_model()) {
|
||||
num_failures = 1;
|
||||
// this time force expanding recursive function definitions
|
||||
// that are not forced true in the current model.
|
||||
check_quantifiers(true, found_relevant, num_failures);
|
||||
}
|
||||
if (num_failures == 0)
|
||||
m_curr_model->cleanup();
|
||||
if (m_params.m_mbqi_trace) {
|
||||
if (num_failures == 0)
|
||||
verbose_stream() << "(smt.mbqi :succeeded true)\n";
|
||||
else
|
||||
verbose_stream() << "(smt.mbqi :num-failures " << num_failures << ")\n";
|
||||
}
|
||||
return num_failures == 0;
|
||||
}
|
||||
|
||||
void model_checker::check_quantifiers(bool strict_rec_fun, bool& found_relevant, unsigned& num_failures) {
|
||||
ptr_vector<quantifier>::const_iterator it = m_qm->begin_quantifiers();
|
||||
ptr_vector<quantifier>::const_iterator end = m_qm->end_quantifiers();
|
||||
for (; it != end; ++it) {
|
||||
quantifier * q = *it;
|
||||
if(!m_qm->mbqi_enabled(q)) continue;
|
||||
|
@ -406,7 +436,7 @@ namespace smt {
|
|||
}
|
||||
found_relevant = true;
|
||||
if (m.is_rec_fun_def(q)) {
|
||||
if (!check_rec_fun(q)) {
|
||||
if (!check_rec_fun(q, strict_rec_fun)) {
|
||||
TRACE("model_checker", tout << "checking recursive function failed\n";);
|
||||
num_failures++;
|
||||
}
|
||||
|
@ -420,26 +450,6 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found_relevant)
|
||||
m_iteration_idx++;
|
||||
|
||||
TRACE("model_checker", tout << "model after check:\n"; model_pp(tout, *md););
|
||||
TRACE("model_checker", tout << "model checker result: " << (num_failures == 0) << "\n";);
|
||||
m_max_cexs += m_params.m_mbqi_max_cexs;
|
||||
|
||||
if (num_failures == 0 && !m_context->validate_model()) {
|
||||
num_failures = 1;
|
||||
}
|
||||
if (num_failures == 0)
|
||||
m_curr_model->cleanup();
|
||||
if (m_params.m_mbqi_trace) {
|
||||
if (num_failures == 0)
|
||||
verbose_stream() << "(smt.mbqi :succeeded true)\n";
|
||||
else
|
||||
verbose_stream() << "(smt.mbqi :num-failures " << num_failures << ")\n";
|
||||
}
|
||||
return num_failures == 0;
|
||||
}
|
||||
|
||||
void model_checker::init_search_eh() {
|
||||
|
|
|
@ -59,7 +59,8 @@ namespace smt {
|
|||
void assert_neg_q_m(quantifier * q, expr_ref_vector & sks);
|
||||
bool add_blocking_clause(model * cex, expr_ref_vector & sks);
|
||||
bool check(quantifier * q);
|
||||
bool check_rec_fun(quantifier* q);
|
||||
bool check_rec_fun(quantifier* q, bool strict_rec_fun);
|
||||
void check_quantifiers(bool strict_rec_fun, bool& found_relevant, unsigned& num_failures);
|
||||
|
||||
struct instance {
|
||||
quantifier * m_q;
|
||||
|
|
|
@ -397,6 +397,10 @@ namespace smt {
|
|||
return m_imp->m_quantifiers.end();
|
||||
}
|
||||
|
||||
unsigned quantifier_manager::num_quantifiers() const {
|
||||
return m_imp->m_quantifiers.size();
|
||||
}
|
||||
|
||||
// The default plugin uses E-matching, MBQI and quick-checker
|
||||
class default_qm_plugin : public quantifier_manager_plugin {
|
||||
quantifier_manager * m_qm;
|
||||
|
|
|
@ -91,6 +91,8 @@ namespace smt {
|
|||
|
||||
ptr_vector<quantifier>::const_iterator begin_quantifiers() const;
|
||||
ptr_vector<quantifier>::const_iterator end_quantifiers() const;
|
||||
unsigned num_quantifiers() const;
|
||||
|
||||
};
|
||||
|
||||
class quantifier_manager_plugin {
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace smt {
|
|||
bool m_minimizing_core;
|
||||
bool m_core_extend_patterns;
|
||||
unsigned m_core_extend_patterns_max_distance;
|
||||
bool m_core_extend_nonlocal_patterns;
|
||||
obj_map<expr, expr*> m_name2assertion;
|
||||
|
||||
public:
|
||||
|
@ -48,13 +49,15 @@ namespace smt {
|
|||
m_context(m, m_smt_params),
|
||||
m_minimizing_core(false),
|
||||
m_core_extend_patterns(false),
|
||||
m_core_extend_patterns_max_distance(UINT_MAX) {
|
||||
m_core_extend_patterns_max_distance(UINT_MAX),
|
||||
m_core_extend_nonlocal_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();
|
||||
m_core_extend_patterns_max_distance = smth.core_extend_patterns_max_distance();
|
||||
m_core_extend_nonlocal_patterns = smth.core_extend_nonlocal_patterns();
|
||||
}
|
||||
|
||||
virtual solver * translate(ast_manager & m, params_ref const & p) {
|
||||
|
@ -81,6 +84,8 @@ namespace smt {
|
|||
m_context.updt_params(p);
|
||||
smt_params_helper smth(p);
|
||||
m_core_extend_patterns = smth.core_extend_patterns();
|
||||
m_core_extend_patterns_max_distance = smth.core_extend_patterns_max_distance();
|
||||
m_core_extend_nonlocal_patterns = smth.core_extend_nonlocal_patterns();
|
||||
}
|
||||
|
||||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
|
@ -172,6 +177,8 @@ namespace smt {
|
|||
|
||||
if (m_core_extend_patterns)
|
||||
add_pattern_literals_to_core(r);
|
||||
if (m_core_extend_nonlocal_patterns)
|
||||
add_nonlocal_pattern_literals_to_core(r);
|
||||
}
|
||||
|
||||
virtual void get_model(model_ref & m) {
|
||||
|
@ -250,7 +257,7 @@ namespace smt {
|
|||
}
|
||||
};
|
||||
|
||||
void collect_pattern_func_decls(expr_ref & e, func_decl_set & fds) {
|
||||
void collect_pattern_fds(expr_ref & e, func_decl_set & fds) {
|
||||
collect_pattern_fds_proc p(get_manager(), fds);
|
||||
expr_mark visited;
|
||||
for_each_expr(p, visited, e);
|
||||
|
@ -295,7 +302,7 @@ namespace smt {
|
|||
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);
|
||||
collect_pattern_fds(assrtn, pattern_fds);
|
||||
}
|
||||
|
||||
if (!pattern_fds.empty()) {
|
||||
|
@ -317,6 +324,55 @@ namespace smt {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct collect_body_fds_proc {
|
||||
ast_manager & m;
|
||||
func_decl_set & m_fds;
|
||||
collect_body_fds_proc(ast_manager & m, func_decl_set & fds) :
|
||||
m(m), m_fds(fds) {
|
||||
}
|
||||
void operator()(var * n) {}
|
||||
void operator()(app * n) {}
|
||||
void operator()(quantifier * n) {
|
||||
collect_fds_proc p(m, m_fds);
|
||||
expr_fast_mark1 visited;
|
||||
quick_for_each_expr(p, visited, n->get_expr());
|
||||
}
|
||||
};
|
||||
|
||||
void collect_body_func_decls(expr_ref & e, func_decl_set & fds) {
|
||||
ast_manager & m = get_manager();
|
||||
collect_body_fds_proc p(m, fds);
|
||||
expr_mark visited;
|
||||
for_each_expr(p, visited, e);
|
||||
}
|
||||
|
||||
void add_nonlocal_pattern_literals_to_core(ptr_vector<expr> & core) {
|
||||
ast_manager & m = get_manager();
|
||||
|
||||
obj_map<expr, expr*>::iterator it = m_name2assertion.begin();
|
||||
obj_map<expr, expr*>::iterator end = m_name2assertion.end();
|
||||
for (unsigned i = 0; it != end; it++, i++) {
|
||||
expr_ref name(it->m_key, m);
|
||||
expr_ref assrtn(it->m_value, m);
|
||||
|
||||
if (!core.contains(name)) {
|
||||
func_decl_set pattern_fds, body_fds;
|
||||
collect_pattern_fds(assrtn, pattern_fds);
|
||||
collect_body_func_decls(assrtn, body_fds);
|
||||
|
||||
func_decl_set::iterator pit = pattern_fds.begin();
|
||||
func_decl_set::iterator pend= pattern_fds.end();
|
||||
for (; pit != pend; pit++) {
|
||||
func_decl * fd = *pit;
|
||||
if (!body_fds.contains(fd)) {
|
||||
core.insert(name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -177,6 +177,22 @@ namespace smt {
|
|||
virtual void restart_eh() {
|
||||
}
|
||||
|
||||
/**
|
||||
\brief This method is called by smt_context before the search starts
|
||||
to get any extra assumptions the theory wants to use.
|
||||
(See theory_str for an example)
|
||||
*/
|
||||
virtual void add_theory_assumptions(expr_ref_vector & assumptions) {
|
||||
}
|
||||
|
||||
/**
|
||||
\brief This method is called from smt_context when an unsat core is generated.
|
||||
The theory may change the answer to UNKNOWN by returning l_undef from this method.
|
||||
*/
|
||||
virtual lbool validate_unsat_core(expr_ref_vector & unsat_core) {
|
||||
return l_false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief This method is invoked before the search starts.
|
||||
*/
|
||||
|
|
|
@ -339,8 +339,13 @@ namespace smt {
|
|||
tout << mk_pp(var, get_manager()) << "\n";
|
||||
tout << "power " << power << ": " << expt(i, power) << "\n";
|
||||
display_interval(tout << "target before: ", target); tout << "\n";);
|
||||
|
||||
i.expt(power);
|
||||
target *= i;
|
||||
|
||||
get_manager().limit().inc((target.is_lower_open() || target.minus_infinity()) ? 1 : target.get_lower_value().bitsize());
|
||||
get_manager().limit().inc((target.is_upper_open() || target.plus_infinity()) ? 1 : target.get_upper_value().bitsize());
|
||||
|
||||
TRACE("non_linear", display_interval(tout << "target after: ", target); tout << "\n";);
|
||||
}
|
||||
|
||||
|
|
|
@ -255,6 +255,11 @@ final_check_status theory_seq::final_check_eh() {
|
|||
TRACE("seq", tout << ">>solve_eqs\n";);
|
||||
return FC_CONTINUE;
|
||||
}
|
||||
if (check_contains()) {
|
||||
++m_stats.m_propagate_contains;
|
||||
TRACE("seq", tout << ">>propagate_contains\n";);
|
||||
return FC_CONTINUE;
|
||||
}
|
||||
if (solve_nqs(0)) {
|
||||
++m_stats.m_solve_nqs;
|
||||
TRACE("seq", tout << ">>solve_nqs\n";);
|
||||
|
@ -290,11 +295,6 @@ final_check_status theory_seq::final_check_eh() {
|
|||
TRACE("seq", tout << ">>propagate_automata\n";);
|
||||
return FC_CONTINUE;
|
||||
}
|
||||
if (check_contains()) {
|
||||
++m_stats.m_propagate_contains;
|
||||
TRACE("seq", tout << ">>propagate_contains\n";);
|
||||
return FC_CONTINUE;
|
||||
}
|
||||
if (is_solved()) {
|
||||
TRACE("seq", tout << ">>is_solved\n";);
|
||||
return FC_DONE;
|
||||
|
@ -1159,7 +1159,7 @@ bool theory_seq::check_extensionality() {
|
|||
}
|
||||
|
||||
/*
|
||||
\brief check negated contains constriants.
|
||||
\brief check negated contains constraints.
|
||||
*/
|
||||
bool theory_seq::check_contains() {
|
||||
context & ctx = get_context();
|
||||
|
@ -1199,6 +1199,11 @@ bool theory_seq::is_solved() {
|
|||
IF_VERBOSE(10, display_disequation(verbose_stream() << "(seq.giveup ", m_nqs[0]); verbose_stream() << " is unsolved)\n";);
|
||||
return false;
|
||||
}
|
||||
if (!m_ncs.empty()) {
|
||||
TRACE("seq", display_nc(tout << "(seq.giveup ", m_ncs[0]); tout << " is unsolved)\n";);
|
||||
IF_VERBOSE(10, display_nc(verbose_stream() << "(seq.giveup ", m_ncs[0]); verbose_stream() << " is unsolved)\n";);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1984,6 +1989,22 @@ bool theory_seq::solve_nc(unsigned idx) {
|
|||
m_new_propagation = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
expr* e1, *e2;
|
||||
if (m.is_eq(c, e1, e2)) {
|
||||
literal eq = mk_eq(e1, e2, false);
|
||||
propagate_lit(deps, 0, 0, ~eq);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m.is_or(c)) {
|
||||
for (unsigned i = 0; i < to_app(c)->get_num_args(); ++i) {
|
||||
expr_ref ci(to_app(c)->get_arg(i), m);
|
||||
m_ncs.push_back(nc(ci, deps));
|
||||
}
|
||||
m_new_propagation = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2345,6 +2366,17 @@ bool theory_seq::add_itos_axiom(expr* e) {
|
|||
return false;
|
||||
}
|
||||
add_axiom(mk_eq(e2, n, false));
|
||||
|
||||
#if 1
|
||||
expr_ref num_re(m), opt_re(m);
|
||||
num_re = m_util.re.mk_range(m_util.str.mk_string(symbol("0")), m_util.str.mk_string(symbol("9")));
|
||||
num_re = m_util.re.mk_plus(num_re);
|
||||
opt_re = m_util.re.mk_opt(m_util.re.mk_to_re(m_util.str.mk_string(symbol("-"))));
|
||||
num_re = m_util.re.mk_concat(opt_re, num_re);
|
||||
app_ref in_re(m_util.re.mk_in_re(e, num_re), m);
|
||||
internalize_term(in_re);
|
||||
propagate_in_re(in_re, true);
|
||||
#endif
|
||||
m_trail_stack.push(push_replay(alloc(replay_axiom, m, e)));
|
||||
return true;
|
||||
}
|
||||
|
@ -2407,13 +2439,17 @@ void theory_seq::display(std::ostream & out) const {
|
|||
if (!m_ncs.empty()) {
|
||||
out << "Non contains:\n";
|
||||
for (unsigned i = 0; i < m_ncs.size(); ++i) {
|
||||
out << "not " << mk_pp(m_ncs[i].contains(), m) << "\n";
|
||||
display_deps(out << " <- ", m_ncs[i].deps()); out << "\n";
|
||||
display_nc(out, m_ncs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void theory_seq::display_nc(std::ostream& out, nc const& nc) const {
|
||||
out << "not " << mk_pp(nc.contains(), m) << "\n";
|
||||
display_deps(out << " <- ", nc.deps()); out << "\n";
|
||||
}
|
||||
|
||||
void theory_seq::display_equations(std::ostream& out) const {
|
||||
for (unsigned i = 0; i < m_eqs.size(); ++i) {
|
||||
display_equation(out, m_eqs[i]);
|
||||
|
|
|
@ -570,6 +570,7 @@ namespace smt {
|
|||
void display_disequation(std::ostream& out, ne const& e) const;
|
||||
void display_deps(std::ostream& out, dependency* deps) const;
|
||||
void display_deps(std::ostream& out, literal_vector const& lits, enode_pair_vector const& eqs) const;
|
||||
void display_nc(std::ostream& out, nc const& nc) const;
|
||||
public:
|
||||
theory_seq(ast_manager& m);
|
||||
virtual ~theory_seq();
|
||||
|
|
|
@ -34,6 +34,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
|
||||
struct rw_cfg : public default_rewriter_cfg {
|
||||
ast_manager & m;
|
||||
params_ref m_params;
|
||||
bv_util m_util;
|
||||
simplifier m_simp;
|
||||
ref<filter_model_converter> m_mc;
|
||||
|
@ -47,6 +48,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
|
||||
rw_cfg(ast_manager & _m, params_ref const & p) :
|
||||
m(_m),
|
||||
m_params(p),
|
||||
m_util(_m),
|
||||
m_simp(_m),
|
||||
m_bindings(_m),
|
||||
|
@ -178,7 +180,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
|
||||
quantifier_ref new_q(m);
|
||||
new_q = m.update_quantifier(q, body);
|
||||
unused_vars_eliminator el(m);
|
||||
unused_vars_eliminator el(m, m_params);
|
||||
el(new_q, result);
|
||||
|
||||
TRACE("elim_small_bv", tout << "elimination result: " << mk_ismt2_pp(result, m) << std::endl; );
|
||||
|
@ -203,6 +205,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_params = p;
|
||||
m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
|
||||
m_max_steps = p.get_uint("max_steps", UINT_MAX);
|
||||
m_max_bits = p.get_uint("max_bits", 4);
|
||||
|
|
|
@ -50,7 +50,7 @@ class distribute_forall_tactic : public tactic {
|
|||
quantifier_ref tmp_q(m);
|
||||
tmp_q = m.update_quantifier(old_q, not_arg);
|
||||
expr_ref new_q(m);
|
||||
elim_unused_vars(m, tmp_q, new_q);
|
||||
elim_unused_vars(m, tmp_q, params_ref(), new_q);
|
||||
new_args.push_back(new_q);
|
||||
}
|
||||
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
||||
|
@ -70,7 +70,7 @@ class distribute_forall_tactic : public tactic {
|
|||
quantifier_ref tmp_q(m);
|
||||
tmp_q = m.update_quantifier(old_q, arg);
|
||||
expr_ref new_q(m);
|
||||
elim_unused_vars(m, tmp_q, new_q);
|
||||
elim_unused_vars(m, tmp_q, params_ref(), new_q);
|
||||
new_args.push_back(new_q);
|
||||
}
|
||||
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
||||
|
|
|
@ -34,19 +34,19 @@ Notes:
|
|||
class bounded_int2bv_solver : public solver_na2as {
|
||||
ast_manager& m;
|
||||
params_ref m_params;
|
||||
bv_util m_bv;
|
||||
arith_util m_arith;
|
||||
expr_ref_vector m_assertions;
|
||||
mutable bv_util m_bv;
|
||||
mutable arith_util m_arith;
|
||||
mutable expr_ref_vector m_assertions;
|
||||
ref<solver> m_solver;
|
||||
ptr_vector<bound_manager> m_bounds;
|
||||
func_decl_ref_vector m_bv_fns;
|
||||
func_decl_ref_vector m_int_fns;
|
||||
mutable ptr_vector<bound_manager> m_bounds;
|
||||
mutable func_decl_ref_vector m_bv_fns;
|
||||
mutable func_decl_ref_vector m_int_fns;
|
||||
unsigned_vector m_bv_fns_lim;
|
||||
obj_map<func_decl, func_decl*> m_int2bv;
|
||||
obj_map<func_decl, func_decl*> m_bv2int;
|
||||
obj_map<func_decl, rational> m_bv2offset;
|
||||
bv2int_rewriter_ctx m_rewriter_ctx;
|
||||
bv2int_rewriter_star m_rewriter;
|
||||
mutable obj_map<func_decl, func_decl*> m_int2bv;
|
||||
mutable obj_map<func_decl, func_decl*> m_bv2int;
|
||||
mutable obj_map<func_decl, rational> m_bv2offset;
|
||||
mutable bv2int_rewriter_ctx m_rewriter_ctx;
|
||||
mutable bv2int_rewriter_star m_rewriter;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -78,7 +78,19 @@ public:
|
|||
}
|
||||
|
||||
virtual void assert_expr(expr * t) {
|
||||
unsigned i = m_assertions.size();
|
||||
m_assertions.push_back(t);
|
||||
while (i < m_assertions.size()) {
|
||||
t = m_assertions[i].get();
|
||||
if (m.is_and(t)) {
|
||||
m_assertions.append(to_app(t)->get_num_args(), to_app(t)->get_args());
|
||||
m_assertions[i] = m_assertions.back();
|
||||
m_assertions.pop_back();
|
||||
}
|
||||
else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void push_core() {
|
||||
|
@ -184,7 +196,7 @@ private:
|
|||
}
|
||||
filter_model_converter filter(m);
|
||||
for (unsigned i = 0; i < m_bv_fns.size(); ++i) {
|
||||
filter.insert(m_bv_fns[i]);
|
||||
filter.insert(m_bv_fns[i].get());
|
||||
}
|
||||
filter(mdl, 0);
|
||||
}
|
||||
|
@ -205,13 +217,13 @@ private:
|
|||
ext(mdl, 0);
|
||||
}
|
||||
|
||||
void accumulate_sub(expr_safe_replace& sub) {
|
||||
void accumulate_sub(expr_safe_replace& sub) const {
|
||||
for (unsigned i = 0; i < m_bounds.size(); ++i) {
|
||||
accumulate_sub(sub, *m_bounds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void accumulate_sub(expr_safe_replace& sub, bound_manager& bm) {
|
||||
void accumulate_sub(expr_safe_replace& sub, bound_manager& bm) const {
|
||||
bound_manager::iterator it = bm.begin(), end = bm.end();
|
||||
for (; it != end; ++it) {
|
||||
expr* e = *it;
|
||||
|
@ -252,19 +264,20 @@ private:
|
|||
sub.insert(e, t);
|
||||
}
|
||||
else {
|
||||
IF_VERBOSE(1,
|
||||
verbose_stream() << "unprocessed entry: " << mk_pp(e, m) << "\n";
|
||||
TRACE("pb",
|
||||
tout << "unprocessed entry: " << mk_pp(e, m) << "\n";
|
||||
if (bm.has_lower(e, lo, s1)) {
|
||||
verbose_stream() << "lower: " << lo << " " << s1 << "\n";
|
||||
tout << "lower: " << lo << " " << s1 << "\n";
|
||||
}
|
||||
if (bm.has_upper(e, hi, s2)) {
|
||||
verbose_stream() << "upper: " << hi << " " << s2 << "\n";
|
||||
tout << "upper: " << hi << " " << s2 << "\n";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned get_num_bits(rational const& k) {
|
||||
|
||||
unsigned get_num_bits(rational const& k) const {
|
||||
SASSERT(!k.is_neg());
|
||||
SASSERT(k.is_int());
|
||||
rational two(2);
|
||||
|
@ -277,11 +290,13 @@ private:
|
|||
return num_bits;
|
||||
}
|
||||
|
||||
void flush_assertions() {
|
||||
void flush_assertions() const {
|
||||
if (m_assertions.empty()) return;
|
||||
bound_manager& bm = *m_bounds.back();
|
||||
for (unsigned i = 0; i < m_assertions.size(); ++i) {
|
||||
bm(m_assertions[i].get());
|
||||
}
|
||||
TRACE("int2bv", bm.display(tout););
|
||||
expr_safe_replace sub(m);
|
||||
accumulate_sub(sub);
|
||||
proof_ref proof(m);
|
||||
|
@ -304,6 +319,17 @@ private:
|
|||
m_assertions.reset();
|
||||
m_rewriter.reset();
|
||||
}
|
||||
|
||||
virtual unsigned get_num_assertions() const {
|
||||
flush_assertions();
|
||||
return m_solver->get_num_assertions();
|
||||
}
|
||||
|
||||
virtual expr * get_assertion(unsigned idx) const {
|
||||
flush_assertions();
|
||||
return m_solver->get_assertion(idx);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
solver * mk_bounded_int2bv_solver(ast_manager & m, params_ref const & p, solver* s) {
|
||||
|
|
|
@ -163,6 +163,14 @@ public:
|
|||
ext(mdl, 0);
|
||||
}
|
||||
|
||||
virtual unsigned get_num_assertions() const {
|
||||
return m_solver->get_num_assertions();
|
||||
}
|
||||
|
||||
virtual expr * get_assertion(unsigned idx) const {
|
||||
return m_solver->get_assertion(idx);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
solver * mk_enum2bv_solver(ast_manager & m, params_ref const & p, solver* s) {
|
||||
|
|
|
@ -27,9 +27,9 @@ Notes:
|
|||
class pb2bv_solver : public solver_na2as {
|
||||
ast_manager& m;
|
||||
params_ref m_params;
|
||||
expr_ref_vector m_assertions;
|
||||
ref<solver> m_solver;
|
||||
pb2bv_rewriter m_rewriter;
|
||||
mutable expr_ref_vector m_assertions;
|
||||
mutable ref<solver> m_solver;
|
||||
mutable pb2bv_rewriter m_rewriter;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -107,8 +107,19 @@ public:
|
|||
filter(mdl, 0);
|
||||
}
|
||||
|
||||
virtual unsigned get_num_assertions() const {
|
||||
flush_assertions();
|
||||
return m_solver->get_num_assertions();
|
||||
}
|
||||
|
||||
virtual expr * get_assertion(unsigned idx) const {
|
||||
flush_assertions();
|
||||
return m_solver->get_assertion(idx);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void flush_assertions() {
|
||||
void flush_assertions() const {
|
||||
proof_ref proof(m);
|
||||
expr_ref fml(m);
|
||||
expr_ref_vector fmls(m);
|
||||
|
|
|
@ -417,7 +417,7 @@ expr * ufbv_rewriter::rewrite(expr * n) {
|
|||
q = m_manager.update_quantifier(to_quantifier(actual), new_body);
|
||||
m_new_exprs.push_back(q);
|
||||
expr_ref new_q(m_manager);
|
||||
elim_unused_vars(m_manager, q, new_q);
|
||||
elim_unused_vars(m_manager, q, params_ref(), new_q);
|
||||
m_new_exprs.push_back(new_q);
|
||||
rewrite_cache(e, new_q, true);
|
||||
m_rewrite_todo.pop_back();
|
||||
|
|
Loading…
Reference in a new issue