3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-26 15:53:41 +00:00
z3/src/ast/euf/euf_justification.h
Nikolaj Bjorner 9be8fc7857 Add EUF (congruence closure) proof hints and checker to the new core
EUF proofs are checked modulo union-find.
Equalities are added to to union-find if they are assumptions or if they can be derived using congruence closure. The congruence closure assumptions are added as proof-hints.
Note that this proof format does not track equality inferences, symmetry and transitivity. Instead they are handled by assuming a union-find based checker.
2022-09-25 14:26:20 -07:00

107 lines
2.9 KiB
C++

/*++
Copyright (c) 2020 Microsoft Corporation
Module Name:
euf_justification.h
Abstract:
justification structure for euf
Author:
Nikolaj Bjorner (nbjorner) 2020-08-23
Notes:
- congruence closure justifications are given a timestamp so it is easy to sort them.
See the longer descriptoin in euf_proof_checker.cpp
--*/
#pragma once
namespace euf {
class justification {
enum class kind_t {
axiom_t,
congruence_t,
external_t
};
kind_t m_kind;
bool m_comm;
union {
void* m_external;
uint64_t m_timestamp;
};
justification(bool comm, uint64_t ts):
m_kind(kind_t::congruence_t),
m_comm(comm),
m_timestamp(ts)
{}
justification(void* ext):
m_kind(kind_t::external_t),
m_comm(false),
m_external(ext)
{}
public:
justification():
m_kind(kind_t::axiom_t),
m_comm(false),
m_external(nullptr)
{}
static justification axiom() { return justification(); }
static justification congruence(bool c, uint64_t ts) { return justification(c, ts); }
static justification external(void* ext) { return justification(ext); }
bool is_external() const { return m_kind == kind_t::external_t; }
bool is_congruence() const { return m_kind == kind_t::congruence_t; }
bool is_commutative() const { return m_comm; }
uint64_t timestamp() const { SASSERT(is_congruence()); return m_timestamp; }
template <typename T>
T* ext() const { SASSERT(is_external()); return static_cast<T*>(m_external); }
justification copy(std::function<void*(void*)>& copy_justification) const {
switch (m_kind) {
case kind_t::external_t:
return external(copy_justification(m_external));
case kind_t::axiom_t:
return axiom();
case kind_t::congruence_t:
return congruence(m_comm, m_timestamp);
default:
UNREACHABLE();
return axiom();
}
}
std::ostream& display(std::ostream& out, std::function<void (std::ostream&, void*)> const& ext) const {
switch (m_kind) {
case kind_t::external_t:
if (ext)
ext(out, m_external);
else
out << "external";
return out;
case kind_t::axiom_t:
return out << "axiom";
case kind_t::congruence_t:
return out << "congruence";
default:
UNREACHABLE();
return out;
}
return out;
}
};
inline std::ostream& operator<<(std::ostream& out, justification const& j) {
return j.display(out, nullptr);
}
}