From 9fd1bd65512febbca95d62661e8c0c8c2759a206 Mon Sep 17 00:00:00 2001 From: Brent Yorgey Date: Fri, 19 Jul 2024 07:30:52 -0400 Subject: [PATCH] add maps and graphs to reference documentation --- docs/reference/REPL.rst | 7 +++ docs/reference/addition.rst | 5 +- docs/reference/collections.rst | 2 + docs/reference/graph.rst | 94 +++++++++++++++++++++++++++++++ docs/reference/map.rst | 63 +++++++++++++++++++++ docs/reference/missing-doc.rst | 6 -- docs/reference/multiplication.rst | 3 +- 7 files changed, 169 insertions(+), 11 deletions(-) create mode 100644 docs/reference/graph.rst create mode 100644 docs/reference/map.rst delete mode 100644 docs/reference/missing-doc.rst diff --git a/docs/reference/REPL.rst b/docs/reference/REPL.rst index 037ecd5d..e6f268c1 100644 --- a/docs/reference/REPL.rst +++ b/docs/reference/REPL.rst @@ -18,6 +18,13 @@ which are evaluated. However, you can also enter :doc:`definitions various special REPL commands, listed below. All the special REPL commands begin with a colon. +``:{`` / ``:}`` +--------------- + +You can enter a multi-line input (*e.g.* a whole function definition) +at the REPL by first entering ``:{``, then entering all the lines you +want, then typing ``:}`` when you're done. + ``:help`` --------- diff --git a/docs/reference/addition.rst b/docs/reference/addition.rst index a418a2e6..7b1f247e 100644 --- a/docs/reference/addition.rst +++ b/docs/reference/addition.rst @@ -4,9 +4,8 @@ Addition .. note:: This page concerns the ``+`` operator on numbers; for the ``+`` - operator on :doc:`types `, see :doc:`sum types `; for - the ``+`` operator on :doc:`graphs `, see :doc:`overlay - `. + operator on :doc:`types `, see :doc:`sum types `; + or see the ``+`` (``overlay``) operator on :doc:`graphs `. Values of all :doc:`numeric types ` can be added using the ``+`` operator. For example: diff --git a/docs/reference/collections.rst b/docs/reference/collections.rst index e0a2fdf4..f8a17bb6 100644 --- a/docs/reference/collections.rst +++ b/docs/reference/collections.rst @@ -22,3 +22,5 @@ used on them. filter comprehension boom + map + graph diff --git a/docs/reference/graph.rst b/docs/reference/graph.rst new file mode 100644 index 00000000..6c60398c --- /dev/null +++ b/docs/reference/graph.rst @@ -0,0 +1,94 @@ +Graphs +====== + +Disco has a built-in type of (directed, unweighted) *graphs*. +``Graph(v)`` is the type of directed graphs with vertices labelled by +values from the type ``v``. + +* We can use ``summary : Graph(v) -> Map(v, Set(v))`` turn turn a graph into + a :doc:`map ` associating each vertex with the set of its + (outgoing) neighbors. + +* The empty graph, with no vertices and no edges, is written ``emptyGraph``. + +* The simplest kind of nonempty graph we can make is a graph with a + single vertex and no edges, using the function ``vertex : v -> + Graph(v)``. + + :: + + Disco> :type vertex(1) + vertex(1) : Graph(ℕ) + Disco> summary(vertex(1)) + map({(1, {})}) + +* We can *union* (aka *overlay*) two graphs using ``overlay : + Graph(v) * Graph(v) -> Graph(v)``. We can also abbreviate ``overlay`` by + ``+``. The resulting graph has all the vertices and all the edges + from either input graph. + + :: + + Disco> summary(vertex(1) + vertex(2)) + map({(1, {}), (2, {})}) + Disco> summary((vertex(1) + vertex(2)) + (vertex(2) + vertex(3))) + map({(1, {}), (2, {}), (3, {})}) + +* We can *connect* two graphs using ``connect : Graph(v) * Graph(v) -> + Graph(v)``, which we can also abbreviate by ``*``. The resulting + graph is the ``overlay`` of the two graphs, plus a directed edge + pointing from each vertex in the first graph to each vertex in the + second graph. + + :: + + Disco> summary(vertex(1) * vertex(2)) -- two vertices and a single edge + map({(1, {2}), (2, {})}) + Disco> summary(vertex(1) * vertex(2) + vertex(2) * vertex(1)) -- edges in both directions + map({(1, {2}), (2, {1})}) + Disco> summary((vertex(1) + vertex(2)) * vertex(3)) + map({(1, {3}), (2, {3}), (3, {})}) + +As a more extended example, here is how you could build path, cycle, +and complete graphs: + +:: + + path : N -> Graph(N) + path(0) = emptyGraph + path(1) = vertex(0) + path(n) = vertex(n.-1) * vertex(n.-2) + path(n.-1) + + cycle : N -> Graph(N) + cycle(0) = emptyGraph + cycle(n) = path(n) + (vertex(0) * vertex(n.-1)) + + uConnect : Graph(a) * Graph(a) -> Graph(a) + uConnect (g,h) = g * h + h * g + + complete : N -> Graph(N) + complete(0) = emptyGraph + complete(1) = vertex(0) + complete(n) = uConnect(vertex(n.-1), complete(n.-1)) + +:: + + Disco> summary(cycle(4)) + map({(0, {3}), (1, {0}), (2, {1}), (3, {2})}) + Disco> summary(complete(4)) + map({(0, {1, 2, 3}), (1, {0, 2, 3}), (2, {0, 1, 3}), (3, {0, 1, 2})}) + +The Algebra of Graphs +--------------------- + +.. warning:: + + This section includes advanced information. Don't worry about it + unless you are interested in the abstract mathematics underlying + the Disco language. + +The operators Disco has for building graphs (``vertex``, ``overlay``, +and ``connect``) are based on a theory called the *algebra of +graphs*. You can `read the 2017 paper about it here`_. + +.. _`read the 2017 paper about it here`: https://github.com/snowleopard/alga-paper/releases/download/final/algebraic-graphs.pdf diff --git a/docs/reference/map.rst b/docs/reference/map.rst new file mode 100644 index 00000000..79526152 --- /dev/null +++ b/docs/reference/map.rst @@ -0,0 +1,63 @@ +Maps +==== + +Disco has a built-in type of *maps*, or dictionaries, that map keys to +values. The type of a map is written ``Map(K, V)`` where ``K`` is the +type of the keys and ``V`` is the type of the values. For example, +``Map(N, List(Char))`` is the type of maps which associate :doc:`natural +number ` keys to :doc:`string ` values. + +* The most basic way to construct a ``Map`` is to use the built-in + function ``map : Set(k * a) -> Map(k, a)``. That is, ``map`` takes + as input a set of key-value pairs and constructs a corresponding + ``Map``. + + :: + + Disco> map({}) + map({}) + Disco> map({(7, "hi"), (5, "there")}) + map({(5, "there"), (7, "hi")}) + + Notice that ``map`` is also used when printing out values of type + ``Map``. + +* To look up the value associated with a particular key, you can use + ``lookup : k * Map(k, a) -> (Unit + a)``. That is, ``lookup`` takes + a pair of a key and a ``Map``, and looks up that key, returning + either a ``left(unit)`` if the key was not found, or ``right(a)`` + with the value ``a`` corresponding to the key if it was found. + + :: + + Disco> m : Map(N, List(Char)) + Disco> m = map({(5, "there"), (7, "hi")}) + Disco> lookup(5, m) + right("there") + Disco> lookup(6, m) + left(unit) + +* To insert a new key/value pair into a map, or to change the value + associated with an existing key, you can use the function ``insert : + k * a * Map(k, a) -> Map(k, a)``. This function takes three + arguments: a key, a value, and an existing ``Map``, and returns an + updated ``Map`` where the given key is now associated to the given + value. + + :: + + Disco> insert(5, "you", m) + map({(5, "you"), (7, "hi")}) + Disco> insert(9, "you", m) + map({(5, "there"), (7, "hi"), (9, "you")}) + + Note that calling ``insert`` did not actually change ``m``; it + simply returned a new map. + +* To turn a map back into a set of key/value pairs, use ``mapToSet : + Map(k, a) -> Set(k * a)``. + + :: + + Disco> mapToSet(m) + {(5, "there"), (7, "hi")} diff --git a/docs/reference/missing-doc.rst b/docs/reference/missing-doc.rst deleted file mode 100644 index 450773ea..00000000 --- a/docs/reference/missing-doc.rst +++ /dev/null @@ -1,6 +0,0 @@ -Missing documentation -===================== - -If you're seeing this page, it's because the language reference page -for something has not been written yet! Try bugging Dr. Yorgey to -write it for you. diff --git a/docs/reference/multiplication.rst b/docs/reference/multiplication.rst index 69216eef..d06bbec5 100644 --- a/docs/reference/multiplication.rst +++ b/docs/reference/multiplication.rst @@ -5,8 +5,7 @@ Multiplication This page concerns the ``*`` operator on numbers; for the ``*`` operator on :doc:`types `, see :doc:`pair types - `; for the ``*`` operator on :doc:`graphs `, see - :doc:`connect `. + `; or see the ``*`` (``connect``) operator on :doc:`graphs `. All :doc:`numeric types ` can be multiplied using the ``*`` operator. For example: