//@
es un "traspaso de árbol posterior a la orden". Visita cada nodo en una estructura de árbol, los hijos de cada nodo son visitados antes que el nodo en sí. La función suministrada se llama con cada nodo como su argumento, los hijos del nodo ya han sido "expandidos" por una llamada previa. Las estructuras de datos de árbol son comunes, junto con la necesidad de atravesarlas. Pero me atrevo a decir que el caso de uso primario para //@
en un contexto de Mathematica es implementar evaluadores.inicio
Vamos mediante la creación de una expresión con estructura de árbol al azar:
In[1]:=
$expr = 500 //.
n_Integer /; RandomInteger[100] < n :>
RandomChoice[{p, m}] @@ RandomInteger[Floor[n/2], 2]
$expr//TreeForm
Out[2]= p[m[p[34, 22], m[11, 24]], p[m[6, 7], 10]]

Digamos que queremos crear un evaluador para un mini-idioma con expresiones de esta forma, donde p
medios "más" y m
significa menos. Podemos escribir un evaluador de descenso recursivo para este mini-lengua así:
In[4]:=
eval1[p[a_, b_]] := eval1[a] + eval1[b]
eval1[m[a_, b_]] := eval1[a] - eval1[b]
eval1[a_] := a
In[7]:=
eval1[$expr]
Out[7]= 78
Se vuelve tedioso tener que escribir de forma explícita las llamadas recursivas a eval1
en cada una de las reglas. Además, es fácil olvidarse de agregar la llamada recursiva en una regla. Consideremos ahora la siguiente versión del mismo evaluador:
In[8]:=
eval2[p[a_, b_]] := a + b
eval2[m[a_, b_]] := a - b
eval2[a_] := a
El "ruido" de las llamadas recursivas se ha eliminado de manera que las reglas son más fáciles de leer. ¿Seguramente podemos encontrar alguna manera de insertar automáticamente las llamadas recursivas necesarias? Introduzca //@
:
In[11]:=
eval2 //@ $expr
Out[11]= 78
No sólo lo que necesita. Con un ligero abuso de la terminología tomada de la programación funcional, podemos decir que hemos elevado eval2
para que sea una función de descenso recursivo. Puedes ver el efecto en el siguiente diagrama.
In[12]:=
"eval2" //@ $expr // TreeForm

PostScript
En Mathematica siempre hay muchas maneras de lograr un efecto. Por esta evaluador juguete, toda la discusión anterior es una exageración:
In[13]:=
$expr /. {p -> Plus, m -> Subtract}
Out[13]= 78
... aunque sólo fuera siempre tan fácil de comprobar si un evaluador estaba dando los resultados correctos :)
http: // libros .google.com/libros? id = 3OtUpdFiXvkC y pg = PA525 y lpg = PA525 y dq = Mathematica + mapall y fuente = BL & ots = hQBU27AfXZ y sig = LI3VDlvNq4AkVIDA_IgzUJFBPaQ & hl = es & ei = vHawTYroJY-w0QHauKiiCQ & SA = X & oi = book_result y ct = resultado # v = OnePage y q = Mathematica% 20mapall & f = false –
tengo una Es difícil tratar de recordar si lo he usado en absoluto ... –
Gracias a todos por sus respuestas. Me costó mucho elegir cuál aceptar. –