It might be that the best solution depends on the definitions for f and m (avoiding initial capitals per best practices), the right-hand sides (RHS) of a defining formula. It appears that m has at least one in terms of f and other functions.
Some ideas:
If f[a,b,c,d] always evaluates to some value ((a+b)/(c+d), for instance), then the symmetry should be present in the value,
and we should have to implement symmetry rules for f per se. The function m as described in the OP seems to fit in this category: the symmetry of m should be handled by the symmetry of f in the formula for m.
The usual trick is to put the arguments into a canonical order.
Comparators such as > and < work only on numeric arguments. OrderedQ[] compares any list of expressions. Sort[] put expressions into a canonical order.
The attribute Orderless is used by Mathematica to automatically sort arguments into a canonical order. Unfortunately, it sorts all arguments, and in the present case, we want to sort subsets of the arguments.
Functions like HypergeometricPFQ and MeijerG use lists to group arguments into ordered subsets, but there's no ready-made mechanism for making lists into orderless subsets. One can make one, though.
Orderless subset grouping
ESC<ESC and ESC>ESC can be used to enter AngleBracket, and AngleBracket will be displayed using them.
AngleBracket // ClearAll;
SetAttributes[AngleBracket, Orderless];
f // ClearAll;
f[a_, b_, c_, d_] :=
f[\[LeftAngleBracket]a, b\[RightAngleBracket],
\[LeftAngleBracket]c, d\[RightAngleBracket]];
(* other definitions of f[] *)
m // ClearAll;
m[a_, b_, c_, d_, e_, f_] :=
m[\[LeftAngleBracket]a, b, c\[RightAngleBracket],
\[LeftAngleBracket]d, e, f\[RightAngleBracket]];
(* other definitions of m[] *)
f[u2, u1, d1, d2]
(*
f[[LeftAngleBracket]u1, u2[RightAngleBracket],
[LeftAngleBracket]d1, d2[RightAngleBracket]]
*)
f[u1, u2, d1, d2] == f[u2, u1, d1, d2]
(* True *)
Sorting subsets of arguments
f // ClearAll;
f[a_, b_, c_, d_] /; ! (OrderedQ[{a, b}] && OrderedQ[{c, d}]) :=
f[Sequence @@ Sort[{a, b}], Sequence @@ Sort[{c, d}]];
(* other definitions of f[] *)
m // ClearAll;
m[a_, b_, c_, d_, e_, f_] /;
! (OrderedQ[{a, b, c}] && OrderedQ[{d, e, f}]) :=
m[Sequence @@ Sort[{a, b, c}], Sequence @@ Sort[{d, e, f}]];
(* other definitions of m[] *)
f[u2, u1, d1, d2]
(* f[u1, u2, d1, d2] *)
f[u1, u2, d1, d2] == f[u2, u1, d1, d2]
(* True *)
Manual canonicalization
canonicalize may be applied to any expression whenever desired to bring f[] (and m[] if desired, as shown) into canonical form. It may be used as a transformation function in (Full)Simplify, but simplification may reject the transformation if it does not lead to a measurably simpler expression. One could write a ComplexityFunction to go with it that adds a penalty if the expression contains an f or m with unordered arguments.
ClearAll[m, f, canonicalize];
canonicalize[expr_] := expr /. {
f[a_, b_, c_, d_] :>
f[Sequence @@ Sort[{a, b}], Sequence @@ Sort[{c, d}]],
m[a_, b_, c_, d_, e_, f_] :>
m[Sequence @@ Sort[{a, b, c}], Sequence @@ Sort[{d, e, f}]]};
f[u2, u1, d1, d2] // canonicalize
(* f[u1, u2, d1, d2] *)
f[u1, u2, d1, d2] == f[u2, u1, d1, d2] // canonicalize
(* True *)
Simplify[f[u1, u2, d1, d2] == f[u2, u1, d1, d2],
TransformationFunctions -> {Automatic, canonicalize}]
(* True *)
Simplify[f[u2, u1, d1, d2],
TransformationFunctions -> {Automatic, canonicalize},
ComplexityFunction -> (
Simplify`SimplifyCount[#] +
Count[
#,
f[a_, b_, c_, d_] /; ! (OrderedQ[{a, b}] && OrderedQ[{c, d}]),
{0, Infinity}] &)]
(* f[u1, u2, d1, d2] *)
It turns out that the ComplexityFunction is not needed on the example f[u2, u1, d1, d2]. However, the expression and its canonicalization have the same complexity:
Simplify`SimplifyCount /@ {f[u2, u1, d1, d2], f[u1, u2, d1, d2]}
(* {5, 5} *)
The documentation indicates that returning either one would be correct. If you want to guarantee which will be returned, then use an appropriate complexity function. The one above measure the unordered expression as more complex:
Simplify`SimplifyCount[#] +
Count[
#,
f[a_, b_, c_, d_] /; ! (OrderedQ[{a, b}] && OrderedQ[{c, d}]),
{0, Infinity}] & /@
{f[u2, u1, d1, d2], f[u1, u2, d1, d2]}
(* {6, 5} *)
Remark on "other definitions of f"
Care must be taken when giving multiple definitions. If the problem is located in the RHS of a definition — for instance, if the formula has a symmetry that Mathematica does not recognize in some cases, then f[a,b,c,d] must be canonicalized before such a definition is applied.
Note that the canonical order may change if one substitutes an expression for an argument:
f[a, b, c, d] // canonicalize
% /. b -> 2
% // canonicalize
(*
f[a, b, c, d] -- canonical
f[a, 2, c, d] -- substituted, no longer canonical
f[2, a, c, d] -- canonical
*)
You may not want to let evaluation of f[a,b,c,d] occur until all arguments are numeric. NumericQ is good for that.
u[x1,x2]==u[x2,x1]one considers another functionv[x1,x2]=1/2*(u[x1,x2]+u[x2,x1]). – Alexei Boulbitch May 09 '23 at 09:00f[OrderlessPatternSequence[u1_, u2_], OrderlessPatternSequence[d1_, d2_]] := {{u1, u2}, {d1, d2}}and then withoutFullSimplifyor anyAssumptions:2*f[1, 2, 3, 4] - f[2, 1, 3, 4] - f[1, 2, 4, 3]– Syed May 09 '23 at 09:10f? – jms547 May 10 '23 at 11:22