Langages de programmation pour un calcul efficace

32

Il est impossible d'écrire un langage de programmation qui autorise toutes les machines qui s'arrêtent sur toutes les entrées et aucune autre. Cependant, il semble facile de définir un tel langage de programmation pour n'importe quelle classe de complexité standard. En particulier, nous pouvons définir un langage dans lequel nous pouvons exprimer tous les calculs efficaces et seulement les calculs efficaces.

Par exemple, pour quelque chose comme : prenez votre langage de programmation préféré, et après avoir écrit votre programme (correspondant à Turing Machine M ' ), ajoutez trois valeurs à l'en-tête: un entier c , et un entier k , et une sortie par défaut d . Lorsque le programme est compilé, sortir une machine de Turing M qui, étant donné l'entrée x de taille n, exécute M ' sur x pour c n k étapes. Si M ne s'arrête pas avant le c n kPMckdMxnMxcnkMcnkles étapes sont en hausse, sortir la sortie par défaut . Sauf erreur, ces langages de programmation nous permettront d'exprimer tous les calculs en P et rien de plus. Cependant, ce langage proposé est intrinsèquement non intéressant.dP

Ma question: existe-t-il des langages de programmation qui capturent des sous-ensembles de fonctions calculables (telles que toutes les fonctions efficacement calculables) de manière non triviale? S'il n'y en a pas, y a-t-il une raison à cela?

Artem Kaznatcheev
la source
7
Quelques exemples simples de langages de programmation qui capturent des sous-ensembles de fonctions calculables: expressions régulières et grammaires sans contexte.
Jukka Suomela
2
En fait, les langages qui capturent la classe de complexité comme P V (qui est défini de manière similaire aux fonctions récursives primitives avec récursivité remplacée par récursivité bornée) sont assez intéressants (au moins du point de vue théorique). :)PPV
Kaveh
La programmation linéaire et entière capture des sous-ensembles intéressants de fonctions calculables.
Diego de Estrada,
Datalog ne peut exprimer que des algorithmes de temps polynomiaux, mais je ne sais pas s'il peut exprimer tous les algorithmes de temps polynomiaux.
Jules
Le document bien connu "Programmation fonctionnelle totale" fait valoir que les langages de programmation qui n'ont pas de problème d'arrêt indécidable sont en fait pratiques et utiles. jucs.org/jucs_10_7/total_functional_programming
aucun

Réponses:

32

Un langage essayant d'exprimer uniquement des calculs de temps polynomiaux est le calcul lambda doux . Son système de types est enraciné dans une logique linéaire. Une thèse récente porte sur les calculs de temps polynomiaux et fournit un bon résumé des développements récents basés sur cette approche. Martin Hofmann travaille sur le sujet depuis un certain temps. Une ancienne liste de documents pertinents peut être trouvée ici ; Beaucoup de ses papiers continuent dans cette direction.

D'autres travaux adoptent l'approche consistant à vérifier que le programme utilise une certaine quantité de ressources, en utilisant des types dépendants ou un langage d'assemblage typé .

Pourtant, d'autres approches sont basées sur des calculs formels limités en ressources , tels que des variantes du calcul ambiant.

Ces approches ont la propriété que des programmes bien typés satisfont certaines limites de ressources prédéfinies. La ressource liée peut être du temps ou de l'espace, et peut généralement dépendre de la taille des entrées.

Les premiers travaux dans ce domaine portent sur des calculs fortement normalisants, ce qui signifie que tous les programmes bien typés s'arrêtent. Le système F , alias le calcul lambda polymorphe, se normalise fortement. Il n'a pas d'opérateur de point fixe, mais est néanmoins assez expressif, bien que je ne pense pas que l'on sache à quelle classe de complexité il correspond. Par définition, tout calcul fortement normalisant exprime une classe de calculs de terminaison.

Le langage de programmation Charity est un langage fonctionnel assez expressif qui s'arrête sur toutes les entrées. Je ne sais pas quelle classe de complexité il peut exprimer, mais la fonction Ackermann peut être écrite dans Charity.

Dave Clarke
la source
Que voulez-vous dire par «au moins» ici?
nponeccop
«Au moins» signifie ici «certains». Je vais changer ma réponse pour la rendre un peu plus précise.
Dave Clarke
Je suis à peu près sûr que la complexité des fonctions définissables dans le système F est la classe de fonctions qui se terminent dans le temps "une fonction prouvée totale d'arithmétique de second ordre" de l'entrée. Pas une classe de complexité très conventionnelle, mais quand même ...
cody
cody: selon "Theorems for free" de Wadler, le système F peut exprimer "toutes les fonctions récursives qui peuvent être prouvées totales en arithmétique Peano de second ordre", et cela "inclut [...] la fonction d'Ackermann". Je ne sais pas si c'est la même chose que vous décrivez. La principale caractéristique de Charity est son support pour les codata, alors que je pense que la vérification de terminaison d'Agda permet plus d'expressivité que Coq et System F tout en garantissant la terminaison.
Blaisorblade
8

Je voudrais également mentionner la théorie de la complexité implicite en tant qu'approche, car je l'ai vue apparaître dans plusieurs questions quelque peu liées. Pour citer cette réponse de Neel Krishnaswami :

La technique de base consiste à relier les classes de complexité aux sous-systèmes de logique linéaire (les soi-disant "logiques linéaires légères"), avec l'idée que l'élimination des coupures pour le système logique devrait être complète pour la classe de complexité donnée (comme LOGSPACE, PTIME, etc.). Ensuite, via Curry-Howard, vous obtenez un langage de programmation dans lequel précisément les programmes de la classe donnée sont exprimables.

Chris Pressey
la source
5

Je suis surpris que personne n'ait mentionné la récursion primitive. En se limitant aux boucles bornées (c'est-à-dire que le nombre d'itérations pour chaque boucle doit être calculé avant le début de la boucle) le programme résultant est récursif primitif, et donc total. Douglas Hofstadter a proposé un langage de programmation, BLOOP, qui permettait toutes et seulement les fonctions récursives primitives.

David Harris
la source
1
C'est une sous-classe appropriée de toutes les fonctions, mais l'appeler une classe de fonctions «efficaces» peut être un peu exagéré.
Raphael
PP
D'autres ont mentionné le système F et d'autres langages fortement normalisants, qui dans un sens ne prennent en charge que la «récursion primitive». Cependant, comme ils prennent en charge les fonctions de première classe, ils permettent d'écrire plus de programmes (comme la fonction Ackermann).
Blaisorblade