<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="4.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  xmlns:map="http://www.w3.org/2005/xpath-functions/map"
  xmlns:math="http://www.w3.org/2005/xpath-functions/math"
  xmlns:array="http://www.w3.org/2005/xpath-functions/array"
  xmlns:tm="http://www.datenverdrahten.de/tm"
  xmlns:cx="http://example.org/cx"
  xmlns="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="#all"
  expand-text="yes">

  <!-- by T. Meinike 11/22 -->

  <xsl:output method="xml" version="1.0" html-version="5" encoding="UTF-8"
    indent="yes" include-content-type="no" omit-xml-declaration="yes"/>

  <xsl:template name="xsl:initial-template">

    <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html>&#xA;</xsl:text>
    <html lang="de">
      <head>
        <meta charset="UTF-8"/>
        <title>Redord Type</title>
        <style>* {{ font-family: sans-serif; }}
               p {{ color: #090; font-weight: bold; }}
              h2 {{ color: #666; }}</style>
      </head>
      <body>
        <h1>Record Type</h1>
        <!-- zum Thema Komplexe Zahlen: https://de.wikipedia.org/wiki/Komplexe_Zahl -->

        <h2>Addition komplexer Zahlen</h2>
        <xsl:variable name="result1" as="map(*)" select="cx:add(cx:complex(7,5), cx:complex(3,3))"/>
        <p>(7 + 5i) + (3 + 3i) = {$result1?r} + {$result1?i}i</p>

        <h2>Subtraktion komplexer Zahlen</h2>
        <xsl:variable name="result2" as="map(*)" select="cx:sub(cx:complex(10,20), cx:complex(7,-3))"/>
        <p>(10 + 20i) - (7 - 3i) = {$result2?r} + {$result2?i}i</p>
 
        <h2>Multiplikation komplexer Zahlen</h2>
        <xsl:variable name="result3" as="map(*)" select="cx:mul(cx:complex(5,-2), cx:complex(3,4))"/>
        <p>(5 - 2i) * (3 + 4i) = {$result3?r} + {$result3?i}i</p>

        <h2>Division komplexer Zahlen</h2>
        <xsl:variable name="result4" as="map(*)" select="cx:div(cx:complex(2,3), cx:complex(1,-4))"/>
        <p>(2 + 3i) / (1 - 4i) = {$result4?r} + {$result4?i}i</p>

        <!-- ***************************************************************************** -->

        <h2>Gemeinsames Beispiel</h2>
        <xsl:variable name="czahl1" select="cx:complex(4, 6)"/>
        <xsl:variable name="czahl2" select="cx:complex(8,-3)"/>
        <xsl:variable name="adderg" as="map(*)" select="cx:add($czahl1, $czahl2)"/>
        <xsl:variable name="suberg" as="map(*)" select="cx:sub($czahl1, $czahl2)"/>
        <xsl:variable name="mulerg" as="map(*)" select="cx:mul($czahl1, $czahl2)"/>
        <xsl:variable name="diverg" as="map(*)" select="cx:div($czahl1, $czahl2)"/>
        <p>(4 + 6i) + (8 + -3i) = {$adderg?r} + {$adderg?i}i</p>
        <p>(4 + 6i) - (8 + -3i) = {$suberg?r} + {$suberg?i}i</p>
        <p>(4 + 6i) * (8 + -3i) = {$mulerg?r} + {$mulerg?i}i</p>
        <p>(4 + 6i) / (8 + -3i) = {$diverg?r} + {$diverg?i}i</p>
      </body>
    </html>
  
  </xsl:template>

  <!-- cx:complex und cx:add übernommen von
       https://www.saxonica.com/documentation11/index.html#!v4extensions/new-types/record-types
       cx:sub, cx:mul, cx:div nachgebaut
  -->
  <xsl:function name="cx:complex" as="record(r as xs:double, i as xs:double)">
    <xsl:param name="real" as="xs:double"/>
    <xsl:param name="imag" as="xs:double"/>
    <xsl:sequence select="map{'r':$real, 'i':$imag}"/>
  </xsl:function>

  <xsl:function name="cx:add" as="record(r as xs:double, i as xs:double)">
    <xsl:param name="x" as="record(r as xs:double, i as xs:double)"/>
    <xsl:param name="y" as="record(r as xs:double, i as xs:double)"/>
    <xsl:sequence select="cx:complex($x?r + $y?r, $x?i + $y?i)"/>
  </xsl:function>

  <xsl:function name="cx:sub" as="record(r as xs:double, i as xs:double)">
    <xsl:param name="x" as="record(r as xs:double, i as xs:double)"/>
    <xsl:param name="y" as="record(r as xs:double, i as xs:double)"/>
    <xsl:sequence select="cx:complex($x?r - $y?r, $x?i - $y?i)"/>
  </xsl:function>

  <xsl:function name="cx:mul" as="record(r as xs:double, i as xs:double)">
    <xsl:param name="x" as="record(r as xs:double, i as xs:double)"/>
    <xsl:param name="y" as="record(r as xs:double, i as xs:double)"/>
    <xsl:sequence select="cx:complex($x?r * $y?r - $x?i * $y?i, $x?r * $y?i + $x?i * $y?r)"/>
  </xsl:function>

  <xsl:function name="cx:div" as="record(r as xs:double, i as xs:double)">
    <xsl:param name="x" as="record(r as xs:double, i as xs:double)"/>
    <xsl:param name="y" as="record(r as xs:double, i as xs:double)"/>
    <xsl:sequence select="cx:complex(($x?r * $y?r + $x?i * $y?i) div ($y?r * $y?r + $y?i * $y?i),
                                     ($x?i * $y?r - $x?r * $y?i) div ($y?r * $y?r + $y?i * $y?i))"/>
  </xsl:function>

</xsl:stylesheet>