Buscar..


Observaciones

Se supone que esto explica el orden de evaluación de la manera más inequívoca posible. Es probable que sea menos adecuado para una introducción a la ejecución de Mathematica. Se basa en el tutorial/Evaluation página de tutorial/Evaluation Mathematica explicando el orden en que se aplican las diferentes reglas y explicando qué funciones son tratadas especialmente por el motor de evaluación.

Contextos de evaluación

En cualquier punto, el código se ejecuta dentro de un contexto. Un contexto consiste en un conjunto de reglas de reemplazo (su diccionario) y una prioridad en la cual deben ser evaluadas. Agrupamos cinco tipos de contextos con diferentes comportamientos y restricciones: * Establecer contexto * Bloquear contexto * Contexto coincidente * Reemplazar todo el contexto * Reemplazar el contexto repetido

Establecer contextos

Un contexto de conjunto es el definido por algún conjunto de operaciones de conjunto [] (la función escrita más comúnmente = ). El ejemplo principal es el entorno de ejecución principal. Su diccionario se modifica cada vez que se ejecuta un Conjunto [] en una variable que, de lo contrario, no es un ámbito. Las otras instancias de Set Contexts surgen de paquetes. Un contexto de paquete está relacionado con su contexto primario, ya que cualquier patrón dentro del paquete también se convierte en patrones dentro del contexto primario, con un prefijo apropiado (una definición foo[x_]=3*x convierte en InnerPackageName\ foo [x _] = 3 * x `).

Los contextos establecidos solo pueden contener reglas que tengan una "etiqueta" asociada, una cadena asociada con la cabeza para identificar la aplicabilidad de la regla más rápidamente. Una aplicación de Set[yyy_,zzz_] determinará una etiqueta al verificar si yyy es un símbolo. Si lo es, entonces es la etiqueta. De lo contrario, comprueba yyy[[0]] , yyy[[0,0]] , y así sucesivamente. Si en algún momento se determina que es un símbolo, entonces se toma como etiqueta. Si, en cambio, es un átomo que no es un símbolo (como Cadena, Entero, Real ...), arrojará un error y no se creará ninguna regla.

Las funciones UpSet (escrito ^= ) y TagSet (escrito /: / = ) (y sus primos UpSetDelayed y TagSetDelayed) permiten asociar una regla con una etiqueta diferente. Existe la restricción de que la etiqueta debe ser un símbolo. UpSet lo asociará con cada uno de los argumentos en la expresión, o su cabeza si son una función con un símbolo para una cabeza. Por ejemplo, llamar a UpSet en f[a,b,c+d,e[f,g],5,h[i][j][k],p_] asociará la regla creada con a , b , e , y h . Los argumentos c+d , 5 y p_ no tendrán nada asociado con ellos, y harán que se muestre un mensaje de error. La asignación seguirá teniendo éxito en cada uno de los argumentos, y (como se aclarará más adelante en el orden de evaluación) seguirá funcionando para casi todos los propósitos. TagSet es como UpSet, pero puede especificar exactamente un símbolo para la etiqueta. El símbolo aún debe ser algo que se pueda establecer mediante Set o UpSet (un símbolo de nivel superior en la cabeza o los argumentos). Por ejemplo, TagSet[f, f[a,b[c]], 2] es aceptable y asociará la definición con f ; TagSet[a, f[a,b[c]], 2] y TagSet[b, f[a,b[c]], 2] también son aceptables, pero TagSet[c, f[a,b[c]], 2] no lo es.

Las reglas dentro de un contexto necesitan una prioridad de aplicación, ya que puede haber muchas reglas que se aplican a una expresión dada. (Esto también es cierto en los contextos ReplaceAll y ReplaceRepeated, pero lo manejan de manera muy diferente). La prioridad generalmente tiene la intención de corresponder a la especificidad del patrón. Dada una expresión a[q][b[c,d],e[f,g]] para evaluar, con la cabeza y los argumentos evaluados de la forma más completa posible (consulte TODO), comience por buscar reglas etiquetadas con b que apliquen; luego las reglas etiquetadas con e ; luego las reglas etiquetadas con a . Dentro de cada conjunto de reglas, se mantiene un orden en aquellas asociadas con un símbolo dado. Las reglas sin espacios en blanco (como f[a,b]=3 ) se colocan automáticamente en la parte superior y se clasifican en orden canónico (el orden de clasificación). Cada vez que se agrega una nueva regla, el núcleo pasará por la lista; Si alguna regla tiene exactamente el mismo LHS, entonces se reemplaza en el lugar. De lo contrario, hace una comparación de especificidad. Si se determina que una regla X que ya está en la lista es "menos específica" que la nueva regla Y, entonces se coloca Y inmediatamente antes de X. De lo contrario, continúa a través de la lista. Si ninguna regla es menos específica, la regla se coloca al final de la lista. La verificación de la especificidad es más complicada y se explica con más detalle en la siguiente sección.

Especificidad de la regla

* Si dos expresiones tienen ninguna instancia de BlankSequence ( __ ), BlankNullSequence ( ___ ), opcional ( : ), Alternativas ( | ), repetida ( .. ), RepeatedNull ( ... ), o argumentos opcionales ( _. ), A continuación, Se pueden comparar estructuralmente. Dados dos árboles de expresión equivalente X e Y, donde todos los espacios en blanco en Y también son espacios en blanco en X, pero X tiene espacios en blanco donde Y no, entonces Y es más específico. * Si dos expresiones son equivalentes, excepto que algunas instancias de _ se han reemplazado con __ en la otra expresión, o __ se han reemplazado con h ___ , entonces la primera es más específica. * Si pelar una más opcional ( : ) (u opcional _. ) Términos da la otra expresión, a continuación, este último es más específico. * Si un cierto conjunto de opciones de Alternativas da la otra expresión, entonces la última es más específica. * Si reemplaza todas las instancias de RepeatedNull[foo] con Repeated[foo] , o Repeated[foo] con foo , da la otra expresión, entonces esta última es más específica * Algunas combinaciones de estas reglas se pueden aplicar a la vez, pero no es actualmente Sepa cuáles son los casos para esto. * Las combinaciones de expresiones tales como _List y {___} teóricamente deben tratarse de manera idéntica, pero la comparación parece ser extrañamente dependiente del contexto, ocasionalmente clasificándolas de una forma u otra.

Bloque de contexto

Un contexto de bloque es más restrictivo, ya que el LHS de una regla en un bloque solo puede ser un símbolo. Es decir, solo las definiciones de la forma f=2+x , no f[x_]=2+x . (Tenga en cuenta que, desde un punto de vista práctico, las funciones aún pueden construirse con definiciones tales como `Set [Bloque está relacionado con su contexto principal, ya que cualquier definición nueva durante la evaluación del Bloque se reenvía al contexto rodeado como de costumbre, pero "ensombrecerá" algún conjunto de variables, proporcionando definiciones que pueden ocultar las del contexto circundante. Las definiciones del contexto circundante aún son accesibles durante la evaluación de la expresión interna. Dado que solo puede haber una definición asociada con un símbolo, no hay una idea de prioridad como el anterior.

Contexto emparejado

Después de que una regla ha sido comparada, hay definiciones vinculadas localmente para las variables. Esto ocurre de manera léxica . Es decir, subsituye en las definiciones vinculadas para las variables en la expresión, sin evaluar nada más. Solo una vez que han ocurrido todas las subdivisiones, comienza a evaluar la expresión, como un todo, desde la parte superior nuevamente. La forma principal en que se crean los contextos emparejados es una regla de un contexto o regla establecido. Por ejemplo, en

g[a_]:=a+x;
f[x_]:=x+g[1];
f[x^2]
(*Yields 1+x+x^2 *)

Al hacer coincidir la regla f[x_] con f[y] , el símbolo x está vinculado al valor x^2 . Realiza una sustitución, pero como no evalúa g , devuelve x^2+g[1] . Luego esto se evalúa nuevamente en el contexto de contexto que lo rodea y se convierte en 1+x+x^2 . La diferencia significativa en la evaluación en un contexto emparejado es que el reemplazo no es recursivo. Cuando sustituye x->x^2 , no se repite incluso en sus propios resultados.

Contextos emparejados también son creados por With , Module , Function y Replace notablemente. Muchas otras funciones las crean internamente, por ejemplo, Plot usa este tipo de contexto al evaluar la expresión que se va a trazar.

Reemplazar contexto repetido

Se crea un Contexto ReplaceRepeated cuando ocurre cualquier aplicación de ReplaceRepeated . Esto es distinto, ya que puede tener cualquier expresión como regla LHS, incluidas las que no tienen etiqueta, como _[_] . En este sentido es el contexto más flexible. También puede incluir varias reglas que pueden entrar en conflicto, por lo que debe mantener una prioridad. Un contexto ReplaceRepeated aplicará la primera regla en la lista primero donde sea aplicable. Si no coincide, pasa al segundo, y así sucesivamente. Si en algún punto una regla coincide, vuelve a la primera regla y comienza de nuevo. Si en algún momento se produce una aplicación de reglas y no se produce ningún cambio, se cerrará, incluso si otras reglas más adelante en la lista realizarían un cambio. Esto significa que cualquier regla menos específica anterior en la lista evitará que se utilicen reglas posteriores. Además, colocar a_->a en el frente de la lista de reglas causará la terminación inmediata de todo el ReplaceRepeated .

Reemplazar todo el contexto

Se crea un Contexto ReplaceAll cuando ocurre cualquier aplicación de ReplaceAll . Su funcionamiento es similar al de ReplaceRepeated en el sentido de que la prioridad de su aplicación de reglas va en orden en la lista cuando dos pueden aplicarse al mismo nivel de la expresión. Sin embargo, es como un contexto coincidente en que los contenidos reemplazados no se evalúan más, ni siquiera por las reglas posteriores . Por ejemplo, x/.{x->y,y->z} produce y . Por lo tanto, es incorrecto ver que una aplicación de ReplaceAll aplica cada regla por turno. En su lugar, atraviesa el árbol, buscando reglas aplicables. Cuando encuentra algo que coincide, ejecuta el reemplazo, luego regresa al árbol, sin atravesar el nuevo árbol. También vale la pena señalar que intenta aplicar reglas de arriba hacia abajo, como resultado posiblemente salirse del orden de la lista. Por ejemplo,

Cos[1 + 2 Sqrt[Sin[x]]] /. {Cos[_] -> 5, Sin[_] :> (Print[1]; 10)}
Cos[1 + 2 Sqrt[Sin[x]]] /. {Sin[_] :> (Print[1]; 10), Cos[_] -> 5}

Ambos rinden 5 sin imprimir nada. Debido a que Cos[_] coincide con un nivel superior del árbol, aplica ese primero.

Hold y Evaluate y la orden de ejecución.

El orden de evaluación, dada una expresión, se desarrolla de la siguiente manera: * Evalúe el encabezado de la manera más exhaustiva posible * Si el encabezado tiene una propiedad de Hold ( HoldFirst , HoldRest , HoldAll , HoldAllComplete ), entonces * Verifique los argumentos relevantes. A menos que sea HoldAllComplete , verifique si la cabeza es Evaluate . Si es así, quita la Evaluate y márcala para que se evalúe de todos modos. * Verifique los argumentos de las instancias de Unevaluated y Unevaluated según sea necesario, a menos que la propiedad HoldAllComplete esté presente. * Aplanar los argumentos de la Sequence s, a menos que se aplique SequenceHold . * Aplique los atributos Flat , Listable , Orderless Listable , según corresponda. * Aplicar la evaluación asociada con los valores superiores del argumento (sus etiquetas) * Aplicar la evaluación asociada con la cabeza.

Cuando se completa la evaluación de una expresión, se marca como totalmente evaluada. Las evaluaciones posteriores que lleguen a esa expresión no intentarán evaluarla. Si se define una nueva regla en un símbolo que aparece dentro, se elimina la bandera y se puede evaluar nuevamente. El lugar notable en que este 'falla' es con Condition ( \; ): una regla condicional posiblemente no se aplique en la evaluación inicial. Si un símbolo no relacionado cambia los valores y ahora la condición es aplicable, la expresión aún está marcada completamente evaluada y no cambiará como resultado. La función Update es única, ya que evaluará su argumento independientemente de su estado ya evaluado o no, lo que obligará a un "vaciado de caché" de clases.

Hay una serie de otras funciones que a menudo son considerados como excepcionales, tales Hold , Defer , ReplacePart , Extract , o ReleaseHold . Todos estos efectos se pueden lograr a través de atributos (como HoldAll ) y la definición de la función normal, y no necesitan ser manejados de forma única por el evaluador.

Aplicación de `ReplaceAll` y` ReplaceRepeated`

Ejemplo de cómo ReplaceAll solo aplica una regla como máximo una vez, mientras que ReplaceRepeated lo hará en un bucle pero siempre reiniciará la aplicación desde la primera regla.

x + a /. {
  a_ + z :> (Print[0]; DoneA),
   a_ + x :> (Print[1]; y + z), 
   a_ + y :> (Print[2]; DoneB)}

(* Prints "1", yields "y+z" *)

x + a //. {
  a_ + z :> (Print[0]; DoneA),
   a_ + x :> (Print[1]; y + z), 
   a_ + y :> (Print[2]; DoneB)}

(* Prints "1", then prints "0", yields "DoneA" *)

Ordenamiento de burbuja

Clasificación de burbujas con reglas y reemplazos:

list = {1, 4, 2, 3, 6, 7, 8, 0, 1, 2, 5, 4}

list //. {fsts___, x_, y_, lsts___} :> {fsts, y, x, lsts} /; y < x

(* 
    Out[1] := {1, 4, 2, 3, 6, 7, 8, 0, 1, 2, 5, 4}
    Out[1] := {0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8}
*)


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow