RChain 的谓词演算(Predicate Calculus)

RChain微博:RChain官方

这是RCast第62期。
https://blog.rchain.coop/blog/2019/12/18/rcast-62-predicate-calculus-for-rchain/
原文链接有完整音频,欢迎收听。

克里斯蒂安·威廉姆斯(Christian Williams)与格雷格·梅雷迪思(Greg Meredith)和艾萨克·德弗兰(Isaac DeFrain)讨论了其最新研究成果。在谈话中引用了该研究。相应的幻灯片在整理稿下方。

Greg: 今天,Christian将与我们讨论的是他正在研究的一项架构,该架构将帮助清理一些我和Mike与LADL一直在进行的工作。也许方向略有不同,但Christian,来吧。

Christian: 以防有人不认识我,我来快速介绍一下自己,我叫Christian Williams,是加州大学河滨分校的博士在读学生,与John Baez一起研究范畴理论。我是通过与Baez曾经一起工作过的学生Mike Stay与RChain建立联系的。对此我感到非常高兴,也终于取得了一些重大进展。

我今天要谈论的是LADL概念的形式化,Greg和Mike一直致力于此。我将此演讲称为“ RChain的谓词演算”。大家可以在网上找到该概念的一些主要示例,就是Greg关于命名空间逻辑(LADL)的论文。

你可能已经听Greg讨论过(并作了更好的解释),其基本思想是我们希望采用RChain中使用的语言并为其配备谓词概念,以便进行更高阶处理,并对语言中的术语进行推理,以便我们可以形成由术语的逻辑结构确定的语言类型,而我们可以使用这些类型来检查RChain上程序的输入和输出。对于RChain系统而言,这是非常有用且强大的功能。

基本上,我们可以对这些逻辑公式进行编写来表示进程或名称条件。例如,我们可以编写一个被称为Sole Access的公式,如果您关心的是互联网的某些区域(或Greg所说的命名空间)(网络中的某些本地社区),就可以编写该公式来进行过滤且仅接受使用该名称空间收取费用而不使用任何其他名称空间收取的进程。这会形成社区保护的防火墙,并充当检查社区将与之交互的每个流程的社区边界上的筛选器。除此之外,该流程还与谁进行互动以确保安全呢?

Greg: Christian,我补充一下,这种防火墙与标准防火墙技术之间的区别在于,这是一种编译时现象。我们在部署流程之前先进行检查,而在运行时则不做检查。

Christian: 没错。这还无法完整解释名称空间逻辑功能的强大之处。

Greg: 你做得很棒。这确实是社区所需要了解的。它之所以如此与众不同,是因为大多数防火墙都是运行时的。它们在执行期间检查地址,而这会降低执行速度。而对于我们所说的情况而来,我们是在开始运行该流程之前先进行检查的。这发生在编译或部署时,即所谓的连接到进程的服务绑定时。

Isaac: 我有一个评论和一个问题。注释开始时,该Sole Access谓词基本上说的是诸如名称空间之类的东西,可以将其视为一组名称,而我要查看的是仅接收到我所想到的名称空间中名称的所有流程;所以我会收到这些名称(或其中的一些子集),而不接收此名称空间之外的任何名称,对吗?

Christian: 没错,就是这样。

Isaac: 好的。我的问题是:这将能达到什么程度?这是仅用于顶层接收还是用于可以连续显示的任何接收?它适用于这些情况还是只适用于顶层呢?

Christian: 很好的问题。Greg,你想回答这个问题嘛?

Greg: 好的,你这种编写公式的方式是不会递归的。而当你将Sole Access作为接收的延续时,你将获得一个递归公式,并且一直延续下去。

Isaac: 好的。你的意思是不是只有顶层接收可以满足条件,而是任何由此产生的延续都可以满足条件。

Greg: 是的。这个问题很有洞见。

