Logic

The logic nodes compute Boolean functions of Boolean variables. A model uses them to build a probabilistic circuit, such as z ~ AND(x, y) in RxInfer's syntax. Each variable carries a Bernoulli belief, the probability that it is true.

The nodes are deterministic: their clusters are out and the joint over the inputs, whatever the factorisation. Every rule is therefore exact belief propagation over Bernoulli messages. The message towards out is the probability that the function is true, given independent inputs. The message towards an input weighs each of its two values by the message on out at the function's output, averaged over the message on the other input. The nodes run under DefaultAlgorithm.

nodefunctioninterfaces
AND$\mathrm{out} = \mathrm{in}_1 \wedge \mathrm{in}_2$out, in1, in2
OR$\mathrm{out} = \mathrm{in}_1 \vee \mathrm{in}_2$out, in1, in2
NOT$\mathrm{out} = \neg \mathrm{in}$out, in
IMPLY$\mathrm{out} = \mathrm{in}_1 \Rightarrow \mathrm{in}_2$out, in1, in2

The message towards out has log scale zero. A message towards an input is normalised, and it declares the log of its normaliser as its log scale. The joint marginal of two inputs is a Contingency table, with rows for in1 and columns for in2, false first. None of the nodes has an average energy of its own.

Example

Two fair coins, combined by OR, are true with probability 3/4. An implication that is true, with a true premise, forces its conclusion to be true:

julia> using StandardMessagePassingRules, MessagePassingRulesBase, Distributions

julia> message = getresult(@call_message_update_rule(node = OR, target = :out, m = (in1 = Bernoulli(0.5), in2 = Bernoulli(0.5))));

julia> mean(message) ≈ 0.75
true

julia> result = @call_message_update_rule(node = IMPLY, target = :in2, m = (out = Bernoulli(1.0), in1 = Bernoulli(1.0)));

julia> mean(getresult(result)) ≈ 1.0
true

AND

MessagePassingRulesBase.nodespec(AND)
NodeSpec: AND
in1in2outANDdeterministic
interfacealiases
out
in1
in2
default algorithmMessagePassingRulesBase.DefaultAlgorithm()
static inputsnone
definednodes/logic.jl:85
MessagePassingRulesBase.rule_coverage(AND)
Rule coverage for AND
DefaultAlgorithm
→ out✓
→ in1✓
→ in2✓
q(in1, in2)✓

The message towards out multiplies the probabilities of the inputs:

@call_message_update_rule(node = AND, target = :out, m = (in1 = Bernoulli(0.5), in2 = Bernoulli(0.8)))
RuleResult: message of AND towards :outbelief propagation
in1in2outAND
Result
valueDistributions.Bernoulli{Float64}(p=0.4)
typeDistributions.Bernoulli{Float64}
log scale0 (declared)
Inputs
edgevalue
in1mDistributions.Bernoulli{Float64}(p=0.5)
in2mDistributions.Bernoulli{Float64}(p=0.8)
Rule
declared inputsm[:in1]::Distributions.Bernoulli, m[:in2]::Distributions.Bernoulli
algorithmDefaultAlgorithm()
log scale0
definedand/rules.jl:1
body
args->Bernoulli(mean(args.m[:in1]) * mean(args.m[:in2]))
StandardMessagePassingRules.AND — Type
AND

The conjunction node, out = in1 ∧ in2, with interfaces out, in1 and in2. The message towards out is Bernoulli(p₁ p₂) for inputs Bernoulli(p₁) and Bernoulli(p₂).

Rules. Every message is a Bernoulli, the probability of true, and every rule is belief propagation over the other interfaces' messages: a deterministic node's clusters are always out and the joint over its inputs, whatever the factorisation. The rules towards out have log scale zero; those towards an input declare the log of their normaliser. The node runs under DefaultAlgorithm and has no average energy of its own.

The joint marginal of the inputs, q(in1, in2), is a Contingency table over {false, true}², rows in1 and columns in2, false first.

Examples

julia> message = getresult(@call_message_update_rule(node = AND, target = :out, m = (in1 = Bernoulli(0.5), in2 = Bernoulli(0.2))));

julia> mean(message) ≈ 0.1
true

See also OR, NOT, IMPLY.

source

OR

MessagePassingRulesBase.rule_coverage(OR)
Rule coverage for OR
DefaultAlgorithm
→ out✓
→ in1✓
→ in2✓
q(in1, in2)✓
StandardMessagePassingRules.OR — Type
OR

The disjunction node, out = in1 ∨ in2, with interfaces out, in1 and in2. The message towards out is Bernoulli(p₁ + p₂ - p₁ p₂) for inputs Bernoulli(p₁) and Bernoulli(p₂).

Rules. Every message is a Bernoulli, the probability of true, and every rule is belief propagation over the other interfaces' messages: a deterministic node's clusters are always out and the joint over its inputs, whatever the factorisation. The rules towards out have log scale zero; those towards an input declare the log of their normaliser. The node runs under DefaultAlgorithm and has no average energy of its own.

The joint marginal of the inputs, q(in1, in2), is a Contingency table over {false, true}², rows in1 and columns in2, false first.

See also AND, NOT, IMPLY.

source

NOT

MessagePassingRulesBase.rule_coverage(NOT)
Rule coverage for NOT
DefaultAlgorithm
→ out✓
→ in✓
StandardMessagePassingRules.NOT — Type
NOT

The negation node, out = ¬in, with interfaces out and in. Each message is the other interface's flipped: Bernoulli(1 - p) for Bernoulli(p), both ways.

Rules. Every message is a Bernoulli, the probability of true, and every rule is belief propagation over the other interfaces' messages: a deterministic node's clusters are always out and the joint over its inputs, whatever the factorisation. The rules towards out have log scale zero; those towards an input declare the log of their normaliser. The node runs under DefaultAlgorithm and has no average energy of its own. With a single input there is no joint marginal rule.

See also AND, OR, IMPLY.

source

IMPLY

MessagePassingRulesBase.rule_coverage(IMPLY)
Rule coverage for IMPLY
DefaultAlgorithm
→ out✓
→ in1✓
→ in2✓
q(in1, in2)✓
StandardMessagePassingRules.IMPLY — Type
IMPLY

The implication node, out = in1 → in2, with interfaces out, in1 and in2: false only when in1 is true and in2 false. The message towards out is Bernoulli(1 - p₁ + p₁ p₂) for inputs Bernoulli(p₁) and Bernoulli(p₂).

Rules. Every message is a Bernoulli, the probability of true, and every rule is belief propagation over the other interfaces' messages: a deterministic node's clusters are always out and the joint over its inputs, whatever the factorisation. The rules towards out have log scale zero; those towards an input declare the log of their normaliser. The node runs under DefaultAlgorithm and has no average energy of its own.

The joint marginal of the inputs, q(in1, in2), is a Contingency table over {false, true}², rows in1 and columns in2, false first.

See also AND, OR, NOT.

source