class_docstr: A class implementing rewriting systems for `FpGroup`s.
  
  References
  ==========
  .. [1] Epstein, D., Holt, D. and Rees, S. (1991).
         The use of Knuth-Bendix methods to solve the word problem in automatic groups.
         Journal of Symbolic Computation, 12(4-5), pp.397-414.
  
  .. [2] GAP's Manual on its KBMAG package
         https://www.gap-system.org/Manuals/pkg/kbmag-1.5.3/doc/manual.pdf
class_docstr_tok: ["A","class","implementing","rewriting","systems","for","`","FpGroup","`","s",".","References","==========","..","[","1","]","Epstein",",","D.",",","Holt",",","D.","and","Rees",",","S.","(","1991",")",".","The","use","of","Knuth-Bendix","methods","to","solve","the","word","problem","in","automatic","groups",".","Journal","of","Symbolic","Computation",",","12","(","4-5",")",",","pp.397-414",".","..","[","2","]","GAP","'s","Manual","on","its","KBMAG","package","https",":","\/\/www.gap-system.org\/Manuals\/pkg\/kbmag-1.5.3\/doc\/manual.pdf"]
docstr: Try to make the system confluent using the Knuth-Bendix
  completion algorithm
docstr_tok: ["Try","to","make","the","system","confluent","using","the","Knuth-Bendix","completion","algorithm"]
code: def make_confluent(self, check=False):
      """
      Try to make the system confluent using the Knuth-Bendix
      completion algorithm
  
      """
      if self._max_exceeded:
          return self._is_confluent
      lhs = list(self.rules.keys())
  
      def _overlaps(r1, r2):
          len1 = len(r1)
          len2 = len(r2)
          result = []
          for j in range(1, len1 + len2):
              if r1.subword(
                  len1 - j, len1 + len2 - j, strict=False
              ) == r2.subword(j - len1, j, strict=False):
                  a = r1.subword(0, len1 - j, strict=False)
                  a = a * r2.subword(0, j - len1, strict=False)
                  b = r2.subword(j - len1, j, strict=False)
                  c = r2.subword(j, len2, strict=False)
                  c = c * r1.subword(
                      len1 + len2 - j, len1, strict=False
                  )
                  result.append(a * b * c)
          return result
  
      def _process_overlap(w, r1, r2, check):
          s = w.eliminate_word(r1, self.rules[r1])
          s = self.reduce(s)
          t = w.eliminate_word(r2, self.rules[r2])
          t = self.reduce(t)
          if s != t:
              if check:
                  # system not confluent
                  return [0]
              try:
                  new_keys = self.add_rule(t, s, check)
                  return new_keys
              except RuntimeError:
                  return False
          return
  
      added = 0
      i = 0
      while i < len(lhs):
          r1 = lhs[i]
          i += 1
          # j could be i+1 to not
          # check each pair twice but lhs
          # is extended in the loop and the new
          # elements have to be checked with the
          # preceding ones. there is probably a better way
          # to handle this
          j = 0
          while j < len(lhs):
              r2 = lhs[j]
              j += 1
              if r1 == r2:
                  continue
              overlaps = _overlaps(r1, r2)
              overlaps.extend(_overlaps(r1**-1, r2))
              if not overlaps:
                  continue
              for w in overlaps:
                  new_keys = _process_overlap(w, r1, r2, check)
                  if new_keys:
                      if check:
                          return False
                      lhs.extend(new_keys)
                      added += len(new_keys)
                  elif new_keys == False:
                      # too many rules were added so the process
                      # couldn't complete
                      return self._is_confluent
  
              if added > self.tidyint and not check:
                  # tidy up
                  r, a = self._remove_redundancies(changes=True)
                  added = 0
                  if r:
                      # reset i since some elements were removed
                      i = min([lhs.index(s) for s in r])
                  lhs = [l for l in lhs if l not in r]
                  lhs.extend(a)
                  if r1 in r:
                      # r1 was removed as redundant
                      break
  
      self._is_confluent = True
      if not check:
          self._remove_redundancies()
      return True
  
file_path: sympy/sympy/combinatorics/rewritingsystem.py
imports: from collections import deque
  from sympy.combinatorics.rewritingsystem_fsm import StateMachine
label_desc: Use image node_id 8 for calling the RewritingSystem obj's underlying member method code with example usage: obj.make_confluent(check) and returns: True, self, result, list, new_keys, False, False, self