package tsort
All checked builds passInstall
dune-project
Dependency
Authors
Maintainers
Sources
md5=efe0d2a972638bd07a65b30fed372ed2
sha512=162fbeff69a34f00439570f5fbe3112f2ef6d9cf423a9a3c6a7ad1707cc35b6cb19e0bfa1e70c35c12b8a7adfc70a5aca5a43bef63c7f63aca53b396277019b8
Description
Easy to use and user-friendly topological sort.
Example:
Tsort.sort [("foundation", []); ("walls", ["foundation"]); ("roof", ["walls"])]
Added to opam-repository:
README
ocaml-tsort 
ocaml-tsort is a library for sorting graphs in topological order. Its UI/UX is inspired by the classic UNIX tsort(1).
- Uses Kahn's algorithm.
- Easy to use, but not very fast.
- Provides friendly error reporting (e.g., if there's a cycle, tells you what the offending nodes are).
The input type is (('a * 'a list) list). Essentially, a list of "tasks" mapped to lists of their dependencies.
Sorting DAGs
Most of the time cyclic dependencies are bad. The main function, Tsort.sort returns value of this type:
type 'a sort_result =
Sorted of 'a list
| ErrorCycle of 'a listThe function is:
val sort : ('a * 'a list) list -> 'a sort_resultExamples:
# Tsort.sort [
("foundation", []);
("walls", ["foundation"]);
("roof", ["walls"])
] ;;
- : string Tsort.sort_result = Tsort.Sorted ["foundation"; "walls"; "roof"]
# Tsort.sort [
("foundation", ["building permit"]);
("walls", ["foundation"]);
("roof", ["walls"])
] ;;
- : string Tsort.sort_result =
Tsort.Sorted ["building permit"; "foundation"; "walls"; "roof"]
# Tsort.sort [
("foundation", ["roof"]);
("walls", ["foundation"]);
("roof", ["walls"])
] ;;
- : string Tsort.sort_result = Tsort.ErrorCycle ["roof"; "foundation"; "walls"]As you can see from the second example, if there's a dependency on a node that doesn't exist in the input, it's automatically inserted, and assumed to have no dependencies.
Detecting non-existent dependencies
If your graph comes directly from user input, there's a good chance that dependency on a non-existent node is a user error.
To prevent it, use Tsort.find_nonexistent_nodes. Example:
# Tsort.find_nonexistent_nodes [
("foundation", ["building permit"]);
("walls", ["foundation"]);
("roof", ["walls"])] ;;
- : (string * string list) list = [("foundation", ["building permit"])]Sorting graphs with cycles
Sometimes cycles are fine. In this case you can use Tsort.sort_strongly_connected_components to split your graph into strongly connected components and sort its condensation.
Contrived example: suppose you want to line up the Addams family so that children come after parents, but spouse and sibling pairs are not separated.
Tsort.sort_strongly_connected_components [
"Morticia", ["Gomez"; "Grandmama"];
"Gomez", ["Morticia"; "Grandmama"];
"Wednesday", ["Morticia"; "Gomez"; "Pugsley"];
"Pugsley", ["Morticia"; "Gomez"; "Wednesday"];
"Grandmama", [];
"Fester", []
]
;;
- : string list list =
[["Fester"]; ["Grandmama"]; ["Morticia"; "Gomez"]; ["Wednesday"; "Pugsley"]]There's also Tsort.find_strongly_connected_components if you just want to find what them. For the data above, it would return [["Morticia"; "Gomez"]; ["Wednesday"; "Pugsley"]; ["Grandmama"]; ["Fester"]].
Contributing
To run our complete test suite, run make test-complete (requires docker).
Dev Dependencies (1)
-
alcotest
with-test
Optional Dependencies
None
Used by (5)
- dkml-install
-
dscheck
>= "0.2.0" & < "0.6.0" -
sihl
>= "1.0.0~rc3" - soteria
-
soupault
>= "1.12.0"
Conflicts
None
Build status
Results of building tsort with each compiler on check.ci.ocaml.org, run of against opam-repository 7cdc698. All results for this package.
Each result links to its build log. To keep crawlers from overloading the site, build logs require a GitHub sign-in (see ocurrent/opam-health-check). On your first log, GitHub asks you to “Authorize opam-health-check”, the OCurrent app that runs these checks; it sees only your public profile, not your repositories. The sign-in lasts 30 days.
| Version | OCaml 4.11 | OCaml 4.14 | OCaml 5.2 | OCaml 5.4 | OCaml 5.5 |
|---|---|---|---|---|---|
| 2.2.0 (this version) | good | good | good | good | good |
- good Package successfully built
- partial One of the dependencies failed to build
- bad Package failed to build
- n/a Package is not available in this environment
- internal Internal failure