  
  [1X3 Method Selection[0X
  
  The  setup  described  in  this chapter is intended for situations, in which
  lots  of  different  methods are available to fulfill a certain task, but in
  which  it  is  not  possible  in  the beginning to decide, which one to use.
  Therefore  this setup regulates, rather than just which method to choose, in
  which  order  the  various  methods are tried. The methods themselves return
  whether they were successful and, if not, whether it is sensible to try them
  again at a later stage.
  
  The  design is intentionally kept as simple as possible and at the same time
  as  versatile  as  possible,  thereby  providing a useful framework for many
  situations as described above.
  
  Note the differences to the [5XGAP[0m method selection, which is designed with the
  idea  in  mind  that it will be quite clear in most situations, which one is
  "the  best" method for a given set of input data, and that we do not want to
  try  different  things. On the other hand, the [5XGAP[0m method selection is quite
  complicated,  which  is  to some extend necessary to make sure, that lots of
  different  information  about  the objects in question can be used to really
  find the best method.
  
  Our  setup  here  in  particular has to fulfill the requirement, that in the
  end,  with  lots  of  methods installed, one still has to be able to have an
  overview and to "prove", that the whole system always does the right thing.
  
  
  [1X3.1 What are methods?[0X
  
  A  method  is  just  a  [5XGAP[0m  function  together with an agreement about what
  arguments  it  takes  and  what  result  it returns. The agreement about the
  arguments of course has to be made for every situation in which this generic
  method  selection  code  is  used,  and the user is completely free there. A
  method can (and has to) return one of the following four values:
  
  [8X[10Xtrue[0m[8X[0m
        means  that  the  method was successful and no more methods have to be
        tried.
  
  [8X[10Xfalse[0m[8X[0m
        means that the method was not successful and that there is no point to
        call the method again in this situation whatsoever.
  
  [8X[10Xfail[0m[8X[0m
        means  that  the  method  temporarily failed, that it however could be
        sensible  to  call  it  again in this situation at a later stage. This
        value  is  typical for a Las Vegas algorithm using randomised methods,
        which has failed, but which may succeed when called again.
  
  [8X[10XNotApplicable[0m[8X[0m
        means that the method for some reason refused to do its work. However,
        it is possible that it will become applicable later such that it makes
        sense to call it again, may when more information is available.
  
  For  administration  in  the  method  selection,  a method is described by a
  record with the following components bound:
  
  [8X[10Xmethod[0m[8X[0m
        holds the function itself.
  
  [8X[10Xrank[0m[8X[0m
        holds an integer used to sort the various methods. Higher numbers mean
        that  the method is tried earlier. The numbering scheme is left to the
        user.
  
  [8X[10Xstamp[0m[8X[0m
        holds  a string value that uniquely describes the method. This is used
        for bookkeeping and to keep track of what has to be tried how often.
  
  [8X[10Xcomment[0m[8X[0m
        a string valued comment. This field is optional and can be left out.
  
  The  different methods for a certain task are collected in so-called "method
  databases".  A  [13Xmethod database[0m is just a list of records, each describing a
  method in the format described above. Usually, the ranks will be descending,
  but that is not necessary.
  
  There  is  one  convenience  function  to  put  a  new  method into a method
  database:
  
  [1X3.1-1 AddMethod[0m
  
  [2X> AddMethod( [0X[3Xdb, meth, rank, stamp[, comment][0X[2X ) ____________________[0Xfunction
  [6XReturns:[0X  nothing
  
  [3Xdb[0m must be a method database (list of records, see above) with non-ascending
  rank  values.  [3Xmeth[0m is the method function, [3Xrank[0m the rank and [3Xstamp[0m a string
  valued  stamp.  The  optional  argument [3Xcomment[0m can be a string comment. The
  record describing the method is created and inserted at the correct position
  in the method database. Nothing is returned.
  
  
  [1X3.2 How methods are called[0X
  
  Whenever  the  method  selection  shall  be  used,  one  calls the following
  function:
  
  [1X3.2-1 CallMethods[0m
  
  [2X> CallMethods( [0X[3Xdb, limit[, furtherargs][0X[2X ) __________________________[0Xfunction
  [6XReturns:[0X  a record [10Xms[0m describing this method selection procedure.
  
  The argument [3Xdb[0m must be a method database in the sense of Section [14X3.1[0m. [3Xlimit[0m
  must  be  a non-negative integer. [3Xfurtherargs[0m stands for an arbitrary number
  of  additional  arguments,  which  are handed down to the called methods. Of
  course  they  must  fulfill  the  conventions defined for the methods in the
  database [3Xdb[0m.
  
  The  function first creates a "method selection" record keeping track of the
  things  that happened during the method trying procedure, which is also used
  during  this  procedure.  Then it calls methods with the algorithm described
  below and in the end returns the method selection record in its final state.
  
  The method selection record has the following components:
  
  [8X[10Xfalsemethods[0m[8X[0m
        a record, in which for every method that returned [10Xfalse[0m the value 1 is
        bound to the component with name the stamp of the method.
  
  [8X[10Xfailedmethods[0m[8X[0m
        a  record,  in  which  for every time a method returned [10Xfail[0m the value
        bound  to the component with name the stamp of the method is increased
        by 1 (not being bound means zero).
  
  [8X[10Xsuccessmethod[0m[8X[0m
        the  stamp of the method that succeeded, if one did. This component is
        only bound after successful completion.
  
  [8X[10Xresult[0m[8X[0m
        a  boolean  value  which is either [10Xtrue[0m or [10Xfail[0m depending on whether a
        successful  method  was  found  or the procedure gave up respectively.
        This  component is only bound after completion of the method selection
        procedure.
  
  [8X[10Xtolerance[0m[8X[0m
        the number of times all methods failed until one succeeded. See below.
  
  The  algorithm  used  by  [2XCallMethods[0m is extremely simple: It sets a counter
  [10Xtolerance[0m  to  zero.  The  main  loop  starts at the beginning of the method
  database and runs through the methods in turn. Provided a method did not yet
  return  [10Xfalse[0m  and did not yet return [10Xfail[0m more than [10Xtolerance[0m times before,
  it  is  tried.  According to the value returned by the method, the following
  happens:
  
  [8X[10Xfalse[0m[8X[0m
        this is marked in the method selection record and the main loop starts
        again at the beginning of the method database.
  
  [8X[10Xfail[0m[8X[0m
        this  is  counted  in  the  method  selection record and the main loop
        starts again at the beginning of the method database.
  
  [8X[10XNotApplicable[0m[8X[0m
        the main loop goes to the next method in the method database.
  
  [8X[10Xtrue[0m[8X[0m
        this  is  marked  in  the  method  selection  record and the procedure
        returns successfully.
  
  If  the  main  loop reaches the end of the method database without calling a
  method (because all methods have already failed or are not applicable), then
  the  counter  [10Xtolerance[0m  is  increased by one and everything starts all over
  again.  This  is repeated until [10Xtolerance[0m is greater than the [10Xlimit[0m which is
  the  second argument of [2XCallMethods[0m. The last value of the [10Xtolerance[0m counter
  is returned in the component [10Xtolerance[0m of the method selection record.
  
  Note that the main loop starts again at the beginning of the method database
  after  each  failed  method call! However, this does not lead to an infinite
  loop,  because  the  failure is recorded in the method selection record such
  that the method is skipped until the [10Xtolerance[0m increases. Once the [10Xtolerance[0m
  has  been  increased  methods having returned [10Xfail[0m will be called again. The
  idea behind this approach is that even failed methods can collect additional
  information  about  the arguments changing them accordingly. This might give
  methods  that come earlier and were not applicable up to now the opportunity
  to begin working. Therefore one can install very good methods that depend on
  some  already  known knowledge which will only be acquired during the method
  selection procedure by other methods, with a high rank.
  
