Didacticiel · Java 21
Construire votre premier graphe.
Nous allons créer des véhicules, leurs puissances et leurs couleurs. À chaque étape, le code actuel est rapproché des visualisations Blender qui ont accompagné l'histoire de Generic System.
Avant de coder
Regardez ce que nous allons construire.
La vidéo parcourt le même univers graphique que les images du didacticiel : rouge pour le niveau méta, bleu pour la structure, vert pour les données concrètes.
Les rendus et la vidéo datent de 2015. Ils sont conservés pour leur valeur pédagogique. Le code de cette page, lui, suit l'API actuelle.
Le lecteur est bloqué ? Regarder directement sur YouTube ↗
Construire le moteur depuis le workspace.
Le projet utilise Java 21 et publie actuellement ses artefacts en version 1.0.0-SNAPSHOT dans le dépôt Maven local.
./build-gs.sh gs-kernelDans votre projet Maven :
<dependency>
<groupId>org.genericsystem</groupId>
<artifactId>gs-kernel</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>Il n'existe pas encore de dépôt Maven public à supposer ici : ce parcours utilise les artefacts construits localement.
Créer la racine, puis laisser les niveaux émerger.
Un Engine est une racine Generic System exécutable. Sans chemin de persistance, il travaille en mémoire.
import org.genericsystem.common.Generic;
import org.genericsystem.kernel.Engine;
Engine engine = new Engine();
Generic vehicle = engine.setInstance("Vehicle");
Generic myVehicle = vehicle.setInstance("myVehicle");

Une seule opération, deux niveaux
Vehicle est une instance de la racine : il devient un type structurel. myVehicle est une instance de Vehicle : il devient une donnée concrète.
Le niveau n'est pas ajouté comme une étiquette extérieure. Il est déduit de la chaîne des meta.
Donner une puissance au véhicule.
Un attribut est lui-même un Generic structurel. Le holder qui porte sa valeur en est une instance concrète.
Generic power = vehicle.setAttribute("Power");
power.enablePropertyConstraint();
Generic power233 = myVehicle.setHolder(power, 233);
System.out.println(myVehicle.getValue(power)); // 233

Power dépend de Vehicle ; sa valeur dépend de myVehicle.Un attribut n'est pas seulement une colonne
Power possède un composant : Vehicle. Le holder 233 possède Power pour meta et myVehicle pour composant.
PropertyConstraint exprime qu'une même composition ne peut porter qu'une valeur effective de cette propriété.
Relier le véhicule à une couleur.
Une relation applique le même mécanisme avec plusieurs composants.
Generic color = engine.setInstance("Color");
Generic red = color.setInstance("red");
Generic yellow = color.setInstance("yellow");
Generic vehicleColor = vehicle.setRelation("VehicleColor", color);
Generic myVehicleRed = myVehicle.setLink(vehicleColor, null, red);

VehicleColor et son link concret.Le link est une instance de la relation
VehicleColor possède les composants ordonnés [Vehicle, Color]. Le link possède les composants correspondants [myVehicle, red].
Il n'existe pas de table de jointure parallèle : relation et link appartiennent au même graphe que les types et leurs instances.
Ajouter le temps sans changer de paradigme.
Pour exprimer « ce véhicule a cette couleur à cet instant », la relation reçoit simplement un troisième composant.
Generic time = engine.setInstance("Time");
Generic now = time.setInstance("now");
Generic vehicleColorTime = vehicle.setRelation("VehColTime", color, time);
Generic observation = myVehicle.setLink(vehicleColorTime, null, yellow, now);

L'arité est portée par les composants
Binaire, ternaire ou n-aire : le formalisme reste identique. La composition ordonnée donne son sens à la relation et à chaque link.
La seconde vue historique isole les mêmes dépendances dans une représentation plus détaillée.

Valider le différentiel avec flush().
Les opérations précédentes modifient d'abord le cache courant. Elles sont déjà visibles dans ce contexte, mais ne rejoignent l'état vivant du moteur qu'après validation.
engine.getCurrentCache().flush();Le moteur vérifie les contraintes et applique les créations comme une unité transactionnelle. Pour abandonner des changements non flushés, utilisez engine.getCurrentCache().clear().
Enfin, fermez proprement le moteur :
engine.close();
Mode en mémoire
new Engine() suffit pour apprendre, tester un modèle et exécuter ce didacticiel.
Mode persistant
Un Engine construit avec un chemin de répertoire archive son état. La vidéo historique de la page Vision montre le principe du répertoire de persistance.
Le graphe en un seul programme.
import org.genericsystem.common.Generic;
import org.genericsystem.kernel.Engine;
public final class FirstGraph {
public static void main(String[] args) {
Engine engine = new Engine();
try {
Generic vehicle = engine.setInstance("Vehicle");
Generic color = engine.setInstance("Color");
Generic time = engine.setInstance("Time");
Generic power = vehicle.setAttribute("Power");
power.enablePropertyConstraint();
Generic vehicleColor = vehicle.setRelation("VehicleColor", color);
Generic vehicleColorTime = vehicle.setRelation("VehColTime", color, time);
Generic myVehicle = vehicle.setInstance("myVehicle");
Generic red = color.setInstance("red");
Generic yellow = color.setInstance("yellow");
Generic now = time.setInstance("now");
myVehicle.setHolder(power, 233);
myVehicle.setLink(vehicleColor, null, red);
myVehicle.setLink(vehicleColorTime, null, yellow, now);
engine.getCurrentCache().flush();
} finally {
engine.close();
}
}
}Continuer
Du premier graphe au modèle complet.
La Documentation décrit le modèle, les règles de modélisation, le moteur et les modèles Java — avec l'API actuelle et ses limites. Le détail de chaque mécanisme est dans la Référence.
