Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
- | [[Математическая Логика, 05 семинар (от 21 ноября)|Предыдущий семинар]] | [[Математическая Логика, 07 семинар (от 19 декабря)|Следующий семинар]]
| + | == From Ebaums Inc to MurkLoar. == |
- | | + | We at EbaumsWorld consider you as disgrace of human race. |
- | === Задача 4.5 === | + | Your faggotry level exceeded any imaginable levels, and therefore we have to inform you that your pitiful resourse should be annihilated. |
- | Проверить вхождение одного списка в другой в качестве подсписка.
| + | Dig yourself a grave - you will need it. |
- | ? check_sublist(x,y)
| + | |
- | | + | |
- | ==== Решение ====
| + | |
- | check_sublist(nil, x) ← ;
| + | |
- | check_sublist(x, x) ← ;
| + | |
- | check_sublist(x<sub>1</sub> . x, x<sub>1</sub> . y) ← check_sublist(x, y);
| + | |
- | check_sublist(x<sub>1</sub> . x, y<sub>1</sub> . y) ← x<sub>1</sub> ≠ y<sub>1</sub>, check_sublist(x<sub>1</sub> . x, y);
| + | |
- | | + | |
- | === Задача 4.6 ===
| + | |
- | Обратить список.
| + | |
- | ? reverse(x,y)
| + | |
- | | + | |
- | ==== Решение ====
| + | |
- | reverse(nil, nil) ← ;
| + | |
- | reverse(x . y, z) ← reverse(y, z<sub>1</sub>), concat(z<sub>1</sub>, x . nil, z);
| + | |
- | | + | |
- | == Расширение возможностей логического программирования ==
| + | |
- | | + | |
- | Повышение удобства работы.
| + | |
- | | + | |
- | === Встроенные предикаты ===
| + | |
- | Некоторые выражения удобно вычислять без использования SLR-резолюции.
| + | |
- | | + | |
- | ==== Отношение равенства ====
| + | |
- | Отношение равенства: =<sup>(2)</sup> — двуместный предикат.
| + | |
- | | + | |
- | Пример записи: t<sub>1</sub> = t<sub>2</sub>
| + | |
- | | + | |
- | Что подразумевает равенство? Если интерпретатор видит, что очередной подцелью является равенство, то он пытается найти наиболее общий унификатор (НОУ), и, если он есть, то это успех. Другими словами, решается уравнение t<sub>1</sub> = t<sub>2</sub>.
| + | |
- | | + | |
- | * Например, x + 2 = 3 + y, НОУ — {<sup>x</sup>/<sub>3</sub>, <sup>y</sup>/<sub>2</sub>} — успех
| + | |
- | * Другой пример — 2 + 3 = 5, НОУ(2 + 3, 5) = ∅, синтаксического совпадения не будет (требуется решение в свободной алгебре термов, без интерпретации)
| + | |
- | | + | |
- | ==== Тождество ====
| + | |
- | Тождество: ==<sup>(2)</sup>
| + | |
- | | + | |
- | Он круче. Будет успех, если t<sub>1</sub> совпадает с t<sub>2</sub>.
| + | |
- | | + | |
- | ==== Неравенство ====
| + | |
- | Неравенство: ≠<sup>(2)</sup>
| + | |
- | | + | |
- | Разрешаетя успешно, если нет НОУ.
| + | |
- | | + | |
- | ==== Нетождество ====
| + | |
- | Нетождество: =/=<sup>(2)</sup>
| + | |
- | | + | |
- | Разрешается успешно с пустой подстановкой, если t<sub>1</sub> и t<sub>2</sub> синтаксически различны.
| + | |
- | | + | |
- | === Задача 4.8 (использование предиката нетождество) ===
| + | |
- | Построить пересечение множеств, представленных бесповторными списками.
| + | |
- | ? common(x,y,z)
| + | |
- | | + | |
- | ==== Решение ====
| + | |
- | common(nil, L, nil) ← ;
| + | |
- | common(L, nil, nil) ← ;
| + | |
- | common(x . L<sub>1</sub>, L<sub>2</sub>, x . L<sub>3</sub>) ← elem(x, L<sub>2</sub>), common(L<sub>1</sub>, L<sub>2</sub>, L<sub>3</sub>);
| + | |
- | common(x . L<sub>1</sub>, L<sub>2</sub>, L<sub>3</sub>) ← nonelem(x, L<sub>2</sub>), common(L<sub>1</sub>, L<sub>2</sub>, L<sub>3</sub>);
| + | |
- |
| + | |
- | nonelem(x, y . z) ← x =/= y, nonelem(x, z);
| + | |
- | nonelem(x, nil) ← ;
| + | |
- | | + | |
- | === Задача 4.10 (введение дооплнительных функций для хранения вспомогательной информации) ===
| + | |
- | Построитьсписок L2,состоящий из тех и только тех элементов списка L1, которые содержатся в нем однократно.
| + | |
- | ? single(L1,L2)
| + | |
- | | + | |
- | ==== Решение ====
| + | |
- | Казалось бы, решение должно быть таким:
| + | |
- | single(x . L1, x . L2) ← nonelem(x, L1), single(L1, L2);
| + | |
- | single(x . L1, L2) ← elem(x, L1), single(L1, L2);
| + | |
- | single(nil, nil) ← ;
| + | |
- | Но эта программа решает дргую задачу — построение списка, в котором каждый из элементов списка L1 входит ровно один раз.
| + | |
- | На самом деле, правильное решение следующее:
| + | |
- | single(L<sub>1</sub>, L<sub>2</sub>) ← R(L<sub>1</sub>, nil, L<sub>2</sub>);
| + | |
- | R(nil, L<sub>2</sub>, nil) ← ;
| + | |
- | R(x . L<sub>2</sub>, L<sub>2</sub>, x . L<sub>3</sub>) ← nonelem(x, L<sub>1</sub>), nonelem(x, L<sub>2</sub>), R(L<sub>1</sub>, L<sub>2</sub>, L<sub>3</sub>);
| + | |
- | R(x . L<sub>1</sub>, L<sub>2</sub>, L<sub>3</sub>) ← elem(x, L<sub>1</sub>), R(L<sub>1</sub>, x . L<sub>2</sub>, L<sub>3</sub>)
| + | |
- | R(x . L<sub>1</sub>, L<sub>2</sub>, L<sub>3</sub>) ← elem(x, L<sub>2</sub>), R(L<sub>1</sub>, L<sub>2</sub>, L<sub>3</sub>);
| + | |
- | В этом решении вводится дополнительный список, в котором хранятся те элементы, котрые входят в L<sub>1</sub> более одного раза. Для хранения этого списка вводится дополнительная функция R, где он передаётся в качестве параметра.
| + | |
- | | + | |
- | == Домашнее задание ==
| + | |
- | Задача 4.9
| + | |
- | | + | |
- | === Задача 4.9 ===
| + | |
- | Построить список L3, состоящий из всех тех и только тех элементов списка L1, которые не содержатся в списке L2
| + | |
- | ? sieve(L1 ,L2, L3)
| + | |
- | | + | |
- | ==== Решение ====
| + | |
- | sieve(L1, nil, L1) ← ;
| + | |
- | sieve(x . L1, L2, x . L3) ← nonelem(x, L2), nonelem(x, L3), sieve(L1, L2, L3);
| + | |
- | sieve(x . L1, L2, L3) ← sieve(L1, L2, L3);
| + | |
- | | + | |
- | == Предикаты, расширяющие вычислительные возможности логических программ ==
| + | |
- | | + | |
- | === Предикаты сравнения ===
| + | |
- | | + | |
- | Для данных типа INTEGER разумно ввести операции сравнения: <, ≤, ≥, >. Тогда мы должны описать операционную семантику. Если текущая подцель — сравнение, то тогда он спрашивает, а правда ли, что t<sub>1</sub>, t<sub>2</sub> — числа, и если числа, то правда, что выполняется отношение сравнения для этих чисел? Если да, то успех с пустой подстановкой.
| + | |
- | | + | |
- | Пример:
| + | |
- | * ? 2 ≤ 3 → success
| + | |
- | * ? x ≤ x + 1 → failure — сравнивать можно только чилса
| + | |
- | * 1 ≤ 2 + 3 → failure; — в правой части — выражение
| + | |
- | | + | |
- | === Задача 1.1 (применение функций сравнения) ===
| + | |
- | Проверить, является ли заданный целочисленный список L упорядоченным.
| + | |
- | ? ordered(L)
| + | |
- | | + | |
- | ==== Решение ====
| + | |
- | ordered(nil) ← ;
| + | |
- | ordered(x . nil) ← ;
| + | |
- | ordered(x . y . L) ← x ≤ y, ordered(y . L);
| + | |
- | | + | |
- | === Задача 1.2 ===
| + | |
- | Для заданного целочисленного списка L отыскать его наибольший элемент.
| + | |
- | ? max(L,x)
| + | |
- | | + | |
- | ==== Решение ====
| + | |
- | max(x . nil, x) ← ;
| + | |
- | max(x . L, x) ← max(L, y), y ≤ x;
| + | |
- | max(x . L, y) ← max(L, y), x < y;
| + | |
- | | + | |
- | Подсчитаем количество операций. В худшем случае их будет 2<sup>len(L)</sup>. Если мы модифицируем решение (сделав рекурсию хвостовой), то получим линейную сложность:
| + | |
- | | + | |
- | max(x . nil, x) ← ;
| + | |
- | max(x . L, y) ← max3(L, x, y);
| + | |
- | max3(nil, x, x) ←
| + | |
- | max3(x . L, y, z) ← x ≤ y, max3(L, y, z);
| + | |
- | max3(x . L, y, z) ← max3(L, x, z);
| + | |
- | | + | |
- | Если нужны дополнительные переменные, которые хранят накапливаемые данные, то введите дополнительные предикаты.
| + | |
- | | + | |
- | === Вычислительные функции ===
| + | |
- | | + | |
- | Есть функции +, −, ×, div, mod, … Но их надо заставить вычислиться.
| + | |
- | | + | |
- | Предикат, который занимается вычислениями: is<sup>(2)</sup>
| + | |
- | | + | |
- | ? t<sub>1</sub> is t<sub>2</sub>
| + | |
- | ↓ {<sup>t<sub>1</sub></sup>/<sub>val(t<sub>2</sub>)</sub>}
| + | |
- | success
| + | |
- | | + | |
- | Спецификация операционной семантики:
| + | |
- | # t<sub>1</sub> ∈ Var
| + | |
- | # t<sub>2</sub> — арифметическое выражение, имеющеезначение, которое можно вычислить (val(t<sub>2</sub>))
| + | |
- | # Выполнить подстановку <sup>t<sub>1</sub></sup>/<sub>val(t<sub>2</sub>)</sub>
| + | |
- | | + | |
- | Пример:
| + | |
- | ? x is 3 × (2 + 1)
| + | |
- | ↓ {<sup>x</sup>/<sub>9</sub>}
| + | |
- | success
| + | |
- | | + | |
- | ? x is y + 1
| + | |
- | failure
| + | |
- | y — переменная, у неё неопределённое значение
| + | |
- | | + | |
- | ? x is x + 1
| + | |
- | failure
| + | |
- | | + | |
- | ? y = 3 + 2, z + 1 = 4 + u, x is z + y
| + | |
- | ↓ {<sup>y</sup>/<sub>3 + 2</sub>}
| + | |
- | ? z + 1 = 4 + u, x is z + (3 + 2)
| + | |
- | ↓ {<sup>z</sup>/<sub>4</sub>, <sup>u</sup>/<sub>1</sub>}
| + | |
- | ? x is 4 + (3 + 2)
| + | |
- | ↓ {<sup>x</sup>/<sub>9</sub>}
| + | |
- | success
| + | |
- | | + | |
- | === Задача 2.2 (Применение арифметических предикатов) ===
| + | |
- | Вычисления суммы элементов целочисленного списка L.
| + | |
- | ? sum(L,x)
| + | |
- | | + | |
- | ==== Решение ====
| + | |
- | sum(nil, 0) ← ;
| + | |
- | sum(x . l, y) ← sum(L, z), y is x + z;
| + | |
- | | + | |
- | {{Математическая Логика}}
| + | |