Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions PackageInfo.g
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ PackageDoc := rec(
),

Dependencies := rec(
GAP := ">= 4.8",
NeededOtherPackages := [ ["Automata", ">=1.13"], [ "GAPDoc", ">= 1.5" ] ],
GAP := ">= 4.16",
NeededOtherPackages := [ ["Automata", ">=1.13"], [ "GAPDoc", ">= 1.5" ], ["GraphvizForGAP", ">=0"] ],
SuggestedOtherPackages := [ ],
ExternalConditions := [ ],
),
Expand Down
1 change: 1 addition & 0 deletions init.g
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ReadPackage( "patternclass", "lib/inversion.gd" );
ReadPackage( "patternclass", "lib/simpleChains.gd" );
ReadPackage( "patternclass", "lib/simpleAuts.gd" );
ReadPackage( "patternclass", "lib/SubAut.gd" );
ReadPackage( "patternclass", "lib/visualisation.gd" );

## This is highly experimental code on grid classes and not automatically loaded
## if you choose to load it, you are doing it so at your own risk.
Expand Down
29 changes: 29 additions & 0 deletions lib/visualisation.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#############################################################################
##
##
#W visualisation.gd Ruth Hoffmann
##
##
#Y Copyright (C) 2026 School of Computer Science,
#Y University of St. Andrews, North Haugh,
#Y St. Andrews, Fife KY16 9SS, Scotland
##

#############################################################################
##
#F TPN2dot( tpn, name )
##
## Returns a String containing dot syntax for the visualisation of the
## Token Passing Network visualised, and named name.
##
DeclareGlobalFunction( "TPN2dot" );


#############################################################################
##
#F Transducer2dot( Transducer, name )
##
## Returns a String containing dot syntax for the visualisation of the
## transducer, and named name.
##
DeclareGlobalFunction( "Transducer2dot" );
84 changes: 84 additions & 0 deletions lib/visualisation.gi
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#############################################################################
##
##
#W visualisation.gi Ruth Hoffmann
##
#Y Copyright (C) 2026 School of Computer Science,
#Y University of St. Andrews, North Haugh,
#Y St. Andrews, Fife KY16 9SS, Scotland
##


#############################################################################
##
#F TPN2dot( tpn, name )
##
## Returns a String containing dot syntax for the visualisation of the
## Token Passing Network visualised, and named name.
##
InstallGlobalFunction(TPN2dot, function( tpn, name )
local f, innode, outnode, nodes, isin, n, m,i;
f := GraphvizDigraph(name);
GraphvizSetAttrs(f, rec(rankdir:="LR", layout:="neato"));
GraphvizSetAttr(f, "node [shape = circle]");

innode := GraphvizAddNode(f, "in");
GraphvizSetAttr(innode, "shape", "none");
GraphvizSetAttr(innode, "label", "\"\"");

outnode := GraphvizAddNode(f, "out");
GraphvizSetAttr(outnode, "shape", "none");
GraphvizSetAttr(outnode, "label", "\"\"");

isin := [1 .. Size(tpn)];
for n in [1 .. Size(tpn)] do
GraphvizSetAttr(GraphvizAddNode(f, String(n)), "shape", "circle") ;
if IsEmpty(tpn[n]) then
GraphvizAddEdge(f, String(n), "out");
else
for m in tpn[n] do
GraphvizAddEdge(f, String(n), String(m));
if m in isin then
Remove(isin, Position(isin, m));
fi;
od;
fi;
od;
for i in isin do
GraphvizAddEdge(f, "in", String(i));
od;
return AsString(f);
end);

#############################################################################
##
#F Transducer2dot( Transducer, name )
##
## Returns a String containing dot syntax for the visualisation of the
## transducer, and named name.
##
InstallGlobalFunction(Transducer2dot, function(transducer, name)
local f, accept, i, start, innode, startnode;
f := GraphvizDigraph(name);
GraphvizSetAttrs(f, rec(rankdir:="LR", layout:="dot"));
GraphvizSetAttr(f, "node [shape = circle]");

accept := GraphvizAddContext(f, "accept");
GraphvizSetAttr(accept, "node [shape=doublecircle]");
for i in transducer.accepting do
GraphvizAddNode(accept, String(i));
od;

start := GraphvizAddContext(f,"start");
innode := GraphvizAddNode(start, "in");
GraphvizSetAttr(innode, "shape", "none");
GraphvizSetAttr(innode, "label","\"\"");
startnode := GraphvizAddNode(start, String(transducer.initial));
GraphvizAddEdge(start, innode, startnode);

for i in transducer.transitions do

GraphvizSetAttr(GraphvizAddEdge(f, String(i[3]), String(i[4])), "label", Concatenation("\"", String(i[1]), "|", String(i[2]), "\""));
od;
return AsString(f);
end);
1 change: 1 addition & 0 deletions read.g
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ReadPackage( "patternclass", "lib/inversion.gi" );
ReadPackage( "patternclass", "lib/simpleChains.gi" );
ReadPackage( "patternclass", "lib/simpleAuts.gi" );
ReadPackage( "patternclass", "lib/SubAut.gi" );
ReadPackage( "patternclass", "lib/visualisation.gi" );

