<!--

  Copyright (C) 2006 Laurent Lemaitre <r29173@users.sourceforge.net>
  Copyright (C) 2006 Helene Parruitte <parruit@enseirb.fr>
  Copyright (C) 2006 Bertrand Ardouin <ardouin@xmodtech.com>
  Copyright (C) 2006, 2007, 2008, 2009 Stefan Jahn <stefan@lkcc.org>
  Copyright (C) 2014 Guilherme Brondani Torri <guitorri@gmail.com>

  This is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.

-->

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE admst SYSTEM "admst.dtd">
<admst version="2.3.0" xmlns:admst="http://mot-adms.sourceforge.net/xml-files/admst">

<!-- controlling variable -->
<admst:variable name="SkipFVariable" string="n"/>

<!-- temporary variable -->
<admst:variable name="pprobe"/>
<admst:variable name="qprobe"/>
<admst:variable name="e"/>
<admst:variable name="ep"/>
<admst:variable name="eq"/>
<admst:variable name="epq"/>

<!--
* Returns the type of a variable. The returned type
* is either int, double, or char *.
-->
<admst:template match="vtype">
  <admst:choose>
    <admst:when test="[type='integer']">int</admst:when>
    <admst:when test="[type='real']">double</admst:when>
    <admst:when test="[type='string']">char*</admst:when>
    <admst:otherwise>
      <admst:fatal format="variable type unknown\n"/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<!-- comparison, bit and logical operators -->
<admst:template match="bname">
  <admst:choose>
    <admst:when test="[name='bw_equr']">
      <admst:return name="bname" string="^~"/>
    </admst:when>
    <admst:when test="[name='bw_equl']">
      <admst:return name="bname" string="~^"/>
    </admst:when>
    <admst:when test="[name='bw_xor']">
      <admst:return name="bname" string="^"/>
    </admst:when>
    <admst:when test="[name='bw_or']">
      <admst:return name="bname" string="|"/>
    </admst:when>
    <admst:when test="[name='bw_and']">
      <admst:return name="bname" string="&amp;"/>
    </admst:when>
    <admst:when test="[name='or']">
      <admst:return name="bname" string="||"/>
    </admst:when>
    <admst:when test="[name='and']">
      <admst:return name="bname" string="&amp;&amp;"/>
    </admst:when>
    <admst:when test="[name='equ']">
      <admst:return name="bname" string="=="/>
    </admst:when>
    <admst:when test="[name='notequ']">
      <admst:return name="bname" string="!="/>
    </admst:when>
    <admst:when test="[name='lt']">
      <admst:return name="bname" string="&lt;"/>
    </admst:when>
    <admst:when test="[name='lt_equ']">
      <admst:return name="bname" string="&lt;="/>
    </admst:when>
    <admst:when test="[name='gt']">
      <admst:return name="bname" string="&gt;"/>
    </admst:when>
    <admst:when test="[name='gt_equ']">
      <admst:return name="bname" string="&gt;="/>
    </admst:when>
    <admst:when test="[name='shiftr']">
      <admst:return name="bname" string="&gt;&gt;"/>
    </admst:when>
    <admst:when test="[name='shiftl']">
      <admst:return name="bname" string="&lt;&lt;"/>
    </admst:when>
    <admst:otherwise>
      <admst:fatal format="variable type unknown\n"/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<!-- expression//function: get function name -->
<admst:template match="funcname">
  <admst:choose>
    <admst:when test="[name='abs']"><admst:return name="fname" string="abs"/></admst:when>
    <admst:when test="[name='\$shrinkl']"><admst:return name="fname" string="shrinkl"/></admst:when>
    <admst:when test="[name='\$shrinka']"><admst:return name="fname" string="shrinka"/></admst:when>
    <admst:when test="[name='log']"><admst:return name="fname" string="log10"/></admst:when>
    <admst:when test="[name='ln']"><admst:return name="fname" string="logE"/></admst:when>
    <admst:when test="[name='limexp']"><admst:return name="fname" string="limexp"/></admst:when>
    <admst:when test="[name='\$limexp']"><admst:return name="fname" string="limexp"/></admst:when>
    <admst:otherwise><admst:return name="fname" string="%(name)"/></admst:otherwise>
  </admst:choose>
</admst:template>

<admst:template match="fname">
  <admst:choose>
    <admst:when test="[name='abs']">abs</admst:when>
    <admst:when test="[name='\$shrinkl']">shrinkl</admst:when>
    <admst:when test="[name='\$shrinka']">shrinka</admst:when>
    <admst:when test="[name='log']">log10</admst:when>
    <admst:when test="[name='ln']">logE</admst:when>
    <admst:when test="[name='limexp']">limexp</admst:when>
    <admst:when test="[name='\$limexp']">limexp</admst:when>
    <admst:otherwise>%(name)</admst:otherwise>
  </admst:choose>
</admst:template>

<admst:template match="e">
  <admst:apply-templates select="." match="%(datatypename)">$e</admst:apply-templates>
</admst:template>

<admst:template match="ddx">
  <admst:apply-templates select="." match="%(datatypename)"/>
</admst:template>

<admst:template match="ddxname">
  <admst:return name="ddxname" string="%(name)_%($pprobe/nature/access)%($pprobe/branch/pnode/name)_%($pprobe/branch/nnode/name)_%($qprobe/nature/access)%($qprobe/branch/pnode/name)_%($qprobe/branch/nnode/name)"/>
</admst:template>

<admst:template match="dxname">
  <admst:return name="dxname" string="%(name)_%($pprobe/nature/access)%($pprobe/branch/pnode/name)_%($pprobe/branch/nnode/name)"/>
</admst:template>

<!-- variables -->
<admst:template match="variable">
  <admst:choose>
    <admst:when test="[input='yes' and parametertype='model']">
      <admst:variable name="e" path="name"/>
    </admst:when>
    <admst:when test="[input='yes' and parametertype='instance']">
      <admst:variable name="e" path="name"/>
    </admst:when>
    <admst:when test="[input='no' and scope='global_model']">
      <admst:variable name="e" path="name"/>
    </admst:when>
    <admst:when test="[input='no' and scope='global_instance']">
      <admst:variable name="e" path="name"/>
    </admst:when>
    <admst:otherwise>
      <admst:variable name="e" path="name"/>
    </admst:otherwise>
  </admst:choose>

  <admst:variable name="ep" string="0.0"/>
  <admst:if test="[insource='yes']">
    <admst:if-inside select="$pprobe" list="%(probe)">
      <admst:variable name="ep" select="%(name)_%($pprobe/nature/access)%($pprobe/branch/pnode/name)_%($pprobe/branch/nnode/name)"/>
    </admst:if-inside>
  </admst:if>
  <admst:if test="$qprobe">

  <admst:variable name="eq" string="0.0"/>
  <admst:if test="[insource='yes']">
    <admst:if-inside select="$qprobe" list="%(probe)">
      <admst:variable name="eq" select="%(name)_%($qprobe/nature/access)%($qprobe/branch/pnode/name)_%($qprobe/branch/nnode/name)"/>
    </admst:if-inside>
  </admst:if>

  <admst:variable name="epq" string="0.0"/>
  <admst:if test="[insource='yes']">
    <admst:if-inside select="$pprobe" list="%(probe)">
      <admst:if-inside select="$qprobe" list="%(probe)">
        <admst:variable name="epq" path="ddxname(.)/[name='ddxname']/value"/>
      </admst:if-inside>
    </admst:if-inside>
  </admst:if>
  </admst:if>
</admst:template>

<!-- expression//probe -->
<admst:template match="probe">
  <admst:choose>
    <admst:when test="branch/nnode[grounded='no']">
      <admst:variable name="e" select="BP(%(branch/pnode/name),%(branch/nnode/name))"/>
    </admst:when>
    <admst:otherwise>
      <admst:variable name="e" select="NP(%(branch/pnode/name))"/>
    </admst:otherwise>
  </admst:choose>

  <admst:choose>
    <admst:when test="[.=$pprobe]">
      <admst:variable name="ep" select="1.0"/>
    </admst:when>
    <admst:otherwise>
      <admst:variable name="ep" string="0.0"/>
    </admst:otherwise>
  </admst:choose>
  <admst:if test="$qprobe">

  <admst:choose>
    <admst:when test="[.=$qprobe]">
      <admst:variable name="eq" select="1.0"/>
    </admst:when>
    <admst:otherwise>
      <admst:variable name="eq" string="0.0"/>
    </admst:otherwise>
  </admst:choose>

  <admst:variable name="epq" string="0.0"/>
  </admst:if>
</admst:template>

<!-- expression//node -->
<admst:template match="node">
  <admst:fatal format="module node not expected here ... %(name)\n"/>

  <admst:fatal format="module node not expected here ... %(name)\n"/>
  <admst:if test="$qprobe">

  <admst:fatal format="module node not expected here ... %(name)\n"/>
  </admst:if>
</admst:template>

<!-- expression//string -->
<admst:template match="string">
  <admst:variable name="e" select="&quot;%(value)&quot;"/>

  <admst:variable name="ep" string="0.0"/>
  <admst:if test="$qprobe">

  <admst:variable name="eq" string="0.0"/>

  <admst:variable name="epq" string="0.0"/>
  </admst:if>
</admst:template>

<!-- expression//number -->
<admst:template match="number">
  <admst:choose>
    <admst:when test="[scalingunit='1']">
      <admst:variable name="e" path="value"/>
    </admst:when>
    <admst:when test="[scalingunit='E']">
      <admst:variable name="e" select="(%(value)*1.0e+18)"/>
    </admst:when>
    <admst:when test="[scalingunit='P']">
      <admst:variable name="e" select="(%(value)*1.0e+15)"/>
    </admst:when>
    <admst:when test="[scalingunit='T']">
      <admst:variable name="e" select="(%(value)*1.0e+12)"/>
    </admst:when>
    <admst:when test="[scalingunit='G']">
      <admst:variable name="e" select="(%(value)*1.0e+9)"/>
    </admst:when>
    <admst:when test="[scalingunit='M']">
      <admst:variable name="e" select="(%(value)*1.0e+6)"/>
    </admst:when>
    <admst:when test="[scalingunit='k']">
      <admst:variable name="e" select="(%(value)*1.0e+3)"/>
    </admst:when>
    <admst:when test="[scalingunit='h']">
      <admst:variable name="e" select="(%(value)*1.0e+2)"/>
    </admst:when>
    <admst:when test="[scalingunit='D']">
      <admst:variable name="e" select="(%(value)*1.0e+1)"/>
    </admst:when>
    <admst:when test="[scalingunit='d']">
      <admst:variable name="e" select="(%(value)*1.0e-1)"/>
    </admst:when>
    <admst:when test="[scalingunit='c']">
      <admst:variable name="e" select="(%(value)*1.0e-2)"/>
    </admst:when>
    <admst:when test="[scalingunit='m']">
      <admst:variable name="e" select="(%(value)*1.0e-3)"/>
    </admst:when>
    <admst:when test="[scalingunit='u']">
      <admst:variable name="e" select="(%(value)*1.0e-6)"/>
    </admst:when>
    <admst:when test="[scalingunit='n']">
      <admst:variable name="e" select="(%(value)*1.0e-9)"/>
    </admst:when>
    <admst:when test="[scalingunit='A']">
      <admst:variable name="e" select="(%(value)*1.0e-10)"/>
    </admst:when>
    <admst:when test="[scalingunit='p']">
      <admst:variable name="e" select="(%(value)*1.0e-12)"/>
    </admst:when>
    <admst:when test="[scalingunit='f']">
      <admst:variable name="e" select="(%(value)*1.0e-15)"/>
    </admst:when>
    <admst:when test="[scalingunit='a']">
      <admst:variable name="e" select="(%(value)*1.0e-18)"/>
    </admst:when>
    <admst:otherwise>
      <admst:fatal format="scaling unit not supported: %(scalingunit)\n"/>
    </admst:otherwise>
  </admst:choose>

  <admst:variable name="ep" string="0.0"/>
  <admst:if test="$qprobe">

  <admst:variable name="eq" string="0.0"/>

  <admst:variable name="epq" string="0.0"/>
  </admst:if>
