Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
NikitchenkoNEWNEW.doc
Скачиваний:
26
Добавлен:
08.11.2019
Размер:
2.99 Mб
Скачать

1.3.5. Визначення семантичних термів

Досі ми не дуже чітко розрізняли функціональний вираз алгебри A_Prog та функцію, що задається цим виразом. Наприклад, запис (fg)h можна тлумачити як функцію, і тоді її можна застосувати до стану st або як вираз, і тоді, наприклад, вивчати тотожність (fg)h=f(gh). У математичній логіці таке розрізнення роблять явним, вважаючи, що (fg)h є виразом (термом, формулою), а не функцією. Саму ж функцію, яка задається цим виразом, позначають, наприклад, (fg)h I , де I ­– інтерпретація символів f, g, h в алгебрі A_Prog.

Таке розрізнення можна було б зробити і для мови SIPL. У такому випадку для опису (дескрипції) функцій, які задаються програмами мови SIPL, можуть використовуватися функціональні вирази алгебри A_SIPL, які називаються термами цієї алгебри. Такі класи термів будуються індуктивно, аналогічно класам синтаксичних категорій. Терми програмної алгебри будемо також називати семантичними термами. Ми зазвичай не будемо використовувати різні позначення для термів та функцій, сподіваючись, що читач із контексту зрозуміє, про яке поняття іде мова. Разом із тим слід пам’ятати, що це розрізнення є важливим у теорії програмування, яка чітко виокремлює синтаксис та семантику програм.

Зауважимо, що можна використовувати різні визначення термів алгебри, у тому числі

  • індуктивне;

  • рекурсивне;

  • аналітичне;

  • БНФ;

  • графічне тощо.

Прохання до читача побудувати індуктивне визначення множини термів самостійно.

Позначимо множини термів, які задають арифметичні вирази, умови, оператори (та програми) мови SIPL відповідно як TFA, TFB, TFS.

1.3.6. Побудова семантичного терму програми

Програма мови SIPL може бути перетворена на семантичний терм (терм програмної алгебри), який задає семантику цієї програми (семантичну функцію програми), перетвореннями такого типу:

  • sem_P: ProgTFS;

  • sem_S: StmTFS;

  • sem_A: AexpTFA;

  • sem_B: BexpTFB.

Ці перетворення задаються рекурсивно (за структурою програми). Тому побудова семантичного терму залежить від вибору структури синтаксичного запису програми. Тут треба зважати на неоднозначність обраної нами граматики, що може призвести до різної семантики програм. Для досягнення однозначності треба користуватися пріоритетами операцій і типом їх асоціативності.

Таблиця 1.6

Правило заміни

Номер

правила

sem_P: ProgTFS задається правилами:

sem_P(begin S end)= sem_S(S)

NS_Prog

sem_S: StmTFS задається правилами:

sem_S(x:=a)=ASx(sem_A(a))

sem_S(S1;S2)= sem_S(S1) sem_S(S2)

sem_S(if b then S1 else S2)=

=IF(sem_B(b), sem_S(S1), sem_S(S2))

sem_S(while b do S)= WH(sem_B(b), sem_S(S))

sem_S(begin S end)=(sem_S(S))

sem_S(skip)=id

NS_Stm_As

NS_Stm_Seq

NS_Stm_If

NS_Stm_Wh

NS_Stm_skip

sem_A: AexpTFA задається правилами:

sem_A(n))=

sem_A(x))=x

sem_A(a1+a2)=S2(add, sem_A(a1), sem_A(a2))

sem_A(a1a2)=S2(sub, sem_A(a1), sem_A(a2))

sem_A(a1a2)=S2(mult, sem_A(a1), sem_A(a2))

sem_A((a))=sem_A(a)

NS_A_Num

NS_A_Var NS_A_Add

NS_A_Sub

NS_A_Mult

NS_A_Par

sem_B: BexpTFB задається правилами:

sem_B(a1=a2)=S2(eq, sem_A(a1), sem_A(a2))

sem_B(a1>a2)=S2(gr, sem_A(a1), sem_A(a2))

sem_B(b1b2)=S2(or, sem_B(b1), sem_B(b2))

sem_B(b)=S1(neg, sem_B(b))

sem_B((b))= sem_B(b)

NS_B_eq

NS_B_gr

NS_B_or

NS_B_neg

NS_B_Par

Наведені правила слід розглядати як загальні правила, які в логіці називають схемами правил. Щоб із загального правила (метаправила) отримати конкретне правило (об’єктне правило), слід замість синтаксичних метасимволів, таких як a, b, S, P, n, x, підставити конкретні синтаксичні елементи (записи), наприклад, замість a підставити N–M, замість bM>N і т.д. Далі ліва частина конкретного правила замінюється на його праву частину і т.д.

