mirror of
https://github.com/Z3Prover/z3
synced 2025-04-14 12:58:44 +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
|
sudo make install
|
||||||
```
|
```
|
||||||
|
|
||||||
Note by default ``gcc`` is used as the C++ compiler if it is available. If you
|
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`` line to
|
would prefer to use Clang change the ``mk_make.py`` invocation to:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
CXX=clang++ CC=clang python scripts/mk_make.py
|
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;
|
lbool r = l_undef;
|
||||||
cancel_eh<reslimit> eh(mk_c(c)->m().limit());
|
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 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);
|
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||||
{
|
{
|
||||||
scoped_timer timer(timeout, &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 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_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(); }
|
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) {
|
check_result query(func_decl_vector& relations) {
|
||||||
array<Z3_func_decl> rs(relations);
|
array<Z3_func_decl> rs(relations);
|
||||||
Z3_lbool r = Z3_fixedpoint_query_relations(ctx(), m_fp, rs.size(), rs.ptr());
|
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.
|
* Create the empty sequence.
|
||||||
*/
|
*/
|
||||||
public SeqExpr MkEmptySeq(Sort s)
|
public SeqExpr mkEmptySeq(Sort s)
|
||||||
{
|
{
|
||||||
checkContextMatch(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.
|
* Create the singleton sequence.
|
||||||
*/
|
*/
|
||||||
public SeqExpr MkUnit(Expr elem)
|
public SeqExpr mkUnit(Expr elem)
|
||||||
{
|
{
|
||||||
checkContextMatch(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.
|
* 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.
|
* Concatentate sequences.
|
||||||
*/
|
*/
|
||||||
public SeqExpr MkConcat(SeqExpr... t)
|
public SeqExpr mkConcat(SeqExpr... t)
|
||||||
{
|
{
|
||||||
checkContextMatch(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.
|
* Retrieve the length of a given sequence.
|
||||||
*/
|
*/
|
||||||
public IntExpr MkLength(SeqExpr s)
|
public IntExpr mkLength(SeqExpr s)
|
||||||
{
|
{
|
||||||
checkContextMatch(s);
|
checkContextMatch(s);
|
||||||
return (IntExpr) Expr.create(this, Native.mkSeqLength(nCtx(), s.getNativeObject()));
|
return (IntExpr) Expr.create(this, Native.mkSeqLength(nCtx(), s.getNativeObject()));
|
||||||
|
@ -1935,128 +1935,219 @@ public class Context implements AutoCloseable {
|
||||||
/**
|
/**
|
||||||
* Check for sequence prefix.
|
* Check for sequence prefix.
|
||||||
*/
|
*/
|
||||||
public BoolExpr MkPrefixOf(SeqExpr s1, SeqExpr s2)
|
public BoolExpr mkPrefixOf(SeqExpr s1, SeqExpr s2)
|
||||||
{
|
{
|
||||||
checkContextMatch(s1, 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.
|
* Check for sequence suffix.
|
||||||
*/
|
*/
|
||||||
public BoolExpr MkSuffixOf(SeqExpr s1, SeqExpr s2)
|
public BoolExpr mkSuffixOf(SeqExpr s1, SeqExpr s2)
|
||||||
{
|
{
|
||||||
checkContextMatch(s1, 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.
|
* 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);
|
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.
|
* Retrieve sequence of length one at index.
|
||||||
*/
|
*/
|
||||||
public SeqExpr MkAt(SeqExpr s, IntExpr index)
|
public SeqExpr mkAt(SeqExpr s, IntExpr index)
|
||||||
{
|
{
|
||||||
checkContextMatch(s, 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.
|
* Extract subsequence.
|
||||||
*/
|
*/
|
||||||
public SeqExpr MkExtract(SeqExpr s, IntExpr offset, IntExpr length)
|
public SeqExpr mkExtract(SeqExpr s, IntExpr offset, IntExpr length)
|
||||||
{
|
{
|
||||||
checkContextMatch(s, offset, 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.
|
* 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);
|
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.
|
* 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);
|
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.
|
* Convert a regular expression that accepts sequence s.
|
||||||
*/
|
*/
|
||||||
public ReExpr MkToRe(SeqExpr s)
|
public ReExpr mkToRe(SeqExpr s)
|
||||||
{
|
{
|
||||||
checkContextMatch(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.
|
* Check for regular expression membership.
|
||||||
*/
|
*/
|
||||||
public BoolExpr MkInRe(SeqExpr s, ReExpr re)
|
public BoolExpr mkInRe(SeqExpr s, ReExpr re)
|
||||||
{
|
{
|
||||||
checkContextMatch(s, 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.
|
* Take the Kleene star of a regular expression.
|
||||||
*/
|
*/
|
||||||
public ReExpr MkStar(ReExpr re)
|
public ReExpr mkStar(ReExpr re)
|
||||||
{
|
{
|
||||||
checkContextMatch(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.
|
* Take the Kleene plus of a regular expression.
|
||||||
*/
|
*/
|
||||||
public ReExpr MPlus(ReExpr re)
|
public ReExpr mkPlus(ReExpr re)
|
||||||
{
|
{
|
||||||
checkContextMatch(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.
|
* Create the optional regular expression.
|
||||||
*/
|
*/
|
||||||
public ReExpr MOption(ReExpr re)
|
public ReExpr mkOption(ReExpr re)
|
||||||
{
|
{
|
||||||
checkContextMatch(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.
|
* Create the concatenation of regular languages.
|
||||||
*/
|
*/
|
||||||
public ReExpr MkConcat(ReExpr... t)
|
public ReExpr mkConcat(ReExpr... t)
|
||||||
{
|
{
|
||||||
checkContextMatch(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.
|
* Create the union of regular languages.
|
||||||
*/
|
*/
|
||||||
public ReExpr MkUnion(ReExpr... t)
|
public ReExpr mkUnion(ReExpr... t)
|
||||||
{
|
{
|
||||||
checkContextMatch(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, symbol::null, symbol::null,
|
||||||
1, patterns);
|
1, patterns);
|
||||||
TRACE("mk_definition_bug", tout << "before elim_unused_vars:\n" << mk_ismt2_pp(q, m_manager) << "\n";);
|
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";);
|
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;
|
expr* t1, *t2;
|
||||||
bool is_int;
|
bool is_int = false;
|
||||||
if (m_util.is_mod(arg2)) {
|
if (m_util.is_mod(arg2)) {
|
||||||
std::swap(arg1, arg2);
|
std::swap(arg1, arg2);
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
|
|
|
@ -138,7 +138,7 @@ void der::operator()(quantifier * q, expr_ref & r, proof_ref & pr) {
|
||||||
// Eliminate variables that have become unused
|
// Eliminate variables that have become unused
|
||||||
if (reduced && is_forall(r)) {
|
if (reduced && is_forall(r)) {
|
||||||
quantifier * q = to_quantifier(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()) {
|
if (m_manager.proofs_enabled()) {
|
||||||
proof * p1 = m_manager.mk_elim_unused_vars(q, r);
|
proof * p1 = m_manager.mk_elim_unused_vars(q, r);
|
||||||
pr = m_manager.mk_transitivity(pr, p1);
|
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."),
|
("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."),
|
("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."),
|
("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 {
|
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 {
|
struct display_expr1 {
|
||||||
|
@ -237,6 +242,7 @@ eautomaton* re2automaton::re2aut(expr* e) {
|
||||||
unsigned nb = s1.num_bits();
|
unsigned nb = s1.num_bits();
|
||||||
expr_ref _start(bv.mk_numeral(start, nb), m);
|
expr_ref _start(bv.mk_numeral(start, nb), m);
|
||||||
expr_ref _stop(bv.mk_numeral(stop, 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));
|
a = alloc(eautomaton, sm, sym_expr::mk_range(_start, _stop));
|
||||||
return a.detach();
|
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();
|
result = m().mk_true();
|
||||||
return BR_DONE;
|
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;
|
return BR_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -1435,6 +1464,7 @@ bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_
|
||||||
zstring s;
|
zstring s;
|
||||||
bool lchange = false;
|
bool lchange = false;
|
||||||
SASSERT(lhs.empty());
|
SASSERT(lhs.empty());
|
||||||
|
TRACE("seq", tout << ls << "\n"; tout << rs << "\n";);
|
||||||
// solve from back
|
// solve from back
|
||||||
while (true) {
|
while (true) {
|
||||||
while (!rs.empty() && m_util.str.is_empty(rs.back())) {
|
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() &&
|
head2 < rs.size() &&
|
||||||
m_util.str.is_string(ls[head1].get(), s1) &&
|
m_util.str.is_string(ls[head1].get(), s1) &&
|
||||||
m_util.str.is_string(rs[head2].get(), s2)) {
|
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());
|
unsigned l = std::min(s1.length(), s2.length());
|
||||||
for (unsigned i = 0; i < l; ++i) {
|
for (unsigned i = 0; i < l; ++i) {
|
||||||
if (s1[i] != s2[i]) {
|
if (s1[i] != s2[i]) {
|
||||||
|
TRACE("seq", tout << "different at position " << i << " " << s1[i] << " " << s2[i] << "\n";);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
||||||
bool m_cache_all;
|
bool m_cache_all;
|
||||||
bool m_push_ite_arith;
|
bool m_push_ite_arith;
|
||||||
bool m_push_ite_bv;
|
bool m_push_ite_bv;
|
||||||
|
bool m_ignore_patterns_on_ground_qbody;
|
||||||
|
|
||||||
// substitution support
|
// substitution support
|
||||||
expr_dependency_ref m_used_dependencies; // set of dependencies of used substitutions
|
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_cache_all = p.cache_all();
|
||||||
m_push_ite_arith = p.push_ite_arith();
|
m_push_ite_arith = p.push_ite_arith();
|
||||||
m_push_ite_bv = p.push_ite_bv();
|
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) {
|
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));
|
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";);
|
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";);
|
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) {
|
void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
||||||
SASSERT(is_well_sorted(m, q));
|
SASSERT(is_well_sorted(m, q));
|
||||||
if (is_ground(q->get_expr())) {
|
if (m_ignore_patterns_on_ground_qbody && is_ground(q->get_expr())) {
|
||||||
// ignore patterns if the body is a ground formula.
|
// Ignore patterns if the body is a ground formula.
|
||||||
result = q->get_expr();
|
result = q->get_expr();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -146,8 +152,8 @@ void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
||||||
SASSERT(is_well_sorted(m, result));
|
SASSERT(is_well_sorted(m, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
|
void elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params, expr_ref & result) {
|
||||||
unused_vars_eliminator el(m);
|
unused_vars_eliminator el(m, params);
|
||||||
el(q, result);
|
el(q, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ Notes:
|
||||||
|
|
||||||
#include"rewriter.h"
|
#include"rewriter.h"
|
||||||
#include"used_vars.h"
|
#include"used_vars.h"
|
||||||
|
#include"params.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Alias for var_shifter class.
|
\brief Alias for var_shifter class.
|
||||||
|
@ -58,12 +59,14 @@ class unused_vars_eliminator {
|
||||||
ast_manager & m;
|
ast_manager & m;
|
||||||
var_subst m_subst;
|
var_subst m_subst;
|
||||||
used_vars m_used;
|
used_vars m_used;
|
||||||
|
params_ref m_params;
|
||||||
|
bool m_ignore_patterns_on_ground_qbody;
|
||||||
public:
|
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 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.
|
\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(encoding enc): m_encoding(enc) {}
|
||||||
|
|
||||||
zstring::zstring(char const* s, encoding enc): m_encoding(enc) {
|
zstring::zstring(char const* s, encoding enc): m_encoding(enc) {
|
||||||
|
unsigned mask = 0xFF; // TBD for UTF
|
||||||
while (*s) {
|
while (*s) {
|
||||||
unsigned ch;
|
unsigned ch;
|
||||||
if (is_escape_char(s, ch)) {
|
if (is_escape_char(s, ch)) {
|
||||||
m_buffer.push_back(ch);
|
m_buffer.push_back(ch & mask);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_buffer.push_back(*s);
|
m_buffer.push_back(*s & mask);
|
||||||
++s;
|
++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_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_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_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_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); }
|
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);
|
quantifier_ref tmp_q(m_manager);
|
||||||
tmp_q = m_manager.update_quantifier(q, not_arg);
|
tmp_q = m_manager.update_quantifier(q, not_arg);
|
||||||
expr_ref new_q(m_manager);
|
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);
|
new_args.push_back(new_q);
|
||||||
}
|
}
|
||||||
expr_ref result(m_manager);
|
expr_ref result(m_manager);
|
||||||
|
|
|
@ -188,7 +188,7 @@ void elim_bounds::operator()(quantifier * q, expr_ref & r) {
|
||||||
}
|
}
|
||||||
quantifier_ref new_q(m_manager);
|
quantifier_ref new_q(m_manager);
|
||||||
new_q = m_manager.update_quantifier(q, new_body);
|
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";);
|
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);
|
expr_ref r(m);
|
||||||
elim_unused_vars(m, q1, r);
|
elim_unused_vars(m, q1, params_ref(), r);
|
||||||
|
|
||||||
proof * pr = 0;
|
proof * pr = 0;
|
||||||
if (m.fine_grain_proofs()) {
|
if (m.fine_grain_proofs()) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ Notes:
|
||||||
#include"bound_manager.h"
|
#include"bound_manager.h"
|
||||||
#include"used_vars.h"
|
#include"used_vars.h"
|
||||||
#include"var_subst.h"
|
#include"var_subst.h"
|
||||||
|
#include"gparams.h"
|
||||||
|
|
||||||
#ifndef _EXTERNAL_RELEASE
|
#ifndef _EXTERNAL_RELEASE
|
||||||
|
|
||||||
|
@ -271,7 +272,7 @@ UNARY_CMD(elim_unused_vars_cmd, "dbg-elim-unused-vars", "<expr>", "eliminate unu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
expr_ref r(ctx.m());
|
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());
|
SASSERT(!is_quantifier(r) || !to_quantifier(r)->may_have_unused_vars());
|
||||||
ctx.display(ctx.regular_stream(), r);
|
ctx.display(ctx.regular_stream(), r);
|
||||||
ctx.regular_stream() << std::endl;
|
ctx.regular_stream() << std::endl;
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace Duality {
|
||||||
|
|
||||||
|
|
||||||
expr expr::qe_lite() const {
|
expr expr::qe_lite() const {
|
||||||
::qe_lite qe(m());
|
::qe_lite qe(m(), params_ref());
|
||||||
expr_ref result(to_expr(raw()),m());
|
expr_ref result(to_expr(raw()),m());
|
||||||
proof_ref pf(m());
|
proof_ref pf(m());
|
||||||
qe(result,pf);
|
qe(result,pf);
|
||||||
|
@ -356,7 +356,7 @@ namespace Duality {
|
||||||
}
|
}
|
||||||
|
|
||||||
expr expr::qe_lite(const std::set<int> &idxs, bool index_of_bound) const {
|
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());
|
expr_ref result(to_expr(raw()),m());
|
||||||
proof_ref pf(m());
|
proof_ref pf(m());
|
||||||
uint_set uis;
|
uint_set uis;
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace datalog {
|
||||||
m_head(m),
|
m_head(m),
|
||||||
m_args(m),
|
m_args(m),
|
||||||
m_hnf(m),
|
m_hnf(m),
|
||||||
m_qe(m),
|
m_qe(m, params_ref()),
|
||||||
m_rwr(m),
|
m_rwr(m),
|
||||||
m_ufproc(m) {}
|
m_ufproc(m) {}
|
||||||
|
|
||||||
|
|
|
@ -2241,7 +2241,7 @@ namespace pdr {
|
||||||
vars.append(aux_vars.size(), aux_vars.c_ptr());
|
vars.append(aux_vars.size(), aux_vars.c_ptr());
|
||||||
|
|
||||||
scoped_ptr<expr_replacer> rep;
|
scoped_ptr<expr_replacer> rep;
|
||||||
qe_lite qe(m);
|
qe_lite qe(m, m_params.p);
|
||||||
expr_ref phi1 = m_pm.mk_and(Phi);
|
expr_ref phi1 = m_pm.mk_and(Phi);
|
||||||
qe(vars, phi1);
|
qe(vars, phi1);
|
||||||
TRACE("pdr", tout << "Eliminated\n" << mk_pp(phi1, m) << "\n";);
|
TRACE("pdr", tout << "Eliminated\n" << mk_pp(phi1, m) << "\n";);
|
||||||
|
|
|
@ -520,7 +520,7 @@ namespace tb {
|
||||||
m_matcher(m),
|
m_matcher(m),
|
||||||
m_refs(m),
|
m_refs(m),
|
||||||
m_subst(m),
|
m_subst(m),
|
||||||
m_qe(m),
|
m_qe(m, params_ref()),
|
||||||
m_rw(m),
|
m_rw(m),
|
||||||
m_solver(m, m_fparams) {}
|
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) {
|
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();
|
reset();
|
||||||
SASSERT(tgt.get_predicate(idx)->get_decl() == src.get_decl());
|
SASSERT(tgt.get_predicate(idx)->get_decl() == src.get_decl());
|
||||||
unsigned var_cnt = std::max(tgt.get_num_vars(), src.get_num_vars());
|
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'"),
|
('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'"),
|
('priority', SYMBOL, 'lex', "select how to priortize objectives: 'lex' (lexicographic), 'pareto', or 'box'"),
|
||||||
('dump_benchmarks', BOOL, False, 'dump benchmarks for profiling'),
|
('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'),
|
('print_model', BOOL, False, 'display model for satisfiable constraints'),
|
||||||
('enable_sls', BOOL, False, 'enable SLS tuning during weighted maxsast'),
|
('enable_sls', BOOL, False, 'enable SLS tuning during weighted maxsast'),
|
||||||
('enable_sat', BOOL, True, 'enable the new SAT core for propositional constraints'),
|
('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_vector m_subst_map;
|
||||||
expr_ref_buffer m_new_args;
|
expr_ref_buffer m_new_args;
|
||||||
th_rewriter m_rewriter;
|
th_rewriter m_rewriter;
|
||||||
|
params_ref m_params;
|
||||||
|
|
||||||
void der_sort_vars(ptr_vector<var> & vars, ptr_vector<expr> & definitions, unsigned_vector & order) {
|
void der_sort_vars(ptr_vector<var> & vars, ptr_vector<expr> & definitions, unsigned_vector & order) {
|
||||||
order.reset();
|
order.reset();
|
||||||
|
@ -563,7 +564,8 @@ namespace eq {
|
||||||
void elim_unused_vars(expr_ref& r, proof_ref &pr) {
|
void elim_unused_vars(expr_ref& r, proof_ref &pr) {
|
||||||
if (is_quantifier(r)) {
|
if (is_quantifier(r)) {
|
||||||
quantifier * q = to_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()) {
|
if (m.proofs_enabled()) {
|
||||||
proof * p1 = m.mk_elim_unused_vars(q, r);
|
proof * p1 = m.mk_elim_unused_vars(q, r);
|
||||||
pr = m.mk_transitivity(pr, p1);
|
pr = m.mk_transitivity(pr, p1);
|
||||||
|
@ -744,7 +746,7 @@ namespace eq {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
der(ast_manager & m):
|
der(ast_manager & m, params_ref const & p):
|
||||||
m(m),
|
m(m),
|
||||||
a(m),
|
a(m),
|
||||||
dt(m),
|
dt(m),
|
||||||
|
@ -753,7 +755,8 @@ namespace eq {
|
||||||
m_new_exprs(m),
|
m_new_exprs(m),
|
||||||
m_subst_map(m),
|
m_subst_map(m),
|
||||||
m_new_args(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;}
|
void set_is_variable_proc(is_variable_proc& proc) { m_is_variable = &proc;}
|
||||||
|
|
||||||
|
@ -2346,9 +2349,9 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
impl(ast_manager& m):
|
impl(ast_manager & m, params_ref const & p):
|
||||||
m(m),
|
m(m),
|
||||||
m_der(m),
|
m_der(m, p),
|
||||||
m_fm(m),
|
m_fm(m),
|
||||||
m_array_der(m),
|
m_array_der(m),
|
||||||
m_elim_star(*this),
|
m_elim_star(*this),
|
||||||
|
@ -2438,8 +2441,8 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
qe_lite::qe_lite(ast_manager& m) {
|
qe_lite::qe_lite(ast_manager & m, params_ref const & p) {
|
||||||
m_impl = alloc(impl, m);
|
m_impl = alloc(impl, m, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
qe_lite::~qe_lite() {
|
qe_lite::~qe_lite() {
|
||||||
|
@ -2471,7 +2474,7 @@ class qe_lite_tactic : public tactic {
|
||||||
|
|
||||||
imp(ast_manager& m, params_ref const & p):
|
imp(ast_manager& m, params_ref const & p):
|
||||||
m(m),
|
m(m),
|
||||||
m_qe(m)
|
m_qe(m, p)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void checkpoint() {
|
void checkpoint() {
|
||||||
|
|
|
@ -31,7 +31,7 @@ class qe_lite {
|
||||||
class impl;
|
class impl;
|
||||||
impl * m_impl;
|
impl * m_impl;
|
||||||
public:
|
public:
|
||||||
qe_lite(ast_manager& m);
|
qe_lite(ast_manager & m, params_ref const & p);
|
||||||
|
|
||||||
~qe_lite();
|
~qe_lite();
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,8 @@ namespace sat {
|
||||||
if (!m_subsumption && !m_elim_blocked_clauses && !m_resolution)
|
if (!m_subsumption && !m_elim_blocked_clauses && !m_resolution)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// solver::scoped_disable_checkpoint _scoped_disable_checkpoint(s);
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
CASSERT("sat_solver", s.check_invariant());
|
CASSERT("sat_solver", s.check_invariant());
|
||||||
|
@ -167,7 +169,6 @@ namespace sat {
|
||||||
CASSERT("sat_solver", s.check_invariant());
|
CASSERT("sat_solver", s.check_invariant());
|
||||||
m_need_cleanup = false;
|
m_need_cleanup = false;
|
||||||
m_use_list.init(s.num_vars());
|
m_use_list.init(s.num_vars());
|
||||||
init_visited();
|
|
||||||
m_learned_in_use_lists = false;
|
m_learned_in_use_lists = false;
|
||||||
if (learned) {
|
if (learned) {
|
||||||
register_clauses(s.m_learned);
|
register_clauses(s.m_learned);
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace sat {
|
||||||
|
|
||||||
solver::solver(params_ref const & p, reslimit& l, extension * ext):
|
solver::solver(params_ref const & p, reslimit& l, extension * ext):
|
||||||
m_rlimit(l),
|
m_rlimit(l),
|
||||||
|
m_checkpoint_enabled(true),
|
||||||
m_config(p),
|
m_config(p),
|
||||||
m_ext(ext),
|
m_ext(ext),
|
||||||
m_par(0),
|
m_par(0),
|
||||||
|
|
|
@ -72,6 +72,7 @@ namespace sat {
|
||||||
struct abort_solver {};
|
struct abort_solver {};
|
||||||
protected:
|
protected:
|
||||||
reslimit& m_rlimit;
|
reslimit& m_rlimit;
|
||||||
|
bool m_checkpoint_enabled;
|
||||||
config m_config;
|
config m_config;
|
||||||
stats m_stats;
|
stats m_stats;
|
||||||
extension * m_ext;
|
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_watch_lit(clause const & cls, unsigned starting_at) const;
|
||||||
unsigned select_learned_watch_lit(clause const & cls) const;
|
unsigned select_learned_watch_lit(clause const & cls) const;
|
||||||
bool simplify_clause(unsigned & num_lits, literal * lits) const;
|
bool simplify_clause(unsigned & num_lits, literal * lits) const;
|
||||||
|
@ -257,6 +268,7 @@ namespace sat {
|
||||||
lbool status(clause const & c) const;
|
lbool status(clause const & c) const;
|
||||||
clause_offset get_offset(clause const & c) const { return m_cls_allocator.get_offset(&c); }
|
clause_offset get_offset(clause const & c) const { return m_cls_allocator.get_offset(&c); }
|
||||||
void checkpoint() {
|
void checkpoint() {
|
||||||
|
if (!m_checkpoint_enabled) return;
|
||||||
if (!m_rlimit.inc()) {
|
if (!m_rlimit.inc()) {
|
||||||
m_mc.reset();
|
m_mc.reset();
|
||||||
m_model_is_current = false;
|
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.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'),
|
('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();
|
m_assumptions.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::mk_unsat_core() {
|
lbool context::mk_unsat_core() {
|
||||||
SASSERT(inconsistent());
|
SASSERT(inconsistent());
|
||||||
if (!tracking_assumptions()) {
|
if (!tracking_assumptions()) {
|
||||||
SASSERT(m_assumptions.empty());
|
SASSERT(m_assumptions.empty());
|
||||||
return;
|
return l_false;
|
||||||
}
|
}
|
||||||
uint_set already_found_assumptions;
|
uint_set already_found_assumptions;
|
||||||
literal_vector::const_iterator it = m_conflict_resolution->begin_unsat_core();
|
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";
|
tout << mk_pp(m_unsat_core.get(i), m_manager) << "\n";
|
||||||
});
|
});
|
||||||
validate_unsat_core();
|
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_scope_lvl == 0);
|
||||||
SASSERT(!m_setup.already_configured());
|
SASSERT(!m_setup.already_configured());
|
||||||
setup_context(m_fparams.m_auto_config);
|
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();
|
internalize_assertions();
|
||||||
lbool r = l_undef;
|
lbool r = l_undef;
|
||||||
if (m_asserted_formulas.inconsistent()) {
|
if (m_asserted_formulas.inconsistent()) {
|
||||||
|
@ -3205,7 +3223,15 @@ namespace smt {
|
||||||
(*it)->setup();
|
(*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++;
|
m_stats.m_num_checks++;
|
||||||
TRACE("check_bug", tout << "STARTING check(num_assumptions, assumptions)\n";
|
TRACE("check_bug", tout << "STARTING check(num_assumptions, assumptions)\n";
|
||||||
tout << "inconsistent: " << inconsistent() << ", m_unsat_core.empty(): " << m_unsat_core.empty() << "\n";
|
tout << "inconsistent: " << inconsistent() << ", m_unsat_core.empty(): " << m_unsat_core.empty() << "\n";
|
||||||
|
@ -3216,6 +3242,15 @@ namespace smt {
|
||||||
m_unsat_core.reset();
|
m_unsat_core.reset();
|
||||||
if (!check_preamble(reset_cancel))
|
if (!check_preamble(reset_cancel))
|
||||||
return l_undef;
|
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))
|
if (!validate_assumptions(num_assumptions, assumptions))
|
||||||
return l_undef;
|
return l_undef;
|
||||||
TRACE("check_bug", tout << "inconsistent: " << inconsistent() << ", m_unsat_core.empty(): " << m_unsat_core.empty() << "\n";);
|
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););
|
TRACE("after_internalization", display(tout););
|
||||||
if (inconsistent()) {
|
if (inconsistent()) {
|
||||||
VERIFY(!resolve_conflict()); // build the proof
|
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;
|
r = l_false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
r = search();
|
r = search();
|
||||||
if (r == l_false)
|
if (r == l_false) {
|
||||||
mk_unsat_core();
|
lbool result = mk_unsat_core();
|
||||||
|
if (result == l_undef) {
|
||||||
|
r = l_undef;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1059,7 +1059,9 @@ namespace smt {
|
||||||
|
|
||||||
void reset_assumptions();
|
void reset_assumptions();
|
||||||
|
|
||||||
void mk_unsat_core();
|
void add_theory_assumptions(expr_ref_vector & theory_assumptions);
|
||||||
|
|
||||||
|
lbool mk_unsat_core();
|
||||||
|
|
||||||
void validate_unsat_core();
|
void validate_unsat_core();
|
||||||
|
|
||||||
|
@ -1444,7 +1446,7 @@ namespace smt {
|
||||||
|
|
||||||
void pop(unsigned num_scopes);
|
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);
|
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)) {
|
if (!is_ground(n)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (is_quantifier(n) && m.is_rec_fun_def(to_quantifier(n))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch (get_assignment(*it)) {
|
switch (get_assignment(*it)) {
|
||||||
case l_undef:
|
case l_undef:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -246,6 +246,7 @@ namespace smt {
|
||||||
|
|
||||||
simple_justification::simple_justification(region & r, unsigned num_lits, literal const * lits):
|
simple_justification::simple_justification(region & r, unsigned num_lits, literal const * lits):
|
||||||
m_num_literals(num_lits) {
|
m_num_literals(num_lits) {
|
||||||
|
if (num_lits != 0) {
|
||||||
m_literals = new (r) literal[num_lits];
|
m_literals = new (r) literal[num_lits];
|
||||||
memcpy(m_literals, lits, sizeof(literal) * num_lits);
|
memcpy(m_literals, lits, sizeof(literal) * num_lits);
|
||||||
#ifdef Z3DEBUG
|
#ifdef Z3DEBUG
|
||||||
|
@ -254,6 +255,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void simple_justification::get_antecedents(conflict_resolution & cr) {
|
void simple_justification::get_antecedents(conflict_resolution & cr) {
|
||||||
for (unsigned i = 0; i < m_num_literals; i++)
|
for (unsigned i = 0; i < m_num_literals; i++)
|
||||||
|
|
|
@ -316,7 +316,7 @@ namespace smt {
|
||||||
return false;
|
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";);
|
TRACE("model_checker", tout << mk_pp(q, m) << "\n";);
|
||||||
SASSERT(q->get_num_patterns() == 2); // first pattern is the function, second is the body.
|
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);
|
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);
|
sub(q->get_expr(), num_decls, args.c_ptr(), tmp);
|
||||||
m_curr_model->eval(tmp, result, true);
|
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);
|
add_instance(q, args, 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -365,10 +365,10 @@ namespace smt {
|
||||||
|
|
||||||
bool model_checker::check(proto_model * md, obj_map<enode, app *> const & root2value) {
|
bool model_checker::check(proto_model * md, obj_map<enode, app *> const & root2value) {
|
||||||
SASSERT(md != 0);
|
SASSERT(md != 0);
|
||||||
|
|
||||||
m_root2value = &root2value;
|
m_root2value = &root2value;
|
||||||
ptr_vector<quantifier>::const_iterator it = m_qm->begin_quantifiers();
|
|
||||||
ptr_vector<quantifier>::const_iterator end = m_qm->end_quantifiers();
|
if (m_qm->num_quantifiers() == 0)
|
||||||
if (it == end)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (m_iteration_idx >= m_params.m_mbqi_max_iterations) {
|
if (m_iteration_idx >= m_params.m_mbqi_max_iterations) {
|
||||||
|
@ -393,6 +393,36 @@ namespace smt {
|
||||||
bool found_relevant = false;
|
bool found_relevant = false;
|
||||||
unsigned num_failures = 0;
|
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) {
|
for (; it != end; ++it) {
|
||||||
quantifier * q = *it;
|
quantifier * q = *it;
|
||||||
if(!m_qm->mbqi_enabled(q)) continue;
|
if(!m_qm->mbqi_enabled(q)) continue;
|
||||||
|
@ -406,7 +436,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
found_relevant = true;
|
found_relevant = true;
|
||||||
if (m.is_rec_fun_def(q)) {
|
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";);
|
TRACE("model_checker", tout << "checking recursive function failed\n";);
|
||||||
num_failures++;
|
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() {
|
void model_checker::init_search_eh() {
|
||||||
|
|
|
@ -59,7 +59,8 @@ namespace smt {
|
||||||
void assert_neg_q_m(quantifier * q, expr_ref_vector & sks);
|
void assert_neg_q_m(quantifier * q, expr_ref_vector & sks);
|
||||||
bool add_blocking_clause(model * cex, expr_ref_vector & sks);
|
bool add_blocking_clause(model * cex, expr_ref_vector & sks);
|
||||||
bool check(quantifier * q);
|
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 {
|
struct instance {
|
||||||
quantifier * m_q;
|
quantifier * m_q;
|
||||||
|
|
|
@ -397,6 +397,10 @@ namespace smt {
|
||||||
return m_imp->m_quantifiers.end();
|
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
|
// The default plugin uses E-matching, MBQI and quick-checker
|
||||||
class default_qm_plugin : public quantifier_manager_plugin {
|
class default_qm_plugin : public quantifier_manager_plugin {
|
||||||
quantifier_manager * m_qm;
|
quantifier_manager * m_qm;
|
||||||
|
|
|
@ -91,6 +91,8 @@ namespace smt {
|
||||||
|
|
||||||
ptr_vector<quantifier>::const_iterator begin_quantifiers() const;
|
ptr_vector<quantifier>::const_iterator begin_quantifiers() const;
|
||||||
ptr_vector<quantifier>::const_iterator end_quantifiers() const;
|
ptr_vector<quantifier>::const_iterator end_quantifiers() const;
|
||||||
|
unsigned num_quantifiers() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class quantifier_manager_plugin {
|
class quantifier_manager_plugin {
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace smt {
|
||||||
bool m_minimizing_core;
|
bool m_minimizing_core;
|
||||||
bool m_core_extend_patterns;
|
bool m_core_extend_patterns;
|
||||||
unsigned m_core_extend_patterns_max_distance;
|
unsigned m_core_extend_patterns_max_distance;
|
||||||
|
bool m_core_extend_nonlocal_patterns;
|
||||||
obj_map<expr, expr*> m_name2assertion;
|
obj_map<expr, expr*> m_name2assertion;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -48,13 +49,15 @@ namespace smt {
|
||||||
m_context(m, m_smt_params),
|
m_context(m, m_smt_params),
|
||||||
m_minimizing_core(false),
|
m_minimizing_core(false),
|
||||||
m_core_extend_patterns(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;
|
m_logic = l;
|
||||||
if (m_logic != symbol::null)
|
if (m_logic != symbol::null)
|
||||||
m_context.set_logic(m_logic);
|
m_context.set_logic(m_logic);
|
||||||
smt_params_helper smth(p);
|
smt_params_helper smth(p);
|
||||||
m_core_extend_patterns = smth.core_extend_patterns();
|
m_core_extend_patterns = smth.core_extend_patterns();
|
||||||
m_core_extend_patterns_max_distance = smth.core_extend_patterns_max_distance();
|
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) {
|
virtual solver * translate(ast_manager & m, params_ref const & p) {
|
||||||
|
@ -81,6 +84,8 @@ namespace smt {
|
||||||
m_context.updt_params(p);
|
m_context.updt_params(p);
|
||||||
smt_params_helper smth(p);
|
smt_params_helper smth(p);
|
||||||
m_core_extend_patterns = smth.core_extend_patterns();
|
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) {
|
virtual void collect_param_descrs(param_descrs & r) {
|
||||||
|
@ -172,6 +177,8 @@ namespace smt {
|
||||||
|
|
||||||
if (m_core_extend_patterns)
|
if (m_core_extend_patterns)
|
||||||
add_pattern_literals_to_core(r);
|
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) {
|
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);
|
collect_pattern_fds_proc p(get_manager(), fds);
|
||||||
expr_mark visited;
|
expr_mark visited;
|
||||||
for_each_expr(p, visited, e);
|
for_each_expr(p, visited, e);
|
||||||
|
@ -295,7 +302,7 @@ namespace smt {
|
||||||
expr_ref name(core[i], m);
|
expr_ref name(core[i], m);
|
||||||
SASSERT(m_name2assertion.contains(name));
|
SASSERT(m_name2assertion.contains(name));
|
||||||
expr_ref assrtn(m_name2assertion.find(name), m);
|
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()) {
|
if (!pattern_fds.empty()) {
|
||||||
|
@ -317,6 +324,55 @@ namespace smt {
|
||||||
break;
|
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() {
|
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.
|
\brief This method is invoked before the search starts.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -339,8 +339,13 @@ namespace smt {
|
||||||
tout << mk_pp(var, get_manager()) << "\n";
|
tout << mk_pp(var, get_manager()) << "\n";
|
||||||
tout << "power " << power << ": " << expt(i, power) << "\n";
|
tout << "power " << power << ": " << expt(i, power) << "\n";
|
||||||
display_interval(tout << "target before: ", target); tout << "\n";);
|
display_interval(tout << "target before: ", target); tout << "\n";);
|
||||||
|
|
||||||
i.expt(power);
|
i.expt(power);
|
||||||
target *= i;
|
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";);
|
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";);
|
TRACE("seq", tout << ">>solve_eqs\n";);
|
||||||
return FC_CONTINUE;
|
return FC_CONTINUE;
|
||||||
}
|
}
|
||||||
|
if (check_contains()) {
|
||||||
|
++m_stats.m_propagate_contains;
|
||||||
|
TRACE("seq", tout << ">>propagate_contains\n";);
|
||||||
|
return FC_CONTINUE;
|
||||||
|
}
|
||||||
if (solve_nqs(0)) {
|
if (solve_nqs(0)) {
|
||||||
++m_stats.m_solve_nqs;
|
++m_stats.m_solve_nqs;
|
||||||
TRACE("seq", tout << ">>solve_nqs\n";);
|
TRACE("seq", tout << ">>solve_nqs\n";);
|
||||||
|
@ -290,11 +295,6 @@ final_check_status theory_seq::final_check_eh() {
|
||||||
TRACE("seq", tout << ">>propagate_automata\n";);
|
TRACE("seq", tout << ">>propagate_automata\n";);
|
||||||
return FC_CONTINUE;
|
return FC_CONTINUE;
|
||||||
}
|
}
|
||||||
if (check_contains()) {
|
|
||||||
++m_stats.m_propagate_contains;
|
|
||||||
TRACE("seq", tout << ">>propagate_contains\n";);
|
|
||||||
return FC_CONTINUE;
|
|
||||||
}
|
|
||||||
if (is_solved()) {
|
if (is_solved()) {
|
||||||
TRACE("seq", tout << ">>is_solved\n";);
|
TRACE("seq", tout << ">>is_solved\n";);
|
||||||
return FC_DONE;
|
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() {
|
bool theory_seq::check_contains() {
|
||||||
context & ctx = get_context();
|
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";);
|
IF_VERBOSE(10, display_disequation(verbose_stream() << "(seq.giveup ", m_nqs[0]); verbose_stream() << " is unsolved)\n";);
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1984,6 +1989,22 @@ bool theory_seq::solve_nc(unsigned idx) {
|
||||||
m_new_propagation = true;
|
m_new_propagation = true;
|
||||||
return 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2345,6 +2366,17 @@ bool theory_seq::add_itos_axiom(expr* e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
add_axiom(mk_eq(e2, n, 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)));
|
m_trail_stack.push(push_replay(alloc(replay_axiom, m, e)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2407,13 +2439,17 @@ void theory_seq::display(std::ostream & out) const {
|
||||||
if (!m_ncs.empty()) {
|
if (!m_ncs.empty()) {
|
||||||
out << "Non contains:\n";
|
out << "Non contains:\n";
|
||||||
for (unsigned i = 0; i < m_ncs.size(); ++i) {
|
for (unsigned i = 0; i < m_ncs.size(); ++i) {
|
||||||
out << "not " << mk_pp(m_ncs[i].contains(), m) << "\n";
|
display_nc(out, m_ncs[i]);
|
||||||
display_deps(out << " <- ", m_ncs[i].deps()); out << "\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
void theory_seq::display_equations(std::ostream& out) const {
|
||||||
for (unsigned i = 0; i < m_eqs.size(); ++i) {
|
for (unsigned i = 0; i < m_eqs.size(); ++i) {
|
||||||
display_equation(out, m_eqs[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_disequation(std::ostream& out, ne const& e) const;
|
||||||
void display_deps(std::ostream& out, dependency* deps) 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_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:
|
public:
|
||||||
theory_seq(ast_manager& m);
|
theory_seq(ast_manager& m);
|
||||||
virtual ~theory_seq();
|
virtual ~theory_seq();
|
||||||
|
|
|
@ -34,6 +34,7 @@ class elim_small_bv_tactic : public tactic {
|
||||||
|
|
||||||
struct rw_cfg : public default_rewriter_cfg {
|
struct rw_cfg : public default_rewriter_cfg {
|
||||||
ast_manager & m;
|
ast_manager & m;
|
||||||
|
params_ref m_params;
|
||||||
bv_util m_util;
|
bv_util m_util;
|
||||||
simplifier m_simp;
|
simplifier m_simp;
|
||||||
ref<filter_model_converter> m_mc;
|
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) :
|
rw_cfg(ast_manager & _m, params_ref const & p) :
|
||||||
m(_m),
|
m(_m),
|
||||||
|
m_params(p),
|
||||||
m_util(_m),
|
m_util(_m),
|
||||||
m_simp(_m),
|
m_simp(_m),
|
||||||
m_bindings(_m),
|
m_bindings(_m),
|
||||||
|
@ -178,7 +180,7 @@ class elim_small_bv_tactic : public tactic {
|
||||||
|
|
||||||
quantifier_ref new_q(m);
|
quantifier_ref new_q(m);
|
||||||
new_q = m.update_quantifier(q, body);
|
new_q = m.update_quantifier(q, body);
|
||||||
unused_vars_eliminator el(m);
|
unused_vars_eliminator el(m, m_params);
|
||||||
el(new_q, result);
|
el(new_q, result);
|
||||||
|
|
||||||
TRACE("elim_small_bv", tout << "elimination result: " << mk_ismt2_pp(result, m) << std::endl; );
|
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) {
|
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_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
|
||||||
m_max_steps = p.get_uint("max_steps", UINT_MAX);
|
m_max_steps = p.get_uint("max_steps", UINT_MAX);
|
||||||
m_max_bits = p.get_uint("max_bits", 4);
|
m_max_bits = p.get_uint("max_bits", 4);
|
||||||
|
|
|
@ -50,7 +50,7 @@ class distribute_forall_tactic : public tactic {
|
||||||
quantifier_ref tmp_q(m);
|
quantifier_ref tmp_q(m);
|
||||||
tmp_q = m.update_quantifier(old_q, not_arg);
|
tmp_q = m.update_quantifier(old_q, not_arg);
|
||||||
expr_ref new_q(m);
|
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);
|
new_args.push_back(new_q);
|
||||||
}
|
}
|
||||||
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
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);
|
quantifier_ref tmp_q(m);
|
||||||
tmp_q = m.update_quantifier(old_q, arg);
|
tmp_q = m.update_quantifier(old_q, arg);
|
||||||
expr_ref new_q(m);
|
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);
|
new_args.push_back(new_q);
|
||||||
}
|
}
|
||||||
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
||||||
|
|
|
@ -34,19 +34,19 @@ Notes:
|
||||||
class bounded_int2bv_solver : public solver_na2as {
|
class bounded_int2bv_solver : public solver_na2as {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
params_ref m_params;
|
params_ref m_params;
|
||||||
bv_util m_bv;
|
mutable bv_util m_bv;
|
||||||
arith_util m_arith;
|
mutable arith_util m_arith;
|
||||||
expr_ref_vector m_assertions;
|
mutable expr_ref_vector m_assertions;
|
||||||
ref<solver> m_solver;
|
ref<solver> m_solver;
|
||||||
ptr_vector<bound_manager> m_bounds;
|
mutable ptr_vector<bound_manager> m_bounds;
|
||||||
func_decl_ref_vector m_bv_fns;
|
mutable func_decl_ref_vector m_bv_fns;
|
||||||
func_decl_ref_vector m_int_fns;
|
mutable func_decl_ref_vector m_int_fns;
|
||||||
unsigned_vector m_bv_fns_lim;
|
unsigned_vector m_bv_fns_lim;
|
||||||
obj_map<func_decl, func_decl*> m_int2bv;
|
mutable obj_map<func_decl, func_decl*> m_int2bv;
|
||||||
obj_map<func_decl, func_decl*> m_bv2int;
|
mutable obj_map<func_decl, func_decl*> m_bv2int;
|
||||||
obj_map<func_decl, rational> m_bv2offset;
|
mutable obj_map<func_decl, rational> m_bv2offset;
|
||||||
bv2int_rewriter_ctx m_rewriter_ctx;
|
mutable bv2int_rewriter_ctx m_rewriter_ctx;
|
||||||
bv2int_rewriter_star m_rewriter;
|
mutable bv2int_rewriter_star m_rewriter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -78,7 +78,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void assert_expr(expr * t) {
|
virtual void assert_expr(expr * t) {
|
||||||
|
unsigned i = m_assertions.size();
|
||||||
m_assertions.push_back(t);
|
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() {
|
virtual void push_core() {
|
||||||
|
@ -184,7 +196,7 @@ private:
|
||||||
}
|
}
|
||||||
filter_model_converter filter(m);
|
filter_model_converter filter(m);
|
||||||
for (unsigned i = 0; i < m_bv_fns.size(); ++i) {
|
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);
|
filter(mdl, 0);
|
||||||
}
|
}
|
||||||
|
@ -205,13 +217,13 @@ private:
|
||||||
ext(mdl, 0);
|
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) {
|
for (unsigned i = 0; i < m_bounds.size(); ++i) {
|
||||||
accumulate_sub(sub, *m_bounds[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();
|
bound_manager::iterator it = bm.begin(), end = bm.end();
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
expr* e = *it;
|
expr* e = *it;
|
||||||
|
@ -252,19 +264,20 @@ private:
|
||||||
sub.insert(e, t);
|
sub.insert(e, t);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IF_VERBOSE(1,
|
TRACE("pb",
|
||||||
verbose_stream() << "unprocessed entry: " << mk_pp(e, m) << "\n";
|
tout << "unprocessed entry: " << mk_pp(e, m) << "\n";
|
||||||
if (bm.has_lower(e, lo, s1)) {
|
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)) {
|
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_neg());
|
||||||
SASSERT(k.is_int());
|
SASSERT(k.is_int());
|
||||||
rational two(2);
|
rational two(2);
|
||||||
|
@ -277,11 +290,13 @@ private:
|
||||||
return num_bits;
|
return num_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_assertions() {
|
void flush_assertions() const {
|
||||||
|
if (m_assertions.empty()) return;
|
||||||
bound_manager& bm = *m_bounds.back();
|
bound_manager& bm = *m_bounds.back();
|
||||||
for (unsigned i = 0; i < m_assertions.size(); ++i) {
|
for (unsigned i = 0; i < m_assertions.size(); ++i) {
|
||||||
bm(m_assertions[i].get());
|
bm(m_assertions[i].get());
|
||||||
}
|
}
|
||||||
|
TRACE("int2bv", bm.display(tout););
|
||||||
expr_safe_replace sub(m);
|
expr_safe_replace sub(m);
|
||||||
accumulate_sub(sub);
|
accumulate_sub(sub);
|
||||||
proof_ref proof(m);
|
proof_ref proof(m);
|
||||||
|
@ -304,6 +319,17 @@ private:
|
||||||
m_assertions.reset();
|
m_assertions.reset();
|
||||||
m_rewriter.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) {
|
solver * mk_bounded_int2bv_solver(ast_manager & m, params_ref const & p, solver* s) {
|
||||||
|
|
|
@ -163,6 +163,14 @@ public:
|
||||||
ext(mdl, 0);
|
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) {
|
solver * mk_enum2bv_solver(ast_manager & m, params_ref const & p, solver* s) {
|
||||||
|
|
|
@ -27,9 +27,9 @@ Notes:
|
||||||
class pb2bv_solver : public solver_na2as {
|
class pb2bv_solver : public solver_na2as {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
params_ref m_params;
|
params_ref m_params;
|
||||||
expr_ref_vector m_assertions;
|
mutable expr_ref_vector m_assertions;
|
||||||
ref<solver> m_solver;
|
mutable ref<solver> m_solver;
|
||||||
pb2bv_rewriter m_rewriter;
|
mutable pb2bv_rewriter m_rewriter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -107,8 +107,19 @@ public:
|
||||||
filter(mdl, 0);
|
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:
|
private:
|
||||||
void flush_assertions() {
|
void flush_assertions() const {
|
||||||
proof_ref proof(m);
|
proof_ref proof(m);
|
||||||
expr_ref fml(m);
|
expr_ref fml(m);
|
||||||
expr_ref_vector fmls(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);
|
q = m_manager.update_quantifier(to_quantifier(actual), new_body);
|
||||||
m_new_exprs.push_back(q);
|
m_new_exprs.push_back(q);
|
||||||
expr_ref new_q(m_manager);
|
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);
|
m_new_exprs.push_back(new_q);
|
||||||
rewrite_cache(e, new_q, true);
|
rewrite_cache(e, new_q, true);
|
||||||
m_rewrite_todo.pop_back();
|
m_rewrite_todo.pop_back();
|
||||||
|
|
Loading…
Reference in a new issue