</admst:template>

<!-- unary operations -->
<admst:template match="mapply_unary">
  <admst:choose>
    <admst:when test="[name='plus']">
      <admst:choose>
        <admst:when test="[arg1/math/value=0.0]">
          <admst:variable name="e" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:apply-templates select="arg1" match="ddx"/>
          <admst:variable name="e" select="(+$e)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='minus']">
      <admst:choose>
        <admst:when test="[arg1/math/value=0.0]">
          <admst:variable name="e" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:apply-templates select="arg1" match="ddx"/>
          <admst:variable name="e" select="(-$e)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='not']">
      <admst:choose>
        <admst:when test="[arg1/math/value=0.0]">
          <admst:variable name="e" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:apply-templates select="arg1" match="ddx"/>
          <admst:variable name="e" select="(!$e)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='bw_not']">
      <admst:choose>
        <admst:when test="[arg1/math/value=0.0]">
          <admst:variable name="e" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:apply-templates select="arg1" match="ddx"/>
          <admst:variable name="e" select="(~$e)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:otherwise>
      <admst:fatal format="%(name): function not handled\n"/>
    </admst:otherwise>
  </admst:choose>

  <admst:choose>
    <admst:when test="[$e='0.0']">
      <admst:variable name="ep" string="0.0"/>
    </admst:when>
    <admst:when test="[$ep='0.0']">
      <admst:variable name="ep" string="0.0"/>
    </admst:when>
    <admst:otherwise>
      <admst:choose>
        <admst:when test="[name='plus']">
          <admst:variable name="ep" select="(+$ep)"/>
        </admst:when>
        <admst:when test="[name='minus']">
          <admst:variable name="ep" select="(-$ep)"/>
        </admst:when>
        <admst:when test="[name='not']">
          <admst:variable name="ep" select="(!$ep)"/>
        </admst:when>
        <admst:when test="[name='bw_not']">
          <admst:variable name="ep" select="(~$ep)"/>
        </admst:when>
      </admst:choose>
    </admst:otherwise>
  </admst:choose>
  <admst:if test="$qprobe">

  <admst:choose>
    <admst:when test="[$e='0.0']">
      <admst:variable name="eq" string="0.0"/>
    </admst:when>
    <admst:when test="[$eq='0.0']">
      <admst:variable name="eq" string="0.0"/>
    </admst:when>
    <admst:otherwise>
      <admst:choose>
        <admst:when test="[name='plus']">
          <admst:variable name="eq" select="(+$eq)"/>
        </admst:when>
        <admst:when test="[name='minus']">
          <admst:variable name="eq" select="(-$eq)"/>
        </admst:when>
        <admst:when test="[name='not']">
          <admst:variable name="eq" select="(!$eq)"/>
        </admst:when>
        <admst:when test="[name='bw_not']">
          <admst:variable name="eq" select="(~$eq)"/>
        </admst:when>
      </admst:choose>
    </admst:otherwise>
  </admst:choose>

  <admst:variable name="epq" string="0.0"/>
  </admst:if>
</admst:template>

<!-- binary operations -->
<admst:template match="mapply_binary">
  <admst:apply-templates select="arg1" match="ddx"/>
  <admst:variable name="x" string="$e"/>
  <admst:variable name="xp" string="$ep"/>
  <admst:variable name="xq" string="$eq"/>
  <admst:variable name="xpq" string="$epq"/>
  <admst:apply-templates select="arg2" match="ddx"/>
  <admst:variable name="y" string="$e"/>
  <admst:variable name="yp" string="$ep"/>
  <admst:variable name="yq" string="$eq"/>
  <admst:variable name="ypq" string="$epq"/>
  <admst:choose>
    <admst:when test="[name='addp']">
      <admst:choose>
        <admst:when test="[(arg1/math/value=0.0)and(arg2/math/value=0.0)]">
          <admst:variable name="e" string="0.0"/>
          <admst:variable name="xp" string="0.0"/>
          <admst:variable name="yp" string="0.0"/>
        </admst:when>
        <admst:when test="[arg1/math/value=0.0]">
          <admst:variable name="e" select="(+$y)"/>
          <admst:variable name="xp" string="0.0"/>
        </admst:when>
        <admst:when test="[arg2/math/value=0.0]">
          <admst:variable name="e" path="$x"/>
          <admst:variable name="yp" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="e" select="($x+$y)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='addm']">
      <admst:choose>
        <admst:when test="[(arg1/math/value=0.0)and(arg2/math/value=0.0)]">
          <admst:variable name="e" string="0.0"/>
          <admst:variable name="xp" string="0.0"/>
          <admst:variable name="yp" string="0.0"/>
        </admst:when>
        <admst:when test="[arg1/math/value=0.0]">
          <admst:variable name="e" select="(-$y)"/>
          <admst:variable name="xp" string="0.0"/>
          <admst:variable name="yp" string="$ep"/>
        </admst:when>
        <admst:when test="arg2/math[value=0.0]">
          <admst:variable name="e" string="$x"/>
          <admst:variable name="yp" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="e" select="($x-$y)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='multtime']">
      <admst:choose>
        <admst:when test="[(arg1/math/value=0.0)or(arg2/math/value=0.0)]">
          <admst:variable name="e" string="0.0"/>
          <admst:variable name="x" string="0.0"/>
          <admst:variable name="y" string="0.0"/>
          <admst:variable name="xp" string="0.0"/>
          <admst:variable name="yp" string="0.0"/>
        </admst:when>
        <admst:when test="[(arg1/math/value=1.0)and(arg2/math/value=1.0)]">
          <admst:variable name="e" select="1.0"/>
          <admst:variable name="x" string="0.0"/>
          <admst:variable name="y" string="0.0"/>
          <admst:variable name="xp" string="0.0"/>
          <admst:variable name="yp" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="e" select="($x*$y)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='multdiv']">
      <admst:choose>
        <admst:when test="[arg1/math/value=0.0]">
          <admst:variable name="e" string="0.0"/>
          <admst:variable name="x" string="0.0"/>
          <admst:variable name="y" string="0.0"/>
          <admst:variable name="xp" string="0.0"/>
          <admst:variable name="yp" string="0.0"/>
        </admst:when>
        <admst:when test="[(arg1/math/value=1.0)and(arg2/math/value=1.0)]">
          <admst:variable name="e" select="1.0"/>
          <admst:variable name="x" string="0.0"/>
          <admst:variable name="y" string="0.0"/>
          <admst:variable name="xp" string="0.0"/>
          <admst:variable name="yp" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="e" select="($x/$y)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:otherwise>
      <admst:variable name="e" select="($x%(bname(.)/[name='bname']/value)$y)"/>
    </admst:otherwise>
  </admst:choose>

    <admst:choose>
      <admst:when test="[name='addp']">
        <admst:choose>
          <admst:when test="[$xp='0.0' and $yp='0.0']">
            <admst:variable name="ep" string="0.0"/>
          </admst:when>
          <admst:when test="[$xp='0.0']">
            <admst:variable name="ep" string="$yp"/>
          </admst:when>
          <admst:when test="[$yp='0.0']">
            <admst:variable name="ep" string="$xp"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="ep" select="($xp+$yp)"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='addm']">
        <admst:choose>
          <admst:when test="[$xp='0.0' and $yp='0.0']">
            <admst:variable name="ep" string="0.0"/>
          </admst:when>
          <admst:when test="[$xp='0.0']">
            <admst:variable name="ep" select="(-$yp)"/>
          </admst:when>
          <admst:when test="[$yp='0.0']">
            <admst:variable name="ep" string="$xp"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="ep" select="($xp-$yp)"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='multtime']">
        <admst:choose>
          <admst:when test="[$x='0.0' and $y='0.0']">
            <admst:variable name="ep" string="0.0"/>
          </admst:when>
          <admst:when test="[$xp='0.0' and $yp='0.0']">
            <admst:variable name="ep" string="0.0"/>
          </admst:when>
          <admst:when test="[$xp='0.0' and $yp='1.0']">
            <admst:variable name="ep" select="($x)"/>
          </admst:when>
          <admst:when test="[$xp='1.0' and $yp='0.0']">
            <admst:variable name="ep" select="($y)"/>
          </admst:when>
          <admst:when test="[$xp='0.0']">
            <admst:variable name="ep" select="($x*$yp)"/>
          </admst:when>
          <admst:when test="[$yp='0.0']">
            <admst:variable name="ep" select="$xp*$y"/>
          </admst:when>
          <admst:when test="[$xp='1.0' and $yp='1.0']">
            <admst:variable name="ep" select="($x+$y)"/>
          </admst:when>
          <admst:when test="[$xp='1.0']">
            <admst:variable name="ep" select="($y+($yp*$x))"/>
          </admst:when>
          <admst:when test="[$yp='1.0']">
            <admst:variable name="ep" select="(($xp*$y)+$x)"/>
          </admst:when>
          <admst:when test="[$x='1.0']">
            <admst:variable name="ep" string="$yp"/>
          </admst:when>
          <admst:when test="[$y='1.0']">
            <admst:variable name="ep" string="$xp"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="ep" select="(($xp*$y)+($x*$yp))"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='multdiv']">
        <admst:choose>
          <admst:when test="[$x='0.0']">
            <admst:variable name="ep" string="0.0"/>
          </admst:when>
          <admst:when test="[$xp='0.0' and $yp='0.0']">
            <admst:variable name="ep" string="0.0"/>
          </admst:when>
          <admst:when test="[$x='1.0']">
            <admst:choose>
              <admst:when test="[$yp='1.0']">
                <admst:variable name="ep" select="(-1/$y/$y)"/>
              </admst:when>
              <admst:otherwise>
                <admst:variable name="ep" select="(-$yp/$y/$y)"/>
              </admst:otherwise>
            </admst:choose>
          </admst:when>
          <admst:when test="[$xp='0.0']">
            <admst:choose>
              <admst:when test="[$yp='1.0']">
                <admst:variable name="ep" select="(-$x/$y/$y)"/>
              </admst:when>
              <admst:otherwise>
                <admst:variable name="ep" select="(-$x*$yp/$y/$y)"/>
              </admst:otherwise>
            </admst:choose>
          </admst:when>
          <admst:when test="[$xp='1.0']">
            <admst:choose>
              <admst:when test="[$yp='0.0']">
                <admst:variable name="ep" select="(1/$y)"/>
              </admst:when>
              <admst:when test="[$yp='1.0']">
                <admst:variable name="ep" select="(($y-$x)/$y/$y)"/>
              </admst:when>
              <admst:otherwise>
                <admst:variable name="ep" select="(($y-($x*$yp))/$y/$y)"/>
              </admst:otherwise>
            </admst:choose>
          </admst:when>
          <admst:otherwise>
            <admst:choose>
              <admst:when test="[$y='1.0']">
                <admst:variable name="ep" string="$xp"/>
              </admst:when>
              <admst:when test="[$yp='0.0']">
                <admst:variable name="ep" select="($xp/$y)"/>
              </admst:when>
              <admst:when test="[$yp='1.0']">
                <admst:variable name="ep" select="(($xp*$y-$x)/$y/$y)"/>
              </admst:when>
              <admst:otherwise>
                <admst:variable name="ep" select="(($xp*$y-$x*$yp)/$y/$y)"/>
              </admst:otherwise>
            </admst:choose>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:otherwise>
        <admst:variable name="ep" string="0.0"/>
      </admst:otherwise>
    </admst:choose>
  <admst:if test="$qprobe">

    <admst:choose>
      <admst:when test="[name='addp']">
        <admst:choose>
          <admst:when test="[$xq='0.0' and $yq='0.0']">
            <admst:variable name="eq" string="0.0"/>
          </admst:when>
          <admst:when test="[$xq='0.0']">
            <admst:variable name="eq" string="$yq"/>
          </admst:when>
          <admst:when test="[$yq='0.0']">
            <admst:variable name="eq" string="$xq"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="eq" select="($xq+$yq)"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='addm']">
        <admst:choose>
          <admst:when test="[$xq='0.0' and $yq='0.0']">
            <admst:variable name="eq" string="0.0"/>
          </admst:when>
          <admst:when test="[$xq='0.0']">
            <admst:variable name="eq" select="(-$yq)"/>
          </admst:when>
          <admst:when test="[$yq='0.0']">
            <admst:variable name="eq" string="$xq"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="eq" select="($xq-$yq)"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='multtime']">
        <admst:choose>
          <admst:when test="[$x='0.0' and $y='0.0']">
            <admst:variable name="eq" string="0.0"/>
          </admst:when>
          <admst:when test="[$xq='0.0' and $yq='0.0']">
            <admst:variable name="eq" string="0.0"/>
          </admst:when>
          <admst:when test="[$xq='0.0' and $yq='1.0']">
            <admst:variable name="eq" select="($x)"/>
          </admst:when>
          <admst:when test="[$xq='1.0' and $yq='0.0']">
            <admst:variable name="eq" select="($y)"/>
          </admst:when>
          <admst:when test="[$xq='0.0']">
            <admst:variable name="eq" select="($x*$yq)"/>
          </admst:when>
          <admst:when test="[$yq='0.0']">
            <admst:variable name="eq" select="$xq*$y"/>
          </admst:when>
          <admst:when test="[$xq='1.0' and $yq='1.0']">
            <admst:variable name="eq" select="($x+$y)"/>
          </admst:when>
          <admst:when test="[$xq='1.0']">
            <admst:variable name="eq" select="($y+($yq*$x))"/>
          </admst:when>
          <admst:when test="[$yq='1.0']">
            <admst:variable name="eq" select="(($xq*$y)+$x)"/>
          </admst:when>
          <admst:when test="[$x='1.0']">
            <admst:variable name="eq" string="$yq"/>
          </admst:when>
          <admst:when test="[$y='1.0']">
            <admst:variable name="eq" string="$xq"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="eq" select="(($xq*$y)+($x*$yq))"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='multdiv']">
        <admst:choose>
          <admst:when test="[$x='0.0']">
            <admst:variable name="eq" string="0.0"/>
          </admst:when>
          <admst:when test="[$xq='0.0' and $yq='0.0']">
            <admst:variable name="eq" string="0.0"/>
          </admst:when>
          <admst:when test="[$x='1.0']">
            <admst:choose>
              <admst:when test="[$yq='1.0']">
                <admst:variable name="eq" select="(-1/$y/$y)"/>
              </admst:when>
              <admst:otherwise>
                <admst:variable name="eq" select="(-$yq/$y/$y)"/>
              </admst:otherwise>
            </admst:choose>
          </admst:when>
          <admst:when test="[$xq='0.0']">
            <admst:choose>
              <admst:when test="[$yq='1.0']">
                <admst:variable name="eq" select="(-$x/$y/$y)"/>
              </admst:when>
              <admst:otherwise>
                <admst:variable name="eq" select="(-$x*$yq/$y/$y)"/>
              </admst:otherwise>
            </admst:choose>
          </admst:when>
          <admst:when test="[$xq='1.0']">
            <admst:choose>
              <admst:when test="[$yq='0.0']">
                <admst:variable name="eq" select="(1/$y)"/>
              </admst:when>
              <admst:when test="[$yq='1.0']">
                <admst:variable name="eq" select="(($y-$x)/$y/$y)"/>
              </admst:when>
              <admst:otherwise>
                <admst:variable name="eq" select="(($y-($x*$yq))/$y/$y)"/>
              </admst:otherwise>
            </admst:choose>
          </admst:when>
          <admst:otherwise>
            <admst:choose>
              <admst:when test="[$y='1.0']">
                <admst:variable name="eq" string="$xq"/>
              </admst:when>
              <admst:when test="[$yq='0.0']">
                <admst:variable name="eq" select="($xq/$y)"/>
              </admst:when>
              <admst:when test="[$yq='1.0']">
                <admst:variable name="eq" select="(($xq*$y-$x)/$y/$y)"/>
              </admst:when>
              <admst:otherwise>
                <admst:variable name="eq" select="(($xq*$y-$x*$yq)/$y/$y)"/>
              </admst:otherwise>
            </admst:choose>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:otherwise>
        <admst:variable name="eq" string="0.0"/>
      </admst:otherwise>
    </admst:choose>

    <admst:choose>
      <admst:when test="[name='addp']">
        <admst:variable name="t1" select="+$xpq"/>
        <admst:variable name="t2" select="+$ypq"/>
        <admst:variable name="epq" select="$t1$t2"/>
        <admst:choose>
          <admst:when test="[$epq='']">
            <admst:variable name="epq" string="0.0"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="epq" select="($epq)"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='addm']">
        <admst:variable name="t1" select="+$xpq"/>
        <admst:variable name="t2" select="-$ypq"/>
        <admst:variable name="epq" select="$t1$t2"/>
        <admst:choose>
          <admst:when test="[$epq='']">
            <admst:variable name="epq" string="0.0"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="epq" select="($epq)"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='multtime']">
        <admst:variable name="t1" select="+$xpq*$y"/>
        <admst:variable name="t2" select="+$xp*$yq"/>
        <admst:variable name="t3" select="+$xq*$yp"/>
        <admst:variable name="t4" select="+$x*$ypq"/>
        <admst:variable name="epq" select="$t1$t2$t3$t4"/>
        <admst:choose>
          <admst:when test="[$eq='0.0']">
            <admst:variable name="eq" string="0.0"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="eq" select="($eq)"/>
          </admst:otherwise>
        </admst:choose>
        <admst:choose>
          <admst:when test="[$epq='']">
            <admst:variable name="epq" string="0.0"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="epq" select="($epq)"/>
          </admst:otherwise>
        </admst:choose>
      </admst:when>
      <admst:when test="[name='multdiv']">
        <admst:variable name="epq" select="($xpq/$y-($xp*$yq+$xq*$yp+$x*$ypq)/$y/$y+2*$x*$yp*$yq/$y/$y/$y)"/>
      </admst:when>
    </admst:choose>
  </admst:if>
