# Pattern to match any differential of a certain variable

I'm trying to come up with a pattern or just implement a function DifferentialEquationQ so I can have another function assume different behaviour when it's input is a differential equation

MyFunction[x_?DifferentialEquationQ]:=...

My first attempt is to go

DifferentialEquationQ[x_]:=StringContainsQ[#, "=="] && StringContainsQ[#, "Derivative"] &[ToString[InputForm[x]]]


I really don't like this solution because I know there's certainly a better way plus maybe I can learn something new by posting. Also, I would ideally like to parameterize DifferentialEquationQ with an independent and dependant variable. So DifferentialEquationQ[y,t][ode_] would match any ode of $$y(t)$$.

Thanks

A quick and dirty attempt. Let me know if there is a bug somewhere. All bugs are fixed in the order they are recieved. ## code

The function getPatterns thanks to Carl Woll, see Using Cases and when to make input a list or not

getPatterns[expr_, pat_] :=
Last@Reap[expr /. a : pat :> Sow[a], _, Sequence @@ #2 &];


The parser

(* Basic Parsing function *)
(*version alpha 1.01 Released . on April 27, 2020 at 9:38 PM*)
checkIfValidODE[odeInput_, y_[arg_], x_] :=
Module[{ode, lhs, rhs, order, tmp, tmp0, tmp00, maxOrder, n, z,
independentVariables, xx, yy},

If[Not[SameQ[arg, x]],
Return[
Row[{"Argument of dependent variable ", y,
" is not what is expected."}], Module]
];

Return[Row[{"Expected equation as input but found ", odeInput}],
Module]
];

tmp = getPatterns[odeInput, Derivative[n_][yy_][xx_]];
If[Length@tmp == 0,
Return[Row[{"No derivative found in ", odeInput}], Module]
];

tmp0 = Cases[tmp, Derivative[n_][yy_][xx_] :> xx];
tmp00 = getPatterns[tmp0, Derivative[n_][yy_][xx_]];

If [Length@tmp00 > 0,
Return[Row[{"Nested derivatives not allowed"}], Module]
];

order = Cases[tmp, Derivative[n_][y][x] :> n];
If[order === {},
Return[Row[{"No ", y'[x], " found in the ODE ", odeInput}], Module]
];

tmp = getPatterns[odeInput, y[xx_]];
independentVariables = Union@Cases[tmp, y[xx_] :> xx];
If [Length@independentVariables > 1,
Return[Row[{"Unexpected argument for ", y , " found ", y[x]}],
Module]
];

If[Length@independentVariables ==
1 && (First@independentVariables) =!=  x,
Return[
Row[{"Unexpected argument for", y , " found", independentVariables}], Module]
];

Print["Input is valid ODE of order ", order]

]


## Test code

checkIfValidODE[y'[y'[x]] == x^3, y[x], x]
checkIfValidODE[y''[x] == z, y[x], x]
checkIfValidODE[y''[x], y[x], x]
checkIfValidODE[y''[x] == 0, y[x], x]
checkIfValidODE[y''[x] == 0, y[z], x]
checkIfValidODE[y''[x] == 0, y[x], z]
checkIfValidODE[y[x] == 0, y[x], x]
checkIfValidODE[y''[x] == 0, y[x], y]
checkIfValidODE[y''[x] == Tan[y[x]], y[x], x]
checkIfValidODE[y''[x] == Tan[y[z]], y[x], x]
checkIfValidODE[1/y''[x] == Tan[y[x]], y[x], x]
checkIfValidODE[1/y''[x] == x^3, y[x], x]
checkIfValidODE[y[x] == x^3, y[x], x]