/************************************************************************* * * * 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 * @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 time_out/3 command relies on the alarm/3 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 time_out. 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 alarm/3, 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. %% @}