Christian: 自从了解这个概念之后,我就爱上了它。我喜欢这么对朋友解释——它是Google的更深入版本。你不仅可以按关键字搜索,还可以按术语的逻辑结构进行搜索。这是一种非常深刻且固有的语言输入系统方法。尽管大多数语言都会有一些基本类型并对某些类型构造函数进行描述,但在这里,你实际上使用的是Rho演算本身以及一阶逻辑的基本构造函数。你可以从中创建任意细粒度的逻辑公式。这是基于Rho演算的一个非常自然而强大的输入系统。

问题是如何在范畴论中将这一概念形式化。Greg用了LADL这个词;该缩写代表的是“逻辑作为分配法则”。Greg和Mike通过将语言建模为一个monad,将某种集合概念建模为另一monad,并试图从它们之间的分配律中推算出一个公式来解决这个问题。

我今天要介绍的是另一种不同的方法,它看起来可以自由使用且无需在语言或我们想要的逻辑上附加条件。问题仍然存在,可能会有一些限制,但是这在今天还仅仅只是一个基本概念。

我们将要讨论的是代数理论。Greg,你还记得我们上次在播客上谈论代数理论吗?

Greg: 这已经是挺久之前了。

Christian: 确实很久了。

Greg: 值得回顾一下。

Christian: 代数理论是一种将你所关心的结构抽象化并将其转化为一般抽象形式的方法,它可以帮你在不同的上下文中对理论进行建模,并且可以识别某个类别中的对象何时具有这种你想要明确的额外结构。

例如,人们非常关心代数中的组。你可以谈论组理论,但有一个理论是很少有数学家知道却广为范畴论学者所关心的,那就是一个单位半群(monoid)。单位半群(monoid)就是一个二进制运算的东西(可以称为乘法)和一个可以使乘法具有关联性的单位。如果你有三样东西,怎么相乘的顺序并不重要,因此乘法就是单位的。该单元就是操作的标识。

这是一个非常常见的结构。例如,自然数就是单位半群的经典示例,你可以选择为加法或乘法,然后这个单位就是0或1。

Greg: 如果你不介意的话,我想发表一些意见。首先,Christian在下面列了几个不错的图,这些图表达了关联约束和单位约束。这些通常是我们要求代数所具有的相干条件,可以告诉我们它们应该如何运行或者运行得好不好,而所有运算之间都能很好地互动。其次,这是一种非常紧凑且富有表现力的表征方式,这就是为什么它们在范畴论中如此受欢迎的原因所在。

此外,当我们谈论单位半群和自然数时,会发生一些神奇的事情。当你将自然数视为加法运算中的一个等分面时,就会产生一个为零的标识和一个生成器,由此构成一个非常小的结构。如果考虑的是乘法的自然数,那么单位就是1,而生成器是无限的。它们是素数。这两个单位半群之间的关系一直是许多深层数论的主题。

Christian: 令人惊讶的是,即使是最高等数学,它也仍在思考乘法与加法之间的这种差异。代数理论是一种很好的、紧凑的、精巧的方式,可以解决你所关心的这种结构。我们的使用方式是这样的——我们将会写下Rho演算或RChain中用作某些特定理论的其他语言,然后用这个简单的理论来进行讨论。

这个理论是一个类别。它具有一个对象M,所有其他对象仅仅是该对象的有限乘积。因此,您可以在初始运算中讨论从M到N再到M的某些形态,这样一来我们就可以将该结构打包为特定类别。然后,当我们想对该理论进行建模时,它就能由保留结果的函子来进行建模。

如果我们在集合的类别中做建模,我们会将这种抽象M(它是理想的抽象单位半群)携带到一个实际的单位半群中(它是集合类别中的某些特定集合)。然后,我们将乘法运算从该平方乘以其自身延续到一个函数;同理,该单元将选择集合中的实际元素。我们就得到了理论提供的语法和模型提供的语义之间的双重性。

Isaac: 在所有这些内容中,我认为保存产品是一个非常重要的属性,但我不是100%确定为什么会这样。

Christian: 代数和我们所关心的这类结构实际上只是由运算和方程式指定的。您需要指定操作的唯一一种结构只有乘积,因为操作会从你的单位半群提取两个物体,而只回馈给你一个物体。这就是我们所需要保留的所有内容了。

