class_docstr: A database of rewrites that should be applied until equilibrium is reached.
  
  Canonicalize, Stabilize, and Specialize are all equilibrium rewriters.
  
  Notes
  -----
  We can use `NodeRewriter` and `GraphRewriter` since `EquilibriumGraphRewriter`
  supports both.
  
  It is probably not a good idea to have both ``ignore_newtrees == False``
  and ``tracks_on_change_inputs == True``.
class_docstr_tok: ["A","database","of","rewrites","that","should","be","applied","until","equilibrium","is","reached",".","Canonicalize",",","Stabilize",",","and","Specialize","are","all","equilibrium","rewriters",".","Notes","--","--","-","We","can","use","`","NodeRewriter","`","and","`","GraphRewriter","`","since","`","EquilibriumGraphRewriter","`","supports","both",".","It","is","probably","not","a","good","idea","to","have","both","``","ignore_newtrees","==","False","``","and","``","tracks_on_change_inputs","==","True","``","."]
code: def register(
      self,
      name: str,
      rewriter: Union["RewriteDatabase", RewritesType],
      *tags: str,
      final_rewriter: bool = False,
      cleanup: bool = False,
      **kwargs,
  ):
      if final_rewriter and cleanup:
          raise ValueError(
              "`final_rewriter` and `cleanup` cannot both be true."
          )
      super().register(name, rewriter, *tags, **kwargs)
      self.__final__[name] = final_rewriter
      self.__cleanup__[name] = cleanup
  
imports: import copy
  import math
  import sys
  from collections.abc import Iterable, Sequence
  from functools import cmp_to_key
  from io import StringIO
  from typing import Optional, Union
  from pytensor.configdefaults import config
  from pytensor.graph.rewriting import basic
  from pytensor.misc.ordered_set import OrderedSet
  from pytensor.utils import DefaultOrderedDict
label_desc: Use image node_id 2 for calling the EquilibriumDB obj's underlying member method code with example usage: obj.register(name, rewriter) without return types