Wou*_*eek 9 module package-managers prolog swi-prolog git-submodules
我想知道与其他程序员共享Prolog代码/库的最佳实践(以及多个项目之间的自己).我自己也在使用SWI-Prolog,但也对其他Prolog如何解决这个问题感兴趣.
相比之下,Java有Maven + JAR,Python有EasyInstall + PythonEggs,其他语言可能还有很多其他语言.但Prolog还有吗?
在SWI-Prolog中有Packs,由模块支持library(prolog_pack).这些的缺点是:
另一种我直到现在使用过的方法是Git子模块.通过将一个存储库导入另一个存储库来实现库之间的依赖关系.这与SWI-Prolog包有一些相同的缺点:
我个人对完美的Prolog代码共享方法的偏好是:
以上暗示我理想的库共享方法是基于文件的,而不是基于包的.如果Prolog模块A使用Prolog模块B并且加载了A,则从本地文件(如果存在)加载B或从存储库下载B. 我不确定基于文件的方法在其他语言中有多常见.前面提到的Maven + JAR和EasyInstall + PythonEggs都是基于包的.
我对其他Prolog程序员使用和思考这个主题非常感兴趣!
小智 2
我想这样一个简单的遍历算法可以给你一个模块的集合,如果你已经注释了那些属于包的模块和那些不属于包的模块。它将产生尚不属于包的模块子集。
但我有一种感觉,这没有抓住重点。我认为软件包的软件工程与简单地交付一个软件包有着不同的目标。通常,一个人会面对多个包,并且这些包可能具有依赖关系,这些依赖关系植根于模块本身的依赖关系。
数学上:
M: The set of modules
P: The set of packages
p(m): The package a module belongs to or null.
Run Code Online (Sandbox Code Playgroud)
因此,如果我有模块依赖项,我可以从中派生包依赖项:
d(m1,m2): The module m1 depends on the module m2
d'(p1,p2): The package p1 depends on the package p2
d'(p1,p2) <=> exists m1,m2 (p(m1)=p1 & p(m2)=p2 & d(m1,m2))
Run Code Online (Sandbox Code Playgroud)
您的算法可能会派生一个包 p,然后它可能依赖于一些已用于注释现有模块的包 p1, .., pm。但是软件工程已经找到了很多识别多个包的方法,典型的架构是垂直分层、水平分层等。也许也有相应的算法。
但事情并没有那么简单。包通常被定义为帮助模块的共同演化并促进变更管理和发布管理。如果模块共同进化,则不希望一个接一个地释放模块。想要发布一组达到相同进化级别的模块,让这组模块能够卓有成效地交互。
但如果我们有模块的演变,我们也会有包的演变。如果您只有一个软件包,或者您更多地使用多个软件包来存储您的东西,这种演变就会发生。我不确定 Prologs 的现有软件包系统是否已经在这里提供帮助。我所看到的 SWI-Prolog 是包的版本控制和包的待办事项列表:
http://www.swi-prolog.org/howto/PackTodo.txt
上述待办事项都很有意义。但它们并没有直接解决包依赖性及其演变。在 Jekejeke Prolog 中,我目前正在尝试改进模块依赖性。例如,最终用户可以通过以下命令加载模块 clpfd:
?- use_module(library(clpfd)).
Run Code Online (Sandbox Code Playgroud)
如果安装并激活了包含模块 clpfd 的软件包,则该命令将成功。如果未安装此类软件包或安装了软件包但尚未激活,则该命令将失败。主包和模块 clpfd 将使用其他模块和包。如果它使用其自己的包本地的模块,则可以按如下方式执行,不需要library/1:
?- use_module(helper).
Run Code Online (Sandbox Code Playgroud)
但是,如果它使用的模块不是其自己的包的本地模块,那么它通常会采取不同的做法。例如,模块 clpfd 可能使用模块 apply。它将对 Library/1 执行此操作:
?- use_module(library(apply)).
Run Code Online (Sandbox Code Playgroud)
现在我们认识到,通过检查 clpfd 或辅助模块,我们无法知道它何时从何处获取 apply 模块执行上述操作。只有当我们手头有一组特定的包并且我们解析适用于其包的模块名称时,我们才知道包依赖关系。
这种灵活性有其优点和缺点。缺点是我们无法建立固定的包依赖关系。并且依赖于固定包依赖项的版本控制等工具将无法工作。因此,解决方案是从模块的版本控制引导包的版本控制,类似于我们如何从模块的依赖关系导出包之间的依赖关系。
但我还不确定这将如何运作。如果我们能够区分公共模块和私有模块,那么复杂度肯定会降低。例如,上面的模块助手可以仅由 clpfd 使用,并且在确定包依赖项和包版本控制时可以省略。
到目前为止我的想法:
再见