Pred にはバインドされていない変数が含まれています。最初の繰り返しで Pred を呼び出すと、これらの変数は最初に可能な値にバインドされます。再帰的なステップでは、Pred には既に変数がバインドされており、値を変更することはできません。だから...この解決策はうまくいきません。
SWI-Prolog からのトレース (何らかの理由で、new/2 を item/2 に名前変更する必要がありました):
第 1 レベル (呼び出し: my_findall(A,B,member(p(A,B), [p(1,2), p(3,4)]), L). )。
Call: (7) my_findall(_G819, _G820, member(p(_G819, _G820), [p(1, 2), p(3, 4)]), _G840) ? creep
Call: (8) lists:member(p(_G819, _G820), [p(1, 2), p(3, 4)]) ? creep
Exit: (8) lists:member(p(1, 2), [p(1, 2), p(3, 4)]) ? creep
p(A,B) = p(1,2) を得ました。この時点で、A は 1 にバインドされ、B は 2 にバインドされます。
^ Call: (8) not(item(1, 2)) ? creep
Call: (9) item(1, 2) ? creep
Fail: (9) item(1, 2) ? creep
^ Exit: (8) not(item(1, 2)) ? creep
OK、データベースに項目 (1,2) はありません。
^ Call: (8) assert(item(1, 2)) ? creep
^ Exit: (8) assert(item(1, 2)) ? creep
これで、item(1,2) が真になります。再帰呼び出し:
Call: (8) my_findall(_L215, _L216, member(p(1, 2), [p(1, 2), p(3, 4)]), _L199) ? creep
Pred を実行する別のソリューションを取得しましょう。
Call: (9) lists:member(p(1, 2), [p(1, 2), p(3, 4)]) ? creep
^^^^^^^
下線部が見えますか?
この手法を機能させるには、おそらく Pred をコピーして、N と P を再帰的に新しい変数に変更する必要があります。繰り返しごとに、N と P の新しいペアを「作成」する必要があります。copy_term/2 ( http://www.swi-prolog.org/pldoc/doc_for?object=copy_term%2f2 ) を確認してください。