% $Id: overloaded.tex,v 1.1.1.6 2005/01/26 13:42:23 nthiery Exp $
\begin{Mhelppage}{overloaded}{N.~Thiéry}
  [ImplState=stable,TestState=stable,DocState=stable]
%\Mproofread{user}{date}{comment}

\begin{MInfo}
  \eng{conversions and overloaded functions}
\end{MInfo}

\MDeclareOption{\Explicit}{Explicit}
\MDeclareOption{\Facade}{Facade}
\MDeclareOption{\Default}{Default}
\MDeclareOption{\Cost}{Cost}

\begin{MIntro}
  \eng{The library \Mthis{} provides a framework for conversions
    between domains. It also allows for defining multiparameter
    overloaded functions.}
\end{MIntro}

\MKeywords{conversions,overloading,multi-parameter overloading}

\begin{MDetails}
  \eng{In the first place, \Mthis{} is a library which allows for
    declaring and using conversions between \mupad{} domains.
    Those conversions can be implicit or explicit. }
  
  \eng{Implicit conversions can be used automatically by the system,
    for example in overloaded function calls (see below). They are
    applied transitively: if there is a conversion from $A$ to $B$,
    and one from $B$ to $C$, then this provides by composition a
    conversion from $A$ to $C$; we call this a \emph{composite}
    conversion.}
  
  \eng{At any given time, there is at most one conversion between two
    domains $A$ and $B$. On the other hand there may be several
    possible composite conversions. To resolve this, implicit
    conversions have an associated weight which is additive versus
    composition.  This weight is supposed to represent a rough
    evaluation of the cost of the conversion. When two composite
    conversions are possible, one with minimal weight is chosen.}
  
  \eng{Explicit conversions are only applied when requested explicitly
    (see \Mup{operators::overloaded::convertExplicit}). They are not
    applied transitively.}
  
  \eng{\Mthis{} is also a domain whose objects are multi-parameter
    overloaded functions \Mex{f}, which may have several simultaneous
    implementations with associated signatures (here, a
    \emph{signature} consists of a list of \mupad{} domains, which
    represent the domains of the arguments; the domain of the result
    is not included in this signature). When such a function is called
    as \Mex{f(a,b,c)}, it looks up the list of the domains of its
    arguments \Mex{a}, \Mex{b}, and \Mex{c} (as returned by
    \Mup{domtype}), tries to match them with the available signatures,
    and chooses accordingly the appropriate implementation.}
  
  \eng{This is a new library. It has been already used quite
    extensively, but all the aspects of its semantic are not yet
    completely fixed. The long term goal is to use it as a complete
    and systematic replacement of the current conversion mechanism of
    \mupad{}, and in particular to have
    \Mex{\Mthis{}::convertExplicit} replace the standard \Mup{convert}
    function. Feedback is particularly welcome.}
\end{MDetails}


\begin{MDomElConst}
  \MCall{default, \Mopt{signatures}
  }
%  \MCall{}
\end{MDomElConst}

\begin{MParameters}
  \param{default}%
  \eng{A function.}
  \param{signatures}%
  \eng{A table associating implementations to signatures.}
\end{MParameters}

\begin{MDetails}
  \eng{\Mex{\Mthis(default, \Mopt{signatures})} returns a new
    overloaded function, with \Mpar{default} as default
    implementation, and with signatures and corresponding
    implementations taken from \Mpar{signatures}.}
\end{MDetails}


\begin{MMethodDetails}{declareDomain}
  \infoEng{declaration of a domain}
  \call{
    \Mtype{\mupad{} domain} F
  }
  \eng{Declares a new domain for which conversions might be declared.}
\end{MMethodDetails}