</admst:template>

<!-- ternary operations -->
<admst:template match="mapply_ternary">
  <admst:apply-templates select="arg1" match="ddx"/>
  <admst:variable name="x" string="$e"/>
  <admst:apply-templates select="arg2" match="ddx"/>
  <admst:variable name="y" string="$e"/>
  <admst:variable name="yp" string="$ep"/>
  <admst:variable name="yq" string="$eq"/>
  <admst:apply-templates select="arg3" match="ddx"/>
  <admst:variable name="z" string="$e"/>
  <admst:variable name="zp" string="$ep"/>
  <admst:variable name="zq" string="$eq"/>
  <admst:variable name="e" select="($x?$y:$z)"/>

  <admst:variable name="ep" select="($x?$yp:$zp)"/>
  <admst:if test="$qprobe">

  <admst:variable name="ep" select="($x?$yp:$zp)"/>

  <admst:variable name="epq" string="fixme"/>
  </admst:if>
</admst:template>

<!-- expression//function: mapping verilog-name == C-name of function -->
<admst:template match="function">
  <admst:choose>
    <admst:when test="[name='absdelay']">
      <admst:apply-templates select="arguments[1]" match="ddx"/>
      <admst:variable name="e" string="$e"/>
    </admst:when>
    <admst:when test="[name='ddt']">
      <admst:apply-templates select="arguments[1]" match="ddx"/>
      <admst:variable name="x" string="$e"/>
      <admst:variable name="xp" string="$ep"/>
      <admst:variable name="xq" string="$eq"/>
      <admst:variable name="xpq" string="$epq"/>
      <admst:variable name="e" select="_DDT($x)"/>
    </admst:when>
    <admst:when test="[name='\$given' or name='\$param_given']">
      <admst:variable name="arg1" path="arguments[1]"/>
      <admst:assert test="$arg1[datatypename='variable' and input='yes']" format="%(name): argument is not a parameter\n"/>
      <admst:choose>
        <admst:when test="$arg1/[parametertype='model']">
          <admst:variable name="e" select="_param_given(&quot;%($arg1/name)&quot;)"/>
        </admst:when>
        <admst:when test="$arg1/[parametertype='instance']">
          <admst:variable name="e" select="_param_given(&quot;%($arg1/name)&quot;"/>
        </admst:when>
        <admst:otherwise>
          <admst:fatal format="%(name): should not be reached\n"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='\$limit']">
      <admst:fatal format="%(name): function not implemented \n"/>
    </admst:when>
    <admst:when test="[name='\$temperature']">
      <admst:assert test="[nilled(arguments)]" format="%(name): should not have arguments\n"/>
      <admst:variable name="e" string="_circuit_temp"/>
    </admst:when>
    <admst:when test="[name='\$mfactor']">
      <admst:assert test="[nilled(arguments)]" format="%(name): should not have arguments\n"/>
      <admst:variable name="e" string="MFACTOR"/>
    </admst:when>
    <admst:when test="[name='\$vt']">
      <admst:choose>
        <admst:when test="[nilled(arguments)]">
          <admst:variable name="e" string="_vt_nom"/>
        </admst:when>
        <admst:when test="arguments[count(.)=1]">
          <admst:apply-templates select="arguments[1]" match="ddx"/>
          <admst:variable name="x" string="$e"/>
          <admst:variable name="xp" string="$ep"/>
          <admst:variable name="xq" string="$eq"/>
          <admst:variable name="xpq" string="$epq"/>
          <admst:variable name="e" select="m00_vt($x)"/>
        </admst:when>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='\$scale']">
      <admst:assert test="[nilled(arguments)]" format="%(name): should not have arguments\n"/>
      <admst:variable name="e" string="_scale"/>
    </admst:when>
    <admst:when test="[name='\$abstime']">
      <admst:assert test="[nilled(arguments)]" format="%(name): should not have arguments\n"/>
      <admst:variable name="e" string="_abstime"/>
    </admst:when>
    <admst:when test="[name='ddx']">
      <admst:assert test="arguments[count(.)=2]" format="%(name): should have two arguments exactly\n"/>
      <admst:assert test="arguments[2]/adms[datatypename='probe']" format="%(name): second argument is not a probe\n"/>
      <admst:apply-templates select="arguments[1]" match="ddx"/>
      <admst:variable name="e" select="not-used"/>
    </admst:when>
    <admst:when test="[name='floor']">
      <admst:assert test="arguments[count(.)=1]" format="%(name): should have one argument exactly\n"/>
      <admst:apply-templates select="arguments[1]" match="ddx"/>
      <admst:variable name="e" select="floor($e)"/>
    </admst:when>
    <admst:when test="[name='ceil']">
      <admst:assert test="arguments[count(.)=1]" format="%(name): should have one argument exactly\n"/>
      <admst:apply-templates select="arguments[1]" match="ddx"/>
      <admst:variable name="e" select="ceil($e)"/>
    </admst:when>
    <admst:when test="[$SkipFVariable='y']">
      <admst:variable name="fname" path="funcname(.)/[name='fname']/value"/>
      <admst:variable name="args" select=""/>
      <admst:for-each select="arguments">
        <admst:if test="[$args!='']">
          <admst:variable name="args" select="$args,"/>
        </admst:if>
        <admst:apply-templates select="." match="ddx"/>
        <admst:variable name="args" select="$args$e"/>
      </admst:for-each>
      <admst:variable name="e" select="$(fname)($args)"/>
    </admst:when>
