{
"cells": [
{
"cell_type": "markdown",
"source": [
"# Basics of wiring diagrams\n",
"\n",
"\n",
"using GATlab, you can create, manipulate, serialize, and visualize *wiring\n",
"diagrams*, also known as [string\n",
"diagrams](https://ncatlab.org/nlab/show/string+diagram). The flexible data\n",
"structure for wiring diagrams allows arbitrary data to be attached to boxes,\n",
"ports, and wires, and supports recursively nested diagrams.\n",
"\n",
"You can interact with wiring diagrams using two different progamming\n",
"interfaces:\n",
"\n",
"1. **Categorical**: A high-level, functional interface expressed in terms of\n",
" categorical concepts, such as composition (`compose`), monoidal products\n",
" (`otimes`), duplication (`mcopy`), and deletion (`delete`).\n",
"\n",
"2. **Imperative**: A lower-level, mutating interface to directly manipulate\n",
" boxes, ports, and wires, via operations like adding boxes (`add_box`) and\n",
" wires (`add_wire`).\n",
"\n",
"In this notebook, we introduce both interfaces. We do not explicitly cover the\n",
"visualization API, although for illustrative purposes we will draw wiring\n",
"diagrams using Graphviz. Thus, you should install\n",
"[Graphviz](https://www.graphviz.org/) if you wish to run this notebook."
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "show_diagram (generic function with 1 method)"
},
"metadata": {},
"execution_count": 1
}
],
"cell_type": "code",
"source": [
"using Catlab.WiringDiagrams\n",
"\n",
"using Catlab.Graphics\n",
"import Catlab.Graphics: Graphviz\n",
"\n",
"show_diagram(d::WiringDiagram) = to_graphviz(d,\n",
" orientation=LeftToRight,\n",
" labels=true, label_attr=:xlabel,\n",
" node_attrs=Graphviz.Attributes(\n",
" :fontname => \"Courier\",\n",
" ),\n",
" edge_attrs=Graphviz.Attributes(\n",
" :fontname => \"Courier\",\n",
" )\n",
")"
],
"metadata": {},
"execution_count": 1
},
{
"cell_type": "markdown",
"source": [
"## Data structures\n",
"\n",
"The basic building blocks of a wiring diagram are boxes, ports, and wires. The\n",
"top-level data structure is `WiringDiagram`, defined in the module\n",
"`Catlab.WiringDiagrams`. A wiring diagram consists of boxes (usually of type\n",
"`Box`) connected by wires (of type `Wire`). Each box has a sequence of input\n",
"ports and a sequence of output ports, as does the wiring diagram itself. The\n",
"wires have sources and targets, both of which consist of a box and a port on\n",
"that box.\n",
"\n",
"The boxes in a wiring diagram are indexed by integer IDs. Boxes can be\n",
"retrieved by ID, and wires refer to boxes using their IDs. Two special IDs,\n",
"obtained by `input_id` and `output_id` methods, refer to the inputs and\n",
"outputs of the diagram itself. In this way, wires can connect the (inner)\n",
"boxes of a diagram to the diagram's \"outer box\".\n",
"\n",
"The `WiringDiagram` data structure is an elaborate wrapper around a directed\n",
"graph from [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl).\n",
"The underlying `DiGraph` object can be accessed using the `graph` method. The\n",
"vertices of this graph are exactly the box IDs. The graph should never be\n",
"mutated directly, on pain of creating inconsistent state, but it does allow\n",
"convenient access to the large array of graph algorithms supported by Graphs.\n",
"\n",
"All this is somewhat abstract but should become clearer as we see concrete\n",
"examples."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## Categorical interface\n",
"\n",
"In this example, the wiring diagrams will carry symbolic expressions (of type\n",
"`Catlab.ObExpr` and `Catlab.HomExpr`)."
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "f: A → B",
"text/latex": "$f : A \\to B$"
},
"metadata": {},
"execution_count": 2
}
],
"cell_type": "code",
"source": [
"using Catlab.Theories\n",
"\n",
"A, B, C, D = Ob(FreeBiproductCategory, :A, :B, :C, :D)\n",
"f = Hom(:f, A, B)\n",
"g = Hom(:g, B, C)\n",
"h = Hom(:h, C, D)\n",
"\n",
"f"
],
"metadata": {},
"execution_count": 2
},
{
"cell_type": "markdown",
"source": [
"### Generators\n",
"\n",
"Convert each of the morphism generators into a diagram with a single box."
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "WiringDiagram{Catlab.Theories.ThBiproductCategory.Meta.T}([:A], [:B], \n[ -2 => {inputs},\n -1 => {outputs},\n 1 => Box(:f, [:A], [:B]) ],\n[ Wire((-2,1) => (1,1)),\n Wire((1,1) => (-1,1)) ])"
},
"metadata": {},
"execution_count": 3
}
],
"cell_type": "code",
"source": [
"f, g, h = to_wiring_diagram(f), to_wiring_diagram(g), to_wiring_diagram(h)\n",
"f"
],
"metadata": {},
"execution_count": 3
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"f\", :fillcolor => \"white\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"
\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"A\", :id => \"e1\", :xlabel => \"A\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e2\", :xlabel => \"B\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Courier\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Courier\"))",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"G \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n1 \n",
" \n",
"f \n",
" \n",
"\n",
"\n",
"\n",
"n0in1:e->n1:w \n",
" \n",
" \n",
"A \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n1:e->n0out1:w \n",
" \n",
" \n",
"B \n",
" \n",
" \n",
" \n"
]
},
"metadata": {},
"execution_count": 4
}
],
"cell_type": "code",
"source": [
"show_diagram(f)"
],
"metadata": {},
"execution_count": 4
},
{
"cell_type": "markdown",
"source": [
"### Composition"
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "WiringDiagram{Catlab.Theories.ThBiproductCategory.Meta.T}([:A], [:C], \n[ -2 => {inputs},\n -1 => {outputs},\n 1 => Box(:f, [:A], [:B]),\n 2 => Box(:g, [:B], [:C]) ],\n[ Wire((-2,1) => (1,1)),\n Wire((1,1) => (2,1)),\n Wire((2,1) => (-1,1)) ])"
},
"metadata": {},
"execution_count": 5
}
],
"cell_type": "code",
"source": [
"compose(f,g)"
],
"metadata": {},
"execution_count": 5
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"f\", :fillcolor => \"white\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"g\", :fillcolor => \"white\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"A\", :id => \"e1\", :xlabel => \"A\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e2\", :xlabel => \"B\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"C\", :id => \"e3\", :xlabel => \"C\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Courier\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Courier\"))",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"G \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n1 \n",
" \n",
"f \n",
" \n",
"\n",
"\n",
"\n",
"n0in1:e->n1:w \n",
" \n",
" \n",
"A \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n2 \n",
" \n",
"g \n",
" \n",
"\n",
"\n",
"\n",
"n1:e->n2:w \n",
" \n",
" \n",
"B \n",
" \n",
"\n",
"\n",
"\n",
"n2:e->n0out1:w \n",
" \n",
" \n",
"C \n",
" \n",
" \n",
" \n"
]
},
"metadata": {},
"execution_count": 6
}
],
"cell_type": "code",
"source": [
"show_diagram(compose(f,g))"
],
"metadata": {},
"execution_count": 6
},
{
"cell_type": "markdown",
"source": [
"### Monoidal products"
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "WiringDiagram{Catlab.Theories.ThBiproductCategory.Meta.T}([:A,:C], [:B,:D], \n[ -2 => {inputs},\n -1 => {outputs},\n 1 => Box(:f, [:A], [:B]),\n 2 => Box(:h, [:C], [:D]) ],\n[ Wire((-2,1) => (1,1)),\n Wire((-2,2) => (2,1)),\n Wire((1,1) => (-1,1)),\n Wire((2,1) => (-1,2)) ])"
},
"metadata": {},
"execution_count": 7
}
],
"cell_type": "code",
"source": [
"otimes(f,h)"
],
"metadata": {},
"execution_count": 7
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\")), Catlab.Graphics.Graphviz.Node(\"n0in2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0in2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\")), Catlab.Graphics.Graphviz.Node(\"n0out2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"f\", :fillcolor => \"white\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"h\", :fillcolor => \"white\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"A\", :id => \"e1\", :xlabel => \"A\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in2\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"C\", :id => \"e2\", :xlabel => \"C\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e3\", :xlabel => \"B\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"D\", :id => \"e4\", :xlabel => \"D\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Courier\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Courier\"))",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"G \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"n1 \n",
" \n",
"f \n",
" \n",
"\n",
"\n",
"\n",
"n0in1:e->n1:w \n",
" \n",
" \n",
"A \n",
" \n",
"\n",
"\n",
"\n",
"n2 \n",
" \n",
"h \n",
" \n",
"\n",
"\n",
"\n",
"n0in2:e->n2:w \n",
" \n",
" \n",
"C \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"n1:e->n0out1:w \n",
" \n",
" \n",
"B \n",
" \n",
"\n",
"\n",
"\n",
"n2:e->n0out2:w \n",
" \n",
" \n",
"D \n",
" \n",
" \n",
" \n"
]
},
"metadata": {},
"execution_count": 8
}
],
"cell_type": "code",
"source": [
"show_diagram(otimes(f,h))"
],
"metadata": {},
"execution_count": 8
},
{
"cell_type": "markdown",
"source": [
"### Copy and merge, delete and create"
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "WiringDiagram{Catlab.Theories.ThBiproductCategory.Meta.T}([:B], [:B,:B], \n[ -2 => {inputs},\n -1 => {outputs},\n ],\n[ Wire((-2,1) => (-1,1)),\n Wire((-2,1) => (-1,2)) ])"
},
"metadata": {},
"execution_count": 9
}
],
"cell_type": "code",
"source": [
"mcopy(codom(f),2)"
],
"metadata": {},
"execution_count": 9
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\")), Catlab.Graphics.Graphviz.Node(\"n0out2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e1\", :xlabel => \"B\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e2\", :xlabel => \"B\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Courier\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Courier\"))",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"G \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"\n",
"n0in1:e->n0out1:w \n",
" \n",
" \n",
"B \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n0in1:e->n0out2:w \n",
" \n",
" \n",
"B \n",
" \n",
"\n",
" \n",
" \n"
]
},
"metadata": {},
"execution_count": 10
}
],
"cell_type": "code",
"source": [
"show_diagram(mcopy(codom(f),2))"
],
"metadata": {},
"execution_count": 10
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\")), Catlab.Graphics.Graphviz.Node(\"n0out2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"f\", :fillcolor => \"white\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"A\", :id => \"e1\", :xlabel => \"A\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e2\", :xlabel => \"B\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e3\", :xlabel => \"B\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Courier\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Courier\"))",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"G \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n1 \n",
" \n",
"f \n",
" \n",
"\n",
"\n",
"\n",
"n0in1:e->n1:w \n",
" \n",
" \n",
"A \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"n1:e->n0out1:w \n",
" \n",
" \n",
"B \n",
" \n",
"\n",
"\n",
"\n",
"n1:e->n0out2:w \n",
" \n",
" \n",
"B \n",
" \n",
" \n",
" \n"
]
},
"metadata": {},
"execution_count": 11
}
],
"cell_type": "code",
"source": [
"show_diagram(compose(f, mcopy(codom(f),2)))"
],
"metadata": {},
"execution_count": 11
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\")), Catlab.Graphics.Graphviz.Node(\"n0out2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"f\", :fillcolor => \"white\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"f\", :fillcolor => \"white\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"A\", :id => \"e1\", :xlabel => \"A\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"A\", :id => \"e2\", :xlabel => \"A\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e3\", :xlabel => \"B\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e4\", :xlabel => \"B\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Courier\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Courier\"))",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"G \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n1 \n",
" \n",
"f \n",
" \n",
"\n",
"\n",
"\n",
"n0in1:e->n1:w \n",
" \n",
" \n",
"A \n",
" \n",
"\n",
"\n",
"\n",
"n2 \n",
" \n",
"f \n",
" \n",
"\n",
"\n",
"\n",
"n0in1:e->n2:w \n",
" \n",
" \n",
"A \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"n1:e->n0out1:w \n",
" \n",
" \n",
"B \n",
" \n",
"\n",
"\n",
"\n",
"n2:e->n0out2:w \n",
" \n",
" \n",
"B \n",
" \n",
" \n",
" \n"
]
},
"metadata": {},
"execution_count": 12
}
],
"cell_type": "code",
"source": [
"show_diagram(compose(mcopy(dom(f),2), otimes(f,f)))"
],
"metadata": {},
"execution_count": 12
},
{
"cell_type": "markdown",
"source": [
"## Imperative interface\n",
"\n",
"We now show how to manipulate wiring diagrams using the low-level, imperative\n",
"interface. The diagrams will carry Julia symbols."
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Box(:f, [:A], [:B])"
},
"metadata": {},
"execution_count": 13
}
],
"cell_type": "code",
"source": [
"f = Box(:f, [:A], [:B])\n",
"g = Box(:g, [:B], [:C])\n",
"h = Box(:h, [:C], [:D])\n",
"\n",
"f"
],
"metadata": {},
"execution_count": 13
},