为什么将单个谓词添加到单个谓词与 3 个单独谓词的作用不同?
具有多个子句的谓词(您称为单个谓词)被评估为OR,而具有由, 分隔的多个语句的单个子句谓词被评估为AND。
如果你改变这个
preOrder(bst(L,X,R)) :-
write(X),
write(" "),
preOrder_04(L),
preOrder_04(R).
也可以写成
preOrder(bst(L,X,R)) :-
write(X),
write(" "),
(
preOrder_04(L)
,
preOrder_04(R)
).
到
preOrder(bst(L,X,R)) :-
write(X),
write(" "),
(
preOrder_04(L)
;
preOrder_04(R)
).
那么你会得到你想要的。
由于您是 Prolog 的新手,因此我还将对您的代码进行审查。
使用您的原始树和谓词
bst(bst(bst(empty,2,empty),4,empty),5,bst(bst(empty,6,empty),8,empty))
preOrder(bst(_,X,_)) :- write(X).
preOrder(bst(L,_,_)) :- preOrder(L).
preOrder(bst(_,_,R)) :- preOrder(R).
我做了这个
tree(bst(bst(bst(empty,2,empty),4,empty),5,bst(bst(empty,6,empty),8,empty))).
test_01 :-
tree(T),
preOrder_01(T).
preOrder_01(bst(_,X,_)) :- write(X).
preOrder_01(bst(L,_,_)) :- preOrder_01(L).
preOrder_01(bst(_,_,R)) :- preOrder_01(R).
tree(T) 行将树作为事实读取,然后将树绑定到变量 T,这样我就不必每次都输入它。
然后我创建了一个名为 _01 的测试谓词,这样我就不会与即将到来的其他测试发生冲突。
示例运行:
?- test_01.
5
true ;
4
true ;
2
true ;
8
true ;
6
true ;
false.
为什么每次回答后都要按空格键?
(这是使用 SWI-Prolog 完成的)。
这个例子说明了原因。
test_02 :- write("First").
test_02 :- write("Second").
?- test_02.
First
true ;
Second
true.
每次执行谓词test_02/0 都会产生一个解决方案,当给出一个解决方案时,您必须按空格键才能看到下一个解决方案。
还要注意第一个答案末尾的;。这是 Prolog 告诉你存在一个选择点,可能还有另一个答案。如果是.,那么就没有更多的答案了。
对于你的重写不起作用
preOrder_03(bst(L,X,R)) :-
write(X),
write(" "),
preOrder_03(L),
preOrder_03(R).
test_03 :-
tree(T),
preOrder_03(T).
示例运行:
?- test_03.
5 4 2
false.
如果您使用跟踪运行它,您会发现它没有到达选择点。
见What is redo in Prolog when you trace?
但是如果你这样做
preOrder_04(bst(L,X,R)) :-
write(X),
write(" "),
(
preOrder_04(L)
;
preOrder_04(R)
).
test_04 :-
tree(T),
preOrder_04(T).
示例运行:
?- test_04.
5 4 2 8 6
false.
你会得到你想要的。 preOrder_03 和 preOrder_04 之间的主要区别在于,preOrder_03 在一个地方有一个,,而preOrder_04 在一个地方有一个;。逗号 (,) 是逻辑 AND,分号 (;) 是逻辑 OR。