<!--   hypot function name removed from single argument list. If left in list a cADM compile error occurs: Mike Brinson March 2014. -->
    <admst:when
      test="[
            name='sin' or
            name='cos' or
            name='tan' or
            name='asin' or
            name='acos' or
            name='atan' or
            name='sinh' or
            name='cosh' or
            name='tanh' or
            name='asinh' or
            name='acosh' or
            name='atanh' or
            name='ln' or
            name='limexp' or
            name='abs' or
            name='exp' or
            name='log' or
            name='sqrt'
            ]">
      <admst:assert test="arguments[count(.)=1]" format="%(name): should have one argument exactly\n"/>
      <admst:variable name="index" path="index(subexpression/expression/function,.)"/>
      <admst:variable name="fname" path="funcname(.)/[name='fname']/value"/>
      <admst:apply-templates select="arguments[1]" match="ddx"/>
      <admst:variable name="x" string="$e"/>
      <admst:variable name="xp" string="$ep"/>
      <admst:variable name="xq" string="$eq"/>
      <admst:variable name="xpq" string="$epq"/>
      <admst:variable name="e" select="d00_$(fname)$index"/>
    </admst:when>
    <admst:when
      test="[
      name='div' or
      name='pow' or
      name='hypot' or
      name='min' or
      name='max' or
      name='atan2'
      ]">
      <admst:assert test="arguments[count(.)=2]" format="%(name): should have two argument exactly\n"/>
      <admst:variable name="index" path="index(./subexpression/expression/function,.)"/>
      <admst:variable name="fname" path="funcname(.)/[name='fname']/value"/>
      <admst:apply-templates select="arguments[1]" match="ddx"/>
      <admst:variable name="x" string="$e"/>
      <admst:variable name="xp" string="$ep"/>
      <admst:variable name="xq" string="$eq"/>
      <admst:variable name="xpq" string="$epq"/>
      <admst:apply-templates select="arguments[2]" match="ddx"/>
      <admst:variable name="y" string="$e"/>
      <admst:variable name="yp" string="$ep"/>
      <admst:variable name="yq" string="$eq"/>
      <admst:variable name="ypq" string="$epq"/>
      <admst:variable name="e" select="d00_$(fname)$index"/>
    </admst:when>
    <admst:otherwise>
      <admst:variable name="fname" path="funcname(.)/[name='fname']/value"/>
      <admst:variable name="args" select=""/>
      <admst:for-each select="arguments">
        <admst:if test="[$args!='']">
          <admst:variable name="args" select="$args,"/>
        </admst:if>
        <admst:apply-templates select="." match="ddx"/>
        <admst:variable name="args" select="$args$e"/>
      </admst:for-each>
      <admst:variable name="dargs" select=""/>
      <admst:for-each select="arguments">
        <admst:if test="[$dargs!='']">
          <admst:variable name="dargs" select="$dargs,"/>
        </admst:if>
        <admst:apply-templates select="." match="ddx"/>
        <admst:variable name="dargs" select="$dargs$ep"/>
      </admst:for-each>
      <admst:choose>
        <admst:when test="[class='builtin']">
          <admst:variable name="e" select="$(fname)($args)"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="e" select="$(module)_$(fname)($args)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:otherwise>
  </admst:choose>

  <admst:variable name="ep" string="0.0"/>
  <admst:choose>
    <admst:when test="[name='absdelay']">
    </admst:when>
    <admst:when test="[name='\$given' or name='\$param_given']">
    </admst:when>
    <admst:when test="[name='\$temperature']">
    </admst:when>
    <admst:when test="[name='\$mfactor']">
    </admst:when>
    <admst:when test="[name='\$vt']">
      <admst:choose>
        <admst:when test="[nilled(arguments)]">
          <admst:variable name="ep" string="0.0"/>
        </admst:when>
        <admst:when test="arguments[count(.)=1]">
          <admst:variable name="ep" select="$xp*m10_vt($x)"/>
        </admst:when>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='\$scale']">
    </admst:when>
    <admst:when test="[name='\$abstime']">
    </admst:when>
    <admst:when test="[name='ddx']">
    </admst:when>
    <admst:when test="[name='floor']">
    </admst:when>
    <admst:when test="[name='ceil']">
    </admst:when>
    <admst:when test="[$SkipFVariable='y']">
    </admst:when>
    <admst:when test="[name='ddt']">
      <admst:variable name="ep" string="$xp"/>
    </admst:when>
    <admst:when
      test="[
            name='sin' or
            name='cos' or
            name='tan' or
            name='asin' or
            name='acos' or
            name='atan' or
            name='hypot' or
            name='sinh' or
            name='cosh' or
            name='tanh' or
            name='asinh' or
            name='acosh' or
            name='atanh' or
            name='ln' or
            name='limexp' or
            name='abs' or
            name='exp' or
            name='log' or
            name='sqrt'
            ]">
      <admst:variable name="index" path="index(subexpression/expression/function,.)"/>
      <admst:choose>
        <admst:when test="[$xp='0.0']">
          <admst:variable name="ep" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="ep" select="$xp*d10_$(fname)$index"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when
      test="[
      name='div' or
      name='pow' or
      name='hypot' or
      name='min' or
      name='max' or
      name='atan2'
      ]">
      <admst:variable name="index" path="index(./subexpression/expression/function,.)"/>
      <admst:choose>
        <admst:when test="[$xp='0.0' and $yp='0.0']">
          <admst:variable name="ep" string="0.0"/>
        </admst:when>
        <admst:when test="[$xp='0.0']">
          <admst:variable name="ep" select="(d11_$(fname)$index*$yp)"/>
        </admst:when>
        <admst:when test="[$yp='0.0']">
          <admst:variable name="ep" select="(d10_$(fname)$index*$xp)"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="ep" select="(d10_$(fname)$index*$xp+d11_$(fname)$index*$yp)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:otherwise>
      <admst:choose>
        <admst:when test="[class='builtin']">
          <admst:variable name="ep" select="d_$(fname)($args,$dargs)"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="ep" select="$(module)_d_$(fname)($args,$dargs)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:otherwise>
  </admst:choose>
  <admst:if test="$qprobe">

  <admst:variable name="eq" string="0.0"/>
  <admst:choose>
    <admst:when test="[name='absdelay']">
    </admst:when>
    <admst:when test="[name='\$given' or name='\$param_given']">
    </admst:when>
    <admst:when test="[name='\$temperature']">
    </admst:when>
    <admst:when test="[name='\$mfactor']">
    </admst:when>
    <admst:when test="[name='\$vt']">
      <admst:choose>
        <admst:when test="[nilled(arguments)]">
          <admst:variable name="eq" string="0.0"/>
        </admst:when>
        <admst:when test="arguments[count(.)=1]">
          <admst:variable name="eq" select="$xq*m10_vt($x)"/>
        </admst:when>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='\$scale']">
    </admst:when>
    <admst:when test="[name='\$abstime']">
    </admst:when>
    <admst:when test="[name='ddx']">
    </admst:when>
    <admst:when test="[name='floor']">
    </admst:when>
    <admst:when test="[name='ceil']">
    </admst:when>
    <admst:when test="[$SkipFVariable='y']">
    </admst:when>
    <admst:when test="[name='ddt']">
      <admst:variable name="eq" string="$xq"/>
    </admst:when>

    <admst:when
      test="[
            name='sin' or
            name='cos' or
            name='tan' or
            name='asin' or
            name='acos' or
            name='atan' or
            name='hypot' or
            name='sinh' or
            name='cosh' or
            name='tanh' or
            name='asinh' or
            name='acosh' or
            name='atanh' or
            name='ln' or
            name='limexp' or
            name='abs' or
            name='exp' or
            name='log' or
            name='sqrt'
            ]">
      <admst:variable name="index" path="index(subexpression/expression/function,.)"/>
      <admst:choose>
        <admst:when test="[$xq='0.0']">
          <admst:variable name="eq" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="eq" select="$xq*d10_$(fname)$index"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>

    <admst:when
      test="[
      name='div' or
      name='pow' or
      name='hypot' or
      name='min' or
      name='max' or
      name='atan2']">
      <admst:variable name="index" path="index(./subexpression/expression/function,.)"/>
      <admst:choose>
        <admst:when test="[$xq='0.0' and $yq='0.0']">
          <admst:variable name="eq" string="0.0"/>
        </admst:when>
        <admst:when test="[$xq='0.0']">
          <admst:variable name="eq" select="(d11_$(fname)$index*$yq)"/>
        </admst:when>
        <admst:when test="[$yq='0.0']">
          <admst:variable name="eq" select="(d10_$(fname)$index*$xq)"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="eq" select="(d10_$(fname)$index*$xq+d11_$(fname)$index*$yq)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:otherwise>
      <admst:variable name="eq" select="d_$(fname)($args,$dargs)"/>
    </admst:otherwise>
  </admst:choose>

  <!-- handle ddx (?)-->
  <admst:choose>
    <admst:when
      test="[
            name='sin' or
            name='cos' or
            name='tan' or
            name='asin' or
            name='acos' or
            name='atan' or
            name='hypot' or
            name='sinh' or
            name='cosh' or
            name='tanh' or
            name='asinh' or
            name='acosh' or
            name='atanh' or
            name='ln' or
            name='limexp' or
            name='abs' or
            name='exp' or
            name='log' or
            name='sqrt'
            ]">
      <admst:variable name="index" path="index(./subexpression/expression/function,.)"/>
      <admst:variable name="fname" path="funcname(.)/[name='fname']/value"/>
      <admst:choose>
        <admst:when test="[$x='0.0']">
          <admst:variable name="epq" string="0.0"/>
        </admst:when>
        <admst:when test="[$xp='0.0']">
          <admst:variable name="epq" string="0.0"/>
        </admst:when>
        <admst:when test="[$xq='0.0']">
          <admst:variable name="epq" string="0.0"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="epq" select="(m20_$(fname)($x)*$xq*$xp+d10_$(fname)$index*$xpq)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='pow' and $yp='0.0' and $yq='0.0']">
      <admst:choose>
        <admst:when test="[$x='0.0' or $xp='0.0' or $xq='0.0']">
          <admst:variable name="epq" string="0.0"/>
        </admst:when>
        <admst:when test="[$xpq='0.0']">
          <admst:variable name="epq" select="(m20_$(fname)($x,$y)*$xq*$xp)"/>
        </admst:when>
        <admst:otherwise>
          <admst:variable name="epq" select="(m20_$(fname)($x,$y)*$xq*$xp+d10_$(fname)$index*$xpq)"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:when test="[name='div' or name='pow' or name='hypot' or name='min' or name='max']">
      <admst:variable name="epq" string="fixme"/>
      <admst:warning format="%(name): ddx dependency not implemented %(arguments[1]|' '|arguments[2])\n"/>
    </admst:when>
  </admst:choose>
  </admst:if>
