问题
I have a function that returns equalities, which I want to print, for example, x==y, or 2x+5==10. These usually have no meaning for mathematica, it cannot simplify it furhter.
However, sometimes the both sides are equal, but I want to be able to print the equality in unevaluated form: that is, I want Mathematica to print x==x, and not True.
A very simple example:
Print[printableEqual[x,y]]
should print x==y, while
Print[printableEqual[x,x]]
should print x==x
Edit: The reason is that I have a relation among graphs. I would like to return things like
G1 == t*G2 + s*G3
where t,s are integers, and Gi are Graphics objects in Mathematica. Just returning this works great, (Since Mathematica cannot simplify such things) EXCEPT G1 == G1 which will be True.
The trouble is that using Defer, or HoldForm gives
Private`lhs$714 == Private`rhs$714
as output, that is, the private variables in my package is not evaluated as my Graphics.
回答1:
You can use Defer to do this:
In[5]:= printableEqual[x_, y_] := Defer[x == y];
In[6]:= printableEqual[1, 2]
Out[6]= 1 == 2
回答2:
Another trick is to just use Unevaluated:
In[1] := Print[Unevaluated[1 == 1]]
1==1
回答3:
Usually one uses HoldForm
for this sort of thing. HoldForm
is a head that works like Hold
, in that it doesn't evaluate its contents, but it's not displayed when it's printed as output, like so:
In[1]:= HoldForm[x == 3]
Out[1]= x == 3
In[2]:= HoldForm[x == x]
Out[2]= x == x
As with Hold
, you can interpolate things into a HoldForm
using With
or function argument substitution, like so:
In[3]:= PrintableEqual[x_, y_] := HoldForm[x == y]
In[4]:= PrintableEqual[x, x]
Out[4]= x == x
However, this will mean that the arguments are evaluated before substitution, like so:
In[5]:= PrintableEqual[x + x, 2 x]
Out[5]= 2 x == 2x
If you don't want this to happen, you can use SetAttributes
and HoldAll
:
In[6]:= SetAttributes[PrintableEqual, {HoldAll}]
In[7]:= PrintableEqual[x + x, 2 x]
Out[7]= x + x == 2 x
Note that HoldForm
is always there, it's just not displayed in output form:
In[8]:= PrintableEqual[x, x] // InputForm
Out[8]= HoldForm[x == x]
If you want to evaluate things, use ReleaseHold
:
In[9]:= ReleaseHold@PrintableEqual[x, x]
Out[9]= True
回答4:
Another thing you can do is to is use Grid[]
to align all of your equalities - the added advantage is that since you don't actually create expressions with Equal[]
, you don't have to prevent their evaluation.
In[1]:= Grid[Table[{LHS[i],"\[LongEqual]",RHS[i]},{i,2}],
Alignment -> {Right,Center,Left}]
Out[1]= LHS[1] == RHS[1]
LHS[2] == RHS[2]
On a similar vein, you could manually typeset using
printableEqual[LHS_, RHS_] := Row[{LHS, " \[LongEqual] ", RHS}]
or more generally
printableEqual[LHS_, mid___, RHS_] := Row[Riffle[{LHS, mid, RHS}, " \[LongEqual] "]]
By the way, the output from the printableEqual[]
defined above can be converted back to a real Expression using ToExpression[ToString[#]]&
or something like
toRealEqual[Row[lst_List]] := Equal@@lst[[1;;-1;;2]] /; OddQ[Length[lst]] && Union[lst[[2;;-2;;2]]] == {" \[LongEqual] "}
来源:https://stackoverflow.com/questions/4851948/return-equality-from-mathematica-function