Add graph:union

* src/graph.xsl (graph:union): Added
* test/graph-test.xsl: Test data added
* test/graph.xspec: Tests added
master
Mike Gerwitz 2016-07-05 15:18:38 -04:00
parent e34cf22d6b
commit 551e489c5f
3 changed files with 162 additions and 0 deletions

View File

@ -144,4 +144,50 @@
</preproc:sym-deps>
</function>
<!--
Merge sequence of graphs @var{$graphs} into a single graph by taking
the union of all vertices and edges.
Directionality will be preserved.
Edge attributes (@code{preproc:sym-ref/@@*)} will be set to the
union of all attributes on all edges of the same @code{@@name}.
@emph{If edge attributes do not share the same value,
the behavior is undefined.}
For example:
@float Figure, fig:union-graph
@verbatim
G₁: A->B->C
G₂: C->A
G₃: B->C->D
G: A->B->C->D
^____/
@end verbatim
@caption{(G₁ G₂ G₃)}
@end float
-->
<function name="graph:union" as="element( preproc:sym-deps )*">
<param name="graphs" as="element( preproc:sym-deps )*" />
<preproc:sym-deps>
<for-each-group select="$graphs/preproc:sym-dep"
group-by="@name">
<preproc:sym-dep name="{@name}">
<for-each-group select="current-group()/preproc:sym-ref"
group-by="@name">
<preproc:sym-ref>
<sequence select="current-group()/@*" />
<!-- keep our name (overrides the above) -->
<attribute name="name" select="@name" />
</preproc:sym-ref>
</for-each-group>
</preproc:sym-dep>
</for-each-group>
</preproc:sym-deps>
</function>
</stylesheet>

View File

@ -99,6 +99,76 @@
</variable>
<variable name="foo:graph-empty" as="element( preproc:sym-deps )">
<preproc:sym-deps />
</variable>
<variable name="foo:graph-vtwo" as="element( preproc:sym-deps )">
<preproc:sym-deps>
<preproc:sym-dep name="a">
<preproc:sym-ref name="a" attr1="foo" />
<preproc:sym-ref name="b" attr2="bar" />
</preproc:sym-dep>
<!-- test empty for merge -->
<preproc:sym-dep name="b" />
</preproc:sym-deps>
</variable>
<variable name="foo:graph-vthree" as="element( preproc:sym-deps )">
<preproc:sym-deps>
<preproc:sym-dep name="a">
<preproc:sym-ref name="b" attr1="foo" />
<preproc:sym-ref name="c" />
</preproc:sym-dep>
<preproc:sym-dep name="b">
<preproc:sym-ref name="c" attr3="baz" />
</preproc:sym-dep>
<preproc:sym-dep name="c">
<preproc:sym-ref name="a" />
</preproc:sym-dep>
<!-- disconnected -->
<preproc:sym-dep name="d">
<preproc:sym-ref name="e" />
</preproc:sym-dep>
<preproc:sym-dep name="e" />
</preproc:sym-deps>
</variable>
<!-- result of merging the above two -->
<variable name="foo:graph-vtwo-vthree" as="element( preproc:sym-deps )">
<preproc:sym-deps>
<preproc:sym-dep name="a">
<preproc:sym-ref name="a" attr1="foo" />
<preproc:sym-ref name="b" attr1="foo" attr2="bar" />
<preproc:sym-ref name="c" />
</preproc:sym-dep>
<preproc:sym-dep name="b">
<preproc:sym-ref name="c" attr3="baz" />
</preproc:sym-dep>
<preproc:sym-dep name="c">
<preproc:sym-ref name="a" />
</preproc:sym-dep>
<!-- disconnected -->
<preproc:sym-dep name="d">
<preproc:sym-ref name="e" />
</preproc:sym-dep>
<preproc:sym-dep name="e" />
</preproc:sym-deps>
</variable>
<function name="foo:lookup">
<param name="yield" as="element()" />
<param name="symbol" as="element( preproc:sym )" />

View File

@ -171,4 +171,50 @@
$edge/@cattr = 'cvalue'
and $edge/@cattr2 = 'cvalue2'" />
</scenario>
<scenario label="graph:union">
<scenario label="given nothing">
<call function="graph:union">
<param name="graphs"
select="()" />
</call>
<expect label="produces an empty graph"
select="$foo:graph-empty" />
</scenario>
<scenario label="given two empty graphs">
<call function="graph:union">
<param name="graphs"
select="( $foo:graph-empty, $foo:graph-empty )" />
</call>
<expect label="produces an empty graph"
select="$foo:graph-empty" />
</scenario>
<scenario label="given graph with empty">
<call function="graph:union">
<param name="graphs"
select="( $foo:graph-empty, $foo:graph-vtwo )" />
</call>
<expect label="produces the non-empty graph"
select="$foo:graph-vtwo" />
</scenario>
<scenario label="given two different graphs">
<call function="graph:union">
<param name="graphs"
select="( $foo:graph-vtwo, $foo:graph-vthree )" />
</call>
<expect label="merges vertices and edges of unique vertices"
select="$foo:graph-vtwo-vthree" />
</scenario>
</scenario>
</description>