代数图-0.7:代数图构造和转换库
版权(c) 安德烈·莫霍夫2016-2022
许可证MIT(请参阅文件LICENSE)
维护人员andrey.mokhov@gmail.com
稳定性实验的
安全哈斯克尔
语言哈斯克尔2010

代数。图表。非空

描述

藻类是用于图的代数构造和操作的库在哈斯克尔。请参阅这篇论文对于图书馆背后的动机、基础理论和实施细节。

此模块定义数据类型图表对于已知的代数图在编译时为非空。避免名称与冲突代数。图表,此模块可以合格导入:

导入合格的代数。图表。非空表示非空

命名约定通常遵循数据。列表。非空:我们使用后缀1指示其接口必须更改的函数代数。图表,例如。垂直1.

简介

非空代数图

数据 图表来源 #

非空代数图,使用三个原语构建:顶点,覆盖连接参见模块代数。图表用于代数可以为空的图形。

我们定义了一个号码实例作为处理图形的方便符号:

0           ==顶点01 + 2       ==覆盖(顶点1) (顶点2)1 * 2       ==连接(顶点1) (顶点2)1 + 2 * 3   ==覆盖(顶点1) (连接(顶点2) (顶点3))1 * (2 + 3) ==连接(顶点1) (覆盖(顶点2) (顶点3))

注:这个符号类型类的方法号码无法实现,并且将抛出错误。此外号码实例不满足几个的“习惯法”号码,这就决定了from整数 0from整数 1应作为加法和乘法恒等式,以及否定作为加法逆。然而,超载from整数,+*在处理代数图时非常方便;我们希望在未来的Haskell的Prelude将为代数结构,我们可以在不违反任何法律。

这个等式实例满足非空代数图的下列定律。

  • 覆盖是交换的、结合的和幂等的:

    x+y==y+xx+(y+z)==(x+y)+zx+x==x
  • 连接是关联的:

    x*(y*z)==(x*y)*z
  • 连接分布在覆盖:

    x*(y+z)==x*y+x*z(x+y)*z==x*z+y*z
  • 连接可以分解为:

    x*y*z==x*y+x*z+y*z
  • 连接满足吸收和饱和:

    x*y+x+y==x*yx*x*x==x*x

在指定图形算法的时间和内存复杂性时,n个表示图中的顶点数,将表示图中的边,以及将表示大小图表表达式,定义为顶点叶数(注意n个<=). 如果是一个图表,对应n个,可以计算如下:

n个==顶点计数米==边缘计数秒==大小

转换图表到相应的相邻地图O(s+m*log(m))时间和O(s+m)内存。这也是图等式测试的复杂性,因为它目前由基于邻接的图表达式到规范表示的转换地图。

总订单订单关于图的定义使用尺寸-详图比较:

  • 比较顶点数。如果出现平局,请继续。
  • 比较顶点集。如果出现平局,请继续。
  • 比较边的数量。如果出现平局,请继续。
  • 比较边缘集。

以下是几个示例:

顶点1 <顶点2顶点3 <边缘1 2顶点1 <边缘1 1边缘1 1 <边缘1 2边缘1 2 <边缘1 1 +边缘2 2边缘1 2 <边缘1 3

请注意,结果订单细化了是SubgraphOf关系和是与兼容覆盖连接操作:

是SubgraphOfx y==>x<=y
x<=x+yx+y<=x*y

建造师

顶点 
覆盖(图表a)(图表a) 
连接(图表a)(图表a) 

实例

实例详细信息
莫纳德 图表 来源 # 
实例详细信息

定义于代数。图表。非空

方法

(>>=)::图表a->(a->图表b) ->图表b#

(>>)::图表a->图表b->图表b#

返回::a->图表#

Functor(仿真器) 图表 来源 # 
实例详细信息

定义于代数。图表。非空

方法

功能性维修计划::(a->b)->图表a->图表b#

(<$)::a->图表b->图表#

适用 图表 来源 # 
实例详细信息

定义于代数。图表。非空

方法

纯净的::a->图表#

(<*>)::图表(a->b)->图表a->图表b#

提升A2::(a->b->c)->图表a->图表b->图表c#

(*>)::图表a->图表b->图表b#

(<*)::图表a->图表b->图表#

订单a=>等式(图表a) 来源 # 
实例详细信息

定义于代数。图表。非空

号码a=>号码(图表a) 来源 #

