def generate_network_states(address_space, machine_states):
    """
    Recursively generate all possible network states from set of possible machine states for each
    machine on the network

    Network state = [((0,0), (compromised, [s0, ..., sn])), ... ]
    """
    network_states = []
    m = address_space[0]
    if len(address_space) == 1:
        for s in machine_states:
            network_states.append([(m, s)])
        return network_states

    for subState in generate_network_states(address_space[1:], machine_states):
        for s in machine_states:
            network_states.append([(m, s)] + subState)
    return network_states