Розширення мови SIPL: Введення викликів функцій
Подамо у наступній таблиці (Табл.1.8) cинтаксис розширення БНФ:
Таблиця 1.8.
Ліва частина правила – метазмінна | Права частина правила | Ім’я правила |
<програма> ::= | …| program <списокоб’явленьфункцій> begin<оператор> end | NP1 NP2 |
<вираз> ::= | …| if<умова> then <вираз> else <вираз> | <виклик функції> | NA1–NA7 NA8 NA9 |
<списокоб’явленьфункцій>::= | e | <об’явленняфункції> | <об’явленняфункції> ; <списокоб’явленьфункцій> | LDF1 LDF2 LDF3 |
<об’явленняфункції>::= | func<ім’я функції>=<вираз> | func<ім’я функції>(<списокформальних параметрів>)= <вираз> | DF1 DF2 |
<ім’я функції> ::= | <змінна> | NF |
<список формальних параметрів>::= | <змінна> | <змінна> , <список формальних параметрів> | LFP1 LFP2 |
<виклик функції> ::= | <ім’я функції> | <ім’я функції> (<список фактичних параметрів>) | CF1 CF2 |
<список фактичних параметрів>::= | <вираз> | <вираз> , <список фактичних параметрів> | LAP1 LAP2 |
Тобто ми змінили синтаксис виразу: додавши варіант завдання виразу за допомогою умов
<вираз> ::= if<умова> then <вираз1> else <вираз2>
якщо умова виконується, то <вираз> := <вираз1> інакше <вираз> := <вираз2>, або ж
<вираз> ::= <виклик функції>
значення виразу буде дорівнювати результату виклику функції.
Зміниться і синтаксис програми: додамо варіант
<програма> ::=program <списокоб’явленьфункцій> begin<оператор> end
|
|
де <списокоб’явленьфункцій> може бути порожнім, або складатися з об’явленьфункцій перерахованих через кому. Так ми додамо можливість використовувати функції із списку об’явленьфункцій
Синтаксис об’явленняфункції митаме такий вигляд:
<об’явленняфункції>::=func<ім’я функції>=<вираз> |
func<ім’я функції>(<списокформальних параметрів>)= <вираз>
де список формальних параметрів це список змінних перерахованих через кому.
Синтаксис виклику функції має вигляд:
<виклик функції>::=<ім’я функції> , якщо функція не має параметрів, та
<виклик функції> ::=<ім’я функції> (<список фактичних параметрів>) де список фактичних параметрів – список виразів перерахованих через кому.
Семантика суперпозиції при цьому може бути 2-х видів:
Глобальною суперпозицією функцій g1,g2,…,gn в номінативну функцію f називається функція, яка задається формулою: S(v1,v2,..vn)(f,g1,g2,…,gn)(st) = f([v1®g1(st),v2®g2(st),…,vn®gn(st)])
Локальною суперпозицією функцій g1,g2,…,gn в номінативну функцію f називається функція, яка задається формулою
S[v1,v2,..vn](f,g1,g2,…,gn)(st) = f(stÑ[v1®g1(st),v2®g2(st),…,vn®gn(st)])
+ семантика – формально + повно
|
|
…
1.5. пункти і т.д. = оформлення: шрифт (14) + абзаци (відступи) + підписи таблиць (стандарт) + відступи у тексті + міжстрокові…
Приклади задач
…
Задача. Обчислення X^Y через виклик рекурсивної функції множення двох чисел, реалізованої через додавання.
program
func mul(a, b)=if b>0 then a+mul(a,b-1) else 0
begin
res:=1;
|
|
|
|
|
y:=y-1
end
end
Дерево синтаксичного виводу програми у мові SIPL:
Повернути, оформити !!!
Transpose picture !!!
Семантичний терм:
sem_P(P)=sem_S(F1)=sem_S(F2)=ASres(1) • sem_S(F3)=ASres(1) • WH(sem_B(y>0), sem_S(F4))=ASres(1) • WH(S2(gr,y=>,0), ASres(sem_A(mul(x,res)))• ASy(S2(sub,y=>,1)))=ASres(1) • WH(S2(gr,y=>,0), ASres(Sa,b(sem_A(mul),x=>,res=>)• ASy(S2(sub,y=>,1))).
Знайдемо sem_A(mul):
sem_A(mul)=IF_A(S2(gr, b=>, 0), sem_A(a+mul(a,b-1)), 0)=IF_A(S2(gr, b=>, 0), S2(add, a=>, sem_A(mul(a,b-1)), 0)=IF_A(S2(gr, b=>, 0), S2(add,a=>,Sa,b(sem_A(mul),a=>,S2(sub,b=>,1))), 0)
Маємо рекурсивно задану семантику для функції.
Доведемо, що sem_A(mul)([aaA, baB])=A*B індукцією за B.
1) База. Якщо B=0, то
sem_A(mul)(st)= IF(S2(gr,b=>,0),S2(add,a=>,Sa,b(sem_A(mul),a=>,S2(sub,b=>,1))),0)(st)=0, оскільки B=0.
2) Припущення. Нехай sem_A(mul)([aaA, baB])=A*B, для всіх B<k.
3) Крок індукції. Нехай B=k>0, маємо:
sem_A(mul)(st)=
IF_A(S2(gr,b=>,0),S2(add,a=>,Sa,b(sem_A(mul),a=>,S2(sub,b=>,1))),0)(st)=
S2(add,a=>,Sa,b(sem_A(mul),a=>,S2(sub,b=>,1)))(st). Використовуючи означення локальної композиції, отримаємо:
|
|
sem_A(mul)(st)=S2(add,a=>(st),sem_A(mul)(st∇[aaA, baB-1]))=
A+A*(B-1)=A+A*B-A=A*B
Формула доведена.
Доведемо часткову коректність програми.
Нехай на вхід програмі дається стан st=[xaX, yaY]. X,Y≥0
sem_P(P)(st)=ASres(1) • WH(S2(gr,y=>,0), ASres(Sa,b(sem_A(mul),x=>,res=>)• ASy(S2(sub,y=>,1)))(st)=WH(S2(gr,y=>,0), ASres(Sa,b(sem_A(mul),x=>,res=>)• ASy(S2(sub,y=>,1)))(st∇[resa1]).
Нехай WH(S2(gr,y=>,0), ASres(Sa,b(sem_A(mul),x=>,res=>)• ASy(S2(sub,y=>,1)))=f. Тоді висунемо гіпотезу, що f(stin)=stout, де
stin=[xaU, yaV, resaR] , U,V≥0 – вхідний стан для циклу,
stout=[xaU, ya0, resaR*U^V]– результат виконання циклу. Доведемо, що ця рівність виконується, індукцією за кількістю ітерацій циклу:
1) База індукції. NumItWH=0. Тому V≤0, з умови V≥0 випливає, що V=0. Тоді рівність f(stin)=stout виконується.
2) Припущення. Нехай рівність f(stin)=stout виконується для всіх циклів з кількістю ітерацій менше деякого додатнього k:
NumItWH<k, k>0
3) Крок індукції. Доведемо, що рівність виконується і для циклів з k ітерацій.
f(stin)=WH(S2(gr,y=>,0),ASres(Sa,b(sem_A(mul),x=>,res=>)•ASy(S2(sub,y=>,1)))(stin). Використаємо формулу: WH(p, f)=IF(p, f •WH(p,f), id), враховуючи, що кількість ітерацій додатня, а тому умова p на початковому стані істина, маємо: (ASres(Sa,b(sem_A(mul),x=>,res=>)•ASy(S2(sub,y=>,1))•f)(stin). Розпишемо композицію:
f(stin)=f(ASres(Sa,b(sem_A(mul),x=>,res=>)•ASy(S2(sub,y=>,1)))(stin))= f(ASy(S2(sub,y=>,1)(ASres(Sa,b(sem_A(mul),x=>,res=>)(stin)))=f(ASy(S2(sub,y=>,1)([xaU, yaV, resaU*R]))=f([xaU, yaV-1,resaU*R]), оскільки ми виконали одну ітерацію циклу, то для стану [xaU, yaV-1,resaU*R] кількість ітерацій буде k-1, тому, оскільки з умови y>0 випливає, що V-1≥0:
|
|
f([xaU, yaV-1,resaU*R])=[xaU, ya0,resa (U*R)*U^(V-1)] - за припущенням індукції. Але [xaU, ya0,resa (U*R)*U^(V-1)]=[xaU, ya0, resaR*U^V]= stout
Тому f(stin)=stout для кожного stin=[xaU, yaV, resaR], при умові, що U,V≥0. Тому
sem_P(P)=f([xaX, yaY, resa1])=[xaX, ya0, resaX^Y]
Часткова коректність доведена.
Неважко бачити, що значення y на кожній ітерації циклу утворюють строго спадну послідовність, обмежену нулем. В силу скінченності значення y цикл завжди завершить своє виконання, при умові y=0 цикл не буде виконуватись взагалі. В силу скінченності команд програми, вона завжди зупиняється. Тому справджується повна коректність програми.
Завдання для самостійної роботи
Завдання для самостійної роботи:
1. Ділення двох чисел будь-якого знаку.
2. Обчислити: .
3. Обчислити суму арифметичної прогресії.
4. Обчислити суму геометричної прогресії за формулою суми геометричної прогресії.
5. Додавання двох невід’ємних чисел черес плюс два і мінус один.
6. Обчислити: .
7. Знайти подвійний факторіал, якщо n – непарне.
8. Обчислити: .
9. Обчислити: через плюс один.
10. Обчислити: .
11. Обчислити: .
Завдання для контрольної роботи:
1. Додавання двох чисел будь-якого знаку через плюс один.
2. Обчислити: .
3. Знайти n- те число Фібоначчі.
4. Обчислити суму геометричної прогресії.
5. Додавання двох невід’ємних чисел черес плюс три і мінус один.
6. Знайти остачу від ділення двох чисел.
7. Обчислити: .
8. Знайти подвійний факторіал, якщо n – парне.
9. Обчислити: .
10. Обчислити: .
11. Обчислити дискримінант .
Дата добавления: 2018-04-05; просмотров: 340; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!