.. index:: single: linda .. _linda/0: .. rst-class:: right **object** ``linda`` ========= Linda tuple-space implementation for process communication. Provides a server that acts as a shared blackboard where clients can write (``out/1``), read (``rd/1``), and remove (``in/1``) tuples. Uses threaded engines for the server implementation and the sockets library for network communication. | **Availability:** | ``logtalk_load(linda(loader))`` | **Author:** Paulo Moura | **Version:** 1:0:0 | **Date:** 2026-02-26 | **Compilation flags:** | ``static, context_switching_calls, threaded`` | **Provides:** | :ref:`logtalk::message_prefix_stream/4 ` | **Uses:** | :ref:`list ` | :ref:`logtalk ` | :ref:`os ` | :ref:`socket ` | **Remarks:** - Supported backends: ECLiPSe, GNU Prolog, SICStus Prolog, SWI-Prolog, and Trealla Prolog (requires both multi-threading and sockets support). - Linda operations: The basic operations are ``out/1`` (write tuple), ``in/1`` (remove tuple, blocking), ``rd/1`` (read tuple, blocking), ``in_noblock/1`` (remove tuple, non-blocking), and ``rd_noblock/1`` (read tuple, non-blocking). - Tuple matching: Tuples are matched using unification. - Blocking behavior: The ``in/1`` and ``rd/1`` predicates block until a matching tuple is available. The ``in_noblock/1`` and ``rd_noblock/1`` predicates fail immediately if no matching tuple is found. - Multiple clients: Multiple clients can connect to the same server. A tuple removed by ``in/1`` or ``in_noblock/1`` is only removed for one client. - API compatibility: The API is inspired by the SICStus Prolog Linda library. - Network communication: Uses TCP sockets for client-server communication, allowing processes to run on different machines. | **Inherited public predicates:** | (none) .. contents:: :local: :backlinks: top Public predicates ----------------- .. index:: linda/0 .. _linda/0::linda/0: ``linda/0`` ^^^^^^^^^^^ Starts a Linda server on an automatically assigned port. The server address (``Host:Port``) is written to the current output stream. The predicate succeeds when all clients have disconnected after a shutdown request. | **Compilation flags:** | ``static`` | **Mode and number of proofs:** | ``linda`` - ``one`` ------------ .. index:: linda/1 .. _linda/0::linda/1: ``linda/1`` ^^^^^^^^^^^ Starts a Linda server with the given options. The predicate succeeds when all clients have disconnected after a shutdown request. | **Compilation flags:** | ``static`` | **Template:** | ``linda(Options)`` | **Meta-predicate template:** | ``linda(::)`` | **Mode and number of proofs:** | ``linda(+list)`` - ``one`` | **Remarks:** - Option ``port(Port)``: Use ``Port`` as the server port. Must be an integer and an available port. - Option ``Address-Goal``: ``Address`` is unified with ``Host:Port`` and ``Goal`` is called when the server starts. Useful for saving the address or starting clients. - Option ``accept_hook(Client,Stream,Goal)``: When a client connects, ``Client`` is unified with the client address, ``Stream`` with the connection stream, and ``Goal`` is called. If ``Goal`` fails, the connection is rejected. ------------ .. index:: linda_client/1 .. _linda/0::linda_client/1: ``linda_client/1`` ^^^^^^^^^^^^^^^^^^ Connects to a Linda server at the given address (``Host:Port``). | **Compilation flags:** | ``static`` | **Template:** | ``linda_client(Address)`` | **Mode and number of proofs:** | ``linda_client(+compound)`` - ``one_or_error`` | **Exceptions:** | Already connected: | ``linda_error(already_connected)`` | Connection failed: | ``linda_error(connection_failed(Error))`` ------------ .. index:: close_client/0 .. _linda/0::close_client/0: ``close_client/0`` ^^^^^^^^^^^^^^^^^^ Closes the connection to the Linda server. | **Compilation flags:** | ``static`` | **Mode and number of proofs:** | ``close_client`` - ``one`` ------------ .. index:: shutdown_server/0 .. _linda/0::shutdown_server/0: ``shutdown_server/0`` ^^^^^^^^^^^^^^^^^^^^^ Sends a shutdown signal to the server. The server stops accepting new connections but continues serving existing clients until they all disconnect. Call ``close_client/0`` after this predicate. | **Compilation flags:** | ``static`` | **Mode and number of proofs:** | ``shutdown_server`` - ``one_or_error`` | **Exceptions:** | Not connected: | ``linda_error(not_connected)`` ------------ .. index:: linda_timeout/2 .. _linda/0::linda_timeout/2: ``linda_timeout/2`` ^^^^^^^^^^^^^^^^^^^ Gets or sets the client timeout. ``OldTime`` is unified with the current timeout and the timeout is set to ``NewTime``. The timeout value is either ``off`` (no timeout, wait forever) or ``Seconds:Milliseconds``. | **Compilation flags:** | ``static`` | **Template:** | ``linda_timeout(OldTime,NewTime)`` | **Mode and number of proofs:** | ``linda_timeout(?compound,+compound)`` - ``one`` ------------ .. index:: out/1 .. _linda/0::out/1: ``out/1`` ^^^^^^^^^ Places the tuple ``Tuple`` in the tuple-space. | **Compilation flags:** | ``static`` | **Template:** | ``out(Tuple)`` | **Mode and number of proofs:** | ``out(+term)`` - ``one`` ------------ .. index:: in/1 .. _linda/0::in/1: ``in/1`` ^^^^^^^^ Removes a tuple matching ``Tuple`` from the tuple-space. Blocks if no matching tuple is available. | **Compilation flags:** | ``static`` | **Template:** | ``in(Tuple)`` | **Mode and number of proofs:** | ``in(?term)`` - ``one`` ------------ .. index:: in_noblock/1 .. _linda/0::in_noblock/1: ``in_noblock/1`` ^^^^^^^^^^^^^^^^ Removes a tuple matching ``Tuple`` from the tuple-space. Fails if no matching tuple is available. | **Compilation flags:** | ``static`` | **Template:** | ``in_noblock(Tuple)`` | **Mode and number of proofs:** | ``in_noblock(?term)`` - ``zero_or_one`` ------------ .. index:: in/2 .. _linda/0::in/2: ``in/2`` ^^^^^^^^ Removes a tuple matching one of the patterns in ``TupleList`` from the tuple-space. ``Tuple`` is unified with the matched tuple. Blocks if no matching tuple is available. | **Compilation flags:** | ``static`` | **Template:** | ``in(TupleList,Tuple)`` | **Mode and number of proofs:** | ``in(+list,?term)`` - ``one`` ------------ .. index:: in_list/2 .. _linda/0::in_list/2: ``in_list/2`` ^^^^^^^^^^^^^ Removes a tuple matching one of the patterns in ``TupleList`` from the tuple-space. ``Tuple`` is unified with the matched tuple. Blocks if no matching tuple is available. | **Compilation flags:** | ``static`` | **Template:** | ``in_list(TupleList,Tuple)`` | **Mode and number of proofs:** | ``in_list(+list,?term)`` - ``one`` ------------ .. index:: rd/1 .. _linda/0::rd/1: ``rd/1`` ^^^^^^^^ Reads a tuple matching ``Tuple`` from the tuple-space without removing it. Blocks if no matching tuple is available. | **Compilation flags:** | ``static`` | **Template:** | ``rd(Tuple)`` | **Mode and number of proofs:** | ``rd(?term)`` - ``one`` ------------ .. index:: rd_noblock/1 .. _linda/0::rd_noblock/1: ``rd_noblock/1`` ^^^^^^^^^^^^^^^^ Reads a tuple matching ``Tuple`` from the tuple-space without removing it. Fails if no matching tuple is available. | **Compilation flags:** | ``static`` | **Template:** | ``rd_noblock(Tuple)`` | **Mode and number of proofs:** | ``rd_noblock(?term)`` - ``zero_or_one`` ------------ .. index:: rd/2 .. _linda/0::rd/2: ``rd/2`` ^^^^^^^^ Reads a tuple matching one of the patterns in ``TupleList`` from the tuple-space without removing it. ``Tuple`` is unified with the matched tuple. Blocks if no matching tuple is available. | **Compilation flags:** | ``static`` | **Template:** | ``rd(TupleList,Tuple)`` | **Mode and number of proofs:** | ``rd(+list,?term)`` - ``one`` ------------ .. index:: rd_list/2 .. _linda/0::rd_list/2: ``rd_list/2`` ^^^^^^^^^^^^^ Reads a tuple matching one of the patterns in ``TupleList`` from the tuple-space without removing it. ``Tuple`` is unified with the matched tuple. Blocks if no matching tuple is available. | **Compilation flags:** | ``static`` | **Template:** | ``rd_list(TupleList,Tuple)`` | **Mode and number of proofs:** | ``rd_list(+list,?term)`` - ``one`` ------------ .. index:: findall_rd_noblock/3 .. _linda/0::findall_rd_noblock/3: ``findall_rd_noblock/3`` ^^^^^^^^^^^^^^^^^^^^^^^^ Returns a list of all instances of ``Template`` for tuples matching ``Tuple`` in the tuple-space. The operation is atomic. | **Compilation flags:** | ``static`` | **Template:** | ``findall_rd_noblock(Template,Tuple,List)`` | **Mode and number of proofs:** | ``findall_rd_noblock(?term,+term,?list)`` - ``one`` ------------ .. index:: findall_in_noblock/3 .. _linda/0::findall_in_noblock/3: ``findall_in_noblock/3`` ^^^^^^^^^^^^^^^^^^^^^^^^ Removes and returns a list of all instances of ``Template`` for tuples matching ``Tuple`` in the tuple-space. The operation is atomic - all matching tuples are removed in one synchronized operation. | **Compilation flags:** | ``static`` | **Template:** | ``findall_in_noblock(Template,Tuple,List)`` | **Mode and number of proofs:** | ``findall_in_noblock(?term,+term,?list)`` - ``one`` ------------ Protected predicates -------------------- (no local declarations; see entity ancestors if any) Private predicates ------------------ .. index:: server_socket_/1 .. _linda/0::server_socket_/1: ``server_socket_/1`` ^^^^^^^^^^^^^^^^^^^^ Stores the server socket descriptor. | **Compilation flags:** | ``dynamic`` | **Template:** | ``server_socket_(ServerSocket)`` | **Mode and number of proofs:** | ``server_socket_(?term)`` - ``zero_or_one`` ------------ .. index:: client_connection_/3 .. _linda/0::client_connection_/3: ``client_connection_/3`` ^^^^^^^^^^^^^^^^^^^^^^^^ Stores active client connections. Each client has an ID, input stream, and output stream. | **Compilation flags:** | ``dynamic`` | **Template:** | ``client_connection_(ClientId,InputStream,OutputStream)`` | **Mode and number of proofs:** | ``client_connection_(?term,?term,?term)`` - ``zero_or_more`` ------------ .. index:: accept_hook_/1 .. _linda/0::accept_hook_/1: ``accept_hook_/1`` ^^^^^^^^^^^^^^^^^^ Stores the optional accept hook goal to call when a client connects. | **Compilation flags:** | ``dynamic`` | **Template:** | ``accept_hook_(Hook)`` | **Mode and number of proofs:** | ``accept_hook_(?callable)`` - ``zero_or_one`` ------------ .. index:: server_running_/0 .. _linda/0::server_running_/0: ``server_running_/0`` ^^^^^^^^^^^^^^^^^^^^^ Flag indicating the server is running. | **Compilation flags:** | ``dynamic`` | **Mode and number of proofs:** | ``server_running_`` - ``zero_or_one`` ------------ .. index:: server_shutdown_/0 .. _linda/0::server_shutdown_/0: ``server_shutdown_/0`` ^^^^^^^^^^^^^^^^^^^^^^ Flag indicating the server has received a shutdown request. | **Compilation flags:** | ``dynamic`` | **Mode and number of proofs:** | ``server_shutdown_`` - ``zero_or_one`` ------------ .. index:: tuple_/1 .. _linda/0::tuple_/1: ``tuple_/1`` ^^^^^^^^^^^^ Stores tuples in the Linda tuple space. | **Compilation flags:** | ``dynamic`` | **Template:** | ``tuple_(Tuple)`` | **Mode and number of proofs:** | ``tuple_(?term)`` - ``zero_or_more`` ------------ .. index:: waiting_/3 .. _linda/0::waiting_/3: ``waiting_/3`` ^^^^^^^^^^^^^^ Stores blocked clients waiting for tuples. Records the client ID, request pattern, and output stream. | **Compilation flags:** | ``dynamic`` | **Template:** | ``waiting_(ClientId,Request,OutputStream)`` | **Mode and number of proofs:** | ``waiting_(?term,?term,?term)`` - ``zero_or_more`` ------------ .. index:: engine_counter_/1 .. _linda/0::engine_counter_/1: ``engine_counter_/1`` ^^^^^^^^^^^^^^^^^^^^^ Counter for generating unique client engine names. | **Compilation flags:** | ``dynamic`` | **Template:** | ``engine_counter_(Counter)`` | **Mode and number of proofs:** | ``engine_counter_(?integer)`` - ``zero_or_one`` ------------ .. index:: client_engine_/2 .. _linda/0::client_engine_/2: ``client_engine_/2`` ^^^^^^^^^^^^^^^^^^^^ Maps client IDs to their corresponding threaded engine names. | **Compilation flags:** | ``dynamic`` | **Template:** | ``client_engine_(ClientId,EngineName)`` | **Mode and number of proofs:** | ``client_engine_(?term,?atom)`` - ``zero_or_more`` ------------ .. index:: client_connection_input_/1 .. _linda/0::client_connection_input_/1: ``client_connection_input_/1`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Stores the input stream for the client connection to the server. | **Compilation flags:** | ``dynamic`` | **Template:** | ``client_connection_input_(InputStream)`` | **Mode and number of proofs:** | ``client_connection_input_(?term)`` - ``zero_or_one`` ------------ .. index:: client_connection_output_/1 .. _linda/0::client_connection_output_/1: ``client_connection_output_/1`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Stores the output stream for the client connection to the server. | **Compilation flags:** | ``dynamic`` | **Template:** | ``client_connection_output_(OutputStream)`` | **Mode and number of proofs:** | ``client_connection_output_(?term)`` - ``zero_or_one`` ------------ .. index:: client_timeout_/1 .. _linda/0::client_timeout_/1: ``client_timeout_/1`` ^^^^^^^^^^^^^^^^^^^^^ Stores the timeout value for blocking client operations. Value is either ``off`` or ``Seconds:Milliseconds``. | **Compilation flags:** | ``dynamic`` | **Template:** | ``client_timeout_(Timeout)`` | **Mode and number of proofs:** | ``client_timeout_(?compound)`` - ``zero_or_one`` ------------ .. index:: ts_out/1 .. _linda/0::ts_out/1: ``ts_out/1`` ^^^^^^^^^^^^ Synchronized predicate to add a tuple to the tuple space and wake waiting clients. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_out(Tuple)`` | **Mode and number of proofs:** | ``ts_out(+term)`` - ``one`` ------------ .. index:: ts_in/4 .. _linda/0::ts_in/4: ``ts_in/4`` ^^^^^^^^^^^ Synchronized predicate to remove a matching tuple or register a waiting client. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_in(Tuple,ClientId,OutputStream,Found)`` | **Mode and number of proofs:** | ``ts_in(+term,+term,+term,-compound)`` - ``one`` ------------ .. index:: ts_in_noblock/2 .. _linda/0::ts_in_noblock/2: ``ts_in_noblock/2`` ^^^^^^^^^^^^^^^^^^^ Synchronized predicate to try removing a matching tuple without blocking. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_in_noblock(Tuple,Found)`` | **Mode and number of proofs:** | ``ts_in_noblock(+term,-compound)`` - ``zero_or_one`` ------------ .. index:: ts_in_list/4 .. _linda/0::ts_in_list/4: ``ts_in_list/4`` ^^^^^^^^^^^^^^^^ Synchronized predicate to remove a tuple matching one of multiple patterns or register a waiting client. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_in_list(TupleList,ClientId,OutputStream,Found)`` | **Mode and number of proofs:** | ``ts_in_list(+list,+term,+term,-compound)`` - ``one`` ------------ .. index:: ts_rd/4 .. _linda/0::ts_rd/4: ``ts_rd/4`` ^^^^^^^^^^^ Synchronized predicate to read a matching tuple or register a waiting client. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_rd(Tuple,ClientId,OutputStream,Found)`` | **Mode and number of proofs:** | ``ts_rd(+term,+term,+term,-compound)`` - ``one`` ------------ .. index:: ts_rd_noblock/2 .. _linda/0::ts_rd_noblock/2: ``ts_rd_noblock/2`` ^^^^^^^^^^^^^^^^^^^ Synchronized predicate to try reading a matching tuple without blocking. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_rd_noblock(Tuple,Found)`` | **Mode and number of proofs:** | ``ts_rd_noblock(+term,-compound)`` - ``zero_or_one`` ------------ .. index:: ts_rd_list/4 .. _linda/0::ts_rd_list/4: ``ts_rd_list/4`` ^^^^^^^^^^^^^^^^ Synchronized predicate to read a tuple matching one of multiple patterns or register a waiting client. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_rd_list(TupleList,ClientId,OutputStream,Found)`` | **Mode and number of proofs:** | ``ts_rd_list(+list,+term,+term,-compound)`` - ``one`` ------------ .. index:: ts_findall_rd_noblock/3 .. _linda/0::ts_findall_rd_noblock/3: ``ts_findall_rd_noblock/3`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Synchronized predicate to collect all tuples matching a pattern. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_findall_rd_noblock(Template,Tuple,List)`` | **Mode and number of proofs:** | ``ts_findall_rd_noblock(+term,+term,-list)`` - ``zero_or_more`` ------------ .. index:: ts_findall_in_noblock/3 .. _linda/0::ts_findall_in_noblock/3: ``ts_findall_in_noblock/3`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Synchronized predicate to collect and remove all tuples matching a pattern. | **Compilation flags:** | ``static, synchronized`` | **Template:** | ``ts_findall_in_noblock(Template,Tuple,List)`` | **Mode and number of proofs:** | ``ts_findall_in_noblock(+term,+term,-list)`` - ``zero_or_more`` ------------ Operators --------- (none)