Skip to content

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:

P(defective) = 1 − (1 − 0.3)(1 − 0.2)(1 − 0.1)
             = 1 − 0.7 × 0.8 × 0.9
             = 1 − 0.504
             = 0.496

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:

P(all reliable) = 0.95 × 0.90 × 0.85
                = 0.72675

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 PROB
  • expr AS alias PROB
  • expr 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 exceeded max_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