МФСП, 03 семинар (от 15 сентября)
Материал из eSyr's wiki.
(Новая: Продолжаем изучть язык RSL В прошлый раз рассм. типы, операции с ними, призв. типы. Разбрались с функц., к...) |
м |
||
(6 промежуточных версий не показаны.) | |||
Строка 1: | Строка 1: | ||
- | + | В прошлый раз рассматривались типы, операции с ними, производные типы. Разобрались с функциями, константами. | |
- | + | Сейчас: дорешать задачи про функции и перейти к множествам. | |
- | Сейчас: дорешать задачи пр функции и перейти к множествам. | ||
- | |||
- | Даны типы: | ||
+ | '''Задача.''' Даны типы: | ||
'''type''' position = Real×Real; | '''type''' position = Real×Real; | ||
'''value''' | '''value''' | ||
- | origin : Position = (0.0, 0.0) | + | origin : Position = (0.0, 0.0) /* начало координат */ |
dist : Position × Position → Real | dist : Position × Position → Real | ||
- | dist((x_1, y_1), (x_2, y_2)) | + | dist((x_1, y_1), (x_2, y_2)) ≡ ((x_1 - x_2)^2.0 + (y_1 - y_2)^2.0)^0.5 |
определить: тип circle, функцию on_circle | определить: тип circle, функцию on_circle | ||
+ | '''Решение:''' | ||
'''type''' | '''type''' | ||
Circle = Real × Position # радиус, центр | Circle = Real × Position # радиус, центр | ||
'''value''' | '''value''' | ||
on_circle : Circle × Position → Bool | on_circle : Circle × Position → Bool | ||
- | on_circle((r, c_0), c) | + | on_circle((r, c_0), c) ≡ (dist(c_0, c) = r) |
- | Описать | + | '''Задача.''' Описать окружность с радиусом 3 и центром в начале координат. |
'''value''' | '''value''' | ||
- | c_3_0_0 : Circle | + | c_3_0_0 : Circle ≡ (3.0, Origin) |
- | Описать точку, | + | '''Задача.''' Описать точку, лежащую на этой окружности |
+ | '''Решение:''' | ||
'''value''' | '''value''' | ||
- | d_on_c_3_0_0 : Position & | + | d_on_c_3_0_0 : Position • on_circle(c_3_0_0, d_on_c_3_0_0) = True |
- | Написать sqrt, | + | '''Задача.''' Написать функцию sqrt, возвращающую значения, отличные от корня из x не более, чем на ε. |
+ | '''Решение:''' | ||
'''value''' | '''value''' | ||
- | sqrt : Real × Real; | + | sqrt : Real × Real; ⥲ Real |
sqrt(a,b) as x | sqrt(a,b) as x | ||
- | '''post''' (abs(sqrt(a)-x) ≤ b) && (x ≥ 0) | + | '''post''' (abs(sqrt(a) - x) ≤ b) && (x ≥ 0) |
- | '''pre''' (b | + | '''pre''' (b ≥ 0) && (a ≥ 0) |
- | + | '''Задача.''' Дано определение: | |
'''value''' | '''value''' | ||
- | f: Int | + | f: Int ⥲ Int |
- | f(x) | + | f(x) ≡ f(x) |
- | + | Удовлетворяет ли этому определению следующее определение: | |
'''value''' | '''value''' | ||
f: Int → Int | f: Int → Int | ||
- | f | + | f ≡ 1, chaos, 5 — все три раза да |
- | Множества в RSL | + | == Множества в RSL == |
- | + | Множество — конечный или бесконечный набор неповторяющихся элементов данного типа. | |
- | + | Обозначение: | |
{1, 2, 3} | {1, 2, 3} | ||
- | + | В языке RSL множество определяется следующим образом: | |
- | + | * <tt>T - infset</tt> — для бесконечных множеств | |
- | + | * <tt>T - set</tt> — для конечных множеств | |
- | Для | + | Для любого типа определено пустое множество — {}. |
- | + | Над множеством определены следующие операции: ∩, ∪, ⊂, ⊃, ⊆, ⊇, ∉, ∈, \. | |
- | card — | + | Другие операции: |
- | card: T - infset | + | |
- | card M | + | '''card''' — размер множества: |
+ | card: T - infset ⥲ Nat | ||
+ | card M ≡ |M| | ||
card {} = 0 | card {} = 0 | ||
- | card {n|n:Nat} | + | card {n|n:Nat} ≡ chaos |
- | card {1,2,3} | + | card {1,2,3} ≡ 3 |
- | Примеры: | + | '''Примеры''': |
* {"abc", "db", "efo"} | * {"abc", "db", "efo"} | ||
* {1..4} = {1,2,3,4} | * {1..4} = {1,2,3,4} | ||
* {4..1} = {} | * {4..1} = {} | ||
- | Такое | + | Такое определение множества малоприменимо на практике, поэтому обычно множества определяют через выражения и ограничения: |
{expr|limit} | {expr|limit} | ||
- | Пример: | + | '''Пример''': |
- | {2*n|n:Nat & | + | {2*n | n:Nat • n < 3} = {0, 2, 4} |
- | Задача: даны типы Student, Course, и | + | '''Задача''': даны типы Student, Course, и призводные типы: |
'''type''' Student, Course, | '''type''' Student, Course, | ||
- | CourseIno = Course × Student -set | + | CourseIno = Course × Student-set |
- | University = Student - set × CourseInfo - set | + | University = Student-set × CourseInfo-set |
- | + | Требуется: | |
- | * | + | * Определить для университета множество всех студентов (функция <tt>AllStudents</tt>) |
- | * HasCourse — курс читается в университете | + | * <tt>HasCourse</tt> — курс читается в университете |
- | * NumberOk — каждый курс посещают не менее 5 и не более 100 человек | + | * <tt>NumberOk</tt> — каждый курс посещают не менее 5 и не более 100 человек |
+ | '''Решение:''' | ||
'''value''' | '''value''' | ||
- | AllStudents : University → Student - set | + | AllStudents : University → Student-set |
- | AllStudents ((s,ci)) | + | AllStudents ((s,ci)) ≡ s |
HasCourse : Course × University → Bool | HasCourse : Course × University → Bool | ||
- | HasCourse(c,(s,ci)) | + | HasCourse(c,(s,ci)) ≡ ∃ (c, si) : CourseInfo • (c,si) ∈ ci |
NumberOk : University → Bool | NumberOk : University → Bool | ||
- | NumberOk((s, ci)) | + | NumberOk((s, ci)) ≡ ∀ (c, s) : CourseInfo • (((c,s) ∈ ci) ⇒ ((card s > 5) ∧ (card s < 100))) |
Почему импликация, а не конъюнкция: | Почему импликация, а не конъюнкция: | ||
- | |||
'''value''' | '''value''' | ||
c2 : Course | c2 : Course | ||
u : University = {{s1, s2, s3, s4, s5, s6}, (c1, {s1, s2, s3, s4, s5, s6})} | u : University = {{s1, s2, s3, s4, s5, s6}, (c1, {s1, s2, s3, s4, s5, s6})} | ||
- | При проверки с c=c2 получим false и значение функции false. | + | При проверки с c=c2 получим <tt>false</tt> и значение функции <tt>false</tt>. |
- | Описать функцию | + | '''Задача.''' Описать функцию <tt>StudentOf</tt>, возвращающую множество студентов, посещающих заданный курс. |
+ | '''Решение:''' | ||
'''value''' | '''value''' | ||
StudentOf : Course × University → Student - set | StudentOf : Course × University → Student - set | ||
- | StudentOf(c, (s, ci)) | + | StudentOf(c, (s, ci)) ≡ {st | st : Student • (c_i, st) : CourseInfo • ((c_i, st) ∈ ci) } |
- | '''pre''' HasCourse(c, (s, ci)) | + | '''pre''' HasCourse(c, (s, ci)) ≡ True |
- | Неявная | + | Неявная спецификация: |
'''value''' | '''value''' | ||
StudentOf : Course × University → Student - set | StudentOf : Course × University → Student - set | ||
- | '''pre''' HasCourse(c, (s, ci)) | + | '''pre''' HasCourse(c, (s, ci)) ≡ True |
StudentOf(c, (s, ci)) as r | StudentOf(c, (s, ci)) as r | ||
'''post''' | '''post''' | ||
- | + | /* (r, c) ∈ c_i — для случая, если курсы уникальны */ | |
- | & | + | ∀ (c1, ss1) : CourseIno • (c1, ss1) ∈ ci ∧ r &ssub; ss1 ∧ ... |
- | Функция, | + | '''Задача.''' Функция, которая возвращает множество курсов, которые посещает заданный студент. |
+ | |||
+ | '''Решение:''' | ||
'''value''' | '''value''' | ||
Attending : Student × University → Course - set | Attending : Student × University → Course - set | ||
- | Attending(s, (st, ci)) | + | Attending(s, (st, ci)) ≡ {c | c : Course • (c, st_i) : CourseInfo • ((c, st_i) ∈ ci) ∧ (st ∈ st_i) } |
- | Функция newStudent, | + | '''Задача.''' Функция newStudent, добавляющая нового студента и возвращающая обновлённый университет. DropStud — удаляет студента. |
- | + | ||
- | DropStud — удаляет студента | + | |
+ | '''Решение:''' | ||
'''value''' | '''value''' | ||
- | NewStud : University × Student | + | NewStud : University × Student ⥲ University |
- | NewStud((ss, ci), s) | + | NewStud((ss, ci), s) ≡ (ss ∪ {s}, ci) |
'''pre''' s ∉ ss | '''pre''' s ∉ ss | ||
- | DropStud : University × Student | + | DropStud : University × Student ⥲ University |
- | DropStud((ss, ci), s) | + | DropStud((ss, ci), s) ≡ (ss \ {s}, ci_1) |
- | {(ss1, c) : CourseInfo & | + | {(ss1, c) : CourseInfo • (ss1 ∪ s, c) ∈ cis ∧ s ∉ ss1} |
'''pre''' s ∈ ss | '''pre''' s ∈ ss | ||
- | '''post''' s ≠ ss ∧ &orall; (c, ss1) : CourseInfo & | + | '''post''' s ≠ ss ∧ &orall; (c, ss1) : CourseInfo • (c, ss1) ∈ cis → s ∈ cis |
+ | |||
+ | '''Задача.''' Удаление курса. | ||
+ | |||
+ | '''Решение:''' | ||
+ | DelCourse : University × Course → University | ||
{{МФСП}} | {{МФСП}} | ||
- | {{Lection-stub}} |
Текущая версия
В прошлый раз рассматривались типы, операции с ними, производные типы. Разобрались с функциями, константами.
Сейчас: дорешать задачи про функции и перейти к множествам.
Задача. Даны типы:
type position = Real×Real; value origin : Position = (0.0, 0.0) /* начало координат */ dist : Position × Position → Real dist((x_1, y_1), (x_2, y_2)) ≡ ((x_1 - x_2)^2.0 + (y_1 - y_2)^2.0)^0.5
определить: тип circle, функцию on_circle
Решение:
type Circle = Real × Position # радиус, центр value on_circle : Circle × Position → Bool on_circle((r, c_0), c) ≡ (dist(c_0, c) = r)
Задача. Описать окружность с радиусом 3 и центром в начале координат.
value c_3_0_0 : Circle ≡ (3.0, Origin)
Задача. Описать точку, лежащую на этой окружности
Решение:
value d_on_c_3_0_0 : Position • on_circle(c_3_0_0, d_on_c_3_0_0) = True
Задача. Написать функцию sqrt, возвращающую значения, отличные от корня из x не более, чем на ε.
Решение:
value sqrt : Real × Real; ⥲ Real sqrt(a,b) as x post (abs(sqrt(a) - x) ≤ b) && (x ≥ 0) pre (b ≥ 0) && (a ≥ 0)
Задача. Дано определение:
value f: Int ⥲ Int f(x) ≡ f(x)
Удовлетворяет ли этому определению следующее определение:
value f: Int → Int f ≡ 1, chaos, 5 — все три раза да
[править] Множества в RSL
Множество — конечный или бесконечный набор неповторяющихся элементов данного типа.
Обозначение:
{1, 2, 3}
В языке RSL множество определяется следующим образом:
- T - infset — для бесконечных множеств
- T - set — для конечных множеств
Для любого типа определено пустое множество — {}.
Над множеством определены следующие операции: ∩, ∪, ⊂, ⊃, ⊆, ⊇, ∉, ∈, \.
Другие операции:
card — размер множества:
card: T - infset ⥲ Nat card M ≡ |M|
card {} = 0 card {n|n:Nat} ≡ chaos card {1,2,3} ≡ 3
Примеры:
- {"abc", "db", "efo"}
- {1..4} = {1,2,3,4}
- {4..1} = {}
Такое определение множества малоприменимо на практике, поэтому обычно множества определяют через выражения и ограничения:
{expr|limit}
Пример:
{2*n | n:Nat • n < 3} = {0, 2, 4}
Задача: даны типы Student, Course, и призводные типы:
type Student, Course, CourseIno = Course × Student-set University = Student-set × CourseInfo-set
Требуется:
- Определить для университета множество всех студентов (функция AllStudents)
- HasCourse — курс читается в университете
- NumberOk — каждый курс посещают не менее 5 и не более 100 человек
Решение:
value AllStudents : University → Student-set AllStudents ((s,ci)) ≡ s HasCourse : Course × University → Bool HasCourse(c,(s,ci)) ≡ ∃ (c, si) : CourseInfo • (c,si) ∈ ci NumberOk : University → Bool NumberOk((s, ci)) ≡ ∀ (c, s) : CourseInfo • (((c,s) ∈ ci) ⇒ ((card s > 5) ∧ (card s < 100)))
Почему импликация, а не конъюнкция:
value c2 : Course u : University = {{s1, s2, s3, s4, s5, s6}, (c1, {s1, s2, s3, s4, s5, s6})}
При проверки с c=c2 получим false и значение функции false.
Задача. Описать функцию StudentOf, возвращающую множество студентов, посещающих заданный курс.
Решение:
value StudentOf : Course × University → Student - set StudentOf(c, (s, ci)) ≡ {st | st : Student • (c_i, st) : CourseInfo • ((c_i, st) ∈ ci) } pre HasCourse(c, (s, ci)) ≡ True
Неявная спецификация:
value StudentOf : Course × University → Student - set pre HasCourse(c, (s, ci)) ≡ True StudentOf(c, (s, ci)) as r post /* (r, c) ∈ c_i — для случая, если курсы уникальны */ ∀ (c1, ss1) : CourseIno • (c1, ss1) ∈ ci ∧ r &ssub; ss1 ∧ ...
Задача. Функция, которая возвращает множество курсов, которые посещает заданный студент.
Решение:
value Attending : Student × University → Course - set Attending(s, (st, ci)) ≡ {c | c : Course • (c, st_i) : CourseInfo • ((c, st_i) ∈ ci) ∧ (st ∈ st_i) }
Задача. Функция newStudent, добавляющая нового студента и возвращающая обновлённый университет. DropStud — удаляет студента.
Решение:
value NewStud : University × Student ⥲ University NewStud((ss, ci), s) ≡ (ss ∪ {s}, ci) pre s ∉ ss
DropStud : University × Student ⥲ University DropStud((ss, ci), s) ≡ (ss \ {s}, ci_1) {(ss1, c) : CourseInfo • (ss1 ∪ s, c) ∈ cis ∧ s ∉ ss1} pre s ∈ ss post s ≠ ss ∧ &orall; (c, ss1) : CourseInfo • (c, ss1) ∈ cis → s ∈ cis
Задача. Удаление курса.
Решение:
DelCourse : University × Course → University
Формальная спецификация и верификация программ
|
|