\begin{MMethodDetails}{declareConversion}
  \infoEng{declaration of a new conversion}
  \call{
    \Mtype{\mupad{} domain} F,
    \Mtype{\mupad{} domain} G,
    \Mtype{function} conversion
    \Mopt{, option}
  }%
  \eng{Declares a new conversion from the domain \Mpar{F} to the
    domain \Mpar{G} implemented by \Mpar{conversion}. The optional
    parameter \Mpar{option} can be either \Explicit, to declare an
    explicit conversion, or describe the weight of the conversion.
    This weight can be a positive (non-negative?) rational (real?)
    number, or one of the predefined weights \Default or \Facade.
    Until proper weight scales are proposed, we strongly recommend to
    only use those predefined weights.}
  
  \eng{The weight \Facade{} should be used when the conversion
    represents the inclusion of a system domain (say for example \Mup{DOM_INT})
    into a facade domain (say \Mup{Dom::Integer}); in this case,
    \Mpar{conversion} should be the identity \Mex{id}.}
  % Link to the doc of Facade domain
  
  \eng{\Mpar{conversion} should be a function taking an element of the
    domain \Mpar{F}, and returning an element of the domain \Mpar{G}
    (note that, for a facade domain \Mpar{G}, the domain of an element
    of \Mpar{G} may differ from \Mpar{G}).  If the conversion cannot be
    done, an error should be raised.}
  
  \eng{If a different conversion already exists from \Mpar{F} to
    \Mpar{G}, the former conversion is silently overwritten.
    %, and a warning is issued
  }
\end{MMethodDetails}

\begin{MMethodDetails}{convert}
  \infoEng{conversion of an object}
  \call{object, \Mtype{MuPAD domain} G}%
  \eng{Converts \Mpar{object} into the domain \Mpar{G} using only
    implicit conversions, if this is possible; otherwise, returns
    \Mup{FAIL}. In the case where \Mpar{G} is a facade domain, the
    domain of the result may differ from \Mpar{G}.} %%% reread
\end{MMethodDetails}

\begin{MMethodDetails}{convertExplicit}
  \infoEng{explicit conversion of an object}
  \call{object, \Mtype{MuPAD domain} G}%
  \eng{Similar to \Mup{convert}, but both implicit and explicit
    conversions may be applied.}
  
  \eng{This method is typically intended to be used in the
    implementation of the constructor \Mpar{new} or of the method
    \Mpar{convert} of a domain. See also the category
    \Mup{Cat::UseOverloading}.}
\end{MMethodDetails}

\begin{MMethodDetails}{conversion}
  \infoEng{conversion between domains}
  \call{\Mtype{MuPAD domain} F, \Mtype{MuPAD domain} G}%
  \eng{Returns the minimum weight conversion between \Mpar{F} and
    \Mpar{G}. The result is a list of functions \Mex{[f1,\Mseq{},fk]}
    such that an element \Mex{x} of \Mpar{F} can be converted into an
    element of \Mpar{G} by \Mex{(fk@\Mseq{}@f2@f1)(x)}. If there is no
    such conversion, \Mup{FAIL} is returned.}
  \call{\Mtype{MuPAD domain} F, \Mtype{MuPAD domain} G, \Cost}%
  \eng{Same as above, but returns the cost of the conversion, or
    \Mup{FAIL}.}
\end{MMethodDetails}

\begin{MMethodDetails}{printConversions}
  \infoEng{summary of existing conversions}
  \call{}%
  \eng{Outputs a quick summary of the existing conversions.}
\end{MMethodDetails}

\begin{MMethodDetails}{declareSignature}
  \infoEng{declaration of a new signature}
  \call{
    \Mtype{overloaded function} f,
    \Mtype{list of \mupad{} domains} signature,
    \Mtype{function} implementation
  }

  \eng{Declares a new signature for the overloaded function \Mex{f},
    implemented by \Mpar{implementation}.}
\end{MMethodDetails}

\begin{MExample}{ex-conversion}
  \eng{We start by using some predefined conversions. Here is how to
    convert an integer into an element of $\mathbb{Z}/3\mathbb{Z}$
    using the canonical projection:}.
  \begin{Mexin}
Z3 := Dom::IntegerMod(3):
a := operators::overloaded::convert(7, Z3)
  \end{Mexin}
  \begin{Mexout}
                            1 mod 3
  \end{Mexout}
  \eng{Then, we can embed $\mathbb{Z}/3\mathbb{Z}$ into an algebraic
    extension, and do the conversion:}
  \begin{Mexin}
K := Dom::AlgebraicExtension(Z3, X^2=1):
b := operators::overloaded::convert(a, K);
domtype(b)
  \end{Mexin}
  \begin{Mexout}
                               1

                                               2
  Dom::AlgebraicExtension(Dom::IntegerMod(3), X  - 1 = 0, X)
  \end{Mexout}
  \eng{Being aware of the two basic conversions above, the system can
    apply them transitively: }
  \begin{Mexin}
