Notable changes to State-space. Earlier releases are described in the GitHub release notes.
The public API was redesigned around three rules: a function has one kind of result, each thing is said in one way, and a mistake fails where it is made. Almost every change below breaks code written for 0.5.0; the table at the end maps old spellings to new ones.
state-space.trace offers dfs,
postorder, bfs, and best-first with the arguments of the searches in
state-space.core, returning events. The :events? option is gone, so the
functions in state-space.core always return visits (or, for propagate,
progress records).{:event :start|:edge|:enter|:exit ...}.
:start and :edge events carry :accepted? and, when rejected, a
:reason (:already-visited, :on-path, or :not-better). The nested
:phase, the :candidate/:origin/:disposition/:effect vocabulary,
and the :expand and :skip phases are gone. A best-first candidate that
displaces a pending one reports it under :replaced. Breadth-first
duplicates are now reported as rejected edges, like depth-first ones.
In depth-first traces, an edge back to a visit that is still being explored
has the reason :on-path, which tells a cycle from a repeat.
propagate has no event form: its progress records already are its trace.:dedupe chooses the deduplication policy on every search: :search
(default, each key once), :path (each key once per route), or :none.
It replaces simple-paths, :visit-key nil, and :visit-order.
:visit-key is now always a function.postorder is the only way to ask for post-order. dfs no longer
accepts :visit-order.best-first no longer treats :priority :distance specially. Without
:priority, visits carry :distance and are ordered by it, plus
:heuristic when given. With :priority, the search orders by your
function and adds nothing. A nil priority throws instead of silently
ordering first-in, first-out.propagate takes its join as an argument and no :bottom:
(propagate space initial-values join), with options as an optional
fourth argument. A state reached for the first time takes the contribution
as its value; the join combines later ones.path, depth, trail, distance.:transition
instead of :via, and :on-path? instead of :back-edge.ExceptionInfo whose data name the :function and the :option or
:argument at fault. Previously unused options were ignored. nil
uniformly means "use the default".best-first rejects weights its default order cannot handle. A
transition whose :weight is negative or not a number throws when the
search meets it, as does a :heuristic that does not return a number.
A custom :priority is not restricted.:decode-edge result without
:state, an extension or :descend callback that returns something other
than a map or replaces :state, and visit fields that collide with a
fold's :value, :transition, or :on-path? throw instead of corrupting the
search.:decode-edge accepts a vector of field names for successors that are
tuples: [:state :weight] reads [:b 5] as {:state :b :weight 5}.:heuristic on best-first for A* search.:dedupe :path and :none on bfs and best-first: simple paths in
order of length, and routes ranked from cheapest to most expensive.:dedupe :path and :none evaluate each occurrence on its
own, without retaining results; under :path, an edge back to the current
route arrives with :on-path? true.| 0.5.0 | Now |
|---|---|
ss/path-extension, ss/depth-extension, ss/trail-extension, ss/distance-extension | ss/path, ss/depth, ss/trail, ss/distance |
(ss/simple-paths space starts opts) | (ss/dfs space starts (assoc opts :dedupe :path)) |
{:visit-key nil} | {:dedupe :none} |
(ss/dfs ... {:visit-order :postorder}) | (ss/postorder ...) |
(ss/simple-paths ... {:visit-order :postorder}) | (ss/postorder ... {:dedupe :path}) |
(ss/dfs ... {:events? true}) | (trace/dfs ...) |
{:event :visit :phase :enter :visit v} | {:event :enter :visit v} |
{:event :candidate :origin :edge :disposition :discarded ...} | {:event :edge :accepted? false ...} |
:reason :on-current-path, :already-settled | :reason :on-path, :already-visited |
:effect :improved-pending | :replaced previous-visit |
{:decode-edge (fn [[s w]] {:state s :weight w})} | {:decode-edge [:state :weight]} (the function still works) |
{:extensions [ss/distance-extension] :priority #(+ (:distance %) (h (:state %)))} | {:heuristic #(h (:state %))} |
(ss/propagate space values {:bottom #{} :join set/union}) | (ss/propagate space values set/union) |
(:back-edge child), (:via child) | (:on-path? child), (:transition child) |
{:visit-key :path :extensions [ss/path-extension]} to list every route | {:dedupe :path} |
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |