DCG和左递归

2023-12-20

我正在尝试实现一个 dcg,它采用一组 {a,b,c,d}* 形式的字符串。我遇到的问题是,如果我有一个 s([a,c,b], []),它返回 true,这是正确的答案,但是当我有 s([a,c,f],[]) 形式的查询时,它不会返回答案,并且会耗尽本地堆栈。

s --> [].
s --> s,num.
num --> [a].
num--> [b].
num--> [c].
num--> [d].

Use phrase/2

咱们试试吧phrase(s,[a,b,c])代替s([a,b,c],[])。原因很简单:通过这种方式,我们清楚地表明我们正在使用 DCG(dcg /questions/tagged/dcg) 而不是普通的谓词。phrase/2是语法的“官方”界面。

所以你的第一个问题是为什么phrase(s,[a,c,f])不终止,同时phrase(s,[a,b,c])“给出正确的答案”——正如你所说。现在,很快就能回答:both不要终止!但phrase(s,[a,b,c])找到解决方案/答案。

通用端接

These are two things to distinguish: If you enter a query and you get an answer like true or X = a; you might be interested to get more. Usually you do this by entering SPACE or ;ENTER at the toplevel. A query thus might start looping only after the first or several answers are found. This gets pretty confusing over time: Should you always remember that this predicate might produce an answer ; another predicate produces two and only later will loop?

The easiest way out is to establish the notion of universal termination which is the most robust notion here. A Goal terminates iff Goal, false terminates. This false goal corresponds to hitting SPACE indefinitely ; up to the moment when the entire query fails.

所以现在尝试:



?- phrase(s,[a,c,f]), false.
   loops.
  

但是也:



?- phrase(s,[a,b,c]), false.
   loops.
  

从通用终止的角度来看,两个查询都不会终止。在最常用的词中,终止相当于通用终止。找到答案或解决方案就是这样,但不是终止。因此,只要您对答案感到满意,有些查询看起来就无害,但本质上不会终止。但很高兴您这么快就发现了这一点:如果您仅在正在运行的应用程序中发现这一点,那就更糟糕了。

查明原因

下一步让我们确定不终止的原因。您可以尝试使用调试器或跟踪器,但很可能它根本不会给您一个很好的解释。但有一个更简单的方法:使用故障切片 /questions/tagged/failure-slice。只需添加非终结符{false}进入你的语法;和目标false到谓词中。我们可以在这里利用一个非常美丽的财产:

If失败切片不会终止then原程序不会终止。

因此,如果我们很幸运并且找到了这样的切片,那么我们可以确定只有当剩余的可见部分发生更改时才会发生终止somehow。最有帮助的切片是:



?- phrase(s,[a,b,c]), false

s --> [], {false}.
s --> s, {false}, num.
  

你的程序已经所剩无几了!走了是num//0!没人关心num//0。这意味着:num//0可以描述anything,无论如何——程序仍然会循环。

为了解决这个问题,我们必须改变可见部分的一些东西。所剩无几了!正如您已经观察到的,我们这里有一个左递归。修复它的经典方法是:

重新制定语法

您可以轻松地将语法重新表述为正确的递归:



s --> [].
s --> num, s.
  

现在两个查询都终止。这是编译器构造中也已知的经典方法。

但在某些情况下,重新表述语法是不合适的。这个简单的例子不是这种类型,但它经常发生在具有某种故意歧义的语法中。在这种情况下,您仍然可以:

添加终止诱导参数



?- Xs = [a,b,c], phrase(s(Xs,[]), Xs).

s(Xs,Xs) --> [].
s([_|Xs0],Xs) --> s(Xs0,Xs1), num, {Xs1=Xs}.
  

本质上不终止的查询

无论您做什么,请记住并非每个查询都可以终止。如果你问:“告诉我所有存在的自然数——实际上是所有的自然数,一一的!”那么回答这个问题的唯一方法就是从 0 开始,然后将它们数起来。因此存在疑问,其中存在无限的答案/解决方案,我们不能责怪可怜的 Prolog 试图实现我们的愿望。然而,在这种情况下我们最喜欢的是以公平的方式枚举所有解决方案。我们可以通过具有良好终止属性的语法来做到这一点;也就是说,以固定长度列表结尾的语法。就像这样:



?- length(Xs, M), phrase(s, Xs).
  

有关如何应用失败切片的其他示例,请参阅标签故障切片 /questions/tagged/failure-slice.

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

