- •Лекция 6: логические схемы на основе булевых функций (процедурный подход к построению сии)
- •Теорема
- •1 Способ:
- •Составление логических схем
- •Примеры синтеза контактных схем
- •1 Способ
- •2 Способ
- •Пролог. Рекурсивные методы решения задач
- •Задача о размещениях (факториал)
- •Задача о числах Фибоначчи
- •Задача о ханойской башне
Составление логических схем
Применение пропозициональных формул к контактным схемам
Каждой пропозициональной переменной ставится в соответствие выключатель, в исходном положении размыкающий цепь (рис1.a).
Отрицанию пропозициональной переменной ставится в соответствие выключатель, в исходном положении замыкающий цепь (рис1.b).
Конъюнкции p & q ставится в соответствие схема с последовательным соединением выключателей (рис1.c).
Дизъюнкции p V q ставится в соответствие схема с параллельным соединением выключателей (рис1.d).
Одной и той же пропозициональной переменной (и ее отрицанию) несколько раз входящей в формулу, ставится выключатели, связанные между собой механически, т.е. работающие синхронно (рис1.e).
Рис 1. Соответствие схем переключателей логическим переменным и формулам
Примеры синтеза контактных схем
Пример 1.
В 2-х комнатах есть выключатели. Необходимо разработать такую схему, которая позволяла переключателем любой из них включать и выключать свет.
Запишем таблицу для возможных состояний.
p |
q |
Состояние лампы |
0 |
0 |
0 - выкл |
0 |
1 |
1 - вкл |
1 |
0 |
1 - вкл |
1 |
1 |
0 - выкл |
1 Способ
Для второй и третьей строк записываем
(p0)&(q1) V (p1)&(q0) = p & q V p & q
2 Способ
Для первой и четвертой строк записываем
((p0)V(q0))&((p1)V(q1)) = (p V q) & ( p V q)
Рис. 2 Реализация схемы: a) по первому варианту; b) по второму варианту
Пример 2.
Разработать схему голосования трех судей. Если два любых судьи "за", то лампа зажигается.
Составим таблицу истинности.
|
a & b & c V a & b & c V a & b & c V a & b & c
|
Рис. 3. Схема голосования
Можно ли ее упростить?
Пролог. Рекурсивные методы решения задач
План
Рекурсия
Задача о размещениях (факториал)
Задача о сумме
Задача о кроликах (числа Фибоначчи)
Задача о Ханойской башне
Задача о предках и правнуках
Рекурсия является мощным средством программирования. В Прологе она приобретает особую важность, поскольку в нем отсутствуют циклические конструкции while .. do и repeat .. until, присущие обычным языкам программирования.
Рекурсия это сведение решения задачи к ней же, но меньшей размерности. Новую задачу можно свести к еще меньшей размерности и этот процесс продолжается до тех пор, пока задача не станет настолько простой, что ее можно решить непосредственно. Способ, при котором решение состоит из двух фаз: первая фаза – разбиения на подзадачи, вторая фаза – решение подзадач, называется нисходящей стратегией. Он прост, но не всегда эффективен. Главный недостаток – большой расход памяти. При каждом рекурсивном вызове динамически выделяется участок памяти для всех переменных.
Иногда удается построить решение, начав с простого случая, поднимаясь вверх по иерархии подзадач, пока не будет решена исходная задача. Такой подход называется восходящей стратегией. Тогда рекурсивный вызов – последний оператор в правиле, и запоминать значения переменных нет надобности. Все сведения передаются как параметры. Поэтому, если можно записать решение задачи поднимаясь от простого решения к более сложному, то надо переходить к решению задачи методом восходящей рекурсии.
Вообще, любая рекурсивная процедура должна содержать хотя бы одну из двух компонент:
1. Нерекурсивную фразу, определяющую правило, применяемое в момент прекращения рекурсии.
2. Рекурсивное правило, первая подцель которого вырабатывает новые значения аргументов, а вторая – рекурсивная подцель – использует эти значения.
База правил просматривается сверху вниз. Сначала делается попытка выполнения нерекурсивной фразы. Если условие окончания рекурсии не указано, то правило может работать бесконечно.
Например, имеются следующие факты о том, какая валюта котируется выше:
doroje(dollar, rubl). - дороже
doroje(evro, rubl).
doroje(rubl, iena).
doroje(funt, euro).
Выполним запрос:
? doroje(evro, rubl).
Yes
Будет получен утвердительный ответ, поскольку такой факт явно описан в программе. Если же сделать запрос,
? doroje(evro, iena).
То ответ будет отрицательный, поскольку такой факт отсутствует. Аналогичным будет ответ на вопрос:
? doroje(funt, rubl).
Избежать противоречий здесь можно введением правила, в котором допустимо сравнение между собой не только двух, но и трех объектов:
doroje1(X, Y):- doroje(X, Y). /* два объекта */
doroje1(X, Y):- doroje(X, Z), doroje(Z, Y). /* три объекта */
Второе правило описывает, очевидно, вариант, когда X>Z, а Z>Y, откуда делается вывод, что X>Y.
Однако цепочка взаимных сравнений может быть длинной. Например, при четырех сравнениях потребуется конструкция:
doroje2(X, Y):- doroje(X, M), doroje(M, K), doroje(K, Z), doroje(Z, Y).
Описывать такие длинные правила неудобно. Здесь выгоднее применить рекурсию, обратившись к правилу из самого этого правила:
doroje1(X, Y):- doroje(X, Y).
doroje1(X, Y):- doroje(X, Z), doroje1(Z, Y).
Первое предложение в этой конструкции определяет момент прекращения рекурсивных вызовов.
Второе правило описывает возможности рекурсивных вызовов, когда существуют непроверенные варианты решения.
