Dear all,

below is a search engine with timeout -- perhaps handy for somebody else ;-) Comments are welcome!

This is the core of some realtime constraint programming stuff I am currently working on.

Best
Torsten


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% test cases
%%

%% finding a solution within 100 msecs
declare
proc {MyScript Xs}
   Xs = {FD.list 3 60#72}
   {FD.distinct Xs}
   {FD.distribute ff Xs}
end
{Browse {RT.searchWithTimeout MyScript
         unit(maxSearchTime:100)}}


%% timeout: 1 msec search time is usually not enough (sometimes it works..)
%% default solution returned, and message printed at stdout.
%% NB: Oz scheduling probably not to 1 msec exact anyway, max precision 10 msecs??
declare
proc {MyScript Xs}
   Xs = {FD.list 3 60#72}
   {FD.distinct Xs}
   {FD.distribute ff Xs}
end
SolScore = {RT.searchWithTimeout MyScript
            unit(maxSearchTime:1
                 defaultSolution:nil)}
{Browse SolScore}


%% script failure. defaultSolution returned and message printed at stdout.
declare
proc {MyScript Xs}
   Xs = {FD.list 3 1#10}
   %% contradiction
   {FD.distinct Xs}
   {Nth Xs 1} = {Nth Xs 3}
   %%
   {FD.distribute ff Xs}
end
SolScore = {RT.searchWithTimeout MyScript
            unit(defaultSolution:failure
                 comment:'script with contradiction')}
{Browse SolScore}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% implementation
%%

/** %% SearchWithTimeout is a 'meta search engine' with a timeout: in case a user-specified maximum search time is elapsed, a user-specified default solution is returned (defaults to nil). %% MyScript is a unary procedure defining the CSP plus a distribution strategy. Args is a record of the following optional arguments (feature-value pairs). The argument maxSearchTime specifies the maximum search time in msecs (default: 1000). The default solution is given at the argument defaultSolution. The argument solver specifies the solver to use. The solver must be a procedure with the following interface {MySolver MyScript KillP MyScore}, and it must return a list with solution(s), or nil in case of no solution (only the first solution is ever used). The default solver is

   proc {$ MyScript KillP ?MyScore}
      MyScore = {Search.one.depth MyScript 1 KillP}
   end

%% In case of a timeout or a fail, a warning is printed at stdout, together with Args (e.g., additional Arg features can be handed over for a more informative warning).
   %%
%% NB: only searching is terminated after timeout: a script with keeps computing forever without search (e.g., because it contains an infinite loop) can not be killed.
   %% */
   proc {SearchWithTimeout MyScript Args ?Result}
      Defaults = unit(maxSearchTime:1000
                      defaultSolution:nil
                      solver:proc {$ MyScript KillP ?MyScore}
                                MyScore = {Search.one.depth MyScript 1 KillP}
                             end)
      As = {Adjoin Defaults Args}
      KillSearchP
%% Result is either Solution or As.defaultSolution (in case of timeout or failure)
      Solution                  
   in
      thread Solution = {As.solver MyScript KillSearchP} end

      %% Output solution as soon as it is found. However, stop search
      %% if no solution is found after As.maxSearchTime msecs and
      %% return As.defaultSolution instead.
      %%
      %% These two threads terminate each other as soon as there
      %% respective condition is fulfilled.
      local
         Thread1 Thread2
      in
         thread
            Thread1 = {Thread.this}
            {Wait Solution}
            %% stop other thread. raises an exception kernel(terminate ...)
            {Thread.terminate Thread2}
            if Solution == nil
            then
               Result = As.defaultSolution
               {System.showInfo
                "SearchWithTimeout: no solution! args:\n"
                #{Value.toVirtualString As 3 1000}}
            else Result = Solution.1
            end
         end    
         thread
            Thread2 = {Thread.this}
            %% max waiting time
            {Delay As.maxSearchTime}
            {KillSearchP}
            %% stop other thread
            {Thread.terminate Thread1}
            Result = As.defaultSolution
            {System.showInfo
             "SearchWithTimeout: search timeout! args:\n"
             #{Value.toVirtualString As 3 1000}}
         end
      end
   end



--
Torsten Anders
Interdisciplinary Centre for Computer Music Research
University of Plymouth
strasheela.sourceforge.net
www.torsten-anders.de




_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users

Reply via email to