pop.spy(pred, trckey)トレース・キーを省略した場合は,述語名がトレース・キーになります.
pop.trace(trcmask)トレース・マスクを省略した場合は,'.*' が仮定されますので,トレース・キーを設定したすべての述語がトレースの対象になります.
例えば,すべての使用者定義述語をトレースする設定は,次のようにすればできます.
for p in pop.userdefs(): pop.spy(p) pop.trace()
pop.spies()トレース・キー,トレース・マスクの解除は,それぞれ
pop.trace_mask()
pop.nospy(pred)を使用します. 詳細はリファレンスを参照してください.
pop.notrace()
このプログラムは,appendを逆に使って,リスト[1,2,3]のすべての分割を求めるものです.1: from PoP import * 2: pop = PoP() 3: Append = Atom('append') 4: a = Variable('a') 5: x = Variable('x') 6: y = Variable('y') 7: z = Variable('z') 8: pop.assertz(Append([], x, x)) 9: pop.assertz(Append(List(a, tail=x), y, List(a, tail=z)), 10: Append(x, y, z)) 11: pop.spy('append') 12: pop.trace() 13: r = pop.inquire(Append(x, y, [1,2,3])) 14: while r <> None: 15: print r 16: r = pop.inquire_next()
この結果,つぎのようにトレースが出力されます(これにも行番号を付けています).
‘ [spy]’で始まっている行がトレースの出力です. そうでない3,8,13,18行目がprint文の出力結果になっています(解は4つありましたね).1: [spy] C<0,0> append(_x#8ccb20, _y#8ccd70, [1, 2, 3]) 2: [spy] >> append([], _x, _x) --> append([], [1, 2, 3], [1, 2, 3]) 3: {'x': [], 'y': [1, 2, 3]} 4: [spy] R<0,1> append(_x#8ccb20, _y#8ccd70, [1, 2, 3]) 5: [spy] => append([_a | _x], _y, [_a | _z]) --> append([1 | _x#8d2bb0],_y#8d2be0, [1, 2, 3]) :- append(_x#8d2bb0, _y#8d2be0, [2, 3]) 6: [spy] C<1,0> append(_x#8d2bb0, _y#8d2be0, [2, 3]) 7: [spy] >> append([], _x, _x) --> append([], [2, 3], [2, 3]) 8: {'x': [1], 'y': [2, 3]} 9: [spy] R<1,1> append(_x#8d2bb0, _y#8d2be0, [2, 3]) 10: [spy] => append([_a | _x], _y, [_a | _z]) --> append([2 | _x#8d3cb0],_y#8d3ce0, [2, 3]) :- append(_x#8d3cb0, _y#8d3ce0, [3]) 11: [spy] C<2,0> append(_x#8d3cb0, _y#8d3ce0, [3]) 12: [spy] >> append([], _x, _x) --> append([], [3], [3]) 13: {'x': [1, 2], 'y': [3]} 14: [spy] R<2,1> append(_x#8d3cb0, _y#8d3ce0, [3]) 15: [spy] => append([_a | _x], _y, [_a | _z]) --> append([3 | _x#8d4dd0],_y#8d4e60, [3]) :- append(_x#8d4dd0, _y#8d4e60, []) 16: [spy] C<3,0> append(_x#8d4dd0, _y#8d4e60, []) 17: [spy] >> append([], _x, _x) --> append([], [], []) 18: {'x': [1, 2, 3], 'y': []} 19: [spy] R<3,1> append(_x#8d4dd0, _y#8d4e60, []) 20: [spy] << FAIL 21: [spy] R<2,2> append(_x#8d3cb0, _y#8d3ce0, [3]) 22: [spy] << FAIL 23: [spy] R<1,2> append(_x#8d2bb0, _y#8d2be0, [2, 3]) 24: [spy] << FAIL 25: [spy] R<0,2> append(_x#8ccb20, _y#8ccd70, [1, 2, 3]) 26: [spy] << FAIL
x:‘C’ならば呼出し(CALL)を,‘R’ならば再呼出し(REDO)を表わします.変数は,‘_’+(変数名)+(変数を一意に識別する値)の形式で表示されます.
y:一つの述語に対する一連の評価を区別するための識別子です.
z:評価の回数です.0ならば最初の呼出し,1以上ならば再呼出しの回数を表わします.
‘>>’は,事実と単一化が成功したことを表わします.‘>>’や,‘=>’の後には,どの事実/規則と単一化されたか,新たなゴール節は何かという情報が出力されています. 見ればわかりますね.
‘=>’は,規則と単一化が成功したことを表わします.
‘<< FAIL’は,失敗を表わします.
組込み述語や,コールバックが設定されているときには,これら以外の情報も出力されます. やはり‘ [spy]’で始まります.これらも意味は見ればわかるでしょうから,ここでは省略します.