While message queues realizes communicating agents sharing the same program and optionally dynamic data, the predicate thread_wait/2 facilitates agents that communicate based on a shared blackboard. An important difference is were message queues require the sender and receiver to know about the queue used to communicate and every message can wakeup at most one thread, the blackboard model allows any number (including zero) of threads to listen to changes on the blackboard. Any module can act as a blackboard. The blackboard can be updated using the standard Prolog database update predicates (assert/1, retract/1 and friends).
Waiting is implemented using a POSIX condition variable and matching mutex. On a matching database change the condition variable is signalled using a broadcast, waking up all threads waiting in thread_wait/2. Multiple database updates can be grouped and cause a single wakeup using thread_update/2. This predicate also allows signalling the module condition variable without updating the database and controlling whether all or a single thread is activated.
The blackboard architecture is a good match for an intelligent agent system that has to react on a changing world. Input threads gather sensor data from the world and update a shared world view in a set of dynamic predicates in one or more modules. Agent threads listen to this data or a subset thereof and trigger actions. This is notably a good match with tabling, in particular incremental tabling (see section 7.7) and Well Founded Semantics (see section 7.6).205Future versions may provide additional triggers, for example to learn about invalidated tables. Please share your experience.
The wait is associated with a module. This module is derived from the Options argument.
The Options list specifies when Goal is re-evaluated and optionally when the call terminates due to a timeout.
wait_preds(+Preds)
is not provided.+
(PI)
207Note
that +p/1
is read as /(+(p),1)., Goal is only triggered if
a clause was added (assert/1).
If the element is -
(PI)
, Goal is
only triggered if a clause was retracted (retract/1
or
erase/1).
Default is to wakeup on both assert and retract.wait_preds
option that have been modified.
List must be unbound at entry.The execution of Goal is synchronized between all threads calling this predicate on the same module, changes to dynamic predicates in this module and calls to thread_update/2 on the same module.
This predicate raises a permision_error
exception when
called recursively or called from inside a transaction. See
section 4.14.1.2 for
details about interaction with transactions.
broadcast
,
default) or a single thread (signal
).
Compatibility The thread_wait/2
predicate is modelled after the
Qu-Prolog
predicate thread_wait_on_goal/2.
It is largely compatible. Our current implementation does not support
predicate time stamps.208See predicate_property/2,
property generation
. We made this predicate
act on a specific module rather than the entire database. The timeout
specification follows that of the other thread waiting predicates and
may be combined with the retry_every
option. The default
retry-time is also 1 second rather than infinite.