mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	remove hassel table from unstable: does not compile under other plantforms
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									b670f0bb69
								
							
						
					
					
						commit
						c0895e5548
					
				
					 21 changed files with 1070 additions and 2935 deletions
				
			
		| 
						 | 
				
			
			@ -399,4 +399,4 @@
 | 
			
		|||
  <Target Name="AfterBuild">
 | 
			
		||||
  </Target>
 | 
			
		||||
  -->
 | 
			
		||||
</Project>
 | 
			
		||||
</Project>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,23 +1,23 @@
 | 
			
		|||
This directory contains scripts to build the test application using
 | 
			
		||||
OCaml. You also need CamlIDL to be able to generate the OCaml API.
 | 
			
		||||
 | 
			
		||||
- To download OCaml:
 | 
			
		||||
  http://caml.inria.fr/ocaml/      
 | 
			
		||||
 | 
			
		||||
- To download CamlIDL:
 | 
			
		||||
  http://forge.ocamlcore.org/projects/camlidl/
 | 
			
		||||
 | 
			
		||||
- One must build the OCaml library before compiling the example.
 | 
			
		||||
  Go to directory ../ocaml
 | 
			
		||||
 | 
			
		||||
- Use 'build-test.cmd' to build the test application using the OCaml compiler.
 | 
			
		||||
 | 
			
		||||
Remark: The OCaml and C compiler tool chains must be configured in your environment.
 | 
			
		||||
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
 | 
			
		||||
 | 
			
		||||
- The script 'exec.cmd' adds the bin directory to the path. So,
 | 
			
		||||
  test_mlapi.exe can find z3.dll.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
This directory contains scripts to build the test application using
 | 
			
		||||
OCaml. You also need CamlIDL to be able to generate the OCaml API.
 | 
			
		||||
 | 
			
		||||
- To download OCaml:
 | 
			
		||||
  http://caml.inria.fr/ocaml/      
 | 
			
		||||
 | 
			
		||||
- To download CamlIDL:
 | 
			
		||||
  http://forge.ocamlcore.org/projects/camlidl/
 | 
			
		||||
 | 
			
		||||
- One must build the OCaml library before compiling the example.
 | 
			
		||||
  Go to directory ../ocaml
 | 
			
		||||
 | 
			
		||||
- Use 'build-test.cmd' to build the test application using the OCaml compiler.
 | 
			
		||||
 | 
			
		||||
Remark: The OCaml and C compiler tool chains must be configured in your environment.
 | 
			
		||||
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
 | 
			
		||||
 | 
			
		||||
- The script 'exec.cmd' adds the bin directory to the path. So,
 | 
			
		||||
  test_mlapi.exe can find z3.dll.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,23 +1,23 @@
 | 
			
		|||
The OCaml API for Z3 was tested using OCaml 3.12.1.
 | 
			
		||||
You also need CamlIDL to be able to generate the OCaml API.
 | 
			
		||||
 | 
			
		||||
- To download OCaml:
 | 
			
		||||
  http://caml.inria.fr/ocaml/      
 | 
			
		||||
 | 
			
		||||
- To download CamlIDL:
 | 
			
		||||
  http://forge.ocamlcore.org/projects/camlidl/
 | 
			
		||||
 | 
			
		||||
- To build the OCaml API for Z3:
 | 
			
		||||
  .\build-lib.cmd
 | 
			
		||||
 | 
			
		||||
Remark: The OCaml and C compiler tool chains must be configured in your environment.
 | 
			
		||||
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
 | 
			
		||||
 | 
			
		||||
Remark: Building the OCaml API copies some pathnames into files,
 | 
			
		||||
so the OCaml API must be recompiled if the Z3 library files are moved.
 | 
			
		||||
 | 
			
		||||
See ..\examples\ocaml\build-test.cmd for an example of how to compile and link with Z3.
 | 
			
		||||
 | 
			
		||||
Acknowledgements:
 | 
			
		||||
The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg. 
 | 
			
		||||
Many thanks to them!
 | 
			
		||||
The OCaml API for Z3 was tested using OCaml 3.12.1.
 | 
			
		||||
You also need CamlIDL to be able to generate the OCaml API.
 | 
			
		||||
 | 
			
		||||
- To download OCaml:
 | 
			
		||||
  http://caml.inria.fr/ocaml/      
 | 
			
		||||
 | 
			
		||||
- To download CamlIDL:
 | 
			
		||||
  http://forge.ocamlcore.org/projects/camlidl/
 | 
			
		||||
 | 
			
		||||
- To build the OCaml API for Z3:
 | 
			
		||||
  .\build-lib.cmd
 | 
			
		||||
 | 
			
		||||
Remark: The OCaml and C compiler tool chains must be configured in your environment.
 | 
			
		||||
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
 | 
			
		||||
 | 
			
		||||
Remark: Building the OCaml API copies some pathnames into files,
 | 
			
		||||
so the OCaml API must be recompiled if the Z3 library files are moved.
 | 
			
		||||
 | 
			
		||||
See ..\examples\ocaml\build-test.cmd for an example of how to compile and link with Z3.
 | 
			
		||||
 | 
			
		||||
Acknowledgements:
 | 
			
		||||
The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg. 
 | 
			
		||||
Many thanks to them!
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
@echo off
 | 
			
		||||
 | 
			
		||||
call .\compile_mlapi.cmd ..\include ..\bin ..\bin
 | 
			
		||||
@echo off
 | 
			
		||||
 | 
			
		||||
call .\compile_mlapi.cmd ..\include ..\bin ..\bin
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,19 +1,19 @@
 | 
			
		|||
@echo off
 | 
			
		||||
 | 
			
		||||
