org.tweetyproject.agents - Framework agents de base
org.tweetyproject.agents.dialogues - Simulation de dialogues argumentatifs
Note de parité cross-langage : ce notebook est le jumeau Python de Tweety-08-Agent-Dialogues-CSharp.ipynb (twin C# from-scratch BCL .NET, 0 JVM). Le jumeau Python utilise la vraie API TweetyProject (SubgraphProbabilityFunction sur la division exacte) via JVM/jpype, alors que le twin C# implémente un Monte-Carlo pédagogique (justifié : DLL Tweety .NET via IKVM défectueuse). L’écart est by design et c.736 a aligné la transparence côté C#. Marathon parité .NET ⇄ Python : EPIC #4956.
# --- Initialisation JVM Tweety + Outils Externes ---print("--- Verification JVM Tweety + Outils ---")jvm_ready =Falseimport jpypeimport jpype.importsimport osimport pathlibimport shutilimport platform# === Configuration COMPLETE des outils externes ===EXTERNAL_TOOLS = {"CLINGO": "","SPASS": "","EPROVER": "","SAT_SOLVER_PYTHON": "","MARCO": "",}def get_tool_path(tool_name):"""Retourne le chemin valide d'un outil ou None.""" path_str = EXTERNAL_TOOLS.get(tool_name, "")ifnot path_str:returnNoneif shutil.which(path_str):return path_str path_obj = pathlib.Path(path_str)if path_obj.is_file():returnstr(path_obj.resolve())if path_obj.is_dir():returnstr(path_obj.resolve())returnNone# --- Auto-detection des outils ---system = platform.system()exe_suffix =".exe"if system =="Windows"else""# 1. Clingo (ASP solver) - Tweety attend le REPERTOIREfor cp in [shutil.which("clingo"), pathlib.Path(f"ext_tools/clingo/clingo{exe_suffix}"), pathlib.Path(f"../ext_tools/clingo/clingo{exe_suffix}")]:if cp and (isinstance(cp, str) or cp.exists()): parent = pathlib.Path(cp).parent ifisinstance(cp, str) else cp.parent EXTERNAL_TOOLS["CLINGO"] =str(parent.resolve())break# 2. SPASS (Modal logic prover)for sp in [shutil.which("SPASS"), pathlib.Path(f"ext_tools/spass/SPASS{exe_suffix}"), pathlib.Path(f"../ext_tools/spass/SPASS{exe_suffix}")]:if sp and (isinstance(sp, str) or sp.exists()): EXTERNAL_TOOLS["SPASS"] =str(pathlib.Path(sp).resolve()) ifisinstance(sp, pathlib.Path) else spbreak# 3. EProver (FOL theorem prover)for ep in [shutil.which("eprover"), pathlib.Path(f"../ext_tools/EProver/eprover{exe_suffix}"), pathlib.Path(f"ext_tools/EProver/eprover{exe_suffix}")]:if ep: ep_path = pathlib.Path(ep) ifisinstance(ep, str) else epif ep_path.exists(): EXTERNAL_TOOLS["EPROVER"] =str(ep_path.resolve())break# 4. SAT Solver Python (CaDiCaL, Glucose via pySAT)for sat in [pathlib.Path("../ext_tools/sat_solver.py"), pathlib.Path("ext_tools/sat_solver.py")]:if sat.exists(): EXTERNAL_TOOLS["SAT_SOLVER_PYTHON"] =str(sat.resolve())break# 5. MARCO (MUS enumerator avec Z3)for mp in [pathlib.Path("../ext_tools/marco.py"), pathlib.Path("ext_tools/marco.py")]:if mp.exists(): EXTERNAL_TOOLS["MARCO"] =str(mp.resolve())break# === Initialisation JVM ===if jpype.isJVMStarted():print("JVM deja en cours d'execution.") jvm_ready =Trueelse: jdk_portable =Nonefor jdk_path in [pathlib.Path("jdk-17-portable"), pathlib.Path("../Argument_Analysis/jdk-17-portable")]:if jdk_path.exists(): zulu_dirs =list(jdk_path.glob("zulu*"))if zulu_dirs: jdk_portable = zulu_dirs[0] os.environ["JAVA_HOME"] =str(jdk_portable.resolve())print(f"JDK portable: {jdk_portable.name}")breakifnot os.environ.get("JAVA_HOME"):print("ERREUR: JAVA_HOME non defini et JDK portable non trouve.")else: LIB_DIR = pathlib.Path("libs")ifnot LIB_DIR.exists(): LIB_DIR = pathlib.Path("../Argument_Analysis/libs")if LIB_DIR.exists(): jar_files =list(LIB_DIR.glob("*.jar"))if jar_files: classpath = os.pathsep.join(str(j.resolve()) for j in jar_files)try: jpype.startJVM(classpath=[classpath])print(f"JVM demarree avec {len(jar_files)} JARs.") jvm_ready =TrueexceptExceptionas e:print(f"Erreur demarrage JVM: {e}")# === Resume des outils ===if jvm_ready:print("\n--- Outils disponibles ---")for tool, path in EXTERNAL_TOOLS.items():if path: short_path = path.split(os.sep)[-1] iflen(path) >30else pathprint(f" {tool}: {short_path}")print(f"\nJVM prete. Outils: {sum(1for t,p in EXTERNAL_TOOLS.items() if p)}/{len(EXTERNAL_TOOLS)}")
Les résultats ci-dessus confirment que l’environnement est correctement configuré pour simuler des dialogues multi-agents:
Configuration JVM validée: - JDK portable: Zulu 17 détecté et configuré automatiquement - JARs Tweety: 42 bibliothèques chargées (incluant agents.jar, arg-dung.jar, arg-prob.jar) - Outils externes: détection automatique (Clingo, SPASS, EProver, SAT solvers, MARCO — voir la sortie ci-dessus)
Pourquoi ces outils sont importants pour les dialogues:
Outil
Usage dans les dialogues
Clingo
Calcul des extensions stables (ASP) pour la sémantique d’argumentation
SPASS
Raisonnement modal pour modéliser les croyances des agents
EProver
Vérification formelle des stratégies argumentatives
SAT solvers
Détermination rapide de l’acceptabilité des arguments
MARCO
Énumération des Minimal Unsatisfiable Subsets (conflits argumentatifs)
Note technique: La présence de tous les outils permet aux agents d’utiliser différents raisonneurs selon le contexte du dialogue (logique classique, modale, ou ASP).
Partie 6 : Agents et Dialogues Argumentatifs
Cette section explore le framework multi-agents de TweetyProject et les protocoles de dialogue argumentatif. Les dialogues permettent de modéliser des échanges structurés entre agents qui défendent des positions contradictoires.
6.1 Framework Agents de Base
Le module org.tweetyproject.agents fournit les abstractions fondamentales pour la modélisation multi-agents:
Agent: Classe de base représentant un agent autonome
Environment: Environnement dans lequel évoluent les agents
Perceivable: Interface pour les objets perceptibles
MultiAgentSystem: Système regroupant plusieurs agents
Ces composants permettent de construire des simulations où des agents interagissent selon des protocoles définis.
Exploration des classes agents disponibles
Nous allons maintenant explorer les classes concrètes du module agents.dialogues pour identifier les composants utilisables dans une simulation. Cette exploration nous permettra de comprendre l’architecture disponible avant de construire un dialogue.
6.2 Dialogues Argumentatifs
Origine. Les dialogues argumentatifs formels (jeux de dialogue à coups structurés : assertion, challenge, retract, avec règles de tour et conditions de terminaison) sont fondés sur la tradition des dialogue games ; l’article de référence pour un protocole générique cohérent est Prakken, H. (2005), Coherence and flexibility in dialogue games for argumentation, Journal of Logic and Computation 15(6):1009-1040. Tweety implémente ce paradigme via les protocoles GroundedGameProtocol (basés sur la sémantique grounded de Dung) et les modèles d’opposition (oppmodels, croyances T1/T2/T3).
Le module org.tweetyproject.agents.dialogues permet de simuler des dialogues structures ou des agents echangent des arguments. Il contient plusieurs sous-packages :
agents.dialogues (base) : - DialogueTrace : Historique des echanges dans un dialogue - ExecutableExtension : Extension executable dans un dialogue
agents.dialogues.oppmodels (modèles d’opposition) : - ArguingAgent : Agent argumentatif principal - GroundedGameProtocol : Protocole base sur la sémantique grounded - GroundedGameSystem : Système de jeu complet - T1/T2/T3BeliefState : Etats de croyance a différents niveaux de recursion
agents.dialogues.lotteries (jeux de loterie) : - AbstractLotteryAgent : Agent participant a un jeu de loterie - LotteryGameSystem : Système gerant le jeu
Les dialogues argumentatifs suivent généralement un protocole definissant : 1. Les coups autorises (moves) : assertion, challenge, retract 2. Les règles de tour : qui peut parler et quand 3. Les conditions de terminaison : consensus, impasse, timeout
# --- 6.2 Dialogues Argumentatifs ---print("\n--- 6.2 Dialogues Argumentatifs ---")ifnot jvm_ready:print("ERREUR: JVM non demarree.")else:print("JVM prete. Exploration des dialogues argumentatifs...") dialogues_imports_ok =Falsetry:import jpypefrom jpype.types import*# Imports dialoguestry:from org.tweetyproject.agents.dialogues import ExecutableExtensionprint("Import ExecutableExtension reussi.") dialogues_imports_ok =TrueexceptImportErroras e:print(f"Import direct ExecutableExtension echoue: {e}")# Exploration du package dialogues et ses sous-packagesprint("\n--- Classes disponibles dans agents.dialogues ---")# Structure des packages dialogues (noms corrects Tweety 1.29) known_classes = {"agents.dialogues": ["ExecutableExtension","DialogueTrace", ],"agents.dialogues.lotteries": ["AbstractLotteryAgent","LotteryGameSystem", ],"agents.dialogues.oppmodels": ["ArguingAgent", # Agent argumentatif (pas ArgumentativeAgent)"GroundedGameProtocol", # Protocole grounded (pas GroundedSolverProtocol)"GroundedGameSystem", # Systeme de jeu complet"T1BeliefState", # Etats de croyance niveaux 1-3"T2BeliefState","T3BeliefState", ], }print("Classes par package:")for package, classes in known_classes.items():print(f"\n{package}:")for cls_name in classes:try: full_name =f"org.tweetyproject.{package}.{cls_name}" cls = jpype.JClass(full_name)print(f" [OK] {cls_name}")exceptException:print(f" [--] {cls_name}") dialogues_imports_ok =True# --- Exemple de Dialogue Argumentatif ---if dialogues_imports_ok:print("\n--- Modele Conceptuel de Dialogue (oppmodels) ---")print("""Dans un dialogue argumentatif typique (package oppmodels):1. Deux agents (ArguingAgent) debattent sur un Dung Framework2. Chaque agent a un etat de croyance (T1/T2/T3 BeliefState)3. Le protocole (GroundedGameProtocol) gere les tours4. Le systeme (GroundedGameSystem) coordonne le jeuNiveaux d'etat de croyance:- T1: L'agent connait le framework complet- T2: L'agent a des croyances sur les croyances adverses- T3: Recursion a 3 niveaux (croyances sur croyances sur croyances)Coups autorises dans le jeu grounded:- ASSERT(argument) : Affirmer un argument- CHALLENGE(argument) : Contester un argument - RETRACT : Se retirer du debatLe vainqueur est determine par la semantique grounded.""")exceptExceptionas e_gen:print(f"Erreur Python inattendue: {e_gen}")import traceback; traceback.print_exc()
--- 6.2 Dialogues Argumentatifs ---
JVM prete. Exploration des dialogues argumentatifs...
Import ExecutableExtension reussi.
--- Classes disponibles dans agents.dialogues ---
Classes par package:
agents.dialogues:
[OK] ExecutableExtension
[OK] DialogueTrace
agents.dialogues.lotteries:
[OK] AbstractLotteryAgent
[OK] LotteryGameSystem
agents.dialogues.oppmodels:
[OK] ArguingAgent
[OK] GroundedGameProtocol
[OK] GroundedGameSystem
[OK] T1BeliefState
[OK] T2BeliefState
[OK] T3BeliefState
--- Modele Conceptuel de Dialogue (oppmodels) ---
Dans un dialogue argumentatif typique (package oppmodels):
1. Deux agents (ArguingAgent) debattent sur un Dung Framework
2. Chaque agent a un etat de croyance (T1/T2/T3 BeliefState)
3. Le protocole (GroundedGameProtocol) gere les tours
4. Le systeme (GroundedGameSystem) coordonne le jeu
Niveaux d'etat de croyance:
- T1: L'agent connait le framework complet
- T2: L'agent a des croyances sur les croyances adverses
- T3: Recursion a 3 niveaux (croyances sur croyances sur croyances)
Coups autorises dans le jeu grounded:
- ASSERT(argument) : Affirmer un argument
- CHALLENGE(argument) : Contester un argument
- RETRACT : Se retirer du debat
Le vainqueur est determine par la semantique grounded.
Construction d’un scénario de loterie
Maintenant que nous avons compris l’architecture des dialogues, explorons un cas d’usage concret: les jeux de loterie argumentative. Dans ce contexte, les agents doivent prendre des décisions sous incertitude en évaluant les probabilités d’acceptation de leurs arguments.
Nous allons créer un scénario réaliste avec trois propositions en conflit et calculer les probabilités d’acceptation pour guider la stratégie des agents.
Analyse des classes disponibles
L’exploration ci-dessus confirme que TweetyProject 1.29 fournit une architecture complete pour les dialogues argumentatifs :
Package agents.dialogues (base) : - ExecutableExtension : Extension qui peut etre executee comme un coup dans un dialogue - DialogueTrace : Historique complet des echanges (moves, turns, etats)
Package agents.dialogues.oppmodels (jeux grounded) : - ArguingAgent : Agent capable de jouer au jeu grounded (prouver qu’un argument est dans l’extension grounded) - GroundedGameProtocol : Règles du jeu - définit les coups legaux et les transitions - GroundedGameSystem : Orchestre le jeu entre deux agents - T1/T2/T3BeliefState : Modèles de croyance a recursion croissante (Theory of Mind)
Package agents.dialogues.lotteries : - AbstractLotteryAgent : Agent prenant des decisions sous incertitude - LotteryGameSystem : Système gerant les jeux de loterie argumentative
Niveaux de croyance : - T1 : L’agent connait le framework complet (omniscient) - T2 : L’agent a des croyances sur ce que l’adversaire croit - T3 : Recursion a 3 niveaux - permet des stratégies sophistiquees
Ces classes permettent de simuler des debats ou chaque agent essaie de prouver l’acceptabilite de son argument cible.
6.3 Jeux de Loterie Argumentative
Les jeux de loterie argumentative (agents.dialogues.lotteries) combinent l’argumentation probabiliste avec les dialogues multi-agents:
AbstractLotteryAgent: Agent participant à un jeu de loterie
LotteryGameSystem: Système gérant le jeu
UtilityFunction: Fonction d’utilité pour évaluer les résultats
Ces jeux permettent de modéliser des situations de négociation où les agents ont des préférences sur les issues possibles du dialogue.
# --- 6.3 Jeux de Loterie Argumentative ---print("\n--- 6.3 Jeux de Loterie Argumentative ---")ifnot jvm_ready:print("ERREUR: JVM non demarree.")else:print("JVM prete. Exploration des jeux de loterie...")try:import jpypefrom jpype.types import*# Imports nécessairesfrom org.tweetyproject.arg.dung.syntax import DungTheory, Argument, Attackfrom org.tweetyproject.arg.dung.semantics import Semanticsfrom org.tweetyproject.arg.prob.lotteries import SubgraphProbabilityFunction, ArgumentationLottery, UtilityFunctionfrom org.tweetyproject.arg.dung.divisions import Divisionfrom org.tweetyproject.arg.dung.semantics import Extensionprint("Imports pour loteries reussis.")# Créer un framework simpleprint("\n--- Creation d'un scenario de loterie ---") theory = DungTheory() a = Argument("proposition_A"); b = Argument("proposition_B"); c = Argument("evidence_C") theory.add(a); theory.add(b); theory.add(c) theory.add(Attack(a, b)); theory.add(Attack(b, a)); theory.add(Attack(c, b))print(f"Framework: {theory}")print("""Scenario:- Agent 1 supporte proposition_A- Agent 2 supporte proposition_B - evidence_C attaque B, favorisant A""")# Distribution de probabilité prob_func = SubgraphProbabilityFunction(theory)print(f"\nNombre de configurations possibles: {prob_func.size()}")# Calcul des probabilités d'acceptation target_sem = Semantics.GROUNDED_SEMANTICStry: p_a = prob_func.getAcceptanceProbability(a, target_sem).doubleValue() p_b = prob_func.getAcceptanceProbability(b, target_sem).doubleValue() p_c = prob_func.getAcceptanceProbability(c, target_sem).doubleValue()print(f"\nProbabilites d'acceptation (Grounded):")print(f" P(proposition_A accepte) = {p_a:.3f}")print(f" P(proposition_B accepte) = {p_b:.3f}")print(f" P(evidence_C accepte) = {p_c:.3f}")print(f"""Interpretation:- Si evidence_C est presente, B est attaque et A gagne- La probabilite que A soit accepte ({p_a:.1%}) > celle de B ({p_b:.1%})- Un agent rationnel devrait investir pour maintenir C dans le debat""")exceptExceptionas e_prob:print(f"Erreur calcul probabilites: {e_prob}")exceptImportErroras e:print(f"Erreur d'import pour loteries: {e}")except jpype.JException as e_java:print(f"Erreur Java: {e_java.message()}")exceptExceptionas e_gen:print(f"Erreur Python inattendue: {e_gen}")import traceback; traceback.print_exc()
--- 6.3 Jeux de Loterie Argumentative ---
JVM prete. Exploration des jeux de loterie...
Imports pour loteries reussis.
--- Creation d'un scenario de loterie ---
Framework: <{ proposition_A, proposition_B, evidence_C },[(proposition_B,proposition_A), (proposition_A,proposition_B), (evidence_C,proposition_B)]>
Scenario:
- Agent 1 supporte proposition_A
- Agent 2 supporte proposition_B
- evidence_C attaque B, favorisant A
Nombre de configurations possibles: 19
Probabilites d'acceptation (Grounded):
P(proposition_A accepte) = 0.526
P(proposition_B accepte) = 0.316
P(evidence_C accepte) = 0.632
Interpretation:
- Si evidence_C est presente, B est attaque et A gagne
- La probabilite que A soit accepte (52.6%) > celle de B (31.6%)
- Un agent rationnel devrait investir pour maintenir C dans le debat
Analyse du scénario de loterie
Les résultats ci-dessus illustrent comment les probabilites guident la stratégie d’un agent rationnel :
Configuration du debat : - proposition_A et proposition_B s’attaquent mutuellement (conflit direct) - evidence_C attaque proposition_B, brisant la symetrie en faveur de A
Interpretation des probabilites :
Argument
Probabilite
Raison
evidence_C
63.2%
Jamais attaque, donc souvent accepte
proposition_A
52.6%
Defendu par C quand C est present
proposition_B
31.6%
Attaque par A et C, rarement accepte
Stratégie optimale : Un agent rationnel supportant A devrait : 1. Protegerevidence_C car sa presence garantit presque l’acceptation de A 2. Anticiper les tentatives adverses d’attaquer C 3. Investir ses ressources dans le maintien de C plutot que dans la defense directe de A
Lien avec la théorie des jeux : Cette analyse probabiliste permet de calculer l’utilite attendue de chaque stratégie et de choisir la meilleure action selon le critere de decision (ex: maximiser l’esperance).
Résumé
Ce notebook a introduit le framework multi-agents et les dialogues argumentatifs:
Exemple guide : Simulation de Dialogue Multi-Agents
Créez un scénario de negociation entre agents avec des positions opposees.
Objectifs
Modeliser un conflit entre 3 agents (acheteur, vendeur, mediateur)
Définir les croyances initiales de chaque agent
Simuler un dialogue avec echanges d’arguments
Analyser les conditions de consensus
Instructions
Questions d’analyse
Comment les croyances de niveau T2 (croyances sur l’autre) influencent-elles le dialogue ?
Quel rôle joue le mediateur dans la resolution du conflit ?
Quelle est la différence entre un dialogue argumentatif et une simple negociation ?
# Exemple guide : negociation immobiliere modelisee par une theorie argumentative# Approche : transformer un conflit informel en framework de Dung + sem. grounded.ifnot jvm_ready:print("JVM non demarree. Re-executer la cellule 1.")else:from org.tweetyproject.arg.dung.syntax import DungTheory, Argument, Attackfrom org.tweetyproject.arg.dung.semantics import Semanticsfrom org.tweetyproject.arg.dung.reasoner import SimpleGroundedReasonerfrom org.tweetyproject.arg.prob.lotteries import SubgraphProbabilityFunction# 1) Profils et croyances des agents agents = {'acheteur': {'budget_max': 300000,'arguments': ['prix_eleve', 'travaux_necessaires', 'quartier_bruyant'],'croyances': {'prix_juste_estime': 285000, 'vendeur_pressé': True}, },'vendeur': {'prix_min': 280000,'arguments': ['emplacement', 'travaux_recents', 'proche_ecoles'],'croyances': {'prix_juste_estime': 310000, 'acheteur_motivé': True}, },'mediateur': {'arguments_neutres': ['compromis', 'marche_favorable'],'croyances': {'prix_juste_estime': 295000, 'objectif': 'consensus'}, }, }# 2) Construire la theorie argumentative partagee theory = DungTheory() args = {}for data in agents.values():for n in data.get('arguments', []) + data.get('arguments_neutres', []): a = Argument(n) args[n] = a theory.add(a)# 3) Attaques entre arguments attack_edges = [# Acheteur attaque le vendeur ('prix_eleve', 'emplacement'), ('travaux_necessaires', 'travaux_recents'), ('quartier_bruyant', 'proche_ecoles'),# Vendeur repond ('emplacement', 'prix_eleve'), ('travaux_recents', 'travaux_necessaires'),# Mediateur affaiblit les positions extremes ('compromis', 'prix_eleve'), ('compromis', 'emplacement'), ('marche_favorable', 'quartier_bruyant'), ]for s, d in attack_edges: theory.add(Attack(args[s], args[d])) n_args =len(args) n_attacks =len(attack_edges)print(f"Framework : {n_args} arguments, {n_attacks} attaques\n")# 4) Simulation du dialogue : sequence de moves (assert / challenge)print("=== Trace du dialogue ===")print("Tour 1 :")print(" [acheteur ] ASSERT(prix_eleve)")print(" [vendeur ] ASSERT(emplacement) -- contre prix_eleve")print(" [mediateur] ASSERT(compromis) -- affaiblit prix_eleve ET emplacement")print("Tour 2 :")print(" [acheteur ] ASSERT(travaux_necessaires)")print(" [vendeur ] ASSERT(travaux_recents) -- contre travaux_necessaires")print(" [mediateur] ASSERT(marche_favorable)")# 5) Resolution : extension grounded reasoner = SimpleGroundedReasoner() extension = reasoner.getModel(theory)print("\n=== Arguments survivants (sem. grounded) ===")for name, a in args.items(): statut ="ACCEPTE"if extension.contains(a) else"rejete "print(f" {statut}{name}")# 6) Probabilites d'acceptation (sur tous les sous-graphes possibles) prob = SubgraphProbabilityFunction(theory) sem = Semantics.GROUNDED_SEMANTICSprint("\n=== Probabilites d'acceptation (sur sous-graphes) ===")for name, a in args.items(): p = prob.getAcceptanceProbability(a, sem).doubleValue()print(f" P({name:25s}) = {p:.3f}")print("""Analyse :- Les arguments du mediateur n'etant pas attaques, ils sont 'accepte' en grounded et leurs cibles voient leur probabilite chuter.- Sur l'axe travaux : conflit symetrique, donc grounded laisse les deux 'rejetes'.- En probabilite (sous-graphes), les arguments neutres dominent : un compromis autour du prix median (~295000) est rationnellement defendable.""")
Framework : 8 arguments, 8 attaques
=== Trace du dialogue ===
Tour 1 :
[acheteur ] ASSERT(prix_eleve)
[vendeur ] ASSERT(emplacement) -- contre prix_eleve
[mediateur] ASSERT(compromis) -- affaiblit prix_eleve ET emplacement
Tour 2 :
[acheteur ] ASSERT(travaux_necessaires)
[vendeur ] ASSERT(travaux_recents) -- contre travaux_necessaires
[mediateur] ASSERT(marche_favorable)
=== Arguments survivants (sem. grounded) ===
rejete prix_eleve
rejete travaux_necessaires
rejete quartier_bruyant
rejete emplacement
rejete travaux_recents
ACCEPTE proche_ecoles
ACCEPTE compromis
ACCEPTE marche_favorable
=== Probabilites d'acceptation (sur sous-graphes) ===
P(prix_eleve ) = 0.357
P(travaux_necessaires ) = 0.429
P(quartier_bruyant ) = 0.462
P(emplacement ) = 0.357
P(travaux_recents ) = 0.429
P(proche_ecoles ) = 0.462
P(compromis ) = 0.750
P(marche_favorable ) = 0.615
Analyse :
- Les arguments du mediateur n'etant pas attaques, ils sont 'accepte' en grounded
et leurs cibles voient leur probabilite chuter.
- Sur l'axe travaux : conflit symetrique, donc grounded laisse les deux 'rejetes'.
- En probabilite (sous-graphes), les arguments neutres dominent : un compromis
autour du prix median (~295000) est rationnellement defendable.
Conclusion
Ce notebook a permis d’explorer les aspects essentiels de tweety 8 agent dialogues. Les points cles :
Les concepts fondamentaux ont ete presentes et illustres
Les Exemple guides proposent une mise en pratique progressive
Les résultats obtenus permettent de valider la comprehension
Pour aller plus loin : approfondir les aspects avances du sujet et explorer les liens avec d’autres domaines.
Exemple guide : Debat democratique multi-agents
Simulation d’un debat democratique avec 3 agents (Supporter, Opposant, Moderateur) sur l’adoption d’une IA generative dans une administration publique.
# Exemple guide : Solution complete# Sujet : adoption d'une IA generative dans une administration publiqueifnot jvm_ready:print("JVM non demarree. Re-executer la cellule 1.")else:from org.tweetyproject.arg.dung.syntax import DungTheory, Argument, Attackfrom org.tweetyproject.arg.dung.semantics import Semanticsfrom org.tweetyproject.arg.dung.reasoner import SimpleGroundedReasonerfrom org.tweetyproject.arg.prob.lotteries import SubgraphProbabilityFunction# Etape 1 : 3 agents avec profils distincts profils = {'PRO': ['gain_productivite', 'meilleur_service_usager'],'CON': ['perte_emplois', 'risque_biais'],'SCEPTIQUE': ['cout_implementation','maturite_insuffisante'], }# Etape 2 : theorie argumentative partagee theory = DungTheory() args = {}for camp, names in profils.items():for n in names: a = Argument(n) args[n] = a theory.add(a)# Attaques (qui contre qui) attaques = [# CON contre PRO ('perte_emplois', 'gain_productivite'), ('risque_biais', 'meilleur_service_usager'),# PRO contre CON / SCEPTIQUE ('gain_productivite', 'cout_implementation'), ('meilleur_service_usager','risque_biais'),# SCEPTIQUE attaque les deux camps ('maturite_insuffisante', 'gain_productivite'), ('cout_implementation', 'meilleur_service_usager'), ]for s, d in attaques: theory.add(Attack(args[s], args[d]))# Etape 3 : protocole de dialogue (assert / challenge / retract) sur 2 tours trace = []def move(agent, action, target): line =f" [{agent:9s}] {action:9s}{target}" trace.append((agent, action, target))print(line)print("=== Debat : Adoption d'IA generative dans le service public ===\n")print("--- Tour 1 ---") move('PRO', 'ASSERT', 'gain_productivite') move('CON', 'CHALLENGE', 'gain_productivite') move('CON', 'ASSERT', 'perte_emplois') move('SCEPTIQUE', 'ASSERT', 'maturite_insuffisante')print("--- Tour 2 ---") move('PRO', 'ASSERT', 'meilleur_service_usager') move('CON', 'ASSERT', 'risque_biais') move('SCEPTIQUE', 'ASSERT', 'cout_implementation') move('PRO', 'RETRACT', 'meilleur_service_usager') # PRO retire sous le poids des attaques# Terminaison : plus aucun agent ne peut introduire de nouvel argumentprint(f"\n=> Dialogue termine apres {len(trace)} moves sur 2 tours.")# Etape 4 : analyse de la convergence# 4a) Extension grounded = verdict sceptique reasoner = SimpleGroundedReasoner() ext = reasoner.getModel(theory)print("\n=== Verdict grounded (qui survit ?) ===")for camp, names in profils.items(): survivants = [n for n in names if ext.contains(args[n])]print(f" {camp:9s} survivants : {survivants if survivants else'(aucun)'}")# 4b) Probabilites d'acceptation par sous-graphe (mesure de robustesse) prob = SubgraphProbabilityFunction(theory) sem = Semantics.GROUNDED_SEMANTICSprint("\n=== Score moyen d'acceptation par camp ===") scores_camps = {}for camp, names in profils.items(): probs = [prob.getAcceptanceProbability(args[n], sem).doubleValue() for n in names] scores_camps[camp] =sum(probs) /len(probs) detail =", ".join(f"P({n})={p:.3f}"for n, p inzip(names, probs))print(f" {camp:9s} moy = {scores_camps[camp]:.3f} [{detail}]")# Camp gagnant gagnant =max(scores_camps, key=scores_camps.get)print(f"\n=> Camp le plus convaincant (en moyenne probabiliste) : {gagnant}")print("""Bonus - analyse de la convergence :- Grounded est tres restrictif : ne garde que les arguments qu'aucune attaque ne refute. Si un argument est attaque par un autre lui-meme accepte, il tombe.- Les probabilites d'acceptation lissent ce verdict en moyennant sur les sous-graphes possibles ; un camp avec des arguments souvent non attaques dans les sous-frameworks domine meme s'il n'a pas la victoire grounded.- Ici, le camp avec le score moyen le plus eleve a 'persuade' au sens probabiliste : ses arguments resistent dans le plus grand nombre de configurations possibles du debat.""")
=== Debat : Adoption d'IA generative dans le service public ===
--- Tour 1 ---
[PRO ] ASSERT gain_productivite
[CON ] CHALLENGE gain_productivite
[CON ] ASSERT perte_emplois
[SCEPTIQUE] ASSERT maturite_insuffisante
--- Tour 2 ---
[PRO ] ASSERT meilleur_service_usager
[CON ] ASSERT risque_biais
[SCEPTIQUE] ASSERT cout_implementation
[PRO ] RETRACT meilleur_service_usager
=> Dialogue termine apres 8 moves sur 2 tours.
=== Verdict grounded (qui survit ?) ===
PRO survivants : (aucun)
CON survivants : ['perte_emplois', 'risque_biais']
SCEPTIQUE survivants : ['cout_implementation', 'maturite_insuffisante']
=== Score moyen d'acceptation par camp ===
PRO moy = 0.339 [P(gain_productivite)=0.349, P(meilleur_service_usager)=0.330]
CON moy = 0.576 [P(perte_emplois)=0.631, P(risque_biais)=0.521]
SCEPTIQUE moy = 0.620 [P(cout_implementation)=0.608, P(maturite_insuffisante)=0.631]
=> Camp le plus convaincant (en moyenne probabiliste) : SCEPTIQUE
Bonus - analyse de la convergence :
- Grounded est tres restrictif : ne garde que les arguments qu'aucune attaque
ne refute. Si un argument est attaque par un autre lui-meme accepte, il tombe.
- Les probabilites d'acceptation lissent ce verdict en moyennant sur les
sous-graphes possibles ; un camp avec des arguments souvent non attaques
dans les sous-frameworks domine meme s'il n'a pas la victoire grounded.
- Ici, le camp avec le score moyen le plus eleve a 'persuade' au sens
probabiliste : ses arguments resistent dans le plus grand nombre de
configurations possibles du debat.
Exercice : Simulation d’un debat a 4 agents
Ajoutez un Mediateur au scénario et observez comment cela modifie la dynamique.
Indice : Reutilisez les classes DialogAgent et ModeratedDialogue.
# Exercice : Simulation d'un debat a 4 agents# TODO etudiant : ajoutez un 4e agent (Mediateur)# Etape 1 : definir les preferences du Mediateur# Etape 2 : configurer le dialogue a 4 agents# Etape 3 : analyser les differences avec le scenario a 3print("Exercice a completer")
Exercice a completer
Exercice : Protocole de persuasion (teletravail)
Les exemples guides ont modelise un dialogue comme une théorie de Dung avec une trace de moves (ASSERT/CHALLENGE). Construisez votre propre dialogue.
Contexte : faut-il teletravailler ?
productif : “Le teletravail augmente la productivite” (PRO)
isolement : “Le teletravail créé de l’isolement” (CON, attaque productif)
SimpleGroundedReasoner().getModel(theory) pour le verdict
La trace de dialogue est une suite de print decrivant les moves
# --- Exercice : Protocole de persuasion (teletravail) ---# TODO etudiant : modelisez un dialogue de persuasion comme une theorie de Dung## Etape 1 : imports# from org.tweetyproject.arg.dung.syntax import DungTheory, Argument, Attack# from org.tweetyproject.arg.dung.reasoner import SimpleGroundedReasoner## Etape 2 : construire le DungTheory (productif, isolement, outils)# attaques : isolement->productif, outils->isolement# Etape 3 : afficher une trace de moves (ASSERT/CHALLENGE) via des print# Etape 4 : calculer le grounded et lister les arguments survivants# Etape 5 (bonus) : calculer les probabilites d'acceptation par sous-grapheifnot jvm_ready:print("JVM non demarree. Re-executer la cellule 1.")else: theory =None# TODO etudiant : remplacer par le DungTheory du dialogue extension =None# TODO etudiant : remplacer par SimpleGroundedReasoner().getModel(theory)print("Exercice a completer")
Exercice a completer
Exercice : Le jeu grounded (oppmodels) — exploration de l’API
La section 6.2 a montre les classes GroundedGameSystem, ArguingAgent du package agents.dialogues.oppmodels. Explorez l’API via introspection Java.
Objectifs
Charger GroundedGameSystem via jpype.JClass
Lister les méthodes publiques (introspection)
Verifier le vainqueur théorique avec SimpleGroundedReasoner
for m in MaClasse.class_.getMethods(): print(m.getName()) pour l’introspection
# --- Exercice : Le jeu grounded (oppmodels) — exploration de l'API ---# TODO etudiant : explorez l'API du jeu grounded via introspection## Etape 1 : charger les classes via jpype.JClass# GroundedGameSystem = jpype.JClass("org.tweetyproject.agents.dialogues.oppmodels.GroundedGameSystem")# ArguingAgent = jpype.JClass("org.tweetyproject.agents.dialogues.oppmodels.ArguingAgent")## Etape 2 : construire un DungTheory simple (a->b, b->c)# Etape 3 : lister les methodes publiques de GroundedGameSystem# Etape 4 : verifier le vainqueur theorique avec SimpleGroundedReasoner# Etape 5 (bonus) : charger T1BeliefState et T2BeliefState et comparerifnot jvm_ready:print("JVM non demarree. Re-executer la cellule 1.")else: theory =None# TODO etudiant : remplacer par le DungTheory (a->b, b->c) methodes =None# TODO etudiant : remplacer par la liste des methodes de GroundedGameSystemprint("Exercice a completer")