logic-and-learning-lab/Popper

KeyError, but sometimes solution, without changing things

Closed this issue · 2 comments

Greetings! I'm experimenting with Popper and encountered some strange behavior. When giving popper the files below I get the following error:

16:45:35 Generating programs of size: 2
16:45:35 Generating programs of size: 3
16:45:35 Generating programs of size: 4
Traceback (most recent call last):
  File "/bin/popper-ilp", line 8, in <module>
    prog, score, stats = learn_solution(settings)
  File "/lib/python3.10/site-packages/popper/loop.py", line 1092, in learn_solution
    timeout(settings, popper, (settings,), timeout_duration=int(settings.timeout),)
  File "/lib/python3.10/site-packages/popper/util.py", line 81, in timeout
    result = func(*args, **kwargs)
  File "lib/python3.10/site-packages/popper/loop.py", line 1050, in popper
    generator.constrain(new_cons, model)
  File "/lib/python3.10/site-packages/popper/generate.py", line 598, in constrain
    cons_ = self.unsat_constraint2(con_prog)
  File "lib/python3.10/site-packages/popper/generate.py", line 944, in unsat_constraint2
    args2 = tuple(assignment[x] for x in atom.arguments)
  File "/lib/python3.10/site-packages/popper/generate.py", line 944, in <genexpr>
    args2 = tuple(assignment[x] for x in atom.arguments)
KeyError: 'F'

Sometimes with 'F' and sometimes with 'D'. But other times it actually finds a solution giving no error:

16:45:35 Generating programs of size: 2
16:45:36 Generating programs of size: 3
16:45:36 Generating programs of size: 4
16:45:36 Generating programs of size: 5
16:45:36 ********************
16:45:36 New best hypothesis:
16:45:36 tp:1 fn:1 tn:14 fp:0 size:5
16:45:36 action(A,B,C):- is_action_pickup(B),arg(D,C),on(A,D,F),clear(E,F).
16:45:36 ********************
********** SOLUTION **********
Precision:1.00 Recall:1.00 TP:2 FN:0 TN:14 FP:0 Size:5
action(A,B,C):- clear(A,D),on(A,D,E),arg(D,C),is_action_pickup(B).
******************************

bias.pl:

head_pred(action, 3).

body_pred(clear, 2).
body_pred(on, 3).

body_pred(is_action_pickup, 1).
body_pred(is_action_putdown, 1).

body_pred(arg, 2).

type(action, (element, element, list)).
type(arg, (element, list)).

bk.pl:

clear(s_p004_1, b0).

clear(s_p004_2, b0).
clear(s_p004_2, b1).

on(s_p004_1, b0, b1).
on(s_p004_1, b1, b2).
on(s_p004_1, b2, b3).

on(s_p004_2, b1, b2).
on(s_p004_2, b2, b3).

is_action_putdown(putdown).
is_action_pickup(pickup).

arg(X, [X]).

exs.pl:

neg(action(s_p004_1, pickup, [X])) :- member(X, [b1, b2, b3]).
neg(action(s_p004_1, putdown, [X])) :- member(X, [b0, b1, b2, b3]).
neg(action(s_p004_2, pickup, [X])) :- member(X, [b0, b2, b3]).
neg(action(s_p004_2, putdown, [X])) :- member(X, [b0, b1, b2, b3]).

pos(action(s_p004_1, pickup, [b0])).
pos(action(s_p004_2, pickup, [b1])).

Hi,

Which version of Popper are you using? That looks like an old bug. I suggest downloading the latest version.

Also, you have missing types for some relations, which will make Popper crash.

You can also make Popper much faster by providing simpler examples and BK.

Here are the revised files:

bias.pl

head_pred(action, 3).

body_pred(clear, 2).
body_pred(on, 3).

body_pred(is_action_pickup, 1).
body_pred(is_action_putdown, 1).

%% body_pred(arg, 2).

%% type(action, (element, element, list)).
%% type(arg, (element, list)).

bk:

clear(s_p004_1, b0).

clear(s_p004_2, b0).
clear(s_p004_2, b1).

on(s_p004_1, b0, b1).
on(s_p004_1, b1, b2).
on(s_p004_1, b2, b3).

on(s_p004_2, b1, b2).
on(s_p004_2, b2, b3).

is_action_putdown(putdown).
is_action_pickup(pickup).

%% arg(X, [X]).

exs:

neg(action(s_p004_1, pickup, X)) :- member(X, [b1, b2, b3]).
neg(action(s_p004_1, putdown, X)) :- member(X, [b0, b1, b2, b3]).
neg(action(s_p004_2, pickup, X)) :- member(X, [b0, b2, b3]).
neg(action(s_p004_2, putdown, X)) :- member(X, [b0, b1, b2, b3]).

pos(action(s_p004_1, pickup, b0)).
pos(action(s_p004_2, pickup, b1)).

Given this input, Popper learns:

Generating programs of size: 4
********** SOLUTION **********
Precision:1.00 Recall:1.00 TP:2 FN:0 TN:14 FP:0 Size:4
action(V0,V1,V2):- is_action_pickup(V1),clear(V0,V2),on(V0,V2,V3).

Thank you for your fast response! Yes you were right, I was using an older version and in the new version it seems to works good.

In my examples I needed the last argument to be a list because of other cases I left out, who had more than one item.