无聊的日记

昨日阅读和翻译Pfenning的构造性逻辑讲义弄得头昏脑胀, 不仅是因为其言辞精妙深微, 更是因为反复出现的各种自然演绎的图形让我手忙脚乱. 最后我实在忍无可忍, 决心设计和实现一个DSL用于绘制自然演绎. 这个(E)DSL基于Curry-Howard对应, 所以也可以算是一个proof checker. 不过, 它不能绘制原文那些中间步骤 (实际上或许也可以, 但是我有意没有实现), 只是绘制最终的完整的自然演绎图形. 

(define (type-of var env)

  (cond ((assoc var env) => cdr)

        (else (error 'type-of "unknown variable ~s" var))))

(define (extend-env var type env)

  (cons (cons var type) env))

(define (reify t)

  (define (reify t)

    (match t

      ((-> ,t1 ,t2) (&impl (@reify t1) (@reify t2)))

      ((conj ,t1 ,t2) (&conj (@reify t1) (@reify t2)))

      ((disj ,t1 ,t2) (&disj (@reify t1) (@reify t2)))

      (bot $bottom)

      (top $top)

      (,else t)))

  (define (@reify t)

    (match t

      ((-> ,t1 ,t2) (@impl (@reify t1) (@reify t2)))

      ((conj ,t1 ,t2) (@conj (@reify t1) (@reify t2)))

      ((disj ,t1 ,t2) (@disj (@reify t1) (@reify t2)))

      (bot $bottom)

      (top $top)

      (,else t)))

  (reify t))

(struct result (t c) #:transparent)

(define (VAR u)

  (lambda (env)

    (define t (type-of u env))

    (result t (assume u (&true (reify t))))))

(define (GIVEN l t)

  (lambda (env)

    (result t (label l (&true (reify t))))))

(define (CONS a b)

  (lambda (env)

    (match-define (result ta ca) (a env))

    (match-define (result tb cb) (b env))

    (define type `(conj ,ta ,tb))

    (result type

            (&rull $conjI ca cb

                   (&true (reify type))))))

(define (CAR a)

  (lambda (env)

    (match-define (result ta ca) (a env))

    (match ta

      ((conj ,t1 ,t2)

       (result t1 (&rull $conjE1 ca

                         (&true (reify t1))))))))

(define (CDR a)

  (lambda (env)

    (match-define (result ta ca) (a env))

    (match ta

      ((conj ,t1 ,t2)

       (result t2 (&rull $conjE2 ca

                         (&true (reify t2))))))))

(define (LAM u t body)

  (lambda (env)

    (match-define (result tbody cbody)

      (body (extend-env u t env)))

    (define type `(-> ,t ,tbody))

    (result type

            (&rull (&implI u) cbody

                   (&true (reify type))))))

(define (APP a b)

  (lambda (env)

    (match-define (result ta ca) (a env))

    (match-define (result tb cb) (b env))

    (match ta

      ((-> ,t1 ,t2)

       (unless (equal? t1 tb)

         (error 'APP "type mismatch"))

       (result t2 (&rull $implE ca cb

                         (&true (reify t2))))))))

(define (INL tb a)

  (lambda (env)

    (match-define (result ta ca) (a env))

    (define type `(disj ,ta ,tb))

    (result type (&rull $disjI1 ca

                        (&true (reify type))))))

(define (INR ta b)

  (lambda (env)

    (match-define (result tb cb) (b env))

    (define type `(disj ,ta ,tb))

    (result type (&rull $disjI2 cb

                        (&true (reify type))))))

(define (CASE a u1 b1 u2 b2)

  (lambda (env)

    (match-define (result ta ca) (a env))

    (match ta

      ((disj ,t1 ,t2)

       (match-define (result tb1 cb1)

         (b1 (extend-env u1 t1 env)))

       (match-define (result tb2 cb2)

         (b2 (extend-env u2 t2 env)))

       (unless (equal? tb1 tb2)

         (error 'CASE "branch type mismatch"))

       (result tb1 (&rull (&disjE u1 u2) ca cb1 cb2

                          (&true (reify tb1))))))))

(define (ND proof)

  (result-c (proof '())))

当然这里我有意省略了所有并不直接算是这个DSL的实现的次要代码, 那些代码实际上都是用于绘制自然演绎的定义.

以下是一些来源于讲义或是个人随手而写的图形.

你的回應