• Aucun résultat trouvé

Terminons cette partie par la définition de morphisme entre deux algèbres sur la même signature. Informellement, un morphisme est une application qui respecte les opérations de l’algèbre. C’est ce respect de la structure qui nous conduira à utiliser les morphismes comme fonctions d’abstraction.

Définition – 4.1.8

Soit Θ = (S, Ω) une signature algébrique et M, N deux Θ-algèbres. On appelle mor-phisme de M vers N toute famille d’applications :

α = (αs)s∈S avec αs: Ms→ Ns

telle que, quel que soit f : s1× . . . × sn→ s0 ∈ Ω, quels que soient m1∈ Ms1, . . . , mn∈ Msn, on ait :

αs0(fM(m1, . . . , mn)) = fNs1(m1), . . . , αsn(mn))

Dans la suite, on notera α à la place de αs.

Remarque : Il existe aussi une notion de morphisme entre deux structures M et N sur la même signature Σ = (S, Ω, Π). Il s’agit d’un morphisme α de [M] vers [N ] tel que, quels que soient P : s1× . . . × sn∈ Π et m1∈ Ms1, . . . , mn∈ Msn, on ait :

PM(m1, . . . , mn) ⇒ PN(α(m1), . . . , α(mn))

Cette définition n’apparaîtra pas dans la suite (sauf, en filigrane, dans la définition de modèle initial d’une spécification). En particulier, elle ne sera pas utilisée dans la définition des abs-tractions, où les seuls morphismes qui entrent en jeu sont des morphismes d’algèbres. 

4.2 Égalité et spécifications

Nous avons vu plus haut que, même dans le cas de la signature assez simple des listes d’entiers, définir une structure pouvait se révéler fastidieux. Nous allons expliquer ici com-ment décrire ces structures de manière plus succincte. Tout d’abord, on peut éviter de traiter explicitement le prédicat d’égalité au moyen de la définition suivante.

Définition – 4.2.1

Soit Σ = (S, Ω, Π) une signature du premier ordre. On note ΣEq la signature définie par :

ΣEq = (S, Ω, Πˆ Eq)

ΠEq = Π ∪ {__ = __ : s × s | s ∈ S}ˆ

(la notation __ = __ sert simplement à indiquer que l’opérateur = sera noté de manière infixe). On appelle Σ-structure avec égalité toute ΣEq-structure M telle que quel que soit s ∈ S on ait :

=M = {(m, m) | m ∈ Mˆ s}

et les énoncés du premier ordre avec égalité sur Σ et un ensemble X de variables sont simplement les éléments de Sen(ΣEq). On notera StrEq(Σ) (respectivement SenEq(Σ)) les Σ-structures (respectivement les énoncés du premier ordre sur Σ et X) avec égalité. Notons que toute Σ-structure s’étend de manière unique n une Σ-structure avec égalité. Cette définition nous permet donc d’écrire des signatures et des structures de manière plus simple, puisqu’il n’y a plus besoin de décrire explicitement l’égalité. Afin de définir des structures de manière encore plus concise, nous allons maintenant présenter quelques rudi-ments de spécifications algébriques, au moyen du langage Casl. Une spécification en Casl décrit une signature du premier ordre ainsi qu’un ensemble de structures avec égalité sur cette signature (ses modèles). Nous n’en définirons ni la syntaxe précise, ni la sémantique, qui sortiraient du cadre de cette thèse, et nous laissons au lecteur le soin de se reporter à [BM01, ABK+02] pour une introduction et [Cof] pour une description plus précise. Nous nous contenterons d’expliquer les constructions employées au moyen de quelques exemples et, dans la suite, nous n’utiliserons pas de nouvelle construction sans en donner en même temps la signification. Commençons avec la spécification suivante :

spec NatList = sorts Nat, List ops 0 : Nat;

succ: Nat → Nat; [] : List;

__ :: __ : Nat × List → List preds __ ≤ __ : Nat × Nat;

__ ∈ __ : Nat × List end

Cette spécification se contente de définir les sortes Nat et List, les symboles de fonctions 0, succ, [], __ :: __ et les symboles de prédicats __ ≤ __ et __ ∈ __. Notons que nous nous sommes autorisés à employer des notations un peu plus parlantes, 0 pour le zéro des entiers, [] pour la constante désignant la liste vide et :: pour le constructeur de listes, qui sera noté de manière infixe, ainsi que ≤ pour la relation d’ordre sur les entiers et ∈ pour l’appartenance. La signature du premier ordre associée est la signature Σ utilisée jusqu’à présent pour traiter les listes d’entiers, modulo ces quelques changements de notations et la disparition des prédicats d’égalité. Les modèles de cette spécification sont toutes les Σ-structures du premier ordre avec égalité. On peut abréger cette spécification en :

spec NatList =

types Nat ::= 0 | succ(Nat);

List ::= [] | __ :: __(Nat; List) preds __ ≤ __ : Nat × Nat;

__ ∈ __ : Nat × List end

