mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 12:08:18 +00:00
Merge branch 'master' of https://github.com/z3prover/z3
This commit is contained in:
commit
536f4f84bb
|
@ -2,7 +2,7 @@
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_compiler_flags_overrides.cmake")
|
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_compiler_flags_overrides.cmake")
|
||||||
project(Z3 VERSION 4.12.3.0 LANGUAGES CXX)
|
project(Z3 VERSION 4.12.5.0 LANGUAGES CXX)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Project version
|
# Project version
|
||||||
|
|
|
@ -9,7 +9,16 @@ Version 4.next
|
||||||
- polysat
|
- polysat
|
||||||
- native word level bit-vector solving.
|
- native word level bit-vector solving.
|
||||||
- introduction of simple induction lemmas to handle a limited repertoire of induction proofs.
|
- introduction of simple induction lemmas to handle a limited repertoire of induction proofs.
|
||||||
- Light quantifier elimination based on term graphs (egraphs), and corresponding Model Based Projection for arrays and ADTs. Used by Spacer and QSAT.
|
|
||||||
|
Version 4.12.5
|
||||||
|
==============
|
||||||
|
|
||||||
|
Version 4.12.4
|
||||||
|
==============
|
||||||
|
- Re-release fixing a few issues with 4.12:
|
||||||
|
- Python dependency on importlib.resources vs importlib_resources break automatic pypi installations. Supposedly fixed by conditioning dependency on Python 3.9 where the feature is built-in.
|
||||||
|
- Missing release of arm64 for Ubuntu.
|
||||||
|
- Futile attempt to streamline adding readme.md file as part of Nuget distribution. Nuget.org now requires a readme file. I was able to integrate the readme with the cmake build, but the cross-platform repackage in scripts/mk_nuget_task.py does not ingest a similar readme file with the CI pipelines.
|
||||||
|
|
||||||
Version 4.12.3
|
Version 4.12.3
|
||||||
==============
|
==============
|
||||||
|
@ -23,6 +32,12 @@ Version 4.12.3
|
||||||
- Various (ongoing) performance fixes and improvements to smt.arith.solver=6
|
- Various (ongoing) performance fixes and improvements to smt.arith.solver=6
|
||||||
- A working version of solver.proof.trim=true option. Proofs logs created when using sat.smt=true may be trimmed by running z3
|
- A working version of solver.proof.trim=true option. Proofs logs created when using sat.smt=true may be trimmed by running z3
|
||||||
on the generated proof log using the option solver.proof.trim=true.
|
on the generated proof log using the option solver.proof.trim=true.
|
||||||
|
- Optimizations LIA and NIA (linear integer arithmetic and non-linear integer (and real) arithmetic reasoning).
|
||||||
|
smt.arith.solver=6 is the default for most use cases. It trails smt.arith.solver=2 in some scenarios and the gap has been either removed or reduced.
|
||||||
|
smt.arith.solver=6 is complete for integrations of non-linear real arithmetic and theories, smt.arith.solver=2 is not.
|
||||||
|
- qel: Light quantifier elimination based on term graphs (egraphs), and corresponding Model Based Projection for arrays and ADTs. Used by Spacer and QSAT.
|
||||||
|
- added real-closed fields features to C API, exposed more RCF over OCaml API
|
||||||
|
- fixes to FP
|
||||||
|
|
||||||
Version 4.12.2
|
Version 4.12.2
|
||||||
==============
|
==============
|
||||||
|
|
|
@ -24,13 +24,16 @@ def mk_dir(d):
|
||||||
os_info = { 'ubuntu-latest' : ('so', 'linux-x64'),
|
os_info = { 'ubuntu-latest' : ('so', 'linux-x64'),
|
||||||
'ubuntu-18' : ('so', 'linux-x64'),
|
'ubuntu-18' : ('so', 'linux-x64'),
|
||||||
'ubuntu-20' : ('so', 'linux-x64'),
|
'ubuntu-20' : ('so', 'linux-x64'),
|
||||||
'x64-glibc-2.31' : ('so', 'linux-x64'),
|
'x64-glibc-2.35' : ('so', 'linux-x64'),
|
||||||
'x64-win' : ('dll', 'win-x64'),
|
'x64-win' : ('dll', 'win-x64'),
|
||||||
'x86-win' : ('dll', 'win-x86'),
|
'x86-win' : ('dll', 'win-x86'),
|
||||||
'x64-osx' : ('dylib', 'osx-x64'),
|
'x64-osx' : ('dylib', 'osx-x64'),
|
||||||
'arm64-osx' : ('dylib', 'osx-arm64'),
|
|
||||||
'debian' : ('so', 'linux-x64') }
|
'debian' : ('so', 'linux-x64') }
|
||||||
|
|
||||||
|
# Nuget not supported for ARM
|
||||||
|
#'arm-glibc-2.35' : ('so', 'linux-arm64'),
|
||||||
|
#'arm64-osx' : ('dylib', 'osx-arm64'),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def classify_package(f, arch):
|
def classify_package(f, arch):
|
||||||
|
@ -85,6 +88,8 @@ def mk_targets(source_root):
|
||||||
def mk_icon(source_root):
|
def mk_icon(source_root):
|
||||||
mk_dir("out/content")
|
mk_dir("out/content")
|
||||||
shutil.copy(f"{source_root}/resources/icon.jpg", "out/content/icon.jpg")
|
shutil.copy(f"{source_root}/resources/icon.jpg", "out/content/icon.jpg")
|
||||||
|
shutil.copy(f"{source_root}/src/api/dotnet/README.md", "out/content/README.md")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_nuget_spec(version, repo, branch, commit, symbols, arch):
|
def create_nuget_spec(version, repo, branch, commit, symbols, arch):
|
||||||
|
@ -104,6 +109,7 @@ Linux Dependencies:
|
||||||
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
|
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
|
||||||
<tags>smt constraint solver theorem prover</tags>
|
<tags>smt constraint solver theorem prover</tags>
|
||||||
<icon>content/icon.jpg</icon>
|
<icon>content/icon.jpg</icon>
|
||||||
|
<readme>content/README.md</readme>
|
||||||
<projectUrl>https://github.com/Z3Prover/z3</projectUrl>
|
<projectUrl>https://github.com/Z3Prover/z3</projectUrl>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<repository type="git" url="{1}" branch="{2}" commit="{3}" />
|
<repository type="git" url="{1}" branch="{2}" commit="{3}" />
|
||||||
|
@ -113,6 +119,10 @@ Linux Dependencies:
|
||||||
<group targetFramework=".netstandard2.0" />
|
<group targetFramework=".netstandard2.0" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<file src="content/README.md" target="content/README.md"/>
|
||||||
|
<file src="content/icon.jpg" target="content/icon.jpg"/>
|
||||||
|
</files>
|
||||||
</package>""".format(version, repo, branch, commit, arch)
|
</package>""".format(version, repo, branch, commit, arch)
|
||||||
print(contents)
|
print(contents)
|
||||||
sym = "sym." if symbols else ""
|
sym = "sym." if symbols else ""
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
from mk_util import *
|
from mk_util import *
|
||||||
|
|
||||||
def init_version():
|
def init_version():
|
||||||
set_version(4, 12, 3, 0) # express a default build version or pick up ci build version
|
set_version(4, 12, 5, 0) # express a default build version or pick up ci build version
|
||||||
|
|
||||||
# Z3 Project definition
|
# Z3 Project definition
|
||||||
def init_project_def():
|
def init_project_def():
|
||||||
|
|
|
@ -1736,6 +1736,7 @@ class DotNetDLLComponent(Component):
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Authors>Microsoft</Authors>
|
<Authors>Microsoft</Authors>
|
||||||
<Company>Microsoft</Company>
|
<Company>Microsoft</Company>
|
||||||
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||||
<Description>Z3 is a satisfiability modulo theories solver from Microsoft Research.</Description>
|
<Description>Z3 is a satisfiability modulo theories solver from Microsoft Research.</Description>
|
||||||
<Copyright>Copyright Microsoft Corporation. All rights reserved.</Copyright>
|
<Copyright>Copyright Microsoft Corporation. All rights reserved.</Copyright>
|
||||||
|
@ -1745,9 +1746,10 @@ class DotNetDLLComponent(Component):
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\%s\*.cs;*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
|
<Compile Include="..\%s\*.cs;*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
|
||||||
|
<None Include="..\%s\README.md" Pack="true" PackagePath="/"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>""" % (version, key, self.to_src_dir)
|
</Project>""" % (version, key, self.to_src_dir, self.to_src_dir)
|
||||||
|
|
||||||
mk_dir(os.path.join(BUILD_DIR, 'dotnet'))
|
mk_dir(os.path.join(BUILD_DIR, 'dotnet'))
|
||||||
csproj = os.path.join('dotnet', 'z3.csproj')
|
csproj = os.path.join('dotnet', 'z3.csproj')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
variables:
|
variables:
|
||||||
Major: '4'
|
Major: '4'
|
||||||
Minor: '12'
|
Minor: '12'
|
||||||
Patch: '3'
|
Patch: '5'
|
||||||
AssemblyVersion: $(Major).$(Minor).$(Patch).$(Build.BuildId)
|
AssemblyVersion: $(Major).$(Minor).$(Patch).$(Build.BuildId)
|
||||||
NightlyVersion: $(AssemblyVersion)-$(Build.DefinitionName)
|
NightlyVersion: $(AssemblyVersion)-$(Build.DefinitionName)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
trigger: none
|
trigger: none
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
ReleaseVersion: '4.12.3'
|
ReleaseVersion: '4.12.5'
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ stages:
|
||||||
displayName: "Download Ubuntu Arm64"
|
displayName: "Download Ubuntu Arm64"
|
||||||
inputs:
|
inputs:
|
||||||
artifactName: 'UbuntuArm64'
|
artifactName: 'UbuntuArm64'
|
||||||
targetPath: tmp
|
path: $(Agent.TempDirectory)
|
||||||
- task: DownloadPipelineArtifact@2
|
- task: DownloadPipelineArtifact@2
|
||||||
displayName: "Download Doc"
|
displayName: "Download Doc"
|
||||||
inputs:
|
inputs:
|
||||||
|
@ -583,7 +583,7 @@ stages:
|
||||||
|
|
||||||
# Enable on release:
|
# Enable on release:
|
||||||
- job: PyPIPublish
|
- job: PyPIPublish
|
||||||
condition: eq(1,0)
|
condition: eq(1,1)
|
||||||
displayName: "Publish to PyPI"
|
displayName: "Publish to PyPI"
|
||||||
pool:
|
pool:
|
||||||
vmImage: "ubuntu-latest"
|
vmImage: "ubuntu-latest"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# - !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
############################################
|
############################################
|
||||||
# Copyright (c) 2012 Microsoft Corporation
|
# Copyright (c) 2012 Microsoft Corporation
|
||||||
#
|
#
|
||||||
|
@ -1831,7 +1831,10 @@ import atexit
|
||||||
import sys, os
|
import sys, os
|
||||||
import contextlib
|
import contextlib
|
||||||
import ctypes
|
import ctypes
|
||||||
import importlib_resources
|
if sys.version_info >= (3, 9):
|
||||||
|
import importlib.resources as importlib_resources
|
||||||
|
else:
|
||||||
|
import importlib_resources
|
||||||
from .z3types import *
|
from .z3types import *
|
||||||
from .z3consts import *
|
from .z3consts import *
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
<AssemblyName>Microsoft.Z3</AssemblyName>
|
<AssemblyName>Microsoft.Z3</AssemblyName>
|
||||||
<RootNamespace>Microsoft.Z3</RootNamespace>
|
<RootNamespace>Microsoft.Z3</RootNamespace>
|
||||||
|
|
||||||
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
|
|
||||||
<Title>Z3 .NET Interface</Title>
|
<Title>Z3 .NET Interface</Title>
|
||||||
<AssemblyTitle>Z3 .NET Interface</AssemblyTitle>
|
<AssemblyTitle>Z3 .NET Interface</AssemblyTitle>
|
||||||
|
|
||||||
|
@ -15,8 +17,8 @@
|
||||||
<Description>Z3 is a satisfiability modulo theories solver from Microsoft Research.</Description>
|
<Description>Z3 is a satisfiability modulo theories solver from Microsoft Research.</Description>
|
||||||
<AssemblyDescription>.NET Interface to the Z3 Theorem Prover</AssemblyDescription>
|
<AssemblyDescription>.NET Interface to the Z3 Theorem Prover</AssemblyDescription>
|
||||||
|
|
||||||
<Copyright>Copyright (C) 2006-2019 Microsoft Corporation</Copyright>
|
<Copyright>Copyright (C) 2006- Microsoft Corporation</Copyright>
|
||||||
<AssemblyCopyright>Copyright (C) 2006-2019 Microsoft Corporation</AssemblyCopyright>
|
<AssemblyCopyright>Copyright (C) 2006- Microsoft Corporation</AssemblyCopyright>
|
||||||
|
|
||||||
<Company>Microsoft Corporation</Company>
|
<Company>Microsoft Corporation</Company>
|
||||||
<AssemblyCompany>Microsoft Corporation</AssemblyCompany>
|
<AssemblyCompany>Microsoft Corporation</AssemblyCompany>
|
||||||
|
@ -65,6 +67,11 @@
|
||||||
${Z3_DOTNET_COMPILE_ITEMS}
|
${Z3_DOTNET_COMPILE_ITEMS}
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- Readme -->
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="${CMAKE_CURRENT_LIST_DIR}/README.md" Pack="true" PackagePath="\"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- Legacy .NET framework native library helper routines -->
|
<!-- Legacy .NET framework native library helper routines -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="${CMAKE_CURRENT_LIST_DIR}/Microsoft.Z3.props">
|
<Content Include="${CMAKE_CURRENT_LIST_DIR}/Microsoft.Z3.props">
|
||||||
|
|
3
src/api/dotnet/README.md
Normal file
3
src/api/dotnet/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Z3 Nuget Package
|
||||||
|
|
||||||
|
For more information see [the Z3 github page](https://github.com/z3prover/z3.git)
|
|
@ -18,7 +18,7 @@ from setuptools.command.bdist_egg import bdist_egg as _bdist_egg
|
||||||
|
|
||||||
build_env = dict(os.environ)
|
build_env = dict(os.environ)
|
||||||
build_env['PYTHON'] = sys.executable
|
build_env['PYTHON'] = sys.executable
|
||||||
build_env['CXXFLAGS'] = build_env.get('CXXFLAGS', '') + " -std=c++11"
|
build_env['CXXFLAGS'] = build_env.get('CXXFLAGS', '') + " -std=c++17"
|
||||||
|
|
||||||
# determine where we're building and where sources are
|
# determine where we're building and where sources are
|
||||||
ROOT_DIR = os.path.abspath(os.path.dirname(__file__))
|
ROOT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
@ -313,6 +313,8 @@ if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv:
|
||||||
osver = RELEASE_METADATA[3]
|
osver = RELEASE_METADATA[3]
|
||||||
if osver.count('.') > 1:
|
if osver.count('.') > 1:
|
||||||
osver = '.'.join(osver.split('.')[:2])
|
osver = '.'.join(osver.split('.')[:2])
|
||||||
|
if osver.startswith("11"):
|
||||||
|
osver = "11_0"
|
||||||
if arch == 'x64':
|
if arch == 'x64':
|
||||||
plat_name ='macosx_%s_x86_64' % osver.replace('.', '_')
|
plat_name ='macosx_%s_x86_64' % osver.replace('.', '_')
|
||||||
elif arch == 'arm64':
|
elif arch == 'arm64':
|
||||||
|
@ -339,6 +341,7 @@ setup(
|
||||||
license='MIT License',
|
license='MIT License',
|
||||||
keywords=['z3', 'smt', 'sat', 'prover', 'theorem'],
|
keywords=['z3', 'smt', 'sat', 'prover', 'theorem'],
|
||||||
packages=['z3'],
|
packages=['z3'],
|
||||||
|
install_requires = ['importlib-resources'],
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
package_data={
|
package_data={
|
||||||
'z3': [os.path.join('lib', '*'), os.path.join('include', '*.h'), os.path.join('include', 'c++', '*.h')]
|
'z3': [os.path.join('lib', '*'), os.path.join('include', '*.h'), os.path.join('include', 'c++', '*.h')]
|
||||||
|
|
|
@ -1572,7 +1572,12 @@ class BoolRef(ExprRef):
|
||||||
return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
|
return BoolSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
return If(self, 1, 0) + If(other, 1, 0)
|
if isinstance(other, BoolRef):
|
||||||
|
other = If(other, 1, 0)
|
||||||
|
return If(self, 1, 0) + other
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
return self + other
|
||||||
|
|
||||||
def __rmul__(self, other):
|
def __rmul__(self, other):
|
||||||
return self * other
|
return self * other
|
||||||
|
@ -1593,6 +1598,9 @@ class BoolRef(ExprRef):
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
return Or(self, other)
|
return Or(self, other)
|
||||||
|
|
||||||
|
def __xor__(self, other):
|
||||||
|
return Xor(self, other)
|
||||||
|
|
||||||
def __invert__(self):
|
def __invert__(self):
|
||||||
return Not(self)
|
return Not(self)
|
||||||
|
|
|
@ -94,7 +94,10 @@ namespace polymorphism {
|
||||||
t.push(value_trail(m_decl_qhead));
|
t.push(value_trail(m_decl_qhead));
|
||||||
for (; m_decl_qhead < num_decls; ++m_decl_qhead) {
|
for (; m_decl_qhead < num_decls; ++m_decl_qhead) {
|
||||||
func_decl* p = m_decl_queue.get(m_decl_qhead);
|
func_decl* p = m_decl_queue.get(m_decl_qhead);
|
||||||
for (expr* e : m_occurs[m.poly_root(p)])
|
func_decl* r = m.poly_root(p);
|
||||||
|
if (!m_occurs.contains(r))
|
||||||
|
continue;
|
||||||
|
for (expr* e : m_occurs[r])
|
||||||
instantiate(p, e, instances);
|
instantiate(p, e, instances);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -611,4 +611,19 @@ void emonics::set_propagated(monic const& m) {
|
||||||
m_u_f_stack.push(set_unpropagated(*this, m.var()));
|
m_u_f_stack.push(set_unpropagated(*this, m.var()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emonics::set_bound_propagated(monic const& m) {
|
||||||
|
struct set_bound_unpropagated : public trail {
|
||||||
|
emonics& em;
|
||||||
|
unsigned var;
|
||||||
|
public:
|
||||||
|
set_bound_unpropagated(emonics& em, unsigned var): em(em), var(var) {}
|
||||||
|
void undo() override {
|
||||||
|
em[var].set_bound_propagated(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SASSERT(!m.is_bound_propagated());
|
||||||
|
(*this)[m.var()].set_bound_propagated(true);
|
||||||
|
m_u_f_stack.push(set_bound_unpropagated(*this, m.var()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,7 @@ public:
|
||||||
void after_merge_eh(unsigned r2, unsigned r1, unsigned v2, unsigned v1) {}
|
void after_merge_eh(unsigned r2, unsigned r1, unsigned v2, unsigned v1) {}
|
||||||
|
|
||||||
void set_propagated(monic const& m);
|
void set_propagated(monic const& m);
|
||||||
|
void set_bound_propagated(monic const& m);
|
||||||
|
|
||||||
// this method is required by union_find
|
// this method is required by union_find
|
||||||
trail_stack & get_trail_stack() { return m_u_f_stack; }
|
trail_stack & get_trail_stack() { return m_u_f_stack; }
|
||||||
|
|
|
@ -59,6 +59,7 @@ class monic: public mon_eq {
|
||||||
bool m_rsign;
|
bool m_rsign;
|
||||||
mutable unsigned m_visited;
|
mutable unsigned m_visited;
|
||||||
bool m_propagated = false;
|
bool m_propagated = false;
|
||||||
|
bool m_bound_propagated = false;
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
monic(lpvar v, unsigned sz, lpvar const* vs, unsigned idx):
|
monic(lpvar v, unsigned sz, lpvar const* vs, unsigned idx):
|
||||||
|
@ -77,6 +78,8 @@ public:
|
||||||
void sort_rvars() { std::sort(m_rvars.begin(), m_rvars.end()); }
|
void sort_rvars() { std::sort(m_rvars.begin(), m_rvars.end()); }
|
||||||
void set_propagated(bool p) { m_propagated = p; }
|
void set_propagated(bool p) { m_propagated = p; }
|
||||||
bool is_propagated() const { return m_propagated; }
|
bool is_propagated() const { return m_propagated; }
|
||||||
|
void set_bound_propagated(bool p) { m_bound_propagated = p; }
|
||||||
|
bool is_bound_propagated() const { return m_bound_propagated; }
|
||||||
|
|
||||||
svector<lpvar>::const_iterator begin() const { return vars().begin(); }
|
svector<lpvar>::const_iterator begin() const { return vars().begin(); }
|
||||||
svector<lpvar>::const_iterator end() const { return vars().end(); }
|
svector<lpvar>::const_iterator end() const { return vars().end(); }
|
||||||
|
|
|
@ -1517,6 +1517,9 @@ void core::add_bounds() {
|
||||||
for (lpvar j : m.vars()) {
|
for (lpvar j : m.vars()) {
|
||||||
if (!var_is_free(j))
|
if (!var_is_free(j))
|
||||||
continue;
|
continue;
|
||||||
|
if (m.is_bound_propagated())
|
||||||
|
continue;
|
||||||
|
m_emons.set_bound_propagated(m);
|
||||||
// split the free variable (j <= 0, or j > 0), and return
|
// split the free variable (j <= 0, or j > 0), and return
|
||||||
m_literals.push_back(ineq(j, lp::lconstraint_kind::EQ, rational::zero()));
|
m_literals.push_back(ineq(j, lp::lconstraint_kind::EQ, rational::zero()));
|
||||||
TRACE("nla_solver", print_ineq(m_literals.back(), tout) << "\n");
|
TRACE("nla_solver", print_ineq(m_literals.back(), tout) << "\n");
|
||||||
|
|
|
@ -59,21 +59,20 @@ namespace nla {
|
||||||
if (m_delay_base > 0)
|
if (m_delay_base > 0)
|
||||||
--m_delay_base;
|
--m_delay_base;
|
||||||
|
|
||||||
if (is_conflicting())
|
|
||||||
return;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (propagate_bounds())
|
|
||||||
|
if (is_conflicting())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (propagate_eqs())
|
if (propagate_eqs())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (propagate_factorization())
|
if (propagate_factorization())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (propagate_linear_equations())
|
if (propagate_linear_equations())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
|
|
||||||
|
@ -111,17 +110,9 @@ namespace nla {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grobner::propagate_bounds() {
|
|
||||||
unsigned changed = 0;
|
|
||||||
for (auto eq : m_solver.equations())
|
|
||||||
if (propagate_bounds(*eq) && ++changed >= m_solver.number_of_conflicts_to_report())
|
|
||||||
return true;
|
|
||||||
return changed > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool grobner::propagate_eqs() {
|
bool grobner::propagate_eqs() {
|
||||||
unsigned changed = 0;
|
unsigned changed = 0;
|
||||||
for (auto eq : m_solver.equations())
|
for (auto eq : m_solver.equations())
|
||||||
if (propagate_fixed(*eq) && ++changed >= m_solver.number_of_conflicts_to_report())
|
if (propagate_fixed(*eq) && ++changed >= m_solver.number_of_conflicts_to_report())
|
||||||
return true;
|
return true;
|
||||||
return changed > 0;
|
return changed > 0;
|
||||||
|
@ -129,7 +120,7 @@ namespace nla {
|
||||||
|
|
||||||
bool grobner::propagate_factorization() {
|
bool grobner::propagate_factorization() {
|
||||||
unsigned changed = 0;
|
unsigned changed = 0;
|
||||||
for (auto eq : m_solver.equations())
|
for (auto eq : m_solver.equations())
|
||||||
if (propagate_factorization(*eq) && ++changed >= m_solver.number_of_conflicts_to_report())
|
if (propagate_factorization(*eq) && ++changed >= m_solver.number_of_conflicts_to_report())
|
||||||
return true;
|
return true;
|
||||||
return changed > 0;
|
return changed > 0;
|
||||||
|
@ -165,19 +156,12 @@ namespace nla {
|
||||||
rational d = lcm(denominator(a), denominator(b));
|
rational d = lcm(denominator(a), denominator(b));
|
||||||
a *= d;
|
a *= d;
|
||||||
b *= d;
|
b *= d;
|
||||||
#if 0
|
|
||||||
c().lra.update_column_type_and_bound(v, lp::lconstraint_kind::EQ, b/a, eq.dep());
|
|
||||||
lp::explanation exp;
|
|
||||||
explain(eq, exp);
|
|
||||||
c().add_fixed_equality(c().lra.column_to_reported_index(v), b/a, exp);
|
|
||||||
#else
|
|
||||||
ineq new_eq(term(a, v), llc::EQ, b);
|
ineq new_eq(term(a, v), llc::EQ, b);
|
||||||
if (c().ineq_holds(new_eq))
|
if (c().ineq_holds(new_eq))
|
||||||
return false;
|
return false;
|
||||||
new_lemma lemma(c(), "pdd-eq");
|
new_lemma lemma(c(), "pdd-eq");
|
||||||
add_dependencies(lemma, eq);
|
add_dependencies(lemma, eq);
|
||||||
lemma |= new_eq;
|
lemma |= new_eq;
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,73 +361,18 @@ namespace nla {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grobner::propagate_bounds(const dd::solver::equation& e) {
|
|
||||||
return false;
|
|
||||||
// TODO
|
|
||||||
auto& di = c().m_intervals.get_dep_intervals();
|
|
||||||
dd::pdd_interval eval(di);
|
|
||||||
eval.var2interval() = [this](lpvar j, bool deps, scoped_dep_interval& a) {
|
|
||||||
if (deps) c().m_intervals.set_var_interval<dd::w_dep::with_deps>(j, a);
|
|
||||||
else c().m_intervals.set_var_interval<dd::w_dep::without_deps>(j, a);
|
|
||||||
};
|
|
||||||
scoped_dep_interval i(di), i_wd(di);
|
|
||||||
eval.get_interval<dd::w_dep::without_deps>(e.poly(), i);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool grobner::propagate_linear_equations() {
|
bool grobner::propagate_linear_equations() {
|
||||||
unsigned changed = 0;
|
unsigned changed = 0;
|
||||||
m_mon2var.clear();
|
m_mon2var.clear();
|
||||||
for (auto const& m : c().emons())
|
for (auto const& m : c().emons())
|
||||||
m_mon2var[m.vars()] = m.var();
|
m_mon2var[m.vars()] = m.var();
|
||||||
|
|
||||||
for (auto eq : m_solver.equations())
|
for (auto eq : m_solver.equations())
|
||||||
if (propagate_linear_equations(*eq))
|
if (propagate_linear_equations(*eq))
|
||||||
++changed;
|
++changed;
|
||||||
#if 0
|
|
||||||
for (auto eq : m_solver.equations())
|
|
||||||
if (check_missed_bound(*eq))
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
return changed > 0;
|
return changed > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grobner::check_missed_bound(dd::solver::equation const& e) {
|
|
||||||
auto& di = c().m_intervals.get_dep_intervals();
|
|
||||||
auto set_var_interval = [&](lpvar j, scoped_dep_interval& a) {
|
|
||||||
c().m_intervals.set_var_interval<dd::w_dep::with_deps>(j, a);
|
|
||||||
};
|
|
||||||
scoped_dep_interval i(di), t(di), s(di), u(di);
|
|
||||||
di.set_value(i, rational::zero());
|
|
||||||
|
|
||||||
for (auto const& [coeff, vars] : e.poly()) {
|
|
||||||
if (vars.empty())
|
|
||||||
di.add(coeff, i);
|
|
||||||
else {
|
|
||||||
di.set_value(t, coeff);
|
|
||||||
for (auto v : vars) {
|
|
||||||
set_var_interval(v, s);
|
|
||||||
di.mul<dd::w_dep::with_deps>(t, s, t);
|
|
||||||
}
|
|
||||||
if (m_mon2var.find(vars) != m_mon2var.end()) {
|
|
||||||
auto v = m_mon2var.find(vars)->second;
|
|
||||||
set_var_interval(v, u);
|
|
||||||
di.mul<dd::w_dep::with_deps>(coeff, u, u);
|
|
||||||
di.intersect<dd::w_dep::with_deps>(t, u, t);
|
|
||||||
}
|
|
||||||
di.add<dd::w_dep::with_deps>(i, t, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!di.separated_from_zero(i))
|
|
||||||
return false;
|
|
||||||
// m_solver.display(verbose_stream() << "missed bound\n", e);
|
|
||||||
// exit(1);
|
|
||||||
std::function<void (const lp::explanation&)> f = [this](const lp::explanation& e) {
|
|
||||||
new_lemma lemma(m_core, "pdd");
|
|
||||||
lemma &= e;
|
|
||||||
};
|
|
||||||
return di.check_interval_for_conflict_on_zero(i, e.dep(), f);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool grobner::propagate_linear_equations(dd::solver::equation const& e) {
|
bool grobner::propagate_linear_equations(dd::solver::equation const& e) {
|
||||||
if (equation_is_true(e))
|
if (equation_is_true(e))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -35,20 +35,14 @@ namespace nla {
|
||||||
bool is_conflicting();
|
bool is_conflicting();
|
||||||
bool is_conflicting(dd::solver::equation const& eq);
|
bool is_conflicting(dd::solver::equation const& eq);
|
||||||
|
|
||||||
bool propagate_bounds();
|
|
||||||
bool propagate_bounds(dd::solver::equation const& eq);
|
|
||||||
|
|
||||||
bool propagate_eqs();
|
bool propagate_eqs();
|
||||||
bool propagate_fixed(dd::solver::equation const& eq);
|
bool propagate_fixed(dd::solver::equation const& eq);
|
||||||
|
|
||||||
bool propagate_factorization();
|
bool propagate_factorization();
|
||||||
bool propagate_factorization(dd::solver::equation const& eq);
|
bool propagate_factorization(dd::solver::equation const& eq);
|
||||||
|
|
||||||
|
|
||||||
bool propagate_linear_equations();
|
bool propagate_linear_equations();
|
||||||
bool propagate_linear_equations(dd::solver::equation const& eq);
|
bool propagate_linear_equations(dd::solver::equation const& eq);
|
||||||
|
|
||||||
bool check_missed_bound(dd::solver::equation const& eq);
|
|
||||||
|
|
||||||
void add_dependencies(new_lemma& lemma, dd::solver::equation const& eq);
|
void add_dependencies(new_lemma& lemma, dd::solver::equation const& eq);
|
||||||
void explain(dd::solver::equation const& eq, lp::explanation& exp);
|
void explain(dd::solver::equation const& eq, lp::explanation& exp);
|
||||||
|
|
|
@ -164,7 +164,7 @@ namespace sat {
|
||||||
unsigned m_rephase_inc;
|
unsigned m_rephase_inc;
|
||||||
backoff m_rephase;
|
backoff m_rephase;
|
||||||
backoff m_reorder;
|
backoff m_reorder;
|
||||||
var_queue m_case_split_queue;
|
var_queue<unsigned_vector> m_case_split_queue;
|
||||||
unsigned m_qhead;
|
unsigned m_qhead;
|
||||||
unsigned m_scope_lvl;
|
unsigned m_scope_lvl;
|
||||||
unsigned m_search_lvl;
|
unsigned m_search_lvl;
|
||||||
|
|
|
@ -509,10 +509,10 @@ namespace smt {
|
||||||
// Assuming `app` is equal to a constructor term, return the constructor enode
|
// Assuming `app` is equal to a constructor term, return the constructor enode
|
||||||
inline enode * theory_datatype::oc_get_cstor(enode * app) {
|
inline enode * theory_datatype::oc_get_cstor(enode * app) {
|
||||||
theory_var v = app->get_root()->get_th_var(get_id());
|
theory_var v = app->get_root()->get_th_var(get_id());
|
||||||
SASSERT(v != null_theory_var);
|
if (v == null_theory_var)
|
||||||
|
return nullptr;
|
||||||
v = m_find.find(v);
|
v = m_find.find(v);
|
||||||
var_data * d = m_var_data[v];
|
var_data * d = m_var_data[v];
|
||||||
SASSERT(d->m_constructor);
|
|
||||||
return d->m_constructor;
|
return d->m_constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,8 +802,9 @@ namespace smt {
|
||||||
return false;
|
return false;
|
||||||
func_decl* con = m_util.get_accessor_constructor(f);
|
func_decl* con = m_util.get_accessor_constructor(f);
|
||||||
for (enode* app : ctx.enodes_of(f)) {
|
for (enode* app : ctx.enodes_of(f)) {
|
||||||
enode* arg = app->get_arg(0)->get_root();
|
enode* arg = app->get_arg(0);
|
||||||
if (is_constructor(arg) && arg->get_decl() != con)
|
enode* arg_con = oc_get_cstor(arg);
|
||||||
|
if (arg_con && is_constructor(arg_con) && arg_con->get_decl() != con)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -223,6 +223,16 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class dll_elements {
|
||||||
|
T const* m_list;
|
||||||
|
public:
|
||||||
|
dll_elements(T const* list) : m_list(list) {}
|
||||||
|
dll_iterator<T> begin() const { return dll_iterator<T>::mk_begin(m_list); }
|
||||||
|
dll_iterator<T> end() const { return dll_iterator<T>::mk_end(m_list); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template < typename T
|
template < typename T
|
||||||
, typename U = std::enable_if_t<std::is_base_of_v<dll_base<T>, T>> // should only match if T actually inherits from dll_base<T>
|
, typename U = std::enable_if_t<std::is_base_of_v<dll_base<T>, T>> // should only match if T actually inherits from dll_base<T>
|
||||||
>
|
>
|
||||||
|
|
|
@ -316,6 +316,12 @@ unsigned mpq_manager<SYNCH>::prev_power_of_two(mpq const & a) {
|
||||||
return prev_power_of_two(_tmp);
|
return prev_power_of_two(_tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool SYNCH>
|
||||||
|
unsigned mpq_manager<SYNCH>::next_power_of_two(mpq const & a) {
|
||||||
|
_scoped_numeral<mpz_manager<SYNCH> > _tmp(*this);
|
||||||
|
ceil(a, _tmp);
|
||||||
|
return next_power_of_two(_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
template<bool SYNCH>
|
template<bool SYNCH>
|
||||||
template<bool SUB>
|
template<bool SUB>
|
||||||
|
|
|
@ -848,6 +848,14 @@ public:
|
||||||
unsigned prev_power_of_two(mpz const & a) { return mpz_manager<SYNCH>::prev_power_of_two(a); }
|
unsigned prev_power_of_two(mpz const & a) { return mpz_manager<SYNCH>::prev_power_of_two(a); }
|
||||||
unsigned prev_power_of_two(mpq const & a);
|
unsigned prev_power_of_two(mpq const & a);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Return the smallest k s.t. a <= 2^k.
|
||||||
|
|
||||||
|
\remark Return 0 if a is not positive.
|
||||||
|
*/
|
||||||
|
unsigned next_power_of_two(mpz const & a) { return mpz_manager<SYNCH>::next_power_of_two(a); }
|
||||||
|
unsigned next_power_of_two(mpq const & a);
|
||||||
|
|
||||||
bool is_int_perfect_square(mpq const & a, mpq & r) {
|
bool is_int_perfect_square(mpq const & a, mpq & r) {
|
||||||
SASSERT(is_int(a));
|
SASSERT(is_int(a));
|
||||||
reset_denominator(r);
|
reset_denominator(r);
|
||||||
|
|
|
@ -2288,6 +2288,19 @@ unsigned mpz_manager<SYNCH>::bitsize(mpz const & a) {
|
||||||
return mlog2(a) + 1;
|
return mlog2(a) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool SYNCH>
|
||||||
|
unsigned mpz_manager<SYNCH>::next_power_of_two(mpz const & a) {
|
||||||
|
if (is_nonpos(a))
|
||||||
|
return 0;
|
||||||
|
if (is_one(a))
|
||||||
|
return 0;
|
||||||
|
unsigned shift;
|
||||||
|
if (is_power_of_two(a, shift))
|
||||||
|
return shift;
|
||||||
|
else
|
||||||
|
return log2(a) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
template<bool SYNCH>
|
template<bool SYNCH>
|
||||||
bool mpz_manager<SYNCH>::is_perfect_square(mpz const & a, mpz & root) {
|
bool mpz_manager<SYNCH>::is_perfect_square(mpz const & a, mpz & root) {
|
||||||
if (is_neg(a))
|
if (is_neg(a))
|
||||||
|
|
|
@ -692,6 +692,13 @@ public:
|
||||||
\remark Return 0 if a is not positive.
|
\remark Return 0 if a is not positive.
|
||||||
*/
|
*/
|
||||||
unsigned prev_power_of_two(mpz const & a) { return log2(a); }
|
unsigned prev_power_of_two(mpz const & a) { return log2(a); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Return the smallest k s.t. a <= 2^k.
|
||||||
|
|
||||||
|
\remark Return 0 if a is not positive.
|
||||||
|
*/
|
||||||
|
unsigned next_power_of_two(mpz const & a);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return true if a^{1/n} is an integer, and store the result in a.
|
\brief Return true if a^{1/n} is an integer, and store the result in a.
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
explicit rational(double z) { UNREACHABLE(); }
|
explicit rational(double z) { UNREACHABLE(); }
|
||||||
|
|
||||||
explicit rational(char const * v) { m().set(m_val, v); }
|
explicit rational(char const * v) { m().set(m_val, v); }
|
||||||
|
|
||||||
explicit rational(unsigned const * v, unsigned sz) { m().set(m_val, sz, v); }
|
explicit rational(unsigned const * v, unsigned sz) { m().set(m_val, sz, v); }
|
||||||
|
|
||||||
struct i64 {};
|
struct i64 {};
|
||||||
|
@ -489,6 +489,18 @@ public:
|
||||||
return get_num_digits(rational(10));
|
return get_num_digits(rational(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the biggest k s.t. 2^k <= a.
|
||||||
|
* \remark Return 0 if a is not positive.
|
||||||
|
*/
|
||||||
|
unsigned prev_power_of_two() const { return m().prev_power_of_two(m_val); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the smallest k s.t. a <= 2^k.
|
||||||
|
* \remark Return 0 if a is not positive.
|
||||||
|
*/
|
||||||
|
unsigned next_power_of_two() const { return m().next_power_of_two(m_val); }
|
||||||
|
|
||||||
bool get_bit(unsigned index) const {
|
bool get_bit(unsigned index) const {
|
||||||
return m().get_bit(m_val, index);
|
return m().get_bit(m_val, index);
|
||||||
}
|
}
|
||||||
|
@ -501,6 +513,15 @@ public:
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Number of trailing zeros in an N-bit representation */
|
||||||
|
unsigned parity(unsigned num_bits) const {
|
||||||
|
SASSERT(!is_neg());
|
||||||
|
SASSERT(*this < rational::power_of_two(num_bits));
|
||||||
|
if (is_zero())
|
||||||
|
return num_bits;
|
||||||
|
return trailing_zeros();
|
||||||
|
}
|
||||||
|
|
||||||
static bool limit_denominator(rational &num, rational const& limit);
|
static bool limit_denominator(rational &num, rational const& limit);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -649,3 +670,7 @@ inline rational gcd(rational const & r1, rational const & r2, rational & a, rati
|
||||||
rational::m().gcd(r1.m_val, r2.m_val, a.m_val, b.m_val, result.m_val);
|
rational::m().gcd(r1.m_val, r2.m_val, a.m_val, b.m_val, result.m_val);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void swap(rational& r1, rational& r2) {
|
||||||
|
r1.swap(r2);
|
||||||
|
}
|
||||||
|
|
|
@ -21,20 +21,20 @@ Revision History:
|
||||||
#include "util/heap.h"
|
#include "util/heap.h"
|
||||||
|
|
||||||
|
|
||||||
|
template <class ActivityVector>
|
||||||
class var_queue {
|
class var_queue {
|
||||||
typedef unsigned var;
|
typedef unsigned var;
|
||||||
|
|
||||||
struct lt {
|
struct lt {
|
||||||
svector<unsigned> & m_activity;
|
ActivityVector & m_activity;
|
||||||
lt(svector<unsigned> & act):m_activity(act) {}
|
lt(ActivityVector & act):m_activity(act) {}
|
||||||
bool operator()(var v1, var v2) const { return m_activity[v1] > m_activity[v2]; }
|
bool operator()(var v1, var v2) const { return m_activity[v1] > m_activity[v2]; }
|
||||||
};
|
};
|
||||||
heap<lt> m_queue;
|
heap<lt> m_queue;
|
||||||
public:
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
var_queue(svector<unsigned> & act):m_queue(128, lt(act)) {}
|
var_queue(ActivityVector & act):m_queue(128, lt(act)) {}
|
||||||
|
|
||||||
void activity_increased_eh(var v) {
|
void activity_increased_eh(var v) {
|
||||||
if (m_queue.contains(v))
|
if (m_queue.contains(v))
|
||||||
|
@ -68,6 +68,8 @@ public:
|
||||||
void reset() {
|
void reset() {
|
||||||
m_queue.reset();
|
m_queue.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool contains(var v) const { return m_queue.contains(v); }
|
||||||
|
|
||||||
bool empty() const { return m_queue.empty(); }
|
bool empty() const { return m_queue.empty(); }
|
||||||
|
|
||||||
|
@ -90,11 +92,12 @@ public:
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
using const_iterator = decltype(m_queue)::const_iterator;
|
using const_iterator = const int *;
|
||||||
const_iterator begin() const { return m_queue.begin(); }
|
const_iterator begin() const { return m_queue.begin(); }
|
||||||
const_iterator end() const { return m_queue.end(); }
|
const_iterator end() const { return m_queue.end(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, var_queue const& queue) {
|
template <typename T>
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, var_queue<T> const& queue) {
|
||||||
return queue.display(out);
|
return queue.display(out);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue