Technopedia Center
PMB University Brochure
Faculty of Engineering and Computer Science
S1 Informatics S1 Information Systems S1 Information Technology S1 Computer Engineering S1 Electrical Engineering S1 Civil Engineering

faculty of Economics and Business
S1 Management S1 Accountancy

Faculty of Letters and Educational Sciences
S1 English literature S1 English language education S1 Mathematics education S1 Sports Education
  • Registerasi
  • Brosur UTI
  • Kip Scholarship Information
  • Performance
  1. Weltenzyklopädie
  2. Programming Computable Functions — Wikipédia
Programming Computable Functions — Wikipédia 👆 Click Here! Read More..
Un article de Wikipédia, l'encyclopédie libre.

En informatique théorique, Programming Computable Functions ou PCF est un langage de programmation théorique apparu pour la première fois dans une publication en 1977 dans un article de Gordon Plotkin[1], mais qui est basé sur des notes de Dana S. Scott de 1969 qui n'ont été publiées qu'en 1993[2]. Ce langage consiste en une extension du lambda-calcul simplement typé avec des combinateurs de points fixes et des entiers naturels, ce qui permet de récupérer la complétude au sens de Turing, c'est-à-dire la possibilité d'exprimer n'importe quelle fonction calculable. En effet, l'ajout d'une discipline de types au lambda-calcul, donnant le lambda-calcul simplement typé, limite l'expressivité du langage et les fonctions qui y sont définissables ; l'ajout de combinateurs de point fixe et d'entiers résout ce problème.

Syntaxe et typage

[modifier | modifier le code]

PCF reprend les types du lambda-calcul simplement typé en y adjoignant un type représentant comme types de base les booléens, o {\displaystyle o} {\displaystyle o}, et un type représentant les entiers, ι {\displaystyle \iota } {\displaystyle \iota }[1],[3]. Les types sont donc o {\displaystyle o} {\displaystyle o}, ι {\displaystyle \iota } {\displaystyle \iota }, ou α → β {\displaystyle \alpha \to \beta } {\displaystyle \alpha \to \beta } avec α {\displaystyle \alpha } {\displaystyle \alpha } et β {\displaystyle \beta } {\displaystyle \beta } des types déjà formés. Ce type représente le type des fonctions de α {\displaystyle \alpha } {\displaystyle \alpha } vers β {\displaystyle \beta } {\displaystyle \beta }. La notation α → β → γ {\displaystyle \alpha \to \beta \to \gamma } {\displaystyle \alpha \to \beta \to \gamma } doit être lue comme α → ( β → γ ) {\displaystyle \alpha \to (\beta \to \gamma )} {\displaystyle \alpha \to (\beta \to \gamma )}.

De plus, la syntaxe de PCF comprend la syntaxe du lambda-calcul simplement typé, et les constructions de base y sont les mêmes : il y a des variables, notées x , y , z , … {\displaystyle x,y,z,\dots } {\displaystyle x,y,z,\dots }  ; si M {\displaystyle M} {\displaystyle M} est un terme de type α → β {\displaystyle \alpha \to \beta } {\displaystyle \alpha \to \beta } et N {\displaystyle N} {\displaystyle N} un terme de type α {\displaystyle \alpha } {\displaystyle \alpha }, M N {\displaystyle MN} {\displaystyle MN} est un terme de type β {\displaystyle \beta } {\displaystyle \beta } qui représente l'évaluation de la fonction M {\displaystyle M} {\displaystyle M} en N {\displaystyle N} {\displaystyle N} ; et si M {\displaystyle M} {\displaystyle M} est un terme de type β {\displaystyle \beta } {\displaystyle \beta } dans un contexte où la variable x {\displaystyle x} {\displaystyle x} est de type α {\displaystyle \alpha } {\displaystyle \alpha }, λ x α . M {\displaystyle \lambda x^{\alpha }.M} {\displaystyle \lambda x^{\alpha }.M} est de type α → β {\displaystyle \alpha \to \beta } {\displaystyle \alpha \to \beta } et représente la fonction x ↦ M {\displaystyle x\mapsto M} {\displaystyle x\mapsto M}. Si M {\displaystyle M} {\displaystyle M} est un terme de type α {\displaystyle \alpha } {\displaystyle \alpha }, on notera M : α {\displaystyle M:\alpha } {\displaystyle M:\alpha }. Pour plus de détails, consulter les sections Syntaxe et Règles de typage de l'article sur le lambda-calcul simplement typé.

À cela se rajoutent les constantes propres permettant de manipuler les types de base. Pour chaque entier naturel n ∈ N {\displaystyle n\in \mathbb {N} } {\displaystyle n\in \mathbb {N} }, on ajoute une constante n _ : ι {\displaystyle {\underline {n}}:\iota } {\displaystyle {\underline {n}}:\iota }. De plus, il y a une constante pour chaque booléen, true : o {\displaystyle \operatorname {true} :o} {\displaystyle \operatorname {true} :o} et false : o {\displaystyle \operatorname {false} :o} {\displaystyle \operatorname {false} :o}. Pour chaque type de base σ {\displaystyle \sigma } {\displaystyle \sigma }, c'est-à-dire ι {\displaystyle \iota } {\displaystyle \iota } et o {\displaystyle o} {\displaystyle o}, on a une constante if ⁡   then ⁡   else : o → σ → σ → σ {\displaystyle \operatorname {if} \ \operatorname {then} \ \operatorname {else} :o\to \sigma \to \sigma \to \sigma } {\displaystyle \operatorname {if} \ \operatorname {then} \ \operatorname {else} :o\to \sigma \to \sigma \to \sigma } représentant une instruction conditionnelle : l'idée étant que si b {\displaystyle b} {\displaystyle b} vaut true {\displaystyle \operatorname {true} } {\displaystyle \operatorname {true} }, l'expression if ⁡ b then ⁡ M else ⁡ N {\displaystyle \operatorname {if} b\operatorname {then} M\operatorname {else} N} {\displaystyle \operatorname {if} b\operatorname {then} M\operatorname {else} N}vaut M {\displaystyle M} {\displaystyle M}, si b {\displaystyle b} {\displaystyle b} vaut false {\displaystyle \operatorname {false} } {\displaystyle \operatorname {false} }, elle s'évalue en N {\displaystyle N} {\displaystyle N}. De plus, il y a deux fonctions pour manipuler les entiers, la fonction successeur succ : ι → ι {\displaystyle \operatorname {succ} :\iota \to \iota } {\displaystyle \operatorname {succ} :\iota \to \iota } et la fonction prédécesseur pred : ι → ι {\displaystyle \operatorname {pred} :\iota \to \iota } {\displaystyle \operatorname {pred} :\iota \to \iota }, qui correspondent à ajouter ou soustraire 1 {\displaystyle 1} {\displaystyle 1} à leur argument. Enfin, il y a une fonction zero ? : ι → o {\displaystyle \operatorname {zero} ?:\iota \to o} {\displaystyle \operatorname {zero} ?:\iota \to o} qui renvoie true {\displaystyle \operatorname {true} } {\displaystyle \operatorname {true} } si son argument vaut l'entier 0 _ {\displaystyle {\underline {0}}} {\displaystyle {\underline {0}}}, false {\displaystyle \operatorname {false} } {\displaystyle \operatorname {false} } sinon.

Enfin, le principal ingrédient de PCF est sa construction de point fixe : pour chaque type α {\displaystyle \alpha } {\displaystyle \alpha }, on dispose d'une constante Y : ( α → α ) → α {\displaystyle Y:(\alpha \to \alpha )\to \alpha } {\displaystyle Y:(\alpha \to \alpha )\to \alpha } dont l'interprétation est qu'il renvoie le plus petit point fixe de la fonction qu'on lui passe en argument. Certains auteurs[4] rajoutent à chaque type une constante Ω : α {\displaystyle \Omega :\alpha } {\displaystyle \Omega :\alpha } qui répresente un programme qui ne termine pas. Cette construction n'est pas incluse dans la présentation originelle de Gordon Plotkin[1], mais peut y être définie comme Y ( λ x α . x ) {\displaystyle Y(\lambda x^{\alpha }.x)} {\displaystyle Y(\lambda x^{\alpha }.x)}.

Sémantique opérationnelle

[modifier | modifier le code]