if not exist ..\..\ocaml\z3.cmxa (
 | 
			
		||||
        echo "YOU MUST BUILD OCAML API! Go to directory ..\ocaml"
 | 
			
		||||
        goto :EOF
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
REM ocaml (>= 3.11) calls the linker through flexlink
 | 
			
		||||
ocamlc -version >> ocaml_version
 | 
			
		||||
set /p OCAML_VERSION= <ocaml_version
 | 
			
		||||
if %OCAML_VERSION% GEQ 3.11 (
 | 
			
		||||
    set XCFLAGS=
 | 
			
		||||
) else (
 | 
			
		||||
    set XCFLAGS=/nologo /MT /DWIN32
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
ocamlc -w A -ccopt "%XCFLAGS%" -o test_mlapi_byte.exe -I ..\..\ocaml z3.cma test_mlapi.ml
 | 
			
		||||
 | 
			
		||||
ocamlopt -w A -ccopt "%XCFLAGS%" -o test_mlapi.exe -I ..\..\ocaml z3.cmxa test_mlapi.ml
 | 
			
		||||
@echo off
 | 
			
		||||
 | 
			
		||||
if not exist ..\..\ocaml\z3.cmxa (
 | 
			
		||||
        echo "YOU MUST BUILD OCAML API! Go to directory ..\ocaml"
 | 
			
		||||
        goto :EOF
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
REM ocaml (>= 3.11) calls the linker through flexlink
 | 
			
		||||
ocamlc -version >> ocaml_version
 | 
			
		||||
set /p OCAML_VERSION= <ocaml_version
 | 
			
		||||
if %OCAML_VERSION% GEQ 3.11 (
 | 
			
		||||
    set XCFLAGS=
 | 
			
		||||
) else (
 | 
			
		||||
    set XCFLAGS=/nologo /MT /DWIN32
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
ocamlc -w A -ccopt "%XCFLAGS%" -o test_mlapi_byte.exe -I ..\..\ocaml z3.cma test_mlapi.ml
 | 
			
		||||
 | 
			
		||||
ocamlopt -w A -ccopt "%XCFLAGS%" -o test_mlapi.exe -I ..\..\ocaml z3.cmxa test_mlapi.ml
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
@echo off
 | 
			
		||||
SETLOCAL
 | 
			
		||||
set PATH=..\..\bin;%PATH%
 | 
			
		||||
test_mlapi.exe
 | 
			
		||||
ENDLOCAL
 | 
			
		||||
@echo off
 | 
			
		||||
SETLOCAL
 | 
			
		||||
set PATH=..\..\bin;%PATH%
 | 
			
		||||
test_mlapi.exe
 | 
			
		||||
ENDLOCAL
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,2 +1,2 @@
 | 
			
		|||
Command context provides the infrastructure for executing commands in front-ends such as SMT-LIB 2.0.
 | 
			
		||||
It is also provides the solver abstraction to plugin solvers in this kind of front-end.
 | 
			
		||||
It is also provides the solver abstraction to plugin solvers in this kind of front-end.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,2 +1,2 @@
 | 
			
		|||
Basic Euclidean solver for linear integer equations.
 | 
			
		||||
This solver generates "explanations". 
 | 
			
		||||
This solver generates "explanations". 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,2 +1,2 @@
 | 
			
		|||
Template for interval arithmetic. The template can be instantiated using different numeral (integers/mpz, rationals/mpq, floating-point/mpf, etc) packages.
 | 
			
		||||
The class im_default_config defines a default configuration for the template that uses rationals. It also shows what is the expected signature used by the template.
 | 
			
		||||
The class im_default_config defines a default configuration for the template that uses rationals. It also shows what is the expected signature used by the template.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
Polynomial manipulation package.
 | 
			
		||||
It contains support for univariate (upolynomial.*) and multivariate polynomials (polynomial.*).
 | 
			
		||||
Multivariate polynomial factorization does not work yet (polynomial_factorization.*), and it is disabled.
 | 
			
		||||
Multivariate polynomial factorization does not work yet (polynomial_factorization.*), and it is disabled.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,434 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2013 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    dl_hassel_common.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include "dl_hassel_common.h"
 | 
			
		||||
#include "dl_context.h"
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
namespace datalog {
 | 
			
		||||
 | 
			
		||||
    static void formula_to_dnf_aux(app *and, unsigned idx, std::set<expr*>& conjexpr, std::set<expr*>& toplevel, ast_manager& m) {
 | 
			
		||||
        if (idx == and->get_num_args()) {
 | 
			
		||||
            std::vector<expr*> v(conjexpr.begin(), conjexpr.end());
 | 
			
		||||
            toplevel.insert(m.mk_and((unsigned)v.size(), &v[0]));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        expr *e = and->get_arg(idx);
 | 
			
		||||
        if (is_app(e) && to_app(e)->get_decl_kind() == OP_OR) {
 | 
			
		||||
            app *or = to_app(e);
 | 
			
		||||
            // quick subsumption test: if any of the elements of the OR is already ANDed, then we skip this OR
 | 
			
		||||
            for (unsigned i = 0; i < or->get_num_args(); ++i) {
 | 
			
		||||
                if (conjexpr.count(or->get_arg(i))) {
 | 
			
		||||
                    formula_to_dnf_aux(and, idx+1, conjexpr, toplevel, m);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (unsigned i = 0; i < or->get_num_args(); ++i) {
 | 
			
		||||
                std::set<expr*> conjexpr2(conjexpr);
 | 
			
		||||
                conjexpr2.insert(or->get_arg(i));
 | 
			
		||||
                formula_to_dnf_aux(and, idx+1, conjexpr2, toplevel, m);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            conjexpr.insert(e);
 | 
			
		||||
            formula_to_dnf_aux(and, idx+1, conjexpr, toplevel, m);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    expr_ref formula_to_dnf(expr_ref f) {
 | 
			
		||||
        app *a = to_app(f);
 | 
			
		||||
        SASSERT(a->get_decl_kind() == OP_AND);
 | 
			
		||||
        std::set<expr*> toplevel, conjexpr;
 | 
			
		||||
        formula_to_dnf_aux(a, 0, conjexpr, toplevel, f.m());
 | 
			
		||||
 | 
			
		||||
        if (toplevel.size() > 1) {
 | 
			
		||||
            std::vector<expr*> v(toplevel.begin(), toplevel.end());
 | 
			
		||||
            return expr_ref(f.m().mk_or((unsigned)v.size(), &v[0]), f.m());
 | 
			
		||||
        } else {
 | 
			
		||||
            return expr_ref(*toplevel.begin(), f.m());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool bit_vector::contains(const bit_vector & other) const {
 | 
			
		||||
        unsigned n = num_words();
 | 
			
		||||
        if (n == 0)
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < n - 1; ++i) {
 | 
			
		||||
            if ((m_data[i] & other.m_data[i]) != other.m_data[i])
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
        unsigned bit_rest = m_num_bits % 32;
 | 
			
		||||
        unsigned mask = (1 << bit_rest) - 1;
 | 
			
		||||
        if (mask == 0) mask = UINT_MAX;
 | 
			
		||||
        unsigned other_data = other.m_data[n-1] & mask;
 | 
			
		||||
        return (m_data[n-1] & other_data) == other_data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool bit_vector::contains(const bit_vector & other, unsigned idx) const {
 | 
			
		||||
        // TODO: optimize this to avoid copy
 | 
			
		||||
        return slice(idx, other.size()).contains(other);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool bit_vector::contains_consecutive_zeros() const {
 | 
			
		||||
        unsigned n = num_words();
 | 
			
		||||
        if (n == 0)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < n - 1; ++i) {
 | 
			
		||||
            if ((((m_data[i] << 1) | m_data[i]) & 0xAAAAAAAA) != 0xAAAAAAAA)
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
        unsigned bit_rest = m_num_bits % 32;
 | 
			
		||||
        unsigned mask = (1 << bit_rest) - 1;
 | 
			
		||||
        if (mask == 0) mask = UINT_MAX;
 | 
			
		||||
        mask &= 0xAAAAAAAA;
 | 
			
		||||
        return ((((m_data[n-1] << 1) | m_data[n-1]) & mask) != mask);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bit_vector bit_vector::slice(unsigned idx, unsigned length) const {
 | 
			
		||||
        bit_vector Res(length);
 | 
			
		||||
        // TODO: optimize w/ memcpy when possible
 | 
			
		||||
        for (unsigned i = idx; i < idx + length; ++i) {
 | 
			
		||||
            Res.push_back(get(i));
 | 
			
		||||
        }
 | 
			
		||||
        SASSERT(Res.size() == length);
 | 
			
		||||
        return Res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void bit_vector::append(const bit_vector & other) {
 | 
			
		||||
        if (other.empty())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if ((m_num_bits % 32) == 0) {
 | 
			
		||||
            unsigned prev_num_bits = m_num_bits;
 | 
			
		||||
            resize(m_num_bits + other.m_num_bits);
 | 
			
		||||
            memcpy(&get_bit_word(prev_num_bits), other.m_data, other.num_words() * sizeof(unsigned));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO: optimize the other cases.
 | 
			
		||||
        for (unsigned i = 0; i < other.m_num_bits; ++i) {
 | 
			
		||||
            push_back(other.get(i));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint64 bit_vector::to_number(unsigned idx, unsigned length) const {
 | 
			
		||||
        SASSERT(length <= 64);
 | 
			
		||||
        uint64 r = 0;
 | 
			
		||||
        for (unsigned i = 0; i < length; ++i) {
 | 
			
		||||
            r = (r << 1) | (uint64)get(idx+i);
 | 
			
		||||
        }
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool bit_vector::operator<(bit_vector const & other) const {
 | 
			
		||||
        SASSERT(m_num_bits == other.m_num_bits);
 | 
			
		||||
        unsigned n = num_words();
 | 
			
		||||
        if (n == 0)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < n - 1; ++i) {
 | 
			
		||||
            if (m_data[i] > other.m_data[i])
 | 
			
		||||
               return false;
 | 
			
		||||
            if (m_data[i] < other.m_data[i])
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        unsigned bit_rest = m_num_bits % 32;
 | 
			
		||||
        unsigned mask = (1 << bit_rest) - 1;
 | 
			
		||||
        if (mask == 0) mask = UINT_MAX;
 | 
			
		||||
        return (m_data[n-1] & mask) < (other.m_data[n-1] & mask);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    table_information::table_information(table_plugin & p, const table_signature& sig) :
 | 
			
		||||
        m_column_info(sig.size()+1),
 | 
			
		||||
        m_bv_util(p.get_context().get_manager()),
 | 
			
		||||
        m_decl_util(p.get_context().get_manager()) {
 | 
			
		||||
 | 
			
		||||
        unsigned column = 0;
 | 
			
		||||
        for (unsigned i = 0; i < sig.size(); ++i) {
 | 
			
		||||
            unsigned num_bits = uint64_log2(sig[i]);
 | 
			
		||||
            SASSERT(num_bits == 64 || (1ULL << num_bits) == sig[i]);
 | 
			
		||||
            m_column_info[i] = column;
 | 
			
		||||
            column += num_bits;
 | 
			
		||||
        }
 | 
			
		||||
        m_column_info[sig.size()] = column;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void table_information::expand_column_vector(unsigned_vector& v, const table_information *other) const {
 | 
			
		||||
        unsigned_vector orig;
 | 
			
		||||
        orig.swap(v);
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < orig.size(); ++i) {
 | 
			
		||||
            unsigned col, limit;
 | 
			
		||||
            if (orig[i] < get_num_cols()) {
 | 
			
		||||
                col = column_idx(orig[i]);
 | 
			
		||||
                limit = col + column_num_bits(orig[i]);
 | 
			
		||||
            } else {
 | 
			
		||||
                unsigned idx = orig[i] - get_num_cols();
 | 
			
		||||
                col = get_num_bits() + other->column_idx(idx);
 | 
			
		||||
                limit = col + other->column_num_bits(idx);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (; col < limit; ++col) {
 | 
			
		||||
                v.push_back(col);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void table_information::display(std::ostream & out) const {
 | 
			
		||||
        out << '<';
 | 
			
		||||
        for (unsigned i = 0; i < get_num_cols(); ++i) {
 | 
			
		||||
            if (i > 0)
 | 
			
		||||
                out << ", ";
 | 
			
		||||
            out << column_num_bits(i);
 | 
			
		||||
        }
 | 
			
		||||
        out << ">\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ternary_bitvector::ternary_bitvector(unsigned size, bool full) :
 | 
			
		||||
        bit_vector() {
 | 
			
		||||
        resize(size, full);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ternary_bitvector::ternary_bitvector(uint64 n, unsigned num_bits) :
 | 
			
		||||
        bit_vector(2 * num_bits) {
 | 
			
		||||
        append_number(n, num_bits);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ternary_bitvector::ternary_bitvector(const table_fact& f, const table_information& t) :
 | 
			
		||||
        bit_vector(2 * t.get_num_bits()) {
 | 
			
		||||
        for (unsigned i = 0; i < f.size(); ++i) {
 | 
			
		||||
            SASSERT(t.column_idx(i) == size());
 | 
			
		||||
            append_number(f[i], t.column_num_bits(i));
 | 
			
		||||
        }
 | 
			
		||||
        SASSERT(size() == t.get_num_bits());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::fill1() {
 | 
			
		||||
        memset(m_data, 0xFF, m_capacity * sizeof(unsigned));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned ternary_bitvector::get(unsigned idx) const {
 | 
			
		||||
        idx *= 2;
 | 
			
		||||
        return (bit_vector::get(idx) << 1) | (unsigned)bit_vector::get(idx+1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::set(unsigned idx, unsigned val) {
 | 
			
		||||
        SASSERT(val == BIT_0 || val == BIT_1 || val == BIT_x);
 | 
			
		||||
        idx *= 2;
 | 
			
		||||
        bit_vector::set(idx,   (val >> 1) != 0);
 | 
			
		||||
        bit_vector::set(idx+1, (val & 1)  != 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::push_back(unsigned val) {
 | 
			
		||||
        SASSERT(val == BIT_0 || val == BIT_1 || val == BIT_x);
 | 
			
		||||
        bit_vector::push_back((val >> 1) != 0);
 | 
			
		||||
        bit_vector::push_back((val & 1)  != 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::append_number(uint64 n, unsigned num_bits) {
 | 
			
		||||
        SASSERT(num_bits <= 64);
 | 
			
		||||
        for (int bit = num_bits-1; bit >= 0; --bit) {
 | 
			
		||||
            if (n & (1ULL << bit)) {
 | 
			
		||||
                push_back(BIT_1);
 | 
			
		||||
            } else {
 | 
			
		||||
                push_back(BIT_0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::mk_idx_eq(unsigned idx, ternary_bitvector& val) {
 | 
			
		||||
        for (unsigned i = 0; i < val.size(); ++i) {
 | 
			
		||||
            set(idx+i, val.get(i));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ternary_bitvector ternary_bitvector::and(const ternary_bitvector& other) const{
 | 
			
		||||
        ternary_bitvector result(*this);
 | 
			
		||||
        result &= other;
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::neg(union_ternary_bitvector<ternary_bitvector>& result) const {
 | 
			
		||||
        ternary_bitvector negated;
 | 
			
		||||
        negated.resize(size());
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < size(); ++i) {
 | 
			
		||||
            switch (get(i)) {
 | 
			
		||||
            case BIT_0:
 | 
			
		||||
                negated.fill1();
 | 
			
		||||
                negated.set(i, BIT_1);
 | 
			
		||||
                break;
 | 
			
		||||
            case BIT_1:
 | 
			
		||||
                negated.fill1();
 | 
			
		||||
                negated.set(i, BIT_0);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            result.add_fact(negated);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void join_fix_eqs(ternary_bitvector& TBV, unsigned idx, unsigned col2_offset,
 | 
			
		||||
                             const unsigned_vector& cols1, const unsigned_vector& cols2,
 | 
			
		||||
                             union_ternary_bitvector<ternary_bitvector>& result) {
 | 
			
		||||
        if (idx == cols1.size()) {
 | 
			
		||||
            result.add_fact(TBV);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        unsigned idx1 = cols1[idx];
 | 
			
		||||
        unsigned idx2 = cols2[idx] + col2_offset;
 | 
			
		||||
        unsigned v1 = TBV.get(idx1);
 | 
			
		||||
        unsigned v2 = TBV.get(idx2);
 | 
			
		||||
 | 
			
		||||
        if (v1 == BIT_x) {
 | 
			
		||||
            if (v2 == BIT_x) {
 | 
			
		||||
                // both x: duplicate row
 | 
			
		||||
                ternary_bitvector TBV2(TBV);
 | 
			
		||||
                TBV2.set(idx1, BIT_0);
 | 
			
		||||
                TBV2.set(idx2, BIT_0);
 | 
			
		||||
                join_fix_eqs(TBV2, idx+1, col2_offset, cols1, cols2, result);
 | 
			
		||||
 | 
			
		||||
                TBV.set(idx1, BIT_1);
 | 
			
		||||
                TBV.set(idx2, BIT_1);
 | 
			
		||||
            } else {
 | 
			
		||||
                TBV.set(idx1, v2);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (v2 == BIT_x) {
 | 
			
		||||
            TBV.set(idx2, v1);
 | 
			
		||||
        } else if (v1 != v2) {
 | 
			
		||||
            // columns don't match
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        join_fix_eqs(TBV, idx+1, col2_offset, cols1, cols2, result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::join(const ternary_bitvector& other,
 | 
			
		||||
                                 const unsigned_vector& cols1,
 | 
			
		||||
                                 const unsigned_vector& cols2,
 | 
			
		||||
                                 union_ternary_bitvector<ternary_bitvector>& result) const {
 | 
			
		||||
        ternary_bitvector TBV(*this);
 | 
			
		||||
        TBV.append(other);
 | 
			
		||||
        join_fix_eqs(TBV, 0, size(), cols1, cols2, result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool ternary_bitvector::project(const unsigned_vector& delcols, ternary_bitvector& result) const {
 | 
			
		||||
        unsigned *rm_cols = delcols.c_ptr();
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < size(); ++i) {
 | 
			
		||||
            if (*rm_cols == i) {
 | 
			
		||||
                ++rm_cols;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            result.push_back(get(i));
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void copy_column(ternary_bitvector& CopyTo, const ternary_bitvector& CopyFrom,
 | 
			
		||||
                            unsigned col_dst, unsigned col_src, const table_information& src_table,
 | 
			
		||||
                            const table_information& dst_table) {
 | 
			
		||||
        unsigned idx_dst = dst_table.column_idx(col_dst);
 | 
			
		||||
        unsigned idx_src = src_table.column_idx(col_src);
 | 
			
		||||
        unsigned num_bits = dst_table.column_num_bits(col_dst);
 | 
			
		||||
        SASSERT(num_bits == src_table.column_num_bits(col_src));
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < num_bits; ++i) {
 | 
			
		||||
            CopyTo.set(idx_dst+i, CopyFrom.get(idx_src+i));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::rename(const unsigned_vector& cyclecols,
 | 
			
		||||
                                   const unsigned_vector& out_of_cycle_cols,
 | 
			
		||||
                                   const table_information& src_table,
 | 
			
		||||
                                   const table_information& dst_table,
 | 
			
		||||
                                   ternary_bitvector& result) const {
 | 
			
		||||
        result.resize(dst_table.get_num_bits());
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 1; i < cyclecols.size(); ++i) {
 | 
			
		||||
            copy_column(result, *this, cyclecols[i-1], cyclecols[i], src_table, dst_table);
 | 
			
		||||
        }
 | 
			
		||||
        copy_column(result, *this, cyclecols[cyclecols.size()-1], cyclecols[0], src_table, dst_table);
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < out_of_cycle_cols.size(); ++i) {
 | 
			
		||||
            unsigned col = out_of_cycle_cols[i];
 | 
			
		||||
            copy_column(result, *this, col, col, src_table, dst_table);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned ternary_bitvector::size_in_bytes() const {
 | 
			
		||||
        return sizeof(*this) + m_capacity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::display(std::ostream & out) const {
 | 
			
		||||
        for (unsigned i = 0; i < size(); ++i) {
 | 
			
		||||
            switch (get(i)) {
 | 
			
		||||
            case BIT_0:
 | 
			
		||||
                out << '0';
 | 
			
		||||
                break;
 | 
			
		||||
            case BIT_1:
 | 
			
		||||
                out << '1';
 | 
			
		||||
                break;
 | 
			
		||||
            case BIT_x:
 | 
			
		||||
                out << 'x';
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                UNREACHABLE();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if Z3DEBUG
 | 
			
		||||
    void ternary_bitvector::expand(std::set<bit_vector> & BVs) const {
 | 
			
		||||
        bit_vector BV(m_num_bits);
 | 
			
		||||
        expand(BVs, BV, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_bitvector::expand(std::set<bit_vector> & BVs, bit_vector &BV, unsigned idx) const {
 | 
			
		||||
        if (idx == size()) {
 | 
			
		||||
            BVs.insert(BV);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (get(idx)) {
 | 
			
		||||
        case BIT_0:
 | 
			
		||||
            BV.push_back(false);
 | 
			
		||||
            expand(BVs, BV, idx+1);
 | 
			
		||||
            break;
 | 
			
		||||
        case BIT_1:
 | 
			
		||||
            BV.push_back(true);
 | 
			
		||||
            expand(BVs, BV, idx+1);
 | 
			
		||||
            break;
 | 
			
		||||
        case BIT_x: { // x: duplicate
 | 
			
		||||
            bit_vector BV2(BV);
 | 
			
		||||
            BV.push_back(false);
 | 
			
		||||
            BV2.push_back(true);
 | 
			
		||||
            expand(BVs, BV, idx+1);
 | 
			
		||||
            expand(BVs, BV2, idx+1);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,219 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2013 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    dl_hassel_diff_table.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include "ast_printer.h"
 | 
			
		||||
#include "dl_context.h"
 | 
			
		||||
#include "dl_util.h"
 | 
			
		||||
#include "dl_hassel_diff_table.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace datalog {
 | 
			
		||||
 | 
			
		||||
    ternary_diff_bitvector::ternary_diff_bitvector(unsigned size, bool full) :
 | 
			
		||||
        m_pos(size, full), m_neg(size) { }
 | 
			
		||||
 | 
			
		||||
    ternary_diff_bitvector::ternary_diff_bitvector(uint64 n, unsigned num_bits) :
 | 
			
		||||
        m_pos(n, num_bits), m_neg(num_bits) { }
 | 
			
		||||
 | 
			
		||||
    ternary_diff_bitvector::ternary_diff_bitvector(const ternary_bitvector & tbv) :
 | 
			
		||||
        m_pos(tbv), m_neg(tbv.size()) { }
 | 
			
		||||
 | 
			
		||||
    bool ternary_diff_bitvector::contains(const ternary_diff_bitvector & other) const {
 | 
			
		||||
        return m_pos.contains(other.m_pos) && other.m_neg.contains(m_neg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool ternary_diff_bitvector::is_empty() const {
 | 
			
		||||
        if (m_pos.is_empty())
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        return m_neg.contains(m_pos);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ternary_diff_bitvector ternary_diff_bitvector::and(const ternary_diff_bitvector& other) const {
 | 
			
		||||
        ternary_diff_bitvector result(m_pos.and(other.m_pos));
 | 
			
		||||
        result.m_neg.swap(m_neg.or(other.m_neg));
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_diff_bitvector::neg(union_ternary_bitvector<ternary_diff_bitvector>& result) const {
 | 
			
		||||
        // not(A\B) <-> (T\A) U B
 | 
			
		||||
        ternary_diff_bitvector negated(size(), true);
 | 
			
		||||
        negated.m_neg.add_new_fact(m_pos);
 | 
			
		||||
        result.add_fact(negated);
 | 
			
		||||
 | 
			
		||||
        for (union_ternary_bitvector<ternary_bitvector>::const_iterator I = m_neg.begin(),
 | 
			
		||||
            E = m_neg.end(); I != E; ++I) {
 | 
			
		||||
            result.add_fact(*I);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_diff_bitvector::subtract(const union_ternary_bitvector<ternary_diff_bitvector>& other,
 | 
			
		||||
        union_ternary_bitvector<ternary_diff_bitvector>& result) const {
 | 
			
		||||
        ternary_diff_bitvector newfact(*this);
 | 
			
		||||
        for (union_ternary_bitvector<ternary_diff_bitvector>::const_iterator I = other.begin(),
 | 
			
		||||
            E = other.end(); I != E; ++I) {
 | 
			
		||||
            if (!I->m_neg.empty()) {
 | 
			
		||||
                NOT_IMPLEMENTED_YET();
 | 
			
		||||
            }
 | 
			
		||||
            newfact.m_neg.add_fact(I->m_pos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!newfact.is_empty())
 | 
			
		||||
            result.add_fact(newfact);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_diff_bitvector::join(const ternary_diff_bitvector& other,
 | 
			
		||||
                                      const unsigned_vector& cols1,
 | 
			
		||||
                                      const unsigned_vector& cols2,
 | 
			
		||||
                                      union_ternary_bitvector<ternary_diff_bitvector>& result) const {
 | 
			
		||||
        unsigned new_size = size() + other.size();
 | 
			
		||||
        ternary_diff_bitvector res(new_size);
 | 
			
		||||
 | 
			
		||||
        res.m_pos = m_pos;
 | 
			
		||||
        res.m_pos.append(other.m_pos);
 | 
			
		||||
 | 
			
		||||
        for (unsigned i = 0; i < cols1.size(); ++i) {
 | 
			
		||||
            unsigned idx1 = cols1[i];
 | 
			
		||||
            unsigned idx2 = size() + cols2[i];
 | 
			
		||||
            unsigned v1 = res.m_pos.get(idx1);
 | 
			
		||||
            unsigned v2 = res.m_pos.get(idx2);
 | 
			
		||||
 | 
			
		||||
            if (v1 == BIT_x) {
 | 
			
		||||
                if (v2 == BIT_x) {
 | 
			
		||||
                    // add to subtracted TBVs: 1xx0 and 0xx1
 | 
			
		||||
                    {
 | 
			
		||||
                    ternary_bitvector r(new_size, true);
 | 
			
		||||
                    r.set(idx1, BIT_0);
 | 
			
		||||
                    r.set(idx2, BIT_1);
 | 
			
		||||
                    res.m_neg.add_new_fact(r);
 | 
			
		||||
                    }
 | 
			
		||||
                    {
 | 
			
		||||
                    ternary_bitvector r(new_size, true);
 | 
			
		||||
                    r.set(idx1, BIT_1);
 | 
			
		||||
                    r.set(idx2, BIT_0);
 | 
			
		||||
                    res.m_neg.add_new_fact(r);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    res.m_pos.set(idx1, v2);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (v2 == BIT_x) {
 | 
			
		||||
                res.m_pos.set(idx2, v1);
 | 
			
		||||
            } else if (v1 != v2) {
 | 
			
		||||
                // columns don't match
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // handle subtracted TBVs:  1010 -> 1010xxx
 | 
			
		||||
        if (!m_neg.empty()) {
 | 
			
		||||
            ternary_bitvector padding(other.size(), true);
 | 
			
		||||
            for (union_ternary_bitvector<ternary_bitvector>::const_iterator I = m_neg.begin(),
 | 
			
		||||
                E = m_neg.end(); I != E; ++I) {
 | 
			
		||||
                ternary_bitvector BV(*I);
 | 
			
		||||
                BV.append(padding);
 | 
			
		||||
                res.m_neg.add_new_fact(BV);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!other.m_neg.empty()) {
 | 
			
		||||
            ternary_bitvector padding(size(), true);
 | 
			
		||||
            for (union_ternary_bitvector<ternary_bitvector>::const_iterator I = other.m_neg.begin(),
 | 
			
		||||
                E = other.m_neg.end(); I != E; ++I) {
 | 
			
		||||
                ternary_bitvector BV(padding);
 | 
			
		||||
                BV.append(*I);
 | 
			
		||||
                res.m_neg.add_new_fact(BV);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        result.add_fact(res);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool ternary_diff_bitvector::project(const unsigned_vector& delcols, ternary_diff_bitvector& result) const {
 | 
			
		||||
        m_pos.project(delcols, result.m_pos);
 | 
			
		||||
        if (m_neg.empty())
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        ternary_bitvector newneg;
 | 
			
		||||
        for (union_ternary_bitvector<ternary_bitvector>::const_iterator I = m_neg.begin(),
 | 
			
		||||
                E = m_neg.end(); I != E; ++I) {
 | 
			
		||||
            for (unsigned i = 0; i < delcols.size()-1; ++i) {
 | 
			
		||||
                unsigned idx = delcols[i];
 | 
			
		||||
                if (I->get(idx) != BIT_x && m_pos.get(idx) == BIT_x)
 | 
			
		||||
                    goto skip_row;
 | 
			
		||||
            }
 | 
			
		||||
            newneg.reset();
 | 
			
		||||
            I->project(delcols, newneg);
 | 
			
		||||
            result.m_neg.add_fact(newneg);
 | 
			
		||||
skip_row:   ;
 | 
			
		||||
        }
 | 
			
		||||
        return !result.is_empty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_diff_bitvector::rename(const unsigned_vector& cyclecols,
 | 
			
		||||
                                        const unsigned_vector& out_of_cycle_cols,
 | 
			
		||||
                                        const table_information& src_table,
 | 
			
		||||
                                        const table_information& dst_table,
 | 
			
		||||
                                        ternary_diff_bitvector& result) const {
 | 
			
		||||
        m_pos.rename(cyclecols, out_of_cycle_cols, src_table, dst_table, result.m_pos);
 | 
			
		||||
        m_neg.rename(cyclecols, out_of_cycle_cols, src_table, dst_table, result.m_neg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned ternary_diff_bitvector::get(unsigned idx) {
 | 
			
		||||
        return m_pos.get(idx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_diff_bitvector::set(unsigned idx, unsigned val) {
 | 
			
		||||
        m_pos.set(idx, val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_diff_bitvector::swap(ternary_diff_bitvector & other) {
 | 
			
		||||
        m_pos.swap(other.m_pos);
 | 
			
		||||
        m_neg.swap(other.m_neg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_diff_bitvector::reset() {
 | 
			
		||||
        m_pos.reset();
 | 
			
		||||
        m_neg.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ternary_diff_bitvector::display(std::ostream & out) const {
 | 
			
		||||
        m_pos.display(out);
 | 
			
		||||
        if (!m_neg.empty()) {
 | 
			
		||||
            out << " \\ ";
 | 
			
		||||
            if (m_neg.num_disjs() > 1) out << '(';
 | 
			
		||||
            m_neg.display(out);
 | 
			
		||||
            if (m_neg.num_disjs() > 1) out << ')';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned ternary_diff_bitvector::size_in_bytes() const {
 | 
			
		||||
        return m_pos.size_in_bytes() + m_neg.num_bytes();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if Z3DEBUG
 | 
			
		||||
    void ternary_diff_bitvector::expand(std::set<bit_vector> & BVs) const {
 | 
			
		||||
        m_pos.expand(BVs);
 | 
			
		||||
        SASSERT(!BVs.empty());
 | 
			
		||||
 | 
			
		||||
        std::set<bit_vector> NegBVs;
 | 
			
		||||
        m_neg.expand(NegBVs);
 | 
			
		||||
        BVs.erase(NegBVs.begin(), NegBVs.end());
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    hassel_diff_table_plugin::hassel_diff_table_plugin(relation_manager & manager)
 | 
			
		||||
        : common_hassel_table_plugin(symbol("hassel_diff"), manager) {}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,87 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2013 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    dl_hassel_diff_table.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#ifndef _DL_HASSEL_DIFF_TABLE_H_
 | 
			
		||||
#define _DL_HASSEL_DIFF_TABLE_H_
 | 
			
		||||
 | 
			
		||||
#include "dl_hassel_common.h"
 | 
			
		||||
 | 
			
		||||
namespace datalog {
 | 
			
		||||
 | 
			
		||||
    class hassel_diff_table;
 | 
			
		||||
 | 
			
		||||
    class ternary_diff_bitvector {
 | 
			
		||||
        // pos \ (neg0 \/ ... \/ negn)
 | 
			
		||||
        ternary_bitvector m_pos;
 | 
			
		||||
        union_ternary_bitvector<ternary_bitvector> m_neg;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        ternary_diff_bitvector() : m_pos(), m_neg(0) {}
 | 
			
		||||
        ternary_diff_bitvector(unsigned size) : m_pos(size), m_neg(size) {}
 | 
			
		||||
        ternary_diff_bitvector(unsigned size, bool full);
 | 
			
		||||
        ternary_diff_bitvector(uint64 n, unsigned num_bits);
 | 
			
		||||
        ternary_diff_bitvector(const ternary_bitvector & tbv);
 | 
			
		||||
 | 
			
		||||
        bool contains(const ternary_diff_bitvector & other) const;
 | 
			
		||||
        bool is_empty() const;
 | 
			
		||||
 | 
			
		||||
        ternary_diff_bitvector and(const ternary_diff_bitvector& other) const;
 | 
			
		||||
        void neg(union_ternary_bitvector<ternary_diff_bitvector>& result) const;
 | 
			
		||||
 | 
			
		||||
        static bool has_subtract() { return true; }
 | 
			
		||||
        void subtract(const union_ternary_bitvector<ternary_diff_bitvector>& other,
 | 
			
		||||
            union_ternary_bitvector<ternary_diff_bitvector>& result) const;
 | 
			
		||||
 | 
			
		||||
        void join(const ternary_diff_bitvector& other, const unsigned_vector& cols1,
 | 
			
		||||
            const unsigned_vector& cols2, union_ternary_bitvector<ternary_diff_bitvector>& result) const;
 | 
			
		||||
 | 
			
		||||
        bool project(const unsigned_vector& delcols, ternary_diff_bitvector& result) const;
 | 
			
		||||
 | 
			
		||||
        void rename(const unsigned_vector& cyclecols, const unsigned_vector& out_of_cycle_cols,
 | 
			
		||||
            const table_information& src_table, const table_information& dst_table,
 | 
			
		||||
            ternary_diff_bitvector& result) const;
 | 
			
		||||
 | 
			
		||||
        unsigned get(unsigned idx);
 | 
			
		||||
        void set(unsigned idx, unsigned val);
 | 
			
		||||
 | 
			
		||||
        void swap(ternary_diff_bitvector & other);
 | 
			
		||||
        void reset();
 | 
			
		||||
 | 
			
		||||
        unsigned size() const { return m_pos.size(); }
 | 
			
		||||
 | 
			
		||||
        void display(std::ostream & out) const;
 | 
			
		||||
        unsigned size_in_bytes() const;
 | 
			
		||||
 | 
			
		||||
#if Z3DEBUG
 | 
			
		||||
        void expand(std::set<bit_vector> & BVs) const;
 | 
			
		||||
#endif
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef union_ternary_bitvector<ternary_diff_bitvector> union_ternary_diff_bitvector;
 | 
			
		||||
 | 
			
		||||
    class hassel_diff_table : public common_hassel_table<union_ternary_diff_bitvector> {
 | 
			
		||||
    public:
 | 
			
		||||
        hassel_diff_table(table_plugin & p, const table_signature & sig) :
 | 
			
		||||
            common_hassel_table(p, sig) {}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class hassel_diff_table_plugin : public common_hassel_table_plugin<hassel_diff_table> {
 | 
			
		||||
    public:
 | 
			
		||||
        hassel_diff_table_plugin(relation_manager & manager);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2013 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    dl_hassel_table.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include "ast_printer.h"
 | 
			
		||||
#include "dl_context.h"
 | 
			
		||||
#include "dl_util.h"
 | 
			
		||||
#include "dl_hassel_table.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace datalog {
 | 
			
		||||
 | 
			
		||||
    hassel_table_plugin::hassel_table_plugin(relation_manager & manager)
 | 
			
		||||
        : common_hassel_table_plugin(symbol("hassel"), manager) {}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,39 +0,0 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2013 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    dl_hassel_table.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    <abstract>
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#ifndef _DL_HASSEL_TABLE_H_
 | 
			
		||||
#define _DL_HASSEL_TABLE_H_
 | 
			
		||||
 | 
			
		||||
#include "dl_hassel_common.h"
 | 
			
		||||
 | 
			
		||||
namespace datalog {
 | 
			
		||||
 | 
			
		||||
    class hassel_table;
 | 
			
		||||
    typedef union_ternary_bitvector<ternary_bitvector> union_ternary_bitvectors;
 | 
			
		||||
 | 
			
		||||
    class hassel_table : public common_hassel_table<union_ternary_bitvectors> {
 | 
			
		||||
    public:
 | 
			
		||||
        hassel_table(table_plugin & p, const table_signature & sig) :
 | 
			
		||||
            common_hassel_table(p, sig) {}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class hassel_table_plugin : public common_hassel_table_plugin<hassel_table> {
 | 
			
		||||
    public:
 | 
			
		||||
        hassel_table_plugin(relation_manager & manager);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1561,15 +1561,16 @@ namespace pdr {
 | 
			
		|||
            m_fparams.m_arith_auto_config_simplex = true;
 | 
			
		||||
            m_fparams.m_arith_propagate_eqs = false;
 | 
			
		||||
            m_fparams.m_arith_eager_eq_axioms = false;
 | 
			
		||||
            if (classify.is_utvpi() && m_params.use_utvpi()) {
 | 
			
		||||
            if (classify.is_dl()) {
 | 
			
		||||
                m_fparams.m_arith_mode = AS_DIFF_LOGIC;
 | 
			
		||||
                m_fparams.m_arith_expand_eqs = true;
 | 
			
		||||
            }
 | 
			
		||||
            else if (classify.is_utvpi() && m_params.use_utvpi()) {
 | 
			
		||||
                IF_VERBOSE(1, verbose_stream() << "UTVPI\n";);
 | 
			
		||||
                m_fparams.m_arith_mode = AS_UTVPI;
 | 
			
		||||
                m_fparams.m_arith_expand_eqs = true;                
 | 
			
		||||
            }
 | 
			
		||||
            else if (classify.is_dl()) {
 | 
			
		||||
                m_fparams.m_arith_mode = AS_DIFF_LOGIC;
 | 
			
		||||
                m_fparams.m_arith_expand_eqs = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        if (!use_mc && m_params.use_inductive_generalizer()) {
 | 
			
		||||
            m_core_generalizers.push_back(alloc(core_bool_inductive_generalizer, *this, 0));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,6 @@ Revision History:
 | 
			
		|||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#define Z3_HASSEL_TABLE
 | 
			
		||||
 | 
			
		||||
#include"rel_context.h"
 | 
			
		||||
#include"dl_context.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -33,10 +32,6 @@ Revision History:
 | 
			
		|||
#include"dl_mk_karr_invariants.h"
 | 
			
		||||
#include"dl_finite_product_relation.h"
 | 
			
		||||
#include"dl_sparse_table.h"
 | 
			
		||||
#ifdef Z3_HASSEL_TABLE
 | 
			
		||||
# include"dl_hassel_table.h"
 | 
			
		||||
# include"dl_hassel_diff_table.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include"dl_table.h"
 | 
			
		||||
#include"dl_table_relation.h"
 | 
			
		||||
#include"aig_exporter.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -94,10 +89,6 @@ namespace datalog {
 | 
			
		|||
        get_rmanager().register_plugin(alloc(bitvector_table_plugin, get_rmanager()));
 | 
			
		||||
        get_rmanager().register_plugin(alloc(equivalence_table_plugin, get_rmanager()));
 | 
			
		||||
 | 
			
		||||
#ifdef Z3_HASSEL_TABLE
 | 
			
		||||
        get_rmanager().register_plugin(alloc(hassel_table_plugin, get_rmanager()));
 | 
			
		||||
        get_rmanager().register_plugin(alloc(hassel_diff_table_plugin, get_rmanager()));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        // register plugins for builtin relations
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -311,4 +311,4 @@
 | 
			
		|||
                    (= (?is (?select (?select (?asElems e) a) i)
 | 
			
		||||
                            (?elemtype (?typeof a))) 1)
 | 
			
		||||
                    :pats { (?select (?select (?asElems e) a) i) })
 | 
			
		||||
   )
 | 
			
		||||
   )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -418,9 +418,6 @@ namespace smt {
 | 
			
		|||
            return FC_GIVEUP;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            m_graph.set_to_zero(to_var(m_zero_int), to_var(m_zero_real));
 | 
			
		||||
            m_graph.set_to_zero(neg(to_var(m_zero_int)), neg(to_var(m_zero_real)));
 | 
			
		||||
            m_graph.set_to_zero(to_var(m_zero_int), neg(to_var(m_zero_int)));
 | 
			
		||||
            return FC_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -691,16 +688,33 @@ namespace smt {
 | 
			
		|||
       \brief adjust values for variables in the difference graph
 | 
			
		||||
              such that for variables of integer sort it is
 | 
			
		||||
              the case that x^+ - x^- is even.
 | 
			
		||||
       The informal justification for the procedure enforce_parity is that
 | 
			
		||||
       the graph does not contain a strongly connected component where
 | 
			
		||||
       x^+ and x+- are connected. They can be independently changed.
 | 
			
		||||
       Since we would like variables representing 0 (zero) map to 0,
 | 
			
		||||
       we selectively update the subgraph that can be updated without
 | 
			
		||||
       changing the value of zero (which should be 0).
 | 
			
		||||
       The informal justification for the procedure enforce_parity relies
 | 
			
		||||
       on a set of properties:
 | 
			
		||||
       1. the graph does not contain a strongly connected component where
 | 
			
		||||
          x^+ and x+- are connected. They can be independently changed.
 | 
			
		||||
          This is checked prior to enforce_parity.
 | 
			
		||||
       2. When x^+ - x^- is odd, the values are adjusted by first 
 | 
			
		||||
          decrementing the value of x^+, provided x^- is not 0-dependent.
 | 
			
		||||
          Otherwise decrement x^-. 
 | 
			
		||||
          x^- is "0-dependent" if there is a set of tight 
 | 
			
		||||
          inequalities from x^+ to x^-.
 | 
			
		||||
       3. The affinity to x^+ (the same component of x^+) ensures that 
 | 
			
		||||
          the parity is broken only a finite number of times when 
 | 
			
		||||
          traversing that component. Namely, suppose that the parity of y
 | 
			
		||||
          gets broken when fixing 'x'. Then first note that 'y' cannot 
 | 
			
		||||
          be equal to 'x'. If it were, then we have a state where:
 | 
			
		||||
             parity(x^+) != parity(x^-) and 
 | 
			
		||||
             parity(y^+) == parity(y^-)
 | 
			
		||||
          but x^+ and y^+ are tightly connected and x^- and y^- are
 | 
			
		||||
          also tightly connected using two copies of the same inequalities.
 | 
			
		||||
          This is a contradiction.
 | 
			
		||||
          Thus, 'y' cannot be equal to 'x' if 'y's parity gets broken when
 | 
			
		||||
          repairing 'x'.
 | 
			
		||||
                 
 | 
			
		||||
     */
 | 
			
		||||
    template<typename Ext>
 | 
			
		||||
    void theory_utvpi<Ext>::enforce_parity() {
 | 
			
		||||
       unsigned_vector todo;
 | 
			
		||||
        unsigned_vector todo;
 | 
			
		||||
        
 | 
			
		||||
        unsigned sz = get_num_vars();
 | 
			
		||||
        for (unsigned i = 0; i < sz; ++i) {
 | 
			
		||||
| 
						 | 
				
			
			@ -712,6 +726,8 @@ namespace smt {
 | 
			
		|||
        if (todo.empty()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        IF_VERBOSE(2, verbose_stream() << "disparity: " << todo.size() << "\n";);
 | 
			
		||||
        unsigned iter = 0;
 | 
			
		||||
        while (!todo.empty()) {
 | 
			
		||||
            unsigned i = todo.back();
 | 
			
		||||
            todo.pop_back();
 | 
			
		||||
| 
						 | 
				
			
			@ -720,21 +736,17 @@ namespace smt {
 | 
			
		|||
            }
 | 
			
		||||
            th_var v1 = to_var(i);
 | 
			
		||||
            th_var v2 = neg(v1);
 | 
			
		||||
            TRACE("utvpi", tout << "disparity: " << v1 << "\n";);
 | 
			
		||||
 | 
			
		||||
            // IF_VERBOSE(1, verbose_stream() << "disparity: " << v1 << "\n";);
 | 
			
		||||
            int_vector zero_v;
 | 
			
		||||
            m_graph.compute_zero_succ(v1, zero_v);
 | 
			
		||||
            bool found0 = false;
 | 
			
		||||
            for (unsigned j = 0; !found0 && j < zero_v.size(); ++j) {
 | 
			
		||||
                found0 = 
 | 
			
		||||
                    (to_var(m_zero_int) == zero_v[j]) ||
 | 
			
		||||
                    (neg(to_var(m_zero_int)) == zero_v[j]);                
 | 
			
		||||
            }
 | 
			
		||||
            // variables that are tightly connected 
 | 
			
		||||
            // to 0 should not have their values changed.
 | 
			
		||||
            if (found0) {
 | 
			
		||||
                zero_v.reset();
 | 
			
		||||
                m_graph.compute_zero_succ(v2, zero_v);
 | 
			
		||||
            for (unsigned j = 0; j < zero_v.size(); ++j) {
 | 
			
		||||
                if (zero_v[j] == v2) {
 | 
			
		||||
                    zero_v.reset();
 | 
			
		||||
                    m_graph.compute_zero_succ(v2, zero_v);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            TRACE("utvpi", 
 | 
			
		||||
                  for (unsigned j = 0; j < zero_v.size(); ++j) {
 | 
			
		||||
                      tout << "decrement: " << zero_v[j] << "\n";
 | 
			
		||||
| 
						 | 
				
			
			@ -745,10 +757,23 @@ namespace smt {
 | 
			
		|||
                m_graph.acc_assignment(v, numeral(-1));
 | 
			
		||||
                th_var k = from_var(v);
 | 
			
		||||
                if (!is_parity_ok(k)) {
 | 
			
		||||
                    TRACE("utvpi", tout << "new disparity: " << k << "\n";);
 | 
			
		||||
                    // IF_VERBOSE(1, verbose_stream() << "new disparity: " << k << "\n";);
 | 
			
		||||
                    todo.push_back(k);
 | 
			
		||||
                }
 | 
			
		||||
            }            
 | 
			
		||||
            }         
 | 
			
		||||
            if (iter >= 10000) {
 | 
			
		||||
                IF_VERBOSE(1,
 | 
			
		||||
                           verbose_stream() << "decrement: ";
 | 
			
		||||
                           for (unsigned j = 0; j < zero_v.size(); ++j) {
 | 
			
		||||
                               rational r = m_graph.get_assignment(zero_v[j]).get_rational();
 | 
			
		||||
                               verbose_stream() << zero_v[j] << " (" << r << ") ";
 | 
			
		||||
                           }
 | 
			
		||||
                           verbose_stream() << "\n";);
 | 
			
		||||
                if (!is_parity_ok(i)) {
 | 
			
		||||
                    IF_VERBOSE(1, verbose_stream() << "Parity not fixed\n";);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            ++iter;
 | 
			
		||||
        }
 | 
			
		||||
        SASSERT(m_graph.is_feasible());
 | 
			
		||||
        DEBUG_CODE(
 | 
			
		||||
| 
						 | 
				
			
			@ -764,10 +789,13 @@ namespace smt {
 | 
			
		|||
 | 
			
		||||
    // models:
 | 
			
		||||
    template<typename Ext>
 | 
			
		||||
    void theory_utvpi<Ext>::init_model(model_generator & m) {    
 | 
			
		||||
    void theory_utvpi<Ext>::init_model(model_generator & m) {            
 | 
			
		||||
        m_factory = alloc(arith_factory, get_manager());
 | 
			
		||||
        m.register_factory(m_factory);
 | 
			
		||||
        enforce_parity();
 | 
			
		||||
        m_graph.set_to_zero(to_var(m_zero_int), to_var(m_zero_real));
 | 
			
		||||
        m_graph.set_to_zero(neg(to_var(m_zero_int)), neg(to_var(m_zero_real)));
 | 
			
		||||
        m_graph.set_to_zero(to_var(m_zero_int), neg(to_var(m_zero_int)));
 | 
			
		||||
        compute_delta();   
 | 
			
		||||
        DEBUG_CODE(validate_model(););
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue