Aplicar una regla particular a una función mantenida (o no evaluada) en Mathematica

CorePress2024-01-24  10

Soy un usuario muy novato de Mathematica y todavía no puedo entender su control de evaluación, todas las construcciones posibles relacionadas con él (por ejemplo, Mantener, No evaluado, etc.) y cómo funcionan, a pesar de la documentación exhaustiva y los numerosos Preguntas de StackExchange y StackOverflow que tratan este tema. Así que nos disculpamos por los posibles duplicados.

Mi caso de uso es el siguiente: tengo una función (digamos f) definida por miles de reglas y patrones (DownValues). Quiero comenzar desde una representación desenrollada de f[expr] (para alguna expr) y obtener el resultado de aplicar una regla única y particular a f[expr]. Quiero que el resultado también permanezca desenrollado.

Como ejemplo particular, supongamos que tenemos lo siguiente:

 In[1]: nat[0] := 0
 In[2]: nat[n_] := 1 + nat[n - 1]
 In[3]: DownValues[nat]
Out[3]: {HoldPattern[nat[0]] :> 0, HoldPattern[nat[n_]] :> 1 + nat[n - 1]}
 In[4]: nat[10]
Out[4]: 10

Ahora quiero comenzar con una expresión representadad como nat[10] (¡sin evaluar!) y desea aplicar específicamente la segunda regla (HoldPattern[nat[n_]] :> 1 + nat[n - 1]) para obtener la expresión en la forma de 1 + nat[ 9]. De manera análoga, si quisiera aplicar la primera regla (HoldPattern[nat[0]] :> 0), esperaría que el resultado se mantuviera sin cambios en su forma original, es decir, nat[10].

¡Gracias por tu ayuda!

Esta pregunta también se hizo en StackExchange de Mathematica aquí.

-momo_vn

31 de marzo de 2021 a las 15:37



------------------------------------

Esto debería ayudarle a comprender el método de operación de Mathematica.

Referencia de Wolfram: El orden de las definiciones

Es decir Mathematica "busca el valor de una expresión de la forma f[n], prueba primero el caso especial f[1], y sólo si esto no se aplica, prueba el caso general f[n_]."

Entonces, con las funciones siguientes, nat[0] siempre se prueba primero, pero, por supuesto, solo se evalúa si el argumento es 0. Luego se prueba nat[n_].

nat[0] := 0
nat[n_] := 1 + nat[n - 1]

Para tu pregunta sobre cómo obtener 1 + nat[9] aquí tienes una forma

Clear[nat]

nat[0] := 0
nat[n_] := HoldForm[1 + nat[o]] /. o -> n - 1

ans = nat[10]

1 + nat[9]

Do[ans = ReleaseHold[ans], 10]

ans

10

Alternativamente (y mejor)

Clear[nat]

nat[0] := 0
nat[n_] := With[{m = n - 1}, HoldForm[1 + nat[m]]]

ans = nat[10]

1 + nat[9]

Do[ans = ReleaseHold[ans], 9]

ans

9 + (1 + nat[0])

Tenga en cuenta que este es el resultado después de 10 iteraciones. El ReleaseHold final da como resultado que nat[0] se evalúe como 0.

ReleaseHold[ans]

10

Puede que le resulte más fácil ver lo que sucede si usa Hold en lugar de HoldForm en la demostración anterior.



------------------------------------

Como se publicó como respuesta en una discusión paralela en StackExchange de Mathematica, encontré una forma relativamente más directa y sencilla de abordar el problema:

 In[6] rules = DownValues[nat]                                                 
Out[6] {HoldPattern[nat[0]] :> 0, HoldPattern[nat[n_]] :> 1 + nat[n - 1]}

 In[7] DownValues[nat] = {}                                                    
Out[7] {}

 In[8] nat[10]                                                                 
Out[8] nat[10]

 In[9] nat[10] /. rules[[1]]                                                   
Out[9] nat[10]

 In[10] nat[10] /. rules[[2]]                                                  
Out[10] 1 + nat[9]

1

nat[10] /. reglas[[1]] en realidad no está haciendo nada con la regla 1. La regla 1 solo opera en nat[0]. Todo lo que está viendo es la entrada entregada como salida, sin reemplazo. Además, si todavía tiene definiciones para nat, entonces nat[10] se evalúa como 10 antes de intentar cualquier reemplazo. Mathematica tiene un sistema para evaluar funciones sombreadas, como mencioné en mi respuesta. La elección de qué regla se utiliza sigue este sistema.

- Chris Degnen

31 de marzo de 2021 a las 21:52

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare