<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:strip-space elements = "plan"/>
  <xsl:output method = "text"/>

  <xsl:template match = "*"/>

<xsl:template match = "/plan">
digraph nixplain {

<xsl:for-each select = ".//*[@addr]">
  <xsl:variable name = "x" select = "."/>
  <xsl:if test = "not($x/preceding::*[@addr = $x/@addr])">
    <xsl:apply-templates select = "." mode = "node"/>
    <xsl:apply-templates select = "." mode = "edges"/>
  </xsl:if>
</xsl:for-each>

}

</xsl:template>

<xsl:template match = "filter-expression" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  fontsize=10,
  height=0.2,
  width=0.4,
  fixedsize=false,
  label="FXP"
]
</xsl:template>

<xsl:template match = "location-path" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  fontsize=10,
  height=0.23,
  width=0.8,
  fixedsize=false,
  label="location-path"
]
</xsl:template>

<xsl:template match = "step-function" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  label="step-fun"
]
</xsl:template>

<xsl:template match = "location-step" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  fontsize=10,
  label="<xsl:value-of select = "axis/@name"/>\n<xsl:value-of select = "nodetest/@name"/>#<xsl:value-of select = "nodetest/@form"/>\nppd=<xsl:value-of select = "./@ppd"/>"
]
</xsl:template>

<xsl:template match = "split-predicate" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  fontsize=10,
  label="split-pred\n<xsl:value-of select = "./@flags"/>"
]
  A<xsl:value-of select = "./@addr"/>[
    shape=box,
    fixedsize=false,
    fontsize=10,
    label="nn"
  ]
  B<xsl:value-of select = "./@addr"/>[
    shape=box,
    fixedsize=false,
    fontsize=10,
    label="cp"
  ]
  C<xsl:value-of select = "./@addr"/>[
    shape=box,
    fixedsize=false,
    fontsize=10,
    label="cs"
  ]
</xsl:template>

<xsl:template match = "function-call" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  fontsize=9,
  fixedsize=false,
  height=0.25,
  label="<xsl:value-of select = "./@name"/><xsl:if test="./@reg">\nin Reg <xsl:value-of select="./@reg"/></xsl:if>"
]
</xsl:template>

<xsl:template match = "context" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  color=black,
  fontsize=10,
  shape=circle,
  fixedsize=false,
  height=0.3,
  <xsl:if test="./@global = 'true'">label="G" </xsl:if>
  <xsl:if test="./@global = 'false' and not(./@clone-of)">label="L"</xsl:if>
  <xsl:if test="./@global = 'false' and ./@clone-of">label="Lc"</xsl:if>
]
</xsl:template>

<xsl:template match = "var" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=circle,
  fontsize=10,
  label="<xsl:value-of select = "./@name"/>"
]
</xsl:template>

<xsl:template match = "const" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box, 
  fontsize=10,
  fixedsize=false,
  height=0.3,
  color=green,
  style=bold,
  label="<xsl:value-of select = "./@val"/>"
]
</xsl:template>

<xsl:template match = "algop" mode = "node">
  X<xsl:value-of select = "./@addr"/>[
  shape=box,
  style=bold,
  fontsize=10,
  fontcolor=blue,
  fixedsize=false,
  height=0.3,
  label="<xsl:value-of select = "./@name"/>"
  ]
</xsl:template>

<xsl:template match = "algop[@name='Map' and ./count]" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  style=bold,
  fontsize=10,
  fontcolor=blue,
  fixedsize=false,
  height=0.35,
  label="Map\ncount"
]
</xsl:template>

<xsl:template match = "algop[@name='ScanSingleton']" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  style=filled,
  fillcolor=lightgrey,
  fixedsize=false,
  height=0.3,
  width=0.3,
  fontsize=9,
  label = "Singleton Scan<xsl:if test="@reg">\nReg <xsl:value-of select="./@reg"/></xsl:if>"
]
</xsl:template>

