获得谓词解析的顺序

ri5*_*5b6 5 prolog clpfd

看看以下目标(我使用来自Markus Triska的clpfd的swi-prolog):

result(Input,Result) :-
    Input #> 10,
    Result=decline.
result(Input,Result) :-
    Input in 0..20,
    Result=offer.
Run Code Online (Sandbox Code Playgroud)

可能的查询如下所示:

?- result(15,B).
B = decline ;
B = offer.
Run Code Online (Sandbox Code Playgroud)

我想添加订单或某种解决方案优先级.如果"拒绝"是有效的响应Input=15,则不应再考虑第二个目标,因此只有B=decline解决方案而不是B=offer.

我知道我可以添加一个!/0然后反过来也行不通.给我这个谓词的所有可能答案.

考虑到这个例子,a Result=offer应该只适用于Input 0..10,否则应该触发较高的先前下降目标.

当我尝试在谓词中考虑订单时,我是否认为太迫切了?

fal*_*lse 6

这里有几个问题,让我们先从最明显的开始:

建模问题

你有关系(result/2是也许不是最好的名字),并且这种关系应该模型时decline,当offer应该是真实的.在阅读你的课程之前,我更喜欢问Prolog:

?- result(X, decline), result(X, offer).
X in 11..20 ;
false.

因此,对于从11到20的值,您的关系是模糊的.如果您想做出决定,请先修复此关系.实际上,我会先说

  • 关系的更好名称,表明它是一种关系
  • 没有必要的措辞(比如Input或命令)
  • 更紧凑的配方,您(=)/2的程序中不需要这么多目标.相反,你可以这样写:
heigth_decision(I, decline) :-
   I #< 10.

CLP中的答案和成功与解决方案

然后还有另一个更基本的问题.这实际上要严重得多,因为到目前为止给出的所有SO答案完全忽略了这一方面.它是关于答案和成功的概念,另一方面是解决方案的概念.

当您在Prolog中询问查询时 - 您得到的是一个答案.这样的答案可能包含解决方案,例如L = [_,_]包含无限多解决方案的答案.或者答案可能只包含一个解决方案Decision = decline.但是如果你使用像这样的约束,那么还有更多library(clpfd).

您现在可以获得有限的许多解决方案:

?- abs(X) #< 3.
X in -2..2.

或无限多:

?- X #> Y.
Y#=<X+ -1.

但是你也可以得到一个解决方案,它看起来不像一个:

?- 2^X #= 1.
2^X#=1.

所以,重申一下:我们在整数中只有一个解决方案,但对于Prolog来说,这太复杂了.我们得到的答案是:答案是:是的,这一切都是真的,只要这一切都是真实的.

更糟糕的是,有时我们会得到不包含任何解决方案的答案.

?- X^X#=0.
X^X#=0.

如果Prolog足够聪明,它会回答false.但它并不总是那么聪明,仅仅因为你可以很容易地制定不可判定的问题.这样的答案有时被称为不一致.德国概念Scheinlösung (假的解决方案,但具有较少的负面含义)传达了这个想法更好.

所以答案可能包含解决方案,但有些答案根本不包含解决方案.因此,目标的成功不能视为解决方案的存在!也就是说,所有SO-answers建议某种提交为(;)/ 2 - if-then-else,一次/ 1或!/ 0都是不正确的,如果他们将成功作为解决方案.要看到这一点,请尝试使用:

?- X^X#=0, result(X,decline).
X in 11..sup,
X^X#=0 ;
false.

?- X^X#=0, result(X,offer).
X in 0..20,
X^X#=0.

那你怎么能确定什么呢?

  • 你可以依靠目标的失败.

  • 你可以尝试labeling/2,但这只适用于有限域.

  • 您可以使用call_residue_vars/2copy_term/3确定是否存在"闲置"的约束

  • 不幸的是,你不能完全依赖于SWI的顶层,它隐藏了与答案中的变量无关的约束.只有SICStus才能正确显示它们.

  • 哇,再次感谢你为我提供了这么多背景资料.我真的很感激,你在这里完全理解我的问题.成功在这里确实并不总是一个解决方案. (2认同)