ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
compile_to_ddnnf.cpp
Go to the documentation of this file.
1/**
2 * @file compile_to_ddnnf.cpp
3 * @brief SQL function @c provsql.compile_to_ddnnf() – return the
4 * compiled d-DNNF of a provenance circuit as c2d / d4 ".nnf" text.
5 *
6 * Companion to @c compile_to_ddnnf_dot (which returns GraphViz DOT for a
7 * human): this returns the standard NNF interchange format, so the
8 * compiled circuit can be fed to an external d-DNNF reasoner / verifier
9 * or saved alongside the @c tseytin_cnf output (the two share the same
10 * variable numbering). Dispatch is the shared @c makeDDByName, so it
11 * accepts the same compiler / meta-route names as the DOT version.
12 */
13extern "C" {
14#include "postgres.h"
15#include "fmgr.h"
16#if PG_VERSION_NUM >= 160000
17#include "varatt.h"
18#endif
19#include "catalog/pg_type.h"
20#include "utils/uuid.h"
21#include "provsql_shmem.h"
22#include "provsql_utils.h"
23
24PG_FUNCTION_INFO_V1(compile_to_ddnnf);
25}
26
27#include "c_cpp_compatibility.h"
28#include "BooleanCircuit.h"
29#include "CircuitFromMMap.h"
30#include "dDNNF.h"
31#include "provsql_utils_cpp.h"
32#include "tool_registry_sync.h"
33
34#include <string>
35#include <unordered_map>
36
37using namespace std;
38
39/**
40 * @brief PostgreSQL-callable entry point.
41 *
42 * Arguments: @c token (uuid), @c compiler (text, default @c "d4").
43 * Returns: the compiled d-DNNF in NNF text format.
44 */
45Datum compile_to_ddnnf(PG_FUNCTION_ARGS)
46{
47 provsql_sync_tool_registry(); // honour persisted tool-registry overrides
48 try {
49 if(PG_ARGISNULL(0))
50 PG_RETURN_NULL();
51 pg_uuid_t *token = DatumGetUUIDP(PG_GETARG_DATUM(0));
52
53 string compiler = ""; // empty => preference-ranked best available compiler
54 if(!PG_ARGISNULL(1)) {
55 text *t = PG_GETARG_TEXT_P(1);
56 compiler = string(VARDATA(t), VARSIZE(t)-VARHDRSZ);
57 }
58
59 gate_t root;
60 BooleanCircuit c = getBooleanCircuit(*token, root);
62
63 // Map each input's UUID to its Tseytin-CNF variable (gate id + 1),
64 // the same numbering tseytin_cnf / tseytin_cnf_mapping use. Passing
65 // this into toNNF makes the NNF's input variables agree with the
66 // CNF even when an external compiler renumbered them internally.
67 std::unordered_map<std::string, int> uuid2var;
68 for(gate_t in : c.getInputs())
69 uuid2var[c.getUUID(in)] =
70 static_cast<int>(static_cast<std::underlying_type<gate_t>::type>(in)) + 1;
71 auto var_of_uuid = [&uuid2var](const std::string &u) -> int {
72 auto it = uuid2var.find(u);
73 return it == uuid2var.end() ? -1 : it->second;
74 };
75
76 // "inversion-free" builds the structured d-DNNF over the order keys on the
77 // generic circuit (see buildInversionFreeDDNNF); its input leaves carry the
78 // same UUIDs as c, so var_of_uuid still aligns the NNF with the CNF.
79 // NB: this surface serialises to NNF (toNNF), which requires negation only
80 // on inputs, so it keeps the external-compilation default rather than the
81 // makeDD cost optimizer -- interpret-as-dd's d-DNNF carries internal NOTs
82 // that toNNF rejects. The cost optimizer ('auto') is for the shapley /
83 // banzhaf surfaces (and Studio), whose consumers accept that form.
84 dDNNF d = (compiler == "inversion-free")
86 : c.makeDDByName(root, compiler);
87 string nnf = d.toNNF(var_of_uuid);
88
89 text *result = (text *) palloc(VARHDRSZ + nnf.size());
90 SET_VARSIZE(result, VARHDRSZ + nnf.size());
91 memcpy((void *) VARDATA(result), nnf.c_str(), nnf.size());
92 PG_RETURN_TEXT_P(result);
93 } catch(const std::exception &e) {
94 provsql_error("%s", e.what());
95 } catch(...) {
96 provsql_error("Unknown exception");
97 }
98 PG_RETURN_NULL();
99}
Boolean provenance circuit with support for knowledge compilation.
BooleanCircuit getBooleanCircuit(GenericCircuit &gc, pg_uuid_t token, gate_t &gate, std::unordered_map< gate_t, gate_t > &gc_to_bc)
Build a BooleanCircuit from an already-loaded GenericCircuit.
Build in-memory circuits from the mmap-backed persistent store.
dDNNF buildInversionFreeDDNNF(pg_uuid_t token)
Compile a query certified inversion-free to its structured d-DNNF.
gate_t
Strongly-typed gate identifier.
Definition Circuit.h:49
Fix macro conflicts between PostgreSQL headers and the C++ STL/Boost.
Boolean circuit for provenance formula evaluation.
const std::set< gate_t > & getInputs() const
Return the set of input (IN) gate IDs.
void rewriteMultivaluedGates()
Rewrite all MULVAR/MULIN gate clusters into standard AND/OR/NOT circuits.
dDNNF makeDDByName(gate_t g, const std::string &name) const
Build a dDNNF from a single compiler/route name.
uuid getUUID(gate_t g) const
Return the UUID string associated with gate g.
Definition Circuit.hpp:46
A d-DNNF circuit supporting exact probabilistic and game-theoretic evaluation.
Definition dDNNF.h:71
std::string toNNF(const std::function< int(const std::string &)> &var_of_uuid={}) const
Serialise the d-DNNF in the c2d / d4 ".nnf" text format.
Definition dDNNF.cpp:811
Datum compile_to_ddnnf(PG_FUNCTION_ARGS)
PostgreSQL-callable entry point.
Decomposable Deterministic Negation Normal Form circuit.
#define provsql_error(fmt,...)
Report a fatal ProvSQL error and abort the current transaction.
Shared-memory segment and inter-process pipe management.
Core types, constants, and utilities shared across ProvSQL.
C++ utility functions for UUID manipulation.
UUID structure.
void provsql_sync_tool_registry()
Rebuild the in-memory registry as "compiled seed overlaid with the provsql.tool_overrides rows"...
Reload the in-memory external-tool registry from its persistent overrides.