Le but de ce TP est d'enrichir le gestionnaire de formules logiques développé lors des précédents travaux pratiques afin de lui permettre de représenter et d'utiliser la logique du premier ordre $\mathcal{L}_{1}$
Vous avez toute liberté pour réaliser les demandes de ce projet du moment que vous respectez les contraintes suivantes:
- Le travail sera obligatoirement en solo.
- Le projet doit être réalisé en Java
- La représentation des données et les algorithmes demandés doivent être complètement implantés et, sauf mention contraire, ne doivent pas déléguer leur traitement à une librairie.
Utilisation d'outils d'aide par l'IA
L'utilisation d'outils d'aide d'IA (ChatGPT, Copilot, Grok, ...) sera intégrée à la notation de la façon suivante:
- Un travail rendu sans aucune aide d'IA sera noté sur une base de 100%
- Un travail réalisé avec l'aide d'IA et déclaré comme tel sera noté sur une base de 60%
- Un travail rendu, réalisé avec l'aide de l'IA sans que cela soit explicitement déclaré sera noté sur une base de 30%
1. Représentation de formules du premier ordre
Implanter en Java une représentation de formules du premier ordre. Cette représentation doit permettre les fonctionnalités détaillées dans les points ci-dessous.
Tous les développements relatif à ce travail doivent se trouver dans le package fr.utln.logic.firstorder.
1.1. Représentation (2pt)
En logique du premier ordre, le premier concept à implanter est le domaine d'interprétation. Un domaine est l'ensemble des valeurs que pourront prendre les variables ou les fonctions. Par exemple, $\Omega_{\mathcal{I}}\ =\ \{0, 1, 2, 3, 4\}$ est un domaine d'interprétation. Les variables relatives à ce domaine pourront y prendre les valeurs 0, 1, 2, 3 ou 4.
Votre bibliothèque doit proposer au moins:
- La classe ou interface Formula doit maintenant permettre de représenter un formule du premier ordre
- une classe ou interface Predicate permettant de représenter un prédicat
- une classe ou interface Function permettant de représenter une fonction
- les classes ou interfaces Var permettant de représenter une variable
La hiérarchie de classe que vous concevrez pourra être plus complexe que seulement les classes Formula et Var. Penser à la façon de représenter les connecteurs ($\neg{}, \wedge{}, \vee{}, \rightarrow{}$ et $\leftrightarrow{}$) et choisissez une structure sous-jacente adaptée (Arbre, Graphe, Tableaux, ....)
1.2. Instanciation de Formule (2pt)
Il doit être possible pour un développeur utilisant vos classes de créer n'importe quelle formule du premier ordre à partir de votre API de façon programmatique.
Exemple
Soit le domaine d'interprétation $\Omega_{\mathcal{I}}\ =\ \{0, 1, 2, 3, 4\}$, l'ensemble des variables $\mathcal{V}\ =\ \{x, y\}$, l'ensemble des prédicats $\mathcal{P}\ =\ \{P, Q, R\}$ et l'ensemble des fonctions $\mathcal{F}\ =\ \{f, g\}$. la formule:
$$\forall{}x\ (((\neg{}P(x)\vee{}Q(f(x), y))\wedge{}(R(x)\rightarrow{}Q(y, x)))\leftrightarrow{}(R(z)\vee{}Q(y, z)))$$
Peut être instanciée grâce à l'instruction:
Formula f = forall("x", equiv(and(or(not(pred("P", "x")), pred("Q", func("f", "x"), "y")), imp(pred("R","x"), pred("Q","y","x"))), or(pred("R", "z"), pred("Q","y","z"))));
1.3. Affichage d'une formule (1 pt)
bibliothèque doit permettre d'afficher une instance de Formula sur la console en utilisant une notation textuelle des opérateurs tels que:
- $\neg{}A$ sera affiché !A
- $A\wedge{}B$ sera affiché A & B
- $A\vee{}B$ sera affiché A | B
- $A\rightarrow{}B$ sera affiché A -> B
- $B\leftrightarrow{}B$ sera affiché A <-> B
- $\forall{}x$ sera affiché #
- $exists{}y$ sera affiché $
Exemple
Les instructions:
Formula f = equiv(and(or(not(var("a")), var("b")), imp(var("c"), var("d"))), or(var("a"), var("d")));
System.out.println("F: "+f);
doivent afficher:
F: (((!a | b) & (c -> d)) <-> (a | d))
1.4. Ecriture de formules (1 pt)
Pour la suite du travail, nous utiliserons a formalisation suivante:
- Domaine d'interprétation: $\Omega_{mathcal{I}}\ =\ =\{Mathieu, Chen, Amir, Laura, Nia, Jin, Amara, Noah, Jack, Kilian, Louiza\}$
- Variables: $\mathcal{V}\ =\ \{x, y, z\}$
- Prédicats: $\mathcal{P}\ =\ \{pere, mere\}$ avec:
- $pere(x, y)$ est vrai si x est le père de y
- $mere(x,y)$ est vrai si x est la mère de y
- Fonctions: $\mathcal{F}\ =\ \{conjoint\}$
Les prédicats sont définis tels que:
- $pere(Jin, Mathieu)$, $pere(Amara, Mathieu)$, $pere(Noah, Amir)$, $pere(Jack, Jin)$, $pere(Kilian, Noah)$
- $mere(Jin, Chen)$, $mere(Amara, Chen)$, $mere(Noah, Laura)$, $mere(Jack, Nia)$, $mere(Kilian, Amara)$
Exercice.
Créer un package fr.utln.logic.firstorder.example.family et y coder les prédicats $pere$, $mere$ définis dans l'exemple précédent.
Les fonctions sont définies telles que:
| $x$ | $conjoint(x)$ |
| Amara | Noah |
| Amir | Laura |
| Chen | Mathieu |
| Emilie | Jack |
| Jack | Emilie |
| Jin | Nia |
| Kilian | Louiza |
| Laura | Amir |
| Louiza | Kilian |
| Mathieu | Chen |
| Nia | Jin |
| Noah | Amara |
Exercice.
Dans le package fr.utln.logic.firstorder.example.family, coder la fonction $conjoint$ définie dans l'exemple précédent.
A partir des prédicats et des fonctions définies, il est possible d'exprimer des relations familiales.
Exercice.
Dans le package fr.utln.logic.firstorder.example.family, ajouter une classe Family.java contenant une méthode main qui instancie la formule $COUSIN(x, y)$ étant vraie si $x$ et $y$ sont cousins. La formule instanciée doit être affichée sur la console.
To be continued...