Prolog DCG set_prolog_flag double_quotes 源代码指令位置很重要;文档?

2024-06-18

我通过 SWI-Prolog 惨痛地了解到 Prolog 指令的位置set_prolog_flag重要的是源代码文件。

我发现的关于使用指令加载源代码文件的唯一有价值的文档位于加载Prolog源文件 http://www.swi-prolog.org/pldoc/man?section=consulting

指令是给编译器的指令。指令用于 设置(谓词)属性(参见第 4.15 节),设置标志(参见 set_prolog_flag/2)并加载文件(本节)。指令就是条款 形式:- 。

SWI-Prolog 是否有文档涵盖源代码的加载,并注明指令是否适用于整个文件或取决于源代码文件中的位置?

或者从源代码文件加载的所有行都只是将语句简单地播放到顶层并且位置总是很重要?

补充/TL;DR

Default

当在 Prolog 中使用定语从句语法 (DCG) 时,我们知道 DCG 要求输入是字符代码列表,例如

?- string_codes("abc123",Cs).
Cs = [97, 98, 99, 49, 50, 51].

并在源代码文件中添加以下 DCG 规则并加载到顶层

digit(0) --> "0".

DCG 可与

?- string_codes("0",Cs),phrase(digit(D),Cs,R).
Cs = [48],
D = 0,
R = []

设置序言标志

现在可以更轻松地使用 DCG,而不必使用string_codesProlog指令

:- set_prolog_flag(double_quotes, chars).

可以在源代码文件中使用,并在源代码文件中使用以下 DCG 规则并加载到顶层

digit(0) --> "0".

DCG 可与

?- phrase(digit(D),"0",R).
D = 0,
R = [].

这遗漏了一些重要的东西

事实证明,如果set_prolog_flag出现before然后跳过 DCG 规则string_codes有效,但如果set_prolog_flag出现after然后跳过 DCG 规则string_codes fails.

:- set_prolog_flag(double_quotes, chars).
digit(0) --> "0".

?- phrase(digit(D),"0",R).
D = 0,
R = [].

vs

digit(0) --> "0".
:- set_prolog_flag(double_quotes, chars).

?- phrase(digit(D),"0",R).
false.

导致我发生冲突的推理

虽然我知道很多使用 Prolog 的编程都可以在顶层完成,但我倾向于依赖源代码文件和咨询/1 http://www.swi-prolog.org/pldoc/man?predicate=consult/1.
在编写大量代码时我开始使用modules http://www.swi-prolog.org/pldoc/man?section=modules。对于模块,我发现 Prolog 标志对于每个模块都是独立的。

?- current_prolog_flag(double_quotes,V).
V = string.

?- current_prolog_flag(symbolic:double_quotes,V).
V = string.

?- set_prolog_flag(symbolic:double_quotes,chars).
true.

?- current_prolog_flag(double_quotes,V).
V = string.

?- current_prolog_flag(symbolic:double_quotes,V).
V = chars.

默认的顶级模块是user

?- current_prolog_flag(double_quotes,V).
V = string.

?- current_prolog_flag(user:double_quotes,V).
V = string.

?- set_prolog_flag(double_quotes,chars).
true.

?- current_prolog_flag(double_quotes,V).
V = chars.

?- current_prolog_flag(user:double_quotes,V).
V = chars.

?- set_prolog_flag(user:double_quotes,codes).
true.

?- current_prolog_flag(double_quotes,V).
V = codes.

?- current_prolog_flag(user:double_quotes,V).
V = codes.

这让我误以为 Prolog 指令set_prlog_flag应用于整个模块,无论它是在哪里编写的。

是什么打破了模具

在编写大量示例代码时,将所有小示例保存在一个文件中并与每个小示例相关联会更容易set_prolog_flag。对于标识符示例,它需要两个小示例 DCG 规则,一个用于数字,一个用于字母。数字规则高于字母规则并有效,但字母规则具有set_prolog_flag指令,因为我当时正在研究它们。请记住,我认为该指令此时适用于整个文件。然后在测试中ident针对字母的 DCG 规则有效,但针对数字的 DCG 规则失败了。

digit(0) --> "0", !.
digit(1) --> "1", !.
digit(2) --> "2", !.

:- set_prolog_flag(double_quotes, chars).

ident(Id) --> letter(C), identr(Cs), { name(Id, [C|Cs]) }.

identr([C|Cs]) --> letter(C), !, identr(Cs).
identr([C|Cs]) --> digit(C), !, identr(Cs).
identr([])     --> [].

letter(a) --> "a", !.
letter(b) --> "b", !.
letter(c) --> "c", !.

?- phrase(ident(Id),"ab12",R).
Id = ab,
R = ['1', '2'].

根本原因

所以使用清单/1 http://listing/1

