prolog - 如何重复积累(永远)

标签 prolog infinite-loop

在硬件设备的命令和控制上下文中,我需要一个无限循环“获取-详细-发布”并记住当前状态,以观察 bool 值等输入的演变这“成为”真实。

我编写了一个模型,即以下程序,它产生了奇怪的行为(对我来说),我很惊讶,因为我设置了有界变量Previous而没有失败,为什么?

我期望出现类似“变量 Previous 已绑定(bind)”之类的错误消息,但事实并非如此,回溯是为了解决约束(很多次!)。

#!/usr/bin/swipl

init( Previous, AtStart ) :-
    get_time( AtStart ),
    Previous is 0.

run( AtStart, Previous ) :- % I want this to be executed only once for each period!
    get_time( Now ),
    Elapsed is Now - AtStart,
    Current is Previous + random( 20 ),
    format( "~w: Previous = ~w~n", [Elapsed, Previous] ),
    format( "~w: Current  = ~w~n", [Elapsed, Current ] ),
    Previous is Current.

periodicTask :-
    init( Previous, AtStart ),
    repeat,
        run( AtStart, Previous ),
        sleep( 1.0 ).

:-
    periodicTask.

它会以这种输出无限期地运行:

?- periodicTask.
?- periodicTask.
0.0231266: Previous = 0
0.0231266: Current  = 10
0.243902: Previous = 0
0.243902: Current  = 16
............................ A lot of lines
0.934601: Previous = 0
0.934601: Current  = 0
true ;
2693.8: Previous = 0
2693.8: Current  = 19
............................ A lot of lines
2694.65: Previous = 0
2694.65: Current  = 0
 true ;
3694.98: Previous = 0
3694.98: Current  = 2
............................ A lot of lines
3695.17: Previous = 0
3695.17: Current  = 0
 true ;
4695.47: Previous = 0
4695.47: Current  = 10
............................ A lot of lines
4695.55: Previous = 0
4695.55: Current  = 0
true 
  1. 为什么?

  2. 如何编写无限循环代码来重置(解除绑定(bind))一些变量并保留全局上下文?

“通过递归”的答案似乎在这里不适用,不是吗?

最佳答案

这是一个用尾递归调用编写的简单循环,它将激活 T 时的“状态”传输到激活 T+1 时的“状态”,这很自然(正如哥德尔在每个人都开始使用之前的意图) forwhile):

periodicTask :-
    get_time(AtStart),
    run(AtStart,0).        

stopCriteriumFulfilled :- fail. % TO BE DONE

run(AtStart,Previous) :-
    !,                       % Possibly optional: drop open chociepoints in infinite loop                       
    get_time(Now),
    Elapsed is Now - AtStart,
    Current is Previous + random( 20 ),
    format( "~w: Previous = ~w~n", [Elapsed, Previous] ),
    format( "~w: Current  = ~w~n", [Elapsed, Current ] ),
    % 
    % Now call yourself with a new context in which the 
    % variable "Current" ("here", in this activation)
    % becomes the variable "Previous" ("there", in the next activation)
    % But first sleep a bit (N.B. numbers are numbers, one can use 1 
    % instead of 1.0)
    % One may want to add a stop criterium here to succeed the predicate
    % instead of performing the tail-recursive call unconditionally.
    % 
    (stopCriteriumFulfilled
     -> true
      ; (sleep(1),
         run(AtStart,Current))). % RECURSIVE TAIL CALL
 
:- periodicTask.

如果需要更多的“状态性”而不是将当前状态传递到下一个激活,请查看以下内容:

关于prolog - 如何重复积累(永远),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64856890/

相关文章:

java - 统一 - 无限的结果

big-o - 使用无限循环计算时间 T(n) 和 Big-O

C++循环条件不会结束循环

prolog - 你如何在列表中找到丢失的号码?

Prolog - 了解 cut 的使用

prolog - 用 `last/2` 或 `append/3` 实现 `reverse/2`

performance - 如何测试 Prolog 程序的性能?

loops - 一旦进入无限循环,如何终止从Sublime Text 2终端运行的程序?

java - 初学者 : Number Guessing Game

c++ - 基本菜单驱动程序 C++,无限循环