2012-11-23 108 views
-1

当且仅当L是包含R中不是列表的所有项的列表时,我需要编写一个成功的谓词f(L,R)。 例如:Prolog中的子列表中的所有元素的列表

f(L,[1,2,3,[4,5,6],[[7,8,9]],[]]). 

应该给:

L = [1,2,3,4,5,6,7,8,9] 

我写了一个谓词,给出了以下的结果,而不是:

L = [1,2,3,4,5,6,7,8,9,[]] 

空列表不应该出现在结果中。我的谓语如下:

f([],[]). 
f(V,[H|T]):- H = [_|_] -> append(L,R,V), 
       f(L,H), f(R,T),!; 
       V = [H1|T1], H1=H, f(T1,T). 

我有两个疑问。首先,空列表不应该出现在结果中。另外我不知道为什么它不起作用,如果我不切(!)。事实上,如果我不放弃它,它给了我上面的结果,但如果我要求另一个结果,它会永远循环。我真的不明白为什么这会循环。

+1

见本问题http://stackoverflow.com/questions/11220567/flatting-a-list/。通常,Input是第一个参数,输出第二个参数,例如f([1,2,3,[4,5,6],[[7,8,9]],[]],L)==> L [1,2,3,4,5,6,7,8,9] – joel76

回答

1

要删除空列表,请处理该情况(放弃它)。

关于循环:我认为原因可能是你调用append(L,R,V)与所有参数没有实例化:在递归调用后移动append。

最后,也许你不使用正确的“如果当时别人的构造:我已经使用通常的SWI-Prolog的源式的缩进,使用缩进来突出“顺序”呼吁

f([], []). 
f(V, [H|T]) :- 
    ( H = []  % if H = [] 
    -> f(V, T)  % then discard 
    ; H = [_|_] % else if H is list 
    -> f(L,H),  % flat head 
     f(R,T),  % ... 
     append(L,R,V) 
    ; V = [H|T1], % else 
     f(T1,T)  % ... 
    ). 
+0

非常感谢您的提示!现在它完美地工作。 – markusian