• PLAI笔记


    01 AE

    AE : Concrete syntax

    <AE> ::= <num>
           | {+ <AE> <AE>}
           | {- <AE> <AE>}
    

    AE : Abstract syntax

    (define-type AE
      [num (n number?)]
      [add (lhs AE?)
           (rhs AE?)]
      [sub (lhs AE?)
           (rhs AE?)])
    

    parse : sexp -> AE

    (define (parse sexp)
      (cond 
        [(number? sexp) (num sexp)] 
        [(list? sexp) 
         (case (first sexp) 
           [(+) (add (parse (second sexp)) 
                     (parse (third sexp)))] 
           [(-) (sub (parse (second sexp)) 
                     (parse (third sexp)))])]))
    
    (define (parse sexp)
      (cond 
        [(number? sexp) (num sexp)] 
        [(and (= 3 (length sexp)) 
              (eq? (first sexp) ’+)) 
         (add (parse (second sexp))
              (parse (third sexp)))] 
        [(and (= 3 (length sexp)) 
              (eq? (first sexp) ’-)) 
         (sub (parse (second sexp))
              (parse (third sexp)))] 
        [else (error ’parse "bad syntax: ~a" sexp)]))
    
    (define (parse sexp)
      (cond
        [(number? sexp) (num sexp)]
        [(and (= 3 (length sexp)) (eq? (first sexp) '+))
         (add (parse (second sexp)) (parse (third sexp)))]
        [(and (= 3 (length sexp)) (eq? (first sexp) '-))
         (sub (parse (second sexp)) (parse (third sexp)))]
        [else (error 'parse "bad syntax: ~a" sexp)]))
    
    (define (parse sexp)
      (match sexp
        [(? number?) (num sexp)]
        [(list '+ l r) (add (parse l) (parse r))]
        [(list '- l r) (sub (parse l) (parse r))]
        [else (error 'parse "bad syntax: ~a" sexp)]))
    

    interp : AE -> number

    (define (interp ae)
      (type-case AE ae
        [num (n) n]
        [add (l r) (+ (interp l) (interp r))]
        [sub (l r) (- (interp l) (interp r))]))
    

    02 WAE

    WAE : Concrete syntax

    <WAE> ::= <num>
            | {+ <WAE> <WAE>}
            | {- <WAE> <WAE>}
            | {with {<id> <WAE>} <WAE>}
            | <id>
    

    WAE : Abstract syntax

    (define-type WAE
      [num (n number?)]
      [add (lhs WAE?) (rhs WAE?)]
      [sub (lhs WAE?) (rhs WAE?)]
      [with (name symbol?) (named-expr WAE?) (body WAE?)]
      [id (name symbol?)])
    

    parse : sexp -> WAE

    (define (parse sexp)
      (match sexp
        [(? number?)                (num sexp)]
        [(list '+ l r)              (add (parse l) (parse r))]
        [(list '- l r)              (sub (parse l) (parse r))]
        [(list ’with (list x i) b)  (with x (parse i) (parse b))] 
        [(? symbol?)                (id sexp)]
        [else (error 'parse "bad syntax: ~a" sexp)]))
    

    subst : WAE symbol number -> WAE

    (define (subst wae x val)
      (type-case WAE wae
        [num (n)       wae]
        [add (l r)    (add (subst l x val) (subst r x val))]
        [sub (l r)    (sub (subst l x val) (subst r x val))]
        [with (y i b) (with y
                            (subst i x val)
                            (if (symbol=? y x) b (subst b x val)))]
        [id (s)       (if (symbol=? s x) (num val) wae)])))
    

    interp : WAE -> number

    (define (interp wae)
      (type-case WAE wae
        [num (n)       n]
        [add (l r)     (+ (interp l) (interp r))]
        [sub (l r)     (- (interp l) (interp r))]
        [with (x i b)  (interp (subst b x (interp i)))]
        [id (s)        (error 'interp "free variable")]))
    

    03 F1WAE

    F1WAE : Concrete syntax

    <FunDef> ::= {deffun {<id> <id>} <F1WAE>}
    
    <F1WAE> ::= <num>
              | {+ <F1WAE> <F1WAE>}
              | {- <F1WAE> <F1WAE>}
              | {with {<id> <F1WAE>} <F1WAE>}
              | <id>
              | {<id> <F1WAE>}
    

    F1WAE : Abstrac syntax

    Fundef定义function。
    在interp过程中,Fundef以list-of-Fundef的形态传递到env。
    
    (define-type FunDef
      [fundef (fun-name symbol?)
              (arg-name symbol?)
              (body F1WAE?)])
    
    (define-type F1WAE
      [num (n number?)]
      [add (lhs F1WAE?) (rhs F1WAE?)]
      [sub (lhs F1WAE?) (rhs F1WAE?)]
      [with (name symbol?) (named-expr F1WAE?) (body F1WAE?)]
      [id (name symbol?)]
      [app (ftn symbol?) (arg F1WAE?)])
    

    parse-fd : sexp -> FunDef

    (define (parse-fd sexp)
      (match sexp
        [(list 'deffun (list f x) b) (fundef f x (parse b))]))
    

    parse : sexp -> F1WAE

    (define (parse sexp)
      (match sexp
        [(? number?)                (num sexp)]
        [(list '+ l r)              (add (parse l) (parse r))]
        [(list '- l r)              (sub (parse l) (parse r))]
        [(list 'with (list x i) b)  (with x (parse i) (parse b))]
        [(? symbol?)                (id sexp)]
        [(list f a)                 (app f (parse a))]
        [else (error 'parse "bad syntax: ~a" sexp)]))
    

    interp : F1WAE list-of-FunDef -> number

    (define (interp f1wae fundefs)
      (type-case F1WAE f1wae
        [num (n)      n]
        [add (l r)    (+ (interp l fundefs) (interp r fundefs))]
        [sub (l r)    (- (interp l fundefs) (interp r fundefs))]
        [with (x i b) (interp (subst b x (interp i fundefs))
                              fundefs)]
        [id (s)       (error 'interp "free variable")]
        [app (f a)    (local [(define a-fundef (lookup-fundef f fundefs))]
                         (interp (subst (fundef-body a-fundef)
                                        (fundef-arg-name a-fundef)
                                        (interp a fundefs))
                                 fundefs))]))
    

    subst : F1WAE symbol number -> F1WAE

    (define (subst f1wae x val)
      (type-case F1WAE f1wae
        [num (n)      f1wae]
        [add (l r)    (add (subst l x val) (subst r x val))]
        [sub (l r)    (sub (subst l x val) (subst r x val))]
        [with (y i b) (with y
                            (subst i x val)
                            (if (symbol=? y x) b
                                (subst b x val)))]
        [id (s)       (if (symbol=? s x) (num val) f1wae)]
        [app (f a)    (app f (subst a x val))]))
    

    lookup-fundef : symbol list-of-FunDef -> FunDef

    (define (lookup-fundef name fundefs)
      (cond
        [(empty? fundefs) (error 'lookup-fundef "unknown function")]
        [else (if (symbol=? name (fundef-fun-name (first fundefs)))
                  (first fundefs)
                  (lookup-fundef name (rest fundefs)))]))
    

    Examples

    {deffun {identity x} x}
    {identity 8}
    
    {deffun {twice x} {+ x x}}
    {twice 10}
    {twice 17}
    

    04 Deferred Substitution

    Deferred Substitution

    在执行出现with时,利用“substitution”,每次with的出现,它都绕着整个body置换。这一方式是由F1WAE到env再到list-of-FunDef为止,然后再到substitution列表中,以env的形式进行。

    In Case of WAE

    DefrdSub

    (define-type DefrdSub
      [mtSub]
      [aSub (name symbol?)
            (value number?)
            (rest DefrdSub?)])
    

    lookup : symbol DefrdSub -> number

    (define (lookup name ds)
      (type-case DefrdSub ds
        [mtSub () (error 'lookup "free variable")]
        [aSub (x val rest) (if (symbol=? x name)
                               val
                               (lookup name rest))]))
    

    interp : WAE -> number 换成 WAE DefrdSub -> number

    (define (interp wae ds)
      (type-case WAE wae
        [num (n) n]
        [add (l r) (+ (interp l ds) (interp r ds))]
        [sub (l r) (- (interp l ds) (interp r ds))]
        [with (x i b) (interp b (aSub x (interp i ds) ds))]
        [id (s) (lookup s ds)]))
    

    In Case of F1WAE

    不经思考,会造成如下后果:

    {deffun {f x} {+ y x}}
    (interp (parse '{with {y 2} {f 10}})), env:[]
    ->(interp (parse '{f 10})), env:[y=2]
    ->(interp (parse '{+ y x})), env:[x=10 y=2]
    ->12 wrong!
    更准确地说,这是static scope不适合的体现。
    

    interp : F1WAE list-of-FunDef DefrdSub -> number

    (define (interp f1wae fundefs ds)
      (type-case F1WAE f1wae
        ...
        [app (ftn arg)
             (local [(define a-fundef (lookup-fundef ftn fundefs))])
                (interp (fundef-body a-fundef)
                        fundefs
                        (aSub (fundef-arg-name a-fundef)
                              (interp arg fundefs ds)
                              (mtSub)))]))
    在进行“function call”时,将DefrdSub重新装入env,使其成为“arg substitution”。(local设计)
    

    05 FWAE

    FWAE : Concrete syntax

    <FWAE> ::= <num>
             | {+ <FWAE> <FWAE>}
             | {- <FWAE> <FWAE>}
             | {with {<id> <FWAE>} <FWAE>}
             | <id>
             | {fun {<id>} <FWAE>}
             | {<FWAE> <FWAE>}
    

    FWAE : Abstract syntax

    其中的“function definition”和“function call”在language structure内以lambda函数形式包含在其中,所以不需要像F1WAE那样的FunDef。
    (define-type FWAE
      [num (n number?)]
      [add (lhs FWAE?) (rhs FWAE?)]
      [sub (lhs FWAE?) (rhs FWAE?)]
      [with (name symbol?) (named-expr FWAE?) (body FWAE?)]
      [id (name symbol?)]
      [fun (param symbol?) (body FWAE?)]
      [app (ftn FWAE?) (arg FWAE?)])
    
    (fun x (add 1 x))等lambda函数形态本身就是with-namd-expr的FWAE∼ae类型,那么在with-body中,与with-name一致的相应id被调换到fun,并进入app的ftn之中。

    parse : sexp -> FWAE

    (define (parse sexp)
      (match sexp
        [(? number?) (num sexp)]
        [(list '+ l r) (add (parse l) (parse r))]
        [(list '- l r) (sub (parse l) (parse r))]
        [(list 'with (list x i) b) (with x (parse i) (parse b))]
        [(? symbol?) (id sexp)]
        [(list 'fun (list x) b) (fun x (parse b))]
        [(list f a) (app (parse f) (parse a))]
        [else (error 'parse "bad syntax :~a" sexp)]))
    

    interp : FWAE -> FWAE

    因为最终的结果是FWAE,所以add和sub的结果会使num重新加入。
    (define (num+ x y)
      (num (+ (num-n x) (num-n y))))
    (define (num- x y)
      (num (- (num-n x) (num-n y))))
      
    (define (interp fwae)
      (type-case FWAE fwae
        [num (n) fwae]
        [add (l r) (num+ (interp l) (interp r))]
        [sub (l r) (num- (interp l) (interp r))]
        [with (x i b) (interp (subst b x (interp i)))]
        [id (s) (error 'interp "free variable")]
        [fun (x b) fwae]
        [app (f a) (local [(define ftn (interp f))]
                      (interp (subst (fun-body ftn)
                                     (fun-param ftn)
                                     (interp a))))]))
    
    app中将ftn作为local define,如果f是未定义的函数,那么将出现free variable error,如果f是已经定义的函数,那么就是fun的形态,所以ftn具有fun的structure。

    subst : FWAE symbol FWAE -> FWAE

    (define (subst exp sub-id val)
      (type-case FWAE exp
        [num (n) exp]
        [add (l r) (add (subst l sub-id val) (subst r sub-id val))]
        [sub (l r) (sub (subst l sub-id val) (subst r sub-id val))]
        [with (x i b) (with x
                            (subst i sub-id val)
                            (if (symbol=? sub-id x)
                                b
                                (subst b sub-id val)))]
        [id (name) (cond [(equal? name sub-id) val]
                         [else exp])]
        [app (f arg) (app (subst f sub-id val)
                          (subst arg sub-id val))]
        [fun (id body) (if (equal? sub-id id)
                           exp
                           (fun id (subst body sub-id val)))]))
    

    Examples

    F1WAE : first-order functions
    {deffun {f x} {+ 1 x}}
    {f 10}
    
    FWAE : first-class functions
    {with {f {fun {x} {+ 1 x}}} {f 10}}
    

    06 FAE

    没有了with表达,with,exp,body的id换成exp的lambda函数,从而可以没有with来进行实现。即,{with {id exp} body}换成了{{fun {id} body} exp}。

    FAE : Concrete syntax

    <FWAE> ::= <num>
             | {+ <FWAE> <FWAE>}
             | {- <FWAE> <FWAE>}
             | <id>
             | {fun {<id>} <FWAE>}
             | {<FWAE> <FWAE>}
    

    FAE : Abstrac syntax

    (define-type FAE
      [num (n number?)]
      [add (lhs FAE?) (rhs FAE?)]
      [sub (lhs FAE?) (rhs FAE?)]
      [id (name symbol?)]
      [fun (param symbol?) (body FAE?)]
      [app (ftn FAE?) (arg FAE?)])
    

    parse : sexp -> FAE

    (define (parse sexp)
      (match sexp
        [(? number?) (num sexp)]
        [(list '+ l r) (add (parse l) (parse r))]
        [(list '- l r) (sub (parse l) (parse r))]
        [(? symbol?) (id sexp)]
        [(list 'fun (list x) b) (fun x (parse b))]
        [(list f a) (app (parse f) (parse a))]
        [else (error 'parse "bad syntax: ~a" sexp)]))
    

    interp : FAE -> 'FAE'

    (define (num+ x y)
      (num (+ (num-n x) (num-n y))))
    (define (num- x y)
      (num (- (num-n x) (num-n y))))
    
    (define (interp fae)
      (type-case FAE fae
        [num (n) fae]
        [add (l r) (num+ (interp l) (interp r))]
        [sub (l r) (num- (interp l) (interp r))]
        [id (s) (error 'interp "free variable")]
        [fun (x b) fae]
        [app (f a) (local [(define ftn (interp f))]
                      (interp (subst (fun-body ftn)
                                     (fun-param ftn)
                                     (interp a))))]))
    

    subst : 'FAE' 'symbol' 'FAE' -> 'FAE'

    (define (subst exp sub-id val)
      (type-case FAE exp
        [num (n) exp]
        [add (l r) (add (subst l sub-id val) (subst r sub-id val))]
        [sub (l r) (sub (subst l sub-id val) (subst r sub-id val))]
        [id (name) (cond [(equal? name sub-id) val]
                         [else exp])]
        [app (f arg) (app (subst f sub-id val)
                          (subst arg sub-id val))]
        [fun (id body) (if (equal? sub-id id)
                           exp
                           (fun id (subst body sub-id val)))]))
    

    07 FAE with Deferred Substitution

    FAE-parse : 一成不变

    FAE-Value : interp的最终转让值

    numV: value
    closureV: param-FAE(或value,或function) pair list
    (define-type FAE-Value
      [numV (n number?)]
      [closureV (param symbol?) (body FAE?) (ds DefrdSub?)])
    

    DefrdSub : 传达environment

    以前WAE中使用的DefrdSub只用于with,但是在这里with的置换和function call这两种作用是同时进行的。所以在FAE-Value上有numV和closureV两种组合。
    (define-type DefrdSub
      [mtSub]
      [aSub (name symbol?) (value FAE-Value?) (ds DefrdSub?)])
    

    lookup : symbol DefrdSub -> FAE-Value

    (define (lookup name ds)
      (type-case DefrdSub ds
        [mtSub () (error 'lookup "free variable")]
        [aSub (x val rest) (if (symbol=? x name)
                               val
                               (lookup name rest))]))
    

    interp : FAE - >FAE 修改为 FAE DefrdSub -> FAE-Value

    如果interp f ds中有f存在于ds中,在id (s)的lookup s ds中,closureV重新出现,那么f-val中的closureV a-val将成为numV。
    app中aSub为什么不是mtsub ?F1WAE with deferred substitution中是mtSub的理由是static scope。这里是由ds决定lambda函数的scope。这时的ds不是叫app时的ds,而是相当于function被定义时scope的ds。
    (define (interp fae ds)
      (type-case FAE fae
        [num (n) (numV n)]
        [add (l r) (num+ (interp l ds) (interp r ds))]
        [sub (l r) (num- (interp l ds) (interp r ds))]
        [id (s) (lookup s ds)]
        [fun (x b) (closureV x b ds)]
        [app (f a) (local [(define f-val (interp f ds))
                           (define a-val (interp a ds))]
                      (interp (closureV-body f-val)
                              (aSub (closureV-param f-val)
                                    a-val
                                    (closureV-ds f-val))))]))
    
    如果(closureV-ds - f-val)中加入ds,就会成为dynamic scope。
  • 相关阅读:
    pip install
    自动更新高清电影文件中文名
    csv、excel导入oracle
    02_Jenkins配置任务
    01_Jenkins windows安装
    run_jmeter.py
    02_禅道的基本使用
    01_禅道搭建手册
    01_charles 下载安装(破解版)
    06_Linux常见的命令
  • 原文地址:https://www.cnblogs.com/nightyk/p/12869306.html
Copyright © 2020-2023  润新知