是什么让 DCG 谓词变得昂贵?

2024-01-02

我正在构建一个定语从句语法来解析 20,000 段半自然文本。随着我的谓词数据库大小的增长(现在达到 1,200 条规则),解析字符串可能需要相当长的时间 — 特别是对于 DCG 目前无法解释的字符串,因为我尚未编码语法。对于包含 30 个单词的字符串,当前最坏的情况是 3 分钟。我正在尝试弄清楚如何优化它,或者我是否应该开始研究云计算。

我正在使用 SWI-Prolog,它提供了一个“配置文件”目标,它提供了一些统计数据。我惊讶地发现数据库中最简单的规则占用了大部分执行时间。我的语料库包含代表数字的字符串,我想将它们捕获到scalar/3谓词。这些占用了总执行时间的 50-60%。

一开始,我的电脑里有 70 行scalars.pl,代表我的语料库中数字的数字和自然语言表示。就像这样:

scalar(scalar(3)) --> ["three"].
scalar(scalar(3)) --> ["3"].
scalar(scalar(4)) --> ["four"].
scalar(scalar(4)) --> ["4"].

...等等。

认为文件的长度是问题所在,我添加了一条新规则,该规则将自动解析任何数字表示形式:

scalar(scalar(X)) --> [Y], { atom_number(Y, X) }.

多亏了这一点,我的规则从 70 条减少到了 31 条,并提供了一些帮助——但这并不是一个巨大的节省。还有什么可以做的吗?我的感觉可能不是,因为还有什么比列表中的单个原子更简单的呢?

这些标量在整个语法的很多地方都会被调用,我认为这是问题的根源。尽管它们是简单的规则,但它们无处不在,而且不可避免。高度通用的语法不适用于我的应用程序,如果我最终得到 3,000 条或更多规则,我也不会感到惊讶。

我从来没有建造过这么大的 DCG,所以我不确定在性能方面我能期望多少。很高兴接受有关此问题的任何建议:是否有其他方式来编码这些规则?我是否应该接受某些解析将花费很长时间,并弄清楚如何并行运行解析?

先感谢您!

编辑:我被要求提供一个可重现的示例,但要做到这一点,我必须将 SO 链接到整个项目,因为这是一个规模问题。为了完整起见,这是我正在做的事情的玩具版本。想象一下,有大量文件描述了数百个名词、数百个动词和数百个句法结构。

sent(sent(VP, NP)) --> vp(VP), np(NP).
vp(vp(V)) --> v(V).
np(np(Qty, Noun)) --> qty(Qty), n(Noun).
scalar(scalar(3)) --> ["three"].
scalar(scalar(X)) --> [Y], { atom_number(Y, X) }.

qty(qty(Scalar)) --> scalar(Scalar).
v(v(eat)) --> ["eat"].
n(n(pie)) --> ["pie"].

您可能要研究的程序的一方面是确保各个谓词快速成功并快速失败。这对于检查具有许多子句的谓词特别有用。

例如,当对不是标量的标记求值 scalar(X) 时,程序将必须尝试 31 次(根据您的最后计数)才能确定 scalar//1 失败。如果程序的结构是针对每个标记检查标量(X),那么这可能会非常昂贵。

此外,如果 scalar(X) 确实发现一个标记匹配,但后续目标失败,那么您的程序似乎将重试 scalar(X),直到尝试了所有 scalar//1 子句。

明智地使用 cut (!) 或 if-then-else (C1->G1;C2->G2;G3) 可以提供巨大的性能改进。 或者,您可以构建谓词,以便它们依赖索引来选择适当的子句。例如。:

scalar(scalar(N)) --> [Token], {scalar1(Token, scalar(N))}.

scalar1("3", scalar(3)) :- !.
scalar1(Y, scalar(X)) :- atom_number(Y, X).

这使用了带有 scalar1/1 谓词的剪切索引和子句索引(如果编译器提供了它)。

编辑:你应该读 R. A. O'Keefe 的Prolog 的工艺。它是 Prolog 实用方面的优秀指南。

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

