我应该在 Prolog 和一般情况下避免尾递归吗?

2024-05-18

我正在阅读“立即学习 Prolog”在线书籍,以获取乐趣。

我正在尝试编写一个谓词,该谓词遍历列表的每个成员并向其添加一个,使用累加器。我已经在没有尾递归的情况下轻松完成了。

addone([],[]).
addone([X|Xs],[Y|Ys]) :- Y is X+1, addone(Xs,Ys).

但我读到出于性能原因最好避免这种类型的递归。这是真的?始终使用尾递归是否被认为是“良好实践”?使用累加器来养成一个好习惯值得付出努力吗?

我尝试将此示例更改为使用累加器,但它颠倒了列表。我怎样才能避免这种情况?

accAddOne([X|Xs],Acc,Result) :- Xnew is X+1, accAddOne(Xs,[Xnew|Acc],Result).
accAddOne([],A,A).
addone(List,Result) :- accAddOne(List,[],Result).

简短的回答:尾递归是可取的,但不要过分强调它。

您的原始程序是 Prolog 中可以得到的尾递归程序。但还有更重要的问题:正确性和终止。

事实上,许多实现非常愿意为了他们认为更重要的其他属性而牺牲尾递归性。例如坚定 https://stackoverflow.com/q/13100364/772868.

但您尝试的优化有一定的意义。至少从历史的角度来看是这样。

早在 20 世纪 70 年代,主要的人工智能语言是 LISP。相应的定义是


(defun addone (xs)
  (cond ((null xs) nil)
    (t (cons (+ 1 (car xs))
         (addone (cdr xs))))))
  

这不是直接尾递归:原因是cons:在当时的实现中,首先评估其参数,然后才评估cons可以被执行。因此,按照您的指示重写此内容(并反转结果列表)是一种可能的优化技术。

然而,在 Prolog 中,借助逻辑变量,您可以在了解实际值之前创建 cons。很多在 LISP 中不是尾递归的程序在 Prolog 中被转换为尾递归程序。

