Сброс каждого значения в хеш-таблице на ноль в Лиспе - PullRequest
1 голос
/ 20 апреля 2020

Эта функция сбрасывает значение для каждой из указанных частей речи в NIL, используя putp. Первый аргумент - это хеш-таблица, для этого примера давайте назовем его word-dict.
Существует переменное количество частей речи, переданных resetPartsOfSpeech.

Пример: (resetPartsOfSpeech word-dict 'subject' глагол 'prep' directObj)

(defun resetPartsOfSpeech(word-dict &rest parts)
(do ((partsVar parts (cdr partsVar)))
( (null partsVar) T)
;;; procces the car 
(putp NIL word-dict (car partsVar))
))

; here is the results of the function
#S(HASH-TABLE :TEST FASTHASH-EQL (NIL . VERB) (LICKED . VERB) (HAS . VERB) (ATE . VERB) (RAN . VERB) (TAUGHT . VERB)

Как видите, он только добавляет переменную NIL в список, а не очищает их все.

Вспомогательные функции, которые у меня есть, работа этих две функции - поместить и получить данные из созданной хеш-таблицы.

; creating the hash table
(setf word-dict (MAKE-HASH-TABLE))

(defun putp (symbol ht value)
(if (ATOM symbol)
    (setf (gethash symbol ht) value)
    (ERROR "~s is not a valid symbol for putp" symbol)
))

(defun getp (symbol ht)
 (gethash symbol ht) )

(defun isa(word partOfSpeech)      ; this function returns T if the specified word is that specified partOfSpeech,  
; otherwise, NIL is returned. 
(eql (getp word word-dict) partOfSpeech))

(defun set_isa (partOfSpeech &rest words)    ; this function defines each
word in the list of words to the specified partOfSpeech  

; в словаре (жесткий код слово-dict). (do ((wordVar words (cdr wordVar))) ((NULL wordVar) T) ;;; обрабатывать CAR (putp (car wordVar) word-dict partOfSpeech) (печатать (car wordVar))))

Что мне трудно понять, так это то, как я должен go пересмотреть каждое значение в таблице ha sh. Я думал о том, чтобы делать вложенный do или dolist l oop, но не могу понять, как это сделать go со значениями из таблицы, или если это вообще возможно.

1 Ответ

4 голосов
/ 20 апреля 2020

Основная проблема связана с:

(putp NIL word-dict (car partsVar))

Когда вызывается putp, nil связан с symbol, word-dict связан с ht и (car partsVar), т. е. следующий символ в списке частей речи связан с value. В пределах putp выражение:

(setf (gethash symbol ht) value)

становится:

