第三条原则:表达式求值
上一个例子使我们来到第三条原则:表达式求值以及改写规则(全局规则库)原则。它其实是这样的:当Mathematica 遇到某一个表达式时,它首先会在全局规则库里寻找匹配某一段表达式的规则。一个典型的改写规则看上去是这样的:对象1->对象2。如果能找到这样一个规则,对于这条表达式或它的子表达式(其实是先从子表达式开始),(子)表达式会被重写,然后这一过程再次重复。这一过程会一直进行下去,直到全局规则库中没有一条规则能够匹配这条表达式或它的任何一个部分。当表达式无法再发生变化时,它就被当作结果返回给用户。请记住这一流程其实已经被极度简化,真正的求值过程要更加细致琐碎,但主要的思路就是这样的。 全局规则库中同时包含内嵌进核的规则以及用户自定义的规则。用户定义的规则优先级比系统自带规则更高,这使得在必要情况下我们可以重新定义几乎所有的内置函数。事实上,所有对变量的赋值以及对函数的定义都被以某种全局规则的形式储存起来。从这种意义上来说,函数和变量之间其实没有本质上的区别(虽然在作用上还是有区别的)。
这样的结果就是,我们会得到如下的结果:
In[X]:= FullForm[Sin[Pi+Pi]]
Out[X]:= 0
产生这个结果的原因在于在核内部有像Plus[x,x]->2x,Sin[2*Pi]->0这样的规则,而且由于求值过程默认是从最内部(叶)开始的,因而在FullForm函数有机会“看到“表达式之前0已经产生了。内部的求值过程可以用Trace命令查看:
In[X]:= Trace[FullForm[Sin[Pi+Pi]]]
Out[X]:= {{{Pi+Pi, 2Pi}, Sin[2*Pi], 0}, 0}
注意:如果有多少表达式时,Mathematica自行根据算法排序,结果和我们想像的不一样。最好一个函数就一个表达式,真的有多个表达式也最好互斥。以后会遇到这种情况。