127 个版本

0.9.4 2024年2月29日
0.9.3 2023年11月2日
0.9.1 2022年11月10日
0.8.127 2020年8月3日
0.8.33 2019年3月31日

#45 in 过程宏

33 个月下载量
3 个包中使用(直接使用 2 个)

BSD-3-Clause

3.5MB
86K SLoC

Rust 53K SLoC // 0.0% comments Perl 33K SLoC // 0.0% comments Emacs Lisp 87 SLoC // 0.2% comments Shell 7 SLoC // 0.3% comments

Scryer Prolog

Scryer Prolog 的目标是要成为 ISO Prolog 一样的东西:一个开源的工业级生产环境,同时也是逻辑和约束编程前沿研究的测试平台,它本身是用高级语言编写的。

Scryer Prolog 通过了所有关于 语法一致性variable_names/1dif/2 的测试。

项目主页为: https://www.scryer.pl

Scryer Logo: Cryer

第一阶段

在 Rust 中实现 Warren 抽象机,根据 Warren 的抽象机:教程重建 中语言的进展进行。

第一阶段已完成,Scryer Prolog 以某种形式实现了 WAM 书籍的所有内容,包括列表、切割、Debray 分配、第一个参数索引、最后调用优化和合取查询。

第二阶段

扩展 Scryer Prolog 以包括以下功能(以及其他功能)

  • 内置元谓词 call/N。
  • ISO Prolog 兼容的 throw/catch。
  • 所有结合性的内置和用户定义运算符,具有自定义结合性和优先级。
  • 大数、有理数和浮点数算术。
  • 内置控制运算符(,;-> 等)。
  • 改进的、不糟糕的模块系统。
  • 用于列表处理和顶级声明性控制的内建谓词(如setup_call_cleanup/3call_with_inference_limit/3等)
  • 使用紧凑的内部表示法将字符串默认表示为字符列表。
  • term_expansion/2goal_expansion/2
  • 确定子句语法。
  • 使用SICStus Prolog接口和语义的属性变量。通过属性变量添加协程如dif/2freeze/2等非常简单。
    • 支持verify_attributes/3
    • 支持attribute_goals/2project_attributes/2
    • call_residue_vars/2
  • if_/3和相关谓词,遵循论文"索引dif/2"的发展。
  • 全解谓词(如findall/{3,4}bagof/3setof/3forall/2)。
  • 具有逻辑更新语义的子句创建和销毁(asserta/1assertz/1retract/1abolish/1)。
  • 通过bb_get/2 bb_put/2(不可回溯)和bb_b_put/2(可回溯)实现可回溯和不可回溯的全局变量。
  • 基于reset/3、shift/1的划分连续(在"Prolog的划分连续"中记录)。
  • 基于划分连续的tabling库(在"带有划分控制的tabling作为库"中记录)。
  • 使用紧凑的内部表示法将字符串表示为字符差异列表的重新表示。
  • 作为内建库的clp(B)和clp(ℤ)。
  • 流和流控制的谓词。
    • 将TCP连接作为流表示的简单套接字库。
  • 增量编译和加载过程,主要是用Prolog编写的新。
  • 对WAM编译器和堆表示的改进
    • 将基于内联半确定谓词(如atomvar等)的选择点替换为if/else梯子。(进行中
    • 内联所有内建和系统调用指令。
    • 大大减少编译析取式使用的指令数量。
    • 将短原子存储到堆单元格中而不写入原子表。
  • 一个紧凑的垃圾收集器满足"Prolog的精确垃圾收集"的五个属性。(进行中
  • 模式声明。

第3阶段

使用由完成后的代码生成器产生的WAM代码来获取即时编译和执行Prolog程序。如何从WAM代码中获得汇编代码是我仍在考虑的问题。

我希望使用Scryer Prolog作为低级(理想情况下,非常快速)Shen实现的逻辑引擎。

一些不错的特性

目前没有计划实现这些特性,但将来可能会有所帮助。对于想要为Scryer Prolog贡献代码的人来说,这会是一个很好的项目。

  1. 实现Peter van Roy在其论文《Can Logic Programming Execute as Fast as Imperative Programming?》中描述的全局分析技术。

  2. 添加unum表示法和算术,可以使用现有的unum实现或自定义实现。Unums在Gustafson的书籍《The End of Error》中有所描述。

  3. 添加并发表来管理对原子和字符串的共享引用。

  4. 添加某种形式的JIT谓词索引。

安装Scryer Prolog

二进制文件

预编译的二进制文件可在以下位置下载:

https://github.com/mthom/scryer-prolog/releases/tag/v0.9.3

本地编译

首先,使用您首选的方法安装最新版本的Rust。Scryer倾向于使用较新Rust版本中的功能,而Linux发行版、Macports等中的Rust包往往落后。使用rustup可以保持Rust更新到最新稳定版本;在rustup使用之前,应从系统中卸载现有的Rust发行版。

目前安装Scryer最新版本的唯一方法是直接从git仓库克隆,然后编译系统。以下是操作方法

$> git clone https://github.com/mthom/scryer-prolog
$> cd scryer-prolog
$> cargo build --release

--release标志执行各种优化,产生更快的可执行文件。

编译完成后,可执行文件scryer-prolog位于目录target/release中,可以调用它来运行系统。

在Windows上,在MSYS2环境中构建Scryer Prolog更容易,因为某些crate可能需要本地C编译。然而,生成的二进制文件不需要MSYS2运行。在shell中执行Scryer时,建议使用比mintty(默认MSYS2 shell)更先进的shell。Windows Terminal可以正常工作。

要构建Windows安装程序,首先需要以发布模式编译Scryer Prolog,然后安装WiX Toolset,执行以下操作:

candle.exe scryer-prolog.wxs
light.exe scryer-prolog.wixobj

它将生成一个非常基本的MSI文件,用于安装主可执行文件和启动菜单中的快捷方式。可以通过双击安装。要卸载,请转到控制面板,然后按常规卸载。

Scryer Prolog必须使用Rust 1.70及更高版本构建。

构建WebAssembly

Scryer Prolog具有基本的WebAssembly支持。您可以按照wasm-pack官方说明来安装wasm-pack并以您喜欢的方式构建。

然而,目前不支持任何默认功能。禁用它们的推荐方法是向wasm-pack传递额外选项

例如,如果您想创建一个最小的工作包,不使用任何捆绑器(如webpack),可以这样做:

wasm-pack build --target web -- --no-default-features

然后将会创建一个pkg目录,其中包含构建webapp所需的所有内容。您可以创建一个html文件来测试包是否成功构建,这个文件可以从wasm-bindgen官方示例中改编如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Scryer Prolog - Sudoku Solver Example</title>
        <script type="module">
        import init, { eval_code } from './pkg/scryer_prolog.js';

        const run = async () => {
            await init("./pkg/scryer_prolog_bg.wasm");
            let code = `
            :- use_module(library(format)).
            :- use_module(library(clpz)).
            :- use_module(library(lists)).
            
            sudoku(Rows) :-
            length(Rows, 9), maplist(same_length(Rows), Rows),
            append(Rows, Vs), Vs ins 1..9,
            maplist(all_distinct, Rows),
            transpose(Rows, Columns),
            maplist(all_distinct, Columns),
            Rows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is],
            blocks(As, Bs, Cs),
            blocks(Ds, Es, Fs),
            blocks(Gs, Hs, Is).
            
            blocks([], [], []).
            blocks([N1,N2,N3|Ns1], [N4,N5,N6|Ns2], [N7,N8,N9|Ns3]) :-
            all_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]),
            blocks(Ns1, Ns2, Ns3).
            
            problem(1, [[_,_,_,_,_,_,_,_,_],
                        [_,_,_,_,_,3,_,8,5],
                        [_,_,1,_,2,_,_,_,_],
                        [_,_,_,5,_,7,_,_,_],
                        [_,_,4,_,_,_,1,_,_],
                        [_,9,_,_,_,_,_,_,_],
                        [5,_,_,_,_,_,_,7,3],
                        [_,_,2,_,1,_,_,_,_],
                        [_,_,_,_,4,_,_,_,9]]).
            
            main :-
            problem(1, Rows), sudoku(Rows), maplist(portray_clause, Rows).
            
            :- initialization(main).
            `;
            const result = eval_code(code);
            document.write(`<p>Sudoku solver returns:</p><pre>${result}</pre>`);
        }
        run();
        </script>    
    </head>
    <body></body>
</html>

然后您可以使用您喜欢的HTTP服务器来提供它,例如使用 python -m http.servernpx serve,并通过浏览器访问页面。

Docker 安装

首先,在 Linux、Windows 或 Mac 上安装 Docker

安装 Docker 后,您可以通过一条命令下载并运行 Scryer Prolog

$> docker run -it mjt128/scryer-prolog

要咨询您的 Prolog 文件,请将程序文件夹绑定为 Docker 卷

$> docker run -v /home/user/prolog:/mnt -it mjt128/scryer-prolog
?- consult('/mnt/program.pl').
true.

这也适用于 Windows

$> docker run -v C:\Users\user\Documents\prolog:/mnt -it mjt128/scryer-prolog
?- consult('/mnt/program.pl').
true.

教程

通过在命令行上指定它们作为参数来加载 Prolog 文件。例如,要加载 program.pl,使用

$> scryer-prolog program.pl

加载 Prolog 文件也称为“咨询”它。可以使用内置谓词 consult/1 在 Prolog 内部咨询文件

?- consult('program.pl').

作为 consult/1 的缩写,您可以指定一个 列表 的程序文件,作为 原子 提供

?- ['program.pl'].

特殊表示法 [user] 用于从标准输入读取 Prolog 文本。例如,

?- [user].
hello(declarative_world).
hello(pure_world).

按下 RETURN 后跟 Ctrl-d 停止从标准输入读取并咨询输入的 Prolog 文本。

程序咨询后,您可以询问它定义的谓词的 查询。例如,使用上面的程序

?- hello(What).
   What = declarative_world
;  What = pure_world.

SPACE 显示更多答案(如果有的话)。按 RETURN. 终止搜索并返回到顶层提示。按 f 显示下一个5的倍数答案,按 a 显示所有答案。按 h 显示帮助信息。

使用 TAB 在查询中完成原子和谓词名称。例如,在咨询上述程序后,键入 decl 后跟 TAB 得到 declarative_world。按 TAB 重复循环以查看不同的补全。

要退出 Scryer Prolog,请使用标准谓词 halt/0

?- halt.

启动 Scryer Prolog

可以通过指定选项、文件和附加参数从命令行启动 Scryer Prolog。所有组件都是可选的

scryer-prolog [OPTIONS] [FILES] [-- ARGUMENTS]

支持以下选项

   -h, --help             Display help message
   -v, --version          Print version information and exit
   -g, --goal GOAL        Run the query GOAL after consulting files
   -f                     Fast startup. Do not load initialization file (~/.scryerrc)
   --no-add-history       Prevent adding input to history file (~/.scryer_history)

咨询所有指定的 Prolog 文件。

在 Prolog 文件之后,可以在命令行上指定特定于应用程序的参数。可以从 Prolog 应用程序中使用谓词 argv/1 访问这些参数,它返回作为字符串表示的参数列表。

Prolog 文件也可以转换为 shell 脚本,如 https://github.com/mthom/scryer-prolog/issues/2170#issuecomment-1821713993 中所述。

动态运算符

Scryer 支持动态运算符。使用具有常规优先级的内置算术运算符

?- write_canonical(-5 + 3 - (2 * 4) // 8), nl.
-(+(-5,3),//(*(2,4),8))
   true.

可以使用 op 声明定义新运算符。

第一实例化的参数索引

Scryer Prolog 对谓词定义中所有子句中左侧非变量的第一个参数进行索引。我们称这种策略为第一 实例化 参数索引。

第一实例化参数索引的一个关键动机是启用元谓词(如 maplist/Nfoldl/N)的索引,这些谓词的第一个参数是一个部分目标,它在这些谓词的定义中是变量,因此不能用于索引。

例如,maplist/2 的自然定义读取如下

maplist(_, []).
maplist(Goal_1, [L|Ls]) :-
        call(Goal_1, L),
        maplist(Goal_1, Ls).

在这种情况下,首先实例化的参数索引自动使用第二个参数进行索引,从而防止了调用固定长度列表(和确定性目标)的选择点。方便的是,在这种情况下不需要重新排序参数的辅助谓词来从索引中获益。

当谓词定义中的任何子句实例化第一个参数时,传统的第一个参数索引自然地成为这种策略的特殊情况。

字符串和部分字符串

Scryer Prolog中字符串的非常紧凑的内部表示是其主要创新之一。这意味着在Prolog程序中作为字符列表出现的项被引擎以压缩的UTF-8编码存储。

如果没有这种创新,将字符列表存储在内存中会使用一个WAM内存单元格来存储每个字符,一个单元格来存储每个列表构造函数,以及每个列表中出现的每个尾。由于一个单元格在Scryer Prolog的WAM实现中占用8个字节,这种压缩表示可以提供高达24倍的内存使用率降低,以及创建和处理字符串时内存访问的相应降低。

Scryer Prolog紧凑的内部字符串表示使其非常适合Prolog最初开发的用例:高效便捷的文本处理,尤其是在有明确子句语法(DCGs)的情况下,如由library(dcgs)library(pio)提供的,以便透明地将DCGs应用于文件。

在Scryer Prolog中,Prolog标志double_quotes的默认值是chars,这也是推荐的设置。这意味着字符列表可以写成双引号字符串,遵循马赛Prolog的传统。

例如,以下查询成功

?- "abc" = [a,b,c].
   true.

这表明字符串 "abc"(在内部表示为3个字节的序列),对Prolog程序来说似乎是一个字符列表。

Scryer Prolog使用相同的有效编码来表示部分字符串,它们在Prolog代码中表现为部分字符列表。来自library(iso_ext)的谓词partial_string/3允许您显式地构造部分字符串。例如

?- partial_string("abc", Ls0, Ls).
   Ls0 = [a,b,c|Ls].

在这种情况下,并且正如答案所示,"Ls0"与尾部为"Ls"的部分列表不可区分,而高效的压缩表示在内部使用。

Scryer Prolog的设计目标之一是自动在可能的情况下使用有效的字符串表示。因此,只有在极少数情况下才需要显式使用partial_string/3在上述示例中,声明Ls0 = [a,b,c|Ls]

会产生完全相同的外部表示,并且具有仅使用标准谓词"="的优势。

出现检查和循环项

“出现检查”是执行句法统一的算法中的一个元素,如果变量与包含该变量的正确子项的项进行统一,则会导致统一失败。为了提高效率,Scryer Prolog以及许多其他Prolog系统默认省略了“出现检查”。

在Scryer Prolog中,只有省略“出现检查”才能成功的统一会生成“循环项”,也称为“有理树”。例如

?- X = f(X), Y = g(X,Y).
   X = f(X), Y = g(f(X),Y).

循环项的创建通常表明Prolog谓词的表述中存在编程错误,为了获得逻辑上合理的结果,最好是使用带有“出现检查”的统一,或者在需要启用“出现检查”以防止统一的情况下,让Prolog抛出错误。

Scryer Prolog通过Prolog标志occurs_check支持这一功能。它可以设置为以下值以获得期望的行为

  • false 不执行“出现检查”。这是默认设置。
  • true 使用带有“出现检查”的统一执行所有统一。
  • error 如果执行了“出现检查”将阻止的统一,则产生错误。

特别是在刚开始使用Prolog时,我们建议将以下指令添加到~/.scryerrc配置文件中,以便通过错误指示由谓词中导致创建循环项的编程错误

:- set_prolog_flag(occurs_check, error).

Scryer Prolog通过实现专门的推理,在许多经常出现的情况下使统一快速,即使启用了“出现检查”也是如此。

表查询(SLG解决)

Prolog最吸引人的特点之一是可以通过各种不同的执行策略推导出纯程序的逻辑后果,这些策略在诸如终止性、完备性和效率等基本属性方面有所不同。

Prolog的默认执行策略是深度优先搜索和按时间顺序回溯。这种策略非常高效。其主要缺点是它是不完整的:它可能找不到任何解决方案,即使解决方案确实存在。

Scryer Prolog支持一种称为“表查询”(也称为表查询和SLG解决)的替代执行策略。要为谓词启用表查询,使用library(tabling)并添加一个(table)/1指令来指定谓词指示符。例如,如果我们写

:- use_module(library(tabling)).
:- table a/0.

a :- a.

那么查询?- a. 终止(失败),而使用默认执行策略时它不会终止。

Scryer Prolog通过分界连续体实现表查询,正如在Desouter等人所著的分界控制中的表查询作为库中所描述的那样。

约束逻辑编程(CLP)

Scryer Prolog为约束逻辑编程(CLP)提供了出色的支持,这是逻辑编程(LP)和约束的结合。

除了内置对 dif/2freeze/2CLP(B)CLP(ℤ) 的支持外,Scryer 还提供了一个方便的方式来实现新的用户定义约束:通过 library(atts) 提供了属性变量,类似于 SICStus Prolog,这是现有最复杂和最快的约束系统之一。在 library(iso_ext) 中,Scryer 提供了回溯(bb_b_put/2)和非回溯(bb_put/2)的全局变量谓词,这些变量是实现某些类型约束求解器所必需的。

这些功能使 Scryer Prolog 成为教学、学习和开发可移植 CLP 应用程序的理想平台。

模块

Scryer 拥有一个简单的基于谓词的模块系统。它提供了一种将代码单元分离到不同命名空间的方法,适用于谓词和运算符。请参阅文件 src/lib/*.pl 以获取示例。

在撰写本文时,许多谓词都位于自己的模块中,在使用之前需要导入。Scryer Prolog 中的模块也称为 库模块,包括

  • lists 提供 length/2member/2select/3append/[2,3]foldl/[4,5]maplist/[2-9]same_length/2transpose/2 等等。
  • dcgs 确定性子句文法(DCGs),这是一个内置的文法机制,使用运算符 (-->)/2 来定义文法规则,以及谓词 phrase/[2,3] 来调用它们。
  • dif谓词dif/2提供声明式不等于:如果其参数不同,则为真,并且延迟测试直到可以做出合理决策。
  • reif提供if_/3tfilter/3和相关谓词,如索引dif/2中所述。
  • clpz CLP(ℤ):整数上的约束逻辑编程,通过(#=)/2(#=)/2(#>=)/2等,以及用于解决组合任务的多种全局约束和枚举谓词。
  • pairs按照惯例,成对是具有主要函子(-)/2的Prolog项,写作-。此库提供pairs_keys_values/3pairs_keys/2和其他关于成对的谓词。
  • si谓词atom_si/1integer_si/1atomic_si/1list_si/1实现了合理的类型检查。如果无法做出决策,它们会引发实例化错误。它们是逻辑上存在缺陷的底层类型测试的声明式替代。例如,为了确保程序的正确性,而不是写integer(X),写integer_si(X)。“si”代表足够实例化,也代表合理的推理
  • debug各种允许声明式调试的谓词。
  • piophrase_from_file/2 将DCG非终结符应用于文件内容,以所需的最小量惰性读取。由于紧凑的内部字符串表示,使用Scryer Prolog以这种方式可以有效地处理非常大的文件。 phrase_to_file/2phrase_to_stream/2 分别将DCG描述的字符列表写入文件和流。
  • lambda 用于简化高阶编程的Lambda表达式。
  • charsio 提供了各种有助于解析和处理字符的谓词,特别是 char_type/2 谓词,用于根据字符类型进行分类,以及字符串不同编码的转换谓词。
  • errormust_be/2can_be/2 谓词补充了 library(si) 提供的类型检查,对于Prolog库的作者特别有用。
  • tabling 操作符 (table)/1 用于准备用于表式执行(SLG求解)的谓词。
  • format 非终结符 format_//2 用于描述格式化的输出,根据给定的格式字符串排列参数。谓词 format/[2,3]portray_clause/[1,2]listing/1 提供格式化的 非纯 输出。
  • assoc 提供了 empty_assoc/1get_assoc/3put_assoc/4 等谓词,用于管理AVL树中的元素,这些树确保 O(log(N)) 访问。
  • ordsets 将有序集合表示为列表。
  • clpb CLP(B):基于BDD的SAT求解器,通过谓词 sat/1taut/2labeling/1 等提供。
  • arithmetic 包含诸如 lsb/2msb/2number_to_rational/2 等算术谓词。
  • time 用于时间推理的谓词,包括 time/1 来测量目标函数的 CPU 时间,current_time/1 获取当前系统时间,非终结符 format_time//2 描述带日期和时间的字符串,以及 sleep/1 来减慢计算速度。
  • files 用于文件和目录推理的谓词,例如 directory_files/2file_exists/1file_size/2
  • cont 通过 reset/3shift/1 提供了 分隔的延续
  • random 概率谓词和随机数生成器。
  • http/http_open 打开流以从网络服务器读取答案。也支持 HTTPS。
  • http/http_server 运行 HTTP/1.1 和 HTTP/2.0 网络服务器。使用 Warp 作为后端。支持一些查询和处理表单。
  • sgml load_html/3load_xml/3 将 HTML 和 XML 文档表示为 Prolog 项,以便于高效推理。使用 library(xpath) 从解析的文档中提取信息。
  • csv parse_csv//1parse_csv//2 可与 phrase_from_file/2phrase/2 一起使用来解析 CSV。
  • serialization/abnf 描述 ABNF 语法核心 (RFC 5234) 的 DCGs,该语法核心用于描述许多 IETF 语法,例如 HTTP v1.1SMTPiCalendar 等。
  • serialization/json json_chars//1 可与 phrase_from_file/2phrase/2 一起使用,以解析和生成 JSON
  • xpath谓词 xpath/3 用于方便地处理 HTML 和 XML 文档,受 XPath 语言的启发。此库通常与 library(sgml) 一起使用。
  • sockets 用于打开和接受 TCP 连接作为流的谓词。
  • os 用于推理环境变量的谓词。
  • iso_ext 符合 Prolog ISO 标准的扩展,以及可能包含在内的候选项,例如 setup_call_cleanup/3call_nth/2call_with_inference_limit/3
  • crypto 提供加密安全的随机数和散列,基于 HMAC 的密钥派生(HKDF),基于密码的密钥派生(PBKDF2),使用 Ed25519 的公钥签名和签名验证,Curve25519(X25519)上的 ECDH 密钥交换,ChaCha20-Poly1305 的认证对称加密,以及关于椭圆曲线的推理。
  • uuid 生成 UUIDv4 和十六进制表示
  • tls 用于显式协商 TLS 连接的谓词。
  • ugraphs 图操作库
  • simplex 提供 assignment/2transportation/4 和其他用于解决线性规划问题的谓词。

要使用 lists 库提供的谓词,请编写

?- use_module(library(lists)).

要加载文件中包含的模块,可以省略 library 函数子,提示 Scryer 从其工作目录搜索指定的文件(作为原子指定)

?- use_module('file.pl').

use_module 指令可以通过添加一个导入列表来限定。

?- use_module(library(lists), [member/2]).

限定的 use_module 可以通过使用空导入列表来调用,从而从顶级环境中移除导入。

操作符 (:)/2 解决了当前工作命名空间可能未导入的谓词调用。

?- lists:member(X, Xs).

在 REPL 中,也可以使用 [用户] 提示来定义模块。

?- [user].
:- module(test, [local_member/2]).
:- use_module(library(lists)).

local_member(X, Xs) :- member(X, Xs).

用户列表也可以通过在流末尾放置 end_of_file. 来终止。

配置文件

启动时,Scryer Prolog 会咨询文件 ~/.scryerrc(如果该文件存在)。此文件很有用,可以自动加载库并定义你经常需要的谓词。

例如,~/.scryerrc 的一个合理的起点是

:- use_module(library(lists)).
:- use_module(library(dcgs)).
:- use_module(library(reif)).

开发环境

为了编写和编辑 Prolog 程序,我们推荐使用由 Stefan Bruda 维护的 GNU Emacs 中的 Prolog 模式

使用 ediprolog 在任意 Emacs 缓冲区中咨询 Prolog 代码和评估 Prolog 查询。

工具 中提供了显示 Prolog 项作为树的 Emacs 定义。

为了 调试 Prolog 代码,我们推荐来自 library(debug) 的谓词,最著名的是

  • (*)/1“泛化” Prolog 目标。使用它通过泛化你的定义直到它们成功来调试意外的失败。只需在目标前放置 * 来泛化它。
  • ($)/1 以发出执行的 跟踪,显示何时调用目标以及何时成功。在目标前放置 $ 来为该目标发出此信息。

这种调试 Prolog 代码的方式有几个主要优点,例如:它始终接近正在考虑的实际 Prolog 代码,它不需要为其应用提供额外工具和形式,并且还鼓励可以原则上自动执行的可声明推理。

应用

Scryer Prolog 对 Prolog ISO 标准的坚定承诺使其非常适合在需要遵守有关互操作性、标准合规性和保修的严格规定的公司和国家机关中使用。

Scryer Prolog 的现有成功应用包括生成 Scryer 自身文档和主页的 DocLog 系统、奥地利联邦计算中心的 补助金符号分析,以及描述在 使用 Prolog 的肿瘤学剂量递增方案的可执行规范 中的安全关键和高监管领域剂量递增试验分析的 precautionary 包的一部分。

Scryer Prolog 也很适合用于 Prolog 的教学和学习,以及测试现有 Prolog 程序的语法兼容性和可移植性。

支持和讨论

如果Scryer Prolog崩溃或出现意外错误,请考虑提交一个问题

要联系Scryer Prolog社区,请参与讨论或访问我们的Libera上的#scryer IRC频道!

依赖项

~21–39MB
~724K SLoC