Greg: 你用的是与Lawvere理论同义的具体理论吗?

Christian: 是的,因为Lawvere多种理论基本上就是具有有限乘积的类别。我们所需要做的就是考虑一下其中的某些操作树。这些操作树将对应于基于单位半群理论的谓词的构造函数。

范畴论中有一个叫做筛子的概念。它是某种形态射影,可以在预先合成的情况下关闭。例如,如果我们选择运算M(乘法),然后说“给我所有以该乘法结束的态射,所有运算”,它们就会通过该乘法进行分解。你实际上指定的是某种谓词,例如M表示空白。“给我两件事物的所有乘积。”

这确实很简单,但是我们可以将其视为谓词的构造函数。例如,在Rho演算中,我们可以将par视为乘法。W可能会说:“给我所有与两件事物平行的东西。”它本身并不是一个非常有用的谓词,但是您可以从中将它作为构造函数来使用谓词。

为了跳过这一步,我们需要关注素数。以下是一个单位半群谓词的示例。“给我所有不是身份,不是单位,不是乘法,不是两个单位的事物的乘积的元素。”这就是成为素数的含义。

我们希望有一个框架,在该框架中我们可以指定此谓词并实际提取一个单位半群的主要元素。我们通过筛子获得这些构造函数。暂停一下,这部分大家听得明白吗?

Greg: 是的,很清楚。我的直觉是一般本科或一年级研究生数学中的老式构造,就是逐点运算。如果有一个操作,比如在一个单位半群上定义的乘法,则可以通过逐点操作将其提升为在该单位半群的子集上定义的乘法。

Christian: 就是这样。这是一个很好的解释方法。

Isaac: 我了解你所描述的想法,但不太确定我是否了解这个筛子对象与你这种想法之间的联系。

Christian: 我可能需要再解释清楚一点。在绘制操作树时,我们要指定所有以M结尾的操作,而得到的是所有能使它们具有其他两个操作的形式的M操作的集合。你先得到一个因子M是平方的M中的某个元素,然后再是M。

Isaac: 通过那个乘法操作。

Christian: 没错。这个筛子里的东西就是以M形式乘以其他形式的所有事物。

Greg: 你会得到我所谓的空间连接词,它会提供与术语构造函数相关的所有谓词。但它不会提供例如“和”或“不”或“隐含”的逻辑谓词。

Isaac: 没有模式或任何类似的东西?

Christian: 目前为止没有。

Isaac: Okay. 酷。我懂了。

Christian: 酷。通过这种重要的等价关系,我们就可以将逻辑融入其中。这些筛子和某个特殊函子的子功能之间是等价的。想一想空白逗号M的理论,就像我们的理论一样,我在这里用这个符号来表示可以提供hom-set的东西。这是一个将M代入N的函子,是理论中的其他对象,而且它可以给你提供所有初始运算的集合。

这就像命名空间逻辑中的 “true” 一样,可以提供接受一切的所有操作。我们真正关心的是此函子的子函子的格。大多数人不会想到的奇怪字眼。描绘这种现象的方式是,除了函子级以外,子函子就像子集一样。

这就意味着对于获得每个N,你都会以一种功能性的方式获得一部分初始操作。也就是您挑选的这棵运算树针对的是要挑选满足该公式的初始运算子集的每一端。你得到了所有的初始代码,然后开始检查,“好吧,哪些是M形式的某物乘某物。”我们真正在考虑的是这种结构,这种排除所有初步操作的通用的子函子的词图。

Isaac: 您之所以说它是子函数,是因为最后的顶层运算必须是乘法,就像这个例子一样。

Christian: 对。

Isaac: 好的,这就说得通了。根据你的理论,最后一个操作或最顶层的操作通常可以是任何操作。

Christian: 是的。这个词图就是我们获得一阶逻辑运算的地方。

Isaac: 也许我该多问一个问题。为什么你如此强调词图结构?

