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

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

问题描述

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

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

一个可能的查询如下所示:

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

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

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

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

当我尝试考虑谓词中的顺序时,我是否认为太必要了?

解决方案

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

建模问题

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

<预>?- 结果(X,拒绝),结果(X,报价).11..20 中的 X ;错误的.

因此对于从 11 到 20 的值,您的关系是不明确的.如果你想做出决定,那么首先修复这个关系.实际上,我会从

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

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

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

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

您现在可以得到有限多个解:

?- abs(X) #<3.X 输入 -2..2.

或无限多个:

?- X #> Y.Y#=

但是你也可以得到一个完全不同的解决方案:

<预>?- 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,下降).11..sup 中的 X,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天全站免登陆