{"id":829,"date":"2018-12-12T04:46:20","date_gmt":"2018-12-12T04:46:20","guid":{"rendered":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/?p=829"},"modified":"2021-10-02T18:42:59","modified_gmt":"2021-10-02T17:42:59","slug":"united-monoids","status":"publish","type":"post","link":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/united-monoids\/","title":{"rendered":"United Monoids"},"content":{"rendered":"<p>In this blog post we will explore the consequences of postulating\u00a0<span style=\"color: #000080\">0\u00a0=\u00a01<\/span> in an algebraic structure with two binary operations\u00a0<span style=\"color: #000080\">(S,\u00a0+,\u00a00)<\/span> and <span style=\"color: #000080\">(S,\u00a0\u22c5,\u00a01)<\/span>. Such <em>united monoids<\/em>\u00a0have a few interesting properties, which are not immediately obvious. For example, we will see that the axiom\u00a0<span style=\"color: #000080\">0\u00a0=\u00a01<\/span>\u00a0is equivalent to a seemingly less extravagant axiom <span style=\"color: #000080\">ab\u00a0=\u00a0ab\u00a0+\u00a0a<\/span>, which will send us tumbling down the rabbit hole of <a href=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/an-algebra-of-graphs\/\">algebraic graphs<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Simplicial_complex\">topology<\/a>.<\/p>\n<p><!--more--><\/p>\n<p>We start with a brief introduction to monoids, rings and lattices. Feel free to jump straight to the section <a href=\"#whatif\">&#8220;What if 0\u00a0=\u00a01?&#8221;<\/a>, where the fun starts.<\/p>\n<h4>Monoids<\/h4>\n<p>A <a href=\"https:\/\/en.wikipedia.org\/wiki\/Monoid\">monoid<\/a>\u00a0<span style=\"color: #000080\">(S,\u00a0\u2218,\u00a0e)<\/span>\u00a0is a way to express a basic form of composition in mathematics: any two elements <span style=\"color: #000080\">a<\/span> and <span style=\"color: #000080\">b<\/span> of the set <span style=\"color: #000080\">S<\/span>\u00a0can be composed into a new element <span style=\"color: #000080\">a\u00a0\u2218\u00a0b<\/span> of the same set <span style=\"color: #000080\">S<\/span>, and furthermore there is a special element\u00a0<span style=\"color: #000080\">e\u00a0\u2208\u00a0S<\/span>, which is the <em>identity\u00a0element<\/em> of the composition, as expressed by the following <em>identity axioms<\/em>:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a \u2218 e = a<br \/>\ne \u2218 a = a<\/span><\/p>\n<p>In words, composing the identity\u00a0element with another element does not change the latter. The identity element is sometimes also called <em>unit.<\/em><\/p>\n<p>As two familiar everyday examples, consider addition and multiplication over <a href=\"https:\/\/en.wikipedia.org\/wiki\/Integer\">integer numbers<\/a>: <span style=\"color: #000080\">(\u2124,\u00a0+,\u00a00)<\/span> and <span style=\"color: #000080\">(\u2124,\u00a0\u22c5,\u00a01)<\/span>. Given any two integers, these operations produce another integer, e.g.\u00a0<span style=\"color: #000080\">2\u00a0+\u00a03\u00a0=\u00a05<\/span> and <span style=\"color: #000080\">2\u00a0\u22c5\u00a03\u00a0=\u00a06<\/span>, never leaving the underlying set of integers <span style=\"color: #000080\">\u2124<\/span>; they also respect the identity axioms, i.e. both\u00a0<span style=\"color: #000080\">a\u00a0+\u00a00 = 0\u00a0+\u00a0a\u00a0=\u00a0a<\/span> and <span style=\"color: #000080\">a\u00a0\u22c5\u00a01 = 1\u00a0\u22c5\u00a0a\u00a0=\u00a0a<\/span>\u00a0hold for all integers\u00a0<span style=\"color: #000080\">a<\/span>. Note: from now on we will often omit the multiplication operator and write simply <span style=\"color: #000080\">ab<\/span> instead of <span style=\"color: #000080\">a\u00a0\u22c5\u00a0b<\/span>, which is a usual convention.<\/p>\n<p>Another important monoid axiom is <em>associativity:<\/em><\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a \u2218 (b \u2218 c) = (a \u2218 b) \u2218 c<\/span><\/p>\n<p>It tells us that the order in which we group composition operations does not matter. This makes monoids convenient to work with and allows us to omit unnecessary parentheses. Addition and multiplication are associative: <span style=\"color: #000080\">a\u00a0+\u00a0(b\u00a0+\u00a0c) = (a\u00a0+\u00a0b)\u00a0+\u00a0c<\/span> and <span style=\"color: #000080\">a(bc)\u00a0=\u00a0(ab)c<\/span>.<\/p>\n<p>Monoids are interesting to study, because they appear everywhere in mathematics, programming and engineering. Another example comes from <a href=\"https:\/\/en.wikipedia.org\/wiki\/Boolean_algebra\">Boolean algebra<\/a>: the logical disjunction (OR) monoid\u00a0<span style=\"color: #000080\">({0,1},\u00a0\u2228,\u00a00)<\/span> and the logical conjunction (AND) monoid\u00a0<span style=\"color: #000080\">({0,1},\u00a0\u2227,\u00a01)<\/span>. Compared to numbers, in Boolean algebra the meanings of composition and identity elements are very different (e.g. <em>number zero<\/em> vs <em>logical false<\/em>), yet we can abstract from these differences, which allows us to reuse general results about monoids across various specific instances.<\/p>\n<p>In this blog post we will also come across <em>commutative<\/em> and <em>idempotent<\/em> monoids. In commutative monoids, the order of composition does not matter:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a \u2218 b = b \u2218 a<\/span><\/p>\n<p>All four examples above <span style=\"color: #000080\">(+,\u00a0\u22c5,\u00a0\u2228,\u00a0\u2227)<\/span> are commutative monoids. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Concatenation\">String concatenation<\/a> <span style=\"color: #000080\">(S,\u00a0++,\u00a0&#8220;&#8221;)<\/span> is an example of a non-commutative monoid: indeed, <span style=\"color: #000080\">&#8220;a&#8221;\u00a0++\u00a0&#8220;b&#8221;\u00a0=\u00a0&#8220;ab&#8221;<\/span> and\u00a0<span style=\"color: #000080\">&#8220;b&#8221;\u00a0++\u00a0&#8220;a&#8221;\u00a0=\u00a0&#8220;ba&#8221;<\/span>\u00a0are different strings.<\/p>\n<p>Finally, in an idempotent monoid, composing an element with itself does not change it:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a \u2218 a = a<\/span><\/p>\n<p>The disjunction <span style=\"color: #000080\">\u2228\u00a0<\/span>and conjunction <span style=\"color: #000080\">\u2227\u00a0<\/span>monoids are idempotent, whereas the addition <span style=\"color: #000080\">+<\/span>, multiplication <span style=\"color: #000080\">\u22c5\u00a0<\/span>and concatenation <span style=\"color: #000080\">++<\/span> monoids are not.<\/p>\n<p>A monoid which is both commutative and idempotent is a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Semilattice\">bounded semilattice<\/a>; both\u00a0disjunction<span style=\"color: #000080\">\u00a0<\/span>and conjunction are bounded semilattices.<\/p>\n<h4>Rings and lattices<\/h4>\n<p>As you might have noticed, monoids often come in pairs: addition and multiplication <span style=\"color: #000080\">(+,\u00a0\u22c5)<\/span>, disjunction and conjunction <span style=\"color: #000080\">(\u2228,\u00a0\u2227)<\/span>, set union and intersection <span style=\"color: #000080\">(\u22c3,\u00a0\u22c2)<\/span>, parallel and sequential composition <span style=\"color: #000080\">(||,\u00a0;<i><\/i>)<span style=\"color: #000000\">\u00a0etc.<\/span><\/span>\u00a0I&#8217;m sure you can list a few more examples of such pairs. Two common ways in which such monoid pairs can be formed are called <em>rings<\/em> and <em>lattices<\/em>.<\/p>\n<p>A <a href=\"https:\/\/en.wikipedia.org\/wiki\/Ring_(mathematics)\">ring<\/a>, or more generally a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Semiring\">semiring<\/a>, <span style=\"color: #000080\">(S,\u00a0+,\u00a00,\u00a0\u22c5,\u00a01)<span style=\"color: #000000\"> comprises an\u00a0<em>additive<\/em> monoid <span style=\"color: #000080\">(S,\u00a0+,\u00a00)<\/span> and a <em>multiplicative<\/em> monoid <span style=\"color: #000080\">(S,\u00a0\u22c5,\u00a01)<\/span>, such that: they both operate on the same set <span style=\"color: #000080\">S<\/span>, the additive monoid is commutative, and the multiplicative monoid\u00a0<em>distributes<\/em> over the additive one:<\/span><\/span><\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a(b + c) = ab + ac<br \/>\n(a + b)c = ac + bc<\/span><\/p>\n<p>Distributivity is very convenient and allows us to open parentheses, and (if applied in reverse) to factor out a common term of two expressions. Furthermore, ring-like algebraic structures require that\u00a0<span style=\"color: #000080\">0<\/span>\u00a0<em>annihilates<\/em> all elements under multiplication:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a\u00a0\u22c5 0 = 0<br \/>\n0\u00a0\u22c5 a = 0<\/span><\/p>\n<p>The most basic and widely known ring is that of integer numbers with addition and multiplication: we use this pair of monoids every day, with no fuss about the underlying theory. Various lesser known\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Tropical_semiring\">tropical<\/a>\u00a0and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Semiring#Star_semirings\">star semirings<\/a>\u00a0are a great tool in optimisation on graphs\u00a0&#8212; read <a href=\"http:\/\/stedolan.net\/research\/semirings.pdf\">this cool functional pearl<\/a>\u00a0by\u00a0Stephen Dolan if you want to learn more.<\/p>\n<p>A <a href=\"https:\/\/en.wikipedia.org\/wiki\/Lattice_(order)#Bounded_lattice\">bounded lattice<\/a> <span style=\"color: #000080\">(S,\u00a0\u2228,\u00a00,\u00a0\u2227,\u00a01)<span style=\"color: #000000\">\u00a0also comprises two monoids, which are called <em>join<\/em>\u00a0<span style=\"color: #000080\">(S,\u00a0\u2228,\u00a00)<\/span> and <em>meet<\/em>\u00a0<span style=\"color: #000080\">(S,\u00a0\u2227,\u00a01).<\/span>\u00a0They operate on the same set <span style=\"color: #000080\">S<\/span>, are required to be commutative and idempotent, and satisfy the following <em>absorption<\/em> axioms:<\/span><\/span><\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a\u00a0\u2227\u00a0(a \u2228 b) = a<br \/>\na \u2228\u00a0(a \u2227 b) = a<br \/>\n<\/span><\/p>\n<p>Like rings, lattices show up very frequently in different application areas. Most basic examples include Boolean algebra\u00a0<span style=\"color: #000080\">({0,1},\u00a0\u2228,\u00a00,\u00a0\u2227,\u00a01),<span style=\"color: #000000\">\u00a0the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Power_set\">power set<\/a> <span style=\"color: #000080\">(2<sup>S<\/sup>,\u00a0\u22c3,\u00a0\u00d8,\u00a0\u22c2,\u00a0S)<span style=\"color: #000000\">, as well as integer numbers with negative and positive infinities and the operations <span style=\"color: #000080\">max<\/span>\u00a0and <span style=\"color: #000080\">min<\/span>:\u00a0<span style=\"color: #000080\">(\u2124<sup>\u00b1\u221e<\/sup>,\u00a0max,\u00a0-\u221e,\u00a0min,\u00a0+\u221e)<\/span>. All of these lattices are <em>distributive,<\/em> i.e.\u00a0<span style=\"color: #000080\">\u2227<\/span> distributes over\u00a0<span style=\"color: #000080\">\u2228<\/span> and vice versa.<\/span><\/span><\/span><\/span><\/p>\n<h4 id=\"whatif\">What if 0 = 1?<\/h4>\n<p>Now that the scene has been set and all characters introduced, let&#8217;s see what happens when the identity elements of the two monoids in a pair <span style=\"color: #000080\">(S,\u00a0+,\u00a00)<\/span> and <span style=\"color: #000080\">(S,\u00a0\u22c5,\u00a01)\u00a0<\/span>coincide, i.e. when <span style=\"color: #000080\">0\u00a0=\u00a01<\/span>.<\/p>\n<p>In a ring <span style=\"color: #000080\">(S,\u00a0+,\u00a00,\u00a0\u22c5,\u00a01)<\/span>, this leads to devastating consequences. Not only <span style=\"color: #000080\">1<\/span> becomes equal to <span style=\"color: #000080\">0<\/span>, but all other elements of the ring become equal to <span style=\"color: #000080\">0<\/span> too, as demonstrated below:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #000080\">\u00a0a\u00a0\u00a0\u00a0 <\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a \u22c5 1<\/span><\/td>\n<td>(identity of <span style=\"color: #000080\">\u22c5<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a \u22c5 0<\/span><\/td>\n<td>(we postulate <span style=\"color: #000080\">0 = 1<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">0<\/span><\/td>\n<td>(annihilating <span style=\"color: #000080\">0<\/span>)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The ring is <em>annihilated<\/em> into a single point <span style=\"color: #000080\">0<\/span>.<\/p>\n<p>In a bounded lattice <span style=\"color: #000080\">(S,\u00a0\u2228,\u00a00,\u00a0\u2227,\u00a01)<\/span>, postulating\u00a0<span style=\"color: #000080\">0\u00a0=\u00a01<\/span> leads to the same catastrophe, albeit in a different manner:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #000080\">\u00a0a\u00a0\u00a0\u00a0<\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">1 \u2227 a<\/span><\/td>\n<td>(identity of <span style=\"color: #000080\">\u2227<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">1 \u2227 (0 \u2228 a)<\/span><\/td>\n<td>(identity of <span style=\"color: #000080\">\u2228<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">0 \u2227 (0 \u2228 a)<\/span><\/td>\n<td>(we postulate <span style=\"color: #000080\">0 = 1<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">0<\/span><\/td>\n<td>(absorption axiom)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The lattice is <em>absorbed<\/em> into a single point <span style=\"color: #000080\">0<\/span>.<\/p>\n<p>Postulating the axiom\u00a0<span style=\"color: #000080\">0\u00a0=\u00a01<\/span> has so far led to nothing but disappointment. Let&#8217;s find another way of pairing monoids, which does not involve the axioms of annihilation and absorption.<\/p>\n<h4>United monoids<\/h4>\n<p>Consider two monoids\u00a0<span style=\"color: #000080\">(S,\u00a0+,\u00a00)<\/span> and <span style=\"color: #000080\">(S,\u00a0\u22c5,\u00a01)<\/span>, which operate on the same set <span style=\"color: #000080\">S<\/span>, such that <span style=\"color: #000080\">+<\/span> is commutative and\u00a0<span style=\"color: #000080\">\u22c5<\/span> distributes over <span style=\"color: #000080\">+<\/span>. We call these monoids <span style=\"color: #000080\"><strong>united<\/strong><\/span> if\u00a0<span style=\"color: #000080\">0\u00a0=\u00a01<\/span>. To avoid confusion with rings and lattices, we will use <span style=\"color: #000080\">e<\/span> to denote the identity element of both monoids:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a + e = ae = ea = a<\/span><\/p>\n<p>We will call this the <em>united identity axiom<\/em>. We&#8217;ll also refer to <span style=\"color: #000080\">e<\/span> as <em>empty<\/em>, the operation <span style=\"color: #000080\">+<\/span> as <em>overlay,<\/em> and the operation\u00a0<span style=\"color: #000080\">\u22c5<\/span> as <em>connect.<\/em><\/p>\n<p>What can we tell about united monoids? First of all, it is easy to prove that the monoid\u00a0<span style=\"color: #000080\">(S,\u00a0+,\u00a0e)<\/span> is idempotent:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #000080\">\u00a0a + a\u00a0\u00a0\u00a0<\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ae + ae<\/span><\/td>\n<td>(united identity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a(e + e)<\/span><\/td>\n<td>(distributivity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ae<\/span><\/td>\n<td>(united identity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a<\/span><\/td>\n<td>(united identity)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Recall that this means that\u00a0<span style=\"color: #000080\">(S,\u00a0+,\u00a0e)<\/span> is a bounded semilattice.<\/p>\n<p>The next consequence of the united identity axiom is a bit more unusual:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">ab = ab + a<\/span><br \/>\n<span style=\"color: #000080\">ab = ab + b<br \/>\nab = ab + a + b<\/span><\/p>\n<p>We will refer to the above properties as\u00a0<em>containment laws:<\/em> intuitively, when you connect\u00a0<span style=\"color: #000080\">a<\/span> and <span style=\"color: #000080\">b<\/span>, the constituent parts are contained in the result <span style=\"color: #000080\">ab<\/span>. Let us prove containment:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #000080\">ab + a\u00a0\u00a0\u00a0<\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ab + ae<\/span><\/td>\n<td>(united identity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a(b + e)<\/span><\/td>\n<td>(distributivity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ab<\/span><\/td>\n<td>(united identity)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The two other laws are proved analogously (in fact, they are equivalent to each other).<\/p>\n<p>Surprisingly, the containment law\u00a0<span style=\"color: #000080\">ab\u00a0=\u00a0ab\u00a0+\u00a0a<\/span> is equivalent to the united identity law\u00a0<span style=\"color: #000080\">0\u00a0=\u00a01<\/span>, i.e. the latter can be proved from the former:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #000080\">0\u00a0 \u00a0<\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">1 \u22c5 0<\/span><\/td>\n<td>(<span style=\"color: #000080\">1<\/span> is identity of <span style=\"color: #000080\">\u22c5<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">1 \u22c5 0 + 1<\/span><\/td>\n<td>(containment)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">0 + 1<\/span><\/td>\n<td>(<span style=\"color: #000080\">1<\/span> is identity of <span style=\"color: #000080\">\u22c5<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">1<\/span><\/td>\n<td>(<span style=\"color: #000080\">0<\/span> is identity of <span style=\"color: #000080\">+<\/span>)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>This means that united monoids can equivalently be defined as follows:<\/p>\n<ul>\n<li><span style=\"color: #000080\">(S,\u00a0+)<\/span> is a commutative <a href=\"https:\/\/en.wikipedia.org\/wiki\/Semigroup\">semigroup<\/a>.<\/li>\n<li><span style=\"color: #000080\">(S,\u00a0\u22c5,\u00a0e)<\/span> is a monoid that distributes over\u00a0<span style=\"color: #000080\">+<\/span>.<\/li>\n<li>Containment axiom: <span style=\"color: #000080\">ab\u00a0=\u00a0ab\u00a0+\u00a0a<\/span>.<\/li>\n<\/ul>\n<p>Then the fact that <span style=\"color: #000080\">(S, +,\u00a0e)<\/span>\u00a0is also a monoid can be proved as above.<\/p>\n<p>Finally, let&#8217;s prove one more property of\u00a0united monoids: non-empty elements of <span style=\"color: #000080\">S<\/span> can have no inverses. More precisely:<\/p>\n<p style=\"text-align: center\">if <span style=\"color: #000080\">a\u00a0+\u00a0b\u00a0=\u00a0e<\/span>\u00a0or\u00a0<span style=\"color: #000080\">ab\u00a0=\u00a0e<\/span> then <span style=\"color: #000080\">a\u00a0=\u00a0b\u00a0=\u00a0e<\/span>.<\/p>\n<p>The lack of overlay inverses follows from overlay idempotence:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #000080\">a\u00a0 \u00a0<\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a + e<\/span><\/td>\n<td>(united identity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a + a + b<\/span><\/td>\n<td>(assumption <span style=\"color: #000080\">a + b = e<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a + b<\/span><\/td>\n<td>(idempotence)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">e<\/span><\/td>\n<td>(assumption <span style=\"color: #000080\">a + b = e<\/span>)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The lack of connect inverses follows from the containment law:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #000080\">a\u00a0 \u00a0<\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">e + a<\/span><\/td>\n<td>(united identity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ab + a<\/span><\/td>\n<td>(assumption <span style=\"color: #000080\">ab = e<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ab<\/span><\/td>\n<td>(containment)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">e<\/span><\/td>\n<td>(assumption <span style=\"color: #000080\">ab = e<\/span>)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>It is time to look at some examples of united monoids.<\/p>\n<h4>Example 1: max and plus, united<\/h4>\n<p>One example appears in\u00a0<a href=\"https:\/\/dl.acm.org\/ft_gateway.cfm?id=2976007\">this paper<\/a> on Haskell&#8217;s <span style=\"color: #000080\">ApplicativeDo<\/span> language extension. It uses a simple cost model for defining the execution time of programs composed in parallel or in sequence. The two monoids are:<\/p>\n<ul>\n<li><span style=\"color: #000080\">(\u2124<sup>\u22650<\/sup>,\u00a0max,\u00a00)<\/span>: the execution time of programs <span style=\"color: #000080\">a<\/span> and <span style=\"color: #000080\">b<\/span> composed in parallel is defined to be the maximum of their execution times:\n<p style=\"text-align: center\"><span style=\"color: #000080\"><br \/>\ntime(a\u00a0||\u00a0b) = max(time(a), time(b))<\/span><\/p>\n<\/li>\n<li><span style=\"color: #000080\">(\u2124<sup>\u22650<\/sup>,\u00a0+,\u00a00)<\/span>: the execution time of programs <span style=\"color: #000080\">a<\/span> and <span style=\"color: #000080\">b<\/span> composed in sequence is defined to be the sum of their execution times:\n<p style=\"text-align: center\"><span style=\"color: #000080\"><br \/>\ntime(a\u00a0;\u00a0b) = time(a) + time(b)<\/span><\/p>\n<\/li>\n<\/ul>\n<p>Execution times are non-negative, hence both\u00a0<span style=\"color: #000080\">max<\/span> and <span style=\"color: #000080\">+<\/span>\u00a0have identity <span style=\"color: #000080\">0<\/span>, which is the execution time of the\u00a0<em>empty program<\/em>: <span style=\"color: #000080\">max(a,\u00a00) = <\/span><span style=\"color: #000080\">a\u00a0+\u00a00\u00a0=\u00a0a<\/span>.\u00a0It is easy to check distributivity (<span style=\"color: #000080\">+<\/span> distributes over <span style=\"color: #000080\">max<\/span>) and containment:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a + max(b, c) = max(a + b, a + c)<br \/>\nmax(a + b, a) = a + b<\/span><\/p>\n<p>Note that the resulting algebraic structure is different from the tropical <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tropical_semiring\">max-plus semiring<\/a>\u00a0<span style=\"color: #000080\">(\u211d<sup>\u2212\u221e<\/sup>,\u00a0max,\u00a0\u2212\u221e,\u00a0+,\u00a00)<\/span> commonly used in scheduling, where the identity of <span style=\"color: #000080\">max<\/span> is\u00a0<span style=\"color: #000080\">\u2212\u221e<\/span>.<\/p>\n<p>In general, various flavours of parallel and sequential composition often form united monoids. In <a href=\"http:\/\/staffwww.dcs.shef.ac.uk\/people\/G.Struth\/CKAreport.pdf\">this paper<\/a> about Concurrent Kleene Algebra the authors use the term <em>bimonoid<\/em> to refer to such structures, but this term is also used to describe\u00a0an <a href=\"https:\/\/ncatlab.org\/nlab\/show\/bimonoid\">unrelated concept in category theory<\/a>, so let me stick to &#8220;united monoids&#8221; here, which has zero google hits.<\/p>\n<h4>Example 2: algebraic graphs<\/h4>\n<p>My favourite algebraic structure is the <em>algebra of graphs<\/em>\u00a0described in <a href=\"https:\/\/dl.acm.org\/authorize?N46678\">this paper<\/a>. The algebra comprises two monoids that have the same identity, which motivated me to study similar algebraic structures, and led to writing this blog post about the generalised notion of\u00a0united monoids.<\/p>\n<p>As a brief introduction, consider the following operations on <a href=\"https:\/\/en.wikipedia.org\/wiki\/Graph_(discrete_mathematics)\">graphs<\/a>. The <em>overlay<\/em> operation <span style=\"color: #000080\">+<\/span> takes two graphs\u00a0<span style=\"color: #000080\">(V<sub>1<\/sub>,\u00a0E<sub>1<\/sub>)<\/span> and <span style=\"color: #000080\">(V<sub>2<\/sub>,\u00a0E<sub>2<\/sub>)<\/span>, and produces the graph containing the union of their vertices and edges:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">(V<sub>1<\/sub>, E<sub>1<\/sub>) + (V<sub>2<\/sub>, E<sub>2<\/sub>) = (V<sub>1<\/sub>\u00a0\u222a V<sub>2<\/sub>, E<sub>1<\/sub>\u00a0\u222a E<sub>2<\/sub>)<\/span><\/p>\n<p>The <em>connect<\/em> operation\u00a0<span style=\"color: #000080\">\u22c5<\/span> is similar to overlay, but it also adds an edge from each vertex of the first graph to each vertex of the second graph:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">(V<sub>1<\/sub>, E<sub>1<\/sub>) \u22c5 (V<sub>2<\/sub>, E<sub>2<\/sub>) = (V<sub>1<\/sub>\u00a0\u222a V<sub>2<\/sub>, E<sub>1<\/sub>\u00a0\u222a E<sub>2<\/sub>\u00a0\u222a V<sub>1<\/sub>\u00a0\u00d7 V<sub>2<\/sub>)<\/span><\/p>\n<p>The operations have the same identity <span style=\"color: #000080\">e<\/span> &#8212; the <em>empty graph<\/em> <span style=\"color: #000080\">(\u2205,\u00a0\u2205)<\/span>\u00a0&#8212; and form a pair of united monoids, where\u00a0<span style=\"color: #000080\">\u22c5<\/span> distributes over <span style=\"color: #000080\">+<\/span>.<\/p>\n<p>In addition to the laws of united monoids described above, the algebra of graphs has the axiom of <em>decomposition:<\/em><\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">abc = ab + ac + bc<\/span><\/p>\n<p>The intuition behind this axiom is that any expression in the algebra of graphs can be broken down into vertices\u00a0and pairs of vertices (edges). Note that the containment laws follow from decomposition, e.g.:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #000080\">ab\u00a0 \u00a0<\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">aeb<\/span><\/td>\n<td>(<span style=\"color: #000080\">e<\/span> identity of <span style=\"color: #000080\">\u22c5<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ae + ab + eb<\/span><\/td>\n<td>(decomposition)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ae + ab + b<\/span><\/td>\n<td>(<span style=\"color: #000080\">e<\/span> identity of <span style=\"color: #000080\">\u22c5<\/span>)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">a(e + b) + b<\/span><\/td>\n<td>(distributivity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">ab + b<\/span><\/td>\n<td>(<span style=\"color: #000080\">e<\/span> identity of <span style=\"color: #000080\">+<\/span>)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>By postulating the commutativity of the connect operation (<span style=\"color: #000080\">ab\u00a0=\u00a0ba<\/span>), we can readily obtain <em>undirected graphs<\/em>.<\/p>\n<p>The algebra of graphs can be considered a &#8220;2D&#8221; special case of united monoids, where one can only connect elements pairwise; any 3-way connection\u00a0<span style=\"color: #000080\">abc<\/span> falls apart into pieces. A 3-dimensional variant of the algebra can be obtained by replacing the decomposition axiom with:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">abcd = abc + abd + acd + bcd<\/span><\/p>\n<p>This allows us to connect vertices into pairs (edges) and triples (faces), but forces 4-way products <span style=\"color: #000080\">abcd<\/span>\u00a0to fall apart into faces, as shown below:<\/p>\n<p><a href=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/3-decomposition.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-205\" src=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/3-decomposition.png\" alt=\"3D graph decomposition\" width=\"2400\" height=\"1016\" \/><\/a><\/p>\n<p>Note that 3-decomposition follows from 2-decomposition: if all 3-way products fall apart then so do all 4-way products, but not vice versa. Borrowing an example from David Spivak&#8217;s <a href=\"https:\/\/arxiv.org\/pdf\/0909.4314.pdf\">paper<\/a> on modelling higher- dimensional\u00a0networks, such 3D graphs allow us to distinguish these two different situations:<\/p>\n<ul>\n<li>Three people having a conversation together, e.g. over a restaurant table. This can be modelled with a <em>filled-in triangle<\/em>\u00a0<span style=\"color: #000080\">abc<\/span>.<\/li>\n<li>Three people having three separate\u00a0t\u00eate-\u00e0-t\u00eate conversations. This can be modelled with a <em>hollow triangle<\/em> <span style=\"color: #000080\">ab\u00a0+\u00a0ac\u00a0+\u00a0bc<\/span>.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/triangles.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/triangles.png\" alt=\"Triangles: filled-in (abc) and hollow (ab + ac + bc)\" width=\"300\" height=\"118\" \/><\/a><\/p>\n<p>Similar examples show up in concurrency theory, where one might need to distinguish three truly concurrent events from three events that are concurrent pairwise, but whose overall concurrency is limited by shared resources, e.g. three people eating ice-cream with two spoons, or going through a two-person-wide door. There is a <a href=\"https:\/\/www.staff.ncl.ac.uk\/alex.yakovlev\/home.formal\/lattices-Bul-EATCS-37-Feb-1989.pdf\">short paper<\/a>\u00a0on this topic by my PhD advisor Alex Yakovlev, written in 1989 (on a typewriter!).<\/p>\n<h4>Example 3: simplicial complexes<\/h4>\n<p>United monoids of growing dimension lead us to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Topology\">topology<\/a>, specifically to\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Simplicial_complex\">simplicial complexes<\/a>, which are composed of simple <em>n<\/em>-dimensional shapes called <em>simplices<\/em>, such as <em>point<\/em> (0-simplex),\u00a0<em>segment<\/em>\u00a0(1-simplex), <em>triangle<\/em> (2-simplex), <em>tetrahedron<\/em> (3-simplex), etc. &#8212; <a href=\"https:\/\/www.youtube.com\/watch?v=rlI1KOo1gp4\">here is a cool video<\/a>. We show an example of a simplicial complex below, along with a united monoid expression <span style=\"color: #000080\">C<\/span> that describes it, and two containment properties.\u00a0 We&#8217;ll further assume commutativity of connection: <span style=\"color: #000080\">ab\u00a0=\u00a0ba<\/span>.<\/p>\n<p><a href=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/simplicial-complex.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-205\" src=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/simplicial-complex.png\" alt=\"A simplicial complex\" width=\"2400\" height=\"1304\" \/><\/a><\/p>\n<p>Simplicial complexes are closed in terms of containment. For example, a filled-in triangle contains its edges and vertices, and cannot appear in a simplicial complex without any of them. This property can be expressed algebraically as follows:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">abc = abc + ab + ac + bc + a + b + c<\/span><\/p>\n<p>Interestingly, this 3D containment law follows from the 2D version that we defined for united monoids:<\/p>\n<table>\n<tbody style=\"font-size: 16px\">\n<tr>\n<td style=\"text-align: right\"><span style=\"color: #000080\">abc<\/span><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">(ab + a + b)c<\/span><\/td>\n<td>(containment)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">(ab)c + ac + bc<\/span><\/td>\n<td>(distributivity)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">(abc + ab + c) + (ac + a) + (bc + b)<\/span><\/td>\n<td>(containment)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><span style=\"color: #000080\">=<\/span><\/td>\n<td><span style=\"color: #000080\">abc + ab + ac + bc + a + b + c<\/span><\/td>\n<td>(commutativity)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>We can similarly prove\u00a0<em>n<\/em>-dimensional versions of the containment law; they all trivially follow from the basic containment axiom <span style=\"color: #000080\">ab\u00a0=\u00a0ab\u00a0+\u00a0a<\/span>, or, alternatively, from the united identity axiom\u00a0<span style=\"color: #000080\">0\u00a0=\u00a01<\/span>.<\/p>\n<h4>United monoids in Haskell<\/h4>\n<p>Now let&#8217;s put together a small library for united monoids in Haskell and express some of the above examples in it.<\/p>\n<p>Monoids are already represented in the standard Haskell library <span style=\"color: #000080\">base<\/span> by the type class <span style=\"color: #000080\">Monoid<\/span>. We need to extend it to the\u00a0type class\u00a0<span style=\"color: #000080\">Semilattice<\/span>, which does not define any new methods, but comes with two new laws. We also provide a few convenient aliases, following the <a href=\"http:\/\/hackage.haskell.org\/package\/algebraic-graphs\/docs\/Algebra-Graph.html\">API<\/a> of the <span style=\"color: #000080\">algebraic-graphs<\/span> library:<br \/>\n<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f8f8f8;overflow: auto;width: auto;padding: 0em;margin: 0em 0em 1em\">\n<pre style=\"margin: 0;line-height: 150%\"><span style=\"color: #8f5902;font-style: italic\">-- Laws:<\/span>\n<span style=\"color: #8f5902;font-style: italic\">-- * Commutativity: a &lt;&gt; b = b &lt;&gt; a<\/span>\n<span style=\"color: #8f5902;font-style: italic\">-- * Idempotence:   a &lt;&gt; a = a<\/span>\n<span style=\"color: #204a87;font-weight: bold\">class<\/span> <span style=\"color: #204a87;font-weight: bold\">Monoid<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000\">m<\/span>\n\n<span style=\"color: #000000\">empty<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000\">empty<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">mempty<\/span>\n\n<span style=\"color: #000000\">overlay<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000\">overlay<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">mappend<\/span>\n\n<span style=\"color: #000000\">overlays<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000;font-weight: bold\">[<\/span><span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">]<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000\">overlays<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">foldr<\/span> <span style=\"color: #000000\">overlay<\/span> <span style=\"color: #000000\">empty<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">infixr<\/span> <span style=\"color: #0000cf;font-weight: bold\">6<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span>\n<span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">overlay<\/span>\n\n<span style=\"color: #8f5902;font-style: italic\">-- The natural partial order on the semilattice<\/span>\n<span style=\"color: #000000\">isContainedIn<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Eq<\/span> <span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Bool<\/span>\n<span style=\"color: #000000\">isContainedIn<\/span> <span style=\"color: #000000\">x<\/span> <span style=\"color: #000000\">y<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">x<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span> <span style=\"color: #000000\">y<\/span> <span style=\"color: #ce5c00;font-weight: bold\">==<\/span> <span style=\"color: #000000\">y<\/span>\n<\/pre>\n<\/div>\n<p>We are now ready to define the type class for united monoids that defines a new method <span style=\"color: #000080\">connect<\/span> and associated laws:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f8f8f8;overflow: auto;width: auto;padding: 0em;margin: 0em 0em 1em\">\n<pre style=\"margin: 0;line-height: 150%\"><span style=\"color: #8f5902;font-style: italic\">-- Laws:<\/span>\n<span style=\"color: #8f5902;font-style: italic\">-- * United identity:     a &lt;.&gt; empty == empty &lt;.&gt; a == a\n-- * Associativity:   a &lt;.&gt; (b &lt;.&gt; c) == (a &lt;.&gt; b) &lt;.&gt; c<\/span>\n<span style=\"color: #8f5902;font-style: italic\">-- * Distributivity:  a &lt;.&gt; (b &lt;+&gt; c) == a &lt;.&gt; b &lt;+&gt; a &lt;.&gt; c \n--                    (a &lt;+&gt; b) &lt;.&gt; c == a &lt;.&gt; c &lt;+&gt; b &lt;.&gt; c\n<\/span><span style=\"color: #204a87;font-weight: bold\">class<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">United<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">connect<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">infixr<\/span> <span style=\"color: #0000cf;font-weight: bold\">7<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span>\n<span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">United<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">connect<\/span>\n\n<span style=\"color: #000000\">connects<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">United<\/span> <span style=\"color: #000000\">m<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000;font-weight: bold\">[<\/span><span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">]<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000\">connects<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">foldr<\/span> <span style=\"color: #000000\">connect<\/span> <span style=\"color: #000000\">empty<\/span>\n<\/pre>\n<\/div>\n<p>Algebraic graphs are a trivial instance:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f8f8f8;overflow: auto;width: auto;padding: 0em;margin: 0em 0em 1em\">\n<pre style=\"margin: 0;line-height: 150%\"><span style=\"color: #204a87;font-weight: bold\">import<\/span> <span style=\"color: #000000\">Algebra.Graph<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Graph<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n<span style=\"color: #204a87;font-weight: bold\">import<\/span> <span style=\"color: #204a87;font-weight: bold\">qualified<\/span> <span style=\"color: #000000\">Algebra.Graph<\/span> <span style=\"color: #204a87;font-weight: bold\">as<\/span> <span style=\"color: #000000\">Graph<\/span>\n\n<span style=\"color: #8f5902;font-style: italic\">-- TODO: move orphan instances to algebraic-graphs library <\/span>\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Semigroup<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Graph<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #ce5c00;font-weight: bold\">&lt;&gt;<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Graph<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">overlay<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Monoid<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Graph<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">mempty<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Graph<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">empty<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Graph<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">United<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Graph<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">connect<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Graph<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">connect<\/span>\n<\/pre>\n<\/div>\n<p>We can now express the above simplicial complex example in Haskell and test whether it contains the filled-in and the hollow triangles:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f8f8f8;overflow: auto;width: auto;padding: 0em;margin: 0em 0em 1em\">\n<pre style=\"margin: 0;line-height: 125%\"><span style=\"color: #8f5902;font-style: italic\">-- We are using OverloadedStrings for creating vertices<\/span>\n<span style=\"color: #000000\">example<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">United<\/span> <span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #204a87;font-weight: bold\">IsString<\/span> <span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000\">example<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">overlays<\/span> <span style=\"color: #000000;font-weight: bold\">[<\/span> <span style=\"color: #4e9a06\">\"p\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"q\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"r\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"s\"<\/span>\n                   <span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #4e9a06\">\"r\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span> <span style=\"color: #4e9a06\">\"s\"<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"t\"<\/span>\n                   <span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #4e9a06\">\"u\"<\/span>\n                   <span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #4e9a06\">\"v\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"x\"<\/span>\n                   <span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #4e9a06\">\"w\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #4e9a06\">\"x\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span> <span style=\"color: #4e9a06\">\"y\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span> <span style=\"color: #4e9a06\">\"z\"<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n                   <span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #4e9a06\">\"x\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"y\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"z\"<\/span> <span style=\"color: #000000;font-weight: bold\">]<\/span>\n\n<span style=\"color: #8f5902;font-style: italic\">-- Filled-in triangle<\/span>\n<span style=\"color: #000000\">rstFace<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">United<\/span> <span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #204a87;font-weight: bold\">IsString<\/span> <span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000\">rstFace<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #4e9a06\">\"r\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"s\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"t\"<\/span>\n\n<span style=\"color: #8f5902;font-style: italic\">-- Hollow triangle<\/span>\n<span style=\"color: #000000\">rstSkeleton<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">United<\/span> <span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #204a87;font-weight: bold\">IsString<\/span> <span style=\"color: #000000\">m<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #000000\">m<\/span>\n<span style=\"color: #000000\">rstSkeleton<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #4e9a06\">\"r\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"s\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span> <span style=\"color: #4e9a06\">\"r\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"t\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;+&gt;<\/span> <span style=\"color: #4e9a06\">\"s\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;.&gt;<\/span> <span style=\"color: #4e9a06\">\"t\"<\/span>\n<\/pre>\n<\/div>\n<p>To perform the test, we need to instantiate the polymorphic united monoid expression to the concrete data type like <span style=\"color: #000080\">Graph\u00a0Point<\/span>:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f8f8f8;overflow: auto;width: auto;padding: 0em;margin: 0em 0em 1em\">\n<pre style=\"margin: 0;line-height: 150%\"><span style=\"color: #204a87;font-weight: bold\">newtype<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span> <span style=\"color: #000000;font-weight: bold\">{<\/span> <span style=\"color: #000000\">getPoint<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">String<\/span> <span style=\"color: #000000;font-weight: bold\">}<\/span>\n    <span style=\"color: #204a87;font-weight: bold\">deriving<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Eq<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #204a87;font-weight: bold\">IsString<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n\n<span style=\"color: #a40000;border: 0px solid #ef2929\">\u03bb<\/span><span style=\"color: #ce5c00;font-weight: bold\">&gt;<\/span> <span style=\"color: #000000\">rstFace<\/span> <span style=\"color: #000000;font-weight: bold\">`<\/span><span style=\"color: #000000\">isContainedIn<\/span><span style=\"color: #000000;font-weight: bold\">`<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #000000\">example<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Graph<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n<span style=\"color: #204a87;font-weight: bold\">True<\/span>\n\n<span style=\"color: #a40000;border: 0px solid #ef2929\">\u03bb<\/span><span style=\"color: #ce5c00;font-weight: bold\">&gt;<\/span> <span style=\"color: #000000\">rstSkeleton<\/span> <span style=\"color: #000000;font-weight: bold\">`<\/span><span style=\"color: #000000\">isContainedIn<\/span><span style=\"color: #000000;font-weight: bold\">`<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #000000\">example<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Graph<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n<span style=\"color: #204a87;font-weight: bold\">True<\/span>\n<\/pre>\n<\/div>\n<p>As you can see, if we interpret the example simplicial complex using the algebraic graphs instance, we cannot distinguish the filled-in and hollow triangles, because the filled-in triangle falls apart into edges due to the 2-decomposition law <span style=\"color: #000080\">abc\u00a0=\u00a0ab\u00a0+\u00a0ac\u00a0+\u00a0bc<\/span>.<\/p>\n<p>Let&#8217;s define a data type for representing simplicial complexes. We start with simplices, which can be modelled by sets.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f8f8f8;overflow: auto;width: auto;padding: 0em;margin: 0em 0em 1em\">\n<pre style=\"margin: 0;line-height: 150%\"><span style=\"color: #8f5902;font-style: italic\">-- A simplex is formed on a set of points<\/span>\n<span style=\"color: #204a87;font-weight: bold\">newtype<\/span> <span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000;font-weight: bold\">{<\/span> <span style=\"color: #000000\">getSimplex<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #000000;font-weight: bold\">}<\/span>\n    <span style=\"color: #204a87;font-weight: bold\">deriving<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Eq<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #204a87;font-weight: bold\">Semigroup<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n\n<span style=\"color: #8f5902;font-style: italic\">-- Size-lexicographic order: https:\/\/en.wikipedia.org\/wiki\/Shortlex_order<\/span>\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">compare<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">x<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">y<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span>\n        <span style=\"color: #000000\">compare<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">size<\/span> <span style=\"color: #000000\">x<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">size<\/span> <span style=\"color: #000000\">y<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;&gt;<\/span>\n        <span style=\"color: #000000\">compare<\/span> <span style=\"color: #000000\">x<\/span> <span style=\"color: #000000\">y<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Show<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Show<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">show<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">intercalate<\/span> <span style=\"color: #4e9a06\">\".\"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #000000\">map<\/span> <span style=\"color: #000000\">show<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">toList<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #000000\">getSimplex<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">IsString<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">IsString<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">fromString<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">singleton<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #000000\">fromString<\/span>\n\n<span style=\"color: #000000\">isFaceOf<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Bool<\/span>\n<span style=\"color: #000000\">isFaceOf<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">x<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">y<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">isSubsetOf<\/span> <span style=\"color: #000000\">x<\/span> <span style=\"color: #000000\">y<\/span>\n<\/pre>\n<\/div>\n<p>Note that the <span style=\"color: #000080\">Ord<\/span> instance is defined using the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Shortlex_order\">size-lexicographic order<\/a> so that a simplex <span style=\"color: #000080\">x<\/span> can be a face of a simplex <span style=\"color: #000080\">y<\/span> only when\u00a0<span style=\"color: #000080\">x\u00a0&lt;=\u00a0y<\/span>.<\/p>\n<p>Now we can define simplicial complexes, which are sets of simplices that are closed with respect to the subset relation.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f8f8f8;overflow: auto;width: auto;padding: 0em;margin: 0em 0em 1em\">\n<pre style=\"margin: 0;line-height: 150%\"><span style=\"color: #8f5902;font-style: italic\">-- A simplicial complex is a set of simplices<\/span>\n<span style=\"color: #8f5902;font-style: italic\">-- We only store maximal simplices for efficiency<\/span>\n<span style=\"color: #204a87;font-weight: bold\">newtype<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000;font-weight: bold\">{<\/span> <span style=\"color: #000000\">getComplex<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #000000;font-weight: bold\">}<\/span>\n    <span style=\"color: #204a87;font-weight: bold\">deriving<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Eq<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Show<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Show<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">show<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">intercalate<\/span> <span style=\"color: #4e9a06\">\" + \"<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #000000\">map<\/span> <span style=\"color: #000000\">show<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">toList<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #000000\">getComplex<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">IsString<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">IsString<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">fromString<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">singleton<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #000000\">fromString<\/span>\n\n<span style=\"color: #8f5902;font-style: italic\">-- Do not add a simplex if it is contained in existing ones<\/span>\n<span style=\"color: #000000\">addSimplex<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Simplex<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span>\n<span style=\"color: #000000\">addSimplex<\/span> <span style=\"color: #000000\">x<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">y<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n    <span style=\"color: #ce5c00;font-weight: bold\">|<\/span> <span style=\"color: #000000\">any<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #000000\">isFaceOf<\/span> <span style=\"color: #000000\">x<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #000000\">y<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">y<\/span>\n    <span style=\"color: #ce5c00;font-weight: bold\">|<\/span> <span style=\"color: #000000\">otherwise<\/span>          <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">insert<\/span> <span style=\"color: #000000\">x<\/span> <span style=\"color: #000000\">y<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n\n<span style=\"color: #8f5902;font-style: italic\">-- Drop all non-minimal simplices<\/span>\n<span style=\"color: #000000\">normalise<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">-&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span>\n<span style=\"color: #000000\">normalise<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">foldr<\/span> <span style=\"color: #000000\">addSimplex<\/span> <span style=\"color: #000000\">empty<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #000000\">sort<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">toList<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #000000\">getComplex<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Semigroup<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">x<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">y<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">normalise<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #ce5c00;font-weight: bold\">$<\/span> <span style=\"color: #000000\">x<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;&gt;<\/span> <span style=\"color: #000000\">y<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Monoid<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">mempty<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">empty<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">Semilattice<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n\n<span style=\"color: #204a87;font-weight: bold\">instance<\/span> <span style=\"color: #204a87;font-weight: bold\">Ord<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">=&gt;<\/span> <span style=\"color: #204a87;font-weight: bold\">United<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">a<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">where<\/span>\n    <span style=\"color: #000000\">connect<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">x<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #000000\">y<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span> <span style=\"color: #204a87;font-weight: bold\">=<\/span> <span style=\"color: #000000\">normalise<\/span> <span style=\"color: #ce5c00;font-weight: bold\">.<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #ce5c00;font-weight: bold\">$<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">fromList<\/span>\n        <span style=\"color: #000000;font-weight: bold\">[<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #ce5c00;font-weight: bold\">&lt;&gt;<\/span> <span style=\"color: #000000\">b<\/span> <span style=\"color: #ce5c00;font-weight: bold\">|<\/span> <span style=\"color: #000000\">a<\/span> <span style=\"color: #204a87;font-weight: bold\">&lt;-<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">toList<\/span> <span style=\"color: #000000\">x<\/span><span style=\"color: #000000;font-weight: bold\">,<\/span> <span style=\"color: #000000\">b<\/span> <span style=\"color: #204a87;font-weight: bold\">&lt;-<\/span> <span style=\"color: #204a87;font-weight: bold\">Set<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">toList<\/span> <span style=\"color: #000000\">y<\/span> <span style=\"color: #000000;font-weight: bold\">]<\/span>\n<\/pre>\n<\/div>\n<p>Now let&#8217;s check that simplicial complexes allow us to distinguish the filled-in triangle from the hollow one:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f8f8f8;overflow: auto;width: auto;padding: 0em;margin: 0em 0em 1em\">\n<pre style=\"margin: 0;line-height: 150%\"><span style=\"color: #a40000;border: 0px solid #ef2929\">\u03bb<\/span><span style=\"color: #ce5c00;font-weight: bold\">&gt;<\/span> <span style=\"color: #000000\">example<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span>\n<span style=\"color: #000000\">u<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">r<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">t<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">s<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">t<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">v<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">x<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">w<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">x<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">w<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">y<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">w<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">z<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">x<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">y<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">z<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">p<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">q<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">r<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">s<\/span>\n\n<span style=\"color: #a40000;border: 0px solid #ef2929\">\u03bb<\/span><span style=\"color: #ce5c00;font-weight: bold\">&gt;<\/span> <span style=\"color: #000000\">rstFace<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span>\n<span style=\"color: #000000\">r<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">s<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">t<\/span>\n\n<span style=\"color: #a40000;border: 0px solid #ef2929\">\u03bb<\/span><span style=\"color: #ce5c00;font-weight: bold\">&gt;<\/span> <span style=\"color: #000000\">rstSkeleton<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span>\n<span style=\"color: #000000\">r<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">s<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">r<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">t<\/span> <span style=\"color: #ce5c00;font-weight: bold\">+<\/span> <span style=\"color: #000000\">s<\/span><span style=\"color: #ce5c00;font-weight: bold\">.<\/span><span style=\"color: #000000\">t<\/span>\n\n<span style=\"color: #a40000;border: 0px solid #ef2929\">\u03bb<\/span><span style=\"color: #ce5c00;font-weight: bold\">&gt;<\/span> <span style=\"color: #000000\">rstFace<\/span> <span style=\"color: #000000;font-weight: bold\">`<\/span><span style=\"color: #000000\">isContainedIn<\/span><span style=\"color: #000000;font-weight: bold\">`<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #000000\">example<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n<span style=\"color: #204a87;font-weight: bold\">False<\/span>\n\n<span style=\"color: #a40000;border: 0px solid #ef2929\">\u03bb<\/span><span style=\"color: #ce5c00;font-weight: bold\">&gt;<\/span> <span style=\"color: #000000\">rstSkeleton<\/span> <span style=\"color: #000000;font-weight: bold\">`<\/span><span style=\"color: #000000\">isContainedIn<\/span><span style=\"color: #000000;font-weight: bold\">`<\/span> <span style=\"color: #000000;font-weight: bold\">(<\/span><span style=\"color: #000000\">example<\/span> <span style=\"color: #204a87;font-weight: bold\">::<\/span> <span style=\"color: #204a87;font-weight: bold\">Complex<\/span> <span style=\"color: #204a87;font-weight: bold\">Point<\/span><span style=\"color: #000000;font-weight: bold\">)<\/span>\n<span style=\"color: #204a87;font-weight: bold\">True<\/span>\n<\/pre>\n<\/div>\n<p>Success! As you can check in the diagram above, the example simplicial complex contains a hollow triangle <span style=\"color: #000080\">rs\u00a0+\u00a0rt\u00a0+\u00a0st<\/span>, but does not contain the filled-in triangle <span style=\"color: #000080\">rst<\/span>.<\/p>\n<p>If you would like to experiment with the code above, check out this repository:\u00a0<a href=\"https:\/\/github.com\/snowleopard\/united\">https:\/\/github.com\/snowleopard\/united<\/a>.<\/p>\n<h4>Final remarks<\/h4>\n<p>I&#8217;ve got a few more thoughts, but it&#8217;s time to wrap up this blog post. I&#8217;m impressed that you&#8217;ve made it this far =)<\/p>\n<p>Let me simply list a few things I&#8217;d like to explore in future:<\/p>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li>What about monoids that lurk in applicative functors and monads? As we know (e.g. from the <a href=\"https:\/\/www.youtube.com\/watch?v=gHiyzctYqZ0\">final lecture<\/a> of a great lecture series by Bartosz Milewski), <span style=\"color: #000080\">pure\u00a0::\u00a0a\u00a0\u2192\u00a0m\u00a0a<\/span>\u00a0and <span style=\"color: #000080\">join\u00a0::\u00a0m\u00a0(m\u00a0a)\u00a0\u2192\u00a0m\u00a0a<\/span> are the monoid identity and composition in disguise. Couldn&#8217;t we unite this monoid with the monoid that corresponds to the\u00a0<em>commutative monad<\/em>? Note that they have the same identity <span style=\"color: #000080\">pure\u00a0::\u00a0a\u00a0\u2192\u00a0m\u00a0a<\/span>! This thought popped into my head when watching Edward Kmett&#8217;s <a href=\"https:\/\/www.youtube.com\/watch?v=Nv5tf8pvgrY\">live-coding session<\/a> on commutative applicative functors and monads.<\/li>\n<li>There are cases where a single overlay monoid is united with many, possibly infinitely many connect monoids. An example comes from <em>algebraic graphs with edge labels<\/em> that have\u00a0a connect operation for each possible edge label &#8212; see my <a href=\"https:\/\/skillsmatter.com\/skillscasts\/12361-labelled-algebraic-graphs\">Haskell eXchange 2018 talk<\/a>.<\/li>\n<li>We can also define\u00a0<em>united semigroups<\/em> that satisfy the containment axiom <span style=\"color: #000080\">ab\u00a0=\u00a0ab\u00a0+\u00a0a<\/span>\u00a0but have no identity element, for example, <em>non-empty algebraic graphs<\/em>. The term &#8220;united semigroups&#8221; sounds somewhat nonsensical since semigroups have no &#8220;units&#8221;, however note that if they secretly had identity elements, they would have been the same.<\/li>\n<li>Speaking of &#8220;units&#8221;, in ring theory, a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Unit_(ring_theory)\">unit<\/a> is any element <span style=\"color: #000080\">a<\/span> that has a multiplicative inverse <span style=\"color: #000080\">b<\/span> such that <span style=\"color: #000080\">ab\u00a0=\u00a01<\/span>. The lack of inverses, which we proved above, means there is only one unit in united monoids &#8212; the shared identity <span style=\"color: #000080\">e<\/span>.<\/li>\n<li>I have a feeling that united monoids are somehow inherently linked to Brent Yorgey&#8217;s <a href=\"https:\/\/byorgey.wordpress.com\/2018\/10\/01\/monoidal-sparks\/\">monoidal sparks<\/a>.<\/li>\n<li>We can also consider\u00a0<em>united partial monoids<\/em>\u00a0where the two operations may be defined only partially. For example, <a href=\"https:\/\/www.cs.auckland.ac.nz\/research\/groups\/CDMTCS\/researchreports\/001damgs.pdf\">this paper<\/a> by Jeremy Gibbons defines operations <span style=\"color: #000080\">above<\/span> and <span style=\"color: #000080\">beside<\/span> for composing directed acyclic graphs so that they both have the same identity (the empty graph), but the operation <span style=\"color: #000080\">beside<\/span> is defined only for graphs of matching <em>types<\/em>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Finally, I&#8217;d like to ask a question: have you come across united monoids, perhaps under a different name? As we&#8217;ve seen, having\u00a0<span style=\"color: #000080\">0\u00a0=\u00a01<\/span>\u00a0does make sense in some cases, but I couldn&#8217;t find much literature on this topic.<\/p>\n<h4 id=\"derivatives\">Update: boundary operator and derivatives<\/h4>\n<p>Consider the following definition of the <em>boundary operator<\/em>:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">\u2202x = overlay { a | a &lt; x }\u00a0<\/span><\/p>\n<p>where the overlay is over all elements of the set, and\u00a0<span style=\"color: #000080\">a\u00a0&lt; b\u00a0<\/span>denotes\u00a0<em>strict containment<\/em>, i.e.<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">a &lt; b\u00a0 \u00a0\u21d4\u00a0 \u00a0a + b = b\u00a0\u2227 a \u2260 b<\/span><\/p>\n<p>First, let&#8217;s apply this definition to a few basic simplices:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">\u2202a = empty<\/span><br \/>\n<span style=\"color: #000080\">\u2202(ab) = a + b + empty = a + b<\/span><br \/>\n<span style=\"color: #000080\">\u2202(abc) = ab + ac + bc + a + b + c + empty = ab + ac + bc<\/span><\/p>\n<p>This looks very similar to the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Boundary_(topology)\">boundary operator from topology<\/a>, e.g. the boundary of the filled-in triangle <span style=\"color: #000080\">abc<\/span> is the hollow triangle <span style=\"color: #000080\">ab + ac + bc<\/span>, and if we apply the boundary operator twice, the result is unchanged, i.e.\u00a0 <span style=\"color: #000080\">\u2202(ab + ac + bc) =\u00a0ab + ac + bc<\/span>.<\/p>\n<p><a href=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/derivative-ish.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/derivative-ish.png\" alt=\"Boundary operator\" width=\"300\" height=\"118\" \/><\/a><\/p>\n<p>Surprisingly, the boundary operator seems to satisfy the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Product_rule\">product rule<\/a> for derivatives for non-empty <span style=\"color: #000080\">a<\/span> and <span style=\"color: #000080\">b<\/span>:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">\u2202(ab) =\u00a0\u2202(a)b + a\u2202(b)<\/span><\/p>\n<p>I&#8217;m not sure where this is going, but it&#8217;s cool. Perhaps, there is a link with <a href=\"http:\/\/strictlypositive.org\/diff.pdf\">derivatives of types<\/a>?<\/p>\n<p>Thanks to Dave Clarke who suggested to look at the boundary operator.<\/p>\n<p><strong>Further update:<\/strong> One problem with the above definition is that the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Sum_rule_in_differentiation\">sum rule<\/a> for derivatives doesn&#8217;t hold, i.e.\u00a0<span style=\"color: #000080\">\u2202(a + b) \u2260 \u2202(a) + \u2202(b)<\/span>. Sjoerd Visscher <a href=\"https:\/\/twitter.com\/sjoerd_visscher\/status\/1076439066508488704\">suggested<\/a> to define\u00a0<span style=\"color: #000080\">\u2202<\/span> using the desired (usual) laws for derivatives:<\/p>\n<p style=\"text-align: center\"><span style=\"color: #000080\">\u2202(ab) =\u00a0\u2202(a)b + a\u2202(b)<br \/>\n<\/span><span style=\"color: #000080\">\u2202(a + b) = \u2202(a) + \u2202(b)<\/span><\/p>\n<p>Coupled with\u00a0<span style=\"color: #000080\">\u2202(empty) = <\/span><span style=\"color: #000080\">\u2202(a) = empty<\/span> (where <span style=\"color: #000080\">a<\/span> is a vertex), this leads to a different boundary operator, where\u00a0the boundary of the filled-in triangle <span style=\"color: #000080\">abc<\/span> is the hollow triangle <span style=\"color: #000080\">ab + ac + bc<\/span>, and the boundary of the hollow triangle is simply the three underlying vertices <span style=\"color: #000080\">a + b + c<\/span>:<\/p>\n<p><a href=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/derivative.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/files\/2018\/12\/derivative.png\" alt=\"Boundary operator\" width=\"300\" height=\"118\" \/><\/a><br \/>\nThis definition of the boundary operator reduces the &#8220;dimension&#8221; of a united monoid expression by 1 (unless it is already empty).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post we will explore the consequences of postulating\u00a00\u00a0=\u00a01 in an algebraic structure with two binary operations\u00a0(S,\u00a0+,\u00a00) and (S,\u00a0\u22c5,\u00a01). Such united monoids\u00a0have a few interesting properties, which are not immediately obvious. For example, we will see that the axiom\u00a00\u00a0=\u00a01\u00a0is equivalent to a seemingly less extravagant axiom ab\u00a0=\u00a0ab\u00a0+\u00a0a, which will send us tumbling down &hellip; <a href=\"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/united-monoids\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">United Monoids<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1174,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,10,3],"tags":[13,4],"class_list":["post-829","post","type-post","status-publish","format-standard","hentry","category-coding","category-math","category-thinking","tag-algebra","tag-haskell"],"_links":{"self":[{"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/posts\/829","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/users\/1174"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/comments?post=829"}],"version-history":[{"count":266,"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/posts\/829\/revisions"}],"predecessor-version":[{"id":1309,"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/posts\/829\/revisions\/1309"}],"wp:attachment":[{"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/media?parent=829"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/categories?post=829"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.ncl.ac.uk\/andreymokhov\/wp-json\/wp\/v2\/tags?post=829"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}