Inferring an Arithmetic Expression

Following the examples in Probabilistic Models of Cognition on inferring arithmetic expressions (chapter 8), we show how to sample an arithmetic expression.

Using annotated disjunctions

Let’s start with a version where we sample an arithmetic expressing using annotated disjunctions:

0.7::leaf(T). 0.5::operator('+',T) ; 0.5::operator('-',T). Px::l(x,T); P::l(0,T); P::l(1,T); P::l(2,T); P::l(3,T); P::l(4,T); P::l(5,T); P::l(6,T); P::l(7,T); P::l(8,T); P::l(9,T) :- Px = 0.5, P is (1-Px)/10. expr(A) :- expr(A,1,R). expr(L,T1,T2) :- leaf(T1), T2 is T1+1, l(L,T1). expr(S,T1,T2) :- \+ leaf(T1), Ta is T1+1, expr(E1,Ta,Tb), expr(E2,Tb,T2), operator(Operator,Ta), S =.. [Operator,E1,E2]. query(expr(A)).

The output of sampling this program will be similar to:

expr(x)
expr(7)
expr('+'('+'('-'(5,8),x),1))
expr('+'('-'(x,x),6))
expr('-'(x,'+'('+'(7,8),'-'('+'(x,'-'(x,'+'(1,x))),'+'(4,9)))))

Using the lists library

As an alternative to an annotated disjunction which may be cumbersome to write down, we can we also make use of the lists library that is included with ProbLog. More specifically, the select_uniform predicate allows us to uniformly sample an element from a list.

:- use_module(library(lists)). 0.7::leaf(T). 0.5::operator('+',T) ; 0.5::operator('-',T). 0.5::select_x(T). l(x,T) :- select_x(T). % x=1 l(Value,T) :- \+select_x(T), findall(X, between(0,9,X), L), select_uniform(T, L, Value, _). expr(A) :- expr(A,1,R). expr(L,T1,T2) :- leaf(T1), T2 is T1+1, l(L,T1). expr(S,T1,T2) :- \+ leaf(T1), Ta is T1+1, expr(E1,Ta,Tb), expr(E2,Tb,T2), operator(Operator,Ta), S =.. [Operator,E1,E2]. query(expr(A)).