2016-10-25 9 views
0

Я работаю в проекте НЛП с ракеткой.Как использовать трассировку в этом коде Racket?

Этот код работает нормально. Однако, я бы хотел проследить его.

У меня возникли проблемы с отслеживанием поведения функции 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)) 

Трассировка прекрасно работает и у меня есть ожидаемый результат:

>(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 

Однако при попытке проследить что-то что это не в сети, трассировка имеет странное поведение. Например, когда я звоню:

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

Вывод is '(), который является правильным. Но я ожидал более подробной информации, чем:

'() 

Я был в значительной степени сомневаюсь в том, где поставить команду (trace узнавать-дальше). Я поставил его перед самым окончательным определением. Не уверен, что это подходящее место.

ответ

0

Форма trace изменяет привязку для вставки трассировки, но обычно это не то, что вы хотите использовать напрямую. Вместо этого обычно проще использовать trace-define, trace-lambda, или trace-let. Удалите непосредственное использование (trace recognize-next), и заменить определение recognize-next с одним, который использует trace-define:

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

Это должно сделать следы работать как задумано.

+0

спасибо! Он работал нормально. Есть еще одна вещь, которую я не могу понять. Поскольку kim определяется моим сокращением, почему вызов (признавать английский-1 '(kim)) возвращает empty'()? –

+0

@fallowzito Я признаю, что понятия не имею, я на самом деле не читал ни одного вашего кода, а только части, связанные с 'racket/trace'. ;) Я уверен, что вы можете понять это: я бы попытался сыграть с вашими функциями в REPL, чтобы выяснить, где они идут не так. Вы также можете взглянуть на пакет 'debug', который предоставляет некоторые полезные формы для отладки программ. –