<xsl:template match = "algop[@name='UnnestMap']" mode = "node">
X<xsl:value-of select = "./@addr"/>[ 
  shape=box,
  style=bold,
  fontsize=10,
  fontcolor=blue,
  fixedsize=false,
  label="UnnestMap\n<xsl:value-of select= "./axis"/>\n<xsl:value-of select = "./nodetest/@name"/>(<xsl:value-of select = "./nodetest/@form"/>)"
]
</xsl:template>

<xsl:template match = "algop[@name='XStep']" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  style=bold,
  fontsize=10,
  fontcolor=blue,
  fixedsize=false,
  label="XStep\n<xsl:value-of select= "./axis"/>\n<xsl:value-of select = "./nodetest/@name"/>(<xsl:value-of select = "./nodetest/@form"/>)"
]
</xsl:template>


<xsl:template match = "algop[@name='UnnestMapGroup']" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  style=bold,
  fontsize=10,
  fontcolor=blue,
  fixedsize=false,
  label="UnnestMap\n<xsl:value-of select= "./axis"/>\n<xsl:value-of select = "./nodetest/@name"/>(<xsl:value-of select = "./nodetest/@form"/>)"
]
</xsl:template>


<xsl:template match = "algop[@name='Aggr']" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  style=bold,
  fontsize=10,
  fontcolor=blue,
  fixedsize=false,
  height=0.35,
  label="<xsl:value-of select = "./@name"/>\n<xsl:value-of select = "./@kind"/>"
]
</xsl:template>

<xsl:template match = "algop[@name='Join']" mode = "node">
X<xsl:value-of select = "./@addr"/>[
  shape=box,
  style=bold,
  fontsize=10,
  fontcolor=blue,
  fixedsize=false,
  height=0.35,
  label="<xsl:value-of select = "./@name"/>\n<xsl:value-of select = "./@impl"/>"
]
</xsl:template>

<xsl:template match = "*" mode = "edges"/>

<xsl:template match = "*[@addr and not(self::split-predicate) and not(self::algop)]" mode = "edges">
  <xsl:variable name = "x" select = "."/>
  <xsl:for-each select = "./*[@addr]">
    X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>
  </xsl:for-each>
  <xsl:for-each select = "./*[not(@addr)]/*[@addr]">
    X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>
  </xsl:for-each>
  <xsl:for-each select = "./*[not(@addr)]/*[not(@addr)]/*[@addr]">
    X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>
  </xsl:for-each>
</xsl:template>

<xsl:template match = "split-predicate" mode = "edges">
  <xsl:variable name = "x" select = "."/>
  X<xsl:value-of select = "./@addr"/> -> A<xsl:value-of select = "./@addr"/>
  X<xsl:value-of select = "./@addr"/> -> B<xsl:value-of select = "./@addr"/>
  X<xsl:value-of select = "./@addr"/> -> C<xsl:value-of select = "./@addr"/>
  <xsl:for-each select = "$x/sp-no-pos-no-last/item/*">
    A<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>[weight=0.8]
  </xsl:for-each>
  <xsl:for-each select = "$x/sp-pos-no-last/item/*">
    B<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>[weight=0.8]
  </xsl:for-each>
  <xsl:for-each select = "$x/sp-last/item/*">
    C<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>[weight=0.8]
  </xsl:for-each>
</xsl:template>



<!-- edges for a d-join -->
<xsl:template match = "algop[@name='d-join']" mode = "edges">
  <xsl:variable name = "x" select = "."/>
    <xsl:if test = "$x/subscript">
      X<xsl:value-of select = "$x/@addr"/>
      ->
      X<xsl:value-of select = "$x/subscript/*/@addr"/>[style=dashed]
    </xsl:if>
    <xsl:for-each select = "$x/arg[1]/*">
      X<xsl:value-of select = "$x/@addr"/>
      ->
      X<xsl:value-of select = "./@addr"/>[weight=2]
    </xsl:for-each>
    <xsl:for-each select = "$x/arg[2]/*">
      X<xsl:value-of select = "$x/@addr"/> 
      -> 
      X<xsl:value-of select = "./@addr"/>[style=bold,label="I",weight=2]
  </xsl:for-each>
