Information / Information`InformationValueForm usando Full- ou InputForm

Sep 12 2020

Eu tenho um problema com a Informationfunção embutida para símbolos definidos pelo usuário com StandardForm personalizado no Mathematica 12.1.1.0:

Por exemplo, com as definições de função

ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b___], StandardForm] := Row[{a, b}, " "]
CM::usage = "CM";

a consulta Information[CM]resulta em:

As definições na saída são formatadas usando StandardForm, mesmo sem exibi-lo corretamente. O mesmo problema ocorre quando se define UpValues . Neste ponto, isso torna a caixa de Informações ilegível, mas fica pior quando é usada InterpretationBox. Com

ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b___], StandardForm] := With[{box = ToBoxes[Row[{a, b}," "]]},
    RawBoxes[InterpretationBox[RowBox[{box}], CM[a, b]]]
];
CM::usage = "CM";

Uma chamada para Information[CM]resulta em uma recursão infinita e vários avisos e erros:

Inspecionando os FullFormresultados das Information[CM]revelações

InformationData[Association[
    ...
    Rule["DownValues",Information`InformationValueForm[DownValues,CM,List[RuleDelayed[CM[1,Pattern[a,BlankSequence[]]],CM[a]]]]],
    ...
    Rule["FormatValues",Information`InformationValueForm[FormatValues,CM,List[RuleDelayed[MakeBoxes[CM[Pattern[a,Blank[]],Pattern[b,BlankNullSequence[]]],StandardForm],Format[With[List[Set[box,ToBoxes[Row[List[a,b]," "]]]],RawBoxes[InterpretationBox[RowBox[List[box]],CM[a,b]]]],StandardForm]]]]],
    ...
]]

e com ela a função interna e, claro, não documentada, ...InformationValueFormque é usada para gerar as definições encontradas.

Existe uma maneira de configurar ou manipular Informationou o subjacente InformationValueFormpara exibir as definições de função usando Full- ou InputForm ? Consegui manipular a saída FullForm convertendo os argumentos de RuleDelayedinside InformationValueFormem Strings, mas não fui capaz de anexar essa correção a Informationou InformationValueForm.

Eu não entendo a decisão de design por trás do uso de StandardForm na saída de Informationfunções definidas pelo usuário e toda a situação é basicamente um bug na minha opinião. O verdadeiro problema são as recursões e erros infinitos para funções de formatação mais envolvidas, que podem travar o kernel e / ou front-end. Tendo a documentar minhas funções e às vezes gosto de usar Informationpara me lembrar da ordem dos argumentos. A solução alternativa bastante insatisfatória que estou usando atualmente é desativar Informationminhas funções formatadas usando UpValues:

CM /: Information[CM, opts___] := CM::usage;

Dessa forma, pelo menos tenho acesso à mensagem de uso, mas as definições, opções e todos os outros Informationdados não podem ser acessados ​​com esta solução alternativa.

Respostas

1 N0va Oct 07 2020 at 04:48

Eu encontrei a resposta para minha pergunta no código-fonte de várias funções centrais do Mathematica. Usar a função imensamente útil GeneralUtilities`PrintDefinitionsem eg InterpolatingFunction(ou qualquer outra função central usada BoxForm` ArrangeSummaryBoxpara sua saída formatada) revela a função / variável protegida do kernel BoxForm`UseIcons. Esta parece ser uma variável dinâmica relacionada à BoxFormqual é falsa para as caixas geradas por Information. O código a seguir permite a formatação personalizada no notebook, mas não na saída de Information(incluindo ?e ??) e outros ambientes com BoxForm`UseIcons=False:

MakeBoxes[..., StandartForm] /; BoxForm`UseIcons := ...

Anexar a formatação personalizada em MakeBoxesvez de Formate verificar a variável BoxForm`UseIconsresolve e responde minha pergunta para minha satisfação. Essa solução é de longe a melhor em comparação com minha resposta anterior e o método de escolha para pelo menos algumas funções principais com saída formatada sofisticada. Publiquei esta nova resposta porque a estratégia da solução é diferente da anterior.

É uma pena que este não está documentada ao lado Formatou MakeBoxesou até mesmo uma opção ou padrão dessas funções.

N0va Sep 18 2020 at 06:01

Eu encontrei uma solução um tanto viável com base em UpValues ​​nos métodos / símbolos do usuário problemáticos, por exemplo:

ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b__], StandardForm] := Row[{a, b}, " "]
CM /: Format[CM[a_], StandardForm] := a

Unprotect[CMinfo]; ClearAll[CMinfo];
CMinfo /: Format[CMinfo, StandardForm] = "CM";
Attributes[CMinfo] = {Protected, Constant};
CM /: Information`InformationValueForm[val_, CM, exp_List] := 
 With[{s = ReleaseHold[Hold[exp] /. CM -> CMinfo]}, 
  Information`InformationValueForm[val, CMinfo, s]]
CM /: Information`InformationValueForm[FormatValues, CM, exp_List] := 
 With[{s = {Skeleton[Length[exp]]}}, 
  Information`InformationValueForm[val, CMinfo, s]]
CM::usage = "CM::usage";

que resulta na saída

O símbolo CMinfoé usado em em ...InformationValueForm[...]vez de CMpara evitar a formatação nas definições. A saída de FormatValuesainda está formatada e, portanto, não é muito informativa, portanto, inseri um marcador de posição. Talvez com um pouco mais de trabalho se pudesse fazer o FormatValuestrabalho também.

Esta abordagem funciona bem para mim, mas ainda não estou satisfeito com a necessidade de tais medidas. O Information[...]método deve funcionar fora da caixa em funções de usuário válidas. Portanto, ainda sou a favor de chamar toda essa bagunça de bug, mas agradeço a @Michael E2 por apontar nos comentários sob a pergunta que a tag 'bug' requer verificação. Não li a descrição da tag e usei incorretamente - desculpe por isso.

Observe que ambos Information[CM]e ??CMfuncionam conforme pretendido ao modificar ...InformationValueForm[...], o que, surpreendentemente, não é o caso para a correção apresentada em minha pergunta (cenário CM /: Information[CM] := CM::usage).

As formas especiais de entrada ?e ??não são apenas especial pelo nome, mas também especiais porque upvalues contornar para Informationque novamente apenas soa muito razoável para mim.