Играйте переводчиком, беря лист бумаги и записывая каждый шаг. Для каждого шага вы записываете, какое правило было / может быть запущено и какая переменная была связана с каким значением.
Например:
(append-to-form (a b) (c d) ?z)
запускает правило
(rule (append-to-form (?u . ?v) ?y (?u . ?z))
(append-to-form ?v ?y ?z))
с
?u = a, ?v = (b), ?y = (c d), ?z = (a . ?z_2)
Примечание: предполагается, что? Z в исходном запросе отличается от? Z в теле правила, поэтому переименуйте правило? Z в? Z_2. Список (1 2 3) при сопоставлении с (? A.? B) создает? A = 1,? B = (2 3), как при обработке списка.
Эти привязки применяются к основному правилу (append-to-form ?v ?y ?z)
Итак, мы получаем
(append-to-form (b) (c d) ?z_2)
, который снова становится
(append-to-form () (c d) ?z_3)
и запускает другое правило: (rule (append-to-form () ?y ?y))
привязка? Z_3 к (c d).
Затем запускается рекурсия,? Z_2 был определен как (b.? Z_3),? Z был определен как (a.? Z2)
Исходный запрос (append-to-form (a b) (c d) ?z)
применяется к привязкам, в которых? Z = (a. (B. (C d))) и возвращает (append-to-form (a b) (c d) (a b c d))
Остальные упражнения оставлены читателю;)
Ключевыми понятиями здесь являются сопоставление и унификация шаблонов, которые можно найти в раздел 4.2.2 . Весь анализатор запросов - действительно самая сложная часть в SICP, так что не расстраивайтесь. Это стоит усилий. Попробуйте запустить код (в схеме R5RS) и поиграть с ним, например, добавив трассировку.