Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/jquery-mobile/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 满足特定条件的子列表的Findall/3_List_Prolog - Fatal编程技术网

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].