Lazi

compute, nouveau mot clé compute

Cette étude est abandonnée, elle reste comme archive d'exploration d'une voie infructueuse.

Contexte

Le postulat sur "tout ce qui existe" implique d'utiliser un mot clé pour forcer à calculer des valeurs. Pour cela on introduit le mot clé "compute" et on modifie la manière de calculer.

Question

Comment implémenter ce nouveau mot clé dans le logiciel compute ?

Étude

Quand l'exécuter ?

Les arguments sont empilés sur une liste "args". Il serait facile de tester au moment de l'empilement si l'argument est un "compute" et dans ce cas le calculer. Cela implique la récursivité des évaluations (il me semble que ça ne pose pas de problème, il y a déjà le cas pour la condition du if).

Représentation de l'application de "compute"

Pour accélérer la détection de l'application de "compute" à une formule, on pourrait créer un type de formule spéciale représentant "compute x".
Mais alors si on veut utiliser le mot tout seul ? Il faudrait :

  1. soit chercher à reconnaître "compute x" à chaque fois que l'on forme une application
  2. interdire de former de nouvelles applications "compute x"

Solution 1

C'est tellement coûteux qu'avoir une représentation spéciale pour compute n'apporte rien.

Solution 2

Il est juste nécessaire que "compute" soit toujours une fonction d'une application (même s'il y a des variables à l'intérieur). Donc "$F x → compute x" est possible, mais pas "($F c → c a) compute". Comme compute est un mot clé qui n'a rien à voir avec les fonctions normales, il n'est jamais nécessaire qu'il soit ailleurs qu'en tant que fonction d'une application. Donc la solution 2 est la meilleure.

Cohérence avec le code "everything"

La fonction "computeStep" agit différemment de la solution trouvée ici.
Mais la fonction computeStep n'est pas efficace pour le calcul de la partie "fonction" : on récupère les arguments puis on reforme la formule pour chaque argument. computeStep pourrait calquer le fonctionnement de LaziCompute et créer une pile des arguments, même si ça ne sert qu'une fois ça devrait être plus rapide. computeStep calculerait alors les arguments au moment de l'empilement.

Problème avec l'optimisation

Le problème

Le problème est que l'optimisation peut remplacer une application par son résultat, donc le compute n'est plus dans un argument et n'est plus exécuté.
Exemple :
$Let cxf = compute \ computeFormula xf;
$Let cxa = compute \ computeFormula xa;
$T[xt, $T[cxf,cxa]]

Normalement le fait d'utiliser $Let provoque l'utilisation d'une fonction avec ici deux arguments. Mais comme cxf et cxa ne sont utilisés qu'une fois c'est remplacé par l'optimiseur de translate en :
$T[xt, $T[compute \ computeFormula xf,compute \ computeFormula xa]]
qui est pareil que :
pair (xt , pair(compute \ computeFormula xf,compute \ computeFormula xa))

Quand un compute doit-il être réalisé ?

Si les computes sont réalisés quand tout est fini ?

On se place dans le cas où l'on ne fait rien sauf à la fin du calcul normal.
Peut-on avoir le problème de données trop grosses ?
Il faut pour cela que la donnée qui grossit ne soit pas évaluée. Par exemple pour
(recurse $F f,n,x → if(isZero n; x; f(n - 1, x x))) 10000 1b
on aura 210000 x à la fin.
Donc la réponse est oui.
Donc il faut réaliser le calcul du compute en cours d'évaluation.
Pour qu'une sous-formule grossisse, faut-il qu'elle soit passée directement en argument ?
La partie qui grossit peut être intégrée dans une formule, par exemple :
(recurse $F f,n,$T[_,x] → if(isZero n; x; f(n - 1, $T[0b, x x]))) 10000 $T[0b,1b]
mais alors quand on récupère la sous-partie, elle est directement argument.
Pour faire grossir une formule il faut qu'elle soit l'argument d'une fonction, si on prend une sous-partie alors pour extraire cette sous-partie il faut aussi qu'elle soit l'argument d'une fonction. Donc la réponse est oui.

Donc réaliser les compute dans les arguments évite le cas des formules devenant énormes ou des calculs innéficaces par évaluation trop tardive.

Mais il reste alors d'autres "compute x" qui peuvent ne pas avoir été réalisés, voir ci-dessus "Le problème". Pour cela on peut parcourir la formule et réaliser les computes.

Voir "compute x" comme un apply ?

On peut voir "compute" comme un mot ou encore "compute x" comme un "formula_shell" transparent servant d'indication d'ordre dans le calcul.
C'est important pour les représentations.

Cohérence avec lazi : lazi se représente lui-même et peut aussi représenter son calcul. La question apparaît alors aussi et il serait bon d'avoir une cohérence entre laziCompute et lazi. Pour lazi les deux solutions sont aussi possible : un autre mot clé ou un type de formule en plus. Il me semble qu'un type de formule est plus cohérent car il n'y a pas de règle pour compute. Donc il faudrait changer son implémentation et utiliser par exemple la notation $Comp[...].

Mais alors dans les 1-formules lazi il faut ajouter la notion de formule_shell. Mais par exemple pour l'égalité, il faut distinguer l'égalité des formules et l'égalité des objets (défini par unionT).

Réponse

  • compute est exécuté à l'empilement des arguments
  • on fait la même chose pour le computeStep de everything
  • on crée un nouveau type de formule signifiant "compute x"
  • compute ne peut être utilisé sans être une fonction d'une application