La déclaration types permet de regrouper la déclaration d’une sorte et de ses constructeurs (i.e. des symboles de fonctions dont le type de la valeur de retour est la sorte en question). La première chose à faire pour restreindre cet ensemble de modèles jusqu’à obtenir la Σ-structure des listes d’entiers, est d’imposer que le domaine d’interprétation de Nat (respectivement List) soit l’ensemble des entiers (respectivement des suites finies d’entiers). Remarquons pour cela que les entiers ont la propriété d’être engendrés par 0 et le successeur et ce de manière libre (i.e. il n’y a pas d’équations entre des entiers définis par 0 et successeur autres que les équations triviales). Il en est d’ailleurs de même pour les listes. Casl propose une notation pour spécifier qu’une sorte est engendrée de manière libre par ces constructeurs, et c’est la suivante :

spec NatList =

free types Nat ::= 0 | succ(Nat);

List ::= [] | __ :: __(Nat; List) preds __ ≤ __ : Nat × Nat;

__ ∈ __ : Nat × List end

De cette manière, non seulement les domaines d’interprétation de Nat et List sont fixés, mais aussi l’interprétation des constructeurs. Les modèles de cette spécification sont les Σ-structures avec égalité, pour lesquelles la [Σ]-algèbre sous-jacente est la même que pour la Σ-structure des listes d’entiers. Il ne reste donc plus qu’à définir l’interprétation des symboles de prédicats. Pour cela, introduisons des axiomes dans notre spécification :

spec NatList =

free types Nat ::= 0 | succ(Nat);

List ::= [] | __ :: __(Nat; List) preds __ ≤ __ : Nat × Nat;

__ ∈ __ : Nat × List ∀x , y : Nat; l : List • 0 ≤ x • x ≤ y ⇒ succ(x ) ≤ succ(y) • x ∈ x :: l • x ∈ l ⇒ x ∈ y :: l end

Par rapport à la spécification précédente, celle-ci n’a pour modèles que ceux qui satisfont ces quatre axiomes. Nous avons ainsi éliminé quelques interprétations des symboles de pré-dicats qui ne convenaient pas (par exemple les interprétations où les prépré-dicats sont toujours faux), mais il est toujours possible de les interpréter de manière autre que dans la Σ-structure des listes d’entiers (par exemple, l’interprétation où les prédicats sont toujours vrais reste

possible). L’idée est alors de choisir pour chaque symbole de prédicat une interprétation satis-faisant ces axiomes et qui soit de plus minimale. Ceci est possible dans notre cas particulier car les axiomes sont des clauses de Horn, et ils possèdent par conséquent un plus petit modèle. La syntaxe Casl permettant de faire ce choix est la suivante :

spec NatList = free {

free types Nat ::= 0 | succ(Nat);

List ::= [] | __ :: __(Nat; List) preds __ ≤ __ : Nat × Nat;

__ ∈ __ : Nat × List ∀x , y : Nat; l : List • 0 ≤ x • x ≤ y ⇒ succ(x ) ≤ succ(y) • x ∈ x :: l • x ∈ l ⇒ x ∈ y :: l } end

La construction free autour d’une spécification a pour but de choisir, parmi les modèles de cette spécification, le modèle initial (dans le cas qui nous intéresse, c’est le modèle pour lequel l’interprétation des prédicats est minimale, ce qui est cohérent avec la définition de morphisme entre structures donnée plus haut). Signalons que cette construction est redondante avec la déclaration free types, et on pourrait donc plus simplement écrire :

spec NatList =

free types Nat ::= 0 | succ(Nat);

List ::= [] | __ :: __(Nat; List) preds __ ≤ __ : Nat × Nat;

__ ∈ __ : Nat × List then free { ∀x , y : Nat; l : List • 0 ≤ x • x ≤ y ⇒ succ(x ) ≤ succ(y) • x ∈ x :: l • x ∈ l ⇒ x ∈ y :: l } end

L’emploi de listes d’éléments d’une sorte donnée est suffisamment fréquent pour justifier l’utilisation d’une spécification générique de liste, de la forme :

spec List[sort Elem] =

free type List[Elem] ::= [] | __ :: __(Elem; List[Elem]) pred __ ∈ __ : Elem × List

then free {

∀x , y : Elem; l : List • x ∈ x :: l

• x ∈ l ⇒ x ∈ y :: l } end

Cette spécification prend en paramètre une spécification déclarant une sorte Elem et construit, sur cette spécification, les listes d’éléments de sorte Elem (en définissant par la même occasion le prédicat d’appartenance). Si on dispose d’une spécification des entiers, par exemple :

spec Nat =

free type Nat ::= 0 | succ(Nat) pred __ ≤ __ : Nat × Nat then free {

∀x , y : Nat • 0 ≤ x

• x ≤ y ⇒ succ(x ) ≤ succ(y) } end

On peut alors obtenir la spécification NatList en instanciant List avec Nat : spec NatList = List[Nat fit Elem 7→ Nat]

La déclaration fit Elem 7→ Nat permet d’utiliser Nat à la place de Elem. La spécifica-tion NatList ainsi obtenue définit en particulier une sorte List[Nat] qui représente les listes d’entiers. La spécification List sera beaucoup utilisée dans la partie suivante. Nous aurons également l’occasion de voir plus loin d’autres exemples de constructions Casl ainsi que leur signification.