{ "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(\"\\n\\n\\n\\n\\n\\n
f
\"), :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(\"\\n\\n\\n\\n\\n\\n
f
\"), :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(\"\\n\\n\\n\\n\\n\\n
g
\"), :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(\"\\n\\n\\n\\n\\n\\n
f
\"), :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(\"\\n\\n\\n\\n\\n\\n
h
\"), :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(\"\\n\\n\\n\\n\\n\\n
f
\"), :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(\"\\n\\n\\n\\n\\n\\n
f
\"), :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(\"\\n\\n\\n\\n\\n\\n
f
\"), :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(\"\\n\\n\\n\\n\\n\\n
f
\"), :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(\"\\n\\n\\n\\n\\n\\n
g
\"), :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(\"\\n\\n\\n\\n\\n\\n
f
\"), :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(\"\\n\\n\\n\\n\\n\\n
h
\"), :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 }