From 2927512ade070e1d45a539d3f53d5dcc602b5399 Mon Sep 17 00:00:00 2001 From: Ruth Hoffmann Date: Tue, 29 Sep 2026 17:13:23 +0200 Subject: [PATCH 1/5] start on the visualisation --- lib/vis.g | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 lib/vis.g diff --git a/lib/vis.g b/lib/vis.g new file mode 100644 index 0000000..1dc88a9 --- /dev/null +++ b/lib/vis.g @@ -0,0 +1,90 @@ +LoadPackage("graphvizforgap"); + +# hex:=[[2,3],[4],[5],[3,6],[6],[]]; +# hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ]; +# tpn := tpn2dot(hex,"tpn"); +# tpn2 := tpn2dot(hex2,"tpn2"); + +tpn2dot := function( tpn, name ) +local f, innode, outnode, nodes, isin, n, m,i; + f := GraphvizDigraph(name); + GraphvizSetAttrs(f, rec(rankdir:="LR", size:="\"8,5\"", layout:="neato")); + + innode := GraphvizAddNode(f, "in"); + GraphvizSetAttr(innode, "shape", "none"); + GraphvizSetAttr(innode, "label", "\"\""); + + outnode := GraphvizAddNode(f, "out"); + GraphvizSetAttr(outnode, "shape", "none"); + GraphvizSetAttr(outnode, "label", "\"\""); + + nodes := GraphvizAddContext(f, "nodes"); + GraphvizSetAttr(nodes, "node [shape=circle]"); + +# THIS IS SUPER INEFFICIENT and only here because adding nodes after edges currently doesn't work + for i in [1 .. Size(tpn)] do + GraphvizAddNode(f,String(i)); + od; + + isin := [1 .. Size(tpn)]; + for n in [1 .. Size(tpn)] do +# Add this back in once issue has been resolved +# GraphvizAddNode(nodes, String(n)); + 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; + + +# 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 ] ] ); + + +# 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 ] ] ); + +transducer2dot := function(transducer, name) + local f, accept, i, start, innode, startnode; + f := GraphvizDigraph(name); + GraphvizSetAttrs(f, rec(rankdir:="LR", size:="\"8,5\"", layout:="dot")); + + 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; + +# Splash(transducer2dot(trans,"trans")); +# Splash(transducer2dot(trans2,"trans2")); +# # Display(transducer2dot(trans2,"trans2")); \ No newline at end of file From 0f2ab94c279b25863caceb2bb6229522e8c22876 Mon Sep 17 00:00:00 2001 From: Ruth Hoffmann Date: Wed, 30 Sep 2026 17:55:09 +0200 Subject: [PATCH 2/5] minor adjustments --- lib/vis.g | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/vis.g b/lib/vis.g index 1dc88a9..b1557e4 100644 --- a/lib/vis.g +++ b/lib/vis.g @@ -1,14 +1,10 @@ LoadPackage("graphvizforgap"); -# hex:=[[2,3],[4],[5],[3,6],[6],[]]; -# hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ]; -# tpn := tpn2dot(hex,"tpn"); -# tpn2 := tpn2dot(hex2,"tpn2"); - tpn2dot := function( tpn, name ) local f, innode, outnode, nodes, isin, n, m,i; f := GraphvizDigraph(name); GraphvizSetAttrs(f, rec(rankdir:="LR", size:="\"8,5\"", layout:="neato")); + GraphvizSetAttr(f, "node [shape = circle]"); innode := GraphvizAddNode(f, "in"); GraphvizSetAttr(innode, "shape", "none"); @@ -18,18 +14,18 @@ local f, innode, outnode, nodes, isin, n, m,i; GraphvizSetAttr(outnode, "shape", "none"); GraphvizSetAttr(outnode, "label", "\"\""); - nodes := GraphvizAddContext(f, "nodes"); - GraphvizSetAttr(nodes, "node [shape=circle]"); + # nodes := GraphvizAddContext(f, "nodes"); + # GraphvizSetAttr(nodes, "node [shape=circle]"); # THIS IS SUPER INEFFICIENT and only here because adding nodes after edges currently doesn't work - for i in [1 .. Size(tpn)] do - GraphvizAddNode(f,String(i)); - od; + # for i in [1 .. Size(tpn)] do + # GraphvizAddNode(f,String(i)); + # od; isin := [1 .. Size(tpn)]; for n in [1 .. Size(tpn)] do # Add this back in once issue has been resolved -# GraphvizAddNode(nodes, String(n)); + GraphvizSetAttr(GraphvizAddNode(f, String(n)), "shape", "circle") ; if IsEmpty(tpn[n]) then GraphvizAddEdge(f, String(n), "out"); else @@ -47,23 +43,19 @@ local f, innode, outnode, nodes, isin, n, m,i; return AsString(f); end; +hex:=[[2,3],[4],[5],[3,6],[6],[]]; +hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ]; +tpn := tpn2dot(hex,"Network"); +tpn2 := tpn2dot(hex2,"Network2"); - -# 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 ] ] ); - - -# 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 ] ] ); +# Splash(tpn); +# Splash(tpn2); transducer2dot := function(transducer, name) local f, accept, i, start, innode, startnode; f := GraphvizDigraph(name); GraphvizSetAttrs(f, rec(rankdir:="LR", size:="\"8,5\"", layout:="dot")); + GraphvizSetAttr(f, "node [shape = circle]"); accept := GraphvizAddContext(f, "accept"); GraphvizSetAttr(accept, "node [shape=doublecircle]"); @@ -85,6 +77,18 @@ transducer2dot := function(transducer, name) return AsString(f); end; -# Splash(transducer2dot(trans,"trans")); -# Splash(transducer2dot(trans2,"trans2")); -# # Display(transducer2dot(trans2,"trans2")); \ No newline at end of file +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 ] ] ); + + +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 ] ] ); + +vist := transducer2dot(trans,"trans"); +vist2 := transducer2dot(trans2,"trans2"); +#Splash(vist); +Splash(vist2,rec(filename:="test", path:="./", directory:="./")); \ No newline at end of file From 8ba5e3d3434cfb736ffb6122a8e6951a3ec68bd0 Mon Sep 17 00:00:00 2001 From: Ruth Hoffmann Date: Fri, 2 Oct 2026 11:23:51 +0200 Subject: [PATCH 3/5] very inital work for making dot for TPNs and transducers --- lib/vis.g | 41 ++++++++++++++++------------------------- tst/vis.tst | 13 +++++++++++++ 2 files changed, 29 insertions(+), 25 deletions(-) create mode 100644 tst/vis.tst diff --git a/lib/vis.g b/lib/vis.g index b1557e4..3d18f9d 100644 --- a/lib/vis.g +++ b/lib/vis.g @@ -14,17 +14,8 @@ local f, innode, outnode, nodes, isin, n, m,i; GraphvizSetAttr(outnode, "shape", "none"); GraphvizSetAttr(outnode, "label", "\"\""); - # nodes := GraphvizAddContext(f, "nodes"); - # GraphvizSetAttr(nodes, "node [shape=circle]"); - -# THIS IS SUPER INEFFICIENT and only here because adding nodes after edges currently doesn't work - # for i in [1 .. Size(tpn)] do - # GraphvizAddNode(f,String(i)); - # od; - isin := [1 .. Size(tpn)]; for n in [1 .. Size(tpn)] do -# Add this back in once issue has been resolved GraphvizSetAttr(GraphvizAddNode(f, String(n)), "shape", "circle") ; if IsEmpty(tpn[n]) then GraphvizAddEdge(f, String(n), "out"); @@ -43,10 +34,10 @@ local f, innode, outnode, nodes, isin, n, m,i; return AsString(f); end; -hex:=[[2,3],[4],[5],[3,6],[6],[]]; -hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ]; -tpn := tpn2dot(hex,"Network"); -tpn2 := tpn2dot(hex2,"Network2"); +# hex:=[[2,3],[4],[5],[3,6],[6],[]]; +# hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ]; +# tpn := tpn2dot(hex,"Network"); +# tpn2 := tpn2dot(hex2,"Network2"); # Splash(tpn); # Splash(tpn2); @@ -77,18 +68,18 @@ transducer2dot := function(transducer, name) return AsString(f); end; -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 ] ] ); +# 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 ] ] ); -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 ] ] ); +# 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 ] ] ); -vist := transducer2dot(trans,"trans"); -vist2 := transducer2dot(trans2,"trans2"); -#Splash(vist); -Splash(vist2,rec(filename:="test", path:="./", directory:="./")); \ No newline at end of file +# vist := transducer2dot(trans,"trans"); +# vist2 := transducer2dot(trans2,"trans2"); +# #Splash(vist); +# Splash(vist2,rec(filename:="test", path:="./", directory:="./")); \ No newline at end of file diff --git a/tst/vis.tst b/tst/vis.tst new file mode 100644 index 0000000..360a68a --- /dev/null +++ b/tst/vis.tst @@ -0,0 +1,13 @@ +############################################################################# +## +#A vis.tst PatternClass package Ruth Hoffmann +## +gap> START_TEST("PatternClass"); +gap> LoadPackage("patternclass",false); +true +gap> SetAssertionLevel(1); +gap> hex:=[[2,3],[4],[5],[3,6],[6],[]];; +gap> tpn2dot(hex,"tpn"); +"//dot\ndigraph tpn {\n\tsize=\"8,5\" rankdir=LR layout=neato \n\tin [label=\"\", shape=none]\n\tout [label=\"\", shape=none]\n// nodes context \n{\n\tnode [shape=\ +circle] \n}\n\t1\n\t2\n\t3\n\t4\n\t5\n\t6\n\t1 -> 2\n\t1 -> 3\n\t2 -> 4\n\t3 -> 5\n\t4 -> 3\n\t4 -> 6\n\t5 -> 6\n\t6 -> out\n\tin -> 1\n}\n" +gap> \ No newline at end of file From 45baba9dedd11bb641ef783f310cae020db85cb2 Mon Sep 17 00:00:00 2001 From: Ruth Hoffmann Date: Fri, 2 Oct 2026 11:25:59 +0200 Subject: [PATCH 4/5] added back the intermediate tests into vis.g --- lib/vis.g | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/vis.g b/lib/vis.g index 3d18f9d..8ab41c3 100644 --- a/lib/vis.g +++ b/lib/vis.g @@ -34,13 +34,13 @@ local f, innode, outnode, nodes, isin, n, m,i; return AsString(f); end; -# hex:=[[2,3],[4],[5],[3,6],[6],[]]; -# hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ]; -# tpn := tpn2dot(hex,"Network"); -# tpn2 := tpn2dot(hex2,"Network2"); +hex:=[[2,3],[4],[5],[3,6],[6],[]]; +hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ]; +tpn := tpn2dot(hex,"Network"); +tpn2 := tpn2dot(hex2,"Network2"); -# Splash(tpn); -# Splash(tpn2); +Splash(tpn); +Splash(tpn2); transducer2dot := function(transducer, name) local f, accept, i, start, innode, startnode; @@ -68,18 +68,18 @@ transducer2dot := function(transducer, name) return AsString(f); end; -# 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 ] ] ); +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 ] ] ); -# 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 ] ] ); +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 ] ] ); -# vist := transducer2dot(trans,"trans"); -# vist2 := transducer2dot(trans2,"trans2"); -# #Splash(vist); -# Splash(vist2,rec(filename:="test", path:="./", directory:="./")); \ No newline at end of file +vist := transducer2dot(trans,"trans"); +vist2 := transducer2dot(trans2,"trans2"); +Splash(vist); +Splash(vist2);#,rec(filename:="test", path:="./", directory:="./")); \ No newline at end of file From 9bb95dd4ab556fddce816ee5f7ff7dde7a971ac2 Mon Sep 17 00:00:00 2001 From: Ruth Hoffmann Date: Fri, 2 Oct 2026 14:13:36 +0200 Subject: [PATCH 5/5] starting on making the changes ready for a release --- PackageInfo.g | 4 +-- init.g | 1 + lib/visualisation.gd | 29 +++++++++++++++ lib/{vis.g => visualisation.gi} | 63 ++++++++++++++++----------------- read.g | 1 + tst/vis.tst | 35 +++++++++++++++--- 6 files changed, 94 insertions(+), 39 deletions(-) create mode 100644 lib/visualisation.gd rename lib/{vis.g => visualisation.gi} (58%) diff --git a/PackageInfo.g b/PackageInfo.g index f88ac9e..0ef6a9e 100644 --- a/PackageInfo.g +++ b/PackageInfo.g @@ -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 := [ ], ), diff --git a/init.g b/init.g index c56b0f9..4339280 100644 --- a/init.g +++ b/init.g @@ -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. diff --git a/lib/visualisation.gd b/lib/visualisation.gd new file mode 100644 index 0000000..e3fdbea --- /dev/null +++ b/lib/visualisation.gd @@ -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" ); \ No newline at end of file diff --git a/lib/vis.g b/lib/visualisation.gi similarity index 58% rename from lib/vis.g rename to lib/visualisation.gi index 8ab41c3..cd542d5 100644 --- a/lib/vis.g +++ b/lib/visualisation.gi @@ -1,9 +1,25 @@ -LoadPackage("graphvizforgap"); +############################################################################# +## +## +#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 +## -tpn2dot := function( tpn, name ) -local f, innode, outnode, nodes, isin, n, m,i; + +############################################################################# +## +#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", size:="\"8,5\"", layout:="neato")); + GraphvizSetAttrs(f, rec(rankdir:="LR", layout:="neato")); GraphvizSetAttr(f, "node [shape = circle]"); innode := GraphvizAddNode(f, "in"); @@ -32,20 +48,19 @@ local f, innode, outnode, nodes, isin, n, m,i; GraphvizAddEdge(f, "in", String(i)); od; return AsString(f); +end); -end; -hex:=[[2,3],[4],[5],[3,6],[6],[]]; -hex2:=[ [ 2, 6 ], [ 3, 9 ], [ 2, 4 ], [ 3, 5 ], [ 4 ], [ 7, 9 ], [ 6, 8 ], [ 7 ], [ ] ]; -tpn := tpn2dot(hex,"Network"); -tpn2 := tpn2dot(hex2,"Network2"); - -Splash(tpn); -Splash(tpn2); - -transducer2dot := function(transducer, name) +############################################################################# +## +#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", size:="\"8,5\"", layout:="dot")); + GraphvizSetAttrs(f, rec(rankdir:="LR", layout:="dot")); GraphvizSetAttr(f, "node [shape = circle]"); accept := GraphvizAddContext(f, "accept"); @@ -66,20 +81,4 @@ transducer2dot := function(transducer, name) GraphvizSetAttr(GraphvizAddEdge(f, String(i[3]), String(i[4])), "label", Concatenation("\"", String(i[1]), "|", String(i[2]), "\"")); od; return AsString(f); -end; - -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 ] ] ); - - -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 ] ] ); - -vist := transducer2dot(trans,"trans"); -vist2 := transducer2dot(trans2,"trans2"); -Splash(vist); -Splash(vist2);#,rec(filename:="test", path:="./", directory:="./")); \ No newline at end of file +end); \ No newline at end of file diff --git a/read.g b/read.g index 090356f..da3c872 100644 --- a/read.g +++ b/read.g @@ -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. diff --git a/tst/vis.tst b/tst/vis.tst index 360a68a..a89e24a 100644 --- a/tst/vis.tst +++ b/tst/vis.tst @@ -2,12 +2,37 @@ ## #A vis.tst PatternClass package Ruth Hoffmann ## -gap> START_TEST("PatternClass"); +gap> START_TEST("visualisation"); gap> LoadPackage("patternclass",false); true gap> SetAssertionLevel(1); gap> hex:=[[2,3],[4],[5],[3,6],[6],[]];; -gap> tpn2dot(hex,"tpn"); -"//dot\ndigraph tpn {\n\tsize=\"8,5\" rankdir=LR layout=neato \n\tin [label=\"\", shape=none]\n\tout [label=\"\", shape=none]\n// nodes context \n{\n\tnode [shape=\ -circle] \n}\n\t1\n\t2\n\t3\n\t4\n\t5\n\t6\n\t1 -> 2\n\t1 -> 3\n\t2 -> 4\n\t3 -> 5\n\t4 -> 3\n\t4 -> 6\n\t5 -> 6\n\t6 -> out\n\tin -> 1\n}\n" -gap> \ No newline at end of file +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 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