我想從prolog中減去另一個列表。在我的程序輸入列表中都有空格(如[1,2,_,4])Prolog Subtract List Unification
我得到以下輸出:
?- subtract([1,2,3,4],[3,4,_],L).
L = [2].
時,我想我的輸出是
L = [1,2].
所以我的問題是如何防止空白與其他元素統一?一直困在這一點上。
我想從prolog中減去另一個列表。在我的程序輸入列表中都有空格(如[1,2,_,4])Prolog Subtract List Unification
我得到以下輸出:
?- subtract([1,2,3,4],[3,4,_],L).
L = [2].
時,我想我的輸出是
L = [1,2].
所以我的問題是如何防止空白與其他元素統一?一直困在這一點上。
假設你想要的「空白空間」被忽略,你可以簡單地做一個版本的每個列表與刪除,並計算它們的區別:
listWOblanks([], []).
listWOblanks([H|T], Tx) :- var(H), !, listWOblanks(T, Tx).
listWOblanks([H|T], [H|Tx]) :- listWOblanks(T, Tx).
如果,當第一個列表有一個空白,第二個沒有,你需要結果仍然是空白的,你可以修改上面添加第三個參數,告訴你是否有空白被刪除,所以你可以相應地修正差異。我相信SWI-Prolog有一個謂詞,基礎,它會告訴你,如果一個術語沒有變量,它會做這個工作而不需要修改listWOblanks。
請不要通過調用匿名變量空白來提供OP的混淆。他們不是; ''''是空白的。 – 2012-02-28 14:32:32
實際上''''(0x20)是_space_字符(SP),不是空格:D – 2012-02-28 17:28:22
larsmans是正確的,_
是匿名變量,和lists:subtract/3
的定義(我假設你正在使用SWI-Prolog的)總是會統一使用他們到地面,因爲它的定義列表成員memberchk/2
。
如果你想subtract
行爲,其中的變量是一樣地方面來處理,那麼你可以重新定義它:
subtract2([], _, []) :- !.
subtract2([A|C], B, D) :-
var_memberchk(A, B), !,
subtract2(C, B, D).
subtract2([A|B], C, [A|D]) :-
subtract2(B, C, D).
注意subtract2/3
這裏幾乎是一樣的lists:subtract/3
定義(試行listing(subtract).
親自查看)。唯一的區別是所述列表成員謂詞,var_memberchk/2
,其被這樣定義:
var_memberchk(A0, [A1|_]) :-
A0 == A1, !.
var_memberchk(A0, [_|R]) :-
var_memberchk(A0, R).
此檢查是否一個變量,原子或術語是在列表中。所以,試圖由此我們得到:如果我們命名變量
?- subtract2([1,2,3,4],[3,4,_],L).
L = [1, 2].
注意,它仍然有效,如你所期望:
?- subtract2([1,2,A,3,B,4],[3,A,4],L).
L = [1, 2, B].
它也可以,如果我們明確給出名匿名變量,像這樣:
?- subtract2([1,2,_A,3,_B,4],[3,_A,4],L).
L = [1, 2, _B].
最後,需要注意的是,由於_
沒有一個名字,subtract2/3
將永遠能夠匹配它在任何列表中的其他變量的匿名,例如:
subtract2([1,2,_,4],[3,_,4],L).
L = [1, 2, _G415].
凡_G415
是由_
在第一輸入表所表示的匿名全局變量。第二個是不同的全局變量(例如_G416
),所以不能匹配第一個列表中的匿名變量。
另一種方式:
% Uses list catenation to generate sublists /subtraction
conc([], L, L).
conc([X|L1], L2, [X|L3]) :-
conc(L1, L2, L3).
% Finds all list members that have values and then
% use list catenation to generate the sublists
subtract(L1, L2, L3) :-
findall(D, (nth0(N, L2, D), nonvar(D)), PureL2),
conc(L3, PureL2, L1).
這假定只有一個列表中有「_」,但你可以做L1相同的findall如果兩個列表有同樣的問題。
這不是一個「空白空間」,這是一個匿名變量。 – 2012-02-28 14:31:53