Prolog CLP 的操作顺序?

Prolog CLP order of operations?

您好,希望有人能帮助我。我只是想知道我下面的代码是否足以设置 12 x 12 的矩阵,并且假设 'constrain(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).

您应该始终将约束post与实际搜索 (labeling/2) 分开

原因很明显:寻找具体解决方案的成本通常非常高。另一方面,发布约束通常非常快。

如果像您的情况一样,这两个部分混在一起不干净,如果出现未终止等意外问题,您将无法轻易分辨出哪个部分负责。

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

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

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

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

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

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

matrix(M) :-
        constraints_hold(M),
        ... relate M to variables Vs ...
        labeling(Strategy, Vs).

显然,由于上面解释的原因,labeling/2的调用是我们要从这个谓词中移除的部分。当然,如您所见,我们仍然希望以某种方式访问​​应该被标记的 变量

我们这样做如下:

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

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

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

matrix_(M, Vs) :-
        constraints_hold(M),
        ... relate M to variables Vs ...

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

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

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

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

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

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