Hello,
I’m encountering an issue with the call_with_time_limit/2
predicate in SWI-Prolog, where the time limit doesn’t seem to be enforced as expected. I’ve created two test cases that illustrate the problem: one using sleep/1
and the other using a computationally intensive operation.
System Details:
- SWI-Prolog Version: 9.3.10-7-gfbc8aa081 (64 bits, threaded)
- Operating System: Debian 12 on WSL (Windows Subsystem for Linux)
Test Case 1: Using sleep/1
Here’s a simple test case that uses sleep/1
:
Prolog Code:
:- use_module(library(plunit)).
% Test case to ensure that call_with_time_limit/2 interrupts the sleep operation.
:- begin_tests(time_limit_test).
test(time_limit_exceeded, [throws(error(time_limit_exceeded, _))]) :-
time(call_with_time_limit(1, forall(between(1,80,_), sleep(0.1)))).
:- end_tests(time_limit_test).
% Run the test
:- run_tests.
Expected Behavior:
The goal should be interrupted after 1 second, raising a time_limit_exceeded
exception.
Actual Behavior:
?- time(call_with_time_limit(1,forall(between(1,80,_),sleep(0.1)))).
% 169 inferences, 0.002 CPU in 8.009 seconds (0% CPU, 70165 Lips)
true.
The goal continues to run well beyond the specified time limit without raising an exception, as demonstrated by the output above where the goal took over 8 seconds to complete.
Test Case 2: Using a Computationally Intensive Operation
I also created a test case that involves summing a large range of numbers, which should take enough time to trigger the time limit.
Bash Script to Create and Run the Test:
#!/bin/bash
# Create the Prolog test file
cat << 'EOF' > time_limit_test.pl
:- use_module(library(plunit)).
% A simple predicate that performs a large number of computations.
% It sums all integers from 1 to N.
sum_to(N, Sum) :-
sum_to(N, 0, Sum).
sum_to(0, Acc, Acc).
sum_to(N, Acc, Sum) :-
N > 0,
NewAcc is Acc + N,
NewN is N - 1,
sum_to(NewN, NewAcc, Sum).
% Test predicate to simulate a long-running operation without using sleep.
test_long_running :-
Max = 10^8, % This large number ensures the computation takes a significant amount of time.
sum_to(Max, _).
% Test case to ensure that call_with_time_limit/2 interrupts the computation.
:- begin_tests(time_limit_test).
test(time_limit_exceeded, [throws(error(time_limit_exceeded, _))]) :-
call_with_time_limit(1, test_long_running). % Set timeout to 1 second
:- end_tests(time_limit_test).
% Run the test
:- run_tests.
EOF
# Run the Prolog test
swipl -q -s time_limit_test.pl -t halt
Expected Behavior:
The computation should be interrupted after 1 second, raising a time_limit_exceeded
exception.
Actual Behavior:
Similar to the sleep/1
example, the time limit is not enforced, and the computation continues beyond the specified limit.
Additional Notes:
These test cases demonstrate that call_with_time_limit/2
is not enforcing the time limits as expected in different scenarios. I would appreciate any insights or suggestions on how to address this issue. Is this a known problem, or could there be something specific to my environment causing this behavior?
Thank you for your attention to this matter!
Best regards,
Douglas