PCF peut être muni d'une sémantique opérationnelle → {\displaystyle \to } {\displaystyle \to }[5]. Si M {\displaystyle M} {\displaystyle M} et N {\displaystyle N} {\displaystyle N} sont des termes, on a M → N {\displaystyle M\to N} {\displaystyle M\to N} si M {\displaystyle M} {\displaystyle M} se transforme en N {\displaystyle N} {\displaystyle N} après une étape élémentaire de calcul. On note M → ∗ N {\displaystyle M\to ^{*}N} {\displaystyle M\to ^{*}N} pour dire que M {\displaystyle M} {\displaystyle M} se transforme en N {\displaystyle N} {\displaystyle N} en zéro ou plusieurs étapes. La relation → {\displaystyle \to } {\displaystyle \to } est définie comme suit :

  • ( λ x α . M ) N → M [ x := N ] {\displaystyle (\lambda x^{\alpha }.M)N\to M[x:=N]} {\displaystyle (\lambda x^{\alpha }.M)N\to M[x:=N]} : pour évaluer l'application de la fonction x ↦ M {\displaystyle x\mapsto M} {\displaystyle x\mapsto M} en N {\displaystyle N} {\displaystyle N}, on remplace x {\displaystyle x} {\displaystyle x} par N {\displaystyle N} {\displaystyle N} dans M {\displaystyle M} {\displaystyle M} ;
  • Y M → M ( Y M ) {\displaystyle YM\to M(YM)} {\displaystyle YM\to M(YM)} : cela exprime que Y M {\displaystyle YM} {\displaystyle YM} est un point fixe de M {\displaystyle M} {\displaystyle M} ;
  • succ ⁡ ( n _ ) → n + 1 _ {\displaystyle \operatorname {succ} ({\underline {n}})\to {\underline {n+1}}} {\displaystyle \operatorname {succ} ({\underline {n}})\to {\underline {n+1}}};
  • pred ⁡ ( n + 1 _ ) → n _ {\displaystyle \operatorname {pred} ({\underline {n+1}})\to {\underline {n}}} {\displaystyle \operatorname {pred} ({\underline {n+1}})\to {\underline {n}}} ;
  • zero ? ( 0 _ ) → true {\displaystyle \operatorname {zero} ?({\underline {0}})\to \operatorname {true} } {\displaystyle \operatorname {zero} ?({\underline {0}})\to \operatorname {true} } ;
  • zero ? ( n + 1 _ ) → false {\displaystyle \operatorname {zero} ?({\underline {n+1}})\to \operatorname {false} } {\displaystyle \operatorname {zero} ?({\underline {n+1}})\to \operatorname {false} } ;
  • if ⁡ true ⁡ then ⁡ M else ⁡ N → M {\displaystyle \operatorname {if} \operatorname {true} \operatorname {then} M\operatorname {else} N\to M} {\displaystyle \operatorname {if} \operatorname {true} \operatorname {then} M\operatorname {else} N\to M} ;
  • if ⁡ false ⁡ then ⁡ M else ⁡ N → N {\displaystyle \operatorname {if} \operatorname {false} \operatorname {then} M\operatorname {else} N\to N} {\displaystyle \operatorname {if} \operatorname {false} \operatorname {then} M\operatorname {else} N\to N} ;
  • Les règles contextuelles sont les suivantes : si M → M ′ {\displaystyle M\to M'} {\displaystyle M\to M'} alors M N → M ′ N {\displaystyle MN\to M'N} {\displaystyle MN\to M'N}, succ ⁡ M → succ ⁡ M ′ {\displaystyle \operatorname {succ} M\to \operatorname {succ} M'} {\displaystyle \operatorname {succ} M\to \operatorname {succ} M'}, pred ⁡ M → pred ⁡ M ′ {\displaystyle \operatorname {pred} M\to \operatorname {pred} M'} {\displaystyle \operatorname {pred} M\to \operatorname {pred} M'}, zero ? ( M ) → zero ? ( M ′ ) {\displaystyle \operatorname {zero} ?(M)\to \operatorname {zero} ?(M')} {\displaystyle \operatorname {zero} ?(M)\to \operatorname {zero} ?(M')} et if ⁡ M then ⁡ N else ⁡ P → if ⁡ M ′ then ⁡ N else ⁡ P {\displaystyle \operatorname {if} M\operatorname {then} N\operatorname {else} P\to \operatorname {if} M'\operatorname {then} N\operatorname {else} P} {\displaystyle \operatorname {if} M\operatorname {then} N\operatorname {else} P\to \operatorname {if} M'\operatorname {then} N\operatorname {else} P}. Elles donnent à PCF une sémantique d'appel par nom.

Cette sémantique est déterministe, c'est-à-dire que si M → N {\displaystyle M\to N} {\displaystyle M\to N} et M → N ′ {\displaystyle M\to N'} {\displaystyle M\to N'}, alors N = N ′ {\displaystyle N=N'} {\displaystyle N=N'}. De plus, elle préserve le typage : si M → N {\displaystyle M\to N} {\displaystyle M\to N} et M {\displaystyle M} {\displaystyle M} est de type α {\displaystyle \alpha } {\displaystyle \alpha }, alors N {\displaystyle N} {\displaystyle N} aussi.

On pourrait autoriser la réduction dans tous les contextes, plutôt qu'uniquement dans ceux précisés dans la dernière règle (qui interdit, par exemple, la réduction N M → N M ′ {\displaystyle NM\to NM'} {\displaystyle NM\to NM'} avec M → M ′ {\displaystyle M\to M'} {\displaystyle M\to M'} et N {\displaystyle N} {\displaystyle N} qui n'est pas une lambda-abstraction ou succ {\displaystyle \operatorname {succ} } {\displaystyle \operatorname {succ} } ou pred {\displaystyle \operatorname {pred} } {\displaystyle \operatorname {pred} } ou zero ? {\displaystyle \operatorname {zero} ?} {\displaystyle \operatorname {zero} ?}). Dans ce cas, la réduction obtenue préserve encore le typage et est confluente. De plus, si M → ∗ N {\displaystyle M\to ^{*}N} {\displaystyle M\to ^{*}N} avec cette réduction, et si N {\displaystyle N} {\displaystyle N} est en forme normale, alors M → ∗ N {\displaystyle M\to ^{*}N} {\displaystyle M\to ^{*}N} avec la version restreinte. En clair, la sémantique opérationnelle définie ici est standardisante[6].

Exemple

[modifier | modifier le code]

PCF permet par exemple de définir des programmes effectuant l'addition de deux entiers. En voici un[6] :

a d d := Y ( λ f ι → ι → ι . λ x ι . λ y ι . if ⁡ zero ? ( x ) then ⁡ y else ⁡ succ ⁡ ( f ( pred ⁡ x ) y ) ) {\displaystyle add:=Y(\lambda f^{\iota \to \iota \to \iota }.\lambda x^{\iota }.\lambda y^{\iota }.\operatorname {if} \operatorname {zero} ?(x)\operatorname {then} y\operatorname {else} \operatorname {succ} (f(\operatorname {pred} x)y))} {\displaystyle add:=Y(\lambda f^{\iota \to \iota \to \iota }.\lambda x^{\iota }.\lambda y^{\iota }.\operatorname {if} \operatorname {zero} ?(x)\operatorname {then} y\operatorname {else} \operatorname {succ} (f(\operatorname {pred} x)y))}.

Si on note a d d ′ {\displaystyle add'} {\displaystyle add'} la fonction à l'intérieur de Y {\displaystyle Y} {\displaystyle Y}, la somme de deux et trois est calculée par la suite de réductions suivante :

a d d   2 _   3 _ → a d d ′   a d d   2 _   3 _ → ∗ if ⁡ zero ? ( 0 _ ) then ⁡ 3 _ else ⁡ succ ⁡ ( a d d ( pred ⁡ 2 _ ) 3 _ ) → ∗ succ ⁡ ( a d d   1 _   3 _ ) → ∗ {\displaystyle add~{\underline {2}}~{\underline {3}}\to add'~add~{\underline {2}}~{\underline {3}}\to ^{*}\operatorname {if} \operatorname {zero} ?({\underline {0}})\operatorname {then} {\underline {3}}\operatorname {else} \operatorname {succ} (add(\operatorname {pred} {\underline {2}}){\underline {3}})\to ^{*}\operatorname {succ} (add~{\underline {1}}~{\underline {3}})\to ^{*}} {\displaystyle add~{\underline {2}}~{\underline {3}}\to add'~add~{\underline {2}}~{\underline {3}}\to ^{*}\operatorname {if} \operatorname {zero} ?({\underline {0}})\operatorname {then} {\underline {3}}\operatorname {else} \operatorname {succ} (add(\operatorname {pred} {\underline {2}}){\underline {3}})\to ^{*}\operatorname {succ} (add~{\underline {1}}~{\underline {3}})\to ^{*}}

succ ⁡ ( if ⁡ zero ? ( 1 _ ) then ⁡ 3 _ else ⁡ succ ⁡ ( a d d ( pred ⁡ 1 _ ) 3 _ ) ) → ∗ succ ⁡ ( succ ⁡ ( a d d   0 _   3 _ ) ) → ∗ {\displaystyle \operatorname {succ} (\operatorname {if} \operatorname {zero} ?({\underline {1}})\operatorname {then} {\underline {3}}\operatorname {else} \operatorname {succ} (add(\operatorname {pred} {\underline {1}}){\underline {3}}))\to ^{*}\operatorname {succ} (\operatorname {succ} (add~{\underline {0}}~{\underline {3}}))\to ^{*}} {\displaystyle \operatorname {succ} (\operatorname {if} \operatorname {zero} ?({\underline {1}})\operatorname {then} {\underline {3}}\operatorname {else} \operatorname {succ} (add(\operatorname {pred} {\underline {1}}){\underline {3}}))\to ^{*}\operatorname {succ} (\operatorname {succ} (add~{\underline {0}}~{\underline {3}}))\to ^{*}}

succ ⁡ ( succ ⁡ ( if ⁡ zero ? ( 0 _ ) then ⁡ 3 _ else ⁡ succ ⁡ ( a d d ( pred ⁡ 0 _ ) 3 _ ) ) ) → ∗ succ ⁡ ( succ ⁡ ( 3 _ ) ) ) → ∗ 5 _ {\displaystyle \operatorname {succ} (\operatorname {succ} (\operatorname {if} \operatorname {zero} ?({\underline {0}})\operatorname {then} {\underline {3}}\operatorname {else} \operatorname {succ} (add(\operatorname {pred} {\underline {0}}){\underline {3}})))\to ^{*}\operatorname {succ} (\operatorname {succ} ({\underline {3}})))\to ^{*}{\underline {5}}} {\displaystyle \operatorname {succ} (\operatorname {succ} (\operatorname {if} \operatorname {zero} ?({\underline {0}})\operatorname {then} {\underline {3}}\operatorname {else} \operatorname {succ} (add(\operatorname {pred} {\underline {0}}){\underline {3}})))\to ^{*}\operatorname {succ} (\operatorname {succ} ({\underline {3}})))\to ^{*}{\underline {5}}}.

