Probabilistic Logic (MNOR / MPROD / PROB)¶
The Problem¶
Standard fold operators break down for probability combination:
- MSUM overestimates — summing probabilities can exceed 1.0, producing invalid results.
- MMAX underestimates — taking the maximum ignores the reinforcement from multiple independent paths.
When your domain is probabilities (values in [0, 1]), you need operators that respect probability semantics.
MNOR — Noisy-OR¶
Formula: P = 1 − ∏(1 − pᵢ)
Semantics: "Any independent cause can trigger the effect." Each input is an independent probability that some cause produces the effect. The combined probability is: what is the chance that at least one cause fires?
| Property | Value |
|---|---|
| Identity | 0.0 (no causes → no effect) |
| Direction | Non-decreasing (more causes → higher probability) |
| Domain | Inputs clamped to [0, 1] |
Worked Example¶
Three quality signals flag a component as defective with probabilities 0.3, 0.2, and 0.1:
In Locy:
CREATE RULE component_failure_risk AS
MATCH (c:Component)-[:HAS_SIGNAL]->(s:QualitySignal)
FOLD risk = MNOR(1.0 - s.pass_rate)
YIELD KEY c, risk
With three signals having pass rates 0.7, 0.8, and 0.9 (failure probabilities 0.3, 0.2, 0.1), the fold computes 1 − (1−0.3)(1−0.2)(1−0.1) = 0.496.
MPROD — Product¶
Formula: P = ∏ pᵢ
Semantics: "All conditions must hold simultaneously." Each input is an independent probability of success. The combined probability is: what is the chance that every condition holds?
| Property | Value |
|---|---|
| Identity | 1.0 (no conditions → certain) |
| Direction | Non-increasing (more conditions → lower probability) |
| Domain | Inputs clamped to [0, 1] |
Underflow Protection¶
When many small probabilities are multiplied, the product can underflow to zero. MPROD automatically switches to log-space accumulation (exp(∑ ln(pᵢ))) when the running product drops below 1e-15. If any input is exactly 0.0, the result is immediately 0.0.
Worked Example¶
A vendor supplies three components with individual reliabilities 0.95, 0.90, and 0.85:
In Locy:
CREATE RULE vendor_reliability AS
MATCH (v:Vendor)-[:SUPPLIES]->(c:Component)
WHERE c IS component_failure_risk
FOLD reliability = MPROD(1.0 - component_failure_risk.risk)
YIELD KEY v, reliability
MPROD multiplies over matched rows, not over an expected set
MPROD takes the product of the rows that actually match the clause body for each group. A condition that produces no matching row is simply absent from the product — it does not force the result to zero. So MPROD alone does not encode "every required element must be present."
To express a true all-elements conjunction — e.g. a patent claim is infringed only
when a product maps every one of its elements — pair MPROD with an explicit
completeness guard: count the matched elements and the total elements and keep only
groups where they are equal, or exclude incomplete groups with an IS NOT complement.
// total elements per claim
CREATE RULE claim_size AS
MATCH (c:Claim) WHERE c IS claim_elements TO ce
FOLD n_total = COUNT(ce) YIELD KEY c, n_total
// product over the elements this product actually maps
CREATE RULE pc_mapped AS
MATCH (p:Product), (c:Claim)
WHERE c IS claim_elements TO ce, p IS element_mapped TO ce
FOLD n_mapped = COUNT(ce), infringement = MPROD(mapping_conf)
YIELD KEY p, KEY c, n_mapped, infringement
// keep only fully-mapped (p, c) pairs — the all-elements guard
CREATE RULE claim_infringed AS
MATCH (p:Product), (c:Claim)
WHERE (p, c) IS pc_mapped, c IS claim_size TO n_total, n_mapped = n_total
YIELD KEY p, KEY c, infringement
When to Use Which¶
| Operator | Semantics | Direction | Use When |
|---|---|---|---|
| MSUM | Sum | ↑ | Non-negative counts or weights |
| MMAX | Maximum | ↑ | Worst-case / dominant signal |
| MMIN | Minimum | ↓ | Best-case / bottleneck |
| MNOR | Noisy-OR | ↑ | Independent OR-causes (probabilities) |
| MPROD | Product | ↓ | Independent AND-conditions (probabilities) |
Rule of thumb: If you're asking "could any of these cause X?" use MNOR. If you're asking "do all of these hold?" use MPROD.
Compiler Guardrails¶
ProbabilityDomainViolation warning. When MNOR or MPROD is used with non-literal arguments, the compiler emits a warning reminding you that inputs should be valid probabilities in [0, 1]. Literal constants (e.g., MNOR(0.3)) are checked at compile time and do not trigger the warning.
BEST BY rejection. Monotonic folds (including MNOR and MPROD) are incompatible with BEST BY witness selection. The compiler rejects this combination with a BestByWithMonotonicFold error.
Input clamping. At runtime, values outside [0, 1] are clamped before computation. This prevents NaN or negative results from bad data, but you should fix the upstream source rather than relying on clamping.
PROB Columns and Probabilistic Negation¶
PROB marks one output column in a rule as the probability channel for that relation:
CREATE RULE supplier_risk AS
MATCH (s:Supplier)-[:HAS_SIGNAL]->(sig:Signal)
FOLD risk = MNOR(sig.risk)
YIELD KEY s, risk AS PROB
Accepted forms:
expr AS PROBexpr AS alias PROBexpr PROB
If IS NOT targets a rule with a PROB column, Locy uses probabilistic complement (1 - p) instead of Boolean anti-join:
CREATE RULE usable_supplier AS
MATCH (s:Supplier)
WHERE s IS NOT supplier_risk
YIELD KEY s, 1.0 AS confidence PROB
If the referenced rule has no PROB column, IS NOT keeps standard Boolean semantics.
Shared-Proof Detection and Exact Mode¶
MNOR and MPROD assume independent derivations. When multiple proof paths in the same aggregate group share the same underlying evidence, the runtime emits SharedProbabilisticDependency.
Set exact_probability = true in LocyConfig to enable BDD-backed exact probability computation for those groups. Two important fallbacks remain:
BddLimitExceeded: the group exceededmax_bdd_variables, so Locy falls back to the independence result for that key group.CrossGroupCorrelationNotExact: shared evidence spans multiple aggregate groups; each group is exact internally, but cross-group correlation is still approximate.
Rows from approximate groups are marked with _approximate = true, and Rust LocyResult values also expose approximate_groups.
TopKProofs Semiring (DNF Inclusion-Exclusion)¶
LocyConfig.semiring = TopKProofs(k) is an alternative to the BDD path. The runtime keeps the top k proofs per derived fact (ranked by proof probability) and, for MNOR aggregates whose proofs share base facts, computes the exact joint via DNF inclusion-exclusion instead of the independence approximation. Cheaper than BDD for moderate k; emits TopKPruningCrossedDependency when pruning drops a proof that shares a base fact with a retained one, so you can decide whether to bump k.
MaxMinProb Semiring (Viterbi / Fuzzy)¶
LocyConfig.semiring = MaxMinProb changes the aggregate math: MNOR becomes max(pᵢ) and MPROD becomes min(pᵢ). Useful when the values aren't probabilities (e.g. fuzzy-set memberships) and you want monotone composition without the independence assumption. Locy emits FuzzyNotProbabilistic on any rule that also declares PROB under this semiring, since you've opted out of probability semantics.
Relevant Config Knobs¶
| Field | Default | Effect |
|---|---|---|
strict_probability_domain |
false |
Reject out-of-range values instead of clamping |
probability_epsilon |
1e-15 |
MPROD threshold for switching to log-space accumulation |
exact_probability |
false |
Enable BDD-based exact evaluation for shared-proof groups |
max_bdd_variables |
1000 |
Cap per-group BDD complexity before fallback |
Combining with similar_to¶
similar_to() returns scores in [0, 1], making its output natural probability input for MNOR and MPROD:
-- Combine semantic relevance signals with noisy-OR
CREATE RULE evidence_strength AS
MATCH (claim:Claim)-[:SUPPORTED_BY]->(doc:Document)
FOLD strength = MNOR(similar_to(doc.embedding, claim.text))
YIELD KEY claim, strength
-- Joint confidence across required criteria
CREATE RULE joint_match AS
MATCH (job:Job)-[:REQUIRES]->(skill:Skill)<-[:HAS]-(candidate:Candidate)
FOLD fit = MPROD(similar_to(skill.embedding, candidate.resume))
YIELD KEY job, KEY candidate, fit
Related¶
- ALONG / FOLD / BEST BY — full FOLD documentation
- Rule Semantics — monotonicity and stratification
- Vector Search guide —
similar_to()documentation - Neural Predicates —
CREATE MODEL/CALIBRATE/VALIDATEand theNeuralProvenanceaudit trail