首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Prolog中负值变量的目标满意度

Prolog中负值变量的目标满意度
EN

Stack Overflow用户
提问于 2015-03-05 15:18:16
回答 2查看 509关注 0票数 0

我已经开始学习PROLOG了,我对一个非常基本的例子有一个问题。我正在使用SWI PROLOG,代码如下:

代码语言:javascript
复制
is_true(a).
is_true(c).
is_true(d).
is_false(b).
is_false(e).

and(A,B) :- is_true(A),is_true(B).
nand(A,B) :- \+(and(A,B)).

然后:

代码语言:javascript
复制
[imanol@I56106 prolog]$ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.6.4)
Copyright (c) 1990-2013 University of Amsterdam, VU Amsterdam
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.

For help, use ?- help(Topic). or ?- apropos(Word).

?- consult(test).
% test compiled 0.00 sec, 8 clauses
true.

?- and(a,X).
X = a ;
X = c ;
X = d.

一切都是伟大的自动取款机,我做了PROLOG回溯所有可能的值,符合目标和(A,B)的A=a。但如果我尝试目标nand(A,B):

代码语言:javascript
复制
?- nand(a,X).
false.

要么它认为目标是不可能的,要么它不会倒退,而我也不知道为什么。:/

有人知道我做错了什么吗?

提前谢谢。

PS:我也尝试过:

代码语言:javascript
复制
nand(A,B) :- not(and(A,B)).

也得到了同样的结果。

编辑:看到我的问题对一些人来说很神秘:

我希望PROLOG给我一个变量A和B的值列表,这些变量使和(A,B)不可满足

EDIT2:我希望PROLOG能告诉我:

代码语言:javascript
复制
?- nand(a,X).
    X = e ;
    X = b.
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-05 19:23:23

一种简单的方法是引入一个对有效变量成功的谓词。因此,在现有谓词中添加:

代码语言:javascript
复制
is_valid(X) :- is_true(X) ; is_false(X).

然后,nand/2谓词可以在该域中工作,并限制可能值的范围。否则,\+ and(A, B)就不知道从哪些值中选择来判断and(A, B)的失败。

代码语言:javascript
复制
nand(A, B) :- is_valid(A), is_valid(B), \+ and(A, B).

| ?- nand(a, X).

X = b ? ;

X = e ? ;

no

换句话说,is_valid/1nand/2提供了一种方法来生成可以测试\+ and(A, B)的可能选项。

您也可以合理地将这种“宇宙的限制”应用于其他谓词,如and/2and(A, B) :- is_valid(A), is_valid(B), is_true(A), is_true(B).,但您可以看到这是多余的。

票数 1
EN

Stack Overflow用户

发布于 2015-03-05 15:42:21

来自SWI-Prolog文档

“.如果`目标‘无法证明.”

换句话说,只有当\+(and(A, B))失败时,and(A, B)才会成功。换句话说,如果有and(A, B)的解决方案,\+(and(A, B))就会失败。

据我所见,and(a, X)and(A, B)都有一个解决方案。

尝试查询未显式声明为is_true/1的参数。

尝试谷歌的“否定为失败”,和“封闭的世界假设”。两者都有值得一读的维基百科文章。

当您混合布尔逻辑和Prolog时要小心。他们不做同样的假设。

对于你的问题:你有一堆逻辑变量。有些是真的,有些是假的。你想要能够计算出真值表。假设当输出列为true时,and(A, B)应该成功,否则失败。此时,您已经混淆了两个不同的概念:

  1. 逻辑真与假
  2. Prolog的成功与失败

这实际上是错误的,我建议反对。相反:

代码语言:javascript
复制
and(f, f, f).
and(f, t, f).
and(t, f, f).
and(t, t, t).

not(t, f).
not(f, t).

nand(A, B, R) :- and(A, B, R0), not(R0, R).

val(a, t). val(c, t). val(d, t).
val(b, f). val(e, f).

solve(and(A, B), R) :- val(A, VA), val(B, VB), and(VA, VB, R).
% solve(nand...) as exercise

诸若此类。

然后,您可以获得更多的信息查询:

代码语言:javascript
复制
?- solve(and(a, c), R).
R = t.

?- solve(and(a, X), R).
X = a,
R = t ;
X = c,
R = t ;
X = d,
R = t ;
X = b,
R = f ;
X = e,
R = f ;
false.

?- solve(nand(a, X), R).
X = a,
R = f ;
X = c,
R = f ;
X = d,
R = f ;
X = b,
R = t ;
X = e,
R = t ;
false.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28881326

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档