Странный EVAL: неопределенная ошибка функции T в Common LISP

Я пишу функцию на Common Lisp, но получаю ошибку, упомянутую в заголовке.

(defun sample (graph-id vertices)
    (cond
        ((null vertices) nil)
        (t 
            (and
                (setf 
                    (gethash (list graph-id (first vertices)) *keys*)
                    MOST-POSITIVE-DOUBLE-FLOAT)
                (sample graph-id (rest vertices))))))

В частности, когда компилятор достигает строки (gethash (list graph-id (first vertices)) *vertex-keys*), если я поменяю местами graph-id (first vertices) с (first vertices) graph-id, ошибка исчезнет. Также исчезает, если я использую second, third или любые другие функции nth вместо first, я не могу понять, почему это происходит. vertices — это список, подобный (A B C D E F)


person giovannibrumana    schedule 27.12.2020    source источник
comment
Я вызываю это как (sample 0 '(A B C D E F)) с *keys*, определенным как пустая хеш-таблица, и я не получаю ошибок в CLISP или SBCL. Как вы это называете и каково значение соответствующей глобальной переменной?   -  person Silvio Mayolo    schedule 27.12.2020
comment
@SilvioMayolo спасибо за ответ. Я вызываю функцию с (sample id '(A B C D E F)), где id равно 'grafo. Я полагаю, что MOST-POSITIVE-DOUBLE-FLOAT — это константа, определенная в Лиспе, как здесь сказано ссылка   -  person giovannibrumana    schedule 27.12.2020
comment
Хм ... к сожалению, похоже, что должен быть какой-то другой фрагмент кода, который возится с вашей средой, поскольку я все еще не могу воспроизвести вашу ошибку с этими точными входными данными. Попробуйте запустить это в чистой среде без предшествующего кода.   -  person Silvio Mayolo    schedule 27.12.2020
comment
Я тоже не могу воспроизвести ошибку. Сообщение об ошибке, по-видимому, вызвано проблемами со скобками вокруг ветки cond (например, чем-то вроде ((t ...)   -  person Renzo    schedule 27.12.2020
comment
Такое ощущение, что ошибка где-то еще в моем коде, но все равно спасибо за помощь!   -  person giovannibrumana    schedule 27.12.2020
comment
почему бы просто не использовать DOLIST вместо сложной рекурсивной функции?   -  person Rainer Joswig    schedule 27.12.2020
comment
@RainerJoswig Я разрабатываю этот проект для курсовой работы и не могу использовать многие функции (включая эту)   -  person giovannibrumana    schedule 27.12.2020
comment
что делает И?   -  person Rainer Joswig    schedule 28.12.2020
comment
Я использую его как способ выполнения обеих инструкций (setf и sample).   -  person giovannibrumana    schedule 29.12.2020


Ответы (1)


Я чувствую, что ваша проблема связана с тем, как вы строите хэш-таблицу *key*. Принцип работы gethash заключается в том, что он использует назначенную хеш-таблице функцию :test (заданную во время вызова make-hash-table).

Теперь, учитывая, что вы устанавливаете значение для ключа, который представляет собой список каждый раз в рекурсии, я сомневаюсь, что вы добавите что-либо в свою хэш-таблицу, если она использует make-hash-table по умолчанию (которая использует eql для тестирования), потому что каждый раз, когда ваш (gethash (list graph-id (first vertices)) *keys*) запускается, вызов (list ..) создает список, который никогда не соответствует какому-либо предыдущему списку.

Если вы еще этого не сделали, измените, возможно:

(defvar *key* (make-hash-table)) 

линия к чему-то вроде

(defvar *key* (make-hash-table :test #'equal)) 

и все должно работать лучше.

person AlbusMPiroglu    schedule 30.12.2020
comment
Прежде всего, спасибо за помощь. Моя хеш-таблица уже объявлена, как вы предложили. В любом случае, я не могу объяснить, почему, потому что я не думаю, что изменил что-либо, связанное с этой частью кода, но моя ошибка, похоже, исчезла. Такое ощущение, что компилятор напортачил с каким-то кодом, который на самом деле не был связан с ошибкой, вытолкнувшей меня, но это только мое предположение... - person giovannibrumana; 01.01.2021