{'fraction_non_alphanumeric': 0.03623507228158391, 'fraction_numerical': 0.009522313010685103, 'mean_word_length': 4.348067226890756, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 1, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
SymBuild: a package for the computation of integrable symbols in scattering amplitudes

The article presents and documents the Mathematica package SymBuild. This package implements the computation and manipulation of integrable symbols appearing in various calculations in high-energy scattering amplitudes. By using Gr\"obner bases, implementing various simplifications and by the potential utilization of the C++ program SpaSM, integrable symbols in a large class of alphabets (including roots) can be computed to high weights.


Introduction
An ancient idea in the field of scattering amplitudes, going back to the analytic S-matrix program [1], has been to determine, or bootstrap, a given scattering amplitude by using its physical and analytical properties. In some 1-loop cases, the constraints of perturbative unitarity and the known collinear/soft limits have been used to determine explicitly entires classes of n-particle scattering amplitudes [2]. A big impediment to the implementation of this method at higher loop orders has been the fact that higher-loop Feynman integrals are significantly less understood. However, once it was realized that a large class of Feynman integrals are given by iterated integrals which in many situations can be efficiently described via their 1 symbols [7], further progress became possible. The idea behind the symbol is to encode the way in which the functions are defined from elementary integrands (called letters, the set of which is called the alphabet). Then, the symbol of an L-fold iterated integral (referred to as a weight L function) encodes its analytic structure such as branch surfaces and poles.
As soon as one knows the symbol alphabet of a given scattering amplitude, one can write a very constraining ansatz for it. In many cases, the ansatz for a loop order amplitude is made out of a set of prefactors (that can be determined by computing leading singularities) that multiply a transcendental function of weight 2 . Instead of working with the functions, one works with their symbols and reconstructs the full answer at the end. The set of symbols of all such transcendental functions can be constructed iteratively from the alphabet by solving a set of integrability conditions, which basically impose that that symbol represents a well-defined function, and the so-called n-entry conditions 2 , which come from physical constraints on the branch surfaces. It is however a non-trivial linear algebra problem to compute the set of integrable symbols subject to the n-entry conditions, a task that the package introduced in this article should simplify.
Once the set of integrable symbols is known, all one in principle needs to do is to solve a set of linear equations coming from collinear/soft constraints and others and hope that this proves enough to fix all unknown coefficients in the ansatz. This modern incarnation of the bootstrap program has been applied successfully to many cases, such as the 6-and 7-point amplitudes in planar N = 4 super Yang-Mills (SYM) [8][9][10][11][12][13][14][15], the computation of Feynman integrals [16][17][18], the QCD soft anomalous dimension [19] or Higgs boson amplitudes [20]. As the loop order , and hence also the weight, increases, solving the integrability conditions becomes increasingly harder, since the size of the underlying linear algebra problem grows roughly as M 2 where M is the number of letters in the alphabet. It eventually becomes necessary to use tools that go beyond what a standard computer algebra program like Mathematica can do in order to compute the integrable symbols and then manipulate them. As an aside, not only is the computation of the integrable symbols for a given alphabet difficult, but even the comparatively easier task of computing their number is not solved in general. One known case is that of the alphabet whose letters are cluster coordinates on Gr(2, n) for which the integrable symbols of arbitrary weight have been enumerated in [21].
Our goal in this paper is introduce the Mathematica package SymBuild whose job it is to compute high-weight integrable symbols rapidly and to then manipulate them (for the purpose of computing derivatives or limits of them) efficiently. In order to solve the large matrix equations that arise at high weight, we use the C++ linear algebra package SpaSM [22], which allows for efficient parallelization 3 .
The outline of the paper is as follows. In section 2 we introduce the notation and necessary definitions for the problem. In section 3 we present the organization of the Mathematica package and then explain the workings and functionalities of the various algorithms used. In section 4, we present the most important commands of the package and comment on their usage. We conclude in section 6.
The package SymBuild, version 1.0, can be downloaded from, https://github.com/vladimirmitev/SymbolBuilding-development/archive/v1.0.tar. gz The package file itself is contained in the file SymBuild.wl. The other file, the notebook PackageTesting.nb, contains examples of the different functionalities of the package. The other directories are not important for the end users.

Setup and notation
We start with an alphabet A = {W 1 , . . . , W M } of algebraic functions (called letters) W i (x) in the kinematic variables x = (x 1 , . . . , x N ). In particular, the functions W i can contain roots ρ r (x), which we will deal with in section 3.2. We demand that the letters be independent in the sense that the Let |A| be the number of elements in an alphabet, here M . We remark that two alphabets A = {W i } and A = W i are equivalent if there exists an invertible matrix with rational entries Let us introduce the set of iterated integrals in alphabet A. Such an integral (of weight L) is defined by picking a path γ : [0, 1] → C N and computing the ordered iterated contour integral (beware the change of order between the LHS and the RHS) where ∂ s ≡ ∂ ∂xs ,γ(t) ≡ ∂ t γ(t) and we use the convention of summing over repeated indices. Let us denote by x b the initial or boundary point of the path, x b = γ(0) and simply by x the final point x = γ(1). We can generalize the set of iterated integrals that we look at by taking linear combinations of (2.2) of the form I c I [W i1 , . . . , W i L ] γ , where I = (i 1 , . . . , i N ) is a multiindex and the c I are constants. Hence, we consider the set of iterated integrals of weight L as a vector space over the rational numbers. Furthermore, the space of all iterated integrals is a graded algebra, since the product of two iterated integrals of respective weights L 1 and L 2 is an iterated integral of weight In general, such iterated integrals will depend not just on the initial and final point, but also on the specific path γ. We can make a specific linear combination independent of infinitesimal variations of the contour by carefully choosing the constants such that they satisfy the relations for all r = 1, . . . , L − 1 and for all a < b = 1, . . . , N . Iterated integrals that satisfy (2.3) depend only on the initial and final point of the path as well as on its homotopy class.
Having introduced iterated integrals, we shall now move on to discuss their symbols. First, a note on notation: we denote the symbol of a function f as SB[f ]. In particular, the symbol of the iterated integrals of (2.2) is written as 4 (2.4) Having introduced the notation for the symbols, let us talk about the symbols themselves. The symbol SB[f ] is essentially a generalized primitive (i.e. a solution of a differential equation) and contains all the information on the positions of the branch points and singularities of the function f as well as of its derivatives. We shall refrain from presenting a fully self-contained introduction to symbols here and refer to the article [23] instead. The important pieces of information that the reader needs is that, due to the properties of the logarithm, the following identities hold for the symbols: [· · · , AB, · · · ] = [· · · , A, · · · ] + [· · · , B, · · · ] , [· · · , A −1 , · · · ] = − [· · · , A, · · · ] , [· · · , const, · · · ] = 0 .
Furthermore, if one is armed with the symbol of a function and knowledge of the appropriate boundary conditions, it becomes possible to reconstruct the function itself [7,23]. As an example of a symbol of a very well known function, let us take the dilogarithm. Since Li Finally, we remark that the first entry W a1 of the symbol [W a1 , . . .] contains information on the its discontinuities, while derivatives in act on the last entry; for instance

The integrability tensor
In order to deal with the integrability condition (2.3) in a more systematic way, we define the following set of algebraic functions Due to the antisymmetry, we can restrict to r < s = 1 . . . , N and i < j = 1, . . . , M . First, we are interested in the set of linearly independent constant solutions c ij to the set of equations ij (x) = 0 , ∀x and ∀r, s .
Instead of the set of solutions, we are actually more interested in the set of constraints. That is, we need to determine a constant tensor F A ij with i, j = 1, . . . , M and A = 1, . . . , R that is antisymmetric for all A is the same as the space of solutions to (2.8). In this setup, the number R, the integrability rank of the alphabet A, is the minimal number for which this is possible. We shall refer to F A ij as the integrability tensor and we can represent it as a list (of length R) of M × M antisymmetric matrices. As an example, .
It is easy to see that the three functions satisfy a single linear equation and thus R = 2. We find The advantages of working with the integrability tensor is that 1) it is constant and 2) it is minimal and packs in a neat way all the conditions coming from the integrability equation (2.3). Once it has been determined, the computation of the integrable symbols can be done without any reference to the functional form of the letter of the alphabet A.