operators::overloaded::convert(7, K)
  \end{Mexin}
  \begin{Mexout}
                               1
  \end{Mexout}
  \eng{Currently only the natural conversions between the basic
    \mupad{} domains are predefined in the system:}
  \begin{Mexin}
operators::overloaded::printConversions()
  \end{Mexin}
  \begin{Mexout}
Dom::IntegerMod(3)      -> Dom::AlgebraicExtension(Dom::IntegerMod(3), X^2 - 1 = 0, X)
DOM_COMPLEX     -> Dom::Complex
Dom::Float      -> Dom::Complex
Dom::Rational   -> Dom::Complex
DOM_EXPR        -> Dom::ExpressionField()
DOM_IDENT       -> Dom::ExpressionField()
Dom::Complex    -> Dom::ExpressionField()
Dom::Real       -> Dom::ExpressionField()
DOM_FLOAT       -> Dom::Float
Dom::Rational   -> Dom::Float
DOM_INT         -> Dom::Integer
Dom::Integer    -> Dom::IntegerMod(3)
DOM_RAT         -> Dom::Rational
Dom::Integer    -> Dom::Rational
Dom::Float      -> Dom::Real
Dom::Rational   -> Dom::Real
  \end{Mexout}
  \eng{Most of those conversions are actually trivial, since the
    target domains are facade domains like \Mex{Dom::Integer}.
    Furthermore, for parametrized domains like
    \Mupc{Dom::IntegerMod}{3}, the conversions are declared on the fly
    when the domains are created.}
  
  \eng{It is easy to extend the system to deal with new domains and
    conversions. We define the ring \Mex{P} of univariate polynomials
    over \Mex{K}, declare it to the conversion system, and declare the
    canonical embedding from the field \Mex{K}::}
  \begin{Mexin}
P := Dom::UnivariatePolynomial(x, K):
operators::overloaded::declareDomain(P):
operators::overloaded::declareConversion(K, P, 
                  c -> multcoeffs(P::one, c)):
  \end{Mexin}
  \begin{Mexout}
  \end{Mexout}
  \eng{Now, we indifferently can do conversions from the integers,
    from $\Mex{Z3}$, or from $\Mex{K}$ into \Mex{P}:}
  \begin{Mexin}
c := operators::overloaded::convert(7, P);
domtype(c)
  \end{Mexin}
  \begin{Mexout}
                               1

Dom::UnivariatePolynomial(x, Dom::AlgebraicExtension(

                        2
   Dom::IntegerMod(3), X  - 1 = 0, X), LexOrder)
  \end{Mexout}
\end{MExample}

\begin{MExample}{ex-overloaded}
  \eng{We define a new overloaded function \Mex{myconcat} which, by
    default, returns an unevaluated call:}
  \begin{Mexin}
myconcat := operators::overloaded
(() -> (userinfo(0, "default implementation"); hold(myconcat)(args())),
 table([DOM_STRING, DOM_STRING] =
         ((s1,s2) -> (userinfo(0, "concatenating strings"); s1.s2)),
       [DOM_LIST,   DOM_LIST]   =
         ((s1,s2) -> (userinfo(0, "concatenating lists"); s1.s2)))):
  \end{Mexin}
  \eng{\Mex{myconcat} can be used indifferently to concatenate two
    strings or two lists:}
  \begin{Mexin}
setuserinfo(Any, 1):
setuserinfo(Graph, 0):
myconcat("bla", "ble");
myconcat([1, 2, 3], [4, 5, 6])
  \end{Mexin}
  \begin{Mexout}
Info: concatenating strings

                           "blable"
Info: concatenating lists

                      [1, 2, 3, 4, 5, 6]
  \end{Mexout}
  \eng{By default, an unevaluated call is returned:}
  \begin{Mexin}
myconcat(35, 73)
  \end{Mexin}
  \begin{Mexout}
Info: default implementation

                       myconcat(35, 73)
  \end{Mexout}
  \eng{Let us extend the concatenation to integers, in a non standard way:}
  \begin{Mexin}
operators::overloaded::declareSignature
  (myconcat,
   [Dom::Integer, Dom::Integer],
   (x, y) -> (userinfo(0, "concatenating integers");
              text2expr(expr2text(x).expr2text(y)))):
myconcat(35, 73)
  \end{Mexin}
  \begin{Mexout}
