Tickers in Prolog

Our example demonstrates the use of tickers in Prolog. Tickers are used when you want to perform an action repeatedly at regular intervals.

:- use_module(library(system)).

main :-
    ticker(500, Done),
    sleep(1.6),
    Done ! stop,
    writeln('Ticker stopped').

ticker(Interval, Done) :-
    thread_create(ticker_loop(Interval, Done), _, []).

ticker_loop(Interval, Done) :-
    get_time(Now),
    format('Tick at ~w~n', [Now]),
    (   receive(Done, stop, 0) ->
        true
    ;   sleep(Interval / 1000),
        ticker_loop(Interval, Done)
    ).

receive(Port, Term, Timeout) :-
    catch(
        call_with_time_limit(Timeout, thread_get_message(Port, Term)),
        time_limit_exceeded,
        fail
    ).

In this Prolog implementation:

  1. We define a main predicate that creates a ticker with a 500 millisecond interval.

  2. The ticker/2 predicate creates a new thread that runs the ticker_loop/2 predicate.

  3. ticker_loop/2 is the core of our ticker. It prints the current time, then either stops if it receives a stop message or continues after sleeping for the specified interval.

  4. We use thread_create/3 to start the ticker in a separate thread.

  5. The receive/3 predicate is used to check for messages with a timeout.

  6. In main, we sleep for 1.6 seconds (allowing for about 3 ticks), then send a stop message to the ticker.

When we run this program, the ticker should tick about 3 times before we stop it:

?- main.
Tick at 1686431234.123
Tick at 1686431234.623
Tick at 1686431235.123
Ticker stopped
true.

This example demonstrates how to implement a simple ticker mechanism in Prolog using threads and message passing. While Prolog doesn’t have built-in tickers like some other languages, we can achieve similar functionality using its concurrency features.