Select in Prolog

Our example demonstrates how to wait on multiple operations in Prolog. We’ll use threads and message passing to simulate concurrent operations.

:- use_module(library(thread)).

main :-
    thread_create(send_message(1, one), _, []),
    thread_create(send_message(2, two), _, []),
    receive_messages(2).

send_message(Seconds, Message) :-
    sleep(Seconds),
    thread_send_message(main_thread, Message).

receive_messages(0).
receive_messages(N) :-
    N > 0,
    thread_get_message(Message),
    format('received ~w~n', [Message]),
    N1 is N - 1,
    receive_messages(N1).

In this example, we’re using Prolog’s thread library to create concurrent operations. Here’s a breakdown of the code:

  1. We import the thread library to use Prolog’s threading capabilities.

  2. In the main predicate, we create two threads using thread_create/3. Each thread will sleep for a certain amount of time and then send a message.

  3. The send_message/2 predicate simulates a blocking operation by sleeping for a specified number of seconds, then sends a message to the main thread.

  4. The receive_messages/1 predicate acts similarly to the select statement in the original example. It waits for and processes incoming messages.

To run this program:

?- main.
received one
received two
true.

Note that the total execution time will be about 2 seconds, as both the 1 and 2 second sleeps execute concurrently.

While Prolog doesn’t have a direct equivalent to Go’s select statement, we can achieve similar functionality using threads and message passing. This approach allows us to wait on multiple operations concurrently and process them as they complete.