9个版本

使用旧的Rust 2015

0.8.1 2019年3月2日
0.8.0 2019年2月23日
0.7.16 2018年11月16日
0.7.15 2018年10月25日
0.7.13 2018年9月16日

#294 in 编程语言

26 每月下载量

BSD-3-ClauseLGPL-3.0+

1MB
26K SLoC

rusty-wam

rusty-wam旨在成为ISO Prolog的GHC对Haskell一样:一个开源的工业级生产环境,也是一个逻辑和约束编程前沿研究的测试平台,而它本身是用高级语言编写的。

第一阶段

在Rust中实现Warren抽象机的实现,按照Warren的抽象机:教程重建中语言进化的顺序。

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

第二阶段

扩展rusty-wam以包括以下内容,以及其他内容:

  • call/N作为内置元谓词(已完成)。
  • 与ISO Prolog兼容的throw/catch(已完成)。
  • 所有固定性的内置和用户定义的算子,具有自定义的关联性和优先级(已完成)。
  • 大数、有理数和浮点算术(已完成)。
  • 内置控制算子(, ; ->等)(已完成)。
  • 修订的、相当不错的模块系统(已完成,我认为)。
  • 使用SICStus Prolog接口和语义的属性变量。添加诸如diffreeze等协程非常简单(已完成)。
  • 字符串的默认表示为字符列表,使用打包的内部表示(已完成)。
    • 将“部分字符串”表示为字符差分列表(已完成)。
  • term_expansiongoal_expansion已完成)。
  • 属性文法(已完成)。
  • 使用SICStus Prolog接口和语义的属性变量。添加诸如diffreeze等协程非常简单(已完成)。
    • 支持 verify_attributes/3
    • 支持 attribute_goals/2project_attributes/2
    • call_residue_vars/2
  • if_ 以及相关的谓词,遵循论文 "Indexing dif/2" 的发展 (已完成)。
  • 所有解的谓词 (findall/{3,4}bagof/3setof/3) (已完成)。
  • 子句创建和销毁 (asserta/1assertz/1retract/1abolish/1) 具有逻辑更新语义 (已完成)。
  • 流和用于流控制的谓词 (进行中)。
  • 一个满足 "Prolog 中的精确垃圾回收" 五大属性的增量压缩垃圾回收器。
  • 模式声明。
  • clp(FD) 扩展。

第 3 阶段

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

我希望使用 rusty-wam 作为底层 (理想情况下,非常快速) Shen 实现的逻辑引擎。

期望拥有的功能

目前没有计划实现这些功能,但未来可能会有所帮助。它们对于想要为 rusty-wam 贡献代码的人来说是个不错的项目。

  1. 实现 Peter van Roy 论文中描述的全局分析技术,"Can Logic Programming Execute as Fast as Imperative Programming?"

  2. 添加 unum 表示法和算术运算,使用现有的 unum 实现或定制的实现。Unums 在 Gustafson 的书籍 "The End of Error" 中有所描述。

  3. 添加对 shift/reset 定界继续的支持,见 "Delimited Continuations for Prolog"。

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

  5. 添加可选的 SLG 解析以快速缓存谓词。

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

安装 rusty-wam

首先,使用您首选的方法安装最新稳定的 Rust。然后使用 cargo 安装最新版本的 rusty-wam,如下所示

$> cargo install rusty-wam

cargo 将自动下载并安装 rusty-wam 所需的库。您可以在 ~/.cargo/bin 中找到 rusty-wam 可执行文件。

关于兼容性的说明:rusty-wam 应该可以在 Linux、Mac OS X 和 FreeBSD 上运行。Windows 支持取决于 Termion 库在 Windows 终端中工作,目前还没有这种情况,尽管正在进行相关工作。有关更多信息,请参阅相关的 Termion 问题

内置谓词