这种影响仍然可以在许多 Prolog 教科书中找到。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该在 Prolog 和一般情况下避免尾递归吗? 的相关文章

  • 非成员规则在 Prolog 中无法按预期工作

    我正在尝试在 Prolog 中创建一个迷宫程序 其目的是找到一条从迷宫起点到迷宫中心点 m 的路线 迷宫由使用四种颜色之一连接的正方形组成 蓝色 绿色 紫色或橙色 从起点到中心的路线遵循四种颜色的重复图案 我创建了以下代码 link2 A
  • iPhone 开发——performSelector:withObject:afterDelay 还是 NSTimer?

    重复方法调用 或消息发送 我猜合适的术语是 x秒 是使用 NSTimer NSTimer 的 ScheduledTimerWithTimeInterval target selector userInfo repeats 还是让该方法在最后
  • 在列表列表中查找形状

    节目说明 该计划的目的 我的程序旨在计算 20X15 大小的平面中形状的位置 我有一个形状列表 其中包含形状类型 其 ID 半径或高度以及其在平面上的预期 X Y 位置 我有一个不同的二元运算列表 仅包含形状类型 其 id 及其与另一个形状
  • 列表中的连续元素

    我正在阻止一个谓词来编码Prolog 我需要对两个谓词进行编码 如果我打电话 u a b c d e f X 它会给X a b X b c X c d 如果我打电话 v a b c d e f X 它会给X a b X c d X e f
  • 适合从记录中提取 OneToMany 关系的约束编程

    也许有人可以帮助我解决 Prolog 或任何约束编程语言的问题 想象一个项目表 学生与母亲一起做某事的学校项目 每个项目都有一名或多名儿童参与 对于每个孩子 我们存储其姓名及其母亲的姓名 但对于每个项目 只有一个包含所有母亲的单元和一个包含
  • 如何在Scala中实现尾递归快速排序

    我写了一个递归版本 def quickSort T xs List T p T T gt Boolean List T xs match case Nil gt Nil case gt val x xs head val left righ
  • Prolog:子句在源文件中不在一起

    我有这段代码 Family tree female pen male tom male bob female liz female pat female ann male jim parent pam bob parent tom bob
  • SWI-Prolog 中的跨模块“接口”调用

    这可能是 SWI Prolog 模块系统特有的 假设我们有三个 Prolog 模块 在 SWI Prolog 模块系统中 robin 在文件中robin pl arthur 在文件中arthur pl helper 在文件中helper p
  • SWI Prolog 转义引号

    我需要在序言中将 放在字符串周围 我从另一个程序获取输入 看起来我无法转义该程序中的 因此我必须在序言中添加 否则序言语句将不起作用 感谢您的帮助 为了讨论strings https stackoverflow com a 39922411
  • Prolog - 通过演绎减少知识库

    我需要创建一个规则来搜索与 my rule 匹配的事实 这些事实将用于改变知识库 my rule Conclusion Premise 我有这个知识库可以开始 dynamic is 2 is m1 house is m1 thing is
  • 判断第一个字母是否是元音序言

    我习惯了过程式编程语言 而且我在 prolog 上遇到了一些困难 缺乏在线资源也是一个遗憾 获取给定变量的第一个字符并检查它是否是元音的最 序言 方式是什么 我想 这样的东西就是我所追求的 这都是伪代码 但这是你解决问题的方法吗 isVow
  • 列表中小于给定数字的数字

    xMenores xMenores X H T R Z xMenores X T Z X gt H R is H xMenores采用三个参数 第一个是数字 第二个是数字列表 第三个是一个列表 是将包含结果的变量 规则的目标xMenores
  • SWI-Prolog 与 C++ 接口的问题

    我试图让 SWI Prolog 与 C 很好地配合 现在束手无策 现在 在我开始准确解释我的问题是什么之前 我想首先说明我的项目是关于什么的以及我选择了哪些工具来开发解决方案 我的教授分配给我的任务是开发一个 GUI 程序 作为 SWI p
  • 序言中的“如果”?

    有没有办法在序言中执行 if 操作 例如如果变量为 0 则执行一些操作 将文本写入终端 甚至不需要 else 但我找不到 if 的任何文档 是的 ISO Prolog 中有这样一个控制结构 称为 gt 你像这样使用它 condition g
  • Prolog 在技术上是如何工作的?引擎盖下是什么?

    我想更多地了解 Prolog 的内部结构并了解它是如何工作的 我知道如何使用它 但不是它内部如何运作 Prolog 中使用的算法和概念的名称是什么 它可能会构建某种树结构或有向对象图 然后在查询时使用复杂的算法遍历该图 也许是深度优先搜索
  • 将人员分配到床位 - 自动化方法[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我每年都会帮助举办青年营 将与会者分配到卧室是一项艰巨的任务 有 92 个卧室 活动持续一周 与会者停留的时间长短不一 而且床需要重复
  • Prolog真的基于封闭世界假设吗?

    在下面封闭世界假设 https en wikipedia org wiki Closed world assumption 目前未知的事实是错误的 Prolog 的语义通常被认为遵循封闭世界假设 例如 here https cstheory
  • Prolog 谓词参数中实例化模式指示符的含义

    查看Prolog文档 谓词签名有时会写成如下 foo Bar Baz Qux Mop 什么是 and 我该如何解释它们 另外 这些是唯一存在的还是还有更多 在这种情况下 这些前缀运算符代表实例化模式 即它们告诉您哪些参数应该是变量或在调用谓
  • prolog跟踪如何使用

    跟踪prolog程序时如何进行第二步 例如 我想跟踪以下简单程序 length1 0 length1 X Xs N length1 Xs N1 N is N1 1 我跟踪程序 trace length 1 2 3 N Call 7 leng
  • Prolog,确定图是否是非循环的

    我需要定义一个谓词 acycling 1 它将一个图作为输入并确定该图是否是非循环的 所以根据我的理解 graph1 a b graph1 b c graph1 c a 将返回 no 和 graph2 a b graph2 b c 将返回是

随机推荐

  • VB - 以隐式方式链接 DLL

    我正在开发 VB6 图形界面 并且需要隐式链接到 DLL 这样做的动机来自于我上一个问题 https stackoverflow com questions 5194573 有问题的 DLL 使用静态 TLS declspec thread
  • ios7 navigationController PushViewController 动画错误

    看来我在 navigationController PushViewController 方法中发现了一个错误 为了重新创建它 我采用了示例主详细信息项目并对 didSelectRow method void tableView UITab
  • 为什么 ZipList 不是 List 的默认应用实例

    我目前正在学习 Haskell 中的应用程序 如果我没记错的话 列表有两个不同的应用实例 List and ZipList 第二个被定义为包装列表值的新类型 这ZipList应用实例对我来说似乎更直观 这可能是一个愚蠢的问题 但有具体原因吗
  • 如何在 C# 中为命名空间指定别名

    我有一个很大的命名空间 Foo Bar Space Station Bar 我的别名是更短的东西 比如 Station 我该如何在使用部分做到这一点 使用 Foo Bar Space Station Bar 对象 所以我可以这样做 Stat
  • T4 模板在某些 PC 上生成额外的新行

    在将 T4 类用于实体框架时 有一些开发人员生成类 并为生成的每一行添加一个额外的新行 我想知道这是否是某种需要更改的设置 以便他们的 T4 生成的文件看起来像其他开发人员生成的文件 作为我正在谈论的示例 删除了特定名称 但您应该能够看到从
  • 为什么内核需要虚拟寻址?

    在Linux中 每个进程都有其虚拟地址空间 例如 32位系统为4GB 其中3GB为进程保留 1GB为内核保留 这种虚拟寻址机制有助于隔离每个进程的地址空间 对于流程来说这是可以理解的 因为有很多流程 但既然我们只有 1 个内核 那么为什么我
  • Python `print` 将额外文本传递给 sys.stdout?

    这可能是我错过的一些愚蠢的事情 但它确实让我挂在了一个更大的项目上 c扩展 我正在写的 Why is print Hello World 通过None和一个额外的 n to sys stdout here gt gt gt import s
  • 如何从维基数据属性中获取最新值?

    假设我想获取每个国家 Q6256 及其最近记录的人类发展指数 P1081 值的列表 该国家 地区的人类发展指数属性包含在不同时间点获取的数据点列表 但我只关心最新的数据 此查询不起作用 因为它会为每个国家 地区获取多个结果 每个人类发展指数
  • git 日志历史记录图,每次提交一行,彩色,带有日期

    我需要的格式如下 git log decorate graph oneline date order 但我也需要它 包含日期 短 具有相同的颜色 I tried git log decorate graph oneline date ord
  • clang 是否提供类似于 GCC 6.x 的函数多版本控制 (target_clones) 的功能?

    我读了这篇 LWN 文章 https lwn net Articles 691932 饶有兴趣 执行摘要 GCC 6 x 支持所谓的函数多版本控制 它可以构建同一函数的多个版本 并针对不同的指令集进行优化 假设您有一台支持 AVX2 的机器
  • 使用 Denon 时如何避免权限问题

    我正在运行 denon 它就像节点中的 nodemon 但即使我手动指定了相关标志 特别是 allow net flag 如何使用 Denon 运行我的应用程序 这样我就不必不断重新启动 如果不知道确切的错误 很难给你正确的答案 但是den
  • PHP - 扩展 __construct

    我想知道你是否可以帮助我 我有两个类 一个扩展了另一个 B 类将由各种不同的对象扩展 并用于常见的数据库交互 现在我希望 B 类能够处理其连接和断开连接 而无需来自 A 类或任何外部输入的指示 据我了解 问题是扩展类不会自动运行其 cons
  • 找出所有程序 dynpro 屏幕?

    我是ABAP新手 我想制作一个具有多个屏幕和一个初始主屏幕的程序 可以在其中看到所有程序屏幕的列表 我知道我可以对它们进行硬编码 但应该有更好的方法 如果有任何类型的字段 区域 我需要使该列表可点击 以转到屏幕 到目前为止 我已经制作了一个
  • 使用 Azure AD 通过 OAuth2 对 Azure API 管理进行身份验证

    我正在尝试通过 AzureAD 使用 OAuth2 来保护 APIM API 方法是阅读以下文章 通过 Azure AD 使用 OAuth 2 0 授权来保护 Azure API 管理中的 Web API 后端 https learn mi
  • 如何向 CSS 形状添加偏移轮廓?

    我在创建带有斜角边缘的块时遇到了一些问题 此外我需要一个斜角的边框并稍微偏离主块 问题是这个块可以根据屏幕响应 不知道具体的方法 希望大家帮忙 这就是我现在所做的 box display flex padding 20px height 2
  • 我该如何实现这个折叠功能呢?

    给出了两种数据类型 颜色 和 植物 data Color Red Pink White Blue Purple Green Yellow deriving Show Eq data Plant Leaf Blossom Color Stal
  • 为什么我的“While Loop”不打印查找平均“分数”的计算结果?

    我正在编写一个程序来读取用户输入的正整数序列 用户一次只能输入一个整数 然后它将计算这些整数的平均值 当用户输入0时程序结束 0不计入平均值 程序结束后程序将打印出平均值 问题 当我进入 while 循环时 我的代码停止工作 因此它不会计算
  • Package.json 表示 firebase-functions 的版本已过时

    我有云功能项目 并将该项目从旧笔记本电脑移至新笔记本电脑 我已经安装了所有必要的东西 我的问题是当我尝试时firebase deploy它给了我这个错误 函数 package json 表示 firebase functions 的过时版本
  • JSF 命名 Bean,Eager 应用程序范围(又名 @ManagedBean(eager=true) )

    有没有办法初始化带有注释的命名Beanjavax inject Named javax enterprise context ApplicationScoped like ManagedBean eager true from javax
  • 我应该在 Prolog 和一般情况下避免尾递归吗?

    我正在阅读 立即学习 Prolog 在线书籍 以获取乐趣 我正在尝试编写一个谓词 该谓词遍历列表的每个成员并向其添加一个 使用累加器 我已经在没有尾递归的情况下轻松完成了 addone addone X Xs Y Ys Y is X 1 a