Repository navigation
Combinatorica Audit
Reference audit (2026-10-09), not a design. Combinatorica is the legacy Wolfram combinatorics package (Skiena and Pemmaraju); this maps its 456 names against enumeratio and core Wolfram, for gaps, head-naming (Speculative-Statistics-and-Maps §3.2) and oracle use.
Audit of Wolfram 15's legacy Combinatorica package (456 public names, 41 also System names) against enumeratio main (2026-10-09). Nothing in the repo was edited. Spot checks ran in wolframscript 15.0.0 with Needs["Combinatorica"]; our side was read from reference records, sources and dist/` metadata only (no engine runs).
- Counts over 456 names: a (we have it) 153 = 82 dedicated head, 64 derivable from our heads/families with no dedicated head (
a~), 7 only in FindStat catalog data or a stub record (a†); b (core Wolfram has it) 132 = 96 direct, 36 only indirectly (b~); c (gap) 81; d (out of scope) 90 = 45 drawing, 2 I/O, 29 option/tag symbols, 14 plumbing for Combinatorica's own graph record and obsolete names. -
Combinatorica has no
Descents,AscentsorMajorIndex.Names["CombinatoricaDescent"],Ascent,MajorandSupportare all empty. Its major index is calledIndex. The wiki's Speculative-Statistics-and-Maps §3.2/§4.3 and BL-202 both say Combinatorica documentsDescents[p]; that is wrong. The only permutation statistics it names that we also have areInversions,Index(= ourMajorIndex),Runs(different meaning),SignaturePermutation(= ourSign) andLongestIncreasingSubsequence` (different return type). -
Runsis not aSystemname either (the BL-202 candidate list calls it a Wolfram collision, from memory). The real clash is with Combinatorica: itsRuns[p]returns the list of increasing runs, ours returns their count. - Two of our docs are stale against code:
KSubsetssummary anddocs/ranking-and-unranking.mdstill say colexicographic, while the code and the example row (At(KSubsets(5,2), 3) = {1,4}) are lexicographic since #576 ("Subsets by size, then lex"). Worth a one-line fix. - Real conventions that bite (details in §4):
Permuteis the inverse of ours and core; ranks and unranks are 0-based with wraparound;Compositions[n,k]means weak compositions;Partitions[n,k]bounds the largest part (core and ours bound the number of parts);StirlingFirstis unsigned;ToInversionVectoris indexed by value, not position;SetPartitionslists in a different order. - Oracle: yes as a narrow second system (~40 heads, about 1-2 days), not as a general one. See §5.
| Class | Meaning |
|---|---|
| a | we have it as a declared head, statistic or map; Note flags name/semantic differences |
| a~ | derivable from our heads or lazy families (membership, rank/unrank, count, sampling), no dedicated head |
| a† | only a FindStat catalog entry (data, no kernel) or a stub: carrier record |
| b | core Wolfram has it; Core column names it |
| b~ | core has it only indirectly (GraphData, a combination, a different-but-related head) |
| c | gap: neither we nor core |
| d-draw / d-io / d-opt / d-rep | out of scope: drawing; file I/O; option or tag symbols; Combinatorica's own graph record and obsolete names |
Crosswalk says whether the core name already appears in packages/reference/src/crosswalk-data.ts (as one of our heads or as the Wolfram symbol the transpiler emits). The crosswalk only records a Wolfram symbol for a head of ours, so a class-b row with no head of ours is no by construction: there is nothing to map yet. No Combinatorica name appears in the crosswalk, the transpiler's HEADS, or system-names.ts (the only mention in the tree is a comment in packages/reference/scripts/provenance.ts that a Combinatorica`… target is a package, not a built-in).
Sources used: declared names from every dist/declares.json (1,389 names), the reference record folders, ALL_STATISTICS (84 definitions: 38 Permutation, 19 IntegerPartition, 16 DyckPath, 11 SetPartition) and the 40-odd permutation/tableau/set-partition maps from dist/index.mjs, the FindStat slice (1,997 statistics, 336 maps), system-names.ts (7,736 System names) and the crosswalk data. Every name in the Ours/Core columns was machine-checked against those sets.
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| DerangementQ | a~ | Derangements, FixedPoints | membership in Derangements(n), or FixedPoints = 0 | ||
| Derangements | a | Derangements | ours takes n (the family on 1..n); Combinatorica takes a list | ||
| FromCycles | a | CycleDecomposition | PermutationList | mapped | Permutation(CycleDecomposition(...)) |
| FromInversionVector | a~ | PermutationInversion | inverse of ToLehmerCode; conventions differ (see ToInversionVector) | ||
| HideCycles | a | Foata | VARIANT: Combinatorica starts cycles at their minima in decreasing order; ours is Foata's maxima in increasing order | ||
| IdentityPermutation | a~ | SymmetricGroup | first element of SymmetricGroup(n) | ||
| Index | a | MajorIndex | same statistic (sum of 1-based descent positions), different name | ||
| InversePermutation | a | InversePermutation | InversePermutation | mapped | same convention |
| Inversions | a | Inversions | same name, same count | ||
| InvolutionQ | a~ | Involutions | membership in Involutions(n), or p = Inverse(p) | ||
| Involutions | a | Involutions | ours takes n; Combinatorica order puts the identity last | ||
| LexicographicPermutations | a | Permutations, SymmetricGroup | Permutations | no | |
| LongestIncreasingSubsequence | a | LongestIncreasingSubsequence | LongestOrderedSequence | no | NAME CLASH in return type: ours is the length; Combinatorica and core return a subsequence |
| NextPermutation | a~ | SymmetricGroup | successor in the family order; Combinatorica wraps {3,2,1} to {1,2,3} | ||
| NthPermutation | a~ | SymmetricGroup | unrank: Combinatorica is 0-based and wraps; At is 1-based | ||
| NumberOfDerangements | a | Subfactorial | Subfactorial | mapped | |
| NumberOfInvolutions | a~ | Involutions | Count(Involutions(n)) | ||
| NumberOfPermutationsByCycles | a~ | StirlingS1 | unsigned; our StirlingS1 is signed | ||
| NumberOfPermutationsByType | a† | FindStat St000182, catalog only | |||
| PermutationType | a | CycleType | CONVENTION: Combinatorica gives the multiplicity vector, ours the partition of cycle lengths | ||
| PermutationWithCycle | a | CycleDecomposition, Cycles | Cycles | mapped | CycleDecomposition(Cycles(...), n) |
| Permute | a | Permute | Permute | mapped | CONVENTION: Combinatorica gives lp, ours and core move item i to p[i]; they are inverse |
| RankPermutation | a~ | SymmetricGroup | rank in lexicographic order: Combinatorica is 0-based (identity = 0) | ||
| RevealCycles | a | Foata | VARIANT: inverse of HideCycles; see HideCycles | ||
| Runs | a | Runs, DescentComposition | NAME CLASH: Combinatorica returns the list of runs; our Runs is their count; DescentComposition gives the run lengths | ||
| SignaturePermutation | a | Sign | Signature | no | ours Sign (permutation statistic) clashes in spirit with numeric Sign |
| StirlingFirst | a~ | StirlingS1 | Combinatorica is unsigned, ours signed | ||
| StirlingSecond | a | Stirling | StirlingS2 | mapped | our name is Stirling |
| ToCycles | a | CycleDecomposition, PermutationCycles | PermutationCycles | mapped | CONVENTION: Combinatorica starts each cycle at the image of its least point; core and ours start at the least point |
| ToInversionVector | a | ToLehmerCode | CONVENTION: Combinatorica indexes by value, length n-1; ours is the Lehmer code by position, length n | ||
| UnrankPermutation | a~ | SymmetricGroup | unrank: Combinatorica is 0-based, At is 1-based | ||
| DistinctPermutations | b | Permutations | no | Permutations on a list with repeats is the multiset case | |
| PermutationQ | b | PermutationListQ | no | ours: Permutation carrier validates | |
| RandomPermutation | b | RandomPermutation | no | ours: sample from SymmetricGroup(n) | |
| EncroachingListSet | c | patience-sorting piles; ties to longest increasing subsequence | |||
| Eulerian | c | Eulerian numbers (A008292); usage string says "runs" but k counts descents | |||
| Josephus | c | A054995-style permutation | |||
| MinimumChangePermutations | c | Steinhaus-Johnson-Trotter order | |||
| NumberOfPermutationsByInversions | c | Mahonian numbers (A008302) | |||
| PermutationGraph | c | inversion graph; links permutations to graphs |
d-opt: Cycles
d-rep: RandomPermutation1, RandomPermutation2
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| Compositions | a | WeakCompositions | NAME CLASH: Combinatorica Compositions[n,k] allows zero parts (our WeakCompositions); our Compositions(n) is all positive compositions | ||
| DurfeeSquare | a | DurfeeSquare | same name, same meaning (FindStat St000183) | ||
| NextComposition | a~ | WeakCompositions | successor in the family order | ||
| NextPartition | a~ | IntegerPartitions | successor in the family order | ||
| NumberOfCompositions | a~ | WeakCompositions | Count(WeakCompositions(n, k)) = Binomial(n+k-1, k-1) | ||
| NumberOfPartitions | a | PartitionNumbers | PartitionsP | no | |
| PartitionQ | a~ | IntegerPartition | membership in IntegerPartitions(n) | ||
| Partitions | a | IntegerPartitions | IntegerPartitions | mapped | Partitions[n, k] bounds the LARGEST part; IntegerPartitions[n, k] bounds the NUMBER of parts (ours follows core) |
| RandomComposition | a~ | WeakCompositions | sample: At(F, RandomInteger(Count(F))) | ||
| RandomPartition | a~ | IntegerPartitions | sample | ||
| TransposePartition | a† | FindStat Mp00044 conjugate, catalog only; stats like ConjugateOddParts conjugate inline | |||
| DominatingIntegerPartitionQ | c | dominance order; majorization appears in roadmap polytope guide content |
d-draw: FerrersDiagram
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| ConstructTableau | a | RskInsertion | insertion tableau of the permutation | ||
| FirstLexicographicTableau | a~ | StandardTableaux | first element of the family, if its order is lexicographic | ||
| InsertIntoTableau | a~ | RskInsertion | single bumping step not exposed | ||
| LastLexicographicTableau | a~ | StandardTableaux | last element of the family, if lexicographic | ||
| NextTableau | a~ | StandardTableaux | successor in the family order | ||
| NumberOfTableaux | a | StandardTableaux, HookProduct | Count(StandardTableaux(λ)); hook-length formula via HookProduct | ||
| PermutationToTableaux | a | Rsk | |||
| RandomTableau | a~ | StandardTableaux | sample | ||
| TableauQ | a~ | StandardTableau | membership | ||
| Tableaux | a | StandardTableaux | |||
| TableauxToPermutation | a† | stub ToPermutation on StandardTableauPair; inverse RSK | |||
| TransposeTableau | a† | FindStat Mp00084 conjugate, catalog only | |||
| DeleteFromTableau | c | part of inverse RSK | |||
| TableauClasses | c |
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| BinarySubsets | a~ | BinaryStrings, Finset | subsets in binary-rank order: BinaryStrings mapped to Finset | ||
| CartesianProduct | a | Tuples | Tuples | mapped | also Outer |
| GrayCode | a | GrayCodes | |||
| GrayCodeSubsets | a | GrayCodeSubsets | check order against Combinatorica (reflected, last element fastest) | ||
| KSubsets | a | KSubsets | Subsets | mapped | lexicographic and matches core; but our summary and docs/ranking-and-unranking.md still say colex (stale since #576) |
| ListNecklaces | a | KNecklaces, KBracelets, BinaryNecklaces | cyclic = necklaces, dihedral = bracelets | ||
| NextBinarySubset | a~ | BinaryStrings | successor in the family order; Combinatorica wraps around | ||
| NextGrayCodeSubset | a~ | GrayCodeSubsets | successor in the family order | ||
| NextKSubset | a~ | KSubsets | successor in the family order | ||
| NextSubset | a~ | Subsets | successor in the family order | ||
| NthSubset | a~ | Subsets | unrank, 0-based vs 1-based | ||
| NumberOfNecklaces | a~ | KNecklaces, KBracelets | Count of the family | ||
| RandomKSubset | a~ | KSubsets | RandomSample | no | sample |
| RandomSubset | a~ | Subsets | RandomSample | no | sample |
| RankBinarySubset | a~ | BinaryStrings | rank: 0-based here | ||
| RankGrayCodeSubset | a~ | GrayCodeSubsets | rank: 0-based here | ||
| RankKSubset | a~ | KSubsets | rank: 0-based here | ||
| RankSubset | a~ | Subsets | rank: 0-based here | ||
| UnrankBinarySubset | a~ | BinaryStrings | unrank: 0-based here | ||
| UnrankGrayCodeSubset | a~ | GrayCodeSubsets | unrank: 0-based here | ||
| UnrankKSubset | a~ | KSubsets | unrank: 0-based here | ||
| UnrankSubset | a~ | Subsets | unrank: 0-based here | ||
| GrayCodeKSubsets | c | revolving-door order | |||
| LexicographicSubsets | c | pure lex order (not graded); ours is by size then lex like core | |||
| NextLexicographicSubset | c | needs the pure lex order first |
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| KSetPartitions | a | SetPartitionsIntoKBlocks, SetPartitions | SetPartitions(n, k) also | ||
| RGFQ | a~ | RestrictedGrowthStrings | membership | ||
| RGFToSetPartition | a | SetPartition | map from restricted growth string | ||
| RGFs | a | RestrictedGrowthStrings | |||
| RandomKSetPartition | a~ | SetPartitionsIntoKBlocks | sample | ||
| RandomRGF | a~ | RestrictedGrowthStrings | sample | ||
| RandomSetPartition | a~ | SetPartitions | sample | ||
| RankKSetPartition | a~ | SetPartitionsIntoKBlocks | rank | ||
| RankRGF | a~ | RestrictedGrowthStrings | rank | ||
| RankSetPartition | a~ | SetPartitions | rank (set-partition order differs) | ||
| SetPartitionListViaRGF | a~ | RestrictedGrowthStrings | |||
| SetPartitionQ | a~ | SetPartition | membership | ||
| SetPartitionToRGF | a | RestrictedGrowthString | |||
| SetPartitions | a | SetPartitions | ORDER differs: Combinatorica 123, 1/23, 12/3, 13/2, 1/2/3; ours 123, 12/3, 13/2, 1/23, 1/2/3 | ||
| ToCanonicalSetPartition | a~ | SetPartition | |||
| UnrankKSetPartition | a~ | SetPartitionsIntoKBlocks | unrank | ||
| UnrankRGF | a~ | RestrictedGrowthStrings | unrank | ||
| UnrankSetPartition | a~ | SetPartitions | unrank | ||
| CoarserSetPartitionQ | c | refinement order on set partitions |
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| AcyclicQ | a | IsAcyclicGraph | AcyclicGraphQ | mapped | renamed predicate |
| AllPairsShortestPath | a | GraphDistanceMatrix | GraphDistanceMatrix | mapped | Combinatorica can also return parents (Parent tag); ours distances only |
| BipartiteQ | a | IsBipartiteGraph | BipartiteGraphQ | mapped | |
| CirculantGraph | a | CirculantGraph | CirculantGraph | mapped | |
| CompleteBinaryTree | a | CompleteKaryTree | CompleteKaryTree | mapped | k = 2 |
| CompleteGraph | a | CompleteGraph | CompleteGraph | mapped | |
| CompleteKaryTree | a | CompleteKaryTree | CompleteKaryTree | mapped | |
| CompleteQ | a | IsCompleteGraph | CompleteGraphQ | mapped | |
| ConnectedComponents | a | ConnectedComponents | ConnectedComponents | mapped | |
| ConnectedQ | a | IsConnectedGraph | ConnectedGraphQ | mapped | |
| CubicalGraph | a~ | HypercubeGraph | GraphData | no | HypercubeGraph(3) |
| Cycle | a | CycleGraph | CycleGraph | mapped | |
| DegreeSequence | a† | DegreeSequence | stub record only (LabeledGraph map), no kernel | ||
| Diameter | a | GraphDiameter | GraphDiameter | mapped | |
| Distances | a~ | GraphDistanceMatrix | GraphDistance | mapped | one row of the distance matrix |
| Eccentricity | a | VertexEccentricity | VertexEccentricity | mapped | |
| Edges | a | EdgeList | EdgeList | mapped | |
| ExactRandomGraph | a | RandomGraph | RandomGraph | mapped | RandomGraph[{n, e}] in core |
| FromAdjacencyMatrix | a | AdjacencyGraph | AdjacencyGraph | mapped | |
| FunctionalGraph | a~ | Endofunction | Endofunction is the carrier | ||
| Girth | a† | FindStat St000264, catalog only; no core head | |||
| Graph | a | Graph | Graph | mapped | NAME CLASH: Combinatorica Graph[edges, coords, opts] is a different object from core's Graph |
| GraphCenter | a | GraphCenter | GraphCenter | mapped | |
| GridGraph | a | GridGraph | GridGraph | mapped | |
| Harary | a | HararyGraph | HararyGraph | mapped | |
| Hypercube | a | HypercubeGraph | HypercubeGraph | mapped | |
| IdenticalQ | a~ | Same | SameQ | mapped | compares edge lists |
| InDegree | a | VertexInDegree | VertexInDegree | mapped | |
| IncidenceMatrix | a | IncidenceMatrix | IncidenceMatrix | mapped | |
| InduceSubgraph | a | Subgraph | Subgraph | mapped | |
| IsomorphicQ | a | IsIsomorphicGraph | IsomorphicGraphQ | mapped | |
| LineGraph | a | LineGraph | LineGraph | mapped | |
| M | a | EdgeCount | EdgeCount | mapped | |
| Neighborhood | a~ | NeighborhoodGraph | NeighborhoodGraph | mapped | vertex set vs graph |
| NumberOfSpanningTrees | a† | FindStat St000096, catalog only; core route is KirchhoffMatrix then Det | |||
| OutDegree | a | VertexOutDegree | VertexOutDegree | mapped | |
| PetersenGraph | a | PetersenGraph | PetersenGraph | mapped | |
| PseudographQ | a~ | IsLoopFreeGraph | LoopFreeGraphQ | mapped | negation, roughly |
| Radius | a | GraphRadius | GraphRadius | mapped | |
| RandomGraph | a | RandomGraph | RandomGraph | mapped | |
| SelfLoopsQ | a~ | IsLoopFreeGraph | LoopFreeGraphQ | mapped | negation |
| ShortestPath | a | FindShortestPath | FindShortestPath | mapped | |
| SimpleQ | a | IsSimpleGraph | SimpleGraphQ | mapped | |
| TetrahedralGraph | a~ | CompleteGraph | GraphData | no | CompleteGraph(4) |
| ToAdjacencyMatrix | a | AdjacencyMatrix | AdjacencyMatrix | mapped | |
| ToOrderedPairs | a | EdgeList | EdgeList | mapped | |
| ToUnorderedPairs | a | EdgeList | EdgeList | mapped | |
| Turan | a | TuranGraph | TuranGraph | mapped | |
| V | a | VertexCount | VertexCount | mapped | |
| Wheel | a | WheelGraph | WheelGraph | mapped | |
| AddEdge | b | EdgeAdd | no | ||
| AddEdges | b | EdgeAdd | no | ||
| AddVertex | b | VertexAdd | no | ||
| AddVertices | b | VertexAdd | no | ||
| ArticulationVertices | b~ | KVertexConnectedComponents | no | no direct core head; derive from 2-connected components | |
| Automorphisms | b | GraphAutomorphismGroup | no | ||
| BellmanFord | b | FindShortestPath | mapped | Method "BellmanFord" | |
| BiconnectedComponents | b~ | KVertexConnectedComponents | no | k = 2 | |
| BiconnectedQ | b | KVertexConnectedGraphQ | no | k = 2 | |
| BipartiteMatching | b | FindIndependentEdgeSet | no | unweighted; weighted case needs FindMinimumCostFlow | |
| BreadthFirstTraversal | b | BreadthFirstScan | no | ||
| BrelazColoring | b | FindVertexColoring | no | ||
| Bridges | b~ | KEdgeConnectedComponents | no | no direct core head | |
| ButterflyGraph | b | ButterflyGraph | no | ||
| CageGraph | b~ | GraphData | no | named graph | |
| ChromaticNumber | b | VertexChromaticNumber | no | FindStat St000098 is in our catalog (no kernel) | |
| ChromaticPolynomial | b | ChromaticPolynomial | no | same name; Combinatorica returns a pure function | |
| ChvatalGraph | b~ | GraphData | no | named graph | |
| CliqueQ | b~ | CompleteGraphQ | mapped | test via Subgraph then CompleteGraphQ | |
| CompleteKPartiteGraph | b | CompleteGraph | mapped | multipartite form CompleteGraph[{a,b,c}] | |
| Contract | b | EdgeContract | no | ||
| CoxeterGraph | b~ | GraphData | no | named graph | |
| DeBruijnGraph | b | DeBruijnGraph | no | ||
| Degrees | b | VertexDegree | mapped | ||
| DeleteEdge | b | EdgeDelete | no | ||
| DeleteEdges | b | EdgeDelete | no | ||
| DeleteVertex | b | VertexDelete | no | ||
| DeleteVertices | b | VertexDelete | no | ||
| DepthFirstTraversal | b | DepthFirstScan | no | ||
| Dijkstra | b | FindShortestPath | mapped | ||
| DodecahedralGraph | b~ | GraphData | no | named graph | |
| EdgeColoring | b | FindEdgeColoring | no | ||
| EdgeConnectivity | b | EdgeConnectivity | no | same name | |
| EmptyGraph | b | Graph | mapped | Graph[Range[n], {}] | |
| EmptyQ | b | EmptyGraphQ | no | ||
| EulerianCycle | b | FindEulerianCycle | no | ||
| EulerianQ | b | EulerianGraphQ | no | ||
| FindCycle | b | FindCycle | no | same name, different signature | |
| FolkmanGraph | b~ | GraphData | no | named graph | |
| FranklinGraph | b~ | GraphData | no | named graph | |
| FromAdjacencyLists | b | Graph | mapped | ||
| FromOrderedPairs | b | Graph | mapped | ||
| FromUnorderedPairs | b | Graph | mapped | ||
| FruchtGraph | b~ | GraphData | no | named graph | |
| GeneralizedPetersenGraph | b~ | GraphData | no | named family | |
| GetEdgeLabels | b~ | PropertyValue | no | ||
| GetEdgeWeights | b~ | PropertyValue | no | ||
| GetVertexLabels | b~ | PropertyValue | no | ||
| GetVertexWeights | b~ | PropertyValue | no | ||
| GraphComplement | b | GraphComplement | no | ||
| GraphDifference | b | GraphDifference | no | ||
| GraphIntersection | b | GraphIntersection | no | ||
| GraphJoin | b | GraphJoin | no | ||
| GraphPower | b | GraphPower | no | ||
| GraphProduct | b | GraphProduct | no | ||
| GraphSum | b | GraphSum | no | ||
| GraphUnion | b | GraphUnion | no | ||
| GrayGraph | b~ | GraphData | no | named graph | |
| GroetzschGraph | b~ | GraphData | no | named graph (also misspelled alias GrotztschGraph) | |
| GrotztschGraph | b~ | GraphData | no | alias of GroetzschGraph | |
| HamiltonianCycle | b | FindHamiltonianCycle | no | ||
| HamiltonianPath | b | FindHamiltonianPath | no | ||
| HamiltonianQ | b | HamiltonianGraphQ | no | ||
| HeawoodGraph | b~ | GraphData | no | named graph | |
| HerschelGraph | b~ | GraphData | no | named graph | |
| IcosahedralGraph | b~ | GraphData | no | named graph | |
| IndependentSetQ | b | IndependentVertexSetQ | no | ||
| Isomorphism | b | FindGraphIsomorphism | no | ||
| KnightsTourGraph | b | KnightTourGraph | no | name differs | |
| LeviGraph | b~ | GraphData | no | named graph | |
| ListGraphs | b~ | GraphData | no | ours only has labeled graphs | |
| MakeDirected | b | DirectedGraph | no | ||
| MakeGraph | b | RelationGraph | no | ||
| MakeSimple | b | SimpleGraph | no | ||
| MakeUndirected | b | UndirectedGraph | no | ||
| MaximalMatching | b | FindIndependentEdgeSet | no | ||
| MaximumClique | b | FindClique | no | ||
| MaximumIndependentSet | b | FindIndependentVertexSet | no | ||
| MaximumSpanningTree | b | FindSpanningTree | no | negate weights | |
| McGeeGraph | b~ | GraphData | no | named graph | |
| MeredithGraph | b~ | GraphData | no | named graph | |
| MinimumSpanningTree | b | FindSpanningTree | no | ||
| MinimumVertexColoring | b | FindVertexColoring | no | ||
| MinimumVertexCover | b | FindVertexCover | no | ||
| MultipleEdgesQ | b | MultigraphQ | no | ||
| NetworkFlow | b | FindMaximumFlow | no | ||
| NetworkFlowEdges | b | FindMaximumFlow | no | ||
| OctahedralGraph | b~ | GraphData | no | named graph | |
| PlanarQ | b | PlanarGraphQ | no | ||
| RegularGraph | b~ | DegreeGraphDistribution | no | random k-regular graph | |
| RemoveMultipleEdges | b | SimpleGraph | no | ||
| RemoveSelfLoops | b | SimpleGraph | no | ||
| ReverseEdges | b | ReverseGraph | no | ||
| RobertsonGraph | b~ | GraphData | no | named graph | |
| ShortestPathSpanningTree | b~ | ShortestPathFunction | no | ||
| Spectrum | b~ | Eigenvalues | mapped | of AdjacencyMatrix | |
| StronglyConnectedComponents | b | ConnectedComponents | mapped | core on a directed graph | |
| ToAdjacencyLists | b | AdjacencyList | no | ||
| TopologicalSort | b | TopologicalSort | no | same name | |
| TransitiveClosure | b | TransitiveClosureGraph | no | ||
| TransitiveReduction | b | TransitiveReductionGraph | no | ||
| TravelingSalesman | b | FindShortestTour | no | ||
| TreeIsomorphismQ | b | IsomorphicGraphQ | mapped | ||
| TreeToCertificate | b~ | CanonicalGraph | no | ||
| TutteGraph | b~ | GraphData | no | named graph | |
| TwoColoring | b | FindVertexColoring | no | ||
| UndirectedQ | b | UndirectedGraphQ | no | ||
| UnweightedQ | b | WeightedGraphQ | no | negation | |
| VertexColoring | b | FindVertexColoring | no | ||
| VertexConnectivity | b | VertexConnectivity | no | same name | |
| VertexCover | b | FindVertexCover | no | ||
| VertexCoverQ | b | VertexCoverQ | no | same name | |
| WeaklyConnectedComponents | b | WeaklyConnectedComponents | no | same name | |
| AlternatingPaths | c | matching theory helper | |||
| ApproximateVertexCover | c | 2-approximation; core FindVertexCover is exact | |||
| BipartiteMatchingAndCover | c | König dual | |||
| CostOfPath | c | sum of edge weights along a path, trivial | |||
| CubeConnectedCycle | c | named family | |||
| DegreesOf2Neighborhood | c | ||||
| DeleteCycle | c | ||||
| Equivalences | c | vertex classes by degree | |||
| ExtractCycles | c | maximal edge-disjoint cycles; core only has FindFundamentalCycles | |||
| GraphPolynomial | c | counts nonisomorphic graphs by edges (A008406) | |||
| GraphicQ | c | Erdos-Gallai; Sage has is_graphical | |||
| GreedyVertexCover | c | heuristic | |||
| IntervalGraph | c | ||||
| IsomorphismQ | c | check a given permutation; trivial | |||
| MycielskiGraph | c | ||||
| NoPerfectMatchingGraph | c | named graph | |||
| NonLineGraphs | c | forbidden subgraphs | |||
| NumberOf2Paths | c | matrix power of adjacency | |||
| NumberOfDirectedGraphs | c | A000273 | |||
| NumberOfGraphs | c | A000088 | |||
| NumberOfKPaths | c | ||||
| OddGraph | c | ||||
| OrientGraph | c | strong orientation | |||
| ParentsToPaths | c | ||||
| PerfectQ | c | ||||
| PermuteSubgraph | c | ||||
| RankGraph | c | BFS layering | |||
| RealizeDegreeSequence | c | Havel-Hakimi | |||
| RegularQ | c | trivial | |||
| ResidualFlowGraph | c | ||||
| SelfComplementaryQ | c | ||||
| ShuffleExchangeGraph | c | ||||
| SmallestCyclicGroupGraph | c | ||||
| ThomassenGraph | c | named graph | |||
| TravelingSalesmanBounds | c | ||||
| TriangleInequalityQ | c | ||||
| Uniquely3ColorableGraph | c | named graph | |||
| UnitransitiveGraph | c | named graph | |||
| VertexConnectivityGraph | c | ||||
| WaltherGraph | c | named graph |
d-draw: AnimateGraph, CircularEmbedding, CircularVertices, DilateVertices, EdgeColor, EdgeLabel, EdgeLabelColor, EdgeLabelPosition, EdgeStyle, Highlight, HighlightedEdgeColors, HighlightedEdgeStyle, HighlightedVertexColors, HighlightedVertexStyle, LoopPosition, LowerLeft, LowerRight, NormalDashed, NormalizeVertices, RadialEmbedding, RandomVertices, RankedEmbedding, RootedEmbedding, RotateVertices, ShakeGraph, ShowGraph, ShowGraphArray, ShowLabeledGraph, SpringEmbedding, ThickDashed, ThinDashed, TranslateVertices, UpperLeft, UpperRight, VertexColor, VertexLabel, VertexLabelColor, VertexLabelPosition, VertexNumber, VertexNumberColor, VertexNumberPosition, VertexStyle, Vertices, Zoom
d-io: ReadGraph, WriteGraph
d-opt: EdgeWeight, Invariants, VertexWeight
d-rep: ChangeEdges, ChangeVertices, ExpandGraph, FiniteGraphs, GraphOptions, PathConditionGraph, PointsAndLines, SetEdgeLabels, SetEdgeWeights, SetGraphOptions, SetVertexLabels, SetVertexWeights
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| BooleanAlgebra | a | BooleanLattice | Hasse diagram of subsets of [n] | ||
| HasseDiagram | b | TransitiveReductionGraph | no | ||
| SymmetricQ | b | SymmetricMatrixQ | no | ||
| AntiSymmetricQ | c | relation predicate on a matrix | |||
| DominationLattice | c | dominance lattice on partitions of n | |||
| EquivalenceRelationQ | c | relation predicate | |||
| InversionPoset | c | weak order on S_n | |||
| MaximumAntichain | c | Dilworth side | |||
| MinimumChainPartition | c | Dilworth side | |||
| PartialOrderQ | c | relation predicate | |||
| PartitionLattice | c | refinement order on set partitions | |||
| ReflexiveQ | c | relation predicate | |||
| TransitiveQ | c | relation predicate |
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| AlternatingGroup | a | AlternatingGroup | AlternatingGroup | mapped | Combinatorica returns the element list; ours is a group object |
| CycleStructure | a~ | CycleType | CycleType gives the partition; the monomial is a one-liner | ||
| CyclicGroup | a | CyclicGroup | CyclicGroup | mapped | |
| DihedralGroup | a | DihedralGroup | DihedralGroup | mapped | |
| SymmetricGroup | a | SymmetricGroup | SymmetricGroup | mapped | |
| AlternatingGroupIndex | b | CycleIndexPolynomial | no | see CycleIndex | |
| CycleIndex | b | CycleIndexPolynomial | no | on roadmap with species / plethysm | |
| CyclicGroupIndex | b | CycleIndexPolynomial | no | ||
| DihedralGroupIndex | b | CycleIndexPolynomial | no | ||
| MultiplicationTable | b | GroupMultiplicationTable | no | general table of a binary op is Outer; ours MultiplicationTable is the Z/m ring table | |
| OrbitRepresentatives | b~ | GroupOrbits | no | ||
| Orbits | b | GroupOrbits | no | ||
| SymmetricGroupIndex | b | CycleIndexPolynomial | no | ||
| KSubsetGroup | c | induced action on k-subsets | |||
| KSubsetGroupIndex | c | ||||
| NecklacePolynomial | c | Pólya counting polynomial | |||
| OrbitInventory | c | Pólya substitution into a cycle index | |||
| PairGroup | c | induced action on 2-sets | |||
| PairGroupIndex | c | ||||
| PermutationGroupQ | c | ||||
| Polya | c | Pólya count with m colors | |||
| SamenessRelation | c |
d-opt: Dihedral
| Name | Class | Ours | Core | Crosswalk | Note |
|---|---|---|---|---|---|
| CodeToLabeledTree | a~ | PruferSequence, LabeledTree | carriers exist, no named conversion map | ||
| LabeledTreeToCode | a~ | PruferSequence, LabeledTree | carriers exist, no named conversion map | ||
| Strings | a | Tuples | Tuples | mapped | |
| Cofactor | b~ | Minors | no | ||
| DeBruijnSequence | b | DeBruijnSequence | no | ||
| Distribution | b | Tally | no | ||
| EquivalenceClasses | b~ | ConnectedComponents | mapped | of the relation graph | |
| HeapSort | b | Sort | mapped | algorithm choice not math | |
| SelectionSort | b | Sort | mapped | algorithm choice not math | |
| Backtrack | c | generic search driver, not math | |||
| BinarySearch | c | list utility, not math | |||
| FindSet | c | union-find structure | |||
| Heapify | c | data structure | |||
| InitializeUnionFind | c | union-find structure | |||
| NthPair | c | pairing enumeration | |||
| RandomHeap | c | data structure | |||
| StableMarriage | c | Gale-Shapley | |||
| UnionSet | c | union-find structure |
d-opt: Algorithm, Approximate, Brelaz, Cut, Directed, Edge, EdgeDirection, Euclidean, Greedy, LNorm, NoMultipleEdges, NoSelfLoops, One, Optimum, Ordered, Parent, Simple, Strong, Type, Undirected, Value, Weak, WeightRange, WeightingFunction
Ranked by usefulness to enumeratio (combinatorial math, evaluation, oracles). Only class c, plus the a† rows where FindStat already hands us a spec and sample data. "Backlog" is a grep of .git/lanes/BACKLOG.md, the wiki drafts (Roadmap, Legacy-Port) and the lane log.
| # | Gap | Why | Overlap |
|---|---|---|---|
| 1 | TransposePartition (conjugate partition) [a†] | Fundamental map on partitions; our stats (ConjugateOddParts, IsSelfConjugate, LegOfFirstCell) already conjugate inline, FindStat Mp00044 gives samples. A named map makes them compose and unlocks Conjugate laws. |
BL-200/BL-204 (FindStat objects, map laws) touch it; no item for this map. |
| 2 | Eulerian | Eulerian numbers A(n,k) (A008292) are not in core; closed form plus the Descents distribution we already have. Combinatorica's usage string says "runs" but k counts descents (k = 0 for the identity); watch that when writing the example. |
none |
| 3 | NumberOfPermutationsByInversions | Mahonian numbers (A008302), the Inversions distribution and q-factorial coefficients; pairs with Inversions/MajorIndex equidistribution already stated on the Inversions page. |
none |
| 4 | Polya, NecklacePolynomial, OrbitInventory, PairGroup(+Index), KSubsetGroup(+Index) | Group-action counting over the groups we already carry (SymmetricGroup, PermutationGroup, KNecklaces, KBracelets). Core has only CycleIndexPolynomial (class b, no head of ours yet). Oracle-checkable in Oscar/GAP and Sage. |
Roadmap: "Combinatorial species ... cycle-index/plethysm machinery" (Legacy-Port §3) overlaps; do these as readings, not a separate stack. |
| 5 | DominatingIntegerPartitionQ, DominationLattice | Dominance order is the standard order on partitions (Gale-Ryser, symmetric functions, majorization). Cheap predicate, then the lattice via incidence. |
Roadmap lists majorization (Rado) containment under polytope guide content; no head. |
| 6 | PartitionLattice, CoarserSetPartitionQ, InversionPoset (weak order) | Natural clients of @enumeratio/incidence (zeta, Möbius): the partition lattice has Möbius value (-1)^(n-1)(n-1)!, a free correctness test. Weak order pairs with Inversions. |
Legacy-Port §2 open question on poset Hasse vs 1-skeleton. |
| 7 | DeleteFromTableau, and TableauxToPermutation [a†] | Completes the RSK bijection (inverse RSK is a stub ToPermutation today). Combinatorica's ConstructTableau and PermutationToTableaux already agree with our RskInsertion/Rsk. |
BL-204 map laws would test it as an inverse pair. |
| 8 | GraphicQ, RealizeDegreeSequence | Erdos-Gallai and Havel-Hakimi; core has neither. Sage has is_graphical, so oracle-checkable. Fits the LabeledGraph DegreeSequence stub. |
none |
| 9 | Girth, NumberOfSpanningTrees, DegreeSequence [a†] | FindStat St000264, St000096 and the degree-sequence map already specified; Girth has no core head, spanning trees need KirchhoffMatrix then Det in core. |
BL-200 (FindStat object readers) is the vehicle. |
| 10 | MinimumChangePermutations, GrayCodeKSubsets, LexicographicSubsets (+NextLexicographicSubset) | New orders on families we have (Steinhaus-Johnson-Trotter, revolving door, pure lex). The design treats order as first-class, so each is a family with its own rank/unrank. | BL-70 and BL-75 are about rank/unrank cost, not these orders. |
| 11 | Generic successor/predecessor (Next*, 9 names) [design, a~ today] | One Next(F, x) over a family's order would replace nine heads; At(F, IndexOf(F, x) + 1) already does it with wraparound semantics matching Combinatorica's. |
none; ties to the BL-202 "no head per statistic/map" stance. |
| 12 | PermutationGraph, IntervalGraph, PerfectQ, MycielskiGraph, NumberOfGraphs/NumberOfDirectedGraphs/GraphPolynomial | Graph counts (A000088, A000273) and families; need unlabeled enumeration. Sage/nauty can cross-check. Lower value than the permutation/partition items above. | none; LabeledGraph stats are FindStat-only |
| 13 | Relation predicates: ReflexiveQ, AntiSymmetricQ, TransitiveQ, PartialOrderQ, EquivalenceRelationQ (core has SymmetricMatrixQ) |
Trivial, but belong with the Element-Relations design rather than as eight heads. | Legacy-Port §2 / wiki Element-Relations |
| 14 | EncroachingListSet, Josephus, StableMarriage, NthPair | Patience-sorting piles (LIS, Greene's theorem), the Josephus permutation (A054995), Gale-Shapley, pair enumeration. Fun and small; none block anything. | none |
| 15 | Skip: Backtrack, Heapify, RandomHeap, BinarySearch, union-find (FindSet, UnionSet, InitializeUnionFind), graph-algorithm odds and ends (AlternatingPaths, ResidualFlowGraph, ...) | Algorithm plumbing, not math; or core already covers the headline version (class b). | - |
Graph algorithms are the big class-b block (about 100 names). Core Wolfram has them under different names (FindHamiltonianCycle, FindVertexCover, FindGraphIsomorphism, ...). The right move there is transpiler/oracle mappings when we declare graph heads, not reimplementation; today we declare only constructors, distances and a few predicates.
Design §3.2: no head per statistic or map, except where it obviously merits one; the exception criterion is that compute-engine or Wolfram's current language names it, and whether Combinatorica counts is open (§4.3).
Finding that changes the question: Combinatorica names far fewer of our statistics than the wiki assumes. Of the 38 permutation statistics we declare, it names five (two of them clashing, two under other spellings). Only Inversions and DurfeeSquare are same-spelling, same-meaning.
| Combinatorica | Carrier | Ours | Same name? | Same meaning? | Core Wolfram | Head if core only | Head if core + Combinatorica |
|---|---|---|---|---|---|---|---|
| Inversions | Permutation |
Inversions (stat, declared head) |
yes | yes (pairs i<j, p_i>p_j) | none | no | yes (only reading that gives it a head) |
| Index | Permutation | MajorIndex |
no | yes (sum of 1-based descent positions; checked: Index[{3,1,2,5,4}] = 5) | none | no | no: spelling differs, at most an alias |
| Runs | Permutation |
Runs (count) |
yes |
no: list of runs vs count (DescentComposition gives the lengths) |
none (Split groups runs) |
no | no: clash; a head named Runs would have to return the list |
| SignaturePermutation | Permutation | Sign |
no | yes |
Signature (also 0 for repeats) |
yes: rename or add Signature
|
same |
| LongestIncreasingSubsequence | Permutation |
LongestIncreasingSubsequence (length) |
yes | no: returns the subsequence |
LongestOrderedSequence (subsequence) |
head for the subsequence, not the length | same |
| PermutationType | Permutation |
CycleType (partition) |
no | representation differs (multiplicity vector vs partition) | none | no | no |
| ToCycles / CycleStructure | Permutation |
CycleDecomposition, PermutationCycles, CycleType
|
no | start-of-cycle convention differs | PermutationCycles |
already a head | already a head |
| ToInversionVector / FromInversionVector | Permutation |
ToLehmerCode (+ inverse) |
no | no: by value, length n-1 vs by position, length n | none | no | no |
| InversePermutation | Permutation | InversePermutation |
yes | yes | InversePermutation |
already a head | already a head |
| HideCycles / RevealCycles | Permutation | Foata |
no | variant (minima, decreasing vs maxima, increasing) | none | no | no |
| ConstructTableau, PermutationToTableaux | Permutation to tableaux |
RskInsertion, Rsk
|
no | yes | none | no | no |
| DerangementQ, InvolutionQ | Permutation | membership in Derangements/Involutions; FixedPoints
|
no | yes | none | no | no |
| Eulerian, NumberOfPermutationsBy{Cycles,Inversions,Type} | Permutation |
StirlingS1 (signed), none, FindStat St000182 |
no | distribution counts, not statistics | none | no | no (these are counts) |
| DurfeeSquare | IntegerPartition |
DurfeeSquare (stat) |
yes | yes | none | no | yes |
| NumberOfTableaux | IntegerPartition |
Count(StandardTableaux(λ)), HookProduct
|
no | yes | none | no | no |
| TransposePartition / TransposeTableau | IntegerPartition / tableau | FindStat Mp00044 / Mp00084 only | no | yes | none | no | no |
| SetPartitionToRGF, RGFToSetPartition | SetPartition |
RestrictedGrowthString, SetPartition
|
no | yes | none | no | no |
| Girth, Diameter, Radius, Eccentricity, ChromaticNumber, NumberOfSpanningTrees, DegreeSequence, M, V | Graph | FindStat only (St000264, St000259, St000260, St000098, St000096); GraphDiameter etc. declared |
partly | yes |
GraphDiameter, GraphRadius, VertexEccentricity, VertexChromaticNumber, EdgeCount, VertexCount; none for Girth |
core names, not Combinatorica's | same |
Core semantics checked in wolframscript on Cycles[{{1,3,2},{5,6}}] and lists.
| Core head | Meaning (checked) | Ours today | Head merited (core only) | Head merited (core + Combinatorica) |
|---|---|---|---|---|
| PermutationOrder | lcm of cycle lengths (6 for (1 3 2)(5 6)) |
Order (stat). Bare Order is also a System name: Order[a,b], a canonical-order comparator |
yes: add/alias PermutationOrder, which resolves the Order collision |
same (Combinatorica adds nothing) |
| PermutationLength | number of integers moved (5 for the example; fixed points listed in a cycle do not count) | none; CycleCount, ReflectionLength, FixedPoints are different |
yes, and it is a new statistic | same |
| PermutationSupport | sorted list of moved integers | none (list-valued, so a map to Finset, not a statistic) |
yes (map) | same |
| PermutationMax / PermutationMin | largest / smallest moved integer (6 and 1) | none | yes (new) | same |
| Signature | +1 / -1; 0 on repeated entries ({1,1} gives 0) |
Sign (stat on Permutation, +/-1 only). Numeric Sign is a CE head and a System name |
yes: Signature; settles the open Sign question in §3.2 of the wiki by moving to the core spelling |
same (SignaturePermutation is not the spelling) |
| PermutationCycles / PermutationList / PermutationReplace / Permute / InversePermutation / Cycles | as documented | all present (groupalgebra; PermutationCycles, PermutationList, PermutationReplace in the crosswalk) |
already heads | same |
| PermutationProduct / PermutationPower | product applies the left factor first: with (1 2) then (2 3), 1 maps to 3 | none: no public head for composing permutations | yes (new, and the convention is the point) | same |
| PermutationMatrix, FindPermutation, PermutationGroup, PermutationCyclesQ, PermutationListQ, RandomPermutation, LongestOrderedSequence | as documented |
PermutationGroup present; the rest absent |
heads for completeness, not statistics | same |
Lean: Combinatorica should not count as a criterion, only as a tiebreaker. Reasons: it is superseded (loading it prints General::compat and shadows 41 System names, so a user cannot mix it with core in one session); its names are inconsistent with core (Index, SignaturePermutation, PermutationType); its documentation misstates behavior in places (the Eulerian usage string says runs; Names shows no Descents); and its two same-spelling matches (Inversions, DurfeeSquare) are exactly the cases where we would keep the bare head anyway because the name is the obvious one. Proposed reading: a statistic or map gets a head if core Wolfram names it, or if Combinatorica (or compute-engine) uses the identical spelling for the identical meaning and core does not use that spelling for something else. That keeps Inversions and DurfeeSquare, rejects Index (spelling), Runs and LongestIncreasingSubsequence (meaning), and leaves Descents/Ascents/MajorIndex as Statistic(p, "Descents") cases, since Combinatorica never named them. Net effect on the 84 stats: heads for Inversions and DurfeeSquare by the Combinatorica tiebreaker, PermutationOrder, Signature by core, and four new core heads (PermutationLength/Support/Max/Min) plus PermutationProduct/Power.
Wolfram side from wolframscript (Combinatorica loaded unless stated); our side from reference examples, the ranking-and-unranking.md doc and source comments. Conventions that differ are marked DIFF.
| # | Check | Combinatorica result | Core Wolfram | Ours | Verdict |
|---|---|---|---|---|---|
| 1 | Permute (composition order) |
Permute[{a,b,c},{2,3,1}] = {b,c,a} (lp) |
Permute[{a,b,c},{2,3,1}] = {c,a,b} (item i goes to position p[i]); same with Cycles[{{1,2,3}}]
|
Permute([a,b,c,d],[2,3,4,1]) = {d,a,b,c}; Permute([a,b,c,d,k],[3,1,2]) = {b,c,a,d,k}
|
DIFF: Combinatorica is the inverse of core and ours (ours matches core) |
| 2 | Inversions |
Inversions[{3,1,2}] = 2, {2,3,1} = 2 (pairs i<j, p_i>p_j) |
none |
Inversions([3,1,2]) = 2; summary: pairs ip_j
|
agree |
| 3 | Index vs MajorIndex |
Index[{3,1,2,5,4}] = 5 (1-based descent positions 1 and 4) |
none |
MajorIndex: "sum of the descent positions" with p_i > p_{i+1}, 1-based |
agree (name differs) |
| 4 | Runs |
Runs[{1,3,2,4}] = {{1,3},{2,4}}; only defined on permutations (unevaluated on {1,3,2,4,0}) |
no Runs in System
|
Runs([3,1,2]) = 2 (count, = descents + 1) |
DIFF: list vs count |
| 5 | RankPermutation / UnrankPermutation / NthPermutation |
RankPermutation[{1,2,3}] = 0, {3,2,1} = 5, {1,3,2} = 1; UnrankPermutation[r,3] for r = 0..5 is the lex list; NthPermutation[1,{1,2,3}] = {1,3,2} and NthPermutation[6,{1,2,3}] = identity (wraps) |
no rank/unrank |
At(F, k) is 1-based unrank and wraps (ranking-and-unranking.md); rank kernels are per-family, positions bigint; SymmetricGroup(n) is lexicographic |
DIFF: 0-based vs 1-based; wraparound agrees |
| 6 | NextPermutation |
{1,3,2} gives {2,1,3}; {3,2,1} wraps to {1,2,3}
|
none | no head; successor is At(F, rank+1)
|
agree on order; wrap is Combinatorica's explicit behavior |
| 7 | Partitions[n,k] |
Partitions[5,2] = {{2,2,1},{2,1,1,1},{1,1,1,1,1}}: largest part <= k; Partitions[4] = {4},{3,1},{2,2},{2,1,1},{1,1,1,1}
|
IntegerPartitions[5,2] = parts at most 2 in number ({5},{4,1},{3,2}); IntegerPartitions[5,{2}] = {4,1},{3,2}
|
IntegerPartitions(8, 3) = at most 3 parts (core semantics); reverse lex like core |
DIFF on the second argument (conjugate); order agrees |
| 8 | Compositions[n,k] |
Compositions[4,2] = {0,4},{1,3},{2,2},{3,1},{4,0} (zeros allowed); NumberOfCompositions[4,2] = 5 |
none |
Compositions(n) = all positive compositions; CompositionsIntoKParts positive; WeakCompositions(2,2) first three = {0,2},{1,1},{2,0}
|
DIFF: Combinatorica's Compositions[n,k] is our WeakCompositions
|
| 9 | KSubsets / Subsets order |
KSubsets[Range[5],2] starts {1,2},{1,3},{1,4},{1,5},{2,3} (lex); RankKSubset[{1,3},Range[5]] = 1 (0-based); LexicographicSubsets[3] = {},{1},{1,2},{1,2,3},{1,3},{2},{2,3},{3} (pure lex) |
Subsets[Range[3]] graded: {},{1},{2},{3},{1,2},...
|
Subsets is size then lex (#576); KSubsets lex (code, example) though its summary and docs say colex |
agree with core; Combinatorica's Subsets canonical order is also graded (NthSubset[3] = {3}); only its LexicographicSubsets is pure lex |
| 10 | SetPartitions order |
SetPartitions[3]: 123, 1/23, 12/3, 13/2, 1/2/3; RankSetPartition[{{1,2},{3}},{1,2,3}] = 2 |
none |
SetPartitions([a,b,c]): abc, ab/c, ac/b, a/bc, a/b/c |
DIFF: order differs |
| 11 | StirlingFirst vs StirlingS1 |
StirlingFirst[4,k] = 6, 11, 6, 1 (unsigned) |
StirlingS1[4,k] = -6, 11, -6, 1 (signed) |
StirlingS1(5,2) = -50 (signed); Stirling = second kind |
DIFF from Combinatorica; agrees with core |
| 12 | ToInversionVector |
{3,1,2} gives {1,1}, {2,3,1} gives {2,0} (by value: how many larger entries sit to its left; length n-1) |
none |
ToLehmerCode([2,3,1]) = [1,1,0] (by position: later smaller entries; length n) |
DIFF: different table, different length |
| 13 | ToCycles / cycle form |
ToCycles[{3,1,2,5,4,6}] = {{3,2,1},{5,4},{6}} (each cycle starts at the image of its least point; fixed points kept) |
PermutationCycles = Cycles[{{1,3,2},{5,6}}]-style (from least point, fixed points dropped) |
CycleDecomposition keeps fixed points, cycle from its least point; PermutationCycles/Cycles as core |
DIFF in rotation; same cyclic structure |
| 14 | SignaturePermutation |
{2,3,1} gives 1, {2,1,3} gives -1 |
Signature same, 0 on repeats |
Sign on Permutation |
agree |
| 15 | LongestIncreasingSubsequence |
{3,1,4,2,5} gives {1,2,5} (a subsequence) |
LongestOrderedSequence gives {1,2,5}
|
length ([3,1,2] gives 2) |
DIFF: return type |
| 16 | PermutationType |
{3,1,2,5,4,6} gives {1,1,1,0,0,0} (cycles of each length) |
none |
CycleType([2,3,1]) = partition [3]
|
DIFF: representation |
| 17 | Eulerian[n,k] |
Eulerian[4,k] for k = 0..3 gives 1, 11, 11, 1 (k = descents, 0-based despite the "runs" usage string) |
none | not declared; derivable from Descents tallies |
gap |
| 18 | Derangements / Involutions |
Derangements[{1,2,3}] = {2,3,1},{3,1,2}; Involutions[3] = {2,1,3},{3,2,1},{1,3,2},{1,2,3} (identity last) |
none |
Derangements(n), Involutions(n) take n; counts 9 and 10 for n = 4 |
argument form differs; Involutions order differs from lex |
| 19 | HideCycles |
HideCycles[{{1,3,2},{4,5}}] = {4,5,1,3,2}
|
none |
Foata([2,3,1]) = [3,1,2] (cycles to their max, increasing max) |
DIFF: the min/decreasing variant |
Permutation composition has no Combinatorica name beyond Permute (and MultiplicationTable[perms, Permute]). Core PermutationProduct applies the left factor first. We have no public product head, so the convention is still ours to choose; matching core is the lean.
Lean: yes, as a separate narrow system combinatorica (about 40 heads), low priority; no as a general-purpose oracle.
What it adds beyond the wired systems (Wolfram, Sage, Oscar, Julia Combinatorics.jl, Mathlib): a second Wolfram-family opinion for heads core Wolfram lacks. Candidates, all class a/a~ above with no core head: Inversions, MajorIndex (Index), Derangements, Involutions, SetPartitions/SetPartitionsIntoKBlocks, RestrictedGrowthStrings and the RGF maps, Rsk/RskInsertion, DurfeeSquare, WeakCompositions, GrayCodeSubsets, KNecklaces/KBracelets (cyclic and dihedral), ToLehmerCode, CycleType, Foata (variant), PruferSequence, StandardTableaux counts, plus any future Eulerian, Polya, NecklacePolynomial, partition-lattice heads. Sage already covers most of these and is the stronger combinatorics oracle, so the realistic gain is cross-checking conventions on exactly the places this audit found they diverge (ranks, orders, Permute) and being the only Wolfram-language source for the counting heads we have not written.
Why a separate system, not a prelude on wolfram: loading Combinatorica puts Combinatorica`` first on $ContextPathand shadows 41System names (Graph, CompleteGraph, Cycles, Permute, InversePermutation, GraphJoin, ...), prints General::compatplus::shdw messages, and fails to redefine two protected symbols (EdgeChromaticNumber, TreeQ). Running it in the wolframlane would silently change core results. It must be its ownwolframscript` process.
Mechanics checked: wolframBatchCode hands each item to ToExpression as a string, so after a preamble Quiet[Needs["Combinatorica"]];unqualified names in the item strings resolve to Combinatorica (checked:{Inversions[{3,1,2}], Index[...], Runs[...], Eulerian[4,2]}andContext[Inversions]giveCombinatorica). The outer batch code is parsed before `Needs` runs, but it only creates helper symbols (`tex`, `atoms`, `k`), so there is no `Global pollution of item names. Cold start plus load is about 5 s; one load per batch.
What wiring takes (files under packages/oracle and packages/reference):
-
oracle/src/systems.ts: add"combinatorica"toSystemandSYSTEMS(label,wired: true, strength).SYMBOLIC_SYSTEMSstays unchanged (or add it; it evaluates symbolically). -
oracle/src/run.ts: arunIncase that reusesrunWolframwith theNeedspreamble and thewolframscriptbinary (about 20-30 lines);collectWolframand the FullForm compare path apply unchanged. Honor the 2-kernel license limit by not running it concurrently with the wolfram lane. -
oracle/kernels.json: pin the Combinatorica version (it ships inside the Wolfram install, so the Wolfram version string is the pin). - Mapping rows:
form: combinatoricabindings with templates in each head's record (oracle/src/mapping-rows.tsturnsorigin: mappedbindings intoemitrows). About 40 heads, one binding each, with adapter templates where conventions differ (RankPermutation[$1] + 1,Permuteinverse,Compositions[n,k]forWeakCompositions, thePartitions[n,k]conjugate). Thenotefield is the place to record the DIFF rows of §4. -
reference:CrosswalkSystemincrosswalk/sources.ts,examples.values.combinatorica.tsvwriters inoracle-scan.tsandcollect-oracle-agreements.ts, the--systemselection, and a docs chip. These enumeratewiredSystems()already, so mostly type-level changes. - A few emit tests (
oracle/tests/emit.test.ts) for the adapter templates, and onecollect-*pass to regenerate mappings/crosswalk data.
Rough size: 1-2 days for one person: about 300-500 lines including the 40 binding rows and tests, then a scan of roughly 300 examples (minutes of wall time, one kernel). A cheaper stopgap, half a day: no new system; add known + source: Combinatorica cites to the examples where it is the only Wolfram-family source, produced by a one-off script. Do it after BL-202 settles which statistic heads exist, since that changes which heads need bindings.
Risks: the package is legacy and documentation is not always accurate (the Eulerian usage string, Runs accepting only valid permutations), so every disagreement is as likely to be Combinatorica's convention as our bug; each needs the usual triage (emit/compare/ours/convention). Its graph half is not worth wiring: core Wolfram covers the algorithms, and the Graph object shape differs.
- Names:
names.json(456). Classification was done by hand against the usage strings, then every Ours name checked against declared names, record folders,ALL_STATISTICSand map names, and every Core name againstsystem-names.ts, by script; zero misses. -
a~rows are a judgment: the family or membership exists, but a dedicated head does not. Rank/unrank/Next rows area~because each lazy family carries rank/unrank kernels (collections/src/families/types.ts) andAtis the 1-based unrank; the user-facing rank direction (IndexOf/Positionon lazy families) was not exercised since the engine was not run. -
SetPartitions(n)order is taken from the explicit-list reference example (SetPartitions([a,b,c])) and theSetPartitions(3,2)example. -
DerangementsandInvolutionsorder on our side was not checked (counts only). - About a dozen
wolframscriptcalls were used, one at a time. No repo file was changed; scratch files live next to this report.