Обновление глубокой структуры данных (Common Lisp) - PullRequest
1 голос
/ 04 мая 2020

Я хотел бы получить несколько советов по доступу и обновлению структуры данных, которая имеет несколько уровней. Изначально я хотел использовать функцию 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 возможных символов края.) Спасибо за любые идеи ...

...