Для ее работы не требуются никакие дополнительные библиотеки. Из стандартных include-файлов подключается только stdlib.h. Динамическое выделение памяти также не используется. Даже при конвертировании объектов в строку (методы toString классов SC и BP) используется всегда один и тот же массив, выделяемый статически. С одной стороны, это создает определенные неудобства для пользователя, с другой - уменьшает риск возникновения ``утечек памяти``, (подробнее - см. далее).
В заголовочном файле описан тип кортежа:
typedef unsigned char corteg;а также два класса:
class SC{..} // Set of Corteges (множество кортежей)и
class BP{..} // Boolean polynoms (булевы полиномы)
Настройка пакета на работу с булевыми многочленами от данного количества переменных осуществляется с помощью константы nVar, определенной в файле booleanf.h:
#define nVar 8 // the number of boolean variablesТаким образом, количество булевых переменных задается один раз и до конца работы программы. Это, конечно же, является недостатком реализации но, с другой стороны, заметно упрощает работу с системой. В реальных задачах, где приходилось использовать булевы полиномы, количество исходных переменных всегда оставалось одним и тем же, поэтому указанный недостаток не являлся существенным.
Обычно в наших примерах nVar будет равно 8, то есть кортеж является байтом, но не исключаются и другие варианты. Кортеж определяется беззнаковым числом, лежащим в пределах от 0 до 2nVar-1. Поэтому при nVar ≤ 8 кортеж представлен байтом (unsigned char), при nVar ≤ 16 - беззнаковым коротким числом (unsigned short), при nVar ≤ 32 - беззнаковым целым(unsigned). Никаких особых операций над кортежами, помимо обычных арифметических и битовых операций над беззнаковыми числами мы пока не определяем.
void set0(); // this = 0 void ins(corteg a); // добавить к множеству кортеж a void join (SC &s); // добавить к this множество s void inters(SC &s); // this := this пересечение с множеством s void xor (SC &s); // this := this XOR s bool get(corteg a); // входит ли кортеж a в множество bool isBitSymmetric( int k ); // симметрично ли множество // относительно бита k int weight(); // количество элементов в множестве char *toString();
Они достаточно очевидны и не требуют особых комментариев, кроме последнего (toString). Чтобы не сталкиваться с проблемами выделения и освобождения памяти, эта функция строит ответ всегда в одной и той же статически созданной строке и именно её возвращает в качестве результата. Это удобно, так как пользователю не надо заботиться ни о выделении, ни об освобождении памяти. С другой стороны, это приводит к невозможности одновременного использования двух и более объектов в одном выражении, типа
printf( "s=%s; t=%s\n", s.toString(), t.toString() );
Булевы полиномы - это суммы некоторого количества мономов. Каждый моном определяется списком переменных, в него входящих, то есть некоторым кортежем. Поэтому как множество, булев полином - то же самое, что и множество кортежей. Различаются они набором операций и методов.
Замечание. Каждому кортежу b длины N соответствует булев моном M(b) от переменных (x0, ... , xnVar-1), например
M(10010011) = x0 * x1 * x4 * x7Значение монома M(b) на кортеже a равно 1, если b&a==b. В противном случае это значение равно 0.
Основные методы класса:
void set0(); // обнулить полином void set1(corteg a); // коэффициент при мономе a := 1 void add1(corteg a); // прибавить моном a к полиному void add(BP &b); // this += b void mult(BP &b, BP &c); // this = b*c bool get(corteg a); // значение полинома в точке a void values(SC &r); // r:= значение полинома во всех точках void Roots (SC &r); // r:= множество корней полинома void OneUnit(corteg a); // строим полином равный 1 в точке a // и 0 в остальных void OneRoot(corteg a); // строим полином равный 0 в точке a // и 1 в остальных void or(BP &b, BP &c); // this = b OR c void givenRoots(SC &r); // строим полином с данным набором корней void givenUnits(SC &r); // строим полином с данным набором единиц // (т.е. не корней) char *toString();
Единственная требуемая настройка пакета - выбор количества булевых переменных. Она осуществляется с помощью константы nVar, определенной в файле booleanf.h:
#define nVar 8 // the number of boolean variablesТаким образом, количество булевых переменных задается один раз и до конца работы программы.
В зависимости от величины nVar тип corteg имеет разные определения:
#if nVar<= 8 typedef unsigned char corteg; // <= BYTE #elif nVar<= 16 typedef unsigned short corteg; // <= __in16 #elif nVar<= 32 typedef unsigned corteg; // <= __in32 #elif nVar<= 64 typedef unsigned __int64 corteg;// <= __in64 #else #error nVar too large #endif
Таким образом, константа nVar не должна принимать значения, большие 64. На самом деле, при nVar > 32 объекты типов SC и BP потребуют слишком много памяти и работа с ними может быть затруднена или вообще невозможна. Даже при nVar=32 следует очень осторожно подходить созданию объектов из этих классов.
#include "BP.h" ... SC s, t; s.ins(7); s.ins(17); s.ins(200); printf( "s=%s>\n", s.toString() );
Будет выведено на экран множество, состоящее из трех элементов: {7,17,200}.
#include "BP.h" ... BP f; SC r; f.add1(2);f.add1(5); printf( "f=<%s>\n", f.toString() ); f.Roots(r); printf( "r=<%s>\n", r.toString() ); f.givenRoots(r); printf( "F=<%s>\n", f.toString() );