<?xml version="1.0" encoding="UTF-8"?>

<!--
    Document   : use-case-5.27.xml
    Created on : July 5, 2006, 12:50 PM
    Author     : alex
    Description:
    
       Receives a gap-matrix element with a matrix and weight vector
       and returns the gap and component that generated the gap.
       
-->

<p:pipeline xmlns:p='http://www.w3.org/2006/XProc'
          xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
          xsi:schemaLocation='http://www.w3.org/2006/XProc pipeline.xsd'
          xmlns:m="http://www.milowski.com/Vocabulary/Math/Monos/2005/1/0"
          xmlns:monos="http://www.milowski.com/Vocabulary/Math/Monos/Steps/2005/1/0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <p:input name="gap-matrix"/>
   <p:output name="result" from="gap"/>
   <p:parameter input="gap-matrix" name="matrix" select="m:matrix"/>
   <p:parameter input="gap-matrix" name="weight" select="m:weight"/>

   <!-- transform the request document into the input for monos -->
   <p:step kind="p:xslt">
      <p:input name="input" from="gap-matrix"/>
      <p:input name="stylesheet">
        <xsl:transform version="1.0">
           <xsl:template match="m:gap-matrix">
              <m:compute-basis monomial-order="wgrevlex" output="matrix-compact">
                  <m:binomial-ideal>
                    <xsl:copy-of select="m:matrix"/>
                  </m:binomial-ideal>
                  <xsl:copy-of select="m:weight"/>
                  <xsl:copy-of select="m:matrix"/>
              </m:compute-basis>
           </xsl:template>
        </xsl:transform>
      </p:input>
      <p:output name="compute-basis-request"/>
   </p:step>

   <!-- do a column sum on the matrix for a row-space vector -->
   <p:for-each select="m:compute-basis/m:matrix" over="compute-basis-request" to="matrix" replacement="row-vector">
      <p:output name="request-with-row-vector"/>
      <p:step kind="monos:column-sum-matrix">
         <p:input name="matrix" from="matrix"/>
         <p:output name="column-sum"/>
      </p:step>
      <p:step kind="p:rename">
         <p:input name="column-sum"/>
         <p:output name="row-vector"/>
         <p:parameter name="expression" value="m:ilist"/>
         <p:parameter name="name" value="m:row-space-vector"/>
      </p:step>
   </p:for-each>

   <!-- compute the kernel of the matrix (a filter on the matrix element) -->
   <p:step kind="monos:kernel-basis">
      <p:input name="input" from="request-with-row-vector"/>
      <p:output name="kernel-computed"/>
   </p:step>

   <!-- compute the groebner basis -->
   <p:step kind="monos:binomial-groebner">
      <p:input name="input" from="kernel-computed"/>
      <p:output name="basis-computed"/>
      <p:parameter name="toric" value="true"/>
   </p:step>

   <!-- use the whole result to generate an initial ideal -->
   <p:step kind="monos:initial-ideal">
      <p:input name="input" from="basis-computed"/>
      <p:output name="initial-ideal-computed"/>
   </p:step>

   <!-- step the decompose request -->
   <p:step kind="p:wrap">
      <p:input name="input" from="initial-ideal-component"/>
      <p:output name="decompose-request"/>
      <p:parameter name="name" value="m:decompose"/>
   </p:step>
   <p:step kind="monos:decompose">
      <p:input name="input" from="decompose-request"/>
      <p:output name="decomposition-computed"/>
   </p:step>

   <p:step kind="p:xslt">
      <p:input name="input" from="decomposition-computed"/>
      <p:input name="stylesheet">
         <xsl:transform version="1.0">
            <xsl:param name="matrix"/>
            <xsl:param name="weight"/>
            <xsl:template match="/">
               <m:formulate-gap>
                  <xsl:copy-of select="$matrix"/>
                  <xsl:copy-of select="$weight"/>
                  <xsl:copy-of select="."/>
               </m:formulate-gap>
            </xsl:template>
         </xsl:transform>
      </p:input>
      <p:output name="gap-formulate-request"/>
   </p:step>

   <!-- filter the components and generate gap LP's for each one -->
   <p:step kind="monos:formulate-gap-lp">
      <p:input name="input" from="gap-formulate-request"/>
      <p:output name="lps-computed"/>
   </p:step>

   <!-- Solve each LP in the instance -->
   <p:step kind="monos:solve-lp">
      <p:input name="input" from="lps-computed"/>
      <p:output name="lps-solved"/>
   </p:step>

   <p:step kind="p:xquery">
      <p:input name="input" from="lps-solved"/>
      <p:input name="query">
         <query>
             declare namespace m = "http://www.milowski.com/Vocabulary/Math/Monos/2005/1/0";
             declare namespace gap = "http://www.milowski.com/example";

             declare function gap:convert-rational($v) as xs:double {
                if (contains($v,"/"))
                   then number(substring-before($v,"/")) div
                        number(substring-after($v,"/")) 
                   else number($v)
             };

             (for $sol in /m:component-lp-list/m:component-lp/m:solution
                           order by gap:convert-rational($sol/@value) descending
                return $sol)[1]/..
         </query>
      </p:input>
      <p:output name="gap"/>
    </p:step>
</p:pipeline>

