在Prolog中查找列表项的前置/后继

时间:2014-04-24 18:41:28

标签: list prolog

我很难将想法从Lisp转换为Prolog。我确实找到了如何在Lisp中找到前任和后继者,但我很难在Prolog中实现相同的想法。我的语法很差。请帮帮我。

示例查询:

?- predecessor(b,[a,b,c],P).
P = a.                          % expected result

?- successor(b,[a,b,c],S).
S = c.                          % expected result

3 个答案:

答案 0 :(得分:3)

以下是DCG方法:

pred(X, P) --> stuff, [P,X], stuff.
succ(X, S) --> stuff, [X,S], stuff.
stuff --> [] | [_], stuff.

predecessor(X, L, P) :- phrase(pred(X, P), L).
successor(X, L, P) :- phrase(succ(X, S), L).

零星试验:

| ?- predecessor(a, [a,1,2,a,3], L).

L = 2 ? ;

no
| ?- predecessor(X, [1,2,3,2,5], 2).

X = 3 ? a

X = 5

no
| ?- successor(a, [a,1,2,a,3], L).

L = 1 ? a

L = 3

no
| ?- successor(X, [1,2,3,2,5], 2).

X = 1 ? a

X = 3

no
| ?-

Per @ false的评论,实现可以稍微整理一下:

predecessor(X, L, P) :- phrase((..., [P,X], ...), L).
successor(X, L, S) :- phrase((..., [X,S], ...), L).
... --> [] | [_], ... .

具有相同的测试结果。

答案 1 :(得分:2)

如果X是列表的第二个元素,则前一个(Y)是第一个:

pred( X, [Y,X|_], Y).

否则,请在列表的其余部分中查找前一个:

pred( X, [_|Z], Y ) :- pred( X, Z, Y ).

如果X是列表的第一个元素,则继承者(Y)是第二个:

succ( X, [X,Y|_], Y).

否则,请在列表的其余部分中查找后继者:

succ( X, [_|Z], Y ) :- succ( X, Z, Y ).

答案 2 :(得分:2)

你可以......

  • 使用内置append/3

    predecessor( X , L , P ) :- append( _ , [P,X|_] , L ) .
    
    successor(   X , L , S ) :- append( _ , [X,S|_] , L ) .
    
  • 自己动手:

    predecessor( X , [P,X|_] , P ) .
    predecessor( X , [_|T]   , P ) :- predecessor(X,T,P) .
    
    successor(   X , [X,S|T] , S ) .
    successor(   X , [_|T]   , S ) :- successor(X,T,S) .