Iterative notation
To each weight L integrable symbol S (L) ∈ H L corresponds by definition a tensor c I with L indices Such linear combinations can easily end up having millions of terms and thus be prohibitively demanding of computer memory as L gets large. It is therefore necessary to use an alternate method of representation. In the iterative notation, introduced by Dixon et al. [10], the symbols are written as 5 We shall refer to the 3-index tensors d as the weight L integrable tensors. The set of inte- } contains all the information needed to work with the integrable symbols of weight L. In all cases we have worked out, the integrable tensors are very sparse, boasting a density of less than one percent.
Iterating the notation (2.11) one step further, and using the fact that by definition H 0 = Q, so that j 0 = 1 is a trivial index, we obtain One of the advantages of the iterative notation is the fact that the integrability condition (2.3) for the weight L symbols (assuming that the symbols of lower weight are integrable) can be written in a very simple manner: (2.13) 5 We let the index j L label the basis elements as H L = span{S The above can be rewritten as a matrix equation with (dim H L−2 ) × R rows and (dim H L−1 ) × M columns for the unknowns d . We assume implicitly that the weight L − 1 integrable tensor has already been determined. We remind that the index j L in (2.13) is a dummy index that simply enumerates the elements of a basis set of solutions. As it turns out, in all cases tested, (2.13) is a sparse system of equations that can be solved very efficiently with SpaSM or directly in Mathematica if the size of the system is not too big. We remark that it is also common and possible to require that the last entries of the integrable symbols come from some other (smaller) set of letters A whose members can be expressed as linear combinations of the letters of A. Implementing such conditions in straighforward in this framework and the whole procedure is implemented in the command determineNextWeightSymbols, see section 4 for more information.

Counting products
One interesting question appears often: what is the number of integrable symbols of weight L that are products? The product of a function f 1 of weight L 1 and of a function f 2 of weight L 2 is a function of weight L 1 + L 2 and its symbol is given by the shuffle product of the symbols SB[f 1 ] and SB[f 2 ]: The shuffle product of two integrable symbols is again integrable. We define the product symbols at weight L to be the integrable symbols that are obtained by using the shuffle product on lower weight symbols and we call the associated space P L . The space of irreducible symbols Q L is then defined as (2.16) In particular Q 1 = H 1 . We find via simple combinatorics that i.e. it is a sum over partitions λ and the binomials take care of the appropriate symmetrizations. Using (2.17) and the obvious equation dim H L = dim P L + dim Q L , we can easily express dim Q L through dim H i . The counting of symbols that are products/are irreducible is implemented in the package SymBuild using the commands dimProductSymbols/dimIrreducibleSymbols, see the auxiliary example file. As a corrolary of (2.17), it follows that we have the following dimensions bounds (ignoring n-entry conditions) where the right bound is saturated for the alphabet A = {x 1 , . . . , x N }. The space of functions for that alphabet is made up only of products of logs. In addition to computing the dimension of the space of irreducible symbols, we can project onto it explicitly. Specifically, product symbols are annihilated by the ρ operation, see for example [24]. This map ρ : V L → V L is defined recursively by setting ρ([W ]) = [W ] and then demanding that for k > 1. The map ρ is implemented in the package by the command removeProductsFromSymbol-TensorArray, see the auxiliary example file. In priniple, we have the identifications P L = Ker(ρ) H L and Q L = Im(ρ) H L . However, if we have imposed some special n-entry conditions, it can be the case that not all elements annihilated by ρ can be written as products of lower weight symbols.

Explanation of the algorithms
In this section, we present the organization of the package as well as the inner working of the various algorithms. We begin with the steps to follow when computing the symbols, shown in figure 1.

Computing the integrability tensor
The computation of the F A ij tensor proceeds as follows. If the alphabet A is rational, then the set of equations (2.8) involves only rational functions in the variables x r . If the alphabet is not rational, then we need to use Gröbner bases first in order to obtain a set of equations involving purely rational functions. This will be discussed in section 3.2. Ignoring that case for now, we shall generate the integrability tensor from (2.8) in the following way: We start with an empty matrix M 1. We first take one of the equations of (2.8), say for r = 1 and s = 2.
2. Set the variables x r to random values. For this, we choose random primes numbers (determined by the parameter sampleSize) such that the x r are all different. This gives a row of M 2 constants that we append to M.
3. We repeat this maxSamplePoints number of times. We go back to step 1. and do the same for the next equation in (2.8) until we run out of equations.
4. We can now row reduce the M matrix and drop the zero rows at the end. The final rank of M is the integrability rank R.
We can then directly extract F A ij from M AI by unrolling the indices appropriately. In all cases that were tested, the integrability tensor F A ij is a very sparse tensor (less than 1% of occupancy) and its entries tend to be simple rational numbers. All along, the computations are done in a finite field Z p for a given large prime number p, after which we apply Wang's reconstruction algorithm. The procedure is then repeated for a different large prime p and if the results agree, the computation terminates.

Dealing with roots
The alphabet A in the variables x = {x 1 , . . . , x N } can contain a number Q of roots ρ = {ρ 1 , . . . , ρ Q }, which are of course functions in the variables x i . We shall assume that the roots are zeroes of the Q Figure 1. Flowchart describing the main steps in computing the integrable symbols as well as the possible operation that can be applied to the results.
ij (x, ρ) in (2.8), which is a rational function of the x's and of the ρ's as Since the roots are algebraically independent, each integrability equation (2.8) (for a given fixed r and s) gives now rise to m 1 × · · · × m Q equations involving only the purely rational functions f (rs) ij (n 1 , . . . , n Q ; x). This allows one to apply the same procedure as for the rational alphabets and to thus determine the integrability tensor for that alphabet.

Computing the integrable symbols
Once the integrability tensor has been computed, we can proceed to solve (2.13) iteratively, starting from L = 1 (for which there is nothing to solve) and continuing to a used specified maximal weight L max . Before the computation is done, we may optionally specify 1. the n−entry conditions, i.e. which letters, or combinations of letters are forbidden from appearing in the n entry of the symbols.
2. which letters of the alphabet are even and which are odd. The package SymBuild then automatically separates the solutions accordingly in even and odd symbols. In this context even/odd refers to the behavior of the letters W i under an automorphism π (such as for example complex conjugation) under which d log W i → ±d log W i with + for even and − for odd.
Depending on the options specified, one may use determineNextWeightSymbolsSimple or deter-mineNextWeightSymbolsSimple as explained more thoroughly in section 4. Thus, the computation of the sets of integrable symbols proceeds iteratively. We would like to remark here that an alternative algorithm for the computation of weight L integrable symbols, in which the the equations to solve arise from consistency conditions for the gluing of weight a and weight L − a symbols, was presented in [14]. While it has some advantages, we preferred for simplicity to implement the standard iterative method here in which the weight L integrable symbols are constructed from the already computed weight L − 1 ones.

The inversion tensor and transformations of symbols
The weight L inversion tensor E j L j L−1 i L that has the following property. Given an arbitrary integrable tensor of weight L, written iteratively as , then that symbol can be expanded in the basis of H L given by the integrable tensors (2.11) as The inversion tensor E j L j L−1 i L is the left-inverse of the integrable tensor d in the following sense: we can think of the pair (j L−1 , i L ) as a single index I = |A|(j L−1 − 1) + i L ∈ {1, . . . , |A| dim H L−1 }. Applying this procedure on the integrable tensor d j L that has more rows than columns and has rank dim H L by construction. Such a matrix has a (non-unique) left inverse matrix ) for which we can replace I by the bi-index (j L−1 , i L ) to obtain the desired 3-tensor.
The inversion tensor is useful in determining the transformation matrices implementing various symmetries of the alphabet on the space of integrable symbols, as well as in computing the limits of integrable symbols. Specifically, if one is given a linear transformation T mapping the weight 1 symbols in one alphabet A to those of another 6 then we can compute the transformation map T : H L → H L acting on arbitrary integrable symbols iteratively as where we have summed over repeating indices. Thus, we have determined the weight L transformation map in terms of the weight L inversion tensor E , the weight L − 1 transformation matrix T (L−1) j L−1 and the original transformation input T i i . Since at weight zero, the transformation matrix trivially T (0) j 0 j0 = T (0) 1 1 = 1, we can directly compute the other transformation matrices.

