Findall / 3表示满足特定条件的子列表

时间:2016-04-28 14:22:35

标签: list prolog

我有两个列表L1L2

L1=[1,4,5,6,7,8].
L2=[2,3].

一个谓词:

related(X,Y).

我想找一个列表L3

  1. 这是L1

  2. 的子列表
  3. 其中L3的所有元素都是Y的解决方案,其中L2的任何值都是X的解

    < / LI>

    换句话说,将L2的所有值都提供给X,并找出L1的哪些值将是Y的对应解决方案。

2 个答案:

答案 0 :(得分:2)

使用findall/3这可以通过这种方式完成(如果我理解您的情况):

findall(Y, (member(Y, L1), member(X, L2), related(X, Y)), L3).

在我的评论中,由于误读了你的条件,我让X混合了一点,但这个想法仍然是一样的。您只需要建立正确的目标作为findall/3的第二个参数,以获得所需的结果。

<小时/> 如果您需要独特的有序结果,可以使用setof/3

setof(Y, (member(Y, L1), member(X, L2), related(X, Y)), L3).

答案 1 :(得分:1)

findall/3的结构如下:

findall(+Template, :Goal, -Bag)

其中:

  • Bag是您要获取的结果列表;
  • Goal是应该成功的谓词(或谓词的组合);和
  • Template是一个描述结果格式的表达式。

现在让我们使用这个谓词做一些构建:

  
      
  1. 这是L1
  2. 的子列表   

您正在Y中查看所有元素L1,因此模板显然是X1,目标至少包含member(X,L1) 。所以现在或findall/3形如:

findall(Y,(member(Y,L1),...),L3)
  
      
  1. 其中L3的所有元素都是Y的解决方案,其中L2的任何值都是X的解决方案
  2.   

由于X中应至少有一个L2related(X,Y)成立once/1。这意味着我们使用X强制执行,从找到Y的那一刻开始,我们的调用就会终止(并且不会重复X),这样member/2就是一个元素L2related/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

所以X只会发生一次,而条件成立的Y=1有两个#talkbubble { width: 120px; height: 80px; background: red; position: relative; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; } #talkbubble:before { content:""; position: absolute; left: 100%; top: 26px; width: 0; height: 0; border-top: 13px solid transparent; border-left: 26px solid red; border-bottom: 13px solid transparent; }