def attempt_actions_for_machine(machine_action_definition, machine, context, actions):
    """Check the given actions for a machine and determine which action was successfully taken.

    For the given list of actions, the corresponding function from the given machine_action_definition will be called
    with the machine and context objects. If there is no context object (None), then machine will be passed as the only
    parameter to the function.
    If the function returns a value equal to the associated "successful return value", the action would be considered
    successfully taken and will be returned. Symbolically:
        <successful return value> == <function>(<machine>, <context>)
        or
        <successful return value> == <function>(<machine>)

    If a function appears multiple times for different actions, it will be called exactly once and the value returned
    will be matched against the other cases to determine the successful action.

    If a function raises an exception, the action will not be considered successful and subsequent actions will be
    attempted.

    If an action doesn't exist in the machine_action_definition, it will be ignored.

    :param machine_action_definition: A mapping of the form:
                                      {
                                          <Action 1 for Machine 1(str)>: (<function>, <successful return value>),
                                          ...
                                      }
    :param machine:                   Any object representative of the machine.
    :param context:                   The context object.
    :param actions:                   List of strings representing the actions to check.
    :return:                          The action performed (string).
    """
    action_cache = {}
    for action in actions:
        if action not in machine_action_definition:
            continue
        action_performer, successful_action = machine_action_definition[action]
        args = (machine, context) if context is not None else (machine,)
        try:
            if action_cache.setdefault(action_performer, action_performer(*args)) == successful_action:
                return action
        except Exception:
            continue