Примеры моноидов/полугрупп в программировании

Хорошо известно, что моноиды невероятно распространены в программировании. Они настолько вездесущи и настолько полезны, что я в качестве «хобби-проекта» работаю над системой, полностью основанной на их свойствах (распределенная агрегация данных). Чтобы система была полезной, мне нужны полезные моноиды :)

Я уже знаю о них:

  • Числовая или матричная сумма
  • Числовое или матричное произведение
  • Минимум или максимум в общем порядке с верхним или нижним элементом (в более общем случае соединение или встреча в ограниченной решетке или, в более общем случае, продукт или побочный продукт в категории)
  • Установить союз
  • Объединение карт, где конфликтующие значения объединяются с помощью моноида
  • Пересечение подмножеств конечного множества (или просто пересечение множеств, если мы говорим о полугруппах)
  • Пересечение карт с ограниченным ключевым доменом (то же самое здесь)
  • Слияние отсортированных последовательностей, возможно, с объединением значений, равных ключу, в другом моноиде/полугруппе.
  • Ограниченное слияние отсортированных списков (то же, что и выше, но мы берем верхнее N результата)
  • Декартово произведение двух моноидов или полугрупп
  • Объединение списков
  • Композиция эндоморфизмов.

Теперь давайте определим квазисвойство операции как свойство, которое выполняется до отношения эквивалентности. Например, конкатенация списков является квазикоммутативной, если мы считаем эквивалентными списки одинаковой длины или с идентичным содержимым вплоть до перестановки.

Вот некоторые квазимоноиды и квазикоммутативные моноиды и полугруппы:

  • Любая (a+b = a или b, если считать все элементы множества носителей эквивалентными)
  • Любой удовлетворяющий предикат (a + b = тот из a и b, который не равен нулю и удовлетворяет некоторому предикату P, если ни один не соответствует нулю; если мы считаем, что все элементы, удовлетворяющие P, эквивалентны)
  • Ограниченная смесь случайных выборок (xs+ys = случайная выборка размера N из объединения xs и ys; если мы считаем, что любые две выборки с тем же распределением, что и весь набор данных, эквивалентны)
  • Ограниченная смесь взвешенных случайных выборок
  • Назовем это «топологическим слиянием»: учитывая два ациклических и непротиворечивых графа зависимостей, граф, который содержит все зависимости, указанные в обоих. Например, составьте «конкатенацию», которая может привести к любой перестановке, в которой элементы каждого списка следуют по порядку (скажем, 123+456=142356).

Какие другие существуют?


person jkff    schedule 20.03.2010    source источник
comment
Я откатил изменения в тегах, т.к. имхо вопрос совсем не в функциональном программировании.   -  person jkff    schedule 21.03.2010
comment
Оффтоп: Как сложить моноид с помощью параллельных вычислений?   -  person Andrey Vlasovskikh    schedule 01.04.2010
comment
@Andrey Если моноид коммутативен, вы можете просто складывать значения в произвольном порядке, на произвольных потоках/процессорах/машинах, пока не останется только одно значение (или вы можете сделать так, чтобы оно оставалось 1 значением на машину и каким-то образом суммировать их только во время доступ для чтения и др.). Я собираюсь использовать только коммутативные моноиды. Если моноид некоммутативный, то значения суммируются с помощью сбалансированного дерева, построенного по списку значений: уровни проходятся последовательно, но узлы на каждом уровне могут сокращаться параллельно. См. также работы Гая Блеллоха о векторном параллелизме.   -  person jkff    schedule 01.04.2010


Ответы (4)


Частотный моноид — это еще один способ формирования моноидов (квазимоноидов?): задан моноид M и эквивалентность отношение ~ совместимо с умножением, оно дает еще один моноид. Например:

  • конечные мультимножества с объединением: если A* — свободный моноид (списки с конкатенацией), ~ — отношение «перестановка», то A*/~ — свободный коммутативный моноид.

  • конечные множества с объединением: если ~ изменить, чтобы игнорировать количество элементов (так что «аа» ~ «а»), то A*/~ является свободным коммутативным идемпотентным моноидом.

  • синтаксический моноид: любой регулярный язык порождает синтаксический моноид, являющийся частным от A* по отношению "неразличимость по языку". Вот реализация этой идеи в виде дерева пальцев. Например, язык {a3n:n natural} имеет Z3 в качестве синтаксического моноида.

Фактормоноиды автоматически приходят с гомоморфизмом M -> M/~, который является сюръективным.

«Двойственной» конструкцией являются субмоноиды. Они приходят с гомоморфизмом A -> M, который является инъективным.

Еще одна конструкция на моноидах — это тензорное произведение.

Моноиды позволяют возводить в степень путем возведения в квадрат за O(log n) и быстрого параллельного вычисления префиксных сумм. Также они используются в монаде Writer.

person sdcvvc    schedule 20.03.2010
comment
Спасибо; Не могли бы вы рассказать что-нибудь о полезности тензорного произведения? В статье не было примеров, а я не настолько крут в алгебре, чтобы самому их придумывать :) - person jkff; 23.03.2010

Стандартную библиотеку Haskell то хвалят, то критикуют за использование фактических математических терминов для ее классов типов. (На мой взгляд, это хорошо, так как без него я бы даже не узнал, что такое моноид!). В любом случае вы можете проверить http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html еще несколько примеров:

  • the dual of any monoid is a monoid: given a+b, define a new operation ++ with a++b = b+a
  • conjunction and disjunction of booleans
  • over the Maybe monad (aka "option" in Ocaml), first and last. That is,
    first (Just a) b = Just a
    first Nothing b = b
    and likewise for last

Последнее является лишь верхушкой айсберга целого семейства моноидов, связанных с монадами и стрелками, но я не могу понять их (кроме просто монадических эндоморфизмов). Но поиск в Google по monads monoids дает совсем немного.

person Steve    schedule 20.03.2010
comment
Точно, я совсем забыл о двойных и логических значениях! Что касается монады Maybe, то пример по существу упоминается как Любой удовлетворяющий предикат. Эндоморфизмы монад также являются хорошей идеей. - person jkff; 21.03.2010

Действительно полезным примером коммутативного моноида является унификация в языках логики и ограничений. См. раздел 2.8.2.2 книги «Концепции, методы и модели компьютерного программирования» для точного определения возможного алгоритма унификации.

Удачи вам в изучении языка! Я делаю что-то подобное с параллельным языком, используя моноиды для слияния подрезультатов параллельных вычислений.

person Daira Hopwood    schedule 28.05.2012

Вычисление значения римской цифры произвольной длины. https://gist.github.com/4542999

person Chad Brewbaker    schedule 16.01.2013