package fuzzy_compare

Not available on OCaml 5.5
  1. Overview
  2. Docs
Fastest bounded Levenshtein comparator over generic structures

Install

dune-project
 Dependency

Authors

Maintainers

Sources

2.0.1.tar.gz
md5=90ba5dd28b12af0bb795f6bdbca34deb
sha512=7550a654b200d82eac9ccdc58bb21627e29ff78bb9f0b06dd75b7aeb3960f58b42632b6836ce09103b29f254fb628bab5418e0e34f08a79833c7e01c3709b094

Description

This library does not calculate the edit distance.

Rather, it provides extremely efficient automata that answer whether 2 values are within a predetermined number of edits of one another. Edits are: additions, deletions, replacements.

Once generated, an automaton can be reused to compare any 2 values in around 2-8 µs.

Added to opam-repository:

README

fuzzy_compare

Extremely fast Levenshtein comparator.

Checks whether 2 values are within a predetermined number of edits of one another.

  • most comparisons take under 5 µs, depending on the length of the values
  • a Functor is provided to enable comparisons across any arbitrary types
  • string comparisons are provided (functorized) out of the box
  • reuse the same automaton across all comparisons with the same max_edits, regardless of the type of the values being compared
  • max_edits must be between 0 and 3 (inclusively) due to the astronomical scaling factor during graph building

Example

(* Create an automaton *)
let within3 = Fuzzy_compare.create ~max_edits:3 in

(* true *)
let b1 = Fuzzy_compare.String.eval within3 "kitten" "kitsch" in

(* false *)
let b2 = Fuzzy_compare.String.eval within3 "kittens" "kitsch" in

Unicode / arbitrary types

This example demonstrates how to compare unicode string as well as how to compare your own types.

For unicode we'll need uunf and uuseg:

opam install uunf uuseg

First apply the Make functor:

(* Fuzzy_compare.Make is documented in [fuzzy_compare.mli] *)
module Utf8 = Fuzzy_compare.Make (struct
  type t = string

  type cmp = string [@@deriving equal]

  type index = string array

  let index x =
    (* Normalize to Unicode NFC,
       then break the string into an array of Grapheme Clusters *)
    Uunf_string.normalize_utf_8 `NFC x
    |> Uuseg_string.fold_utf_8 `Grapheme_cluster (fun acc s -> s :: acc) []
    |> Array.of_list_rev

  let length = Array.length

  let get = Array.get

  let fold = Array.fold
end)

Then proceed as usual:

let within2 = Fuzzy_compare.create ~max_edits:2 in

(* false because each emoji is made of multiple bytes *)
let b1 = Fuzzy_compare.String.eval within2 "🏁🏴🚩" "🚩🏴🏁" in


(* true thanks to Unicode awareness *)
let b1 = Utf8.eval within2 "🏁🏴🚩" "🚩🏴🏁" in

(* false *)
let b2 = Utf8.eval within2 "🏁🏴🚩" "🚩🏳️" in

Thanks

Thanks to Paul Masurel and Jules Jacob for explaining clearly the beauty of the algorithms contained within the "Fast String Correction with Levenshtein-Automata" paper, and thanks to Klaus Schulz and Stoyan Mihov for writing the paper.

This library implements the most sophisticated (and most efficient) version described by Paul Masurel, with several additional low level optimizations.

Recommended reading: https://julesjacobs.com/2015/06/17/disqus-levenshtein-simple-and-fast.html https://fulmicoton.com/posts/levenshtein/

Dependencies (3)

  1. core >= "v0.15.0" & < "v0.17.0"
  2. dune >= "1.9.0"
  3. ocaml >= "4.10.0"

Dev Dependencies (2)

  1. uunf with-test
  2. uuseg with-test

Optional Dependencies

None

Used by

None

Conflicts

None

Build status

Results of building fuzzy_compare with each compiler on check.ci.ocaml.org, run of against opam-repository 8a77e58. 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.0.1 (this version) good good good n/a n/a
  • 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