24#include "catalog/pg_type.h"
25#include "utils/jsonb.h"
26#include "utils/fmgrprotos.h"
27#include "utils/uuid.h"
41#include <unordered_map>
47json_escape(std::ostringstream &out,
const std::string &s)
51 case '"': out <<
"\\\"";
break;
52 case '\\': out <<
"\\\\";
break;
53 case '\b': out <<
"\\b";
break;
54 case '\f': out <<
"\\f";
break;
55 case '\n': out <<
"\\n";
break;
56 case '\r': out <<
"\\r";
break;
57 case '\t': out <<
"\\t";
break;
59 if (
static_cast<unsigned char>(c) < 0x20) {
61 snprintf(buf,
sizeof buf,
"\\u%04x", c);
71emit_str(std::ostringstream &out,
const std::string &s)
85emit_node_row(std::ostringstream &out,
89 const std::string &node_uuid,
90 const std::string *parent_uuid,
94 if (!first) out <<
',';
103 const unsigned NO_INFO =
static_cast<unsigned>(-1);
106 out <<
"\"node\":"; emit_str(out, node_uuid);
107 out <<
",\"parent\":";
108 if (parent_uuid) emit_str(out, *parent_uuid);
110 out <<
",\"child_pos\":";
111 if (parent_uuid) out << child_pos;
113 out <<
",\"gate_type\":"; emit_str(out, type_name);
114 out <<
",\"info1\":";
115 if (infos.first == NO_INFO) { out <<
"null"; }
116 else { out <<
'"' << infos.first <<
'"'; }
117 out <<
",\"info2\":";
118 if (infos.second == NO_INFO) { out <<
"null"; }
119 else { out <<
'"' << infos.second <<
'"'; }
120 out <<
",\"extra\":";
132 const double p = gc.
getProb(g);
134 if (p != p) out <<
"null";
144 out <<
",\"boolean_assumed\":true";
146 out <<
",\"depth\":" << depth;
156 int max_depth = PG_GETARG_INT32(1);
158 std::ostringstream out;
172 Datum json_datum = DirectFunctionCall1(
173 jsonb_in, CStringGetDatum(pstrdup(out.str().c_str())));
174 PG_RETURN_DATUM(json_datum);
194 std::unordered_map<gate_t, int> depth_of;
195 std::queue<gate_t> bfs;
196 depth_of[root_gate] = 0;
198 while (!bfs.empty()) {
199 gate_t g = bfs.front(); bfs.pop();
201 if (d >= max_depth)
continue;
203 auto it = depth_of.find(c);
204 if (it == depth_of.end()) {
215 const std::string root_uuid = gc.
getUUID(root_gate);
216 emit_node_row(out, first, gc, root_gate, root_uuid,
220 for (
const auto &[g, d] : depth_of) {
221 if (d >= max_depth)
continue;
222 const std::string parent_uuid = gc.
getUUID(g);
224 for (std::size_t i = 0; i < wires.size(); ++i) {
226 auto cit = depth_of.find(c);
227 if (cit == depth_of.end())
continue;
228 if (cit->second > max_depth)
continue;
229 const std::string child_uuid = gc.
getUUID(c);
230 emit_node_row(out, first, gc, c, child_uuid,
231 &parent_uuid,
static_cast<int>(i + 1),
235 }
catch (
const std::exception &e) {
238 provsql_error(
"simplified_circuit_subgraph: unknown exception");
243 Datum json_datum = DirectFunctionCall1(
244 jsonb_in, CStringGetDatum(pstrdup(out.str().c_str())));
245 PG_RETURN_DATUM(json_datum);
GenericCircuit getGenericCircuit(pg_uuid_t token)
Build a GenericCircuit from the mmap store rooted at token.
Build in-memory circuits from the mmap-backed persistent store.
gate_t
Strongly-typed gate identifier.
Semiring-agnostic in-memory provenance circuit.
Peephole simplifier for continuous gate_arith sub-circuits.
Datum simplified_circuit_subgraph(PG_FUNCTION_ARGS)
Exception type thrown by circuit operations on invalid input.
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.
gate_t getGate(const uuid &u)
Return (or create) the gate associated with UUID u.
In-memory provenance circuit with semiring-generic evaluation.
std::string getExtra(gate_t g) const
Return the string extra for gate g.
double getProb(gate_t g) const
Return the probability for gate g.
bool isBooleanAssumed(gate_t g) const
Report whether g carries the Boolean-assumption flag.
std::pair< unsigned, unsigned > getInfos(gate_t g) const
Return the integer annotation pair for gate g.
unsigned runHybridSimplifier(GenericCircuit &gc)
Run the peephole simplifier over gc.
bool provsql_hybrid_evaluation
Run the hybrid-evaluator simplifier inside probability_evaluate; controlled by the provsql....
#define provsql_error(fmt,...)
Report a fatal ProvSQL error and abort the current transaction.
const char * gate_type_name[]
Names of gate types.
Core types, constants, and utilities shared across ProvSQL.
string uuid2string(pg_uuid_t uuid)
Format a pg_uuid_t as a std::string.
C++ utility functions for UUID manipulation.