Я работаю в проекте НЛП с ракеткой.Как использовать трассировку в этом коде 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 узнавать-дальше). Я поставил его перед самым окончательным определением. Не уверен, что это подходящее место.
спасибо! Он работал нормально. Есть еще одна вещь, которую я не могу понять. Поскольку kim определяется моим сокращением, почему вызов (признавать английский-1 '(kim)) возвращает empty'()? –
@fallowzito Я признаю, что понятия не имею, я на самом деле не читал ни одного вашего кода, а только части, связанные с 'racket/trace'. ;) Я уверен, что вы можете понять это: я бы попытался сыграть с вашими функциями в REPL, чтобы выяснить, где они идут не так. Вы также можете взглянуть на пакет 'debug', который предоставляет некоторые полезные формы для отладки программ. –