2010-04-19 14 views
5

Mi problema es con un cierto estilo de código que se parece mucho a la recursión, pero no es bastante eso. Recursion es, citando Wikipedia, "un método para definir funciones en las que la función que se está definiendo se aplica dentro de su propia definición". De manera similar, la recursión mutua aplica otra función que, directa o indirectamente, aplica la función que estamos definiendo.¿Cómo se llama este tipo de "recursión" mutua?

¡El problema es que el código que estoy pensando y con el que trato no utiliza la misma función! Utiliza el mismo código en otra función (como método o cierre).

El problema aquí es que aunque mi código es el mismo, las funciones no lo son. Echar un vistazo a la siguiente ejemplo básico recursión mutua:

def is_even(x): 
    if x == 0: 
     return True 
    else: 
     return is_odd(x - 1) 

def is_odd(x): 
    if x == 0: 
     return False 
    else: 
     return is_even(x - 1) 

Esto es algo intuitivo, y muy claramente mutuamente recursivo. Sin embargo, si envuelvo cada función como una función interna que se crea una vez cada llamada, se vuelve menos claro:

def make_is_even(): 
    def is_even(x): 
     if x == 0: 
      return True 
     else: 
      return make_is_odd()(x - 1) 
    return is_even 

def make_is_odd(): 
    def is_odd(x): 
     if x == 0: 
      return False 
     else: 
      return make_is_even()(x - 1) 
    return is_odd 

def is_even2(x): 
    return make_is_even()(x) 

def is_odd2(x): 
    return make_is_odd()(x) 

Haciendo caso omiso de optimizaciones como memoization implícita etc., esto produce una cadena de llamadas a funciones que no está estrictamente recursivo, creando y llamando varias funciones nuevas sin llamar al mismo dos veces. Sin embargo, todas estas funciones siguen una plantilla común, y son la misma función creada una y otra vez (posiblemente con diferentes variables libres.

Y de nuevo, podemos llegar a un equivalente directo (después de todo, las clases son realmente justas) cierres, derecha;) implementación usando clases Esto es especialmente significativo, ya que este estilo de [insertar nombre aquí] se usa, por ejemplo, en el Composite Pattern. La diferencia es que con el patrón de diseño compuesto, y la mayoría de los usos (incluso de los cierres), las instancias generalmente no se crean sobre la marcha. Sigue siendo esencialmente el mismo.

class EvenChecker(object): 
    def check(self, x): 
     if x == 0: 
      return True 
     else: 
      return OddChecker().check(x - 1) 

class OddChecker(object): 
    def check(self, x): 
     if x == 0: 
      return False 
     else: 
      return EvenChecker().check(x - 1) 

def is_even3(x): 
    return EvenChecker().check(x) 

def is_odd3(x): 
    return OddChecker().check(x) 

This el tiempo de la cadena es de creación de objetos y llamadas a métodos, pero el principio es el mismo. (Realmente notaría que es ligeramente diferente, en que Python define un envoltorio simple por objeto que a su vez llama a la misma función cada vez-- pero esto no es necesariamente algo que necesitemos saber, y no lo hace t necesidad de ser cierto para otras implementaciones de clases y objetos. Pero sí, en sentido estricto es mutuamente recursivo, así como ... algo más, y es esa otra cosa que quiero saber.)

Respuesta

2

Como usted señala, esto sigue siendo recursividad mutua. No creo que el "algo más" sobre el que preguntas tenga un nombre; si lo hace, nunca lo escuché.

+0

El último ejemplo solo es ciertamente recursividad mutua porque cada llamada de método en Python está contra un contenedor (método de instancia), que llama a una función-- esta función es la que usted definió en su clase, y solo hay una. Así que la cadena de llamadas podría verse así: '[is_odd3 (3)] -> [método-instancia [OddChecker.check] (3)] -> [OddChecker.check (self, 3)] -> ... - > [OddChecker.check (self, 1)] -> ... -> True'. Esto es mutuamente recursivo, sigue llamándose a sí mismo. Pero, por ejemplo, para los cierres uno, o para el mismo ejemplo OO pero en E, la misma función nunca se llama nuevamente. –

1

al parecer, se llama Mutual Recursion :)

el artículo da incluso el mismo ejemplo que usted, con odd? y even? funciones.

+0

Ha perdido el quid de la cuestión. Usó el mismo ejemplo que mi * primer * ejemplo. Esa que llamé específicamente "recursión mutua". Son los otros que me preocupan. –

+0

Sí, pero sus otros ejemplos aún usan la misma idea fundamental. –

+0

sí, pero con un giro: las recursiones recíprocas devuelven a la misma función, pero no es así. –