</xsl:template>

<!-- edges for the tmp-cs operator -->
<xsl:template match = "algop[@name='Tmp-CS']" mode="edges">
   <xsl:variable name = "x" select = "."/>
     <xsl:if test="$x/subscript">
       <!-- loop to display position and/or last -->
         <xsl:for-each select="$x/subscript/*/@addr">
         X<xsl:value-of select = "../../../@addr"/> 
         -> 
         X<xsl:value-of select = "."/>[style=dashed,fontsize=7,label="produces"]         
       </xsl:for-each>
     </xsl:if>

     <!-- all producers -->
     <xsl:for-each select = "$x/arg/*">
       X<xsl:value-of select = "$x/@addr"/>
       ->
       X<xsl:value-of select = "./@addr"/>[weight=2]
     </xsl:for-each>
</xsl:template>

<!-- edges for counting map -->
<xsl:template match = "algop[@name='Map' and count]" mode="edges">
   <xsl:variable name = "x" select = "."/>
     <xsl:if test="$x/subscript">
       <xsl:for-each select="$x/subscript/*/@addr">
         X<xsl:value-of select = "../../../@addr"/> -> X<xsl:value-of select = "."/>[style=dashed,fontsize=7,label="produces"]         
       </xsl:for-each>
       <xsl:for-each select = "$x/arg/*">
         X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>[weight=2]
       </xsl:for-each>
     </xsl:if>
</xsl:template>

<xsl:template match = "algop[@name='UnnestMapGroup' and function-call/@name='position']" mode="edges">
     <xsl:variable name = "x" select = "."/>
     <xsl:if test="$x/subscript">
       <xsl:for-each select="$x/subscript/*/@addr">
         X<xsl:value-of select = "../../../@addr"/> -> X<xsl:value-of select = "."/>[style=dashed,fontsize=7,label="produces"]
       </xsl:for-each>
       <xsl:for-each select = "$x/arg/*">
         X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>[weight=2]
       </xsl:for-each>
     </xsl:if>
     <xsl:if test="$x/function-call/@name='position'">
     	X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select ="$x/function-call/@addr"/>[style=dashed,fontsize=7,label="produces"]
     </xsl:if>
</xsl:template>

<xsl:template match = "algop[@name='UnnestMap' and function-call/@name='position']" mode="edges">
     <xsl:variable name = "x" select = "."/>
     <xsl:if test="$x/subscript">
       <xsl:for-each select="$x/subscript/*/@addr">
         X<xsl:value-of select = "../../../@addr"/> -> X<xsl:value-of select = "."/>[style=dashed,fontsize=7,label="produces"]
       </xsl:for-each>
       <xsl:for-each select = "$x/arg/*">
         X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>[weight=2]
       </xsl:for-each>
     </xsl:if>
     <xsl:if test="$x/function-call/@name='position'">
        X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select ="$x/function-call/@addr"/>[style=dashed,fontsize=7,label="produces"]
     </xsl:if>
</xsl:template>

<!-- fallback if no of the above templates matches for an algop -->
<xsl:template match = "algop" mode = "edges">
  <xsl:variable name = "x" select = "."/>
  <xsl:if test = "$x/subscript">
    X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "$x/subscript/*/@addr"/>[style=dashed,weight=1.0,fontsize=7<xsl:if test="./@name='UnnestMap'">,label="produces"</xsl:if>]
  </xsl:if>
  <xsl:for-each select = "$x/arg/*">
    X<xsl:value-of select = "$x/@addr"/> -> X<xsl:value-of select = "./@addr"/>[weight=2]
  </xsl:for-each>
</xsl:template>

<xsl:template match = "context[@clone-of]" mode = "edges">
X<xsl:value-of select = "./@addr"/> -> X<xsl:value-of select = "./@clone-of"/>[style=dotted]
</xsl:template>


</xsl:stylesheet>


