
concurrent_or(+MaxThreads, +Goals, +Options)

   Execute alternative goals concurrently, using multiple threads

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

Type
   library(concurrency)

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
