5

我有一个即将举行的逻辑考试,并且一直在研究我课程中过去的一些论文。我遇到了一个关于具体化的问题,并将其发布在下面;

通过使用它来表示变量 B 可以取值 1 或 8 的属性来说明具体化。

在阅读了一些资源并查看了 SWI Prolog 手册之后,我仍然发现物化的概念相当混乱(主要是学习 Java,因此转向学习 Prolog 很困难)。在 prolog 查询中使用布尔逻辑非常令人困惑。

如果没有具体化,我将不得不编写以下代码(我知道这太长了,不能成为正确的答案);

 B in 1..8, B #\= 2,B #\= 3,B #\= 4,B #\= 5,B #\= 6,B #\= 7. 

如果有人可以向我展示上述查询,但使用具体化,将不胜感激。

4

3 回答 3

5

首先,尝试您的查询:

?- B in 1..8, B #\= 2,B #\= 3,B #\= 4,B #\= 5,B #\= 6,B #\= 7.
 B in 1\/ 8 .

这告诉您您的查询等同于单一目标B in 1\/8

由此可见,您不需要具体化来表示有限域变量等于 1 或 8。

具体化允许您具体化约束的真值。例如,您可以说:

?- T #<==> B 在 1\/8 中。
T 在 0..1 中,
B 在 1\/8#<==>T。

?- T #<==> B 在 1\/8 中,B = 3。
T = 0,
B = 3。

从第二个查询中,您可以看到 if B = 3, then T = 0,因为在这种情况下约束B in 1\/8 不成立

如果您想对约束本身进行推理,具体化约束可能很有用。例如,这允许您表示一定数量的列表元素必须等于给定的整数。我把解决这个问题作为一个更有意义的练习来理解具体化。

于 2016-05-08T10:44:14.557 回答
5

从文档中:

/2、#=/2、#\=/2、#/2、#==/2 中的约束可以被具体化,即将它们的真值反映为整数 0 和 1 表示的布尔值。令 P 和Q 表示可具体化的约束或布尔变量,则:

...
P #\/ Q True iff either P or Q
...

对你来说,它似乎PisB #= 1Qis B #= 8,所以你最终得到:

?- B #= 1 #\/ B #= 8.
B in 1\/8.

如您所见,您并没有真正使用具体化的值。您只是将具体化用作声明变量域的一种迂回方式。B in 1 \/ 8如果您想说“B 是 1 或 8”,您可能会直接使用查询的答案。如果您仔细查看 的文档in/2,您应该会看到域可以是整数、范围Lower .. Upper或 的并集Domain1 \/ Domain2。在您的情况下,两个域都是一个整数,1 和 8。

PS:一旦你走上这条路,为什么不:

?- B in 1..8 #/\ #\ B in 2..7.
B in 1\/8.

B 在 [1,8] 中且 B 不在 [2,7] 中。

可能性是无止境 :)

于 2016-05-09T05:33:21.343 回答
2

最初,我的想法与@Boris 和@mat 相同。但是在思考了一会儿这个问题之后,我想到了另一种可能的任务解释。但是,请记住,我不熟悉您的课程材料,因此这是高度推测性的。话虽如此,也许任务描述要求编写一个谓词,如果上述属性成立,则评估为真,否则为。像这样的谓词可以定义为:

val_either_or_t(X,Y,Z,true) :-
   ( X#=Y ; X#=Z).
val_either_or_t(X,Y,Z,false) :-
   X #\= Y,
   X #\= Z.

我承认这个名字有点笨拙,但我真的想不出更好的名字。无论如何,它根据我上面描述的任务解释来完成工作:

   ?- val_either_or_t(X,1,8,T).
T = true,
X = 1 ? ;
T = true,
X = 8 ? ;
T = false,
X in inf..0\/2..7\/9..sup

   ?- val_either_or_t(X,Y,Z,T).
T = true,
X = Y,
X in inf..sup ? ;
T = true,
X = Z,
X in inf..sup ? ;
T = false,
X#\=Z,
X#\=Y

我想出了这个想法,因为最近我在玩一些我在 Stackoverflow 上找到的具体化谓词,我突然想到这个任务可能针对一个方向,即所描述的属性可以用作此类谓词的条件. 例如,我在条件中使用了很多带有(=)/3的if_/3,但为什么不将它与 val_either_or_t/4 之类的东西一起使用。考虑以下最小示例:

a(condition_was_true).
b(condition_was_false).

somepredicate(X,Y) :-
   if_(val_either_or_t(X,1,8),a(Y),b(Y)).

使用相应的查询:

   ?- somepredicate(X,Y).
X = 1,
Y = condition_was_true ? ;
X = 8,
Y = condition_was_true ? ;
Y = condition_was_false,
X in inf..0\/2..7\/9..sup

这个例子当然不是很有意义,只是为了说明如何使用给定属性的具体化。此外,我正在使用原子true并具体化falseif_/3一起使用它们的真实值。但是,您也可以使用1and0来具体化真值,例如 @mat 的示例。只需将 val_either_or_t/4 定义中的第 4 个参数分别替换为10。此外,您可能会发现@repeat 在评论中提出的这个想法的改进也很有趣。

于 2016-05-14T19:18:17.970 回答