注:这并不满足通常的环定律;看见图表了解更多细节。

实例详细信息

定义于代数。图表。非空

订单a=>订单(图表a) 来源 # 
实例详细信息

定义于代数。图表。非空

显示a=>显示(图表a) 来源 # 
实例详细信息

定义于代数。图表。非空

IsString(IsString)a=>IsString(IsString)(图表a) 来源 # 
实例详细信息

定义于代数。图表。非空

半群(图表a) 来源 #

通过定义覆盖.

实例详细信息

定义于代数。图表。非空

NFData公司a=>NFData公司(图表a) 来源 # 
实例详细信息

定义于代数。图表。非空

方法

径向基函数::图表a->()#

ToGraph(ToGraph)(图表a) 来源 # 
实例详细信息

定义于代数。图表。非空

关联的类型

类型 ToVertex(顶点)(图表a)来源 #

方法

toGraph(目标图表)::图表a->图0(ToVertex(顶点)(图表a) )来源 #

折叠::r->(ToVertex(顶点)(图表a) ->r)->(r->r->r)->(r->r->r)->图表a->r来源 #

栈空::图表a->布尔 来源 #

hasVertex公司::到顶点(图表a) ->图表a->布尔 来源 #

hasEdge公司::ToVertex(顶点)(图表a) ->ToVertex(顶点)(图表a) ->图表a->布尔 来源 #

顶点计数::图表a->国际 来源 #

边缘计数::图表a->国际 来源 #

顶点列表::图表a->[ToVertex(顶点)(图表a) ]来源 #

边缘列表::图表a->[(ToVertex(顶点)(图表a) ,ToVertex(顶点)(图表a) )]来源 #

顶点集::图表a->设置(ToVertex(顶点)(图表a) )来源 #

顶点IntSet::图表a->IntSet(IntSet) 来源 #

边缘设置::图表a->设置(ToVertex(顶点)(图表a) ,ToVertex(顶点)(图表a) )来源 #

预设::ToVertex(顶点)(图表a) ->图表a->设置(ToVertex(顶点)(图表a) )来源 #

预IntSet::国际->图表a->IntSet(IntSet) 来源 #

postSet(postSet)::ToVertex(顶点)(图表a) ->图表a->设置(ToVertex(顶点)(图表a) )来源 #

后IntSet::国际->图表a->IntSet(IntSet) 来源 #

邻接列表::图表a->[(ToVertex(顶点)(图表a) [ToVertex(顶点)(图表a) ])]来源 #

dfs森林::图表a->森林(ToVertex(顶点)(图表a) )来源 #

dfs预测自::图表a->[ToVertex(顶点)(图表a) ]->森林(ToVertex(顶点)(图表a) )来源 #

数据流服务::图表a->[ToVertex(顶点)(图表a) ]->[ToVertex(顶点)(图表a) ]来源 #

可达成的::图表a->ToVertex(顶点)(图表a) ->[ToVertex(顶点)(图表a) ]来源 #

top排序::图表a->要么(循环(ToVertex(顶点)(图表a) ))[ToVertex(顶点)(图表a) ]来源 #

is非循环::图表a->布尔 来源 #

到相邻地图::图表a->相邻地图(ToVertex(顶点)(图表a) )来源 #

到相邻地图转换::图表a->相邻地图(ToVertex(顶点)(图表a) )来源 #

到相邻IntMap::图表a->相邻IntMap 来源 #

到相邻IntMapTranspose::图表a->相邻IntMap 来源 #

是DfsForestOf::森林(ToVertex(顶点)(图表a) )->图表a->布尔 来源 #

排名靠前:: [ToVertex(顶点)(图表a) ]->图表a->布尔 来源 #

类型 到顶点(图表a) 来源 # 
实例详细信息

定义于代数。图表。非空

到非空::图表a->也许 吧(图表a)来源 #

转换代数图(从代数。图表)转换为非空代数图。退换商品没有什么如果参数是空的.复杂性:O(s)个时间、内存和大小。

到非空空的==无至非空(toGraph(目标图表)x) ==只是(x::图表a)

基本图构造基元

顶点::a->图表来源 #

构建包含以下内容的图形单个孤立顶点。的别名建造师顶点.

hasVertex公司x(顶点y)==(x==y)顶点计数(顶点x)==1边缘计数(顶点x)==0大小(顶点x)==1

边缘::a->a->图表来源 #

构建包含以下内容的图形单边.

