You’re right, this should not happen- it’s either a bug or there’s garbage left behind in the dynamic database. I’ll give it a try with a clean session.
Edit: your meta-intepreter from the SO question sure looks useful for quick debugging.
Edit: OK, I see what happened- you’re putting the entire program and background knowledge (BK) together in the _Ts variable, which is for the program alone, so if a successful refutation sequence exists for an example that includes a clause in the BK you will get that clause in the output.
The question is: where does a successful refutation sequence come from, that involves s/2? The answer is: from the positive example, s^2(foo)
itself. prove_examples/6
asserts the positive examples in _Pos to the dynamic database. So there always is at least one refutation sequence for each example in _Pos that includes the example itself.
I can see this happening when I turn on logging with debug(remove_null)
:
% Proving positive example
% nat(s(s(foo))).
% Called clause 4
% s(s(foo),foo).
% Called clause 4
% s(s(s(foo)),s(foo)).
% Called clause 7
% nat(s(s(foo))).
% Proved positive example
% nat(s(s(foo))).
% Collected clause indices
% [4,7].
Why are the positive examples added to the dynamic database. Are they not always entailed by the program? Yes, but there are some recursive clauses that were induced by resolution with the positive examples. This allows Louise to construct some recursive clauses, those that don’t need to self-resolve, but can be constructed by resolution of their recursive goals with positive examples. So the positive examples must be in the program database along with the rest of the program (which would have normally been learned by Louise) to act as a base-case for some recursions. This is part of why what I’m trying to do is so fiddly- and why I need to find all refutation sequences. If you look at the code, it should also explain why the examples in _Pos are asserted to the dynamic database (with a call to assert_program/3
and why this is done after the clauses in _Ts are asserted).
Edit 2: on second thoughts that doesn’t quite explain it- clause 4 (s/2) never resolves successfully so it shouldn’t be in the successful refutation sequence. There’s a bug for sure. Thanks for pointing it out
Edit 3: For the time being, if you separate the program from the BK you get a result that makes sense:
?- _Ts = [(nat(X1) :- even(X1)), (nat(X2) :- odd(X2)), (odd(A):-s(A,B),even(B)), s(s(X3),X3), even(0), (even(s(X4)):-odd(X4))],
_BK = [],
_Pos = [nat(s(s(foo)))],
_Neg = [],
_Ss = [nat/1],
prove_examples(_Ts, _Pos, _Neg, _BK, _Ss, _Ts_), print_clauses(_Ts_).
s(s(A),A).
nat(s(s(foo))).
true.