Skip to content

Commit

Permalink
Export morphisms for pyzx
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Kuhmichel committed Aug 25, 2023
1 parent 4d719bc commit 6b9cdd3
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 0 deletions.
1 change: 1 addition & 0 deletions PackageInfo.g
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Dependencies := rec(
],
SuggestedOtherPackages := [
[ "FunctorCategories", ">= 2023.07-01" ], # CategoryOfDecoratedQuivers
[ "json", "2.1.1" ], # Exporting to JSON
],
ExternalConditions := [ ],
),
Expand Down
16 changes: 16 additions & 0 deletions gap/Tools.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# ZXCalculusForCAP: The category of ZX-diagrams
#
# Declarations
#
#! @Chapter Tools

#! @Section Exporting ZX-diagrams

#! @Description
#! Takes a morphism in a category of ZX-diagrams and a filename **file**
#! and exports the morphism as **file**.qgraph.
#! See https://github.com/Quantomatic/quantomatic/blob/stable/docs/json_formats.txt
#! for an overview of the qgraph format.
#! @Arguments morphism, filename
DeclareGlobalFunction( "ExportAsQGraph" );
158 changes: 158 additions & 0 deletions gap/Tools.gi
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# ZXCalculusForCAP: The category of ZX-diagrams
#
# Implementations
#

InstallGlobalFunction( ExportAsQGraph,

function ( phi, filename )
local pair, labels, edges, pos, edge_positions, new_edge, edge_1, edge_2,
remaining_indices, node_vertices, undir_edges, edge, source, target,
edge_name, qgraph, file;

pair := MorphismDatum( phi );

labels := ShallowCopy( pair[1] );
edges := ShallowCopy( pair[2] );

# remove neutral nodes
while "neutral" in labels do

pos := SafePosition( labels, "neutral" );

# find the edges connecting to the current node
edge_positions := PositionsProperty( edges, e -> (pos - 1) in e );

new_edge := fail;

# degenerate case: loop
if Length( edge_positions ) = 1 then

# nothing to do

# usual case: two edges
elif Length( edge_positions ) = 2 then

edge_1 := edges[edge_positions[1]];
edge_2 := edges[edge_positions[2]];

new_edge := [ ];

if edge_1[1] = pos - 1 then

Assert( 0, edge_1[2] <> pos - 1 );

Add( new_edge, edge_1[2] );

elif edge_1[2] = pos - 1 then

Assert( 0, edge_1[1] <> pos - 1 );

Add( new_edge, edge_1[1] );

else

Error( "this should never happen" );

fi;

if edge_2[1] = pos - 1 then

Assert( 0, edge_2[2] <> pos - 1 );

Add( new_edge, edge_2[2] );

elif edge_2[2] = pos - 1 then

Assert( 0, edge_2[1] <> pos - 1 );

Add( new_edge, edge_2[1] );

else

Error( "this should never happen" );

fi;

else

Error( "this should never happen" );

fi;

Remove( labels, pos );

# we cannot use Remove for the two edges because the position of the second edge might change after the first is removed
remaining_indices := Difference( [ 1 .. Length( edges ) ], edge_positions );
edges := edges{remaining_indices};

if new_edge <> fail then

Add( edges, new_edge );

fi;

# adjust edges from/to nodes after the removed node
edges := List( edges, function ( e )

e := ShallowCopy( e );

Assert( 0, e[1] <> pos - 1 );

if e[1] > pos - 1 then

e[1] := e[1] - 1;

fi;

Assert( 0, e[2] <> pos - 1 );

if e[2] > pos - 1 then

e[2] := e[2] - 1;

fi;

return e;

end );

od;

# See https://github.com/Quantomatic/quantomatic/blob/stable/docs/json_formats.txt
# for an overview of the qgraph format.

node_vertices := rec( );

for pos in [ 1 .. Length( labels ) ] do

node_vertices.( pos - 1 ) := rec( data := rec( type := labels[ pos ] ) );

od;

undir_edges := rec( );

for edge in edges do

source := edge[1];
target := edge[2];

edge_name := Concatenation( "E", String( source ), String( target ) );

undir_edges.( edge_name ) := rec( src := source, tgt := target );

od;

qgraph := rec( node_vertices := node_vertices,
undir_edges := undir_edges );

qgraph := GapToJsonString( qgraph );

file := OutputTextFile( Concatenation( filename, ".qgraph" ), false );;

SetPrintFormattingStatus( file, false );

PrintTo( file, qgraph );

end );
2 changes: 2 additions & 0 deletions init.g
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ ReadPackage( "ZXCalculusForCAP", "gap/CategoryOfCospans_for_ZXCalculus.gd" );
ReadPackage( "ZXCalculusForCAP", "gap/CategoryOfZXDiagrams.gd" );

ReadPackage( "ZXCalculusForCAP", "gap/CategoryOfZXDiagrams_as_CategoryOfCospans_CategoryOfDecoratedQuivers.gd" );

ReadPackage( "ZXCalculusForCAP", "gap/Tools.gd" );
2 changes: 2 additions & 0 deletions read.g
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ ReadPackage( "ZXCalculusForCAP", "gap/precompiled_categories/CategoryOfZXDiagram

ReadPackage( "ZXCalculusForCAP", "gap/CategoryOfZXDiagrams.gi" );

ReadPackage( "ZXCalculusForCAP", "gap/Tools.gi" );

#= comment for Julia
if IsPackageMarkedForLoading( "FunctorCategories", ">= 2023.07-01" ) then

Expand Down

0 comments on commit 6b9cdd3

Please sign in to comment.