Christian: 主要是因为它比讨厌的代数要短,但这只是值我们要有交集,并集,然后要有顶部和底部。它是一种通用的功能,可以执行所有初始操作,然后执行空的操作,而该操作始终是空的。然后我们也会得到一个非常有用的蕴涵,就是Cartesian封闭的偏序版本。这就像一个命题。如果我们将这些子功能视为命题,那么形成蕴涵就是命题的蕴涵。

Isaac: 好吧。这对应于某种子集关系——你所说的是偏序集,对吗?

Christian: 是的。它实际上是一种偏序集合结构,例如当你说P小于或等于通用束前束时,你说的就是P是该函数的子函子。

Isaac: 明白了。

Christian: 想一想集合的幂集而不是所有子集,这会形成一个很好的词图结构。这是一个布尔代数。人们倾向于将其绘制为类似于这种形式,箭头表示包含。

Greg: 抱歉打断一下。那是因为你要执行几组操作。如果您要使用其他类型的操作小工具,例如操作列表之类的,则情况可能有所不同。

Christian: 是的。

Isaac: 你很自然地将子集概念扩展到了子函子,因为你采用的是集合结构。

Christian: 是的。

Isaac: 明白了。

Christian: 我们从集合类别中继承了这些出色的操作。现在,这种结构存在的地方就是所有理论操作的函子;它们是相互矛盾的。这被称为理论预层。每当您对某个类别进行预层时,它都会形成一个称为topos的、具有丰富的内部逻辑的类别。这就是我们所要利用的。这个理论空白M普遍具有这种子函子的词图,而我们使用的是其逻辑结构。

举例来说,如果我们要考虑素数的话——素数意味着既不是单位,也不是两个非单位的乘积。对于第一个部分(非单位),请想一想乘法的同一示例,但要考虑单位运算从1到M生成的筛子。你说,“请给我所有以单位结尾的运算。”(对应于这些子函子之一)。然后我们就可以使用这种否定,在这里我们将其定义为暗示为空的预层,就像暗示为矛盾一样,这种否定会在词图的其他位置上提供另一个子函子。

你会注意到,为了要形成另一个子函子,这里的公式部分会有些不同,因为我们还希望能够提升理论运算能力以作用于这些谓词本身。我们想要的是一个完整的谓词演算,不仅可以对谓词进行逻辑运算,并且实际上仍然可以进行理论中的代数运算。这就是Greg所说的逐点乘法。

如果我们对元素进行乘法,也有一种自然方法,那就是通过逐点定义将其提升为子集。这就是我们需要明确的最后一个难题了。一旦实现这一点,我们就会得到这两个子函子的交集。我们得到某个函子,将其插入N,它就恰好能提供这种素数定义下的初始运算。当你插入一个之后时,你就能获得理论的素数元素。

Greg: 我非常喜欢这种结构。我所要寻找的正是构造的模块性,其中空间谓词的来源不同于逻辑谓词的来源。我们希望能够在某种意义上独立地对它们进行改变。如果我们采用一些其他的小工具(例如树,图形或列表),而不是进行一系列操作,会发生什么情况呢?我很希望能见证这一点。

Christian: 指定谓词素数的最后一个难题就是如何提升理论操作来作用于谓词。我之前忘记说了,我们实际上一直在使用的是谓词(例如X大于3)与满足该谓词的一组条件(例如所有大于3的数字)之间的对应关系 。

我们在这些事情之间来回进行。我们将谓词看作是满足它们术语的子集。就像Greg所说的那样,如果你的单位半群用了乘法并且你有两个单位半群的子集,那么就有一种自然的方法来获得它们的“乘积”。你获得这些子集的乘积,将子集A和子集B中的所有可能的对都提取出来,然后将所有这些对相乘,就能得到所有以小A乘小B形式的东西。这样一来,你就可以将乘积M提升为子集。

我刚才在子集的例子中所说的一切都可以扩展到子函子框架。理念都是一样的。现在,我们已经理解素数谓词了。我们可以取对应于单位的子函子,取反,然后取与两个非单位的提升乘法的求反的交集。

