gpt4 book ai didi

list - Prolog-如何检查列表是否包含某些元素?

转载 作者:行者123 更新时间:2023-12-04 05:09:25 24 4
gpt4 key购买 nike

我是第一次尝试Prolog,并且在使用列表时遇到了一些困难。

说我有一个元素列表。我要检查列表是否包含以下元素:

全部:A1,A2,A3,A4,A5

下列其中一项:B1,B2,B3,B4

其中两个:C1,C2,C3,C4,C5,C6

例如,[A1,A2,B2,C1,A3,A4,C4,A5]符合要求,而[A2,A1,C1,B1,A3,A4]不符合要求。

如果列表满足要求,而返回“是/真”,否则返回否/“假”,我将如何写呢?同样,编写满足要求的列表中返回缺少值的东西又如何呢?

最佳答案

你问了很多问题!让我开始为您提供一些可以满足您大部分要求的谓词。

首先,让我们解决检查一个列表的所有条目也都在另一个列表中的情况:

subset([ ],_).
subset([H|T],List) :-
member(H,List),
subset(T,List).

这种简单的递归利用熟悉的 成员/2 谓词来验证 子集/2 的第一个参数指定的列表中的每个条目也都在第二个参数指定的列表中。 [为简单起见,我假定这些列表的条目是不同的。如果我们要验证第一个列表的条目的多个实例至少与第二个列表中的多个实例匹配,则需要一个更详细的版本。]

好吧,检查(至少)第一个列表中的一个也属于第二个列表又如何呢?显然,这是与上述谓词不同的谓词。如果没有 存在,而不是第一个列表中的所有项目,而不是 ,则要满足目标,即第一个列表中属于第二个列表的任何一个项目都存在
intersects([H|_],List) :-
member(H,List),
!.
intersects([_|T],List) :-
intersects(T,List).

如果递归 如果到达第一个参数的空列表,则失败,但是如果在找到第一个列表的成员的第二个列表之前的任何时候成功,则失败。 [即使一个项目的多个实例出现在任一列表中,此谓词也能正常工作。但是,如果我们想检查 到底是第一个列表的一个项是否属于第二个列表,则需要改进逻辑,这将使您担心多个实例是否与一个实例的确切计数一致或相对。

如果我们想对此检查进行概括,以验证(至少)第一个列表中的N个项目在第二个列表中,该怎么办?结果谓词将需要第三个参数:
intersectsAtLeast(_,_,N) :- N <= 0, !.
intersectsAtLeast([H|T],L,N) :-
member(H,L),
!,
M is N-1,
intersectsAtLeast(T,L,M).
intersectsAtLeast([_|T],L,N) :-
intersectsAtLeast(T,L,N).

此递归遍历整个列表,每当第一个列表中的一项也出现在第二个列表中时,将第三个参数递减一个,并在计数减少到0(或更少)时成功。 [如果列表可以重复,这里的代码又需要做更多的工作。]

最后,您会问有关编写满足要求的“返回缺失值”的东西的问题。在检查两个列表中的一个或多个项目的情况下,这没有很好地定义,因为“缺失值”可能是许多可能项目中的任何一个。在特殊情况下,如果我们要求第一个列表中的所有项目都属于第二个列表,则可以确定“缺失值”(如果有)。
missingValues([ ],_,[ ]).
missingValues([H|T],L,K) :-
member(H,L),
!,
missingValues(T,L,K).
missingValues([H|T],L,[H|K]) :-
missingValues(T,L,K).

在递归中,当且仅当递归项没有出现在第二个列表中时,才将它们从输入的第一个列表“移动”到输出的“缺失项”第三个列表。

关于您的问题的最后一点是关于符号。在Prolog中,变量是以大写字母或下划线开头的标识符,因此,如果将A1,A2等用作列表中的项目,则将其视为麻烦(如果将其视为“未知”而不是(如我假设您的意思是)不同的原子(常数)。切换到小写字母可以解决该问题。

关于list - Prolog-如何检查列表是否包含某些元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5188084/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com