Получив бинарные логические базисы, я решил пойти дальше и рассмотреть тернарные. Конечно, с утилитарной точки зрения это действие ненужное. Ведь с помощью любого бинарного базиса можно получить канонический, а он через нормальную форму порождает любую n-арную логическую функцию.
Но я хотел обобщить исходный код и проверить пределы наших пределов, push the limits, так сказать. Тем более поиск бинарных базисов доставил неимоверно. Не ошибся я и с тернарными, и получил большое эстетическое удовлетворение.
Налабал обобщённый код, а он работает слишком медленно. И оттого, что обобщённый, и из-за интерпретированного языка. Тернарных ведь функций - 256, и строить клоны на них уже не шутки (с точки зрения перфоманса).
Ладно, думаю, и сделал ход конём: выделил ядро - замыкание клона - в сишную функцию и прикрутил к схеме через FFI. Транслитерировал списки в массивы, логические функции в индексы массива (!), а действие функций в битовые операции, и всё полетело аки птица. Конечно, сишный код получился в стиле того соревнования на обфускацию си вручную
*, да и заточенным под тернарные функции, зато быстрым.
Тут я задумался: а так ли уж он быстр, и заметил, что оптимизация-то в gcc отключена по умолчанию... В общем, базисы я пока так и не выделил, зато с компиляторами и асмом натрахался и заюзал прожку свою как бенчмарк. Впрочем, это отдельная тема уже.