问题标签 [prolog-cut]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
prolog - 在 Prolog 中使用 cut 定义一个 once_member/2 函数
免责声明:这是在我自己的时间做的非正式和非评估课程。我自己尝试过,失败了,现在正在寻找一些指导。
我正在尝试实现 member/2 函数的一个版本,它只会返回一个列表的成员一次。
例如:
我希望它最多只打印每个数字一次。
我们被告知要通过剪切“!”来做到这一点。操作员,但我已经查看了我的课程的笔记,以便在线查看更多内容,但仍然无法让它在我的脑海中点击!
到目前为止,我已经设法得到:
返回 1 然后什么都没有,我觉得我的剪辑位置错误,并且阻止了每场可能的比赛的回溯,但我真的不确定下一步该去哪里。
我查看了我的课程笔记以及:http ://www.cs.ubbcluj.ro/~csatol/log_funk/prolog/slides/5-cuts.pdf和Prolog 中的编程(Google 图书)
关于如何在逻辑上应用削减的指导将是最有用的,但答案可能会帮助我自己弄清楚这一点。
我们还被告知要做另一种方法,该方法使用'\+' 否定失败,但希望一旦 cut 对我来说这可能会更简单?
prolog - Prolog 附加切割运算符
当我们将 append 与 cut 运算符一起使用时会出现什么问题?
我尝试了几种不同的输入,但总是成功。
prolog - 这个查询的 SLD 树是什么?
让我们考虑以下 Prolog 程序(来自“Prolog 的艺术”):
和查询:
SICStus 和 SWI 都会产生预期的Z = s(s(s(s(0))))
答案,但会向用户查询下一个答案(正确no
/false
答案)。但是,我无法理解为什么在找到唯一目标之后 SLD 树中有一个开放的分支。我尝试在 SICStus 和 SWI 下进行调试,但我还不能真正解释结果。我只能说,据我所知,两者都回溯到plus(s(s(s(0))), 0, _Z2)
. 有人可以帮助我理解这种行为吗?
prolog - 后继算术和的最佳绿色削减是什么?
为了了解 Prolog 中的绿色切割,我试图将它们添加到后继算术中 sum 的标准定义中(参见What's the SLD tree for this query?plus
中的谓词)。这个想法是通过消除所有无用的回溯(即 no )来尽可能“清理”输出,同时在所有可能的参数实例化组合下保持相同的行为 - 所有实例化,一/二/三个完全未实例化,以及所有变体包括部分实例化的参数。... ; false
这是我在尝试尽可能接近这个理想时能够做到的(我承认 false 对如何将绿色剪辑append/3
作为源插入的回答):
在 SWI 下,这似乎适用于所有查询,但形状为 的查询除外?- plus(+X, -Y, +Z).
,至于SWI 的谓词描述符号。例如,?- plus(s(s(0)), Y, s(s(s(0)))).
产量Y = s(0) ; false.
。我的问题是:
- 我们如何证明上述削减是(或不是)绿色?
- 我们能否比上述程序做得更好,并通过添加一些其他绿色削减来消除最后的回溯?
- 如果是,如何?
list - 删除重复的解决方案
我的代码以下列方式逐项合并两个列表列表:
这是我使用的代码:
这似乎可行,但如果我用两个相同大小的列表调用它,我会得到三个重复的结果。示例(两个列表都只包含一个元素):
有没有一种干净的方法可以使这个输出只有一个解决方案?
prolog - 使用切割提高效率
如果我有以下知识库,如何在 parent_of 术语中添加一个剪辑,以便如果 X 已经确定为父亲,prolog 不会尝试“检查”X 是否也是母亲?
例如,我想要:
parent_of(max,Y) 为:Y=john, Y=james, Y=gabe
parent_of(june,Y) 为:Y=john, Y=james
对于第一个,我什至不希望 prolog 尝试检查 max 是否是母亲,因为已经确定他是父亲。
我已经尝试了很多组合,包括:
这甚至可能吗?
recursion - 如何防止序言中没有?
Prolog,递归函数:我希望它使用列表的每个元素打印 C,例如:C=30 和 [H|T]= [-9,-10,-30]
我在开始时检查列表的头部不为空。它给了我这个输出
这个输出是我想要的,但我不想在最后得到一个“否”,因为这会使父函数也失败!我怎样才能将其删除并改为“是”?
parsing - 在递归下降解析器中实现“cut”
我正在用 Python 实现一个 PEG 解析器生成器,到目前为止我已经取得了成功,除了“剪切”功能,任何知道 Prolog 的人都必须知道。
这个想法是,在!
解析了 cut ( ) 符号之后,不应在同一级别尝试其他选项。
表示在(
看到之后,解析必须成功,否则不尝试第二个选项就失败。
我正在使用 Python 的(非常有效的)异常系统来强制回溯,所以我尝试了一个特殊的FailedCut
异常来中止封闭的选择,但这没有用。
任何有关如何在其他解析器生成器中实现此功能的指针都会有所帮助。
也许我遇到的问题是缺乏地方性。为规则的左侧部分生成的代码类似于:
然后,为choice( |
) 运算符生成的代码如果捕获到a 将跳过以下选择FailedCut
。我所说的缺乏局部性的意思是,捕捉到的选择FailedCut
可能在电话中很深,因此产生的效果很难辨别。
我可以让为选择生成的代码提防它们,而不是让为序列生成的代码尝试通知封闭选择cut 。与 Prolog 不同,这将使削减的范围非常本地化,但对于我在 PEG 解析器中想要的东西来说已经足够了,即在看到某个标记序列后提交一个选项,因此错误报告是指该位置在源中,而不是到另一个可能有其他选项的位置。
我突然想到,如果为规则/谓词生成的代码捕获FailedCut
并将其转换为正常FailedParse
异常,那么剪切将具有正确的范围。
关于@false的问题,这是我想要工作的完整示例:
在该语法中,word
可以通过named
or到达term
,但我希望解析器在named
看到:
.
解决方案
公平地说,到目前为止,我已经在https://bitbucket.org/apalala/grako/上发表了我的作品。
在最终解决方案中,序列包含在此上下文管理器中:
选择函数中的选项包含在以下内容中:
这迫使退出选择而不是返回尝试下一个选项。
削减本身是这样实施的:
完整的源代码可以在Bitbucket上找到。
prolog - 知道何时在 prolog 中使用 cut
我参加了一门课程,其中我学到了一些序言。我不知道如何/何时使用削减。即使我了解削减的一般概念,但我似乎无法正确使用它们。任何人都可以简要解释一下,或者就他们可以推荐的“削减”提供一个很好的教程(不是 learnprolognow.org)吗?
prolog - Prolog 中的切割和失败
考虑以下代码:
查询a(X).
产生
但有了这段代码
查询a(X).
结果:
所以我的问题是,为什么fail/1
产生错误?它应该强制回溯,对吗?然后b(1)
会c(1).
被检查,我想,那为什么会失败呢?