</admst:template>

<!-- analog//block -->
<admst:template match="block">
  <admst:text format="{\n"/>
  <admst:apply-templates select="item" match="%(datatypename)"/>
  <admst:text format="}\n"/>
</admst:template>

<!-- analog//blockvariable -->
<admst:template match="blockvariable">
  <admst:text select="variable" format="%(vtype(.)) %(name);\n"/>
  <admst:if test="variable[insource='yes']/probe">

    <admst:for-each select="variable">
      <admst:variable name="myvariable" path="."/>
      <admst:for-each select="probe">
          <admst:variable name="pprobe" path="."/>
          <admst:variable name="ddxinsidethisprobe" string="no"/>
          <admst:if test="$myvariable/ddxprobe/branch/pnode[.=$pprobe/branch/pnode or .=$pprobe/branch/nnode]">
            <admst:variable name="ddxinsidethisprobe" string="yes"/>
          </admst:if>
          <admst:text test="[$ddxinsidethisprobe='yes']" format="#if defined(_DERIVATEFORDDX)\n"/>
          <admst:text test="[$ddxinsidethisprobe='no']" format="#if defined(_DERIVATE)\n"/>
          <admst:text format="double %($myvariable/name)_%(nature/access)%(branch/pnode/name)_%(branch/nnode/name);\n"/>
          <admst:text format="#endif\n"/>
      </admst:for-each>
    </admst:for-each>

    <admst:for-each select="variable">
      <admst:variable name="myvariable" path="."/>
      <admst:new datatype="list" arguments="list of ddx probes">
        <admst:variable name="ddxprobes" path="."/>
        <admst:for-each select="$myvariable/probe">
          <admst:variable name="pprobe" path="."/>
          <admst:push into="$ddxprobes/item" select="$myvariable/ddxprobe/branch/pnode[.=$pprobe/branch/pnode or .=$pprobe/branch/nnode]/$pprobe" onduplicate="ignore"/>
        </admst:for-each>
      </admst:new>
      <admst:text test="$ddxprobes/item" format="#if defined(_DERIVATE)\n"/>
      <admst:for-each select="$ddxprobes/item">
        <admst:variable name="pprobe" path="."/>
        <admst:for-each select="$myvariable/probe">
          <admst:variable name="qprobe" path="."/>
          <admst:text format="  double %(ddxname($myvariable)/[name='ddxname']/value);\n"/>
        </admst:for-each>
      </admst:for-each>
      <admst:text test="$ddxprobes/item" format="#endif\n"/>
    </admst:for-each>
  </admst:if>
</admst:template>

<!-- analog//function: ddx handling -->
<admst:template match="function:precomputation">
  <admst:variable name="index" path="index(../function,.)"/>
  <admst:variable name="fname" path="funcname(.)/[name='fname']/value"/>
  <admst:choose>
    <admst:when test="[name='add']">
      <admst:text format="m00_add(d00_add$index"/>
    </admst:when>
    <admst:when test="[name='div']">
      <admst:text format="m00_div(d00_div$index,d10_$(fname)$index"/>
    </admst:when>
    <admst:when test="[name='mult']">
      <admst:text format="m00_mult(d00_mult$index,d10_mult$index,d11_mult$index"/>
    </admst:when>
    <admst:otherwise>
      <admst:text format="double m00_$(fname)(d00_$(fname)$index"/>
    </admst:otherwise>
  </admst:choose>
  <admst:text select="arguments" format=",%(e(.))"/>
  <admst:text format=")\n"/>
</admst:template>

<admst:template match="function:derivate:precomputation">
  <admst:apply-templates select="function" match="function:precomputation"/>
  <admst:if test="[hasVoltageDependentFunction='yes']">
        <admst:choose>
          <admst:when test="[$ddxinsidederivate='yes']">
            <admst:text format="#if defined(_DERIVATEFORDDX)\n"/>
          </admst:when>
          <admst:otherwise>
            <admst:text format="#if defined(_DERIVATE)\n"/>
          </admst:otherwise>
        </admst:choose>
    <admst:for-each select="function">
      <admst:variable name="index" path="index(../function,.)"/>
      <admst:variable name="fname" path="funcname(.)/[name='fname']/value"/>
      <admst:choose>
        <admst:when test="[name='exp']">
            <admst:if test="arguments/math[dependency!='constant' and dependency!='noprobe']">
              <admst:text format="#define d10_exp$index d00_exp$index\n"/>
            </admst:if>
        </admst:when>
        <admst:when test="[name='add']">
            <admst:if test="arguments/math[dependency!='constant' and dependency!='noprobe']">
              <admst:text format="#define d10_add$index 1\n"/>
              <admst:text format="#define d11_add$index 1\n"/>
            </admst:if>
        </admst:when>
        <admst:when test="[name='mult']"/>
        <admst:when test="[name='add']"/>
        <admst:when test="[name='div']">
          <admst:for-each select="arguments">
            <admst:variable name="position" path="position(.)-1"/>
            <admst:if test="math[dependency!='constant' and dependency!='noprobe']">
              <admst:text format="m1$(position)_$(fname)(d1$(position)_$(fname)$index,d00_$(fname)$index,d10_$(fname)$index"/>
              <admst:text select="../arguments" format=",%(e(.))"/>
              <admst:text format=")\n"/>
            </admst:if>
          </admst:for-each>
        </admst:when>
        <admst:otherwise>
          <admst:for-each select="arguments">
            <admst:variable name="position" path="position(.)-1"/>
            <admst:if test="math[dependency!='constant' and dependency!='noprobe']">
              <admst:text format="double m1%(position(.)-1)_$(fname)(d1%(position(.)-1)_$(fname)$index,d00_$(fname)$index"/>
              <admst:text select="../arguments" format=",%(e(.))"/>
              <admst:text format=")\n"/>
            </admst:if>
          </admst:for-each>
        </admst:otherwise>
      </admst:choose>
    </admst:for-each>
    <admst:text format="#endif\n"/>
  </admst:if>
</admst:template>

<!-- analog//assignment -->
<admst:template match="assignment">
  <admst:variable name="assignment" path="."/>
  <admst:variable name="rhs" path="rhs"/>
  <admst:variable name="lhs" path="lhs"/>
  <admst:text test="[dynamic='yes']" format="#if defined(_DYNAMIC)\n"/>
  <admst:text test="rhs/function" format="{\n"/>
  <admst:variable name="ddxinsidederivate" string="no"/>
  <admst:for-each select="lhs/probe">
    <admst:variable name="pprobe" path="."/>
    <admst:if test="$lhs/ddxprobe/branch/pnode[.=$pprobe/branch/pnode or .=$pprobe/branch/nnode]">
      <admst:variable name="ddxinsidederivate" string="yes"/>
    </admst:if>
  </admst:for-each>
  <admst:apply-templates select="rhs[not(nilled(function))]" match="function:derivate:precomputation"/>
  <admst:choose>
    <admst:when test="rhs/tree/adms[datatypename='function']/..[name='ddx']">
      <admst:text format="#if defined(_DDX)\n"/>
      <admst:variable name="ddxprobe" path="rhs/tree/arguments[2]"/>
      <admst:text test="lhs[insource='yes']/probe" format="#if defined(_DERIVATE)\n"/>
      <admst:for-each select="lhs[insource='yes']/probe">
        <admst:variable name="qprobe" path="."/>
        <admst:variable name="allepq"/>
        <admst:for-each select="$lhs/probe">
          <admst:variable name="pprobe" path="."/>
          <admst:choose>
            <admst:when test="$pprobe/branch/pnode[.=$ddxprobe/branch/pnode]">
              <admst:apply-templates select="$rhs/tree/arguments[1]" match="%(datatypename)"/>
              <admst:variable name="allepq" select="$allepq+($epq)"/>
            </admst:when>
<!--            <admst:when test="$pprobe/branch/nnode/[.=$ddxprobe/branch/nnode]"> -->
            <admst:when test="$pprobe/branch/nnode/[.=$ddxprobe/branch/pnode]">
              <admst:apply-templates select="$rhs/tree/arguments[1]" match="%(datatypename)"/>
              <admst:variable name="allepq" select="$allepq-($epq)"/>
            </admst:when>
          </admst:choose>
        </admst:for-each>
        <admst:variable name="pprobe" path="$qprobe"/>
        <admst:text format="%(dxname($lhs)/[name='dxname']/value)=$allepq;\n"/>
      </admst:for-each>
      <admst:text test="lhs[insource='yes']/probe" format="#endif\n"/>
      <admst:variable name="allep"/>
      <admst:variable name="qprobe"/>
      <admst:for-each select="$lhs/probe">
        <admst:variable name="pprobe" path="."/>
        <admst:choose>
          <admst:when test="$pprobe/branch/pnode[.=$ddxprobe/branch/pnode]">
            <admst:apply-templates select="$rhs/tree/arguments[1]" match="%(datatypename)"/>
            <admst:variable name="allep" select="$allep+($ep)"/>
          </admst:when>
          <admst:when test="$pprobe/branch/nnode/[.=$ddxprobe/branch/pnode]">
<!--          <admst:when test="$pprobe/branch/nnode/[.=$ddxprobe/branch/nnode]"> -->
            <admst:apply-templates select="$rhs/tree/arguments[1]" match="%(datatypename)"/>
            <admst:variable name="allep" select="$allep-($ep)"/>
          </admst:when>
        </admst:choose>
      </admst:for-each>
      <admst:apply-templates select="lhs" match="variable"/>
      <admst:text format="$e=$allep;\n"/>
      <admst:text format="#endif\n"/>
    </admst:when>
    <admst:otherwise>
      <admst:if test="lhs[insource='yes']">
        <admst:variable name="definedrequired" string="yes"/>
        <admst:choose>
          <admst:when test="[$ddxinsidederivate='yes']">
            <admst:text format="#if defined(_DERIVATEFORDDX)\n"/>
          </admst:when>
          <admst:when test="lhs/probe">
            <admst:text format="#if defined(_DERIVATE)\n"/>
          </admst:when>
          <admst:otherwise>
            <admst:variable name="definedrequired" string="no"/>
          </admst:otherwise>
        </admst:choose>
        <admst:for-each select="lhs/probe">
          <admst:variable name="pprobe" path="."/>
          <admst:variable name="ddxinsidethisprobe" string="no"/>
          <admst:if test="$lhs/ddxprobe/branch/pnode[.=$pprobe/branch/pnode or .=$pprobe/branch/nnode]">
            <admst:variable name="ddxinsidethisprobe" string="yes"/>
          </admst:if>
          <admst:variable name="isinside" string="0"/>
          <admst:if test="$rhs/probe[.=$pprobe]">
            <admst:variable name="isinside" string="1"/>
          </admst:if>
          <admst:variable name="qprobe"/>
          <admst:variable name="ep" string="0.0"/>
          <admst:apply-templates select="[$isinside='1']/$rhs/tree" match="%(datatypename)"/>
          <admst:text test="[$ddxinsidederivate='yes' and $ddxinsidethisprobe='no']" format="#if defined(_DERIVATE)\n"/>
          <admst:text format="%(dxname($lhs)/[name='dxname']/value)=$ep;\n"/>
          <admst:text test="[$ddxinsidederivate='yes' and $ddxinsidethisprobe='no']" format="#endif\n"/>
          <admst:text test="[$ddxinsidethisprobe='yes']" format="#if defined(_DERIVATE)\n"/>
          <admst:for-each select="$lhs[$ddxinsidethisprobe='yes']/probe">
            <admst:variable name="epq" string="0.0"/>
            <admst:variable name="qprobe" path="."/>
            <admst:apply-templates select="[$isinside='1']/$rhs/tree" match="%(datatypename)"/>
            <admst:text format="  %(ddxname($lhs)/[name='ddxname']/value)=$epq;\n"/>
          </admst:for-each>
          <admst:text test="$lhs[$ddxinsidethisprobe='yes']" format="#endif\n"/>
        </admst:for-each>
        <admst:text test="[$definedrequired='yes']" format="#endif\n"/>
      </admst:if>
      <admst:variable name="qprobe"/>
      <admst:apply-templates select="lhs" match="variable"/>
      <admst:text format="$e=%(e(rhs/tree));\n"/>
    </admst:otherwise>
  </admst:choose>
  <admst:text test="rhs/function" format="}\n"/>
  <admst:text test="[dynamic='yes']" format="#endif\n"/>
