TRIZ, Haskell et la pensée fonctionnelle

Au mot TRIZ, on rappelle souvent la thèse «un système idéal est un système qui n'existe pas (et sa fonction est remplie)». Comme un bon administrateur qui n'apparaît pas au bureau, mais tout fonctionne correctement.


La fonction et le système sont des concepts essentiels dans TRIZ, ils parlent même d'un style de pensée fonctionnel. Certes, avec ces mots, je m'associe immédiatement aux langages de programmation fonctionnels.


Essayons de voir comment les idées de la pensée fonctionnelle de TRIZ sont affichées de manière organique sur Haskell, l'un des purs langages fonctionnels à usage général.



Fonction


Fonction - un modèle de modification de la propriété d'un objet fonction ("produit") par un support de fonction ("outil").


Un outil est quelque chose avec lequel nous travaillons, c'est-à-dire Nous changeons quelque chose. En règle générale, c'est elle qui doit être améliorée ou créée. En conséquence, c'est le porteur de la fonction que l'on entend généralement par le mot "système" dans tous les arguments de TRIZ à son sujet.


Un produit est ce que nous changeons (processus) avec un outil.



La fonction principale est une propriété de consommation pour laquelle un système technique est créé.


La fonction elle-même est généralement définie par un simple verbe, reflétant l'essence du processus (pas un terme spécial, afin de ne pas interférer avec l'inertie de la pensée), le porteur et l'objet de la fonction sont inclus dans la formulation.


Par exemple: un marteau déplace un clou; un balai déplace les déchets; la tasse contient du café; l'aspirateur déplace la poussière; le carburant déplace la fusée.


Considérez en particulier une tasse de café.
Une tasse contient du café.
Le porteur de la fonction (outil) est une tasse, l'objet de la fonction est le café, la fonction est de tenir.



--        -- ,       -  hold :: Cup -> Coffee -> Coffee --   hold - ""         cup `hold` coffee 

La fonction de maintien doit être polymorphe, car une tasse peut contenir non seulement du café et le café peut être versé non seulement dans une tasse:


 --        b,      b hold :: a -> b -> b --  ,      thermos `hold` coffee --  ,      shirt `hold` coffee 

L'outil et le produit peuvent changer, et l'essence de leur interaction, exprimée par la fonction, reste la même. Selon les statistiques, la plupart des fonctions de paire entre les éléments des systèmes techniques peuvent être décrites par trois douzaines de verbes (déplacer, maintenir, chauffer, absorber, informer, etc.). Chacun d'eux du point de vue de l'implémentation de Haskell est une fonction polymorphe. Comme, cependant, le reste des verbes du langage naturel.


Fonction inverse


Dans le monde réel, il y a toujours la fonction opposée - l'action du produit sur l'instrument (personne n'a annulé la troisième loi de Newton).



Par exemple, le métal traité émousse la perceuse, un élève négligent fatigue l'enseignant et le fichier réduit l'espace disque libre.
Dans l'exemple du café, il chauffe et tache la tasse.



En règle générale, la fonction inverse nous nuit (usure de l'outil, coûts supplémentaires), mais dans d'autres situations, nous pouvons en bénéficier. Par exemple, réchauffez vos mains sur une tasse chaude dans une pièce fraîche.


 hold:: a -> b -> b warm :: a -> b -> b cup `hold` coffee coffee `warm` cup 

Chaînes de fonctions


Dans le cas où le nombre d'éléments du système est supérieur à deux (c'est-à-dire, en fait, toujours), ils sont considérés par paires, recevant des chaînes de fonctions.


Par exemple, dans la figure ci-dessous, une main porte (déplace) un plateau avec une tasse, un plateau contient une tasse et une tasse contient du café.



 ((arm `move` wrist) `hold` cup) `hold` coffee 

Supprimer les parenthèses en spécifiant l'associativité gauche


 infixl 9 hold arm `move` wrist `hold` cup `hold` coffee 

L'enregistrement en Haskell est très proche de l'enregistrement en langage naturel.


Et la chaîne dans le sens inverse: le café chauffe la tasse, la tasse chauffe la soucoupe, la soucoupe charge la main.


 infixl 9 warm, weight coffee `warm` cup `warm` wrist `weight` arm 

La compréhension de la fonction principale et des interactions entre les éléments vous permet de choisir de manière optimale les limites du système, d'inclure uniquement ce qui est nécessaire pour terminer la tâche cible (sans rien manquer) et de ne pas compliquer le modèle au-delà de ce qui est nécessaire.


Un système qui n'existe pas ...


Nous avons besoin d'une fonction, ou plutôt du résultat de son application, et l'outil lui-même n'est pas nécessaire. C'est un consommable, attiré uniquement par nécessité.


Le café peut être tenu par un cezve, une théière, un thermos, une soucoupe et une table et une chemise (si du café est renversé par inadvertance).


Cela ne nous dérangerait même pas si le café lui-même se maintenait. Comment cela se produit, par exemple, avec de l'eau en apesanteur dans une station spatiale.



Cependant, il n'est pas habituel de s'attarder sur des formulations en boucle comme «le café contient du café» dans TRIZ, car il est inutile d'un point de vue pratique - il ne fournit pas d'informations sur les éléments par lesquels le résultat est obtenu.


Du point de vue de la programmation, une telle formulation récursive est mauvaise en ce sens qu'il n'y a aucune condition pour mettre fin à la récursivité.


Il est nécessaire d'aller plus loin et d'indiquer quelles parties (sous-systèmes) assurent l'accomplissement de la fonction.


Le liquide prend une forme compacte à gravité nulle en raison des forces de tension superficielle. T.O. une description plus appropriée de la situation serait: la couche de surface contient le volume interne du café.


Vous pouvez imaginer le volume entier de café comme une matriochka de couches, chacune se tenant. Dans ce cas, le travail principal est effectué par la couche externe.



 --    - ,  -   let coffee = [layer1, layer2, layer3, layer4, layer5] head coffee `hold` tail coffee 

Cependant, s'il est important pour nous que les couches s'influencent mutuellement (par exemple, en termes d'absorption de la lumière),
on peut inventer un vélo et décrire explicitement les interactions séquentielles.


La nature récursive du phénomène est préservée, mais en comprenant les interconnexions des sous-systèmes, nous pouvons fixer les conditions de sortie de la récursivité et en faire notre service.



 --  "",      hold :: String -> String -> String hold tool "" = tool hold tool workpiece = tool ++ " -> holds -> " ++ workpiece --  " ". --        --     "" --       selfHold :: [String] -> String selfHold [] = "" selfHold (x:xs) = x `hold` selfHold xs --     selfHold ["Layer1","Layer2","Layer3"] 

à la fin, nous obtenons


Layer1 -> hold -> Layer2 -> hold -> Layer3

Le caractère récursif de la mise en œuvre n'a disparu nulle part, mais il est devenu constructif et n'est pas obsédé sans signification.


La même chose peut être écrite en bref, par la convolution de la liste:


 foldl1 hold ["Layer1","Layer2","Layer3"] 

Conclusion


La vision d'un système technique comme un tissu de fonctions qui l'unissent et déterminent l'essence et le but de TRIZ est extrêmement liée à TRIZ avec des langages de programmation fonctionnels, dans lesquels une fonction est la principale structure de contrôle.


L'approche considérée est une bonne aide en termes de décomposition du problème et de contrôle de la complexité du modèle.

Source: https://habr.com/ru/post/fr414929/


All Articles