使用is / 2谓词不能将变量N增加1

时间:2013-12-03 22:46:51

标签: prolog

使用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 .

2 个答案:

答案 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,
  • 统一起来
  • 以N + 1递增N1,使得N1 = 1
  • 如果N1不是5000(它是),
  • 就会失败。
  • 失败后,prolog引擎开始回溯......
  • 通过incr / 2回溯,取消N1的绑定,使其再次变化。
  • 回溯到重复/ 0,再次成功。

此时,您将返回到您开始的位置,N绑定为0。

洗涤,冲洗,重复。