以下谓词是 rusty-wam 内置的。

  • 算术支持
    • is/2(+)/2(-)/{1,2}(*)/2(//)/2(**)/2(div)/2(/)/2(rdiv)/2(xor)/2(rem)/2(mod)/2(/)/2(/)/2(>>)/2(<<)/2abs/1 都有效。
    • 比较运算符: ><=<>==:===
  • (:)/2
  • (@>)/2
  • (@>=)/2
  • (@=<)/2
  • (@<)/2
  • (=@=)/2
  • (\=@=)/2
  • (\+)/1
  • (==)/2
  • (\==)/2
  • (=)/2
  • (\=)/2
  • (=..)/2
  • (->)/2
  • (;)/2
  • 废除/1
  • acyclic_term/2
  • append/3
  • arg/3
  • asserta/1
  • assertz/1
  • atom/1
  • atomic/1
  • bagof/3
  • between/3
  • call/1..62
  • call_cleanup/2
  • call_with_inference_limit/3
  • call_residue_vars/2
  • can_be/2
  • catch/3
  • clause/2
  • compare/3
  • compound/1
  • copy_term/2
  • current_predicate/1
  • cyclic_term/1
  • dif/2
  • expand_goal/2
  • expand_term/2
  • false/0
  • findall/{3,4}
  • float/1
  • freeze/2
  • functor/3
  • gen_int/1
  • gen_nat/1
  • goal_expansion/2
  • ground/1
  • integer/1
  • is_list/1
  • is_partial_string/1
  • keysort/2
  • length/2
  • maplist/2..9
  • member/2
  • memberchk/2
  • must_be/2
  • nl/0
  • nonvar/1
  • numbervars/2
  • numlist/{2,3}
  • once/1
  • partial_string/2
  • phrase/{2,3}
  • rational/1
  • read/1
  • repeat/{0,1}
  • retract/1
  • reverse/2
  • select/3
  • setof/3
  • setup_call_cleanup/3
  • sort/2
  • string/1
  • term_expansion/2
  • term_variables/2
  • throw/1
  • /0
  • 用户:goal_expansion/2
  • 用户:term_expansion/2
  • 变量/1
  • 写入/1
  • 写入规范/1
  • 写入队列/1
  • 写入术语/2

教程

要输入多行谓词,请使用指令"[用户]"。

例如,

prolog> [user]
(type Enter + Ctrl-D to terminate the stream when finished)
p(f(f(X)), h(W), Y) :- g(W), h(W), f(X).
p(X, Y, Z) :- h(Y), z(Z).
prolog> [user]
(type Enter + Ctrl-D to terminate the stream when finished)
h(x). h(y).
h(z).

在示例中,使用Enter + Ctrl-D来终止标准输入流。指导信息始终会打印出来。

查询以以下方式发出

prolog> ?- p(X, Y, Z).

按下空格将在存在其他可能的答案时回溯。按下.将终止搜索并返回提示符。

通配符也适用

prolog> [user]
member(X, [X|_]).
member(X, [_|Xs]) :- member(X, Xs).
prolog> ?- member(X, [a, b, c]).
true .
X = a ;
X = b ;
X = c ;
false.

以及连接查询也适用

prolog> [user]
f(X) :- g(X).
prolog> [user]
g(x). g(y). g(z).
prolog> [user]
h(call(f, X)).
prolog> ?- h(X), X.
true .
X = call(f, x) ;
X = call(f, y) ;
X = call(f, z).

请注意,成功查询的变量的值会按行打印出来。未实例化的变量由一个带有下划线的数字表示(在上面的示例中为X = _0)。

动态操作符

rusty-wam支持动态操作符。使用具有通常优先级的内置算术运算符,

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

可以使用op声明来定义新操作符。

部分字符串

rusty-wam有两个专用的、非ISO内置谓词来处理所谓的“部分字符串”。部分字符串模仿字符的差分列表,但空间效率更高。这种效率是以完全通用性为代价的--你不能统一两个不同的部分字符串的尾部变量,因为它们的缓冲区始终是不同的。

如果X是一个自由变量,则查询

?- partial_string("abc",X),X= [a,b,c|Y], is_partial_string(X), is_partial_string(Y).

将成功。进一步地,如果Y是一个自由变量,统一Y与另一个字符串(在这种情况下为“def”),会产生以下等式

X= [a,b,c,d,e,f],Y= [d,e,f].

模块

rusty-wam有一个基于谓词的简单模块系统。它提供了一种将代码单元分离到不同的命名空间的方法,无论是谓词还是操作符。请参阅文件src/prolog/lib/*.pl中的示例。

在撰写本文时,几个控制和列表处理操作符和谓词被隐藏在其自己的模块中,这些模块尚未导出到顶层。要导出它们,请编写

prolog> :- use_module(library(lists)).
prolog> :- use_module(library(control)).

用户提示也可以用于在REPL中内联定义模块

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

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

use_module指令可以通过添加导入列表进行限定

prolog> :- use_module(library(lists), [member/2]).

可以通过调用它并带有空导入列表来使用限定use_module以从顶层移除导入

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

prolog> ?- lists:member(X, Xs).

依赖关系

~4.5MB
~76K SLoC