为一组约束生成令人满意的值列表

时间:2010-08-31 16:13:13

标签: prolog

给定一组约束,我想有效地生成一组值。

假设我对我的Thungus有一些限制[1]:

goodThungus(X) :-
               X > 100,
               X < 1000.
               sin(X) = 0.

现在,我可以通过询问检查 Thungus。

goodThungus(500).

我想生成所有好的Thungi 。我不知道该怎么做;我真的不确定如何有效地做到这一点。

注意:这当然必须是可计算的一代。

[1]为此示例选择了任意对象。

3 个答案:

答案 0 :(得分:1)

在完整的一般情况下无法完成您的要求:想象做f(X)= 0其中f是例如根不能被分析确定的函数。或者假设f(X)是“程序X停止吗?”的功能。没有电脑可以解决这个问题。

您的选择基本上是:

  • 将约束集限制为可以推理的内容。例如不平等是好的,因为你可以识别范围,然后在范围内有效地进行交叉和联合等。

  • 将值集限制为足够小的数字,您可以针对每个约束单独测试它们

更新:对于问题中所述的约束类型(可以通过解析求解并且在任何范围内具有有限数量的解决方案的实值和实值函数的范围),我建议采用以下方法:

  • 编写一个生成函数,可以迭代地返回给定范围内的函数解决方案......这需要以分析方式完成,例如:利用sin(X)= 0的事实意味着X = n * pi,其中n是任何整数。
  • 执行interval arithmetic并限制范围约束以计算出需要扫描的范围(在示例中,您希望范围100
  • 将生成函数应用于每个目标范围,以创建所有可能的解决方案。

答案 1 :(得分:1)

我将通过声明我不是使用数字约束逻辑编程系统的专家来提出我的建议,但是这里......

从表面上看,我认为在PROLOG中解决这类问题最适合数字约束逻辑编程系统,也许,例如CLP(R)(对于实数)在SWI-PROLOG;不幸的是,你所要求的具体问题是寻求解决一系列约束,包括非线性约束,这在PROLOG实现中似乎没有得到很好或广泛支持;相反,它们似乎主要处理线性约束,并且通常对非线性约束(例如X = sin(Y))的支持有限。

参考SWI-PROLOG的CLP(R)库和以下示例程序:

:- use_module(library(clpr)).

report_xsq_zeros :-
    findall(X, {0 = (X * X) - 10}, Results),
    write_ln(Results).

report_sin_zeros :-
    findall(X, {0 = sin(X)}, Results),
    write_ln(Results).

现在,执行report_xsq_zeros会给我们:

 ?- report_xsq_zeros.
[3.16228, -3.16228]
true.

这里,系统正确地计算了二次x^2 - 10的零,它们确实大约是3.16228-3.16228,其中X的范围是无界的。但是,当我们执行report_sin_zeros时,我们会得到:

 ?- report_sin_zeros.
[0.0]
true.

我们看到系统只计算了函数sin(X)的单个零,即使X的范围确实也是无界限的。也许这是因为人们认识到这里有无数的解决方案(尽管我只是猜测......)。如果我们要编制您要求的内容:

report_sin_zeros :-
    findall(X, {X > 100, X < 1000, 0 = sin(X)}, Results),
    write_ln(Results).

我们没有得到任何结果,因为底层系统只计算sin(X)的单个零,如前所示(即,将X绑定到0.0,这超出了规定的范围):< / p>

 ?- report_sin_zeros.
[]
true.

我得出结论,我要么没有正确使用SWI-PL CLP(R)(我建议你自己调查),它不能解决你的具体问题(非线性)问题。其他CLP(R)实现可能与SWI-PROLOG CLP(R)的行为不同,但我没有安装它们因此我无法检查,但您可以尝试SICSTUS CLP(R)或其他人;语法看起来很相似。

答案 2 :(得分:0)

他正在搜索[100..1000]中的任何X以获得该罪(x)= 0.但这是一个纯粹的数学问题,并不适用于关系逻辑演绎/回溯。简单的Prolog不适合这个吗?