系统限制

内存区域限制

SWI-Prolog 引擎使用三种栈。局部栈(local stack,也称环境栈 environment stack)保存用于调用谓词的环境帧以及选择点。全局栈(global stack,也称堆 heap)包含项、浮点数、字符串和大整数。最后,轨迹栈(trail stack)记录变量绑定和赋值,以支持回溯(backtracking)。除可用内存外,栈大小没有硬限制。9.3.6 以前的旧版本在 32 位硬件上每个栈有 128Mb 的硬限制。

组合后的栈大小(按线程计)有一个软限制,由可写标志 stack_limit 或命令行选项 --stack-limit 实现。目前默认限制是 1Gb。考虑到可移植性,需要修改默认限制的应用建议使用 Prolog 标志 stack_limit

区域名称描述
局部栈局部栈用于存储过程调用的执行环境。环境占用的空间会在以下情况下回收:该环境失败;退出时没有留下选择点;备选分支被 !/0 谓词剪切;或自调用以来没有创建选择点并且最后一个子子句开始执行(最后调用优化)。
全局栈全局栈用于存储 Prolog 执行期间创建的项、字符串、大整数、有理数和浮点数。该栈上的数据会在回溯到数据创建之前的某个点时回收,或在数据不再被引用时由垃圾收集回收。
轨迹栈轨迹栈用于存储执行期间的赋值。该栈上的条目会一直存活,直到回溯到创建点之前,或垃圾收集器判定它们不再需要。由于轨迹栈和全局栈一起进行垃圾收集,过小的轨迹栈可能导致过多垃圾收集。为避免这种情况,轨迹栈会自动调整大小,使其至少达到全局栈大小的六分之一。

这里所说的堆,是指 malloc() 及相关函数使用的内存区域。SWI-Prolog 使用这一区域存储原子、函子、谓词及其子句、记录和其他动态数据。对 malloc() 及相关函数返回的地址不施加限制。

其他限制

  • 子句

    子句唯一的限制是元数(头部参数数量),目前限制为 1024。提高这个限制很容易,而且代价相对较低;移除该限制则更困难。

  • 原子和字符串

    SWI-Prolog 对原子或字符串长度没有限制。原子数量没有限制。原子受垃圾收集管理。见原子垃圾收集相关章节。原子和字符串都可以表示所有 Unicode 码点,包括 0(\u0000)。目前,SWI-Prolog 对 ISO Latin-1 文本(码点 0..255)和包含更高码点的文本使用不同表示。后者使用 C 的 wchar_t 类型表示。在大多数系统上,这意味着 UCS-4,也就是 32 位无符号整数。在 Windows 上,wchar_t 使用 UTF-16,这意味着它不能把为代理对保留的码点表示为单个码点。未来版本可能会切换为全程使用 UTF-8。

  • 项的嵌套

    大多数处理 Prolog 项的内置谓词都会创建一个显式管理的栈,并针对处理项的最后一个参数进行优化。这意味着它们可以在 C 栈使用量恒定且较低的情况下处理深度嵌套的项;如果无法再分配栈,系统会抛出资源错误。目前只有 read/1write/1(以及它们的所有变体)仍使用 C 栈,可能导致系统以不受控方式崩溃,也就是不会映射为可捕获的 Prolog 异常。

  • 整数

    SWI-Prolog 有两种整数表示。有标签整数(tagged integers)目前限制为 57 位。9.3.6 以前,32 位系统上的有标签整数为 25 位,并且还有第三种 64 位整数表示。无界整数默认由 GNU GMP 库提供。也可以由随附的 LibBf 库提供。系统也可以构建为不支持无界整数。

  • 浮点数

    浮点数表示为 C 原生双精度浮点数,在大多数机器上是 64 位 IEEE。

保留名称

引导编译器(见 -b 选项)不支持模块系统。由于系统的大部分内容本身就是用 Prolog 编写的,我们需要某种方式避免与用户的谓词、数据库键等发生名称冲突。与 Edinburgh C-Prolog 一样,所有应对用户隐藏的谓词、数据库键等,都以美元符号($)开头。