orden=2;  (*orden=p es numero de elementos del conjunto *)

Verificación de que (Subscript[ℤ, p]) es cuerpo ⇔ p es primo

Consigna : 
1) Leer el programa y los comentarios ( los textos que aparecen entre (* *)) 
2) Tratar de entender el programa.
3) Hacer las evaluaciones para p=3, p=4, y p=12
4) Preguntar en la consulta todo lo que no entendieron del programa.

Definicion de las tablas de sumar y multiplicar

(*orden es una variable a la cual le asignamos el valor de p que queremos verificar*)
(*Notar que los argumentos de las  funciones en Mathematica van entre corchetes [] a diferencia de la notación matemática usual, que usa () *)
(* Mod[a,b]  da el resto de a en la división por b:  a=n*b+Mod[a,b] con  n un número entero *)
(* Table construye listas de valores. El primer argumento es la regla para calcular el valor, y el resto de los argumentos son listas de la forma {indice, valor inicial, valor final} (las listas van entre llaves)*)
(* El operador //  es la "aplicacion de funcion por derecha:   x // f es lo mismo que f[x]    *)
(*MatrixForm[A] muestra A como una matriz*)
(*Una instruccion terminada en ; no muestra su resultado en la pantalla  *)

(* el operador producto en Mathematica se representa por el *  *)

Tabla de sumar en  (Subscript[ℤ, orden])

Z3Sum=Table[Mod[i+j,orden],{i,0,orden-1},{j,0,orden-1}];
Z3Sum//MatrixForm

Tabla de multiplicar en  (Subscript[ℤ, orden])

Z3Mult=Table[Mod[i*j,orden],{i,0,orden-1},{j,0,orden-1}];
Z3Mult//MatrixForm

Verificacion de las propiedades de la suma

La suma es asociativa :

(*Ojo con los 'iguales':    *)
(*a=b  significa 'hacer que a valga lo que vale b'*)
(*a==b es la condición de igualdad, que se evalua como "True" si son iguales o "False" si no lo son*)
(*a=. significa "olvidarse de lo que vale a"*)
(*El operador @@ significa "usar la lista que sigue a @@ y usarla como los argumentos de la funcion que le precede" *)
(*F@@{a,b,c,d} se lee como F[a,b,c,d]*)
(*Cuando armamos una tabla con varios "indices", lo que obtenemos son listas "anidadas". Para usar @@ *)
(* hay que "achatar" la lista, lo que se hace con la función Flatten *)

check1=Table[(Mod[Mod[a+b,orden]+c,orden])==Mod[a+ Mod[b+c,orden],orden] ,{a,0,orden-1},{b,0,orden-1},{c,0,orden-1}]
asociativaAdd=And@@Flatten[check1] (* Evalua la conjunción lógica sobre cada elemento en check1 *)
check1=.

La suma es conmutativa :

check1=Table[(Mod[a+b,orden])==Mod[b+a,orden] ,{a,0,orden-1},{b,0,orden-1}];
conmutativaAdd=And@@Flatten[check1] (* Evalua la conjunción lógica sobre cada elemento en check1 *)
check1=.

La suma tiene elemento neutro :

(*Do[algo,{indice, valorinicial,valorfinal}] remplaza las ocurrencias de "indice" en la expresión "algo"  sucesivamente por los valores valorindice, valorindice+1, valorindice+2... valorfinal. En programación, esto es un ejemplo de "bucle".*)
(* La diferencia con Table es que no guarda los resultados de las evaluaciones   *)
(* Break[] sirve para salirse de un bucle*)
(* If[condicion, valorsiverdadero, valorsifalso] es una instruccion "condicional" dependiendo de si la "condicion" es verdadera o falsa, *)(* la expresion If[condicion,valorsiverdadero,valorsifalso] tomará el valor del primero o el  *)
(* segundo argumento respectivamente*)

NeutroAdd=False;
Do[
If[And@@Table[Mod[i+j,orden]==j,{j,0,orden-1}],Print["El elemento neutro es ",i];ZERO=i;NeutroAdd=True;Break[]]
,{i,0,orden-1}]

Existe el inverso aditivo

InversoAdd=True;
InversosAditivos=Table[
inv=-1;
Do[If[Mod[i+j,orden]==ZERO,inv=j;Break[]],{j,0,orden-1}];If[inv==-1,Print["No existe el inverso aditivo para ",i,"!"];InversoAdd=False;{i,Null},{i,inv}]
,{i,0,orden-1}]

Verificacion de las propiedades del producto

El producto es asociativo :

check1=Table[(Mod[Mod[a*b,orden]*c,orden])==Mod[a* Mod[b*c,orden],orden] ,{a,0,orden-1},{b,0,orden-1},{c,0,orden-1}]
asociativaProd=And@@Flatten[check1] (* Evalua la conjunción lógica sobre cada elemento en check1 *)
check1=.

El producto es conmutativo :

check1=Table[(Mod[a*b,orden])==Mod[b*a,orden] ,{a,0,orden-1},{b,0,orden-1}];
conmutativaProd=And@@Flatten[check1] (* Evalua la conjunción lógica sobre cada elemento en check1 *)
check1=.

El producto tiene elemento neutro :

NeutroProd=False;
Do[
If[And@@Table[Mod[i*j,orden]==j,{j,0,orden-1}],Print["El elemento neutro es ",i];ZERO=i;NeutroProd=True;Break]
,{i,0,orden-1}]

Existe el inverso multiplicativo

InversoProd=True;
InversosMultiplicativos=Table[
inv=-1;
Do[If[Mod[i*j,orden]==ZERO,inv=j;Break[]],{j,0,orden-1}];If[inv==-1,Print["No existe el inverso multiplicativo para ",i,"!"];InversoProd=False;{i-> Null},{i-> inv}]
,{i,1,orden-1}]

Propiedad distributiva

check1=Table[(Mod[Mod[a+b,orden]*c,orden])==Mod[Mod[a*c,orden]+Mod[b*c,orden],orden] ,{a,0,orden-1},{b,0,orden-1},{c,0,orden-1}]
distributiva=And@@Flatten[check1] 
check1=.

Resultado

If[And[distributiva, asociativaAdd,conmutativaAdd,NeutroAdd,InversoAdd,
asociativaProd,conmutativaProd,NeutroProd,InversoProd],Print [(Subscript["Ζ", orden])," es cuerpo"],
Print [(Subscript["Ζ", orden])," no es cuerpo"]]