λ-calculus的语法

news/2025/2/3 2:33:50/文章来源:https://www.cnblogs.com/qixingzhi/p/18697299

图灵(Turing)和丘奇(Church)都为“计算”建立了模型,图灵的模型是图灵机,丘奇的模型是\(\lambda\)-calculus。可以证明这两个模型在计算能力(可计算的问题的集合)上是等价的。基于图灵机的原理诞生了Fortran,Pascal等等的编程语言,他们称为指令式编程语言(imperative programming language),它们是通过按照顺序执行指令控制读写头的移动和读写来实现计算的;与之相对的,基于\(\lambda\)-calculus的原理诞生了Lisp,Coq等等,它们称为函数式编程语言(functional programming language),它们是通过按照一定规则对字符串表达式进行重写(rewrite)而完成计算的。\(\newcommand{\l}{\lambda}\)

\(\lambda\)-terms

我们把符号\(v\)与若干个撇称为一个变量(variable)符号,全体变量符号的集合为\(V=\{v,v',v'',\cdots\}\)。满足以下构造规则的符号串称为一个\(\lambda\)-term:

  • 单个变量\(x\in V\)是一个\(\lambda\)-term;
  • 如果\(M,N\)都是\(\lambda\)-term,那么\((MN)\)是一个\(\lambda\)-term;
  • 如果\(x\in V\),并且\(M\)是一个\(\lambda\)-term,那么\((\lambda xM)\)是一个\(\lambda\)-term;

所有\(\lambda\)-term组成的集合记为\(\Lambda\)。例如,\(((\lambda v(v'v))v'')\in \Lambda\)。通常,我们可以用\(x,y,z,\cdots\)来表示变量,并且省略最外层括号。例如,\((\lambda x(yx))z\in \Lambda\)

自由变量(free variables)

下面归纳地定义一个\(\lambda\)-term中的自由变量(free variable)集合,\(M\)中的自由变量集合记为\(FV(M)\)

  • 对于单个变量\(x\in V\)\(FV(x) = {x}\)
  • 对于两个\(\lambda\)-term \(M,N\)\(FV(MN) = FV(M)\cup FV(N)\)
  • 对于变量\(x\)\(\lambda\)-term \(M\)\(FV(\lambda xM) = FV(M)\setminus \{x\}\)

在一个\(\l\)-term中,如果\(x\)不是自由变量,就称\(x\)是一个受限变量(bounded variable)。如果\(M\)中没有自由变量(比如\(M=\lambda x x\)),就称\(M\)是一个封闭的\(\l\)-term (closed \(\l\)-term)。全体封闭\(\lambda\)-term集合记为\(\Lambda^0\)

替换(substitutions)

假设\(M,N\)\(\l\)-term,\(x\)是一个变量,我们用记号\(M[x:=N]\)表示把\(M\)中所有自由出现的\(x\)替换为\(N\)。具体定义如下:

  • 对于单个变量\(x\in V\)\(x[x:=N]\)表示\(x\)
  • 对于单个变量\(y\in V\),若\(y\neq x\),则\(y[x:=N]\)表示\(y\)
  • 对于\(\lambda\)-term \(M_1,M_2,N\)\((M_1M_2)[x:=N]\)表示\((M_1[x:=N])(M_2[x:=N])\)
  • 对于变量\(x,y\)\(\lambda\)-term \(M,N\)\((\lambda yM)[x:=N]\)表示\(\lambda y(M[x:=N])\)

演算规则(Rules)

\(\l\)-calculus的最基本的演算规则是:对于\(\l\)-term \(M,N\)和变量\(x\)\((\lambda xM)N\)可以演算得到\(M[x:=N]\)。其中,我们用等号来表示“可以演算得到”,所以这一规则可以写作

\[(\l x M)N=M[x:=N]\tag{$\beta$} \]

这一规则称为\(\beta\)-conversion,这使得\(\l xM\)这样的项可以被看作“函数”,当一个函数“作用(apply)”在一个\(\l\)-term上时,就是把这个term“代入”该函数的表达式。由于紧跟在\(\l\)后面的受限变量\(x\)仅仅起到一个临时变量的作用,我们并不关心这个变量的取值,所以\(\l\)-calculus还提供以下演算规则,称为\(\alpha\)-equivalance(前提是\(M\)中不包含变量\(y\)):

\[\l xM=\l y(M[x:=y])\tag{$\alpha$} \]

除了\(\beta\)-conversion和\(\alpha\)-equivalance,在\(\l\)-calculus中还必须保证以下基本的演算规则:

(1) 演算的等价关系性质:

  • 自反性:\(M=M\)
  • 对称性:\(M=N \iff N=M\)
  • 传递性:\(M=N,N=L\implies M=L\)

(2) 兼容性(compatibility):

  • \(M=M'\implies MZ=M'Z\)
  • \(M=M'\implies ZM=ZM'\)
  • \(M=M'\implies \l xM=\l xM'\)

compatibility意味着我们总是可以用根据等式的局部替换来rewrite一个\(\l\)-term。

柯里化(Currying)

根据\(\beta\)-conversion,\(\lambda x M\)可以看作“一元函数”。如果要表示“二元函数”,可以用\(\lambda x(\lambda y M)\)的形式。这是因为当一个二元函数apply在两个term上时,可以看作该二元函数首先apply在第一个term上得到了一个一元函数,这个一元函数再apply在第二个term上得到了函数值。这种把多元函数拆分成多个一元函数的想法最早是由H.B. Curry提出的,称为函数的柯里化(Currying)。

\(F=\l x(\l y M)\),它apply在\(N_1,N_2\)上时应当写作\((FN_1)N_2\),这样就会有\((FN_1)N_2=((\l x(\l y M))N_1)N_2=(\l y (M[x:=N_1]))(N_2)\)\(=(M[x:=N_1])[y:=N_2]\)。一般地,如果\(F\)\(n\)元函数,它apply在\(N_1,\cdots,N_n\)时应当写作\(( \cdots((FN_1)N_2)\cdots N_n)\)。方便起见,我们规定apply是左结合的,这样我们就可以在表示多元函数时省略括号,写为\(FN_1N_2\cdots N_n\)

在函数本身的表示上,对于二元函数我们写\(\l x_1(\l x_2 M)\),对于\(n\)元函数我们写\(\l x_1(\l x_2(\l x_3(\cdots (\l x_nM))))\)。所以,多个\(\l x_i\)之间是右结合的,不能省略括号。为了方便,我们发明下面的符号来简化书写:只写一个\(\l\),然后把变量并排依次写出,然后写一个点,然后写函数体,这样\(n\)元函数简写为\(\l x_1x_2\cdots x_n.M\)

用归纳法易证\((\l x_1\cdots x_n.M)N_1\cdots N_n=(( \cdots(M[x_1:=N_1])\cdots)[x_n:=N_n])\)

“函数”一词是集合论或日常语言中的定义。在\(\l\)-calculus中,形如\(\l x_1\cdots x_n.M\)的term称为combinator(组合子)。例如,通常记\(\textsf{I}\equiv \l x.x\),这就是“恒等映射”,\(\textsf{I}M=M\);记\(\textsf{K}\equiv \l xy.x\),它用来取两个term中的前一个,\(\textsf{K}MN=M\);记\(\textsf{K}_\ast\equiv \l xy.y\),用来取两个term中的后一个,\(\textsf{K}_\ast MN=N\);…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/878168.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Easysearch 集群重置 admin 用户密码

admin 用户是 Easysearch 通过配置文件 user.yml 默认添加的,配置如下: ## Demo users admin:hash: "$2y$12$mA9DDk7iOBQA3u.Ebc0QSOVKsgwlkm6OJcrEcpyrTrT5M5It86usq" # 465f7466f79a67b9039dreserved: trueexternal_roles:- "admin"description: "…

Linux 中awk命令自定义函数

001、[root@PC1 test]# echo a | awk function my_length(str) {return length(str)}; {text = "Hello"; print "Length of text:", my_length(text)} Length of text: 5 。

【CodeForces训练记录】Codeforces Round 1002 (Div. 2)

训练情况赛后反思 这个B题感觉太猜猜乐了,个人感觉B难度远大于C A题 想要数组 \(c\) 至少有三个不同的元素,数组 \(a,b\) 的元素数的和必须 \(\ge 4\),如果种类和为 \(3\) 种,最多能凑出两种不同的数字点击查看代码 #include <bits/stdc++.h> // #define int long lo…

进程的基本概念

写在前面 这是一篇十分简短的文章,主要讲述了进程的基本概念,如何创建进程以及一些细节问题,为接下来学习进程调度打好基础。 什么是进程 简单来说,进程就是运行中的程序。比如,我们双击了存放在硬盘中的某个exe程序,程序被加载到内存中运行起来后,就是所谓的进程。所以…

python 中实现gz文件的解压

python 中实现gz文件的解压。001、(base) [root@PC1 test]# ls a.txt.gz test.py (base) [root@PC1 test]# zcat a.txt.gz ## 测试的压缩文件 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 (base) [root@PC1 test]# cat test.py ## 测试的py…

【模拟电子技术】19-差分放大电路的构成

【模拟电子技术】19-差分放大电路的构成 我们知道在直接耦合放大电路中零点漂移是一个很困扰的问题(可以理解为静态工作点稳定问题),我们通过增加电阻Re来抑制温漂,前面我们也提到过有一种电路可以在直流的时候doubleRe,而交流的时候使得Re消失我们想要抑制这种现象,想到…

球钟问题

球钟问题,对栈和队列的实际应用球钟问题 1. 问题背景 ​ 球钟是一个利用球的移动来记录时间的简单装置。它有三个可以容纳若干个球的指示器:分钟指示器,五分钟指示器和小时指示器。 举例:若分钟指示器中有2个球,五分钟指示器中有6个球,小时指示器中有5个球,则时间为5:32…

本地部署deepseek

前言 如果你电脑配置不错,且期望不受网络限制也可以流畅使用deepseek,那就本地部署deepseek试试吧。下载并安装Ollama Ollama是一个开源的 LLM(大型语言模型)服务工具(就是大模型运行工具),用于简化在本地运行大语言模型,降低使用大语言模型的门槛,使得大模型的开发者…

【邮件安全】近期常见的钓鱼邮件(202411期)

本期主要分享自2024年11月至今几种典型的钓鱼邮件样本。希望通过这种分享,可以帮助广大用户提高警惕性,增强识别与防范钓鱼邮件的能力。 邮箱账户异常类 以下图为例,该钓鱼邮件伪造用户账户出现异常登录情况,引导用户点击“认证账户”按钮进入钓鱼页面。 下图是一封伪造用户…

AI医院:大语言模型在多智能体医疗交互模拟器中的表现如何?

近年来,人工智能(AI)技术,尤其是大语言模型(LLMs),在医学领域取得了显著进展。这些模型在静态医疗问答任务中表现优异,甚至在某些情况下能够媲美人类专家。然而,医学诊断并非单一静态的任务,而是一个动态、复杂的过程,涉及多轮互动和信息收集。 为了更全面地评估LLM…

万字综述|一文掌握大语言模型在生物信息学中的应用

随着大语言模型(LLMs)技术的飞速发展,其在自然语言处理(NLP)领域的成功应用逐渐扩展到了生物信息学领域。生物信息学作为一个跨学科的领域,涉及基因组学、蛋白质组学、药物发现等多个方向,LLMs的引入为这些领域带来了新的研究工具和方法。 2025年1月,佐治亚大学Tianmin…

自主做前端页面小工程07

通过使用elementui和js部分代码实现 其重点在于导航栏与弹窗和数据的回显与数据只可预览,基本完成 这是补发昨天学习记录