</admst:template>

<!-- analog//contribution[noise] -->
<admst:template match="contribution:noise">
  <admst:variable name="SkipFVariable" string="y"/>
  <admst:variable name="pnode" path="lhs/branch/pnode/name"/>
  <admst:variable name="nnode" path="lhs/branch/nnode/name"/>
  <admst:text format="_save_"/>
  <admst:if test="[whitenoise='yes']">
    <admst:choose>
    <admst:when test="lhs/branch/nnode[grounded='no']">
      <admst:text format="whitenoise2($pnode,$nnode"/>
    </admst:when>
    <admst:otherwise>
      <admst:text format="whitenoise1($pnode"/>
    </admst:otherwise>
    </admst:choose>
  </admst:if>
  <admst:if test="[flickernoise='yes']">
    <admst:choose>
    <admst:when test="lhs/branch/nnode[grounded='no']">
      <admst:text format="flickernoise2($pnode,$nnode"/>
    </admst:when>
    <admst:otherwise>
      <admst:text format="flickernoise1($pnode"/>
    </admst:otherwise>
    </admst:choose>
  </admst:if>
  <admst:for-each select="rhs/tree/arguments">
    <admst:apply-templates select="." match="%(datatypename)"/>
    <admst:text format=",$e"/>
  </admst:for-each>
  <admst:if test="[flickernoise='yes']">
    <admst:if test="rhs/tree/arguments[count(.)=2]">
      <admst:text format=",NULL"/>
    </admst:if>
  </admst:if>
  <admst:if test="[whitenoise='yes']">
    <admst:if test="rhs/tree/arguments[count(.)=1]">
      <admst:text format=",NULL"/>
    </admst:if>
  </admst:if>
  <admst:text format=");\n"/>
  <admst:variable name="SkipFVariable" string="n"/>
</admst:template>

<!-- analog//contribution -->
<admst:template match="contribution">
  <admst:choose>
    <admst:when test="[whitenoise='no' and flickernoise='no']">
      <admst:apply-templates select="." match="contribution:nonoise" required="yes"/>
    </admst:when>
    <admst:otherwise>
      <admst:apply-templates select="." match="contribution:noise" required="yes"/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<!-- analog//contribution[nonoise] -->
<admst:template match="contribution:nonoise">
  <admst:text test="[dynamic='yes']" format="#if defined(_DYNAMIC)\n"/>
  <admst:text test="rhs/function" format="{\n"/>
  <admst:apply-templates select="rhs[not(nilled(function))]" match="function:derivate:precomputation"/>
  <admst:variable name="sourcepnode" path="lhs/branch/pnode"/>
  <admst:variable name="sourcennode" path="lhs/branch/nnode"/>
  <admst:variable name="sourcepnodename" path="$sourcepnode/name"/>
  <admst:variable name="sourcennodename" path="$sourcennode/name"/>
  <admst:text format="_load_"/>
  <admst:choose>
    <admst:when test="[dynamic='yes']">
      <admst:variable name="jname" string="dQ_dV"/>
      <admst:variable name="lname" string="dynamic"/>
      <admst:text format="$(lname)_"/>
      <admst:choose>
        <admst:when test="$sourcennode[grounded='no']">
          <admst:text format="residual2($sourcepnodename,$sourcennodename,%(e(rhs/tree)));\n"/>
        </admst:when>
        <admst:otherwise>
          <admst:text format="residual1($sourcepnodename,%(e(rhs/tree)));\n"/>
        </admst:otherwise>
      </admst:choose>
    </admst:when>
    <admst:otherwise>
      <admst:variable name="jname" string="dI_dV"/>
      <admst:variable name="lname" string="static"/>
      <admst:text format="$(lname)_"/>
      <admst:choose>
        <admst:when test="$sourcennode[grounded='no']">
          <admst:text format="residual2($sourcepnodename,$sourcennodename,%(e(rhs/tree)));\n"/>
        </admst:when>
        <admst:otherwise>
          <admst:text format="residual1($sourcepnodename,%(e(rhs/tree)));\n"/>
        </admst:otherwise>
      </admst:choose>
    </admst:otherwise>
  </admst:choose>
  <admst:text format="#if defined(_DERIVATE)\n"/>
  <admst:for-each select="rhs/probe">
    <admst:variable name="probepnode" path="branch/pnode"/>
    <admst:variable name="probennode" path="branch/nnode"/>
    <admst:variable name="probepnodename" path="$probepnode/name"/>
    <admst:variable name="probennodename" path="$probennode/name"/>
    <admst:variable name="pprobe" path="."/>
    <admst:apply-templates select="../tree" match="%(datatypename)"/>
    <admst:text format="_load_"/>
    <admst:text format="$(lname)_"/>
    <admst:choose>
      <admst:when test="$probennode[grounded='no']">
        <admst:if test="$sourcennode[grounded='no']">
          <admst:text format="jacobian4($sourcepnodename,$sourcennodename,$probepnodename,$probennodename,$ep);\n"/>
        </admst:if>
        <admst:if test="$sourcennode[grounded='yes']">
          <admst:text format="jacobian2p($sourcepnodename,$probepnodename,$probennodename,$ep);\n"/>
        </admst:if>
      </admst:when>
      <admst:otherwise>
        <admst:if test="$sourcennode[grounded='no']">
          <admst:text format="jacobian2s($sourcepnodename,$sourcennodename,$probepnodename,$ep);\n"/>
        </admst:if>
        <admst:if test="$sourcennode[grounded='yes']">
          <admst:text format="jacobian1($sourcepnodename,$probepnodename,$ep);\n"/>
        </admst:if>
      </admst:otherwise>
    </admst:choose>
  </admst:for-each>
  <admst:text format="#endif\n"/>
  <admst:text test="rhs/function" format="}\n"/>
  <admst:text select="[dynamic='yes']" format="#endif\n"/>
</admst:template>

<!-- analog//conditional -->
<admst:template match="conditional">
  <admst:text select="if[dynamic='yes']" format="#ifdef _DYNAMIC\n"/>
  <admst:text test="if/function" format="{\n"/>
  <admst:apply-templates select="if/function" match="function:precomputation"/>

  <!-- avoid extraneous parenthesis `if ((...))` compiler warning.
       add parenthesis for `variable` or `number`, others already have -->
  <admst:value-of select="./if/tree/adms/datatypename"/>
  <admst:variable name="TYPE" select="%s"/>
  <admst:choose>
    <admst:when
      test="[
        $TYPE='variable' or
        $TYPE='number'
        ]">
      <admst:text format="if\n(%(e(if/tree)))\n"/>
    </admst:when>
    <admst:otherwise>
      <admst:text format="if\n%(e(if/tree))\n"/>
    </admst:otherwise>
  </admst:choose>

  <admst:text select="then/adms[datatypename!='block']" format="{\n"/>
  <admst:apply-templates select="then" match="%(datatypename)"/>
  <admst:text select="then/adms[datatypename!='block']" format="}\n"/>
  <admst:if test="else">
    <admst:text format="else\n"/>
    <admst:text test="else/adms[datatypename!='block']" format="{\n"/>
    <admst:apply-templates select="else" match="%(datatypename)"/>
    <admst:text test="else/adms[datatypename!='block']" format="}\n"/>
  </admst:if>
  <admst:text test="if/function" format="}\n"/>
  <admst:text select="if[dynamic='yes']" format="#endif /* if (...) */\n"/>
</admst:template>

<!-- analog//nilled -->
<admst:template match="nilled">
</admst:template>

<!-- analog//whileloop -->
<admst:template match="whileloop">
  <admst:text select="while[dynamic='yes']" format="#ifdef _DYNAMIC\n"/>
  <admst:variable name="SkipFVariable" string="y"/>
  <admst:text format="while\n(%(e(while/tree)))\n"/>
  <admst:variable name="SkipFVariable" string="n"/>
  <admst:text select="whileblock/adms[datatypename!='block']" format="{\n"/>
  <admst:apply-templates select="whileblock" match="%(datatypename)"/>
  <admst:text select="whileblock/adms[datatypename!='block']" format="}\n"/>
  <admst:text select="while[dynamic='yes']" format="#endif /*&lt;/dynamic_while&gt;*/\n"/>
</admst:template>

<!-- analog//forloop -->
<admst:template match="forloop">
  <admst:text select="condition[dynamic='yes']" format="#ifdef _DYNAMIC\n"/>
  <admst:variable name="SkipFVariable" string="y"/>
  <admst:text format="for\n("/>
  <admst:text format="%(e(initial/lhs))=%(e(initial/rhs/tree));"/>
  <admst:text format="%(e(condition/tree));"/>
  <admst:text format="%(e(update/lhs))=%(e(update/rhs/tree))"/>
  <admst:text format=")\n"/>
  <admst:variable name="SkipFVariable" string="n"/>
  <admst:text select="forblock/adms[datatypename!='block']" format="{\n"/>
  <admst:apply-templates select="forblock" match="%(datatypename)"/>
  <admst:text select="forblock/adms[datatypename!='block']" format="}\n"/>
  <admst:text select="condition[dynamic='yes']" format="#endif /*&lt;/dynamic_for&gt;*/\n"/>
</admst:template>

<!-- analog//case -->
<admst:template match="case">
  <admst:text select="case[dynamic='yes']" format="#ifdef _DYNAMIC\n"/>
  <admst:variable name="casecondition" path="case/tree"/>
  <admst:variable name="havedefault" string="no"/>
  <admst:for-each select="caseitem">
    <admst:if test="[defaultcase='yes']">
      <admst:variable name="havedefault" string="yes"/>
    </admst:if>
  </admst:for-each>
  <admst:for-each select="caseitem">
    <admst:if test="[defaultcase='no']">
      <admst:text format="if\n("/>
      <admst:join select="condition" separator="||">
        <admst:apply-templates select="." match="%(datatypename)"/>
	<admst:text format="($casecondition)==($e)"/>
      </admst:join>
      <admst:text format=")\n"/>
      <admst:apply-templates select="code" match="%(datatypename)" required="yes"/>
      <admst:text format="else\n"/>
    </admst:if>
  </admst:for-each>
  <admst:text select="[$havedefault='no']" format="{ /* no default */ }\n"/>
  <admst:for-each select="caseitem">
    <admst:if test="[defaultcase='yes']">
      <admst:apply-templates select="code" match="%(datatypename)" required="yes"/>
    </admst:if>
  </admst:for-each>
  <admst:text select="case[dynamic='yes']" format="#endif /*&lt;/dynamic_case&gt;*/\n"/>
