2

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?

tolUene
  • 572
  • 3
  • 18

2 Answers2

2

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).
Daniel Lyons
  • 22,421
  • 2
  • 50
  • 77
  • The list you refer to is outdated. [This one is current](http://stackoverflow.com/questions/10914155/a-searchable-prolog-language-description-online/10914371#10914371). – false Mar 19 '13 at 17:18
  • Would it have killed you to link to [the actual list](http://www.complang.tuwien.ac.at/ulrich/iso-prolog/prologue#status_quo) rather than your answer? – Daniel Lyons Mar 19 '13 at 17:20
0

In Ciao Prolog the same is called pause/1. And there is a draft
standard for threads which suggests a thread_sleep/1 predicate:

3.2.11 thread_sleep/1
thread sleep(Seconds) suspends the current threads execution until Seconds seconds elapsed. When the number of seconds is zero or a negative value, the call succeeds and returns immediately. https://logtalk.org/plstd/threads.pdf

But as long as there is no PEP or somesuch Prolog systems might
do it differently. For example in this realization the argument
is in milliseconds:

<h1>Example 63: Sleepy Hello</h1>
<script src="https://www.rubycap.ch/rscsrv/dogelog.js"></script>
<script type="application/x-dogelog">
:- write('Hello '), flush_output,
   sleep(1000),
   write('World!'), nl.
</script>
Rúben Dias
  • 336
  • 2
  • 9