2012-04-08 31 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