是什么让 DCG 谓词变得昂贵? 的相关文章

  • 如何在SWI-Prolog中启用所有统一中的发生检查?

    根据维基百科 https en wikipedia org wiki Occurs check 为所有统一提供声音统一的实现是 Qu Prolog 和 Strawberry Prolog 以及 可选地 通过运行时标志 XSB SWI Pro
  • Prolog:覆盖谓词和使用它之间的区别

    我觉得自己真的很愚蠢 感觉自己错过了一些东西 我基本上有两个文件 module pl通用逻辑规则 可重用 state pl一个针对当前场景 在模块文件中 module pl 我已经声明 inside Food Eater T isTime
  • Prolog 中的掩码

    我最近一直在尝试理解 Prolog 并且一直在搞乱 Prolog 中的列表列表 我正在尝试创建一种我想在 p 中的面具 序言 我有一个谓词 它确定 Prolog 中两个列表列表 比如说 L1 和 L2 之间的差异 并将它们保存为列表列表 比
  • Prolog:消除查询中的重复

    我一直在尝试编写一个简单的代码 其行为方式如下 hasCoppiesOf X a b a b a b a b X a b X a b a b X a b a b a b a b And hasCoppiesOf a b a b a b a
  • Prolog - 递归列表构建

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

    尝试解决练习 07http www ic unicamp br meidanis courses mc336 2009s2 prolog problemas http www ic unicamp br meidanis courses m
  • AllegroGraph 检查现有三元组

    我正在使用 AllegroGraph 4 我有一个三元组存储 并且只有在新的三元组尚不存在时我才会尝试添加它们 这是我的 Prolog 查询 select news alfas news a news tst has annotation
  • 如何在 Prolog 中求反

    我是 PROLOG 新手 正处于练习的开始阶段这一页 https sites google com site prologsite prolog course a first glimpse 给定规则parent X Y 和male X 我
  • Prolog 中的聊天机器人

    我一直在尝试在序言中创建一个聊天机器人 作为作业 到目前为止 我已经在 pl 文件中创建了一个数据库 并且列出了很多可能的对话 我知道序言是这样工作的 例如如果我们有 Chatbot good 然后我们输入 Chatbot good 它会回
  • 在 Prolog 中表达“交换性”的替代方案?

    作为一个Prolog的初学者 我发现Prolog中的交换表达式非常不直观 例如 如果我想表达 X 和 Y 属于一个家庭 例如 family X Y married X Y relative X Y father son X Y 我还应该在定
  • 如何在 Prolog 中为变量(如字符串)分配多个值?

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

    谁给了 SWI Prolog 幽默感 Welcome to SWI Prolog threaded 64 bits version 7 3 35 SWI Prolog comes with ABSOLUTELY NO WARRANTY Th
  • Prolog 中的迷你数独求解器中途停止

    我正在学习 七周七种语言 我只是想从书中找到一个例子 它解决迷你数独网格 4x4 作者使用的是 gprolog 但我使用的是 swi prolog 无论出于何种原因 我都无法让 gprolog 在我的虚拟机上工作 但 swi prolog
  • 井字游戏的极小极大

    我正在尝试用简单的极小极大算法来解决井字游戏 简单 但应该涵盖很多语言 到目前为止我所拥有的 该板表示为 9 个 未绑定 变量的数组 这些变量可以设置为x or o 获胜条件基本上是 win Player X1 X2 X3 X1 Playe
  • Prolog 匹配 vs miniKanren 统一

    在 Prolog 人工智能编程中 Bratko 在第 58 页说了以下内容 Prolog 中的匹配对应于逻辑中所谓的统一 但是 我们避免使用 统一 这个词 因为出于效率原因 在大多数 Prolog 系统中 匹配的实现方式并不完全对应于统一
  • 求解序言中极其简单的方程:A = B + C?

    我有一个非常简单的方程 我希望能够在序言中求解 A B C 我希望能够编写一个谓词来表达这种关系 它可以处理任何一个未实例化的参数 无需推广到更复杂的关系或方程 myEquation A B C something 我可以使用以下语义进行调
  • Prolog 实现 and/2、or/2、nand/2、nor/2、xor/2 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想在序言中实现以下谓词并将它们用于真值表 and 2 or 2 nand 2 nor 2 xor 2 也许有人可以告诉我如何实现和
  • 转换句子会产生无限循环 - 但如何转换呢?

    我不明白这是哪里出了问题 请注意 我对 Prolog 很陌生 我确信我错过了一些东西 只是不知道那可能是什么 有人可以帮我吗 谢谢 这是我的代码 printSentence printSentence W write W write nl
  • Prolog 罗马数字(属性语法)

    我正在做一项作业prolog questions tagged prolog扫描数字列表并应返回该列表是否是有效的罗马数字以及数字的十进制值 前任 1 roman N I N 1 true 2 当我运行我认为应该工作的程序时 十进制值总是正
  • 问题 - 序言中的形式语言

    我正在尝试构建一个 DCG 它可以识别与此形式匹配的所有列表 a n b 2m c 2m d n 我写下了以下规则 s gt s gt ad ad gt a ad d ad gt bc bc gt b b bc c c bc gt a gt