Most common commands
This article is accompanied by an annotated Mathematica file that shows explicitly how to compute the integrable symbols of a variety of alphabets (with or without roots). It further contains examples of implementing symmetry and limit operations. In this section, we want to emphasize the most important parameters and commands of the package.
• computeTheIntegrabilityTensor takes as inputs an alphabet (array of functions), the array of variables of the alphabet, the list of roots appearing in the alphabet (is an empty list if the alphabet is rational), the list of minimal polynomials describing the roots, an optional list of replacement rules for voluminous objects in the list of minimal polynomials, and three further integers. Those integers are: 1) one determining the size of the random prime numbers used in the algorithm of section 3.1, 2) one setting the number of sampling points and 3) the last one specifying the number of retries allowed if the sample points turn out to contain infinities.
• findRelationsInAlphabet takes the same inputs as computeTheIntegrabilityTensor and computes all linear relations existing between the letters of the alphabet in the sense of (2.1).
• weight1Solution and weight1SolutionEvenAndOdd are two commands that prepare the weight 1 integrable tensors. The first command takes an alphabet and a list (potentially empty) of forbidden first entries, while the second also takes as second argument a list of digits (0 for even, 1 for odd) that indicate which letters are even/odd. The first command returns an the weight 1 integrable tensor, while the second returns an array of two elements consisting of the weight 1 integrable tensor and an array indicating their signs.
• determineNextWeightSymbolsSimple and determineNextWeightSymbols are two commands that compute the next weight symbols. The simplified command determineNextWeightSymbolsSimple takes the weight L − 1 integrable tensor and the integrability tensor F (and two optional parameters, see the auxiliary example file) and directly determines the weight L integrable tensor. On the other hand, the command determineNextWeightSymbols takes (in this order) the weight L − 1 integrable tensor, the list of its signs, the integrability tensor, the list determining the signs of the letters, an optional matrix of equations that determine the forbidden entries at weight L (either = False or a matrix generated with the command weightLForbiddenSequencesEquationMatrix) and an optional matrix that gives the last entries of the symbol as linear combinations of the letters of the alphabet. This more complicated command returns the integrable tensor of weight L as well as a list indicating the signs of the integrable symbols.
• weightLForbiddenSequencesEquationMatrix is a command that takes the weight L − 1 integrable tensor, a list of forbidden sequences of entries at weight L and the size of the alphabet as inputs and then generates a matrix of equations that is used in determineNextWeightSymbols to remove the forbidden weight L entries.
• presentIntegrableSymbolsData is a command that takes either an integrable tensor or a list consisting of an integrable tensor and the array indicating its signs, and presents them in a legible way.
• expressTensorAsSymbols takes a product of integrable tensors and presents them as a list of explicit formal symbols in several possible ways. Specifically, its inputs are a product where repeated indices are summed over (a ≤ b) and an optional string opt giving the display specification. The object d is a tensor with 3 + b − a indices that contains all the information for the integrable symbols between weight a and b. Plugging d into expressTensorAsSymbols together with opt="Recursive" leads to the output which is an array of length dim H b of explicit integrable symbols. In the above, S are placeholders for the integrable symbols of weight a−1. Furthermore, if a = 1 and the option opt="Complete" is used, then the S part of the expression (4.2) is dropped since there is only one symbols of weight 0.
• convertFormalSymbol takes two inputs: 1) an integrable symbols written as I c I sb[{i 1 , . . . , i L }] and 2) an alphabet A = {W 1 , W 2 , . . .}. Its output is an expression of explicit symbols , which can sometimes be useful for the computation of limits of symbols.
• symbolDerivative takes three elements as input: 1) a symbol (written like in (4.2)) whose derivative is to be computed, 2) the alphabet in which the symbol is written and 3) the variable w. r. t. to which to take the derivative. Alternatively, it can act on expressions of explicit symbols SB (such as those produces by convertFormalSymbol) in which case the alphabet should not be given.
• IntegrableQ is a command that can be applied to a linear combination S of formal symbols (either sb or SB) to determine if S is integrable. If acting on sb symbols, the integrability tensor F should be given as second input. If acting on the explicit SB symbols, the list of variables must be given as second input.
• determineLeftInverse acts on a matrix A of size m×n with m ≥ n but with full rank (rank(A) = n) and computes its left-inverse, i.e. a n × m matrix B such that BA = 1 n .
• computeTheInversionTensor takes a symbol tensor d and computes the inversion tensor E j L j L−1 i L as explained in section 3.4.
• buildTransformationMatrix computes the weight L transformation matrix between the sets of integrable symbols in the alphabet A and those in the alphabet A , as explained in (3.4). It takes (in this order) as input the weight L integrable tensor d for A, the transformation matrix T (L−1) , the initial transformation matrix T and the weight L inversion tensor E j L j L−1 i L for the alphabet A .
• radicalRefine is an auxiliary command that takes a list of expressions involving roots and attempts to provide a system of minimal polynomials that can then be used in, for example, the command computeTheIntegrabilityTensor. For instance, {mp, rules} = radicalRefine where "mp" is the list of minimal polynomials in the auxiliary variables X [1] and X [2] and "rules" tells us how to express the desired roots √ a, √ b from the roots of the minimal polynomials 7 .
All of these commands are illustrated in several examples in the Mathematica notebook accompanying this package.
Furthermore, the package contains a number of global parameters that can be modified to adapt some of the algorithms used. These parameters are globalLowerThreshold, globalSpaSMThreshold, glob-alGetNullSpaceStep, globalSpaSMListOfPrimes, globalGetNullSpaceSpaSMPrimes, globalSetOfBigPrimes, globalRowReduceOverPrimesInitialNumberOfIterations, globalRowReduceOverPrimesMaxNumberOfIterations, globalRowReduceOverPrimesMethod, globalRowReduceMatrixSpaSMPrimes and globalVerbose. Their standard values can be seen at the beginning of the auxiliary example notebook and their purpose examined with the ? and ?? commands. If not using SpaSM, the most important would be globalVerbose (a boolean. Setting it to False suppresses all monitoring messages) and globalGetNullSpaceStep which is the size of the pieces into which big matrices are cut when the program tries to determine their null space. Its default value is 200 and reducing that number can sometimes improve the performance for very large matrices.

