recursive diff (splits around longest substring and runs diff on head and tail remnants).\
  global_a_slice is used for recursion and should be left undefined in outer call.\
  returns a list of Delta tuples.

def rediff(a,b,global_a_slice=None):
  "recursive diff (splits around longest substring and runs diff on head and tail remnants).\
  global_a_slice is used for recursion and should be left undefined in outer call.\
  returns a list of Delta tuples."
  if not (a or b): return []
  global_a_slice=global_a_slice or (0,len(a))
  csresult=contigsub(a,b)
  if not csresult: return (Delta(global_a_slice[0],global_a_slice[1],b),) # i.e. total replacement
  slicea,sliceb=csresult
  if slicea[0]==0 and sliceb[0]==0 and slicea[1]==len(a) and sliceb[1]==len(b): return [] # i.e. nochange
  head=rediff(a[:slicea[0]],b[:sliceb[0]],subslice(slicea,global_a_slice,'head'))
  tail=rediff(a[slicea[1]:],b[sliceb[1]:],subslice(slicea,global_a_slice,'tail'))
  return list(head)+list(tail)