2014-02-20 32 views
2

我寫了下面的謂詞append/3可以實現兩個列表組合:覆蓋預定義的謂詞的Prolog

append([L|Ls],R,[L|Result]):-append(Ls,R,Result). 
append([],X,X). 

它給出了一個正確的輸出,但是當我跟蹤代碼的執行流程,在這裏是我所得到的:

1 ?- edit. 
true. 

2 ?- make. 
% //dougal/cs0u$/cyw03u/desktop/lab3 compiled 0.00 sec, 3 clauses 
true. 

3 ?- trace. 
true. 

[trace] 3 ?- append([a,b,c],[d,e],X). 
    Call: (6) append([a, b, c], [d, e], _G554) ? creep 
    Call: (7) lists:append([b, c], [d, e], _G636) ? creep 
    Exit: (7) lists:append([b, c], [d, e], [b, c, d, e]) ? creep 
    Exit: (6) append([a, b, c], [d, e], [a, b, c, d, e]) ? creep 
X = [a, b, c, d, e]. 

看來,Prolog的是用我自己的附加謂詞在第一圈,但因爲它進入遞歸的第二個層次,Prolog有利用自身的謂詞在庫中定義。

我怎樣才能覆蓋Prolog的預定義謂詞(除了給我自己的謂詞另一個名字)?

+0

當我嘗試你的例子(在SWI Prolog中)時,我沒有得到相同的結果;它使用私有的「附加」版本。您使用的是哪個prolog解釋器? – lurker

+0

我也在使用SWI Prolog(版本是6.2.6) – Pingu

+0

我在版本6.0.2上。不知道這是結果不同的原因。你有更大的上下文,還是你看到這些結果只是輸入'swipl'並把你的代碼放在'[user]'中? – lurker

回答

1

append/3謂詞不是SWI-Prolog中的內置謂詞,而是庫謂詞,在模塊lists中定義。當您執行代碼時,該模塊可能會自動加載。有兩個標誌可以幫助這裏。 autoload標誌控制庫的自動加載。它可以關閉調用set_prolog_flag(autoload, false)。還有另一個標誌verbose_autoload,您可以將其設置爲true,以便自動加載變得冗長。最後但並非最不重要的,你可以使用listing/1謂詞來檢查你的代碼。嘗試listing(append/3)。它應該在你的謂詞的子句體中顯示對list:append/3的呼叫。

這就是我得到:

?- set_prolog_flag(verbose_autoload, true). 
true. 

?- [user]. 
append([L|Ls],R,[L|Result]):-append(Ls,R,Result). 
|: append([],X,X). 
|: % user://1 compiled 0.00 sec, 3 clauses 
true. 

?- listing(append/3). 
% autoloading user:listing/1 from /Users/pmoura/lib/swipl-7.1.8/library/listing 
% autoloading system:append/3 from /Users/pmoura/lib/swipl-7.1.8/library/lists 
lists:append([], A, A). 
lists:append([A|B], C, [A|D]) :- 
    append(B, C, D). 

system:append([], A, A). 
system:append([A|B], C, [A|D]) :- 
    append(B, C, D). 

append([A|B], C, [A|D]) :- 
    append(B, C, D). 
append([], A, A). 

true. 

?- trace. 
true. 

[trace] ?- append([a,b,c],[d,e],X). 
    Call: (6) append([a, b, c], [d, e], _G354) ? creep 
    Call: (7) append([b, c], [d, e], _G436) ? creep 
    Call: (8) append([c], [d, e], _G439) ? creep 
    Call: (9) append([], [d, e], _G442) ? creep 
    Exit: (9) append([], [d, e], [d, e]) ? creep 
    Exit: (8) append([c], [d, e], [c, d, e]) ? creep 
    Exit: (7) append([b, c], [d, e], [b, c, d, e]) ? creep 
    Exit: (6) append([a, b, c], [d, e], [a, b, c, d, e]) ? creep 
X = [a, b, c, d, e]. 

[trace] ?- 

您可以編輯您的文章,並告訴我們調用導致的結果你得到的精確序列?

+0

我已經編輯了我的調用序列的帖子。順便說一句,當我明確地鍵入命令'set_prolog_flag(autoload,false).'時,自動加載不會再次發生。 – Pingu

+0

我無法重現您的結果。我注意到你的'lab3'文件似乎包含10個子句,但你只向我們展示了'append/3'子句。也許該文件中的其他內容會導致您獲得的結果? –

+0

我剛剛試圖刪除其他代碼,只留下3行,但我仍然得到相同的結果(編輯後)。然而,如果我使用'[user]'方法,即使沒有明確調用set_prolog_flag(autoload,false),我也不會遇到這個問題。' – Pingu