让订单进入谓词解析 [英] Getting an order into predicate resolution

查看:15
本文介绍了让订单进入谓词解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看以下目标(我正在使用 swi-prolog 和 Markus Triska 的 clpfd):

result(Input,Result) :-输入#>10,结果=拒绝.结果(输入,结果):-输入 0..20,结果=报价.

可能的查询如下所示:

?- 结果(15,B).B = 下降;B = 报价.

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

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

考虑到这个例子,Result=offer 应该只对 Input 0..10 为真,否则应该触发更高的先前下降目标.

当我尝试考虑谓词中的顺序时,我是否认为过于迫切?

解决方案

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

建模问题

你有一个关系(result/2 可能不是最好的名字),并且这个关系应该在 declineoffer 应该是真的.在阅读你的程序之前,我更喜欢问 Prolog:

<上一页>?- 结果(X,拒绝),结果(X,报价).X 在 11..20 ;错误的.

因此,对于从 11 到 20 的值,您的关系是不明确的.如果您要做出决定,请先修复此关系.其实,我会从

  • 一个更好的关系名称,表明它是一个关系
  • 没有命令式措辞(如 Input 或命令式)
  • 一个更紧凑的公式,您的程序中不需要那么多 (=)/2 目标.相反,你可以这样写:
<上一页>heigth_decision(我,拒绝):-我#<10.

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

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

当您在 Prolog 中提出查询时 - 您得到的是一个答案.这样的答案可能包含解决方案,例如答案 L = [_,_] 包含无限多的解决方案.或者一个答案可能只包含一个解决方案,如 Decision = 拒绝.但是,如果您使用 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、once/1 或 !/0 都是不正确的,如果他们将成功作为解决方案.要看到这一点,请尝试:

<上一页>?- X^X#=0,结果(X,下降).X 在 11..sup,X^X#=0 ;错误的.?- X^X#=0,结果(X,报价).X 在 0..20,X^X#=0.

那么你现在怎么能确定任何事情呢?

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

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

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

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

Look at the following goals (I am using swi-prolog with clpfd from Markus Triska):

result(Input,Result) :-
    Input #> 10,
    Result=decline.
result(Input,Result) :-
    Input in 0..20,
    Result=offer.

A possible query looks like this:

?- result(15,B).
B = decline ;
B = offer.

I want to add an order or some sort of solution priority. If "decline" is a valid response for Input=15, then the second goal should not be considered anymore, so that only B=decline is a solution but not B=offer.

I know that I could add a !/0 but then the other way round would not work. Give me all possible answers for this predicate.

Considering this example, a Result=offer should only be true for Input 0..10, because otherwise the higher prior decline goal should fire.

Am I thinking too imperative when I try to consider an order within predicates?

解决方案

There are several issues here, let's start first with the most obvious:

Modeling problems

You have a relation (result/2 is maybe not the best name), and this relation is supposed to model when decline and when offer should be true. Before reading your program, I prefer to ask Prolog:

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

So for the values from 11 up to 20, your relation is ambiguous. If you want to make a decision, then fix this relation first. Actually, I would start with

  • a better name for the relation that makes clear it is a relation
  • no imperative verbiage (like Input or imperatives)
  • a more compact formulation, you don't need so many (=)/2 goals in your program. Instead, you can write it like:

heigth_decision(I, decline) :-
   I #< 10.

Answers and success vs. solutions in CLP

And then there is another problem which is more fundamental. This is actually much more serious, since all the SO-answers given so far ignore this aspect entirely. It is about the notion of answers and success and on the other hand the notion of solutions.

When you ask a query in Prolog - what you get back is an answer. Such an answer might contain solutions, like the answer L = [_,_] which contains infinitely many solutions. Or an answer may contain exactly one solution like Decision = decline. But there is much more in between if you are using constraints like library(clpfd).

You can now get finitely many solutions:

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

Or infinitely many:

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

But you can get also exactly one solution, which does not look like one:

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

So, just to restate this: We have here exactly one solution in the integers, but for Prolog this is way too complex. What we got back was an answer that states: Yes that is all true, provided all this fine print is true.

Worse, sometimes we get answers back that do not contain any solution.

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

If Prolog would be smart enough, it would answer false. But it cannot be always that smart, simply because you can easily formulate undecidable problems. Such an answer is sometimes called inconsistency. The German notion Scheinlösung (~fake solution, but with less negative connotation) conveys the idea a bit better.

So an answer may contain solutions, but some answers do not contain solutions at all. For this reason, the success of a goal cannot be taken as the existence of a solution! That is, all SO-answers suggesting some kind of commit as (;)/2 – if-then-else, once/1, or !/0 are all incorrect, if they take the success as a solution. To see this, try them with:

?- 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.

So how can you now be sure of anything?

  • You can rely on the failure of a goal.

  • You can try labeling/2, but this only works on finite domains.

  • You can use call_residue_vars/2 and copy_term/3 to determine if there are constraints "hanging around"

  • Unfortunately, you cannot entirely rely on SWI's toplevel which hides constraints that are unrelated to the variables in an answer. Only SICStus does display them correctly.

这篇关于让订单进入谓词解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