List 满足特定条件的子列表的Findall/3
我有两个列表List 满足特定条件的子列表的Findall/3,list,prolog,List,Prolog,我有两个列表L1和L2: L1=[1,4,5,6,7,8]. L2=[2,3]. 和一个谓词: related(X,Y). 我想找到一个列表L3: 这是L1 其中L3的所有元素都是Y的解,其中L2的任何值都是X 换句话说,使用findall/3将L2的所有值输入到X,并找出L1的哪些值将是Y的相应解决方案这可以通过这种方式完成(如果我正确理解您的条件): 在我的评论中,由于误读了您的条件,我的X有点混淆,但想法仍然是一样的。您只需建立适当的目标作为findall/3的第二个参数即可获得所需的
L1
和L2
:
L1=[1,4,5,6,7,8].
L2=[2,3].
和一个谓词:
related(X,Y).
我想找到一个列表L3
:
L1
L3
的所有元素都是Y
的解,其中L2
的任何值都是X
换句话说,使用
findall/3
将L2
的所有值输入到X
,并找出L1
的哪些值将是Y
的相应解决方案这可以通过这种方式完成(如果我正确理解您的条件):
在我的评论中,由于误读了您的条件,我的X
有点混淆,但想法仍然是一样的。您只需建立适当的目标作为findall/3
的第二个参数即可获得所需的结果。
如果希望得到唯一、有序的结果,可以使用
setof/3
:
setof(Y, (member(Y, L1), member(X, L2), related(X, Y)), L3).
结构如下:
findall(+Template, :Goal, -Bag)
其中:
是您想要获得的结果列表李>Bag
是应该成功的谓词(或谓词组合);及Goal
是一个描述结果格式的表达式模板
L1
L1
中查找所有元素Y
,因此模板显然是X1
,目标将至少包含成员(X,L1)
。因此,现在或findall/3
的形状如下:
findall(Y,(member(Y,L1),...),L3)
L3
的所有元素都是Y
的解,其中L2
的任何值都是X
L2
中应该至少有一个X
,使得相关(X,Y)
保持不变。这意味着我们使用一次/1
来强制执行,从找到一个X
的那一刻起,我们的调用终止(并且不会重复Y
),这样X
就是L2
的一个元素(成员/2
),而相关的/2
保持不变<因此,代码>等于:
once((member(X,L2),rel(X,Y)))
或者现在是完整版本:
findall(Y,(member(Y,L1),once((member(X,L2),rel(X,Y)))),L3)
示例:
例如:
rel(2,1).
rel(3,1).
rel(2,4).
rel(3,7).
结果是:
?- L1=[1,4,5,6,7,8],L2=[2,3],findall(Y,(member(Y,L1),once((member(X,L2),rel(X,Y)))),L3).
L1 = [1, 4, 5, 6, 7, 8],
L2 = [2, 3],
L3 = [1, 4, 7].
因此,
1
只会出现一次,而对于Y=1
,有两个X
s,条件适用。您的标题说明了使用什么(findall/3
),请在第二个参数中描述您的条件。您希望找到所有的X
,例如,成员(X,L1)
(您的第一个条件),然后您有一个连接条件(b)来包含。在findall/3
中可以有一个复合表达式:findall(X,(成员(X,L1),…,…),L3)。
我能想到的唯一问题是,对于成员(X,L2),相关(X,Y)
,应该只存在一个。回答得好,顺便说一句+1。@WillemVanOnsem谢谢!,而且,是的,接得好。在这种情况下,我可能会使用setof/3
。使用once/1
时,需要小心不要删掉有效的、唯一的解决方案。目前还不清楚related/2
的行为是什么。我认为,这组行为仍然不是完全等价的。结果应该是一个子列表。原始列表可以包含重复项,这些重复项可能应该在结果中重复。尽管如此,这个问题还是有点不明确。@WillemVanOnsem同意这个不明确的问题。我用setof/3
选项做了一些不成文的假设。这是真的,但在这种情况下,我们不使用X
做任何事情。我们只能猜测OP真正想要什么,我认为这两个答案可以共存;)。
?- L1=[1,4,5,6,7,8],L2=[2,3],findall(Y,(member(Y,L1),once((member(X,L2),rel(X,Y)))),L3).
L1 = [1, 4, 5, 6, 7, 8],
L2 = [2, 3],
L3 = [1, 4, 7].