2012-04-08 33 views
2

還有一個問題,我已經刪除了良好的工作「功能」:刪除或列表中SWI-Prolog的

remove([],X,[]) :- !. 
remove([X|T],X,L1) :- !, remove(T,X,L1).   
remove([H|T],X,[H|L1]) :- remove(T,X,L1). 

但它不喜歡的工作,我希望它工作。 它刪除元素或甚至列表...

...但不刪除所有外觀。這就是目標:

remove([A,B,[C],[A,[B]],[[A,[B]]]],[A,[B]],X). 
X=[A,B,[C],[]] 

任何想法?

回答

4

如果你想刪除所有出現例如,讓除去([1,2,3,1],1,X)計算X = [2,3]只是替換

remove([X|T],X,L1) :- remove(T,X,L1), !. 
第二條款

但是,您似乎希望a)使用應作爲變量保存的變量,以及b)從子列表中刪除列表。

我們將首先解決b)問題。

remove([],_,[]) :- !. 
remove(A,_,A) :- \+ (A = [_|_]), !. 
remove([X|T],X,L1) :- remove(T,X,L1), !.   
remove([H|T],X,[G|L1]) :- remove(H,X,G), remove(T,X,L1). 

正如您所看到的,我們將第二個遞歸調用添加到最後一個子句來處理內部列表。此外,由於第一個參數不一定是列表,我們必須添加一個特例(第二個子句)。

最後,要解決a)需要使用Sterling和Shapiro的「freeze」/「melt」謂詞。凍結用表達式#VAR(0),#VAR(1),...替換變量,而熔化則相反。熔體傳統上被稱爲melt_new

numvars('#VAR'(N),N,N1) :- N1 is N+1. 
numvars(Term,N1,N2) :- nonvar(Term), functor(Term,_,N), 
          numvars(0,N,Term,N1,N2). 

numvars(N,N,_,N1,N1). 
numvars(I,N,Term,N1,N3) :- I<N, I1 is I+1, 
      arg(I1,Term,Arg), numvars(Arg,N1,N2), 
      numvars(I1,N,Term,N2,N3). 

frz(A,B) :- frz(A,B,0). 
frz(A,B,Min) :- copy_term(A,B), numvars(B,Min,_),!. 


melt_new(A,B) :- 
    melt(A,B,Dictionary), !. 

melt('$VAR'(N),X,Dictionary) :- 
    lookup(N,Dictionary,X). 
melt(X,X,Dictionary) :- 
    constant(X). 
melt(X,Y,Dictionary) :- 
    compound(X), 
    functor(X,F,N), 
    functor(Y,F,N), 
    melt(N,X,Y,Dictionary). 

melt(N,X,Y,Dictionary) :- 
    N > 0, 
    arg(N,X,ArgX), 
    melt(ArgX,ArgY,Dictionary), 
    arg(N,Y,ArgY), 
    N1 is N-1, 
    melt(N1,X,Y,Dictionary). 
melt(0,X,Y,Dictionary). 

/* 
    lookup(Key,Dictionary,Value) :- 
    Dictionary contains the value indexed under Key. 
    Dictionary is represented as an ordered binary tree. 

*/ 

    lookup(Key,dict(Key,X,Left,Right),Value) :- 
     !, X = Value. 
    lookup(Key,dict(Key1,X,Left,Right),Value) :- 
     Key < Key1 , lookup(Key,Left,Value). 
    lookup(Key,dict(Key1,X,Left,Right),Value) :- 
     Key > Key1, lookup(Key,Right,Value). 

順便說一句,我真的建議英鎊和夏皮羅「序言的藝術」的書。 熔融和冷凍在第15章中討論。

+0

非常感謝您用盡代碼! 關於第一個(更簡單)的問題。這是我得到的: ' - 刪除([A,B,[C],[A,[B]],[[A,[B]]]],[A,[B] 。 B = C,C = [C,[C]], X = [[],[]]。爲什麼? – 2012-04-09 06:29:24

+2

你得到的答案與意想不到的統一有關。如上所定義的謂詞刪除將按照您期望的僅用於(列表)基礎條件列表(=沒有變量的條件)。如果您想將其應用於非地面案例,您首先需要制定條件(凍結),然後調用remove/3,最後返回非地面案例(melt_new)。 – 2012-04-09 10:01:57

+0

@AlexanderSerebrenik對我來說簡單的修改工作(下)。但即使使用跟蹤,我仍然困惑於遞歸如何工作。你可以通過下面的例子走路嗎? '無([],_ X,[]): - !。 ([X | T],X,Result): - !,無(T,X,Result)。 ([H | T],X,[H |結果]): - 無(T,X,結果) 。 '使用查詢:'無([1,3,5],3,X)' – mdo123 2016-12-05 22:11:59