边缘x y==连接(顶点x)(顶点年)hasEdge公司x y(边x y)==真边缘计数(边缘x y)==1顶点计数(边缘1 1)==1顶点计数(边缘1 2)==2

覆盖::图表a->图表a->图表来源 #

覆盖两张图。构造函数的别名覆盖。这是一个交换、结合和幂等运算。复杂性:O(1)时间和记忆,O(s1+s2)大小。

hasVertex公司z(覆盖x y)==hasVertex公司z x轴||hasVertex公司z y方向顶点计数(覆盖x y)>=顶点计数x顶点计数(覆盖x y)<=顶点计数x个+顶点计数边缘计数(覆盖x y)>=边缘计数x边缘计数(覆盖x y)<=边缘计数x个+边缘计数大小(覆盖x y)==大小x个+大小顶点计数(叠加12)==2边缘计数(覆盖12)==0

重叠1::图表a->图表a->图表来源 #

覆盖可能为空的图形(来自代数。图表)非空图表。如果第一个参数是空的,函数返回第二个论证;否则,它在语义上与覆盖.复杂性:O(s1)时间和记忆,以及O(s1+s2)大小。

覆盖层1空的x==xx个/=空的==>覆盖1 x y==覆盖(fromJust$toNonEmpty x)y

连接::图表a->图表a->图表来源 #

连接两张图。构造函数的别名连接。这是一个关联操作,分布在覆盖并遵守分解公理。复杂性:O(1)时间和记忆,O(s1+s2)大小。请注意结果图中边的数量与参数的顶点:m=O(m1+m2+n1*n2).

hasVertex公司z(连接x y)==hasVertex公司z x轴||hasVertex公司z y(z y)顶点计数(连接x y)>=顶点计数x顶点计数(连接x y)<=顶点计数x个+顶点计数边缘计数(连接x y)>=边缘计数x边缘计数(连接x y)>=边缘计数边缘计数(连接x y)>=顶点计数x个*顶点计数边缘计数(连接x y)<=顶点计数x个*顶点计数年+边缘计数x个+边缘计数大小(连接x y)==大小x个+大小顶点计数(连接1 2)==2边缘计数(连接12)==1

垂直1::非空a->图表来源 #

构造包含给定孤立顶点列表的图。复杂性:O(左)时间、内存和大小,其中L(左)是的长度给定列表。

垂直1[x]==顶点xhasVertex公司x。垂直1==元素x顶点计数.垂直1==长度.结节
顶点集.vertices1==设置。来自列表.到列表

边缘1::非空(a,a)->图表来源 #

从边列表构造图形。复杂性:O(左)时间、内存和大小,其中L(左)是的长度给定列表。

边缘1[(x,y)]==边缘x年边缘1==覆盖层1.功能性维修计划(未修剪的 边缘)边缘计数.边缘1==长度.节点

覆盖层1::非空(图表a) ->图表来源 #

覆盖给定的图形列表。复杂性:O(左)时间和记忆,以及O(S)型大小,其中L(左)是长度给定列表的S公司是列表中图形的大小之和。

重叠1[x]==x覆盖1[x,y]==覆盖x年

连接1::非空(图表a) ->图表来源 #

连接给定的图表列表。复杂性:O(左)时间和记忆,以及O(S)型大小,其中L(左)是长度给定列表的S公司是列表中图形的大小之和。

连接1[x]==x连接1[x,y]==连接x年

图形折叠

折叠1::(a->b)->(b->b->b)->(b->b->b)->图表a->b来源 #

广义图折叠:递归折叠图表通过将提供的函数应用于表达式。参数的顺序是:顶点、覆盖和连接。复杂性:O(s)个给定函数的应用。例如复杂性大小O(s)个,自常量+成本不变。

折叠1顶点    覆盖 连接==id折叠1顶点    覆盖(轻弹 连接) ==转置折叠1(常量1) (+)     (+)            ==大小折叠1(==x)(||)(|||)==hasVertex公司x

图上的关系

是SubgraphOf::订单a=>图表a->图表a->布尔 来源 #

这个是SubgraphOf函数接受两个图形并返回真的如果第一个图形是子图第二个。复杂性:O(s+m*log(m))时间。请注意,边的数量图形可以是表达式大小的二次曲线.

是x的子图(覆盖x y)==真是SubgraphOf(覆盖x年)(连接x y)==真是SubgraphOf(路径1X轴)(电路1xs)==正确是x y的子图==>x<=y

