[ library(concurrency) | Reference Manual | Alphabetic Index ]

# concurrent_or(+MaxThreads, +Goals, +Options)

Execute alternative goals concurrently, using multiple threads

MaxThreads
  A positive integer
Goals
  A list of callable terms
Options
  A list of option terms

## Description

Execute the goals in Goals concurrently/in parallel. Succeed once the first goal succeeds, and use this goal's solution. Only one solution is computed. Fails if none of the goals has a solution. Operationally, a copy of each goal is executed in an engine. The first goal to succeed is chosen as the solution, and all others are aborted and ignored. The equivalent sequential operation could be written as:

        concurrent_or(1, Goals, _) :-
    	member(Goal, Goals),
    	copy_term(Goal, Copy),
    	call(Copy),
    	!, Goal = Copy.

A maximum of MaxThreads engines is used to work in parallel. If there are more goals than engines, engines are reused as they become available.

Use get_flag(cpu_count,N) to obtain the number of processors on the machine, which might be a good value for MaxThreads. If some solutions are expected to be easier to find than others, a higher number of threads (up to one thread per goal) can be advantageous for finding these easy solutions earlier. The latter is essentially a breadth-first-search.

The Options argument can be used to pass extra options for the creation of the worker engines. In particular, the stack size options local(KBytes) and global(KBytes) can be used to limit their memory consumption.

Due to the overheads of engine creation and destruction, this predicate is only useful for sufficiently long-running goals.

### Modes and Determinism

- concurrent_or(+, +, +) is semidet

### Modules

This predicate is sensitive to its module context (tool predicate, see @/2).

## See Also

concurrent / 3, engine_create / 2