Info: concatenating integers

                             3573
  \end{Mexout}
  \eng{Of course, this is not very well defined, in particular if the
    second argument is negative!}
  \begin{Mexin}
myconcat(35, -73)
  \end{Mexin}
  \begin{Mexout}
Info: concatenating integers

                            35 - 73
  \end{Mexout}
  \begin{Mexin}
setuserinfo(Any, 0):
  \end{Mexin}
  \begin{Mexout}
  \end{Mexout}
%
  \eng{The point of all this is just to highlight the fact that the
    programmer should be very careful with the semantic of the
    conversions and overloaded operators he or she defines. The system
    does not check that they are consistent in any way; in most cases
    that would be impossible.}%

  \eng{To conclude here are some examples of not-so-well defined
    conversions that are likely to produce problems in a larger scale
    environment:}
  \begin{Mexin}
operators::overloaded::declareDomain(DOM_IDENT):
operators::overloaded::declareDomain(DOM_STRING):
operators::overloaded::declareConversion(DOM_IDENT, DOM_STRING, expr2text):
myconcat(bla,   "ble");
myconcat("bla", ble);
myconcat(bla,   ble)
  \end{Mexin}
  \begin{Mexout}
                           "blable"

                           "blable"

                           "blable"
  \end{Mexout}
  \eng{Note in particular what happens in the last computation: the
    system did not know how to concatenate two identifiers; so it
    decided to lift \emph{both} identifiers into strings, and
    concatenate them as strings. In some cases, this behavior is
    perfectly acceptable (the result may, for example, live in a
    domain that is isomorphic to the domain of at least one of the
    operands), but in most cases it is not. In a future version of
    this library, we plan to provide means to forbid such
    conversions.}
\end{MExample}

\begin{MBackground}
  \eng{\Mwarn{Overloaded functions shows the so-called a reference
      effect. This is required to be able to add new signatures to an
      existing overloaded function. Technically, this is achieved
      through closures. % link to the def of closures in the MuPAD doc
    }}
  
  \eng{Implicit conversions should be canonical in the sense that, if
    there are two different ways to convert an element of a domain $A$
    to a domain $D$ (say, $A\mapsto B \mapsto D$, or $A\mapsto
    C\mapsto D$) then the two conversions should yield mathematically
    equivalent results. In other words, the diagram of implicit
    conversions should be commutative. This does not rule out loops in
    the conversion diagram, and conversions are neither required to be
    injective nor surjective. Here are some typical good candidates
    for implicit conversions:
    \begin{itemize}
    \item \Mup{Dom::Integer} to \Mup{Dom::Rational} (natural embedding
      of sets);
    \item \Mup{DOM_INT} to \Mup{Dom::Integer} (system representation
      to facade domain);
    \item \Mup{Dom::Rational} to \Mupc{Dom::UnivariatePolynomial}{[x],
        Dom::Rational} (natural embedding from the ground field of a
      ring with one);
    \item \Mup{Dom::Rational} to
      \Mupc{Dom::AlgebraicExtension}{Dom::Rational, x^2=2} (natural
      embedding of a field into an extension field);
    \item \Mup{Dom::Integer} to \Mupc{Dom::IntegerMod}{4} (canonical
      projection);
    \item \Mex{(\Mex{examples::SymmetricFunctions}{})::p} to
      \Mex{(\Mex{examples::SymmetricFunctions}{})::s} (canonical
      isomorphism between different representations of a fixed
      ring over several basis). Note: those domains are defined in the
      \Mex{Combinat} package.
    \end{itemize}

    On the other hand, the conversion from the indexes of a basis of a
    vector space to this vector space (say, for example, from
    partitions to monomial symmetric functions) are usually not
    canonical, and in most cases should not be declared as implicit.
    
    In most cases, those rules of thumb are enough for the programmer
    for deciding whether a conversion should be implicit or explicit.
    However a more subtle issue can arise: to be on the safe side, an
    implicit conversion $A\mapsto B$ should be a morphism for each and
    every overloaded function that is defined on $B$. }

  %\eng{}
\end{MBackground}

\begin{MChanges}
  \version{3}%
  \eng[New library]{\Mthis{} is a new library} %
\end{MChanges}

\end{Mhelppage}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: main
%%% TeX-master: t
%%% End: 
