<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add(self, pattern: Union[Pattern, FlatTerm], final_label: T=None) -> int: """Add a pattern to the discrimination net. Args: pattern: The pattern which is added to the DiscriminationNet. If an expression is given, it will be converted to a `FlatTerm` for internal processing. You can also pass a `FlatTerm` directly. final_label: A label that is returned if the pattern matches when using :meth:`match`. This will default to the pattern itself. Returns: The index of the newly added pattern. This is used internally to later to get the pattern and its final label once a match is found. """

        index = len(self._patterns)
        self._patterns.append((pattern, final_label))
        flatterm = FlatTerm(pattern.expression) if not isinstance(pattern, FlatTerm) else pattern
        if flatterm.is_syntactic or len(flatterm) == 1:
            net = self._generate_syntactic_net(flatterm, index)
        else:
            net = self._generate_net(flatterm, index)

        if self._root:
            self._root = self._product_net(self._root, net)
        else:
            self._root = net
        return index