Ainsi, add ⁡   2 _   3 _ {\displaystyle \operatorname {add} ~{\underline {2}}~{\underline {3}}} {\displaystyle \operatorname {add} ~{\underline {2}}~{\underline {3}}} se réduit bien en la valeur 5 _ {\displaystyle {\underline {5}}} {\displaystyle {\underline {5}}}.

Sémantique dénotationnelle

[modifier | modifier le code]

La sémantique opérationnelle présentée plus haut permet de déterminer comment exécuter un terme de PCF comme un programme. Mais pour étudier PCF, il peut être intéressant de traduire un terme comme λ x α . M {\displaystyle \lambda x^{\alpha }.M} {\displaystyle \lambda x^{\alpha }.M} en une fonction au sens mathématique du terme. C'est le rôle de la sémantique dénotationnelle[7].

Contrairement au lambda-calcul simplement typé, on ne peut pas interpréter PCF directement dans les ensembles et les fonctions, puisqu'il existe des fonctions qui n'ont pas de point fixe. On va donc interpréter les termes de PCF comme des fonctions continues entre cpo. Un cpo est un ensemble ordonné dans lequel toutes les parties filtrantes ont une borne supérieure, et qui possède un plus petit élément[8]. L'intérêt des cpo réside dans ce que chaque fonction continue, possède un plus petit point fixe. Une fonction est continue au sens des cpo si elle préserve les bornes supérieures de partie filtrantes. La catégorie des cpo est cartésienne fermée[9].

La sémantique dénotationnelle va traduire chaque terme M {\displaystyle M} {\displaystyle M} par un objet [ [ M ] ] {\displaystyle [\![M]\!]} {\displaystyle [\![M]\!]} appartenant à un certain modèle, fixé à l'avance. La propriété de correction énoncera ensuite que si M → N {\displaystyle M\to N} {\displaystyle M\to N}, alors [ [ M ] ] = [ [ N ] ] {\displaystyle [\![M]\!]=[\![N]\!]} {\displaystyle [\![M]\!]=[\![N]\!]}.

Modèle continu

[modifier | modifier le code]

Le modèle continu est l'interprétation usuelle de PCF[10],[11]. On va définir pour chaque type, chaque contexte et chaque terme une traduction [ [ ⋅ ] ] {\displaystyle [\![\cdot ]\!]} {\displaystyle [\![\cdot ]\!]} telle que l'interprétation d'un contexte ou d'un type soit un cpo, et si Γ ⊢ M : α {\displaystyle \Gamma \vdash M:\alpha } {\displaystyle \Gamma \vdash M:\alpha } dans PCF, alors [ [ M ] ] : [ [ Γ ] ] → [ [ α ] ] {\displaystyle [\![M]\!]:[\![\Gamma ]\!]\to [\![\alpha ]\!]} {\displaystyle [\![M]\!]:[\![\Gamma ]\!]\to [\![\alpha ]\!]} est une fonction continue de l'interprétation du contexte vers l'interprétation du type de M {\displaystyle M} {\displaystyle M}.

Les types de base sont interprétés comme des domaines plats : on a [ [ ι ] ] = N ⊥ {\displaystyle [\![\iota ]\!]=\mathbb {N} _{\bot }} {\displaystyle [\![\iota ]\!]=\mathbb {N} _{\bot }} et [ [ o ] ] = B ⊥ {\displaystyle [\![o]\!]=\mathbb {B} _{\bot }} {\displaystyle [\![o]\!]=\mathbb {B} _{\bot }}, où N {\displaystyle \mathbb {N} } {\displaystyle \mathbb {N} } est l'ensemble des entiers naturels, B {\displaystyle \mathbb {B} } {\displaystyle \mathbb {B} } l'ensemble des booléens et pour tout ensemble X {\displaystyle X} {\displaystyle X}, X ⊥ {\displaystyle X_{\bot }} {\displaystyle X_{\bot }} est le cpo défini sur l'ensemble X {\displaystyle X} {\displaystyle X} auquel on adjoint un élément ⊥ {\displaystyle \bot } {\displaystyle \bot }, avec l'ordre défini par ⊥ ≤ x {\displaystyle \bot \leq x} {\displaystyle \bot \leq x} pour tout x {\displaystyle x} {\displaystyle x}, et les éléments de X {\displaystyle X} {\displaystyle X} sont incomparables entre eux. Intuitivement, ⊥ {\displaystyle \bot } {\displaystyle \bot } désigne un programme qui ne termine pas. Le type α → β {\displaystyle \alpha \to \beta } {\displaystyle \alpha \to \beta } est interprété comme l'ensemble des fonctions continues de [ [ α ] ] {\displaystyle [\![\alpha ]\!]} {\displaystyle [\![\alpha ]\!]} vers [ [ β ] ] {\displaystyle [\![\beta ]\!]} {\displaystyle [\![\beta ]\!]}. L'idée intuitive derrière cet ordre étant que pour deux fonctions f {\displaystyle f} {\displaystyle f} et g {\displaystyle g} {\displaystyle g} de même type, représentant des fonctions partiellement définies, f ≤ g {\displaystyle f\leq g} {\displaystyle f\leq g} signifie que f {\displaystyle f} {\displaystyle f} est une approximation de g {\displaystyle g} {\displaystyle g}, ou que g {\displaystyle g} {\displaystyle g} est définie en plus de points que f {\displaystyle f} {\displaystyle f}. Un contexte x 1 : α 1 , … , x n : α n {\displaystyle x_{1}:\alpha _{1},\dots ,x_{n}:\alpha _{n}} {\displaystyle x_{1}:\alpha _{1},\dots ,x_{n}:\alpha _{n}} est interprété par [ [ α 1 ] ] × ⋯ × [ [ α n ] ] {\displaystyle [\![\alpha _{1}]\!]\times \dots \times [\![\alpha _{n}]\!]} {\displaystyle [\![\alpha _{1}]\!]\times \dots \times [\![\alpha _{n}]\!]}. On remarque que chaque type est un cpo, donc a un plus petit élément ⊥ {\displaystyle \bot } {\displaystyle \bot }.

Considérons maintenant un terme typé et son contexte Γ ⊢ M : α {\displaystyle \Gamma \vdash M:\alpha } {\displaystyle \Gamma \vdash M:\alpha }, avec Γ = x 1 : α 1 , … , x n : α n {\displaystyle \Gamma =x_{1}:\alpha _{1},\dots ,x_{n}:\alpha _{n}} {\displaystyle \Gamma =x_{1}:\alpha _{1},\dots ,x_{n}:\alpha _{n}}.

L'interprétation des constructions issues du lambda-calcul est la suivante :

  • [ [ x i ] ] = ( x 1 , … , x n ) ↦ x i {\displaystyle [\![x_{i}]\!]=(x_{1},\dots ,x_{n})\mapsto x_{i}} {\displaystyle [\![x_{i}]\!]=(x_{1},\dots ,x_{n})\mapsto x_{i}}.
  • [ [ λ x α . M ] ] = ( x 1 , … , x n ) ↦ ( x ↦ [ [ M ] ] ( x 1 , … , x n , x ) ) {\displaystyle [\![\lambda x^{\alpha }.M]\!]=(x_{1},\dots ,x_{n})\mapsto (x\mapsto [\![M]\!](x_{1},\dots ,x_{n},x))} {\displaystyle [\![\lambda x^{\alpha }.M]\!]=(x_{1},\dots ,x_{n})\mapsto (x\mapsto [\![M]\!](x_{1},\dots ,x_{n},x))}.
  • [ [ M N ] ] = ( x 1 , … , x n ) ↦ [ [ M ] ] ( x 1 , … , x n ) ( [ [ N ] ] ( x 1 , … , x n ) ) {\displaystyle [\![MN]\!]=(x_{1},\dots ,x_{n})\mapsto [\![M]\!](x_{1},\dots ,x_{n})([\![N]\!](x_{1},\dots ,x_{n}))} {\displaystyle [\![MN]\!]=(x_{1},\dots ,x_{n})\mapsto [\![M]\!](x_{1},\dots ,x_{n})([\![N]\!](x_{1},\dots ,x_{n}))}.

L'opérateur de point fixe est définie comme suit :

  • [ [ Y ] ] {\displaystyle [\![Y]\!]} {\displaystyle [\![Y]\!]} est la fonction ( [ [ α ] ] → [ [ α ] ] ) → [ [ α ] ] {\displaystyle ([\![\alpha ]\!]\to [\![\alpha ]\!])\to [\![\alpha ]\!]} {\displaystyle ([\![\alpha ]\!]\to [\![\alpha ]\!])\to [\![\alpha ]\!]} qui à chaque f : [ [ α ] ] → [ [ α ] ] {\displaystyle f:[\![\alpha ]\!]\to [\![\alpha ]\!]} {\displaystyle f:[\![\alpha ]\!]\to [\![\alpha ]\!]} associe son plus petit point fixe. Il est défini comme ⋁ n ∈ N f n ( ⊥ ) {\displaystyle \bigvee _{n\in \mathbb {N} }f^{n}(\bot )} {\displaystyle \bigvee _{n\in \mathbb {N} }f^{n}(\bot )}, c'est-à-dire comme le supremum de la suite croissante ⊥ , f ( ⊥ ) , f ( f ( ⊥ ) ) , … {\displaystyle \bot ,f(\bot ),f(f(\bot )),\dots } {\displaystyle \bot ,f(\bot ),f(f(\bot )),\dots }.
  • Puisque intuitivement, Ω = Y ( λ x α . x ) {\displaystyle \Omega =Y(\lambda x^{\alpha }.x)} {\displaystyle \Omega =Y(\lambda x^{\alpha }.x)}, et que le plus petit point fixe de la fonction identité est ⊥ {\displaystyle \bot } {\displaystyle \bot }, s'il est présent, [ [ Ω ] ] = ⊥ {\displaystyle [\![\Omega ]\!]=\bot } {\displaystyle [\![\Omega ]\!]=\bot }.

