14#include "utils/uuid.h"
27#include <unordered_set>
38void sha1(
const unsigned char *data, std::size_t len,
unsigned char out[20])
40 uint32_t h[5] = {0x67452301u, 0xEFCDAB89u, 0x98BADCFEu, 0x10325476u,
42 const std::size_t total = ((len + 8) / 64 + 1) * 64;
43 std::vector<unsigned char> buf(total, 0);
44 std::copy(data, data + len, buf.begin());
46 const uint64_t bits =
static_cast<uint64_t
>(len) * 8;
47 for (
int i = 0; i < 8; ++i)
48 buf[total - 1 - i] =
static_cast<unsigned char>(bits >> (8 * i));
50 for (std::size_t chunk = 0; chunk < total; chunk += 64) {
52 for (
int i = 0; i < 16; ++i)
53 w[i] = (
static_cast<uint32_t
>(buf[chunk + 4*i]) << 24) |
54 (
static_cast<uint32_t
>(buf[chunk + 4*i + 1]) << 16) |
55 (
static_cast<uint32_t
>(buf[chunk + 4*i + 2]) << 8) |
56 static_cast<uint32_t
>(buf[chunk + 4*i + 3]);
57 for (
int i = 16; i < 80; ++i) {
58 const uint32_t v = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
59 w[i] = (v << 1) | (v >> 31);
61 uint32_t a = h[0], b = h[1], c = h[2], d = h[3], e = h[4];
62 for (
int i = 0; i < 80; ++i) {
65 f = (b & c) | (~b & d);
71 f = (b & c) | (b & d) | (c & d);
77 const uint32_t tmp = ((a << 5) | (a >> 27)) + f + e + k + w[i];
80 c = (b << 30) | (b >> 2);
84 h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e;
86 for (
int i = 0; i < 5; ++i) {
87 out[4*i] =
static_cast<unsigned char>(h[i] >> 24);
88 out[4*i + 1] =
static_cast<unsigned char>(h[i] >> 16);
89 out[4*i + 2] =
static_cast<unsigned char>(h[i] >> 8);
90 out[4*i + 3] =
static_cast<unsigned char>(h[i]);
99 static const unsigned char ns[16] = {
100 0x92, 0x0d, 0x4f, 0x02, 0x87, 0x18, 0x53, 0x19,
101 0x95, 0x32, 0xd4, 0xab, 0x83, 0xa6, 0x44, 0x89
103 std::vector<unsigned char> data(16 + name.size());
104 std::copy(ns, ns + 16, data.begin());
105 std::copy(name.begin(), name.end(), data.begin() + 16);
106 unsigned char digest[20];
107 sha1(data.data(), data.size(), digest);
109 std::copy(digest, digest + 16, u.
data);
110 u.
data[6] =
static_cast<unsigned char>((u.
data[6] & 0x0F) | 0x50);
111 u.
data[8] =
static_cast<unsigned char>((u.
data[8] & 0x3F) | 0x80);
116 const dDNNF &dd,
const std::vector<gate_t> &roots)
118 std::unordered_map<gate_t, pg_uuid_t, hash_gate_t> uuid_of;
122 static std::unordered_set<std::string> created;
123 constexpr std::size_t kCreatedCap = 4u << 20;
124 if (created.size() > kCreatedCap)
127 bool have_one =
false;
129 const auto ensureOne = [&]() {
139 const std::vector<pg_uuid_t> &children,
142 if (!created.insert(key).second)
146 static_cast<unsigned>(children.size()),
147 children.empty() ? NULL : children.
data());
153 std::vector<gate_t> stack(roots);
154 while (!stack.empty()) {
155 CHECK_FOR_INTERRUPTS();
156 const gate_t g = stack.back();
157 if (uuid_of.find(g) != uuid_of.end()) {
165 const std::string tok = dd.
getUUID(g);
166 if (!tok.empty() && tok[0] ==
'\x01') {
190 for (
const auto &c : dd.
getWires(g))
191 if (uuid_of.find(c) == uuid_of.end()) {
207 createOnce(token,
gate_monus, {one, child},
false);
222 }
else if (wires.size() == 1) {
223 token = uuid_of[wires[0]];
225 std::vector<std::string> texts;
226 texts.reserve(wires.size());
227 for (
const auto &c : wires)
229 std::sort(texts.begin(), texts.end());
231 for (std::size_t i = 0; i < texts.size(); ++i) {
238 std::vector<pg_uuid_t> children;
239 children.reserve(wires.size());
240 for (
const auto &c : wires)
241 children.push_back(uuid_of[c]);
243 children, certified);
249 provsql_error(
"materializeCertifiedDD: unsupported gate type");
250 throw std::runtime_error(
"unreachable");
262 static std::unordered_set<std::string> created;
263 constexpr std::size_t kCreatedCap = 1u << 20;
264 if (created.size() > kCreatedCap)
Boolean provenance circuit with support for knowledge compilation.
constexpr unsigned DNNF_CERT_INFO
d-DNNF certificate value for the (gate-type-specific) per-gate info field.
@ NOT
Logical negation of a single child gate.
@ OR
Logical disjunction of child gates.
@ AND
Logical conjunction of child gates.
@ IN
Input (variable) gate representing a base tuple.
@ MULIN
Multivalued-input gate (one of several options).
std::unordered_map< gate_t, pg_uuid_t, hash_gate_t > materializeCertifiedDD(const dDNNF &dd, const std::vector< gate_t > &roots)
Materialise (the reachable part of) a certified d-D into the mmap store.
pg_uuid_t wrapAssumedAbsorptive(const pg_uuid_t &child)
Wrap a materialised root in the 'absorptive' assumption marker and return the wrapper's UUID.
pg_uuid_t provsqlUuidV5(const std::string &name)
RFC 4122 version-5 UUID in the ProvSQL namespace.
Content-addressed materialisation of a certified d-D into the mmap provenance store.
gate_t
Strongly-typed gate identifier.
bool isDNNFCertified(gate_t g) const
Is gate g certified by the d-DNNF per-gate marking?
double getProb(gate_t g) const
Return the probability stored for gate g.
std::vector< gate_t > & getWires(gate_t g)
Return a mutable reference to the child-wire list of gate g.
gateType getGateType(gate_t g) const
Return the type of gate g.
uuid getUUID(gate_t g) const
Return the UUID string associated with gate g.
A d-DNNF circuit supporting exact probabilistic and game-theoretic evaluation.
#define provsql_error(fmt,...)
Report a fatal ProvSQL error and abort the current transaction.
void provsql_internal_set_extra(const pg_uuid_t *token, const char *str)
Internal entry point behind set_extra(): worker IPC only.
void provsql_internal_create_gate(const pg_uuid_t *token, gate_type type, unsigned nb_children, const pg_uuid_t *children_data)
Internal entry point behind create_gate(): cache + worker IPC.
bool provsql_internal_set_prob(const pg_uuid_t *token, double prob)
Internal entry point behind set_prob(): worker IPC only.
void provsql_internal_set_infos(const pg_uuid_t *token, unsigned info1, unsigned info2)
Internal entry point behind set_infos(): worker IPC only.
Background worker and IPC primitives for mmap-backed circuit storage.
Core types, constants, and utilities shared across ProvSQL.
@ gate_assumed
Structural marker over a single child whose sub-circuit was computed under a Boolean-provenance assum...
pg_uuid_t string2uuid(const string &source)
Parse a UUID string into a pg_uuid_t.
string uuid2string(pg_uuid_t uuid)
Format a pg_uuid_t as a std::string.
C++ utility functions for UUID manipulation.