(===)::等式a=>图表a->图表a->布尔 中缀4 来源 #

图表达式上的结构相等。复杂性:O(s)个时间。

x==x==正确x+y===x+y=真1+2===2+1==错误x+y===x*y==错误

图形属性

大小::图表a->国际 来源 #

这个大小即表达式的叶数。复杂性:O(s)个时间。

尺寸(顶点x) ==1尺寸(覆盖x y)==尺寸x+尺寸y尺寸(连接x y)==尺寸x+尺寸y尺寸x>=1尺寸x>=顶点计数x

hasVertex公司::等式a=>a->图表a->布尔 来源 #

检查图形是否包含给定的顶点。复杂性:O(s)个时间。

hasVertex x(具有顶点x)(顶点y) ==(x==y)

hasEdge公司::等式a=>a->a->图表a->布尔 来源 #

检查图形是否包含给定边。复杂性:O(s)个时间。

hasEdge x y轴(顶点z) ==错误hasEdge x y轴(边缘x y)==真hasEdge x y。删除边缘x年==常量False(错误)hasEdge x y轴==元素(x,y)。边缘列表

顶点计数::订单a=>图表a->国际 来源 #

图中的顶点数。复杂性:O(s*log(n))时间。

顶点计数(顶点x) ==1顶点计数==长度.顶点列表顶点计数x<顶点计数y==>x<y

边缘计数::订单a=>图表a->国际 来源 #

图中的边数。复杂性:O(s+m*log(m))时间。请注意,边的数量相对于表达式大小,图可以是二次的.

边缘计数(顶点x) ==0边缘计数(边缘x y)==1边缘计数==长度.边缘列表

顶点列表1::订单a=>图表a->非空来源 #

给定图的顶点排序列表。复杂性:O(s*log(n))时间和O(n)内存。

顶点列表1(顶点x) ==[x]顶点列表1。垂直1==节点.分类

边缘列表::订单a=>图表a->[(a,a)]来源 #

图的边的排序列表。复杂性:O(s+m*log(m))时间和O(米)内存。请注意边缘图的大小可以是表达式大小的二次方.

边缘列表(顶点x) ==[]边缘列表(边缘x y)==[(x,y)]边缘列表(明星2 [3,1]) == [(2,1), (2,3)]边缘列表。边缘1==节点.分类.到列表边缘列表。转置==分类.地图 互换.edgeList(.edge列表)

顶点集::订单a=>图表a->设置来源 #

给定图的顶点集。复杂性:O(s*log(n))时间和O(n)内存。

顶点集。顶点==设置。单子顶点集。垂直1==设置。来自列表.到列表顶点集。小集团1==设置。来自列表.到列表

边缘设置::订单a=>图表a->设置(a、a)来源 #

给定图的边集。复杂性:O(s*log(m))时间和O(米)内存。

边缘设置(顶点x) ==设置。空的边缘设置(边缘x y)==设置。单子(x,y)边缘设置。边缘1==设置。来自列表.到列表

标准图形族

路径1::非空a->图表来源 #

这个路径在顶点列表上。复杂性:O(左)时间、内存和大小,其中L(左)是的长度给定列表。

路径1[x]==顶点x路径1[x,y]==边缘x年路径1。颠倒==转置.路径1

电路1::非空a->图表来源 #

这个电路在顶点列表上。复杂性:O(左)时间、内存和大小,其中L(左)是的长度给定列表。

电路1[x]==边缘x x x电路1[x,y]==边缘1[(x,y),(y,x)]电路1。颠倒==转置.电路1

小集团1::非空a->图表来源 #

这个集团在顶点列表上。复杂性:O(左)时间、内存和大小,其中L(左)是的长度给定列表。

剪贴画1[x]==顶点x剪贴画1[x,y]==边缘x年clique1[x,y,z]==边缘1[(x,y),(x,z),(y,z)]剪贴画1(xs<>年)==连接(剪辑1xs)(剪辑1ys)小集团1。颠倒==转置.剪辑1

双液1::非空a->非空a->图表来源 #

这个二液化在两个顶点列表上。复杂性:O(L1+L2)时间、内存和大小,其中第一层L2级给定列表的长度。

双液1[x1,x2][y1,y2]==边缘1[(x1,y1),(x1、y2),(x2、y1)、(x2,y2)]双液1 xs-ys==连接(垂直1X轴)(垂直1年)

