3

I would like to find all solutions to a goal within some time limit. I mean that I would like to search for solutions for at most the time limit, and return all solutions found, whether the time limit has been reached or not, which is regardless of whether the list of solutions is complete or not.

I have tried the following:

catch(call_with_time_limit(60, findall(S,my_goal(S),Sol)), time_limit_exceeded,false)

However, it does not return the partial list of solutions found if the time limit has been reached, and "false" can not be an expression relying on Sol.

This question is related to Prolog: "findall" for limited number of solutions, but instead of having a maximum number of solution I am interested in maximum search time.

Would you please have any insight for this?

catbow
  • 85
  • 9
  • Of interest: [Is it possible to create something similar to call_with_time_limit/2 which doesn’t kill the goal after timeout?](https://swi-prolog.discourse.group/t/is-it-possible-to-create-something-similar-to-call-with-time-limit-2-which-doesnt-kill-the-goal-after-timeout/1313) – Guy Coder Dec 27 '21 at 23:51

1 Answers1

2

Something like this may work to you:

findall_time(Duration, Template, Goal, Bag):-
  get_time(TimeStamp),
  Time is TimeStamp + Duration,
  findall(Template, findall_time1(Time, Goal), Bag).
  
findall_time1(Time, Goal) :-
    catch(setup_call_cleanup(alarm_at(Time,
                                      throw(time_limit_exceeded),
                                      Id),
                             (get_time(TimeStamp), Time>TimeStamp, Goal),
                             remove_alarm(Id)),
          time_limit_exceeded,
          fail).

with this sample code and test:

my_goal(X):-
 between(0, 5, X),
 sleep(1).
 

?- findall_time(2.5, X, my_goal(X), Bag).
Bag = [0, 1].
gusbro
  • 22,357
  • 35
  • 46