Francy - An Interactive Discrete Mathematics Framework for GAP


Manuel Martins

Universidade Aberta, Lisbon - Portugal

manuelmachadomartins@gmail.com

Markus Pfeiffer

University of St Andrews, St Andrews - Scotland

markus.pfeiffer@morphism.de


Agenda

  1. Motivation
  2. Solution
  3. Features
  4. Hands-on
  5. Future


1. Motivation

  • Francy arose from the necessity of having a lightweight framework for building interactive graphics, generated from GAP, running primarily on the web, primarily in a Jupyter Notebook.

1.1 What is Francy?

  • an interface to draw graphics using objects;
  • based on simple concepts of drawing and graph theory;
  • 2 components:
    1. a GAP package that is responsible for the semantic representation of graphics;
    2. a GUI library that is responsible for generating the actual interactive graphical representation.


2. Solution

2.1 GAP Package

  • provides a semantic representation of graphics is provided by a thin layer.
  • uses JSON, a lightweight, text-based, language-independent data interchange format.
  • follows a JSON Schema, and is identified with the application/vnd.francy+json MIME type.

2.2 GUI Library - Javascript

  • based on d3.js, for rendering the semantic representation produced by the GAP package;
  • this library is distributed both as a browser module and as a Jupyter extension.

2.3 Jupyter GAP Kernel

  • pure GAP package that implements the Jupyter Kernel specification;
  • "glues" everything together.

The Jupyter extension can be used in Jupyter Notebooks or Jupyter Lab, using the Jupyter GAP Kernel and the MIME type application/vnd.francy+json to render the document.

This creates an abstraction and allows the development of new GUI libraries, using different data rendering dependencies or even different programming languages, independently of the GAP package.


3. Features

  • allows the creation of directed and undirected graphs, trees, line charts, bar charts and scatter charts;
  • enables interaction with graphical objects by clicking, selecting, dragging and zooming;

3.1 How to install

1. download latest release and extract the GAP package to GAP packages directory

user@local:~$ wget https://github.com/mcmartins/francy/archive/v0.8.2.tar.gz && \
    mkdir -p $GAPROOT/pkg/francy && \
    tar xzvf v0.8.2.tar.gz -C $GAPROOT/pkg/francy francy-0.8.2/gap

2. install latest jupyter extension using pip and install on Jupyter lab and/or notebook

user@local:~$ pip install jupyter_francy
user@local:~$ jupyter lab build # for JupyterLab
user@local:~$ jupyter nbextension enable --py --sys-prefix jupyter_francy # for Notebook


4. Hands-on


In [2]:
LoadPackage("francy");
LoadPackage("digraph");


Out[2]:
true
Out[2]:
true

In [3]:
FrancyDigraphs := function(G)
    local as, d, v, e, graph, nodes, m, IsGroupSimple, canvas, i;

    as := AllSubgroups(G);;

    d := Digraph(as, {H, K} -> IsSubgroup(H, K));;
    v := DigraphVertices(d);;
    e := DigraphEdges(d);;

    graph := Graph(GraphType.DIRECTED);;
    canvas := Canvas(Concatenation("Subgroups Digraph of ", String(G)));;
    Add(canvas, graph);;

    nodes := [];;

    m := FrancyMessage(FrancyMessageType.INFO, "Simple Groups", 
        "A group is simple if it is nontrivial and has no nontrivial normal subgroups.");;
    
    IsGroupSimple := function(i)
        Add(canvas, m);;
        if IsSimpleGroup(as[i]) then
            Add(canvas, FrancyMessage("Simple", Concatenation("The vertex ", 
                String(i), ", representing the subgroup ", String(as[i]), ", is simple.")));;
        else
            Add(canvas, FrancyMessage("Not Simple", Concatenation("The vertex ", 
                String(i), ", representing the subgroup ", String(as[i]), ", is not simple.")));;
        fi;;
        return Draw(canvas);
    end;;

    for i in v do;
        nodes[i] := Shape(ShapeType.CIRCLE, String(i));;
        Add(nodes[i], Menu("Simple", Callback(IsGroupSimple, [i])));;
        Add(graph, nodes[i]);;
    od;;

    for i in e do
        Add(graph, Link(nodes[i[1]], nodes[i[2]]));;
    od;;

    return Draw(canvas);
end;


Out[3]:
function( G ) ... end

In [5]:
G := DihedralGroup(4);
FrancyDigraphs(G);


Out[5]:
<group of size 4 with 2 generators>
Out[5]:

4.1 More examples

Try these notebooks:

  1. Francy Features
  2. Subgroup Lattice
  3. Francy Monoids


5. Future

  • rendering multiple topological graphs on the same canvas.
  • allow the creation of "free graphics" using lines and text.
  • introduce new concepts like tables for matrices representations.
  • validate the JSON against its JSON Schema between GAP and GUI.
  • rendering is done on SVG which might be "heavy" when loading huge graphs.


Questions?


Thanks!


In [ ]: