This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/library/timeout.yap

110 lines
2.5 KiB
Prolog

/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: timeout.yap *
* Last rev: 5/12/99 *
* mods: *
* comments: Goal within timeout *
* *
*************************************************************************/
/**
* @file timeout.yap
* @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
* @date Wed Nov 18 01:26:14 2015
*
* @brief Calls With Timeout
*
*
*/
:- module(timeout, [
time_out/3
]).
/** @defgroup timeout Calls With Timeout
@ingroup library
@{
The <tt>time_out/3</tt> command relies on the <tt>alarm/3</tt> built-in to
implement a call with a maximum time of execution. The command is
available with the `use_module(library(timeout))` command.
*/
/*
@pred time_out(+ _Goal_, + _Timeout_, - _Result_)
Execute goal _Goal_ with time limited _Timeout_, where
_Timeout_ is measured in milliseconds. If the goal succeeds, unify
_Result_ with success. If the timer expires before the goal
terminates, unify _Result_ with <tt>time_out</tt>.
This command is implemented by activating an alarm at procedure
entry. If the timer expires before the goal completes, the alarm will
throw an exception _timeout_.
One should note that time_out/3 is not reentrant, that is, a goal
called from `time_out` should never itself call
time_out/3. Moreover, time_out/3 will deactivate any previous
alarms set by alarm/3 and vice-versa, hence only one of these
calls should be used in a program.
Last, even though the timer is set in milliseconds, the current
implementation relies on <tt>alarm/3</tt>, and therefore can only offer
precision on the scale of seconds.
*/
:- meta_predicate time_out(0,+,-).
:- use_module(library(hacks), [
virtual_alarm/3
]).
%
% not the nicest program I've ever seen.
%
time_out(Goal, Time, Result) :-
T is Time//1000,
UT is (Time mod 1000)*1000,
catch( ( Result0 = success,
setup_call_cleanup(
virtual_alarm(T.UT,throw(time_out),_),
Goal,
virtual_alarm(0,_,RT)),
( var(RT)
-> virtual_alarm(0,_,_),
(
true
;
virtual_alarm(T.UT,throw(time_out),_),
fail
)
; true
)
),
time_out,
Result0 = time_out ),
Result = Result0.
%% @}