Prolog 无法使用is/2谓词将变量N增加1
无法使用Prolog 无法使用is/2谓词将变量N增加1,prolog,Prolog,无法使用is/2谓词将变量N递增1N在重复循环中始终为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) -> retr
is/2
谓词将变量N
递增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 .
因为
N是0
。Prolog中的变量不是。以下是跟踪循环时发生的情况:
?- 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
执行的操作,因为N是0
。Prolog中的变量不是。以下是跟踪循环时发生的情况:
?- 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
来完成的操作,我不知道您在这里试图完成什么,但似乎您正在尝试编写过程性的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统一
- 用N+1增加N1,使N1=1
- 如果N1不是5000(实际值),则失败
- 失败时,prolog引擎开始回溯
- 通过incr/2进行回溯将撤消N1的绑定,使其再次变为变量
- 回溯到repeat/0,再次成功
清洗、冲洗、重复。我不知道您在这里试图完成什么,但似乎您正在尝试编写过程性的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统一
- 用N+1增加N1,使N1=1
- 如果N1不是5000(实际值),则失败
- 失败时,prolog引擎开始回溯
- 通过incr/2进行回溯将撤消N1的绑定,使其再次变为变量
- 回溯到repeat/0,再次成功