Prolog获取列表中的每一项

时间:2013-11-21 16:35:56

标签: list prolog

我想写一个Prolog谓词 evenElement(List,Term)如果EvenElement等于Term

,则shoud suceed

到目前为止,我有这段代码

evenElement(L,TERM) :- evenElement_rec(L,TERM).
evenElement_rec([],0).
evenElement_rec([_,HEven|T],TERM):-
    evenElement_rec(T,TERM),
    isEqual(HEven,TERM).
isEqual(A,B) :- A is B.

永远不会调用isEqual,我该怎么做才能更改它将被执行?

输出是:

 trace,evenElement([1,2,3,4,5,6], 4).
    Call: (7) evenElement([1, 2, 3, 4, 5, 6], 4) ? creep
    Call: (8) evenElement_rec([1, 2, 3, 4, 5, 6], 4) ? creep
    Call: (9) evenElement_rec([3, 4, 5, 6], 4) ? creep
    Call: (10) evenElement_rec([5, 6], 4) ? creep
    Call: (11) evenElement_rec([], 4) ? creep
    Fail: (11) evenElement_rec([], 4) ? creep
    Fail: (10) evenElement_rec([5, 6], 4) ? creep
    Fail: (9) evenElement_rec([3, 4, 5, 6], 4) ? creep
    Fail: (8) evenElement_rec([1, 2, 3, 4, 5, 6], 4) ? creep
    Fail: (7) evenElement([1, 2, 3, 4, 5, 6], 4) ? creep
false.

2 个答案:

答案 0 :(得分:3)

当您编写Prolog谓词时,您可以像其他编程语言一样开始,立即深入研究这个问题。或者你可以先考虑这种关系,并考虑一些更简单的东西,即更通用的。你希望第一个参数是一个列表,第二个参数是一个“偶数”元素 - 我假设你的意思是一个元素出现在偶数位置。那就是:

list_evenelement(L, E) :-
   nth1(I,L,E),
   I mod 2 =:= 0.

但是,说你想自己实现它。我们可以从概括开始。在这种情况下:list_element/2对所有元素都适用:

list_element([E|_], E).
list_element([_|Es], E) :-
   list_element(Es, E).

这几乎就是你想要的。除了它有点过于笼统。也就是说,这套解决方案还包含您不喜欢的答案。特别是,第一个元素不应该是解决方案的一部分。因此,您必须专注于该计划。我们可以通过添加目标或删除子句来专门化程序(这相当于添加 false )。然而,消除这一事实太过分了 - 将不再有任何解决方案。

我会以不同的方式尝试,展开这样的定义:

list_element([E|_], E).
list_element([_|Es], E) :-
   list_element2(Es, E).

list_element2([E|_], E).
list_element2([_|Es], E) :-
   list_element(Es, E).

那应该是我们很好的定义太过笼统。但是,现在我们可以插入 false

list_element([E|_], E) :- false.
list_element([_|Es], E) :-
   list_element2(Es, E).

list_element2([E|_], E).
list_element2([_|Es], E) :-
   list_element(Es, E).

这剩下的部分是我们追捧的定义,你也可以更紧凑地说:

list_evenelement([_,E|_], E).
list_evenelement([_,_|Es], E) :-
   list_evenelement(Es, E).

答案 1 :(得分:2)

您的代码看起来比从问题陈述中获得的任何权利更复杂

  

我想编写一个Prolog谓词evenElement(List,Term),如果EvenElement等于Term,它就会成功。

假设您为列表元素编号相对于一个编号,因此对于列表[a,b,c,d],奇数元素(第1和第3个)分别为ac,事件元素(第2和第4)是bd(而不是零相对,其中a将是第0个元素而c是第2个,类似这样将会这样做。我们一次查看列表,2个元素:

even_element( [_,T|Xs] , T ) . 
even_element( [_,_|Xs] , T ) :-
  even_element( Xs , T ) .