8
votes

Modèle pour correspondre uniquement aux "enfants" de certains éléments

J'aimerais pouvoir avoir un modèle qui ne correspond que des expressions qui sont (alternativement: ne sont pas) des enfants de certains autres éléments.

Par exemple, un motif pour correspondre à toutes les s n'est pas dans un graphique objet: xxx

Ce modèle correspondrait {1,2,3} mais pas < code> {{1,2}, {3,4}} .

Il existe des moyens relativement faciles de extraire les expressions correspondant à ces critères, mais les modèles ne sont pas seulement pour l'extraction, mais aussi pour remplacement , qui est mon cas d'utilisation principal ici ( remplaillel ).

Savez-vous de simples, concis, et des moyens généraux de faire cela?

est-il possible de le faire du tout avec des modèles juste?


1 commentaires

Quelle serait la sortie requise correspondant à une entrée comme {{{{1,2,3}}}, cycles [{{1,2,3}, {4,5,6}}], graphiques [ligne [{{ {1,2}, {3,4}}]]}?


4 Réponses :


0
votes

Je suis probablement mal compris, mais si je comprends bien, vous voulez correspondre à toutes les expressions avec la liste de la tête qui ont la propriété qui, en haut dans l'arbre d'expression, nous ne rencontrerons jamais un graphiques . Je ne sais pas comment faire cela en une seule passe, mais si vous êtes prêt à faire correspondre deux fois, vous pouvez faire quelque chose comme xxx

qui sélectionne d'abord des éléments de sorte que la tête n'est pas graphiques (ceci est effectué par cas [#, sauf @ graphiques [___]] & , qui retourne {randhead [5], { 1, 2, {3, 5}}} ), puis sélectionne ceux-ci avec tête à partir de la liste renvoyée. Notez que j'ai ajouté d'autres choses à lst .

Mais vous le savez probablement et j'étais après un seul motif pour faire le travail?


2 commentaires

En fait, j'aimerais que cela fonctionne à n'importe quel niveau de l'expression, mais qui soit facilement corrigé dans votre exemple en utilisant Supprimer pour vous débarrasser de graphiques à n'importe quel niveau. Mais le plus gros problème est que ce dont j'ai besoin est de remplacer: remplacez toute l'expression correspondant à ce "motif" et laissez le reste inchangé. Je suppose que la solution la plus simple possible consiste à trouver les positions des éléments, puis en utilisant remplappart . Mais cela peut également être assez compliqué à la fin.


@Szabolcs Oui Vous avez mentionné cela dans votre question. Eh bien, je ne vois aucune voie directe non plus. Peut-être que quelqu'un d'autre va.



3
votes

Vous pouvez écrire une fonction récursive qui descend une arborescence d'expression et agit sur les types d'expression que vous souhaitez uniquement si dans le bon type de sous-expression, tout en laissant tout le reste. Les modèles seraient fortement utilisés dans la définition de la fonction.

considère, par exemple, l'expression suivante. xxx

Supposons que nous voulions faire pivoter chaque paire commandée Nous voyons dans le premier argument de graphiques sur l'origine via l'angle PI / 4, tout en laissant d'autres points seuls. La fonction suivante est-ce que cela. xxx

Nous vérifions maintenant xxx


0 commentaires

8
votes

Je proposerai une solution basée sur l'expression prétraitement et les redéfinitions douces des opérations à l'aide de règles, plutôt que des règles elles-mêmes. Voici le code:

In[171]:= expr = {{1,2,3},Graphics[Line[{{1,2},{3,4}}]]};

In[168]:= expr/.matchChildren[_Graphics,x_List:>f[x]]//FullForm
Out[168]//FullForm= List[List[1,2,3],Graphics[Line[f[List[List[1,2],List[3,4]]]]]]

In[172]:= expr/.matchChildren[_Graphics,x:{__Integer}:>f[x]]//FullForm
Out[172]//FullForm= List[List[1,2,3],Graphics[Line[List[f[List[1,2]],f[List[3,4]]]]]]

In[173]:= expr/.exceptChildren[_Graphics,x_List:>f[x]]//FullForm
Out[173]//FullForm= List[f[List[1,2,3]],Graphics[Line[List[List[1,2],List[3,4]]]]]

In[174]:= expr = (Tan[p]*Cot[p+q])*(Sin[Pi n]+Cos[Pi m])*(Tan[q]+Cot[q]);

In[175]:= expr/.matchChildren[_Plus,x_Tan:>f[x]]
Out[175]= Cot[p+q] (Cot[q]+f[Tan[q]]) (Cos[m \[Pi]]+Sin[n \[Pi]]) Tan[p]

In[176]:= expr/.exceptChildren[_Plus,x_Tan:>f[x]]
Out[176]= Cot[p+q] f[Tan[p]] (Cos[m \[Pi]]+Sin[n \[Pi]]) (Cot[q]+Tan[q])

In[177]:= Cases[expr,matchChildren[_Plus,x_Tan:>f[x]],Infinity]
Out[177]= {f[Tan[q]]}

In[178]:= Cases[expr,exceptChildren[_Plus,x_Tan:>f[x]],Infinity]
Out[178]= {f[Tan[p]]}

In[179]:= Cases[expr,matchChildren[_Plus,x_Tan],Infinity]
Out[179]= {Tan[q]}

In[180]:= Cases[expr,matchChildren[_Plus,x_Tan],Infinity]
Out[180]= {Tan[q]}


1 commentaires

@Szabolcs Eh bien, ce n'est pas vraiment compliqué, au moins les idées sont simples. J'ai édité le poste et j'ai ajouté un paragraphe expliquant certaines idées et détails de la mise en œuvre.



7
votes

Selon votre explication dans le commentaire à la réponse de l'ACL:

En fait, j'aimerais que cela fonctionne à tout moment Niveau dans l'expression <...>. <...> Ce dont j'ai besoin est de remplacement: remplacer toute expression qui correspond à ceci "motif", et laissez le reste inchangé. Je suppose que le plus simple solution possible consiste à trouver le positions d'éléments, puis en utilisant RemplacerPART CODE>. Mais cela peut aussi obtenir assez compliqué à la fin. P> BlockQuote>

Je pense que cela pourrait être fait en une seule passe avec remplaillel code>. Nous pouvons compter ici sur le Caractéristique documentée du de remplacement code >: Il ne regarde pas les parties de l'expression d'origine déjà remplacée même si elles sont remplacées par elles-mêmes! Citer la documentation: " remplailleLL code> regarde chaque partie de expr code> em>, essaie toutes les règles de la situation, puis passe à la partie suivante de expr code> em>. La première règle qui s'applique à une pièce particulière est utilisée; aucune autre règle n'est essayée sur cette partie ou sur l'un de ses sous-parties. " P> Voici ma solution ( WhaInwant code> est ce que vous voulez faire avec des pièces assorties): p> xxx pré>

Voici votre cas de test: P >

=> {{1, 2, 3}, Graphics[Line[whatIwant[{{1, 2}, {3, 4}}]]]}


2 commentaires

Ah, c'est une belle astuce à pas remplacer les expressions jointes par une certaine autre expression (nous pouvons utiliser y_graphics dans votre exemple ci-dessus). Mais il reste toujours le cas de remplacer les choses seulement à l'intérieur d'une certaine tête. :)


Remplacez dans un remplacement, aussi agréable.