Розширення мови 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;

P
while (y>0) do

F1
F2
begin

F3
F4
   res:=mul(x,res);

   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; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!