gpt4 book ai didi

prolog - 对 swi-prolog 等中的每个列表元素执行操作

转载 作者:行者123 更新时间:2023-12-03 19:42:58 25 4
gpt4 key购买 nike

如何按顺序对列表的每个元素执行操作?

基于这两个资源:

  • http://www.swi-prolog.org/pldoc/doc/swi/library/lists.pl
  • http://www.swi-prolog.org/pldoc/doc_for?object=foreach/2

  • 我想我总是可以依靠:
  • foreach(member(X, [1,2]), write(X)).

  • 这是确定性的,我可以在我自己的谓词中随心所欲地包装 member/2 谓词,并且仍然总是按顺序迭代吗?

    最佳答案

    是的,但是您必须担心谓词失败。如果可以,则不会处理列表中的其余元素,因为它会产生连接而不是失败驱动的循环。

    我会更热衷于使用 maplist/2因为我认为它比 foreach/2 使用更广泛但我之前也没有见过这个选项。 :)

    编辑 :让我们讨论一下我对故障驱动循环的意思。

    Prolog 中有两种原始迭代方法:递归和故障驱动循环。假设我想打印出列表中的每个项目。递归方法将如下所示:

    print_all([]).
    print_all([X|Rest]) :- write(X), nl, print_all(Rest).

    所以给出一个列表,如 [1,2,3] ,这将像这样扩展:
    print_all([1,2,3])
    write(1), nl, print_all([2,3])
    write(1), nl, write(2), nl, print_all([3])
    write(1), nl, write(2), nl, write(3), nl, print_all([])
    write(1), nl, write(2), nl, write(3), nl.

    就是这样 member/2通常是这样实现的:
    member(X, [X|_]).
    member(X, [_|Xs]) :- member(X, Xs).

    所以你可以看到递归方法非常简单和通用。

    另一种简单但有点令人不悦的方法是模拟无法使用回溯机制。这称为故障驱动循环,如下所示:
    print_all(List) :- member(X, List), write(X), nl, fail.
    print_all(_).

    当您运行此版本的 print_all/1 时,发生的事情比简单的扩展稍微复杂一点。
    print_all([1,2,3])
    member([1,2,3], 1)
    write(1), nl
    fail
    retry member([1,2,3], 2)
    write(2), nl
    fail
    retry member([1,2,3], 3)
    write(3), nl
    fail
    retry print_all(_)
    true

    口头上, fail强制 Prolog 备份到它所做的最后一个选择点并尝试使用下一个解决方案。那么, write/1nl/0不要产生选择点,因为他们只有一个解决方案,但是 member/2确实有多种解决方案 - 列表中的每个项目一个。因此 Prolog 将每个项目从列表中取出并打印出来。最后当 member/2用完解,Prolog 回到上一个选择点,即 print_all/1 的第二个主体谓词,它总是成功。所以输出看起来是一样的。我认为现在人们通常不喜欢使用失败驱动的循环,但我不太了解这些论点,无法有效地模仿它们。

    可以帮助您了解正在发生的事情的一件事是使用 trace谓词并逐步完成两个版本的扩展,看看您是否能理解差异。我上面的符号完全弥补了这个答案,可能不太清楚。

    回顾我最初写的内容和您的实际问题:
  • foreach将是确定性的
  • member将始终按顺序迭代,因为列表的定义方式是您必须依次访问每个项目

  • 此外,这些天至少在 S.O.你会得到很多人告诉你使用 maplist和它的同类,所以它可能不仅会起作用,而且还是一个好主意。

    关于prolog - 对 swi-prolog 等中的每个列表元素执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7537804/

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