\documentclass{article}
\usepackage{axiom}
\begin{document}

\title{src/algebra moebius.spad}
\author{Stephen M. Watt}
\maketitle

\begin{abstract}
\end{abstract}

\tableofcontents
\eject

\section{domain MOEBIUS MoebiusTransform}
<<domain MOEBIUS MoebiusTransform>>=
import OnePointCompletion
)abbrev domain MOEBIUS MoebiusTransform
++ 2-by-2 matrices acting on P1(F).
++ Author: Stephen "Say" Watt
++ Date Created: January 1987
++ Date Last Updated: 11 April 1990
++ Keywords:
++ Examples:
++ References:
MoebiusTransform(F): Exports == Implementation where
  ++ MoebiusTransform(F) is the domain of fractional linear (Moebius)
  ++ transformations over F.
  F : Field
  OUT ==> OutputForm
  P1F ==> OnePointCompletion F         -- projective 1-space over F
 
  Exports ==> Group with
 
    moebius: (F,F,F,F) -> %
      ++ moebius(a,b,c,d) returns \spad{matrix [[a,b],[c,d]]}.
    shift: F -> %
      ++ shift(k) returns \spad{matrix [[1,k],[0,1]]} representing the map 
      ++ \spad{x -> x + k}.
    scale: F -> %
      ++ scale(k) returns \spad{matrix [[k,0],[0,1]]} representing the map 
      ++ \spad{x -> k * x}.
    recip: () -> %
      ++ recip() returns \spad{matrix [[0,1],[1,0]]} representing the map 
      ++ \spad{x -> 1 / x}.
    shift: (%,F) -> %
      ++ shift(m,h) returns \spad{shift(h) * m} 
      ++ (see \spadfunFrom{shift}{MoebiusTransform}).
    scale: (%,F) -> %
      ++ scale(m,h) returns \spad{scale(h) * m}
      ++ (see \spadfunFrom{shift}{MoebiusTransform}).
    recip: % -> %
      ++ recip(m) = recip() * m
    eval: (%,F) -> F
      ++ eval(m,x) returns \spad{(a*x + b)/(c*x + d)} 
      ++ where \spad{m = moebius(a,b,c,d)}
      ++ (see \spadfunFrom{moebius}{MoebiusTransform}).
    eval: (%,P1F) -> P1F
      ++ eval(m,x) returns \spad{(a*x + b)/(c*x + d)} 
      ++ where \spad{m = moebius(a,b,c,d)}
      ++ (see \spadfunFrom{moebius}{MoebiusTransform}).

  Implementation ==> add
 
    Rep := Record(a': F,b': F,c': F,d': F)
 
    moebius(aa,bb,cc,dd) == [aa,bb,cc,dd]
 
    a(t:%):F == t.a'
    b(t:%):F == t.b'
    c(t:%):F == t.c'
    d(t:%):F == t.d'
 
    1 == moebius(1,0,0,1)
    t * s ==
      moebius(b(t)*c(s) + a(t)*a(s), b(t)*d(s) + a(t)*b(s), _
              d(t)*c(s) + c(t)*a(s), d(t)*d(s) + c(t)*b(s))
    inv t == moebius(d(t),-b(t),-c(t),a(t))
 
    shift f == moebius(1,f,0,1)
    scale f == moebius(f,0,0,1)
    recip() == moebius(0,1,1,0)
 
    shift(t,f) == moebius(a(t) + f*c(t), b(t) + f*d(t), c(t), d(t))
    scale(t,f) == moebius(f*a(t),f*b(t),c(t),d(t))
    recip(t: %): % == moebius(c(t),d(t),a(t),b(t))
 
    eval(t:%,f:F) == (a(t)*f + b(t))/(c(t)*f + d(t))
    eval(t:%,f:P1F) ==
      (ff := retractIfCan(f)@Union(F,"failed")) case "failed" =>
        (a(t)/c(t)) :: P1F
      zero?(den := c(t) * (fff := ff :: F) + d(t)) => infinity()
      ((a(t) * fff + b(t))/den) :: P1F
 
    coerce t ==
      var := "%x" :: OUT
      num := (a(t) :: OUT) * var + (b(t) :: OUT)
      den := (c(t) :: OUT) * var + (d(t) :: OUT)
      rarrow(var,num/den)
 
    proportional?: (List F,List F) -> Boolean
    proportional?(list1,list2) ==
      empty? list1 => empty? list2
      empty? list2 => false
      zero? (x1 := first list1) =>
        (zero? first list2) and proportional?(rest list1,rest list2)
      zero? (x2 := first list2) => false
      map(#1 / x1,list1) = map(#1 / x2,list2)
 
    t = s ==
      list1 : List F := [a(t),b(t),c(t),d(t)]
      list2 : List F := [a(s),b(s),c(s),d(s)]
      proportional?(list1,list2)

@
\section{License}
<<license>>=
--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
--    - Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--
--    - Redistributions in binary form must reproduce the above copyright
--      notice, this list of conditions and the following disclaimer in
--      the documentation and/or other materials provided with the
--      distribution.
--
--    - Neither the name of The Numerical ALgorithms Group Ltd. nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@
<<*>>=
<<license>>

<<domain MOEBIUS MoebiusTransform>>
@
\eject
\begin{thebibliography}{99}
\bibitem{1} nothing
\end{thebibliography}
\end{document}