En realidad, la función ValueQ no es inocente, ya que se escapa de evaluación de código con los efectos secundarios. Ejemplos:
ClearAll[f, g];
f[x_] := Print[x];
g[x_][0] := Print[x];
{ValueQ[f[1]],ValueQ[g[2][0]]}
Si quita el atributo de ReadProtected ValueQ y mirar el código, verá por qué - el código es muy simplista y hace un trabajo decente para sólo OwnValues. Aquí está una versión más compleja que he desarrollado para evitar este problema (se puede probar que, al menos para los ejemplos anteriores, no se escapa de evaluación):
ClearAll[symbolicHead];
SetAttributes[symbolicHead, HoldAllComplete];
symbolicHead[f_Symbol[___]] := f;
symbolicHead[f_[___]] := symbolicHead[f];
symbolicHead[f_] := Head[Unevaluated[f]];
ClearAll[partialEval];
SetAttributes[partialEval, HoldAllComplete];
partialEval[a_Symbol] /; OwnValues[a] =!= {} :=
Unevaluated[partialEval[a]] /. OwnValues[a];
partialEval[a : f_Symbol[___]] /; DownValues[f] =!= {} :=
With[{dv = DownValues[f]},
With[{eval = Hold[partialEval[a]] /. dv},
ReleaseHold[eval] /;
(First[Extract[eval, {{1, 1}}, HoldComplete]] =!=
HoldComplete[a])]];
partialEval[a_] :=
With[{sub = SubValues[Evaluate[symbolicHead[a]]]},
With[{eval = Hold[partialEval[a]] /. sub},
ReleaseHold[eval] /;
(First[Extract[eval, {{1, 1}}, HoldComplete]] =!=
HoldComplete[a])]];
ClearAll[valueQ];
SetAttributes[valueQ, HoldAllComplete];
valueQ[expr_] := partialEval[expr] =!= Unevaluated[partialEval[expr]];
Esto no es completa, ya sea, ya no lo hace cuenta para UpValues, NValues y FormatValues, pero esto parece ser suficiente para sus necesidades declaradas, y también, las reglas para estos tres casos adicionales también pueden agregarse en la misma línea que arriba.
Genial, parece funcionar como se espera para los 3 formularios –