【问题标题】:How to use trace in this Racket code?如何在这个 Racket 代码中使用跟踪?
【发布时间】:2016-10-25 17:01:17
【问题描述】:

我正在使用 Racket 从事 NLP 项目。

此代码运行良好。不过,我希望我能追踪到它。

我无法跟踪 generate-next 函数的行为。

这是我的代码:

#lang racket

(require racket/trace)

(require rackunit)

(define english-1
  '((Initial (1))
    (Final (9))
    (From 1 to 1 by NP)
    (From 1 to 2 by DET)
    (From 1 to 3 by NP)
    (From 2 to 3 by N)
    (From 3 to 4 by BV)
    (From 4 to 5 by ADV)
    (From 4 to 5 by |#|)
    (From 5 to 6 by DET)
    (From 5 to 7 by DET)
    (From 5 to 8 by |#|)
    (From 6 to 7 by ADJ)    
    (From 6 to 6 by MOD)
    (From 7 to 9 by N)
    (From 8 to 8 by MOD)
    (From 8 to 9 by ADJ)
    (From 9 to 4 by CNJ)
    (From 9 to 1 by CNJ)
    (From 9 to 2 by CNJ)
    (From 9 to 3 by CNJ)
    (From 9 to 6 by CNJ)))

(define (getf x y)
  (if (eq? (car x) y)
      (cadr x)
      (getf (cdr x) y)))

(define (initial-nodes network)
  (list-ref (assoc 'Initial network) 1))

(define (final-nodes network)
  (list-ref  (assoc 'Final network) 1))

(define (transitions network)
  (filter (lambda (x) (eq? (car x) 'From)) network))

(define (trans-node transition)
  (getf transition 'From))

(define(trans-newnode transition)
  (getf transition 'to))

(define (trans-label transition)
  (getf transition 'by))

(define abbreviations
  '((NP kim sandy lee)
    (DET a the her)
    (N consumer man woman)
    (BV is was)
    (CNJ and or)
    (ADJ happy stupid)
    (MOD very)
  (ADV often always sometimes)))

(define (recognize network tape)
  ;; returns t if sucessfully recognizes tape - nil otherwise
  (call/cc (lambda (return)
             (define (recognize-next node tape network)
               (if (null? tape)
                   (if (member node (final-nodes network))
                       (return #t)
                       (return '())); success
                   (for ([transition (transitions network)])
                           ;; try each transition of the network
                           (when (equal? node (trans-node transition)) ; if it starts at the right node
                               (for ([newtape (recognize-move (trans-label transition) tape)])
                                       ;; try each possible new value of tape
                                 (recognize-next (trans-newnode transition) newtape network)))))(trace recognize-next))
             (for ([initialnode (initial-nodes network)])
               (recognize-next initialnode tape network))
             null))) ; failed to recognize

(define (recognize-move label tape)
  (if (or (eq? label (car tape))
          (member (car tape) (or (assoc label abbreviations) '())))
      (list (cdr tape))
      (if (eq? label '|#|)
          (list tape)
          null)))

当我打电话时:

(recognize english-1 '(sandy is a happy woman))

Trace 工作正常,我得到了预期的输出:

>(recognize-next
  3
  '(is a happy woman)
  '((Initial (1))
    (Final (9))
    (From 1 to 1 by NP)
    (From 1 to 2 by DET)
    (From 1 to 3 by NP)
    (From 2 to 3 by N)
    (From 3 to 4 by BV)
    (From 4 to 5 by ADV)
    (From 4 to 5 by |#|)
    (From 5 to 6 by DET)
    (From 5 to 7 by DET)
    (From 5 to 8 by |#|)
    (From 6 to 7 by ADJ)
    (From 6 to 6 by MOD)
    (From 7 to 9 by N)
    (From 8 to 8 by MOD)
    (From 8 to 9 by ADJ)
    (From 9 to 4 by CNJ)
    (From 9 to 1 by CNJ)
    (From 9 to 2 by CNJ)
    (From 9 to 3 by CNJ)
    (From 9 to 6 by CNJ)))
> (recognize-next
   4
   '(a happy woman)
   '((Initial (1))
     (Final (9))
     (From 1 to 1 by NP)
     (From 1 to 2 by DET)
     (From 1 to 3 by NP)
     (From 2 to 3 by N)
     (From 3 to 4 by BV)
     (From 4 to 5 by ADV)
     (From 4 to 5 by |#|)
     (From 5 to 6 by DET)
     (From 5 to 7 by DET)
     (From 5 to 8 by |#|)
     (From 6 to 7 by ADJ)
     (From 6 to 6 by MOD)
     (From 7 to 9 by N)
     (From 8 to 8 by MOD)
     (From 8 to 9 by ADJ)
     (From 9 to 4 by CNJ)
     (From 9 to 1 by CNJ)
     (From 9 to 2 by CNJ)
     (From 9 to 3 by CNJ)
     (From 9 to 6 by CNJ)))
> >(recognize-next
    5
    '(a happy woman)
    '((Initial (1))
      (Final (9))
      (From 1 to 1 by NP)
      (From 1 to 2 by DET)
      (From 1 to 3 by NP)
      (From 2 to 3 by N)
      (From 3 to 4 by BV)
      (From 4 to 5 by ADV)
      (From 4 to 5 by |#|)
      (From 5 to 6 by DET)
      (From 5 to 7 by DET)
      (From 5 to 8 by |#|)
      (From 6 to 7 by ADJ)
      (From 6 to 6 by MOD)
      (From 7 to 9 by N)
      (From 8 to 8 by MOD)
      (From 8 to 9 by ADJ)
      (From 9 to 4 by CNJ)
      (From 9 to 1 by CNJ)
      (From 9 to 2 by CNJ)
      (From 9 to 3 by CNJ)
      (From 9 to 6 by CNJ)))
> > (recognize-next
     6
     '(happy woman)
     '((Initial (1))
       (Final (9))
       (From 1 to 1 by NP)
       (From 1 to 2 by DET)
       (From 1 to 3 by NP)
       (From 2 to 3 by N)
       (From 3 to 4 by BV)
       (From 4 to 5 by ADV)
       (From 4 to 5 by |#|)
       (From 5 to 6 by DET)
       (From 5 to 7 by DET)
       (From 5 to 8 by |#|)
       (From 6 to 7 by ADJ)
       (From 6 to 6 by MOD)
       (From 7 to 9 by N)
       (From 8 to 8 by MOD)
       (From 8 to 9 by ADJ)
       (From 9 to 4 by CNJ)
       (From 9 to 1 by CNJ)
       (From 9 to 2 by CNJ)
       (From 9 to 3 by CNJ)
       (From 9 to 6 by CNJ)))
> > >(recognize-next
      7
      '(woman)
      '((Initial (1))
        (Final (9))
        (From 1 to 1 by NP)
        (From 1 to 2 by DET)
        (From 1 to 3 by NP)
        (From 2 to 3 by N)
        (From 3 to 4 by BV)
        (From 4 to 5 by ADV)
        (From 4 to 5 by |#|)
        (From 5 to 6 by DET)
        (From 5 to 7 by DET)
        (From 5 to 8 by |#|)
        (From 6 to 7 by ADJ)
        (From 6 to 6 by MOD)
        (From 7 to 9 by N)
        (From 8 to 8 by MOD)
        (From 8 to 9 by ADJ)
        (From 9 to 4 by CNJ)
        (From 9 to 1 by CNJ)
        (From 9 to 2 by CNJ)
        (From 9 to 3 by CNJ)
        (From 9 to 6 by CNJ)))
> > > (recognize-next
       9
       '()
       '((Initial (1))
         (Final (9))
         (From 1 to 1 by NP)
         (From 1 to 2 by DET)
         (From 1 to 3 by NP)
         (From 2 to 3 by N)
         (From 3 to 4 by BV)
         (From 4 to 5 by ADV)
         (From 4 to 5 by |#|)
         (From 5 to 6 by DET)
         (From 5 to 7 by DET)
         (From 5 to 8 by |#|)
         (From 6 to 7 by ADJ)
         (From 6 to 6 by MOD)
         (From 7 to 9 by N)
         (From 8 to 8 by MOD)
         (From 8 to 9 by ADJ)
         (From 9 to 4 by CNJ)
         (From 9 to 1 by CNJ)
         (From 9 to 2 by CNJ)
         (From 9 to 3 by CNJ)
         (From 9 to 6 by CNJ)))
#t

然而,当试图追踪不在网络上的东西时,trace 有一个奇怪的行为。例如,当我打电话时:

(recognize english-1 '(not defined on the network))

输出是正确的'()。但我希望得到比以下更详细的信息:

'()

我非常怀疑将命令放在哪里(跟踪识别下一个)。我把它放在识别下一个定义结束之前。不确定这是否合适。

【问题讨论】:

    标签: nlp lisp racket trace


    【解决方案1】:

    trace 表单会修改绑定本身以插入跟踪,但通常您不想直接使用它。相反,使用trace-definetrace-lambdatrace-let 通常更容易。删除您对(trace recognize-next) 的直接使用,并将您对recognize-next 的定义替换为使用trace-define 的定义:

    (trace-define (recognize-next node tape network)
      ...)
    

    这应该使跟踪按预期工作。

    【讨论】:

    • 谢谢!它工作得很好。还有一件事我无法理解。既然 kim 在我的缩写定义中,为什么调用 (recognize english-1 '(kim)) 返回空 '()?
    • @fallowzito 我承认我不知道——我实际上并没有读过你的任何代码,只是与racket/trace 相关的部分。 ;) 不过,我相信你可以弄清楚:我会尝试在 REPL 中使用你的函数来找出它们哪里出错了。你也可以看看debug 包,它提供了一些有用的表格来帮助调试程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多