有趣的是,当你按照单位半群理论进行操作时,它实际上是空的。这并没有问题,因为除了身份之外,单位半群理论中并没有其他要素。你可以尝试说“不是身份”,就会明白是什么意思了。在每个操作中,如果您仅将N个身份加载到身份中,就相当于该身份。没有什么可以真正摆脱身份。只有当你真正进入理论模型时,才能获得非身份元素,然后获得实际的素数元素。

Greg: 还有一个解决方法,就是继续进行,输入生成器。如果您有从一个到生成器类的操作,那么就可以解决问题。

Christian: 这就是为什么Rho演算不会出现这种问题,因为有很多流程不必经过模型即可成为非流过程。这只是针对这个更笼统的理论而言,通常是有用的,可以将谓词和理论转移到模型的谓词上,然后就可以获得实际的素数元素。

我们之所以会关注RChain中的素数,是因为如果你认为单位是空过程而乘法是平价的,那么当我们说“所有不是空过程且它们不是两个非空进程的并行”时,那么你指定的就是所有不是两件事并行的单线程进程。

这是一组非常重要的流程,因为它们是其他流程的基础。只要说到竞争条件或并行术语所涉及到的复杂性时,都要从掌握这些基本要素开始,逐一构建并检查这些竞争条件。

我们一直在讨论的这些谓词可以应用于Rho演算和空间演算理论,以及RChain中所使用的其他类型语言。我强烈建议大家都看一下这篇名为《命名空间逻辑》(LADL)的论文,它就是通过我们一直在描述的框架来实现的。

Greg: 你说的不是绑定运算符,这就有些微妙之处。我们已经有了映射和具象,但没有解决绑定的模态运算符。

Christian: 你是说Mu吗?

Greg: 不,Mu是固定的。你可以轻松地在使用这个结构来得到它。我说的是在操作后会有替换。

Christian: 我本来不打算就这一点说太多,但是我所用的框架是Marcelo Fiore的二阶代数理论。它的基本思想不是考虑有限乘积的类别(生成器对象),而是将它们指定为指数对象,这样您就可以进行替换的评估图。在此左下角,我们可以将输入操作指定为N乘以指数P到N的形式,这表示“具有排序名称的自由变量的过程”。

在定义通信时,它是一个使用了从指定N为指数对象后内置的评估的、特定的通信图。如果大家想看的话,我可以将二阶代数理论论文附在博客上。这感觉就像是Rho演算理论。

Greg: 那简直太棒了。这意味着我们能够在一个基本框架内,围绕所观察到的、一个过程不能包含该过程的引号的名称(由于语法的工作方式),从而实现这种全新的概念。根据该观察结果,我们很容易就能够建立相对于给定过程中的名称而言、全新的名称。你应该能够彻底将该结构提升到谓词级别。我们应该能够给出新的谓词,从某种意义上说,它比我们在名义结构中获得的新鲜度构造还要更深,因为对于它们而言,这是一个内置概念,而在这里它源自结构。如果能够做到两者兼而有之,那就太棒了:新鲜的本质就是一个流程不能包含包含该流程引号的名称,然后为其建立谓词,然后为该谓词建立更通用的新鲜谓词。在我看来,这是一个非常棒的结构。

Christian: 是的,听上去很棒。

Isaac: 谓词是否新鲜与Caires工作中的隐藏名称谓词有关系吗?

Greg: 是的,完全正确。但是Caires是原始的。

Isaac: 我明白了。

Greg: 而对于我们来说,我们可以从较小的部件中构建它。

Isaac: 哦是的,这非常酷。

Greg: 正解。我们解释更多的现象。他必须假设某些现象,而我们则进行解释。

Isaac: 明白了。

Christian: 过去几周一直在思考这个问题,而想得越多,我就越兴奋,因为布局框架阐明了过去很多无法解释的内容。而事实证明,你讲得比我想得要更多。

以输入操作为例,在原始示例中我们考虑的是“在某个名称空间上输入,在某个谓词上输入,然后执行某些过程。”在这里,如果将此操作提升为谓词,则该操作 对应于将第一个N限制为某个谓词。你监听的是某个名称空间。你也可以在P到N上执行此操作。不是接受流经管道中的任何内容,而是只接受提供特定谓词的内容。

Greg: 是的。过滤系统。完全正确。它是伴随模式匹配出现的。

Christian: 听上去很厉害。这是不是就是我们所说到的更深层的Google搜索?

Greg: 哦,不。更深层的Google还得更上一台阶。我所说的泛化Google不是特定模型的级别,而是能够根据其结构和行为来搜索代码的级别。无论是Rho演算还是Rust还是JavaScript都可以。现在,搜索代码的唯一方法是通过元数据或社交——我知道的某个开发人员认识另一个开发人员。但那是不可持续的。随着代码量的增加,记忆代码能力会有局限性限制。但通过这个方法,我们就能够维护更大的代码库,因为我们现在可以根据代码的功能和行为方式进行搜索了。

Christian: 您不但可以将其视为强大的查询,它还可以将整个Rho演算提升到谓词水平,成为Rho演算的二阶版本,就像你用的类似接收一样的术语?你接收了第一个术语,但并不仅仅将其视为表示满足的一组过程,而是看作一个可以与大量过程进行通信的术语。

Greg: 正是如此。我敢肯定你们对逻辑编程都很熟悉。现在,我们将逻辑编程与简单类型的Lambda演算相关的逻辑剥离开来,并将它提升到与某些特定重写系统相关的任何逻辑。这非常有趣,因为我们希望做到的是整体编程。以生物系统编程为例,你不会告诉他们该怎么做。你只是投入了一堆实体,由于其特性,它们会自我组织。他们自组织的方式可以满足某些条件,而表达这些条件的方式则是公式级别的。公式级别使我们能够进行基于集合的编程,如果我们要以生物学规模甚至是更小的互联网规模进行编程,这就是必不可少的。

Christian: 听上去太棒了。

Greg: 对,就是这样。这是可实现性的精髓所在。可实现性要求谓词的含义是一堆程序。只要我们开始考虑谓词是允许代理进行自组织和自组装的特征,那么我们就可以将其用作此高阶编程模型。

Isaac: 老实说,我很喜欢听到你们谈论这些东西。这一切真的很酷。我想——也许这只是一个幼稚的想法——为什么这件事还没人做过呢?

Greg: 从某种意义上说,我只是遵循了一个几十年前就存在的指引。Abramsky以逻辑形式提出了这种畴理论,你可以根据畴理论规范以及计算生成逻辑。从某种意义上说,他基本上只考虑了本质上类似于Lambda演算的计算模型,这其实也可以,但是如果考虑到自然中大多数计算系统是并发的,这就行不通了。这一类计算概念太过局限,无法在现实环境中使用。当然,互联网编程必须是并发的,这是绝对无法绕过的。

顺便说一句,这个方法聪明至极,人们理应为这个结构感到惊叹。我对它的批评纯粹只是因为它太好了,值得批评。除此之外,畴理论在很大程度上是语义而不是句法上的。LADL方法的转变主要是句法上的,因为大多数计算概念最终都是象征性的。Lisp显然是计算的象征形式,而Java则同时具有两方面特征。至于Prologue和其他,它们是计算的象征形式。Pi演算绝对是象征性的,而Rho演算也是象征性的。

实际上,向句法方向的转移非常重要,因为可以在正在做的事情和操作语义之间建立更紧密的联系。指称语义消除了操作语义中的许多可用信息。这些信息正是我们需要推理的复杂性之类的信息。概念是一样的。Caires借助空间行为逻辑再次使用了它。他们只是不想使用类别理论来解决这个问题而已。这一过程已经存在很长时间,如果有人说:“嘿,我认为它的范围要大得多”,那可就真是太蠢了。

Isaac: 这种向句法方法的转变也使其可以在编译时进行所有检查。只需要有代码即可。

Greg: 正是如此。你不会使用某种本质上更具语义的中间格式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值