def _get_transitions(self, expression: Any, expected_type: PredicateType) -> Tuple[List[str], PredicateType]:
        """
        This is used when converting a logical form into an action sequence.  This piece
        recursively translates a lisp expression into an action sequence, making sure we match the
        expected type (or using the expected type to get the right type for constant expressions).
        """
        if isinstance(expression, (list, tuple)):
            function_transitions, return_type, argument_types = self._get_function_transitions(expression[0],
                                                                                               expected_type)
            if len(argument_types) != len(expression[1:]):
                raise ParsingError(f'Wrong number of arguments for function in {expression}')
            argument_transitions = []
            for argument_type, subexpression in zip(argument_types, expression[1:]):
                argument_transitions.extend(self._get_transitions(subexpression, argument_type)[0])
            return function_transitions + argument_transitions, return_type
        elif isinstance(expression, str):
            if expression not in self._functions:
                raise ParsingError(f"Unrecognized constant: {expression}")
            constant_types = self._function_types[expression]
            if len(constant_types) == 1:
                constant_type = constant_types[0]
                # This constant had only one type; that's the easy case.
                if expected_type and expected_type != constant_type:
                    raise ParsingError(f'{expression} did not have expected type {expected_type} '
                                       f'(found {constant_type})')
                return [f'{constant_type} -> {expression}'], constant_type
            else:
                if not expected_type:
                    raise ParsingError('With no expected type and multiple types to pick from '
                                       f"I don't know what type to use (constant was {expression})")
                if expected_type not in constant_types:
                    raise ParsingError(f'{expression} did not have expected type {expected_type} '
                                       f'(found these options: {constant_types}; none matched)')
                return [f'{expected_type} -> {expression}'], expected_type

        else:
            raise ParsingError('Not sure how you got here. Please open an issue on github with details.')
This is used when converting a logical form into an action sequence.  This piece
        recursively translates a lisp expression into an action sequence, making sure we match the
        expected type (or using the expected type to get the right type for constant expressions).