是否有Prolog的包管理器?

时间:2014-04-08 19:11:51

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

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

为了比较,Java有Maven + JAR,Python有EasyInstall + PythonEggs,其他语言也可能有很多其他语言。但Prolog有没有?

SWI-Prolog Packs

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

  1. 您必须为每个包创建存档文件或Git存储库。说我想创建10包。现在我需要创建10个Git存储库。我有时会进行编辑,影响多个文件,可能存在于多个包/ repos中,要求我为单个(多文件)编辑提交几个Git存储库。
  2. 为了创建一个包,您必须亲自挑选一些属于一起的文件。有时候我发现文件X属于包A和包B.现在我需要在存储库A和B中维护文件X的副本,或者我需要创建另一个包C只包含X和导入C到A和B.
  3. 包在公共网站上发布。我的大部分图书馆对我来说都很有趣。其中一些对我与之合作的特定人员很有意思,只有少数人准备好了#39;更广泛/公开传播。
  4. 包维护者必须指定包间依赖关系。对于复杂的图书馆等级,对我来说似乎是不必要的工作。我已经非常严格地使用Prolog模块,并且只想使用Prolog模块导入的层次结构作为依赖图。
  5. Git子模块

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

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

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

      1. 您传播的图书馆数量和您拥有的Git存储库数量是独立的。具体来说,我可以有一个相当大的存储库,其中的一部分以不同的方式传播。如果有人喜欢(重新)使用我的Prolog模块和DCG帮助器谓词,那么我可以简单地将该单个文件(以及潜在的依赖关系)传播给该人。
      2. 您不必亲自挑选和手动复制单个文件,而是让算法遍历模块导入的层次结构以提取那些(显然)属于一起的文件。首次运行程序时会下载文件。这些文件可能都属于同一个Git存储库,也可能属于多个存储库,算法根本不关心存储库和库之间或存储库和文件之间的映射。
      3. 代码的维护者能够决定一个库是公开发布还是发布给有限的一组人(或者只限于包括维护者在内的有限组)。
      4. 文件之间的模块导入层次结构是依赖关系跟踪所需的全部内容。
      5. 以上暗示我理想的图书馆共享方法是基于文件的,而不是基于包的。如果Prolog模块A使用Prolog模块B并且加载了A,则从本地文件(如果存在)加载B或从存储库下载B.我不确定基于文件的方法在其他语言中有多常见。前面提到的Maven + JAR和EasyInstall + PythonEggs都是基于包的。

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

2 个答案:

答案 0 :(得分:2)

我想这么简单的遍历算法可以给你 一组模块,如果您已经注释过 那些属于包和那些模块的模块 哪个还不属于包裹。它会屈服 尚未属于a的模块的子集 封装

但我觉得这忽略了这一点。一世 认为软件包的软件工程有所不同 目标不仅仅是提供一个包裹。通常一个 面临着多个包和这些包 可以具有以依赖为根的依赖项 模块本身。

在数学上:

   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,可以在确定时遗漏 包依赖关系和包版本控制。

到目前为止我的想法:

  • 从模块中获取包依赖项
  • 从模块中导出软件包版本控制
  • 允许包内的私有和公共模块。

再见

答案 1 :(得分:2)

关于Swi-prolog包:

  1. 我将包看作是Prolog模块的集合。单个模块应仅属于单个软件包,而不属于软件包A和B.
  2. 如果文件X想要属于软件包A和软件包B,那么它实际上应属于软件包C,它是A和B的依赖关系。
  3. 您现在可以拥有私有软件包,只需要非常小心,不要在安装过程中自动发布它们。这确实需要改进。欢迎补丁:)
  4. 我认为显式依赖是唯一理智的解决方案。 pack.pl中已经需要/ 1。需要一些工作来指定版本范围。
  5. Imho,当前规范/实现的最大问题是它没有强制进行语义版本控制。有些软件包明确声明它们使用它,有些软件包使用它但不指出它。语义版本控制如果受到包维护者的尊重,将使版本更容易识别检测/解析。另一个问题是Swi包适用于Swi,并且让其他Prologs处于寒冷状态。

    我希望包装规格/实施尽可能简单且无魔法。有足够的Prolog&#34; AI这个&#34;和#34;人工智能&#34;代码已经。另一个包管理器可以在这些之上实现,并作为包发布:)。