List Prolog,尝试附加2个列表,但不断出错

List Prolog,尝试附加2个列表,但不断出错,list,prolog,append,rules,List,Prolog,Append,Rules,我基本上是想得到一个返回X=[c,a],但一直都是假的。Prolog不是函数式语言。在编写appendsecondX、firstX、X时,第一个和第二个参数不会分别替换为List[\uS、\uU]和List[F、\uU、\uU]。如果您尝试改为: lists([a,b,c]). first(F):-lists([F,_,_]). second(S):-lists([_,S,_]). last(L):-lists([_,_,L]). sf(X):-append(second(X),

我基本上是想得到一个返回X=[c,a],但一直都是假的。

Prolog不是函数式语言。在编写appendsecondX、firstX、X时,第一个和第二个参数不会分别替换为List[\uS、\uU]和List[F、\uU、\uU]。如果您尝试改为:

lists([a,b,c]).

first(F):-lists([F,_,_]).  
second(S):-lists([_,S,_]).  
last(L):-lists([_,_,L]).  

sf(X):-append(second(X),first(X),X).

?-sf(X) //returns false
您将获得失败:

sf(List) :-
    second(Second),
    first(First),
    append(Second, First, List).
为了理解原因,让我们在调试器中跟踪调用:

| ?- sf(List).

no

事实上的标准append/3谓词,通常作为库谓词或内置谓词提供,将列表作为参数,但这里我们用原子a和b来调用它。你能从这里继续吗?

这里有几个问题。首先,像这样的电话:

| ?- trace.
The debugger will first creep -- showing everything (trace)

yes
{trace}
| ?- sf(List).
      1    1  Call: sf(_279) ? 
      2    2  Call: second(_346) ? 
      3    3  Call: lists([_332,_334,_336]) ? 
      3    3  Exit: lists([a,b,c]) ? 
      2    2  Exit: second(b) ? 
      4    2  Call: first(_400) ? 
      5    3  Call: lists([_386,_388,_390]) ? 
      5    3  Exit: lists([a,b,c]) ? 
      4    2  Exit: first(a) ? 
      6    2  Call: append(b,a,_279) ? 
      6    2  Fail: append(b,a,_279) ? 
      1    1  Fail: sf(_279) ? 

(1 ms) no
{trace}
但是现在它仍然是不正确的,这里我们用X统一了第一个和第二个列表,并且我们将它附加到X,appendX,X,X只能在一种情况下成功:如果X是空列表,因为附加两个空列表会导致一个空列表

sf(X) :- second(X), first(X), append(X, X, X).
不能将/3两个常量b和a一起追加,可以将列表a和b一起追加,因此:

?- first(X).
X = a.
第一个/1和第二个/1谓词也太具体了:如果lists/1包含一个包含四个元素的列表,那么这些谓词将失败,因此我建议您重构它们

sf(X) :- second(S), first(F), append(S, F, X).
?- first(X).
X = a.
sf(X) :- second(S), first(F), append([S], [F], X).