5

如何添加一个函数(例如,hammingweight)并在右侧出现的表达式中使用它是一些(is)/2目标?

像goal_expansion 或term_expansion 这样的东西在这里有帮助吗?

我承认这不是一个大特性,但它可以增加我的一些 Prolog 程序的可读性。

编写自定义(is)/2谓词(实现自定义表达式求值器)是可行的,但我希望将运行时开销保持在较低水平,因为在这种情况下我不想牺牲运行时开销的可读性。

4

4 回答 4

3

ISO Prolog 中没有这样的规定,既不扩展(is)/2也不依赖目标扩展。并且,查看某些实现为此提供的各种实现特定功能,没有普遍同意的方法来做到这一点。所以实施你自己的(my_is)/2似乎是最好的方法。

另请注意,这不仅会影响(is)/2所有其他使用可评估函子的内置函数。特别是,所有算术比较内置函数(8.7 算术比较)(请参阅此概述)都会受到影响。

于 2015-03-04T13:19:51.933 回答
2

我头脑简单(~20 LOC)的语法糖,lifter,它基于goal_expansion。

带升降机,从句

longer(A,B) :-
    length(A,º) > length(B,º).

扩展为

longer(A, B) :-
    length(A, C),
    length(B, D),
    C > D.
于 2015-03-04T14:36:20.890 回答
1

您可以使用 Logtalk 的术语扩展机制,该机制是可移植的,可与十二个受支持的 Prolog 编译器 (*) 一起使用。Logtalk 编译加载和加载谓词接受 Prolog 文件,并会输出对应的 Prolog 扩展文件。例如,假设您要扩展的文件已命名source.pl,并且您的term_expansion/2goal_expansion/2谓词定义位于名为 的文件中expansions.pl,您可以执行以下操作:

% first, load the expansion hooks:
| ?- [expansions].
...

% second, expand a file using those hooks:
| ?- logtalk_compile(source, [hook(user)]).
...

您将获得扩展文件,该文件将(默认情况下)命名source_pl.pl(在取决于scratch_directoryLogtalk 标志值的目录中)。如果扩展包含在 Prolog 模块中,请在模块名称上方使用,而不是user. 如果source.pl文件包含模块而不是普通的 Prolog 代码,则需要为term_expansion/2谓词定义一些子句以避免 Logtalk 将模块编译为对象。但是在不使用模块的更简单的情况下,上面的两个查询就足够了。

Logtalk 的术语扩展机制的一个可能有用的特性是,您可以通过将术语或目标与{}/1控制结构包装起来,将其标记为不扩展或进一步扩展。

(*) 请注意,术语扩展机制不是标准的,并非所有 Prolog 实现都提供,并且实现之间存在显着差异。

于 2015-03-04T14:04:54.527 回答
-1

许多 Prolog 系统不允许用户定义的可评估谓词。有时问题是可评估谓词存在于另一个命名空间中。有时,Prolog 系统在使用宿主语言进行算术评估时会回避跳回 Prolog 执行。

然而,一些 Prolog 系统具有用户定义的可评估谓词,例如 ECLiPSe Prolog 和 Jekejeke Prolog。在 Jekejeke Prolog 中,开销是两倍。令我惊讶的是,在新的 Dogelog 运行时用户可定义的可评估谓词显示了一个优势:

/* Dogelog Runtime 0.9.5 */
fact(0, 1) :- !.
fact(N, X) :- M is N-1, fact(M, Y), X is Y*N.

fact2(0, 1) :- !.
fact2(N, X) :- X is fact2(N-1)*N.

for(_).
for(N) :- N > 1, M is N - 1, for(M).

% ?- time((for(1000), fact(1000, _), fail; true)).
% % Wall 1595 ms, trim 0 ms

% ?- time((for(1000), _ is fact2(1000), fail; true)).
% % Wall 1394 ms, trim 0 ms

我将轻微的速度优势归因于事实上更简洁的公式 2/2。该公式使用较少的 Prolog 逻辑变量。并且用户定义的可评估谓词在(is)/2内部也没有 Prolog 逻辑变量,发生的宿主语言分配不分配

一个 Prolog 逻辑变量或 trail 相同,这样最后就有了加速。

于 2021-09-05T23:39:24.473 回答