packages feed

HyloDP-1.0.0: examples/EditDistance.hs

module EditDistance where

-- * A classical Dynamic Programing problem.
--
-- $EditDistance
-- Edit distance is a way of quantifying how dissimilar two strings (e.g., words)
-- are to one another by counting the minimum number of operations required to
-- transform one string into the other.

import HyloDP
import Data.Maybe(fromJust)

type EDProblem = (String, String)
type Distance = Int

data EDOperation = Ins Char | Del Char | Replace Char Char | Keep Char deriving (Eq, Show)

-- Create DPProblem

edDPProblem :: EDProblem -> DPProblem EDProblem (TMin Distance) EDOperation
edDPProblem p = DPProblem p isTrivial subproblems
  where
    isTrivial = ( == ([], []))
    subproblems (x:xs, []) = [(TMin 1, Del x, (xs, []))]
    subproblems ([], y:ys) = [(TMin 1, Ins y, ([], ys))]
    subproblems (x:xs, y:ys) = [ (s, op, (xs, ys))
                               , (TMin 1, Del x, (x:xs, ys))
                               , (TMin 1, Ins y, (xs, y:ys))]
      where
        s = TMin $ if x == y then 0 else 1
        op = if x == y then Keep x else Replace x y

-- solvers

ed :: String -> String -> Distance
ed xs ys = let (TMin sol) = dpSolve $ edDPProblem (xs, ys) in sol

edOps :: String -> String -> ([EDOperation], Distance)
edOps xs ys = let (BestSolution ops (TMin score)) = dpSolve $ edDPProblem (xs, ys) in (fromJust ops, score)