Prolog中否定变量的目标满意度
Goal satisfaction with negated variable in Prolog
我已经开始学习 PROLOG,但我对一个非常基本的示例有疑问。我使用的是SWI PROLOG,代码如下:
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)).
然后:
[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.
一切都很棒 ATM,我让 PROLOG 回溯所有符合目标和 (A,B) 的可能值,因为 A=a。但是如果我尝试目标 nand(A,B):
?- nand(a,X).
false.
要么它认为这个目标是不可能的,要么它没有回溯,我一点也不知道为什么。 :/
有人知道我做错了什么吗?
提前致谢。
PS:我也试过:
nand(A,B) :- not(and(A,B)).
它产生了相同的结果。
编辑:看到我的问题对某些人来说是神秘的:
我希望 PROLOG 给我一个变量 A 和 B 的值列表,这使得 and(A,B) 不可满足
EDIT2:我希望 PROLOG 告诉我:
?- nand(a,X).
X = e ;
X = b.
来自 the SWI-Prolog documentation:
“...如果无法证明‘目标’则为真...”
换句话说:\+(and(A, B))
只有在and(A, B)
失败时才会成功。也就是说,如果and(A, B)
有解,\+(and(A, B))
就会失败。
据我所知,and(a, X)
和 and(A, B)
.
都有一个解决方案
尝试对未明确声明为 is_true/1
.
的参数进行任何查询
尝试 google "negation as failure" 和 "closed world assumption"。两者都有值得阅读的维基百科文章。
混合使用布尔逻辑和 Prolog 时要小心。他们没有做出相同的假设。
针对您的问题:您有一堆逻辑变量。有些是真的,有些是假的。您希望能够计算真值表。说 and(A, B)
应该在输出列为真时成功,否则失败。此时,您已经混淆了两个不同的概念:
- 逻辑 TRUE 和 FALSE
- Prolog的成功与失败
这实际上是错误的,我建议不要这样做。相反:
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
等等。
然后,您可以进行更多信息查询:
?- 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.
一种简单的方法是引入一个对有效变量成功的谓词。因此,对于您现有的谓词,添加:
is_valid(X) :- is_true(X) ; is_false(X).
然后 nand/2
谓词可以在该域内工作并且 限制可能值的范围。否则,\+ and(A, B)
不知道选择什么值来确定 and(A, B)
:
的失败
nand(A, B) :- is_valid(A), is_valid(B), \+ and(A, B).
| ?- nand(a, X).
X = b ? ;
X = e ? ;
no
换句话说,is_valid/1
为 nand/2
提供了一种方法来生成可以测试 \+ and(A, B)
的可能选项。
您可以合理地将此 "confining of the universe" 应用于其他谓词,例如 and/2
: and(A, B) :- is_valid(A), is_valid(B), is_true(A), is_true(B).
,但您会发现这是多余的。
我已经开始学习 PROLOG,但我对一个非常基本的示例有疑问。我使用的是SWI PROLOG,代码如下:
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)).
然后:
[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.
一切都很棒 ATM,我让 PROLOG 回溯所有符合目标和 (A,B) 的可能值,因为 A=a。但是如果我尝试目标 nand(A,B):
?- nand(a,X).
false.
要么它认为这个目标是不可能的,要么它没有回溯,我一点也不知道为什么。 :/
有人知道我做错了什么吗?
提前致谢。
PS:我也试过:
nand(A,B) :- not(and(A,B)).
它产生了相同的结果。
编辑:看到我的问题对某些人来说是神秘的:
我希望 PROLOG 给我一个变量 A 和 B 的值列表,这使得 and(A,B) 不可满足
EDIT2:我希望 PROLOG 告诉我:
?- nand(a,X).
X = e ;
X = b.
来自 the SWI-Prolog documentation:
“...如果无法证明‘目标’则为真...”
换句话说:\+(and(A, B))
只有在and(A, B)
失败时才会成功。也就是说,如果and(A, B)
有解,\+(and(A, B))
就会失败。
据我所知,and(a, X)
和 and(A, B)
.
尝试对未明确声明为 is_true/1
.
尝试 google "negation as failure" 和 "closed world assumption"。两者都有值得阅读的维基百科文章。
混合使用布尔逻辑和 Prolog 时要小心。他们没有做出相同的假设。
针对您的问题:您有一堆逻辑变量。有些是真的,有些是假的。您希望能够计算真值表。说 and(A, B)
应该在输出列为真时成功,否则失败。此时,您已经混淆了两个不同的概念:
- 逻辑 TRUE 和 FALSE
- Prolog的成功与失败
这实际上是错误的,我建议不要这样做。相反:
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
等等。
然后,您可以进行更多信息查询:
?- 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.
一种简单的方法是引入一个对有效变量成功的谓词。因此,对于您现有的谓词,添加:
is_valid(X) :- is_true(X) ; is_false(X).
然后 nand/2
谓词可以在该域内工作并且 限制可能值的范围。否则,\+ and(A, B)
不知道选择什么值来确定 and(A, B)
:
nand(A, B) :- is_valid(A), is_valid(B), \+ and(A, B).
| ?- nand(a, X).
X = b ? ;
X = e ? ;
no
换句话说,is_valid/1
为 nand/2
提供了一种方法来生成可以测试 \+ and(A, B)
的可能选项。
您可以合理地将此 "confining of the universe" 应用于其他谓词,例如 and/2
: and(A, B) :- is_valid(A), is_valid(B), is_true(A), is_true(B).
,但您会发现这是多余的。