【问题标题】:Prolog CLP order of operations?Prolog CLP 的操作顺序?
【发布时间】:2016-04-08 19:39:55
【问题描述】:

您好,希望有人可以帮助我。我只是想知道我下面的代码是否足以建立一个 12 x 12 的矩阵,并且假设“约束(M)”调用了所有在规则中定义的正确约束,并标记每一行?目前它失败了,我已经追踪了我的约束,所以我知道它们都有效,但不知道是否是因为我在主要谓词之外调用它们?

matrix(M) :-
M = [R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
R1 = [A,B,C,D,E,F,G,H,I,J,K,L],
R2 = [A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2],
R3 = [A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3],
R4 = [A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4],
R5 = [A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5],
R6 = [A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6],
R7 = [A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7],
R8 = [A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8],
R9 = [A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9],
R10 = [A10,B10,C10,D10,E10,F10,G10,H10,I10,J10,K10,L10],
R11 = [A11,B11,C11,D11,E11,F11,G11,H11,I11,J11,K11,L11],
R12 = [A12,B12,C12,D12,E12,F12,G12,H12,I12,J12,K12,L12],

constrain(M),

labeling([],R1),
labeling([],R2),
labeling([],R3),
labeling([],R4),
labeling([],R5),
labeling([],R6),
labeling([],R7),
labeling([],R8),
labeling([],R9),
labeling([],R10),
labeling([],R11),
labeling([],R12).

【问题讨论】:

    标签: prolog clpfd


    【解决方案1】:

    您应该始终约束发布与实际搜索 (labeling/2)。

    原因很清楚:寻找具体解决方案通常会非常昂贵。另一方面,发布约束通常非常快。

    如果像您的情况一样,这两个部分混合不干净,如果出现意外问题(例如未终止),您无法轻易判断哪个部分负责。

    在您的情况下,您应该在主要谓词中改进的唯一一件事是在约束发布和搜索之间强制执行上述分离。

    导致意外失败的错误很可能包含在您未在此处发布的规则之一中。您可以通过系统地替换true 调用它们的目标来找出失败中涉及哪些规则。因此,无需跟踪:您可以通过这种方式以声明方式调试 CLP(FD) 程序。

    编辑:这里是关于发布限制和寻找具体解决方案之间的分离的更多信息。正如GUPU 中介绍的那样,我们将使用核心关系的概念,它具有以下属性:

    1. 按照惯例,它的名称以下划线结尾_
    2. 同样按照惯例,它的最后一个参数是需要标记的变量列表
    3. 发布 CLP(FD) 约束。这也称为(约束)建模部分或(约束)模型
    4. 使用labeling/2

    搜索部分通常由label/1labeling/2执行。

    假设您有一个混合这两个方面的谓词,例如在您当前的情况下:

    矩阵(M):- 约束保持(M), ... 将 M 与变量 Vs 联系起来 ... 标签(策略,Vs)

    显然,由于上述原因,labeling/2 的调用是我们要从该谓词中删除的部分。当然,正如您所观察到的,我们仍然希望以某种方式访问​​应该被标记的变量

    我们这样做如下:

    • 我们向核心关系引入一个新参数,以传递需要标记的有限域变量列表。

      李>
    • 按照惯例,我们通过在谓词名称后附加 下划线 (_) 来反映附加参数。

    所以,我们得到以下核心关系:

    矩阵_(M,Vs):- 约束保持(M), ... 将 M 与变量 Vs 联系起来 ...

    唯一缺少的部分(您还没有完成,但无论如何应该完成)是说明感兴趣对象之间的关系(在这种情况下:矩阵)和有限域变量。这是我留给你的一个简单练习的部分。提示:append/2.

    完成所有这些后,您可以通过将核心关系和labeling/2 组合在单个查询或谓词中来解决整个任务:

    ?- matrix_(M, Vs), labeling(Strategy, Vs).
    

    请注意,核心关系和搜索之间的这种分离:

    • 让尝试不同的标记策略变得非常容易无需重新编译您的程序
    • 允许您确定核心关系的重要程序属性无需搜索具体解决方案

    在判断有关 CLP(FD) 约束的任何文本的质量时,使用对这一重要分离的介绍和解释作为指标。

    【讨论】:

    • 谢谢 - 我知道将它们分开会更好,但我不确定如何将标签与域分开。我只被告知变量、约束和标签放在一个谓词中,虽然我了解矩阵/约束是如何工作的,但这是我第一次遇到标签,我发现库指令不是很有帮助!
    • 我添加了更多关于如何分离这些方面的信息。希望对您有所帮助!
    • 我从来没有遇到过“核心关系”这个词——这是你自己的术语还是来自文献?我通常将其称为(约束)模型
    • 我取自 Ulrich Neumerkel 的 Teaching Prolog and CLP 教程,该教程于 1997 年在鲁汶发表。在 GUPU 中,这称为 Kernrelation(德语)。
    • @mat,您引用的文档不包含该术语。无论如何,我认为在谈论应用程序问题的声明性(数学/逻辑)表示时,使用术语 模型 会更广泛地理解您,而不是 CLP 程序中所关注的那些部分与解决的操作方面。在约束规划的上下文中,core 的概念更好地保留给约束的某些子集(例如,“硬”子问题、没有冗余约束的“最小”子集等)。
    猜你喜欢
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    相关资源
    最近更新 更多