A more interesting application is based on the synergy between intuitionistic and linear implication and their continuation passing couterparts assumei/1 and assume/0 and multiple engines.
The following extension is available with
:-[library(engines)].
The concrete syntaxe is
Answer<=Producer=>Consumer\ or
Answer<=Producerwhen the Consumer is the (implicit) current AND-continuation.
Producer is started on a separate engine. It produces linear facts of the form Answer, from computed answers of Goal, originating from distinct OR-branches. They are usable by Consumer as if they were assumed through use of linear implication, i.e. they are consumed one-by-one. This hides the intricacies of starting a new `orthogonal' logic engine into a simple, easy to use abstraction.
The actual implementation follows (see also file library/engines.pl):
% executes Producer on an `orthogonal' OR-engine Answer<=Producer=>Consumer:-!, % the consumer is explicit cross_run(Producer,Answer,Consumer). Answer<=Producer:- % the consumer is in the `future' cross_run_with_current_continuation(Producer,Answer). cross_run(Producer,Answer,Consumer):- default_engine_params(H,S,T), cross_run(H,S,T,Producer,Answer,Consumer). cross_run(H,S,T,Producer,Answer,Consumer):- compound(Answer),copy_term(Answer,A), new_engine(H,S,T,Producer,Answer,Handle), (A:-ask_or_kill(Handle,A))=>Consumer, destroy_engine(Handle). cross_run_with_current_continuation(Producer,Answer):- default_engine_params(H,S,T), cross_run_with_current_continuation(H,S,T,Producer,Answer). cross_run_with_current_continuation(H,S,T,Producer,Answer):- compound(Answer),copy_term(Answer,A), new_engine(H,S,T,Producer,Answer,Handle), assumei((A:-ask_or_kill(Handle,A))). ask_or_kill(Handle,Answer):-ask_engine(Handle,Answer),!. ask_or_kill(Handle,_):-destroy_engine(Handle),fail. new_engine(H,S,T,Goal,Answer,Handle):- create_engine(H,S,T,Handle), load_engine(Handle,Goal,Answer). % overridable default engine sizes for heap,stack,trail default_engine_params(H,S,T):-assumed(engine_params(H,S,T)),!. default_engine_params(128,32,32).
The following example shows how and OR-stream of answers seen as linear assumptions from an `orthogonal' engine can be used in and AND-branch.
?- a(X)<=member(X,[1,2,3])=>(a(A),a(B),a(C),write([A,B,C]),nl). [1,2,3]
If found interesting, a trully parallel, highly efficient implementation will be made available in future releases.
The same abstraction is already supported in the companion Multi-BinProlog engine, through use of real Solaris 2.x threads (see file multi/myprogs/ortho.pl). On multiple processor Sparcs this extension should allow super-linear speed-up, in the hands of a good programmer, as the answer is speculatively computed in parallel with the computations performed by Consumer. We have verified that when multiple processors are available, Multi-BinProlog background processes will tend to execute on different processors, with super-linear speed-up (see file multi/myprogs/mcolor.pl and scripts seq and par in the same directory).