Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лахов.doc
Скачиваний:
1
Добавлен:
15.04.2019
Размер:
380.42 Кб
Скачать

Распознавание списочных образцов

Предикаты сравнения ЛИСПа, например EQ, EQL, EQUAL, MEMBER и др., уже фактически являются простейшими функциями сопоставления с образцом. Условия совпадения для этих предикатов все же очень жесткие, хотя они и отличаются друг от друга. Если мы хотим использовать более свободные условия сопоставления, то их нужно определять самому. Для начала ограничимся сопоставлением со списочным одноуровневым образцом. Сопоставление со списком можно с помощью рекурсии обобщить для многоуровневых списочных структур.

Условия сопоставимости

К сопоставлению элементов образца и образа можно предъявить различные требования. Во-первых, можно потребовать, чтобы определенные элементы были идентичны. Для более гибких требований мы будем использовать символы-заменители, для которых определены условия сопоставимости. Можно различить следующие основные случаи.

ЗАМЕНИТЕЛЬ

? произвольный символ образа

+ не пустая последовательность символов образа, или сегмент

* сегмент или пустая последовательность

мы хотим определить функцию СОПОСТАВЬ, которая проверяет, подходит ли данный образ к заданному с использованием заменителей образцу:

(СОПОСТАВЬ образец образ)

_(сопоставь ‘(? ? k ?) ‘(ф а к т))

Т

_(сопоставь ‘(+ к т) ‘(о б ъ е к т))

Т

_(сопоставь ‘(* т р * а к т) ‘(а н т р а к т))

Т

_(сопоставь ‘(? С *) ‘ (( а b) c d ( ( e))))

T

Образцы сопоставляются только на самом внешнем уровне списков.

Идя следующего определения функции СОПОСТАВЬ состоит в том, что образец и образ рассматриваются символ за символом и проверяются выполнение условий. Когда встречается заменитель, то используя методы управляемого данными программирования применяется соответствующая функция сопоставления:

Программа sopostav

(defun sopostav (m h)

(cond ((null m) ; konez obrazca

(null h))

((null h) nil) ; konez obraza

((equal (car m)(car h))

;; sovpadaush element

(sopostav (cdr m) (cdr h)))

((and (atom (car m)) ; sopostavlenie

(get (car m) 'sopostvtl))

(funcall ; s obrazcom

(eval (get (car m) 'sopostvtl))

m h))

(t nil))) ; neudacha

Для определения соответствующих заменителям функций сопоставления, или сопоставителей, мы сначала, так же как и ранее в примере дифференцирования, определим макрос определения:

;;;macros opred sopostvtl

(defmacro defsopostvtl

(simvol param telo)

`(setf (get ',simvol 'sopostvtl)

'(lambda ,param ,telo)))

Сопоставителями будут: ? + *

(defsopostvtl ? (m h)

(sopostav (cdr m) (cdr h)))

(defsopostvtl + (m h)

(or (sopostav (cdr m) (cdr h))

(sopostav m (cdr h))))

(defsopostvtl * (m h)

(or (sopostav (cdr m) (cdr h))

(sopostav (cdr m) h)

(sopostav m (cdr h))))

При необходимости выбор условий сопоставления можно расширить. Например заменитель «-“, которому соответствует в образце один символ или пустая последовательность можно было быть реализовать.

(defsopostvtl - (m h)

(or (sopostav (cdr m) (cdr h))

(sopostav (cdr m) h)))

_(сопоставь ‘(? ? – к - -) ‘(т а к т))

Т

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