【问题标题】:Is there a package manager for Prolog?Prolog 有包管理器吗?
【发布时间】:2014-05-21 16:30:29
【问题描述】:

我想知道与其他程序员(以及与自己在多个项目之间)共享 Prolog 代码/库的最佳实践是什么。我自己也在使用 SWI-Prolog,但也对其他 Prolog 如何解决这个问题感兴趣。

相比之下,Java 有 Maven+JAR,Python 有 EasyInstall+PythonEggs,其他语言可能还有很多其他语言。但是 Prolog 有吗?

SWI-Prolog 包

在 SWI-Prolog 中有包,由模块 library(prolog_pack) 支持。这些的缺点是:

  1. 您必须为每个包创建存档文件或 Git 存储库。假设我想创建 10 个包。现在我需要创建 10 个 Git 存储库。我有时会进行影响多个文件的编辑,这些文件可能驻留在多个包/存储库中,需要我提交多个 Git 存储库以进行单个(多文件)编辑。
  2. 为了创建一个包,您必须手动挑选一些“属于一起”的文件。有时我发现文件 X 既属于包 A 又属于包 B。现在我需要在存储库 A 和 B 中维护文件 X 的副本,或者我需要创建另一个只包含 X 的包 C 并将 C 导入A 和 B。
  3. 包在公共网站上发布。我的大部分图书馆只对我感兴趣。其中有一些对我合作过的特定人员很感兴趣,只有少数“准备好”进行更广泛/公开的传播。
  4. 包维护者必须指定包间的依赖关系。对于复杂的库层次结构,这对我来说似乎是不必要的工作。我已经非常严格地使用 Prolog 模块,并且想简单地使用 Prolog 模块导入的层次结构作为依赖图。

Git 子模块

到目前为止,我一直使用的另一种方法是 Git 子模块。库之间的依赖关系是通过将一个存储库导入另一个存储库来实现的。这与 SWI-Prolog 包有一些相同的缺点:

  1. 每个库都有一个 Git 存储库,因此需要维护大量存储库。
  2. 维护者必须明智地选择每个 repo 的文件,并且必须指定需要包含哪些 Git 子模块。
  3. 更新现有库非常困难。我发现(艰难的方式)我交给我的代码的大多数人都无法成功地更新具有许多错综复杂的相互依赖的子模块导入的 Git 存储库。 (我非常尊重偶尔使用子模块并且总是做对的 Git 大师,但是大多数非程序员和与我一起工作的很多程序员都觉得这太难了。)

我的理想方法

我个人对完美 Prolog 代码共享方法的偏好是:

  1. 您传播的库的数量和您拥有的 Git 存储库的数量是独立的。具体来说,我可以拥有一个相当大的存储库,其中的一部分以不同的方式传播。如果有人喜欢(重新)将我的 Prolog 模块与 DCG 辅助谓词一起使用,那么我可以简单地将单个文件(以及潜在的依赖项)传播给那个人。
  2. 您不必手动选择和手动复制单个文件,而是让算法遍历模块导入的层次结构以提取那些(显然)属于一起的文件。第一次运行程序时会下载这些文件。这些文件可能都属于同一个 Git 存储库或多个,算法根本不应该关心存储库和库之间或存储库和文件之间的映射。
  3. 代码的维护者能够决定一个库是公开发布还是发布给有限的一群人(或只包括维护者的有限群体)。
  4. 文件之间的模块导入层次结构是依赖跟踪所需要的。

以上暗示我理想的库共享方法是基于文件而不是基于包的。如果 Prolog 模块 A 使用 Prolog 模块 B 并且加载了 A,则 B 要么从本地文件(如果存在)加载,要么从存储库下载。我不确定基于文件的方法在其他语言中有多普遍。前面提到的 Maven+JAR 和 EasyInstall+PythonEggs 都是基于包的。

我对其他 Prolog 程序员对此主题的使用和思考非常感兴趣!

