Xalg / Fix / Comprendre
Navigation
Apprendre
Recettes
Référence
Comprendre
Bonnes pratiques
En pratique
Explications

Comprendre Fix

Le pourquoi derrière Fix. Trois idées, dont une découle de l'autre : tu décris, le moteur calcule ; les types pilotent l'ingénierie ; et la bidirectionnalité est un choix de modélisation, pas une limite.


Pourquoi « tu décris, il trouve »

En Prolog classique, l'ordre des règles compte, et cut te laisse contrôler la recherche. En Fix, rien de tout ça.

Une requête ne se résout pas réponse après réponse : Fix calcule un point fixe — il applique tes règles encore et encore jusqu'à ce que plus rien de nouveau n'apparaisse. Le résultat est l'ensemble complet des solutions, d'un seul tenant.

Trois conséquences directes :

C'est le renversement déclaratif : tu ne dis pas comment chercher, seulement ce qui est.


Quand le type devient le modèle (TDE)

L'idée du TDEType-Driven Engineering — tient en une phrase : un modèle métier est un AST (un type), et on le transforme en un autre modèle par une simple règle. Une fois qu'on sait déclarer un langage (Syntaxe : l'AST commande), la transformation de modèles en découle. Prenons ER → UML, en deux temps.

En Fix, tout vit dans la même base de faits : les métamodèles (les type), les modèles (des faits), la transformation (des règles ordinaires), la conformité (le typage). Aucun moteur séparé.

Temps 1 — transformer un modèle en un autre

% deux métamodèles (les AST). Le vocabulaire de TYPES est fixe → FERMÉ ;
% les NOMS (entités, attributs) sont des identifiants libres → OUVERTS.
type list(T) = nil | cons(T, list(T)).   % liste générique (type paramétré)
type atype = string | int.               % FERMÉ : types du DSL (aname/ename OUVERTS)
type attr_t  = attr(aname, atype).
type ent_t   = ent(ename, list(attr_t)). % modèle ER
type cls_t   = cls(ename, list(attr_t)). % modèle UML

modele(ent(person, cons(attr(name, string), cons(attr(age, int), nil)))).
classe(cls(N, L)) :- modele(ent(N, L)).   % la transformation : UNE règle
?- classe(C).
C = cls(person, cons(attr(name, string), cons(attr(age, int), nil)))

Le modèle ER est devenu un modèle UML — au niveau des termes, par une règle ordinaire. Pas de moteur de transformation dédié : c'est du Fix normal. Ajoute un attribut au modèle, la classe se recalcule. Rien ne dérive.

Temps 2 — donner une syntaxe de surface aux deux modèles (les DSL)

% on habille chaque modèle d'une syntaxe (un module par langage, comme en [Syntaxe]) :
% module(er, …) lit/écrit « entity … attr … », module(uml, …) « class … field … ».
% En Fix, le MODÈLE vit comme des faits ; lire/ecrire sont les ponts de SURFACE (texte ↔ terme).

% lire : le texte ER devient un terme
?- lire(er, ent_t, "entity person fields [ attr name string , attr age int ] end", M).
M = ent(person, cons(attr(name, string), cons(attr(age, int), nil)))

% la règle du temps 1 transforme le modèle ; ecrire rend le résultat en texte UML
?- classe(cls(person, L)), ecrire(uml, cls_t, cls(person, L), S).
S = class person members [ field name string ; field age int ] end

Trois briques déjà vues : lire (texte→terme), la transformation (temps 1 — une règle sur les faits du modèle) et ecrire (terme→texte). Le modèle vit comme des faits : lire le remplit depuis du texte, la règle en dérive la classe, ecrire la rend. Pas de moteur de transformation magique — du Fix normal. Démontré, pas promis : examples/er-to-uml.fix et le scénario testé scenarios/tde-16-er-to-uml-class.fix-test.


Bidirectionnel : une discipline de richesse de types

Une règle Fix est une relation, et une relation se parcourt dans les deux sens. La transformation ER → UML garde toute la richesse de l'attribut (attr(aname, atype) : le nom ET le type) — donc de la classe UML on retrouve l'entité ER, la même règle répondant à l'envers :

% de la classe (cible), retrouver les attributs de l'entité (source) :
?- classe(cls(person, L)).
L = cons(attr(name, string), cons(attr(age, int), nil))

Mais attention à la bonne idée fausse : le bidirectionnel n'est pas une capacité magique du moteur. C'est une propriété du type.

Autrement dit : la bidirectionnalité se règle au niveau du type, et c'est entre tes mains. Veux-tu l'inverse ? Type richement.

Démontré dans scenarios/tde-13-bidir-is-type-richness.fix-test : un même mécanisme, deux richesses de type, deux comportements au retour.


Les bords honnêtes

Fix nomme ses chantiers plutôt que de les masquer :


Aller plus loin

Chaque feature qui le mérite a son explication dédiée.

Le système de types — programmer les types comme des données :

Le moteur d'inférence — ce que Fix sait faire avec :

La surface — parler la notation de ton domaine :


→ Mettre les mains dedans : Apprendre. La syntaxe exacte : Référence.