-module(tastoids). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src/tastoids.gleam"). -export([blend/2, retract/1, squash/1, smash/2, equal/2]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Tastoids (& their 'Temperate' Algebra)\n" "\n" " It is often said, one can't compare \"apples\" to \"oranges\",\n" " but I daresay.. _perhaps you can?_\n" "\n" " **Let me show you how.**\n" "\n" " On their own, it is hard to figure how one might compare apples to oranges,\n" " let alone deign to approach a calculus of taste however, with _just enough_\n" " structure , a **Taste** can become a **Tastoid**, along with a curious and powerful\n" " _Temperate_ Algebra.\n" "\n" " > Not unlike a [_Tropical_ geometry](https://en.wikipedia.org/wiki/Tropical_geometry),\n" " > where the notion of addition and multiplication are replaced by min(a,b) & add(a,b),\n" " > I pose that a _Temperate Algebra_ is one whose typical notions of (+,ร—) are replaced\n" " > with operations that effectively 'average' taste (with commutativity, distributivity\n" " > and reversibility, no less!)\n" " \n" " ### A Taste (t) Field\n" " \"Tastes\", broadly, are any measurable/comparable sentiment about a thing. Something\n" " with a unique direction and magnitude. _A vector!_\n" " \n" " Consider if you will, then:\n" "\n" " - The set of all Vectors are a field โ„โฟ (aka ๐•).\n" " - You may partition ๐• by some enumerable set of indices (as โ…ˆ <= countable โˆž))\n" " - The '[Algebraic extension](https://en.wikipedia.org/wiki/Algebraic_extension)'\n" " of ๐•/โ…ˆ, is itself a field (with Algebra)\n" "\n" " > In the context of large-language- and embedding-models, this idea of mapping _things_\n" " > (text or otherwise) into a well-defined set of possible indices and probabilities is\n" " > referred to as an '_embedding_'.\n" "\n" " ### A Taste -> One Tastoid\n" "\n" " We're almost there, I promise. Lets talk about plain numbers for a bit; say I told you\n" " knew the average of some set of values was 42. You also know for a fact there was a 13\n" " in there once, somewhere.\n" "\n" " Knowing nothing else, how would you _un_-average 13 from 42?\n" "\n" " _Were there two values that averaged to 42? Three? More?_\n" "\n" " Without the _cardinality_ of the original sampling, its (absolutely) impossible to know.\n" " But with it... say n=13, in which case, we can merely remove 1/13th of 13 (i.e. 1)\n" " from our combined average to find out the average without that 13 was just 41.\n" "\n" " Similarly, on their own Taste vectors _are_ comparable, even averagable in some sense,\n" " but without a cardinality, their operations aren't quite _lined up_ to have solutions\n" " to previously impossible questions become possible and yield seemingly 'free' results.\n" "\n" " Attempting to put some formalism to the above,\n" " \n" " - We can partition a taste-field further, by its cardinality k โˆˆ ๐•‚ (๐•‚ ~ โ„ x โ„โ‚„ ~ โ„‚)\n" " (As well as a 4-cycle of like -> dislike -> unlike -> undislike)\n" " \n" " i.e. someone (or thing) expressing { like ( 1+i ) -> dislike (-1 + i)\n" " ๐•’ taste (valued at weight w), k times -> un-like (-1 + -i) -> un-dislike (1 + -i) } \n" " A Tastoid, can be arrived at by a person/subject, expressing a taste _once_ (tแตข, k=1), \n" " imbedding (sic) that individuals' sentiment in a univesal/possibly infinite set of all\n" " the tastoid's that subject could express ๐•ฅแตคโ†ชแตข โˆˆ ๐•‹แตค\n" "\n" " Then, we may define a handful a tiny, tidy, yet supremely powerful (ฯƒ/sigma-)\n" " _Algebra_ of Taste_\n" "\n" " - [ ] Brief introduction to operators\n" ). -file("src/tastoids.gleam", 95). ?DOC( " Blend the two tastoids, producing a larger tastoid congruent to\n" " the weighted power mean, aka their average (via `squash`)\n" "\n" " See also `retract` - which yields u' which _unblends_ when blended,\n" ). -spec blend(tastoids@tastoid:tastoid(EAE), tastoids@tastoid:tastoid(EAE)) -> tastoids@tastoid:tastoid(EAE). blend(T, U) -> case {T, U} of {tasteless, _} -> U; {_, tasteless} -> T; {{tastoid, T@1, K_t}, {tastoid, U@1, K_u}} -> _pipe = tastoids@taste:add(T@1, U@1), {tastoid, _pipe, gleam@int:add(K_t, K_u)} end. -file("src/tastoids.gleam", 104). ?DOC(" Return the inverse of a taste (over `blend`)\n"). -spec retract(tastoids@tastoid:tastoid(EAI)) -> tastoids@tastoid:tastoid(EAI). retract(Taste) -> case Taste of {tastoid, T, K} -> _pipe = tastoids@taste:negate(T), {tastoid, _pipe, gleam@int:negate(K)}; tasteless -> tasteless end. -file("src/tastoids.gleam", 113). ?DOC( " Reduce k -> 1, yielding the 'average'/normalized tastoid of all\n" " the tastoids blended/present\n" ). -spec squash(tastoids@tastoid:tastoid(EAL)) -> tastoids@tastoid:tastoid(EAL). squash(Tastoid) -> case Tastoid of {tastoid, _, 1} = T -> T; {tastoid, _, 0} -> tasteless; {tastoid, T@1, K} -> Try_divide = gleam@float:divide(1.0, erlang:float(K)), case Try_divide of {ok, One_over_k} -> _pipe = tastoids@taste:scale(T@1, One_over_k), {tastoid, _pipe, 1}; {error, _} -> tasteless end; tasteless -> tasteless end. -file("src/tastoids.gleam", 133). ?DOC(" Combine two tastoids _hard_, blending them and returing their squashed mean.\n"). -spec smash(tastoids@tastoid:tastoid(EAO), tastoids@tastoid:tastoid(EAO)) -> tastoids@tastoid:tastoid(EAO). smash(T, U) -> _pipe = blend(T, U), squash(_pipe). -file("src/tastoids.gleam", 138). ?DOC(" Returns `True` iff Tastoids `t` & `u` are congruent (weakly equivalent)\n"). -spec equal(tastoids@tastoid:tastoid(EAS), tastoids@tastoid:tastoid(EAS)) -> boolean(). equal(T, U) -> case {T, U} of {tasteless, tasteless} -> true; {_, tasteless} -> false; {tasteless, _} -> false; {{tastoid, T@1, K_t}, {tastoid, U@1, K_u}} when K_t =:= K_u -> T@1 =:= U@1; {T@2, U@2} -> equal(squash(T@2), squash(U@2)) end.