Un exemple où le plus petit terme lambda normal n'est pas le plus rapide

12

Soit la de -terms définie comme suit:λsizeλ

  • size(x)=1 ,
  • size(λx.t)=size(t)+1 ,
  • size(ts)=size(t)+size(s)+1 .

Soit la complexité d'un λ -term t définie comme le nombre de réductions bêta parallèles de tx à sa forme normale (en utilisant un évaluateur optimal au sens de Levy).

Je cherche un exemple de deux normales λ -termes pour la même fonction où le terme plus est moins complexe.

...

Modifier pour plus de clarté

comme il semble que ce que je demande n'est pas évident, je vais essayer de donner un exemple solide. On pense souvent que la définition "naïve" / "la plus simple" d'une fonction est lente et non optimale. De meilleures performances augmentent la complexité du terme, car vous avez besoin de structures de données, de formules, etc. supplémentaires. Un excellent exemple est fibonacci, qui peut être défini "naïvement" comme:

-- The fixed fibonacci definition
fib_rec fib n =
    if (is_zero x) 
        then 1 
        else fib (n - 1) + f (n - 2)

-- Using church numbers instead of the λ-combinator to get a normal form
fib n = n fib_rec 0 n 

Ceci est souvent considéré comme la définition "la plus simple" de fib, et est très lent (exponentiel). Si nous développons les dépendances de fib(les définitions habituelles pour l'addition du nombre d'églises, pred, is_zero) et le normalisons, nous obtenons ce terme:

fib = (λa.(a(λbc.(c(λdef.f)(λde.d)(λde.(de))
      (λde.(b(λfg.(c(λhi.(i(hf)))(λh.g)(λh.h)))
      d(b(λfg.(c(λhi.(i(h(λjk.(k(jf))))))(λhi.g)
      (λh.h)(λh.h)))de)))))(λbc.c)a))

Des améliorations telles que des tables de mémorisation rendraient ce terme plus long. Pourtant, il existe un terme différent qui est beaucoup plus petit ...

fib = (λa.(a(λb.(b(λcde.(e(λfg.(cf(dfg)))c))))
      (λb.(b(λcd.(cd))(λcd.d)))(λbc.b)))

et, curieusement, elle est également asymptotiquement supérieure à la naïve qui court O(N). De toutes les définitions que je connais, c'est à la fois la plus rapide et la plus simple . Le même effet se produit avec le tri. Les définitions "naïves" telles que le tri à bulles et le tri par insertion sont souvent développées en termes énormes (20+ lignes de long), mais il existe une petite définition:

-- sorts a church list (represented as the fold) of church numbers
sort = λabc.a(λdefg.f(d(λhij.j(λkl.k(λmn.mhi)l)(h(λkl.l)i))
       (λhi.i(λjk.bd(jhk))(bd(h(λjk.j(λlm.m)k)c))))e)(λde.e)
       (λde.d(λfg.g)e)c

Ce qui se trouve également être plus rapide, asymptotiquement, que toutes les autres définitions que je connais. Cette observation me porte à croire que, contrairement à la croyance commune, le terme le plus simple, avec la plus petite complexité de Kolmogorov, est généralement le plus rapide. Ma question est essentiellement de savoir s'il existe des preuves du contraire, bien que j'aurais du mal à le formaliser.

MaiaVictor
la source
3
Non a une complexité sqrt (n). n!=n.n1....2.1
T ....
2
Je suis sûr que vous pouvez coder la division d'essai par un terme court que l'algorithme AKS. λ
Emil Jeřábek du
2
Je suis d'accord avec @ EmilJeřábek et, en fait, je ne vois pas comment un exemple n'est pas obtenu en regardant les algorithmes de tri, comme vous l'avez déjà fait: le -term implémentant le tri à bulles n'est-il pas plus court que le -term implémentant , disons, sorte de tas? Ou, je ne sais pas, une recherche par force brute, super courte à implémenter mais à temps exponentiel, contre un algorithme de polytime intelligent nécessitant plus de lignes de code ...? Je dois manquer quelque chose, j'ai bien peur de ne pas vraiment comprendre la question. λλλ
Damiano Mazza
1
Je n'ai fait aucun effort pour l'écrire, mais comme principe heuristique, les longueurs relatives de deux algorithmes ne sont généralement pas très affectées par le choix du langage de programmation, et je ne vois absolument aucune raison -calculus devrait être une exception . Notez en particulier que la normalisation est un sujet de redingue ici: la façon la plus naturelle d'exprimer des algorithmes dans -calculus donne des termes normaux dès le départ, et de toute façon, l'IIRC d'après mon expérience avec Unlambda, vous pouvez transformer n'importe quel terme en un durée normale de longueur similaire donnant le même résultat lors de l'application. λλλ
Emil Jeřábek,
2
Et oui, comme le mentionne Damiano, AKS n'était qu'un exemple. La même chose devrait tenir dans plus ou moins toute situation où nous avons un algorithme inefficace trivial, et une solution efficace mais beaucoup plus sophistiquée du même problème.
Emil Jeřábek

Réponses:

10

Le théorème d'accélération de Blum est généralement énoncé dans le langage des fonctions partiellement récursives, mais jusqu'aux différences triviales de notation, il fonctionne de la même façon dans le langage de -calculus.λ

Il dit que compte tenu de toute mesure de complexité raisonnable (par exemple, le nombre optimal de réductions comme dans la question) et d'une fonction récursive (par exemple, ), nous pouvons trouver un prédicat récursif tel que:f ( x , y ) 2 y P ( x )Mf(x,y)2yP(x)

Pour chaque algorithme (c'est-à-dire -term sous forme normale ici) calculant , il existe un autre algorithme pour qui a accélération sur : g P h P f g f ( x , M ( h , x ) ) M ( g , x )  pour toutes les entrées suffisamment grandes  x ,λgPhPfg

f(x,M(h,x))M(g,x) for all large enough inputs x,

où désigne la complexité du calcul de à l' entrée en fonction de la mesure .g x MM(g,x)gxM

Par conséquent:

  • P n'a pas d'algorithme asymptotiquement optimal dans la mesure donnée

  • en particulier, l'algorithme le plus court pour n'est pas asymptotiquement optimalP

  • pour tout algorithme pour , il existe un algorithme asymptotiquement plus rapide dont la forme normale est plus longue (car jusqu'au renommage des variables, il n'y a qu'un nombre fini de termes normaux d'une longueur donnée)P

Emil Jeřábek
la source