How to prove that a function is well defined? I know what "Well Defined" means, and I know how to show that something specifically isn't well defined -- that is, by presenting a case where two different but equivalent forms of $x$ have different images $f(x)$... But if I'm given a function and am asked to prove that it IS well defined, what steps do I have to do to show this?
Take for example the assertion that you can add and multiply congruence classes as such:

  
*
  
*$[a]+[c]=[a+c]$, and
  
*$[a]\cdot[c]=[a\cdot c]$
  

My textbook says that both are well defined statements because the theorem that $a\equiv b\mod{m}$ and $c\equiv d\mod{m}$ imply that $a+c\equiv b+d\mod{m}$ and $ac\equiv bd\mod{m}$ implies they are... I just can't quite follow why.
In general though, neglecting this specific example, what steps do I need to follow to show that something is well defined?
 A: Morally, stating that an object is "well-defined" means that it shouldn't matter what name we call it. Here, we might have issues, since $a$ and $a + m$ are two very different-looking names for the same object, since we're only considering numbers up to addition of multiples of $m$. 
So in general, to check well-definition, you need to write down an object and an arbitrary name for it, and make sure that the particular name doesn't change the result of a function.
So here in particular, if we fix an integer $a$, its other names are all of the form $a + km$ with $k$ an integer. Likewise, every name for $c$ has the form $c + nm$ for some $n$. Now check that the result using $a$ and $c$ agrees with the result using $a + km$ and $c + nm$, and you're done.
A: It's hard to give a completely general answer, because the term "well-defined" is often misused (you might say it's not a well-defined term.)  But we can generalize slightly to say that a function on tuples of equivalence classes "defined" as
\begin{align}\tag{*}
f([a_1],\ldots,[a_n]) = [g(a_1,\ldots,a_n)]
\end{align}
is well-defined if we have
\begin{align}\tag{**}
[g(a_1,\ldots,a_n)] = [g(a_1',\ldots,a_n')]\text{ whenever }[a_i] = [a_i']\text{ for all } i\in \{1,\ldots,n\}.
\end{align}
The reason for this is that generally one defines an $n$-ary function $f$ by saying what $f(C_1,\ldots,C_n)$ is for all possible values of the arguments $C_1,\ldots,C_n$.  Even if the arguments $C_i$ can be written as equivalence classes $[a_i]$, one is not allowed to use the values of $a_i$ when specifying the value of the function $f$; one is only allowed to use the values of the arguments $C_i$.  But sometimes the most convenient "definition" appears to depend on $a_i$, in which case one must check that it really only depends on the equivalence classes $C_i = [a_i]$.
If this condition  (**) fails, then colloquially one says "the function $f$ is not well-defined".  But in reality there is no function $f$ at all in this case: if (**) fails then the statement (*) is not a definition of anything, it is just an absurdity.
A: What makes the concept of a well-defined function $f$ confusing is the fact that functions are by definition well-defined.  So to explain what it means to not be well-defined, we have to take an example where $f$ is not a function.
Lets take the following procedure and call it $f$:  The input is an integer $n$. The output of $f$ is an element of $\{n+1,\ldots,n+6\}$ determined by rolling a dice. This procedure takes an integer $n$ as input, and returns an integer as output. But it is not well-defined, because if you compute $f(n)$ several times for the same $n$, you do not always get the same output. The term used to describe this behavior is to say that $f$ is not well-defined.
Suppose you have some procedure $f$ that takes as input an element of a set $X$, and returns as output an element of a set $Y$. Then you may only call $f$ a function if you can prove that $x=y$ implies $f(x) = f(y)$. This might seem obvious at first, but it is often non-trivial. For example, suppose that the procedure $f$ involves choosing an element of some non-empty set.  In this case, to prove that $f$ is well-defined (and thus: a function), you have to prove that any choice you could have made will result in the same output $f(x)$.
Now lets see how this applies to your example where $[a] + [c]$ is defined to be $[a+c]$. Here, the addition procedure $+$ receives two congruence classes as inputs: $[a]$ and $[c]$.  It does NOT receive $a$ and $c$ as input! So the addition procedure is forced to make two choices: it has to choose an element of the set $[a]$, and an element of the set $[c]$. It then adds them, and the output will be the congruence class of the sum. To prove that this addition procedure is well-defined, you have to show that the final result does not depend on the two choices (it is not hard to prove that, the most important part is to understand why you have to prove that in the first place!).
