mirror of
https://github.com/github/semantic.git
synced 2024-12-26 08:25:19 +03:00
Parameterize SES by the cost function.
This commit is contained in:
parent
230394bde2
commit
7c099bac6f
@ -94,7 +94,7 @@ public enum Algorithm<Term: TermType, B> {
|
|||||||
return f(Dictionary(elements: deleted + inserted + patched)).evaluate(equals, recur: recur)
|
return f(Dictionary(elements: deleted + inserted + patched)).evaluate(equals, recur: recur)
|
||||||
|
|
||||||
case let .Roll(.ByIndex(a, b, f)):
|
case let .Roll(.ByIndex(a, b, f)):
|
||||||
return f(SES(a, b, recur: recur)).evaluate(equals, recur: recur)
|
return f(SES(a, b, cost: cost, recur: recur)).evaluate(equals, recur: recur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,12 @@
|
|||||||
/// Computes the SES (shortest edit script), i.e. the shortest sequence of diffs (`Free<A, Patch<Term>>`) for two arrays of `Term`s which would suffice to transform `a` into `b`.
|
/// Computes the SES (shortest edit script), i.e. the shortest sequence of diffs (`Free<A, Patch<Term>>`) for two arrays of `Term`s which would suffice to transform `a` into `b`.
|
||||||
///
|
///
|
||||||
/// This is computed w.r.t. an `equals` function, which computes the equality of leaf nodes within terms, and a `recur` function, which produces diffs representing matched-up terms.
|
/// This is computed w.r.t. an `equals` function, which computes the equality of leaf nodes within terms, and a `recur` function, which produces diffs representing matched-up terms.
|
||||||
public func SES<Term, A>(a: [Term], _ b: [Term], recur: (Term, Term) -> Free<A, Patch<Term>>?) -> [Free<A, Patch<Term>>] {
|
public func SES<Term, A>(a: [Term], _ b: [Term], cost: Free<A, Patch<Term>> -> Int, recur: (Term, Term) -> Free<A, Patch<Term>>?) -> [Free<A, Patch<Term>>] {
|
||||||
typealias Diff = Free<A, Patch<Term>>
|
typealias Diff = Free<A, Patch<Term>>
|
||||||
|
|
||||||
if a.isEmpty { return b.map { Diff.Pure(Patch.Insert($0)) } }
|
if a.isEmpty { return b.map { Diff.Pure(Patch.Insert($0)) } }
|
||||||
if b.isEmpty { return a.map { Diff.Pure(Patch.Delete($0)) } }
|
if b.isEmpty { return a.map { Diff.Pure(Patch.Delete($0)) } }
|
||||||
|
|
||||||
func cost(diff: Diff) -> Int {
|
|
||||||
return diff.map(const(1)).iterate { syntax in
|
|
||||||
switch syntax {
|
|
||||||
case .Leaf:
|
|
||||||
return 0
|
|
||||||
case let .Indexed(costs):
|
|
||||||
return costs.reduce(0, combine: +)
|
|
||||||
case let .Keyed(costs):
|
|
||||||
return costs.values.reduce(0, combine: +)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func cons(diff: Diff, rest: Memo<Stream<(Diff, Int)>>) -> Stream<(Diff, Int)> {
|
func cons(diff: Diff, rest: Memo<Stream<(Diff, Int)>>) -> Stream<(Diff, Int)> {
|
||||||
return .Cons((diff, cost(diff) + costOfStream(rest)), rest)
|
return .Cons((diff, cost(diff) + costOfStream(rest)), rest)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user