Les primitives sur les entiers et les booléens sont interprétées comme suit, l'idée étant que ⊥ {\displaystyle \bot } {\displaystyle \bot } représente une valeur non déterminée, par exemple un programme qui ne termine pas :

  • [ [ succ ] ] ( n _ ) = n + 1 _ {\displaystyle [\![\operatorname {succ} ]\!]({\underline {n}})={\underline {n+1}}} {\displaystyle [\![\operatorname {succ} ]\!]({\underline {n}})={\underline {n+1}}} si n ∈ N {\displaystyle n\in \mathbb {N} } {\displaystyle n\in \mathbb {N} } et [ [ succ ] ] ( ⊥ ) = ⊥ {\displaystyle [\![\operatorname {succ} ]\!](\bot )=\bot } {\displaystyle [\![\operatorname {succ} ]\!](\bot )=\bot }.
  • [ [ pred ] ] ( n _ ) = n − 1 _ {\displaystyle [\![\operatorname {pred} ]\!]({\underline {n}})={\underline {n-1}}} {\displaystyle [\![\operatorname {pred} ]\!]({\underline {n}})={\underline {n-1}}} si n ∈ N {\displaystyle n\in \mathbb {N} } {\displaystyle n\in \mathbb {N} } et n ≠ 0 {\displaystyle n\neq 0} {\displaystyle n\neq 0}, [ [ pred ] ] ( 0 _ ) = ⊥ {\displaystyle [\![\operatorname {pred} ]\!]({\underline {0}})=\bot } {\displaystyle [\![\operatorname {pred} ]\!]({\underline {0}})=\bot } et [ [ pred ] ] ( ⊥ ) = ⊥ {\displaystyle [\![\operatorname {pred} ]\!](\bot )=\bot } {\displaystyle [\![\operatorname {pred} ]\!](\bot )=\bot }.
  • [ [ zero ? ] ] ( 0 _ ) = true {\displaystyle [\![\operatorname {zero} ?]\!]({\underline {0}})=\operatorname {true} } {\displaystyle [\![\operatorname {zero} ?]\!]({\underline {0}})=\operatorname {true} }, [ [ zero ? ] ] ( n _ ) = false {\displaystyle [\![\operatorname {zero} ?]\!]({\underline {n}})=\operatorname {false} } {\displaystyle [\![\operatorname {zero} ?]\!]({\underline {n}})=\operatorname {false} } si n ∈ N {\displaystyle n\in \mathbb {N} } {\displaystyle n\in \mathbb {N} } et n ≠ 0 {\displaystyle n\neq 0} {\displaystyle n\neq 0}, et [ [ zero ? ] ] ( ⊥ ) = ⊥ {\displaystyle [\![\operatorname {zero} ?]\!](\bot )=\bot } {\displaystyle [\![\operatorname {zero} ?]\!](\bot )=\bot }.
  • [ [ if ⁡   then ⁡   else ] ] ( true ) ( x ) ( y ) = x {\displaystyle [\![\operatorname {if} \ \operatorname {then} \ \operatorname {else} ]\!](\operatorname {true} )(x)(y)=x} {\displaystyle [\![\operatorname {if} \ \operatorname {then} \ \operatorname {else} ]\!](\operatorname {true} )(x)(y)=x}, [ [ if ⁡   then ⁡   else ] ] ( false ) ( x ) ( y ) = y {\displaystyle [\![\operatorname {if} \ \operatorname {then} \ \operatorname {else} ]\!](\operatorname {false} )(x)(y)=y} {\displaystyle [\![\operatorname {if} \ \operatorname {then} \ \operatorname {else} ]\!](\operatorname {false} )(x)(y)=y} et [ [ if ⁡   then ⁡   else ] ] ( ⊥ ) ( x ) ( y ) = y {\displaystyle [\![\operatorname {if} \ \operatorname {then} \ \operatorname {else} ]\!](\bot )(x)(y)=y} {\displaystyle [\![\operatorname {if} \ \operatorname {then} \ \operatorname {else} ]\!](\bot )(x)(y)=y}.

Modèles standards

[modifier | modifier le code]

Plus généralement, on peut interpréter PCF dans des catégories cartésiennes fermées enrichies dans les cpo[10],[11]. Un tel modèle est appelé modèle standard de PCF. Une catégorie cartésienne fermée enrichie dans les cpo est une catégorie cartésienne fermée C {\displaystyle {\mathcal {C}}} {\displaystyle {\mathcal {C}}} telle que :

  • les hom-sets C ( A , B ) {\displaystyle {\mathcal {C}}(A,B)} {\displaystyle {\mathcal {C}}(A,B)} sont des cpo pour tous objets A {\displaystyle A} {\displaystyle A} et B {\displaystyle B} {\displaystyle B} ;
  • la composition, le pairage et la currification sont continues ;
  • l'évaluation et la composition sont strictes : pour tous objets A {\displaystyle A} {\displaystyle A}, B {\displaystyle B} {\displaystyle B} et C {\displaystyle C} {\displaystyle C} et tout morphisme f : A → B {\displaystyle f:A\to B} {\displaystyle f:A\to B}, si l'on désigne par ⊥ D {\displaystyle \bot _{D}} {\displaystyle \bot _{D}} le plus petit élément d'un cpo D {\displaystyle D} {\displaystyle D}, on a :
    ⊥ C ( B , C ) ∘ f = ⊥ C ( A , C ) {\displaystyle \bot _{{\mathcal {C}}(B,C)}\circ f=\bot _{{\mathcal {C}}(A,C)}} {\displaystyle \bot _{{\mathcal {C}}(B,C)}\circ f=\bot _{{\mathcal {C}}(A,C)}},
    et si l'on désigne par B → C {\displaystyle B\to C} {\displaystyle B\to C} l'objet des fonctions de B {\displaystyle B} {\displaystyle B} vers C {\displaystyle C} {\displaystyle C} dans la catégorie cartésienne fermée, par ⟨ ⋅ , ⋅ ⟩ {\displaystyle \langle \cdot ,\cdot \rangle } {\displaystyle \langle \cdot ,\cdot \rangle } l'opération de pairage et par e v B , C : ( B → C ) × B → C {\displaystyle ev_{B,C}:(B\to C)\times B\to C} {\displaystyle ev_{B,C}:(B\to C)\times B\to C} le morphisme d'évaluation, on a :
e v A , B ∘ ⟨ ⊥ C ( A , B → C ) , f ⟩ = ⊥ C ( A , C ) {\displaystyle ev_{A,B}\circ \langle \bot _{{\mathcal {C}}(A,B\to C)},f\rangle =\bot _{{\mathcal {C}}(A,C)}} {\displaystyle ev_{A,B}\circ \langle \bot _{{\mathcal {C}}(A,B\to C)},f\rangle =\bot _{{\mathcal {C}}(A,C)}}.
  • la catégorie possède deux objets D ι {\displaystyle D^{\iota }} {\displaystyle D^{\iota }} et D o {\displaystyle D^{o}} {\displaystyle D^{o}} tels que C ( 1 , D ι ) {\displaystyle {\mathcal {C}}(1,D^{\iota })} {\displaystyle {\mathcal {C}}(1,D^{\iota })} soit isomorphe à N ⊥ {\displaystyle \mathbb {N} _{\bot }} {\displaystyle \mathbb {N} _{\bot }} et C ( 1 , D o ) {\displaystyle {\mathcal {C}}(1,D^{o})} {\displaystyle {\mathcal {C}}(1,D^{o})} soit isomorphe à B ⊥ {\displaystyle \mathbb {B} _{\bot }} {\displaystyle \mathbb {B} _{\bot }} en tant que cpo, où 1 {\displaystyle 1} {\displaystyle 1} l'objet terminal de la catégorie C {\displaystyle {\mathcal {C}}} {\displaystyle {\mathcal {C}}}. Dans la catégorie des cpo, 1 {\displaystyle 1} {\displaystyle 1} est l'ensemble à un élément muni de l'égalité comme relation d'ordre.

Dans ce cas, en interprétant dans C {\displaystyle {\mathcal {C}}} {\displaystyle {\mathcal {C}}} les constructions issues du lambda-calcul simplement typé de la façon uselle, en définissant [ [ Ω ] ] = ⊥ {\displaystyle [\![\Omega ]\!]=\bot } {\displaystyle [\![\Omega ]\!]=\bot } et [ [ Y ] ] = ⋁ n ∈ N [ [ λ f . f n Ω ] ] {\displaystyle [\![Y]\!]=\bigvee _{n\in \mathbb {N} }[\![\lambda f.f^{n}\Omega ]\!]} {\displaystyle [\![Y]\!]=\bigvee _{n\in \mathbb {N} }[\![\lambda f.f^{n}\Omega ]\!]} et en interprétant les constructions sur les types primitifs de la même façon que dans le modèle continu en posant [ [ ι ] ] = D ι {\displaystyle [\![\iota ]\!]=D^{\iota }} {\displaystyle [\![\iota ]\!]=D^{\iota }} et [ [ o ] ] = D o {\displaystyle [\![o]\!]=D^{o}} {\displaystyle [\![o]\!]=D^{o}}, ce qui est rendu possible par les isomorphismes C ( 1 , D ι ) ≃ N ⊥ {\displaystyle {\mathcal {C}}(1,D^{\iota })\simeq \mathbb {N} _{\bot }} {\displaystyle {\mathcal {C}}(1,D^{\iota })\simeq \mathbb {N} _{\bot }} et C ( 1 , D o ) ≃ B ⊥ {\displaystyle {\mathcal {C}}(1,D^{o})\simeq \mathbb {B} _{\bot }} {\displaystyle {\mathcal {C}}(1,D^{o})\simeq \mathbb {B} _{\bot }}, on obtient la sémantique désirée.

