!-so      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~        ! "!#!$!%!&!'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_"`"a"b"c"d"e"f"g"h"i"j"k"l"m"n"o"p"q"r"s"t"u"v"w"x"y"z"{"|"}"~""""""""########################$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    %%%%%% % % %  &&&&& &!&"&#&$&%&&&'&(&)&*&+&,&-&.&/&0&1&2&3&4&5&6&7&8&9&:&;&<&=&>&?&@&A&B&C&D&E&F&G&H&I&J&K&L&M&N&O&P&Q&R&S&T&U&V&W&X&Y&Z&[&\&]&^'_'`'a'b'c'd'e'f'g'h'i'j'k'l'm'n'+Safe>?A>combinat Number of cycles (of partitions) combinatNumber of leaves (of trees) combinatNumber of nodes (of trees)combinat"Shape (of tableaux, skew tableaux)combinat&Duality (of partitions, tableaux, etc)combinat%Weight (of partitions, tableaux, etc)combinatNumber of partscombinat Emptyness   None,FKE combinatThe Rand monad transformercombinat,A simple random monad to make life suck less1combinatThe boolean argument will True only for the last element4combinat8extend lines with spaces so that they have the same lineHcombinatThis may be occasionally usefulIcombinat9Puts a standard-conforming random function into the monad0 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKL0 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLNone-PcombinatOrder of elements in a matrixScombinatVertical separatorTcombinatempty separatorUcombinatn spacesVcombinat$some custom list of characters, eg. " - "5 (the characters are interpreted as below each other)WcombinatHorizontal separatorXcombinatempty separatorYcombinatn spacesZcombinatsome custom string, eg. " | "]combinatVertical alignmentacombinatHorizontal alignmentecombinat1A type class to have a simple way to draw things gcombinatnThe type of a (rectangular) ASCII figure. Internally it is a list of lines of the same length plus the size.LNote: The Show instance is pretty-printing, so that it's convenient in ghci.kcombinatAn empty (0x0) rectanglevcombinat4Horizontal append, centrally aligned, no separation.wcombinat2Vertical append, centrally aligned, no separation.xcombinat4Horizontal concatenation, top-aligned, no separationycombinat7Horizontal concatenation, bottom-aligned, no separationzcombinat3Vertical concatenation, left-aligned, no separation{combinat4Vertical concatenation, right-aligned, no separation|combinat General horizontal concatenation}combinatGeneral vertical concatenation~combinat@Horizontally pads with the given number of spaces, on both sidescombinatCVertically pads with the given number of empty lines, on both sidescombinatAPads by single empty lines vertically and two spaces horizontallycombinatExtends an ASCII figure with spaces horizontally to the given width. Note: the alignment is the alignment of the original picture in the new bigger picture!combinatExtends an ASCII figure with spaces vertically to the given height. Note: the alignment is the alignment of the original picture in the new bigger picture!combinat4Extend horizontally with the given number of spaces.combinat7Extend vertically with the given number of empty lines.combinatHorizontal indentationcombinatVertical indentationcombinat[Cuts the given number of columns from the picture. The alignment is the alignment of the picture, not the cuts.%This should be the (left) inverse of .combinatXCuts the given number of rows from the picture. The alignment is the alignment of the picture, not the cuts.%This should be the (left) inverse of .combinatPastes the first ASCII graphics onto the second, keeping the second one's dimension (that is, overlapping parts of the first one are ignored). The offset is relative to the top-left corner of the second picture. Spaces at treated as transparent.Example: tabulate (HCenter,VCenter) (HSepSpaces 2, VSepSpaces 1) [ [ caption (show (x,y)) $ pasteOnto (x,y) (filledBox '@' (4,3)) (asciiBox (7,5)) | x <- [-4..7] ] | y <- [-3..5] ]combinatPastes the first ASCII graphics onto the second, keeping the second one's dimension. The first argument specifies the transparency condition (on the first picture). The offset is relative to the top-left corner of the second picture.combinat A version of X where we can specify the corner of the second picture to which the offset is relative: &pasteOntoRel (HLeft,VTop) == pasteOntocombinat0Tabulates the given matrix of pictures. Example: tabulate (HCenter, VCenter) (HSepSpaces 2, VSepSpaces 1) [ [ asciiFromLines [ "x=" ++ show x , "y=" ++ show y ] | x<-[7..13] ] | y<-[98..102] ]combinat)Automatically tabulates ASCII rectangles.combinat4Adds a caption to the bottom, with default settings.combinat"Adds a caption to the bottom. The BoolL flag specifies whether to add an empty between the caption and the figurecombinat&An ASCII border box of the given size combinat/An "rounded" ASCII border box of the given sizecombinat,A box simply filled with the given charactercombinatA box of spacescombinat An integercombinattransparency conditioncombinat<offset relative to the top-left corner of the second picturecombinatpicture to pastecombinatpicture to paste ontocombinatAwhether to use row-major or column-major ordering of the elementscombinat (Right x) creates x columns, while (Left y) creates y rowscombinatlist of ASCII rectanglesGPRQSVUTWZYX[\]`_^adcbefghjiklmnopqrstuvwxyz{|}~Gghjiefklmnopqadcb]`_^[\WZYXrsSVUTtuvwxyz{|}~PRQSafeZcombinatLargest integer k such that 2^k is smaller or equal to ncombinatSmallest integer k such that 2^k is larger or equal to ncombinatInteger square root (largest integer whose square is smaller or equal to the input) using Newton's method, with a faster (for large numbers) inital guess based on bit shifts.combinat=Smallest integer whose square is larger or equal to the inputcombinat*We also return the excess residue; that is (a,r) = integerSquareRoot' n means that "a*a + r = n a*a <= n < (a+1)*(a+1)combinatxNewton's method without an initial guess. For very small numbers (<10^10) it is somewhat faster than the above version.Safe( combinat2Infinite list of primes, using the TMWE algorithm.combinatYA relatively simple but still quite fast implementation of list of primes. By Will Ness Ghttp://www.haskell.org/pipermail/haskell-cafe/2009-November/068441.htmlcombinat?List of primes, using tree merge with wheel. Code by Will Ness.combinatTGroups integer factors. Example: from [2,2,2,3,3,5] we produce [(2,3),(3,2),(5,1)] combinat#The naive trial division algorithm.combinatEfficient powers modulo m. powerMod a k m == (a^k) `mod` mcombinateMiller-Rabin Primality Test (taken from Haskell wiki). We test the primality of the first argument n by using the second argument a' as a candidate witness. If it returs False, then n is composite. If it returns True, then n is either prime or composite.A random choice between 2 and (n-2) is a good choice for a.combinatnFor very small numbers, we use trial division, for larger numbers, we apply the Miller-Rabin primality test log4(n)B times, with candidate witnesses derived deterministically from n) using a pseudo-random sequence (which  should be: based on a cryptographic hash function, but isn't, yet). Thus the candidate witnesses should behave essentially like random, but the resulting function is still a deterministic, pure function.8TODO: implement the hash sequence, at the moment we use () instead...combinatA more exhaustive version of r, this one tests candidate witnesses both the first log4(n) prime numbers and then log4(n) pseudo-random numbersocombinatGiven an integer nK, we initialize a system random generator with using a seed derived from nt (note that this uses at most 32 or 64 bits), and generate an infinite sequence of pseudo-random integers between 0..n-1(, generated by that random generator. JNote that this is not really a preferred way of generating such sequences! SafeEcombinat,Integer vectors. The indexing starts from 1.combinat+Vector partitions. Basically a synonym for .combinatjGenerates all vector partitions ("algorithm M" in Knuth). The order is decreasing lexicographic.  Safe combinatNPartitions of a multiset. Internally, this uses the vector partition algorithm Safe*combinat+1 or -1combinat+Negate the second argument if the first is combinat if even,  if oddcombinat (-1)^kcombinat.Negate the second argument if the first is odd NoneٿcombinatA000142.combinatA006882.combinat A007318. Note: This is zero for n<0 or k<0 ; see also  below.combinathThe extension of the binomial function to negative inputs. This should satisfy the following properties: for n,k >=0 : signedBinomial n k == binomial n k for any n,k : signedBinomial n k == signedBinomial n (n-k) for k >= 0 : signedBinomial (-n) k == (-1)^k * signedBinomial (n+k-1) k,Note: This is compatible with Mathematica's Binomial function.combinatA given row of the Pascal triangle; equivalent to a sequence of binomial numbers, but much more efficient. You can also left-fold over it. +pascalRow n == [ binomial n k | k<-[0..n] ]combinatCatalan numbers. OEIS:A000108.combinat(Catalan's triangle. OEIS:A009766. Note: fcatalanTriangle n n == catalan n catalanTriangle n k == countStandardYoungTableaux (toPartition [n,k])combinatcRows of (signed) Stirling numbers of the first kind. OEIS:A008275. Coefficients of the polinomial (x-1)*(x-2)*...*(x-n+1),. This function uses the recursion formula.combinatO(Signed) Stirling numbers of the first kind. OEIS:A008275. This function uses &, so it shouldn't be used to compute many Stirling numbers.Argument order: signedStirling1st n kcombinat3(Unsigned) Stirling numbers of the first kind. See .combinat[Stirling numbers of the second kind. OEIS:A008277. This function uses an explicit formula.Argument order: stirling2nd n kcombinatBernoulli numbers. bernoulli 1 == -1%2 and bernoulli k == 0 for k>2 and odd|. This function uses the formula involving Stirling numbers of the second kind. Numerators: A027641, denominators: A027642.combinatPBell numbers (Sloane's A000110) from B(0) up to B(n). B(0)=B(1)=1, B(2)=2, etc. %The Bell numbers count the number of set partitions of a set of size nSee (http://en.wikipedia.org/wiki/Bell_numbercombinatiThe n-th Bell number B(n), using the Stirling numbers of the second kind. This may be slower than using .*None} NoneQVTcombinat choose_ k n' returns all possible ways of choosing k disjoint elements from [1..n] choose_ k n == choose k [1..n]combinatAll possible ways to choose kZ elements from a list, without repetitions. "Antisymmetric power" for lists. Synonym for .combinat A version of * which also returns the complementer sets. choose k = map fst . choose' kcombinatAnother variation of . This satisfies Dchoose'' k == map (\(xs,ys) -> (map fst xs, map snd ys)) . choose' kcombinatAnother variation on Q which tags the elements based on whether they are part of the selected subset (p ) or not (q): &choose k = map rights . chooseTagged kcombinatAll possible ways to choose k elements from a list, with repetitions*. "Symmetric power" for lists. See also Math.Combinat.Compositions. TODO: better name?combinatA synonym for .combinat*"Tensor power" for lists. Special case of : 2tuplesFromList k xs == listTensor (replicate k xs) See also Math.Combinat.Tuples. TODO: better name?combinat"Tensor product" for lists.combinat@Sublists of a list having given number of elements. Synonym for .combinat# = binom { n } { k }.combinatAll sublists of a list.combinat# = 2^n.combinatrandomChoice k n& returns a uniformly random choice of k elements from the set [1..n]Example: Zdo cs <- replicateM 10000 (getStdRandom (randomChoice 3 7)) mapM_ print $ histogram csrcombinat?From a list of $k$ numbers, where the first is in the interval [1..n], the second in [1..n-1], the third in [1..n-2], we create a size k subset of n.1Knuth's method. The first argument is the number n.scombinat?From a list of $k$ numbers, where the first is in the interval [1..n], the second in [1..n-1], the third in [1..n-2], we create a size k subset of n. None<KVj6combinat;Disjoint cycle notation for permutations. Internally it is [[Int]].4The cycles are to be understood as follows: a cycle [c1,c2,...,ck] means the permutation '( c1 c2 c3 ... ck ) ( c2 c3 c4 ... c1 )combinatCA permutation. Internally it is an (unboxed) array of the integers [1..n]#, with indexing range also being (1,n). If this array of integers is [p1,p2,...,pn]?, then in two-line notations, that represents the permutation '( 1 2 3 ... n ) ( p1 p2 p3 ... pn )That is, it is the permutation sigma! whose (right) action on the set [1..n] is  sigma(1) = p1 sigma(2) = p2 ...((NOTE: this changed at version 0.2.8.0!)combinatNote: this is slower than combinat7Assumes that the input is a permutation of the numbers [1..n].combinatNote: Indexing starts from 1.combinat9Checks whether the input is a permutation of the numbers [1..n].combinat9Checks whether the input is a permutation of the numbers [1..n].combinatChecks the input.combinatReturns n2, where the input is a permutation of the numbers [1..n]combinat:Checks whether the permutation is the identity permutationcombinatGiven a permutation of n and a permutation of m, we return a permutation of n+mC resulting by putting them next to each other. This should satisfy YpermuteList p1 xs ++ permuteList p2 ys == permuteList (concatPermutations p1 p2) (xs++ys)combinat Synonym for combinatThe standard two-line notation, moving the element indexed by the top row into the place indexed by the corresponding element in the bottom row.combinatThe inverse two-line notation, where the it's the bottom line which is in standard order. The columns of this are a permutation of the columns .Remark: the top row of inverseTwoLineNotation perm$ is the same as the bottom row of twoLineNotation (inverse perm).combinat(Two-line notation for any set of numberscombinat#Convert to disjoint cycle notation. This is compatible with Maple's convert(perm,'disjcyc') and also with Mathematica's PermutationCycles[perm]6Note however, that for example Mathematica uses the top row/ to represent a permutation, while we use the  bottom row8 - thus even though this function looks identical, the meaning, of both the input and output is different!combinatPlus 1 or minus 1.combinatAn  inversion of a permutation sigma is a pair (i,j) such that i<j and sigma(i) > sigma(j).6This functions returns the inversion of a permutation.combinat!Returns the number of inversions: 2numberOfInversions perm = length (inversions perm) Synonym for combinatRReturns the number of inversions, using the merge-sort algorithm. This should be  O(n*log(n))combinatBReturns the number of inversions, using the definition, thus it's O(n^2). combinatNBubble sorts breaks a permutation into the product of adjacent transpositions: BmultiplyMany' n (map (transposition n) $ bubbleSort2 perm) == permcNote that while this is not unique, the number of transpositions equals the number of inversions. combinat)Another version of bubble sort. An entry i1 in the return sequence means the transposition (i,i+1): ImultiplyMany' n (map (adjacentTransposition n) $ bubbleSort perm) == perm combinatThe permutation [n,n-1,n-2,...,2,1](. Note that it is the inverse of itself. combinatOChecks whether the permutation is the reverse permutation @[n,n-1,n-2,...,2,1]. combinat)A transposition (swapping two elements). transposition n (i,j) is the permutation of size n which swaps i'th and j 'th elements.combinatProduct of transpositions. Mtranspositions n list == multiplyMany [ transposition n pair | pair <- list ]combinatadjacentTransposition n k swaps the elements k and (k+1).combinat#Product of adjacent transpositions. [adjacentTranspositions n list == multiplyMany [ adjacentTransposition n idx | idx <- list ]combinat5The permutation which cycles a list left by one step: ,permuteList (cycleLeft 5) "abcde" == "bcdea"Or in two-line notation: ( 1 2 3 4 5 ) ( 2 3 4 5 1 )combinat6The permutation which cycles a list right by one step: -permuteList (cycleRight 5) "abcde" == "eabcd"Or in two-line notation: ( 1 2 3 4 5 ) ( 5 1 2 3 4 )combinat&Multiplies two permutations together: p  q, means the permutation when we first apply p , and then q& (that is, the natural action is the right action) See also  for our conventions. combinatThe inverse permutation.combinat&The identity (or trivial) permutation.combinatMultiply together a  non-empty list of permutations (the reason for requiring the list to be non-empty is that we don't know the size of the result). See also .combinatQMultiply together a (possibly empty) list of permutations, all of which has size ncombinatRightU action of a permutation on a set. If our permutation is encoded with the sequence [p1,p2,...,pn](, then in the two-line notation we have '( 1 2 3 ... n ) ( p1 p2 p3 ... pn ).We adopt the convention that permutations act  on the right (as in Knuth): Apermute pi2 (permute pi1 set) == permute (pi1 `multiply` pi2) set Synonym to combinat"Right action on lists. Synonym to permuteListRightcombinat5The right (standard) action of permutations on sets.  PpermuteRight pi2 (permuteRight pi1 set) == permuteRight (pi1 `multiply` pi2) set3The second argument should be an array with bounds (1,n)(. The function checks the array bounds.combinatDThe right (standard) action on a list. The list should be of length n. 4fromPermutation perm == permuteRightList perm [1..n]combinat4The left (opposite) action of the permutation group. MpermuteLeft pi2 (permuteLeft pi1 set) == permuteLeft (pi2 `multiply` pi1) setIt is related to  via: ipermuteLeft pi arr == permuteRight (inverse pi) arr permuteRight pi arr == permuteLeft (inverse pi) arrcombinatCThe left (opposite) action on a list. The list should be of length n. xpermuteLeftList perm set == permuteList (inverse perm) set fromPermutation (inverse perm) == permuteLeftList perm [1..n]combinat`Given a list of things, we return a permutation which sorts them into ascending order, that is: 4permuteList (sortingPermutationAsc xs) xs == sort xstNote: if the things are not unique, then the sorting permutations is not unique either; we just return one of them.combinataGiven a list of things, we return a permutation which sorts them into descending order, that is: ?permuteList (sortingPermutationDesc xs) xs == reverse (sort xs)tNote: if the things are not unique, then the sorting permutations is not unique either; we just return one of them. combinatA synonym for ""combinatAll permutations of [1..n]) in lexicographic order, naive algorithm.$combinat# = n!%combinatA synonym for ).'combinatA synonym for *.)combinat,Generates a uniformly random permutation of [1..n] . Durstenfeld's algorithm (see  *http://en.wikipedia.org/wiki/Knuth_shuffle).*combinatGenerates a uniformly random cyclic permutation of [1..n]. Sattolo's algorithm (see  *http://en.wikipedia.org/wiki/Knuth_shuffle).+combinatYGenerates all permutations of a multiset. The order is lexicographic. A synonym for -,combinat3# = \frac { (sum_i n_i) ! } { \prod_i (n_i !) } -combinatGenerates all permutations of a multiset (based on "algorithm L" in Knuth; somewhat less efficient). The order is lexicographic. T       !"#$%&'()*+,-G       !"#$%&'()*+,-7NoneV ;combinat:A data structure which is essentially an infinite list of Integer2-s, but fast lookup (for reasonable small inputs)?combinatNumber of partitions of n3 (looking up a table built using Euler's algorithm)@combinatZThis uses the power series expansion of the infinite product. It is slower than the above.Acombinat This uses H, and is (very) slowBcombinat+This uses Euler's algorithm to compute p(n)See eg.: NEIL CALKIN, JIMENA DAVIS, KEVIN JAMES, ELIZABETH PEREZ, AND CHARLES SWANNACK COMPUTING THE INTEGER PARTITION FUNCTION Jhttp://www.math.clemson.edu/~kevja/PAPERS/ComputingPartitions-MathComp.pdfCcombinat An infinite list containing all p(n), starting from p(0).Dcombinat)Infinite list of number of partitions of  0,1,2,...This uses the infinite product formula the generating function of partitions, recursively expanding it; it is reasonably fast for small numbers. >partitionCountListInfiniteProduct == map countPartitions [0..]Ecombinat/Naive infinite list of number of partitions of  0,1,2,... 9partitionCountListNaive == map countPartitionsNaive [0..]This is very slow.GcombinatHCount all partitions fitting into a rectangle. # = \binom { h+w } { h }HcombinatJNumber of of d, fitting into a given rectangle. Naive recursive algorithm.IcombinatCount partitions of n into k parts.Naive recursive algorithm.Icombinatk = number of partscombinatn = the integer we partition;<=>?@ABCDEFGHI;<=>?@ABCDEFGHINoneVDJcombinat3Sorts the input, and cuts the nonpositive elements.Kcombinat This returns True. if the input is non-increasing sequence of positive integers (possibly empty); False otherwise.McombinatIA simpler, but bit slower (about twice?) implementation of dual partitionNcombinatFrom a sequence  [a1,a2,..,an]' computes the sequence of differences [a1-a2,a2-a3,...,an-0]OcombinatExample: g_elements [5,4,1] == [ (1,1), (1,2), (1,3), (1,4), (1,5) , (2,1), (2,2), (2,3), (2,4) , (3,1) ]Pcombinat-We convert a partition to exponential form. (i,e) mean (i^e); for example  [(1,4),(2,3)] corresponds to (1^4)(2^3) = [2,2,2,1,1,1,1]. Another example: NtoExponentialForm (Partition [5,5,3,2,2,2,2,1,1]) == [(1,2),(2,4),(3,1),(5,2)]RcombinatPartitions of d , as listsScombinatkAll integer partitions up to a given degree (that is, all integer partitions whose sum is less or equal to d)TcombinatkAll integer partitions up to a given degree (that is, all integer partitions whose sum is less or equal to d), grouped by weightUcombinatInteger partitions of d+, fitting into a given rectangle, as lists.Vcombinat0Uniformly random partition of the given weight. ,NOTE: This algorithm is effective for small n-s (say n up to a few hundred / one thousand it should work nicely), and the first time it is executed may be slower (as it needs to build the table partitionCountList first)+Algorithm of Nijenhuis and Wilf (1975); see+Knuth Vol 4A, pre-fascicle 3B, exercise 47;VNijenhuis and Wilf: Combinatorial Algorithms for Computers and Calculators, chapter 10Wcombinat1Generates several uniformly random partitions of nT at the same time. Should be a little bit faster then generating them individually.Xcombinatq `dominates` p returns True if q >= p] in the dominance order of partitions (this is partial ordering on the set of partitions of n).See ,http://en.wikipedia.org/wiki/Dominance_orderYcombinat+Lists all partitions of the same weight as lambda and also dominated by lambda0 (that is, all partial sums are less or equal): UdominatedPartitions lam == [ mu | mu <- partitions (weight lam), lam `dominates` mu ]Zcombinat+Lists all partitions of the sime weight as mu and also dominating mu3 (that is, all partial sums are greater or equal): VdominatingPartitions mu == [ lam | lam <- partitions (weight mu), lam `dominates` mu ][combinatLists partitions of n into k parts. Xsort (partitionsWithKParts k n) == sort [ p | p <- partitions n , numberOfParts p == k ]Naive recursive algorithm.\combinatPartitions of n with only odd parts]combinatPartitions of n with distinct parts.Note: Klength (partitionsWithDistinctParts d) == length (partitionsWithOddParts d)^combinatReturns Truef of the first partition is a subpartition (that is, fit inside) of the second. This includes equality_combinat7This is provided for convenience/completeness only, as: .isSuperPartitionOf q p == isSubPartitionOf p q`combinat:Sub-partitions of a given partition with the given weight: Psort (subPartitions d q) == sort [ p | p <- partitions d, isSubPartitionOf p q ]acombinat'All sub-partitions of a given partitionbcombinat<Super-partitions of a given partition with the given weight: Rsort (superPartitions d p) == sort [ q | q <- partitions d, isSubPartitionOf p q ]ccombinatThe Pieri rule computes s[lambda]*h[n] as a sum of s[mu]-s (each with coefficient 1).See for example ,http://en.wikipedia.org/wiki/Pieri's_formula| We assume here that lambda, is a partition (non-increasing sequence of positive integers)! dcombinatThe dual Pieri rule computes s[lambda]*e[n] as a sum of s[mu]-s (each with coefficient 1)Ucombinat(height,width)combinatdWcombinat number of partitions to generatecombinatthe weight of the partitions[combinatk = number of partscombinatn = the integer we partitionJKLMNOPQRSTUVWXYZ[\]^_`abcdJKLMNOPQRSTUVWXYZ[\]^_`abcdNone%Veecombinat|A partition of an integer. The additional invariant enforced here is that partitions are monotone decreasing sequences of positive integers. The Ord instance is lexicographical.jcombinatSimulated newtype constructor lcombinatKPattern sysnonyms allows us to use existing code with minimal modificationsocombinat"The first element of the sequence.pcombinat:The length of the sequence (that is, the number of parts).rcombinatQThe weight of the partition (that is, the sum of the corresponding sequence).scombinat"The dual (or conjugate) partition.tcombinatExample: telements (toPartition [5,4,1]) == [ (1,1), (1,2), (1,3), (1,4), (1,5) , (2,1), (2,2), (2,3), (2,4) , (3,1) ]ucombinat-We convert a partition to exponential form. (i,e) mean (i^e); for example  [(1,4),(2,3)] corresponds to (1^4)(2^3) = [2,2,2,1,1,1,1]. Another example: NtoExponentialForm (Partition [5,5,3,2,2,2,2,1,1]) == [(1,2),(2,4),(3,1),(5,2)]wcombinatFrom a sequence  [a1,a2,..,an]' computes the sequence of differences [a1-a2,a2-a3,...,an-0]zcombinatq `dominates` p returns True if q >= p] in the dominance order of partitions (this is partial ordering on the set of partitions of n).See ,http://en.wikipedia.org/wiki/Dominance_order{combinatReturns Truef of the first partition is a subpartition (that is, fit inside) of the second. This includes equality|combinat7This is provided for convenience/completeness only, as: .isSuperPartitionOf q p == isSubPartitionOf p q}combinatThe Pieri rule computes s[lambda]*h[n] as a sum of s[mu]-s (each with coefficient 1).See for example ,http://en.wikipedia.org/wiki/Pieri's_formula~combinatThe dual Pieri rule computes s[lambda]*e[n] as a sum of s[mu]-s (each with coefficient 1)efghijklmnopqrstuvwxyz{|}~efmnopqrstlkjihguvwxyz{|}~NoneVcombinatbWhich orientation to draw the Ferrers diagrams. For example, the partition [5,4,1] corrsponds to:In standard English notation:  @@@@@ @@@@ @<In English notation rotated by 90 degrees counter-clockwise: @ @@ @@ @@ @@@And in French notation:  @ @@@@ @@@@@combinatEnglish notationcombinat7English notation rotated by 90 degrees counterclockwisecombinat:French notation (mirror of English notation to the x axis)combinat3Sorts the input, and cuts the nonpositive elements.combinatBChecks whether the input is an integer partition. See the note at !combinat%Assumes that the input is decreasing.combinat This returns True. if the input is non-increasing sequence of positive integers (possibly empty); False otherwise.combinat/This is simply the union of parts. For example  RPartition [4,2,1] `unionOfPartitions` Partition [4,3,1] == Partition [4,4,3,2,1,1])Note: This is the dual of pointwise sum, combinat(Pointwise sum of the parts. For example: NPartition [3,2,1,1] `sumOfPartitions` Partition [4,3,1] == Partition [7,5,2,1]Note: This is the dual of combinatPartitions of d.combinatRPartitions of d, fitting into a given rectangle. The order is again lexicographic.combinatkAll integer partitions up to a given degree (that is, all integer partitions whose sum is less or equal to d)combinatkAll integer partitions up to a given degree (that is, all integer partitions whose sum is less or equal to d), grouped by weightcombinat6All integer partitions fitting into a given rectangle.combinatIAll integer partitions fitting into a given rectangle, grouped by weight.combinat0Uniformly random partition of the given weight. ,NOTE: This algorithm is effective for small n-s (say n up to a few hundred / one thousand it should work nicely), and the first time it is executed may be slower (as it needs to build the table of partitions counts first)+Algorithm of Nijenhuis and Wilf (1975); see+Knuth Vol 4A, pre-fascicle 3B, exercise 47;VNijenhuis and Wilf: Combinatorial Algorithms for Computers and Calculators, chapter 10combinat1Generates several uniformly random partitions of nT at the same time. Should be a little bit faster then generating them individually.combinat+Lists all partitions of the same weight as lambda and also dominated by lambda0 (that is, all partial sums are less or equal): UdominatedPartitions lam == [ mu | mu <- partitions (weight lam), lam `dominates` mu ]combinat+Lists all partitions of the sime weight as mu and also dominating mu3 (that is, all partial sums are greater or equal): VdominatingPartitions mu == [ lam | lam <- partitions (weight mu), lam `dominates` mu ]combinatLists partitions of n into k parts. Xsort (partitionsWithKParts k n) == sort [ p | p <- partitions n , numberOfParts p == k ]Naive recursive algorithm.combinatPartitions of n with only odd partscombinatPartitions of n with distinct parts.Note: Klength (partitionsWithDistinctParts d) == length (partitionsWithOddParts d)combinat:Sub-partitions of a given partition with the given weight: Psort (subPartitions d q) == sort [ p | p <- partitions d, isSubPartitionOf p q ]combinat'All sub-partitions of a given partitioncombinat<Super-partitions of a given partition with the given weight: Rsort (superPartitions d p) == sort [ q | q <- partitions d, isSubPartitionOf p q ]combinat Synonym for (asciiFerrersDiagram' EnglishNotation '@'Try for example: HautoTabulate RowMajor (Right 8) (map asciiFerrersDiagram $ partitions 9)combinat(height,width)combinatdcombinat(height,width)combinat(height,width)combinat number of partitions to generatecombinatthe weight of the partitionscombinatk = number of partscombinatn = the integer we partition<?FGHIefghijklmnopqrstuvwxyz{|}~#e?HFGINone- combinatA skew partition  lambda/mu' is internally represented by the list &[ (mu_i , lambda_i-mu_i) | i<-[1..n] ]combinatmkSkewPartition (lambda,mu) creates the skew partition  lambda/mu. Throws an error if mu is not a sub-partition of lambda.combinatReturns t if mu is not a sub-partition of lambda.combinatThe weight of a skew partition is the weight of the outer partition minus the the weight of the inner partition (that is, the number of boxes present).combinatFThis function "cuts off" the "uninteresting parts" of a skew partitioncombinatHReturns the outer and inner partition of a skew partition, respectively: )mkSkewPartition . fromSkewPartition == idcombinatThe lambda part of  lambda/mucombinatThe mu part of  lambda/mucombinatHThe dual skew partition (that is, the mirror image to the main diagonal)combinatSee "partitionElements"combinatLLists all skew partitions with the given outer shape and given (skew) weightcombinatJLists all skew partitions with the given outer shape and any (skew) weightcombinatLLists all skew partitions with the given inner shape and given (skew) weightNone:combinatA partition of the set [1..n] (in standard order)combinatyThe "shape" of a set partition is the partition we get when we forget the set structure, keeping only the cardinalities.combinat Synonym for combinat Synonym for  ^sort (setPartitionsWithKParts k n) == sort [ p | p <- setPartitions n , numberOfParts p == k ]combinatList all set partitions of [1..n], naive algorithmcombinatSet partitions of the set [1..n] into k partscombinat.Set partitions are counted by the Bell numberscombinatSet partitions of size k3 are counted by the Stirling numbers of second kindcombinatk = number of partscombinatn = size of the setcombinatk = number of partscombinatn = size of the setcombinatk = number of partscombinatn = size of the set+None;<?FGHIefghijklmnopqrstuvwxyz{|}~NoneK|'combinatMThe series [1,0,0,0,0,...], which is the neutral element for the convolution.combinatConstant zero seriescombinat-Power series representing a constant functioncombinat9The power series representation of the identity function xcombinat#The power series representation of x^ncombinat'A different implementation, taken from:0M. Douglas McIlroy: Power Series, Power Serious combinatEMultiplication of power series. This implementation is a synonym for combinatConvolution of series (that is, multiplication of power series). The result is always an infinite list. Warning: This is slow!combinat3Convolution (= product) of many series. Still slow!combinatDivision of series.<Taken from: M. Douglas McIlroy: Power Series, Power Serious combinatGGiven a power series, we iteratively compute its multiplicative inversecombinat#Given a power series starting with 1?, we can compute its multiplicative inverse without divisions.combinatg `composeSeries` f" is the power series expansion of g(f(x)). This is a synonym for flip substitute.!This implementation is taken from0M. Douglas McIlroy: Power Series, Power Serious combinatsubstitute f g& is the power series corresponding to g(f(x))Y. Equivalently, this is the composition of univariate functions (in the "wrong" order).yNote: for this to be meaningful in general (not depending on convergence properties), we need that the constant term of f is zero.combinatNaive implementation of  (via )combinatNaive implementation of combinat$We expect the input series to match (0:a1:_)X. with a1 nonzero The following is true for the result (at least with exact arithmetic): qsubstitute f (lagrangeInversion f) == (0 : 1 : repeat 0) substitute (lagrangeInversion f) f == (0 : 1 : repeat 0)"This implementation is taken from:0M. Douglas McIlroy: Power Series, Power Serious combinat&Coefficients of the Lagrange inversioncombinat$We expect the input series to match (0:1:_)H. The following is true for the result (at least with exact arithmetic): substitute f (integralLagrangeInversion f) == (0 : 1 : repeat 0) substitute (integralLagrangeInversion f) f == (0 : 1 : repeat 0)combinatNaive implementation of combinatPower series expansion of exp(x)combinatPower series expansion of cos(x)combinatPower series expansion of sin(x)combinat8Alternative implementation using differential equations.;Taken from: M. Douglas McIlroy: Power Series, Power Seriouscombinat8Alternative implementation using differential equations.;Taken from: M. Douglas McIlroy: Power Series, Power SeriouscombinatPower series expansion of cosh(x)combinatPower series expansion of sinh(x)combinatPower series expansion of log(1+x)combinatPower series expansion of (1-Sqrt[1-4x])/(2x)+ (the coefficients are the Catalan numbers)combinatPower series expansion of  /1 / ( (1-x^k_1) * (1-x^k_2) * ... * (1-x^k_n) )Example:(coinSeries [2,3,5])!!k is the number of ways to pay k3 dollars with coins of two, three and five dollars.TODO: better name?combinatBGeneralization of the above to include coefficients: expansion of <1 / ( (1-a_1*x^k_1) * (1-a_2*x^k_2) * ... * (1-a_n*x^k_n) ) combinatConvolution of many G, that is, the expansion of the reciprocal of a product of polynomialscombinatThe same, with coefficients.combinatbThis is the most general function in this module; all the others are special cases of this one. combinatThe power series expansion of -1 / (1 - x^k_1 - x^k_2 - x^k_3 - ... - x^k_n)combinat!Convolve with (the expansion of) -1 / (1 - x^k_1 - x^k_2 - x^k_3 - ... - x^k_n)combinatThe expansion of =1 / (1 - a_1*x^k_1 - a_2*x^k_2 - a_3*x^k_3 - ... - a_n*x^k_n)combinat!Convolve with (the expansion of) =1 / (1 - a_1*x^k_1 - a_2*x^k_2 - a_3*x^k_3 - ... - a_n*x^k_n)combinat!Convolve with (the expansion of)  21 / (1 +- x^k_1 +- x^k_2 +- x^k_3 +- ... +- x^k_n)Should be faster than using  . Note:  corresponds to the coefficient -1 in 8 (since there is a minus sign in the definition there)!33None combinatA  composition of an integer n into k parts is an ordered kB-tuple of nonnegative (sometimes positive) integers whose sum is n.combinatkCompositions fitting into a given shape and having a given degree. The order is lexicographic, that is, .sort cs == cs where cs = compositions' shape kcombinatbAll positive compositions of a given number (filtrated by the length). Total number of these is 2^(n-1) combinat,All compositions fitting into a given shape. combinat+Nonnegative compositions of a given length. combinat # = \binom { len+d-1 } { len-1 } combinat(Positive compositions of a given length.combinatrandomComposition k n8 returns a uniformly random composition of the number n as an (ordered) sum of k  nonnegative numberscombinatrandomComposition1 k n8 returns a uniformly random composition of the number n as an (ordered) sum of k positive numberscombinatshapecombinatsum combinatlengthcombinatsum combinatlengthcombinatsum            NonecombinatVenn diagrams of n= sets. Each possible zone is annotated with a value of type aL. A typical use case is to annotate with the cardinality of the given zone./Internally this is representated by a map from [Bool], where True means element of the set, False means not.NTODO: write a more efficient implementation (for example an array of size 2^n)combinat%How many sets are in the Venn diagramcombinat&How many zones are in the Venn diagram =vennDiagramNumberOfZones v == 2 ^ (vennDiagramNumberOfSets v)combinat How many nonempty zones are in the Venn diagramcombinat~We call venn diagram trivial if all the intersection zones has zero cardinality (that is, the original sets are all disjoint)combinatoGiven a Venn diagram of cardinalities, we compute the cardinalities of the original sets (note: this is slow!)combinatQGiven the cardinalities of some finite sets, we list all possible Venn diagrams.ONote: we don't include the empty zone in the tables, because it's always empty.DRemark: if each sets is a singleton set, we get back set partitions: > [ length $ enumerateVennDiagrams $ replicate k 1 | k<-[1..8] ] [1,2,5,15,52,203,877,4140] > [ countSetPartitions k | k<-[1..8] ] [1,2,5,15,52,203,877,4140]/Maybe this could be called multiset-partitions?Example: KautoTabulate RowMajor (Right 6) $ map ascii $ enumerateVennDiagrams [2,3,3]  None%e',combinatSimulated newtype constructor .combinatKPattern sysnonyms allows us to use existing code with minimal modifications/combinat for debugging0combinatThe lexicographic ordering5combinat !partitionTail p == snd (uncons p)6combinatWe assume that x >= partitionHeight p!7combinat?We assume that the element is not bigger than the last element!:combinatWidth, or the number of parts;combinat3Height, or the first (that is, the largest) element<combinatWidth and height =combinatFrom a non-increasing sequence  [a1,a2,..,an], this computes the sequence of differences [a1-a2,a2-a3,...,an-0]>combinatFrom a non-increasing sequence  [a1,a2,..,an]5 this computes the reversed sequence of differences 7[ a[n]-0 , a[n-1]-a[n] , ... , a[2]-a[3] , a[1]-a[2] ] Acombinat*returns a descending (non-increasing) listBcombinat3Returns a reversed (ascending; non-decreasing) listDcombinat5We assume that the input is a non-increasing list of positive integers!NcombinatExpands to product s[lambda]*h[1] = s[lambda]*e[1] as a sum of s[mu]-s. See -https://en.wikipedia.org/wiki/Pieri's_formulaOcombinatExpands to product s[lambda]*h[k] as a sum of s[mu]-s. See -https://en.wikipedia.org/wiki/Pieri's_formulaDcombinatlengthcombinatthe list5!'&%$#"()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU5!'&%$#"/.-,+*)0123456789:;<=>(?@ABCDEFGHIJKLMNOPQRSTUNone&#YcombinatA wordy, describing (non-uniquely) an element of a group. The identity element is represented (among others) by the empty word.ZcombinatXA generator of a (free) group, indexed by which "copy" of the group we are dealing with.]combinatThe index of a generator^combinatGThe sign of the (exponent of the) generator (that is, the generator is , the inverse is )`combinat&keep the index, but return always the [ one.acombinat'Generators are shown as small letters: a, b, c;, ... and their inverses are shown as capital letters, so A=a^-1, B=b^-1, etc.ccombinatThe inverse of a generatordcombinatThe inverse of a wordecombinat:Lists all words of the given length (total number will be (2g)^n'). The numbering of the generators is [1..g].fcombinatcLists all words of the given length which do not contain inverse generators (total number will be g^n'). The numbering of the generators is [1..g].gcombinat2A random group generator (or its inverse) between 1 and ghcombinat9A random group generator (but never its inverse) between 1 and gicombinatA random word of length n using g generators (or their inverses)jcombinatA random word of length n using g$ generators (but not their inverses)kcombinatkMultiplication of the free group (returns the reduced result). It is true for any two words w1 and w2 that EmultiplyFree (reduceWordFree w1) (reduceWord w2) = multiplyFree w1 w2lcombinatLDecides whether two words represent the same group element in the free groupmcombinat6Reduces a word in a free group by repeatedly removing x*x^(-1) and x^(-1)*x pairs. The set of  reduced words^ forms the free group; the multiplication is obtained by concatenation followed by reduction.ncombinat=Naive (but canonical) reduction algorithm for the free groupsocombinat%Counts the number of words of length n& which reduce to the identity element.Generating function is 9Gf_g(u) = \frac {2g-1} { g-1 + g \sqrt{ 1 - (8g-4)u^2 } }pcombinat%Counts the number of words of length n whose reduced form has length k (clearly n and k3 must have the same parity for this to be nonzero): ^countWordReductionsFree g n k == sum [ 1 | w <- allWords g n, k == length (reduceWordFree w) ]qcombinat'Multiplication in free products of Z2'srcombinat'Multiplication in free products of Z3'sscombinat'Multiplication in free products of Zm'stcombinatQDecides whether two words represent the same group element in free products of Z2ucombinatQDecides whether two words represent the same group element in free products of Z3vcombinatQDecides whether two words represent the same group element in free products of Zmwcombinat%Reduces a word, where each generator x# satisfies the additional relation x^2=1" (that is, free products of Z2's)xcombinat%Reduces a word, where each generator x# satisfies the additional relation x^3=1" (that is, free products of Z3's)ycombinat%Reduces a word, where each generator x# satisfies the additional relation x^m=1" (that is, free products of Zm's)zcombinat%Reduces a word, where each generator x# satisfies the additional relation x^2=1D (that is, free products of Z2's). Naive (but canonical) algorithm.{combinat%Reduces a word, where each generator x# satisfies the additional relation x^3=1D (that is, free products of Z3's). Naive (but canonical) algorithm.|combinat%Reduces a word, where each generator x# satisfies the additional relation x^m=1D (that is, free products of Zm's). Naive (but canonical) algorithm.}combinatBCounts the number of words (without inverse generators) of length n= which reduce to the identity element, using the relations x^2=1.Generating function is 9Gf_g(u) = \frac {2g-2} { g-2 + g \sqrt{ 1 - (4g-4)u^2 } }The first few g cases: A000984 = [ countIdentityWordsZ2 2 (2*n) | n<-[0..] ] = [1,2,6,20,70,252,924,3432,12870,48620,184756...] A089022 = [ countIdentityWordsZ2 3 (2*n) | n<-[0..] ] = [1,3,15,87,543,3543,23823,163719,1143999,8099511,57959535...] A035610 = [ countIdentityWordsZ2 4 (2*n) | n<-[0..] ] = [1,4,28,232,2092,19864,195352,1970896,20275660,211823800,2240795848...] A130976 = [ countIdentityWordsZ2 5 (2*n) | n<-[0..] ] = [1,5,45,485,5725,71445,925965,12335685,167817405,2321105525,32536755565...]~combinatBCounts the number of words (without inverse generators) of length nJ whose reduced form in the product of Z2-s (that is, for each generator x we have x^2=1) has length k (clearly n and k3 must have the same parity for this to be nonzero): _countWordReductionsZ2 g n k == sum [ 1 | w <- allWordsNoInv g n, k == length (reduceWordZ2 w) ]combinatBCounts the number of words (without inverse generators) of length n= which reduce to the identity element, using the relations x^3=1. acountIdentityWordsZ3NoInv g n == sum [ 1 | w <- allWordsNoInv g n, 0 == length (reduceWordZ2 w) ] In mathematica, the formula is: BSum[ g^k * (g-1)^(n-k) * k/n * Binomial[3*n-k-1, n-k] , {k, 1,n} ] ecombinatg = number of generators combinatn = length of the wordfcombinatg = number of generators combinatn = length of the wordgcombinatg = number of generators hcombinatg = number of generators icombinatg = number of generators combinatn = length of the wordjcombinatg = number of generators combinatn = length of the wordocombinat*g = number of generators in the free groupcombinat n = length of the unreduced wordpcombinat*g = number of generators in the free groupcombinat n = length of the unreduced wordcombinatk = length of the reduced word}combinat*g = number of generators in the free groupcombinat n = length of the unreduced word~combinat*g = number of generators in the free groupcombinat n = length of the unreduced wordcombinatk = length of the reduced wordcombinat*g = number of generators in the free groupcombinat n = length of the unreduced word'YZ\[]^_`abcdefghijklmnopqrstuvwxyz{|}~'Z\[]^_`Yabcdefghijklmnopqrstuvwxyz{|}~None;=>?5Fcombinat3A tableau is simply represented as a list of lists.combinatASCII diagram of a tableaucombinatThe shape of a tableaucombinatNumber of entriescombinatAThe dual of the tableau is the mirror image to the main diagonal.combinatThe content of a tableau is the list of its entries. The ordering is from the left to the right and then from the top to the bottomcombinat An element (i,j)x of the resulting tableau (which has shape of the given partition) means that the vertical part of the hook has length i, and the horizontal part j. The  hook length is thus i+j-1. Example: m> mapM_ print $ hooks $ toPartition [5,4,1] [(3,5),(2,4),(2,3),(2,2),(1,1)] [(2,4),(1,3),(1,2),(1,1)] [(1,1)]combinatThe row wordl of a tableau is the list of its entry read from the right to the left and then from the top to the bottom.combinat Semistandard3 tableaux can be reconstructed from their row wordscombinatThe  column wordj of a tableau is the list of its entry read from the bottom to the top and then from the left to the rightcombinatStandardD tableaux can be reconstructed from either their column or row wordscombinat4Checks whether a sequence of positive integers is a  lattice wordF, which means that in every initial part of the sequence any number i) occurs at least as often as the number i+1combinat A tableau is  semistandardV if its entries are weekly increasing horizontally and strictly increasing verticallycombinatASemistandard Young tableaux of given shape, "naive" algorithm combinat+Stanley's hook formula (cf. Fulton page 55)combinat A tableau is standard2 if it is semistandard and its content is exactly [1..n] , where n is the weight.combinatOStandard Young tableaux of a given shape. Adapted from John Stembridge,  ?http://www.math.lsa.umich.edu/~jrs/software/SFexamples/tableaux.combinathook-length formulaNoneAscombinatHA plane partition encoded as a tablaeu (the "Z" heights are the numbers)combinat9Throws an exception if the input is not a plane partitioncombinatDThe XY projected shape of a plane partition, as an integer partitioncombinat!The Z height of a plane partitioncombinatoStacks layers of partitions into a plane partition. Throws an exception if they do not form a plane partition.combinatStacks layers of partitions into a plane partition. This is unsafe in the sense that we don't check that the partitions fit on the top of each other.combinat0The "layers" of a plane partition (in direction Z). We should have ,unsafeStackLayers (planePartLayers pp) == ppcombinat"Plane partitions of a given weight  NoneVi combinatA Gelfand-Tstetlin tableaucombinatHKostka numbers (via counting Gelfand-Tsetlin patterns). See for example *http://en.wikipedia.org/wiki/Kostka_numberK(lambda,mu)==0 unless lambda dominates mu: [[ mu | mu <- partitions (weight lam) , kostkaNumber lam mu > 0 ] == dominatedPartitions lamcombinatFVery naive (and slow) implementation of Kostka numbers, for reference.combinat$Lists all (positive) Kostka numbers  K(lambda,mu) with the given lambda: xkostkaNumbersWithGivenLambda lambda == Map.fromList [ (mu , kostkaNumber lambda mu) | mu <- dominatedPartitions lambda ]_It's much faster than computing the individual Kostka numbers, but not as fast as it could be.combinat$Lists all (positive) Kostka numbers  K(lambda,mu) with the given mu: ukostkaNumbersWithGivenMu mu == Map.fromList [ (lambda , kostkaNumber lambda mu) | lambda <- dominatingPartitions mu ]CThis function uses the iterated Pieri rule, and is relatively fast.combinatMGenerates all Kostka-Gelfand-Tsetlin tableau, that is, triangular arrays like /[ 3 ] [ 3 , 2 ] [ 3 , 1 , 0 ] [ 2 , 0 , 0 , 0 ]_with both rows and column non-increasing such that the top diagonal read lambda (in this case  lambda=[3,2]>) and the diagonal sums are partial sums of mu (in this case  mu=[2,1,1,1])BThe number of such GT tableaux is the Kostka number K(lambda,mu).combinat-This returns the corresponding Kostka number: ^countKostkaGelfandTsetlinPatterns lambda mu == length (kostkaGelfandTsetlinPatterns lambda mu)combinat Computes the Schur expansion of h[n1]*h[n2]*h[n3]*...*h[nk]n via iterating the Pieri rule. Note: the coefficients are actually the Kostka numbers; the following is true: vMap.toList (iteratedPieriRule (fromPartition mu)) == [ (lam, kostkaNumber lam mu) | lam <- dominatingPartitions mu ]KThis should be faster than individually computing all these Kostka numbers.combinatAIterating the Pieri rule, we can compute the Schur expansion of %h[lambda]*h[n1]*h[n2]*h[n3]*...*h[nk]combinat Computes the Schur expansion of e[n1]*e[n2]*e[n3]*...*e[nk]n via iterating the Pieri rule. Note: the coefficients are actually the Kostka numbers; the following is true: Map.toList (iteratedDualPieriRule (fromPartition mu)) == [ (dualPartition lam, kostkaNumber lam mu) | lam <- dominatingPartitions mu ]jThis should be faster than individually computing all these Kostka numbers. It is a tiny bit slower than .combinatAIterating the Pieri rule, we can compute the Schur expansion of %e[lambda]*e[n1]*e[n2]*e[n3]*...*e[nk]None;=qccombinatSet of (i,j) pairs with i>=j>=1.combinatTriangular arrayscombinatGenerates all tableaux of size k. Effective for k<=6.combinat;Note: This is slow (it actually generates all the tableaux)combinat<We can flip the numbers in the tableau so that the interval [1..c] becomes [c..1][. This way we a get a maybe more familiar form, when each row and each column is strictly  decreasing" (to the right and to the bottom).None>?V combinat>A skew tableau is represented by a list of offsets and entriescombinatThe shape of a skew tableau combinatLThe weight of a tableau is the weight of its shape, or the number of entriescombinatJThe dual of a skew tableau, that is, its mirror image to the main diagonalcombinat A tableau is  semistandardV if its entries are weekly increasing horizontally and strictly increasing verticallycombinat A tableau is standard2 if it is semistandard and its content is exactly [1..n] , where n is the weight.combinat8All semi-standard skew tableaux filled with the numbers [1..n]combinat<ASCII drawing of a skew tableau (using the English notation)combinat/The reversed (right-to-left) rows, concatenatedcombinat2The reversed (bottom-to-top) columns, concatenatedcombinat7Fills a skew partition with content, in row word order combinat:Fills a skew partition with content, in column word order combinatZIf the skew tableau's row word is a lattice word, we can make a partition from its contentcombinatBstring representing the elements of the inner (unfilled) partitioncombinat orientationNoneucombinat@A diagram is a set of boxes in a skew shape (in the right order)vcombinat'A filling is a pair consisting a shape nu and a lattice permutation lpcombinatNaive (very slow) reference implementation of the Littlewood-Richardson rule, based on the definition "count the semistandard skew tableaux whose row content is a lattice word"combinatlrRule3 computes the expansion of a skew Schur function  s[lambda/mu]$ via the Littlewood-Richardson rule.-Adapted from John Stembridge's Maple code: >http://www.math.lsa.umich.edu/~jrs/software/SFexamples/LR_rule lrRule (mkSkewPartition (lambda,nu)) == Map.fromList list where muw = weight lambda - weight nu list = [ (mu, coeff) | mu <- partitions muw , let coeff = lrCoeff lambda (mu,nu) , coeff /= 0 ] combinat_lrRule lambda mu4 computes the expansion of the skew Schur function  s[lambda/mu]$ via the Littlewood-Richardson rule.wcombinatNote: we use reverse ordering in Diagrams compared the Stembridge's code. Also, for performance reasons, we need the length of the diagramcombinatlrCoeff lam (mu,nu)a computes the coressponding Littlewood-Richardson coefficients. This is also the coefficient of  s[lambda] in the product  s[mu]*s[nu]%Note: This is much slower than using  or 3 to compute several coefficients at the same time!combinatlrCoeff (lam/nu) mua computes the coressponding Littlewood-Richardson coefficients. This is also the coefficient of s[mu] in the product  s[lam/nu]%Note: This is much slower than using  or 3 to compute several coefficients at the same time!combinat!lrScalar (lambda/mu) (alpha/beta)> computes the scalar product of the two skew Schur functions  s[lambda/mu] and  s[alpha/beta]$ via the Littlewood-Richardson rule.+Adapted from John Stembridge Maple code: >http://www.math.lsa.umich.edu/~jrs/software/SFexamples/LR_rulexcombinatNote: we use reverse ordering in Diagrams compared the Stembridge's code. Also, for performance reasons, we need the length of the diagramcombinat;Computes the expansion of the product of Schur polynomials  s[mu]*s[nu]U using the Littlewood-Richardson rule. Note: this is symmetric in the two arguments.Based on the wikipedia article 8https://en.wikipedia.org/wiki/Littlewood-Richardson_rule lrMult mu nu == Map.fromList list where lamw = weight nu + weight mu list = [ (lambda, coeff) | lambda <- partitions lamw , let coeff = lrCoeff lambda (mu,nu) , coeff /= 0 ] ycombinatdThis basically lists all the outer shapes (with multiplicities) which can be result from the LR rulezcombinatAdds a full row of (length pcols) boxes containing to a partition, with pcols being the upper bounds of the columns, respectively. We also return the newly added columns{combinatReturns the (row,column) pairs of the new boxes which can be added to the given partition with the given column bounds and the 1-Rieri rule |combinatAdds a box to a partition}combinat'Safe head defaulting to zero ~combinat]Computes the sequence of differences from a partition (including the last difference to zero)NoneVcombinat"A box on the border of a partitioncombinatqBorder strips (or ribbons) are defined to be skew partitions which are connected and do not contain 2x2 blocks.The length@ of a border strip is the number of boxes it contains, and its height[ is defined to be one less than the number of rows (in English notation) it occupies. The widthR is defined symmetrically to be one less than the number of columns it occupies.combinat%The coordinates of the outer corners combinatgThe coordinates of the inner corners, including the two on the two coordinate axes. For the partition [5,4,1] the result should be [(0,5),(1,4),(2,1),(3,0)]combinat&Sequence of all the (extended) cornerscombinatThe inner corner boxes; of the partition. Coordinates are counted from 1 (cf.the t^ function), and the first coordinate is the row, the second the column (in English notation).For the partition [5,4,1] the result should be  [(1,4),(2,1)] FinnerCornerBoxes lambda == (tail $ init $ extendedInnerCorners lambda)combinatThe outer corner boxes; of the partition. Coordinates are counted from 1 (cf.the t^ function), and the first coordinate is the row, the second the column (in English notation).For the partition [5,4,1] the result should be [(1,5),(2,4),(3,1)]combinatqThe outer and inner corner boxes interleaved, so together they form the turning points of the full border stripcombinat(Naive (and very slow) implementation of innerCornerBoxes, for testing purposescombinat(Naive (and very slow) implementation of outerCornerBoxes, for testing purposes combinatvA skew partition is a a ribbon (or border strip) if and only if projected to the diagonals the result is an interval. combinatRibbons (or border strips) are defined to be skew partitions which are connected and do not contain 2x2 blocks. This function returns the border strips whose outer partition is the given one. combinat4Inner border strips (or ribbons) of the given length combinatHooks of length n% (TODO: move to the partition module)combinat4Outer border strips (or ribbons) of the given lengthcombinat?Naive (and slow) implementation listing all inner border stripscombinatSNaive (and slow) implementation listing all inner border strips of the given lengthcombinatSNaive (and slow) implementation listing all outer border strips of the given lengthcombinatiThe boxes of the full inner border strip, annotated with whether a border strip can start or end there.combinatiThe boxes of the full outer border strip, annotated with whether a border strip can start or end there.          !Safe%combinatGenerates graphviz .dot file from a forest. The first argument tells whether to make the individual trees clustered subgraphs; the second is the name of the graph.&combinatGenerates graphviz .dot@ file from a tree. The first argument is the name of the graph.%combinat-make the individual trees clustered subgraphscombinat#reverse the direction of the arrowscombinatname of the graph&combinat"reverse the direction of the arrowcombinatname of the graph"#$%&"#$%&None;=combinatDA binary tree with leaves and internal nodes decorated with types a and b, respectively.combinat.A binary tree with leaves decorated with type a.+combinat*The monadic join operation of binary trees-combinatBEnumerates the leaves a tree, starting from 0, ignoring old labels.combinatWEnumerates the leaves a tree, starting from zero, and also returns the number of leaves/combinat0Enumerates the leaves a tree, starting from zero0combinat+Convert a binary tree to a rose tree (from  Data.Tree)<combinat8Generates all sequences of nested parentheses of length 2n in lexigraphic order. Synonym for @.=combinat Synonym for A.>combinat Synonym for B.@combinatGenerates all sequences of nested parentheses of length 2n. Order is lexicographical (when right parentheses are considered smaller then left ones). Based on "Algorithm P" in Knuth, but less efficient because of the "idiomatic" code.AcombinatoGenerates a uniformly random sequence of nested parentheses of length 2n. Based on "Algorithm W" in Knuth.BcombinatONth sequence of nested parentheses of length 2n. The order is the same as in @#. Based on "Algorithm U" in Knuth.Ccombinat Generates all binary trees with n- nodes. At the moment just a synonym for E.Dcombinat9# = Catalan(n) = \frac { 1 } { n+1 } \binom { 2n } { n }.FThis is also the counting function for forests and nested parentheses.Ecombinat=Generates all binary trees with n nodes. The naive algorithm.Fcombinat1Generates an uniformly random binary tree, using G.GcombinatGrows a uniformly random binary tree. "Algorithm R" (Remy's procudere) in Knuth. Nodes are decorated with odd numbers, leaves with even numbers (from the set [0..2n]"). Uses mutable arrays internally.Hcombinat3Draws a binary tree in ASCII, ignoring node labels.Example: FautoTabulate RowMajor (Right 5) $ map asciiBinaryTree_ $ binaryTrees 4Bcombinatncombinat!N; should satisfy 1 <= N <= C(n) 4 "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH4*+,'()23 01-/.<=>?@ABCDEFGH"#$%&456789;:"None;=T!_combinat]A lattice path is a path using only the allowed steps, never going below the zero level line y=0. nNote that if you rotate such a path by 45 degrees counterclockwise, you get a path which uses only the steps (1,0) and (0,1)Z, and stays above the main diagonal (hence the name, we just use a different convention).`combinatA step in a lattice pathacombinat the step (1,1)bcombinat the step (1,-1)ccombinat5Draws the path into a list of lines. For example try: =autotabulate RowMajor (Right 5) (map asciiPath $ dyckPaths 4)dcombinat=A lattice path is called "valid", if it never goes below the y=0 line.ecombinat;A Dyck path is a lattice path whose last point lies on the y=0 linefcombinat Maximal height of a lattice pathgcombinat.Endpoint of a lattice path, which starts from (0,0).hcombinatBReturns the coordinates of the path (excluding the starting point (0,0), but including the endpoint)icombinatCounts the up-stepsjcombinatCounts the down-stepskcombinat'Counts both the up-steps and down-stepslcombinat2Number of peaks of a path (excluding the endpoint)mcombinat-Number of points on the path which touch the y=00 zero level line (excluding the starting point (0,0)S, but including the endpoint; that is, for Dyck paths it this is always positive!).ncombinatBNumber of points on the path which touch the level line at height h (excluding the starting point (0,0), but including the endpoint).ocombinat dyckPaths m lists all Dyck paths from (0,0) to (2m,0). hRemark: Dyck paths are obviously in bijection with nested parentheses, and thus also with binary trees.!Order is reverse lexicographical: +sort (dyckPaths m) == reverse (dyckPaths m)pcombinat dyckPaths m lists all Dyck paths from (0,0) to (2m,0).  .sort (dyckPathsNaive m) == sort (dyckPaths m) *Naive recursive algorithm, order is ad-hocqcombinatThe number of Dyck paths from (0,0) to (2m,0)# is simply the m'th Catalan number.rcombinatThe trivial bijectionscombinat,The trivial bijection in the other directiontcombinatboundedDyckPaths h m lists all Dyck paths from (0,0) to (2m,0) whose height is at most h. Synonym for u.ucombinatboundedDyckPathsNaive h m lists all Dyck paths from (0,0) to (2m,0) whose height is at most h. sort (boundedDyckPaths h m) == sort [ p | p <- dyckPaths m , pathHeight p <= h ] sort (boundedDyckPaths m m) == sort (dyckPaths m) <Naive recursive algorithm, resulting order is pretty ad-hoc.vcombinatAll lattice paths from (0,0) to (x,y). Clearly empty unless x-y is even. Synonym for wwcombinatAll lattice paths from (0,0) to (x,y). Clearly empty unless x-y is even. Note that 1sort (dyckPaths n) == sort (latticePaths (0,2*n))<Naive recursive algorithm, resulting order is pretty ad-hoc.xcombinatALattice paths are counted by the numbers in the Catalan triangle.ycombinattouchingDyckPaths k m lists all Dyck paths from (0,0) to (2m,0)# which touch the zero level line y=0 exactly kI times (excluding the starting point, but including the endpoint; thus, k" should be positive). Synonym for z.zcombinattouchingDyckPathsNaive k m lists all Dyck paths from (0,0) to (2m,0)# which touch the zero level line y=0 exactly kI times (excluding the starting point, but including the endpoint; thus, k should be positive). csort (touchingDyckPathsNaive k m) == sort [ p | p <- dyckPaths m , pathNumberOfZeroTouches p == k ]<Naive recursive algorithm, resulting order is pretty ad-hoc.{combinatDThere is a bijection from the set of non-empty Dyck paths of length 2n which touch the zero lines t times, to lattice paths from (0,0) to  (2n-t-1,t-1) (just remove all the down-steps just before touching the zero line, and also the very first up-step). This gives us a counting formula.|combinatpeakingDyckPaths k m lists all Dyck paths from (0,0) to (2m,0) with exactly k peaks. Synonym for }}combinatpeakingDyckPathsNaive k m lists all Dyck paths from (0,0) to (2m,0) with exactly k peaks. [sort (peakingDyckPathsNaive k m) = sort [ p | p <- dyckPaths m , pathNumberOfPeaks p == k ]<Naive recursive algorithm, resulting order is pretty ad-hoc.~combinatDyck paths of length 2m with k+ peaks are counted by the Narayana numbers &N(m,k) = binom{m}{k} binom{m}{k-1} / mcombinat'A uniformly random Dyck path of length 2m ncombinath = the touch leveltcombinath = maximum heightcombinatm = half-lengthucombinath = maximum heightcombinatm = half-lengthycombinatk = number of zero-touchescombinatm = half-lengthzcombinatk = number of zero-touchescombinatm = half-length{combinatk = number of zero-touchescombinatm = half-length|combinatk = number of peakscombinatm = half-length}combinatk = number of peakscombinatm = half-length~combinatk = number of peakscombinatm = half-length!_`bacdefghijklmnopqrstuvwxyz{|}~!`ba_cdefghijklmnopqrstuvwxyz{|}~#NonerTcombinat$A non-crossing partition of the set [1..n]t in standard form: entries decreasing in each block and blocks listed in increasing order of their first entries.combinat.Checks whether a set partition is noncrossing.Implementation method: we convert to a Dyck path and then back again, and finally compare. Probably not very efficient, but should be better than a naive check for crosses...)combinat5Warning: This function assumes the standard ordering!combinatzConvert to standard form: entries decreasing in each block and blocks listed in increasing order of their first entries.combinat<Throws an error if the input is not a non-crossing partitioncombinatCIf a set partition is actually non-crossing, then we can convert itcombinat7Bijection between Dyck paths and noncrossing partitionsBased on: David Callan: &Sets, Lists and Noncrossing Partitions&Fails if the input is not a Dyck path.combinatSafe version of combinat0The inverse bijection (should never fail proper -s)combinat Safe version combinat%Lists all non-crossing partitions of [1..n]XEquivalent to (but orders of magnitude faster than) filtering out the non-crossing ones: f(sort $ catMaybes $ map setPartitionToNonCrossing $ setPartitions n) == sort (nonCrossingPartitions n)combinat%Lists all non-crossing partitions of [1..n] into k parts. nsort (nonCrossingPartitionsWithKParts k n) == sort [ p | p <- nonCrossingPartitions n , numberOfParts p == k ]combinat:Non-crossing partitions are counted by the Catalan numberscombinatNon-crossing partitions with k* parts are counted by the Naranaya numberscombinat'Uniformly random non-crossing partitioncombinatk = number of parts combinatn = size of the setcombinatk = number of parts combinatn = size of the set$None3;=e%combinat#A completely unlabelled binary treecombinatBA (strict) binary tree with labelled leaves (but unlabelled nodes)combinatxA tree diagram, consisting of two binary trees with the same number of leaves, representing an element of the group F.combinat<the width is the number of leaves, minus 1, of both diagramscombinat"the top diagram correspond to the domaincombinat&the bottom diagram corresponds to the rangecombinat%Creates a tree diagram from two treescombinat/Creates a tree diagram, but does not reduce it.combinatThe generator x0combinatThe generator x1combinatThe generators x0, x1, x2 ...combinat8The identity element in the group F combinatA positive diagram< is a diagram whose bottom tree (the range) is a right vine.combinatSwaps the top and bottom of a tree diagram. This is the inverse in the group F. (Note: we don't do reduction here, as this operation keeps the reducedness)combinat^Decides whether two (possibly unreduced) tree diagrams represents the same group element in F.combinatLReduces a diagram. The result is a normal form of an element in the group F.combinatMList of carets at the bottom of the tree, indexed by their left edge positioncombinatdRemove the carets with the given indices (throws an error if there is no caret at the given index)combinatIf diag1 corresponds to the PL function f, and diag2 to g, then compose diag1 diag2 will correspond to (g.f)D (note that the order is opposite than normal function composition!)*This is the multiplication in the group F.combinat5Compose two tree diagrams without reducing the resultcombinatGiven two binary trees, we return a pair of list of subtrees which, grafted the to leaves of the first (resp. the second) tree, results in the same extended tree.combinat-Returns the list of dyadic subdivision pointscombinat$Returns the list of dyadic intervalscombinat*The monadic join operation of binary treescombinatA list version of combinat6The width of the tree is the number of leaves minus 1.combinat-Enumerates the leaves a tree, starting from 0combinatCEnumerates the leaves a tree, and also returns the number of leavescombinat "Right vine" of the given width combinat"Left vine" of the given width combinat Flips each node of a binary treecombinat and  are the same type, except that  is strict.rTODO: maybe unify these two types? Until that, you can convert between the two with these functions if necessary.combinat=Draws a binary tree, with all leaves at the same (bottom) rowcombinat.Draws a binary tree; when the boolean flag is True, we draw upside downcombinatDraws a binary tree, with all leaves at the same (bottom) row, and labelling the leaves starting with 0 (continuing with letters after 9)combinat*When the flag is true, we draw upside downcombinatDraws a tree diagram55 None;= combinat8Adds unique labels to the nodes (including leaves) of a !combinat8Adds unique labels to the nodes (including leaves) of a .combinatregularNaryTrees d n' returns the list of (rooted) trees on n$ nodes where each node has exactly d0 children. Note that the leaves do not count in n. Naive algorithm.combinatTernary trees on n nodes (synonym for regularNaryTrees 3)combinatWe have clength (regularNaryTrees d n) == countRegularNaryTrees d n == \frac {1} {(d-1)n+1} \binom {dn} {n} combinat %# = \frac {1} {(2n+1} \binom {3n} {n}combinat All trees on nZ nodes where the number of children of all nodes is in element of the given set. Example: autoTabulate RowMajor (Right 5) $ map asciiTreeVertical $ map labelNChildrenTree_ $ semiRegularTrees [2,3] 2 [ length $ semiRegularTrees [2,3] n | n<-[0..] ] == [1,2,10,66,498,4066,34970,312066,2862562,26824386,...](The latter sequence is A027307 in OEIS: https://oeis.org/A027307Remark: clearly, we have .semiRegularTrees [d] n == regularNaryTrees d ncombinat:Vertical ASCII drawing of a tree, without labels. Example: PautoTabulate RowMajor (Right 5) $ map asciiTreeVertical_ $ regularNaryTrees 2 4 Nodes are denoted by @ , leaves by *.combinatPrints all labels. Example: HasciiTreeVertical $ addUniqueLabelsTree_ $ (regularNaryTrees 3 9) !! 666Nodes are denoted by (label) , leaves by label.combinat9Prints the labels for the leaves, but not for the nodes.combinatDThe leftmost spine (the second element of the pair is the leaf node)combinat(The leftmost spine without the leaf nodecombinat/The length (number of edges) on the left spine 0leftSpineLength tree == length (leftSpine_ tree)combinatq is leaf, p is nodecombinat=Attaches the depth to each node. The depth of the root is 0. combinat.Attaches the number of children to each node. combinatfComputes the set of equivalence classes of rooted trees (in the sense that the leaves of a node are  unordered ) with  n = length ks| leaves where the set of heights of the leaves matches the given set of numbers. The height is defined as the number of edges from the leaf to the root. TODO: better name?combinat(degree = number of children of each nodecombinatnumber of nodescombinat!set of allowed number of childrencombinatnumber of nodes8 !"%&,"&%! ,Noneɛd  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH%NonecombinatH"Tuples" fitting into a give shape. The order is lexicographic, that is, &sort ts == ts where ts = tuples' shape Example: \tuples' [2,3] = [[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3],[2,0],[2,1],[2,2],[2,3]]combinat,positive "tuples" fitting into a give shape.combinat# = \prod_i (m_i + 1)combinat# = \prod_i m_i combinat# = (m+1) ^ len combinat # = m ^ lencombinatlength (width)combinatmaximum (height)combinatlength (width)combinatmaximum (height)       -Noneӭ PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-?FGHIefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH_`abcdefghijklmnopqrstuvwxyz{|}~   Safe ,-CFQVg combinat/Hide the type parameter of a functor. Example:  Some BraidcombinatUses the value inside a  combinatMonadic version of combinatZGiven a polymorphic value, we select at run time the one specified by the second argumentcombinatMonadic version of combinatCombination of  and R: we make a temporary structure of the given size, but we immediately consume it.combinat(Half-)monadic version of     &None -0CFQSTV@3combinat3Sometimes we want to hide the type-level parameter nT, for example when dynamically creating braids whose size is known only at runtime.combinatThe braid group B_n on n strands. The number n: is encoded as a type level natural in the type parameter.OBraids are represented as words in the standard generators and their inverses.combinat'A standard Artin generator of a braid: Sigma i- represents twisting the neighbour strands i and (i+1), such that strand i goes under strand (i+1).Note: The strands are numbered 1..n. combinati goes under (i+1)!combinati goes above (i+1)"combinatOThe strand (more precisely, the first of the two strands) the generator twistes%combinat The inverse of a braid generator&combinat"The number of strands in the braid-combinat:Embeds a smaller braid group into a bigger braid group .combinat@Apply "free reduction" to the word, that is, iteratively remove sigma_i sigma_i^-1C pairs. The resulting braid is clearly equivalent to the original./combinatThe braid generator sigma_i as a braid0combinatThe braid generator  sigma_i^(-1) as a braid1combinatdoubleSigma s t (for s<t)is the generator  sigma_{s,t}@ in Birman-Ko-Lee's "new presentation". It twistes the strands s and t* while going over all other strands. For t==s+1 we get back sigma s2combinatpositiveWord [2,5,1] is shorthand for the word sigma_2*sigma_5*sigma_1.3combinatGThe (positive) half-twist of all the braid strands, usually denoted by Delta.4combinatThe untyped version of 35combinat Synonym for 36combinat"The inner automorphism defined by tau(X) = Delta^-1 X Delta , where Delta is the positive half-twist.This sends each generator sigma_j to  sigma_(n-j).7combinatThe involution tau% on permutations (permutation braids)8combinatThe trivial braid9combinat|The inverse of a braid. Note: we do not perform reduction here, as a word is reduced if and only if its inverse is reduced.:combinatMComposes two braids, doing free reduction on the result (that is, removing (sigma_k * sigma_k^-1) pairs@)<combinat0Composes two braids without doing any reduction.=combinat-A braid is pure if its permutation is trivial>combinatWReturns the left-to-right permutation associated to the braid. We follow the strands from the left to the rightf (or from the top to the bottom), and return the permutation taking the left side to the right side.This is compatible with right) (standard) action of the permutations: 'permuteRight (braidPermutationRight b1)D corresponds to the left-to-right permutation of the strands; also: \(braidPermutation b1) `multiply` (braidPermutation b2) == braidPermutation (b1 `compose` b2)vWriting the right numbering of the strands below the left numbering, we got the two-line notation of the permutation.?combinatThis is an untyped version of >@combinat.A positive braid word contains only positive (Sigma ) generators.AcombinatA permutation braidC is a positive braid where any two strands cross at most one, and  positively. BcombinatUntyped version of A for positive words.Ccombinat-For any permutation this functions returns a permutation braidx realizing that permutation. Note that this is not unique, so we make an arbitrary choice (except for the permutation  [n,n-1..1]O reversing the order, in which case the result must be the half-twist braid).4The resulting braid word will have a length at most  choose n 26 (and will have that length only for the permutation  [n,n-1..1]) kbraidPermutationRight (permutationBraid perm) == perm isPermutationBraid (permutationBraid perm) == TrueDcombinatUntyped version of CEcombinat\Returns the individual "phases" of the a permutation braid realizing the given permutation.Fcombinat<We compute the linking numbers between all pairs of strands: 7linkingMatrix braid ! (i,j) == strandLinking braid i j GcombinatUntyped version of FHcombinat0The linking number between two strands numbered i and j (numbered such on the left side).IcombinatMBronfman's recursive formula for the reciprocial of the growth function of positive braids. It was already known (by Deligne) that these generating functions are reciprocials of polynomials; Bronfman [1] gave a recursive formula for them. let count n l = length $ nub $ [ braidNormalForm w | w <- allPositiveBraidWords n l ] let convertPoly (1:cs) = zip (map negate cs) [1..] pseries' (convertPoly $ bronfmanH n) == expandBronfmanH n == [ count n l | l <- [0..] ] J[1] Aaron Bronfman: Growth functions of a class of monoids. Preprint, 2001Jcombinat5An infinite list containing the Bronfman polynomials: !bronfmanH n = bronfmanHsList !! nKcombinatExpands the reciprocial of H(n)V into an infinite power series, giving the growth function of the positive braids on n strands.LcombinateHorizontal braid diagram, drawn from left to right, with strands numbered from the bottom to the topMcombinatyHorizontal braid diagram, drawn from left to right. The boolean flag indicates whether to flip the strands vertically ( means bottom-to-top,  means top-to-bottom) Ncombinat,All positive braid words of the given lengthOcombinat#All braid words of the given lengthPcombinatUntyped version of NQcombinatUntyped version of ORcombinat%Random braid word of the given lengthScombinatRandom positive braid word of the given lengthTcombinat+Given a braid word, we perturb it randomly mf times using the braid relations, so that the resulting new braid word is equivalent to the original.Useful for testing.UcombinatThis version of R0 may be convenient to avoid the type level stuffVcombinatThis version of S0 may be convenient to avoid the type level stuffWcombinatUntyped version of RXcombinatUntyped version of SUcombinatnumber of strandscombinatlength of the random wordVcombinatnumber of strandscombinatlength of the random wordWcombinatnumber of strandscombinatlength of the random wordXcombinatnumber of strandscombinatlength of the random word>! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX>! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX'None-CFQVcombinatFTemporary data structure to be used during the normal form computationcombinat Delta^kcombinat Sigma_jcombinat L_j = Delta * sigma_j^-1combinat tau(L_j)^combinat,A unique normal form for braids, called the left-greedy normal form. It looks like  Delta^i*P, where Delta is the positive half-twist, i is an integer, and P> is a positive word, which can be further decomposed into non-Delta permutation wordsM; these words themselves are not unique, but the permutations they realize are unique.aThis will solve the word problem relatively fast, though it is not the fastest known algorithm.`combinatthe exponent of Deltaacombinatthe permutationsbcombinat/A braid word representing the given normal formccombinataComputes the normal form of a braid. We apply free reduction first, it should be faster that way.dcombinatLThis function does not apply free reduction before computing the normal formecombinatRThis one uses the naive inverse replacement method. Probably somewhat slower than d.combinatReplaces groups of  sigma_i^-1 generators by (Delta^-1 * P) , where P is a positive word.TThis should be more clever (resulting in shorter words) than the naive version belowcombinat Replaces  sigma_i^-1 generators by (Delta^-1 * L_i).combinatWe move the all Delta's to the leftcombinat Expands a positive$ "X-word" into a positive braid wordcombinat<Expands an "X-word" into a braid word. Useful for debugging.combinatposL k (denoted as L_k) is a  positive word which satisfies Delta = L_k * sigma_k, or: 6(inverse halfTwist) `compose` (posL k) ~=~ sigmaInv k@<Thus we can replace any word with a positive word plus some Delta^-1'scombinatposR k n (denoted as R_k) is a permutation braid which satisfies Delta = sigma_k * R_k 6(posR k) `compose` (inverse halfTwist) ~=~ sigmaInv k@<Thus we can replace any word with a positive word plus some Delta^-1'scombinatThe permutation posL k :: Braid n is realizingcombinatThe permutation posR k :: Braid n is realizingcombinat+We recognize left-greedy factors which are Delta4-s (easy, since they are the only ones with length  (n choose 2)), and move them to the left, returning their summed exponent and the filtered new factors. We also filter trivial permutations (which should only happen for the trivial braid, but it happens there?)fcombinatThe  starting set( of a positive braid P is the subset of [1..n-1] defined by VS(P) = [ i | P = sigma_i * Q , Q is positive ] = [ i | (sigma_i^-1 * P) is positive ] KThis function returns the starting set a positive word, assuming it is a permutation braid (see Lemma 2.4 in [2])gcombinatThe  finishing set( of a positive braid P is the subset of [1..n-1] defined by VF(P) = [ i | P = Q * sigma_i , Q is positive ] = [ i | (P * sigma_i^-1) is positive ] AThis function returns the finishing set, assuming the input is a permutation braidhcombinatThis satisfies GpermutationStartingSet p == permWordStartingSet n (_permutationBraid p)icombinatThis satisfies IpermutationFinishingSet p == permWordFinishingSet n (_permutationBraid p)combinatqReturns the list of permutations failing Lemma 2.5 in [2] (so an empty list means the implementaton is correct)combinatCGiven factors defined as permutation braids, we normalize them to left-canonical form by ensuring thatfor each consecutive pair (P,Q)6 the finishing set F(P) contains the starting set S(Q)all DeltaC-s (corresponding to the reverse permutation) are moved to the left$all trivial factors are filtered outFUnfortunately, it seems that we may need multiple sweeps to do that...combinatwDoes 1 sweep of the above normalization process. Unfortunately, it seems that we may need to do this multiple times...combinatGiven a positiveS word, we apply left-greedy factorization of that word into subwords representing permutation braids.$Example 5.1 from the above handbook: JleftGreedyFactors 7 [1,3,2,2,1,3,3,2,3,2] == [[1,3,2],[2,1,3],[3,2,3],[2]] ^_`abcdefghi ^_`abcdefghi./0./1./12342352362372389:;<=>?@ABCDEFGHIJKLMNNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                       ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f ghhijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./01234567899:;<=>?@ABCDEFGHIJKLMNOPQMLRSTUVHFWXYZ[\]^_`abcdefTghijklmnopqrstuvwxyz{|}~      !"#$%&'( ) * + ,!-!.!/!0!123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghi"j"k"l"m"n"o"p"q"r"s"t"u"v"w"x"y"z"{"|"}"~""""""""""""""""""########################$$7$'$($$$$$$$$$$$$$$$$$$$B$$A$$$$$$$$$$6$$5$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    %%%%%%%%%      &&&&&&&&&&& &!&"&#&$&%&&&'&(&)&*&+&,&-&.&/&0&1&2&B&A&&3&&4&5&6&7&8&9&:&;&<&=&>&?&@&A&B&C&D&E&F&G&H&I&J&K&L&M&N&O&P&Q&R&S&T'U'U'V'W'X'Y'Z'['\']'^'_'`'a'b'c'de.fg.fh i j.klmnopqrstuv23w23x23y23z23{23|23}23~232323''''''''''''''''''''combinat-0.2.9.0-7ZL5Gg7rhXtATtDt1VDKosMath.Combinat.TypeLevelMath.Combinat.Trees.BinaryMath.Combinat.ClassesMath.Combinat.HelperMath.Combinat.ASCIIMath.Combinat.Numbers.IntegersMath.Combinat.Numbers.PrimesMath.Combinat.Partitions.Vector!Math.Combinat.Partitions.MultisetMath.Combinat.SignMath.Combinat.Numbers.SequencesMath.Combinat.SetsMath.Combinat.Permutations&Math.Combinat.Partitions.Integer.Count(Math.Combinat.Partitions.Integer.IntList&Math.Combinat.Partitions.Integer.Naive Math.Combinat.Partitions.IntegerMath.Combinat.Partitions.SkewMath.Combinat.Partitions.SetMath.Combinat.Numbers.SeriesMath.Combinat.CompositionsMath.Combinat.Sets.VennDiagrams(Math.Combinat.Partitions.Integer.CompactMath.Combinat.Groups.FreeMath.Combinat.TableauxMath.Combinat.Partitions.Plane%Math.Combinat.Tableaux.GelfandTsetlin*Math.Combinat.Tableaux.GelfandTsetlin.ConeMath.Combinat.Tableaux.Skew+Math.Combinat.Tableaux.LittlewoodRichardson$Math.Combinat.Partitions.Skew.RibbonMath.Combinat.Trees.NaryMath.Combinat.Trees.GraphvizMath.Combinat.LatticePaths$Math.Combinat.Partitions.NonCrossingMath.Combinat.Groups.Thompson.FMath.Combinat.TuplesMath.Combinat.Groups.BraidMath.Combinat.Groups.Braid.NFSystemRandomMath.Combinat.NumbersMath.Combinat.PartitionsMath.Combinat.Trees Math.Combinatbase Data.Proxy asProxyTypeOfProxycontainers-0.5.11.0 Data.Tree subForest rootLabelNodeTreeForestHasNumberOfCyclesnumberOfCyclesHasNumberOfLeavesnumberOfLeavesHasNumberOfNodes numberOfNodesHasShapeshape HasDualitydual HasWeightweight HasHeightheightHasWidthwidthHasNumberOfParts numberOfParts CanBeEmptyisEmptyemptyRandTRanddebugswappairs pairsWithsum' interleaveequatingreverseOrderingreverseComparingreverseCompare reverseSort groupSortBynubOrdisWeaklyIncreasingisStrictlyIncreasingisWeaklyDecreasingisStrictlyDecreasing mapWithLast mapWithFirstmapWithFirstLastmkLinesUniformWidthmkBlocksUniformHeightmkUniformBlocks hConcatLines vConcatLinescount histogramfromJust intToBool boolToIntnestunfold1unfold unfoldEitherunfoldM mapAccumM longZipWithrunRand flipRunRandrunRandT flipRunRandTrandrandRoll randChoose randProxy1$fFunctorRandT$fApplicativeRandT $fMonadRandT MatrixOrderRowMajorColMajorVSep VSepEmpty VSepSpaces VSepStringHSep HSepEmpty HSepSpaces HSepString AlignmentAlignVAlignVTopVCenterVBottomHAlignHLeftHCenterHRight DrawASCIIasciiASCII asciiSize asciiLines emptyRect asciiXSize asciiYSize asciiString printASCIIasciiFromLinesasciiFromStringhSepSize hSepStringvSepSize vSepString|||===hCatTophCatBotvCatLeft vCatRighthCatWithvCatWithhPadvPadpad hExtendTo vExtendTo hExtendWith vExtendWithhIndentvIndenthCutvCut pasteOnto pasteOnto' pasteOntoRel pasteOntoRel'tabulate autoTabulatecaptioncaption'asciiBoxroundedAsciiBox filledBoxtransparentBox asciiNumber asciiShow $fShowASCII $fEqHAlign $fShowHAlign $fEqVAlign $fShowVAlign $fShowHSep $fShowVSep$fEqMatrixOrder$fOrdMatrixOrder$fShowMatrixOrder$fReadMatrixOrder integerLog2 ceilingLog2isSquareintegerSquareRootceilingSquareRootintegerSquareRoot'integerSquareRootNewton'primes primesSimple primesTMWEgroupIntegerFactorsintegerFactorsTrialDivisionpowerModmillerRabinPrimalityTestisProbablyPrimeisVeryProbablyPrime IntVectorvectorPartitions_vectorPartitionsfasc3B_algorithm_MpartitionMultisetSignPlusMinusisPlusisMinus signValuesigned paritySignparitySignValue negateIfOdd oppositeSignmulSignproductOfSigns $fRandomSign $fMonoidSign$fSemigroupSign$fEqSign $fOrdSign $fShowSign $fReadSign factorialdoubleFactorialbinomialsignedBinomial pascalRow multinomialcatalancatalanTrianglesignedStirling1stArraysignedStirling1stunsignedStirling1st stirling2nd bernoullibellNumbersArray bellNumberchoose_choosechoose'choose'' chooseTaggedcombinecomposetuplesFromList listTensor kSublistscountKSublistssublists countSublists randomChoiceDisjointCycles PermutationfromPermutationpermutationUArraypermutationArraytoPermutationUnsafeuarrayToPermutationUnsafe isPermutationmaybePermutation toPermutationpermutationSizeisIdentityPermutationconcatPermutationsasciiPermutationasciiDisjointCyclestwoLineNotationinverseTwoLineNotationgenericTwoLineNotationfromDisjointCyclesdisjointCyclesUnsafedisjointCyclesToPermutationpermutationToDisjointCyclesisEvenPermutationisOddPermutationsignOfPermutationsignValueOfPermutationisCyclicPermutation inversionsnumberOfInversionsnumberOfInversionsMergenumberOfInversionsNaive bubbleSort2 bubbleSortreversePermutationisReversePermutation transpositiontranspositionsadjacentTranspositionadjacentTranspositions cycleLeft cycleRightmultiplyinverseidentity multiplyMany multiplyMany'permute permuteList permuteRightpermuteRightList permuteLeftpermuteLeftListsortingPermutationAscsortingPermutationDesc permutations _permutationspermutationsNaive_permutationsNaivecountPermutationsrandomPermutation_randomPermutationrandomCyclicPermutation_randomCyclicPermutationrandomPermutationDurstenfeldrandomCyclicPermutationSattolopermuteMultisetcountPermuteMultisetfasc2B_algorithm_L$fHasNumberOfCyclesPermutation$fHasWidthPermutation$fDrawASCIIPermutation$fReadPermutation$fShowPermutation!$fHasNumberOfCyclesDisjointCycles$fDrawASCIIDisjointCycles$fEqPermutation$fOrdPermutation$fEqDisjointCycles$fOrdDisjointCycles$fShowDisjointCycles$fReadDisjointCyclesTableOfIntegers lookupIntegermakeTableOfIntegerscountPartitionscountPartitionsInfiniteProductcountPartitionsNaivepartitionCountTablepartitionCountList!partitionCountListInfiniteProductpartitionCountListNaivecountAllPartitionscountAllPartitions'countPartitions'countPartitionsWithKParts _mkPartition _isPartition_dualPartition_dualPartitionNaive _diffSequence _elements_toExponentialForm_fromExponentialForm _partitions_allPartitions_allPartitionsGrouped _partitions'_randomPartition_randomPartitions _dominates_dominatedPartitions_dominatingPartitions_partitionsWithKParts_partitionsWithOddParts_partitionsWithDistinctParts_isSubPartitionOf_isSuperPartitionOf_subPartitions_allSubPartitions_superPartitions _pieriRule_dualPieriRule PartitionLengthTailHead Partition_ConsNilisEmptyPartitionemptyPartitionpartitionHeightpartitionWidth heightWidthpartitionWeight dualPartitionelementstoExponentialFormfromExponentialForm diffSequenceunconsPartition toDescList dominatesisSubPartitionOfisSuperPartitionOf pieriRule dualPieriRule$fHasDualityPartition$fHasWeightPartition$fHasWidthPartition$fHasHeightPartition$fCanBeEmptyPartition$fHasNumberOfPartsPartition $fEqPartition$fOrdPartition$fShowPartition$fReadPartitionPartitionConventionEnglishNotationEnglishNotationCCWFrenchNotation fromPartition mkPartition toPartitiontoPartitionUnsafe isPartitionunionOfPartitionssumOfPartitions partitions partitions' allPartitionsallPartitionsGroupedallPartitions'allPartitionsGrouped'randomPartitionrandomPartitionsdominatedPartitionsdominatingPartitionspartitionsWithKPartspartitionsWithOddPartspartitionsWithDistinctParts subPartitionsallSubPartitionssuperPartitionsasciiFerrersDiagramasciiFerrersDiagram'$fDrawASCIIPartition$fEqPartitionConvention$fShowPartitionConvention SkewPartitionmkSkewPartitionsafeSkewPartitionskewPartitionWeightnormalizeSkewPartitionfromSkewPartitionouterPartitioninnerPartitiondualSkewPartitionskewPartitionElementsskewPartitionsWithOuterShapeallSkewPartitionsWithOuterShapeskewPartitionsWithInnerShapeasciiSkewFerrersDiagramasciiSkewFerrersDiagram'$fDrawASCIISkewPartition$fHasDualitySkewPartition$fHasWeightSkewPartition$fEqSkewPartition$fOrdSkewPartition$fShowSkewPartition SetPartition_standardizeSetPartitionfromSetPartitiontoSetPartitionUnsafetoSetPartition_isSetPartitionsetPartitionShape setPartitionssetPartitionsWithKPartssetPartitionsNaivesetPartitionsWithKPartsNaivecountSetPartitionscountSetPartitionsWithKParts$fHasNumberOfPartsSetPartition$fEqSetPartition$fOrdSetPartition$fShowSetPartition$fReadSetPartition unitSeries zeroSeries constSeriesidSeries powerTerm addSeries sumSeries subSeries negateSeries scaleSeries mulSeriesmulSeriesNaiveproductOfSeriesconvolve convolveMany divSeriesreciprocalSeriesintegralReciprocalSeries composeSeries substitutecomposeSeriesNaivesubstituteNaivelagrangeInversion lagrangeCoeffintegralLagrangeInversionNaivelagrangeInversionNaivedifferentiateSeriesintegrateSeries expSeries cosSeries sinSeries cosSeries2 sinSeries2 coshSeries sinhSeries log1Series dyckSeries coinSeries coinSeries'convolveWithCoinSeriesconvolveWithCoinSeries'productPSeriesproductPSeries'convolveWithProductPSeriesconvolveWithProductPSeries'pseriesconvolveWithPSeriespseries'convolveWithPSeries' signedPSeriesconvolveWithSignedPSeries Composition compositions'countCompositions'allCompositions1allCompositions' compositionscountCompositions compositions1countCompositions1randomCompositionrandomComposition1 VennDiagram vennTablevennDiagramNumberOfSetsvennDiagramNumberOfZones vennDiagramNumberOfNonemptyZonesunsafeMakeVennDiagramisTrivialVennDiagramprintVennDiagramprettyVennDiagramasciiVennDiagramvennDiagramSetCardinalitiesenumerateVennDiagrams$fDrawASCIIVennDiagram$fEqVennDiagram$fOrdVennDiagram$fShowVennDiagramNibbleMedium1Medium2Medium3Medium4WordList c_dual_nibblepartitionPrefixCharcmp singletonuncons partitionTailconssnoc widthHeightreverseDiffSequencetoList toAscList fromDescList fromDescList' makeNibble makeMedium makeMedium1 makeMedium2 makeMedium3 makeMedium4 makeWordListpieriRuleSingleBoxi2ww2isafeTailtoZerotoOneWord GeneratorGenInvgenIdxgenSign genSignValueabsGenshowGenshowWord inverseGen inverseWordallWords allWordsNoInvrandomGeneratorrandomGeneratorNoInv randomWordrandomWordNoInv multiplyFreeequivalentFreereduceWordFreereduceWordFreeNaivecountIdentityWordsFreecountWordReductionsFree multiplyZ2 multiplyZ3 multiplyZm equivalentZ2 equivalentZ3 equivalentZm reduceWordZ2 reduceWordZ3 reduceWordZmreduceWordZ2NaivereduceWordZ3NaivereduceWordZmNaivecountIdentityWordsZ2countWordReductionsZ2countIdentityWordsZ3NoInv$fFunctorGenerator $fEqGenerator$fOrdGenerator$fShowGenerator$fReadGeneratorTableau asciiTableau _tableauShape tableauShape tableauWeight dualTableautableauContenthooks hookLengthsrowWordrowWordToTableau columnWordcolumnWordToTableau isLatticeWordisSemiStandardTableausemiStandardYoungTableauxcountSemiStandardYoungTableauxisStandardTableaustandardYoungTableauxcountStandardYoungTableaux$fHasDuality[] $fHasWeight[]$fHasShape[]Partition $fDrawASCII[]$fCanBeEmpty[] PlanePart fromPlanePartisValidPlanePart toPlanePartplanePartShapeplanePartZHeightplanePartWeight singleLayer stackLayersunsafeStackLayersplanePartLayersplanePartitions$fHasWeightPlanePart$fCanBeEmptyPlanePart $fEqPlanePart$fOrdPlanePart$fShowPlanePartGT kostkaNumberkostkaNumberReferenceNaivekostkaNumbersWithGivenLambdakostkaNumbersWithGivenMuasciiGTkostkaGelfandTsetlinPatternskostkaGelfandTsetlinPatterns'!countKostkaGelfandTsetlinPatternsiteratedPieriRuleiteratedPieriRule'iteratedPieriRule''iteratedDualPieriRuleiteratedDualPieriRule'iteratedDualPieriRule''TriunTriTriangularArraytriangularArrayUnsafefromTriangularArrayasciiTriangularArraygtSimplexContent_gtSimplexContentgtSimplexTableaux_gtSimplexTableauxcountGTSimplexTableauxinvertGTSimplexTableau_invertGTSimplexTableau$fIxTri$fDrawASCIIArray$fEqTri$fOrdTri $fShowTri$fEqHole $fOrdHole $fShowHole SkewTableauskewTableauShapeskewTableauWeightdualSkewTableauisSemiStandardSkewTableauisStandardSkewTableausemiStandardSkewTableauxasciiSkewTableauasciiSkewTableau'skewTableauRowWordskewTableauColumnWordfillSkewPartitionWithRowWordfillSkewPartitionWithColumnWordskewTableauRowContent$fDrawASCIISkewTableau$fHasDualitySkewTableau$fHasWeightSkewTableau"$fHasShapeSkewTableauSkewPartition$fFunctorSkewTableau$fEqSkewTableau$fOrdSkewTableau$fShowSkewTableau lrRuleNaivelrRule_lrRulelrCoefflrCoeff'lrScalar _lrScalarlrMult BorderBox_canStartStrip _canEndStrip_yCoord_xCoordRibbonrbShaperbLengthrbHeightrbWidth outerCornersextendedInnerCornersextendedCornerSequenceinnerCornerBoxesouterCornerBoxescornerBoxSequenceinnerCornerBoxesNaiveouterCornerBoxesNaiveisRibbontoRibbon innerRibbonsinnerRibbonsOfLength listHooksouterRibbonsOfLengthinnerRibbonsNaiveinnerRibbonsOfLengthNaiveouterRibbonsOfLengthNaiveannotatedInnerBorderStripannotatedOuterBorderStrip $fEqRibbon $fOrdRibbon $fShowRibbon$fShowBorderBoxBinTree'Branch'Leaf'BinTreeBranchLeafaddUniqueLabelsForest_addUniqueLabelsTree_addUniqueLabelsForestaddUniqueLabelsTreeDotgraphvizDotBinTreegraphvizDotBinTree'graphvizDotForestgraphvizDotTreeParen LeftParen RightParenleafgraftforgetNodeDecorationsenumerateLeaves_enumerateLeaves'enumerateLeaves toRoseTree toRoseTree'parenthesesToStringstringToParenthesesforestToNestedParenthesesforestToBinaryTreenestedParenthesesToForestnestedParenthesesToForestUnsafenestedParenthesesToBinaryTree#nestedParenthesesToBinaryTreeUnsafebinaryTreeToNestedParenthesesbinaryTreeToForestnestedParenthesesrandomNestedParenthesesnthNestedParenthesescountNestedParenthesesfasc4A_algorithm_Pfasc4A_algorithm_Wfasc4A_algorithm_U binaryTreescountBinaryTreesbinaryTreesNaiverandomBinaryTreefasc4A_algorithm_RasciiBinaryTree_$fDrawASCIIBinTree$fMonadBinTree$fApplicativeBinTree$fTraversableBinTree$fFoldableBinTree$fFunctorBinTree$fHasNumberOfLeavesBinTree$fHasNumberOfNodesBinTree$fHasNumberOfLeavesBinTree'$fHasNumberOfNodesBinTree' $fEqBinTree $fOrdBinTree $fShowBinTree $fReadBinTree $fEqBinTree' $fOrdBinTree'$fShowBinTree'$fReadBinTree' $fEqParen $fOrdParen $fShowParen $fReadParen LatticePathStepUpStepDownStep asciiPath isValidPath isDyckPath pathHeight pathEndpointpathCoordinatespathNumberOfUpStepspathNumberOfDownStepspathNumberOfUpDownStepspathNumberOfPeakspathNumberOfZeroTouchespathNumberOfTouches' dyckPathsdyckPathsNaivecountDyckPathsnestedParensToDyckPathdyckPathToNestedParensboundedDyckPathsboundedDyckPathsNaive latticePathslatticePathsNaivecountLatticePathstouchingDyckPathstouchingDyckPathsNaivecountTouchingDyckPathspeakingDyckPathspeakingDyckPathsNaivecountPeakingDyckPathsrandomDyckPath $fHasWidth[] $fHasHeight[]$fEqStep $fOrdStep $fShowStep NonCrossing_isNonCrossing_isNonCrossingUnsafe_standardizeNonCrossingfromNonCrossingtoNonCrossingUnsafe toNonCrossingtoNonCrossingMaybesetPartitionToNonCrossingdyckPathToNonCrossingPartition#dyckPathToNonCrossingPartitionMaybenonCrossingPartitionToDyckPath$_nonCrossingPartitionToDyckPathMaybenonCrossingPartitionsnonCrossingPartitionsWithKPartscountNonCrossingPartitions$countNonCrossingPartitionsWithKPartsrandomNonCrossingPartition$fHasNumberOfPartsNonCrossing$fEqNonCrossing$fOrdNonCrossing$fShowNonCrossing$fReadNonCrossingTTDiag_width_domain_rangeX1X0CtBrLfmkTDiagmkTDiagDontReduce isValidTDiag isPositive isReducedx0x1xkpositive equivalentreduce treeCaretList removeCaretscomposeDontReduceextensionToCommonTree subdivision1 subdivision2 listGraftbranchcarettreeNumberOfLeaves treeWidth enumerate_ enumerate rightVineleftVineflipTree toBinTree fromBinTreeasciiTasciiT' asciiTLabels asciiTLabels' asciiTDiag$fHasWidthTree$fHasNumberOfLeavesTree$fDrawASCIITree$fHasWidthTDiag$fDrawASCIITDiag$fEqTree $fOrdTree $fShowTree $fFunctorTree $fEqTDiag $fOrdTDiag $fShowTDiagregularNaryTrees ternaryTreescountRegularNaryTreescountTernaryTreessemiRegularTreesasciiTreeVertical_asciiTreeVerticalasciiTreeVerticalLeavesOnly leftSpine rightSpine leftSpine_ rightSpine_leftSpineLengthrightSpineLengthclassifyTreeNode isTreeLeaf isTreeNode isTreeLeaf_ isTreeNode_treeNodeNumberOfChildrencountTreeNodescountTreeLeavescountTreeLabelsWithcountTreeNodesWithlabelDepthTreelabelDepthForestlabelDepthTree_labelDepthForest_labelNChildrenTreelabelNChildrenForestlabelNChildrenTree_labelNChildrenForest_ derivTrees$fHasNumberOfNodesTreetuples'tuples1' countTuples' countTuples1'tuplestuples1 countTuples countTuples1 binaryTuplesSome proxyUndefproxyOfproxyOf1proxyOf2asProxyTypeOf1typeArgiTypeArgwithSome withSomeM selectSome selectSomeM withSelected withSelectedM SomeBraidBraidBrGenSigmaSigmaInvbrGenIdx brGenSign brGenSignIdxinvBrGennumberOfStrands someBraid withSomeBraidmkBraid withBraid braidWordbraidWordLengthextendfreeReduceBraidWordsigmasigmaInv doubleSigma positiveWord halfTwist _halfTwisttheGarsideBraidtautauPerm composeMany isPureBraidbraidPermutation_braidPermutationisPositiveBraidWordisPermutationBraid_isPermutationBraidpermutationBraid_permutationBraid_permutationBraid' linkingMatrix_linkingMatrix strandLinking bronfmanHbronfmanHsListexpandBronfmanHhorizBraidASCIIhorizBraidASCII'allPositiveBraidWords allBraidWords_allPositiveBraidWords_allBraidWordsrandomBraidWordrandomPositiveBraidWordrandomPerturbBraidWordwithRandomBraidWordwithRandomPositiveBraidWord_randomBraidWord_randomPositiveBraidWord$fDrawASCIIBraid $fEqBrGen $fOrdBrGen $fShowBrGen $fShowBraidBraidNF _nfDeltaExp_nfPerms nfReprWordbraidNormalFormbraidNormalForm'braidNormalFormNaive'permWordStartingSetpermWordFinishingSetpermutationStartingSetpermutationFinishingSet $fEqBraidNF $fOrdBraidNF $fShowBraidNF$fEqXGen $fShowXGenintegerRndSequence Data.EitherRightLeftmakeChoiceFromIndicesKnuthmakeChoiceFromIndicesNaiveGHC.BaseNothingDiagramFillingfillings fillings'addMuaddRowOfnewBoxesaddBox headOrZerodiffSequnfoldForestM_BFunfoldTreeM_BF unfoldForestM unfoldTreeM unfoldForest unfoldTreefoldTreelevelsflatten drawForestdrawTreeghc-prim GHC.TypesTrueFalseXGenXDeltaXSigmaXLXTauLreplaceInversesreplaceInversesNaivemoveDeltasLeftexpandPosXWordexpandAnyXWordposLposRposLPermposRPermfilterDeltaFactorsfails_lemmma_2_5normalizePermFactorsnormalizePermFactors1leftGreedyFactors