?- listing(digit).
digit(0, [48|B], A) :- !,
        A=B.
digit(1, [49|B], A) :- !,
        A=B.
digit(2, [50|B], A) :- !,
        A=B.
?- listing(ident).
ident(C, A, F) :-
        letter(D, A, B),
        identr(E, B, G),
        name(C, [D|E]),
        F=G.

?- listing(identr).
identr([A|D], B, F) :-
        letter(A, B, C), !,
        E=C,
        identr(D, E, F).
identr([A|D], B, F) :-
        digit(A, B, C), !,
        E=C,
        identr(D, E, F).
identr([], A, A).

?- listing(letter).
letter(a, [a|B], A) :- !,
        A=B.
letter(b, [b|B], A) :- !,
        A=B.
letter(c, [c|B], A) :- !,
        A=B.

问题很明显

digit(0, [48|B], A) :- !,
    A=B.

letter(a, [a|B], A) :- !,
        A=B.

该数字已转换为使用字符代码48并且字母被转换为使用字符a。就在那时我问自己是否set_prolog_flag来源很重要。

确认根本原因

为了测试这个我创建了一个小源代码文件

digit_before(0) --> "0".

:- set_prolog_flag(double_quotes, chars).

digit_after(0) --> "0".

并在顶层

?- current_prolog_flag(double_quotes,V).
V = string.

?- current_prolog_flag(symbolic:double_quotes,V).
V = string.

?- consult("C:/Users/Eric/Documents/Projects/Calculus Project/test.pl").
true.

?- current_prolog_flag(double_quotes,V).
V = chars.

?- current_prolog_flag(symbolic:double_quotes,V).
V = string.

?- listing(digit_before).
digit_before(0, [48|A], A).

true.

?- listing(digit_after).
digit_after(0, ['0'|A], A).

true

这证实了 Prolog 指令set_prolog_flag不适用于整个文件。请注意,digit_before 已转换为48并将 digital_after 转换为'0'.

Notes

注:指令set_prolog_flag(F,V)也可以用在顶层,不需要前面的:- .

注:所使用的示例:- set_prolog_flag(double_quotes, chars). but :- set_prolog_flag(double_quotes, codes).也有效。使用charsvalue 是首选,因为它使值在调试等时更容易读取。


在SWI-Prolog 中,指令和子句按顺序处理。 Prolog 标志很复杂。总体规则是它们是线程范围的,其中子线程使用写时复制语义共享其创建者的标志,这实际上意味着除了性能和内存使用之外,所有标志都将被复制。但是,某些标志的范围仅限于它们出现的源文件。这意味着 load_files/2 在加载之前保存标志的状态并在加载之后恢复它。其他一些标志是模块范围的,这意味着标志 API 只是更改模块属性的代理。此类标志不是特定于线程的,因为模块是全局的。另请注意,某些标志会影响阅读(例如,double_quotes),而其他影响编译器(optimise)并且大多数影响运行时行为。

理想情况下,文档包含当前序言标志/2 http://www.swi-prolog.org/pldoc/doc_for?object=current_prolog_flag/2应记录这些方面。不确定该文档是否准确。为了double_quotes它说为每个模块维护.

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