DCG和左递归 的相关文章

  • 如何提高词法分析效率?

    在解析一个 3 GB 的大文件时DCG https www metalevel at prolog dcg 效率很重要 我的词法分析器的当前版本主要使用 or 谓词 2 http www swi prolog org pldoc doc f
  • Prolog - 递归列表构建

    对于我正在编写的程序 我需要创建一个列表列表 其中包含代表乘积的数字对和两个给定数字的总和 现在我有一个函数 我可以指定将列表添加到列表中的次数 稍后将使用完整功能进行扩展 这是我所拥有的 s1 0 X s1 Q X N is Q 1 mu
  • 如何在 Prolog 中求反

    我是 PROLOG 新手 正处于练习的开始阶段这一页 https sites google com site prologsite prolog course a first glimpse 给定规则parent X Y 和male X 我
  • 在 Prolog 中表达“交换性”的替代方案?

    作为一个Prolog的初学者 我发现Prolog中的交换表达式非常不直观 例如 如果我想表达 X 和 Y 属于一个家庭 例如 family X Y married X Y relative X Y father son X Y 我还应该在定
  • 执行树元解释

    我有根据我之前的问题制作的跟踪元解释器here https stackoverflow com questions 27235148 implementing cut in tracing meta interpreter prolog 我
  • 如何在 GNU Prolog 中使用“long int”?

    所以基本上看来 GNU Prolog 在我的 32 位 x86 Linux 上使用 28 位整数 下面的代码无法编译 foo A A0 is 0xdeadbeef A1 is A0 gt gt 8 A2 is A0 gt gt 16 A3
  • 如何在 Prolog 中为变量(如字符串)分配多个值?

    今天早些时候 我寻求帮助以在序言中构建数据库以及如何通过参数搜索 有人提出了这个 您还可以向每个处理器添加术语列表 例如 processor pentium g4400 brand intel family pentium series g
  • 如何在Prolog中编写cmp_list/3函数?

    Write a predicate cmp list 3 the first 2 arguments are 2 lists and the last one is Comparison which means ge lt le or gt
  • 求解序言中极其简单的方程:A = B + C?

    我有一个非常简单的方程 我希望能够在序言中求解 A B C 我希望能够编写一个谓词来表达这种关系 它可以处理任何一个未实例化的参数 无需推广到更复杂的关系或方程 myEquation A B C something 我可以使用以下语义进行调
  • 在列表列表中查找形状

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

    我正在做一项作业prolog questions tagged prolog扫描数字列表并应返回该列表是否是有效的罗马数字以及数字的十进制值 前任 1 roman N I N 1 true 2 当我运行我认为应该工作的程序时 十进制值总是正
  • 实现用户定义的算术函数

    如何添加函数 例如汉明权重 并在右侧出现的表达式中使用它是一些 is 2 goal 像 goal expansion 或 term expansion 这样的东西可以帮助这里吗 我承认这不是一个大功能 但它可以提高我的一些 Prolog 程
  • F# 和模糊逻辑

    我知道这可能听起来很奇怪 但我想知道 Microsoft Visual F 正在进入的这个新世界中的一件事 这种语言有很多应用 我要学习 关于解析 函数式编程 结构化编程 但是人工智能呢 模糊逻辑有什么应用吗 F 是一种适合模糊逻辑应用程序
  • 如何在 Prolog 中解决这个算术表达式难题?

    我有一个编程问题 https blog svpino com 2015 05 08 solution to problem 5 and some other thoughts about this type of questions htt
  • Prolog内存问题

    我想找到一种方法来分析我在序言中编写的谓词 一个巨大的谓词 的内存使用情况 我目前正在运行它swi http www swi prolog org and yap http www dcc fc up pt vsc Yap document
  • 根据一个值找到列表内列表的最小值

    我在序言中有这个列表 dublin london 1000 dublin moscow london 5000 我想计算列表的最小值 这样答案应该是 dublin london 1000 这个问题有一些类似的问题序言中列表列表中的最小值 h
  • 谓词对于列表中的所有元素都必须为 true

    我有一组事实 likes john mary likes mary robert likes robert kate likes alan george likes alan mary likes george mary likes har
  • 通过递归扩展 Prolog 目标?

    我 最终 实现了一些目标 这些目标将根据开始由 开始之后 and duration 然而 计划目标仅接受规定数量的任务 我想扩展计划目标的功能以接受单个列表并在计划时迭代该列表 不幸的是 我认为这将需要与can run and 冲突目标如下
  • 如何在 ISO Prolog 中定义(和命名)相应的安全术语比较谓词?

    标准术语顺序 ISO IEC 13211 1 7 2 术语顺序 针对所有术语 包括变量 进行定义 虽然这有很好的用途 想想实施setof 3 这使得 8 4 术语比较中内置函数的许多其他干净且合乎逻辑的使用成为声明式噩梦 到处都是 imps
  • 一次性删除不正确的后续解决方案

    我有一个谓词 它找到正确的解决方案 但随后又找到不正确的解决方案 data D data threshold nonredundantbumps D 5 Bs write D 3 6 7 8 2 4 5 6 9 4 7 3 D 3 6 7