Applications and performance
Let us now discuss the performance of the package. For this, we have timed the time needed for the computation of symbols of various weight in several alphabets.
First, let us take the case of the 5-pt planar alphabet A P of 26 letters, see for example [16] for a definition. On a recent Intel i7 laptop with 8Gb of RAM, the computation of integrability tensor and of the symbols of weight L < 6 (subject to the first entry conditions allowing only the letters {W i } 5 i=1 as first entries) takes in total about 500 seconds, see table 1. The situation for the non-planar alphabet A NP of 31 letters is more complicated 8 . Even after imposing the second entry conditions that restrict the number of symbols significantly, it becomes very difficult, due to memory and patience constraints, to compute the number of integrable symbols of weight 5 on a laptop. Still, the remaining computation time is manageable, see again table 1.
We have also tested the 6-point dual-superconformal alphabet A H of 9 letters, see for example [10] for a definition. We find the number of symbols (with the respective computation time) in table 2. The computations take comparately longer than the similarly sized ones in table 1 because the integrability equations are not as sparse.   Table 1. The number of independent integrable symbols of given weight for the planar and the non-planar 5-pt alphabets, together with the approximate computation time (in seconds unless noted otherwise, done on a system with quad i7 processors and 8Gb RAM) for the symbols and for the integrability tensor separately. In each case, we indicate the number of even | odd symbols, whose computation was also included in the computing time. These computations were done completely within Mathematica, without SpaSM. The computation time using SpaSM on the same machine is put in parenthesis and in blue. In red, we put the computations done on the computer cluster Mogon. We used just two cores, but a lot (300+ Gb) of RAM.  Table 2. We list here the number of independent integrable symbols (note that these are not irreducible symbols!) of given weight for 6-point dual-superconformal alphabet of 9 letters, together with the approximate computation time (i7 processor, 8Gb RAM) for the symbols and for the integrability tensor separately. These computations were done completely within Mathematica, without SpaSM. The computation time using SpaSM on the same machine is put in parenthesis and in blue.

