为SICStus制作/ 0功能

时间:2016-01-01 18:44:26

标签: module prolog sicstus-prolog

如何确保所有模块(理想情况下还包括已加载或包含的所有其他文件)都是最新的?发出mymodule.pl时,SICStus会比较文件include的修改日期并重新加载,如果更新的话。此外,mymodule - ed文件将触发重新编译。但它不会重新检查make/0使用的所有模块。

简介,如何获得与SWI提供的def zipMerge(*lists): dicts = map(dict, lists) base = { } items = 0 for d in dicts: items += 1 for k,v in d.iteritems(): if k not in base: base[k] = [k] + [None] * len(lists) base[k][items] = v return map(tuple, sorted(base.itervalues())) 相似的功能?

2 个答案:

答案 0 :(得分:5)

SICStus Prolog中没有提供这种功能。

一个很大的问题是,除了非常简单的情况之外,当前的Prolog对于像make / 0这样的东西来说太过动态了。通过术语扩展,加载期间执行的目标(包括常见的文件加载目标)等功能,无法知道如何可靠地重新加载文件。我没有密切关注它,但可能在SWI Prolog中使得/ 0有同样的问题。

我通常只是重新启动Prolog进程并再次加载“main”文件,即加载我需要的所有内容的文件。

PS。我无法在评论中获得代码格式,所以我把它放在这里:为什么make / 0需要防范'user'作为来自current_module / 2的文件:

| ?- [user].
% compiling user...
| :- module(m,[p/0]). p. end_of_file.

%  module m imported into user
% compiled user in module m, 0 msec 752 bytes
yes
| ?- current_module(M, F), F==user.
F = user,
M = m ? ;
no
| ?-

答案 1 :(得分:3)

到目前为止,我和几个黑客一起生活过:

高达0.7 - 模块前时间

SICStus始终拥有Quintus原点的ensure_loaded/1,它不仅是指令(如ISO),而且也是一个命令。所以我编写了自己的make-predicate,简单地枚举了所有文件:

l :-
   ensure_loaded([f1,f2,f3]).

发出l.后,只会重新加载同时修改过的那些文件。

也许,我本来也可以这样写 - 我会读懂平均值(原文如此):

l :-
   \+ ( source_file(F), \+ ensure_loaded(F) ).

3.0 - 模块

随着模块的改变,事情发生了变化。一方面,有些文件被手动加载到模块中,如ensure_loaded(module:[f1,f2,f3]),然后是那些干净的模块。事实证明,有一种方法可以全局确保加载模块 - 只需通过声明use_module(m1, [])再次作为指令和命令来干扰实际的导入列表。重点是空列表导致模块被重新检查并重新加载,但由于空列表,该语句可以在任何地方进行。

与此同时,我使用以下模块:

:- module(make,[make/0]).

make :-
   \+ ( current_module(_, F), \+ use_module(F, []) ).

这适用于所有" legal"模块 - 只要接口不变。我仍然不喜欢的是它的冗长:对于每个选中的和未修改的模块,都有一条消息行。所以当我只是想检查一切是否是最新的时候,我得到一个充满了这样的消息的页面。理想情况下,此类消息只会显示是否有新事件发生。

| ?- make.
% module m2 imported into make
% module m1 imported into make
% module SU_messages imported into make
yes
| ?- make.
% module m2 imported into make
% module m1 imported into make
% module SU_messages imported into make
yes

improved version考虑​​了@ PerMildner的评论。

如果它们只与一个模块相关,则可以重新加载其他文件。特别是,加载到模块user中的文件包含在.sicstusrc中。请参阅上面的链接以获取完整代码。

   % reload files that are implicitly modules, but that are still simple to reload
    \+ (
            source_file(F),
            F \== user,
            \+ current_module(_, F),  % not officially declared as a module
            setof(M,
                P^ExF^ExM^(
                    source_file(M:P,F),
                    \+ current_module(M,ExF), % not part of an official module
                    \+ predicate_property(M:P,multifile),
                    \+ predicate_property(M:P,imported_from(ExM))
                    ),[M]),   % only one module per file, others are too complex
            \+ ensure_loaded(M:F)
    ).

请注意,在SWI中,ensure_loaded/1use_module/2都不比较文件修改日期。因此,两者都不能用于确保加载最新版本的文件。