<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def apply_rules(self, rules, recursive=True):
 """Rebuild the expression while applying a list of rules The rules are applied against the instantiated expression, and any sub-expressions if `recursive` is True. Rule application is best though of as a pattern-based substitution. This is different from the *automatic* rules that :meth:`create` uses (see :meth:`add_rule`), which are applied *before* expressions are instantiated. Args: rules (list or ~collections.OrderedDict):
 List of rules or dictionary mapping names to rules, where each rule is a tuple (:class:`Pattern`, replacement callable), cf. :meth:`apply_rule` recursive (bool):
 If true (default), apply rules to all arguments and keyword arguments of the expression. Otherwise, only the expression itself will be re-instantiated. If `rules` is a dictionary, the keys (rules names) are used only for debug logging, to allow an analysis of which rules lead to the final form of an expression. """

        if recursive:
            new_args = [_apply_rules(arg, rules) for arg in self.args]
            new_kwargs = {
                key: _apply_rules(val, rules)
                for (key, val) in self.kwargs.items()}
        else:
            new_args = self.args
            new_kwargs = self.kwargs
        simplified = self.create(*new_args, **new_kwargs)
        return _apply_rules_no_recurse(simplified, rules)