Time 时间超过prolog中的异常,获取中断前的最后一个值

Time 时间超过prolog中的异常,获取中断前的最后一个值,time,prolog,try-catch,Time,Prolog,Try Catch,我有一个计算N的阶乘的谓词,但当时间超过1秒时,它被中断: factorial( 0, 1 ). factorial( N, Value ) :- N > 0, Prev is N - 1, factorial( Prev, Prevfact ), Value is Prevfact * N. fact(N,V) :- catch(call_with_time_limit(1, factorial(N,V) ), time_limit_excee

我有一个计算N的阶乘的谓词,但当时间超过1秒时,它被中断:

factorial( 0, 1 ).
factorial( N, Value ) :-
    N > 0,
    Prev is N - 1,
    factorial( Prev, Prevfact ),
    Value is Prevfact * N.

fact(N,V) :-
catch(call_with_time_limit(1, factorial(N,V)  ),
    time_limit_exceeded,
    write('time exceeded!')).
如何在阶乘被中断之前得到V的最后一个值


谢谢

在计算中断之前,您的代码中没有
V
的最后一个值-它将尚未初始化。如果它被实例化,那么计算已经结束,没有中断

如果你想找出你能在一秒钟内计算出的最大阶乘,你必须通过某种机制来保存它,这种机制不会被回溯破坏(因为
catch/3
backtracks)

但是,按照编写代码的方式,在计算进行到一半之前,您不会有任何值需要保存。如果总共需要3秒,则意味着在运行的第一个1.5秒期间,您将没有任何值可保存:

factorial( 0, 1 ).
factorial( N, Value ) :-
    N > 0,
    Prev is N - 1,
    factorial( Prev, Prevfact ),
    % here - save the value of Prevfact, e.g. with nb_setval/2
    Value is Prevfact * N.
这是因为它在从递归深度返回的过程中计算其阶乘

要使其立即计算某些值,请将其更改为使用累加器:

factorial(N,F):- factorial(N,1,1,F).
factorial(N,A,K,F):- K>N -> F=A ; 
  A2 is A*K, K2 is K+1,   % save (A2,K) here
  factorial(N,A2,K2,F).

在计算被中断之前,代码中没有
V
的最后一个值-它将尚未实例化。如果它被实例化,那么计算已经结束,没有中断

如果你想找出你能在一秒钟内计算出的最大阶乘,你必须通过某种机制来保存它,这种机制不会被回溯破坏(因为
catch/3
backtracks)

但是,按照编写代码的方式,在计算进行到一半之前,您不会有任何值需要保存。如果总共需要3秒,则意味着在运行的第一个1.5秒期间,您将没有任何值可保存:

factorial( 0, 1 ).
factorial( N, Value ) :-
    N > 0,
    Prev is N - 1,
    factorial( Prev, Prevfact ),
    % here - save the value of Prevfact, e.g. with nb_setval/2
    Value is Prevfact * N.
这是因为它在从递归深度返回的过程中计算其阶乘

要使其立即计算某些值,请将其更改为使用累加器:

factorial(N,F):- factorial(N,1,1,F).
factorial(N,A,K,F):- K>N -> F=A ; 
  A2 is A*K, K2 is K+1,   % save (A2,K) here
  factorial(N,A2,K2,F).

使用全局变量?使用全局变量?