Is it possible in Maple to define a function (or operator) with property f(a,b,c) = f(c,a,b) = f(b,c,a), but not necessary other cases like f(a,b,c) = f(a,c,b). In Maple it should work like this:
[> f(a,b,c)-f(c,a,b), f(a,b,c)-f(b,c,a), f(a,b,c)-f(a,c,b);
0, 0, f(a,b,c)-f(a,c,b)
That is, function f could be non symmetric, but it shouldn't change under the substitution [a=b,b=c,c=a]:
[> f(a,b,c)-subs([a=b,b=c,c=a],f(a,b,c));
0
Just to make it clear: the question isn't about giving an example of such function, but about defining such property of function f in Maple, so that it would work as described (Maple would simplify the expression f(a,b,c)-f(c,a,b) to zero for any a,b,c).
I don't offhand see a way to accomplish this using just the define
command. But there are alternative mechanisms.
One of the tricky aspects involves getting Maple's -
(minus) to discern the equivalence while still allowing all calls to f
to return unevaluated with the original order of arguments.
Relaxing that aspect for the time being, here's one easy idea. Devise f
such that it rotates the arguments into a canonical order. The precise nature of the canonicalization may not matter -- here I happen to rotate according to the position of the entry with smallest memory address, but I could also have devised it with a lexicographic measurement.
restart;
f:=proc(x,y,z)
local addr,i,m;
addr:=map(:-addressof,[x,y,z]);
m:=min[':-index'](addr);
'procname'([x,y,z][[seq(`if`(m+i>3,(m+i) mod 3,
m+i),i=0..2)]][]);
end proc:
f(a,b,c)-f(c,a,b), f(a,b,c)-f(b,c,a), f(a,b,c)-f(a,c,b);
0, 0, f(a, b, c) - f(a, c, b)
That gets the results you described, as a consequence of the following behavior.
f(a,b,c), f(b,c,a), f(c,a,b);
f(a, b, c), f(a, b, c), f(a, b, c)
f(a,c,b), f(b,a,c), f(c,b,a);
f(a, c, b), f(a, c, b), f(a, c, b)
You can see that the call f(c,b,a)
actually returns the result f(a,c,b)
. Now, it's possible that you would also desire that,
f(a,b,c) - f(c,b,a)
returns as exactly that same expression. But the code above will return it as f(a,b,c) - f(a,c,b)
. If that is a problem for you then let me know. I can envision two other mechanisms, which involve changing how -
works.
The first is to rebind -
to be procedure that can inspect the calls to f
, while still returning them unevaluated (identical to the inputs) if they don't cancel each other arithmetically. This would just affect -
when you call it from the top level. It wouldn't always affect how -
works when called within other stock Library commands.
Another way would be to construct the calls to f
as objects
which export their own static -
method.