Abstraction elimination
(本文不保证不误人子弟,切勿轻信)
Unlambda指的是lambda计算中去掉lambda操作(does not have lambda(or abstraction) operation of the lambda calculus),那实现消除abstraction是如何做到的呢?
一、基本的abstraction elimination
假设表达式F,我们想用它创建一个函数(function),将这个函数应用到X上,用符号表示变量并写成$x(即^xF,这里用^表示标准的lambda),那么想得到unlambda,需要消除lambda operation。
对F来说,有三种情况:1. F是内建(函数)(或者是非$x的变量);2. F是$x;3. F 是一个应用(函数),即 `GH,其中G和H是比F简单的表达式(就是降低F表达式复杂度),对这三种情况分别讨论:
1. 从^xF中消除lambda,其中F不依赖于$x,故可以将F看作是常函数,这是因为X是输入,F不依赖于输入自然就表示F是常函数,即 `kF
2. 从^x$x中消除lambda,对于输入X,这个函数返回就是$x,即自身,故对应i
3. 从^x`GH中消除lambda,假定我们已经知道如何从^xG和^xH中消除lambda,根据^x`GH意思是有一个输入X,而`GH表示应用G到H上,这表示可以将X传入到^xG 和^xH中,然后将后者结果作为前者的输入,这正是内建s的作用,故^x`GH对应
``s^xG^xH
总结如上规律,考虑消除^xF的lambda,注意这里的F可能是一个复杂的表达式,并且可能跟$x相关,对F从左往右看,遇到一个 `(backquote),将其替代为 ``s, 遇到 $x 则替代为 i, 遇到任何内建函数或者非$x的变量,则在这个函数符号或者变量符号前加一个 `k,如果有几个lambda需要消除,从内部往外部消除,具体参见下面的例子b。
例子:
a.函数 ^x`$xk 的去lambda,此处我们用上面1)、2)和3)的规律来转换。
^x`$xk -> (F是`$xk,是复杂表达式,应用上面第三点)-> ``s^x$x^xk -> (分别对^x$x 和 ^xk 去lambda)-> ``si`kk
b.函数 ^x^y`$y$x 的去lambda,此处我们用上面的总结规律来转换(当然也可以根据1、 2、 3点规律老老实实的转换)
^x^y`$y$x -> (根据例子a的结论)-> ^x``si`k$x ->(根据总结规律先转换左部两个 ` )-> ``s``s si`k$x ->(从第三个s开始转换内建函数s和i,空白格是故意加上去为了区分左部是已经转换的,右部尚未转换)
-> ``s``s`ks`ki` `k$x -> ``s``s`ks`ki``s`kki
如果给出了若干个lambda,那么abstraction eliminate后的表达式将会指数级增长(以3为底的指数)。一个 ` 变为 ``s,然后 ``s 变为 ``s``s`ks,然后又变为 ``s``s`ks``s``s`ks``s`kk`ks,依次类推。
二、高效的abstraction elimination
上面分析的第一种情况下,表达式F是内建函数或者是非$x的变量,则可以将lambda ^xF 写成 `kF,事实上,只要F不包含 x 就可以这么转换,因为此时 F 是与 x 无关的,可以将 F 看作是 x 的常量,此时可以不用遍历繁杂的F表达式而可以直接转换写成`kF。可以将这种转换看作 abstraction elimination的快捷方式(shortcut)。
有一点需要注意,这样的转换在 “纯的隐式类型的lambda计算” 领域可以很好的工作,或者在我们不用过多担心计算非终止(如死循环,或无限大列表)的情况下也是可以很好的工作。因为没有边界作用(side effect),当然目前我们所看到的函数确实不产生边界作用。可是,当我们写 ^xF的时候,我们可能是考虑到有边界作用的或者计算不能结束(因为是lambda),这个边界作用使得某些计算被延迟直到函数被应用到某个变量上(即,直到 $x 接收到一个值,哪怕那个值其实是被忽略的),所以如果我们使用shortcut并写成 `kF,那么一旦遇到这个表达式,F 就会被计算,即使这个函数没有被应用到某个参数变量,这跟原来的 ^xF的延迟性不吻合。
于是使用shortcut将 ^xF写成 `kF 的前提条件是 a)F 不包含 $x;b)计算 F 能计算出来并且没有边界作用。一个确保条件b)能满足的方法是检查F的应用形式为:内建函数 K 应用到一个参数上, 或者内建函数 S 应用到一个或两个参数上,或者内建函数 D 应用到任何表达式上。(这样保证F是无法立即被计算出来)
如果F不包含 x 但是包含一些可能导致边界作用或者无法计算完成(比如死循环)的计算,此时虽然不能使用 shortcut 转换,但仍然有另一种方法较高效地实现 abstraction elimination,即使用内建函数 D,转换成 `d`kF 。(可能,对于一个纯函数论者,他是不会在程序中使用 D 的。)
abstraction elimination的另一个快捷方法是将形如 ^x`F$x 转换为 F,当然这需要确保 F 中没有变量 $x。这在F不是内建函数 D 并且非 $x的情况下,转换非常快捷。然而如果 F 可能会产生边界作用时,跟其他shortcut一样,这种转换带有危险(也可以写成 `dF从而绕开这种危险)。
三、更多的unlambda内建函数
1. v 函数
v 函数好比一个黑洞,v需要一个输入参数,并忽略这个参数然后返回v自己,故 v 可以用来吞噬 N个参数。
v函数可以由 s,k 和 i 来实现(即,也可以使用 s 和 k 来实现)。
2. .x 函数
.x 函数需要一个参数,并将这个参数打印到标准输出。 r 函数 是 .x 函数的一个实例,即x参数是一个换行符, 因此, `ri 的作用是打印一个新行, `rv 或者 `rr 或者 `r(anything) 都是打印一个新行,当然, r 函数本身不会做任何事情,因为 r 函数没有被应用到一个参数中。
3. d 函数
d 函数是一个特例。当unlambda准备计算 `FG,并且 F 计算出来为 d (比如 F 就是 d),那么 G 将不会被计算, 结果为 `dG, `dG允诺会计算G(a promise to evaluate G),只有在 `dG被应用到表达式H上(在此之前,G是保持未计算状态),这时,G 最终被计算出来(在 H 被计算出来之后),然后 再应用到 H 上。
例如, `d`ri 不会做任何事情(保持未计算状态), ``d`rii 打印一个新行,因为 `d`ri 被应用到 i 上,于是 `ri(作为G)被计算出来为i(其副作用是打印新行),然后在应用到 i 上, 还是为 i 本身。另一个例子是 ``dd`ri ,打印一个空白行,事实上, `dd 首先被计算,根据 d 函数的特性,计算结果为允诺计算d(a promise to evaluate d),即可以看作第二个 d 被第一个 d 暂时封住了,所以不会阻止 `ri 打印新行,然后再 计算 d(第二个d),此时新行已经被打印。另一方面, ``id`ri 不会打印新行,因为 `id会被先计算出来为 d,阻止了后面的 `ri, 类似地, ```s`kdri 首先转为 ```kdi`ri (将`kd 看作 X,`r 看作 Y, i 看作 Z),然后 ``kdi 被计算为 d, 然后阻止了后面的 `ri, 故这个函数不会打印新行。
`d`kF 是另一个 promise 的形式(与 `dG 比较):当这个函数 应用到 参数 Y 上, Y 被忽略,然后返回 F 。这在上文 abstraction elimination 中有关 shortcut 的讨论中提到(大概因为 d 函数的 promise 特性与边界作用类似吧)。
Abstraction elimination的更多相关文章
- A.Kaw矩阵代数初步学习笔记 6. Gaussian Elimination
“矩阵代数初步”(Introduction to MATRIX ALGEBRA)课程由Prof. A.K.Kaw(University of South Florida)设计并讲授. PDF格式学习笔 ...
- hdu4975 A simple Gaussian elimination problem.(正确解法 最大流+删边判环)(Updated 2014-10-16)
这题标程是错的,网上很多题解也是错的. http://acm.hdu.edu.cn/showproblem.php?pid=4975 2014 Multi-University Training Co ...
- Effective Java 61 Throw exceptions appropriate to the abstraction
Exception translation: higher layers should catch lower-level exceptions and, in their place, throw ...
- 【转】Duplicate Elimination in Scrapy
本文转载自:http://blog.pluskid.org/?p=381 之前介绍 Scrapy 的时候提过 Spider Trap ,实际上,就算是正常的网络拓扑,也是很复杂的相互链接,虽然我当时给 ...
- SQL Abstraction and Object Hydration
SQL Abstraction and Object Hydration In the last chapter, we introduced database abstraction and a n ...
- 390. Elimination Game
正规解法直接跳到代码上面一点的部分就可以了.但我想记录下自己的思考和尝试过程,希望二刷能看到问题所在. 找规律的时候写了好多,虽然规律很简单. 只要随便写3以上的例子,就应该发现,相邻的2个最后结果是 ...
- Gauss elimination Template
Gauss elimination : #include <iostream> #include <cstdlib> #include <cstring> #inc ...
- 列存储段消除(ColumnStore Segment Elimination)
列存储索引是好的!对于数据仓库和报表工作量,它们是真正的性能加速器.与聚集列存储结合,你会在常规行存储索引(聚集索引,非聚集索引)上获得巨大的压缩好处.而且创建聚集列存储索引非常简单: CREATE ...
- 高斯消元法(Gauss Elimination)【超详解&模板】
高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵.高斯消元法的原理是:若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组. ...
随机推荐
- 如何将 Area 中的 Controller 放到独立的程序集?
目录 背景如何将 Area 中的 Controller 放到独立的程序集?备注 背景返回目录 本文假设您已经熟悉了 ASP.NET MVC 的常规开发方式.执行模型和关键扩展点,这里主要说一下如何使用 ...
- js中内置有对象
statpot:使用mongo+bootstrap+highcharts做统计报表 最近做了一个统计项目,这个统计项目大致的需求是统计接口的访问速度.客户端会调用一个接口来记录接口的访问情况,我的需求 ...
- 没有标准化字符串的后果(IOS)
对于NSString肯定会经常用到,谈谈最近在项目中遇到的一个奇特的现象.如下:我们知道文件系统的命名都是用的字符串,比如你给文件取名“a.pdf”,然后保存文件后,那个文件的名字就真的是 " ...
- SQL Server中的高可用性1
SQL Server中的高可用性(1)----高可用性概览 自从SQL Server 2005以来,微软已经提供了多种高可用性技术来减少宕机时间和增加对业务数据的保护,而随着SQL Server ...
- PHP之算法
PHP之算法偶遇隨感 要求如下: 第1种: A,B,C 期望能够得到的组合是: AB,AC,BC 第2种: A,B,C,D(可通过参数控制结果长度,如长度为2或3) 期 ...
- Java线程同步之一--AQS
Java线程同步之一--AQS 线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序.同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务.每个服务员在同一时刻 ...
- TFS体系结构和概念
TFS体系结构和概念 TFS是Team Fundation Server的简称,是微软VSTS的一部分,它是Microsoft应用程序生命周期管理(ALM)工具的核心协作平台,简单的说它是管理和开发软 ...
- 如何在CMD下运用管理员权限
方法一:鼠标右键 这个方法比较比较普通, 点开开始找到cmd,右击鼠标“以管理员身份运行(A)”这样调用就是管理员的权限: 方法二:快捷模式 在点开win+R后,选择“以管理员身份运行”,然后确定:可 ...
- 在code first结构下的生成的数据迁移文件,upadate-database失败
程序控制台出现 already exist Table "xxx",是由于项目中的Migrations(迁移文件)与连接的mysql数据库里迁移记录表里的数量及名称不一致.
- HostingEnvironment RegisterObject和QueueBackgroundWorkItem
其实网上关于HostingEnvironment 的RegisterObject和QueueBackgroundWorkItem文章已经很多了,典型是的 QueueBackgroundWorkItem ...