明星::a->[a]->图表来源 #

这个明星由连接到叶子列表的中心顶点形成。复杂性:O(左)时间、内存和大小,其中L(左)是的长度给定列表。

星x[]==顶点x星x[y]==边缘x年星x[y,z]==边缘1[(x,y),(x,z)]

恒星1::非空(a,[a])->图表来源 #

这个星星通过覆盖非空列表形成明星第条。复杂性:O(左)时间、内存和大小,其中L(左)是的总大小输入。

星形1[(x,[])]==顶点x星号1[(x,[y])]==边缘x年星1[(x,ys)]==明星x年恒星1==覆盖层1.功能性维修计划(未修剪的 明星)覆盖(星1xs)(星1ys)==星1(xs<>年)

::a->图表来源 #

这个树状图根据给定的数据结构。复杂性:O(T)时间、内存和大小,其中T型是的大小给定树(即树中的顶点数)。

树(节点x[])==顶点x树(节点x[节点y[节点z[]]])==路径1[x,y,z]树(节点x[节点y[],节点z[]])==明星x(y,z)树(节点1[节点2[],节点3[节点4[],结点5[]])==边缘1[(1,2), (1,3), (3,4), (3,5)]

网格1::非空a->非空b->图表(a,b)来源 #

构造一个网格图来自两个顶点列表。复杂性:O(L1*L2)时间、内存和大小,其中第一层L2级给定列表的长度。

网格1[x][y]==顶点(x,y)网格1 xs-ys==(路径1X轴)(路径1年)网格1[1,2,3]['a','b']==边缘1[(1,‘a’),(1,'b')),((1,’a'),(2,‘a'))(1,‘b’)(2,‘a’),(3,‘a”),((3,‘a’),(3,’b’)]

圆环体1::非空a->非空b->图表(a、b)来源 #

构造一个圆环图来自两个顶点列表。复杂性:O(L1*L2)时间、内存和大小,其中第一层L2级给定列表的长度。

圆环体1[x][y]==边缘(x,y)(x,y)圆环1 xs-ys==(电路1X轴)(电路1年)圆环1[1,2][‘a’,‘b’]==边缘1[(1,‘a’),(1,'b')),((1,’a'),(2,‘a'))(1,‘b’),(1,’a’)(2,'a'),((2,‘b’),(1,‘b')),(2,’b’)

图形转换

删除顶点1::等式a=>a->图表a->也许 吧(图表a)来源 #

从给定图形中删除顶点。退换商品没有什么如果结果是图形为空。复杂性:O(s)个时间、内存和大小。

删除顶点1 x(顶点x) ==无删除顶点1(顶点2) ==只是(顶点2)删除顶点1 x(边缘x x)==无删除顶点1(边缘1 2)==仅(顶点2)删除顶点1 x>=>删除顶点x x==删除顶点x

删除边缘::等式a=>a->a->a->图表a->图表来源 #

从给定图形中删除边。复杂性:O(s)个时间、内存和大小。

删除边缘x y(边缘x年)==垂直1[x,y]移除边缘x y。removeEdge x y==删除边缘x y移除边缘1 1(1*1*2*2)==1*2*3移除边缘12(1*1*2*2)==1*1+2*2大小(移除边缘x y z)<=3*大小z(z)

替换顶点::等式a=>a->a->图表a->图表来源 #

功能替换顶点 x年替换顶点x带顶点在一个鉴于图表.如果已经存在,x将合并。复杂性:O(s)个时间、内存和大小。

替换顶点x x==id替换顶点x y(顶点x)==顶点替换顶点x y==合并顶点(==x)y

合并顶点::(a->布尔)->a->图表a->图表来源 #

将满足给定谓词的顶点合并到给定顶点中。复杂性:O(s)个时间、内存和大小,假设谓词恒定时间。

合并顶点(常量假)x==id合并顶点(==x)y==替换顶点x年合并顶点即使1 (0 * 2)     == 1 * 1合并顶点古怪的1 (3 + 4 * 5) == 4 * 1

拆分顶点1::等式a=>a->非空a->图表a->图表来源 #

将顶点拆分为具有相同连接性的顶点列表。复杂性:O(s+k*L)时间、内存和大小,其中k个是的数字表达式中顶点的出现次数和L(左)是的长度给定列表。

splitVertex1 x[x]==idsplitVertex1 x[y]==替换顶点x年splitVertex1 1[0,1]$1*(2+3)==(0+1)*(2/3)

转置::图表a->图表来源 #

转换给定图形。复杂性:O(s)个时间、内存和大小。

转置(顶点x)==顶点x转置(边缘x年)==边缘年x转置。转置==id转置(x年)==(转置x)(转置y)边缘列表.转置==分类.地图 互换.边缘列表

诱导1::(a->布尔) ->图表a->也许 吧(图表a)来源 #

构造诱导子图通过移除不满足给定谓词的顶点。退换商品没有什么如果结果图为空。复杂性:O(s)个时间、内存和大小,假设谓词恒定时间。

诱导1(常量真)x==仅x诱导1(常量假)x==无诱导1(/=x)==删除顶点1x诱导1 p>=>诱导1 q==诱导1(\x->px&&qx)

诱导Just1::图表(也许 吧a) ->也许 吧(图表a)来源 #

构造诱导子图通过删除顶点来确定给定图形的那是没有什么.退货没有什么如果结果图为空。复杂性:O(s)个时间、内存和大小。

诱导Just1(顶点 没有什么)                               ==没有什么诱导Just1(边缘(只是x)没有什么)                        ==只是(顶点x)诱导Just1。功能性维修计划 只是==只是诱导Just1。功能性维修计划(\x->如果p x那么只是x其他没有什么) ==诱导1第页

简化::订单a=>图表a->图表来源 #

简化图形表达式。从语义上来说,这是身份功能,但它根据代数定律简化了给定的表达式。该函数不计算最简单的可能表达式,但使用启发式在合理的时间内获得有用的简化。复杂性:功能执行O(s)个图形比较。这是有保证的结果的大小不超过给定表达式的大小。

简化==id大小(简化x)<=大小x简化1===1简化(1+1)===1简化(1+2+1)===1 + 2简化(1*1*1)===1 * 1

使稀疏::图表a->图表(要么 国际a)来源 #

稀疏化(Sparsify)添加中间层的图左侧 国际顶点之间原始顶点(将后者包裹在赖特)结果是图表是稀疏的,即仅包含O(s)个边,但保留原始顶点之间的可达性关系。稀疏化很有用当使用密集图时,因为它可以减少O(n^2)向下至O(n)密密麻麻地取代派系、比基利和类似组织由中间顶点构建的稀疏子图连接结构。复杂性:O(s)个时间、内存和大小。

分类.可达成的x个==分类.权利.可达成的(稀疏化x)。赖特
顶点计数(稀疏化x)<=顶点计数x个+大小x+1边缘计数(稀疏化x)<=3*大小x大小(稀疏化x)<=3*大小x

稀疏KL::国际->图表 国际->图表 来源 #

对顶点为范围内整数的图进行稀疏化[1..n],其中n个是函数的第一个参数,生成基于数组的图形来自的表示数据。图表(由King和Launchbury介绍,因此函数的名称)。在结果图中,顶点[1..n]对应于原始顶点,并且所有大于n个由稀疏化过程引入。

复杂性:O(s)个时间和记忆。注意,由于稀疏化结果图的边数与原始代数表示,即使后者可能包含二次方O(s^2)边数。

分类.可达成的x个==分类.滤波器(<=n)。可达成的(稀疏KL n x)长度(顶点$sparsifyKL n x)<=顶点计数x个+大小x+1长度(边缘$sparsifyKL n x)<=3*大小x

图形组成

::图表a->图表b->图表(a、b)来源 #

计算笛卡尔积图表。复杂性:O(s1*s2)时间、内存和大小,其中s1s2秒给定图形的大小。

盒子(路径1[0,1]) (路径1[‘a’,‘b’])==边缘1[((0,'a'),(0,'b')),(0,'a'),(1,'a]),(0,‘b’),(1,‘b'),((1,‘a’),(1,'b'))]

直到结果顶点类型之间的同构,此操作是可交换的,相联的,分发结束覆盖、和具有单子图作为身份.下方~~代表平等,最高可达同构,例如。(x, ()~~x.

框x y ~~框y x盒子x(盒子yz)~~盒子(盒子xy)z方框x(覆盖y z)==覆盖(方框x y)(方框x z)方框x(顶点()~~x转置(方框x y)==方框(转置x)(转置年)顶点计数(方框x y)==顶点计数x个*顶点计数边缘计数(方框x y)<=顶点计数x个*边缘计数年+边缘计数x个*顶点计数