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

Использование переменных в образце

Сопоставление можно сделать значительно более разносторонним, используя в образце переменные различных типов. Переменная образца получает в качестве значения некоторую часть образа в том случае, когда сопоставление соответствующего типа удалось. Переменные образцы будем изображать в виде двухэлементного списка, первый элемент которого отображает тип сопоставления, а второй- имя переменной. Мы будим использовать переменные cоответствующие типам ? , + и *.

ПЕРЕМЕННАЯ СОПСТАВЛЯЕТСЯ С

ОБРАЗЦА

(? > переменная) произвольный символ

(+ > переменная) непустым сегментом символов

(* > переменная) пустым или непустым сегментом символов

Tеперь напишем новый вариант функции СОПОСТАВЬ. При успешном сопоставлении она в качестве результата будет возвращать список пар, отображающий значения, связанные с переменными. Если в образце нет переменных и сопоставление прошло успешно, то возвращается Т. Например,

_(сопоставь 1 '((? > x) или (+ > y)) '(дo или после полудня))

((Х . ДО) (У. ПОСЛЕ ПОЛУДНЯ))

_(сопоставь 1 ‘(? или *) '(дo или после полудня))

Т

Для функции сопоставления СОПОСТАВЬ 1 нужен дополнительный параметр (ПАРЫ), который содержит соответствия между переменными и частями образа в виде списка пар: Программа spstv1

;;; second variant

(defun spstv1

(m h &optional (pari nil))

(cond

((null m)

(if (null h) (if pari pari t) nil))

((null h) nil)

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

(spstv1 (cdr m) (cdr h) pari))

((atom (car m))

(if (get (car m) 'spstvtl)

(funcall

(eval (get (car m) 'spstvtl))

m h pari)

nil))

(t (funcall ; sopostavlen s peremennoi

(eval (get (first (car m)) 'spstvtl))

m ; obrazec

h ; obraz

(second (car m)) ; peremennaia

pari))

)) ; sootvetstvia

Сопоставителем как и ранее будут:

(defspstvtl ? (m h pari)

(spstv1 (cdr m) (cdr h) pari))

(defspstvtl + (m h pari)

(or (spstv1 (cdr m) (cdr h) pari)

(spstv1 m (cdr h) pari)))

(defspstvtl * (m h pari)

(or (spstv1 (cdr m) (cdr h) pari)

(spstv1 (cdr m) h pari)

(spstv1 m (cdr h) pari)))

Аналогично можно определить типы сопоставления переменных ? > +> и *> :

(defspstvtl ?> (m h v pari)

(spstv1 (cdr m) (cdr h)

(acons v (car h) pari)))

(defspstvtl +> (m h v pari)

(or (spstv1 (cdr m) (cdr h)

(dobav v (car h) pari))

(spstv1 m (cdr h)

(dobav v (car h) pari))))

(defspstvtl *> (m h v pari)

(or (spstv1 (cdr m) (cdr h)

(dobav v (car h) pari))

(spstv1 m (cdr h)

(dobav v (car h) pari))

(spstv1 (cdr m) h pari)))

;;; dobav prisvaiv peremennoi

;;; ili obnovlaet starui svaz

(defun dobav (ima znach pari)

(cond

((null pari)

(acons ima znach nil))

((eql ima (caar pari))

(if (atom (cdar pari))

(acons ima

(list (cdar pari) znach)

(cdr pari))

(acons ima

(append (cdar pari)

(list znach))

(cdr pari))))

(t (cons (car pari)

(dobav ima znach

(cdr pari))))))

Cоответствиz элементов образца собираются в параметре ПАРЫ функции ДОБАВЬ, который в случае успешного сопоставления возвращается в качестве результата функции СОПОСТАВЬ1.