Логические операторы и функции
Во-первых, булевы функции в среде Mathcad можно определить. Математика (см., например, «Справочник по математике для научных работников и инженеров» Корн Г. и Корн Т.) оперирует одной
одноместной (с одним аргументом) и семью
двухместными (с двумя аргументами) булевыми функциями. Все они определены в пунктах 0-7 на рис. 3.14. Если булеву переменную уподобить выключателю с двумя позициями («вкл» и «выкл»), то конъюнкция
– это последовательное соединение выключателей (пункт), а дизъюнкция – параллельное. Электрический аналог эквиваленции (пункт 3) может очень пригодиться для освещения длинного коридора, свет в котором зажигается и тушится независимо в двух его концах двумя выключателями.
В пункте 8 на рис. 3.14 сформирована трехместная булева функция с именем Решение, возвращающая вердикт жюри из трех человек: решение проходит, когда «за» голосуют двое или трое. Воздерживаться или уклоняться от голосования нельзя.
Функция Решение (программная реализация процедуры голосования) в пункте 8 на рис. 3.14 также имеет электрический аналог (аппаратная реализация – машинка для голосования) – комбинацию выключателей, соединенных последовательно и параллельно.
Двухместные булевы функции (пункты 1-7 на рис 3.14) имеют четыре (22) комбинации значений аргументов (таблица истинности), трехместные – уже 8 (23), одноместная, естественно, только две (21) – 0 или 1. Самих же двухместных булевых функций может быть 16 (42 – мы описали только семь), трехместных уже 64 (43 – мы описали только одну). Одноместных булевых функций четыре (41 – мы описали только одну). Вот другие три одноместные булевы «функции» y2(x):=1, y3(x):=0 и y4(x):=x. Но никакой практической ценности в программировании они не имеют: первые две (y2 и y3) – это константы, а y4 – это просто сам аргумент. Ненаписанные нами остальные девять (16-7) двухместные булевы функции (там тоже есть константы) имен не имеют и, как правило, ни в математике, ни в программировании не применяются.
В математике булева функция выдает два значения (0 – 1, да – нет, истина – ложь и т.д.), в программировании же – минимум три: да, нет и... аварийный останов, связанный с ошибкой (один или несколько аргументов не определены). Такую ошибку можно обработать (в Mathcad для этого служит оператор on error) и пустить расчет по третьему пути. Одноместных булевых функций может быть больше четырех. Как понравится такая функция: y5(x):=if(rnd(1)>0.7, 1, 0), возвращающая единицу с вероятностью 30%, и нуль – с вероятностью 30%.
Функцию Решение можно построить намного проще – вычислить среднее арифметическое значений аргументов. Эту работу выполняет встроенная Mathcad-функция mean. Если оно окажется больше, чем 0.5 – то решение принято (возвращается единица), нет – нуль:
Решение(V):= mean(V) > 0.5
Число аргументов новой функции Решение, таким образом, допустимо увеличивать, не прибегая к сложному дереву булевых операций, показанных в пункте 8 на рис. 3.14.
В пункте 9 на рис. 3.14 формируется еще одна функция Решение для голосования комитета с любым числом членов, принимающих решение большинством голосов. Но при этом часть голосующих обладает правом вето
(пример – Совет Безопасности ООН где, как писал Джорж Оруэл: «все равны, но некоторые равнее»). Люди (или страны: США, Россия, Китай, Франция и Великобритания, если иметь в виду СБ ООН) с правом вето у нас объединены в вектор Const (постоянные члены СБ), а все остальные – в вектор Var. Если для принятия решения большинством голосов годится среднее арифметическое, то для блокировки принятия решения – среднее геометрическое (gmean): корень n-й степени из произведения n сомножителей. Эта встроенная функция появилась только в восьмой версии Mathcad. При этом gmean требует, чтобы все элементы вектора (матрицы) аргумента были ненулевыми. Поэтому в пункте 9 на рис. 3.14 мы сначала переопределили функцию gmean так, чтобы она «проглатывала» и нулевые элементы вектора-аргумента, а потом уже с ее помощью сформулировали функцию Решение для электората типа СБ ООН. В конце пункта 9 показаны три типичных исхода голосования:
— решение принимается большинством голосов;
— решение проваливается одним человеком с правом вето;
— решение не проходит, так как большинство против.
Конечно, использование среднего геометрического для подсчета голосов – это чистой воды извращение (см. название данного этюда). Тут можно использовать функцию And – просто логическое умножение безо всякого корня. В пункте 10 на рис. 3.14 сформулированы функции And и Or, аргументы которых – векторы-столбцы с переменным числом элементов[26].
Этой главке автор хотел дать и другое название – «Казнить нельзя помиловать». Но уж больно оно избитое. Традиционно читателя просят поставить запятую в этом предложении[27]
и проследить, как меняется смысл вердикта в зависимости от места такого невинного знака препинания.
А как вам понравится такой ответ на вопрос о месте запятой: запятую нужно «размазать» по предложению – n процентов запятой поставить после слова «казнить», а 100-n – после слова «нельзя». Трактовать такую новую грамматическую (пунктуалистическую?) конструкцию можно по-разному. Но сначала поговорим о самой постановке вопроса.
Один лидер «третьего рейха» любил повторять, что он всегда хватается за пистолет, слыша слово «культура». Сталкиваясь с логической задачей, программисты «хватаются» за троицу булевых функции Not, And, Or и т.д. Но их-то и нет в списке встроенных
функций Mathcad. Нет там и булевых (логических) переменных. Тут программист чертыхнется (а зря – см. ниже) и напишет соответствующие пользовательские функции (см. пункты 0 – 7 на рис. 3.14), заставляя числовые[28]
переменные выполнять по совместительству и роль булевых. После этого ничего не стоит написать булеву функцию Решение, возвращающую единицу
(логическое «Да») или нуль («Нет») в зависимости от итогов голосования – решение принимается, если двое или трое присяжных проголосуют «За».
Возвращаясь к дилемме «казнить-помиловать» и допуская совмещение должностей присяжного, судьи и палача, можно попытаться заменить в схеме пункта 8 электрическую лампочку на... электрический стул. Говорят, что подобная схема рубильников на самом деле запитывает американское орудие казни. Каждый из трех, приводящих приговор в исполнение, надеется, что он включил не настоящий рубильник, а муляж рубильника.
Еще немного об «электрических цепях». Последнее время в быту получают распространение выключатели, плавно меняющие накал лампочек от нуля до ста процентов. Еще раньше такие устройства (реостаты) стали применяться в театрах и кинозалах. Медики уверяют, что плавный переход от света к темноте через полумрак благотворно влияет на зрение.
А можно ли подобными регуляторами заменить выключатели в вышеприведенной схеме аппаратной реализации процедуры голосования? Может ли функция Решение иметь не только логические, но и вещественные аргументы и возвращать вещественное значение, плавно меняющееся от нуля до единицы (от 0 до 100%)? Очень часто, осуждая или оправдывая кого-либо, трудно прийти к однозначному решению. Даже на первый взгляд явное преступление может иметь такую оценку – «это скорее беда, чем вина подсудимого». Но людей, принимающих решения, по-прежнему заставляют давать только черно-белые оценки[29].
Толерантность[30]
сначала проникла в религию. Человечество, нахлебавшись крови в религиозных войнах[31], относительно поумнело. Сейчас цивилизованный человек может сказать о себе, что он на k процентов атеист, на l процентов мусульманин, на m процентов – католик, а на n процентов – протестант (гугенот – вспомним Варфоломеевскую ночь и Париж, который стоил мессы). И не обязательно, чтобы k+l+n+m равнялось ста процентам. Во многих церквях Америки по пятницам служит мулла, по субботам – раввин, а по воскресеньям – священник (поп, пастор, ксендз) и никого это не шокирует. Затем толерантность охватила мир искусства, размыв систему классических канонов и стилей. Сейчас главное – это талант художника и то, что он хочет сказать миру. И не важно, кто он – реалист, импрессионист (нео-, пост- и т.д.) или просто примитивист, впервые взявшийся за кисть в 70 лет. Теперь стали говорить и о терпимости в науке. Ее проявления – теория нечетких множеств
(fuzzy sets – см. рис. 6.41-6.45 в этюде 6) и теория нечеткой логики (fuzzy logic). Неоднозначность оценок стала превалировать не только в гуманитарных дисциплинах (см. сноску 27 с деликатной подсказкой Word’а), но и в точных науках – в математике, например. Автор где намеренно, а где по незнанию (по недопониманию – хороший пример нечеткого множества в живом языке) не совсем верно трактует положения теории нечетких множеств. Раньше бы такого автора с кашей съели. А теперь ничего – публикуют, читают.
Но это, конечно, не значит, что размываются все грани черно-белых оценок. Об этом хорошо сказано у Пушкина:
Ах! Чувствую: ничто не может нас
Среди мирских печалей успокоить;
Ничто, ничто… едина разве совесть.
Так здравая она восторжествует
Над злобою, над темной клеветою. –
Но если в ней единое пятно,
Единое, случайно завелося,
Тогда – беда! Как язвой моровой
Душа сгорит, нальется сердце ядом,
Как молотком стучит в ушах упрек,
И все тошнит, и голова кружится,
И мальчики кровавые в глазах…
С другой стороны у Ф.М.Достоевского в «Скверном анекдоте» читаем: «Был он и честен, то есть ему не пришлось сделать чего-нибудь особенно бесчестного…».
Давайте посмотрим, как нашу задачу о голосовании можно решить с учетом положений теории нечеткой логики (пункт 10 на рис. 3.14). Задачу можно обогатить элементами нелинейности, приняв во внимание условное деление голосующих на консерваторов (k), традиционно склонных к осуждающим приговорам, центристов (c) и либералов
(l – эль). Степень радикальности жюри присяжных (парламента и вообще любого электората) будем учитывать через коэффициент k. Голосующие устанавливают степень своего решения «за» (от 0 до 1), но на исход голосования влияют функции yk, yc и yl, демпфирующие крайние оценки (см. пункт 10.1).
«Цветная» функция Решение, построенная на функциях min и max (см. пункт 10.2), при логических значениях аргументов (0 или 1) полностью эквивалентна своему «черно-белому» аналогу, использующему функции And и Or (см. пункт 8). Встроенные функции min и max способны работать и с логическими, и с вещественными, и даже с комплексными[32]
аргументами. Кроме того, функции min и max удобны еще и тем, что их аргументами может быть вектор-столбец (аргумент функции max в пункте 10.2), вектор-строка (min) и даже матрица (см. рис. 6.34 в этюде 6). Это позволяет комбинировать типы аргументов (горизонталь-вертикаль) создаваемой «цветной» логической функции, делая ее более компактной и более легкой для понимания. (Здесь вызывается не функция, а постфиксный оператор – это позволяет убрать лишние скобки.)
Ладно, скажет читатель, а что делать с вердиктом присяжных такого рода: «Виновен на 57%, невиновен на 43%»? Что делать? Смотреть на графики, материализующие «цветное» решение!
В пункте 10.2 на рис. 3.14 визуализированы вердикты присяжных при фиксированном решении либерала 0.5 (воздержался – ни то ни се).
Интерпретация цвета участков поверхности решения (здесь, к сожалению, не цвета, а оттенки серого) может быть такая:
- красный цвет графика говорит сам за себя – кровь, «вышка»;
- оранжевый – пожизненное заключение;
- желтый – каторга;
- зеленый – тюремное заключение;
- голубой – условное осуждение;
- синий – общественное порицание;
- фиолетовый – невинен.
Цветовую палитру («Каждый охотник желает знать, где сидят фазаны!») можно сдвигать, учитывая тенденции в общественном сознании и изменения в законодательстве – мораторий на смертную казнь, например. При этом нужно будет «сдвигать вниз» (в холодные тона) и другие виды наказаний. В наших тюрьмах условия содержания такие, что смертная казнь может оказаться просто наградой. Основной довод противников смертной казни в том, что жизнь – это Дар Божий, и только всевышний может приговорить к высшей мере. Но и свобода не меньший дар! Второй довод в том, что смертная казнь делает невозможным исправление судебных ошибок. Но. Отсидел человек 20 лет в камере пожизненного заключения, а ему говорят, пардон, мы ошиблись. Кто вернет загубленную жизнь.
Строить «цветные» логические схемы поможет и нечеткая функция Not:
Not(x):=½1-x½ или ½100-x½.
В пункте 10.3 на рис. 3.14 функции max и min заменены на их «аналоги» – на функции mean (среднее арифметическое) и gmean (среднее геометрическое). Поверхность стала более гладкой – природа, как мы знаем, не терпит острых углов.
В пункте 11 на рис. 3.14 сформированы многомерные функции And и Oг. Но записать допустимо еще проще:
And(x):=min(x) Or(x):=max(x),
А можно работать только с min и max, которые хорошо справляются и с булевыми (четкая логика), и с вещественными (нечеткая логика) аргументами. Но если пользователь оптимизирует программу (см. главку 6.12), то вместо функции min лучше использовать оператор умножения. Дело в том, что при умножении сразу возвращается нуль, если первый сомножитель нулевой. Функция же min излишне педантична – она перебирает все элементы своего аргумента-матрицы (вектора).
Но увлекаться статистическими функциями (min, max, mean, gmean, rnd, var и др.) при реализации логических схем нужно осторожно. Уинстон Черчиль говорил, что есть Большая Ложь, Просто Ложь и… Статистика – героиня этого этюда.