<!--

   methsel.xml        recog package documentation
                                                               Max Neunhoeffer
                                                                   Ákos Seress

      Copyright (C) 2005-2008 by the authors.

   This chapter covers our own method selection.

-->

<Chapter Label="methsel">
<Heading>Method Selection</Heading>

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.<P/>

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.<P/>

Note the differences to the &GAP; method selection, which is designed
with the idea in mind that it will be quite clear in most
situations, which one is <Q>the best</Q> method for a given set of
input data, and that we do not want to try different things. On the other
hand, the &GAP; 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.<P/>

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 <Q>prove</Q>, that the whole system always does
the right thing.<P/>

<Section Label="whataremethods">
    <Heading>What are methods?</Heading>

A method is just a &GAP; 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:<P/>

<List>
<Mark><C>Success</C></Mark>
<Item>means that the method was successful and no more methods have to be
    tried.</Item>
<Mark><C>NeverApplicable</C></Mark>
<Item>means that the method was not successful and that there is no point
    to call the method again in this situation whatsoever.</Item>
<Mark><C>TemporaryFailure</C></Mark>
<Item>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.</Item>
<Mark><C>NotEnoughInformation</C></Mark>
<Item>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.</Item>
</List>

For administration in the method selection, a method is described by
a record with the following components bound:

<List>
<Mark><C>method</C></Mark>
<Item>holds the function itself.</Item>
<Mark><C>rank</C></Mark>
<Item>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.
</Item>
<Mark><C>stamp</C></Mark>
<Item>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.
</Item>
<Mark><C>comment</C></Mark>
<Item>a string valued comment. This field is optional and can be left out.
</Item>
</List>

The different methods for a certain task are collected in so-called
<Q>method databases</Q>. A <E>method database</E> 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.<P/>

There is one convenience function to put a new method into a method database:

<ManSection>
<Func Name="AddMethod" Arg="db, meth, rank, stamp [,comment]"/>
<Returns>nothing</Returns>
<Description>
    <A>db</A> must be a method database (list of records, see above) with
    non-ascending rank values. <A>meth</A> is the method function,
    <A>rank</A> the rank and <A>stamp</A> a string valued stamp. The
    optional argument <A>comment</A> 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.
</Description>
</ManSection>
</Section>

<Section Label="howcalled">
    <Heading>How methods are called</Heading>

Whenever the method selection shall be used, one calls the following
function:

<ManSection>
<Func Name="CallMethods" Arg="db, limit [,furtherargs]"/>
<Returns>a record <C>ms</C> describing this method selection procedure.
</Returns>
<Description>
    The argument <A>db</A> must be a method database in the sense of
    Section <Ref Sect="whataremethods"/>. <A>limit</A> must be a non-negative
    integer. <A>furtherargs</A> 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
    <A>db</A>.<P/>
    The function first creates a <Q>method selection</Q> 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.
</Description>
</ManSection>

The method selection record has the following components:

<List>
    <Mark><C>inapplicableMethods</C></Mark>
    <Item>a record, in which for every method that returned <C>NeverApplicable</C>
        the value 1 is bound to the component with name the stamp
        of the method.</Item>
    <Mark><C>failedMethods</C></Mark>
    <Item>a record, in which for every time a method returned <C>TemporaryFailure</C>
        the value bound to the component with name the stamp of the method
        is increased by 1 (not being bound means zero).</Item>
    <Mark><C>successMethod</C></Mark>
    <Item>the stamp of the method that succeeded, if one did. This component
        is only bound after successful completion.</Item>
    <Mark><C>result</C></Mark>
    <Item>a boolean value which is either <C>Success</C> or <C>TemporaryFailure</C>
        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.</Item>
    <Mark><C>tolerance</C></Mark>
    <Item>the number of times all methods failed until one succeeded. See
        below.</Item>
</List>

The algorithm used by <Ref Func="CallMethods"/> is extremely simple:
It sets a counter <C>tolerance</C> 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 <C>NeverApplicable</C> and did not yet return
<C>TemporaryFailure</C> more than <C>tolerance</C> times before, it is tried. According
to the value returned by the method, the following happens:

<List>
    <Mark><C>NeverApplicable</C></Mark>
    <Item>this is marked in the method selection record and the main
          loop starts again at the beginning of the method database.</Item>
    <Mark><C>TemporaryFailure</C></Mark>
    <Item>this is counted in the method selection record and the main
          loop starts again at the beginning of the method database.</Item>
    <Mark><C>NotEnoughInformation</C></Mark>
    <Item>the main loop goes to the next method in the method database.</Item>
    <Mark><C>true</C></Mark>
    <Item>this is marked in the method selection record and the procedure
          returns successfully.</Item>
</List>

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 <C>tolerance</C> is increased by one and everything
starts all over again. This is repeated until <C>tolerance</C> is greater
than the <C>limit</C> which is the second argument of
<Ref Func="CallMethods"/>. The last value of the <C>tolerance</C> counter
is returned in the component <C>tolerance</C> of the method selection
record.<P/>

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 <C>tolerance</C> increases. Once the
<C>tolerance</C> has been increased methods having returned
<C>TemporaryFailure</C> 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.<P/>

</Section>
<P/>

<!-- ############################################################ -->

</Chapter>
