The complete solution space to a system of ODEs can have a complicated structure, including singular components (e.g. Clairaut equations) and multiple branches. Let us call a solution $y_{\bf C}$ a locally general solution to an ODE system with smooth coefficients of dimension $n$ at $(x,{\bf C})=(x_0,{\bf C}_0)$ to a system of ODEs if the mapping that maps a parameter vector ${\bf C} = (c_1,\,c_2,\dots,\,c_n)$ to a solution $y_{\bf C}$ has an injective derivative at $(x_0,{\bf C}_0)$. If a solution to a linear ODE is locally general, then it is the general solution and, furthermore, it is the complete solution in that it represents all possible solutions.
Here's a not too well tested implementation of these ideas:
ClearAll[nLocallyInjective];
nLocallyInjective[eq_, sol_, {x_, x0_}, params_List -> p0_List] :=
Module[{ivar, dim, dvars, ics, res, der},
ivar = Flatten@{x};
dim = Length@params;(* Check: Length@p0==dim+1 *)
dvars = NestList[D[#, x] &, sol, dim - 1];
der = D[dvars, {params}] /.
Thread[Join[ivar, params] -> Flatten@{x0, p0}];
If[Precision[der] == MachinePrecision,
res = Abs[First@Eigenvalues[der, -1]/
Norm[der, Infinity]/$MachineEpsilon/Length@der] > 10,
res = Simplify[Det[der] != 0]
];
(* Alt: res=MatrixRank[der]==dim *)
res
];
ClearAll[nLocallyGeneralSolution];
nLocallyGeneralSolution[eq_, sol_, y_, {x_, x0_}, p0_List] :=
Module[{ivar, dvar, dorder, params, dvars, ics, res, der},
ivar = Flatten@{x};
dvar = Flatten@{y};
dorder = Total[Internal`ProcessEquations`DifferentialOrder[{eq},
ivar, dvar], Infinity];
(* check dimensions *)
params = Union@Cases[sol, _C, Infinity];
res = Length[params] == dorder;
(* check sol is a solution *)
res = res && FullSimplify[
Flatten@{eq} /.
Thread[dvar -> (Function @@ {ivar, #} & /@ Flatten@{sol})] //
Apply[And]];
(* check locally injective *)
res = res && nLocallyInjective[eq, sol, {x, x0}, params -> p0]
];
Examples:
eq = y''[x] + 4 y[x] == 7;
sol = DSolveValue[{eq}, y[x], x];
nLocallyGeneralSolution[eq, sol, {y}, {x, 0}, {0, 0}]
(* True *)
eq = y''[x] + 4 y[x]^2 == 7;
sol = DSolveValue[{eq}, y[x], x];
nLocallyGeneralSolution[eq, sol, {y}, {x, 0}, N@{1, 1}]
(* True *)