Vocabulaire des modèles standards

[modifier | modifier le code]

On peut distinguer certains types de modèles de PCF. Les définitions présentées ici sont celles de Amadio et Curien[6], et ne sont pas standard ; Milner[12] désigne par le vocable « extensionnel » ce qu'Amadio et Curien désignent par « extensionnellement ordonné »  :

  • Un modèle standard C {\displaystyle {\mathcal {C}}} {\displaystyle {\mathcal {C}}} est extensionnel[13] si pour tous f , g ∈ C ( A , B ) {\displaystyle f,g\in {\mathcal {C}}(A,B)} {\displaystyle f,g\in {\mathcal {C}}(A,B)}, f = g {\displaystyle f=g} {\displaystyle f=g} si et seulement si ∀ h ∈ C ( 1 , A ) , f ∘ h = g ∘ h {\displaystyle \forall h\in {\mathcal {C}}(1,A),f\circ h=g\circ h} {\displaystyle \forall h\in {\mathcal {C}}(1,A),f\circ h=g\circ h}, où 1 {\displaystyle 1} {\displaystyle 1} l'objet terminal de C {\displaystyle {\mathcal {C}}} {\displaystyle {\mathcal {C}}}. Cela signifie que C ( A , B ) {\displaystyle {\mathcal {C}}(A,B)} {\displaystyle {\mathcal {C}}(A,B)} peut être vu comme un ensemble de fonctions de C ( 1 , A ) {\displaystyle {\mathcal {C}}(1,A)} {\displaystyle {\mathcal {C}}(1,A)} vers C ( 1 , B ) {\displaystyle {\mathcal {C}}(1,B)} {\displaystyle {\mathcal {C}}(1,B)}. Cela correspond à la notion de catégorie bien pointée.
  • Un modèle standard C {\displaystyle {\mathcal {C}}} {\displaystyle {\mathcal {C}}} est extensionnellement ordonné[6] s'il est extensionnel et que pour tous f , g ∈ C ( A , B ) {\displaystyle f,g\in {\mathcal {C}}(A,B)} {\displaystyle f,g\in {\mathcal {C}}(A,B)}, f ≤ g {\displaystyle f\leq g} {\displaystyle f\leq g} si et seulement si ∀ h ∈ C ( 1 , A ) , f ∘ h ≤ g ∘ h {\displaystyle \forall h\in {\mathcal {C}}(1,A),f\circ h\leq g\circ h} {\displaystyle \forall h\in {\mathcal {C}}(1,A),f\circ h\leq g\circ h}. Cela signifie que si on regarde f {\displaystyle f} {\displaystyle f} et g {\displaystyle g} {\displaystyle g} comme des fonctions, l'ordre entre f {\displaystyle f} {\displaystyle f} et g {\displaystyle g} {\displaystyle g} est l'ordre point à point.

Adéquation

[modifier | modifier le code]

Le théorème d'adéquation (en anglais : adequacy) énonce que dans tout modèle standard, un programme calculant un entier est interprété par l'entier qu'il calcule[14].

Théorème (Adéquation) — Dans tout modèle standard de PCF, pour tout terme clos M {\displaystyle M} {\displaystyle M} de type entier, c'est-à-dire tel que ⊢ M : ι {\displaystyle \vdash M:\iota } {\displaystyle \vdash M:\iota }, et pour tout entier n ∈ N {\displaystyle n\in \mathbb {N} } {\displaystyle n\in \mathbb {N} }, on a : M → ∗ n _ ⟺ [ [ M ] ] = n {\displaystyle M\to ^{*}{\underline {n}}\iff [\![M]\!]=n} {\displaystyle M\to ^{*}{\underline {n}}\iff [\![M]\!]=n} Notons qu'il y a au plus un entier n {\displaystyle n} {\displaystyle n} tel que M → ∗ n _ {\displaystyle M\to ^{*}{\underline {n}}} {\displaystyle M\to ^{*}{\underline {n}}}.

On en déduit le corollaire suivant :

Corollaire — Dans les mêmes conditions que précédemment, M {\displaystyle M} {\displaystyle M} ne termine pas si et seulement si [ [ M ] ] = ⊥ {\displaystyle [\![M]\!]=\bot } {\displaystyle [\![M]\!]=\bot }.

Ce théorème permet de relier la sémantique dénotationnelle et la sémantique opérationnelle de PCF, et de montrer en particulier que la sémantique de PCF ne distingue pas les termes égaux.

Le sens direct de ce résultat est immédiat, c'est la propriété de correction d'un modèle. Le sens réciproque est plus difficile à démontrer ; les démonstrations données par Plotkin[15] ou par Amadio et Curien[14] utilisent la méthode des relations logiques (en), qui consiste grossièrement à séparer cette preuve en deux propriétés, puis à montrer une première propriété par induction sur les types, et une deuxième sur les termes.

Équivalences entre termes

[modifier | modifier le code]

Étant donné deux termes Γ ⊢ M : α {\displaystyle \Gamma \vdash M:\alpha } {\displaystyle \Gamma \vdash M:\alpha } et Γ ⊢ N : α {\displaystyle \Gamma \vdash N:\alpha } {\displaystyle \Gamma \vdash N:\alpha }, on peut se demander à quelle condition ces deux termes sont « les mêmes ».

Équivalence observationnelle

[modifier | modifier le code]

Une première notion d'équivalence entre termes est l'équivalence observationnelle[16],[17] : intuitivement, deux termes sont observationnellement équivalents si on peut remplacer l'un par l'autre dans n'importe quel programme en obtenant le même résultat.

Une première question soulevée par cette définition vient de la notion même de « résultat ». En effet, on ne peut pas distinguer deux fonctions directement : d'une part, le code d'une fonction n'est pas accessible dans PCF, d'autre part, certaines fonctions sont clairement équivalentes, comme λ x α . x α {\displaystyle \lambda x^{\alpha }.x^{\alpha }} {\displaystyle \lambda x^{\alpha }.x^{\alpha }} et λ x α . ( λ y α . y α )   x α {\displaystyle \lambda x^{\alpha }.(\lambda y^{\alpha }.y^{\alpha })~x^{\alpha }} {\displaystyle \lambda x^{\alpha }.(\lambda y^{\alpha }.y^{\alpha })~x^{\alpha }}, qui calculent toutes deux l'identité, mais sont en forme normale pour → {\displaystyle \to } {\displaystyle \to }. Le seul moyen de distinguer deux fonctions est d'appliquer chacune à un même argument, et observer que leurs résultats diffèrent.

En revanche, étant donné les booléens true {\displaystyle \operatorname {true} } {\displaystyle \operatorname {true} } et false {\displaystyle \operatorname {false} } {\displaystyle \operatorname {false} }, il est évident qu'ils sont différents. On définit donc les termes observables comme ceux qu'on peut intuitivement séparer : il s'agit des entiers n _ {\displaystyle {\underline {n}}} {\displaystyle {\underline {n}}} pour n ∈ N {\displaystyle n\in \mathbb {N} } {\displaystyle n\in \mathbb {N} } et des booléens true {\displaystyle \operatorname {true} } {\displaystyle \operatorname {true} } et false {\displaystyle \operatorname {false} } {\displaystyle \operatorname {false} }. Sans perte de généralité, les résultats qui suivront ne mentionneront que les entiers.

