32bool collectObserveAtoms(
const GenericCircuit &gc,
gate_t g,
33 std::vector<gate_t> &atoms)
44 if (!collectObserveAtoms(gc, c, atoms))
52struct ParsedObservation {
53 DistributionTemplate lik;
64std::optional<ParsedObservation>
65parseObservation(
const GenericCircuit &gc,
gate_t obs)
67 const auto &wires = gc.
getWires(obs);
68 if (wires.size() != 1)
70 const gate_t leaf = wires[0];
75 if (!tmpl || !tmpl->family)
82 const bool w1 = tmpl->p1.wire_slot >= 0;
83 const bool w2 = tmpl->p2.wire_slot >= 0;
87 const auto &leaf_wires = gc.
getWires(leaf);
88 const int slot = w1 ? tmpl->p1.wire_slot : tmpl->p2.wire_slot;
89 if (slot < 0 ||
static_cast<std::size_t
>(slot) >= leaf_wires.size())
92 ParsedObservation out;
94 out.wired_param = w1 ? 0 : 1;
95 out.latent = leaf_wires[slot];
99 }
catch (
const CircuitException &) {
102 if (!std::isfinite(out.datum))
118 const char *n = spec.family->name;
119 const bool is_erlang = std::strcmp(n,
"erlang") == 0;
120 const bool is_exponential = std::strcmp(n,
"exponential") == 0;
121 if (!is_erlang && !is_exponential)
124 if (is_exponential) {
141std::optional<DistributionSpec>
142foldConjugate(
const GenericCircuit &gc, std::optional<gate_t> target,
143 gate_t evidence,
double *log_evidence)
145 std::vector<gate_t> atoms;
146 if (!collectObserveAtoms(gc, evidence, atoms) || atoms.empty())
149 std::optional<gate_t> latent = target;
151 bool have_prior =
false;
154 for (
gate_t obs : atoms) {
155 auto o = parseObservation(gc, obs);
160 else if (o->latent != *latent)
170 if (!prior || !prior->family)
173 canonicalisePrior(post);
178 o->lik.family->name, o->wired_param, post.family->name);
182 if (!rule->log_predictive)
184 const double l = rule->log_predictive(post.p1, post.p2,
190 if (!rule->update(post.p1, post.p2, o->lik, o->datum))
195 *log_evidence = log_m;
201std::optional<DistributionSpec>
204 return foldConjugate(gc, target, evidence,
nullptr);
211 if (!foldConjugate(gc, std::nullopt, evidence, &log_m))
Generic directed-acyclic-graph circuit template and gate identifier.
gate_t
Strongly-typed gate identifier.
Exact conjugate-prior posteriors for observe-evidence circuits.
Per-family polymorphic view over a continuous gate_rv distribution (§F.1 class hierarchy).
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.
In-memory provenance circuit with semiring-generic evaluation.
std::string getExtra(gate_t g) const
Return the string extra for gate g.
std::optional< double > conjugateLogEvidence(const GenericCircuit &gc, gate_t evidence)
The exact log marginal likelihood of a conjugate-shaped evidence circuit; std::nullopt on any shape ...
const ConjugateRule * lookupConjugateRule(const std::string &likelihood_family, int wired_param, const std::string &prior_family)
Look up the conjugate rule for (likelihood family, wired parameter position, prior family); nullptr o...
double parseDoubleStrict(const std::string &s)
Strictly parse s as a double.
std::optional< DistributionSpec > conjugatePosterior(const GenericCircuit &gc, gate_t target, gate_t evidence)
The exact posterior of target given evidence, as a resolved distribution spec, when the circuit match...
std::optional< DistributionSpec > parse_distribution_spec(const std::string &s)
Parse the on-disk text encoding of a gate_rv distribution.
std::optional< DistributionTemplate > parse_distribution_template(const std::string &s)
Parse the on-disk text encoding of a gate_rv distribution, keeping wired (token) parameters as wire r...
const DistributionFamily * lookupDistributionFamily(const std::string &name)
Look up a family by its on-disk name token.
Core types, constants, and utilities shared across ProvSQL.
@ gate_observe
Latent-variable observation (likelihood-weighting evidence): one wire → an observed bare gate_rv leaf...
@ gate_rv
Continuous random-variable leaf (extra encodes distribution).
The conjugate update for one observation of a given likelihood family against the running posterior (...
A registered family's descriptor: its complete identity.
Parsed distribution spec (family + up to two parameters).