</admst:template>

<!-- analog//callfunctions -->
<admst:template match="callfunction">
  <admst:choose>
    <admst:when test="function[name='\$strobe']">
      <admst:text format="logprint(LOG_ERROR"/>
      <admst:for-each select="function/arguments">
      <admst:text format=",%(e(tree))"/>
      </admst:for-each>
      <admst:text format=");\n"/>
      <admst:text format="logprint(LOG_ERROR,&quot;\\n&quot;);\n"/>
    </admst:when>
    <admst:when test="function[name='\$finish']">
      <admst:text format="exit("/>
      <admst:join select="function/arguments" separator=",">
      <admst:text format="%(e(tree))"/>
      </admst:join>
      <admst:text format=");\n"/>
    </admst:when>
    <admst:otherwise>
      <admst:text format="%(function/name): not supported by this interface\n"/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<!-- save all variables used for local declaration -->
<admst:variable name="ddxinsidederivate" string="no"/>


<!-- variable declaration -->
<admst:template match="variable:declaration">
  <admst:variable name="myvariable" path="."/>
  <admst:new datatype="list" arguments="list of ddx probes">
    <admst:variable name="ddxprobes" path="."/>
    <admst:for-each select="$myvariable/probe">
      <admst:variable name="pprobe" path="."/>
      <admst:push into="$ddxprobes/item" select="$myvariable/ddxprobe/branch/pnode[.=$pprobe/branch/pnode or .=$pprobe/branch/nnode]/$pprobe" onduplicate="ignore"/>
    </admst:for-each>
  </admst:new>
  <admst:if test="block/adms[datatypename='module']">
    <admst:text test="[static='no' and dynamic='yes']" format="#if defined(_DYNAMIC)\n"/>
    <admst:text test="[scope='local']" format="%(vtype(.)) %(name);\n"/>
    <admst:if test="[insource='yes']/probe">
      <admst:variable name="ddxinsidederivate" string="no"/>
      <admst:for-each select="probe">
        <admst:variable name="pprobe" path="."/>
        <admst:if test="../ddxprobe/branch/pnode[.=$pprobe/branch/pnode or .=$pprobe/branch/nnode]">
          <admst:variable name="ddxinsidederivate" string="yes"/>
        </admst:if>
      </admst:for-each>
      <admst:choose>
        <admst:when test="[$ddxinsidederivate='yes']">
          <admst:text format="#if defined(_DERIVATEFORDDX)\n"/>
        </admst:when>
        <admst:otherwise>
          <admst:text format="#if defined(_DERIVATE)\n"/>
        </admst:otherwise>
      </admst:choose>
      <admst:text select="probe" format="double %(../name)_%(nature/access)%(branch/pnode/name)_%(branch/nnode/name);\n"/>
      <admst:text test="[$ddxinsidederivate='yes']" format="#if defined(_DERIVATE)\n"/>
      <admst:for-each select="$ddxprobes/item">
        <admst:variable name="pprobe" path="."/>
        <admst:for-each select="$myvariable/probe">
          <admst:variable name="qprobe" path="."/>
          <admst:text format="  double %(ddxname($myvariable)/[name='ddxname']/value);\n"/>
        </admst:for-each>
      </admst:for-each>
      <admst:text test="[$ddxinsidederivate='yes']" format="#endif\n"/>
      <admst:text format="#endif\n"/>
    </admst:if>
    <admst:text test="[static='no' and dynamic='yes']" format="#endif\n"/>
  </admst:if>
</admst:template>

<!-- block local variable declaration -->
<admst:template match="block:local:declaration">
  <admst:choose>
    <admst:when test="adms[datatypename='assignment']">
      <admst:push into="module/evaluation/variable" select="lhs" onduplicate="ignore"/>
    </admst:when>
    <admst:when test="adms[datatypename='block']">
      <admst:apply-templates select="item" match="block:local:declaration"/>
    </admst:when>
    <admst:when test="adms[datatypename='conditional']">
      <admst:apply-templates select="then" match="block:local:declaration"/>
      <admst:apply-templates select="else" match="block:local:declaration"/>
    </admst:when>
    <admst:when test="adms[datatypename='whileloop']">
      <admst:apply-templates select="whileblock" match="block:local:declaration"/>
    </admst:when>
    <admst:when test="adms[datatypename='forloop']">
      <admst:apply-templates select="initial" match="block:local:declaration"/>
      <admst:apply-templates select="forblock" match="block:local:declaration"/>
      <admst:apply-templates select="update" match="block:local:declaration"/>
    </admst:when>
    <admst:when test="adms[datatypename='contribution']"/>
    <admst:when test="adms[datatypename='callfunction']"/>
    <admst:when test="adms[datatypename='nilled']"/>
    <admst:when test="adms[datatypename='blockvariable']"/>
    <admst:when test="adms[datatypename='case']">
      <admst:for-each select="caseitem">
        <admst:apply-templates select="code" match="block:local:declaration"/>
      </admst:for-each>
    </admst:when>
    <admst:otherwise>
      <admst:fatal format="'datatypename=%(datatypename)': should not be reached\n"/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<!-- analog//code -->
<admst:template match="analog:evaluate">
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name!='initial_model' and name!='initial_instance' and name!='noise' and name!='initial_step' and name!='final_step']">
      <admst:apply-templates select="." match="block:local:declaration"/>
    </admst:if>
    <admst:if test="adms[datatypename!='block']">
      <admst:apply-templates select="." match="block:local:declaration"/>
    </admst:if>
  </admst:for-each>
  <admst:apply-templates select="module/evaluation/variable" match="variable:declaration"/>
  <admst:reset select="module/evaluation/variable"/>
  <admst:for-each select="item">
    <admst:choose>
      <admst:when test="adms[datatypename!='block']">
        <admst:apply-templates select="." match="%(datatypename)"/>
      </admst:when>
      <admst:otherwise>
        <admst:if test="[name!='initial_model' and name!='initial_instance' and name!='noise' and name!='initial_step' and name!='final_step']">
          <admst:apply-templates select="." match="block"/>
        </admst:if>
      </admst:otherwise>
    </admst:choose>
  </admst:for-each>
</admst:template>

<!-- analog//[noise] -->
<admst:template match="analog:noise">
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='noise']">
      <admst:apply-templates select="." match="block:local:declaration"/>
    </admst:if>
  </admst:for-each>
  <admst:apply-templates select="module/evaluation/variable" match="variable:declaration"/>
  <admst:reset select="module/evaluation/variable"/>
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='noise']">
      <admst:apply-templates select="." match="block"/>
    </admst:if>
  </admst:for-each>
</admst:template>

<!-- analog//[initial_model] -->
<admst:template match="analog:initial_model">
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='initial_model']">
      <admst:apply-templates select="." match="block:local:declaration"/>
    </admst:if>
  </admst:for-each>
  <admst:apply-templates select="module/evaluation/variable" match="variable:declaration"/>
  <admst:reset select="module/evaluation/variable"/>
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='initial_model']">
      <admst:apply-templates select="." match="block"/>
    </admst:if>
  </admst:for-each>
</admst:template>

<!-- analog//[initial_instance] -->
<admst:template match="analog:initial_instance">
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='initial_instance']">
      <admst:apply-templates select="." match="block:local:declaration"/>
    </admst:if>
  </admst:for-each>
  <admst:apply-templates select="module/evaluation/variable" match="variable:declaration"/>
  <admst:reset select="module/evaluation/variable"/>
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='initial_instance']">
      <admst:apply-templates select="." match="block"/>
    </admst:if>
  </admst:for-each>
</admst:template>

<!-- analog//[initial_step] -->
<admst:template match="analog:initial_step">
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='initial_step']">
      <admst:apply-templates select="." match="block:local:declaration"/>
    </admst:if>
  </admst:for-each>
  <admst:apply-templates select="module/evaluation/variable" match="variable:declaration"/>
  <admst:reset select="module/evaluation/variable"/>
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='initial_step']">
      <admst:apply-templates select="." match="block"/>
    </admst:if>
  </admst:for-each>
</admst:template>

<!-- analog//[final_step] -->
<admst:template match="analog:final_step">
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='final_step']">
      <admst:apply-templates select="." match="block:local:declaration"/>
    </admst:if>
  </admst:for-each>
  <admst:apply-templates select="module/evaluation/variable" match="variable:declaration"/>
  <admst:reset select="module/evaluation/variable"/>
  <admst:for-each select="item">
    <admst:if test="adms[datatypename='block']/..[name='final_step']">
      <admst:apply-templates select="." match="block"/>
    </admst:if>
  </admst:for-each>
</admst:template>

<!--
* This template returns the description of an instance or
* a model parameter. It works for both formats of :
*   `ATTR(info="description"  ...)
* or
*   `ATTR(desc="description"  ...)
-->
<admst:template match="variable:desc">
  <admst:choose>
    <admst:when test="attribute[name='desc' or name='info']">
      <admst:return name="variable:desc" string="&quot;%(attribute[name='desc' or name='info']/value)&quot;"/>
    </admst:when>
    <admst:otherwise>
      <admst:return name="variable:desc" string="NULL"/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<!--
* This template returns the unit of an instance or
* a model parameter as given in the VA file.
-->
<admst:template match="variable:unit">
  <admst:choose>
    <admst:when test="attribute[name='unit']">
      <admst:return name="variable:unit" string="&quot;%(attribute[name='unit']/value)&quot;"/>
    </admst:when>
    <admst:otherwise>
      <admst:return name="variable:unit" string="NULL"/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<!--
* c:math_h template - applied in qucsMODULEcore.xml
* The defined macro functions below are used during
*  - ddx handling
*  - expression//function: mapping

* Why is this templated partially duplicated here and on analogfunction.xml?
  - are both doing the same thing?
  - can we move inlines to [].analogfunction.h and reuse them here?
-->
<admst:template match="c:math_h">
// transcendental LRM p. 59
#define m00_cos(v00,x)          v00 = cos(x);
#define m10_cos(v10,v00,x)      v10 = (-sin(x));
#define m00_sin(v00,x)          v00 = sin(x);
#define m10_sin(v10,v00,x)      v10 = (cos(x));
#define m00_tan(v00,x)          v00 = tan(x);
#define m10_tan(v10,v00,x)      v10 = (1.0/cos(x)/cos(x));
#define m00_cosh(v00,x)         v00 = cosh(x);
#define m10_cosh(v10,v00,x)     v10 = (sinh(x));
#define m00_sinh(v00,x)         v00 = sinh(x);
#define m10_sinh(v10,v00,x)     v10 = (cosh(x));
#define m00_tanh(v00,x)         v00 = tanh(x);
#define m10_tanh(v10,v00,x)     v10 = (1.0/cosh(x)/cosh(x));
#define m00_acos(v00,x)         v00 = acos(x);
#define m10_acos(v10,v00,x)     v10 = (-1.0/sqrt(1-x*x));
#define m00_asin(v00,x)         v00 = asin(x);
#define m10_asin(v10,v00,x)     v10 = (+1.0/sqrt(1-x*x));
#define m00_atan(v00,x)         v00 = atan(x);
#define m10_atan(v10,v00,x)     v10 = (+1.0/(1+x*x));
#define m00_hypot(v00,x,y)      v00 = sqrt((x)*(x)+(y)*(y));
#define m10_hypot(v10,v00,x,y)  v10 = (x)/(v00);
#define m11_hypot(v11,v00,x,y)  v11 = (y)/(v00);
#define m00_atan2(v00,x,y)      v00 = atan2(x,y);
// TODO atan2 derivatives ?
#define m00_acosh(v00,x)        v00 = acosh(x);
#define m10_acosh(v10,v00,x)    v10 = (1.0/(sqrt(x-1)*sqrt(x+1)));
#define m00_asinh(v00,x)        v00 = asinh(x);
#define m10_asinh(v10,v00,x)    v10 = (1.0/(sqrt(x*x+1)));
#define m00_atanh(v00,x)        v00 = atanh(x);
#define m10_atanh(v10,v00,x)    v10 = (1.0/(1-x*x));