(setf (gethash 'nil word-dict) (car partsVar))

Здесь (gethash 'nil word-dict) является местом , для которого установлено значение (car partsVar) , Поскольку в таблице ha sh нет ключа 'nil, создается новый ключ, которому присваивается значение (car partsVar), которое в примере OP равно 'verb.

В оригинале putp выражение, (car partsVal) должно быть в позиции symbol, поскольку это ключ, который необходимо обновить:

(defun resetPartsOfSpeech (word-dict &rest parts)
  (do ((partsVar parts (cdr partsVar)))
      ((null partsVar) t)
    (putp (car partsVar) word-dict 'nil)))

Хотя это решает проблему, есть лучшее решение.

(defun reset-parts-of-speech (word-dict &rest parts)
  (dolist (part parts)
    (putp part word-dict 'nil)))

Если вы хотите сделать простую итерацию по списку элементов, символов для частей речи в этом случае, просто используйте простой dolist. Кроме того, было бы хорошо получить лучшие привычки в отношении стиля Lisp. Предпочитаю кебаб-кейс верблюжьему; поместите все закрывающие скобки в одну строку (почти всегда); используйте правильные отступы, чтобы сделать структуру программы понятной. Хороший текстовый редактор с поддержкой lisp может быть наиболее полезным для последних двух.

Вот несколько тестов в REPL с использованием функции set-isa, основанной на предыдущего вопроса от OP :

SCRATCH> (defvar *word-dict* (make-hash-table))
*WORD-DICT*
SCRATCH> (set-isa 'verb 'eat 'sleep 'walk)
NIL
SCRATCH> (set-isa 'noun 'cake 'ice-cream 'pizza)
NIL
SCRATCH> (gethash 'verb *word-dict*)
(WALK SLEEP EAT)
T
SCRATCH> (gethash 'noun *word-dict*)
(PIZZA ICE-CREAM CAKE)
T
SCRATCH> (set-isa 'adjective 'delicious 'sweet 'crispy)
NIL
SCRATCH> (gethash 'adjective *word-dict*)
(CRISPY SWEET DELICIOUS)
T
SCRATCH> (resetPartsOfSpeech *word-dict* 'verb)
T
SCRATCH> (gethash 'verb *word-dict*)
NIL
T
SCRATCH> (gethash 'noun *word-dict*)
(PIZZA ICE-CREAM CAKE)
T
SCRATCH> (reset-parts-of-speech *word-dict* 'adjective 'noun)
NIL
SCRATCH> (gethash 'noun *word-dict*)
NIL
T
SCRATCH> (gethash 'adjective *word-dict*)
NIL
T

Обновление

Выражение выше было основано на операторе OP: " Эта функция сбрасывает значение для каждой из указанных частей речи в NIL ...,", что, по-видимому, указывает на то, что OP хочет, чтобы таблица ha sh сохраняла части речи в виде ключей, а списки слов - в качестве связанных значений. Это также похоже на предыдущий вопрос , опубликованный OP . Но после обмена комментариями кажется, что OP может предпочесть таблицу ha sh с отдельными словами в качестве ключей и частями речи в качестве связанных значений. Неясно, как следует обрабатывать слова, которые могут быть связаны с несколькими частями речи.

Таблица ha sh, показанная в примере кода OP #S(HASH-TABLE :TEST FASTHASH-EQL (NIL . VERB) (LICKED . VERB) ;..., вместе с комментариями OP, поддерживает эту вторую интерпретацию. Если это так, то что означает «сбросить каждое значение» в таблице ha sh на 'nil? Возможно, разумно было бы полностью удалить каждую запись, значение которой соответствует указанному аргументу части речи.

Это можно легко сделать, используя от dolist до l oop поверх список частей речи и последующее сопоставление таблицы ha sh с maphash и функцией, которая удаляет любую запись, содержащую совпадающее значение:

(defun remove-parts-of-speech (word-dict &rest parts)
  (dolist (part parts)
    (maphash #'(lambda (k v) (if (eql v part) (remhash k word-dict)))
             word-dict)))

Вот еще одна демонстрация REPL с использованием тока OP set-isa функция, которая заполняет таблицу ha sh словами для ключей и частями речи для значений. После заполнения таблицы ha sh девятью словами 'noun s, 'verb s и 'adjectives, функция remove-parts-of-speech используется для удаления всех записей, которые являются существительными или глаголами из *word-dict*. После этого в таблице ha sh остаются только три прилагательных.

CL-USER> (defvar *word-dict* (make-hash-table))
*WORD-DICT*
CL-USER> (set-isa 'verb 'run 'jump 'climb)

RUN 
JUMP 
CLIMB 
T
CL-USER> (set-isa 'noun 'hat 'shoe 'scarf)

HAT 
SHOE 
SCARF 
T
CL-USER> (set-isa 'adjective 'salty 'spicy 'sour)

SALTY 
SPICY 
SOUR 
T
CL-USER> *word-dict*
#<HASH-TABLE :TEST EQL :COUNT 9 {1003CE10C3}>
CL-USER> (hash-table-count *word-dict*)
9
CL-USER> (remove-parts-of-speech *word-dict* 'noun 'verb)
NIL
CL-USER> (hash-table-count *word-dict*)
3
CL-USER> (gethash 'spicy *word-dict*)
ADJECTIVE
T
...