Я хотел бы получить несколько советов по доступу и обновлению структуры данных, которая имеет несколько уровней. Изначально я хотел использовать функцию setf с обобщенными ссылками, но не мог заставить это работать. В качестве альтернативы перечисленные ниже функции работают правильно для запроса и обновления структуры данных (называемой *kb*
). Но это кажется более сложным, чем должно быть. Есть ли более простое решение?
(defun fetch (node edge)
"Retrieves all the nodes in the kb associated with a node and edge."
(alexandria:hash-table-keys (cdr (assoc edge (gethash node *kb*)))))
(defun associate (node1 edge node2)
"Adds an association to the kb."
(declare (symbol node1 edge node2))
(when (not (gethash edge *edges*))
(error "Mentioned edge ~A was not predefined" edge))
(let ((alist (gethash node1 *kb*)))
(if alist
(let ((pair (assoc edge alist)))
(if pair
(setf (gethash node2 (cdr pair)) t)
(let ((ht (make-hash-table :test #'eq)))
(setf (gethash node2 ht) t)
(setf (gethash node1 *kb*) (acons edge ht alist)))))
(let ((ht (make-hash-table :test #'eq)))
(setf (gethash node2 ht) t)
(setf (gethash node1 *kb*) (acons edge ht nil))))))
В качестве фона структура данных *kb*
представляет собой таблицу ha sh. Ключи таблицы ha sh являются символами, а значения являются списками. Каждый список состоит из пар key.value, где ключи - это символы, а значения - это таблицы ha sh. Каждая из последних таблиц ha sh просто представляет набор символов в виде ключей со значениями t. (PS: я выбрал списки для промежуточной структуры, так как есть только около 20 возможных символов края.) Спасибо за любые идеи ...