У меня есть некоторые символы, которые должны быть некоммутативными, но я не хочу помнить, какие выражения имеют такое поведение при построении уравнений.
У меня была мысль использовать MakeExpression, чтобы воздействовать на необработанные блоки, и автоматически повышать множитель до некоммутативного умножения, когда это необходимо (например, когда некоторые символы являются некоммутативными объектами).
Мне было интересно, имел ли кто-нибудь опыт работы с такого рода конфигурацией.
Вот что у меня так далеко:
(* Detect whether a set of row boxes represents a multiplication *)
Clear[isRowBoxMultiply];
isRowBoxMultiply[x_RowBox] := (Print["rowbox: ", x];
Head[ToExpression[x]] === Times)
isRowBoxMultiply[x___] := (Print["non-rowbox: ", x]; False)
(* Hook into the expression maker, so that we can capture any \
expression of the form F[x___], to see how it is composed of boxes, \
and return true or false on that basis *)
MakeExpression[
RowBox[List["F", "[", x___, "]"]], _] := (HoldComplete[
isRowBoxMultiply[x]])
(* Test a number of expressions to see whether they are automatically \
detected as multiplies or not. *)
F[a]
F[a b]
F[a*b]
F[a - b]
F[3 x]
F[x^2]
F[e f*g ** h*i j]
Clear[MakeExpression]
Это, кажется, правильно идентифицирует выражения, которые являются операторами умножения:
During evaluation of In[561]:= non-rowbox: a
Out[565]= False
During evaluation of In[561]:= rowbox: RowBox[{a,b}]
Out[566]= True
During evaluation of In[561]:= rowbox: RowBox[{a,*,b}]
Out[567]= True
During evaluation of In[561]:= rowbox: RowBox[{a,-,b}]
Out[568]= False
During evaluation of In[561]:= rowbox: RowBox[{3,x}]
Out[569]= True
During evaluation of In[561]:= non-rowbox: SuperscriptBox[x,2]
Out[570]= False
During evaluation of In[561]:= rowbox: RowBox[{e,f,*,RowBox[{g,**,h}],*,i,j}]
Out[571]= True
Итак, похоже, что это не из тех вопросов, которые я мог бы условно переписать в ячейки базового выражения; но как это сделать надежно?
Возьмите выражение RowBox[{"e","f","*",RowBox[{"g","**","h"}],"*","i","j"}]
, его нужно переписать как RowBox[{"e","**","f","**",RowBox[{"g","**","h"}],"**","i","**","j"}]
, что выглядит как нетривиальная операция, связанная с сопоставителем шаблонов и набором правил.
Буду благодарен за любые предложения от более опытных со мной.
Я пытаюсь найти способ сделать это без изменения поведения по умолчанию и порядка умножения.
Спасибо! :)
Джо