【问题讨论】:

    标签: module prolog git-submodules swi-prolog package-managers


    【解决方案1】:

    我猜这么简单的遍历算法可以给你 一个模块的集合,如果你已经注释了 属于一个包的那些模块和那些模块 尚不属于一个包。它会产生 不属于某个模块的子集 包。

    但我觉得这没有抓住重点。一世 认为软件包的软件工程有不同的 目标不仅仅是交付一个包裹。通常一个 面临多个包和这些包 可以具有植根于依赖项的依赖项 模块本身。

    数学上:

       M: The set of modules
       P: The set of packages
       p(m): The package a module belongs to or null.
    

    所以如果我有模块依赖,我可以推导出 包依赖:

       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))
    

    您的算法可能会派生一个包 p,然后 可能取决于某些软件包 p1, .., pm 已用于注释现有模块。 但是软件工程已经找到了很多方法 识别多个包,典型架构 有纵向分层、横向分层等。 也许还有算法。

    但事情并没有那么简单。包裹通常是 定义为帮助模块的共同进化和 以促进变更管理和发布管理。 如果模块共同进化一个不想发布一个 一个接一个的模块。想发布一套 已经达到相同进化水平的模块,所以 这组模块可以进行富有成效的交互。

    但是,如果我们有模块的演变,我们也会 有包的演变。而这种演变将 如果你有一个包裹或者如果你去 更多与您的东西的多个包。和我 我不确定现有的包系统是否适用于 Prologs 已经在这里提供了帮助。我看到的 SWI-Prolog 例如是包的版本控制和待办事项 软件包列表:
    http://www.swi-prolog.org/howto/PackTodo.txt

    上述待办事项都很有意义。但他们不 直接解决包依赖及其 进化。在 Jekejeke Prolog 我目前 尝试改善模块依赖性。 例如,这个想法是最终用户可以 通过以下命令加载模块 clpfd:

       ?- use_module(library(clpfd)).
    

    如果安装并激活了具有 一个模块 clpfd 命令将成功。而如果 未安装此类软件包或已安装软件包 并且尚未激活该命令将失败。这 home 包分别是模块 clpfd 将使用的 其他模块和包。如果它使用 它可以做的本地模块 所以如下,不需要库/1:

       ?- use_module(helper).
    

    但是如果它使用的模块不是本地的 它自己的软件包通常会有所不同。 例如,一个模块 clpfd 可能使用一个模块 申请。它会通过 library/1 来实现:

       ?- use_module(library(apply)).
    

    现在我们认识到我们不会知道 通过检查 clpfd 或帮助模块,当 它执行上述操作 应用模块。我们只知道包依赖 当我们有一组特定的包时 手,当我们解析模块名称时应用 到它的包中。

    这种灵活性有利也有弊。缺点 是我们不能建立固定的包 依赖关系。以及用于版本控制的工具 等..依赖于固定的包依赖 不管用。所以一个解决方案是引导 来自模块版本控制的包版本控制, 类似于我们如何导出包之间的依赖关系 来自模块的依赖关系。

    但我还不确定这将如何工作。这 如果我们能够区分复杂性肯定可以降低 公共模块和私有模块之间。例如 上面的模块助手可以单独使用 由 clpfd 确定,在确定时可以省略 包依赖项和包版本控制。

    到目前为止我的想法:

    • 从模块派生包依赖项
    • 从模块派生软件包版本
    • 允许包中的私有和公共模块。

    再见

    【讨论】:

      【解决方案2】:

      关于 Swi-prolog 包:

      1. 我将包视为 Prolog 模块的集合。单个模块应仅属于单个包,而不应属于包 A 和 B。
      2. 如果文件 X 想要属于包 A 和包 B,那么它实际上应该属于包 C,即 A 和 B 的依赖项。
      3. 您现在可以拥有私有包,只是必须非常小心,不要在安装过程中自动发布它们。这确实需要改进。欢迎补丁:)
      4. 我认为显式依赖是唯一合理的解决方案。 pack.pl 中已经存在 requires/1。需要做一些工作来指定版本范围。

      恕我直言,当前包规范/实现的最大问题是它没有强制语义版本控制。有些软件包明确声明他们使用它,有些使用它但没有指出。如果包维护者尊重语义版本控制,将使版本冲突检测/解决变得更加容易。另一个问题是 Swi 包是为 Swi 准备的,而其他 Prologs 则冷落。

      我希望包规范/实现尽可能简单和无魔法。已经有足够多的 Prolog“AI this”和“AI that”代码了。可以在这些之上实现一个替代包管理器并作为一个包发布:)。

      【讨论】:

        猜你喜欢
        • 2015-02-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-14
        • 1970-01-01
        • 2014-10-13
        • 2013-04-20
        • 2011-01-27
        • 2015-02-01
        相关资源
        最近更新 更多