Приклад 1.2 Побудуємо семантичний терм виразу X+Y*Z. Побудова терму полягає в обчисленні значення sem_A(X+Y*Z). Щоб зробити перший крок такого обчислення, треба віднайти правило, ліва частина якого буде збігатися із записом sem_A(X+Y*Z) при відповідній конкретизації такого правила. Цей процес називається уніфікацією двох записів (термів). У нашому випадку можлива уніфікація з лівою частиною правил NS_A_Add та NS_A_Mult. У першому випадку уніфікація sem_A(X+Y*Z) та sem_A(a1+a2) можлива при заміні a1 на X та a2 на Y*Z, а в другому уніфікація sem_A(X+Y*Z) та sem_A(a1a2) можлива при заміні a1 на X+Y та a2 на Z. Наведені заміни (підстановки) називаються уніфікаторами і зазвичай позначаються [a1/X, a2 /Y*Z] та [a1/X+Y, a2 /Z] або [a1X, a2 Y*Z] та [a1X+Y, a2 Z]. Зазначимо, що друга уніфікація порушує пріоритет операцій, тому розглядаємо лише першу уніфікацію. Застосування першого уніфікатора до правила NS_A_Add призводить до наступного конкретного (об’єктного) правила:

NS_A_Add: sem_A(X+Y*Z)= S2(add, sem_A(X), sem_A(Y*Z)).

Застосування цього правила дозволяє перетворити запис sem_A(X+Y*Z) на запис S2(add, sem_A(X), sem_A(Y*Z)). Цей запис містить два підзаписи (sem_A(X) та sem_A(Y*Z)), до яких можна застосувати перетворення. Підзапис sem_A(X) уніфікується з лівою частиною правила NS_A_Var за допомогою уніфікатора [x/X], а підзапис sem_A(Y*Z) – з NS_A_Mult за допомогою уніфікатора [a1/Y, a2/Z]. Застосування цих уніфікаторів призводить до двох нових конкретних правил:

NS_A_Var: sem_A(X)= X та

NS_A_Mult: sem_A(Y*Z)= S2(mult, sem_A(Y), sem_A(Z)).

Застосовуючи ці правила до виразу S2(add, sem_A(X), sem_A(Y*Z)) отримаємо S2(add, X, S2(mult, sem_A(Y), sem_A(Z))). Залишилося конкретизувати правило NS_A_Var, щоб отримати остаточний результат

sem_A(X+Y*Z)= S2(add, X, S2(mult, Y, Z))

Отже, процес побудови семантичного терму програми полягає в послідовному перетворенні запису, для якого будується семантичний терм. Ці перетворення вимагають наступних дій:

  • вибір загального правила, яке можна застосувати до підзапису поточного виразу з урахуванням пріоритету операцій;

  • знаходження уніфікатора лівої частини правила з обраним під записом;

  • отримання конкретного правила застосуванням уніфікатора до обох частин загального правила;

  • заміна у поточному записі лівої частини конкретного правила на його праву частину.

Більш формально процес перетворень такого типу сформульований у теорії переписуючих правил.

Приклад 1.3. Побудувати семантичний терм програми GCD. Побудову будемо робити згідно з вищенаведеними правилами. Деталі не вказуємо.

sem_P(GCD)=

= sem_P(begin

whileM=N do

if M>N then M:=MN else N:=NM

end)=

= sem_S(whileM=N do if M>N then M:=MN else N:=NM)=

= WH(sem_B(M=N), sem_S(if M>N then M:=MN else N:=NM))=

= WH(S1(neg, sem_A(M=N),

IF(sem_B(M>N), sem_S(M:=MN), sem_S(N:=NM)))=

= WH(S1(neg, S2(eq, sem_A(M), sem_A(N))),

IF(sem_B(M>N), sem_S(M:=MN), sem_S(N:=NM)))=

= WH(S1(neg, S2(eq, M, N)), IF(S2(gr,M,N),

ASM(sem_A(MN)), ASN(sem_A(NM))))=

= WH(S1(neg, S2(eq, M, N)), IF(S2(gr,M,N),

ASM(S2(sub,sem_A(M),sem_A(N))), ASN(S2(sub,sem_A(N),sem_A(M)))))=

=WH(S1(neg, S2(eq, M, N)),

IF(S2(gr, M, N),

ASM( S2(sub, M, N)),

ASN( S2(sub, N, M))))

Повернемося тепер до доведення того факту, що семантика довільної програми мови SIPL задається термом алгебри A_SIPL. Дійсно, аналізуючи таблицю 1.6, бачимо, що там фігурують лише базові функції алгебри A_SIPL. Більш строге доведення можна отримати індукцією за структурою програми SIPL. Таким чином, є справедливим наступне твердження.

Теорема 1.1. Для довільної програми мови SIPL її семантична функція задається термом алгебри A_SIPL.

Зауваження 1.7. Відображення побудови семантичного терму можна розглядати і в іншому аспекті – алгебраїчному. У цьому випадку програма розглядається як терм синтаксичної алгебри, який відображається в семантичну алгебру. Це відображення буде гомоморфізмом синтаксичної алгебри в семантичну. Доведення цього факту випливає з аналізу правил, заданих у таблиці 1.6. Прохання до читача довести цей факт самостійно.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]