We prove that the language accepted by a DFA is regular. The proof for NFAs follows from the equivalence between DFAs and NFAs.
Suppose that \(M\) is a DFA, where \(M=(Q,\Sigma,q_0,\delta,F)\text{.}\) Let \(n\) be the number of states in \(M\text{,}\) and write \(Q=\{q_0,q_1,\dots,q_{n-1}\}\text{.}\) We want to consider computations in which \(M\) starts in some state \(q_i\text{,}\) reads a string \(w\text{,}\) and ends in state \(q_k\text{.}\) In such a computation, \(M\) might go through a series of intermediates states between \(q_i\) and \(q_k\text{:}\)
\begin{equation*}
q_i\longrightarrow p_1\longrightarrow p_2 \cdots\longrightarrow p_r\longrightarrow q_k
\end{equation*}
We are interested in computations in which all of the intermediate states--- \(p_1,p_2,\dots,p_r\)---are in the set \(\{q_0,q_1,\dots,q_{j-1}\}\text{,}\) for some number \(j\text{.}\) We define \(R_{i,j,k}\) to be the set of all strings \(w\) in \(\Sigma^*\) that are consumed by such a computation. That is, \(w\in R_{i,j,k}\) if and only if when \(M\) starts in state \(q_i\) and reads \(w\text{,}\) it ends in state \(q_k\text{,}\) and all the intermediate states between \(q_i\) and \(q_k\) are in the set \(\{q_0,q_1,\dots,q_{j-1}\}\text{.}\) \(R_{i,j,k}\) is a language over \(\Sigma\text{.}\) We show that \(R_{i,j,k}\) for \(0\leq i \lt n , 0\leq j \leq n, 0\leq k lt n\text{.}\)
Consider the language \(R_{i,0,k}\text{.}\) For \(w\in R_{i,0,k}\text{,}\) the set of allowable intermediate states is empty. Since there can be no intermediate states, it follows that there can be at most one step in the computation that starts in state \(q_i\text{,}\) reads \(w\text{,}\) and ends in state \(q_k\text{.}\) So, \(|w|\) can be at most one. This means that \(R_{i,0,k}\) is finite, and hence is regular. (In fact, \(R_{i,0,k}=\{a\in\Sigma\st \delta(q_i,a)=q_k\}\text{,}\) for \(i\ne k\text{,}\) and \(R_{i,0,i}=\{\varep\}\cup\{a\in\Sigma\st \delta(q_i,a)=q_i\}\text{.}\) Note that in many cases, \(R_{i,0,k}\) will be the empty set.)
We now proceed by induction on \(j\) to show that \(R_{i,j,k}\) is regular for all \(i\) and \(k\text{.}\) We have proved the base case, \(j=0\text{.}\) Suppose that \(0\leq j \lt n \) we already know that \(R_{i,j,k}\) is regular for all \(i\) and all \(k\text{.}\) We need to show that \(R_{i,j+1,k}\) is regular for all \(i\) and \(k\text{.}\) In fact,
\begin{equation*}
R_{i,j+1,k}=R_{i,j,k}\cup \left( R_{i,j,j}R_{j,j,j}^*R_{j,j,k}\right)
\end{equation*}
which is regular because \(R_{i,j,k}\) is regular for all \(i\) and \(k\text{,}\) and because the union, concatenation, and Kleene star of regular languages are regular.
To see that the above equation holds, consider a string \(w\in\Sigma^*\text{.}\) Now, \(w\in R_{i,j+1,k}\) if and only if when \(M\) starts in state \(q_i\) and reads \(w\text{,}\) it ends in state \(q_k\text{,}\) with all intermediate states in the computation in the set \(\{q_0,q_1,\dots,q_j\}\text{.}\) Consider such a computation. There are two cases: Either \(q_j\) occurs as an intermediate state in the computation, or it does not. If it does not occur, then all the intermediate states are in the set \(\{q_0,q_1,\dots,q_{j-1}\}\text{,}\) which means that in fact \(w\in R_{i,j,k}\text{.}\) If \(q_j\) does occur as an intermediate state in the computation, then we can break the computation into phases, by dividing it at each point where \(q_j\) occurs as an intermediate state. This breaks \(w\) into a concatenation \(w=xy_1y_2\cdots y_rz\text{.}\) The string \(x\) is consumed in the first phase of the computation, during which \(M\) goes from state \(q_i\) to the first occurrence of \(q_j\text{;}\) since the intermediate states in this computation are in the set \(\{q_0,q_1,\dots,q_{j-1}\}, x\in R_{i,j,j}\text{.}\) The string \(z\) is consumed by the last phase of the computation, in which \(M\) goes from the final occurrence of \(q_j\) to \(q_k\text{,}\) so that \(z\in R_{j,j,k}\text{.}\) And each string \(y_t\) is consumed in a phase of the computation in which \(M\) goes from one occurrence of \(q_j\) to the next occurrence of \(q_j\text{,}\) so that \(y_r\in R_{j,j,j}\text{.}\) This means that \(w=xy_1y_2\cdots y_rz\in R_{i,j,j}R_{j,j,j}^*R_{j,j,k}\text{.}\)
We now know, in particular, that \(R_{0,n,k}\) is a regular language for all \(k\text{.}\) But \(R_{0,n,k}\) consists of all strings \(w\in\Sigma^*\) such that when \(M\) starts in state \(q_0\) and reads \(w\text{,}\) it ends in state \(q_k\) (with \textbf{no} restriction on the intermediate states in the computation, since every state of \(M\) is in the set \{q_0,q_1,\dots,q_{n-1}\}). To finish the proof that \(L(M)\) is regular, it is only necessary to note that
\begin{equation*}
L(M)=\bigcup_{q_k\in F} R_{0,n,k}
\end{equation*}
which is regular since it is a union of regular languages. This equation is true since a string \(w\) is in \(L(M)\) if and only if when \(M\) starts in state \(q_0\) and reads \(w\text{,}\) in ends in some accepting state \(q_k\in F\text{.}\) This is the same as saying \(w\in R_{0,n,k}\) for some \(k\) with \(q_k\in F\text{.}\)