Search code examples
prolog

delay execution in prolog?


How would I go about delaying execution in prolog? I can do threadDelay ms in Haskell to delay it by ms milliseconds. Is there any way to do this in prolog? I mean I could probably just do a bunch of empty queries like

delay(0).
delay(X) :- delay(Y), Y is X - 1.

but that seems like a stupid and wrong idea.

EDIT:

Apparently there's sleep/1. However, when I do something like

delayText([H|T]) :- put_char(H), sleep(0.1), delayText(T).
delayText([]).

, sleep will be executed first (so it will sleep for .5 seconds when querying delayText("Hello"). or something) and then it will display all the text at once? How do I prevent this?


Solution

  • Just to formalize my answer, in SWI-Prolog you can use sleep/1 to delay the process. I don't see an ISO predicate in this list and I wouldn't expect one, since the standard doesn't really specify much about threading or other low-level OS concerns.

    To fix delayText/1 you just need to add in flush_output. This is essentially the same as hFlush stdout in Haskell, but you can also change the flush mode of the output stream in Haskell with hSetBuffering. The SWI version of open/4 supports a buffer option, but it mentions that this is not ISO, so there probably isn't an ISO way to cause flush to automatically happen or make the output unbuffered, though hopefully somebody with more experience with the standard will come along and correct me if I'm wrong.

    The corrected code looks like this:

    delayText([H|T]) :- put_char(H), flush_output, sleep(0.1), delayText(T).
    delayText([]).
    

    I'd probably write it like this though:

    delay_put_char(X) :- put_char(X), flush_output, sleep(0.1).
    delayText(X) :- maplist(delay_put_char, X).