Background on ProbLog for Biductive Computing

ProbLog is a variant of Prolog that supports probabilistic reasoning. Any Prolog fact or rule may be prepended with a number like 0.90:: to indicate the fact or rule holds only 90% of the time. Any fact or rule without such a number is assumed to hold 100% of the time, as is the usual case in Prolog. ProbLog takes these probabilities into account when computing the result of a query and gives a probability that the query holds rather than a strict true/false response.

Consider the classic “alarm” case. We have two people, John and Mary. They both call the police, presumably (but not necessarily) because they both heard an alarm. We want to know, was there a burglary or an earthquake that triggered the calls? Or neither?

Suppose there is a 5% chance of a burglary on any given night, and there is a 1% chance of a heavy earthquake, 19% chance of a mild earthquake, and 80% chance of no earthquake. The alarm will go off 90% of the time when both a burglary and a heavy earthquake happen at the same time; 80% chance it will go off if there is a burglary with no earthquake, and so on.

Any person (John or Mary) who hears an alarm has a 80% chance of calling the police, and a person may call the police 1% of the time for some other reason and without hearing an alarm.

Finally, suppose we know both John and Mary called (this is the “evidence”). We can then ask, what is the chance there was a burglary? And what is the chance there was an earthquake of each kind (none, mild, heavy)?

person(john).
person(mary).

0.05::burglary.

0.01::earthquake(heavy).
0.19::earthquake(mild).
0.8::earthquake(none).

0.90::alarm :-   burglary, earthquake(heavy).
0.85::alarm :-   burglary, earthquake(mild).
0.80::alarm :-   burglary, earthquake(none).
0.10::alarm :- \+burglary, earthquake(mild).
0.30::alarm :- \+burglary, earthquake(heavy).

0.8::calls(X) :- alarm, person(X).
0.01::calls(X) :- \+alarm, person(X).

evidence(calls(john),true).
evidence(calls(mary),true).

query(burglary).
query(earthquake(_)).

(Note, in ProbLog, queries are written in the source file as query() predicates.)

Running problog alarm.pl on the command line, we see that the results are:

         burglary:      0.62540235
earthquake(heavy):      0.06178646
 earthquake(mild):      0.49172412
 earthquake(none):      0.89488993

Thus, it is more likely than not that there was a burglary. The burglary and earthquake queries are independent, so we cannot combine the results and say “the most likely situation is burglary and no earthquake.” We would have to create a conjunction predicate:

burglary_earthquake(E) :- burglary, earthquake(E).

And query this specifically:

query(burglary_earthquake(_)).

The results are:

burglary_earthquake(heavy):     0.0086535011
 burglary_earthquake(mild):     0.16046227
 burglary_earthquake(none):     0.59521181

In other words, given that both John and Mary called, a burglary with no earthquake is more likely than a burglary with a simultaneous earthquake.