标签: clp

如何验证涉及dif/2约束的交换性?

围绕dif/2约束存在很多炒作,特别是作为对(\ =)/ 2和(\ ==)/ 2的一些非声明性的拯救.这种非声明性通常被描述为非单调性,并给出了非交际性的​​例子.

但是,测试涉及dif/2的测试用例是否可交换的方法是什么.以下是我想要做的元解释:

我进行了交换性测试,我想探究两种变体给出相同的结果:

?- A, B.
-- versus --
?- B, A.
Run Code Online (Sandbox Code Playgroud)

所以通常你可以用(==)/ 2内置谓词检查单调性,如果它归结为检查交换性.由于此谓词遵循实例化变量.

但是,如果您正在测试产生约束的情况,call_with_residue/2是不够的,您还需要具有相等的约束.这可能很棘手,如下例所示:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.23)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam

?- dif(f(X,X),f(a(U,g(T)),a(g(Z),U))), X=a(g(Z),U).
X = a(g(Z), U),
dif(f(a(g(Z), U), U, Z, U, T), f(a(U, g(T)), g(Z), T, g(Z), Z)).

?- X=a(g(Z),U), dif(f(X,X),f(a(U,g(T)),a(g(Z),U))).
X = a(g(Z), U),
dif(f(U, T), f(g(Z), Z)).
Run Code Online (Sandbox Code Playgroud)

任何想法如何进行?

免责声明,它是一个陷阱:
我不认可交换性测试作为一种好的测试方法,在这种方法中你可以将好的和坏的谓词与规范分开.因为通常好的和坏的谓词都可能没有交换性问题.

我正在使用交换性测试作为一种工具来找出有关dif/2约束相等的方法.然后,可以在更传统的测试用例中将此等式用作验证点.

prolog clp prolog-dif

7
推荐指数
1
解决办法
79
查看次数

SICStus Prolog中的Verify_attributes

属性变量允许扩展统一性。以下是有关界面的奥秘细节。让我们开始追逐吧!

atts提供了使用属性变量的谓词。我想我得到SICStus Prolog用户手册页上关于库(atts)的内容,除了以下内容之外verify_attributes(-Var, +Value, -Goals)

[...]在Var实际绑定到Value之前,调用verify_attributes / 3。如果失败,则认为统一失败。 它可能不确定地成功,在这种情况下,统一可能会倒退以给出另一个答案。在“目标”中,期望返回将Var绑定到“值”后要调用的目标列表。最后,在调用目标之后,将调用在Var上被阻止的所有目标。

上面的句子(由我突出显示)使我感到困惑-还有很多:)

我一直认为统一是可以执行以下任一操作的过程:

  • 成功使用最通用的统一符(模变量重命名)

  • 或失败。

但是一定会成功吗?

约束求解程序的实现者何时才能使用该“功能”?

我想不出一个用例...请帮助!


编辑

实际上,我认为(我的)求解器代码中的不确定性是一个错误,而不是功能。对于任何不确定性,可以通过在中返回一些析取值轻松地进行模拟Goals

prolog sicstus-prolog clp

5
推荐指数
0
解决办法
141
查看次数

将 Prolog & CLP(R) 用于约束系统

我希望使用 Prolog 生成满足约束系统的随机向量。

例如,我们的用户可能会在运行时向我们的软件提供以下信息:

给定一个向量<x1, x2, x3, ... x30>,我们可能有两个约束:

x1 > x2 + x3 + x4
x5 <= sin(x6 + x7)
Run Code Online (Sandbox Code Playgroud)

我想做的是生成一个大致遵循以下形式的 Prolog 程序:

:- random(0.0, 1.0, X1)
:- random(0.0, 1.0, X2)
#...
# its also concievable that the bounds are different than 0 to 1
:- random(0.0, 1.0, X30)

clp(r) :- constraints { 
   X1 > X2 + X3 + X4,
   X5 <= sin(X6 + X7)   
}

?- [ X1, X2, X3, X4, ... X30 ]
Run Code Online (Sandbox Code Playgroud)

这将在 30 …

random constraints prolog clp clpr

5
推荐指数
1
解决办法
523
查看次数

SWI Prolog与GNU Prolog-SWI下的CLP(FD)问题

我在Prolog中写了一个快速谓词,尝试了CLP(FD)及其求解方程组的能力。