随机推荐

  • 调度另一个 Substrate FRAME Pallet 中定义的函数

    我熟悉实现此问题标题中描述的目标的一种机制 在调用在另一个托盘中编写的外部 如 Sudo 托盘或实用程序托盘中定义的多重签名功能 跨托盘调度功能还有哪些其他选项 具体来说 我想包括一个托盘 托盘 A 作为Trait 另一个托盘 托盘 B 的
  • 使用 re.findall() 替换所有匹配项

    Using re findall 我已经设法返回字符串中正则表达式的多个匹配项 然而 我返回的对象是字符串中的匹配列表 这不是我想要的 我想要的是用其他东西替换所有匹配项 我尝试使用与您在 re sub 中使用的类似语法来执行此操作 如下所
  • 以正确的方式重用 setter 和构造函数中的验证逻辑

    我有一个类 其中的属性带有自定义设置器来执行验证 我也希望能够将该属性作为构造函数参数传递 并从构造函数中调用 setter 以重用验证逻辑 class Part object def init self pn self pn None s
  • 如何以编程方式切换 Chrome 的 FPS 仪表?

    经过搜索 我发现this https stackoverflow com questions 22038065 show fps meter chrome 33主题 但这就是如何通过用户界面启用 显示仪表 我想知道是否可以通过启用 禁用仪表
  • 在 Oracle 过程中的字符串中调用函数

    我使用 Oracle 10g 编写一个应用程序 我目前面临这个问题 我将 文件名 作为 varchar2 类型的参数 文件名可能包含的示例值是 TEST to char sysdate DDD 在该过程中 我想获取该文件名的值 如 TEST
  • 是否有使用频率对数除法的 FFT?

    维基百科的小波文章 http en wikipedia org wiki Wavelet Comparisons with Fourier Transform 28Continuous Time 29包含以下文字 离散小波变换的计算复杂度也
  • 如何在 R 中通过高效过滤和分组来对数据进行子集化

    我正在开发一个项目 正在寻求一些帮助以使我的代码运行更有效 我搜索过类似的问题 但似乎找不到像这个问题那么细致的问题 我想出的解决方案非常笨拙 我相信一定有一种更有效的方法来使用像这样的包来做到这一点dplyr data tables et
  • 查找与所有类别匹配的产品 (Rails 3.1)

    我正在努力处理 Rails 3 1 1 中的 ActiveRecord 查询 我有 2 个模型 产品和类别 从产品到类别有一个 has and belongs to many 一个产品可以有多个类别 我正在尝试编写一个搜索查询 它将找到具有
  • Jackrabbit Oak:入门并通过 RMI 连接到独立存储库

    我对长耳大野兔和长耳大野兔橡树完全陌生 不过 我与 Alfresco 进行了很多合作 这是另一个符合 JCR 的开源内容存储库 我想启动一个独立的 Jackrabbit Oak 存储库 然后通过 Java 代码连接到它 不幸的是 Oak 文
  • 使用 geom_smooth 将 glm 拟合到分数

    这篇文章有点相关这个帖子 https stackoverflow com questions 62974766 removing alpha transparency from ggplot legend and setting x axi
  • Java - 子类调用超级构造函数,该构造函数调用子类方法而不是它自己的方法

    我将从一个代码示例开始 class A public A f When accessed through super call this does not call A f as I had expected public void f I
  • Java 中的 Unicode 符号(箭头)

    我想在我的应用程序中使用以下符号作为按钮 箭头http img402 imageshack us img402 3176 arrowso jpg http img402 imageshack us img402 3176 arrowso j
  • 如何使用 Delphi 读取 Windows 事件日志的内容

    是否有一个类或函数允许您读取 Windows 事件日志 这是你打开后看到的日志事件vwr msc 理想情况下选择一个特定的日志 在我的例子中应用领域登录Windows日志 并根据日期和来源设置过滤器 您可以使用Win32 NTLogEven
  • 来自文字的静态 std::string 对象的宏

    假设我需要调用一个函数foo这需要一个常量std string我的代码中很多地方都引用了 int foo const std string foo bar foo baz 使用像这样的字符串文字调用函数将创建临时的std string对象
  • 在 adb logcat 输出中查看 Android 上 Qt 应用程序的日志记录的最简单方法是什么?

    NB I am notQtCreator 用户 我使用 qmake make 和 androiddeployqt 在构建脚本中构建 Android 应用程序 并使用 adb install 将它们部署到设备 我希望能够在 abd logca
  • git pre-commit hook,将文件添加到索引中

    我正在尝试编写一个简单的预提交挂钩来检查文件是否被修改 如果是 则压缩它并将其添加到当前索引中 如下所示 bin sh was the file modified mf git status grep jquery detectBrowse
  • 同步 AJAX 调用在 Chrome 中冻结之前的代码

    我想在执行同步 AJAX 调用时将按钮更改为加载状态 除了将按钮更改为加载状态的 jQuery 代码 在 Chrome 中 之外 它会冻结 直到 AJAX 调用完成 因此 加载状态将在 de ajax 调用后显示大约 1 毫秒 我在 JSF
  • OpenGL:快速离屏渲染

    我需要使用 OpenGL 在屏幕外渲染大量 数万 图像 我在Windows下运行并使用QT作为框架 解决方案只能是Windows 这并不重要 根据我使用谷歌的发现 有很多选择可以做到这一点本文 http www mesa3d org bri
  • 如何在python中将输入值与mysql数据库值进行比较

    所以我想将输入值与我的数据库值进行比较 如果输入值与数据库的值相同 我想print inputvalue 但如果不一样 我想print Data Does Not Exist 所以我尝试过这段代码 cur connection cursor
  • 是什么让 DCG 谓词变得昂贵?

    我正在构建一个定语从句语法来解析 20 000 段半自然文本 随着我的谓词数据库大小的增长 现在达到 1 200 条规则 解析字符串可能需要相当长的时间 特别是对于 DCG 目前无法解释的字符串 因为我尚未编码语法 对于包含 30 个单词的