def edit_distance(s1: str, s2: str) -> int:
  """The minimum number of edits required to make s1 equal to s2.

  This is also known as the Levenshtein distance.

  An edit is the addition, deletion, or replacement of a character.
  """

  if not s1:
    return len(s2)
  if not s2:
    return len(s1)

  M = [[0 for _ in range(len(s2) + 1)] for _ in range(len(s1) + 1)]
  # M[i1][i2] is the edit distance between s1[:i1] and s2[:i2].
  for i1 in range(len(s1) + 1):
    M[i1][0] = i1
  for i2 in range(len(s2) + 1):
    M[0][i2] = i2

  for i1 in range(1, len(s1) + 1):
    for i2 in range(1, len(s2) + 1):
      cost = 0 if s1[i1 - 1] == s2[i2 - 1] else 1
      M[i1][i2] = min(
          [
              1 + M[i1 - 1][i2],
              1 + M[i1][i2 - 1],
              cost + M[i1 - 1][i2 - 1],
          ])

  return M[len(s1)][len(s2)]