
{
"cell_type": "markdown",
"source": [
"### Composition\n",
"\n",
"For example, here is how to manually construct a composition of two boxes.\n",
"\n",
"The `add_box!` method adds a box to a wiring diagrams and returns the ID\n",
"assigned to the box. How the boxes are indexed is an implementation detail\n",
"that you should not rely on; use the IDs that the system gives you."
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "2"
},
"metadata": {},
"execution_count": 14
}
],
"cell_type": "code",
"source": [
"d = WiringDiagram([:A], [:C])\n",
"\n",
"fv = add_box!(d, f)\n",
"gv = add_box!(d, g)\n",
"\n",
"add_wires!(d, [\n",
" (input_id(d),1) => (fv,1),\n",
" (fv,1) => (gv,1),\n",
" (gv,1) => (output_id(d),1),\n",
"])\n",
"\n",
"nboxes(d)"
],
"metadata": {},
"execution_count": 14
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "3"
},
"metadata": {},
"execution_count": 15
}
],
"cell_type": "code",
"source": [
"nwires(d)"
],
"metadata": {},
"execution_count": 15
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "WiringDiagram([:A], [:C], \n[ -2 => {inputs},\n -1 => {outputs},\n 1 => Box(:f, [:A], [:B]),\n 2 => Box(:g, [:B], [:C]) ],\n[ Wire((-2,1) => (1,1)),\n Wire((1,1) => (2,1)),\n Wire((2,1) => (-1,1)) ])"
},
"metadata": {},
"execution_count": 16
}
],
"cell_type": "code",
"source": [
"d"
],
"metadata": {},
"execution_count": 16
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"f\", :fillcolor => \"white\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"g\", :fillcolor => \"white\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"A\", :id => \"e1\", :xlabel => \"A\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e2\", :xlabel => \"B\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"C\", :id => \"e3\", :xlabel => \"C\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Courier\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Courier\"))",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"G \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n1 \n",
" \n",
"f \n",
" \n",
"\n",
"\n",
"\n",
"n0in1:e->n1:w \n",
" \n",
" \n",
"A \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"n2 \n",
" \n",
"g \n",
" \n",
"\n",
"\n",
"\n",
"n1:e->n2:w \n",
" \n",
" \n",
"B \n",
" \n",
"\n",
"\n",
"\n",
"n2:e->n0out1:w \n",
" \n",
" \n",
"C \n",
" \n",
" \n",
" \n"
]
},
"metadata": {},
"execution_count": 17
}
],
"cell_type": "code",
"source": [
"show_diagram(d)"
],
"metadata": {},
"execution_count": 17
},
{
"cell_type": "markdown",
"source": [
"### Products\n",
"\n",
"Here is how to manually construct a product of two boxes."
],
"metadata": {}
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "WiringDiagram([:A,:C], [:B,:D], \n[ -2 => {inputs},\n -1 => {outputs},\n 1 => Box(:f, [:A], [:B]),\n 2 => Box(:h, [:C], [:D]) ],\n[ Wire((-2,1) => (1,1)),\n Wire((-2,2) => (2,1)),\n Wire((1,1) => (-1,1)),\n Wire((2,1) => (-1,2)) ])"
},
"metadata": {},
"execution_count": 18
}
],
"cell_type": "code",
"source": [
"d = WiringDiagram([:A,:C], [:B,:D])\n",
"\n",
"fv = add_box!(d, f)\n",
"hv = add_box!(d, h)\n",
"\n",
"add_wires!(d, [\n",
" (input_id(d),1) => (fv,1),\n",
" (input_id(d),2) => (hv,1),\n",
" (fv,1) => (output_id(d),1),\n",
" (hv,1) => (output_id(d),2),\n",
"])\n",
"\n",
"d"
],
"metadata": {},
"execution_count": 18
},
{
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\")), Catlab.Graphics.Graphviz.Node(\"n0in2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0in2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\")), Catlab.Graphics.Graphviz.Node(\"n0out2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0\", :height => \"0.333\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"f\", :fillcolor => \"white\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"h\", :fillcolor => \"white\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\"), :style => \"solid\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"A\", :id => \"e1\", :xlabel => \"A\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in2\", \"e\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"w\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"C\", :id => \"e2\", :xlabel => \"C\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"B\", :id => \"e3\", :xlabel => \"B\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out1\", \"e\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"w\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"D\", :id => \"e4\", :xlabel => \"D\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Courier\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Courier\"))",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"G \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"n1 \n",
" \n",
"f \n",
" \n",
"\n",
"\n",
"\n",
"n0in1:e->n1:w \n",
" \n",
" \n",
"A \n",
" \n",
"\n",
"\n",
"\n",
"n2 \n",
" \n",
"h \n",
" \n",
"\n",
"\n",
"\n",
"n0in2:e->n2:w \n",
" \n",
" \n",
"C \n",
" \n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"n1:e->n0out1:w \n",
" \n",
" \n",
"B \n",
" \n",
"\n",
"\n",
"\n",
"n2:e->n0out2:w \n",
" \n",
" \n",
"D \n",
" \n",
" \n",
" \n"
]
},
"metadata": {},
"execution_count": 19
}
],
"cell_type": "code",
"source": [
"show_diagram(d)"
],
"metadata": {},
"execution_count": 19
}
],
"nbformat_minor": 3,
"metadata": {
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.10.2"
},
"kernelspec": {
"name": "julia-1.10",
"display_name": "Julia 1.10.2",
"language": "julia"
}
},
"nbformat": 4
}