the epsilon-closure
/ epsilon = EP-si-lon (the symbol ε) /
If a machine has free epsilon-moves, then standing in one state really means you could already be in several states without reading anything. The epsilon-closure of a state is the answer to the question: "starting here and taking only free epsilon-moves, every state I could possibly slip into — what is the full list?" It always includes the state itself, plus everything reachable through any chain of epsilon-transitions.
You compute it like exploring a graph using only the epsilon-edges. Start a set with the given state. Repeatedly: for every state already in the set, add all states reachable from it by a single epsilon-move; stop when nothing new appears. The result, ECLOSE(q), is that stable set. For a SET of states, the epsilon-closure is just the union of the closures of its members. Because there are finitely many states, this process always terminates.
The epsilon-closure is the gadget that lets us simulate epsilon-NFAs cleanly. To run such a machine: start in the epsilon-closure of the start state; to read a symbol a, move on a from your current set and then take the epsilon-closure of the result; accept if the final set meets an accept state. The very same closures appear as the states of the equivalent DFA produced by the subset construction — closing under epsilon is how the construction absorbs the free moves so the DFA never needs them.
Suppose δ(1, ε) = {2}, δ(2, ε) = {3}, and state 3 has no epsilon-moves. Then ECLOSE(1) = {1, 2, 3}: from 1 you may freely slip to 2, and from 2 freely to 3, so all three are reachable on the empty string. ECLOSE(3) = {3}.
The epsilon-closure of a state is everything reachable by free moves, including the state itself.
Always include the state itself in its own epsilon-closure, even if it has no epsilon-moves out — forgetting this is the classic bug when simulating an epsilon-NFA.