problem(A, B) :-
    A-B #= 320,
    A #= 21*B.
Run Code Online (Sandbox Code Playgroud)

当我在SWI中调用它时,我得到:

?- problem(A,B).
320+B#=A,
21*B#=A.
Run Code Online (Sandbox Code Playgroud)

而在GNU中,我得到以下正确答案:

| ?- problem(A,B).

A = 336
B = 16
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?理想情况下,我希望在SWI中获得正确的结果,因为它是一个更加健壮的环境。

prolog swi-prolog gnu-prolog clp clpfd

4
推荐指数
1
解决办法
1360
查看次数

使用 Prolog 在 CLP(R) 中编写递归函数的正确方法

我对 CLP 在 Prolog 中的工作方式感到非常困惑。我不仅发现很难看到好处(我确实在特定情况下看到了它,但发现很难概括这些好处),而且更重要的是,我几乎无法弥补如何正确编写递归谓词。以下哪一项是 CLP(R) 方式的正确形式?

factorial(0, 1).
factorial(N, F):- {
  N > 0,
  PrevN = N - 1,
  factorial(PrevN, NewF),
  F = N * NewF}.
Run Code Online (Sandbox Code Playgroud)

或者

factorial(0, 1).
factorial(N, F):- {
  N > 0,
  PrevN = N - 1,
  F = N * NewF},
  factorial(PrevN, NewF).
Run Code Online (Sandbox Code Playgroud)

换句话说,我不确定何时应该在约束之外编写代码。对我来说,第一种情况似乎更合乎逻辑,因为PrevN并且NewF属于约束条件。但如果这是真的,我很想知道在什么情况下在递归函数中使用约束之外的谓词是有用的。

recursion prolog clp clpr

4
推荐指数
1
解决办法
483
查看次数

Prolog(CLP)的可变装箱问题

我正在尝试使用约束逻辑编程 (CLP) 在 (Swi-) Prolog 中找到 NP-hard 2D Variable Size Bin Packing Problem (2DVSBPP) 的算法。

问题可以这样解释:一些订购的产品需要尽可能有效地包装到一些盒子(箱)中。产品有一些给定的宽度和长度(正方形或矩形,例如 2x3)。有四种不同尺寸的箱子,每种箱子都有给托运人的特定成本(例如,5x5 箱子 4 美元,5x7 箱子 5 美元)。目标是最小化盒子的总成本

一段时间以来,我一直在寻找这个问题的答案,并阅读了许多其他语言的论文和类似示例。但是,我找不到任何可行的解决方案。我特别纠结于如何处理未知数量的 Boxes (bins)


为了能够找到这个问题的解决方案,我试图适应一个类似的问题,但真的不知道如何处理可变数量的盒子。下面的代码可以选择最便宜的盒子来装所有的产品,只要只需要一个盒子就可以装所有的产品。从我们需要多个盒子的那一刻起,程序就失败了。

盒子和产品:

:- use_module(library(clpfd)).
:- use_module(library(clpr)).
:- expects_dialect(sicstus).


%% These are the possible productsizes that could need packing
% product (id, width, length)
product(1, 2, 2). 
product(2, 1, 2). 
product(2, 2, 1). % repeating product n2 because it can lay horizontal or …
Run Code Online (Sandbox Code Playgroud)

prolog swi-prolog clp clpfd

4
推荐指数
1
解决办法
468
查看次数

用于F#的LP DSL,其中Clp作为解算器

由于Microsoft Solver Foundation已被弃用,我试图找到一种替代或合理的方法来创建自己的DSL.

我正在寻找的是在F#中描述LP的DSL必不可少的,用Clp解决它并评估结果.

在重新发明轮子之前:有人知道一个已经为LP提供DSL的好库吗?

否则,你将如何在F#中构建这样的DSL?从本质上讲,我希望能够写出类似的东西

let xs = createVars 100 in 0..1
let ys = [| 1 .. 100 |]
let f i x = i*x
let lp = 
    minimize sumprod(xs, ys) subjectTo [
      xs.[0] + xs.[1] = 1
      sum(xs) <= 1
      sum({for i in 1..100 -> f i xs.[i]}) <= 100
      // ...
    ]
let solver = Clp()
let result = solver.solve lp
Run Code Online (Sandbox Code Playgroud)

clr dsl f# linear-programming clp

2
推荐指数
1
解决办法
326
查看次数