code: def execute(self):
      if not self._children_explored:
          self.optimizer_context.task_stack.push(
              BottomUpRewrite(
                  self.root_expr,
                  self.rule_set,
                  self.optimizer_context,
                  True,
              )
          )
          for child in self.root_expr.children:
              child_expr = self.optimizer_context.memo.groups[
                  child
              ].logical_exprs[0]
              self.optimizer_context.task_stack.push(
                  BottomUpRewrite(
                      child_expr, self.rule_set, self.optimizer_context
                  )
              )
          return
      valid_rules = []
      for rule in self.rule_set:
          if not self.root_expr.is_rule_explored(
              rule.rule_type
          ) and rule.top_match(self.root_expr.opr):
              valid_rules.append(rule)
  
      # sort the rules by promise
      sorted(valid_rules, key=lambda x: x.promise())
      for rule in valid_rules:
          binder = Binder(
              self.root_expr, rule.pattern, self.optimizer_context.memo
          )
          for match in iter(binder):
              if not rule.check(match, self.optimizer_context):
                  continue
              logger.info(
                  "In BottomUp, Rule {} matched for {}".format(
                      rule, self.root_expr
                  )
              )
              after = rule.apply(match, self.optimizer_context)
              plans = list(after)
              assert (
                  len(plans) <= 1
              ), "Rewrite rule cannot generate more than open alternate plan."
              for plan in plans:
                  new_expr = self.optimizer_context.replace_expression(
                      plan, self.root_expr.group_id
                  )
                  logger.info(
                      "After rewriting {}".format(self.root_expr)
                  )
                  self.optimizer_context.task_stack.push(
                      BottomUpRewrite(
                          new_expr,
                          self.rule_set,
                          self.optimizer_context,
                      )
                  )
                  # The root has changed so we cannot apply more rules to the same
                  # root, hence return
                  return
          self.root_expr.mark_rule_explored(rule.rule_type)
  
imports: from __future__ import annotations
  from abc import abstractmethod
  from enum import IntEnum, auto
  from typing import TYPE_CHECKING, List
  from evadb.optimizer.binder import Binder
  from evadb.optimizer.group import Group
  from evadb.optimizer.group_expression import GroupExpression
  from evadb.optimizer.property import PropertyType
  from evadb.optimizer.rules.rules_base import Rule
  from evadb.utils.logging_manager import logger
label_desc: Use image node_id 2 for calling the BottomUpRewrite obj's underlying member method code with example usage: obj.execute() without return types