## This is highly experimental code on grid classes and not automatically loaded
## if you choose to load it, you are doing it so at your own risk.
Expand Down
38 changes: 38 additions & 0 deletions tst/vis.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#############################################################################
##
#A vis.tst PatternClass package Ruth Hoffmann
##
gap> START_TEST("visualisation");
gap> LoadPackage("patternclass",false);
true
gap> SetAssertionLevel(1);
gap> hex:=[[2,3],[4],[5],[3,6],[6],[]];;
gap> hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ];;
gap> tpn := TPN2dot(hex,"Network");
Error, Variable: 'TPN2dot' must have a value
gap> tpn2 := TPN2dot(hex2,"Network2");
Error, Variable: 'TPN2dot' must have a value
gap> trans := rec( accepting := [ 2 ], initial := 1, states := 3, transitions := [ [ 1, 2, 1, 2 ], [ 1, 2, 2, 2 ], [ 2, 2, 1, 3 ], [ 2, 2, 2, 3 ], [ 1, 1, 3, 3 ], [ 2, 2, 3, 3 ] ] );;
gap> trans2 := rec( accepting := [ 1 .. 3 ], initial := 4, states := 4, transitions := [ [ 1, 1, 4, 4 ], [ 0, 1, 4, 1 ], [ 1, 2, 1, 1 ], [ 1, 1, 1, 2 ], [ 2, 3, 1, 1 ], [ 1, 1, 2, 3 ], [ 1, 1, 3, 3 ], [ 2, 2, 4, 4 ], [ 0, 2, 4, 2 ], [ 2, 3, 2, 2 ], [ 2, 2, 2, 3 ], [ 2, 2, 3, 3 ], [ 3, 3, 4, 4 ], [ 0, 3, 4, 3 ], [ 3, 3, 3, 3 ] ] );'
rec( accepting := [ 1 .. 3 ], initial := 4, states := 4,
transitions := [ [ 1, 1, 4, 4 ], [ 0, 1, 4, 1 ], [ 1, 2, 1, 1 ],
[ 1, 1, 1, 2 ], [ 2, 3, 1, 1 ], [ 1, 1, 2, 3 ], [ 1, 1, 3, 3 ],
[ 2, 2, 4, 4 ], [ 0, 2, 4, 2 ], [ 2, 3, 2, 2 ], [ 2, 2, 2, 3 ],
[ 2, 2, 3, 3 ], [ 3, 3, 4, 4 ], [ 0, 3, 4, 3 ], [ 3, 3, 3, 3 ] ] )
Syntax error: Character literal must not include <newline> in stream:1
trans2 := rec( accepting := [ 1 .. 3 ], initial := 4, states := 4, transitions\
:= [ [ 1, 1, 4, 4 ], [ 0, 1, 4, 1 ], [ 1, 2, 1, 1 ], [ 1, 1, 1, 2 ], [ 2, 3, \
1, 1 ], [ 1, 1, 2, 3 ], [ 1, 1, 3, 3 ], [ 2, 2, 4, 4 ], [ 0, 2, 4, 2 ], [ 2, 3\
, 2, 2 ], [ 2, 2, 2, 3 ], [ 2, 2, 3, 3 ], [ 3, 3, 4, 4 ], [ 0, 3, 4, 3 ], [ 3,\
3, 3, 3 ] ] );'
\
\
\
\
^
gap> vist := Transducer2dot(trans,"trans");
Error, Variable: 'Transducer2dot' must have a value
gap> vist2 := Transducer2dot(trans2,"trans2");
Error, Variable: 'Transducer2dot' must have a value
gap> END_TEST("PatternClass");
Error, Variable: 'END_TEST' must have a value
Loading