随机推荐

  • IModelBinder 上的 BindProperty 和 SetProperty 有什么区别

    我正在 Mvc 应用程序中创建自定义模型绑定程序 我想将字符串解析为枚举值并将其分配给模型属性 我已经让它工作了BindProperty方法 但我也注意到有一个SetProperty方法 protected override void Bi
  • PDFBox 按钮执行 javascript 关闭文档

    我的用例是在 pdf 页面上有一个像这样的按钮 实际上是将它们添加到现有页面 但现在我只想看到它对任何东西都有效 Back 它所做的只是关闭当前的 pdf 页面 这个想法是打开多个选项卡 每个选项卡都是一个 pdf 然后当您点击 后退 按钮
  • 从 BigQuery 中的查询返回数组(重复字段)

    我是 BigQuery 和 SQL 的新手 我有一张包含以下详细信息的表格 Schema ID String Nullable BCats String Repeated ID可以重复 Preview ID BCats ABCD BCat2
  • 如何使用美汤进入下一页?

    我必须从网站的 5 个页面中提取信息 每页的末尾都有 下一页 按钮 这是下一个按钮的 html 代码 li class pagination next span class icon arrowright thin pagination b
  • didDiscoverPeripheral“构建失败”错误

    我不确定为什么这段代码无法构建 并且错误消息似乎相当神秘 Code var centralManager CBCentralManager var nrf8001Peripheral CBPeripheral override func v
  • Polymer 1.0:如何在不使用 的情况下将事件传递给子节点元素?

    这个堆栈溢出答案 https stackoverflow com a 32590511 1640892建议使用
  • 调用宏中的其他函数

    如何在宏中调用其他函数 宏 以下似乎不起作用 即使我定义bar with define syntax define bar hello define syntax foo stx syntax case stx a b bar Racket
  • getElementById 其中 Element 在运行时动态创建

    我已经使用innerHTML标签在运行时创建了一个对象 现在我想使用getElementById访问这个元素 当我访问该元素时它返回NULL值 请给我建议任何方向 以便我能够实现这一目标 这是我正在使用的以下代码提示 In HTML div
  • 使用数组设置间隔

    我想使用setInterval函数于jQuery为了每 4 秒创建一个包含一个数组内容的警报 然而 我的警报会在短时间内显示数组的所有值 并且在显示所有值后停止 4 秒 each html5 EDM Coca Cola creativity
  • 使用“hasBackground”进行 Espresso 测试

    如何使用布局背景的颜色进行浓缩咖啡测试 目前使用有背景 https developer android com reference android support test espresso matcher ViewMatchers htm
  • JSON.parse() 不起作用

    我的服务器有一个 json canApprove true hasDisplayed false 我可以像这样解析 json var msg JSON parse canApprove true hasDisplayed false ale
  • 如何在C中定义函数指针数组

    我有一个小问题 我正在尝试动态定义函数指针数组calloc 但我不知道如何写语法 多谢 函数指针的类型就像函数声明一样 但用 代替函数名 所以一个指向 int foo int 将会 int int 为了命名该类型的实例 请将名称放在星号后面
  • 如何从对象的数组记录集中获取嵌套的 HTML 列表?

    我有一个由 SQL 查询返回的对象数组 其中 top id 是我的父 ID 字段 Array 0 gt stdClass Object id gt 1 top id gt 0 name gt Cat 1 1 gt stdClass Obje
  • 如何确定最接近的纵横比

    给定一个矩形形状 S 长宽比为 sx sy 以及另外两个矩形形状 A 长宽比为 ax ay 和 B 长宽比为 bx by 我如何找出形状 A 或 B 中哪一个具有最接近 S 的长宽比 形状的大小并不重要 是 sx sy ax ay 和 sx
  • 获取数据库表中的数据,如果不存在则将其插入,否则返回行 ID

    我有一个包含 date file creation 列的表文件 我想创建一个包含日期文件创建的表日期 当我插入新文件时 我检查表日期是否存在 我返回行 ID 并将其作为外部插入键在表文件中 否则我插入一个新日期并获取其新行 ID 以将其插入
  • 页面中的 Nuxtjs 异步等待在页面刷新时不起作用

    我尝试使用 vuex 和 nuxt js 在页面的 fetch 方法中获取数据 但是每当有人刷新页面时 它都会失败 但当我通过 nuxt 导航导航时 它会工作 所以在我的页面中我有 fetch store params store disp
  • 添加一列排名

    我有一些数据 test lt data frame A c aaabbb aaaabb aaaabb aaaaab bbbaaa 等等 所有元素的长度都相同 并且在我获取它们之前就已经排序了 我需要创建一个新的排名列 第一 第二 第三 之后
  • 删除 R 输出中的反引号

    我有某些变量lm在 R 中自动用反引号 反引号换行 例如名称中带有冒号的变量 经过一些处理后 我尝试用以下方法写出线性模型的变量和系数write table 不幸的是 反引号也被写出来了 如何防止这些反引号被写入 举一个简单但不切实际的例子
  • C# 调用 ActiveDirectory 的 SetPassword 函数的问题

    我成功创建了一个新用户 然后尝试使用以下代码设置其初始密码 newUser AuthenticationType AuthenticationTypes Secure newUser Invoke SetPassword new objec
  • DCG和左递归

    我正在尝试实现一个 dcg 它采用一组 a b c d 形式的字符串 我遇到的问题是 如果我有一个 s a c b 它返回 true 这是正确的答案 但是当我有 s a c f 形式的查询时 它不会返回答案 并且会耗尽本地堆栈 s gt s