使用N
谓词无法将变量is/2
增加1。重复循环中N
始终为0。为什么?如何增加它?
:- dynamic audible/1, flashes/1,tuned/1.
audible(false).
flashes(false).
tuned(false).
turn :-
N is 0 ,
repeat ,
(
incr(N,N1) ,
N1 =:= 5000 ,
audible(true) ,
flashes(true) -> retractall(tuned) ,
retractall(flashes) ,
retractall(audible) ,
assert( tuned(true) ) ,
assert( flashes(true) ) ,
assert( audible(true) )
) .
incr(X,X1) :- X1 is X+1 .
答案 0 :(得分:3)
因为N is 0
。 Prolog中的变量不是assignables。如果你追踪你的循环会发生什么:
?- trace, turn.
Call: (7) turn ?
Call: (8) _G492 is 0 ?
Exit: (8) 0 is 0 ?
Call: (8) repeat ?
Exit: (8) repeat ?
Call: (8) incr(0, _G493) ?
Call: (9) _G495 is 0+1 ?
Exit: (9) 1 is 0+1 ?
Exit: (8) incr(0, 1) ?
Call: (8) 1=:=5000 ?
Fail: (8) 1=:=5000 ?
Redo: (8) repeat ?
Exit: (8) repeat ?
Call: (8) incr(0, _G493) ?
Call: (9) _G495 is 0+1 ?
Exit: (9) 1 is 0+1 ?
Exit: (8) incr(0, 1) ?
Call: (8) 1=:=5000 ?
Fail: (8) 1=:=5000 ?
Redo: (8) repeat ?
Exit: (8) repeat ?
Call: (8) incr(0, _G493) ?
Call: (9) _G495 is 0+1 ?
Exit: (9) 1 is 0+1 ?
Exit: (8) incr(0, 1) ?
Call: (8) 1=:=5000 ?
Fail: (8) 1=:=5000 ?
Redo: (8) repeat ?
看看那里发生了什么?您反复询问1是否为5000,哪个失败,然后再试一次。但是N和N1的值永远不会在谓词的主体内发生变化。 Prolog没有像你习惯的块范围变量。您需要将循环体设置为单独的谓词,并使用递归来完成您尝试执行的操作。它看起来像这样:
turn :- loop(0).
loop(5000) :-
audible(true), ...
loop(N) :-
incr(N, N1),
loop(N1).
顺便说一下,已经有一个谓词succ/2
可以执行您尝试使用incr/2
执行的操作。
答案 1 :(得分:1)
我不知道你在这里想要完成什么,但看起来你正试图编写程序性的prolog代码。
它不起作用。
Prolog变量是一次写入:与对象统一后,它们不再是变量。他们成为那个对象,直到通过回溯来消除统一。
你需要学习递归并使用递归循环来做你想做的事。
你的回合/ 0谓词
turn :-
N is 0 ,
repeat ,
(
incr(N,N1) ,
N1 =:= 5000 ,
audible(true) ,
flashes(true) -> retractall(tuned) ,
retractall(flashes) ,
retractall(audible) ,
assert( tuned(true) ) ,
assert( flashes(true) ) ,
assert( audible(true) )
) .
执行以下操作。它:
此时,您将返回到您开始的位置,N绑定为0。
洗涤,冲洗,重复。