com.github.liblevenshtein.transducer.SubsumesFunction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of liblevenshtein Show documentation
Show all versions of liblevenshtein Show documentation
A library for spelling-correction based on Levenshtein Automata.
The newest version!
package com.github.liblevenshtein.transducer;
import java.io.Serializable;
/**
* Routines for determining whether one position subsumes another.
* @author Dylon Edwards
* @since 2.1.0
*/
public abstract class SubsumesFunction implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Determines whether {@code lhs} subsumes {@code rhs}.
* @param lhs {@link Position} doing the subsumption.
* @param rhs {@link Position} being subsumed.
* @param n Length of the query term.
* @return {@code lhs} subsuem {@code rhs}.
*/
public abstract boolean at(Position lhs, Position rhs, int n);
/**
* Routines for determining whether a standard position subsumes another.
* @author Dylon Edwards
* @since 2.1.0
*/
public static class ForStandardAlgorithm extends SubsumesFunction {
private static final long serialVersionUID = 1L;
/**
* {@inheritDoc}
*/
@Override
public boolean at(final Position lhs, final Position rhs, final int n) {
final int i = lhs.termIndex();
final int e = lhs.numErrors();
final int j = rhs.termIndex();
final int f = rhs.numErrors();
return (i < j ? j - i : i - j) <= (f - e);
}
}
/**
* Routines for determining whether a transposition position subsumes another.
* @author Dylon Edwards
* @since 2.1.0
*/
public static class ForTransposition extends SubsumesFunction {
private static final long serialVersionUID = 1L;
/**
* {@inheritDoc}
*/
@Override
public boolean at(final Position lhs, final Position rhs, final int n) {
final int i = lhs.termIndex();
final int e = lhs.numErrors();
final boolean s = lhs.isSpecial();
final int j = rhs.termIndex();
final int f = rhs.numErrors();
final boolean t = rhs.isSpecial();
if (s) {
if (t) {
return i == j;
}
return f == n && i == j;
}
if (t) {
// We have two cases:
//
// Case 1: (j < i) => (j - i) = - (i - j)
// => |j - (i - 1)| = |j - i + 1|
// = |-(i - j) + 1|
// = |-(i - j - 1)|
// = i - j - 1
//
// Case 1 holds, because i and j are integers, and j < i implies i is at
// least 1 unit greater than j, further implying that i - j - 1 is
// non-negative.
//
// Case 2: (j >= i) => |j - (i - 1)| = |j - i + 1| = j - i + 1
//
// Case 2 holds for the same reason case 1 does, in that j - i >= 0, and
// adding 1 to the difference will only strengthen its non-negativity.
//
//return Math.abs(j - (i - 1)) <= (f - e);
return (j < i ? i - j - 1 : j - i + 1) <= (f - e);
}
return (i < j ? j - i : i - j) <= (f - e);
}
}
/**
* Routines for determining whether a merge-and-split position subsumes another.
* @author Dylon Edwards
* @since 2.1.0
*/
public static class ForMergeAndSplit extends SubsumesFunction {
private static final long serialVersionUID = 1L;
/**
* {@inheritDoc}
*/
@Override
public boolean at(final Position lhs, final Position rhs, final int n) {
final int i = lhs.termIndex();
final int e = lhs.numErrors();
final boolean s = lhs.isSpecial();
final int j = rhs.termIndex();
final int f = rhs.numErrors();
final boolean t = rhs.isSpecial();
if (s && !t) {
return false;
}
return (i < j ? j - i : i - j) <= (f - e);
}
}
}