Si t {\displaystyle t} {\displaystyle t} et u {\displaystyle u} {\displaystyle u} sont des termes clos d'un type de base, ils sont observationnellement équivalents s'ils se réduisent tous deux vers le même observable, ou si tous les deux ne terminent pas. Dans le cas plus général, si A {\displaystyle A} {\displaystyle A} n'est pas un type de base, il n'y a pas d'observable de type A {\displaystyle A} {\displaystyle A}, et si M {\displaystyle M} {\displaystyle M} et N {\displaystyle N} {\displaystyle N} ne sont pas clos, alors ils pourraient se réduire vers des variables, qu'on ne sait pas distinguer intuitivement non plus. On définit donc la notion de contexte (différente de Γ {\displaystyle \Gamma } {\displaystyle \Gamma } dans Γ ⊢ M : α {\displaystyle \Gamma \vdash M:\alpha } {\displaystyle \Gamma \vdash M:\alpha }, qu'on appelle aussi contexte) : un contexte C [ _ ] {\displaystyle C[\_]} {\displaystyle C[\_]} est un terme avec exactement un « trou », c'est-à-dire qu'exactement un sous-terme est remplacé par ◻ {\displaystyle \square } {\displaystyle \square }. Un contexte peut-être typé, et une opération naturelle consiste à remplacer le trou par un terme du même type : on note cela C [ t ] {\displaystyle C[t]} {\displaystyle C[t]}. Un contexte clos d'un type de base permet ainsi de représenter un programme, dont on sait qu'il va s'évaluer vers un observable, et dans lequel on peut mettre soit M {\displaystyle M} {\displaystyle M}, soit N {\displaystyle N} {\displaystyle N}.

Définition (équivalence observationnelle) — Si Γ ⊢ M : α {\displaystyle \Gamma \vdash M:\alpha } {\displaystyle \Gamma \vdash M:\alpha } et Γ ⊢ N : α {\displaystyle \Gamma \vdash N:\alpha } {\displaystyle \Gamma \vdash N:\alpha } alors on dit que M {\displaystyle M} {\displaystyle M} et N {\displaystyle N} {\displaystyle N} sont observationnellement équivalents et on note M = o b s N {\displaystyle M=_{obs}N} {\displaystyle M=_{obs}N} lorsque pour tout contexte C [ _ ] {\displaystyle C[\_]} {\displaystyle C[\_]} clos et de type ι {\displaystyle \iota } {\displaystyle \iota }, et pour tout entier n {\displaystyle n} {\displaystyle n}, on a :

C [ M ] → ∗ n _ ⟺ C [ N ] → ∗ n _ {\displaystyle C[M]\to ^{*}{\underline {n}}\iff C[N]\to ^{*}{\underline {n}}} {\displaystyle C[M]\to ^{*}{\underline {n}}\iff C[N]\to ^{*}{\underline {n}}}

Par exemple, on peut distinguer les deux fonctions λ x ι . 0 _ {\displaystyle \lambda x^{\iota }.{\underline {0}}} {\displaystyle \lambda x^{\iota }.{\underline {0}}} et λ x ι . 1 _ {\displaystyle \lambda x^{\iota }.{\underline {1}}} {\displaystyle \lambda x^{\iota }.{\underline {1}}} de type ι → ι {\displaystyle \iota \to \iota } {\displaystyle \iota \to \iota }, dans le contexte C [ _ ] = ◻   0 _ {\displaystyle C[\_]=\square ~{\underline {0}}} {\displaystyle C[\_]=\square ~{\underline {0}}}, puisque dans ce contexte, la première fonction se réduit vers 0 _ {\displaystyle {\underline {0}}} {\displaystyle {\underline {0}}} tandis que la deuxième se réduit vers 1 _ {\displaystyle {\underline {1}}} {\displaystyle {\underline {1}}}.

Plus généralement, on peut définir un préordre entre termes d'un même type pour lequel t {\displaystyle t} {\displaystyle t} est plus petit que u {\displaystyle u} {\displaystyle u} si u {\displaystyle u} {\displaystyle u} représente un programme qui étend t {\displaystyle t} {\displaystyle t}, dans le sens où quand t {\displaystyle t} {\displaystyle t} renvoie un résultat, u {\displaystyle u} {\displaystyle u} renvoie le même, u {\displaystyle u} {\displaystyle u} peut être défini sur plus d'arguments que t {\displaystyle t} {\displaystyle t}.

Définition (préordre observationnel) — Si Γ ⊢ M : α {\displaystyle \Gamma \vdash M:\alpha } {\displaystyle \Gamma \vdash M:\alpha } et Γ ⊢ N : α {\displaystyle \Gamma \vdash N:\alpha } {\displaystyle \Gamma \vdash N:\alpha } alors on note M ≤ o p N {\displaystyle M\leq _{op}N} {\displaystyle M\leq _{op}N} lorsque pour tout contexte C [ _ ] {\displaystyle C[\_]} {\displaystyle C[\_]} clos et de type ι {\displaystyle \iota } {\displaystyle \iota }, et pour tout entier n {\displaystyle n} {\displaystyle n}, on a :

C [ M ] → ∗ n _ ⟹ C [ N ] → ∗ n _ {\displaystyle C[M]\to ^{*}{\underline {n}}\implies C[N]\to ^{*}{\underline {n}}} {\displaystyle C[M]\to ^{*}{\underline {n}}\implies C[N]\to ^{*}{\underline {n}}}

Par exemple, si M {\displaystyle M} {\displaystyle M} et N {\displaystyle N} {\displaystyle N} sont des fonctions de ι → ι {\displaystyle \iota \to \iota } {\displaystyle \iota \to \iota } telles que M {\displaystyle M} {\displaystyle M} renvoie toujours ⊥ {\displaystyle \bot } {\displaystyle \bot } — sauf en 0 _ {\displaystyle {\underline {0}}} {\displaystyle {\underline {0}}} où M {\displaystyle M} {\displaystyle M} renvoie 0 _ {\displaystyle {\underline {0}}} {\displaystyle {\underline {0}}} — alors M ≤ o p N {\displaystyle M\leq _{op}N} {\displaystyle M\leq _{op}N} si et seulement si N   0 _ → ∗ 0 _ {\displaystyle N~{\underline {0}}\to ^{*}{\underline {0}}} {\displaystyle N~{\underline {0}}\to ^{*}{\underline {0}}}.

Équivalence dénotationnelle

[modifier | modifier le code]

Tout modèle standard induit également une notion d'équivalence entre deux termes[18], à savoir le fait qu'ils aient la même dénotation. De même, un modèle induit également une relation d'ordre entre termes, où M {\displaystyle M} {\displaystyle M} est plus petit que N {\displaystyle N} {\displaystyle N} lorsque [ [ M ] ] ≤ [ [ N ] ] {\displaystyle [\![M]\!]\leq [\![N]\!]} {\displaystyle [\![M]\!]\leq [\![N]\!]}. Cette relation capture l'idée que dans le modèle, M {\displaystyle M} {\displaystyle M} est plus défini que N {\displaystyle N} {\displaystyle N}. Ces relations dépendent du modèle choisi.

Complète adéquation

[modifier | modifier le code]

On peut se demander dans quelle mesure ces deux notions d'équivalence sont comparables[18]. De manière générale, le théorème d'adéquation peut se reformuler comme le fait que pour tous termes M {\displaystyle M} {\displaystyle M} et N {\displaystyle N} {\displaystyle N}, M ≤ o b s N {\displaystyle M\leq _{obs}N} {\displaystyle M\leq _{obs}N} si et seulement si pour tout contexte C [ _ ] {\displaystyle C[\_]} {\displaystyle C[\_]} clos et de type entier, [ [ C [ M ] ] ] ≤ [ [ C [ N ] ] ] {\displaystyle [\![C[M]]\!]\leq [\![C[N]]\!]} {\displaystyle [\![C[M]]\!]\leq [\![C[N]]\!]}[19].

Ce théorème a deux conséquences intéressantes : La première est que pour tous termes clos M {\displaystyle M} {\displaystyle M} et N {\displaystyle N} {\displaystyle N} de type entier, M = o b s N ⟺ [ [ M ] ] = [ [ N ] ] {\displaystyle M=_{obs}N\iff [\![M]\!]=[\![N]\!]} {\displaystyle M=_{obs}N\iff [\![M]\!]=[\![N]\!]}, donc qu'équivalence dénotationnelle et observationnelle coïncident au niveau des types de base[17]. La seconde est que pour tous termes Γ ⊢ M : α {\displaystyle \Gamma \vdash M:\alpha } {\displaystyle \Gamma \vdash M:\alpha } et Γ ⊢ N : α {\displaystyle \Gamma \vdash N:\alpha } {\displaystyle \Gamma \vdash N:\alpha }, [ [ M ] ] ≤ [ [ N ] ] ⟹ M ≤ o b s N {\displaystyle [\![M]\!]\leq [\![N]\!]\implies M\leq _{obs}N} {\displaystyle [\![M]\!]\leq [\![N]\!]\implies M\leq _{obs}N} (donc en particulier que [ [ M ] ] = [ [ N ] ] ⟹ M = o b s N {\displaystyle [\![M]\!]=[\![N]\!]\implies M=_{obs}N} {\displaystyle [\![M]\!]=[\![N]\!]\implies M=_{obs}N})[20],[21].

Définition (Complète adéquation) — Un modèle standard de PCF est dit complètement adéquat[18],[20],[17] (en anglais : fully abstract) lorsque pour tous termes M {\displaystyle M} {\displaystyle M} et N {\displaystyle N} {\displaystyle N} tels que Γ ⊢ M : α {\displaystyle \Gamma \vdash M:\alpha } {\displaystyle \Gamma \vdash M:\alpha } et Γ ⊢ N : α {\displaystyle \Gamma \vdash N:\alpha } {\displaystyle \Gamma \vdash N:\alpha }, la propriété suivante, dite de complète adéquation (en anglais : full abstraction), est vérifiée :

[ [ M ] ] ≤ [ [ N ] ] ⟺ M ≤ o b s N {\displaystyle [\![M]\!]\leq [\![N]\!]\iff M\leq _{obs}N} {\displaystyle [\![M]\!]\leq [\![N]\!]\iff M\leq _{obs}N}

Plotkin a montré que cette propriété n'est pas vérifiée par le modèle continu de PCF[22]. On peut en effet définir dans ce modèle la fonction « ou parallèle » p o r : B ⊥ → B ⊥ → B ⊥ {\displaystyle por:\mathbb {B} _{\bot }\to \mathbb {B} _{\bot }\to \mathbb {B} _{\bot }} {\displaystyle por:\mathbb {B} _{\bot }\to \mathbb {B} _{\bot }\to \mathbb {B} _{\bot }} (en anglais : parallel or) dans ce modèle, qui est définie par :

p o r ( x ) ( y ) = { true si  x = true ⁡  ou  y = true false si  x = false ⁡  et  y = false ⊥ sinon {\displaystyle por(x)(y)={\begin{cases}\operatorname {true} &{\text{si }}x=\operatorname {true} {\text{ ou }}y=\operatorname {true} \\\operatorname {false} &{\text{si }}x=\operatorname {false} {\text{ et }}y=\operatorname {false} \\\bot &{\text{sinon}}\end{cases}}} {\displaystyle por(x)(y)={\begin{cases}\operatorname {true} &{\text{si }}x=\operatorname {true} {\text{ ou }}y=\operatorname {true} \\\operatorname {false} &{\text{si }}x=\operatorname {false} {\text{ et }}y=\operatorname {false} \\\bot &{\text{sinon}}\end{cases}}}

En revanche, cette fonction n'est pas définissable dans PCF : il n'y a pas de terme M {\displaystyle M} {\displaystyle M} bien typé tel que [ [ M ] ] = p o r {\displaystyle [\![M]\!]=por} {\displaystyle [\![M]\!]=por}. Intuitivement, un tel terme lancerait en parallèle les deux programmes qu'on lui passe en argument, renvoyant vrai dès que l'un d'eux retourne vrai, ou faux si les deux retournent faux. Au contraire, PCF est un langage séquentiel[23],[20], qui ne supporte pas l'exécution entrelacée.

On peut montrer que si on définit, pour chaque booléen b {\displaystyle b} {\displaystyle b}, le terme M b {\displaystyle M_{b}} {\displaystyle M_{b}} suivant :

λ g o → o → o . if ⁡   g   ( true ) ( ⊥ )   then ⁡   ( if ⁡   g ( ⊥ ) ( true )   then ⁡   ( if ⁡   g   ( false ) ( false )   then ⁡   ⊥   else ⁡   b )   else ⁡   ⊥ )   else ⁡   ⊥ {\displaystyle \lambda g^{o\to o\to o}.\operatorname {if} ~g~(\operatorname {true} )(\bot )~\operatorname {then} ~(\operatorname {if} ~g(\bot )(\operatorname {true} )~\operatorname {then} ~(\operatorname {if} ~g~(\operatorname {false} )(\operatorname {false} )~\operatorname {then} ~\bot ~\operatorname {else} ~b)~\operatorname {else} ~\bot )~\operatorname {else} ~\bot } {\displaystyle \lambda g^{o\to o\to o}.\operatorname {if} ~g~(\operatorname {true} )(\bot )~\operatorname {then} ~(\operatorname {if} ~g(\bot )(\operatorname {true} )~\operatorname {then} ~(\operatorname {if} ~g~(\operatorname {false} )(\operatorname {false} )~\operatorname {then} ~\bot ~\operatorname {else} ~b)~\operatorname {else} ~\bot )~\operatorname {else} ~\bot }

Alors M true = o b s M false {\displaystyle M_{\operatorname {true} }=_{obs}M_{\operatorname {false} }} {\displaystyle M_{\operatorname {true} }=_{obs}M_{\operatorname {false} }}, mais [ [ M true ] ] ( p o r ) ≠ [ [ M true ] ] ( p o r ) {\displaystyle [\![M_{\operatorname {true} }]\!](por)\neq [\![M_{\operatorname {true} }]\!](por)} {\displaystyle [\![M_{\operatorname {true} }]\!](por)\neq [\![M_{\operatorname {true} }]\!](por)} car pour tout booléen b {\displaystyle b} {\displaystyle b}, [ [ M b ] ] ( p o r ) = b {\displaystyle [\![M_{b}]\!](por)=b} {\displaystyle [\![M_{b}]\!](por)=b}, donc le modèle standard de PCF n'est pas complètement abstrait[20]. On peut étendre le langage PCF pour un obtenir nouveau langage, PCF+por, dans lequelle une nouvelle primitive ‖ {\displaystyle \|} {\displaystyle \|} est ajoutée. Elle est de type o → o → o {\displaystyle o\to o\to o} {\displaystyle o\to o\to o}, elle vérifie true ⁡ ‖ M → true {\displaystyle \operatorname {true} \|M\to \operatorname {true} } {\displaystyle \operatorname {true} \|M\to \operatorname {true} }, M ‖ true → true {\displaystyle M\|\operatorname {true} \to \operatorname {true} } {\displaystyle M\|\operatorname {true} \to \operatorname {true} } et false ⁡ ‖ false → false {\displaystyle \operatorname {false} \|\operatorname {false} \to \operatorname {false} } {\displaystyle \operatorname {false} \|\operatorname {false} \to \operatorname {false} }, si M {\displaystyle M} {\displaystyle M} et N {\displaystyle N} {\displaystyle N} sont des booléens, M ‖ N {\displaystyle M\|N} {\displaystyle M\|N} aussi et on étend la sémantique continue en définissant [ [ ‖ ] ] = p o r {\displaystyle [\![\|]\!]=por} {\displaystyle [\![\|]\!]=por}. La catégorie des CPO est un modèle complètement abstrait pour ce nouveau langage[24], et on peut montrer que les éléments définissables sont exactement les éléments compacts[25].

Problème de la complète adéquation

[modifier | modifier le code]

Milner a fourni en premier en 1977 un modèle standard complètement adéquat de PCF en quotientant la syntaxe de PCF pour identifier les termes observationnellement équivalents. Il a de plus donné, sous certaines conditions, une caractérisation des modèles standard complètement adéquats de PCF[12] :

Théorème (Caractérisation des modèles extensionnellement ordonnés complètement adéquats[26]) — Un modèle de PCF extensionnellement ordonné est complètement adéquat si et seulement tous les hom-sets sont algébriques et tous les éléments compacts sont définissables.

De plus, il a montré que sous ces conditions, tous ces modèles sont isomorphes[12] :

Théorème (Unicité des modèles extensionnellement ordonnés complètement adéquats[26],[21]) — Tous les modèles extensionnellement ordonnés et complètement adéquats de PCF sont isomorphes entre eux, et cet isomorphisme préserve l'ordre.

Néanmoins le modèle proposé par Milner n'a pas été jugé satisfaisant par la communauté scientifique, qui désirait trouver un modèle plus sémantique[26]. La communauté scientifique a donc essayé de trouver une description plus sémantique de cet unique modèle complètement adéquat[17]. Hyland et Ong en proposent un compte rendu détaillé[27], de même que Curien[17]. Gérard Berry a proposé ensuite en 1978 le modèle stable de PCF[28],[29], qui est extensionnel mais pas extensionnellement ordonné, puis Berry et Curien ont proposé en 1982 le modèle des algorithmes séquentiels[30],[31], qui n'est pas extensionnel. Dans ces deux modèles, il y a des éléments compacts non définissables[17]. Cela a ouvert la voie à d'autres travaux qui tentaient de définir la séquentialité pour les fonctions d'ordre supérieur, notamment par Antonio Bucciarelli et Thomas Ehrhard[32],[33].

En 2000, Martin Hyland et Luke Ong d'une part et Samson Abramsky, Radha Jagadeesan et Pasquale Malacaria d'autre part ont indépendamment proposé chacun un modèle basé sur la sémantique des jeux, le modèle des jeux OH[27] et le modèle des jeux AJM[34] (nommés d'après les initiales respectives de leurs auteurs). Ces modèles présentent la propriété que tous les éléments compacts sont définissables, mais ils ne sont pas extensionnels, et correspondent à des descriptions purement sémantiques de la catégorie des arbres de Böhm de PCF[17]. Il est possible, via une construction catégorique, de rendre ces modèles extensionnellement ordonnés, et donc d'obtenir à partir de ces modèles une description du modèle complètement adéquat de PCF[35],[17].

En 2001 Ralph Loader conclut par la négative la quête de la solution au problème de la complète adéquation : il montre que la relation d'équivalence observationnelle dans PCF finitaire, c'est-à-dire PCF sans les entiers, avec uniquement les booléens comme type de base, était indécidable[36], et donc qu'un modèle de PCF vérifiant les critères de Achim Jung and Allen Stoughton[37], qui précisent que les objets interprétants les types finis doivent pouvoir être effectivement décrits, est impossible.

Turing-complétude

[modifier | modifier le code]

Si M : ι → ι → … ⏞ k → ι {\displaystyle M:\overbrace {\iota \to \iota \to \dots } ^{k}\to \iota } {\displaystyle M:\overbrace {\iota \to \iota \to \dots } ^{k}\to \iota } est un programme dans PCF qui prend k {\displaystyle k} {\displaystyle k} entiers en entrée et renvoie un entier, on peut montrer que M {\displaystyle M} {\displaystyle M} détermine une fonction calculable partielle f : N k → N {\displaystyle f:\mathbb {N} ^{k}\to \mathbb {N} } {\displaystyle f:\mathbb {N} ^{k}\to \mathbb {N} } par f ( n 1 , … , n k ) = m {\displaystyle f(n_{1},\dots ,n_{k})=m} {\displaystyle f(n_{1},\dots ,n_{k})=m} si f   n _ 1 … n _ k → ∗ m _ {\displaystyle f~{\underline {n}}_{1}\dots {\underline {n}}_{k}\to ^{*}{\underline {m}}} {\displaystyle f~{\underline {n}}_{1}\dots {\underline {n}}_{k}\to ^{*}{\underline {m}}} et f ( n 1 , … , n k ) {\displaystyle f(n_{1},\dots ,n_{k})} {\displaystyle f(n_{1},\dots ,n_{k})} n'est pas définie sinon.

Réciproquement, étant donnée une fonction calculable partielle f : N k → N {\displaystyle f:\mathbb {N} ^{k}\to \mathbb {N} } {\displaystyle f:\mathbb {N} ^{k}\to \mathbb {N} }, on peut se demander si elle est représentée par un terme M : ι → ι → … ⏞ k → ι {\displaystyle M:\overbrace {\iota \to \iota \to \dots } ^{k}\to \iota } {\displaystyle M:\overbrace {\iota \to \iota \to \dots } ^{k}\to \iota } de PCF tel que pour tous entiers n 1 , … , n k {\displaystyle n_{1},\dots ,n_{k}} {\displaystyle n_{1},\dots ,n_{k}} et m {\displaystyle m} {\displaystyle m},

M   n _ 1 … n _ k → ∗ m _ ⟺ f ( n 1 , … , n k ) = m {\displaystyle M~{\underline {n}}_{1}\dots {\underline {n}}_{k}\to ^{*}{\underline {m}}\iff f(n_{1},\dots ,n_{k})=m} {\displaystyle M~{\underline {n}}_{1}\dots {\underline {n}}_{k}\to ^{*}{\underline {m}}\iff f(n_{1},\dots ,n_{k})=m}.

Ce problème correspond à la notion de complétude au sens de Turing. La réponse est positive, donc PCF peut représenter toutes les fonctions calculables entre entiers[38].

Démonstration — On sait que les fonctions calculables sont obtenues en ajoutant le schéma μ {\displaystyle \mu } {\displaystyle \mu } de minimisation non bornée aux fonctions primitives récursives, et on peut assez facilement montrer que toutes les fonctions primitives récursives sont encodables dans PCF.

Il reste donc à montrer que PCF supporte l'opération de minimisation non bornée : étant donné un terme f : ι → o {\displaystyle f:\iota \to o} {\displaystyle f:\iota \to o}, μ f : ι {\displaystyle \mu f:\iota } {\displaystyle \mu f:\iota } est le plus entier n {\displaystyle n} {\displaystyle n} tel que f   n _ → ∗ true {\displaystyle f~{\underline {n}}\to ^{*}\operatorname {true} } {\displaystyle f~{\underline {n}}\to ^{*}\operatorname {true} } et f   k _ → ∗ false {\displaystyle f~{\underline {k}}\to ^{*}\operatorname {false} } {\displaystyle f~{\underline {k}}\to ^{*}\operatorname {false} } pour tout k < n {\displaystyle k<n} {\displaystyle k<n} si un tel entier n {\displaystyle n} {\displaystyle n} existe, et μ f {\displaystyle \mu f} {\displaystyle \mu f} ne se normalise pas sinon.

Pour cela, on définit μ : ( ι → o ) → ι {\displaystyle \mu :(\iota \to o)\to \iota } {\displaystyle \mu :(\iota \to o)\to \iota } par λ f ι → o . Y ( λ h ι → ι . λ n ι . if ⁡ f   n then ⁡ n else ⁡ h   ( succ ⁡   n ) )   0 _ {\displaystyle \lambda f^{\iota \to o}.Y(\lambda h^{\iota \to \iota }.\lambda n^{\iota }.\operatorname {if} f~n\operatorname {then} n\operatorname {else} h~(\operatorname {succ} ~n))~{\underline {0}}} {\displaystyle \lambda f^{\iota \to o}.Y(\lambda h^{\iota \to \iota }.\lambda n^{\iota }.\operatorname {if} f~n\operatorname {then} n\operatorname {else} h~(\operatorname {succ} ~n))~{\underline {0}}}. On vérifie facilement que μ f {\displaystyle \mu f} {\displaystyle \mu f} vérifie bien la propriété désirée.

Bibliographie

[modifier | modifier le code]
  • (en) Roberto M. Amadio et Pierre-Louis Curien, Domains and Lambda-Calculi, Cambridge University Press, coll. « Cambridge Tracts in Theoretical Computer Science », 1998, 534 p. (ISBN 978-0-521-62277-6, lire en ligne). Ouvrage utilisé pour la rédaction de l'article

Notes et références

[modifier | modifier le code]
  1. ↑ a b et c (en) Gordon Plotkin, « LCF considered as a programming language », Theoretical Computer Science, vol. 5, no 3,‎ 1977, p. 223–255 (DOI 10.1016/0304-3975(77)90044-5 Accès libre, lire en ligne Accès libre [PDF])
  2. ↑ (en) Dana S. Scott, « A type-theoretical alternative to ISWIM, CUCH, OWHY », Theoretical Computer Science, vol. 121, no 1,‎ 6 décembre 1993, p. 411–440 (ISSN 0304-3975, DOI 10.1016/0304-3975(93)90095-B Accès libre, lire en ligne Accès libre [PDF], consulté le 17 novembre 2024) — distribué à l'origine comme des notes non publiées d'un séminaire donné à Oxford en 1969 sous le nom A theory of computable functions of higher type.
  3. ↑ Amadio et Curien 1998, p. 149
  4. ↑ Amadio et Curien 1998, p. 145
  5. ↑ Amadio et Curien 1998, p. 151
  6. ↑ a b c et d Amadio et Curien 1998, p. 150
  7. ↑ Amadio et Curien 1998, p. 5
  8. ↑ Amadio et Curien 1998, p. 14-15
  9. ↑ Amadio et Curien 1998, p. 95
  10. ↑ a et b Amadio et Curien 1998, p. 146
  11. ↑ a et b Amadio et Curien 1998, p. 149-150
  12. ↑ a b et c Robin Milner, « Fully abstract models of typed λ-calculi », Theoretical Computer Science, vol. 4, no 1,‎ 1er février 1977, p. 1–22 (ISSN 0304-3975, DOI 10.1016/0304-3975(77)90053-6, lire en ligne, consulté le 1er mai 2025)
  13. ↑ Amadio et Curien 1998, p. 104
  14. ↑ a et b Amadio et Curien 1998, p. 152
  15. ↑ Plotkin 1977, p. 230
  16. ↑ Amadio et Curien 1998, p. 154-155
  17. ↑ a b c d e f g et h (en) Pierre-Louis Curien, « Definability and Full Abstraction », Electronic Notes in Theoretical Computer Science, computation, Meaning, and Logic: Articles dedicated to Gordon Plotkin, vol. 172,‎ 1er avril 2007, p. 301–310 (ISSN 1571-0661, DOI 10.1016/j.entcs.2007.02.011 Accès libre, lire en ligne Accès libre [PDF], consulté le 25 avril 2025)
  18. ↑ a b et c Plotkin 1977, p. 233-234
  19. ↑ Amadio et Curien 1998, p. 154
  20. ↑ a b c et d Amadio et Curien 1998, p. 155-156
  21. ↑ a et b Plotkin 1977, p. 244
  22. ↑ 155-156
  23. ↑ Plotkin 1977, p. 235-236, Plotkin nomme ce résultat « activité ».
  24. ↑ Plotkin 1977, p. 237
  25. ↑ Plotkin 1977, p. 238
  26. ↑ a b et c Curien et Amadio 1998, p. 156-157
  27. ↑ a et b (en) Martin Hyland et Luke Ong, « On Full Abstraction for PCF: I, II, and III », Information and Computation, vol. 163, no 2,‎ 15 décembre 2000, p. 285–408 (ISSN 0890-5401, DOI 10.1006/inco.2000.2917)
  28. ↑ (en) Gérard Berry, « Stable models of typed λ-calculi », Automata, Languages and Programming, Springer,‎ 1978, p. 72–89 (ISBN 978-3-540-35807-7, DOI 10.1007/3-540-08860-1_7 Accès payant)
  29. ↑ Amadio et Curien 1998, p. 305-310
  30. ↑ (en) Gérard Berry et P. L. Curien, « Sequential algorithms on concrete data structures », Theoretical Computer Science, vol. 20, no 3,‎ 1er juillet 1982, p. 265–321 (ISSN 0304-3975, DOI 10.1016/S0304-3975(82)80002-9 Accès libre)
  31. ↑ Amadio et Curien 1998, p. 386-396
  32. ↑ (en) A. Bucciarelli et T. Ehrhard, « Sequentiality and strong stability », [1991] Proceedings Sixth Annual IEEE Symposium on Logic in Computer Science,‎ juillet 1991, p. 138–145 (DOI 10.1109/LICS.1991.151638 Accès payant)
  33. ↑ (en) Antonio Bucciarelli et Thomas Ehrhard, « A theory of sequentiality », Theoretical Computer Science, vol. 113, no 2,‎ 7 juin 1993, p. 273–291 (ISSN 0304-3975, DOI 10.1016/0304-3975(93)90005-E Accès libre)
  34. ↑ (en) Samson Abramsky, Radha Jagadeesan et Pasquale Malacaria, « Full Abstraction for PCF », Information and Computation, vol. 163, no 2,‎ 15 décembre 2000, p. 409–470 (ISSN 0890-5401, DOI 10.1006/inco.2000.2930 Accès libre)
  35. ↑ Curien et Amadio 1998, p. 162-163
  36. ↑ (en) Ralph Loader, « Finitary PCF is not decidable », Theoretical Computer Science, vol. 266, no 1,‎ 6 septembre 2001, p. 341–364 (ISSN 0304-3975, DOI 10.1016/S0304-3975(00)00194-8 Accès libre)
  37. ↑ (en) Achim Jung et Allen Stoughton, « Studying the fully abstract model of PCF within its continuous function model », Typed Lambda Calculi and Applications, Springer,‎ 1993, p. 230–244 (ISBN 978-3-540-47586-6, DOI 10.1007/BFb0037109, lire en ligne, consulté le 9 mai 2025)
  38. ↑ Scott 1993, p. 435
  • icône décorative Portail de l'informatique théorique
Ce document provient de « https://fr.teknopedia.teknokrat.ac.id/w/index.php?title=Programming_Computable_Functions&oldid=228358181 ».
Catégories :
  • Théorie des types
  • Langage de programmation théorique
  • Langage fonctionnel
Catégories cachées :
  • Article contenant un appel à traduction en anglais
  • Portail:Informatique théorique/Articles liés
  • Portail:Informatique/Articles liés
  • Portail:Mathématiques/Articles liés
  • Portail:Sciences/Articles liés

  • indonesia
  • Polski
  • الرية
  • Deutsch
  • English
  • Español
  • Français
  • Italiano
  • مصر
  • Nederlands
  • 本語
  • Português
  • Sinugboanong Binisaya
  • Svenska
  • Українска
  • Tiếng Việt
  • Winaray
  • 中文
  • Русски
Sunting pranala
Pusat Layanan

UNIVERSITAS TEKNOKRAT INDONESIA | ASEAN's Best Private University
Jl. ZA. Pagar Alam No.9 -11, Labuhan Ratu, Kec. Kedaton, Kota Bandar Lampung, Lampung 35132
Phone: (0721) 702022
Email: pmb@teknokrat.ac.id