用 属性 定义函数 f(a,b,c) = f(c,a,b) = f(b,c,a)

Define function with property f(a,b,c) = f(c,a,b) = f(b,c,a)

是否可以在 Maple 中定义一个函数(或运算符)属性 f(a,b,c) = f(c,a,b) = f(b,c,a) ,但不需要其他情况,例如 f(a,b,c) = f(a,c,b)。 在 Maple 中它应该像这样工作:

[> 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)

也就是说,函数 f 可以是非对称的,但在替换 [a=b,b=c,c=a]:

下它不应该改变
[> f(a,b,c)-subs([a=b,b=c,c=a],f(a,b,c));
                   0

只是说清楚:问题不是给出这样的函数的例子,而是关于在 Maple 中定义这样的 属性 函数 f ,以便它能像描述的那样工作(Maple 会简化表达式 f(a,b,c)-f(c,a,b) 对任何 a,b,c 为零。

我没有立即看到仅使用 define 命令即可完成此操作的方法。但是还有其他机制。

其中一个棘手的方面涉及让 Maple 的 -(减号)辨别等价性,同时仍然允许所有对 f 到 return 的调用不使用原始参数顺序进行评估。

暂时不考虑这方面的问题,这里有一个简单的想法。设计 f 以便将参数旋转为规范顺序。规范化的精确性质可能无关紧要——这里我碰巧根据具有最小内存地址的条目的位置进行旋转,但我也可以用字典序测量来设计它。

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)

这会得到您描述的结果,这是以下行为的结果。

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)

您可以看到调用 f(c,b,a) 实际上 return 是结果 f(a,c,b)。现在,您可能也希望如此,

f(a,b,c) - f(c,b,a)

return与完全相同的表达式。但是上面的代码将 return 设为 f(a,b,c) - f(a,c,b)。如果这对您来说是个问题,请告诉我。我可以设想另外两种机制,它们涉及改变 - 的工作方式。

首先是将 - 重新绑定为可以检查对 f 的调用的过程,同时如果它们不这样做,仍然 return 将它们未评估(与输入相同) t 在算术上互相抵消。当 you 从顶层调用它时,这只会影响 -。它不会总是影响 - 在其他库存库命令中调用时的工作方式。

另一种方法是将对 f 的调用构造为 objects,它导出自己的静态 - 方法。