Conclusions and Outlook
In this article, we presented the package SymBuild which we hope will prove helpful to the community working on the perturbative amplitude bootstrap in computing and manipulating integrable symbols. The package is powerful enough that, even without resorting to SpaSM, the weight four integrable symbols of the non-planar 5-particle alphabet (with 31 letters and one root) can be computed on a laptop in about fifteen minutes. Regarding future research, several important questions remain open. First, it would be very interesting to understand the geometry and counting behind the integrable symbols more thoroughly. For instance, the questions of whether it is possible to devise a formula that would compute the number of integrable symbols of arbitrarily large weight L for a given arbitrary alphabet (even one that is purely rational) is, to our knowledge, unanswered outside of the cases studied in [21].
Somewhat related to the question of counting the number of integrable symbols is the problem of determining the theoretical limits of the applicability of the amplitude bootstrap method itself. Since the number of symbols grows rapidly with the weight, so too does the number of coefficients that need to be determined via consistency with collinear limits, soft limits and others. Disregarding practical concerns on computing time and memory, is it possible to prove that the bootstrap program with succeed at any loop (and hence weight) order or can one determine a priori at which loop order the method will fail?
More practically, it would be interesting to extend this package and the methods therein to the case of elliptic functions [25] or even to the higher generalizations discussed in [26]. Furthermore, the questions of which roots can arise in practical cases (and how to resolve them if possible) and of the a priori determination of the alphabet for a given scattering process are still quite open. We refer to [27] for work on the latter problem.