我想区分表达式并为结果生成Fortran。表达式类似于at(diff(x^2*f(x,y)+y^2*g(x,y),y),x=y)
。结果包含at(diff(f(x,y),y),x=y) and at(diff(g(x,y),y),x=y)
等字词。
在生成Fortran之前,我想删除at函数(我有另一个脚本将diff(f(x,y),y)
和diff(g(x,y),y)
实体转换为子例程调用。因此,我试图编写一个贯穿表达式树的函数,并在找到函数时执行一些特殊操作。但是,如果我比较piece =' at,则总是计算为false,而如果我比较piece =' sin,则正确检测sin函数。我完全不知道为什么没有检测到at-function。
到目前为止我的代码是
eliminateAt(expression) :=
block( [ops,args,result],
if atom(expression)
then expression
else
( ops: op(expression),
args: args(expression),
print("piece=",piece),
if piece='at
then processAt(first(args))
else
(
result: [],
for arg in args do (
result: endcons(eliminateAt(arg),result)
),
apply(ops,result)
)
)
);
processAt(expression) :=
block( [ops,args,result],
print("expression=",expression),
expression
);
如果我将其作为
运行eliminateAt(at(diff(f(x,y),y),x=y));
我得到了
(%i4) eliminateAt(at(diff(f(x,y),y),x=y));
piece= at
piece= derivative
piece= f
piece= =
!
d !
(%o4) -- (f(x, y))!
dy !
!x = y
所以即使作品被打印成" at"函数processAt永远不会被调用。如果我更改了行" if piece =' at" to" if piece =' sin"然后评估
eliminateAt(sin(diff(f(x,y),y)));
我得到了
(%i6) eliminateAt(sin(diff(f(x,y),y)));
piece= sin
d
expression= -- (f(x, y))
dy
d
(%o6) -- (f(x, y))
dy
清楚地表明检测到sin函数没有问题。那么at-function有什么特别之处呢?如何在表达式中找到它?
答案 0 :(得分:1)
您遇到的问题是,当您自己编写Add
时,该符号就是ConcurrentDictionary
所谓的动词形式,而如果您编写'at
,那么该符号是所谓的名词形式。 (是的,那是微妙和令人困惑的。)你可以通过写at
来获得名词形式。
但是一般来说,更好的方法是使用'at(...)
和nounify('at)
或matchdeclare
来处理问题,例如你想要替换表达式中的东西。