Prolog DCG set_prolog_flag double_quotes 源代码指令位置很重要;文档? 的相关文章

  • 适合从记录中提取 OneToMany 关系的约束编程

    也许有人可以帮助我解决 Prolog 或任何约束编程语言的问题 想象一个项目表 学生与母亲一起做某事的学校项目 每个项目都有一名或多名儿童参与 对于每个孩子 我们存储其姓名及其母亲的姓名 但对于每个项目 只有一个包含所有母亲的单元和一个包含
  • 实现用户定义的算术函数

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

    我正在尝试构建一个 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
  • 谓词对于列表中的所有元素都必须为 true

    我有一组事实 likes john mary likes mary robert likes robert kate likes alan george likes alan mary likes george mary likes har
  • 在 SWI Prolog 中使用 process_create/3 使用命令提示符或 shell 时出错

    在 Windows 7 上 当我在 SWI Prolog 中使用 process create 3 打开 Notepad exe 等应用程序时 记事本将打开 但是 它不适用于使用命令提示符的应用程序 例如 当我尝试打开命令提示符窗口时 使用
  • 从终端查询不会打印任何内容

    当在命令行中运行时 这 swipl g write 42 t halt 打印 42 到STDOUT正如预期的那样 然而 这 swipl g X 42 t halt 不打印任何内容 它只是返回 我如何让它打印在 REPL 中打印的内容 即X
  • SWI-Prolog 中的跨模块“接口”调用

    这可能是 SWI Prolog 模块系统特有的 假设我们有三个 Prolog 模块 在 SWI Prolog 模块系统中 robin 在文件中robin pl arthur 在文件中arthur pl helper 在文件中helper p
  • Prolog:如何在不重复的情况下创建所有可能的组合

    我正在尝试创建一个谓词来查找所有可能的组合而不重复相同的数字 我尝试使用排列谓词 但它发现了重复的列表 例如 permutation 0 1 1 L L 0 1 1 L 0 1 1 L 1 0 1 L 1 1 0 L 1 0 1 L 1 1
  • 判断第一个字母是否是元音序言

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

    我有这个跟踪元解释器 它是为 swi prolog 编写的 trace Goal trace Goal 0 trace true Depth true trace fail Depth fail trace A gt B Depth A g
  • Prolog:从哪里开始解决类似扫雷的难题?

    我需要在序言中写一些类似扫雷的东西 我能够用 正常 语言做到这一点 但是当我尝试用序言开始编码时 我完全不知道如何开始 我需要一些提示 输入规格 板尺寸 m n m n 1 16 三元组列表 i j k 在哪里i 1 m j 1 n k 1
  • 序言中的“如果”?

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

    我想更多地了解 Prolog 的内部结构并了解它是如何工作的 我知道如何使用它 但不是它内部如何运作 Prolog 中使用的算法和概念的名称是什么 它可能会构建某种树结构或有向对象图 然后在查询时使用复杂的算法遍历该图 也许是深度优先搜索
  • 将“mod”运算符与“or”一起使用时是否强制具体化?

    我使用 CLP FD 和 SWI Prolog 编写了一个 CSP 程序 我认为当我使用时我需要改进我的约束写作mod操作员 和 一起 在我的谓词中 一个简短的例子 use module library clpfd constr X Y Z
  • WAM 中的扁平化形式

    WAM 教程重构指出查询 p Z h Z W f W 需要使用以下原则进行扁平化 话虽这么说 查询扁平化形式是 X3 h X2 X5 X4 f X5 X1 p X2 X3 X4 我对外部变量的定义感到困惑 请考虑以下内容 p Z h Y a
  • 如何使用append/3在prolog中递归构建列表?

    我需要了解一些事实的价值 这部分似乎正在发挥作用 fact1 A Val1 fact2 B Val2 A B 但是一旦我尝试附加这些值 Val1 Val2 通过使用append 3谓词到列表 OutList 我只得到一个可能的解决方案 而不
  • json 获取 prolog 谓词

    我试图在序言中创建这个谓词 谓词json get 3可以定义为 json get JSON obj Fields Result 这是正确的 当Result可以通过以下方式恢复 中的字段链Fields 列表 从JSON obj 一个字段 代表
  • findall 的异常行为

    以下看起来很不寻常 findall X member X 1 2 3 X X 1 2 3 痕迹更是如此 trace findall X member X 1 2 3 X Call 11 findall 100058 member 10005
  • Prolog 谓词参数中实例化模式指示符的含义

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

    我有一个模板 其中包含文本框 一个 span 标签和一个 div 标签 div 标签具有 selectedColor 自定义指令 我想在输入值更改时更改 span 和 div 标签的背景颜色 所以最后我希望我的指令对输入更改做出反应并设置

