我很难将想法从Lisp转换为Prolog。我确实找到了如何在Lisp中找到前任和后继者,但我很难在Prolog中实现相同的想法。我的语法很差。请帮帮我。
示例查询:
?- predecessor(b,[a,b,c],P).
P = a. % expected result
?- successor(b,[a,b,c],S).
S = c. % expected result
答案 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) .