zoukankan      html  css  js  c++  java
  • lambda演算入门

    介绍如何进行简单lambda演算的计算(规约):形如下面这样的题目:

    intro

    https://www.jianshu.com/p/ebae04e1e47c 这一篇很清晰,基本涵盖了本文的内容。

    可跳过本节,基本对做题没帮助

    关键字

    小写单字符用以命名参数,也叫变量(数学含义的)。

    外加四个符号'(',')','.','λ'。

    由它们组成符号串叫λ表达式,核心λ演算表达式是非常冗长的(见下文).为了清晰和简炼,再加上一类符号:

    大写单字符、 特殊字符(如+、-、*、/)、大小写组成的标识符代替一个λ表达式。

    EBNF语法

    <λ-表达式> :: = <变量>

    ​ | λ<变量>.<λ-表达式>

    ​ | (<λ-表达式><λ-表达式>)

    ​ | (<λ-表达式>)

    ​ <变量> :: =<字母>

    表达式的四种形式分别对应:(表达式也称公式,)[1]

    1. 标识符引用(Identifier reference):标识符引用就是一个名字(实参),这个名字用于匹配函数表达式中的某个参数名。
    2. 函数定义:Lambda演算中的函数是一个表达式,写成:lambda x . body,表示“一个参数(形参)为x的函数,它的返回值为body的计算结果。” 这时我们说:Lambda表达式绑定了参数x
    3. 函数应用(Function application):函数应用写成把函数值放到名字前面的形式,如(lambda x . plus x x) y
    4. 加括号仍是表达式

    变量

    作为变量的标识符可以代表参数或名字。

    闭包(closure)或者叫完全绑定(complete binding)。在对一个Lambda演算表达式进行求值的时候,不能引用任何未绑定的标识符。如果一个标识符是一个闭合Lambda表达式的参数,我们则称这个标识符是(被)绑定的;如果一个标识符在任何封闭上下文中都没有绑定,那么它被称为自由变量。

    函数

    函数是头等程序对象(函数是值),可作为函数的输入输出。

    缩写与变形

    • 用λ演算表示计算首先要表示域,由于λ演算系统的值也是公式,则每个域中先定义最基本几个公式,其它值通过演算实现。这样,表示计算的问题全集中在λ演算上了。由于λ演算中一切语义概念均用λ表达式表达。为了清晰采用命名替换使之更易读。

        T = λx.λy.x          //逻辑真值
      
           F = λx.λy.y          //逻辑假值
      
           1 = λx.λy.x y         //数1
      
           2 = λx.λy.x(x y)       //数2
      
       	n=λx.λy.x(x(…(x y)…)//n个x
           zerop = λn.n(λx.F)T      //判零函数
           + = add = λx.λy.λa.λb.((x a)(y a)b)
      

      zerop中的F、T可以用λ表达式展开,其它用法同。

    • 库里化:将两个参数的函数变为两个单参数函数:写只有一个参数的函数,而这个函数返回一个带一个参数的函数。

      库里化的原因是 核心的λ演算只有单目运算,例如:add 1它返回的结果是函数,再应用到后面的表达式上。这样,3+4就写add 3 4,add 3返回“加3函数”应用到4上当然就是7。写全了是:

      (λx.λy.λa.λb.((x a)(y a) b ))(λp.λq.(p p(p q)))(λs.λt.(s s s(s t)))
                =λa.λb.(a(a(a(a(a(a(a b)))))))
      

    ​ λa.λb.λc.λz.E = λabcz.E

    ​ = λ(abcz).E

    ​ = λ(a,b,c,z).E

    ​ = λa.(λb.(λc.(λz.E)))//库里化,因为语法中lambda后只有一个 变量

    • 命名 以大写单字符或标识符命名其λ表达式:

    ​ G = (λx.(y(yx)))

    ​ ((λx.(y(yx)))(λx.(y(yx)))) = (G G) = H

    规约

    Lambda演算(规约)只有两条真正的法则:称为Alpha和Beta。Alpha也被称为「转换」,Beta也被称为「规约」。λ函数的语义是它应用到变元上所实现的数学函数计算。从符号演算的角度应用就是符号表达式的归约(reduction),归约将复杂的表达式化成简单形式,即按一定的规则对符号表达式进行置换。

    法则

    (1) β归约,β归约的表达式是一个λ应用表达式(λx.M N),其左边子表达式是λ函数表达式,右边是任意λ表达式。β归约以右边的λ表达式置换函数体M中λ指明的那个形参变量。形式地,我们用[N/x,M]表示对(λx.M N)的置换。

    先看一例,相互归约的符号标以下横线。

    例11-4 归约数1的后继

    (succ 1) => (λn. (λx.λy.n x(x y))1) //写出succ的λ表达式

    ​ => (λx.λy.(1 x(x y)))

    ​ => (λx.λy.((λp.λq.p q) x(x y))) //写出1的λ表达式

    ​ => (λx.λy.((λq. x q)(x y))

    ​ => (λx.λy.x(x y))=2 //按定义

    (2) α 换名 归约中如发生改变束定性质,则允许换名(λ后跟的变量名),以保证原有束定关系。例如:

    ​ (λx. (λy.x)) (z y) //(z y)中y是自由变量

    ​ => λy.(z y) //此时(z y)中y被束定了,错误!

    ​ => (λx.(λw.x))(z y) //因(λy.x)中函数体无y,可换名

    ​ => λw.(z y) // 正确!

    (3) η 归约 是消除一层约束的归约,形如λx.F x的表达式若x在F中不自由出现,则:

    λx.F x => F

    它的逆是任何一个F都可以加一套λx( )x,只要x在F中不自由出现。

    显然,λx.f(x) => f 是β归约的特例。

    优先级 【难点】

    注意规约中的优先级比较混乱,其实按照λ演算的运算规则,谁先归约最后归约其结果是一样的。(Church-Rosser定理)每次归约只要找到可归约的子公式(λ应用表达式,即一个是λ函数表达式,一个是变元)即可归约,λ演算没有规定顺序。

    比如

    	λx.λy.x y a b 
    
    =  λx.(λy.x y) a b //库里化的定义
    
    =(λy.a y) b //合并前三项
    =a b//去掉括号,括号可以任意添加,然后合并前三项
    

    空格是可以无视的,主要看括号。那些基本范式的参数后面的body是默认加括号的,比如zerop = λn.n(λx.F)T 其实应该是λn.(n(λx.F)T)

    其实括号也是随意的 以下表达式有相同的语义:

    (fa),f(a),(f)a,(f)(a),((f)(a))

    比如

    λa.λb.((1 a) (1 a) b)
    = λa.λb.((1 a) 1 a b )
    = λa.λb.((1 a) λx. λy. x y a b)
    = λa.λb.((1 a) (a b))
    = λa.λb.(( λx. λy. x y a) (a b))
    = λa.λb.( λx. λy. x y a (a b))//去括号
    = 2
    

    不过2的范式里确实是有括号的,这一点很迷

    规约的语义

    对应用表达式符号归约时,当施行(除α规则外)所有变换规则后没有新形式出现,则这种λ表达式叫范式。(并非所有λ表达式均可归约为范式。前述(λx.x x)(λx.x x)为不可归约的。)范式即λ演算的语义解释,归约后形如λx.F它就是函数,形如x x,(y (λx.z))就只能解释为数据了,只可以把它放在另一个应用中作变元进一步归约。

    一些规则

    有以下规则:

    [1]若x不在M中自由出现,结果为M;

    [2]若M = x,结果为N;

    [3]若M = λy.k, x≠y,y不在N中自由出现,结果为λy.[N/x,k];

    [4]若M = λy.k, x≠y,y在N中自由出现,结果为λz.[N/x,[z/y,k]],z≠x≠y且不在M,N


    1. 我的最爱Lambda演算——开篇 · cgnail's weblog ↩︎

    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    【目录】processing
    【目录】Qt
    【目录】python
    【目录】linux
    【目录】多线程
    【目录】Leetcode
    【leetcode】Restore IP Addresses (middle)
    linux c编程訪问数据库
    『Spring.NET+NHibernate+泛型』框架搭建之Model(二)
    hdu1316(大数的斐波那契数)
  • 原文地址:https://www.cnblogs.com/SuuT/p/15720873.html
Copyright © 2011-2022 走看看