随机推荐

  • 矢量之间的碰撞检查 - 移动矢量 - HTML、JS、P5

    我为我的玩家创建了碰撞检查功能 每次当对象 在本例中为矢量 圆 接触玩家 也是矢量 圆 时 游戏就会结束 我已经成功创建了一个逻辑 并且有一个碰撞检查正在工作 但是它并没有计算元素之间的实际距离 而不是当它们彼此相距一定距离时实际触及其结局
  • 如何将图像转换为纹身? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我后来正在使用纹身应用程序 因为我需
  • JavaFX 抛出 ArrayIndexOutOfBoundsException

    我正在尝试使用 JavaFX 标签和组 通过鼠标拖动将它们移动到屏幕上 新节点从某些线程添加到动画组中 然而 有时我会突然看到以下异常 我假设 当某些节点重叠时 但我不知道问题是什么 因为我的代码不涉及 有谁知道这个异常和根本原因 使用JD
  • 解码 JavaScript 字符串中包含十六进制的转义序列

    我有一个 JS 格式的字符串 http x3a x2f x2fwww url com 我怎样才能从中得到解码后的字符串 我尝试了 unescape string decode 但它没有解码它 如果我在浏览器中显示该编码字符串 它看起来不错
  • 如何从报告中访问报告名称属性?

    在 jasper 报表中 使用 iReports Designer 可以将报表名称设置为某个值 在 iReports 中 该值位于报表检查器的最顶层节点上 稍后如何在例如内部访问此参数的值 同一报告的变量或文本字段 在 的帮助下贾斯珀 报告
  • Jlabel HTML 格式

    我有一个 JLabel 里面有一个电子邮件地址 我在 JLabel 上使用了 HTML 格式 因此它显示为链接 但是 您无法单击该链接 事实上 您无法选择标签中的任何文本 我是否可以在 JLabel 上设置一个属性 以允许用户至少选择电子邮
  • Eclipse:覆盖 Tomcat 中的 JNDI 资源

    我正在 Eclipse 中开发 Java Web 应用程序 并将其部署到由 Eclipse 运行的 Tomcat 实例 我正在尝试让此应用程序通过 JNDI 与另一台主机上的数据库进行通信Resource元素 应用程序中包含的 contex
  • 使用 HttpClient 调用 WCF 服务

    我必须调用 WCF 服务 WCF 服务已开启 我可以编辑其配置 我想创建一个调用该服务的客户端 我无法将服务引用添加到我的客户端 因此我尝试使用 HttpClient 调用它 客户端代码 using var client new HttpC
  • 驱动程序在 Jenkins 中不是可执行错误,但在本地计算机 (MacBook) 中运行

    我正在 MacBook 上工作 当我通过testing xml文件运行测试时 我们的Jenkins服务器正在Linux服务器中运行 所有测试类都在运行 但是当我运行Jenkins构建时 它没有运行 错误提示驱动程序不可执行 我已经在 J e
  • 在 blazor 中添加全局使用指令

    命名空间 MyClassLibrary Models 中不存在类型或命名空间名称 XXX 是否缺少程序集引用 该错误参考此 BlazorProject MyPager azor g cs 在这种情况下我得到了这个错误 创建了一个类型的文件
  • 如何使用 AppDelegate 在视图之间共享 iAd 横幅

    我希望在我的应用程序中实现 iAd 到目前为止 我已经成功地使用下面的方法让它们在每个视图中正确显示 关闭 应用程序委托 import UIKit import iAd UIApplicationMain class AppDelegate
  • Oracle 中的日期字符串(以毫秒为单位)

    我想将以下字符串转换为日期 2004 09 30 23 53 48 140000000 I tried to date YYYY MM DD HH24 MI SS FF9 But PL SQL http en wikipedia org w
  • 如何使用jq将JSON对象流转换为数组

    我想用jq将 json 对象流放入 json 数组中 例如 来自 a 1 b 2 to a 1 b 2 但这是行不通的 echo a 1 b 2 jq 自从我得到 a 1 b 2 用吸吮它 s option jq s lt lt lt a
  • Django - 使用静态文件的奇怪行为

    我是姜戈的新手 我试图理解静态文件 css 和图像 发生了什么而变得疯狂 问题的简历如下 当我使用来自第三方应用程序 Haystack 的静态视图时 我无法使用静态文件 我的项目有这样的目录结构 1001empbr name of the
  • Python 3.6.1 安装位置

    我在 Ubuntu 16 服务器上安装了 Python 3 6 1 但找不到安装位置 我查看了 usr bin 其中提到了除 3 6 1 之外的所有其他版本 在哪里可以找到该版本的可执行文件 使用命令 whereis python3 6 1
  • Chrome 扩展 - 第一个链接在弹出窗口中自动聚焦

    如何停止 Google Chrome 扩展程序的默认操作以自动聚焦我的网站中的第一个链接popup html 我知道我可能可以用 JS 做一些迂回黑客或改变 focusCSS 但我认为这抛弃了我正在尝试做的其他事情 我更愿意阻止它的根本原因
  • 读取上传的Excel文件而不保存它

    在这段代码中 我从用户那里获取上传的文件并将其保存在我的应用程序中的文件夹中 然后对此 Excel 文件进行 OleDbConnection 并读取数据 我的问题是 有人可以建议一种阅读此 Excel 文件的首选方法 但无需预先保存它 因为
  • DOCX 到 PDF:SaveAs2、ExportAsFixedFormat 与 PrintOut

    我有一个小小的目标 即使用 C 和 NET 将大量 docx 文件转换为 pdf 而无需打开 Word 可见 且无需使用任何第三方库 需要管理的组件更少 花费的资金也更少 目前 我正在尝试正确转换单个文档 该文档必须尽可能高效 以便快速转换
  • ostream& operator<< 在类中的实践比使用 std::cout 更好吗?

    在链接列表类中 我创建了一个display打印出链接列表的方法 目前的形式如下 void LinkedList display Node curr m head while curr std cout lt lt curr gt n dat
  • Prolog DCG set_prolog_flag double_quotes 源代码指令位置很重要;文档?

    我通过 SWI Prolog 惨痛地了解到 Prolog 指令的位置set prolog flag重要的是源代码文件 我发现的关于使用指令加载源代码文件的唯一有价值的文档位于加载Prolog源文件 http www swi prolog o