Popper (GitHub - logic-and-learning-lab/Popper: Popper is an inductive logic programming (ILP) system.) is a really interesting Inductive Logic Programming (ILP) system, using SWI-Prolog and ASP (Clingo) to find Prolog programs (as definition of a predicate) given some positive and negative examples. It’s still a work-in-progress but it evolves quite fast now and can solve some interesting/fun instances.
My Popper page (My Popper page) contains some examples that Popper now can solve. Also see Popper’s example directory (Popper/examples at main · logic-and-learning-lab/Popper · GitHub ) for some other examples.
For example, Popper solve this puzzle (which was at Facebook the other day) in some second:
1 + 4 = 5
2 + 5 = 12
3 + 6 = 21
5 + 8 = ??
Here’s Popper’s solution:
f(A,B,C):- mult(A,B,D),plus(A,D,C).
I.e. ??
= 45, which is one of the (many) possible answers to the puzzle.
Popper also supports predicate invention so it can find solutions as the following for a graph problem (relatedness ):
target(A,B) :- inv1(B,C),
inv1(A,C). inv1(A,B) :- parent(A,B).
inv1(A,B) :- parent(C,A),inv1(C,B).
where inv1
is the invented predicate.
Note that some of the solutions that Popper finds might not be the best solution, for example the predicate might not be reversible as one would expect if a Prolog programmer wrote it.
Compared to other ILP systems that I have played with (e.g. Metagol, Progol, Aleph), Popper is - IMHO - a little easier to use since one don’t have to state the type or directions of the background knowledge (BK) predicates; but given this information might boost the performance. However, the other systems - especially Aleph - have features that Popper don’t support (yet?), such as noise. Also it don’t support constants (but one can use “names constants”, see constants1_b for an example). And it don’t handle floats very well.
One approach that I probably will delve into further is to use clpfd
together with Popper to try to find the valid constraints given some examples. Here’s a first tests of this: clpfd_test with quite a few different small tests. Note that it use my SWI Prolog utils file: My SWI-Prolog page /hakank_utils.pl .
For example, given the following positive (pos/1
) and negative (neg/1
) examples:
pos(target([2,3,4,5,1])).
pos(target([2,3,5,1,4])).
pos(target([2,4,5,3,1])).
pos(target([2,4,1,5,3])).
pos(target([2,5,4,1,3])).
neg(target([1,2,3,4,5])).
Popper find the constraint circuit/1
. The negative example ([1,2,3,4,5]
) makes it skip other constraints such as all_different
.