diff --git a/src/SES.hs b/src/SES.hs index 991dfe9bf..1a5277fec 100644 --- a/src/SES.hs +++ b/src/SES.hs @@ -10,13 +10,18 @@ import Data.List (uncons) import qualified Data.Map as Map import Data.Ord (comparing) +-- | A function that maybe creates a diff from two terms. type Compare a annotation = Term a annotation -> Term a annotation -> Maybe (Diff a annotation) + +-- | A function that computes the cost of a diff. type Cost a annotation = Diff a annotation -> Integer +-- | Find the shortest edit script (diff) between two terms given a function to compute the cost. ses :: Compare a annotation -> Cost a annotation -> [Term a annotation] -> [Term a annotation] -> [Diff a annotation] ses diffTerms cost as bs = fst <$> evalState diffState Map.empty where diffState = diffAt diffTerms cost (0, 0) as bs +-- | Find the shortest edit script between two terms at a given vertex in the edit graph. diffAt :: Compare a annotation -> Cost a annotation -> (Integer, Integer) -> [Term a annotation] -> [Term a annotation] -> State (Map.Map (Integer, Integer) [(Diff a annotation, Integer)]) [(Diff a annotation, Integer)] diffAt _ _ _ [] [] = return [] diffAt _ cost _ [] bs = return $ foldr toInsertions [] bs where @@ -46,5 +51,6 @@ diffAt diffTerms cost (i, j) (a : as) (b : bs) = do best = minimumBy (comparing costOf) recur = diffAt diffTerms cost +-- | Prepend a diff to the list with the cumulative cost. consWithCost :: Cost a annotation -> Diff a annotation -> [(Diff a annotation, Integer)] -> [(Diff a annotation, Integer)] consWithCost cost diff rest = (diff, cost diff + maybe 0 snd (fst <$> uncons rest)) : rest