Prolog:如何在列表中找到特定元素?

时间:2013-05-14 21:30:03

标签: list prolog element

我必须实现这个谓词:

predicate(+connections, +[index,position], -leftConnections);

connections变量是一个如下所示的列表:

(conn(symbol1, element11, element21), conn(symbol2, element12, element22), etc)

我必须找到符号等于索引变量的连接。 然后,它必须验证两个elem中的哪一个等于位置变量,并保留另一个(让我们称之为new_pos);接下来,删除找到的连接,并在new_pos中的任意两个元素中搜索其他连接中的哪一个,并保留找到的新符号。

示例:

predicate([conn(1,P1,P2), conn(4,P2,P3), conn(3,P3,P1), conn(2,P6,P7)], [1, P2], left);

index = 1, position = P2 => new_position = P1 => new_symbol = 3
leftConnections = [conn(4,P2,P3), conn(3,P3,P1), conn(2,P6,P7)]

代码表示赞赏!

1 个答案:

答案 0 :(得分:1)

与每种编程语言一样,您必须将其分解为步骤。用你自己的话说,第一步是“找到符号等于索引变量的连接。”

这很简单:

predicate(Connections, [Index,Position], Remaining) :-
    select(conn(Index, Position, _), Connections, Remaining).
predicate(Connections, [Index, Position2], Remaining) :-
    select(conn(Index, _, Position2), Connections, Remaining).

这两个都有一个匿名变量,我们要保留new_pos,所以让我们保留它:

predicate(Connections, [Index, Position], Remaining) :-
    select(conn(Index, Position, NewPos), Connections, Remaining).
predicate(Connections, [Index, Position2], Remaining) :-
    select(conn(Index, NewPos, Position2), Connections, Remaining).

另一种方法:

predicate(Connections, [Index, Position], Remaining) :-
    select(conn(Index, Position, NewPos), Connections, Remaining) ;
    select(conn(Index, NewPos, Position), Connections, Remaining).

事实上,这将是完美的,但我们需要在某处传递NewPos,或者Prolog永远不会向我们展示它统一的内容。

select_position(Connections, [Index,Pos], Remaining, NewPos) :-
    select(conn(Index, Pos, NewPos), Connections, Remaining) ;
    select(conn(Index, NewPos, Pos), Connections, Remaining).

下一步是找到连接。这也不难:

find_with_position(Position, Connections, Connection) :-
    member(Connection, Connections),
    (Connection = conn(_, Position, _) ;
     Connection = conn(_, _, Position)).

这两个都有一些特殊情况逻辑来处理这两个项目都是正确的事实。您可能需要考虑使用列表,以便只使用成员。

将这些粘在一起并不难:

predicate(Connections, [Index, Position], Remaining, Target) :-
    select_position(Connections, [Index, Position], Remaining, NewPos),
    find_with_position(NewPos, Remaining, conn(Target,_,_)).

试一试:

?- predicate([conn(1,p1,p2), conn(4,p2,p3), 
              conn(3,p3,p1), conn(2,p6,p7)], [1, p2], Left, T).
Left = [conn(4, p2, p3), conn(3, p3, p1), conn(2, p6, p7)],
T = 3 ;
false.

你这里有很多问题。如果您正在为课程学习Prolog,我建议您学习一门教程,例如Learn Prolog NowAmzi Adventure