2012-02-28 42 views
1

我想從prolog中減去另一個列表。在我的程序輸入列表中都有空格(如[1,2,_,4])Prolog Subtract List Unification

我得到以下輸出:

?- subtract([1,2,3,4],[3,4,_],L). 

L = [2]. 

時,我想我的輸出是

L = [1,2]. 

所以我的問題是如何防止空白與其他元素統一?一直困在這一點上。

+2

這不是一個「空白空間」,這是一個匿名變量。 – 2012-02-28 14:31:53

回答

1

假設你想要的「空白空間」被忽略,你可以簡單地做一個版本的每個列表與刪除,並計算它們的區別:

listWOblanks([], []). 
listWOblanks([H|T], Tx) :- var(H), !, listWOblanks(T, Tx). 
listWOblanks([H|T], [H|Tx]) :- listWOblanks(T, Tx). 

如果,當第一個列表有一個空白,第二個沒有,你需要結果仍然是空白的,你可以修改上面添加第三個參數,告訴你是否有空白被刪除,所以你可以相應地修正差異。我相信SWI-Prolog有一個謂詞,基礎,它會告訴你,如果一個術語沒有變量,它會做這個工作而不需要修改listWOblanks。

+1

請不要通過調用匿名變量空白來提供OP的混淆。他們不是; ''''是空白的。 – 2012-02-28 14:32:32

+4

實際上''''(0x20)是_space_字符(SP),不是空格:D – 2012-02-28 17:28:22

0

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),所以不能匹配第一個列表中的匿名變量。

0

另一種方式:

% 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如果兩個列表有同樣的問題。