// standard functions LRM p.58
#define m00_logE(v00,x)         v00 = log(x);
#define m10_logE(v10,v00,x)     v10 = (1.0/x);
#define m00_log10(v00,x)        v00 = log10(x);
#define m10_log10(v10,v00,x)    v10 = (1.0/x/M_LN10);
#define m00_exp(v00,x)          v00 = exp(x);
#define m10_exp(v10,v00,x)      v10 = v00;
#define m00_sqrt(v00,x)         v00 = sqrt(x);
#define m10_sqrt(v10,v00,x)     v10 = (0.5/v00);
#define m00_min(v00,x,y)        v00 = ((x)&lt;(y))?(x):(y);
#define m10_min(v10,v00,x,y)    v10 = ((x)&lt;(y))?1.0:0.0;
#define m11_min(v11,v00,x,y)    v11 = ((x)&lt;(y))?0.0:1.0;
#define m00_max(v00,x,y)        v00 = ((x)&gt;(y))?(x):(y);
#define m10_max(v10,v00,x,y)    v10 = ((x)&gt;(y))?1.0:0.0;
#define m11_max(v11,v00,x,y)    v11 = ((x)&gt;(y))?0.0:1.0;
#define m00_pow(v00,x,y)        v00 = pow(x,y);
#define m10_pow(v10,v00,x,y)    v10 = (x==0.0)?0.0:(v00)*(y)/(x);
#define m11_pow(v11,v00,x,y)    v11 = (x==0.0)?0.0:(log(x)*(v00));
#define m00_abs(v00,x)          v00 = ((x)&lt;(0)?(-(x)):(x));
#define m10_abs(v10,v00,x)      v10 = (((x)&gt;=0)?(+1.0):(-1.0));
#define m00_floor(v00,x)        v00 = floor(x);
#define m10_floor(v10,v00,x)    v10 = 1.0;

#define m00_ceil(v00,x)         v00 = ceil(x);
// TODO ceil derivative, needed?

// analog operator, LRM p.61
#define m00_limexp(v00,x)       v00 = ((x)&lt;80.0?exp(x):exp(80.0)*(x-79.0));
#define m10_limexp(v10,v00,x)   v10 = ((x)&lt;80.0?(v00):exp(80.0));

// analog kernel parameter system functions, LRM p.215
#define m00_vt(x)               (kBoverQ*(x))
#define m10_vt(x)               (kBoverQ)

// extra functions (?)
#define m00_div(v00,v10,x,y)    double v10=1/(y); double v00=(x)*v10;
#define m10_div(v10,v00,vv,x,y)
#define m11_div(v11,v00,vv,x,y) double v11 = -v00*vv;
#define m00_mult(v00,v10,v11,x,y) double v10=(x); double v11=(y); double v00=v10*v11;
#define m00_add(v00,x,y)        double v00=(x)+(y);

// second derivatives
#define m20_logE(v00)           (-1.0/v00/v00)
#define m20_exp(v00)            exp(v00)
#define m20_limexp(v00)         ((v00)&lt;80.0?exp(v00):0.0)
#define m20_sqrt(v00)           (-0.25/(v00)/sqrt(v00))
#define m20_abs(v00)           0.0
#define m20_pow(x,y)            ((y)*((y)-1.0)*pow(x,y)/(x)/(x))

</admst:template>

<!-- simulator settings -->
<admst:value-to select="/simulator/package_name" string="qucs"/>
<admst:value-to select="/simulator/package_tarname" string="qucs"/>
<admst:value-to select="/simulator/package_version" string="0.0.15"/>
<admst:value-to select="/simulator/package_string" string="qucs 0.0.15"/>
<admst:value-to select="/simulator/package_bugreport" string="qucs-bugs@lists.sourceforge.net"/>

<admst:for-each select="/module">
  <admst:choose>
    <admst:when test="[name='diode']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="diode"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='hic0_full']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="hicum0"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='hic2_full']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="hicum2"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='hicumL2V2p1']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="hicum2"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='hicumL2V2p23']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="hicum2"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='bjt']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="bjt"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='bjt504_va']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="mextram"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='pspva']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="psp"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='HBT_X']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="HBT_X"/>
      </admst:new>
    </admst:when>
    <admst:when test="[name='log_amp']">
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="log_amp"/>
      </admst:new>
    </admst:when>
    <admst:otherwise>
      <admst:new datatype="attribute" arguments="qucsname">
        <admst:push into="../attribute" select="." onduplicate="abort"/>
        <admst:value-to select="value" string="%(../name)"/>
      </admst:new>
    </admst:otherwise>
  </admst:choose>

  <admst:choose>
    <admst:when test="[name='r2_et_cmc' or name='r2_cmc']">
    </admst:when>
    <admst:when test="[name='mosvar']">
      <admst:if test="[nilled(variable[name='c'])]">
        <admst:new datatype="variable" inputs=".,'c',analog">
          <admst:push into="module/variable" select="." onduplicate="ignore"/>
          <admst:value-to select="sizetype" string="scalar"/>
          <admst:value-to select="type" string="integer"/>
          <admst:value-to select="input" string="yes"/>
          <admst:value-to select="output" string="yes"/>
          <admst:value-to select="parametertype" string="model"/>
          <admst:value-to select="scope" string="global_model"/>
          <admst:new datatype="number" inputs="1">
            <admst:value-to select="scalingunit" string="1"/>
            <admst:new datatype="expression" inputs="../module,.">
              <admst:value-to select="../../default" path="."/>
            </admst:new>
          </admst:new>
        </admst:new>
      </admst:if>
    </admst:when>
    <admst:when test="[name='juncap2']">
      <admst:if test="[nilled(variable[name='d'])]">
        <admst:new datatype="variable" inputs=".,'d',analog">
          <admst:push into="module/variable" select="." onduplicate="ignore"/>
          <admst:value-to select="sizetype" string="scalar"/>
          <admst:value-to select="type" string="integer"/>
          <admst:value-to select="input" string="yes"/>
          <admst:value-to select="output" string="yes"/>
          <admst:value-to select="parametertype" string="model"/>
          <admst:value-to select="scope" string="global_model"/>
          <admst:new datatype="number" inputs="1">
            <admst:value-to select="scalingunit" string="1"/>
            <admst:new datatype="expression" inputs="../module,.">
              <admst:value-to select="../../default" path="."/>
            </admst:new>
          </admst:new>
        </admst:new>
      </admst:if>
    </admst:when>
    <admst:when test="[name='diode']">
    </admst:when>
    <admst:when test="[name='HBT_X']">
    </admst:when>
    <admst:when test="[name='mosfetbsim4']">
    </admst:when>
    <admst:when test="[name='mod_amp']">
    </admst:when>
    <admst:when test="[name='log_amp']">
    </admst:when>
    <admst:when test="[name='hicumL2V2p23']">
    </admst:when>
    <admst:when test="[name='hicumL2V2p1']">
    </admst:when>
    <admst:when test="[name='hic2_full']">
    </admst:when>
    <admst:when test="[name='vbic' or name='bjt' or name='hic0_full' or name='hicumL0V1p2' or name='bjt504_va']">
      <admst:if test="[nilled(variable[name='npn'])]">
        <admst:new datatype="variable" inputs=".,'npn',analog">
          <admst:push into="module/variable" select="." onduplicate="ignore"/>
          <admst:value-to select="sizetype" string="scalar"/>
          <admst:value-to select="type" string="integer"/>
          <admst:value-to select="input" string="yes"/>
          <admst:value-to select="output" string="yes"/>
          <admst:value-to select="parametertype" string="model"/>
          <admst:value-to select="scope" string="global_model"/>
          <admst:new datatype="number" inputs="1">
            <admst:value-to select="scalingunit" string="1"/>
            <admst:new datatype="expression" inputs="../module,.">
              <admst:value-to select="../../default" path="."/>
            </admst:new>
          </admst:new>
        </admst:new>
      </admst:if>
      <admst:if test="[nilled(variable[name='pnp'])]">
        <admst:new datatype="variable" inputs=".,'pnp',analog">
          <admst:push into="module/variable" select="." onduplicate="ignore"/>
          <admst:value-to select="sizetype" string="scalar"/>
          <admst:value-to select="type" string="integer"/>
          <admst:value-to select="input" string="yes"/>
          <admst:value-to select="output" string="yes"/>
          <admst:value-to select="parametertype" string="model"/>
          <admst:value-to select="scope" string="global_model"/>
          <admst:new datatype="number" inputs="0">
            <admst:value-to select="scalingunit" string="1"/>
            <admst:new datatype="expression" inputs="../module,.">
              <admst:value-to select="../../default" path="."/>
            </admst:new>
          </admst:new>
        </admst:new>
      </admst:if>
    </admst:when>
    <admst:when test="[name='pspva' or name='EKV26MOS']">
      <admst:if test="[nilled(variable[name='nmos'])]">
        <admst:new datatype="variable" inputs=".,'nmos',analog">
          <admst:push into="module/variable" select="." onduplicate="ignore"/>
          <admst:value-to select="sizetype" string="scalar"/>
          <admst:value-to select="type" string="integer"/>
          <admst:value-to select="input" string="yes"/>
          <admst:value-to select="output" string="yes"/>
          <admst:value-to select="parametertype" string="model"/>
          <admst:value-to select="scope" string="global_model"/>
          <admst:new datatype="number" inputs="1">
            <admst:value-to select="scalingunit" string="1"/>
            <admst:new datatype="expression" inputs="../module,.">
              <admst:value-to select="../../default" path="."/>
            </admst:new>
          </admst:new>
        </admst:new>
      </admst:if>
      <admst:if test="[nilled(variable[name='pmos'])]">
        <admst:new datatype="variable" inputs=".,'pmos',analog">
          <admst:push into="module/variable" select="." onduplicate="ignore"/>
          <admst:value-to select="sizetype" string="scalar"/>
          <admst:value-to select="type" string="integer"/>
          <admst:value-to select="input" string="yes"/>
          <admst:value-to select="output" string="yes"/>
          <admst:value-to select="parametertype" string="model"/>
          <admst:value-to select="scope" string="global_model"/>
          <admst:new datatype="number" inputs="1">
            <admst:value-to select="scalingunit" string="1"/>
            <admst:new datatype="expression" inputs="../module,.">
              <admst:value-to select="../../default" path="."/>
            </admst:new>
          </admst:new>
        </admst:new>
      </admst:if>
    </admst:when>

    <admst:otherwise>
      <admst:warning format="%(name): device not handled by the adms qucs interface\n"/>
      <admst:warning format="please ensure extra code to be added to the interface\n"/>
    </admst:otherwise>
  </admst:choose>
</admst:for-each>

</admst>
